diff --git a/.postcssrc b/.postcssrc new file mode 100644 index 00000000..2f177c6f --- /dev/null +++ b/.postcssrc @@ -0,0 +1,16 @@ +plugins: + postcss-smart-import: {} + postcss-custom-properties: {} + postcss-apply: {} + postcss-custom-media: {} + postcss-media-minmax: {} + postcss-custom-selectors: {} + postcss-nested-ancestors: {} + postcss-nesting: {} + postcss-nested: {} + postcss-color-function: {} + postcss-color-hex-alpha: {} + postcss-font-variant: {} + postcss-font-family-system-ui: {} + autoprefixer: + browsers: ['last 2 versions', '> 1%'] diff --git a/build/codex-editor.js b/build/codex-editor.js index 95b8bfb4..65ffd604 100644 --- a/build/codex-editor.js +++ b/build/codex-editor.js @@ -7,21 +7,21 @@ var CodexEditor = /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) +/******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; -/******/ +/******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { -/******/ exports: {}, -/******/ id: moduleId, -/******/ loaded: false +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded -/******/ module.loaded = true; +/******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; @@ -34,7109 +34,7291 @@ var CodexEditor = /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(0); +/******/ return __webpack_require__(__webpack_require__.s = 24); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { - /** - * 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 - * ... - */ - - 'use strict'; - - /** - * Require Editor modules places in components/modules dir - */ - - 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 = (["blockManager.js","eventDispatcher.js","renderer.js","toolbar.js","tools.js","ui.js"]).map(function (module) { - - return __webpack_require__(1)("./" + 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 { - - _this2.moduleInstances[Module.name] = 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 modules = {}; - - for (var moduleName in this.moduleInstances) { - - /** - * Skip module with passed name - */ - if (moduleName === name) { - - continue; - } - modules[moduleName] = this.moduleInstances[moduleName]; - } - - return modules; - } - - /** - * 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)).then(prepareDecorator(this.moduleInstances.BlockManager)).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; - // - // })({}); +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +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; }; + +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 () { + function Dom() { + _classCallCheck(this, Dom); + } + + _createClass(Dom, null, [{ + key: 'make', + + + /** + * Helper for making Elements with classname and attributes + * + * @param {string} tagName - new Element tag name + * @param {array|string} classNames - list or name of CSS classname(s) + * @param {Object} attributes - any attributes + * @return {Element} + */ + value: function make(tagName) { + var classNames = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + + var el = document.createElement(tagName); + + if (Array.isArray(classNames)) { + var _el$classList; + + (_el$classList = el.classList).add.apply(_el$classList, _toConsumableArray(classNames)); + } else if (classNames) { + + el.classList.add(classNames); + } + + for (var attrName in attributes) { + + el[attrName] = attributes[attrName]; + } + + return el; + } + + /** + * Append one or several elements to the parent + * + * @param {Element} parent - where to append + * @param {Element|Element[]} - element ore elements list + */ + + }, { + key: 'append', + value: function append(parent, elements) { + + if (Array.isArray(elements)) { + + elements.forEach(function (el) { + return parent.appendChild(el); + }); + } else { + + parent.appendChild(elements); + } + } + + /** + * Selector Decorator + * + * Returns first match + * + * @param {Element} el - element we searching inside. Default - DOM Document + * @param {String} selector - searching string + * + * @returns {Element} + */ + + }, { + key: 'find', + value: function find() { + var el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document; + var selector = arguments[1]; + + + return el.querySelector(selector); + } + + /** + * Selector Decorator. + * + * Returns all matches + * + * @param {Element} el - element we searching inside. Default - DOM Document + * @param {String} selector - searching string + * @returns {NodeList} + */ + + }, { + key: 'findAll', + value: function findAll() { + var el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document; + var selector = arguments[1]; + + + return el.querySelectorAll(selector); + } + }, { + key: 'isNode', + value: function isNode(node) { + + return node && (typeof node === 'undefined' ? 'undefined' : _typeof(node)) === 'object' && node.nodeType && node.nodeType === Node.ELEMENT_NODE; + } + }]); + + return Dom; +}(); + +Dom.displayName = 'Dom'; +exports.default = Dom; +; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { - var map = { - "./_anchors": 2, - "./_anchors.js": 2, - "./_callbacks": 3, - "./_callbacks.js": 3, - "./_caret": 4, - "./_caret.js": 4, - "./_content": 5, - "./_content.js": 5, - "./_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, - "./_sanitizer": 12, - "./_sanitizer.js": 12, - "./_saver": 14, - "./_saver.js": 14, - "./_transport": 15, - "./_transport.js": 15, - "./blockManager": 16, - "./blockManager.js": 16, - "./eventDispatcher": 18, - "./eventDispatcher.js": 18, - "./renderer": 19, - "./renderer.js": 19, - "./toolbar": 21, - "./toolbar.js": 21, - "./toolbar/inline": 22, - "./toolbar/inline.js": 22, - "./toolbar/settings": 23, - "./toolbar/settings.js": 23, - "./toolbar/toolbar": 24, - "./toolbar/toolbar.js": 24, - "./toolbar/toolbox": 25, - "./toolbar/toolbox.js": 25, - "./tools": 26, - "./tools.js": 26, - "./ui": 27, - "./ui.js": 27 - }; - function webpackContext(req) { - return __webpack_require__(webpackContextResolve(req)); - }; - function webpackContextResolve(req) { - return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }()); - }; - webpackContext.keys = function webpackContextKeys() { - return Object.keys(map); - }; - webpackContext.resolve = webpackContextResolve; - module.exports = webpackContext; - webpackContext.id = 1; +"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) { + var success = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; + var fallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {}; + + + 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} success + * @param {Function} fallback + * + * @return {Promise} + */ + function waitNextBlock(chainData, success, fallback) { + + return new Promise(function (resolve) { + + chainData.function().then(function () { + + success(chainData.data); + }).then(resolve).catch(function () { + + fallback(chainData.data); + + // anyway, go ahead even it falls + resolve(); + }); + }); + } + } + + /** + * Make array from array-like collection + * + * @param {*} collection + * + * @return {Array} + */ + + }, { + key: "array", + value: function array(collection) { + + return Array.prototype.slice.call(collection); + } + }]); + + return Util; +}(); + /***/ }), /* 2 */ -/***/ (function(module, exports) { +/***/ (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; - }({}); +"use strict"; + + +/** + * Inline toolbar + * + * Contains from tools: + * Bold, Italic, Underline and Anchor + * + * @author Codex Team + * @version 1.0 + */ + +module.exports = function (inline) { + + var editor = codex.editor; + + inline.buttonsOpened = null; + inline.actionsOpened = null; + inline.wrappersOffset = null; + + /** + * saving selection that need for execCommand for styling + * + */ + inline.storedSelection = null; + + /** + * @protected + * + * Open inline toobar + */ + inline.show = function () { + + var currentNode = editor.content.currentNode, + tool = currentNode.dataset.tool, + plugin; + + /** + * tool allowed to open inline toolbar + */ + plugin = editor.tools[tool]; + + if (!plugin.showInlineToolbar) return; + + var selectedText = inline.getSelectionText(), + toolbar = editor.nodes.inlineToolbar.wrapper; + + if (selectedText.length > 0) { + + /** Move toolbar and open */ + editor.toolbar.inline.move(); + + /** Open inline toolbar */ + toolbar.classList.add('opened'); + + /** show buttons of inline toolbar */ + editor.toolbar.inline.showButtons(); + } + }; + + /** + * @protected + * + * Closes inline toolbar + */ + inline.close = function () { + + var toolbar = editor.nodes.inlineToolbar.wrapper; + + toolbar.classList.remove('opened'); + }; + + /** + * @private + * + * Moving toolbar + */ + inline.move = function () { + + if (!this.wrappersOffset) { + + this.wrappersOffset = this.getWrappersOffset(); + } + + var coords = this.getSelectionCoords(), + defaultOffset = 0, + toolbar = editor.nodes.inlineToolbar.wrapper, + newCoordinateX, + newCoordinateY; + + if (toolbar.offsetHeight === 0) { + + defaultOffset = 40; + } + + newCoordinateX = coords.x - this.wrappersOffset.left; + newCoordinateY = coords.y + window.scrollY - this.wrappersOffset.top - defaultOffset - toolbar.offsetHeight; + + toolbar.style.transform = 'translate3D(' + Math.floor(newCoordinateX) + 'px, ' + Math.floor(newCoordinateY) + 'px, 0)'; + + /** Close everything */ + editor.toolbar.inline.closeButtons(); + editor.toolbar.inline.closeAction(); + }; + + /** + * @private + * + * Tool Clicked + */ + + inline.toolClicked = function (event, type) { + + /** + * For simple tools we use default browser function + * For more complicated tools, we should write our own behavior + */ + switch (type) { + + case 'createLink': + editor.toolbar.inline.createLinkAction(event, type);break; + default: + editor.toolbar.inline.defaultToolAction(type);break; + + } + + /** + * highlight buttons + * after making some action + */ + editor.nodes.inlineToolbar.buttons.childNodes.forEach(editor.toolbar.inline.hightlight); + }; + + /** + * @private + * + * Saving wrappers offset in DOM + */ + inline.getWrappersOffset = function () { + + var wrapper = editor.nodes.wrapper, + offset = this.getOffset(wrapper); + + this.wrappersOffset = offset; + return offset; + }; + + /** + * @private + * + * Calculates offset of DOM element + * + * @param el + * @returns {{top: number, left: number}} + */ + inline.getOffset = function (el) { + + var _x = 0; + var _y = 0; + + while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) { + + _x += el.offsetLeft + el.clientLeft; + _y += el.offsetTop + el.clientTop; + el = el.offsetParent; + } + return { top: _y, left: _x }; + }; + + /** + * @private + * + * Calculates position of selected text + * @returns {{x: number, y: number}} + */ + inline.getSelectionCoords = function () { + + var sel = document.selection, + range; + var x = 0, + y = 0; + + if (sel) { + + if (sel.type != 'Control') { + + range = sel.createRange(); + range.collapse(true); + x = range.boundingLeft; + y = range.boundingTop; + } + } else if (window.getSelection) { + + sel = window.getSelection(); + + if (sel.rangeCount) { + + range = sel.getRangeAt(0).cloneRange(); + if (range.getClientRects) { + + range.collapse(true); + var rect = range.getClientRects()[0]; + + if (!rect) { + + return; + } + + x = rect.left; + y = rect.top; + } + } + } + return { x: x, y: y }; + }; + + /** + * @private + * + * Returns selected text as String + * @returns {string} + */ + inline.getSelectionText = function () { + + var selectedText = ''; + + // all modern browsers and IE9+ + if (window.getSelection) { + + selectedText = window.getSelection().toString(); + } + + return selectedText; + }; + + /** Opens buttons block */ + inline.showButtons = function () { + + var buttons = editor.nodes.inlineToolbar.buttons; + + buttons.classList.add('opened'); + + editor.toolbar.inline.buttonsOpened = true; + + /** highlight buttons */ + editor.nodes.inlineToolbar.buttons.childNodes.forEach(editor.toolbar.inline.hightlight); + }; + + /** Makes buttons disappear */ + inline.closeButtons = function () { + + var buttons = editor.nodes.inlineToolbar.buttons; + + buttons.classList.remove('opened'); + + editor.toolbar.inline.buttonsOpened = false; + }; + + /** Open buttons defined action if exist */ + inline.showActions = function () { + + var action = editor.nodes.inlineToolbar.actions; + + action.classList.add('opened'); + + editor.toolbar.inline.actionsOpened = true; + }; + + /** Close actions block */ + inline.closeAction = function () { + + var action = editor.nodes.inlineToolbar.actions; + + action.innerHTML = ''; + action.classList.remove('opened'); + editor.toolbar.inline.actionsOpened = false; + }; + + /** + * Callback for keydowns in inline toolbar "Insert link..." input + */ + var inlineToolbarAnchorInputKeydown_ = function inlineToolbarAnchorInputKeydown_(event) { + + if (event.keyCode != editor.core.keys.ENTER) { + + return; + } + + var editable = editor.content.currentNode, + storedSelection = editor.toolbar.inline.storedSelection; + + editor.toolbar.inline.restoreSelection(editable, storedSelection); + editor.toolbar.inline.setAnchor(this.value); + + /** + * Preventing events that will be able to happen + */ + event.preventDefault(); + event.stopImmediatePropagation(); + + editor.toolbar.inline.clearRange(); + }; + + /** Action for link creation or for setting anchor */ + inline.createLinkAction = function (event) { + + var isActive = this.isLinkActive(); + + var editable = editor.content.currentNode, + storedSelection = editor.toolbar.inline.saveSelection(editable); + + /** Save globally selection */ + editor.toolbar.inline.storedSelection = storedSelection; + + if (isActive) { + + /** + * Changing stored selection. if we want to remove anchor from word + * we should remove anchor from whole word, not only selected part. + * The solution is than we get the length of current link + * Change start position to - end of selection minus length of anchor + */ + editor.toolbar.inline.restoreSelection(editable, storedSelection); + + editor.toolbar.inline.defaultToolAction('unlink'); + } else { + + /** Create input and close buttons */ + var action = editor.draw.inputForLink(); + + editor.nodes.inlineToolbar.actions.appendChild(action); + + editor.toolbar.inline.closeButtons(); + editor.toolbar.inline.showActions(); + + /** + * focus to input + * Solution: https://developer.mozilla.org/ru/docs/Web/API/HTMLElement/focus + * Prevents event after showing input and when we need to focus an input which is in unexisted form + */ + action.focus(); + event.preventDefault(); + + /** Callback to link action */ + editor.listeners.add(action, 'keydown', inlineToolbarAnchorInputKeydown_, false); + } + }; + + inline.isLinkActive = function () { + + var isActive = false; + + editor.nodes.inlineToolbar.buttons.childNodes.forEach(function (tool) { + + var dataType = tool.dataset.type; + + if (dataType == 'link' && tool.classList.contains('hightlighted')) { + + isActive = true; + } + }); + + return isActive; + }; + + /** default action behavior of tool */ + inline.defaultToolAction = function (type) { + + document.execCommand(type, false, null); + }; + + /** + * @private + * + * Sets URL + * + * @param {String} url - URL + */ + inline.setAnchor = function (url) { + + document.execCommand('createLink', false, url); + + /** Close after URL inserting */ + editor.toolbar.inline.closeAction(); + }; + + /** + * @private + * + * Saves selection + */ + inline.saveSelection = function (containerEl) { + + var range = window.getSelection().getRangeAt(0), + preSelectionRange = range.cloneRange(), + start; + + preSelectionRange.selectNodeContents(containerEl); + preSelectionRange.setEnd(range.startContainer, range.startOffset); + + start = preSelectionRange.toString().length; + + return { + start: start, + end: start + range.toString().length + }; + }; + + /** + * @private + * + * Sets to previous selection (Range) + * + * @param {Element} containerEl - editable element where we restore range + * @param {Object} savedSel - range basic information to restore + */ + inline.restoreSelection = function (containerEl, savedSel) { + + var range = document.createRange(), + charIndex = 0; + + range.setStart(containerEl, 0); + range.collapse(true); + + var nodeStack = [containerEl], + node, + foundStart = false, + stop = false, + nextCharIndex; + + while (!stop && (node = nodeStack.pop())) { + + if (node.nodeType == 3) { + + nextCharIndex = charIndex + node.length; + + if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) { + + range.setStart(node, savedSel.start - charIndex); + foundStart = true; + } + if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) { + + range.setEnd(node, savedSel.end - charIndex); + stop = true; + } + charIndex = nextCharIndex; + } else { + + var i = node.childNodes.length; + + while (i--) { + + nodeStack.push(node.childNodes[i]); + } + } + } + + var sel = window.getSelection(); + + sel.removeAllRanges(); + sel.addRange(range); + }; + + /** + * @private + * + * Removes all ranges from window selection + */ + inline.clearRange = function () { + + var selection = window.getSelection(); + + selection.removeAllRanges(); + }; + + /** + * @private + * + * sets or removes hightlight + */ + inline.hightlight = function (tool) { + + var dataType = tool.dataset.type; + + if (document.queryCommandState(dataType)) { + + editor.toolbar.inline.setButtonHighlighted(tool); + } else { + + editor.toolbar.inline.removeButtonsHighLight(tool); + } + + /** + * + * hightlight for anchors + */ + var selection = window.getSelection(), + tag = selection.anchorNode.parentNode; + + if (tag.tagName == 'A' && dataType == 'link') { + + editor.toolbar.inline.setButtonHighlighted(tool); + } + }; + + /** + * @private + * + * Mark button if text is already executed + */ + inline.setButtonHighlighted = function (button) { + + button.classList.add('hightlighted'); + + /** At link tool we also change icon */ + if (button.dataset.type == 'link') { + + var icon = button.childNodes[0]; + + icon.classList.remove('ce-icon-link'); + icon.classList.add('ce-icon-unlink'); + } + }; + + /** + * @private + * + * Removes hightlight + */ + inline.removeButtonsHighLight = function (button) { + + button.classList.remove('hightlighted'); + + /** At link tool we also change icon */ + if (button.dataset.type == 'link') { + + var icon = button.childNodes[0]; + + icon.classList.remove('ce-icon-unlink'); + icon.classList.add('ce-icon-link'); + } + }; + + return inline; +}({}); /***/ }), /* 3 */ -/***/ (function(module, exports) { +/***/ (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; - }({}); +"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; +}({}); /***/ }), /* 4 */ -/***/ (function(module, exports) { +/***/ (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; - }({}); +"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; +}({}); /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { - 'use strict'; - - var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** - * Codex Editor Content Module - * Works with DOM - * - * @class Content - * @classdesc Class works provides COdex Editor appearance logic - * - * @author Codex Team - * @version 2.0.0 - */ - - var _dom = __webpack_require__(6); - - var _dom2 = _interopRequireDefault(_dom); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - - module.exports = function () { - _createClass(Content, null, [{ - key: 'name', - - - /** - * Module key name - * @returns {string} - */ - get: function get() { - - return 'Content'; - } - - /** - * @constructor - * - * @param {EditorConfig} config - */ - - }]); - - function Content(config) { - _classCallCheck(this, Content); - - this.config = config; - this.Editor = null; - - this.CSS = { - block: 'ce-block', - content: 'ce-block__content', - stretched: 'ce-block--stretched', - highlighted: 'ce-block--highlighted' - }; - - this._currentNode = null; - this._currentIndex = 0; - } - - /** - * Editor modules setter - * @param {object} Editor - */ - - - _createClass(Content, [{ - key: 'composeBlock_', - - - /** - * @private - * @param pluginHTML - * @param {Boolean} isStretched - make stretched block or not - * - * @description adds necessary information to wrap new created block by first-level holder - */ - value: function composeBlock_(pluginHTML) { - var isStretched = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - - var block = _dom2.default.make('DIV', this.CSS.block), - blockContent = _dom2.default.make('DIV', this.CSS.content); - - blockContent.appendChild(pluginHTML); - block.appendChild(blockContent); - - if (isStretched) { - - blockContent.classList.add(this.CSS.stretched); - } - - block.dataset.toolId = this._currentIndex++; - - return block; - } - }, { - key: 'getFirstLevelBlock', - - - /** - * Finds first-level block - * @description looks for first-level block. - * gets parent while node is not first-level - * - * @param {Element} node - selected or clicked in redactors area node - * @protected - * - */ - value: function getFirstLevelBlock(node) { - - if (!_dom2.default.isNode(node)) { - - node = node.parentNode; - } - - if (node === this.Editor.ui.nodes.redactor || node === document.body) { - - return null; - } else { - - while (node.classList && !node.classList.contains(this.CSS.block)) { - - node = node.parentNode; - } - - return node; - } - } - }, { - key: 'insertBlock', - - - /** - * Insert new block to working area - * - * @param {HTMLElement} tool - * - * @returns {Number} tool index - * - */ - value: function insertBlock(tool) { - - var newBlock = this.composeBlock_(tool); - - if (this.currentNode) { - - this.currentNode.insertAdjacentElement('afterend', newBlock); - } else { - - /** - * If redactor is empty, append as first child - */ - this.Editor.ui.nodes.redactor.appendChild(newBlock); - } - - /** - * Set new node as current - */ - this.currentNode = newBlock; - - return newBlock.dataset.toolId; - } - }, { - key: 'state', - set: function set(Editor) { - - this.Editor = Editor; - } - - /** - * Get current working node - * - * @returns {null|HTMLElement} - */ - - }, { - key: 'currentNode', - get: function get() { - - return this._currentNode; - } - - /** - * Set working node. Working node should be first level block, so we find it before set one to _currentNode property - * - * @param {HTMLElement} node - */ - , - set: function set(node) { - - var firstLevelBlock = this.getFirstLevelBlock(node); - - this._currentNode = firstLevelBlock; - } - }]); - - return Content; - }(); - - // module.exports = (function (content) { - // - // let editor = codex.editor; - // - // /** - // * Links to current active block - // * @type {null | Element} - // */ - // content.currentNode = null; - // - // /** - // * clicked in redactor area - // * @type {null | Boolean} - // */ - // content.editorAreaHightlighted = null; - // - // /** - // * @deprecated - // * Synchronizes redactor with original textarea - // */ - // content.sync = function () { - // - // editor.core.log('syncing...'); - // - // /** - // * Save redactor content to editor.state - // */ - // editor.state.html = editor.nodes.redactor.innerHTML; - // - // }; - // - // /** - // * Appends background to the block - // * - // * @description add CSS class to highlight visually first-level block area - // */ - // content.markBlock = function () { - // - // editor.content.currentNode.classList.add(editor.ui.className.BLOCK_HIGHLIGHTED); - // - // }; - // - // /** - // * Clear background - // * - // * @description clears styles that highlights block - // */ - // content.clearMark = function () { - // - // if (editor.content.currentNode) { - // - // editor.content.currentNode.classList.remove(editor.ui.className.BLOCK_HIGHLIGHTED); - // - // } - // - // }; - // - // /** - // * Finds first-level block - // * - // * @param {Element} node - selected or clicked in redactors area node - // * @protected - // * - // * @description looks for first-level block. - // * gets parent while node is not first-level - // */ - // content.getFirstLevelBlock = function (node) { - // - // if (!editor.core.isDomNode(node)) { - // - // node = node.parentNode; - // - // } - // - // if (node === editor.nodes.redactor || node === document.body) { - // - // return null; - // - // } else { - // - // while(!node.classList.contains(editor.ui.className.BLOCK_CLASSNAME)) { - // - // node = node.parentNode; - // - // } - // - // return node; - // - // } - // - // }; - // - // /** - // * Trigger this event when working node changed - // * @param {Element} targetNode - first-level of this node will be current - // * @protected - // * - // * @description If targetNode is first-level then we set it as current else we look for parents to find first-level - // */ - // content.workingNodeChanged = function (targetNode) { - // - // /** Clear background from previous marked block before we change */ - // editor.content.clearMark(); - // - // if (!targetNode) { - // - // return; - // - // } - // - // content.currentNode = content.getFirstLevelBlock(targetNode); - // - // }; - // - // /** - // * Replaces one redactor block with another - // * @protected - // * @param {Element} targetBlock - block to replace. Mostly currentNode. - // * @param {Element} newBlock - // * @param {string} newBlockType - type of new block; we need to store it to data-attribute - // * - // * [!] Function does not saves old block content. - // * You can get it manually and pass with newBlock.innerHTML - // */ - // content.replaceBlock = function (targetBlock, newBlock) { - // - // if (!targetBlock || !newBlock) { - // - // editor.core.log('replaceBlock: missed params'); - // return; - // - // } - // - // /** If target-block is not a frist-level block, then we iterate parents to find it */ - // while(!targetBlock.classList.contains(editor.ui.className.BLOCK_CLASSNAME)) { - // - // targetBlock = targetBlock.parentNode; - // - // } - // - // /** Replacing */ - // editor.nodes.redactor.replaceChild(newBlock, targetBlock); - // - // /** - // * Set new node as current - // */ - // editor.content.workingNodeChanged(newBlock); - // - // /** - // * Add block handlers - // */ - // editor.ui.addBlockHandlers(newBlock); - // - // /** - // * Save changes - // */ - // editor.ui.saveInputs(); - // - // }; - // - // /** - // * @protected - // * - // * Inserts new block to redactor - // * Wrapps block into a DIV with BLOCK_CLASSNAME class - // * - // * @param blockData {object} - // * @param blockData.block {Element} element with block content - // * @param blockData.type {string} block plugin - // * @param needPlaceCaret {bool} pass true to set caret in new block - // * - // */ - // content.insertBlock = function ( blockData, needPlaceCaret ) { - // - // var workingBlock = editor.content.currentNode, - // newBlockContent = blockData.block, - // blockType = blockData.type, - // isStretched = blockData.stretched; - // - // var newBlock = composeNewBlock_(newBlockContent, blockType, isStretched); - // - // if (workingBlock) { - // - // editor.core.insertAfter(workingBlock, newBlock); - // - // } else { - // - // /** - // * If redactor is empty, append as first child - // */ - // editor.nodes.redactor.appendChild(newBlock); - // - // } - // - // /** - // * Block handler - // */ - // editor.ui.addBlockHandlers(newBlock); - // - // /** - // * Set new node as current - // */ - // editor.content.workingNodeChanged(newBlock); - // - // /** - // * Save changes - // */ - // editor.ui.saveInputs(); - // - // - // if ( needPlaceCaret ) { - // - // /** - // * If we don't know input index then we set default value -1 - // */ - // var currentInputIndex = editor.caret.getCurrentInputIndex() || -1; - // - // - // if (currentInputIndex == -1) { - // - // - // var editableElement = newBlock.querySelector('[contenteditable]'), - // emptyText = document.createTextNode(''); - // - // editableElement.appendChild(emptyText); - // editor.caret.set(editableElement, 0, 0); - // - // editor.toolbar.move(); - // editor.toolbar.showPlusButton(); - // - // - // } else { - // - // if (currentInputIndex === editor.state.inputs.length - 1) - // return; - // - // /** Timeout for browsers execution */ - // window.setTimeout(function () { - // - // /** Setting to the new input */ - // editor.caret.setToNextBlock(currentInputIndex); - // editor.toolbar.move(); - // editor.toolbar.open(); - // - // }, 10); - // - // } - // - // } - // - // /** - // * Block is inserted, wait for new click that defined focusing on editors area - // * @type {boolean} - // */ - // content.editorAreaHightlighted = false; - // - // }; - // - // /** - // * Replaces blocks with saving content - // * @protected - // * @param {Element} noteToReplace - // * @param {Element} newNode - // * @param {Element} blockType - // */ - // content.switchBlock = function (blockToReplace, newBlock, tool) { - // - // tool = tool || editor.content.currentNode.dataset.tool; - // var newBlockComposed = composeNewBlock_(newBlock, tool); - // - // /** Replacing */ - // editor.content.replaceBlock(blockToReplace, newBlockComposed); - // - // /** Save new Inputs when block is changed */ - // editor.ui.saveInputs(); - // - // }; - // - // /** - // * Iterates between child noted and looking for #text node on deepest level - // * @protected - // * - // * @param {Element} block - node where find - // * @param {int} postiton - starting postion - // * Example: childNodex.length to find from the end - // * or 0 to find from the start - // * @return {Text} block - // * @uses DFS - // */ - // content.getDeepestTextNodeFromPosition = function (block, position) { - // - // /** - // * Clear Block from empty and useless spaces with trim. - // * Such nodes we should remove - // */ - // var blockChilds = block.childNodes, - // index, - // node, - // text; - // - // for(index = 0; index < blockChilds.length; index++) { - // - // node = blockChilds[index]; - // - // if (node.nodeType == editor.core.nodeTypes.TEXT) { - // - // text = node.textContent.trim(); - // - // /** Text is empty. We should remove this child from node before we start DFS - // * decrease the quantity of childs. - // */ - // if (text === '') { - // - // block.removeChild(node); - // position--; - // - // } - // - // } - // - // } - // - // if (block.childNodes.length === 0) { - // - // return document.createTextNode(''); - // - // } - // - // /** Setting default position when we deleted all empty nodes */ - // if ( position < 0 ) - // position = 1; - // - // var lookingFromStart = false; - // - // /** For looking from START */ - // if (position === 0) { - // - // lookingFromStart = true; - // position = 1; - // - // } - // - // while ( position ) { - // - // /** initial verticle of node. */ - // if ( lookingFromStart ) { - // - // block = block.childNodes[0]; - // - // } else { - // - // block = block.childNodes[position - 1]; - // - // } - // - // if ( block.nodeType == editor.core.nodeTypes.TAG ) { - // - // position = block.childNodes.length; - // - // } else if (block.nodeType == editor.core.nodeTypes.TEXT ) { - // - // position = 0; - // - // } - // - // } - // - // return block; - // - // }; - // - // /** - // * @private - // * @param {Element} block - current plugins render - // * @param {String} tool - plugins name - // * @param {Boolean} isStretched - make stretched block or not - // * - // * @description adds necessary information to wrap new created block by first-level holder - // */ - // var composeNewBlock_ = function (block, tool, isStretched) { - // - // var newBlock = editor.draw.node('DIV', editor.ui.className.BLOCK_CLASSNAME, {}), - // blockContent = editor.draw.node('DIV', editor.ui.className.BLOCK_CONTENT, {}); - // - // blockContent.appendChild(block); - // newBlock.appendChild(blockContent); - // - // if (isStretched) { - // - // blockContent.classList.add(editor.ui.className.BLOCK_STRETCHED); - // - // } - // - // newBlock.dataset.tool = tool; - // return newBlock; - // - // }; - // - // /** - // * Returns Range object of current selection - // * @protected - // */ - // content.getRange = function () { - // - // var selection = window.getSelection().getRangeAt(0); - // - // return selection; - // - // }; - // - // /** - // * Divides block in two blocks (after and before caret) - // * - // * @protected - // * @param {int} inputIndex - target input index - // * - // * @description splits current input content to the separate blocks - // * When enter is pressed among the words, that text will be splited. - // */ - // content.splitBlock = function (inputIndex) { - // - // var selection = window.getSelection(), - // anchorNode = selection.anchorNode, - // anchorNodeText = anchorNode.textContent, - // caretOffset = selection.anchorOffset, - // textBeforeCaret, - // textNodeBeforeCaret, - // textAfterCaret, - // textNodeAfterCaret; - // - // var currentBlock = editor.content.currentNode.querySelector('[contentEditable]'); - // - // - // textBeforeCaret = anchorNodeText.substring(0, caretOffset); - // textAfterCaret = anchorNodeText.substring(caretOffset); - // - // textNodeBeforeCaret = document.createTextNode(textBeforeCaret); - // - // if (textAfterCaret) { - // - // textNodeAfterCaret = document.createTextNode(textAfterCaret); - // - // } - // - // var previousChilds = [], - // nextChilds = [], - // reachedCurrent = false; - // - // if (textNodeAfterCaret) { - // - // nextChilds.push(textNodeAfterCaret); - // - // } - // - // for ( var i = 0, child; !!(child = currentBlock.childNodes[i]); i++) { - // - // if ( child != anchorNode ) { - // - // if ( !reachedCurrent ) { - // - // previousChilds.push(child); - // - // } else { - // - // nextChilds.push(child); - // - // } - // - // } else { - // - // reachedCurrent = true; - // - // } - // - // } - // - // /** Clear current input */ - // editor.state.inputs[inputIndex].innerHTML = ''; - // - // /** - // * Append all childs founded before anchorNode - // */ - // var previousChildsLength = previousChilds.length; - // - // for(i = 0; i < previousChildsLength; i++) { - // - // editor.state.inputs[inputIndex].appendChild(previousChilds[i]); - // - // } - // - // editor.state.inputs[inputIndex].appendChild(textNodeBeforeCaret); - // - // /** - // * Append text node which is after caret - // */ - // var nextChildsLength = nextChilds.length, - // newNode = document.createElement('div'); - // - // for(i = 0; i < nextChildsLength; i++) { - // - // newNode.appendChild(nextChilds[i]); - // - // } - // - // newNode = newNode.innerHTML; - // - // /** This type of block creates when enter is pressed */ - // var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin; - // - // /** - // * Make new paragraph with text after caret - // */ - // editor.content.insertBlock({ - // type : NEW_BLOCK_TYPE, - // block : editor.tools[NEW_BLOCK_TYPE].render({ - // text : newNode - // }) - // }, true ); - // - // }; - // - // /** - // * Merges two blocks — current and target - // * If target index is not exist, then previous will be as target - // * - // * @protected - // * @param {int} currentInputIndex - // * @param {int} targetInputIndex - // * - // * @description gets two inputs indexes and merges into one - // */ - // content.mergeBlocks = function (currentInputIndex, targetInputIndex) { - // - // /** If current input index is zero, then prevent method execution */ - // if (currentInputIndex === 0) { - // - // return; - // - // } - // - // var targetInput, - // currentInputContent = editor.state.inputs[currentInputIndex].innerHTML; - // - // if (!targetInputIndex) { - // - // targetInput = editor.state.inputs[currentInputIndex - 1]; - // - // } else { - // - // targetInput = editor.state.inputs[targetInputIndex]; - // - // } - // - // targetInput.innerHTML += currentInputContent; - // - // }; - // - // /** - // * Iterates all right siblings and parents, which has right siblings - // * while it does not reached the first-level block - // * - // * @param {Element} node - // * @return {boolean} - // */ - // content.isLastNode = function (node) { - // - // // console.log('погнали перебор родителей'); - // - // var allChecked = false; - // - // while ( !allChecked ) { - // - // // console.log('Смотрим на %o', node); - // // console.log('Проверим, пустые ли соседи справа'); - // - // if ( !allSiblingsEmpty_(node) ) { - // - // // console.log('Есть непустые соседи. Узел не последний. Выходим.'); - // return false; - // - // } - // - // node = node.parentNode; - // - // /** - // * Проверяем родителей до тех пор, пока не найдем блок первого уровня - // */ - // if ( node.classList.contains(editor.ui.className.BLOCK_CONTENT) ) { - // - // allChecked = true; - // - // } - // - // } - // - // return true; - // - // }; - // - // /** - // * Checks if all element right siblings is empty - // * @param node - // */ - // var allSiblingsEmpty_ = function (node) { - // - // /** - // * Нужно убедиться, что после пустого соседа ничего нет - // */ - // var sibling = node.nextSibling; - // - // while ( sibling ) { - // - // if (sibling.textContent.length) { - // - // return false; - // - // } - // - // sibling = sibling.nextSibling; - // - // } - // - // return true; - // - // }; - // - // /** - // * @public - // * - // * @param {string} htmlData - html content as string - // * @param {string} plainData - plain text - // * @return {string} - html content as string - // */ - // content.wrapTextWithParagraphs = function (htmlData, plainData) { - // - // if (!htmlData.trim()) { - // - // return wrapPlainTextWithParagraphs(plainData); - // - // } - // - // var wrapper = document.createElement('DIV'), - // newWrapper = document.createElement('DIV'), - // i, - // paragraph, - // firstLevelBlocks = ['DIV', 'P'], - // blockTyped, - // node; - // - // /** - // * Make HTML Element to Wrap Text - // * It allows us to work with input data as HTML content - // */ - // wrapper.innerHTML = htmlData; - // paragraph = document.createElement('P'); - // - // for (i = 0; i < wrapper.childNodes.length; i++) { - // - // node = wrapper.childNodes[i]; - // - // blockTyped = firstLevelBlocks.indexOf(node.tagName) != -1; - // - // /** - // * If node is first-levet - // * we add this node to our new wrapper - // */ - // if ( blockTyped ) { - // - // /** - // * If we had splitted inline nodes to paragraph before - // */ - // if ( paragraph.childNodes.length ) { - // - // newWrapper.appendChild(paragraph.cloneNode(true)); - // - // /** empty paragraph */ - // paragraph = null; - // paragraph = document.createElement('P'); - // - // } - // - // newWrapper.appendChild(node.cloneNode(true)); - // - // } else { - // - // /** Collect all inline nodes to one as paragraph */ - // paragraph.appendChild(node.cloneNode(true)); - // - // /** if node is last we should append this node to paragraph and paragraph to new wrapper */ - // if ( i == wrapper.childNodes.length - 1 ) { - // - // newWrapper.appendChild(paragraph.cloneNode(true)); - // - // } - // - // } - // - // } - // - // return newWrapper.innerHTML; - // - // }; - // - // /** - // * Splits strings on new line and wraps paragraphs with

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

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

') + '

'; - // - // }; - // - // /** - // * Finds closest Contenteditable parent from Element - // * @param {Element} node element looking from - // * @return {Element} node contenteditable - // */ - // content.getEditableParent = function (node) { - // - // while (node && node.contentEditable != 'true') { - // - // node = node.parentNode; - // - // } - // - // return node; - // - // }; - // - // /** - // * Clear editors content - // * - // * @param {Boolean} all — if true, delete all article data (content, id, etc.) - // */ - // content.clear = function (all) { - // - // editor.nodes.redactor.innerHTML = ''; - // editor.content.sync(); - // editor.ui.saveInputs(); - // if (all) { - // - // editor.state.blocks = {}; - // - // } else if (editor.state.blocks) { - // - // editor.state.blocks.items = []; - // - // } - // - // editor.content.currentNode = null; - // - // }; - // - // /** - // * - // * Load new data to editor - // * If editor is not empty, just append articleData.items - // * - // * @param articleData.items - // */ - // content.load = function (articleData) { - // - // var currentContent = Object.assign({}, editor.state.blocks); - // - // editor.content.clear(); - // - // if (!Object.keys(currentContent).length) { - // - // editor.state.blocks = articleData; - // - // } else if (!currentContent.items) { - // - // currentContent.items = articleData.items; - // editor.state.blocks = currentContent; - // - // } else { - // - // currentContent.items = currentContent.items.concat(articleData.items); - // editor.state.blocks = currentContent; - // - // } - // - // editor.renderer.makeBlocksFromData(); - // - // }; - // - // return content; - // - // })({}); +"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; +}({}); /***/ }), /* 6 */ -/***/ (function(module, exports) { +/***/ (function(module, exports, __webpack_require__) { - 'use strict'; - - Object.defineProperty(exports, "__esModule", { - value: true - }); - - 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; }; - - 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 () { - function Dom() { - _classCallCheck(this, Dom); - } - - _createClass(Dom, null, [{ - key: 'make', - - - /** - * Helper for making Elements with classname and attributes - * - * @param {string} tagName - new Element tag name - * @param {array|string} classNames - list or name of CSS classname(s) - * @param {Object} attributes - any attributes - * @return {Element} - */ - value: function make(tagName) { - var classNames = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; - var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - - - var el = document.createElement(tagName); - - if (Array.isArray(classNames)) { - var _el$classList; - - (_el$classList = el.classList).add.apply(_el$classList, _toConsumableArray(classNames)); - } else if (classNames) { - - el.classList.add(classNames); - } - - for (var attrName in attributes) { - - el[attrName] = attributes[attrName]; - } - - return el; - } - - /** - * Append one or several elements to the parent - * - * @param {Element} parent - where to append - * @param {Element|Element[]} - element ore elements list - */ - - }, { - key: 'append', - value: function append(parent, elements) { - - if (Array.isArray(elements)) { - - elements.forEach(function (el) { - return parent.appendChild(el); - }); - } else { - - parent.appendChild(elements); - } - } - - /** - * Selector Decorator - * - * Returns first match - * - * @param {Element} el - element we searching inside. Default - DOM Document - * @param {String} selector - searching string - * - * @returns {Element} - */ - - }, { - key: 'find', - value: function find() { - var el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document; - var selector = arguments[1]; - - - return el.querySelector(selector); - } - - /** - * Selector Decorator. - * - * Returns all matches - * - * @param {Element} el - element we searching inside. Default - DOM Document - * @param {String} selector - searching string - * @returns {NodeList} - */ - - }, { - key: 'findAll', - value: function findAll() { - var el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document; - var selector = arguments[1]; - - - return el.querySelectorAll(selector); - } - }, { - key: 'isNode', - value: function isNode(node) { - - return node && (typeof node === 'undefined' ? 'undefined' : _typeof(node)) === 'object' && node.nodeType && node.nodeType === Node.ELEMENT_NODE; - } - }]); - - return Dom; - }(); - - exports.default = Dom; - ; +"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; +}({}); /***/ }), /* 7 */ -/***/ (function(module, exports) { +/***/ (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; - }({}); +"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; +}({}); /***/ }), /* 8 */ -/***/ (function(module, exports) { +/***/ (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; - }({}); +"use strict"; + + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * Codex Editor Content Module + * Works with DOM + * + * @class Content + * @classdesc Class works provides COdex Editor appearance logic + * + * @author Codex Team + * @version 2.0.0 + */ + +var _dom = __webpack_require__(0); + +var _dom2 = _interopRequireDefault(_dom); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +module.exports = function () { + _createClass(Content, null, [{ + key: 'name', + + + /** + * Module key name + * @returns {string} + */ + get: function get() { + + return 'Content'; + } + + /** + * @constructor + * + * @param {EditorConfig} config + */ + + }]); + + function Content(config) { + _classCallCheck(this, Content); + + this.config = config; + this.Editor = null; + + this.CSS = { + block: 'ce-block', + content: 'ce-block__content', + stretched: 'ce-block--stretched', + highlighted: 'ce-block--highlighted' + }; + + this._currentNode = null; + this._currentIndex = 0; + } + + /** + * Editor modules setter + * @param {object} Editor + */ + + + _createClass(Content, [{ + key: 'composeBlock_', + + + /** + * @private + * @param pluginHTML + * @param {Boolean} isStretched - make stretched block or not + * + * @description adds necessary information to wrap new created block by first-level holder + */ + value: function composeBlock_(pluginHTML) { + var isStretched = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + + var block = _dom2.default.make('DIV', this.CSS.block), + blockContent = _dom2.default.make('DIV', this.CSS.content); + + blockContent.appendChild(pluginHTML); + block.appendChild(blockContent); + + if (isStretched) { + + blockContent.classList.add(this.CSS.stretched); + } + + block.dataset.toolId = this._currentIndex++; + + return block; + } + }, { + key: 'getFirstLevelBlock', + + + /** + * Finds first-level block + * @description looks for first-level block. + * gets parent while node is not first-level + * + * @param {Element} node - selected or clicked in redactors area node + * @protected + * + */ + value: function getFirstLevelBlock(node) { + + if (!_dom2.default.isNode(node)) { + + node = node.parentNode; + } + + if (node === this.Editor.ui.nodes.redactor || node === document.body) { + + return null; + } else { + + while (node.classList && !node.classList.contains(this.CSS.block)) { + + node = node.parentNode; + } + + return node; + } + } + }, { + key: 'insertBlock', + + + /** + * Insert new block to working area + * + * @param {HTMLElement} tool + * + * @returns {Number} tool index + * + */ + value: function insertBlock(tool) { + + var newBlock = this.composeBlock_(tool); + + if (this.currentNode) { + + this.currentNode.insertAdjacentElement('afterend', newBlock); + } else { + + /** + * If redactor is empty, append as first child + */ + this.Editor.ui.nodes.redactor.appendChild(newBlock); + } + + /** + * Set new node as current + */ + this.currentNode = newBlock; + + return newBlock.dataset.toolId; + } + }, { + key: 'state', + set: function set(Editor) { + + this.Editor = Editor; + } + + /** + * Get current working node + * + * @returns {null|HTMLElement} + */ + + }, { + key: 'currentNode', + get: function get() { + + return this._currentNode; + } + + /** + * Set working node. Working node should be first level block, so we find it before set one to _currentNode property + * + * @param {HTMLElement} node + */ + , + set: function set(node) { + + var firstLevelBlock = this.getFirstLevelBlock(node); + + this._currentNode = firstLevelBlock; + } + }]); + + return Content; +}(); + +// module.exports = (function (content) { +// +// let editor = codex.editor; +// +// /** +// * Links to current active block +// * @type {null | Element} +// */ +// content.currentNode = null; +// +// /** +// * clicked in redactor area +// * @type {null | Boolean} +// */ +// content.editorAreaHightlighted = null; +// +// /** +// * @deprecated +// * Synchronizes redactor with original textarea +// */ +// content.sync = function () { +// +// editor.core.log('syncing...'); +// +// /** +// * Save redactor content to editor.state +// */ +// editor.state.html = editor.nodes.redactor.innerHTML; +// +// }; +// +// /** +// * Appends background to the block +// * +// * @description add CSS class to highlight visually first-level block area +// */ +// content.markBlock = function () { +// +// editor.content.currentNode.classList.add(editor.ui.className.BLOCK_HIGHLIGHTED); +// +// }; +// +// /** +// * Clear background +// * +// * @description clears styles that highlights block +// */ +// content.clearMark = function () { +// +// if (editor.content.currentNode) { +// +// editor.content.currentNode.classList.remove(editor.ui.className.BLOCK_HIGHLIGHTED); +// +// } +// +// }; +// +// /** +// * Finds first-level block +// * +// * @param {Element} node - selected or clicked in redactors area node +// * @protected +// * +// * @description looks for first-level block. +// * gets parent while node is not first-level +// */ +// content.getFirstLevelBlock = function (node) { +// +// if (!editor.core.isDomNode(node)) { +// +// node = node.parentNode; +// +// } +// +// if (node === editor.nodes.redactor || node === document.body) { +// +// return null; +// +// } else { +// +// while(!node.classList.contains(editor.ui.className.BLOCK_CLASSNAME)) { +// +// node = node.parentNode; +// +// } +// +// return node; +// +// } +// +// }; +// +// /** +// * Trigger this event when working node changed +// * @param {Element} targetNode - first-level of this node will be current +// * @protected +// * +// * @description If targetNode is first-level then we set it as current else we look for parents to find first-level +// */ +// content.workingNodeChanged = function (targetNode) { +// +// /** Clear background from previous marked block before we change */ +// editor.content.clearMark(); +// +// if (!targetNode) { +// +// return; +// +// } +// +// content.currentNode = content.getFirstLevelBlock(targetNode); +// +// }; +// +// /** +// * Replaces one redactor block with another +// * @protected +// * @param {Element} targetBlock - block to replace. Mostly currentNode. +// * @param {Element} newBlock +// * @param {string} newBlockType - type of new block; we need to store it to data-attribute +// * +// * [!] Function does not saves old block content. +// * You can get it manually and pass with newBlock.innerHTML +// */ +// content.replaceBlock = function (targetBlock, newBlock) { +// +// if (!targetBlock || !newBlock) { +// +// editor.core.log('replaceBlock: missed params'); +// return; +// +// } +// +// /** If target-block is not a frist-level block, then we iterate parents to find it */ +// while(!targetBlock.classList.contains(editor.ui.className.BLOCK_CLASSNAME)) { +// +// targetBlock = targetBlock.parentNode; +// +// } +// +// /** Replacing */ +// editor.nodes.redactor.replaceChild(newBlock, targetBlock); +// +// /** +// * Set new node as current +// */ +// editor.content.workingNodeChanged(newBlock); +// +// /** +// * Add block handlers +// */ +// editor.ui.addBlockHandlers(newBlock); +// +// /** +// * Save changes +// */ +// editor.ui.saveInputs(); +// +// }; +// +// /** +// * @protected +// * +// * Inserts new block to redactor +// * Wrapps block into a DIV with BLOCK_CLASSNAME class +// * +// * @param blockData {object} +// * @param blockData.block {Element} element with block content +// * @param blockData.type {string} block plugin +// * @param needPlaceCaret {bool} pass true to set caret in new block +// * +// */ +// content.insertBlock = function ( blockData, needPlaceCaret ) { +// +// var workingBlock = editor.content.currentNode, +// newBlockContent = blockData.block, +// blockType = blockData.type, +// isStretched = blockData.stretched; +// +// var newBlock = composeNewBlock_(newBlockContent, blockType, isStretched); +// +// if (workingBlock) { +// +// editor.core.insertAfter(workingBlock, newBlock); +// +// } else { +// +// /** +// * If redactor is empty, append as first child +// */ +// editor.nodes.redactor.appendChild(newBlock); +// +// } +// +// /** +// * Block handler +// */ +// editor.ui.addBlockHandlers(newBlock); +// +// /** +// * Set new node as current +// */ +// editor.content.workingNodeChanged(newBlock); +// +// /** +// * Save changes +// */ +// editor.ui.saveInputs(); +// +// +// if ( needPlaceCaret ) { +// +// /** +// * If we don't know input index then we set default value -1 +// */ +// var currentInputIndex = editor.caret.getCurrentInputIndex() || -1; +// +// +// if (currentInputIndex == -1) { +// +// +// var editableElement = newBlock.querySelector('[contenteditable]'), +// emptyText = document.createTextNode(''); +// +// editableElement.appendChild(emptyText); +// editor.caret.set(editableElement, 0, 0); +// +// editor.toolbar.move(); +// editor.toolbar.showPlusButton(); +// +// +// } else { +// +// if (currentInputIndex === editor.state.inputs.length - 1) +// return; +// +// /** Timeout for browsers execution */ +// window.setTimeout(function () { +// +// /** Setting to the new input */ +// editor.caret.setToNextBlock(currentInputIndex); +// editor.toolbar.move(); +// editor.toolbar.open(); +// +// }, 10); +// +// } +// +// } +// +// /** +// * Block is inserted, wait for new click that defined focusing on editors area +// * @type {boolean} +// */ +// content.editorAreaHightlighted = false; +// +// }; +// +// /** +// * Replaces blocks with saving content +// * @protected +// * @param {Element} noteToReplace +// * @param {Element} newNode +// * @param {Element} blockType +// */ +// content.switchBlock = function (blockToReplace, newBlock, tool) { +// +// tool = tool || editor.content.currentNode.dataset.tool; +// var newBlockComposed = composeNewBlock_(newBlock, tool); +// +// /** Replacing */ +// editor.content.replaceBlock(blockToReplace, newBlockComposed); +// +// /** Save new Inputs when block is changed */ +// editor.ui.saveInputs(); +// +// }; +// +// /** +// * Iterates between child noted and looking for #text node on deepest level +// * @protected +// * +// * @param {Element} block - node where find +// * @param {int} postiton - starting postion +// * Example: childNodex.length to find from the end +// * or 0 to find from the start +// * @return {Text} block +// * @uses DFS +// */ +// content.getDeepestTextNodeFromPosition = function (block, position) { +// +// /** +// * Clear Block from empty and useless spaces with trim. +// * Such nodes we should remove +// */ +// var blockChilds = block.childNodes, +// index, +// node, +// text; +// +// for(index = 0; index < blockChilds.length; index++) { +// +// node = blockChilds[index]; +// +// if (node.nodeType == editor.core.nodeTypes.TEXT) { +// +// text = node.textContent.trim(); +// +// /** Text is empty. We should remove this child from node before we start DFS +// * decrease the quantity of childs. +// */ +// if (text === '') { +// +// block.removeChild(node); +// position--; +// +// } +// +// } +// +// } +// +// if (block.childNodes.length === 0) { +// +// return document.createTextNode(''); +// +// } +// +// /** Setting default position when we deleted all empty nodes */ +// if ( position < 0 ) +// position = 1; +// +// var lookingFromStart = false; +// +// /** For looking from START */ +// if (position === 0) { +// +// lookingFromStart = true; +// position = 1; +// +// } +// +// while ( position ) { +// +// /** initial verticle of node. */ +// if ( lookingFromStart ) { +// +// block = block.childNodes[0]; +// +// } else { +// +// block = block.childNodes[position - 1]; +// +// } +// +// if ( block.nodeType == editor.core.nodeTypes.TAG ) { +// +// position = block.childNodes.length; +// +// } else if (block.nodeType == editor.core.nodeTypes.TEXT ) { +// +// position = 0; +// +// } +// +// } +// +// return block; +// +// }; +// +// /** +// * @private +// * @param {Element} block - current plugins render +// * @param {String} tool - plugins name +// * @param {Boolean} isStretched - make stretched block or not +// * +// * @description adds necessary information to wrap new created block by first-level holder +// */ +// var composeNewBlock_ = function (block, tool, isStretched) { +// +// var newBlock = editor.draw.node('DIV', editor.ui.className.BLOCK_CLASSNAME, {}), +// blockContent = editor.draw.node('DIV', editor.ui.className.BLOCK_CONTENT, {}); +// +// blockContent.appendChild(block); +// newBlock.appendChild(blockContent); +// +// if (isStretched) { +// +// blockContent.classList.add(editor.ui.className.BLOCK_STRETCHED); +// +// } +// +// newBlock.dataset.tool = tool; +// return newBlock; +// +// }; +// +// /** +// * Returns Range object of current selection +// * @protected +// */ +// content.getRange = function () { +// +// var selection = window.getSelection().getRangeAt(0); +// +// return selection; +// +// }; +// +// /** +// * Divides block in two blocks (after and before caret) +// * +// * @protected +// * @param {int} inputIndex - target input index +// * +// * @description splits current input content to the separate blocks +// * When enter is pressed among the words, that text will be splited. +// */ +// content.splitBlock = function (inputIndex) { +// +// var selection = window.getSelection(), +// anchorNode = selection.anchorNode, +// anchorNodeText = anchorNode.textContent, +// caretOffset = selection.anchorOffset, +// textBeforeCaret, +// textNodeBeforeCaret, +// textAfterCaret, +// textNodeAfterCaret; +// +// var currentBlock = editor.content.currentNode.querySelector('[contentEditable]'); +// +// +// textBeforeCaret = anchorNodeText.substring(0, caretOffset); +// textAfterCaret = anchorNodeText.substring(caretOffset); +// +// textNodeBeforeCaret = document.createTextNode(textBeforeCaret); +// +// if (textAfterCaret) { +// +// textNodeAfterCaret = document.createTextNode(textAfterCaret); +// +// } +// +// var previousChilds = [], +// nextChilds = [], +// reachedCurrent = false; +// +// if (textNodeAfterCaret) { +// +// nextChilds.push(textNodeAfterCaret); +// +// } +// +// for ( var i = 0, child; !!(child = currentBlock.childNodes[i]); i++) { +// +// if ( child != anchorNode ) { +// +// if ( !reachedCurrent ) { +// +// previousChilds.push(child); +// +// } else { +// +// nextChilds.push(child); +// +// } +// +// } else { +// +// reachedCurrent = true; +// +// } +// +// } +// +// /** Clear current input */ +// editor.state.inputs[inputIndex].innerHTML = ''; +// +// /** +// * Append all childs founded before anchorNode +// */ +// var previousChildsLength = previousChilds.length; +// +// for(i = 0; i < previousChildsLength; i++) { +// +// editor.state.inputs[inputIndex].appendChild(previousChilds[i]); +// +// } +// +// editor.state.inputs[inputIndex].appendChild(textNodeBeforeCaret); +// +// /** +// * Append text node which is after caret +// */ +// var nextChildsLength = nextChilds.length, +// newNode = document.createElement('div'); +// +// for(i = 0; i < nextChildsLength; i++) { +// +// newNode.appendChild(nextChilds[i]); +// +// } +// +// newNode = newNode.innerHTML; +// +// /** This type of block creates when enter is pressed */ +// var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin; +// +// /** +// * Make new paragraph with text after caret +// */ +// editor.content.insertBlock({ +// type : NEW_BLOCK_TYPE, +// block : editor.tools[NEW_BLOCK_TYPE].render({ +// text : newNode +// }) +// }, true ); +// +// }; +// +// /** +// * Merges two blocks — current and target +// * If target index is not exist, then previous will be as target +// * +// * @protected +// * @param {int} currentInputIndex +// * @param {int} targetInputIndex +// * +// * @description gets two inputs indexes and merges into one +// */ +// content.mergeBlocks = function (currentInputIndex, targetInputIndex) { +// +// /** If current input index is zero, then prevent method execution */ +// if (currentInputIndex === 0) { +// +// return; +// +// } +// +// var targetInput, +// currentInputContent = editor.state.inputs[currentInputIndex].innerHTML; +// +// if (!targetInputIndex) { +// +// targetInput = editor.state.inputs[currentInputIndex - 1]; +// +// } else { +// +// targetInput = editor.state.inputs[targetInputIndex]; +// +// } +// +// targetInput.innerHTML += currentInputContent; +// +// }; +// +// /** +// * Iterates all right siblings and parents, which has right siblings +// * while it does not reached the first-level block +// * +// * @param {Element} node +// * @return {boolean} +// */ +// content.isLastNode = function (node) { +// +// // console.log('погнали перебор родителей'); +// +// var allChecked = false; +// +// while ( !allChecked ) { +// +// // console.log('Смотрим на %o', node); +// // console.log('Проверим, пустые ли соседи справа'); +// +// if ( !allSiblingsEmpty_(node) ) { +// +// // console.log('Есть непустые соседи. Узел не последний. Выходим.'); +// return false; +// +// } +// +// node = node.parentNode; +// +// /** +// * Проверяем родителей до тех пор, пока не найдем блок первого уровня +// */ +// if ( node.classList.contains(editor.ui.className.BLOCK_CONTENT) ) { +// +// allChecked = true; +// +// } +// +// } +// +// return true; +// +// }; +// +// /** +// * Checks if all element right siblings is empty +// * @param node +// */ +// var allSiblingsEmpty_ = function (node) { +// +// /** +// * Нужно убедиться, что после пустого соседа ничего нет +// */ +// var sibling = node.nextSibling; +// +// while ( sibling ) { +// +// if (sibling.textContent.length) { +// +// return false; +// +// } +// +// sibling = sibling.nextSibling; +// +// } +// +// return true; +// +// }; +// +// /** +// * @public +// * +// * @param {string} htmlData - html content as string +// * @param {string} plainData - plain text +// * @return {string} - html content as string +// */ +// content.wrapTextWithParagraphs = function (htmlData, plainData) { +// +// if (!htmlData.trim()) { +// +// return wrapPlainTextWithParagraphs(plainData); +// +// } +// +// var wrapper = document.createElement('DIV'), +// newWrapper = document.createElement('DIV'), +// i, +// paragraph, +// firstLevelBlocks = ['DIV', 'P'], +// blockTyped, +// node; +// +// /** +// * Make HTML Element to Wrap Text +// * It allows us to work with input data as HTML content +// */ +// wrapper.innerHTML = htmlData; +// paragraph = document.createElement('P'); +// +// for (i = 0; i < wrapper.childNodes.length; i++) { +// +// node = wrapper.childNodes[i]; +// +// blockTyped = firstLevelBlocks.indexOf(node.tagName) != -1; +// +// /** +// * If node is first-levet +// * we add this node to our new wrapper +// */ +// if ( blockTyped ) { +// +// /** +// * If we had splitted inline nodes to paragraph before +// */ +// if ( paragraph.childNodes.length ) { +// +// newWrapper.appendChild(paragraph.cloneNode(true)); +// +// /** empty paragraph */ +// paragraph = null; +// paragraph = document.createElement('P'); +// +// } +// +// newWrapper.appendChild(node.cloneNode(true)); +// +// } else { +// +// /** Collect all inline nodes to one as paragraph */ +// paragraph.appendChild(node.cloneNode(true)); +// +// /** if node is last we should append this node to paragraph and paragraph to new wrapper */ +// if ( i == wrapper.childNodes.length - 1 ) { +// +// newWrapper.appendChild(paragraph.cloneNode(true)); +// +// } +// +// } +// +// } +// +// return newWrapper.innerHTML; +// +// }; +// +// /** +// * Splits strings on new line and wraps paragraphs with

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

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

') + '

'; +// +// }; +// +// /** +// * Finds closest Contenteditable parent from Element +// * @param {Element} node element looking from +// * @return {Element} node contenteditable +// */ +// content.getEditableParent = function (node) { +// +// while (node && node.contentEditable != 'true') { +// +// node = node.parentNode; +// +// } +// +// return node; +// +// }; +// +// /** +// * Clear editors content +// * +// * @param {Boolean} all — if true, delete all article data (content, id, etc.) +// */ +// content.clear = function (all) { +// +// editor.nodes.redactor.innerHTML = ''; +// editor.content.sync(); +// editor.ui.saveInputs(); +// if (all) { +// +// editor.state.blocks = {}; +// +// } else if (editor.state.blocks) { +// +// editor.state.blocks.items = []; +// +// } +// +// editor.content.currentNode = null; +// +// }; +// +// /** +// * +// * Load new data to editor +// * If editor is not empty, just append articleData.items +// * +// * @param articleData.items +// */ +// content.load = function (articleData) { +// +// var currentContent = Object.assign({}, editor.state.blocks); +// +// editor.content.clear(); +// +// if (!Object.keys(currentContent).length) { +// +// editor.state.blocks = articleData; +// +// } else if (!currentContent.items) { +// +// currentContent.items = articleData.items; +// editor.state.blocks = currentContent; +// +// } else { +// +// currentContent.items = currentContent.items.concat(articleData.items); +// editor.state.blocks = currentContent; +// +// } +// +// editor.renderer.makeBlocksFromData(); +// +// }; +// +// return content; +// +// })({}); /***/ }), /* 9 */ -/***/ (function(module, exports) { +/***/ (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; - }({}); +"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; +}({}); /***/ }), /* 10 */ -/***/ (function(module, exports) { +/***/ (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; - }({}); +"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; +}({}); /***/ }), /* 11 */ -/***/ (function(module, exports) { +/***/ (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; - }({}); +"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; +}({}); /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { - 'use strict'; - - /** - * Codex Sanitizer - */ - - module.exports = function (sanitizer) { - - /** HTML Janitor library */ - var janitor = __webpack_require__(13); - - /** 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; - }({}); +"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; +}({}); /***/ }), /* 13 */ /***/ (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; - - })); +"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; +}({}); + /***/ }), /* 14 */ -/***/ (function(module, exports) { +/***/ (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; - }({}); +"use strict"; + + +/** + * Codex Sanitizer + */ + +module.exports = function (sanitizer) { + + /** HTML Janitor library */ + var janitor = __webpack_require__(26); + + /** 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; +}({}); /***/ }), /* 15 */ -/***/ (function(module, exports) { +/***/ (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; - }({}); +"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; +}({}); /***/ }), /* 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; }; }(); /** - * @class BlockManager - * @classdesc Manage editor`s blocks storage and appearance - * - * - */ - - var _block = __webpack_require__(17); - - var _block2 = _interopRequireDefault(_block); - - var _util = __webpack_require__(20); - - var _util2 = _interopRequireDefault(_util); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - - module.exports = function () { - - /** - * @constructor - * - * @param {EditorConfig} config - */ - function BlockManager(_ref) { - var config = _ref.config; - - _classCallCheck(this, BlockManager); - - this.config = config; - this.Editor = null; - this._blocks = null; - this._currentBloсkIndex = -1; - } - - /** - * Editor modules setting - * - * @param Editor - */ - - - _createClass(BlockManager, [{ - key: 'prepare', - - - /** - * Should be called after Editor.ui preparation - * Define this._blocks property - * - * @returns {Promise} - */ - value: function prepare() { - var _this = this; - - return new Promise(function (resolve) { - - var blocks = new Blocks(_this.Editor.ui.nodes.redactor); - - /** - * We need to use Proxy to overload set/get [] operator. - * So we can use array-like syntax to access blocks - * - * @example - * this._blocks[0] = new Block(...); - * - * block = this._blocks[0]; - * - * @todo proxy the enumerate method - * - * @type {Proxy} - * @private - */ - _this._blocks = new Proxy(blocks, { - set: Blocks.set, - get: Blocks.get - }); - - resolve(); - }); - } - - /** - * Insert new block into _blocks - * - * @param {String} toolName — plugin name - * @param {Object} data — plugin data - */ - - }, { - key: 'insert', - value: function insert(toolName, data) { - - var toolInstance = this.Editor.Tools.construct(toolName, data), - block = new _block2.default(toolInstance); - - this._blocks[++this._currentBloсkIndex] = block; - } - - /** - * Get Block instance by html element - * - * @todo get first level block before searching - * - * @param {HTMLElement} element - * @returns {Block} - */ - - }, { - key: 'getBlock', - value: function getBlock(element) { - - var nodes = this._blocks.nodes, - index = nodes.indexOf(element); - - if (index >= 0) { - - return this._blocks[index]; - } - } - - /** - * Get current Block instance - * - * @return {Block} - */ - - }, { - key: 'state', - set: function set(Editor) { - - this.Editor = Editor; - } - }, { - key: 'currentBlock', - get: function get() { - - return this._blocks[this._currentBloсkIndex]; - } - - /** - * Get working html element - * - * @return {HTMLElement} - */ - - }, { - key: 'currentNode', - get: function get() { - - return this._blocks.nodes[this._currentBloсkIndex]; - } - - /** - * Set _currentBlockIndex to passed block - * - * @todo get first level block before searching - * - * @param {HTMLElement} element - */ - , - set: function set(element) { - - var nodes = this._blocks.nodes; - - this._currentBloсkIndex = nodes.indexOf(element); - } - - /** - * Get array of Block instances - * - * @returns {Block[]} {@link Blocks#array} - */ - - }, { - key: 'blocks', - get: function get() { - - return this._blocks.array; - } - }]); - - return BlockManager; - }(); - - /** - * @class Blocks - * @classdesc Class to work with Block instances array - * - * @private - * - * @property {HTMLElement} workingArea — editor`s working node - * - */ - - var Blocks = function () { - - /** - * @constructor - * - * @param {HTMLElement} workingArea — editor`s working node - */ - function Blocks(workingArea) { - _classCallCheck(this, Blocks); - - this._blocks = []; - this.workingArea = workingArea; - } - - /** - * Push back new Block - * - * @param {Block} block - */ - - - _createClass(Blocks, [{ - key: 'push', - value: function push(block) { - - this._blocks.push(block); - this.workingArea.appendChild(block.html); - } - - /** - * Insert new Block at passed index - * - * @param {Number} index — index to insert Block - * @param {Block} block — Block to insert - */ - - }, { - key: 'insert', - value: function insert(index, block) { - - if (!this.length) { - - this.push(block); - return; - } - - if (index > this.length) { - - // @todo decide how to handle this case - return; - } - - this._blocks[index] = block; - - if (index > 0) { - - var previousBlock = this._blocks[index - 1]; - - previousBlock.html.insertAdjacentElement('afterend', block.html); - } else { - - var nextBlock = this._blocks[index + 1]; - - nextBlock.html.insertAdjacentElement('beforebegin', block.html); - } - } - - /** - * Insert Block after passed target - * - * @todo decide if this method is necessary - * - * @param {Block} targetBlock — target after wich Block should be inserted - * @param {Block} newBlock — Block to insert - */ - - }, { - key: 'insertAfter', - value: function insertAfter(targetBlock, newBlock) { - - var index = this._blocks.indexOf(targetBlock); - - this.insert(index + 1, newBlock); - } - - /** - * Get Block by index - * - * @param {Number} index — Block index - * @returns {Block} - */ - - }, { - key: 'get', - value: function get(index) { - - return this._blocks[index]; - } - - /** - * Return index of passed Block - * - * @param {Block} block - * @returns {Number} - */ - - }, { - key: 'indexOf', - value: function indexOf(block) { - - return this._blocks.indexOf(block); - } - - /** - * Get length of Block instances array - * - * @returns {Number} - */ - - }, { - key: 'length', - get: function get() { - - return this._blocks.length; - } - - /** - * Get Block instances array - * - * @returns {Block[]} - */ - - }, { - key: 'array', - get: function get() { - - return this._blocks; - } - - /** - * Get blocks html elements array - * - * @returns {HTMLElement[]} - */ - - }, { - key: 'nodes', - get: function get() { - - return _util2.default.array(this.workingArea.children); - } - - /** - * Proxy trap to implement array-like setter - * - * @example - * blocks[0] = new Block(...) - * - * @param {Blocks} instance — Blocks instance - * @param {Number|String} index — block index - * @param {Block} block — Block to set - * @returns {Boolean} - */ - - }], [{ - key: 'set', - value: function set(instance, index, block) { - - if (isNaN(Number(index))) { - - return false; - } - - instance.insert(index, block); - - return true; - } - - /** - * Proxy trap to implement array-like getter - * - * @param {Blocks} instance — Blocks instance - * @param {Number|String} index — Block index - * @returns {Block|*} - */ - - }, { - key: 'get', - value: function get(instance, index) { - - if (isNaN(Number(index))) { - - return instance[index]; - } - - return instance.get(index); - } - }]); +"use strict"; - return Blocks; - }(); + +/** + * + * 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; +}({}); /***/ }), /* 17 */ /***/ (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; }; }(); /** - * - * @class Block - * @classdesc This class describes editor`s block, including block`s HTMLElement, data and tool - * - * @property {Tool} tool — current block tool (Paragraph, for example) - * @property {Object} CSS — block`s css classes - * - */ - - var _dom = __webpack_require__(6); - - 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"); } } - - var Block = function () { - - /** - * @constructor - * - * @param {Object} tool — current block plugin`s instance - */ - function Block(tool) { - _classCallCheck(this, Block); - - this.tool = tool; - - this.CSS = { - wrapper: 'ce-block', - content: 'ce-block__content' - }; - - this._html = this.compose(); - } - - /** - * Make default block wrappers and put tool`s content there - * - * @returns {HTMLDivElement} - * @private - */ - - - _createClass(Block, [{ - key: 'compose', - value: function compose() { - - var wrapper = _dom2.default.make('div', this.CSS.wrapper), - content = _dom2.default.make('div', this.CSS.content); - - content.appendChild(this.tool.html); - wrapper.appendChild(content); - - return wrapper; - } - - /** - * Get block`s HTML - * - * @returns {HTMLDivElement} - */ - - }, { - key: 'html', - get: function get() { - - return this._html; - } - }]); - - return Block; - }(); - - exports.default = Block; +"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; }; }(); /** + * @class BlockManager + * @classdesc Manage editor`s blocks storage and appearance + */ + +var _block = __webpack_require__(27); + +var _block2 = _interopRequireDefault(_block); + +var _util = __webpack_require__(1); + +var _util2 = _interopRequireDefault(_util); + +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"); } } + +var BlockManager = function () { + + /** + * @constructor + * + * @param {EditorConfig} config + */ + function BlockManager(_ref) { + var config = _ref.config; + + _classCallCheck(this, BlockManager); + + this.config = config; + this.Editor = null; + this._blocks = null; + this._currentBlockIndex = -1; + } + + /** + * Editor modules setting + * + * @param Editor + */ + + + _createClass(BlockManager, [{ + key: 'prepare', + + + /** + * Should be called after Editor.UI preparation + * Define this._blocks property + * + * @returns {Promise} + */ + value: function prepare() { + var _this = this; + + return new Promise(function (resolve) { + + var blocks = new Blocks(_this.Editor.UI.nodes.redactor); + + /** + * We need to use Proxy to overload set/get [] operator. + * So we can use array-like syntax to access blocks + * + * @example + * this._blocks[0] = new Block(...); + * + * block = this._blocks[0]; + * + * @todo proxy the enumerate method + * + * @type {Proxy} + * @private + */ + _this._blocks = new Proxy(blocks, { + set: Blocks.set, + get: Blocks.get + }); + + resolve(); + }); + } + + /** + * Insert new block into _blocks + * + * @param {String} toolName — plugin name + * @param {Object} data — plugin data + */ + + }, { + key: 'insert', + value: function insert(toolName, data) { + + var toolInstance = this.Editor.Tools.construct(toolName, data), + block = new _block2.default(toolInstance); + + this._blocks[++this._currentBlockIndex] = block; + } + + /** + * Get Block instance by html element + * + * @todo get first level block before searching + * + * @param {HTMLElement} element + * @returns {Block} + */ + + }, { + key: 'getBlock', + value: function getBlock(element) { + + var nodes = this._blocks.nodes, + index = nodes.indexOf(element); + + if (index >= 0) { + + return this._blocks[index]; + } + } + + /** + * Get current Block instance + * + * @return {Block} + */ + + }, { + key: 'state', + set: function set(Editor) { + + this.Editor = Editor; + } + }, { + key: 'currentBlock', + get: function get() { + + return this._blocks[this._currentBlockIndex]; + } + + /** + * Get working html element + * + * @return {HTMLElement} + */ + + }, { + key: 'currentNode', + get: function get() { + + return this._blocks.nodes[this._currentBlockIndex]; + } + + /** + * Set _currentBlockIndex to passed block + * + * @todo get first level block before searching + * + * @param {HTMLElement} element + */ + , + set: function set(element) { + + var nodes = this._blocks.nodes; + + this._currentBlockIndex = nodes.indexOf(element); + } + + /** + * Get array of Block instances + * + * @returns {Block[]} {@link Blocks#array} + */ + + }, { + key: 'blocks', + get: function get() { + + return this._blocks.array; + } + }]); + + return BlockManager; +}(); + +BlockManager.displayName = 'BlockManager'; +; + +/** + * @class Blocks + * @classdesc Class to work with Block instances array + * + * @private + * + * @property {HTMLElement} workingArea — editor`s working node + * + */ + +var Blocks = function () { + + /** + * @constructor + * + * @param {HTMLElement} workingArea — editor`s working node + */ + function Blocks(workingArea) { + _classCallCheck(this, Blocks); + + this._blocks = []; + this.workingArea = workingArea; + } + + /** + * Push back new Block + * + * @param {Block} block + */ + + + _createClass(Blocks, [{ + key: 'push', + value: function push(block) { + + this._blocks.push(block); + this.workingArea.appendChild(block.html); + } + + /** + * Insert new Block at passed index + * + * @param {Number} index — index to insert Block + * @param {Block} block — Block to insert + */ + + }, { + key: 'insert', + value: function insert(index, block) { + + if (!this.length) { + + this.push(block); + return; + } + + if (index > this.length) { + + // @todo decide how to handle this case + return; + } + + this._blocks[index] = block; + + if (index > 0) { + + var previousBlock = this._blocks[index - 1]; + + previousBlock.html.insertAdjacentElement('afterend', block.html); + } else { + + var nextBlock = this._blocks[index + 1]; + + nextBlock.html.insertAdjacentElement('beforebegin', block.html); + } + } + + /** + * Insert Block after passed target + * + * @todo decide if this method is necessary + * + * @param {Block} targetBlock — target after wich Block should be inserted + * @param {Block} newBlock — Block to insert + */ + + }, { + key: 'insertAfter', + value: function insertAfter(targetBlock, newBlock) { + + var index = this._blocks.indexOf(targetBlock); + + this.insert(index + 1, newBlock); + } + + /** + * Get Block by index + * + * @param {Number} index — Block index + * @returns {Block} + */ + + }, { + key: 'get', + value: function get(index) { + + return this._blocks[index]; + } + + /** + * Return index of passed Block + * + * @param {Block} block + * @returns {Number} + */ + + }, { + key: 'indexOf', + value: function indexOf(block) { + + return this._blocks.indexOf(block); + } + + /** + * Get length of Block instances array + * + * @returns {Number} + */ + + }, { + key: 'length', + get: function get() { + + return this._blocks.length; + } + + /** + * Get Block instances array + * + * @returns {Block[]} + */ + + }, { + key: 'array', + get: function get() { + + return this._blocks; + } + + /** + * Get blocks html elements array + * + * @returns {HTMLElement[]} + */ + + }, { + key: 'nodes', + get: function get() { + + return _util2.default.array(this.workingArea.children); + } + + /** + * Proxy trap to implement array-like setter + * + * @example + * blocks[0] = new Block(...) + * + * @param {Blocks} instance — Blocks instance + * @param {Number|String} index — block index + * @param {Block} block — Block to set + * @returns {Boolean} + */ + + }], [{ + key: 'set', + value: function set(instance, index, block) { + + if (isNaN(Number(index))) { + + return false; + } + + instance.insert(index, block); + + return true; + } + + /** + * Proxy trap to implement array-like getter + * + * @param {Blocks} instance — Blocks instance + * @param {Number|String} index — Block index + * @returns {Block|*} + */ + + }, { + key: 'get', + value: function get(instance, index) { + + if (isNaN(Number(index))) { + + return instance[index]; + } + + return instance.get(index); + } + }]); + + return Blocks; +}(); + +Blocks.displayName = 'Blocks'; + + +module.exports = BlockManager; /***/ }), /* 18 */ -/***/ (function(module, exports) { +/***/ (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 - */ - module.exports = 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 - */ - - }], [{ - key: 'name', - - - /** - * Module key name - * @returns {string} - */ - get: function get() { - - return 'Events'; - } - }]); - - 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; - }(); +"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; /***/ }), /* 19 */ /***/ (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 Renderer Module - * - * @author Codex Team - * @version 1.0 - */ - - var _util = __webpack_require__(20); - - var _util2 = _interopRequireDefault(_util); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - - module.exports = function () { - - /** - * @constructor - * - * @param {EditorConfig} config - */ - function Renderer(config) { - _classCallCheck(this, Renderer); - - this.config = config; - this.Editor = null; - } - - /** - * Editor modules setter - * - * @param {Object} Editor - */ - - - _createClass(Renderer, [{ - key: 'render', - - - /** - * - * Make plugin blocks from array of plugin`s data - * - * @param {Object[]} items - */ - value: function render(items) { - var _this = this; - - var chainData = []; - - var _loop = function _loop(i) { - - chainData.push({ - function: function _function() { - return _this.makeBlock(items[i]); - } - }); - }; - - for (var i = 0; i < items.length; i++) { - _loop(i); - } - - _util2.default.sequence(chainData); - } - - /** - * Get plugin instance - * Add plugin instance to BlockManager - * Insert block to working zone - * - * @param {Object} item - * @returns {Promise.} - * @private - */ - - }, { - key: 'makeBlock', - value: function makeBlock(item) { - - var tool = item.type, - data = item.data; - - this.Editor.BlockManager.insert(tool, data); - - return Promise.resolve(); - } - }, { - key: 'state', - set: function set(Editor) { - - this.Editor = Editor; - } - }]); - - return Renderer; - }(); - - // module.exports = (function (renderer) { - // - // let 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 Promise -> 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 «${pluginName}» not found`); - // - // } - // - // /** Check for plugin having render method */ - // if (typeof editor.tools[pluginName].render != 'function') { - // - // throw Error(`Plugin «${pluginName}» must have «render» 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; - // - // })({}); +"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 Renderer Module + * + * @author Codex Team + * @version 1.0 + */ + +var _util = __webpack_require__(1); + +var _util2 = _interopRequireDefault(_util); + +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"); } } + +var Renderer = function () { + + /** + * @constructor + * + * @param {EditorConfig} config + */ + function Renderer(config) { + _classCallCheck(this, Renderer); + + this.config = config; + this.Editor = null; + } + + /** + * Editor modules setter + * + * @param {Object} Editor + */ + + + _createClass(Renderer, [{ + key: 'render', + + + /** + * + * Make plugin blocks from array of plugin`s data + * + * @param {Object[]} items + */ + value: function render(items) { + var _this = this; + + var chainData = []; + + var _loop = function _loop(i) { + + chainData.push({ + function: function _function() { + return _this.makeBlock(items[i]); + } + }); + }; + + for (var i = 0; i < items.length; i++) { + _loop(i); + } + + _util2.default.sequence(chainData); + } + + /** + * Get plugin instance + * Add plugin instance to BlockManager + * Insert block to working zone + * + * @param {Object} item + * @returns {Promise.} + * @private + */ + + }, { + key: 'makeBlock', + value: function makeBlock(item) { + + var tool = item.type, + data = item.data; + + this.Editor.BlockManager.insert(tool, data); + + return Promise.resolve(); + } + }, { + key: 'state', + set: function set(Editor) { + + this.Editor = Editor; + } + }]); + + return Renderer; +}(); + +Renderer.displayName = 'Renderer'; + + +module.exports = Renderer; + +// module.exports = (function (renderer) { +// +// let 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 Promise -> 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 «${pluginName}» not found`); +// +// } +// +// /** Check for plugin having render method */ +// if (typeof editor.tools[pluginName].render != 'function') { +// +// throw Error(`Plugin «${pluginName}» must have «render» 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; +// +// })({}); /***/ }), /* 20 */ -/***/ (function(module, exports) { +/***/ (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) { - var success = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; - var fallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {}; - - - 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(); - }); - }); - } - } - - /** - * Make array from array-like collection - * - * @param {*} collection - * - * @return {Array} - */ - - }, { - key: "array", - value: function array(collection) { - - return Array.prototype.slice.call(collection); - } - }]); - - return Util; - }(); +"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__(0); + +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; /***/ }), /* 21 */ /***/ (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__(6); - - 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 () { - _createClass(Toolbar, null, [{ - key: 'name', - get: function get() { - - return 'Toolbar'; - } - - /** - * @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; - }(); - - module.exports = Toolbar; +"use strict"; + + +/** + * Codex Editor toolbar module + * + * Contains: + * - Inline toolbox + * - Toolbox within plus button + * - Settings section + * + * @author Codex Team + * @version 1.0 + */ + +module.exports = function (toolbar) { + + var editor = codex.editor; + + toolbar.settings = __webpack_require__(3); + toolbar.inline = __webpack_require__(2); + toolbar.toolbox = __webpack_require__(4); + + /** + * Margin between focused node and toolbar + */ + toolbar.defaultToolbarHeight = 49; + + toolbar.defaultOffset = 34; + + toolbar.opened = false; + + toolbar.current = null; + + /** + * @protected + */ + toolbar.open = function () { + + if (editor.hideToolbar) { + + return; + } + + var toolType = editor.content.currentNode.dataset.tool; + + if (!editor.tools[toolType] || !editor.tools[toolType].makeSettings) { + + editor.nodes.showSettingsButton.classList.add('hide'); + } else { + + editor.nodes.showSettingsButton.classList.remove('hide'); + } + + editor.nodes.toolbar.classList.add('opened'); + this.opened = true; + }; + + /** + * @protected + */ + toolbar.close = function () { + + editor.nodes.toolbar.classList.remove('opened'); + + toolbar.opened = false; + toolbar.current = null; + + for (var button in editor.nodes.toolbarButtons) { + + editor.nodes.toolbarButtons[button].classList.remove('selected'); + } + + /** Close toolbox when toolbar is not displayed */ + editor.toolbar.toolbox.close(); + editor.toolbar.settings.close(); + }; + + toolbar.toggle = function () { + + if (!this.opened) { + + this.open(); + } else { + + this.close(); + } + }; + + toolbar.hidePlusButton = function () { + + editor.nodes.plusButton.classList.add('hide'); + }; + + toolbar.showPlusButton = function () { + + editor.nodes.plusButton.classList.remove('hide'); + }; + + /** + * Moving toolbar to the specified node + */ + toolbar.move = function () { + + /** Close Toolbox when we move toolbar */ + editor.toolbar.toolbox.close(); + + if (!editor.content.currentNode) { + + return; + } + + var newYCoordinate = editor.content.currentNode.offsetTop - editor.toolbar.defaultToolbarHeight / 2 + editor.toolbar.defaultOffset; + + editor.nodes.toolbar.style.transform = 'translate3D(0, ' + Math.floor(newYCoordinate) + 'px, 0)'; + + /** Close trash actions */ + editor.toolbar.settings.hideRemoveActions(); + }; + + return toolbar; +}({}); /***/ }), /* 22 */ -/***/ (function(module, exports) { +/***/ (function(module, exports, __webpack_require__) { - 'use strict'; - - /** - * Inline toolbar - * - * Contains from tools: - * Bold, Italic, Underline and Anchor - * - * @author Codex Team - * @version 1.0 - */ - - module.exports = function (inline) { - - var editor = codex.editor; - - inline.buttonsOpened = null; - inline.actionsOpened = null; - inline.wrappersOffset = null; - - /** - * saving selection that need for execCommand for styling - * - */ - inline.storedSelection = null; - - /** - * @protected - * - * Open inline toobar - */ - inline.show = function () { - - var currentNode = editor.content.currentNode, - tool = currentNode.dataset.tool, - plugin; - - /** - * tool allowed to open inline toolbar - */ - plugin = editor.tools[tool]; - - if (!plugin.showInlineToolbar) return; - - var selectedText = inline.getSelectionText(), - toolbar = editor.nodes.inlineToolbar.wrapper; - - if (selectedText.length > 0) { - - /** Move toolbar and open */ - editor.toolbar.inline.move(); - - /** Open inline toolbar */ - toolbar.classList.add('opened'); - - /** show buttons of inline toolbar */ - editor.toolbar.inline.showButtons(); - } - }; - - /** - * @protected - * - * Closes inline toolbar - */ - inline.close = function () { - - var toolbar = editor.nodes.inlineToolbar.wrapper; - - toolbar.classList.remove('opened'); - }; - - /** - * @private - * - * Moving toolbar - */ - inline.move = function () { - - if (!this.wrappersOffset) { - - this.wrappersOffset = this.getWrappersOffset(); - } - - var coords = this.getSelectionCoords(), - defaultOffset = 0, - toolbar = editor.nodes.inlineToolbar.wrapper, - newCoordinateX, - newCoordinateY; - - if (toolbar.offsetHeight === 0) { - - defaultOffset = 40; - } - - newCoordinateX = coords.x - this.wrappersOffset.left; - newCoordinateY = coords.y + window.scrollY - this.wrappersOffset.top - defaultOffset - toolbar.offsetHeight; - - toolbar.style.transform = 'translate3D(' + Math.floor(newCoordinateX) + 'px, ' + Math.floor(newCoordinateY) + 'px, 0)'; - - /** Close everything */ - editor.toolbar.inline.closeButtons(); - editor.toolbar.inline.closeAction(); - }; - - /** - * @private - * - * Tool Clicked - */ - - inline.toolClicked = function (event, type) { - - /** - * For simple tools we use default browser function - * For more complicated tools, we should write our own behavior - */ - switch (type) { - case 'createLink': - editor.toolbar.inline.createLinkAction(event, type);break; - default: - editor.toolbar.inline.defaultToolAction(type);break; - } - - /** - * highlight buttons - * after making some action - */ - editor.nodes.inlineToolbar.buttons.childNodes.forEach(editor.toolbar.inline.hightlight); - }; - - /** - * @private - * - * Saving wrappers offset in DOM - */ - inline.getWrappersOffset = function () { - - var wrapper = editor.nodes.wrapper, - offset = this.getOffset(wrapper); - - this.wrappersOffset = offset; - return offset; - }; - - /** - * @private - * - * Calculates offset of DOM element - * - * @param el - * @returns {{top: number, left: number}} - */ - inline.getOffset = function (el) { - - var _x = 0; - var _y = 0; - - while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) { - - _x += el.offsetLeft + el.clientLeft; - _y += el.offsetTop + el.clientTop; - el = el.offsetParent; - } - return { top: _y, left: _x }; - }; - - /** - * @private - * - * Calculates position of selected text - * @returns {{x: number, y: number}} - */ - inline.getSelectionCoords = function () { - - var sel = document.selection, - range; - var x = 0, - y = 0; - - if (sel) { - - if (sel.type != 'Control') { - - range = sel.createRange(); - range.collapse(true); - x = range.boundingLeft; - y = range.boundingTop; - } - } else if (window.getSelection) { - - sel = window.getSelection(); - - if (sel.rangeCount) { - - range = sel.getRangeAt(0).cloneRange(); - if (range.getClientRects) { - - range.collapse(true); - var rect = range.getClientRects()[0]; - - if (!rect) { - - return; - } - - x = rect.left; - y = rect.top; - } - } - } - return { x: x, y: y }; - }; - - /** - * @private - * - * Returns selected text as String - * @returns {string} - */ - inline.getSelectionText = function () { - - var selectedText = ''; - - // all modern browsers and IE9+ - if (window.getSelection) { - - selectedText = window.getSelection().toString(); - } - - return selectedText; - }; - - /** Opens buttons block */ - inline.showButtons = function () { - - var buttons = editor.nodes.inlineToolbar.buttons; - - buttons.classList.add('opened'); - - editor.toolbar.inline.buttonsOpened = true; - - /** highlight buttons */ - editor.nodes.inlineToolbar.buttons.childNodes.forEach(editor.toolbar.inline.hightlight); - }; - - /** Makes buttons disappear */ - inline.closeButtons = function () { - - var buttons = editor.nodes.inlineToolbar.buttons; - - buttons.classList.remove('opened'); - - editor.toolbar.inline.buttonsOpened = false; - }; - - /** Open buttons defined action if exist */ - inline.showActions = function () { - - var action = editor.nodes.inlineToolbar.actions; - - action.classList.add('opened'); - - editor.toolbar.inline.actionsOpened = true; - }; - - /** Close actions block */ - inline.closeAction = function () { - - var action = editor.nodes.inlineToolbar.actions; - - action.innerHTML = ''; - action.classList.remove('opened'); - editor.toolbar.inline.actionsOpened = false; - }; - - /** - * Callback for keydowns in inline toolbar "Insert link..." input - */ - var inlineToolbarAnchorInputKeydown_ = function inlineToolbarAnchorInputKeydown_(event) { - - if (event.keyCode != editor.core.keys.ENTER) { - - return; - } - - var editable = editor.content.currentNode, - storedSelection = editor.toolbar.inline.storedSelection; - - editor.toolbar.inline.restoreSelection(editable, storedSelection); - editor.toolbar.inline.setAnchor(this.value); - - /** - * Preventing events that will be able to happen - */ - event.preventDefault(); - event.stopImmediatePropagation(); - - editor.toolbar.inline.clearRange(); - }; - - /** Action for link creation or for setting anchor */ - inline.createLinkAction = function (event) { - - var isActive = this.isLinkActive(); - - var editable = editor.content.currentNode, - storedSelection = editor.toolbar.inline.saveSelection(editable); - - /** Save globally selection */ - editor.toolbar.inline.storedSelection = storedSelection; - - if (isActive) { - - /** - * Changing stored selection. if we want to remove anchor from word - * we should remove anchor from whole word, not only selected part. - * The solution is than we get the length of current link - * Change start position to - end of selection minus length of anchor - */ - editor.toolbar.inline.restoreSelection(editable, storedSelection); - - editor.toolbar.inline.defaultToolAction('unlink'); - } else { - - /** Create input and close buttons */ - var action = editor.draw.inputForLink(); - - editor.nodes.inlineToolbar.actions.appendChild(action); - - editor.toolbar.inline.closeButtons(); - editor.toolbar.inline.showActions(); - - /** - * focus to input - * Solution: https://developer.mozilla.org/ru/docs/Web/API/HTMLElement/focus - * Prevents event after showing input and when we need to focus an input which is in unexisted form - */ - action.focus(); - event.preventDefault(); - - /** Callback to link action */ - editor.listeners.add(action, 'keydown', inlineToolbarAnchorInputKeydown_, false); - } - }; - - inline.isLinkActive = function () { - - var isActive = false; - - editor.nodes.inlineToolbar.buttons.childNodes.forEach(function (tool) { - - var dataType = tool.dataset.type; - - if (dataType == 'link' && tool.classList.contains('hightlighted')) { - - isActive = true; - } - }); - - return isActive; - }; - - /** default action behavior of tool */ - inline.defaultToolAction = function (type) { - - document.execCommand(type, false, null); - }; - - /** - * @private - * - * Sets URL - * - * @param {String} url - URL - */ - inline.setAnchor = function (url) { - - document.execCommand('createLink', false, url); - - /** Close after URL inserting */ - editor.toolbar.inline.closeAction(); - }; - - /** - * @private - * - * Saves selection - */ - inline.saveSelection = function (containerEl) { - - var range = window.getSelection().getRangeAt(0), - preSelectionRange = range.cloneRange(), - start; - - preSelectionRange.selectNodeContents(containerEl); - preSelectionRange.setEnd(range.startContainer, range.startOffset); - - start = preSelectionRange.toString().length; - - return { - start: start, - end: start + range.toString().length - }; - }; - - /** - * @private - * - * Sets to previous selection (Range) - * - * @param {Element} containerEl - editable element where we restore range - * @param {Object} savedSel - range basic information to restore - */ - inline.restoreSelection = function (containerEl, savedSel) { - - var range = document.createRange(), - charIndex = 0; - - range.setStart(containerEl, 0); - range.collapse(true); - - var nodeStack = [containerEl], - node, - foundStart = false, - stop = false, - nextCharIndex; - - while (!stop && (node = nodeStack.pop())) { - - if (node.nodeType == 3) { - - nextCharIndex = charIndex + node.length; - - if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) { - - range.setStart(node, savedSel.start - charIndex); - foundStart = true; - } - if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) { - - range.setEnd(node, savedSel.end - charIndex); - stop = true; - } - charIndex = nextCharIndex; - } else { - - var i = node.childNodes.length; - - while (i--) { - - nodeStack.push(node.childNodes[i]); - } - } - } - - var sel = window.getSelection(); - - sel.removeAllRanges(); - sel.addRange(range); - }; - - /** - * @private - * - * Removes all ranges from window selection - */ - inline.clearRange = function () { - - var selection = window.getSelection(); - - selection.removeAllRanges(); - }; - - /** - * @private - * - * sets or removes hightlight - */ - inline.hightlight = function (tool) { - - var dataType = tool.dataset.type; - - if (document.queryCommandState(dataType)) { - - editor.toolbar.inline.setButtonHighlighted(tool); - } else { - - editor.toolbar.inline.removeButtonsHighLight(tool); - } - - /** - * - * hightlight for anchors - */ - var selection = window.getSelection(), - tag = selection.anchorNode.parentNode; - - if (tag.tagName == 'A' && dataType == 'link') { - - editor.toolbar.inline.setButtonHighlighted(tool); - } - }; - - /** - * @private - * - * Mark button if text is already executed - */ - inline.setButtonHighlighted = function (button) { - - button.classList.add('hightlighted'); - - /** At link tool we also change icon */ - if (button.dataset.type == 'link') { - - var icon = button.childNodes[0]; - - icon.classList.remove('ce-icon-link'); - icon.classList.add('ce-icon-unlink'); - } - }; - - /** - * @private - * - * Removes hightlight - */ - inline.removeButtonsHighLight = function (button) { - - button.classList.remove('hightlighted'); - - /** At link tool we also change icon */ - if (button.dataset.type == 'link') { - - var icon = button.childNodes[0]; - - icon.classList.remove('ce-icon-unlink'); - icon.classList.add('ce-icon-link'); - } - }; - - return inline; - }({}); +"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 Codex Editor Tools Submodule + * + * Creates Instances from Plugins and binds external config to the instances + */ + +/** + * Load user defined tools + * Tools must contain the following important objects: + * + * @typedef {Object} ToolsConfig + * @property {String} iconClassname - this a icon in toolbar + * @property {Boolean} displayInToolbox - will be displayed in toolbox. Default value is TRUE + * @property {Boolean} enableLineBreaks - inserts new block or break lines. Default value is FALSE + */ + +/** + * @todo update according to current API + * + * @typedef {Object} Tool + * @property render + * @property save + * @property settings + * @property validate + */ + +/** + * Class properties: + * + * @property {String} name - name of this module + * @property {Object[]} toolInstances - list of tool instances + * @property {Tools[]} available - available Tools + * @property {Tools[]} unavailable - unavailable Tools + * @property {Object} toolsClasses - all classes + * @property {EditorConfig} config - Editor config + */ +var util = __webpack_require__(1); + +var Tools = function () { + _createClass(Tools, [{ + key: 'available', + + + /** + * Returns available Tools + * @return {Tool[]} + */ + get: function get() { + + return this.toolsAvailable; + } + + /** + * Returns unavailable Tools + * @return {Tool[]} + */ + + }, { + key: 'unavailable', + get: function get() { + + return this.toolsUnavailable; + } + + /** + * @param Editor + * @param Editor.modules {@link CodexEditor#moduleInstances} + * @param Editor.config {@link CodexEditor#configuration} + */ + + }, { + key: 'state', + set: function set(Editor) { + + this.Editor = Editor; + } + + /** + * If config wasn't passed by user + * @return {ToolsConfig} + */ + + }, { + key: 'defaultConfig', + get: function get() { + + return { + iconClassName: 'default-icon', + displayInToolbox: false, + enableLineBreaks: false + }; + } + + /** + * @constructor + * + * @param {ToolsConfig} config + */ + + }]); + + function Tools(_ref) { + var config = _ref.config; + + _classCallCheck(this, Tools); + + this.config = config; + + this.toolClasses = {}; + this.toolsAvailable = {}; + this.toolsUnavailable = {}; + } + + /** + * Creates instances via passed or default configuration + * @return {boolean} + */ + + + _createClass(Tools, [{ + key: 'prepare', + value: function prepare() { + var _this = this; + + if (!this.config.hasOwnProperty('tools')) { + + return Promise.reject("Can't start without tools"); + } + + for (var toolName in this.config.tools) { + + this.toolClasses[toolName] = this.config.tools[toolName]; + } + + /** + * getting classes that has prepare method + */ + var sequenceData = this.getListOfPrepareFunctions(); + + /** + * if sequence data contains nothing then resolve current chain and run other module prepare + */ + if (sequenceData.length === 0) { + + return Promise.resolve(); + } + + /** + * to see how it works {@link Util#sequence} + */ + return util.sequence(sequenceData, function (data) { + + _this.success(data); + }, function (data) { + + _this.fallback(data); + }); + } + + /** + * Binds prepare function of plugins with user or default config + * @return {Array} list of functions that needs to be fired sequently + */ + + }, { + key: 'getListOfPrepareFunctions', + value: function getListOfPrepareFunctions() { + + var toolPreparationList = []; + + for (var toolName in this.toolClasses) { + + var toolClass = this.toolClasses[toolName]; + + if (typeof toolClass.prepare === 'function') { + + toolPreparationList.push({ + function: toolClass.prepare, + data: { + toolName: toolName + } + }); + } + } + + return toolPreparationList; + } + + /** + * @param {ChainData.data} data - append tool to available list + */ + + }, { + key: 'success', + value: function success(data) { + + this.toolsAvailable[data.toolName] = this.toolClasses[data.toolName]; + } + + /** + * @param {ChainData.data} data - append tool to unavailable list + */ + + }, { + key: 'fallback', + value: function fallback(data) { + + this.toolsUnavailable[data.toolName] = this.toolClasses[data.toolName]; + } + + /** + * Returns all tools + * @return {Array} + */ + + }, { + key: 'getTools', + value: function getTools() { + + return this.toolInstances; + } + + /** + * Return tool`a instance + * + * @param {String} tool — tool name + * @param {Object} data — initial data + * + * @todo throw exceptions if tool doesnt exist + * + */ + + }, { + key: 'construct', + value: function construct(tool, data) { + + var plugin = this.toolClasses[tool], + config = this.config.toolsConfig[tool]; + + var instance = new plugin(data, config); + + return instance; + } + }]); + + return Tools; +}(); + +Tools.displayName = 'Tools'; + + +module.exports = Tools; /***/ }), /* 23 */ -/***/ (function(module, exports) { +/***/ (function(module, exports, __webpack_require__) { - 'use strict'; - - /** - * Toolbar settings - * - * @version 1.0.5 - */ - - module.exports = function (settings) { - - var editor = codex.editor; - - settings.opened = false; - - settings.setting = null; - settings.actions = null; - - /** - * Append and open settings - */ - settings.open = function (toolType) { - - /** - * Append settings content - * It's stored in tool.settings - */ - if (!editor.tools[toolType] || !editor.tools[toolType].makeSettings) { - - return; - } - - /** - * Draw settings block - */ - var settingsBlock = editor.tools[toolType].makeSettings(); - - editor.nodes.pluginSettings.appendChild(settingsBlock); - - /** Open settings block */ - editor.nodes.blockSettings.classList.add('opened'); - this.opened = true; - }; - - /** - * Close and clear settings - */ - settings.close = function () { - - editor.nodes.blockSettings.classList.remove('opened'); - editor.nodes.pluginSettings.innerHTML = ''; - - this.opened = false; - }; - - /** - * @param {string} toolType - plugin type - */ - settings.toggle = function (toolType) { - - if (!this.opened) { - - this.open(toolType); - } else { - - this.close(); - } - }; - - /** - * Here we will draw buttons and add listeners to components - */ - settings.makeRemoveBlockButton = function () { - - var removeBlockWrapper = editor.draw.node('SPAN', 'ce-toolbar__remove-btn', {}), - settingButton = editor.draw.node('SPAN', 'ce-toolbar__remove-setting', { innerHTML: '' }), - actionWrapper = editor.draw.node('DIV', 'ce-toolbar__remove-confirmation', {}), - confirmAction = editor.draw.node('DIV', 'ce-toolbar__remove-confirm', { textContent: 'Удалить блок' }), - cancelAction = editor.draw.node('DIV', 'ce-toolbar__remove-cancel', { textContent: 'Отмена' }); - - editor.listeners.add(settingButton, 'click', editor.toolbar.settings.removeButtonClicked, false); - - editor.listeners.add(confirmAction, 'click', editor.toolbar.settings.confirmRemovingRequest, false); - - editor.listeners.add(cancelAction, 'click', editor.toolbar.settings.cancelRemovingRequest, false); - - actionWrapper.appendChild(confirmAction); - actionWrapper.appendChild(cancelAction); - - removeBlockWrapper.appendChild(settingButton); - removeBlockWrapper.appendChild(actionWrapper); - - /** Save setting */ - editor.toolbar.settings.setting = settingButton; - editor.toolbar.settings.actions = actionWrapper; - - return removeBlockWrapper; - }; - - settings.removeButtonClicked = function () { - - var action = editor.toolbar.settings.actions; - - if (action.classList.contains('opened')) { - - editor.toolbar.settings.hideRemoveActions(); - } else { - - editor.toolbar.settings.showRemoveActions(); - } - - editor.toolbar.toolbox.close(); - editor.toolbar.settings.close(); - }; - - settings.cancelRemovingRequest = function () { - - editor.toolbar.settings.actions.classList.remove('opened'); - }; - - settings.confirmRemovingRequest = function () { - - var currentBlock = editor.content.currentNode, - firstLevelBlocksCount; - - currentBlock.remove(); - - firstLevelBlocksCount = editor.nodes.redactor.childNodes.length; - - /** - * If all blocks are removed - */ - if (firstLevelBlocksCount === 0) { - - /** update currentNode variable */ - editor.content.currentNode = null; - - /** Inserting new empty initial block */ - editor.ui.addInitialBlock(); - } - - editor.ui.saveInputs(); - - editor.toolbar.close(); - }; - - settings.showRemoveActions = function () { - - editor.toolbar.settings.actions.classList.add('opened'); - }; - - settings.hideRemoveActions = function () { - - editor.toolbar.settings.actions.classList.remove('opened'); - }; - - return settings; - }({}); +"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; }; }(); + +var _dom = __webpack_require__(0); + +var _dom2 = _interopRequireDefault(_dom); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Module UI + * + * @type {UI} + */ +// let className = { + +/** + * @const {string} BLOCK_CLASSNAME - redactor blocks name + */ +// BLOCK_CLASSNAME : 'ce-block', + +/** + * @const {String} wrapper for plugins content + */ +// BLOCK_CONTENT : 'ce-block__content', + +/** + * @const {String} BLOCK_STRETCHED - makes block stretched + */ +// BLOCK_STRETCHED : 'ce-block--stretched', + +/** + * @const {String} BLOCK_HIGHLIGHTED - adds background + */ +// BLOCK_HIGHLIGHTED : 'ce-block--focused', + +/** + * @const {String} - for all default settings + */ +// SETTINGS_ITEM : 'ce-settings__item' +// }; + +var CSS = { + editorWrapper: 'codex-editor', + editorZone: 'ce-redactor' +}; + +/** + * @class + * + * @classdesc Makes CodeX Editor UI: + * + * + * + * + * + * + * @property {EditorConfig} config - editor configuration {@link CodexEditor#configuration} + * @property {Object} Editor - available editor modules {@link CodexEditor#moduleInstances} + * @property {Object} nodes - + * @property {Element} nodes.wrapper - element where we need to append redactor + * @property {Element} nodes.wrapper - + * @property {Element} nodes.redactor - + */ +var UI = function () { + + /** + * @constructor + * + * @param {EditorConfig} config + */ + function UI(_ref) { + var config = _ref.config; + + _classCallCheck(this, UI); + + this.config = config; + this.Editor = null; + + this.nodes = { + holder: null, + wrapper: null, + redactor: null + }; + } + + /** + * Editor modules setter + * @param {object} Editor - available editor modules + */ + + + _createClass(UI, [{ + key: 'prepare', + + + /** + * @protected + * + * Making main interface + */ + value: function prepare() { + var _this = this; + + return new Promise(function (resolve, reject) { + + /** + * Element where we need to append CodeX Editor + * @type {Element} + */ + _this.nodes.holder = document.getElementById(_this.config.holderId); + + if (!_this.nodes.holder) { + + reject(Error("Holder wasn't found by ID: #" + _this.config.holderId)); + return; + } + + /** + * 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.appendChild(_this.nodes.redactor); + _this.nodes.holder.appendChild(_this.nodes.wrapper); + + /** + * Make toolbar + */ + _this.Editor.Toolbar.make(); + + /** + * Load and append CSS + */ + _this.loadStyles(); + + resolve(); + }) + + /** Add toolbox tools */ + // .then(addTools_) + + /** Make container for inline toolbar */ + // .then(makeInlineToolbar_) + + /** Add inline toolbar tools */ + // .then(addInlineToolbarTools_) + + /** Draw wrapper for notifications */ + // .then(makeNotificationHolder_) + + /** Add eventlisteners to redactor elements */ + // .then(bindEvents_) + + .catch(function (e) { + + console.error(e); + + // editor.core.log("Can't draw editor interface"); + }); + } + }, { + key: 'loadStyles', + value: function loadStyles() { + + /** + * Load CSS + */ + var styles = __webpack_require__(28); + + /** + * Make tag + */ + var tag = _dom2.default.make('style', null, { + textContent: styles.toString() + }); + + /** + * Append styles + */ + _dom2.default.append(document.head, tag); + } + }, { + key: 'state', + set: function set(Editor) { + + this.Editor = Editor; + } + }]); + + return UI; +}(); + +UI.displayName = 'UI'; + + +module.exports = UI; + +// /** +// * Codex Editor UI module +// * +// * @author Codex Team +// * @version 1.2.0 +// */ +// +// module.exports = (function (ui) { +// +// let editor = codex.editor; +// +// /** +// * Basic editor classnames +// */ +// ui.prepare = function () { +// + +// +// }; +// +// /** Draw notifications holder */ +// var makeNotificationHolder_ = function () { +// +// /** Append block with notifications to the document */ +// editor.nodes.notifications = editor.notifications.createHolder(); +// +// }; +// +// /** +// * @private +// * Append tools passed in editor.tools +// */ +// var addTools_ = function () { +// +// var tool, +// toolName, +// toolButton; +// +// for ( toolName in editor.settings.tools ) { +// +// tool = editor.settings.tools[toolName]; +// +// editor.tools[toolName] = tool; +// +// if (!tool.iconClassname && tool.displayInToolbox) { +// +// editor.core.log('Toolbar icon classname missed. Tool %o skipped', 'warn', toolName); +// continue; +// +// } +// +// if (typeof tool.render != 'function') { +// +// editor.core.log('render method missed. Tool %o skipped', 'warn', toolName); +// continue; +// +// } +// +// if (!tool.displayInToolbox) { +// +// continue; +// +// } else { +// +// /** if tools is for toolbox */ +// toolButton = editor.draw.toolbarButton(toolName, tool.iconClassname); +// +// editor.nodes.toolbox.appendChild(toolButton); +// +// editor.nodes.toolbarButtons[toolName] = toolButton; +// +// } +// +// } +// +// }; +// +// var addInlineToolbarTools_ = function () { +// +// var tools = { +// +// bold: { +// icon : 'ce-icon-bold', +// command : 'bold' +// }, +// +// italic: { +// icon : 'ce-icon-italic', +// command : 'italic' +// }, +// +// link: { +// icon : 'ce-icon-link', +// command : 'createLink' +// } +// }; +// +// var toolButton, +// tool; +// +// for(var name in tools) { +// +// tool = tools[name]; +// +// toolButton = editor.draw.toolbarButtonInline(name, tool.icon); +// +// editor.nodes.inlineToolbar.buttons.appendChild(toolButton); +// /** +// * Add callbacks to this buttons +// */ +// editor.ui.setInlineToolbarButtonBehaviour(toolButton, tool.command); +// +// } +// +// }; +// +// /** +// * @private +// * Bind editor UI events +// */ +// var bindEvents_ = function () { +// +// editor.core.log('ui.bindEvents fired', 'info'); +// +// // window.addEventListener('error', function (errorMsg, url, lineNumber) { +// // editor.notifications.errorThrown(errorMsg, event); +// // }, false ); +// +// /** All keydowns on Document */ +// editor.listeners.add(document, 'keydown', editor.callback.globalKeydown, false); +// +// /** All keydowns on Redactor zone */ +// editor.listeners.add(editor.nodes.redactor, 'keydown', editor.callback.redactorKeyDown, false); +// +// /** All keydowns on Document */ +// editor.listeners.add(document, 'keyup', editor.callback.globalKeyup, false ); +// +// /** +// * Mouse click to radactor +// */ +// editor.listeners.add(editor.nodes.redactor, 'click', editor.callback.redactorClicked, false ); +// +// /** +// * Clicks to the Plus button +// */ +// editor.listeners.add(editor.nodes.plusButton, 'click', editor.callback.plusButtonClicked, false); +// +// /** +// * Clicks to SETTINGS button in toolbar +// */ +// editor.listeners.add(editor.nodes.showSettingsButton, 'click', editor.callback.showSettingsButtonClicked, false ); +// +// /** Bind click listeners on toolbar buttons */ +// for (var button in editor.nodes.toolbarButtons) { +// +// editor.listeners.add(editor.nodes.toolbarButtons[button], 'click', editor.callback.toolbarButtonClicked, false); +// +// } +// +// }; +// +// ui.addBlockHandlers = function (block) { +// +// if (!block) return; +// +// /** +// * Block keydowns +// */ +// editor.listeners.add(block, 'keydown', editor.callback.blockKeydown, false); +// +// /** +// * Pasting content from another source +// * We have two type of sanitization +// * First - uses deep-first search algorithm to get sub nodes, +// * sanitizes whole Block_content and replaces cleared nodes +// * This method is deprecated +// * Method is used in editor.callback.blockPaste(event) +// * +// * Secont - uses Mutation observer. +// * Observer "observe" DOM changes and send changings to callback. +// * Callback gets changed node, not whole Block_content. +// * Inserted or changed node, which we've gotten have been cleared and replaced with diry node +// * +// * Method is used in editor.callback.blockPasteViaSanitize(event) +// * +// * @uses html-janitor +// * @example editor.callback.blockPasteViaSanitize(event), the second method. +// * +// */ +// editor.listeners.add(block, 'paste', editor.paste.blockPasteCallback, false); +// +// /** +// * Show inline toolbar for selected text +// */ +// editor.listeners.add(block, 'mouseup', editor.toolbar.inline.show, false); +// editor.listeners.add(block, 'keyup', editor.toolbar.inline.show, false); +// +// }; +// +// /** getting all contenteditable elements */ +// ui.saveInputs = function () { +// +// var redactor = editor.nodes.redactor; +// +// editor.state.inputs = []; +// +// /** Save all inputs in global variable state */ +// var inputs = redactor.querySelectorAll('[contenteditable], input, textarea'); +// +// Array.prototype.map.call(inputs, function (current) { +// +// if (!current.type || current.type == 'text' || current.type == 'textarea') { +// +// editor.state.inputs.push(current); +// +// } +// +// }); +// +// }; +// +// /** +// * Adds first initial block on empty redactor +// */ +// ui.addInitialBlock = function () { +// +// var initialBlockType = editor.settings.initialBlockPlugin, +// initialBlock; +// +// if ( !editor.tools[initialBlockType] ) { +// +// editor.core.log('Plugin %o was not implemented and can\'t be used as initial block', 'warn', initialBlockType); +// return; +// +// } +// +// initialBlock = editor.tools[initialBlockType].render(); +// +// initialBlock.setAttribute('data-placeholder', editor.settings.placeholder); +// +// editor.content.insertBlock({ +// type : initialBlockType, +// block : initialBlock +// }); +// +// editor.content.workingNodeChanged(initialBlock); +// +// }; +// +// ui.setInlineToolbarButtonBehaviour = function (button, type) { +// +// editor.listeners.add(button, 'mousedown', function (event) { +// +// editor.toolbar.inline.toolClicked(event, type); +// +// }, false); +// +// }; +// +// return ui; +// +// })({}); /***/ }), /* 24 */ /***/ (function(module, exports, __webpack_require__) { - 'use strict'; - - /** - * Codex Editor toolbar module - * - * Contains: - * - Inline toolbox - * - Toolbox within plus button - * - Settings section - * - * @author Codex Team - * @version 1.0 - */ - - module.exports = function (toolbar) { - - var editor = codex.editor; - - toolbar.settings = __webpack_require__(23); - toolbar.inline = __webpack_require__(22); - toolbar.toolbox = __webpack_require__(25); - - /** - * Margin between focused node and toolbar - */ - toolbar.defaultToolbarHeight = 49; - - toolbar.defaultOffset = 34; - - toolbar.opened = false; - - toolbar.current = null; - - /** - * @protected - */ - toolbar.open = function () { - - if (editor.hideToolbar) { - - return; - } - - var toolType = editor.content.currentNode.dataset.tool; - - if (!editor.tools[toolType] || !editor.tools[toolType].makeSettings) { - - editor.nodes.showSettingsButton.classList.add('hide'); - } else { - - editor.nodes.showSettingsButton.classList.remove('hide'); - } - - editor.nodes.toolbar.classList.add('opened'); - this.opened = true; - }; - - /** - * @protected - */ - toolbar.close = function () { - - editor.nodes.toolbar.classList.remove('opened'); - - toolbar.opened = false; - toolbar.current = null; - - for (var button in editor.nodes.toolbarButtons) { - - editor.nodes.toolbarButtons[button].classList.remove('selected'); - } - - /** Close toolbox when toolbar is not displayed */ - editor.toolbar.toolbox.close(); - editor.toolbar.settings.close(); - }; - - toolbar.toggle = function () { - - if (!this.opened) { - - this.open(); - } else { - - this.close(); - } - }; - - toolbar.hidePlusButton = function () { - - editor.nodes.plusButton.classList.add('hide'); - }; - - toolbar.showPlusButton = function () { - - editor.nodes.plusButton.classList.remove('hide'); - }; - - /** - * Moving toolbar to the specified node - */ - toolbar.move = function () { - - /** Close Toolbox when we move toolbar */ - editor.toolbar.toolbox.close(); - - if (!editor.content.currentNode) { - - return; - } - - var newYCoordinate = editor.content.currentNode.offsetTop - editor.toolbar.defaultToolbarHeight / 2 + editor.toolbar.defaultOffset; - - editor.nodes.toolbar.style.transform = 'translate3D(0, ' + Math.floor(newYCoordinate) + 'px, 0)'; - - /** Close trash actions */ - editor.toolbar.settings.hideRemoveActions(); - }; - - return toolbar; - }({}); +"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 = ["blockManager.js","events.js","renderer.js","toolbar.js","tools.js","ui.js"].map(function (module) { + + return __webpack_require__(25)("./" + 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)).then(prepareDecorator(this.moduleInstances.BlockManager)).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; +// +// })({}); /***/ }), /* 25 */ -/***/ (function(module, exports) { +/***/ (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; - }({}); +var map = { + "./_anchors": 5, + "./_anchors.js": 5, + "./_callbacks": 6, + "./_callbacks.js": 6, + "./_caret": 7, + "./_caret.js": 7, + "./_content": 8, + "./_content.js": 8, + "./_destroyer": 9, + "./_destroyer.js": 9, + "./_listeners": 10, + "./_listeners.js": 10, + "./_notifications": 11, + "./_notifications.js": 11, + "./_parser": 12, + "./_parser.js": 12, + "./_paste": 13, + "./_paste.js": 13, + "./_sanitizer": 14, + "./_sanitizer.js": 14, + "./_saver": 15, + "./_saver.js": 15, + "./_transport": 16, + "./_transport.js": 16, + "./blockManager": 17, + "./blockManager.js": 17, + "./events": 18, + "./events.js": 18, + "./renderer": 19, + "./renderer.js": 19, + "./toolbar": 20, + "./toolbar.js": 20, + "./toolbar/inline": 2, + "./toolbar/inline.js": 2, + "./toolbar/settings": 3, + "./toolbar/settings.js": 3, + "./toolbar/toolbar": 21, + "./toolbar/toolbar.js": 21, + "./toolbar/toolbox": 4, + "./toolbar/toolbox.js": 4, + "./tools": 22, + "./tools.js": 22, + "./ui": 23, + "./ui.js": 23 +}; +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 = 25; /***/ }), /* 26 */ /***/ (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 Codex Editor Tools Submodule - * - * Creates Instances from Plugins and binds external config to the instances - */ - - /** - * Load user defined tools - * Tools must contain the following important objects: - * - * @typedef {Object} ToolsConfig - * @property {String} iconClassname - this a icon in toolbar - * @property {Boolean} displayInToolbox - will be displayed in toolbox. Default value is TRUE - * @property {Boolean} enableLineBreaks - inserts new block or break lines. Default value is FALSE - */ - - /** - * @todo update according to current API - * - * @typedef {Object} Tool - * @property render - * @property save - * @property settings - * @property validate - */ - - /** - * Class properties: - * - * @property {String} name - name of this module - * @property {Object[]} toolInstances - list of tool instances - * @property {Tools[]} available - available Tools - * @property {Tools[]} unavailable - unavailable Tools - * @property {Object} toolsClasses - all classes - * @property {EditorConfig} config - Editor config - */ - var util = __webpack_require__(20); - - module.exports = function () { - _createClass(Tools, [{ - key: 'available', - - - /** - * Returns available Tools - * @return {Tool[]} - */ - get: function get() { - - return this.toolsAvailable; - } - - /** - * Returns unavailable Tools - * @return {Tool[]} - */ - - }, { - key: 'unavailable', - get: function get() { - - return this.toolsUnavailable; - } - - /** - * @param Editor - * @param Editor.modules {@link CodexEditor#moduleInstances} - * @param Editor.config {@link CodexEditor#configuration} - */ - - }, { - key: 'state', - set: function set(Editor) { - - this.Editor = Editor; - } - - /** - * If config wasn't passed by user - * @return {ToolsConfig} - */ - - }, { - key: 'defaultConfig', - get: function get() { - - return { - iconClassName: 'default-icon', - displayInToolbox: false, - enableLineBreaks: false - }; - } - - /** - * @constructor - * - * @param {ToolsConfig} config - */ - - }], [{ - key: 'name', - get: function get() { - - return 'Tools'; - } - }]); - - function Tools(_ref) { - var config = _ref.config; - - _classCallCheck(this, Tools); - - this.config = config; - - this.toolClasses = {}; - this.toolsAvailable = {}; - this.toolsUnavailable = {}; - } - - /** - * Creates instances via passed or default configuration - * @return {boolean} - */ - - - _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"); - } - - for (var toolName in this.config.tools) { - - this.toolClasses[toolName] = this.config.tools[toolName]; - } - - /** - * getting classes that has prepare method - */ - var sequenceData = this.getListOfPrepareFunctions(); - - /** - * if sequence data contains nothing then resolve current chain and run other module prepare - */ - if (sequenceData.length === 0) { - - return Promise.resolve(); - } - - /** - * to see how it works {@link Util#sequence} - */ - return util.sequence(sequenceData, function (data) { - - _this.success(data); - }, function (data) { - - _this.fallback(data); - }); - } - - /** - * Binds prepare function of plugins with user or default config - * @return {Array} list of functions that needs to be fired sequently - */ - - }, { - key: 'getListOfPrepareFunctions', - value: function getListOfPrepareFunctions() { - - var toolPreparationList = []; - - for (var toolName in this.toolClasses) { - - var toolClass = this.toolClasses[toolName]; - - if (typeof toolClass.prepare === 'function') { - - toolPreparationList.push({ - function: toolClass.prepare, - data: { - toolName: toolName - } - }); - } - } - - return toolPreparationList; - } - - /** - * @param {ChainData.data} data - append tool to available list - */ - - }, { - key: 'success', - value: function success(data) { - - this.toolsAvailable[data.toolName] = this.toolClasses[data.toolName]; - } - - /** - * @param {ChainData.data} data - append tool to unavailable list - */ - - }, { - key: 'fallback', - value: function fallback(data) { - - this.toolsUnavailable[data.toolName] = this.toolClasses[data.toolName]; - } - - /** - * Returns all tools - * @return {Array} - */ - - }, { - key: 'getTools', - value: function getTools() { - - return this.toolInstances; - } - - /** - * Return tool`a instance - * - * @param {String} tool — tool name - * @param {Object} data — initial data - * - * @todo throw exceptions if tool doesnt exist - * - */ - - }, { - key: 'construct', - value: function construct(tool, data) { - - var plugin = this.toolClasses[tool], - config = this.config.toolsConfig[tool]; - - var instance = new plugin(data, config); - - return instance; - } - }]); - - return Tools; - }(); +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; + +})); + /***/ }), /* 27 */ /***/ (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; }; }(); - - var _dom = __webpack_require__(6); - - var _dom2 = _interopRequireDefault(_dom); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - - /** - * Module UI - * - * @type {UI} - */ - // let className = { - - /** - * @const {string} BLOCK_CLASSNAME - redactor blocks name - */ - // BLOCK_CLASSNAME : 'ce-block', - - /** - * @const {String} wrapper for plugins content - */ - // BLOCK_CONTENT : 'ce-block__content', - - /** - * @const {String} BLOCK_STRETCHED - makes block stretched - */ - // BLOCK_STRETCHED : 'ce-block--stretched', - - /** - * @const {String} BLOCK_HIGHLIGHTED - adds background - */ - // BLOCK_HIGHLIGHTED : 'ce-block--focused', - - /** - * @const {String} - for all default settings - */ - // SETTINGS_ITEM : 'ce-settings__item' - // }; - - var CSS = { - editorWrapper: 'codex-editor', - editorZone: 'ce-redactor' +"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; }; }(); /** + * + * @class Block + * @classdesc This class describes editor`s block, including block`s HTMLElement, data and tool + * + * @property {Tool} tool — current block tool (Paragraph, for example) + * @property {Object} CSS — block`s css classes + * + */ + +var _dom = __webpack_require__(0); + +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"); } } + +var Block = function () { + + /** + * @constructor + * + * @param {Object} tool — current block plugin`s instance + */ + function Block(tool) { + _classCallCheck(this, Block); + + this.tool = tool; + + this.CSS = { + wrapper: 'ce-block', + content: 'ce-block__content' + }; + + this._html = this.compose(); + } + + /** + * Make default block wrappers and put tool`s content there + * + * @returns {HTMLDivElement} + * @private + */ + + + _createClass(Block, [{ + key: 'compose', + value: function compose() { + + var wrapper = _dom2.default.make('div', this.CSS.wrapper), + content = _dom2.default.make('div', this.CSS.content); + + content.appendChild(this.tool.html); + wrapper.appendChild(content); + + return wrapper; + } + + /** + * Get block`s HTML + * + * @returns {HTMLDivElement} + */ + + }, { + key: 'html', + get: function get() { + + return this._html; + } + }]); + + return Block; +}(); + +Block.displayName = 'Block'; +exports.default = Block; + +/***/ }), +/* 28 */ +/***/ (function(module, exports, __webpack_require__) { + +exports = module.exports = __webpack_require__(29)(undefined); +// imports + + +// module +exports.push([module.i, ":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", ""]); + +// exports + + +/***/ }), +/* 29 */ +/***/ (function(module, exports) { + +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +// css base code, injected by the css-loader +module.exports = function(useSourceMap) { + var list = []; + + // return the list of modules as css string + list.toString = function toString() { + return this.map(function (item) { + var content = cssWithMappingToString(item, useSourceMap); + if(item[2]) { + return "@media " + item[2] + "{" + content + "}"; + } else { + return content; + } + }).join(""); }; - - /** - * @class - * - * @classdesc Makes CodeX Editor UI: - * - * - * - * - * - * - * @property {EditorConfig} config - editor configuration {@link CodexEditor#configuration} - * @property {Object} Editor - available editor modules {@link CodexEditor#moduleInstances} - * @property {Object} nodes - - * @property {Element} nodes.wrapper - element where we need to append redactor - * @property {Element} nodes.wrapper - - * @property {Element} nodes.redactor - - */ - module.exports = function () { - _createClass(UI, null, [{ - key: 'name', - - - /** - * Module key name - * @returns {string} - */ - get: function get() { - - return 'ui'; - } - - /** - * @constructor - * - * @param {EditorConfig} config - */ - - }]); - - function UI(_ref) { - var config = _ref.config; - - _classCallCheck(this, UI); - - this.config = config; - this.Editor = null; - - this.nodes = { - holder: null, - wrapper: null, - redactor: null - }; - } - - /** - * Editor modules setter - * @param {object} Editor - available editor modules - */ - - - _createClass(UI, [{ - key: 'prepare', - - - /** - * @protected - * - * Making main interface - */ - value: function prepare() { - var _this = this; - - return new Promise(function (resolve, reject) { - - /** - * Element where we need to append CodeX Editor - * @type {Element} - */ - _this.nodes.holder = document.getElementById(_this.config.holderId); - - if (!_this.nodes.holder) { - - reject(Error("Holder wasn't found by ID: #" + _this.config.holderId)); - return; - } - - /** - * 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.appendChild(_this.nodes.redactor); - _this.nodes.holder.appendChild(_this.nodes.wrapper); - - /** - * Make toolbar - */ - _this.Editor.Toolbar.make(); - - resolve(); - }) - - /** Add toolbox tools */ - // .then(addTools_) - - /** Make container for inline toolbar */ - // .then(makeInlineToolbar_) - - /** Add inline toolbar tools */ - // .then(addInlineToolbarTools_) - - /** Draw wrapper for notifications */ - // .then(makeNotificationHolder_) - - /** Add eventlisteners to redactor elements */ - // .then(bindEvents_) - - .catch(function (e) { - - console.error(e); - - // editor.core.log("Can't draw editor interface"); - }); - } - }, { - key: 'state', - set: function set(Editor) { - - this.Editor = Editor; - } - }]); - - return UI; - }(); - // /** - // * Codex Editor UI module - // * - // * @author Codex Team - // * @version 1.2.0 - // */ - // - // module.exports = (function (ui) { - // - // let editor = codex.editor; - // - // /** - // * Basic editor classnames - // */ - // ui.prepare = function () { - // - - // - // }; - // - // /** Draw notifications holder */ - // var makeNotificationHolder_ = function () { - // - // /** Append block with notifications to the document */ - // editor.nodes.notifications = editor.notifications.createHolder(); - // - // }; - // - // /** - // * @private - // * Append tools passed in editor.tools - // */ - // var addTools_ = function () { - // - // var tool, - // toolName, - // toolButton; - // - // for ( toolName in editor.settings.tools ) { - // - // tool = editor.settings.tools[toolName]; - // - // editor.tools[toolName] = tool; - // - // if (!tool.iconClassname && tool.displayInToolbox) { - // - // editor.core.log('Toolbar icon classname missed. Tool %o skipped', 'warn', toolName); - // continue; - // - // } - // - // if (typeof tool.render != 'function') { - // - // editor.core.log('render method missed. Tool %o skipped', 'warn', toolName); - // continue; - // - // } - // - // if (!tool.displayInToolbox) { - // - // continue; - // - // } else { - // - // /** if tools is for toolbox */ - // toolButton = editor.draw.toolbarButton(toolName, tool.iconClassname); - // - // editor.nodes.toolbox.appendChild(toolButton); - // - // editor.nodes.toolbarButtons[toolName] = toolButton; - // - // } - // - // } - // - // }; - // - // var addInlineToolbarTools_ = function () { - // - // var tools = { - // - // bold: { - // icon : 'ce-icon-bold', - // command : 'bold' - // }, - // - // italic: { - // icon : 'ce-icon-italic', - // command : 'italic' - // }, - // - // link: { - // icon : 'ce-icon-link', - // command : 'createLink' - // } - // }; - // - // var toolButton, - // tool; - // - // for(var name in tools) { - // - // tool = tools[name]; - // - // toolButton = editor.draw.toolbarButtonInline(name, tool.icon); - // - // editor.nodes.inlineToolbar.buttons.appendChild(toolButton); - // /** - // * Add callbacks to this buttons - // */ - // editor.ui.setInlineToolbarButtonBehaviour(toolButton, tool.command); - // - // } - // - // }; - // - // /** - // * @private - // * Bind editor UI events - // */ - // var bindEvents_ = function () { - // - // editor.core.log('ui.bindEvents fired', 'info'); - // - // // window.addEventListener('error', function (errorMsg, url, lineNumber) { - // // editor.notifications.errorThrown(errorMsg, event); - // // }, false ); - // - // /** All keydowns on Document */ - // editor.listeners.add(document, 'keydown', editor.callback.globalKeydown, false); - // - // /** All keydowns on Redactor zone */ - // editor.listeners.add(editor.nodes.redactor, 'keydown', editor.callback.redactorKeyDown, false); - // - // /** All keydowns on Document */ - // editor.listeners.add(document, 'keyup', editor.callback.globalKeyup, false ); - // - // /** - // * Mouse click to radactor - // */ - // editor.listeners.add(editor.nodes.redactor, 'click', editor.callback.redactorClicked, false ); - // - // /** - // * Clicks to the Plus button - // */ - // editor.listeners.add(editor.nodes.plusButton, 'click', editor.callback.plusButtonClicked, false); - // - // /** - // * Clicks to SETTINGS button in toolbar - // */ - // editor.listeners.add(editor.nodes.showSettingsButton, 'click', editor.callback.showSettingsButtonClicked, false ); - // - // /** Bind click listeners on toolbar buttons */ - // for (var button in editor.nodes.toolbarButtons) { - // - // editor.listeners.add(editor.nodes.toolbarButtons[button], 'click', editor.callback.toolbarButtonClicked, false); - // - // } - // - // }; - // - // ui.addBlockHandlers = function (block) { - // - // if (!block) return; - // - // /** - // * Block keydowns - // */ - // editor.listeners.add(block, 'keydown', editor.callback.blockKeydown, false); - // - // /** - // * Pasting content from another source - // * We have two type of sanitization - // * First - uses deep-first search algorithm to get sub nodes, - // * sanitizes whole Block_content and replaces cleared nodes - // * This method is deprecated - // * Method is used in editor.callback.blockPaste(event) - // * - // * Secont - uses Mutation observer. - // * Observer "observe" DOM changes and send changings to callback. - // * Callback gets changed node, not whole Block_content. - // * Inserted or changed node, which we've gotten have been cleared and replaced with diry node - // * - // * Method is used in editor.callback.blockPasteViaSanitize(event) - // * - // * @uses html-janitor - // * @example editor.callback.blockPasteViaSanitize(event), the second method. - // * - // */ - // editor.listeners.add(block, 'paste', editor.paste.blockPasteCallback, false); - // - // /** - // * Show inline toolbar for selected text - // */ - // editor.listeners.add(block, 'mouseup', editor.toolbar.inline.show, false); - // editor.listeners.add(block, 'keyup', editor.toolbar.inline.show, false); - // - // }; - // - // /** getting all contenteditable elements */ - // ui.saveInputs = function () { - // - // var redactor = editor.nodes.redactor; - // - // editor.state.inputs = []; - // - // /** Save all inputs in global variable state */ - // var inputs = redactor.querySelectorAll('[contenteditable], input, textarea'); - // - // Array.prototype.map.call(inputs, function (current) { - // - // if (!current.type || current.type == 'text' || current.type == 'textarea') { - // - // editor.state.inputs.push(current); - // - // } - // - // }); - // - // }; - // - // /** - // * Adds first initial block on empty redactor - // */ - // ui.addInitialBlock = function () { - // - // var initialBlockType = editor.settings.initialBlockPlugin, - // initialBlock; - // - // if ( !editor.tools[initialBlockType] ) { - // - // editor.core.log('Plugin %o was not implemented and can\'t be used as initial block', 'warn', initialBlockType); - // return; - // - // } - // - // initialBlock = editor.tools[initialBlockType].render(); - // - // initialBlock.setAttribute('data-placeholder', editor.settings.placeholder); - // - // editor.content.insertBlock({ - // type : initialBlockType, - // block : initialBlock - // }); - // - // editor.content.workingNodeChanged(initialBlock); - // - // }; - // - // ui.setInlineToolbarButtonBehaviour = function (button, type) { - // - // editor.listeners.add(button, 'mousedown', function (event) { - // - // editor.toolbar.inline.toolClicked(event, type); - // - // }, false); - // - // }; - // - // return ui; - // - // })({}); + + // import a list of modules into the list + list.i = function(modules, mediaQuery) { + if(typeof modules === "string") + modules = [[null, modules, ""]]; + var alreadyImportedModules = {}; + for(var i = 0; i < this.length; i++) { + var id = this[i][0]; + if(typeof id === "number") + alreadyImportedModules[id] = true; + } + for(i = 0; i < modules.length; i++) { + var item = modules[i]; + // skip already imported module + // this implementation is not 100% perfect for weird media query combinations + // when a module is imported multiple times with different media queries. + // I hope this will never occur (Hey this way we have smaller bundles) + if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) { + if(mediaQuery && !item[2]) { + item[2] = mediaQuery; + } else if(mediaQuery) { + item[2] = "(" + item[2] + ") and (" + mediaQuery + ")"; + } + list.push(item); + } + } + }; + return list; +}; + +function cssWithMappingToString(item, useSourceMap) { + var content = item[1] || ''; + var cssMapping = item[3]; + if (!cssMapping) { + return content; + } + + if (useSourceMap && typeof btoa === 'function') { + var sourceMapping = toComment(cssMapping); + var sourceURLs = cssMapping.sources.map(function (source) { + return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */' + }); + + return [content].concat(sourceURLs).concat([sourceMapping]).join('\n'); + } + + return [content].join('\n'); +} + +// Adapted from convert-source-map (MIT) +function toComment(sourceMap) { + // eslint-disable-next-line no-undef + var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))); + var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64; + + return '/*# ' + data + ' */'; +} + /***/ }) /******/ ]); diff --git a/build/codex-editor.js.map b/build/codex-editor.js.map index 31a75c24..593e564b 100644 --- a/build/codex-editor.js.map +++ b/build/codex-editor.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap 0d74f94a49f2a959d1a9","webpack:///./src/codex.js","webpack:///./src/components/modules ^\\.\\/.*$","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/dom.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/_sanitizer.js","webpack:///./~/html-janitor/src/html-janitor.js","webpack:///./src/components/modules/_saver.js","webpack:///./src/components/modules/_transport.js","webpack:///./src/components/modules/blockManager.js","webpack:///./src/components/block.js","webpack:///./src/components/modules/eventDispatcher.js","webpack:///./src/components/modules/renderer.js","webpack:///./src/components/util.js","webpack:///./src/components/modules/toolbar.js","webpack:///./src/components/modules/toolbar/inline.js","webpack:///./src/components/modules/toolbar/settings.js","webpack:///./src/components/modules/toolbar/toolbar.js","webpack:///./src/components/modules/toolbar/toolbox.js","webpack:///./src/components/modules/tools.js","webpack:///./src/components/modules/ui.js"],"names":["modules","editorModules","map","module","exports","config","moduleInstances","Promise","resolve","then","configuration","init","start","console","log","catch","error","constructModules","configureModules","forEach","Module","name","e","state","getModulesDiff","moduleName","prepareDecorator","prepare","ui","Tools","BlockManager","holderId","placeholder","sanitizer","p","b","a","hideToolbar","tools","toolsConfig","anchors","editor","codex","input","currentNode","settingsOpened","currentBlock","value","dataset","anchor","anchorChanged","newAnchor","target","rusToTranslit","trim","classList","add","className","BLOCK_WITH_ANCHOR","remove","keyDownOnAnchorInput","keyCode","core","keys","ENTER","preventDefault","stopPropagation","blur","toolbar","settings","close","keyUpOnAnchorInput","LEFT","DOWN","string","ru","en","i","length","split","join","toLowerCase","replace","callbacks","globalKeydown","event","enterKeyPressed_","redactorKeyDown","TAB","tabKeyPressedOnRedactorsZone_","enterKeyPressedOnRedactorsZone_","ESC","escapeKeyPressedOnRedactorsZone_","defaultKeyPressedOnRedactorsZone_","globalKeyup","UP","RIGHT","arrowKeyPressed_","isBlockEmpty","content","opened","open","toolbox","leaf","editorAreaHightlighted","caret","inputIndex","enterPressedOnBlock_","NEW_BLOCK_TYPE","initialBlockPlugin","insertBlock","type","block","render","move","contentEditable","saveCurrentInputIndex","currentInputIndex","getCurrentInputIndex","workingNode","tool","isEnterPressedOnToolbar","current","inputs","enableLineBreaks","toolClicked","stopImmediatePropagation","shiftKey","currentSelection","window","getSelection","currentSelectedNode","anchorNode","caretAtTheEndOfText","position","atTheEnd","isTextNodeHasParentBetweenContenteditable","callback","enterPressedOnBlock","parentNode","nodeType","nodeTypes","TEXT","splitBlock","textContent","showPlusButton","islastNode","isLastNode","saveInputs","workingNodeChanged","inline","actionsOpened","clearMark","redactorClicked","detectWhenClickedOnFirstLevelBlockArea_","selectedText","getSelectionText","firstLevelBlock","indexOfLastInput","getFirstLevelBlock","setToBlock","setToNextBlock","inputIsEmpty","currentNodeType","isInitialType","hidePlusButton","markBlock","selection","flag","rangeCount","isDomNode","document","body","toolbarButtonClicked","button","plusButtonClicked","nodes","contains","blockKeydown","blockRightOrDownArrowPressed_","BACKSPACE","backspacePressed_","blockLeftOrUpArrowPressed_","focusedNode","focusedNodeHolder","editableElementIndex","caretInLastChild","lastChild","deepestTextnode","childNodes","getDeepestTextNodeFromPosition","anchorOffset","caretInFirstChild","caretAtTheBeginning","firstChild","setToPreviousBlock","range","selectionLength","firstLevelBlocksCount","isNativeInput","getRange","endOffset","startOffset","atStart","mergeBlocks","redactor","addInitialBlock","setTimeout","showSettingsButtonClicked","currentToolType","toggle","hideRemoveActions","offset","focusedNodeIndex","set","el","index","childs","nodeToSet","focus","createRange","setStart","setEnd","removeAllRanges","addRange","nextInput","emptyTextElement","createTextNode","appendChild","targetInput","previousInput","lastChildNode","lengthOfLastChildNode","pluginsRender","isFirstNode","isOffsetZero","insertNode","node","lastNode","DOCUMENT_FRAGMENT","getRangeAt","deleteContents","setStartAfter","collapse","Editor","CSS","stretched","highlighted","_currentNode","_currentIndex","pluginHTML","isStretched","make","blockContent","toolId","isNode","newBlock","composeBlock_","insertAdjacentElement","Dom","tagName","classNames","attributes","createElement","Array","isArray","attrName","parent","elements","selector","querySelector","querySelectorAll","Node","ELEMENT_NODE","destroyer","removeNodes","wrapper","notifications","destroyPlugins","destroy","destroyScripts","scripts","getElementsByTagName","id","indexOf","scriptPrefix","listeners","removeAll","plugins","allListeners","search","byElement","element","context","listenersOnElement","listener","push","byType","eventType","listenersWithType","byHandler","handler","listenersWithHandler","one","result","all","isCapture","addEventListener","data","alreadyAddedListener","removeEventListener","existingListeners","splice","get","queue","addToQueue","createHolder","holder","draw","errorThrown","errorMsg","notification","message","constructorSettings","cancel","confirm","inputField","confirmHandler","cancelHandler","create","time","okBtn","cancelBtn","okMsg","cancelMsg","send","clear","innerHTML","parser","insertPastedContent","blockType","tag","text","isFirstLevelBlock","TAG","BLOCK_CLASSNAME","paste","patterns","renderOnPastePatterns","pattern","pasted","clipBoardData","clipboardData","getData","analize","plugin","execArray","regex","exec","match","pasteToNewBlock_","blockPasteCallback","needsToHandlePasteEvent","htmlData","plainData","paragraphs","cleanData","wrappedData","clean","wrapTextWithParagraphs","emulateUserAgentBehaviour","insertPastedParagraphs","editableParent","getEditableParent","paragraph","newNode","childElementCount","createDocumentFragment","cloneNode","janitor","require","isEmpty","Config","CUSTOM","BASIC","tags","href","rel","init_","userCustomConfig","dirtyString","customConfig","janitorInstance","saver","save","html","jsonOutput","saveBlocks","blocks","getBlockData","makeOutput","saveBlockData","validateBlockData","pluginName","pluginsContent","inputPosition","available","items","Object","validate","savedData","filter","blockData","Date","version","transport","currentRequest","arguments","fileSelected","clearInput","files","formData","FormData","multiple","append","ajax","url","beforeSend","success","progress","selectAndUpload","args","setAttribute","accept","click","abort","_blocks","_currentBloсkIndex","Blocks","Proxy","toolName","toolInstance","construct","array","workingArea","previousBlock","nextBlock","targetBlock","insert","children","instance","isNaN","Number","Block","_html","compose","subscribers","eventName","reduce","previousData","currentHandler","newData","chainData","function","makeBlock","sequence","item","chains","fallback","reject","previousValue","currentValue","iteration","waitNextBlock","collection","prototype","slice","call","Toolbar","actions","plusButton","settingsToggler","removeBlockButton","pluginSettings","defaultSettings","makeRemoveBlockButton","makeBlockSettingsPanel","buttonsOpened","wrappersOffset","storedSelection","show","showInlineToolbar","inlineToolbar","showButtons","getWrappersOffset","coords","getSelectionCoords","defaultOffset","newCoordinateX","newCoordinateY","offsetHeight","x","left","y","scrollY","top","style","transform","Math","floor","closeButtons","closeAction","createLinkAction","defaultToolAction","buttons","hightlight","getOffset","_x","_y","offsetLeft","offsetTop","clientLeft","clientTop","offsetParent","sel","boundingLeft","boundingTop","cloneRange","getClientRects","rect","toString","showActions","action","inlineToolbarAnchorInputKeydown_","editable","restoreSelection","setAnchor","clearRange","isActive","isLinkActive","saveSelection","inputForLink","dataType","execCommand","containerEl","preSelectionRange","selectNodeContents","startContainer","end","savedSel","charIndex","nodeStack","foundStart","stop","nextCharIndex","pop","queryCommandState","setButtonHighlighted","removeButtonsHighLight","icon","setting","toolType","makeSettings","settingsBlock","blockSettings","removeBlockWrapper","settingButton","actionWrapper","confirmAction","cancelAction","removeButtonClicked","confirmRemovingRequest","cancelRemovingRequest","showRemoveActions","defaultToolbarHeight","showSettingsButton","toolbarButtons","newYCoordinate","openedOnBlock","currentTool","barButtons","nextToolIndex","toolToSelect","visibleTool","displayInToolbox","UNREPLACEBLE_TOOLS","newBlockContent","appendCallback","switchBlock","util","toolsAvailable","toolsUnavailable","iconClassName","toolClasses","self","hasOwnProperty","sequenceData","getListOfPrepareFunctions","toolPreparationList","toolClass","toolInstances","editorWrapper","editorZone","getElementById","Error"],"mappings":"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C;;AAMA,kBAAK/B,MAAL,CAAYgC,WAAZ,GAA0BhC,OAAOgC,WAAP,GAAqBhC,OAAOgC,WAA5B,GAA0C,KAApE;AACA,kBAAKhC,MAAL,CAAYiC,KAAZ,GAAoBjC,OAAOiC,KAAP,IAAgB,EAApC;AACA,kBAAKjC,MAAL,CAAYkC,WAAZ,GAA0BlC,OAAOkC,WAAP,IAAsB,EAAhD;AAEH;;AAED;;;;AAlEJ;AAAA,6BAsEwB;;AAEhB,oBAAO,KAAKlC,MAAZ;AAEH;AA1EL;;AAAA;AAAA;;AAyLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,W;;;;;;AC7WA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAiC,uDAAuD;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;ACzDA;;;;;;;AAOAF,QAAOC,OAAP,GAAiB,UAAUoC,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AAED;;;;;AAvDJ;AAAA,2BA4DoBX,IA5DpB,EA4D0B;;AAElB,iBAAIhF,kBAAkB,KAAKE,kBAAL,CAAwB8E,IAAxB,CAAtB;;AAEA,kBAAKW,YAAL,GAAoB3F,eAApB;AAEH;AAlEL;;AAAA;AAAA;;AAuKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,W;;;;;;;;;;;;;;;;;;;;AC58BA;;;KAGqBsG,G;;;;;;;;;AAEjB;;;;;;;;8BAQYC,O,EAA6C;AAAA,iBAApCC,UAAoC,uEAAvB,IAAuB;AAAA,iBAAjBC,UAAiB,uEAAJ,EAAI;;;AAErD,iBAAI/C,KAAK5C,SAAS4F,aAAT,CAAuBH,OAAvB,CAAT;;AAEA,iBAAKI,MAAMC,OAAN,CAAcJ,UAAd,CAAL,EAAiC;AAAA;;AAE7B,qCAAG9M,SAAH,EAAaC,GAAb,yCAAoB6M,UAApB;AAEH,cAJD,MAIO,IAAIA,UAAJ,EAAiB;;AAEpB9C,oBAAGhK,SAAH,CAAaC,GAAb,CAAiB6M,UAAjB;AAEH;;AAED,kBAAK,IAAIK,QAAT,IAAqBJ,UAArB,EAAiC;;AAE7B/C,oBAAGmD,QAAH,IAAeJ,WAAWI,QAAX,CAAf;AAEH;;AAED,oBAAOnD,EAAP;AAEH;;AAED;;;;;;;;;gCAMcoD,M,EAAQC,Q,EAAU;;AAE5B,iBAAKJ,MAAMC,OAAN,CAAcG,QAAd,CAAL,EAA+B;;AAE3BA,0BAASzP,OAAT,CAAkB;AAAA,4BAAMwP,OAAOvC,WAAP,CAAmBb,EAAnB,CAAN;AAAA,kBAAlB;AAEH,cAJD,MAIO;;AAEHoD,wBAAOvC,WAAP,CAAmBwC,QAAnB;AAEH;AAEJ;;AAED;;;;;;;;;;;;;gCAUqC;AAAA,iBAAzBrD,EAAyB,uEAApB5C,QAAoB;AAAA,iBAAVkG,QAAU;;;AAEjC,oBAAOtD,GAAGuD,aAAH,CAAiBD,QAAjB,CAAP;AAEH;;AAED;;;;;;;;;;;;mCASwC;AAAA,iBAAzBtD,EAAyB,uEAApB5C,QAAoB;AAAA,iBAAVkG,QAAU;;;AAEpC,oBAAOtD,GAAGwD,gBAAH,CAAoBF,QAApB,CAAP;AAEH;;;gCAEahC,I,EAAM;;AAEhB,oBAAOA,QAAQ,QAAOA,IAAP,yCAAOA,IAAP,OAAgB,QAAxB,IAAoCA,KAAKjG,QAAzC,IAAqDiG,KAAKjG,QAAL,KAAkBoI,KAAKC,YAAnF;AAEH;;;;;;mBAzFgBd,G;AA0FpB,E;;;;;;;;;;AC7FD;;;;;;;AAOAhQ,QAAOC,OAAP,GAAiB,UAAU8Q,SAAV,EAAqB;;AAElC,SAAIzO,SAASC,MAAMD,MAAnB;;AAEAyO,eAAUC,WAAV,GAAwB,YAAY;;AAEhC1O,gBAAOuI,KAAP,CAAaoG,OAAb,CAAqBzN,MAArB;AACAlB,gBAAOuI,KAAP,CAAaqG,aAAb,CAA2B1N,MAA3B;AAEH,MALD;;AAOAuN,eAAUI,cAAV,GAA2B,YAAY;;AAEnC,cAAK,IAAI9J,IAAT,IAAiB/E,OAAOH,KAAxB,EAA+B;;AAE3B,iBAAI,OAAOG,OAAOH,KAAP,CAAakF,IAAb,EAAmB+J,OAA1B,KAAsC,UAA1C,EAAsD;;AAElD9O,wBAAOH,KAAP,CAAakF,IAAb,EAAmB+J,OAAnB;AAEH;AAEJ;AAEJ,MAZD;;AAcAL,eAAUM,cAAV,GAA2B,YAAY;;AAEnC,aAAIC,UAAU9G,SAAS+G,oBAAT,CAA8B,QAA9B,CAAd;;AAEA,cAAK,IAAI7M,IAAI,CAAb,EAAgBA,IAAI4M,QAAQ3M,MAA5B,EAAoCD,GAApC,EAAyC;;AAErC,iBAAI4M,QAAQ5M,CAAR,EAAW8M,EAAX,CAAcC,OAAd,CAAsBnP,OAAOoP,YAA7B,IAA6C,CAAjD,EAAoD;;AAEhDJ,yBAAQ5M,CAAR,EAAWlB,MAAX;AACAkB;AAEH;AAEJ;AAEJ,MAfD;;AAkBA;;;;;;;;;;AAUAqM,eAAUK,OAAV,GAAoB,UAAUlN,QAAV,EAAoB;;AAEpC,aAAI,CAACA,QAAD,IAAa,QAAOA,QAAP,yCAAOA,QAAP,OAAoB,QAArC,EAA+C;;AAE3C;AAEH;;AAED,aAAIA,SAASzC,EAAb,EAAiB;;AAEbsP,uBAAUC,WAAV;AACA1O,oBAAOqP,SAAP,CAAiBC,SAAjB;AAEH;;AAED,aAAI1N,SAASoN,OAAb,EAAsB;;AAElBP,uBAAUM,cAAV;AAEH;;AAED,aAAInN,SAAS2N,OAAb,EAAsB;;AAElBd,uBAAUI,cAAV;AAEH;;AAED,aAAIjN,SAASzC,EAAT,IAAeyC,SAASoN,OAAxB,IAAmCpN,SAASP,IAAhD,EAAsD;;AAElD,oBAAOpB,MAAMD,MAAb;AAEH;AAEJ,MAjCD;;AAmCA,YAAOyO,SAAP;AAEH,EA1FgB,CA0Ff,EA1Fe,CAAjB,C;;;;;;;;ACPA;;;;;;;AAOA;;;AAGA/Q,QAAOC,OAAP,GAAiB,UAAU0R,SAAV,EAAqB;;AAElC,SAAIG,eAAe,EAAnB;;AAEA;;;;;;;AAOAH,eAAUI,MAAV,GAAmB,YAAY;;AAE3B,aAAIC,YAAY,SAAZA,SAAY,CAAUC,OAAV,EAAmBC,OAAnB,EAA4B;;AAExC,iBAAIC,qBAAqB,EAAzB;;AAEAD,uBAAUA,WAAWJ,YAArB;;AAEA,kBAAK,IAAIpN,IAAI,CAAb,EAAgBA,IAAIwN,QAAQvN,MAA5B,EAAoCD,GAApC,EAAyC;;AAErC,qBAAI0N,WAAWF,QAAQxN,CAAR,CAAf;;AAEA,qBAAI0N,SAASH,OAAT,KAAqBA,OAAzB,EAAkC;;AAE9BE,wCAAmBE,IAAnB,CAAwBD,QAAxB;AAEH;AAEJ;;AAED,oBAAOD,kBAAP;AAEH,UApBD;;AAsBA,aAAIG,SAAS,SAATA,MAAS,CAAUC,SAAV,EAAqBL,OAArB,EAA8B;;AAEvC,iBAAIM,oBAAoB,EAAxB;;AAEAN,uBAAUA,WAAWJ,YAArB;;AAEA,kBAAK,IAAIpN,IAAI,CAAb,EAAgBA,IAAIwN,QAAQvN,MAA5B,EAAoCD,GAApC,EAAyC;;AAErC,qBAAI0N,WAAWF,QAAQxN,CAAR,CAAf;;AAEA,qBAAI0N,SAASxL,IAAT,KAAkB2L,SAAtB,EAAiC;;AAE7BC,uCAAkBH,IAAlB,CAAuBD,QAAvB;AAEH;AAEJ;;AAED,oBAAOI,iBAAP;AAEH,UApBD;;AAsBA,aAAIC,YAAY,SAAZA,SAAY,CAAUC,OAAV,EAAmBR,OAAnB,EAA4B;;AAExC,iBAAIS,uBAAuB,EAA3B;;AAEAT,uBAAUA,WAAWJ,YAArB;;AAEA,kBAAK,IAAIpN,IAAI,CAAb,EAAgBA,IAAIwN,QAAQvN,MAA5B,EAAoCD,GAApC,EAAyC;;AAErC,qBAAI0N,WAAWF,QAAQxN,CAAR,CAAf;;AAEA,qBAAI0N,SAASM,OAAT,KAAqBA,OAAzB,EAAkC;;AAE9BC,0CAAqBN,IAArB,CAA0BD,QAA1B;AAEH;AAEJ;;AAED,oBAAOO,oBAAP;AAEH,UApBD;;AAsBA,aAAIC,MAAM,SAANA,GAAM,CAAUX,OAAV,EAAmBM,SAAnB,EAA8BG,OAA9B,EAAuC;;AAE7C,iBAAIG,SAASf,YAAb;;AAEA,iBAAIG,OAAJ,EACIY,SAASb,UAAUC,OAAV,EAAmBY,MAAnB,CAAT;;AAEJ,iBAAIN,SAAJ,EACIM,SAASP,OAAOC,SAAP,EAAkBM,MAAlB,CAAT;;AAEJ,iBAAIH,OAAJ,EACIG,SAASJ,UAAUC,OAAV,EAAmBG,MAAnB,CAAT;;AAEJ,oBAAOA,OAAO,CAAP,CAAP;AAEH,UAfD;;AAiBA,aAAIC,MAAM,SAANA,GAAM,CAAUb,OAAV,EAAmBM,SAAnB,EAA8BG,OAA9B,EAAuC;;AAE7C,iBAAIG,SAASf,YAAb;;AAEA,iBAAIG,OAAJ,EACIY,SAASb,UAAUC,OAAV,EAAmBY,MAAnB,CAAT;;AAEJ,iBAAIN,SAAJ,EACIM,SAASP,OAAOC,SAAP,EAAkBM,MAAlB,CAAT;;AAEJ,iBAAIH,OAAJ,EACIG,SAASJ,UAAUC,OAAV,EAAmBG,MAAnB,CAAT;;AAEJ,oBAAOA,MAAP;AAEH,UAfD;;AAiBA,gBAAO;AACHb,wBAAcA,SADX;AAEHM,qBAAcA,MAFX;AAGHG,wBAAcA,SAHX;AAIHG,kBAAcA,GAJX;AAKHE,kBAAcA;AALX,UAAP;AAQH,MA9GkB,EAAnB;;AAgHAnB,eAAUtO,GAAV,GAAgB,UAAU4O,OAAV,EAAmBM,SAAnB,EAA8BG,OAA9B,EAAuCK,SAAvC,EAAkD;;AAE9Dd,iBAAQe,gBAAR,CAAyBT,SAAzB,EAAoCG,OAApC,EAA6CK,SAA7C;;AAEA,aAAIE,OAAO;AACPhB,sBAASA,OADF;AAEPrL,mBAAM2L,SAFC;AAGPG,sBAASA;AAHF,UAAX;;AAMA,aAAIQ,uBAAuBvB,UAAUI,MAAV,CAAiBa,GAAjB,CAAqBX,OAArB,EAA8BM,SAA9B,EAAyCG,OAAzC,CAA3B;;AAEA,aAAI,CAACQ,oBAAL,EAA2B;;AAEvBpB,0BAAaO,IAAb,CAAkBY,IAAlB;AAEH;AAEJ,MAlBD;;AAoBAtB,eAAUnO,MAAV,GAAmB,UAAUyO,OAAV,EAAmBM,SAAnB,EAA8BG,OAA9B,EAAuC;;AAEtDT,iBAAQkB,mBAAR,CAA4BZ,SAA5B,EAAuCG,OAAvC;;AAEA,aAAIU,oBAAoBzB,UAAUI,MAAV,CAAiBe,GAAjB,CAAqBb,OAArB,EAA8BM,SAA9B,EAAyCG,OAAzC,CAAxB;;AAEA,cAAK,IAAIhO,IAAI,CAAb,EAAgBA,IAAI0O,kBAAkBzO,MAAtC,EAA8CD,GAA9C,EAAmD;;AAE/C,iBAAI2I,QAAQyE,aAAaL,OAAb,CAAqB2B,kBAAkB1O,CAAlB,CAArB,CAAZ;;AAEA,iBAAI2I,QAAQ,CAAZ,EAAe;;AAEXyE,8BAAauB,MAAb,CAAoBhG,KAApB,EAA2B,CAA3B;AAEH;AAEJ;AAEJ,MAlBD;;AAoBAsE,eAAUC,SAAV,GAAsB,YAAY;;AAE9BE,sBAAa/R,GAAb,CAAiB,UAAUwH,OAAV,EAAmB;;AAEhCoK,uBAAUnO,MAAV,CAAiB+D,QAAQ0K,OAAzB,EAAkC1K,QAAQX,IAA1C,EAAgDW,QAAQmL,OAAxD;AAEH,UAJD;AAMH,MARD;;AAUAf,eAAU2B,GAAV,GAAgB,UAAUrB,OAAV,EAAmBM,SAAnB,EAA8BG,OAA9B,EAAuC;;AAEnD,gBAAOf,UAAUI,MAAV,CAAiBe,GAAjB,CAAqBb,OAArB,EAA8BM,SAA9B,EAAyCG,OAAzC,CAAP;AAEH,MAJD;;AAMA,YAAOf,SAAP;AAEH,EArLgB,CAqLf,EArLe,CAAjB,C;;;;;;;;ACVA;;;;;;;AAOA3R,QAAOC,OAAP,GAAkB,UAAUiR,aAAV,EAAyB;;AAEvC,SAAI5O,SAASC,MAAMD,MAAnB;;AAEA,SAAIiR,QAAQ,EAAZ;;AAEA,SAAIC,aAAa,SAAbA,UAAa,CAAUtP,QAAV,EAAoB;;AAEjCqP,eAAMlB,IAAN,CAAWnO,QAAX;;AAEA,aAAImJ,QAAQ,CAAZ;;AAEA,gBAAQA,QAAQkG,MAAM5O,MAAd,IAAwB4O,MAAM5O,MAAN,GAAe,CAA/C,EAAkD;;AAE9C,iBAAI4O,MAAMlG,KAAN,EAAazG,IAAb,IAAqB,SAArB,IAAkC2M,MAAMlG,KAAN,EAAazG,IAAb,IAAqB,QAA3D,EAAqE;;AAEjEyG;AACA;AAEH;;AAEDkG,mBAAMlG,KAAN,EAAalJ,KAAb;AACAoP,mBAAMF,MAAN,CAAahG,KAAb,EAAoB,CAApB;AAEH;AAEJ,MApBD;;AAsBA6D,mBAAcuC,YAAd,GAA6B,YAAY;;AAErC,aAAIC,SAASpR,OAAOqR,IAAP,CAAYjF,IAAZ,CAAiB,KAAjB,EAAwB,yBAAxB,CAAb;;AAEApM,gBAAOuI,KAAP,CAAaqG,aAAb,GAA6B1G,SAASC,IAAT,CAAcwD,WAAd,CAA0ByF,MAA1B,CAA7B;;AAEA,gBAAOA,MAAP;AAEH,MARD;;AAWA;;;;AAIAxC,mBAAc0C,WAAd,GAA4B,UAAUC,QAAV,EAAoB3O,KAApB,EAA2B;;AAEnD5C,gBAAO4O,aAAP,CAAqB4C,YAArB,CAAkC,EAACC,SAAS,wCAAV,EAAoDnN,MAAM1B,MAAM0B,IAAhE,EAAlC;AAEH,MAJD;;AAMA;;;;;;;;;;;;;;;;AAgBAsK,mBAAc4C,YAAd,GAA6B,UAAUE,mBAAV,EAA+B;;AAExD;AACA,aAAIF,eAAe,IAAnB;AAAA,aACIG,SAAe,IADnB;AAAA,aAEIrN,OAAe,IAFnB;AAAA,aAGIsN,UAAe,IAHnB;AAAA,aAIIC,aAAe,IAJnB;;AAMA,aAAIC,iBAAiB,SAAjBA,cAAiB,GAAY;;AAE7BjQ;;AAEA,iBAAI,OAAO+P,OAAP,KAAmB,UAAvB,EAAoC;;AAEhC;AAEH;;AAED,iBAAItN,QAAQ,QAAZ,EAAsB;;AAElBsN,yBAAQC,WAAWvR,KAAnB;AACA;AAEH;;AAEDsR;AAEH,UAnBD;;AAqBA,aAAIG,gBAAgB,SAAhBA,aAAgB,GAAY;;AAE5BlQ;;AAEA,iBAAI,OAAO8P,MAAP,KAAkB,UAAtB,EAAmC;;AAE/B;AAEH;;AAEDA;AAEH,UAZD;;AAeA;AACA,kBAASK,MAAT,CAAgBpQ,QAAhB,EAA0B;;AAEtB,iBAAI,EAAEA,YAAYA,SAAS6P,OAAvB,CAAJ,EAAqC;;AAEjCzR,wBAAOqB,IAAP,CAAYhD,GAAZ,CAAgB,+CAAhB;AACA;AAEH;;AAEDuD,sBAAS0C,IAAT,GAAgB1C,SAAS0C,IAAT,IAAiB,OAAjC;AACA1C,sBAASqQ,IAAT,GAAgBrQ,SAASqQ,IAAT,GAAc,IAAd,IAAsB,KAAtC;;AAEA,iBAAItD,UAAU3O,OAAOqR,IAAP,CAAYjF,IAAZ,CAAiB,KAAjB,EAAwB,kBAAxB,CAAd;AAAA,iBACIqF,UAAUzR,OAAOqR,IAAP,CAAYjF,IAAZ,CAAiB,KAAjB,EAAwB,2BAAxB,CADd;AAAA,iBAEIlM,QAAQF,OAAOqR,IAAP,CAAYjF,IAAZ,CAAiB,OAAjB,EAA0B,yBAA1B,CAFZ;AAAA,iBAGI8F,QAAQlS,OAAOqR,IAAP,CAAYjF,IAAZ,CAAiB,MAAjB,EAAyB,0BAAzB,CAHZ;AAAA,iBAII+F,YAAYnS,OAAOqR,IAAP,CAAYjF,IAAZ,CAAiB,MAAjB,EAAyB,8BAAzB,CAJhB;;AAMAqF,qBAAQlL,WAAR,GAAsB3E,SAAS6P,OAA/B;AACAS,mBAAM3L,WAAN,GAAoB3E,SAASwQ,KAAT,IAAkB,IAAtC;AACAD,uBAAU5L,WAAV,GAAwB3E,SAASyQ,SAAT,IAAsB,QAA9C;;AAEArS,oBAAOqP,SAAP,CAAiBtO,GAAjB,CAAqBmR,KAArB,EAA4B,OAA5B,EAAqCJ,cAArC;AACA9R,oBAAOqP,SAAP,CAAiBtO,GAAjB,CAAqBoR,SAArB,EAAgC,OAAhC,EAAyCJ,aAAzC;;AAEApD,qBAAQhD,WAAR,CAAoB8F,OAApB;;AAEA,iBAAI7P,SAAS0C,IAAT,IAAiB,QAArB,EAA+B;;AAE3BqK,yBAAQhD,WAAR,CAAoBzL,KAApB;AAEH;;AAEDyO,qBAAQhD,WAAR,CAAoBuG,KAApB;;AAEA,iBAAItQ,SAAS0C,IAAT,IAAiB,QAAjB,IAA6B1C,SAAS0C,IAAT,IAAiB,SAAlD,EAA6D;;AAEzDqK,yBAAQhD,WAAR,CAAoBwG,SAApB;AAEH;;AAEDxD,qBAAQ7N,SAAR,CAAkBC,GAAlB,CAAsB,sBAAsBa,SAAS0C,IAArD;AACAqK,qBAAQpO,OAAR,CAAgB+D,IAAhB,GAAuB1C,SAAS0C,IAAhC;;AAEAkN,4BAAe7C,OAAf;AACArK,oBAAe1C,SAAS0C,IAAxB;AACAsN,uBAAehQ,SAASgQ,OAAxB;AACAD,sBAAe/P,SAAS+P,MAAxB;AACAE,0BAAe3R,KAAf;;AAEA,iBAAI0B,SAAS0C,IAAT,IAAiB,QAAjB,IAA6B1C,SAAS0C,IAAT,IAAiB,SAAlD,EAA6D;;AAEzDkB,wBAAO8E,UAAP,CAAkBzI,KAAlB,EAAyBD,SAASqQ,IAAlC;AAEH;AAEJ;;AAED;;;AAGA,kBAASK,IAAT,GAAgB;;AAEZtS,oBAAOuI,KAAP,CAAaqG,aAAb,CAA2BjD,WAA3B,CAAuC6F,YAAvC;AACAK,wBAAW3G,KAAX;;AAEAlL,oBAAOuI,KAAP,CAAaqG,aAAb,CAA2B9N,SAA3B,CAAqCC,GAArC,CAAyC,0CAAzC;;AAEAyE,oBAAO8E,UAAP,CAAkB,YAAY;;AAE1BtK,wBAAOuI,KAAP,CAAaqG,aAAb,CAA2B9N,SAA3B,CAAqCI,MAArC,CAA4C,0CAA5C;AAEH,cAJD,EAIG,GAJH;;AAMAgQ,wBAAW,EAAC5M,MAAMA,IAAP,EAAazC,OAAOA,KAApB,EAAX;AAEH;;AAED;;;AAGA,kBAASA,KAAT,GAAiB;;AAEb2P,0BAAatQ,MAAb;AAEH;;AAGD,aAAIwQ,mBAAJ,EAAyB;;AAErBM,oBAAON,mBAAP;AACAY;AAEH;;AAED,gBAAO;AACHN,qBAAQA,MADL;AAEHM,mBAAMA,IAFH;AAGHzQ,oBAAOA;AAHJ,UAAP;AAMH,MAnJD;;AAqJA+M,mBAAc2D,KAAd,GAAsB,YAAY;;AAE9BvS,gBAAOuI,KAAP,CAAaqG,aAAb,CAA2B4D,SAA3B,GAAuC,EAAvC;AACAvB,iBAAQ,EAAR;AAEH,MALD;;AAOA,YAAOrC,aAAP;AAEH,EA/NgB,CA+Nd,EA/Nc,CAAjB,C;;;;;;;;ACPA;;;;;;;AAOAlR,QAAOC,OAAP,GAAkB,UAAU8U,MAAV,EAAkB;;AAEhC,SAAIzS,SAASC,MAAMD,MAAnB;;AAEA;AACAyS,YAAOC,mBAAP,GAA6B,UAAUC,SAAV,EAAqBC,GAArB,EAA0B;;AAEnD5S,gBAAO0D,OAAP,CAAeW,WAAf,CAA2B;AACvBC,mBAAQqO,UAAUrO,IADK;AAEvBC,oBAAQoO,UAAUnO,MAAV,CAAiB;AACrBqO,uBAAOD,IAAIJ;AADU,cAAjB;AAFe,UAA3B;AAOH,MATD;;AAWA;;;AAGAC,YAAOK,iBAAP,GAA2B,UAAU1G,IAAV,EAAgB;;AAEvC,gBAAOA,KAAKjG,QAAL,IAAiBnG,OAAOqB,IAAP,CAAY+E,SAAZ,CAAsB2M,GAAvC,IACH3G,KAAKtL,SAAL,CAAe0H,QAAf,CAAwBxI,OAAOb,EAAP,CAAU6B,SAAV,CAAoBgS,eAA5C,CADJ;AAGH,MALD;;AAOA,YAAOP,MAAP;AAEH,EA5BgB,CA4Bd,EA5Bc,CAAjB,C;;;;;;;;ACPA;;;;;;;AAOA/U,QAAOC,OAAP,GAAiB,UAAUsV,KAAV,EAAiB;;AAE9B,SAAIjT,SAASC,MAAMD,MAAnB;;AAEA,SAAIkT,WAAW,EAAf;;AAEAD,WAAM/T,OAAN,GAAgB,YAAY;;AAExB,aAAIW,QAAQG,OAAOH,KAAnB;;AAEA,cAAK,IAAIkF,IAAT,IAAiBlF,KAAjB,EAAwB;;AAEpB,iBAAI,CAACA,MAAMkF,IAAN,EAAYoO,qBAAb,IAAsC,CAACpF,MAAMC,OAAN,CAAcnO,MAAMkF,IAAN,EAAYoO,qBAA1B,CAA3C,EAA6F;;AAEzF;AAEH;;AAEDtT,mBAAMkF,IAAN,EAAYoO,qBAAZ,CAAkC1V,GAAlC,CAAsC,UAAU2V,OAAV,EAAmB;;AAGrDF,0BAASnD,IAAT,CAAcqD,OAAd;AAEH,cALD;AAOH;;AAED,gBAAOtV,QAAQC,OAAR,EAAP;AAEH,MAvBD;;AAyBA;;;;AAIAkV,WAAMI,MAAN,GAAe,UAAUzQ,KAAV,EAAiB;;AAE5B,aAAI0Q,gBAAgB1Q,MAAM2Q,aAAN,IAAuB/N,OAAO+N,aAAlD;AAAA,aACI7P,UAAU4P,cAAcE,OAAd,CAAsB,MAAtB,CADd;;AAGA,aAAIjD,SAASkD,QAAQ/P,OAAR,CAAb;;AAEA,aAAI6M,MAAJ,EAAY;;AAER3N,mBAAMpB,cAAN;AACAoB,mBAAMyC,wBAAN;AAEH;;AAED,gBAAOkL,MAAP;AAEH,MAhBD;;AAkBA;;;;AAIA,SAAIkD,UAAU,SAAVA,OAAU,CAAUxR,MAAV,EAAkB;;AAE5B,aAAIsO,SAAU,KAAd;AAAA,aACI7M,UAAU1D,OAAO0D,OAAP,CAAevD,WAD7B;AAAA,aAEIuT,SAAUhQ,QAAQnD,OAAR,CAAgBwE,IAF9B;;AAIAmO,kBAASzV,GAAT,CAAc,UAAU2V,OAAV,EAAmB;;AAE7B,iBAAIO,YAAYP,QAAQQ,KAAR,CAAcC,IAAd,CAAmB5R,MAAnB,CAAhB;AAAA,iBACI6R,QAAYH,aAAaA,UAAU,CAAV,CAD7B;;AAGA,iBAAKG,SAASA,UAAU7R,OAAOpB,IAAP,EAAxB,EAAuC;;AAEnC;AACA,qBAAK6C,QAAQ6C,WAAR,CAAoB1F,IAApB,MAA8B6S,UAAU1T,OAAO4B,QAAP,CAAgBwC,kBAA7D,EAAkF;;AAE9E2P;AAEH;;AAEDX,yBAAQpN,QAAR,CAAiB/D,MAAjB,EAAyBmR,OAAzB;AACA7C,0BAAS,IAAT;AAEH;AAEJ,UAnBD;;AAqBA,gBAAOA,MAAP;AAEH,MA7BD;;AA+BA,SAAIwD,mBAAmB,SAAnBA,gBAAmB,GAAY;;AAE/B;AACA/T,gBAAO0D,OAAP,CAAeW,WAAf,CAA2B;;AAEvBC,mBAAOtE,OAAO4B,QAAP,CAAgBwC,kBAFA;AAGvBG,oBAAQvE,OAAOH,KAAP,CAAaG,OAAO4B,QAAP,CAAgBwC,kBAA7B,EAAiDI,MAAjD,CAAwD;AAC5DqO,uBAAO;AADqD,cAAxD;;AAHe,UAA3B,EAOG,KAPH;AASH,MAZD;;AAcA;;;;;;;;;;AAUAI,WAAMe,kBAAN,GAA2B,UAAUpR,KAAV,EAAiB;;AAGxC,aAAI,CAACqR,wBAAwBrR,MAAMjC,MAA9B,CAAL,EAA4C;;AAExC;AAEH;;AAED;AACAiC,eAAMpB,cAAN;;AAEA;AACA,aAAI0S,WAAYtR,MAAM2Q,aAAN,CAAoBC,OAApB,CAA4B,WAA5B,CAAhB;AAAA,aACIW,YAAYvR,MAAM2Q,aAAN,CAAoBC,OAApB,CAA4B,YAA5B,CADhB;;AAGA;AACA,aAAIY,aAAapU,OAAOqR,IAAP,CAAYjF,IAAZ,CAAiB,KAAjB,EAAwB,EAAxB,EAA4B,EAA5B,CAAjB;AAAA,aACIiI,SADJ;AAAA,aAEIC,WAFJ;;AAIA;AACAD,qBAAYrU,OAAOR,SAAP,CAAiB+U,KAAjB,CAAuBL,QAAvB,CAAZ;;AAEA;;;;AAIAI,uBAActU,OAAO0D,OAAP,CAAe8Q,sBAAf,CAAsCH,SAAtC,EAAiDF,SAAjD,CAAd;AACAC,oBAAW5B,SAAX,GAAuB8B,WAAvB;;AAEA;;;AAGA,aAAIF,WAAWhL,UAAX,CAAsB/G,MAAtB,IAAgC,CAApC,EAAuC;;AAEnCoS,uCAA0BL,WAAW3K,UAArC;AACA;AAEH;;AAEDiL,gCAAuBN,WAAWhL,UAAlC;AAEH,MA3CD;;AA6CA;;;;;;AAMA,SAAI6K,0BAA0B,SAA1BA,uBAA0B,CAAU1P,KAAV,EAAiB;;AAE3C;AACA,aAAKvE,OAAOqB,IAAP,CAAYyI,aAAZ,CAA0BvF,KAA1B,CAAL,EAAwC;;AAEpC,oBAAO,KAAP;AAEH;;AAED,aAAIoQ,iBAAiB3U,OAAO0D,OAAP,CAAekR,iBAAf,CAAiCrQ,KAAjC,CAArB;;AAEA;AACA,aAAI,CAACoQ,cAAL,EAAqB;;AAEjB,oBAAO,KAAP;AAEH;;AAED,gBAAO,IAAP;AAEH,MApBD;;AAsBA;;;;;AAKA,SAAID,yBAAyB,SAAzBA,sBAAyB,CAAUN,UAAV,EAAsB;;AAE/C,aAAIjQ,iBAAiBnE,OAAO4B,QAAP,CAAgBwC,kBAArC;AAAA,aACIjE,cAAcH,OAAO0D,OAAP,CAAevD,WADjC;;AAIAiU,oBAAW1V,OAAX,CAAmB,UAAUmW,SAAV,EAAqB;;AAEpC;AACA,iBAAI7U,OAAOqB,IAAP,CAAYoC,YAAZ,CAAyBoR,SAAzB,CAAJ,EAAyC;;AAErC;AAEH;;AAED7U,oBAAO0D,OAAP,CAAeW,WAAf,CAA2B;AACvBC,uBAAQH,cADe;AAEvBI,wBAAQvE,OAAOH,KAAP,CAAasE,cAAb,EAA6BK,MAA7B,CAAoC;AACxCqO,2BAAOgC,UAAUrC;AADuB,kBAApC;AAFe,cAA3B;;AAOAxS,oBAAOgE,KAAP,CAAaC,UAAb;AAEH,UAlBD;;AAoBAjE,gBAAOgE,KAAP,CAAa0F,kBAAb,CAAgC1J,OAAOgE,KAAP,CAAaa,oBAAb,KAAsC,CAAtE;;AAGA;;;AAGA,aAAI7E,OAAOqB,IAAP,CAAYoC,YAAZ,CAAyBtD,WAAzB,CAAJ,EAA2C;;AAEvCA,yBAAYe,MAAZ;AACAlB,oBAAOb,EAAP,CAAUwH,UAAV;AAEH;AAGJ,MAxCD;;AA0CA;;;;;AAKA,SAAI8N,4BAA4B,SAA5BA,yBAA4B,CAAUrI,IAAV,EAAgB;;AAE5C,aAAI0I,OAAJ;;AAEA,aAAI1I,KAAK2I,iBAAT,EAA4B;;AAExBD,uBAAU5M,SAAS8M,sBAAT,EAAV;;AAEA5I,kBAAKhD,UAAL,CAAgB1K,OAAhB,CAAwB,UAAUuG,OAAV,EAAmB;;AAEvC,qBAAI,CAACjF,OAAOqB,IAAP,CAAY4G,SAAZ,CAAsBhD,OAAtB,CAAD,IAAmCA,QAAQ0L,IAAR,CAAa9P,IAAb,OAAwB,EAA/D,EAAmE;;AAE/D;AAEH;;AAEDiU,yBAAQnJ,WAAR,CAAoB1G,QAAQgQ,SAAR,CAAkB,IAAlB,CAApB;AAEH,cAVD;AAYH,UAhBD,MAgBO;;AAEHH,uBAAU5M,SAASwD,cAAT,CAAwBU,KAAK7F,WAA7B,CAAV;AAEH;;AAEDvG,gBAAOgE,KAAP,CAAamI,UAAb,CAAwB2I,OAAxB;AAEH,MA5BD;;AA+BA,YAAO7B,KAAP;AAEH,EA9QgB,CA8Qf,EA9Qe,CAAjB,C;;;;;;;;ACPA;;;;AAIAvV,QAAOC,OAAP,GAAkB,UAAU6B,SAAV,EAAqB;;AAEnC;AACA,SAAI0V,UAAU,mBAAAC,CAAQ,EAAR,CAAd;;AAEA;AACA,SAAInV,SAAUC,MAAMD,MAApB;;AAEAR,eAAUN,OAAV,GAAoB,YAAY;;AAE5B,aAAIc,OAAO4B,QAAP,CAAgBpC,SAAhB,IAA6B,CAACQ,OAAOqB,IAAP,CAAY+T,OAAZ,CAAoBpV,OAAO4B,QAAP,CAAgBpC,SAApC,CAAlC,EAAkF;;AAE9E6V,oBAAOC,MAAP,GAAgBtV,OAAO4B,QAAP,CAAgBpC,SAAhC;AAEH;AAEJ,MARD;;AAUA;;;AAGA,SAAI6V,SAAS;;AAET;AACAC,iBAAS,IAHA;;AAKTC,gBAAQ;;AAEJC,mBAAM;AACF/V,oBAAG,EADD;AAEFE,oBAAG;AACC8V,2BAAM,IADP;AAEC9U,6BAAQ,QAFT;AAGC+U,0BAAK;AAHN;AAFD;AAFF;AALC,MAAb;;AAkBAlW,eAAU6V,MAAV,GAAmBA,MAAnB;;AAEA;;;;;;;;;;AAUA,SAAIM,QAAQ,SAARA,KAAQ,CAAUC,gBAAV,EAA4B;;AAEpC,aAAI3X,gBAAgB2X,oBAAoBP,OAAOC,MAA3B,IAAqCD,OAAOE,KAAhE;;AAEA,gBAAO,IAAIL,OAAJ,CAAYjX,aAAZ,CAAP;AAEH,MAND;;AAQA;;;;;;AAMAuB,eAAU+U,KAAV,GAAkB,UAAUsB,WAAV,EAAuBC,YAAvB,EAAqC;;AAEnD,aAAIC,kBAAkBJ,MAAMG,YAAN,CAAtB;;AAEA,gBAAOC,gBAAgBxB,KAAhB,CAAsBsB,WAAtB,CAAP;AAEH,MAND;;AAQA,YAAOrW,SAAP;AAEH,EA3EgB,CA2Ed,EA3Ec,CAAjB,C;;;;;;ACJA;AACA;AACA;AACA,IAAG;AACH;AACA,IAAG;AACH;AACA;AACA,EAAC;;AAED;AACA,cAAa,OAAO;AACpB,cAAa,QAAQ;AACrB;AACA;;AAEA;AACA;;AAEA;AACA,yBAAwB,iCAAiC,EAAE;AAC3D,8BAA6B,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,iBAAgB,QAAQ;;AAExB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,gEAA+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,sBAAqB,4BAA4B;AACjD;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;;AAEA;AACA;;AAEA;;AAEA,EAAC;;;;;;;;;ACxLD;;;;;;;AAOA9B,QAAOC,OAAP,GAAkB,UAAUqY,KAAV,EAAiB;;AAE/B,SAAIhW,SAASC,MAAMD,MAAnB;;AAEA;;;;AAIAgW,WAAMC,IAAN,GAAa,YAAY;;AAErB;AACAjW,gBAAOlB,KAAP,CAAaoX,IAAb,GAAoBlW,OAAOuI,KAAP,CAAa6B,QAAb,CAAsBoI,SAA1C;;AAEA;AACAxS,gBAAOlB,KAAP,CAAaqX,UAAb,GAA0B,EAA1B;;AAEA,gBAAOC,WAAWpW,OAAOuI,KAAP,CAAa6B,QAAb,CAAsBhB,UAAjC,CAAP;AAEH,MAVD;;AAYA;;;;;;;AAOA,SAAIgN,aAAa,SAAbA,UAAa,CAAUC,MAAV,EAAkB;;AAE/B,aAAI1F,OAAO,EAAX;;AAEA,cAAI,IAAI5F,QAAQ,CAAhB,EAAmBA,QAAQsL,OAAOhU,MAAlC,EAA0C0I,OAA1C,EAAmD;;AAE/C4F,kBAAKZ,IAAL,CAAUuG,aAAaD,OAAOtL,KAAP,CAAb,CAAV;AAEH;;AAED,gBAAOjN,QAAQ0S,GAAR,CAAYG,IAAZ,EACF3S,IADE,CACGuY,UADH,EAEFjY,KAFE,CAEI0B,OAAOqB,IAAP,CAAYhD,GAFhB,CAAP;AAIH,MAdD;;AAgBA;AACA,SAAIiY,eAAe,SAAfA,YAAe,CAAU/R,KAAV,EAAiB;;AAEhC,gBAAOiS,cAAcjS,KAAd,EACJvG,IADI,CACCyY,iBADD,EAEJnY,KAFI,CAEE0B,OAAOqB,IAAP,CAAYhD,GAFd,CAAP;AAIH,MAND;;AAQD;;;;;;;AAOC,SAAImY,gBAAgB,SAAhBA,aAAgB,CAAUjS,KAAV,EAAiB;;AAEjC,aAAImS,aAAanS,MAAMhE,OAAN,CAAcwE,IAA/B;;AAEA;AACA,aAAI,CAAC/E,OAAOH,KAAP,CAAa6W,UAAb,CAAL,EAA+B;;AAE3B1W,oBAAOqB,IAAP,CAAYhD,GAAZ,iBAA2BqY,UAA3B,qBAAoD,OAApD;AACA,oBAAO,EAAC/F,MAAM,IAAP,EAAa+F,YAAY,IAAzB,EAAP;AAEH;;AAED;AACA,aAAI,OAAO1W,OAAOH,KAAP,CAAa6W,UAAb,EAAyBT,IAAhC,KAAyC,UAA7C,EAAyD;;AAErDjW,oBAAOqB,IAAP,CAAYhD,GAAZ,iBAA2BqY,UAA3B,iCAAgE,OAAhE;AACA,oBAAO,EAAC/F,MAAM,IAAP,EAAa+F,YAAY,IAAzB,EAAP;AAEH;;AAED;AACA,aAAItJ,eAAiB7I,MAAM6E,UAAN,CAAiB,CAAjB,CAArB;AAAA,aACIuN,iBAAiBvJ,aAAahE,UAAb,CAAwB,CAAxB,CADrB;AAAA,aAEIvD,WAAW8Q,eAAepW,OAAf,CAAuBqW,aAFtC;;AAIA;AACA,aAAK5W,OAAOH,KAAP,CAAa6W,UAAb,EAAyBG,SAAzB,KAAuC,KAA5C,EAAoD;;AAEhD,oBAAO/Y,QAAQC,OAAR,CAAgB,EAAC4S,MAAM1Q,MAAMD,MAAN,CAAalB,KAAb,CAAmBuX,MAAnB,CAA0BS,KAA1B,CAAgCjR,QAAhC,EAA0C8K,IAAjD,EAAuD+F,sBAAvD,EAAhB,CAAP;AAEH;;AAED,gBAAO5Y,QAAQC,OAAR,CAAgB4Y,cAAhB,EACF3Y,IADE,CACGgC,OAAOH,KAAP,CAAa6W,UAAb,EAAyBT,IAD5B,EAEFjY,IAFE,CAEG;AAAA,oBAAQ+Y,OAAO,EAACpG,UAAD,EAAO+F,sBAAP,EAAP,CAAR;AAAA,UAFH,CAAP;AAIH,MApCD;;AAsCD;;;;;;;AAOC,SAAID,oBAAoB,SAApBA,iBAAoB,OAA8B;AAAA,aAAnB9F,IAAmB,QAAnBA,IAAmB;AAAA,aAAb+F,UAAa,QAAbA,UAAa;;;AAElD,aAAI,CAAC/F,IAAD,IAAS,CAAC+F,UAAd,EAA0B;;AAEtB,oBAAO,KAAP;AAEH;;AAED,aAAI1W,OAAOH,KAAP,CAAa6W,UAAb,EAAyBM,QAA7B,EAAuC;;AAEnC,iBAAIzG,SAASvQ,OAAOH,KAAP,CAAa6W,UAAb,EAAyBM,QAAzB,CAAkCrG,IAAlC,CAAb;;AAEA;;;AAGA,iBAAI,CAACJ,MAAL,EAAa;;AAET,wBAAO,KAAP;AAEH;AAEJ;;AAED,gBAAO,EAACI,UAAD,EAAO+F,sBAAP,EAAP;AAGH,MA1BD;;AA4BD;;;;;;AAMC,SAAIH,aAAa,SAAbA,UAAa,CAAUU,SAAV,EAAqB;;AAElCA,qBAAYA,UAAUC,MAAV,CAAiB;AAAA,oBAAaC,SAAb;AAAA,UAAjB,CAAZ;;AAEA,aAAIL,QAAQG,UAAUxZ,GAAV,CAAc;AAAA,oBAAasZ,OAAO,EAACzS,MAAM6S,UAAUT,UAAjB,EAA6B/F,MAAMwG,UAAUxG,IAA7C,EAAP,CAAb;AAAA,UAAd,CAAZ;;AAEA3Q,gBAAOlB,KAAP,CAAaqX,UAAb,GAA0BW,KAA1B;;AAEA,gBAAO;AACH5H,iBAAIlP,OAAOlB,KAAP,CAAauX,MAAb,CAAoBnH,EAApB,IAA0B,IAD3B;AAEH+C,mBAAM,CAAC,IAAImF,IAAJ,EAFJ;AAGHC,sBAASrX,OAAOqX,OAHb;AAIHP;AAJG,UAAP;AAOH,MAfD;;AAiBA,YAAOd,KAAP;AAEH,EA7JgB,CA6Jd,EA7Jc,CAAjB,C;;;;;;;;ACPA;;;;;;;;AAQAtY,QAAOC,OAAP,GAAkB,UAAU2Z,SAAV,EAAqB;;AAEnC,SAAItX,SAASC,MAAMD,MAAnB;;AAGA;;;AAGA,SAAIuX,iBAAiB,IAArB;;AAGA;;;AAGAD,eAAUpX,KAAV,GAAkB,IAAlB;;AAEA;;;AAGAoX,eAAUE,SAAV,GAAsB,IAAtB;;AAEA;;;AAGAF,eAAUpY,OAAV,GAAoB,YAAY;;AAE5B,aAAIgB,QAAQF,OAAOqR,IAAP,CAAYjF,IAAZ,CAAkB,OAAlB,EAA2B,EAA3B,EAA+B,EAAE9H,MAAO,MAAT,EAA/B,CAAZ;;AAEAtE,gBAAOqP,SAAP,CAAiBtO,GAAjB,CAAqBb,KAArB,EAA4B,QAA5B,EAAsCF,OAAOsX,SAAP,CAAiBG,YAAvD;AACAzX,gBAAOsX,SAAP,CAAiBpX,KAAjB,GAAyBA,KAAzB;AAEH,MAPD;;AASA;AACAoX,eAAUI,UAAV,GAAuB,YAAY;;AAE/B;AACAJ,mBAAUpX,KAAV,GAAkB,IAAlB;;AAEA;AACAoX,mBAAUpY,OAAV;AAEH,MARD;;AAUA;;;;AAIAoY,eAAUG,YAAV,GAAyB,YAAY;;AAEjC,aAAIvX,QAAc,IAAlB;AAAA,aACIkC,CADJ;AAAA,aAEIuV,QAAczX,MAAMyX,KAFxB;AAAA,aAGIC,WAAa,IAAIC,QAAJ,EAHjB;;AAKA,aAAI7X,OAAOsX,SAAP,CAAiBE,SAAjB,CAA2BM,QAA3B,KAAwC,IAA5C,EAAkD;;AAE9C,kBAAM1V,IAAI,CAAV,EAAaA,IAAIuV,MAAMtV,MAAvB,EAA+BD,GAA/B,EAAoC;;AAEhCwV,0BAASG,MAAT,CAAgB,SAAhB,EAA2BJ,MAAMvV,CAAN,CAA3B,EAAqCuV,MAAMvV,CAAN,EAASxD,IAA9C;AAEH;AAEJ,UARD,MAQO;;AAEHgZ,sBAASG,MAAT,CAAgB,OAAhB,EAAyBJ,MAAM,CAAN,CAAzB,EAAmCA,MAAM,CAAN,EAAS/Y,IAA5C;AAEH;;AAED2Y,0BAAiBvX,OAAOqB,IAAP,CAAY2W,IAAZ,CAAiB;AAC9B1T,mBAAO,MADuB;AAE9BqM,mBAAOiH,QAFuB;AAG9BK,kBAAajY,OAAOsX,SAAP,CAAiBE,SAAjB,CAA2BS,GAHV;AAI9BC,yBAAalY,OAAOsX,SAAP,CAAiBE,SAAjB,CAA2BU,UAJV;AAK9BC,sBAAanY,OAAOsX,SAAP,CAAiBE,SAAjB,CAA2BW,OALV;AAM9B5Z,oBAAayB,OAAOsX,SAAP,CAAiBE,SAAjB,CAA2BjZ,KANV;AAO9B6Z,uBAAapY,OAAOsX,SAAP,CAAiBE,SAAjB,CAA2BY;AAPV,UAAjB,CAAjB;;AAUA;AACAd,mBAAUI,UAAV;AAEH,MAlCD;;AAoCA;;;;;;;;;;;;;AAaAJ,eAAUe,eAAV,GAA4B,UAAUC,IAAV,EAAgB;;AAExChB,mBAAUE,SAAV,GAAsBc,IAAtB;;AAEA,aAAKA,KAAKR,QAAL,KAAkB,IAAvB,EAA6B;;AAEzBR,uBAAUpX,KAAV,CAAgBqY,YAAhB,CAA6B,UAA7B,EAAyC,UAAzC;AAEH;;AAED,aAAKD,KAAKE,MAAV,EAAmB;;AAEflB,uBAAUpX,KAAV,CAAgBqY,YAAhB,CAA6B,QAA7B,EAAuCD,KAAKE,MAA5C;AAEH;;AAEDlB,mBAAUpX,KAAV,CAAgBuY,KAAhB;AAEH,MAlBD;;AAoBAnB,eAAUoB,KAAV,GAAkB,YAAY;;AAE1BnB,wBAAemB,KAAf;;AAEAnB,0BAAiB,IAAjB;AAEH,MAND;;AAQA,YAAOD,SAAP;AAEH,EA/HgB,CA+Hd,EA/Hc,CAAjB,C;;;;;;;;sjBCRA;;;;;;;AAOA;;;;AACA;;;;;;;;AAEA5Z,QAAOC,OAAP;;AAEI;;;;;AAKA,iCAAwB;AAAA,aAAVC,MAAU,QAAVA,MAAU;;AAAA;;AAEpB,cAAKA,MAAL,GAAcA,MAAd;AACA,cAAK+O,MAAL,GAAc,IAAd;AACA,cAAKgM,OAAL,GAAe,IAAf;AACA,cAAKC,kBAAL,GAA0B,CAAC,CAA3B;AAEH;;AAED;;;;;;;AAhBJ;AAAA;;;AA2BI;;;;;;AA3BJ,mCAiCc;AAAA;;AAEN,oBAAO,IAAI9a,OAAJ,CAAY,mBAAW;;AAE1B,qBAAIuY,SAAS,IAAIwC,MAAJ,CAAW,MAAKlM,MAAL,CAAYxN,EAAZ,CAAeoJ,KAAf,CAAqB6B,QAAhC,CAAb;;AAEA;;;;;;;;;;;;;;AAcA,uBAAKuO,OAAL,GAAe,IAAIG,KAAJ,CAAUzC,MAAV,EAAkB;AAC7BxL,0BAAKgO,OAAOhO,GADiB;AAE7BmG,0BAAK6H,OAAO7H;AAFiB,kBAAlB,CAAf;;AAKAjT;AAEH,cAzBM,CAAP;AA2BH;;AAED;;;;;;;AAhEJ;AAAA;AAAA,gCAsEWgb,QAtEX,EAsEqBpI,IAtErB,EAsE2B;;AAEnB,iBAAIqI,eAAe,KAAKrM,MAAL,CAAYvN,KAAZ,CAAkB6Z,SAAlB,CAA4BF,QAA5B,EAAsCpI,IAAtC,CAAnB;AAAA,iBACIpM,QAAQ,oBAAUyU,YAAV,CADZ;;AAGA,kBAAKL,OAAL,CAAa,EAAE,KAAKC,kBAApB,IAA0CrU,KAA1C;AAEH;;AAED;;;;;;;;;AA/EJ;AAAA;AAAA,kCAuFaoL,OAvFb,EAuFsB;;AAEd,iBAAIpH,QAAQ,KAAKoQ,OAAL,CAAapQ,KAAzB;AAAA,iBACIwC,QAAQxC,MAAM4G,OAAN,CAAcQ,OAAd,CADZ;;AAGA,iBAAI5E,SAAS,CAAb,EAAgB;;AAEZ,wBAAO,KAAK4N,OAAL,CAAa5N,KAAb,CAAP;AAEH;AAEJ;;AAED;;;;;;AApGJ;AAAA;AAAA,2BAqBc4B,MArBd,EAqBsB;;AAEd,kBAAKA,MAAL,GAAcA,MAAd;AAEH;AAzBL;AAAA;AAAA,6BAyGuB;;AAEf,oBAAO,KAAKgM,OAAL,CAAa,KAAKC,kBAAlB,CAAP;AAEH;;AAED;;;;;;AA/GJ;AAAA;AAAA,6BAoHsB;;AAEd,oBAAO,KAAKD,OAAL,CAAapQ,KAAb,CAAmB,KAAKqQ,kBAAxB,CAAP;AAEH;;AAED;;;;;;;AA1HJ;AAAA,2BAiIoBjJ,OAjIpB,EAiI6B;;AAErB,iBAAIpH,QAAQ,KAAKoQ,OAAL,CAAapQ,KAAzB;;AAEA,kBAAKqQ,kBAAL,GAA0BrQ,MAAM4G,OAAN,CAAcQ,OAAd,CAA1B;AAEH;;AAED;;;;;;AAzIJ;AAAA;AAAA,6BA8IiB;;AAET,oBAAO,KAAKgJ,OAAL,CAAaO,KAApB;AAEH;AAlJL;;AAAA;AAAA;;AAsJA;;;;;;;;;;KASML,M;;AAEF;;;;;AAKA,qBAAYM,WAAZ,EAAyB;AAAA;;AAErB,cAAKR,OAAL,GAAe,EAAf;AACA,cAAKQ,WAAL,GAAmBA,WAAnB;AAEH;;AAED;;;;;;;;;8BAKK5U,K,EAAO;;AAER,kBAAKoU,OAAL,CAAa5I,IAAb,CAAkBxL,KAAlB;AACA,kBAAK4U,WAAL,CAAiBxN,WAAjB,CAA6BpH,MAAM2R,IAAnC;AAEH;;AAED;;;;;;;;;gCAMOnL,K,EAAOxG,K,EAAO;;AAEjB,iBAAI,CAAC,KAAKlC,MAAV,EAAkB;;AAEd,sBAAK0N,IAAL,CAAUxL,KAAV;AACA;AAEH;;AAED,iBAAIwG,QAAQ,KAAK1I,MAAjB,EAAyB;;AAErB;AACA;AAEH;;AAED,kBAAKsW,OAAL,CAAa5N,KAAb,IAAsBxG,KAAtB;;AAEA,iBAAIwG,QAAQ,CAAZ,EAAe;;AAEX,qBAAIqO,gBAAgB,KAAKT,OAAL,CAAa5N,QAAQ,CAArB,CAApB;;AAEAqO,+BAAclD,IAAd,CAAmBzI,qBAAnB,CAAyC,UAAzC,EAAqDlJ,MAAM2R,IAA3D;AAEH,cAND,MAMO;;AAEH,qBAAImD,YAAY,KAAKV,OAAL,CAAa5N,QAAQ,CAArB,CAAhB;;AAEAsO,2BAAUnD,IAAV,CAAezI,qBAAf,CAAqC,aAArC,EAAoDlJ,MAAM2R,IAA1D;AAEH;AAEJ;;AAED;;;;;;;;;;;qCAQYoD,W,EAAa/L,Q,EAAU;;AAE/B,iBAAIxC,QAAQ,KAAK4N,OAAL,CAAaxJ,OAAb,CAAqBmK,WAArB,CAAZ;;AAEA,kBAAKC,MAAL,CAAYxO,QAAQ,CAApB,EAAuBwC,QAAvB;AAEH;;AAED;;;;;;;;;6BAMIxC,K,EAAO;;AAEP,oBAAO,KAAK4N,OAAL,CAAa5N,KAAb,CAAP;AAEH;;AAED;;;;;;;;;iCAMQxG,K,EAAO;;AAEX,oBAAO,KAAKoU,OAAL,CAAaxJ,OAAb,CAAqB5K,KAArB,CAAP;AAEH;;AAED;;;;;;;;6BAKa;;AAET,oBAAO,KAAKoU,OAAL,CAAatW,MAApB;AAEH;;AAED;;;;;;;;6BAKY;;AAER,oBAAO,KAAKsW,OAAZ;AAEH;;AAED;;;;;;;;6BAKY;;AAER,oBAAO,eAAKO,KAAL,CAAW,KAAKC,WAAL,CAAiBK,QAA5B,CAAP;AAEH;;AAED;;;;;;;;;;;;;;6BAWWC,Q,EAAU1O,K,EAAOxG,K,EAAO;;AAE/B,iBAAImV,MAAMC,OAAO5O,KAAP,CAAN,CAAJ,EAA0B;;AAEtB,wBAAO,KAAP;AAEH;;AAED0O,sBAASF,MAAT,CAAgBxO,KAAhB,EAAuBxG,KAAvB;;AAEA,oBAAO,IAAP;AAEH;;AAED;;;;;;;;;;6BAOWkV,Q,EAAU1O,K,EAAO;;AAExB,iBAAI2O,MAAMC,OAAO5O,KAAP,CAAN,CAAJ,EAA0B;;AAEtB,wBAAO0O,SAAS1O,KAAT,CAAP;AAEH;;AAED,oBAAO0O,SAASzI,GAAT,CAAajG,KAAb,CAAP;AAEH;;;;;;;;;;;;;;;;sjBC9VL;;;;;;;;;;AAWA;;;;;;;;KAEqB6O,K;;AAEjB;;;;;AAKA,oBAAY7U,IAAZ,EAAkB;AAAA;;AAEd,cAAKA,IAAL,GAAYA,IAAZ;;AAEA,cAAK6H,GAAL,GAAW;AACP+B,sBAAS,UADF;AAEPjL,sBAAS;AAFF,UAAX;;AAKA,cAAKmW,KAAL,GAAa,KAAKC,OAAL,EAAb;AAEH;;AAED;;;;;;;;;;mCAMU;;AAEN,iBAAInL,UAAU,cAAExB,IAAF,CAAO,KAAP,EAAc,KAAKP,GAAL,CAAS+B,OAAvB,CAAd;AAAA,iBACIjL,UAAU,cAAEyJ,IAAF,CAAO,KAAP,EAAc,KAAKP,GAAL,CAASlJ,OAAvB,CADd;;AAGAA,qBAAQiI,WAAR,CAAoB,KAAK5G,IAAL,CAAUmR,IAA9B;AACAvH,qBAAQhD,WAAR,CAAoBjI,OAApB;;AAEA,oBAAOiL,OAAP;AAEH;;AAED;;;;;;;;6BAKW;;AAEP,oBAAO,KAAKkL,KAAZ;AAEH;;;;;;mBA/CgBD,K;;;;;;;;;;;;ACbrB;;;;;;;;;AASAlc,QAAOC,OAAP;AAAA;AAAA;;;AAYI;;;;;AAZJ,2BAiBcgP,MAjBd,EAiBsB;;AAEd,kBAAKA,MAAL,GAAcA,MAAd;AAEH;;AAED;;;;;;AAvBJ;AAAA;;;AAEI;;;;AAFJ,6BAMsB;;AAEd,oBAAO,QAAP;AAEH;AAVL;;AA4BI,uBAAc;AAAA;;AAEV,cAAKoN,WAAL,GAAmB,EAAnB;AACA,cAAKpN,MAAL,GAAc,IAAd;AAEH;;AAED;;;;;;AAnCJ;AAAA;AAAA,4BAuCOqN,SAvCP,EAuCkBhU,QAvClB,EAuC4B;;AAEpB,iBAAI,EAAEgU,aAAa,KAAKD,WAApB,CAAJ,EAAsC;;AAElC,sBAAKA,WAAL,CAAiBC,SAAjB,IAA8B,EAA9B;AAEH;;AAED;AACA,kBAAKD,WAAL,CAAiBC,SAAjB,EAA4BjK,IAA5B,CAAiC/J,QAAjC;AAEH;;AAED;;;;;AApDJ;AAAA;AAAA,8BAwDSgU,SAxDT,EAwDoBrJ,IAxDpB,EAwD0B;;AAElB,kBAAKoJ,WAAL,CAAiBC,SAAjB,EAA4BC,MAA5B,CAAmC,UAAUC,YAAV,EAAwBC,cAAxB,EAAwC;;AAEvE,qBAAIC,UAAUD,eAAeD,YAAf,CAAd;;AAEA,wBAAOE,UAAUA,OAAV,GAAoBF,YAA3B;AAEH,cAND,EAMGvJ,IANH;AAQH;;AAED;;;;AApEJ;AAAA;AAAA,mCAuEc;;AAEN,kBAAKhE,MAAL,GAAc,IAAd;AACA,kBAAKoN,WAAL,GAAmB,IAAnB;AAEH;AA5EL;;AAAA;AAAA,K;;;;;;;;sjBCTA;;;;;;;AAOA;;;;;;;;AAEArc,QAAOC,OAAP;;AAEI;;;;;AAKA,uBAAYC,MAAZ,EAAoB;AAAA;;AAEhB,cAAKA,MAAL,GAAcA,MAAd;AACA,cAAK+O,MAAL,GAAc,IAAd;AAEH;;AAED;;;;;;;AAdJ;AAAA;;;AAyBI;;;;;;AAzBJ,gCA+BWmK,KA/BX,EA+BkB;AAAA;;AAEV,iBAAIuD,YAAY,EAAhB;;AAFU,wCAIDjY,CAJC;;AAMNiY,2BAAUtK,IAAV,CAAe;AACXuK,+BAAU;AAAA,gCAAM,MAAKC,SAAL,CAAezD,MAAM1U,CAAN,CAAf,CAAN;AAAA;AADC,kBAAf;AANM;;AAIV,kBAAK,IAAIA,IAAI,CAAb,EAAgBA,IAAI0U,MAAMzU,MAA1B,EAAkCD,GAAlC,EAAuC;AAAA,uBAA9BA,CAA8B;AAMtC;;AAED,4BAAKoY,QAAL,CAAcH,SAAd;AAEH;;AAED;;;;;;;;;;AA/CJ;AAAA;AAAA,mCAwDcI,IAxDd,EAwDoB;;AAEZ,iBAAI1V,OAAO0V,KAAKnW,IAAhB;AAAA,iBACIqM,OAAO8J,KAAK9J,IADhB;;AAGA,kBAAKhE,MAAL,CAAYtN,YAAZ,CAAyBka,MAAzB,CAAgCxU,IAAhC,EAAsC4L,IAAtC;;AAEA,oBAAO7S,QAAQC,OAAR,EAAP;AAEH;AAjEL;AAAA;AAAA,2BAmBc4O,MAnBd,EAmBsB;;AAEd,kBAAKA,MAAL,GAAcA,MAAd;AAEH;AAvBL;;AAAA;AAAA;;AAqEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,W;;;;;;;;;;;;ACjRA;;;AAGAjP,QAAOC,OAAP;AAAA;AAAA;AAAA;;AAAA;AAAA;;;AAEI;;;;;;AAMA;;;;;;;;;AARJ,kCAiBoB+c,MAjBpB,EAiBqE;AAAA,iBAAzCvC,OAAyC,uEAA/B,YAAM,CAAE,CAAuB;AAAA,iBAArBwC,QAAqB,uEAAV,YAA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;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,W","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\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\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.loaded = 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// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 0d74f94a49f2a959d1a9","/**\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 */\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 this.moduleInstances[Module.name] = 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 modules = {};\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 modules[moduleName] = this.moduleInstances[moduleName];\n\n }\n\n return modules;\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 .then(prepareDecorator(this.moduleInstances.BlockManager))\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\": 2,\n\t\"./_anchors.js\": 2,\n\t\"./_callbacks\": 3,\n\t\"./_callbacks.js\": 3,\n\t\"./_caret\": 4,\n\t\"./_caret.js\": 4,\n\t\"./_content\": 5,\n\t\"./_content.js\": 5,\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\"./_sanitizer\": 12,\n\t\"./_sanitizer.js\": 12,\n\t\"./_saver\": 14,\n\t\"./_saver.js\": 14,\n\t\"./_transport\": 15,\n\t\"./_transport.js\": 15,\n\t\"./blockManager\": 16,\n\t\"./blockManager.js\": 16,\n\t\"./eventDispatcher\": 18,\n\t\"./eventDispatcher.js\": 18,\n\t\"./renderer\": 19,\n\t\"./renderer.js\": 19,\n\t\"./toolbar\": 21,\n\t\"./toolbar.js\": 21,\n\t\"./toolbar/inline\": 22,\n\t\"./toolbar/inline.js\": 22,\n\t\"./toolbar/settings\": 23,\n\t\"./toolbar/settings.js\": 23,\n\t\"./toolbar/toolbar\": 24,\n\t\"./toolbar/toolbar.js\": 24,\n\t\"./toolbar/toolbox\": 25,\n\t\"./toolbar/toolbox.js\": 25,\n\t\"./tools\": 26,\n\t\"./tools.js\": 26,\n\t\"./ui\": 27,\n\t\"./ui.js\": 27\n};\nfunction webpackContext(req) {\n\treturn __webpack_require__(webpackContextResolve(req));\n};\nfunction webpackContextResolve(req) {\n\treturn map[req] || (function() { throw new Error(\"Cannot find module '\" + req + \"'.\") }());\n};\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = 1;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/modules ^\\.\\/.*$\n// module id = 1\n// module chunks = 0","/**\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 case editor.core.keys.ENTER : enterKeyPressed_(event); break;\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 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 * 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 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 * @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 * @class Content\n * @classdesc Class works provides COdex Editor appearance logic\n *\n * @author Codex Team\n * @version 2.0.0\n */\n\nimport $ from '../dom';\n\nmodule.exports = class Content {\n\n /**\n * Module key name\n * @returns {string}\n */\n static get name() {\n\n return 'Content';\n\n }\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.CSS = {\n block: 'ce-block',\n content: 'ce-block__content',\n stretched: 'ce-block--stretched',\n highlighted: 'ce-block--highlighted',\n };\n\n this._currentNode = null;\n this._currentIndex = 0;\n\n }\n\n /**\n * Editor modules setter\n * @param {object} Editor\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * Get current working node\n *\n * @returns {null|HTMLElement}\n */\n get currentNode() {\n\n return this._currentNode;\n\n }\n\n /**\n * Set working node. Working node should be first level block, so we find it before set one to _currentNode property\n *\n * @param {HTMLElement} node\n */\n set currentNode(node) {\n\n let firstLevelBlock = this.getFirstLevelBlock(node);\n\n this._currentNode = firstLevelBlock;\n\n }\n\n\n /**\n * @private\n * @param pluginHTML\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 composeBlock_(pluginHTML, isStretched = false) {\n\n let block = $.make('DIV', this.CSS.block),\n blockContent = $.make('DIV', this.CSS.content);\n\n blockContent.appendChild(pluginHTML);\n block.appendChild(blockContent);\n\n if (isStretched) {\n\n blockContent.classList.add(this.CSS.stretched);\n\n }\n\n block.dataset.toolId = this._currentIndex++;\n\n return block;\n\n };\n\n /**\n * Finds first-level block\n * @description looks for first-level block.\n * gets parent while node is not first-level\n *\n * @param {Element} node - selected or clicked in redactors area node\n * @protected\n *\n */\n getFirstLevelBlock(node) {\n\n if (!$.isNode(node)) {\n\n node = node.parentNode;\n\n }\n\n if (node === this.Editor.ui.nodes.redactor || node === document.body) {\n\n return null;\n\n } else {\n\n while(node.classList && !node.classList.contains(this.CSS.block)) {\n\n node = node.parentNode;\n\n }\n\n return node;\n\n }\n\n };\n\n /**\n * Insert new block to working area\n *\n * @param {HTMLElement} tool\n *\n * @returns {Number} tool index\n *\n */\n insertBlock(tool) {\n\n let newBlock = this.composeBlock_(tool);\n\n if (this.currentNode) {\n\n this.currentNode.insertAdjacentElement('afterend', newBlock);\n\n } else {\n\n /**\n * If redactor is empty, append as first child\n */\n this.Editor.ui.nodes.redactor.appendChild(newBlock);\n\n }\n\n /**\n * Set new node as current\n */\n this.currentNode = newBlock;\n\n return newBlock.dataset.toolId;\n\n }\n\n};\n\n// module.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 * 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 = null, 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 static isNode(node) {\n\n return node && typeof node === 'object' && node.nodeType && node.nodeType === Node.ELEMENT_NODE;\n\n }\n};\n\n\n// WEBPACK FOOTER //\n// ./src/components/dom.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 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","(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// ./~/html-janitor/src/html-janitor.js\n// module id = 13\n// module chunks = 0","/**\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 * @class BlockManager\n * @classdesc Manage editor`s blocks storage and appearance\n *\n *\n */\n\nimport Block from '../block';\nimport Util from '../util';\n\nmodule.exports = class BlockManager {\n\n /**\n * @constructor\n *\n * @param {EditorConfig} config\n */\n constructor({ config }) {\n\n this.config = config;\n this.Editor = null;\n this._blocks = null;\n this._currentBloсkIndex = -1;\n\n }\n\n /**\n * Editor modules setting\n *\n * @param Editor\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * Should be called after Editor.ui preparation\n * Define this._blocks property\n *\n * @returns {Promise}\n */\n prepare() {\n\n return new Promise(resolve => {\n\n let blocks = new Blocks(this.Editor.ui.nodes.redactor);\n\n /**\n * We need to use Proxy to overload set/get [] operator.\n * So we can use array-like syntax to access blocks\n *\n * @example\n * this._blocks[0] = new Block(...);\n *\n * block = this._blocks[0];\n *\n * @todo proxy the enumerate method\n *\n * @type {Proxy}\n * @private\n */\n this._blocks = new Proxy(blocks, {\n set: Blocks.set,\n get: Blocks.get\n });\n\n resolve();\n\n });\n\n }\n\n /**\n * Insert new block into _blocks\n *\n * @param {String} toolName — plugin name\n * @param {Object} data — plugin data\n */\n insert(toolName, data) {\n\n let toolInstance = this.Editor.Tools.construct(toolName, data),\n block = new Block(toolInstance);\n\n this._blocks[++this._currentBloсkIndex] = block;\n\n }\n\n /**\n * Get Block instance by html element\n *\n * @todo get first level block before searching\n *\n * @param {HTMLElement} element\n * @returns {Block}\n */\n getBlock(element) {\n\n let nodes = this._blocks.nodes,\n index = nodes.indexOf(element);\n\n if (index >= 0) {\n\n return this._blocks[index];\n\n }\n\n }\n\n /**\n * Get current Block instance\n *\n * @return {Block}\n */\n get currentBlock() {\n\n return this._blocks[this._currentBloсkIndex];\n\n }\n\n /**\n * Get working html element\n *\n * @return {HTMLElement}\n */\n get currentNode() {\n\n return this._blocks.nodes[this._currentBloсkIndex];\n\n }\n\n /**\n * Set _currentBlockIndex to passed block\n *\n * @todo get first level block before searching\n *\n * @param {HTMLElement} element\n */\n set currentNode(element) {\n\n let nodes = this._blocks.nodes;\n\n this._currentBloсkIndex = nodes.indexOf(element);\n\n }\n\n /**\n * Get array of Block instances\n *\n * @returns {Block[]} {@link Blocks#array}\n */\n get blocks() {\n\n return this._blocks.array;\n\n }\n\n};\n\n/**\n * @class Blocks\n * @classdesc Class to work with Block instances array\n *\n * @private\n *\n * @property {HTMLElement} workingArea — editor`s working node\n *\n */\nclass Blocks {\n\n /**\n * @constructor\n *\n * @param {HTMLElement} workingArea — editor`s working node\n */\n constructor(workingArea) {\n\n this._blocks = [];\n this.workingArea = workingArea;\n\n }\n\n /**\n * Push back new Block\n *\n * @param {Block} block\n */\n push(block) {\n\n this._blocks.push(block);\n this.workingArea.appendChild(block.html);\n\n }\n\n /**\n * Insert new Block at passed index\n *\n * @param {Number} index — index to insert Block\n * @param {Block} block — Block to insert\n */\n insert(index, block) {\n\n if (!this.length) {\n\n this.push(block);\n return;\n\n }\n\n if (index > this.length) {\n\n // @todo decide how to handle this case\n return;\n\n }\n\n this._blocks[index] = block;\n\n if (index > 0) {\n\n let previousBlock = this._blocks[index - 1];\n\n previousBlock.html.insertAdjacentElement('afterend', block.html);\n\n } else {\n\n let nextBlock = this._blocks[index + 1];\n\n nextBlock.html.insertAdjacentElement('beforebegin', block.html);\n\n }\n\n }\n\n /**\n * Insert Block after passed target\n *\n * @todo decide if this method is necessary\n *\n * @param {Block} targetBlock — target after wich Block should be inserted\n * @param {Block} newBlock — Block to insert\n */\n insertAfter(targetBlock, newBlock) {\n\n let index = this._blocks.indexOf(targetBlock);\n\n this.insert(index + 1, newBlock);\n\n }\n\n /**\n * Get Block by index\n *\n * @param {Number} index — Block index\n * @returns {Block}\n */\n get(index) {\n\n return this._blocks[index];\n\n }\n\n /**\n * Return index of passed Block\n *\n * @param {Block} block\n * @returns {Number}\n */\n indexOf(block) {\n\n return this._blocks.indexOf(block);\n\n }\n\n /**\n * Get length of Block instances array\n *\n * @returns {Number}\n */\n get length() {\n\n return this._blocks.length;\n\n }\n\n /**\n * Get Block instances array\n *\n * @returns {Block[]}\n */\n get array() {\n\n return this._blocks;\n\n }\n\n /**\n * Get blocks html elements array\n *\n * @returns {HTMLElement[]}\n */\n get nodes() {\n\n return Util.array(this.workingArea.children);\n\n }\n\n /**\n * Proxy trap to implement array-like setter\n *\n * @example\n * blocks[0] = new Block(...)\n *\n * @param {Blocks} instance — Blocks instance\n * @param {Number|String} index — block index\n * @param {Block} block — Block to set\n * @returns {Boolean}\n */\n static set(instance, index, block) {\n\n if (isNaN(Number(index))) {\n\n return false;\n\n }\n\n instance.insert(index, block);\n\n return true;\n\n }\n\n /**\n * Proxy trap to implement array-like getter\n *\n * @param {Blocks} instance — Blocks instance\n * @param {Number|String} index — Block index\n * @returns {Block|*}\n */\n static get(instance, index) {\n\n if (isNaN(Number(index))) {\n\n return instance[index];\n\n }\n\n return instance.get(index);\n\n }\n\n}\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/blockManager.js","/**\n *\n * @class Block\n * @classdesc This class describes editor`s block, including block`s HTMLElement, data and tool\n *\n * @property {Tool} tool — current block tool (Paragraph, for example)\n * @property {Object} CSS — block`s css classes\n *\n */\n\n\nimport $ from './dom';\n\nexport default class Block {\n\n /**\n * @constructor\n *\n * @param {Object} tool — current block plugin`s instance\n */\n constructor(tool) {\n\n this.tool = tool;\n\n this.CSS = {\n wrapper: 'ce-block',\n content: 'ce-block__content'\n };\n\n this._html = this.compose();\n\n }\n\n /**\n * Make default block wrappers and put tool`s content there\n *\n * @returns {HTMLDivElement}\n * @private\n */\n compose() {\n\n let wrapper = $.make('div', this.CSS.wrapper),\n content = $.make('div', this.CSS.content);\n\n content.appendChild(this.tool.html);\n wrapper.appendChild(content);\n\n return wrapper;\n\n }\n\n /**\n * Get block`s HTML\n *\n * @returns {HTMLDivElement}\n */\n get html() {\n\n return this._html;\n\n }\n\n}\n\n\n// WEBPACK FOOTER //\n// ./src/components/block.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 */\nmodule.exports = class Events {\n\n /**\n * Module key name\n * @returns {string}\n */\n static get name() {\n\n return 'Events';\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 * @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\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/eventDispatcher.js","/**\n * Codex Editor Renderer Module\n *\n * @author Codex Team\n * @version 1.0\n */\n\nimport Util from '../util';\n\nmodule.exports = class Renderer {\n\n /**\n * @constructor\n *\n * @param {EditorConfig} config\n */\n constructor(config) {\n\n this.config = config;\n this.Editor = null;\n\n }\n\n /**\n * Editor modules setter\n *\n * @param {Object} Editor\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n *\n * Make plugin blocks from array of plugin`s data\n *\n * @param {Object[]} items\n */\n render(items) {\n\n let chainData = [];\n\n for (let i = 0; i < items.length; i++) {\n\n chainData.push({\n function: () => this.makeBlock(items[i])\n });\n\n }\n\n Util.sequence(chainData);\n\n }\n\n /**\n * Get plugin instance\n * Add plugin instance to BlockManager\n * Insert block to working zone\n *\n * @param {Object} item\n * @returns {Promise.}\n * @private\n */\n makeBlock(item) {\n\n let tool = item.type,\n data = item.data;\n\n this.Editor.BlockManager.insert(tool, data);\n\n return Promise.resolve();\n\n }\n\n};\n\n// module.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 Promise -> 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 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 * Make array from array-like collection\n *\n * @param {*} collection\n *\n * @return {Array}\n */\n static array(collection) {\n\n return Array.prototype.slice.call(collection);\n\n }\n\n};\n\n\n// WEBPACK FOOTER //\n// ./src/components/util.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 static get name() {\n\n return 'Toolbar';\n\n }\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 * 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 case 'createLink' : editor.toolbar.inline.createLinkAction(event, type); break;\n default : editor.toolbar.inline.defaultToolAction(type); break;\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 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 * 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 * @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 * @todo update according to current API\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\nmodule.exports = class Tools {\n\n static get name() {\n\n return 'Tools';\n\n }\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 * Return tool`a instance\n *\n * @param {String} tool — tool name\n * @param {Object} data — initial data\n *\n * @todo throw exceptions if tool doesnt exist\n *\n */\n construct(tool, data) {\n\n let plugin = this.toolClasses[tool],\n config = this.config.toolsConfig[tool];\n\n let instance = new plugin(data, config);\n\n return instance;\n\n }\n\n};\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 */\nmodule.exports = class UI {\n\n /**\n * Module key name\n * @returns {string}\n */\n static get name() {\n\n return 'ui';\n\n }\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 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};\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"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap e205e19e81db7792f3c8","webpack:///./src/components/dom.js","webpack:///./src/components/util.js","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/_sanitizer.js","webpack:///./src/components/modules/_saver.js","webpack:///./src/components/modules/_transport.js","webpack:///./src/components/modules/blockManager.js","webpack:///./src/components/modules/events.js","webpack:///./src/components/modules/renderer.js","webpack:///./src/components/modules/toolbar.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/block.js","webpack:///./src/styles/main.css","webpack:///./node_modules/css-loader/lib/css-base.js"],"names":["Dom","tagName","classNames","attributes","el","document","createElement","Array","isArray","classList","add","attrName","parent","elements","forEach","appendChild","selector","querySelector","querySelectorAll","node","nodeType","Node","ELEMENT_NODE","module","exports","chains","success","fallback","Promise","resolve","reduce","previousValue","currentValue","iteration","then","waitNextBlock","length","chainData","function","data","catch","collection","prototype","slice","call","inline","editor","codex","buttonsOpened","actionsOpened","wrappersOffset","storedSelection","show","currentNode","content","tool","dataset","plugin","tools","showInlineToolbar","selectedText","getSelectionText","toolbar","nodes","inlineToolbar","wrapper","move","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","hightlight","offset","getOffset","_x","_y","isNaN","offsetLeft","offsetTop","clientLeft","clientTop","offsetParent","sel","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","focus","listeners","dataType","contains","execCommand","url","containerEl","preSelectionRange","start","selectNodeContents","setEnd","startContainer","startOffset","end","savedSel","charIndex","setStart","nodeStack","foundStart","stop","nextCharIndex","pop","i","push","removeAllRanges","addRange","queryCommandState","setButtonHighlighted","removeButtonsHighLight","tag","anchorNode","parentNode","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","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","config","Editor","CSS","highlighted","_currentNode","_currentIndex","pluginHTML","isStretched","make","blockContent","toolId","isNode","newBlock","composeBlock_","insertAdjacentElement","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","all","isCapture","addEventListener","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","clear","parser","insertPastedContent","blockType","text","isFirstLevelBlock","TAG","BLOCK_CLASSNAME","paste","patterns","prepare","renderOnPastePatterns","pattern","pasted","clipBoardData","clipboardData","getData","analize","execArray","regex","exec","match","pasteToNewBlock_","blockPasteCallback","needsToHandlePasteEvent","htmlData","plainData","paragraphs","cleanData","wrappedData","sanitizer","clean","wrapTextWithParagraphs","emulateUserAgentBehaviour","insertPastedParagraphs","editableParent","getEditableParent","paragraph","newNode","childElementCount","createDocumentFragment","cloneNode","janitor","require","isEmpty","Config","CUSTOM","BASIC","tags","p","a","href","rel","init_","userCustomConfig","configuration","dirtyString","customConfig","janitorInstance","saver","save","html","jsonOutput","saveBlocks","blocks","getBlockData","makeOutput","saveBlockData","validateBlockData","pluginName","pluginsContent","inputPosition","available","items","validate","savedData","filter","Date","version","transport","currentRequest","arguments","fileSelected","clearInput","files","formData","FormData","multiple","append","name","ajax","beforeSend","error","progress","selectAndUpload","args","setAttribute","accept","click","abort","BlockManager","_blocks","_currentBlockIndex","Blocks","UI","Proxy","toolName","toolInstance","Tools","construct","array","workingArea","previousBlock","nextBlock","targetBlock","insert","children","instance","Number","Events","subscribers","eventName","previousData","currentHandler","newData","Renderer","makeBlock","sequence","item","Toolbar","settingsToggler","removeBlockButton","defaultSettings","makeBlockSettingsPanel","defaultToolbarHeight","hideToolbar","showSettingsButton","newYCoordinate","util","toolsAvailable","toolsUnavailable","iconClassName","toolClasses","hasOwnProperty","reject","sequenceData","getListOfPrepareFunctions","toolPreparationList","toolClass","toolInstances","toolsConfig","editorWrapper","editorZone","getElementById","holderId","Error","loadStyles","console","styles","head","modules","editorModules","moduleInstances","init","constructModules","configureModules","Module","displayName","getModulesDiff","diff","moduleName","prepareDecorator","placeholder","b","Block","_html","compose"],"mappings":"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QAArB,CAA8B1L,WAA9B,CAA0CwW,QAA1C;AAEH;;AAED;;;AAGA,iBAAKlU,WAAL,GAAmBkU,QAAnB;;AAEA,mBAAOA,SAAS/T,OAAT,CAAiB6T,MAAxB;AAEH;AAnKL;AAAA;AAAA,0BAsCcT,MAtCd,EAsCsB;;AAEd,iBAAKA,MAAL,GAAcA,MAAd;AAEH;;AAED;;;;;;AA5CJ;AAAA;AAAA,4BAiDsB;;AAEd,mBAAO,KAAKG,YAAZ;AAEH;;AAED;;;;;AAvDJ;AAAA,0BA4DoB5V,IA5DpB,EA4D0B;;AAElB,gBAAI6R,kBAAkB,KAAKE,kBAAL,CAAwB/R,IAAxB,CAAtB;;AAEA,iBAAK4V,YAAL,GAAoB/D,eAApB;AAEH;AAlEL;;AAAA;AAAA;;AAuKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;;;;;;;;;;;AC58BA;;;;;;;AAOAzR,OAAOC,OAAP,GAAiB,UAAUkW,SAAV,EAAqB;;AAElC,QAAI5U,SAASC,MAAMD,MAAnB;;AAEA4U,cAAUC,WAAV,GAAwB,YAAY;;AAEhC7U,eAAOiB,KAAP,CAAaE,OAAb,CAAqBI,MAArB;AACAvB,eAAOiB,KAAP,CAAa6T,aAAb,CAA2BvT,MAA3B;AAEH,KALD;;AAOAqT,cAAUG,cAAV,GAA2B,YAAY;;AAEnC,aAAK,IAAItU,IAAT,IAAiBT,OAAOY,KAAxB,EAA+B;;AAE3B,gBAAI,OAAOZ,OAAOY,KAAP,CAAaH,IAAb,EAAmBuU,OAA1B,KAAsC,UAA1C,EAAsD;;AAElDhV,uBAAOY,KAAP,CAAaH,IAAb,EAAmBuU,O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CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;;;;;;;;;qjBCnRA;;;;;AAGA;;;;;;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAkDMI,O;;AAEF;;;AAGA,qBAAc;AAAA;;AAEV,SAAKxM,MAAL,GAAc,IAAd;;AAEA,SAAK7S,KAAL,GAAa;AACTE,eAAU,IADD;AAETX,eAAU,IAFD;AAGTqE,eAAU,IAHD;;AAKT;AACAmF,kBAAa,IANJ;AAOTR,eAAU,IAPD;;AAST;AACA+W,uBAAkB,IAVT;AAWTC,yBAAmB,IAXV;AAYTtY,gBAAU,IAZD;;AAcT;AACAO,sBAAgB,IAfP;AAgBTgY,uBAAiB;AAhBR,KAAb;;AAmBA,SAAK1M,GAAL,GAAW;AACP/S,eAAS,YADF;AAEPR,eAAS,qBAFF;AAGPqE,eAAS,qBAHF;;AAKP;AACA2E,eAAS,qBANF;AAOPQ,kBAA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EA;;;AAGA,cAAK4N,UAAL;;AAEAljB;AAEH,OApCM;;AAsCP;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAnDO,OAqDFW,KArDE,CAqDI,aAAK;;AAERwiB,gBAAQjE,KAAR,CAAc/R,CAAd;;AAEJ;AAEC,OA3DE,CAAP;AA6DH;;;iCAEY;;AAET;;;AAGA,UAAIiW,SAAS,mBAAAnH,CAAQ,EAAR,CAAb;;AAEA;;;AAGA,UAAInT,MAAM,cAAEwM,IAAF,CAAO,OAAP,EAAgB,IAAhB,EAAsB;AAC5BpL,qBAAakZ,OAAOzd,QAAP;AADe,OAAtB,CAAV;;AAIA;;;AAGA,oBAAEmZ,MAAF,CAAStgB,SAAS6kB,IAAlB,EAAwBva,GAAxB;AAEH;;;sBA/FSiM,M,EAAQ;;AAEd,WAAKA,MAAL,GAAcA,MAAd;AAEH;;;;;;;;;AA+FLrV,OAAOC,OAAP,GAAiBmgB,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,IAAIwD,UAAU,6EAAAC,CAAcxL,GAAd,CAAmB,kBAAU;;AAEvC,WAAO,4BAAQ,GAA0BrY,MAAlC,CAAP;AAEH,CAJa,CAAd;;AAMA;;;;;;;;;;AAUAA,OAAOC,OAAP;AAAA;AAAA;;;AAEI;AAFJ,4BAGyB;;AAEjB,mBAAO,OAAP;AAEH;;AAED;;;;;AATJ;;AAaI,yBAAYmV,MAAZ,EAAoB;AAAA;;AAAA;;AAEhB;;;AAGA,aAAKA,MAAL,GAAc,EAAd;;AAEA;;;AAGA,aAAK0O,eAAL,GAAuB,EAAvB;;AAEAzjB,gBAAQC,OAAR,GACKK,IADL,CACU,YAAM;;AAER,kBAAKwc,aAAL,GAAqB/H,MAArB;AAEH,SALL,EAMKzU,IANL,CAMU;AAAA,mBAAM,MAAKojB,IAAL,EAAN;AAAA,SANV,EAOKpjB,IAPL,CAOU;AAAA,mBAAM,MAAK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ACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,U;;;;;;ACtXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;;;;;;AC5DA;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;;;;;;;;;;;;;;qjBCxLD;;;;;;;;;;AAWA;;;;;;;;IAEqBsP,K;;AAEjB;;;;;AAKA,mBAAY1iB,IAAZ,EAAkB;AAAA;;AAEd,aAAKA,IAAL,GAAYA,IAAZ;;AAEA,aAAKsT,GAAL,GAAW;AACP5S,qBAAS,UADF;AAEPX,qBAAS;AAFF,SAAX;;AAKA,aAAK4iB,KAAL,GAAa,KAAKC,OAAL,EAAb;AAEH;;AAED;;;;;;;;;;kCAMU;;AAEN,gBAAIliB,UAAU,cAAEkT,IAAF,CAAO,KAAP,EAAc,KAAKN,GAAL,CAAS5S,OAAvB,CAAd;AAAA,gBACIX,UAAU,cAAE6T,IAAF,CAAO,KAAP,EAAc,KAAKN,GAAL,CAASvT,OAAvB,CADd;;AAGAA,oBAAQvC,WAAR,CAAoB,KAAKwC,IAAL,CAAUyb,IAA9B;AACA/a,oBAAQlD,WAAR,CAAoBuC,OAApB;;AAEA,mBAAOW,OAAP;AAEH;;AAED;;;;;;;;4BAKW;;AAEP,mBAAO,KAAKiiB,KAAZ;AAEH;;;;;;;kBA/CgBD,K;;;;;;ACbrB;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 = 24);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap e205e19e81db7792f3c8","/**\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 = null, 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 static isNode(node) {\n\n return node && typeof node === 'object' && node.nodeType && node.nodeType === Node.ELEMENT_NODE;\n\n }\n\n};\n\n\n// WEBPACK FOOTER //\n// ./src/components/dom.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} success\n * @param {Function} fallback\n *\n * @return {Promise}\n */\n function waitNextBlock(chainData, success, fallback) {\n\n return new Promise(function (resolve) {\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 * Make array from array-like collection\n *\n * @param {*} collection\n *\n * @return {Array}\n */\n static array(collection) {\n\n return Array.prototype.slice.call(collection);\n\n }\n\n};\n\n\n// WEBPACK FOOTER //\n// ./src/components/util.js","/**\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 * @class Content\n * @classdesc Class works provides COdex Editor appearance logic\n *\n * @author Codex Team\n * @version 2.0.0\n */\n\nimport $ from '../dom';\n\nmodule.exports = class Content {\n\n /**\n * Module key name\n * @returns {string}\n */\n static get name() {\n\n return 'Content';\n\n }\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.CSS = {\n block: 'ce-block',\n content: 'ce-block__content',\n stretched: 'ce-block--stretched',\n highlighted: 'ce-block--highlighted',\n };\n\n this._currentNode = null;\n this._currentIndex = 0;\n\n }\n\n /**\n * Editor modules setter\n * @param {object} Editor\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * Get current working node\n *\n * @returns {null|HTMLElement}\n */\n get currentNode() {\n\n return this._currentNode;\n\n }\n\n /**\n * Set working node. Working node should be first level block, so we find it before set one to _currentNode property\n *\n * @param {HTMLElement} node\n */\n set currentNode(node) {\n\n let firstLevelBlock = this.getFirstLevelBlock(node);\n\n this._currentNode = firstLevelBlock;\n\n }\n\n\n /**\n * @private\n * @param pluginHTML\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 composeBlock_(pluginHTML, isStretched = false) {\n\n let block = $.make('DIV', this.CSS.block),\n blockContent = $.make('DIV', this.CSS.content);\n\n blockContent.appendChild(pluginHTML);\n block.appendChild(blockContent);\n\n if (isStretched) {\n\n blockContent.classList.add(this.CSS.stretched);\n\n }\n\n block.dataset.toolId = this._currentIndex++;\n\n return block;\n\n };\n\n /**\n * Finds first-level block\n * @description looks for first-level block.\n * gets parent while node is not first-level\n *\n * @param {Element} node - selected or clicked in redactors area node\n * @protected\n *\n */\n getFirstLevelBlock(node) {\n\n if (!$.isNode(node)) {\n\n node = node.parentNode;\n\n }\n\n if (node === this.Editor.ui.nodes.redactor || node === document.body) {\n\n return null;\n\n } else {\n\n while(node.classList && !node.classList.contains(this.CSS.block)) {\n\n node = node.parentNode;\n\n }\n\n return node;\n\n }\n\n };\n\n /**\n * Insert new block to working area\n *\n * @param {HTMLElement} tool\n *\n * @returns {Number} tool index\n *\n */\n insertBlock(tool) {\n\n let newBlock = this.composeBlock_(tool);\n\n if (this.currentNode) {\n\n this.currentNode.insertAdjacentElement('afterend', newBlock);\n\n } else {\n\n /**\n * If redactor is empty, append as first child\n */\n this.Editor.ui.nodes.redactor.appendChild(newBlock);\n\n }\n\n /**\n * Set new node as current\n */\n this.currentNode = newBlock;\n\n return newBlock.dataset.toolId;\n\n }\n\n};\n\n// module.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 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 * @class BlockManager\n * @classdesc Manage editor`s blocks storage and appearance\n */\n\nimport Block from '../block';\nimport Util from '../util';\n\nclass BlockManager {\n\n /**\n * @constructor\n *\n * @param {EditorConfig} config\n */\n constructor({ config }) {\n\n this.config = config;\n this.Editor = null;\n this._blocks = null;\n this._currentBlockIndex = -1;\n\n }\n\n /**\n * Editor modules setting\n *\n * @param Editor\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * Should be called after Editor.UI preparation\n * Define this._blocks property\n *\n * @returns {Promise}\n */\n prepare() {\n\n return new Promise(resolve => {\n\n let blocks = new Blocks(this.Editor.UI.nodes.redactor);\n\n /**\n * We need to use Proxy to overload set/get [] operator.\n * So we can use array-like syntax to access blocks\n *\n * @example\n * this._blocks[0] = new Block(...);\n *\n * block = this._blocks[0];\n *\n * @todo proxy the enumerate method\n *\n * @type {Proxy}\n * @private\n */\n this._blocks = new Proxy(blocks, {\n set: Blocks.set,\n get: Blocks.get\n });\n\n resolve();\n\n });\n\n }\n\n /**\n * Insert new block into _blocks\n *\n * @param {String} toolName — plugin name\n * @param {Object} data — plugin data\n */\n insert(toolName, data) {\n\n let toolInstance = this.Editor.Tools.construct(toolName, data),\n block = new Block(toolInstance);\n\n this._blocks[++this._currentBlockIndex] = block;\n\n }\n\n /**\n * Get Block instance by html element\n *\n * @todo get first level block before searching\n *\n * @param {HTMLElement} element\n * @returns {Block}\n */\n getBlock(element) {\n\n let nodes = this._blocks.nodes,\n index = nodes.indexOf(element);\n\n if (index >= 0) {\n\n return this._blocks[index];\n\n }\n\n }\n\n /**\n * Get current Block instance\n *\n * @return {Block}\n */\n get currentBlock() {\n\n return this._blocks[this._currentBlockIndex];\n\n }\n\n /**\n * Get working html element\n *\n * @return {HTMLElement}\n */\n get currentNode() {\n\n return this._blocks.nodes[this._currentBlockIndex];\n\n }\n\n /**\n * Set _currentBlockIndex to passed block\n *\n * @todo get first level block before searching\n *\n * @param {HTMLElement} element\n */\n set currentNode(element) {\n\n let nodes = this._blocks.nodes;\n\n this._currentBlockIndex = nodes.indexOf(element);\n\n }\n\n /**\n * Get array of Block instances\n *\n * @returns {Block[]} {@link Blocks#array}\n */\n get blocks() {\n\n return this._blocks.array;\n\n }\n\n};\n\n/**\n * @class Blocks\n * @classdesc Class to work with Block instances array\n *\n * @private\n *\n * @property {HTMLElement} workingArea — editor`s working node\n *\n */\nclass Blocks {\n\n /**\n * @constructor\n *\n * @param {HTMLElement} workingArea — editor`s working node\n */\n constructor(workingArea) {\n\n this._blocks = [];\n this.workingArea = workingArea;\n\n }\n\n /**\n * Push back new Block\n *\n * @param {Block} block\n */\n push(block) {\n\n this._blocks.push(block);\n this.workingArea.appendChild(block.html);\n\n }\n\n /**\n * Insert new Block at passed index\n *\n * @param {Number} index — index to insert Block\n * @param {Block} block — Block to insert\n */\n insert(index, block) {\n\n if (!this.length) {\n\n this.push(block);\n return;\n\n }\n\n if (index > this.length) {\n\n // @todo decide how to handle this case\n return;\n\n }\n\n this._blocks[index] = block;\n\n if (index > 0) {\n\n let previousBlock = this._blocks[index - 1];\n\n previousBlock.html.insertAdjacentElement('afterend', block.html);\n\n } else {\n\n let nextBlock = this._blocks[index + 1];\n\n nextBlock.html.insertAdjacentElement('beforebegin', block.html);\n\n }\n\n }\n\n /**\n * Insert Block after passed target\n *\n * @todo decide if this method is necessary\n *\n * @param {Block} targetBlock — target after wich Block should be inserted\n * @param {Block} newBlock — Block to insert\n */\n insertAfter(targetBlock, newBlock) {\n\n let index = this._blocks.indexOf(targetBlock);\n\n this.insert(index + 1, newBlock);\n\n }\n\n /**\n * Get Block by index\n *\n * @param {Number} index — Block index\n * @returns {Block}\n */\n get(index) {\n\n return this._blocks[index];\n\n }\n\n /**\n * Return index of passed Block\n *\n * @param {Block} block\n * @returns {Number}\n */\n indexOf(block) {\n\n return this._blocks.indexOf(block);\n\n }\n\n /**\n * Get length of Block instances array\n *\n * @returns {Number}\n */\n get length() {\n\n return this._blocks.length;\n\n }\n\n /**\n * Get Block instances array\n *\n * @returns {Block[]}\n */\n get array() {\n\n return this._blocks;\n\n }\n\n /**\n * Get blocks html elements array\n *\n * @returns {HTMLElement[]}\n */\n get nodes() {\n\n return Util.array(this.workingArea.children);\n\n }\n\n /**\n * Proxy trap to implement array-like setter\n *\n * @example\n * blocks[0] = new Block(...)\n *\n * @param {Blocks} instance — Blocks instance\n * @param {Number|String} index — block index\n * @param {Block} block — Block to set\n * @returns {Boolean}\n */\n static set(instance, index, block) {\n\n if (isNaN(Number(index))) {\n\n return false;\n\n }\n\n instance.insert(index, block);\n\n return true;\n\n }\n\n /**\n * Proxy trap to implement array-like getter\n *\n * @param {Blocks} instance — Blocks instance\n * @param {Number|String} index — Block index\n * @returns {Block|*}\n */\n static get(instance, index) {\n\n if (isNaN(Number(index))) {\n\n return instance[index];\n\n }\n\n return instance.get(index);\n\n }\n\n}\n\nmodule.exports = BlockManager;\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/blockManager.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 * Codex Editor Renderer Module\n *\n * @author Codex Team\n * @version 1.0\n */\n\nimport Util from '../util';\n\nclass Renderer {\n\n /**\n * @constructor\n *\n * @param {EditorConfig} config\n */\n constructor(config) {\n\n this.config = config;\n this.Editor = null;\n\n }\n\n /**\n * Editor modules setter\n *\n * @param {Object} Editor\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n *\n * Make plugin blocks from array of plugin`s data\n *\n * @param {Object[]} items\n */\n render(items) {\n\n let chainData = [];\n\n for (let i = 0; i < items.length; i++) {\n\n chainData.push({\n function: () => this.makeBlock(items[i])\n });\n\n }\n\n Util.sequence(chainData);\n\n }\n\n /**\n * Get plugin instance\n * Add plugin instance to BlockManager\n * Insert block to working zone\n *\n * @param {Object} item\n * @returns {Promise.}\n * @private\n */\n makeBlock(item) {\n\n let tool = item.type,\n data = item.data;\n\n this.Editor.BlockManager.insert(tool, data);\n\n return Promise.resolve();\n\n }\n\n}\n\nmodule.exports = Renderer;\n\n// module.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 Promise -> 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 * 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 * 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 * @todo update according to current API\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 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 * Return tool`a instance\n *\n * @param {String} tool — tool name\n * @param {Object} data — initial data\n *\n * @todo throw exceptions if tool doesnt exist\n *\n */\n construct(tool, data) {\n\n let plugin = this.toolClasses[tool],\n config = this.config.toolsConfig[tool];\n\n let instance = new plugin(data, config);\n\n return instance;\n\n }\n\n}\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 .then(prepareDecorator(this.moduleInstances.BlockManager))\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\": 5,\n\t\"./_anchors.js\": 5,\n\t\"./_callbacks\": 6,\n\t\"./_callbacks.js\": 6,\n\t\"./_caret\": 7,\n\t\"./_caret.js\": 7,\n\t\"./_content\": 8,\n\t\"./_content.js\": 8,\n\t\"./_destroyer\": 9,\n\t\"./_destroyer.js\": 9,\n\t\"./_listeners\": 10,\n\t\"./_listeners.js\": 10,\n\t\"./_notifications\": 11,\n\t\"./_notifications.js\": 11,\n\t\"./_parser\": 12,\n\t\"./_parser.js\": 12,\n\t\"./_paste\": 13,\n\t\"./_paste.js\": 13,\n\t\"./_sanitizer\": 14,\n\t\"./_sanitizer.js\": 14,\n\t\"./_saver\": 15,\n\t\"./_saver.js\": 15,\n\t\"./_transport\": 16,\n\t\"./_transport.js\": 16,\n\t\"./blockManager\": 17,\n\t\"./blockManager.js\": 17,\n\t\"./events\": 18,\n\t\"./events.js\": 18,\n\t\"./renderer\": 19,\n\t\"./renderer.js\": 19,\n\t\"./toolbar\": 20,\n\t\"./toolbar.js\": 20,\n\t\"./toolbar/inline\": 2,\n\t\"./toolbar/inline.js\": 2,\n\t\"./toolbar/settings\": 3,\n\t\"./toolbar/settings.js\": 3,\n\t\"./toolbar/toolbar\": 21,\n\t\"./toolbar/toolbar.js\": 21,\n\t\"./toolbar/toolbox\": 4,\n\t\"./toolbar/toolbox.js\": 4,\n\t\"./tools\": 22,\n\t\"./tools.js\": 22,\n\t\"./ui\": 23,\n\t\"./ui.js\": 23\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 = 25;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/modules ^\\.\\/.*$\n// module id = 25\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 = 26\n// module chunks = 0","/**\n *\n * @class Block\n * @classdesc This class describes editor`s block, including block`s HTMLElement, data and tool\n *\n * @property {Tool} tool — current block tool (Paragraph, for example)\n * @property {Object} CSS — block`s css classes\n *\n */\n\n\nimport $ from './dom';\n\nexport default class Block {\n\n /**\n * @constructor\n *\n * @param {Object} tool — current block plugin`s instance\n */\n constructor(tool) {\n\n this.tool = tool;\n\n this.CSS = {\n wrapper: 'ce-block',\n content: 'ce-block__content'\n };\n\n this._html = this.compose();\n\n }\n\n /**\n * Make default block wrappers and put tool`s content there\n *\n * @returns {HTMLDivElement}\n * @private\n */\n compose() {\n\n let wrapper = $.make('div', this.CSS.wrapper),\n content = $.make('div', this.CSS.content);\n\n content.appendChild(this.tool.html);\n wrapper.appendChild(content);\n\n return wrapper;\n\n }\n\n /**\n * Get block`s HTML\n *\n * @returns {HTMLDivElement}\n */\n get html() {\n\n return this._html;\n\n }\n\n}\n\n\n// WEBPACK FOOTER //\n// ./src/components/block.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 = 28\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 = 29\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file diff --git a/codex-editor.js b/codex-editor.js deleted file mode 100644 index 5bcce768..00000000 --- a/codex-editor.js +++ /dev/null @@ -1,5853 +0,0 @@ -var CodexEditor = -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) -/******/ return installedModules[moduleId].exports; -/******/ -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ exports: {}, -/******/ id: moduleId, -/******/ loaded: false -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.loaded = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - - /** - * Codex Editor - * - * - * - * - * @author CodeX Team - */ - - /** - * @typedef {CodexEditor} CodexEditor - editor class - */ - - /** - * @typedef {Object} EditorConfig - * @property {String} holderId - Element to append Editor - * ... - */ - - 'use strict'; - - /** - * Require Editor modules places in components/modules dir - */ - - 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 = editorModules.map(function (module) { - - return __webpack_require__(1)("./" + 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 { - - _this2.moduleInstances[Module.name] = 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 modules = {}; - - for (var moduleName in this.moduleInstances) { - - /** - * Skip module with passed name - */ - if (moduleName == name) { - - continue; - } - modules[moduleName] = this.moduleInstances[moduleName]; - } - - return modules; - } - - /** - * 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; - } - - /** - * 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; - // - // })({}); - -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - - var map = { - "./_anchors": 2, - "./_anchors.js": 2, - "./_callbacks": 3, - "./_callbacks.js": 3, - "./_caret": 4, - "./_caret.js": 4, - "./_content": 5, - "./_content.js": 5, - "./_destroyer": 6, - "./_destroyer.js": 6, - "./_listeners": 7, - "./_listeners.js": 7, - "./_notifications": 8, - "./_notifications.js": 8, - "./_parser": 9, - "./_parser.js": 9, - "./_paste": 10, - "./_paste.js": 10, - "./_renderer": 11, - "./_renderer.js": 11, - "./_sanitizer": 12, - "./_sanitizer.js": 12, - "./_saver": 14, - "./_saver.js": 14, - "./_transport": 15, - "./_transport.js": 15, - "./eventDispatcher": 16, - "./eventDispatcher.js": 16, - "./toolbar/inline": 17, - "./toolbar/inline.js": 17, - "./toolbar/settings": 18, - "./toolbar/settings.js": 18, - "./toolbar/toolbar": 19, - "./toolbar/toolbar.js": 19, - "./toolbar/toolbox": 20, - "./toolbar/toolbox.js": 20, - "./tools": 21, - "./tools.js": 21, - "./ui": 22, - "./ui.js": 22 - }; - function webpackContext(req) { - return __webpack_require__(webpackContextResolve(req)); - }; - function webpackContextResolve(req) { - return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }()); - }; - webpackContext.keys = function webpackContextKeys() { - return Object.keys(map); - }; - webpackContext.resolve = webpackContextResolve; - module.exports = webpackContext; - webpackContext.id = 1; - - -/***/ }), -/* 2 */ -/***/ (function(module, exports) { - - '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; - }({}); - -/***/ }), -/* 3 */ -/***/ (function(module, exports) { - - '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; - }({}); - -/***/ }), -/* 4 */ -/***/ (function(module, exports) { - - '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; - }({}); - -/***/ }), -/* 5 */ -/***/ (function(module, exports) { - - '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; - }({}); - -/***/ }), -/* 6 */ -/***/ (function(module, exports) { - - '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; - }({}); - -/***/ }), -/* 7 */ -/***/ (function(module, exports) { - - "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; - }({}); - -/***/ }), -/* 8 */ -/***/ (function(module, exports) { - - '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; - }({}); - -/***/ }), -/* 9 */ -/***/ (function(module, exports) { - - "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; - }({}); - -/***/ }), -/* 10 */ -/***/ (function(module, exports) { - - '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; - }({}); - -/***/ }), -/* 11 */ -/***/ (function(module, exports) { - - '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; - }({}); - -/***/ }), -/* 12 */ -/***/ (function(module, exports, __webpack_require__) { - - 'use strict'; - - /** - * Codex Sanitizer - */ - - module.exports = function (sanitizer) { - - /** HTML Janitor library */ - var janitor = __webpack_require__(13); - - /** 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; - }({}); - -/***/ }), -/* 13 */ -/***/ (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; - - })); - - -/***/ }), -/* 14 */ -/***/ (function(module, exports) { - - '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) { - - '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) { - - "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.exports = function () { - function Events() { - _classCallCheck(this, Events); - - this.subscribers = {}; - } - - _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); - } - }, { - key: "emit", - value: function emit(eventName, data) { - - this.subscribers[eventName].reduce(function (previousData, currentHandler) { - - var newData = currentHandler(previousData); - - return newData ? newData : previousData; - }, data); - } - }]); - - return Events; - }(); - -/***/ }), -/* 17 */ -/***/ (function(module, exports) { - - 'use strict'; - - /** - * Inline toolbar - * - * Contains from tools: - * Bold, Italic, Underline and Anchor - * - * @author Codex Team - * @version 1.0 - */ - - module.exports = function (inline) { - - var editor = codex.editor; - - inline.buttonsOpened = null; - inline.actionsOpened = null; - inline.wrappersOffset = null; - - /** - * saving selection that need for execCommand for styling - * - */ - inline.storedSelection = null; - - /** - * @protected - * - * Open inline toobar - */ - inline.show = function () { - - var currentNode = editor.content.currentNode, - tool = currentNode.dataset.tool, - plugin; - - /** - * tool allowed to open inline toolbar - */ - plugin = editor.tools[tool]; - - if (!plugin.showInlineToolbar) return; - - var selectedText = inline.getSelectionText(), - toolbar = editor.nodes.inlineToolbar.wrapper; - - if (selectedText.length > 0) { - - /** Move toolbar and open */ - editor.toolbar.inline.move(); - - /** Open inline toolbar */ - toolbar.classList.add('opened'); - - /** show buttons of inline toolbar */ - editor.toolbar.inline.showButtons(); - } - }; - - /** - * @protected - * - * Closes inline toolbar - */ - inline.close = function () { - - var toolbar = editor.nodes.inlineToolbar.wrapper; - - toolbar.classList.remove('opened'); - }; - - /** - * @private - * - * Moving toolbar - */ - inline.move = function () { - - if (!this.wrappersOffset) { - - this.wrappersOffset = this.getWrappersOffset(); - } - - var coords = this.getSelectionCoords(), - defaultOffset = 0, - toolbar = editor.nodes.inlineToolbar.wrapper, - newCoordinateX, - newCoordinateY; - - if (toolbar.offsetHeight === 0) { - - defaultOffset = 40; - } - - newCoordinateX = coords.x - this.wrappersOffset.left; - newCoordinateY = coords.y + window.scrollY - this.wrappersOffset.top - defaultOffset - toolbar.offsetHeight; - - toolbar.style.transform = 'translate3D(' + Math.floor(newCoordinateX) + 'px, ' + Math.floor(newCoordinateY) + 'px, 0)'; - - /** Close everything */ - editor.toolbar.inline.closeButtons(); - editor.toolbar.inline.closeAction(); - }; - - /** - * @private - * - * Tool Clicked - */ - - inline.toolClicked = function (event, type) { - - /** - * For simple tools we use default browser function - * For more complicated tools, we should write our own behavior - */ - switch (type) { - case 'createLink': - editor.toolbar.inline.createLinkAction(event, type);break; - default: - editor.toolbar.inline.defaultToolAction(type);break; - } - - /** - * highlight buttons - * after making some action - */ - editor.nodes.inlineToolbar.buttons.childNodes.forEach(editor.toolbar.inline.hightlight); - }; - - /** - * @private - * - * Saving wrappers offset in DOM - */ - inline.getWrappersOffset = function () { - - var wrapper = editor.nodes.wrapper, - offset = this.getOffset(wrapper); - - this.wrappersOffset = offset; - return offset; - }; - - /** - * @private - * - * Calculates offset of DOM element - * - * @param el - * @returns {{top: number, left: number}} - */ - inline.getOffset = function (el) { - - var _x = 0; - var _y = 0; - - while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) { - - _x += el.offsetLeft + el.clientLeft; - _y += el.offsetTop + el.clientTop; - el = el.offsetParent; - } - return { top: _y, left: _x }; - }; - - /** - * @private - * - * Calculates position of selected text - * @returns {{x: number, y: number}} - */ - inline.getSelectionCoords = function () { - - var sel = document.selection, - range; - var x = 0, - y = 0; - - if (sel) { - - if (sel.type != 'Control') { - - range = sel.createRange(); - range.collapse(true); - x = range.boundingLeft; - y = range.boundingTop; - } - } else if (window.getSelection) { - - sel = window.getSelection(); - - if (sel.rangeCount) { - - range = sel.getRangeAt(0).cloneRange(); - if (range.getClientRects) { - - range.collapse(true); - var rect = range.getClientRects()[0]; - - if (!rect) { - - return; - } - - x = rect.left; - y = rect.top; - } - } - } - return { x: x, y: y }; - }; - - /** - * @private - * - * Returns selected text as String - * @returns {string} - */ - inline.getSelectionText = function () { - - var selectedText = ''; - - // all modern browsers and IE9+ - if (window.getSelection) { - - selectedText = window.getSelection().toString(); - } - - return selectedText; - }; - - /** Opens buttons block */ - inline.showButtons = function () { - - var buttons = editor.nodes.inlineToolbar.buttons; - - buttons.classList.add('opened'); - - editor.toolbar.inline.buttonsOpened = true; - - /** highlight buttons */ - editor.nodes.inlineToolbar.buttons.childNodes.forEach(editor.toolbar.inline.hightlight); - }; - - /** Makes buttons disappear */ - inline.closeButtons = function () { - - var buttons = editor.nodes.inlineToolbar.buttons; - - buttons.classList.remove('opened'); - - editor.toolbar.inline.buttonsOpened = false; - }; - - /** Open buttons defined action if exist */ - inline.showActions = function () { - - var action = editor.nodes.inlineToolbar.actions; - - action.classList.add('opened'); - - editor.toolbar.inline.actionsOpened = true; - }; - - /** Close actions block */ - inline.closeAction = function () { - - var action = editor.nodes.inlineToolbar.actions; - - action.innerHTML = ''; - action.classList.remove('opened'); - editor.toolbar.inline.actionsOpened = false; - }; - - /** - * Callback for keydowns in inline toolbar "Insert link..." input - */ - var inlineToolbarAnchorInputKeydown_ = function inlineToolbarAnchorInputKeydown_(event) { - - if (event.keyCode != editor.core.keys.ENTER) { - - return; - } - - var editable = editor.content.currentNode, - storedSelection = editor.toolbar.inline.storedSelection; - - editor.toolbar.inline.restoreSelection(editable, storedSelection); - editor.toolbar.inline.setAnchor(this.value); - - /** - * Preventing events that will be able to happen - */ - event.preventDefault(); - event.stopImmediatePropagation(); - - editor.toolbar.inline.clearRange(); - }; - - /** Action for link creation or for setting anchor */ - inline.createLinkAction = function (event) { - - var isActive = this.isLinkActive(); - - var editable = editor.content.currentNode, - storedSelection = editor.toolbar.inline.saveSelection(editable); - - /** Save globally selection */ - editor.toolbar.inline.storedSelection = storedSelection; - - if (isActive) { - - /** - * Changing stored selection. if we want to remove anchor from word - * we should remove anchor from whole word, not only selected part. - * The solution is than we get the length of current link - * Change start position to - end of selection minus length of anchor - */ - editor.toolbar.inline.restoreSelection(editable, storedSelection); - - editor.toolbar.inline.defaultToolAction('unlink'); - } else { - - /** Create input and close buttons */ - var action = editor.draw.inputForLink(); - - editor.nodes.inlineToolbar.actions.appendChild(action); - - editor.toolbar.inline.closeButtons(); - editor.toolbar.inline.showActions(); - - /** - * focus to input - * Solution: https://developer.mozilla.org/ru/docs/Web/API/HTMLElement/focus - * Prevents event after showing input and when we need to focus an input which is in unexisted form - */ - action.focus(); - event.preventDefault(); - - /** Callback to link action */ - editor.listeners.add(action, 'keydown', inlineToolbarAnchorInputKeydown_, false); - } - }; - - inline.isLinkActive = function () { - - var isActive = false; - - editor.nodes.inlineToolbar.buttons.childNodes.forEach(function (tool) { - - var dataType = tool.dataset.type; - - if (dataType == 'link' && tool.classList.contains('hightlighted')) { - - isActive = true; - } - }); - - return isActive; - }; - - /** default action behavior of tool */ - inline.defaultToolAction = function (type) { - - document.execCommand(type, false, null); - }; - - /** - * @private - * - * Sets URL - * - * @param {String} url - URL - */ - inline.setAnchor = function (url) { - - document.execCommand('createLink', false, url); - - /** Close after URL inserting */ - editor.toolbar.inline.closeAction(); - }; - - /** - * @private - * - * Saves selection - */ - inline.saveSelection = function (containerEl) { - - var range = window.getSelection().getRangeAt(0), - preSelectionRange = range.cloneRange(), - start; - - preSelectionRange.selectNodeContents(containerEl); - preSelectionRange.setEnd(range.startContainer, range.startOffset); - - start = preSelectionRange.toString().length; - - return { - start: start, - end: start + range.toString().length - }; - }; - - /** - * @private - * - * Sets to previous selection (Range) - * - * @param {Element} containerEl - editable element where we restore range - * @param {Object} savedSel - range basic information to restore - */ - inline.restoreSelection = function (containerEl, savedSel) { - - var range = document.createRange(), - charIndex = 0; - - range.setStart(containerEl, 0); - range.collapse(true); - - var nodeStack = [containerEl], - node, - foundStart = false, - stop = false, - nextCharIndex; - - while (!stop && (node = nodeStack.pop())) { - - if (node.nodeType == 3) { - - nextCharIndex = charIndex + node.length; - - if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) { - - range.setStart(node, savedSel.start - charIndex); - foundStart = true; - } - if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) { - - range.setEnd(node, savedSel.end - charIndex); - stop = true; - } - charIndex = nextCharIndex; - } else { - - var i = node.childNodes.length; - - while (i--) { - - nodeStack.push(node.childNodes[i]); - } - } - } - - var sel = window.getSelection(); - - sel.removeAllRanges(); - sel.addRange(range); - }; - - /** - * @private - * - * Removes all ranges from window selection - */ - inline.clearRange = function () { - - var selection = window.getSelection(); - - selection.removeAllRanges(); - }; - - /** - * @private - * - * sets or removes hightlight - */ - inline.hightlight = function (tool) { - - var dataType = tool.dataset.type; - - if (document.queryCommandState(dataType)) { - - editor.toolbar.inline.setButtonHighlighted(tool); - } else { - - editor.toolbar.inline.removeButtonsHighLight(tool); - } - - /** - * - * hightlight for anchors - */ - var selection = window.getSelection(), - tag = selection.anchorNode.parentNode; - - if (tag.tagName == 'A' && dataType == 'link') { - - editor.toolbar.inline.setButtonHighlighted(tool); - } - }; - - /** - * @private - * - * Mark button if text is already executed - */ - inline.setButtonHighlighted = function (button) { - - button.classList.add('hightlighted'); - - /** At link tool we also change icon */ - if (button.dataset.type == 'link') { - - var icon = button.childNodes[0]; - - icon.classList.remove('ce-icon-link'); - icon.classList.add('ce-icon-unlink'); - } - }; - - /** - * @private - * - * Removes hightlight - */ - inline.removeButtonsHighLight = function (button) { - - button.classList.remove('hightlighted'); - - /** At link tool we also change icon */ - if (button.dataset.type == 'link') { - - var icon = button.childNodes[0]; - - icon.classList.remove('ce-icon-unlink'); - icon.classList.add('ce-icon-link'); - } - }; - - return inline; - }({}); - -/***/ }), -/* 18 */ -/***/ (function(module, exports) { - - '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; - }({}); - -/***/ }), -/* 19 */ -/***/ (function(module, exports, __webpack_require__) { - - 'use strict'; - - /** - * Codex Editor toolbar module - * - * Contains: - * - Inline toolbox - * - Toolbox within plus button - * - Settings section - * - * @author Codex Team - * @version 1.0 - */ - - module.exports = function (toolbar) { - - var editor = codex.editor; - - toolbar.settings = __webpack_require__(18); - toolbar.inline = __webpack_require__(17); - toolbar.toolbox = __webpack_require__(20); - - /** - * Margin between focused node and toolbar - */ - toolbar.defaultToolbarHeight = 49; - - toolbar.defaultOffset = 34; - - toolbar.opened = false; - - toolbar.current = null; - - /** - * @protected - */ - toolbar.open = function () { - - if (editor.hideToolbar) { - - return; - } - - var toolType = editor.content.currentNode.dataset.tool; - - if (!editor.tools[toolType] || !editor.tools[toolType].makeSettings) { - - editor.nodes.showSettingsButton.classList.add('hide'); - } else { - - editor.nodes.showSettingsButton.classList.remove('hide'); - } - - editor.nodes.toolbar.classList.add('opened'); - this.opened = true; - }; - - /** - * @protected - */ - toolbar.close = function () { - - editor.nodes.toolbar.classList.remove('opened'); - - toolbar.opened = false; - toolbar.current = null; - - for (var button in editor.nodes.toolbarButtons) { - - editor.nodes.toolbarButtons[button].classList.remove('selected'); - } - - /** Close toolbox when toolbar is not displayed */ - editor.toolbar.toolbox.close(); - editor.toolbar.settings.close(); - }; - - toolbar.toggle = function () { - - if (!this.opened) { - - this.open(); - } else { - - this.close(); - } - }; - - toolbar.hidePlusButton = function () { - - editor.nodes.plusButton.classList.add('hide'); - }; - - toolbar.showPlusButton = function () { - - editor.nodes.plusButton.classList.remove('hide'); - }; - - /** - * Moving toolbar to the specified node - */ - toolbar.move = function () { - - /** Close Toolbox when we move toolbar */ - editor.toolbar.toolbox.close(); - - if (!editor.content.currentNode) { - - return; - } - - var newYCoordinate = editor.content.currentNode.offsetTop - editor.toolbar.defaultToolbarHeight / 2 + editor.toolbar.defaultOffset; - - editor.nodes.toolbar.style.transform = 'translate3D(0, ' + Math.floor(newYCoordinate) + 'px, 0)'; - - /** Close trash actions */ - editor.toolbar.settings.hideRemoveActions(); - }; - - return toolbar; - }({}); - -/***/ }), -/* 20 */ -/***/ (function(module, exports) { - - '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; - }({}); - -/***/ }), -/* 21 */ -/***/ (function(module, exports) { - - '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 Codex Editor Tools Submodule - * - * Creates Instances from Plugins and binds external config to the instances - */ - - /** - * Load user defined tools - * Tools must contain the following important objects: - * - * @typedef {Object} ToolsConfig - * @property {String} iconClassname - this a icon in toolbar - * @property {Boolean} displayInToolbox - will be displayed in toolbox. Default value is TRUE - * @property {Boolean} enableLineBreaks - inserts new block or break lines. Default value is FALSE - */ - - /** - * Class properties: - * - * @property {String} this.name - name of this module - * @property {Array} this.toolInstances - list of tool instances - * - */ - module.exports = function () { - _createClass(Tools, [{ - key: 'state', - - - /** - * @param Editor - * @param Editor.modules {@link CodexEditor#moduleInstances} - * @param Editor.config {@link CodexEditor#configuration} - */ - set: function set(Editor) { - - this.Editor = Editor; - } - - /** - * If config wasn't passed by user - * @return {ToolsConfig} - */ - - }, { - key: 'defaultConfig', - get: function get() { - - return { - iconClassName: 'default-icon', - displayInToolbox: false, - enableLineBreaks: false - }; - } - - /** - * @constructor - * - * @param {ToolsConfig} config - */ - - }], [{ - key: 'name', - get: function get() { - - return 'tools'; - } - }]); - - function Tools(config) { - _classCallCheck(this, Tools); - - this.config = config; - - this.availabPlugins = {}; - this.toolInstances = []; - } - - /** - * Creates instances via passed or default configuration - * @return {boolean} - */ - - - _createClass(Tools, [{ - key: 'prepare', - value: function prepare() { - - var toolConfig = this.defaultConfig; - - if (!this.config.hasOwnProperty('tools')) { - - return false; - } - - /** - * Preparation Decorator - * - * @param toolBindedPreparationFunction - * @return {Promise} - */ - function waitNextToolPreparation(toolBindedPreparationFunction) { - - return new Promise(function (resolve, reject) { - - toolBindedPreparationFunction().then(resolve).catch(function (error) { - - console.log('Plugin is not available because of ', error); - - // anyway, go ahead even plugin is not available - resolve(); - }); - }); - } - - return new Promise(function (resolvePreparation, rejectPreparation) { - - var toolPreparationList = []; - - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - for (var _iterator = this.config.tools[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var tool = _step.value; - - - var toolName = tool.name; - - if (toolName in this.config.toolsConfig) { - - toolConfig = this.config.toolsConfig[toolName]; - } - - if (tool.prepare && typeof tool.prepare === 'function') { - - toolPreparationList.push(tool.prepare.bind(toolConfig)); - } - } - - // continue editor initialization if non of tools doesn't need preparation - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } - - if (toolPreparationList.length === 0) { - - resolvePreparation(); - } else { - - toolPreparationList.reduce(function (previousToolPrepared, currentToolReadyToPreparation, iteration) { - - return previousToolPrepared.then(function () { - return waitNextToolPreparation(currentToolReadyToPreparation); - }).then(function () { - - if (iteration == toolPreparationList.length - 1) { - - resolvePreparation(); - } - }); - }, Promise.resolve()); - } - }); - - /** - * - getting class and config - * - push to the toolinstnaces property created instances - */ - // for(let tool in this.config.tools) { - // let toolClass = this.config.tools[tool], - // toolConfig; - // - // if (tool in this.config.toolConfig) { - // toolConfig = this.config.toolConfig[tool]; - // } else { - // toolConfig = this.defaultConfig; - // } - // - // this.toolInstances.push(new toolClass(toolConfig)); - // } - } - - /** - * Returns all tools - * @return {Array} - */ - - }, { - key: 'getTools', - value: function getTools() { - - return this.toolInstances; - } - }]); - - return Tools; - }(); - // /** - // * Module working with plugins - // */ - // module.exports = (function () { - // - // let editor = codex.editor; - // - // /** - // * Initialize plugins before using - // * Ex. Load scripts or call some internal methods - // * @return Promise - // */ - // function prepare() { - // - // return new Promise(function (resolve_, reject_) { - // - // Promise.resolve() - // - // /** - // * Compose a sequence of plugins that requires preparation - // */ - // .then(function () { - // - // let pluginsRequiresPreparation = [], - // allPlugins = editor.tools; - // - // for ( let pluginName in allPlugins ) { - // - // let plugin = allPlugins[pluginName]; - // - // if (plugin.prepare && typeof plugin.prepare != 'function' || !plugin.prepare) { - // - // continue; - // - // } - // - // pluginsRequiresPreparation.push(plugin); - // - // } - // - // /** - // * If no one passed plugins requires preparation, finish prepare() and go ahead - // */ - // if (!pluginsRequiresPreparation.length) { - // - // resolve_(); - // - // } - // - // return pluginsRequiresPreparation; - // - // }) - // - // /** Wait plugins while they prepares */ - // .then(waitAllPluginsPreparation_) - // - // .then(function () { - // - // editor.core.log('Plugins loaded', 'info'); - // resolve_(); - // - // }).catch(function (error) { - // - // reject_(error); - // - // }); - // - // }); - // - // } - // - // /** - // * @param {array} plugins - list of tools that requires preparation - // * @return {Promise} resolved while all plugins will be ready or failed - // */ - // function waitAllPluginsPreparation_(plugins) { - // - // /** - // * @calls allPluginsProcessed__ when all plugins prepared or failed - // */ - // return new Promise (function (allPluginsProcessed__) { - // - // /** - // * 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 - // * - // * If last plugin is "prepared" then go to the next stage of initialization - // */ - // plugins.reduce(function (previousValue, plugin, iteration) { - // - // return previousValue.then(function () { - // - // /** - // * Wait till plugins prepared - // * @calls pluginIsReady__ when plugin is ready or failed - // */ - // return new Promise ( function (pluginIsReady__) { - // - // callPluginsPrepareMethod_( plugin ) - // - // .then( pluginIsReady__ ) - // .then( function () { - // - // plugin.available = true; - // - // }) - // - // .catch(function (error) { - // - // editor.core.log(`Plugin «${plugin.type}» was not loaded. Preparation failed because %o`, 'warn', error); - // plugin.available = false; - // plugin.loadingMessage = error; - // - // /** Go ahead even some plugin has problems */ - // pluginIsReady__(); - // - // }) - // - // .then(function () { - // - // /** If last plugin has problems then just ignore and continue */ - // if (iteration == plugins.length - 1) { - // - // allPluginsProcessed__(); - // - // } - // - // }); - // - // }); - // - // }); - // - // }, Promise.resolve() ); - // - // }); - // - // } - // - // var callPluginsPrepareMethod_ = function (plugin) { - // - // return plugin.prepare( plugin.config || {} ); - // - // }; - // - // return { - // prepare: prepare - // }; - // - // }()); - -/***/ }), -/* 22 */ -/***/ (function(module, exports) { - - '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 UI - * - * @type {UI} - */ - var className = { - - /** - * @const {string} BLOCK_CLASSNAME - redactor blocks name - */ - BLOCK_CLASSNAME: 'ce-block', - - /** - * @const {String} wrapper for plugins content - */ - BLOCK_CONTENT: 'ce-block__content', - - /** - * @const {String} BLOCK_STRETCHED - makes block stretched - */ - BLOCK_STRETCHED: 'ce-block--stretched', - - /** - * @const {String} BLOCK_HIGHLIGHTED - adds background - */ - BLOCK_HIGHLIGHTED: 'ce-block--focused', - - /** - * @const {String} - for all default settings - */ - SETTINGS_ITEM: 'ce-settings__item' - }; - - var CSS_ = { - editorWrapper: 'codex-editor', - editorZone: 'ce-redactor' - }; - - /** - * @class - * - * @classdesc Makes CodeX Editor UI: - * - * - * - * - * - * - * @property {EditorConfig} config - editor configuration {@link CodexEditor#configuration} - * @property {Object} Editor - available editor modules {@link CodexEditor#moduleInstances} - */ - module.exports = function () { - _createClass(UI, null, [{ - key: 'name', - - - /** - * Module key name - * @returns {string} - */ - get: function get() { - - return 'ui'; - } - - /** - * @constructor - * - * @param {EditorConfig} config - */ - - }]); - - function UI(config) { - _classCallCheck(this, UI); - - this.config = config; - this.Editor = null; - } - - /** - * Editor modules setter - * @param {object} Editor - available editor modules - */ - - - _createClass(UI, [{ - key: 'prepare', - - - /** - * @protected - * - * Making main interface - */ - value: function prepare() { - - console.log('ui prepare fired'); - - return; - - return new Promise(function (resolve, reject) { - - var wrapper = this.modules.dom.make('DIV', [CSS_.editorWrapper], {}), - redactor = this.modules.dom.make('DIV', [CSS_.editorZone], {}), - toolbar = makeToolBar_(); - - wrapper.appendChild(toolbar); - wrapper.appendChild(redactor); - - /** Save created ui-elements to static nodes state */ - editor.nodes.wrapper = wrapper; - editor.nodes.redactor = redactor; - - /** Append editor wrapper with redactor zone into holder */ - editor.nodes.holder.appendChild(wrapper); - - resolve(); - }) - - /** Add toolbox tools */ - .then(addTools_) - - /** Make container for inline toolbar */ - .then(makeInlineToolbar_) - - /** Add inline toolbar tools */ - .then(addInlineToolbarTools_) - - /** Draw wrapper for notifications */ - .then(makeNotificationHolder_) - - /** Add eventlisteners to redactor elements */ - .then(bindEvents_).catch(function () { - - editor.core.log("Can't draw editor interface"); - }); - } - }, { - key: 'state', - set: function set(Editor) { - - this.Editor = Editor; - } - }]); - - return UI; - }(); - // /** - // * Codex Editor UI module - // * - // * @author Codex Team - // * @version 1.2.0 - // */ - // - // module.exports = (function (ui) { - // - // let editor = codex.editor; - // - // /** - // * Basic editor classnames - // */ - // ui.prepare = function () { - // - - // - // }; - // - // /** - // * @private - // * Draws inline toolbar zone - // */ - // var makeInlineToolbar_ = function () { - // - // var container = editor.draw.inlineToolbar(); - // - // /** Append to redactor new inline block */ - // editor.nodes.inlineToolbar.wrapper = container; - // - // /** Draw toolbar buttons */ - // editor.nodes.inlineToolbar.buttons = editor.draw.inlineToolbarButtons(); - // - // /** Buttons action or settings */ - // editor.nodes.inlineToolbar.actions = editor.draw.inlineToolbarActions(); - // - // /** Append to inline toolbar buttons as part of it */ - // editor.nodes.inlineToolbar.wrapper.appendChild(editor.nodes.inlineToolbar.buttons); - // editor.nodes.inlineToolbar.wrapper.appendChild(editor.nodes.inlineToolbar.actions); - // - // editor.nodes.wrapper.appendChild(editor.nodes.inlineToolbar.wrapper); - // - // }; - // - // var makeToolBar_ = function () { - // - // let toolbar = editor.draw.toolbar(), - // blockButtons = makeToolbarSettings_(), - // toolbarContent = makeToolbarContent_(); - // - // /** Appending first-level block buttons */ - // toolbar.appendChild(blockButtons); - // - // /** Append toolbarContent to toolbar */ - // toolbar.appendChild(toolbarContent); - // - // /** Make toolbar global */ - // editor.nodes.toolbar = toolbar; - // - // return toolbar; - // - // }; - // - // var makeToolbarContent_ = function () { - // - // let toolbarContent = editor.draw.toolbarContent(), - // toolbox = editor.draw.toolbox(), - // plusButton = editor.draw.plusButton(); - // - // /** Append plus button */ - // toolbarContent.appendChild(plusButton); - // - // /** Appending toolbar tools */ - // toolbarContent.appendChild(toolbox); - // - // /** Make Toolbox and plusButton global */ - // editor.nodes.toolbox = toolbox; - // editor.nodes.plusButton = plusButton; - // - // return toolbarContent; - // - // }; - // - // var makeToolbarSettings_ = function () { - // - // let blockSettings = editor.draw.blockSettings(), - // blockButtons = editor.draw.blockButtons(), - // defaultSettings = editor.draw.defaultSettings(), - // showSettingsButton = editor.draw.settingsButton(), - // showTrashButton = editor.toolbar.settings.makeRemoveBlockButton(), - // pluginSettings = editor.draw.pluginsSettings(); - // - // /** Add default and plugins settings */ - // blockSettings.appendChild(pluginSettings); - // blockSettings.appendChild(defaultSettings); - // - // /** - // * Make blocks buttons - // * This block contains settings button and remove block button - // */ - // blockButtons.appendChild(showSettingsButton); - // blockButtons.appendChild(showTrashButton); - // blockButtons.appendChild(blockSettings); - // - // /** Make BlockSettings, PluginSettings, DefaultSettings global */ - // editor.nodes.blockSettings = blockSettings; - // editor.nodes.pluginSettings = pluginSettings; - // editor.nodes.defaultSettings = defaultSettings; - // editor.nodes.showSettingsButton = showSettingsButton; - // editor.nodes.showTrashButton = showTrashButton; - // - // return blockButtons; - // - // }; - // - // /** Draw notifications holder */ - // var makeNotificationHolder_ = function () { - // - // /** Append block with notifications to the document */ - // editor.nodes.notifications = editor.notifications.createHolder(); - // - // }; - // - // /** - // * @private - // * Append tools passed in editor.tools - // */ - // var addTools_ = function () { - // - // var tool, - // toolName, - // toolButton; - // - // for ( toolName in editor.settings.tools ) { - // - // tool = editor.settings.tools[toolName]; - // - // editor.tools[toolName] = tool; - // - // if (!tool.iconClassname && tool.displayInToolbox) { - // - // editor.core.log('Toolbar icon classname missed. Tool %o skipped', 'warn', toolName); - // continue; - // - // } - // - // if (typeof tool.render != 'function') { - // - // editor.core.log('render method missed. Tool %o skipped', 'warn', toolName); - // continue; - // - // } - // - // if (!tool.displayInToolbox) { - // - // continue; - // - // } else { - // - // /** if tools is for toolbox */ - // toolButton = editor.draw.toolbarButton(toolName, tool.iconClassname); - // - // editor.nodes.toolbox.appendChild(toolButton); - // - // editor.nodes.toolbarButtons[toolName] = toolButton; - // - // } - // - // } - // - // }; - // - // var addInlineToolbarTools_ = function () { - // - // var tools = { - // - // bold: { - // icon : 'ce-icon-bold', - // command : 'bold' - // }, - // - // italic: { - // icon : 'ce-icon-italic', - // command : 'italic' - // }, - // - // link: { - // icon : 'ce-icon-link', - // command : 'createLink' - // } - // }; - // - // var toolButton, - // tool; - // - // for(var name in tools) { - // - // tool = tools[name]; - // - // toolButton = editor.draw.toolbarButtonInline(name, tool.icon); - // - // editor.nodes.inlineToolbar.buttons.appendChild(toolButton); - // /** - // * Add callbacks to this buttons - // */ - // editor.ui.setInlineToolbarButtonBehaviour(toolButton, tool.command); - // - // } - // - // }; - // - // /** - // * @private - // * Bind editor UI events - // */ - // var bindEvents_ = function () { - // - // editor.core.log('ui.bindEvents fired', 'info'); - // - // // window.addEventListener('error', function (errorMsg, url, lineNumber) { - // // editor.notifications.errorThrown(errorMsg, event); - // // }, false ); - // - // /** All keydowns on Document */ - // editor.listeners.add(document, 'keydown', editor.callback.globalKeydown, false); - // - // /** All keydowns on Redactor zone */ - // editor.listeners.add(editor.nodes.redactor, 'keydown', editor.callback.redactorKeyDown, false); - // - // /** All keydowns on Document */ - // editor.listeners.add(document, 'keyup', editor.callback.globalKeyup, false ); - // - // /** - // * Mouse click to radactor - // */ - // editor.listeners.add(editor.nodes.redactor, 'click', editor.callback.redactorClicked, false ); - // - // /** - // * Clicks to the Plus button - // */ - // editor.listeners.add(editor.nodes.plusButton, 'click', editor.callback.plusButtonClicked, false); - // - // /** - // * Clicks to SETTINGS button in toolbar - // */ - // editor.listeners.add(editor.nodes.showSettingsButton, 'click', editor.callback.showSettingsButtonClicked, false ); - // - // /** Bind click listeners on toolbar buttons */ - // for (var button in editor.nodes.toolbarButtons) { - // - // editor.listeners.add(editor.nodes.toolbarButtons[button], 'click', editor.callback.toolbarButtonClicked, false); - // - // } - // - // }; - // - // ui.addBlockHandlers = function (block) { - // - // if (!block) return; - // - // /** - // * Block keydowns - // */ - // editor.listeners.add(block, 'keydown', editor.callback.blockKeydown, false); - // - // /** - // * Pasting content from another source - // * We have two type of sanitization - // * First - uses deep-first search algorithm to get sub nodes, - // * sanitizes whole Block_content and replaces cleared nodes - // * This method is deprecated - // * Method is used in editor.callback.blockPaste(event) - // * - // * Secont - uses Mutation observer. - // * Observer "observe" DOM changes and send changings to callback. - // * Callback gets changed node, not whole Block_content. - // * Inserted or changed node, which we've gotten have been cleared and replaced with diry node - // * - // * Method is used in editor.callback.blockPasteViaSanitize(event) - // * - // * @uses html-janitor - // * @example editor.callback.blockPasteViaSanitize(event), the second method. - // * - // */ - // editor.listeners.add(block, 'paste', editor.paste.blockPasteCallback, false); - // - // /** - // * Show inline toolbar for selected text - // */ - // editor.listeners.add(block, 'mouseup', editor.toolbar.inline.show, false); - // editor.listeners.add(block, 'keyup', editor.toolbar.inline.show, false); - // - // }; - // - // /** getting all contenteditable elements */ - // ui.saveInputs = function () { - // - // var redactor = editor.nodes.redactor; - // - // editor.state.inputs = []; - // - // /** Save all inputs in global variable state */ - // var inputs = redactor.querySelectorAll('[contenteditable], input, textarea'); - // - // Array.prototype.map.call(inputs, function (current) { - // - // if (!current.type || current.type == 'text' || current.type == 'textarea') { - // - // editor.state.inputs.push(current); - // - // } - // - // }); - // - // }; - // - // /** - // * Adds first initial block on empty redactor - // */ - // ui.addInitialBlock = function () { - // - // var initialBlockType = editor.settings.initialBlockPlugin, - // initialBlock; - // - // if ( !editor.tools[initialBlockType] ) { - // - // editor.core.log('Plugin %o was not implemented and can\'t be used as initial block', 'warn', initialBlockType); - // return; - // - // } - // - // initialBlock = editor.tools[initialBlockType].render(); - // - // initialBlock.setAttribute('data-placeholder', editor.settings.placeholder); - // - // editor.content.insertBlock({ - // type : initialBlockType, - // block : initialBlock - // }); - // - // editor.content.workingNodeChanged(initialBlock); - // - // }; - // - // ui.setInlineToolbarButtonBehaviour = function (button, type) { - // - // editor.listeners.add(button, 'mousedown', function (event) { - // - // editor.toolbar.inline.toolClicked(event, type); - // - // }, false); - // - // }; - // - // return ui; - // - // })({}); - -/***/ }) -/******/ ]); -//# sourceMappingURL=codex-editor.js.map \ No newline at end of file diff --git a/codex-editor.js.map b/codex-editor.js.map deleted file mode 100644 index 09538645..00000000 --- a/codex-editor.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap 229ff37c08e532c02f84","webpack:///./src/codex.js","webpack:///./src/components/modules ^\\.\\/.*$","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:///./~/html-janitor/src/html-janitor.js","webpack:///./src/components/modules/_saver.js","webpack:///./src/components/modules/_transport.js","webpack:///./src/components/modules/eventDispatcher.js","webpack:///./src/components/modules/toolbar/inline.js","webpack:///./src/components/modules/toolbar/settings.js","webpack:///./src/components/modules/toolbar/toolbar.js","webpack:///./src/components/modules/toolbar/toolbox.js","webpack:///./src/components/modules/tools.js","webpack:///./src/components/modules/ui.js"],"names":["modules","editorModules","map","module","exports","config","moduleInstances","Promise","resolve","then","configuration","init","start","console","log","catch","error","constructModules","configureModules","forEach","Module","name","e","state","getModulesDiff","moduleName","prepareDecorator","prepare","holderId","placeholder","sanitizer","p","b","a","hideToolbar","anchors","editor","codex","input","currentNode","settingsOpened","currentBlock","value","dataset","anchor","anchorChanged","newAnchor","target","rusToTranslit","trim","classList","add","ui","className","BLOCK_WITH_ANCHOR","remove","keyDownOnAnchorInput","keyCode","core","keys","ENTER","preventDefault","stopPropagation","blur","toolbar","settings","close","keyUpOnAnchorInput","LEFT","DOWN","string","ru","en","i","length","split","join","toLowerCase","replace","callbacks","globalKeydown","event","enterKeyPressed_","redactorKeyDown","TAB","tabKeyPressedOnRedactorsZone_","enterKeyPressedOnRedactorsZone_","ESC","escapeKeyPressedOnRedactorsZone_","defaultKeyPressedOnRedactorsZone_","globalKeyup","UP","RIGHT","arrowKeyPressed_","isBlockEmpty","content","opened","open","toolbox","leaf","editorAreaHightlighted","caret","inputIndex","enterPressedOnBlock_","NEW_BLOCK_TYPE","initialBlockPlugin","insertBlock","type","block","tools","render","move","contentEditable","saveCurrentInputIndex","currentInputIndex","getCurrentInputIndex","workingNode","tool","isEnterPressedOnToolbar","current","inputs","enableLineBreaks","toolClicked","stopImmediatePropagation","shiftKey","currentSelection","window","getSelection","currentSelectedNode","anchorNode","caretAtTheEndOfText","position","atTheEnd","isTextNodeHasParentBetweenContenteditable","callback","enterPressedOnBlock","parentNode","nodeType","nodeTypes","TEXT","splitBlock","textContent","showPlusButton","islastNode","isLastNode","saveInputs","workingNodeChanged","inline","actionsOpened","clearMark","redactorClicked","detectWhenClickedOnFirstLevelBlockArea_","selectedText","getSelectionText","firstLevelBlock","indexOfLastInput","getFirstLevelBlock","setToBlock","setToNextBlock","inputIsEmpty","currentNodeType","isInitialType","hidePlusButton","markBlock","selection","flag","rangeCount","isDomNode","document","body","toolbarButtonClicked","button","plusButtonClicked","nodes","contains","blockKeydown","blockRightOrDownArrowPressed_","BACKSPACE","backspacePressed_","blockLeftOrUpArrowPressed_","focusedNode","focusedNodeHolder","editableElementIndex","caretInLastChild","lastChild","deepestTextnode","childNodes","getDeepestTextNodeFromPosition","anchorOffset","caretInFirstChild","caretAtTheBeginning","firstChild","setToPreviousBlock","range","selectionLength","firstLevelBlocksCount","isNativeInput","getRange","endOffset","startOffset","atStart","mergeBlocks","redactor","addInitialBlock","setTimeout","showSettingsButtonClicked","currentToolType","toggle","hideRemoveActions","offset","focusedNodeIndex","set","el","index","childs","nodeToSet","focus","createRange","setStart","setEnd","removeAllRanges","addRange","nextInput","emptyTextElement","createTextNode","appendChild","targetInput","previousInput","lastChildNode","lengthOfLastChildNode","pluginsRender","isFirstNode","isOffsetZero","insertNode","node","lastNode","DOCUMENT_FRAGMENT","getRangeAt","deleteContents","setStartAfter","collapse","sync","html","innerHTML","BLOCK_HIGHLIGHTED","BLOCK_CLASSNAME","targetNode","replaceBlock","targetBlock","newBlock","replaceChild","addBlockHandlers","blockData","needPlaceCaret","workingBlock","newBlockContent","blockType","isStretched","stretched","composeNewBlock_","insertAfter","editableElement","querySelector","emptyText","switchBlock","blockToReplace","newBlockComposed","blockChilds","text","removeChild","lookingFromStart","TAG","draw","blockContent","BLOCK_CONTENT","BLOCK_STRETCHED","anchorNodeText","caretOffset","textBeforeCaret","textNodeBeforeCaret","textAfterCaret","textNodeAfterCaret","substring","previousChilds","nextChilds","reachedCurrent","push","child","previousChildsLength","nextChildsLength","newNode","createElement","targetInputIndex","currentInputContent","allChecked","allSiblingsEmpty_","sibling","nextSibling","wrapTextWithParagraphs","htmlData","plainData","wrapPlainTextWithParagraphs","wrapper","newWrapper","paragraph","firstLevelBlocks","blockTyped","indexOf","tagName","cloneNode","plainText","getEditableParent","clear","all","blocks","items","load","articleData","currentContent","Object","assign","concat","renderer","makeBlocksFromData","destroyer","removeNodes","notifications","destroyPlugins","destroy","destroyScripts","scripts","getElementsByTagName","id","scriptPrefix","listeners","removeAll","plugins","allListeners","search","byElement","element","context","listenersOnElement","listener","byType","eventType","listenersWithType","byHandler","handler","listenersWithHandler","one","result","isCapture","addEventListener","data","alreadyAddedListener","removeEventListener","existingListeners","splice","get","queue","addToQueue","createHolder","holder","errorThrown","errorMsg","notification","message","constructorSettings","cancel","confirm","inputField","confirmHandler","cancelHandler","create","time","okBtn","cancelBtn","okMsg","cancelMsg","send","parser","insertPastedContent","tag","isFirstLevelBlock","paste","patterns","renderOnPastePatterns","Array","isArray","pattern","pasted","clipBoardData","clipboardData","getData","analize","plugin","execArray","regex","exec","match","pasteToNewBlock_","blockPasteCallback","needsToHandlePasteEvent","paragraphs","cleanData","wrappedData","clean","emulateUserAgentBehaviour","insertPastedParagraphs","editableParent","childElementCount","createDocumentFragment","isEmpty","appendBlocks","nodeSequence","appendNodeAtIndex","getNodeAsync","createBlockFromData","blocksList","toolData","pluginName","Error","available","unavailableBlock","loadingMessage","inputPosition","janitor","require","Config","CUSTOM","BASIC","tags","href","rel","init_","userCustomConfig","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","ajax","url","beforeSend","success","progress","selectAndUpload","args","setAttribute","accept","click","abort","subscribers","eventName","reduce","previousData","currentHandler","newData","buttonsOpened","wrappersOffset","storedSelection","show","showInlineToolbar","inlineToolbar","showButtons","getWrappersOffset","coords","getSelectionCoords","defaultOffset","newCoordinateX","newCoordinateY","offsetHeight","x","left","y","scrollY","top","style","transform","Math","floor","closeButtons","closeAction","createLinkAction","defaultToolAction","buttons","hightlight","getOffset","_x","_y","isNaN","offsetLeft","offsetTop","clientLeft","clientTop","offsetParent","sel","boundingLeft","boundingTop","cloneRange","getClientRects","rect","toString","showActions","action","actions","inlineToolbarAnchorInputKeydown_","editable","restoreSelection","setAnchor","clearRange","isActive","isLinkActive","saveSelection","inputForLink","dataType","execCommand","containerEl","preSelectionRange","selectNodeContents","startContainer","end","savedSel","charIndex","nodeStack","foundStart","stop","nextCharIndex","pop","queryCommandState","setButtonHighlighted","removeButtonsHighLight","icon","setting","toolType","makeSettings","settingsBlock","pluginSettings","blockSettings","makeRemoveBlockButton","removeBlockWrapper","settingButton","actionWrapper","confirmAction","cancelAction","removeButtonClicked","confirmRemovingRequest","cancelRemovingRequest","showRemoveActions","defaultToolbarHeight","showSettingsButton","toolbarButtons","plusButton","newYCoordinate","openedOnBlock","currentTool","barButtons","nextToolIndex","toolToSelect","visibleTool","displayInToolbox","UNREPLACEBLE_TOOLS","appendCallback","call","Editor","iconClassName","availabPlugins","toolInstances","toolConfig","defaultConfig","hasOwnProperty","waitNextToolPreparation","toolBindedPreparationFunction","reject","resolvePreparation","rejectPreparation","toolPreparationList","toolName","toolsConfig","bind","previousToolPrepared","currentToolReadyToPreparation","iteration","SETTINGS_ITEM","CSS_","editorWrapper","editorZone","dom","make","makeToolBar_","addTools_","makeInlineToolbar_","addInlineToolbarTools_","makeNotificationHolder_","bindEvents_"],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;;;;;;;;;AASA;;;;AAIA;;;;;;AAMA;;AAEA;;;;;;;;AAGA,KAAIA,UAAUC,cAAcC,GAAd,CAAmB,kBAAU;;AAEvC,YAAO,2BAAQ,GAA0BC,MAAlC,CAAP;AAEH,EAJa,CAAd;;AAMA;;;;;;;;;;AAUAA,QAAOC,OAAP;AAAA;AAAA;;;AAEI;AAFJ,6BAGyB;;AAEjB,oBAAO,SAAP;AAEH;;AAED;;;;;AATJ;;AAaI,0BAAYC,MAAZ,EAAoB;AAAA;;AAAA;;AAEhB;;;AAGA,cAAKA,MAAL,GAAc,EAAd;;AAEA;;;AAGA,cAAKC,eAAL,GAAuB,EAAvB;;AAEAC,iBAAQC,OAAR,GACKC,IADL,CACU,YAAM;;AAER,mBAAKC,aAAL,GAAqBL,MAArB;AAEH,UALL,EAMKI,IANL,CAMU;AAAA,oBAAM,MAAKE,IAAL,EAAN;AAAA,UANV,EAOKF,IAPL,CAOU;AAAA,oBAAM,MAAKG,KAAL,EAAN;AAAA,UAPV,EAQKH,IARL,CAQU,YAAM;;AAERI,qBAAQC,GAAR,CAAY,uBAAZ;AAEH,UAZL,EAaKC,KAbL,CAaW,iBAAS;;AAEZF,qBAAQC,GAAR,CAAY,4CAAZ,EAA0DE,KAA1D;AAEH,UAjBL;AAmBH;;AAED;;;;;;AA9CJ;AAAA;;;AA0EI;;;;;AA1EJ,gCA+EW;;AAEH;;;AAGA,kBAAKC,gBAAL;;AAEA;;;AAGA,kBAAKC,gBAAL;AAEH;;AAED;;;;AA7FJ;AAAA;AAAA,4CAgGuB;AAAA;;AAEflB,qBAAQmB,OAAR,CAAiB,kBAAU;;AAEvB,qBAAI;;AAEA,4BAAKb,eAAL,CAAqBc,OAAOC,IAA5B,IAAoC,IAAID,MAAJ,CAAW;AAC3Cf,iCAAS,OAAKK;AAD6B,sBAAX,CAApC;AAIH,kBAND,CAME,OAAQY,CAAR,EAAY;;AAEVT,6BAAQC,GAAR,CAAY,8BAAZ,EAA4CM,MAA5C,EAAoDE,CAApD;AAEH;AAEJ,cAdD;AAgBH;;AAED;;;;;;AApHJ;AAAA;AAAA,4CAyHuB;;AAEf,kBAAI,IAAID,IAAR,IAAgB,KAAKf,eAArB,EAAsC;;AAElC;;;AAGA,sBAAKA,eAAL,CAAqBe,IAArB,EAA2BE,KAA3B,GAAmC,KAAKC,cAAL,CAAqBH,IAArB,CAAnC;AAEH;AAEJ;;AAED;;;;AAtIJ;AAAA;AAAA,wCAyIoBA,IAzIpB,EAyI2B;;AAEnB,iBAAIrB,UAAU,EAAd;;AAEA,kBAAI,IAAIyB,UAAR,IAAsB,KAAKnB,eAA3B,EAA4C;;AAExC;;;AAGA,qBAAImB,cAAcJ,IAAlB,EAAwB;;AAEpB;AAEH;AACDrB,yBAAQyB,UAAR,IAAsB,KAAKnB,eAAL,CAAqBmB,UAArB,CAAtB;AAEH;;AAED,oBAAOzB,OAAP;AAEH;;AAED;;;;;;AA/JJ;AAAA;AAAA,iCAoKY;;AAEJ,iBAAI0B,mBAAmB,SAAnBA,gBAAmB;AAAA,wBAAUvB,OAAOwB,OAAP,EAAV;AAAA,cAAvB;;AAEA,oBAAOpB,QAAQC,OAAR,GACFC,IADE,CACGiB,iBAAiB,KAAKpB,eAAL,CAAqB,IAArB,CAAjB,CADH,EAEFG,IAFE,CAEGiB,iBAAiB,KAAKpB,eAAL,CAAqB,OAArB,CAAjB,CAFH,EAGFS,KAHE,CAGI,UAAUC,KAAV,EAAiB;;AAEpBH,yBAAQC,GAAR,CAAY,eAAZ,EAA6BE,KAA7B;AAEH,cAPE,CAAP;AASH;AAjLL;AAAA;AAAA,6BAkDmC;AAAA,iBAAbX,MAAa,uEAAJ,EAAI;;;AAE3B,kBAAKA,MAAL,CAAYuB,QAAZ,GAAuBvB,OAAOuB,QAA9B;AACA,kBAAKvB,MAAL,CAAYwB,WAAZ,GAA0BxB,OAAOwB,WAAP,IAAsB,qBAAhD;AACA,kBAAKxB,MAAL,CAAYyB,SAAZ,GAAwBzB,OAAOyB,SAAP,IAAoB;AACxCC,oBAAG,IADqC;AAExCC,oBAAG,IAFqC;AAGxCC,oBAAG;AAHqC,cAA5C;;AAMA,kBAAK5B,MAAL,CAAY6B,WAAZ,GAA0B7B,OAAO6B,WAAP,GAAqB7B,OAAO6B,WAA5B,GAA0C,KAApE;AAEH;;AAED;;;;AAhEJ;AAAA,6BAoEwB;;AAEhB,oBAAO,KAAK7B,MAAZ;AAEH;AAxEL;;AAAA;AAAA;;AAqLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,W;;;;;;ACzUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAiC,uDAAuD;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;ACrDA;;;;;;;AAOAF,QAAOC,OAAP,GAAiB,UAAU+B,OAAV,EAAmB;;AAEhC,SAAIC,SAASC,MAAMD,MAAnB;;AAEAD,aAAQG,KAAR,GAAsB,IAAtB;AACAH,aAAQI,WAAR,GAAsB,IAAtB;;AAEAJ,aAAQK,cAAR,GAAyB,UAAUC,YAAV,EAAwB;;AAE7CN,iBAAQI,WAAR,GAAsBE,YAAtB;AACAN,iBAAQG,KAAR,CAAcI,KAAd,GAAsBP,QAAQI,WAAR,CAAoBI,OAAp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CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,S;;;;;;;;;;;;ACpVI;;;;;AAKJ,KAAIzhB,YAAY;;AAEZ;;;AAGAgM,sBAAkB,UALN;;AAOZ;;;AAGA6B,oBAAgB,mBAVJ;;AAYZ;;;AAGAC,sBAAkB,qBAfN;;AAiBZ;;;AAGA/B,wBAAoB,mBApBR;;AAsBZ;;;AAGA0W,oBAAgB;AAzBJ,EAAhB;;AA4BA,KAAIC,OAAO;AACPC,oBAAgB,cADT;AAEPC,iBAAgB;AAFT,EAAX;;AAMA;;;;;;;;;;;;;AAaA9lB,QAAOC,OAAP;AAAA;AAAA;;;AAEI;;;;AAFJ,6BAMsB;;AAEd,oBAAO,IAAP;AAEH;;AAED;;;;;;AAZJ;;AAiBI,iBAAaC,MAAb,EAAsB;AAAA;;AAElB,cAAKA,MAAL,GAAcA,MAAd;AACA,cAAKskB,MAAL,GAAc,IAAd;AAEH;;AAGD;;;;;;AAzBJ;AAAA;;;AAmCI;;;;;AAnCJ,mCAwCc;;AAEN9jB,qBAAQC,GAAR,CAAY,kBAAZ;;AAEA;;AAEA,oBAAO,IAAIP,OAAJ,CAAY,UAAUC,OAAV,EAAmB4kB,MAAnB,EAA2B;;AAE1C,qBAAItS,UAAW,KAAK9S,OAAL,CAAakmB,GAAb,CAAiBC,IAAjB,CAAsB,KAAtB,EAA6B,CAAEJ,KAAKC,aAAP,CAA7B,EAAqD,EAArD,CAAf;AAAA,qBACItZ,WAAW,KAAK1M,OAAL,CAAakmB,GAAb,CAAiBC,IAAjB,CAAsB,KAAtB,EAA6B,CAAEJ,KAAKE,UAAP,CAA7B,EAAkD,EAAlD,CADf;AAAA,qBAEIjiB,UAAWoiB,cAFf;;AAIAtT,yBAAQ7E,WAAR,CAAoBjK,OAApB;AACA8O,yBAAQ7E,WAAR,CAAoBvB,QAApB;;AAEA;AACAtK,wBAAOyI,KAAP,CAAaiI,OAAb,GAAwBA,OAAxB;AACA1Q,wBAAOyI,KAAP,CAAa6B,QAAb,GAAwBA,QAAxB;;AAEA;AACAtK,wBAAOyI,KAAP,CAAa8L,MAAb,CAAoB1I,WAApB,CAAgC6E,OAAhC;;AAEAtS;AAEH,cAlBM;;AAoBP;AApBO,cAqBNC,IArBM,CAqBD4lB,SArBC;;AAuBP;AAvBO,cAwBN5lB,IAxBM,CAwBD6lB,kBAxBC;;AA0BP;AA1BO,cA2BN7lB,IA3BM,CA2BD8lB,sBA3BC;;AA6BP;AA7BO,cA8BN9lB,IA9BM,CA8BD+lB,uBA9BC;;AAgCP;AAhCO,cAiCN/lB,IAjCM,CAiCDgmB,WAjCC,EAmCN1lB,KAnCM,CAmCC,YAAY;;AAEhBqB,wBAAOsB,IAAP,CAAY5C,GAAZ,CAAgB,6BAAhB;AAEH,cAvCM,CAAP;AAyCH;AAvFL;AAAA;AAAA,2BA6Bc6jB,MA7Bd,EA6BsB;;AAEd,kBAAKA,MAAL,GAAcA,MAAd;AAEH;AAjCL;;AAAA;AAAA;AA0FA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,W","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\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\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.loaded = 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// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 229ff37c08e532c02f84","/**\n * Codex Editor\n *\n *\n *\n *\n * @author CodeX Team\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 */\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\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 this.moduleInstances[Module.name] = 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 modules = {};\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 modules[moduleName] = this.moduleInstances[moduleName];\n\n }\n\n return modules;\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 .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\": 2,\n\t\"./_anchors.js\": 2,\n\t\"./_callbacks\": 3,\n\t\"./_callbacks.js\": 3,\n\t\"./_caret\": 4,\n\t\"./_caret.js\": 4,\n\t\"./_content\": 5,\n\t\"./_content.js\": 5,\n\t\"./_destroyer\": 6,\n\t\"./_destroyer.js\": 6,\n\t\"./_listeners\": 7,\n\t\"./_listeners.js\": 7,\n\t\"./_notifications\": 8,\n\t\"./_notifications.js\": 8,\n\t\"./_parser\": 9,\n\t\"./_parser.js\": 9,\n\t\"./_paste\": 10,\n\t\"./_paste.js\": 10,\n\t\"./_renderer\": 11,\n\t\"./_renderer.js\": 11,\n\t\"./_sanitizer\": 12,\n\t\"./_sanitizer.js\": 12,\n\t\"./_saver\": 14,\n\t\"./_saver.js\": 14,\n\t\"./_transport\": 15,\n\t\"./_transport.js\": 15,\n\t\"./eventDispatcher\": 16,\n\t\"./eventDispatcher.js\": 16,\n\t\"./toolbar/inline\": 17,\n\t\"./toolbar/inline.js\": 17,\n\t\"./toolbar/settings\": 18,\n\t\"./toolbar/settings.js\": 18,\n\t\"./toolbar/toolbar\": 19,\n\t\"./toolbar/toolbar.js\": 19,\n\t\"./toolbar/toolbox\": 20,\n\t\"./toolbar/toolbox.js\": 20,\n\t\"./tools\": 21,\n\t\"./tools.js\": 21,\n\t\"./ui\": 22,\n\t\"./ui.js\": 22\n};\nfunction webpackContext(req) {\n\treturn __webpack_require__(webpackContextResolve(req));\n};\nfunction webpackContextResolve(req) {\n\treturn map[req] || (function() { throw new Error(\"Cannot find module '\" + req + \"'.\") }());\n};\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = 1;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/modules ^\\.\\/.*$\n// module id = 1\n// module chunks = 0","/**\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 case editor.core.keys.ENTER : enterKeyPressed_(event); break;\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 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 * 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 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 * @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","(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// ./~/html-janitor/src/html-janitor.js\n// module id = 13\n// module chunks = 0","/**\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","\nmodule.exports = class Events {\n\n constructor() {\n\n this.subscribers = {};\n\n }\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 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\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/eventDispatcher.js","/**\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 case 'createLink' : editor.toolbar.inline.createLinkAction(event, type); break;\n default : editor.toolbar.inline.defaultToolAction(type); break;\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 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 * 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 * @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 * Class properties:\n *\n * @property {String} this.name - name of this module\n * @property {Array} this.toolInstances - list of tool instances\n *\n */\nmodule.exports = class Tools {\n\n static get name() {\n\n return 'tools';\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.availabPlugins = {};\n this.toolInstances = [];\n\n }\n\n /**\n * Creates instances via passed or default configuration\n * @return {boolean}\n */\n prepare() {\n\n let toolConfig = this.defaultConfig;\n\n if (!this.config.hasOwnProperty('tools')) {\n\n return false;\n\n }\n\n /**\n * Preparation Decorator\n *\n * @param toolBindedPreparationFunction\n * @return {Promise}\n */\n function waitNextToolPreparation(toolBindedPreparationFunction) {\n\n return new Promise(function (resolve, reject) {\n\n toolBindedPreparationFunction()\n .then(resolve)\n .catch(function (error) {\n\n console.log('Plugin is not available because of ', error);\n\n // anyway, go ahead even plugin is not available\n resolve();\n\n });\n\n });\n\n }\n\n return new Promise(function (resolvePreparation, rejectPreparation) {\n\n let toolPreparationList = [];\n\n for(let tool of this.config.tools) {\n\n let toolName = tool.name;\n\n if (toolName in this.config.toolsConfig) {\n\n toolConfig = this.config.toolsConfig[toolName];\n\n }\n\n if (tool.prepare && typeof tool.prepare === 'function') {\n\n toolPreparationList.push(tool.prepare.bind(toolConfig));\n\n }\n\n }\n\n // continue editor initialization if non of tools doesn't need preparation\n if (toolPreparationList.length === 0) {\n\n resolvePreparation();\n\n } else {\n\n toolPreparationList.reduce(function (previousToolPrepared, currentToolReadyToPreparation, iteration) {\n\n return previousToolPrepared\n .then(() => waitNextToolPreparation(currentToolReadyToPreparation))\n .then(() => {\n\n if (iteration == toolPreparationList.length - 1) {\n\n resolvePreparation();\n\n }\n\n });\n\n }, Promise.resolve());\n\n }\n\n });\n\n /**\n * - getting class and config\n * - push to the toolinstnaces property created instances\n */\n // for(let tool in this.config.tools) {\n // let toolClass = this.config.tools[tool],\n // toolConfig;\n //\n // if (tool in this.config.toolConfig) {\n // toolConfig = this.config.toolConfig[tool];\n // } else {\n // toolConfig = this.defaultConfig;\n // }\n //\n // this.toolInstances.push(new toolClass(toolConfig));\n // }\n\n }\n\n /**\n * Returns all tools\n * @return {Array}\n */\n getTools() {\n\n return this.toolInstances;\n\n }\n\n};\n// /**\n// * Module working with plugins\n// */\n// module.exports = (function () {\n//\n// let editor = codex.editor;\n//\n// /**\n// * Initialize plugins before using\n// * Ex. Load scripts or call some internal methods\n// * @return Promise\n// */\n// function prepare() {\n//\n// return new Promise(function (resolve_, reject_) {\n//\n// Promise.resolve()\n//\n// /**\n// * Compose a sequence of plugins that requires preparation\n// */\n// .then(function () {\n//\n// let pluginsRequiresPreparation = [],\n// allPlugins = editor.tools;\n//\n// for ( let pluginName in allPlugins ) {\n//\n// let plugin = allPlugins[pluginName];\n//\n// if (plugin.prepare && typeof plugin.prepare != 'function' || !plugin.prepare) {\n//\n// continue;\n//\n// }\n//\n// pluginsRequiresPreparation.push(plugin);\n//\n// }\n//\n// /**\n// * If no one passed plugins requires preparation, finish prepare() and go ahead\n// */\n// if (!pluginsRequiresPreparation.length) {\n//\n// resolve_();\n//\n// }\n//\n// return pluginsRequiresPreparation;\n//\n// })\n//\n// /** Wait plugins while they prepares */\n// .then(waitAllPluginsPreparation_)\n//\n// .then(function () {\n//\n// editor.core.log('Plugins loaded', 'info');\n// resolve_();\n//\n// }).catch(function (error) {\n//\n// reject_(error);\n//\n// });\n//\n// });\n//\n// }\n//\n// /**\n// * @param {array} plugins - list of tools that requires preparation\n// * @return {Promise} resolved while all plugins will be ready or failed\n// */\n// function waitAllPluginsPreparation_(plugins) {\n//\n// /**\n// * @calls allPluginsProcessed__ when all plugins prepared or failed\n// */\n// return new Promise (function (allPluginsProcessed__) {\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// * If last plugin is \"prepared\" then go to the next stage of initialization\n// */\n// plugins.reduce(function (previousValue, plugin, iteration) {\n//\n// return previousValue.then(function () {\n//\n// /**\n// * Wait till plugins prepared\n// * @calls pluginIsReady__ when plugin is ready or failed\n// */\n// return new Promise ( function (pluginIsReady__) {\n//\n// callPluginsPrepareMethod_( plugin )\n//\n// .then( pluginIsReady__ )\n// .then( function () {\n//\n// plugin.available = true;\n//\n// })\n//\n// .catch(function (error) {\n//\n// editor.core.log(`Plugin «${plugin.type}» was not loaded. Preparation failed because %o`, 'warn', error);\n// plugin.available = false;\n// plugin.loadingMessage = error;\n//\n// /** Go ahead even some plugin has problems */\n// pluginIsReady__();\n//\n// })\n//\n// .then(function () {\n//\n// /** If last plugin has problems then just ignore and continue */\n// if (iteration == plugins.length - 1) {\n//\n// allPluginsProcessed__();\n//\n// }\n//\n// });\n//\n// });\n//\n// });\n//\n// }, Promise.resolve() );\n//\n// });\n//\n// }\n//\n// var callPluginsPrepareMethod_ = function (plugin) {\n//\n// return plugin.prepare( plugin.config || {} );\n//\n// };\n//\n// return {\n// prepare: prepare\n// };\n//\n// }());\n\n\n// WEBPACK FOOTER //\n// ./src/components/modules/tools.js"," /**\n * Module UI\n *\n * @type {UI}\n */\nlet 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/**\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 */\nmodule.exports = class UI {\n\n /**\n * Module key name\n * @returns {string}\n */\n static get name() {\n\n return 'ui';\n\n }\n\n /**\n * @constructor\n *\n * @param {EditorConfig} config\n */\n constructor( config ) {\n\n this.config = config;\n this.Editor = null;\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 console.log('ui prepare fired');\n\n return;\n\n return new Promise(function (resolve, reject) {\n\n let wrapper = this.modules.dom.make('DIV', [ CSS_.editorWrapper ], {}),\n redactor = this.modules.dom.make('DIV', [ CSS_.editorZone ], {}),\n toolbar = makeToolBar_();\n\n wrapper.appendChild(toolbar);\n wrapper.appendChild(redactor);\n\n /** Save created ui-elements to static nodes state */\n editor.nodes.wrapper = wrapper;\n editor.nodes.redactor = redactor;\n\n /** Append editor wrapper with redactor zone into holder */\n editor.nodes.holder.appendChild(wrapper);\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( function () {\n\n editor.core.log(\"Can't draw editor interface\");\n\n });\n\n }\n\n};\n// /**\n// * Codex Editor UI module\n// *\n// * @author Codex Team\n// * @version 1.2.0\n// */\n//\n// module.exports = (function (ui) {\n//\n// let editor = codex.editor;\n//\n// /**\n// * Basic editor classnames\n// */\n// ui.prepare = function () {\n//\n\n//\n// };\n//\n// /**\n// * @private\n// * Draws inline toolbar zone\n// */\n// var makeInlineToolbar_ = function () {\n//\n// var container = editor.draw.inlineToolbar();\n//\n// /** Append to redactor new inline block */\n// editor.nodes.inlineToolbar.wrapper = container;\n//\n// /** Draw toolbar buttons */\n// editor.nodes.inlineToolbar.buttons = editor.draw.inlineToolbarButtons();\n//\n// /** Buttons action or settings */\n// editor.nodes.inlineToolbar.actions = editor.draw.inlineToolbarActions();\n//\n// /** Append to inline toolbar buttons as part of it */\n// editor.nodes.inlineToolbar.wrapper.appendChild(editor.nodes.inlineToolbar.buttons);\n// editor.nodes.inlineToolbar.wrapper.appendChild(editor.nodes.inlineToolbar.actions);\n//\n// editor.nodes.wrapper.appendChild(editor.nodes.inlineToolbar.wrapper);\n//\n// };\n//\n// var makeToolBar_ = function () {\n//\n// let toolbar = editor.draw.toolbar(),\n// blockButtons = makeToolbarSettings_(),\n// toolbarContent = makeToolbarContent_();\n//\n// /** Appending first-level block buttons */\n// toolbar.appendChild(blockButtons);\n//\n// /** Append toolbarContent to toolbar */\n// toolbar.appendChild(toolbarContent);\n//\n// /** Make toolbar global */\n// editor.nodes.toolbar = toolbar;\n//\n// return toolbar;\n//\n// };\n//\n// var makeToolbarContent_ = function () {\n//\n// let toolbarContent = editor.draw.toolbarContent(),\n// toolbox = editor.draw.toolbox(),\n// plusButton = editor.draw.plusButton();\n//\n// /** Append plus button */\n// toolbarContent.appendChild(plusButton);\n//\n// /** Appending toolbar tools */\n// toolbarContent.appendChild(toolbox);\n//\n// /** Make Toolbox and plusButton global */\n// editor.nodes.toolbox = toolbox;\n// editor.nodes.plusButton = plusButton;\n//\n// return toolbarContent;\n//\n// };\n//\n// var makeToolbarSettings_ = function () {\n//\n// let blockSettings = editor.draw.blockSettings(),\n// blockButtons = editor.draw.blockButtons(),\n// defaultSettings = editor.draw.defaultSettings(),\n// showSettingsButton = editor.draw.settingsButton(),\n// showTrashButton = editor.toolbar.settings.makeRemoveBlockButton(),\n// pluginSettings = editor.draw.pluginsSettings();\n//\n// /** Add default and plugins settings */\n// blockSettings.appendChild(pluginSettings);\n// blockSettings.appendChild(defaultSettings);\n//\n// /**\n// * Make blocks buttons\n// * This block contains settings button and remove block button\n// */\n// blockButtons.appendChild(showSettingsButton);\n// blockButtons.appendChild(showTrashButton);\n// blockButtons.appendChild(blockSettings);\n//\n// /** Make BlockSettings, PluginSettings, DefaultSettings global */\n// editor.nodes.blockSettings = blockSettings;\n// editor.nodes.pluginSettings = pluginSettings;\n// editor.nodes.defaultSettings = defaultSettings;\n// editor.nodes.showSettingsButton = showSettingsButton;\n// editor.nodes.showTrashButton = showTrashButton;\n//\n// return blockButtons;\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"],"sourceRoot":""} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 4e3e670e..739abc3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,12 +4,35 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "acorn": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", - "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==", + "@std/esm": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@std/esm/-/esm-0.16.0.tgz", + "integrity": "sha512-JokzOdnTmxUWJ81VWp0OuSR+VZGuvM9lmnefiPoeTwrOH/wworkRvwkXMpSuso0zYQ0LcbGUKLEdkoKwkYyohg==", "dev": true }, + "acorn": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", + "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", + "dev": true, + "requires": { + "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, "acorn-jsx": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", @@ -28,19 +51,21 @@ } }, "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.0.tgz", + "integrity": "sha1-6yhAdG6dxIvV4GOjbj/UAMXqtak=", "dev": true, "requires": { "co": "4.6.0", - "json-stable-stringify": "1.0.1" + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", "dev": true }, "align-text": { @@ -60,16 +85,10 @@ "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", "dev": true }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", "dev": true }, "ansi-regex": { @@ -84,6 +103,12 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, + "any-promise": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-0.1.0.tgz", + "integrity": "sha1-gwtoCqflbzNFHUsEnzvYBESY7ic=", + "dev": true + }, "anymatch": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", @@ -145,6 +170,17 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, + "asn1.js": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz", + "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, "assert": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", @@ -155,10 +191,13 @@ } }, "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "dev": true, + "requires": { + "lodash": "4.17.4" + } }, "async-each": { "version": "1.0.1", @@ -173,7 +212,7 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000746", + "caniuse-db": "1.0.30000775", "normalize-range": "0.1.2", "num2fraction": "1.2.2", "postcss": "5.2.18", @@ -337,15 +376,45 @@ } }, "babel-loader": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-6.4.1.tgz", - "integrity": "sha1-CzQRLVsHSKjc2/Uaz2+b1C1QuMo=", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.2.tgz", + "integrity": "sha512-jRwlFbINAeyDStqK6Dd5YuY0k5YuzQUvlz2ZamuXrXmxav3pNqe9vfJ402+2G+OmlJSXxCOpB6Uz0INM7RQe2A==", "dev": true, "requires": { - "find-cache-dir": "0.1.1", - "loader-utils": "0.2.17", - "mkdirp": "0.5.1", - "object-assign": "4.1.1" + "find-cache-dir": "1.0.0", + "loader-utils": "1.1.0", + "mkdirp": "0.5.1" + }, + "dependencies": { + "find-cache-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", + "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", + "dev": true, + "requires": { + "commondir": "1.0.1", + "make-dir": "1.1.0", + "pkg-dir": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "2.1.0" + } + } } }, "babel-messages": { @@ -366,6 +435,12 @@ "babel-runtime": "6.26.0" } }, + "babel-plugin-class-display-name": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-class-display-name/-/babel-plugin-class-display-name-2.1.0.tgz", + "integrity": "sha1-GY/xK56r0z4BHuE/L5iYmFYItNE=", + "dev": true + }, "babel-plugin-transform-es2015-arrow-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", @@ -758,13 +833,18 @@ "big.js": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", - "dev": true + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" }, "binary-extensions": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz", - "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", "dev": true }, "brace-expansion": { @@ -788,22 +868,80 @@ "repeat-element": "1.1.2" } }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, "browserify-aes": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-0.4.0.tgz", - "integrity": "sha1-BnFJtmjfMcS1hTPgLQHoBthgjiw=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", + "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", "dev": true, "requires": { + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "browserify-cipher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", + "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "dev": true, + "requires": { + "browserify-aes": "1.1.1", + "browserify-des": "1.0.0", + "evp_bytestokey": "1.0.3" + } + }, + "browserify-des": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", + "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "des.js": "1.0.0", "inherits": "2.0.3" } }, - "browserify-zlib": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", - "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { - "pako": "0.2.9" + "bn.js": "4.11.8", + "randombytes": "2.0.5" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "1.0.6" } }, "browserslist": { @@ -812,8 +950,8 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000746", - "electron-to-chromium": "1.3.26" + "caniuse-db": "1.0.30000775", + "electron-to-chromium": "1.3.27" } }, "buffer": { @@ -827,6 +965,18 @@ "isarray": "1.0.0" } }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", @@ -861,15 +1011,21 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000746", + "caniuse-db": "1.0.30000775", "lodash.memoize": "4.1.2", "lodash.uniq": "4.5.0" } }, "caniuse-db": { - "version": "1.0.30000746", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000746.tgz", - "integrity": "sha1-UBCYxm9fu/Y0wC8lUIsF6ICZEPQ=", + "version": "1.0.30000775", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000775.tgz", + "integrity": "sha1-BLzN0CFO3yW5f2GglmCfetaQQzM=", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30000775", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000775.tgz", + "integrity": "sha1-dNJ/7dxH88hM+8sTDDCSo168LeI=", "dev": true }, "center-align": { @@ -895,6 +1051,12 @@ "supports-color": "2.0.0" } }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, "chokidar": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", @@ -903,7 +1065,7 @@ "requires": { "anymatch": "1.3.2", "async-each": "1.0.1", - "fsevents": "1.1.2", + "fsevents": "1.1.3", "glob-parent": "2.0.0", "inherits": "2.0.3", "is-binary-path": "1.0.1", @@ -912,6 +1074,16 @@ "readdirp": "2.1.0" } }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", @@ -928,12 +1100,12 @@ } }, "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { - "restore-cursor": "1.0.1" + "restore-cursor": "2.0.0" } }, "cli-width": { @@ -962,16 +1134,15 @@ } }, "clone": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", - "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", + "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", "dev": true }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, "coa": { "version": "1.0.4", @@ -979,7 +1150,7 @@ "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", "dev": true, "requires": { - "q": "1.5.0" + "q": "1.5.1" } }, "code-point-at": { @@ -994,15 +1165,15 @@ "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", "dev": true, "requires": { - "clone": "1.0.2", - "color-convert": "1.9.0", + "clone": "1.0.3", + "color-convert": "1.9.1", "color-string": "0.3.0" } }, "color-convert": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", - "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", "dev": true, "requires": { "color-name": "1.1.3" @@ -1046,6 +1217,12 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, + "complex.js": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.0.4.tgz", + "integrity": "sha512-Syl95HpxUTS0QjwNxencZsKukgh1zdS9uXeXX2Us0pHaqBR6kiZZi0AkZ9VpZFwHJyVIUVzI4EumjWdXP3fy6w==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1096,16 +1273,122 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, - "crypto-browserify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.3.0.tgz", - "integrity": "sha1-ufx1u0oO1h3PHNXa6W6zDJw+UGw=", + "cosmiconfig": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", + "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", "dev": true, "requires": { - "browserify-aes": "0.4.0", - "pbkdf2-compat": "2.0.1", - "ripemd160": "0.2.0", - "sha.js": "2.2.6" + "is-directory": "0.3.1", + "js-yaml": "3.7.0", + "minimist": "1.2.0", + "object-assign": "4.1.1", + "os-homedir": "1.0.2", + "parse-json": "2.2.0", + "require-from-string": "1.2.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "create-ecdh": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", + "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "elliptic": "6.4.0" + } + }, + "create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "sha.js": "2.4.9" + } + }, + "create-hmac": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", + "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.9" + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "1.0.0", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.0", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "diffie-hellman": "5.0.2", + "inherits": "2.0.3", + "pbkdf2": "3.0.14", + "public-encrypt": "4.0.0", + "randombytes": "2.0.5", + "randomfill": "1.0.3" + } + }, + "css-color-function": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/css-color-function/-/css-color-function-1.3.3.tgz", + "integrity": "sha1-jtJMLAIFBzM5+voAS8jBQfzLKC4=", + "dev": true, + "requires": { + "balanced-match": "0.1.0", + "color": "0.11.4", + "debug": "3.1.0", + "rgb": "0.1.0" + }, + "dependencies": { + "balanced-match": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.1.0.tgz", + "integrity": "sha1-tQS9BYabOSWd0MXvw12EMXbczEo=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, "css-color-names": { @@ -1115,14 +1398,15 @@ "dev": true }, "css-loader": { - "version": "0.26.4", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.26.4.tgz", - "integrity": "sha1-th6eMNuUMD5v/IkvEOzQmtAlof0=", + "version": "0.28.7", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.7.tgz", + "integrity": "sha512-GxMpax8a/VgcfRrVy0gXD6yLd5ePYbXX/5zGgTVYp4wXtJklS8Z2VaUArJgc//f6/Dzil7BaJObdSv8eKKCPgg==", "dev": true, "requires": { "babel-code-frame": "6.26.0", "css-selector-tokenizer": "0.7.0", "cssnano": "3.10.0", + "icss-utils": "2.1.0", "loader-utils": "1.1.0", "lodash.camelcase": "4.3.0", "object-assign": "4.1.1", @@ -1131,20 +1415,8 @@ "postcss-modules-local-by-default": "1.2.0", "postcss-modules-scope": "1.1.0", "postcss-modules-values": "1.3.0", - "source-list-map": "0.1.8" - }, - "dependencies": { - "loader-utils": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", - "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", - "dev": true, - "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1" - } - } + "postcss-value-parser": "3.3.0", + "source-list-map": "2.0.0" } }, "css-selector-tokenizer": { @@ -1171,6 +1443,12 @@ } } }, + "css-unit-converter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz", + "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=", + "dev": true + }, "cssesc": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", @@ -1233,7 +1511,7 @@ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { - "es5-ext": "0.10.31" + "es5-ext": "0.10.37" } }, "date-now": { @@ -1257,6 +1535,12 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "decimal.js": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-7.2.3.tgz", + "integrity": "sha512-AoFI37QS0S87Ft0r3Bdz4q9xSpm1Paa9lSeKLXgMPk/u/+QPIM5Gy4DHcZQS1seqPJH4gHLauPGn347z0HbsrA==", + "dev": true + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -1282,6 +1566,24 @@ "pify": "2.3.0", "pinkie-promise": "2.0.1", "rimraf": "2.6.2" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" } }, "detect-indent": { @@ -1293,14 +1595,24 @@ "repeating": "2.0.1" } }, - "doctrine": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", - "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", + "diffie-hellman": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", + "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", "dev": true, "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" + "bn.js": "4.11.8", + "miller-rabin": "4.0.1", + "randombytes": "2.0.5" + } + }, + "doctrine": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", + "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", + "dev": true, + "requires": { + "esutils": "2.0.2" } }, "domain-browser": { @@ -1310,34 +1622,41 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.26", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.26.tgz", - "integrity": "sha1-mWQnKUhhp02cfIK5Jg6jAejALWY=", + "version": "1.3.27", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz", + "integrity": "sha1-eOy4o5kGYYe7N07t412ccFZagD0=", "dev": true }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" }, "enhanced-resolve": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", - "integrity": "sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", + "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", "dev": true, "requires": { "graceful-fs": "4.1.11", - "memory-fs": "0.2.0", - "tapable": "0.1.10" - }, - "dependencies": { - "memory-fs": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", - "integrity": "sha1-8rslNovBIeORwlIN6Slpyu4KApA=", - "dev": true - } + "memory-fs": "0.4.1", + "object-assign": "4.1.1", + "tapable": "0.2.8" } }, "errno": { @@ -1349,24 +1668,41 @@ "prr": "0.0.0" } }, - "es5-ext": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.31.tgz", - "integrity": "sha1-e7k4yVp/G59ygJLcCcQe3MOY7v4=", + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "dev": true, "requires": { - "es6-iterator": "2.0.1", + "is-arrayish": "0.2.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + } + } + }, + "es5-ext": { + "version": "0.10.37", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz", + "integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=", + "dev": true, + "requires": { + "es6-iterator": "2.0.3", "es6-symbol": "3.1.1" } }, "es6-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.31", + "es5-ext": "0.10.37", "es6-symbol": "3.1.1" } }, @@ -1377,8 +1713,8 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.31", - "es6-iterator": "2.0.1", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", "es6-set": "0.1.5", "es6-symbol": "3.1.1", "event-emitter": "0.3.5" @@ -1391,8 +1727,8 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.31", - "es6-iterator": "2.0.1", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", "es6-symbol": "3.1.1", "event-emitter": "0.3.5" } @@ -1404,7 +1740,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.31" + "es5-ext": "0.10.37" } }, "es6-weak-map": { @@ -1414,8 +1750,8 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.31", - "es6-iterator": "2.0.1", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", "es6-symbol": "3.1.1" } }, @@ -1438,46 +1774,131 @@ } }, "eslint": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.12.1.tgz", + "integrity": "sha512-28hOYej+NZ/R5H1yMvyKa1+bPlu+fnsIAQffK6hxXgvmXnImos2bA5XfCn5dYv2k2mrKj+/U/Z4L5ICWxC7TQw==", "dev": true, "requires": { + "ajv": "5.5.0", "babel-code-frame": "6.26.0", - "chalk": "1.1.3", + "chalk": "2.3.0", "concat-stream": "1.6.0", - "debug": "2.6.9", - "doctrine": "2.0.0", - "escope": "3.6.0", - "espree": "3.5.1", + "cross-spawn": "5.1.0", + "debug": "3.1.0", + "doctrine": "2.0.2", + "eslint-scope": "3.7.1", + "espree": "3.5.2", "esquery": "1.0.0", "estraverse": "4.2.0", "esutils": "2.0.2", "file-entry-cache": "2.0.0", + "functional-red-black-tree": "1.0.1", "glob": "7.1.2", - "globals": "9.18.0", - "ignore": "3.3.5", + "globals": "11.0.1", + "ignore": "3.3.7", "imurmurhash": "0.1.4", - "inquirer": "0.12.0", - "is-my-json-valid": "2.16.1", + "inquirer": "3.3.0", "is-resolvable": "1.0.0", - "js-yaml": "3.7.0", - "json-stable-stringify": "1.0.1", + "js-yaml": "3.10.0", + "json-stable-stringify-without-jsonify": "1.0.1", "levn": "0.3.0", "lodash": "4.17.4", + "minimatch": "3.0.4", "mkdirp": "0.5.1", "natural-compare": "1.4.0", "optionator": "0.8.2", "path-is-inside": "1.0.2", - "pluralize": "1.2.1", - "progress": "1.1.8", + "pluralize": "7.0.0", + "progress": "2.0.0", "require-uncached": "1.0.3", - "shelljs": "0.7.8", - "strip-bom": "3.0.0", + "semver": "5.4.1", + "strip-ansi": "4.0.0", "strip-json-comments": "2.0.1", - "table": "3.8.3", - "text-table": "0.2.0", - "user-home": "2.0.0" + "table": "4.0.2", + "text-table": "0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "globals": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.0.1.tgz", + "integrity": "sha1-Eqh7sBDlFUOWrMU14eQ/x1Ow5eg=", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } } }, "eslint-loader": { @@ -1506,13 +1927,23 @@ } } }, - "espree": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.1.tgz", - "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=", + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", "dev": true, "requires": { - "acorn": "5.1.2", + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "espree": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", + "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", + "dev": true, + "requires": { + "acorn": "5.2.1", "acorn-jsx": "3.0.1" } }, @@ -1560,7 +1991,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.31" + "es5-ext": "0.10.37" } }, "events": { @@ -1569,11 +2000,30 @@ "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", "dev": true }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "dev": true + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "1.3.4", + "safe-buffer": "5.1.1" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } }, "expand-brackets": { "version": "0.1.5", @@ -1593,6 +2043,17 @@ "fill-range": "2.2.3" } }, + "external-editor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", + "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", + "dev": true, + "requires": { + "chardet": "0.4.2", + "iconv-lite": "0.4.19", + "tmp": "0.0.33" + } + }, "extglob": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", @@ -1603,16 +2064,27 @@ } }, "extract-text-webpack-plugin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-1.0.1.tgz", - "integrity": "sha1-yVvzy6rEnclvHcbgclSfu2VMzSw=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz", + "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==", "dev": true, "requires": { - "async": "1.5.2", - "loader-utils": "0.2.17", - "webpack-sources": "0.1.5" + "async": "2.6.0", + "loader-utils": "1.1.0", + "schema-utils": "0.3.0", + "webpack-sources": "1.1.0" } }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", @@ -1626,13 +2098,12 @@ "dev": true }, "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" + "escape-string-regexp": "1.0.5" } }, "file-entry-cache": { @@ -1718,6 +2189,12 @@ "for-in": "1.0.2" } }, + "fraction.js": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.2.tgz", + "integrity": "sha512-OswcigOSil3vYXgrPSx4NCaSyPikXqVNYN/4CyhS0ucVOJ4GVYr6KQQLLcAudvS/4bBOzxqJ3XIsFaaMjl98ZQ==", + "dev": true + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1725,14 +2202,14 @@ "dev": true }, "fsevents": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.2.tgz", - "integrity": "sha512-Sn44E5wQW4bTHXvQmvSHwqbuiXtduD6Rrjm2ZtUEGbyrig+nUH3t/QD4M4/ZXViY556TBpRgZkHLDx3JxPwxiw==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", + "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", "dev": true, "optional": true, "requires": { - "nan": "2.7.0", - "node-pre-gyp": "0.6.36" + "nan": "2.8.0", + "node-pre-gyp": "0.6.39" }, "dependencies": { "abbrev": { @@ -1890,7 +2367,6 @@ "version": "2.0.5", "bundled": true, "dev": true, - "optional": true, "requires": { "boom": "2.10.1" } @@ -1938,6 +2414,12 @@ "dev": true, "optional": true }, + "detect-libc": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, "ecc-jsbn": { "version": "0.1.1", "bundled": true, @@ -2079,7 +2561,6 @@ "version": "3.1.3", "bundled": true, "dev": true, - "optional": true, "requires": { "boom": "2.10.1", "cryptiles": "2.0.5", @@ -2251,11 +2732,13 @@ "optional": true }, "node-pre-gyp": { - "version": "0.6.36", + "version": "0.6.39", "bundled": true, "dev": true, "optional": true, "requires": { + "detect-libc": "1.0.2", + "hawk": "3.1.3", "mkdirp": "0.5.1", "nopt": "4.0.1", "npmlog": "4.1.0", @@ -2463,7 +2946,6 @@ "version": "1.0.9", "bundled": true, "dev": true, - "optional": true, "requires": { "hoek": "2.16.3" } @@ -2629,20 +3111,23 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "1.0.2" - } + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true }, "glob": { "version": "7.1.2", @@ -2695,6 +3180,31 @@ "object-assign": "4.1.1", "pify": "2.3.0", "pinkie-promise": "2.0.1" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "gonzales-pe": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.2.3.tgz", + "integrity": "sha512-Kjhohco0esHQnOiqqdJeNz/5fyPkOMD/d6XVjwTAoPGUFh0mCollPUTUTa2OZy4dYNAqlPIQdTiNzJTWdd9Htw==", + "dev": true, + "requires": { + "minimist": "1.1.3" + }, + "dependencies": { + "minimist": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz", + "integrity": "sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=", + "dev": true + } } }, "graceful-fs": { @@ -2727,6 +3237,36 @@ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, + "hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, "home-or-tmp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", @@ -2737,6 +3277,12 @@ "os-tmpdir": "1.0.2" } }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, "html-comment-regex": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", @@ -2750,9 +3296,15 @@ "dev": true }, "https-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", - "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", "dev": true }, "icss-replace-symbols": { @@ -2761,6 +3313,69 @@ "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", "dev": true }, + "icss-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", + "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", + "dev": true, + "requires": { + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, "ieee754": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", @@ -2768,9 +3383,9 @@ "dev": true }, "ignore": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", - "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", "dev": true }, "imurmurhash": { @@ -2808,30 +3423,83 @@ "dev": true }, "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", "dev": true, "requires": { - "ansi-escapes": "1.4.0", - "ansi-regex": "2.1.1", - "chalk": "1.1.3", - "cli-cursor": "1.0.2", + "ansi-escapes": "3.0.0", + "chalk": "2.3.0", + "cli-cursor": "2.1.0", "cli-width": "2.2.0", - "figures": "1.7.0", + "external-editor": "2.1.0", + "figures": "2.0.0", "lodash": "4.17.4", - "readline2": "1.0.1", - "run-async": "0.1.0", - "rx-lite": "3.1.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", "through": "2.3.8" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } } }, "interpret": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz", - "integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", "dev": true }, "invariant": { @@ -2843,25 +3511,52 @@ "loose-envify": "1.3.1" } }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, "is-absolute-url": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", "dev": true }, + "is-arrayish": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.1.tgz", + "integrity": "sha1-wt/DhquqDD4zxI2z/ocFnmkGXv0=", + "dev": true + }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.10.0" + "binary-extensions": "1.11.0" } }, "is-buffer": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", - "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true }, "is-dotfile": { @@ -2901,13 +3596,10 @@ } }, "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true }, "is-glob": { "version": "2.0.1", @@ -2918,18 +3610,6 @@ "is-extglob": "1.0.0" } }, - "is-my-json-valid": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", - "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", - "dev": true, - "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" - } - }, "is-number": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", @@ -2951,13 +3631,13 @@ "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", "dev": true, "requires": { - "is-path-inside": "1.0.0" + "is-path-inside": "1.0.1" } }, "is-path-inside": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", - "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { "path-is-inside": "1.0.2" @@ -2981,10 +3661,10 @@ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", "dev": true }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, "is-resolvable": { @@ -2996,6 +3676,12 @@ "tryit": "1.0.3" } }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, "is-svg": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", @@ -3011,6 +3697,18 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isnumeric": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/isnumeric/-/isnumeric-0.2.0.tgz", + "integrity": "sha1-ojR7o2DeGeM9D/1ZD933dVy/LmQ=", + "dev": true + }, "isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", @@ -3020,10 +3718,16 @@ "isarray": "1.0.0" } }, + "javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=", + "dev": true + }, "js-base64": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz", - "integrity": "sha512-Y2/+DnfJJXT1/FCwUebUhLWb3QihxiSC42+ctHLGogmW2jPY6LCapMdFZXRvVP2z6qyKW7s6qncE/9gSqZiArw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.0.tgz", + "integrity": "sha512-Wehd+7Pf9tFvGb+ydPm9TjYjV8X1YHOVyG8QyELZxEMqOhemVwGRmoG8iQ/soqI3n8v4xn59zaLxiCJiaaRzKA==", "dev": true }, "js-tokens": { @@ -3048,32 +3752,27 @@ "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true }, - "json-stable-stringify": { + "json-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "0.0.0" - } + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true }, "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" }, "kind-of": { "version": "3.2.2", @@ -3081,7 +3780,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } }, "lazy-cache": { @@ -3090,6 +3789,15 @@ "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", "dev": true }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -3100,6 +3808,26 @@ "type-check": "0.3.2" } }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, "loader-fs-cache": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.1.tgz", @@ -3110,16 +3838,39 @@ "mkdirp": "0.5.1" } }, + "loader-runner": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", + "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", + "dev": true + }, "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", "dev": true, "requires": { "big.js": "3.2.0", "emojis-list": "2.1.0", - "json5": "0.5.1", - "object-assign": "4.1.1" + "json5": "0.5.1" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } } }, "lodash": { @@ -3128,6 +3879,12 @@ "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", "dev": true }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -3140,6 +3897,25 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "lodash.template": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", + "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.templatesettings": "4.1.0" + } + }, + "lodash.templatesettings": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", + "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0" + } + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -3161,22 +3937,87 @@ "js-tokens": "3.0.2" } }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, "macaddress": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz", "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=", "dev": true }, + "make-dir": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz", + "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==", + "dev": true, + "requires": { + "pify": "3.0.0" + } + }, "math-expression-evaluator": { "version": "1.2.17", "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=", "dev": true }, + "mathjs": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-3.17.0.tgz", + "integrity": "sha512-bFDSjjLV3+csekog1L6z3FjZ0uSkRPFcMlbLef8KXxq68jtQQ48W2f+JKJugM9y6KxJEtt1zWFIGQnYKWR0nxg==", + "dev": true, + "requires": { + "complex.js": "2.0.4", + "decimal.js": "7.2.3", + "fraction.js": "4.0.2", + "javascript-natural-sort": "0.7.1", + "seed-random": "2.2.0", + "tiny-emitter": "2.0.0", + "typed-function": "0.10.6" + } + }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "dev": true, + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + } + } + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, "memory-fs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.3.0.tgz", - "integrity": "sha1-e8xrYp46Q+hx1+Kaymrop/FcuyA=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", "dev": true, "requires": { "errno": "0.1.4", @@ -3204,6 +4045,34 @@ "regex-cache": "0.4.4" } }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0" + } + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -3235,15 +4104,15 @@ "dev": true }, "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, "nan": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.7.0.tgz", - "integrity": "sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY=", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", + "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", "dev": true, "optional": true }, @@ -3254,21 +4123,21 @@ "dev": true }, "node-libs-browser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-0.7.0.tgz", - "integrity": "sha1-PicsCBnjCJNeJmdECNevDhSRuDs=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", + "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", "dev": true, "requires": { "assert": "1.4.1", - "browserify-zlib": "0.1.4", + "browserify-zlib": "0.2.0", "buffer": "4.9.1", "console-browserify": "1.1.0", "constants-browserify": "1.0.0", - "crypto-browserify": "3.3.0", + "crypto-browserify": "3.12.0", "domain-browser": "1.1.7", "events": "1.1.1", - "https-browserify": "0.0.1", - "os-browserify": "0.2.1", + "https-browserify": "1.0.0", + "os-browserify": "0.3.0", "path-browserify": "0.0.0", "process": "0.11.10", "punycode": "1.4.1", @@ -3276,20 +4145,24 @@ "readable-stream": "2.3.3", "stream-browserify": "2.0.1", "stream-http": "2.7.2", - "string_decoder": "0.10.31", + "string_decoder": "1.0.3", "timers-browserify": "2.0.4", "tty-browserify": "0.0.0", "url": "0.11.0", "util": "0.10.3", "vm-browserify": "0.0.4" - }, - "dependencies": { - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.4.1", + "validate-npm-package-license": "3.0.1" } }, "normalize-path": { @@ -3319,6 +4192,15 @@ "sort-keys": "1.1.2" } }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "2.0.1" + } + }, "num2fraction": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", @@ -3362,28 +4244,19 @@ "wrappy": "1.0.2" } }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "onecolor": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/onecolor/-/onecolor-3.0.5.tgz", + "integrity": "sha1-Nu/zIgE3nv3xGA+0ReUajiQl+fY=", "dev": true }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - } + "mimic-fn": "1.1.0" } }, "optionator": { @@ -3401,9 +4274,9 @@ } }, "os-browserify": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", - "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, "os-homedir": { @@ -3412,18 +4285,63 @@ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, - "pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", + "dev": true + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.1.0" + } + }, + "pako": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "dev": true + }, + "parse-asn1": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", + "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "dev": true, + "requires": { + "asn1.js": "4.9.2", + "browserify-aes": "1.1.1", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.14" + } + }, "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", @@ -3436,6 +4354,15 @@ "is-glob": "2.0.1" } }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, "path": { "version": "0.12.7", "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", @@ -3473,22 +4400,52 @@ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", "dev": true }, - "pbkdf2-compat": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pbkdf2-compat/-/pbkdf2-compat-2.0.1.tgz", - "integrity": "sha1-tuDI+plJTZTgURV1gCpZpcFC8og=", - "dev": true + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "pbkdf2": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", + "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", + "dev": true, + "requires": { + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.9" + } }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, "pinkie": { @@ -3506,6 +4463,81 @@ "pinkie": "2.0.4" } }, + "pixrem": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pixrem/-/pixrem-4.0.1.tgz", + "integrity": "sha1-LaSh3m7EQjxfw3lOkwuB1EkOxoY=", + "dev": true, + "requires": { + "browserslist": "2.9.1", + "postcss": "6.0.14", + "reduce-css-calc": "1.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "browserslist": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.9.1.tgz", + "integrity": "sha512-3n3nPdbUqn3nWmsy4PeSQthz2ja1ndpoXta+dwFFNhveGjMg6FXpWYe12vsTpNoXJbzx3j7GZXdtoVIdvh3JbA==", + "dev": true, + "requires": { + "caniuse-lite": "1.0.30000775", + "electron-to-chromium": "1.3.27" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, "pkg-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", @@ -3515,10 +4547,74 @@ "find-up": "1.1.2" } }, + "pleeease-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pleeease-filters/-/pleeease-filters-4.0.0.tgz", + "integrity": "sha1-ZjKy+wVkjSdY2GU4T7zteeHMrsc=", + "dev": true, + "requires": { + "onecolor": "3.0.5", + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, "pluralize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", "dev": true }, "postcss": { @@ -3528,7 +4624,7 @@ "dev": true, "requires": { "chalk": "1.1.3", - "js-base64": "2.3.2", + "js-base64": "2.4.0", "source-map": "0.5.7", "supports-color": "3.2.3" }, @@ -3544,6 +4640,141 @@ } } }, + "postcss-apply": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/postcss-apply/-/postcss-apply-0.8.0.tgz", + "integrity": "sha1-FOVEu7XLbxweBIhXll15rgZrE0M=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "balanced-match": "0.4.2", + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-attribute-case-insensitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-2.0.0.tgz", + "integrity": "sha1-lNxCLI+QmX8WvTOjZUu77AhJY7Q=", + "dev": true, + "requires": { + "postcss": "6.0.14", + "postcss-selector-parser": "2.2.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, "postcss-calc": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", @@ -3555,6 +4786,587 @@ "reduce-css-calc": "1.3.0" } }, + "postcss-color-function": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-color-function/-/postcss-color-function-4.0.1.tgz", + "integrity": "sha1-QCs/LOvD9pR+YY+2vjZU++zvZEQ=", + "dev": true, + "requires": { + "css-color-function": "1.3.3", + "postcss": "6.0.14", + "postcss-message-helpers": "2.0.0", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-gray": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-4.0.0.tgz", + "integrity": "sha1-aBvzBQl91mv+8OHmKC1dmbWsyV0=", + "dev": true, + "requires": { + "color": "1.0.3", + "postcss": "6.0.14", + "postcss-message-helpers": "2.0.0", + "reduce-function-call": "1.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "color": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/color/-/color-1.0.3.tgz", + "integrity": "sha1-5I6DLYXxTvaU+0aIEcLVz+cptV0=", + "dev": true, + "requires": { + "color-convert": "1.9.1", + "color-string": "1.5.2" + } + }, + "color-string": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.2.tgz", + "integrity": "sha1-JuRYFLw8mny9Z1FkikFDRRSnc6k=", + "dev": true, + "requires": { + "color-name": "1.1.3", + "simple-swizzle": "0.2.2" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-hex-alpha": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-3.0.0.tgz", + "integrity": "sha1-HlPmyKyyN5Vej9CLfs2xuLgwn5U=", + "dev": true, + "requires": { + "color": "1.0.3", + "postcss": "6.0.14", + "postcss-message-helpers": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "color": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/color/-/color-1.0.3.tgz", + "integrity": "sha1-5I6DLYXxTvaU+0aIEcLVz+cptV0=", + "dev": true, + "requires": { + "color-convert": "1.9.1", + "color-string": "1.5.2" + } + }, + "color-string": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.2.tgz", + "integrity": "sha1-JuRYFLw8mny9Z1FkikFDRRSnc6k=", + "dev": true, + "requires": { + "color-name": "1.1.3", + "simple-swizzle": "0.2.2" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-hsl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-hsl/-/postcss-color-hsl-2.0.0.tgz", + "integrity": "sha1-EnA2ZvoxBDDj8wpFTawThjF9WEQ=", + "dev": true, + "requires": { + "postcss": "6.0.14", + "postcss-value-parser": "3.3.0", + "units-css": "0.4.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-hwb": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-hwb/-/postcss-color-hwb-3.0.0.tgz", + "integrity": "sha1-NAKxnvTYSXVAwftQcr6YY8qVVx4=", + "dev": true, + "requires": { + "color": "1.0.3", + "postcss": "6.0.14", + "postcss-message-helpers": "2.0.0", + "reduce-function-call": "1.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "color": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/color/-/color-1.0.3.tgz", + "integrity": "sha1-5I6DLYXxTvaU+0aIEcLVz+cptV0=", + "dev": true, + "requires": { + "color-convert": "1.9.1", + "color-string": "1.5.2" + } + }, + "color-string": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.2.tgz", + "integrity": "sha1-JuRYFLw8mny9Z1FkikFDRRSnc6k=", + "dev": true, + "requires": { + "color-name": "1.1.3", + "simple-swizzle": "0.2.2" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-rebeccapurple": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-3.0.0.tgz", + "integrity": "sha1-7rrwPTY7QwC5Z5K9MIHBntZlE9M=", + "dev": true, + "requires": { + "postcss": "6.0.14", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-rgb": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-rgb/-/postcss-color-rgb-2.0.0.tgz", + "integrity": "sha1-FFOcinExSUtILg3RzCZf9lFLUmM=", + "dev": true, + "requires": { + "postcss": "6.0.14", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-color-rgba-fallback": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-rgba-fallback/-/postcss-color-rgba-fallback-3.0.0.tgz", + "integrity": "sha1-N9XJNToHoJJwkSqCYGu0Kg1wLAQ=", + "dev": true, + "requires": { + "postcss": "6.0.14", + "postcss-value-parser": "3.3.0", + "rgb-hex": "2.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, "postcss-colormin": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", @@ -3576,6 +5388,348 @@ "postcss-value-parser": "3.3.0" } }, + "postcss-cssnext": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postcss-cssnext/-/postcss-cssnext-3.0.2.tgz", + "integrity": "sha512-jA6kGdcUMZqLUgw6MdpyNWGFhk0LIITVhC/jTnLRZLoXSTR88qT2cFOn3LbY06udt1PVdTCHDG3plBjxVKf8BQ==", + "dev": true, + "requires": { + "autoprefixer": "7.1.6", + "caniuse-api": "2.0.0", + "chalk": "2.3.0", + "pixrem": "4.0.1", + "pleeease-filters": "4.0.0", + "postcss": "6.0.14", + "postcss-apply": "0.8.0", + "postcss-attribute-case-insensitive": "2.0.0", + "postcss-calc": "6.0.1", + "postcss-color-function": "4.0.1", + "postcss-color-gray": "4.0.0", + "postcss-color-hex-alpha": "3.0.0", + "postcss-color-hsl": "2.0.0", + "postcss-color-hwb": "3.0.0", + "postcss-color-rebeccapurple": "3.0.0", + "postcss-color-rgb": "2.0.0", + "postcss-color-rgba-fallback": "3.0.0", + "postcss-custom-media": "6.0.0", + "postcss-custom-properties": "6.2.0", + "postcss-custom-selectors": "4.0.1", + "postcss-font-family-system-ui": "2.1.1", + "postcss-font-variant": "3.0.0", + "postcss-image-set-polyfill": "0.3.5", + "postcss-initial": "2.0.0", + "postcss-media-minmax": "3.0.0", + "postcss-nesting": "4.2.1", + "postcss-pseudo-class-any-link": "4.0.0", + "postcss-pseudoelements": "5.0.0", + "postcss-replace-overflow-wrap": "2.0.0", + "postcss-selector-matches": "3.0.1", + "postcss-selector-not": "3.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "autoprefixer": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.1.6.tgz", + "integrity": "sha512-C9yv/UF3X+eJTi/zvfxuyfxmLibYrntpF3qoJYrMeQwgUJOZrZvpJiMG2FMQ3qnhWtF/be4pYONBBw95ZGe3vA==", + "dev": true, + "requires": { + "browserslist": "2.9.1", + "caniuse-lite": "1.0.30000775", + "normalize-range": "0.1.2", + "num2fraction": "1.2.2", + "postcss": "6.0.14", + "postcss-value-parser": "3.3.0" + } + }, + "browserslist": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.9.1.tgz", + "integrity": "sha512-3n3nPdbUqn3nWmsy4PeSQthz2ja1ndpoXta+dwFFNhveGjMg6FXpWYe12vsTpNoXJbzx3j7GZXdtoVIdvh3JbA==", + "dev": true, + "requires": { + "caniuse-lite": "1.0.30000775", + "electron-to-chromium": "1.3.27" + } + }, + "caniuse-api": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-2.0.0.tgz", + "integrity": "sha1-sd21pZZrFvSNxJmERNS7xsfZ2DQ=", + "dev": true, + "requires": { + "browserslist": "2.9.1", + "caniuse-lite": "1.0.30000775", + "lodash.memoize": "4.1.2", + "lodash.uniq": "4.5.0" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "postcss-calc": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-6.0.1.tgz", + "integrity": "sha1-PSQXG79udinUIqQ26/5t2VEfQzA=", + "dev": true, + "requires": { + "css-unit-converter": "1.1.1", + "postcss": "6.0.14", + "postcss-selector-parser": "2.2.3", + "reduce-css-calc": "2.1.3" + } + }, + "reduce-css-calc": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.3.tgz", + "integrity": "sha1-Y8TGMl/7v06mwj8dTetHw5U/O4E=", + "dev": true, + "requires": { + "css-unit-converter": "1.1.1", + "postcss-value-parser": "3.3.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-custom-media": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-6.0.0.tgz", + "integrity": "sha1-vlMnhBEOyylQRPtTlaGABushpzc=", + "dev": true, + "requires": { + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-custom-properties": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-6.2.0.tgz", + "integrity": "sha512-eNR2h9T9ciKMoQEORrPjH33XeN/nuvVuxArOKmHtsFbGbNss631tgTrKou3/pmjAZbA4QQkhLIkPQkIk3WW+8w==", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-custom-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-4.0.1.tgz", + "integrity": "sha1-eBOC+UxS5yfvXKR3bqKt9JphE4I=", + "dev": true, + "requires": { + "postcss": "6.0.14", + "postcss-selector-matches": "3.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, "postcss-discard-comments": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", @@ -3632,6 +5786,430 @@ "uniqid": "4.1.1" } }, + "postcss-font-family-system-ui": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-font-family-system-ui/-/postcss-font-family-system-ui-2.1.1.tgz", + "integrity": "sha512-AOAn553wVmMDx2nph0axVDXJwhsd9x4MjKHRH9SOXL4YdiqsYFxyTVTWnlka9iNB70Pb3Idxmj79bIXxq38b/w==", + "dev": true, + "requires": { + "@std/esm": "0.16.0", + "lodash": "4.17.4", + "postcss": "6.0.14", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-font-variant": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-3.0.0.tgz", + "integrity": "sha1-CMzIj2BQuoLtjvLMdsDGprQfGD4=", + "dev": true, + "requires": { + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-image-set-polyfill": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/postcss-image-set-polyfill/-/postcss-image-set-polyfill-0.3.5.tgz", + "integrity": "sha1-Dxk0E3AM8fgr05Bm7wFtZaShgYE=", + "dev": true, + "requires": { + "postcss": "6.0.14", + "postcss-media-query-parser": "0.2.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-initial": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-2.0.0.tgz", + "integrity": "sha1-cnFfczbgu3k1HZnuZcSiU6hEG6Q=", + "dev": true, + "requires": { + "lodash.template": "4.4.0", + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-load-config": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz", + "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=", + "dev": true, + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1", + "postcss-load-options": "1.2.0", + "postcss-load-plugins": "2.3.0" + } + }, + "postcss-load-options": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz", + "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=", + "dev": true, + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1" + } + }, + "postcss-load-plugins": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz", + "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=", + "dev": true, + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1" + } + }, + "postcss-loader": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.9.tgz", + "integrity": "sha512-sgoXPtmgVT3aBAhU47Kig8oPF+mbXl8Unjvtz1Qj1q2D2EvSVJW2mKJNzxv5y/LvA9xWwuvdysvhc7Zn80UWWw==", + "dev": true, + "requires": { + "loader-utils": "1.1.0", + "postcss": "6.0.14", + "postcss-load-config": "1.2.0", + "schema-utils": "0.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-media-minmax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-3.0.0.tgz", + "integrity": "sha1-Z1JWA3pD70C8Twdgv9BtTcadSNI=", + "dev": true, + "requires": { + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true + }, "postcss-merge-idents": { "version": "2.1.7", "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", @@ -3722,7 +6300,7 @@ "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=", "dev": true, "requires": { - "postcss": "6.0.13" + "postcss": "6.0.14" }, "dependencies": { "ansi-styles": { @@ -3731,18 +6309,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.0" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -3752,14 +6330,14 @@ "dev": true }, "postcss": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", - "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", "dev": true, "requires": { - "chalk": "2.1.0", + "chalk": "2.3.0", "source-map": "0.6.1", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "source-map": { @@ -3769,9 +6347,9 @@ "dev": true }, "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -3786,7 +6364,7 @@ "dev": true, "requires": { "css-selector-tokenizer": "0.7.0", - "postcss": "6.0.13" + "postcss": "6.0.14" }, "dependencies": { "ansi-styles": { @@ -3795,18 +6373,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.0" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -3816,14 +6394,14 @@ "dev": true }, "postcss": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", - "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", "dev": true, "requires": { - "chalk": "2.1.0", + "chalk": "2.3.0", "source-map": "0.6.1", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "source-map": { @@ -3833,9 +6411,9 @@ "dev": true }, "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -3850,7 +6428,7 @@ "dev": true, "requires": { "css-selector-tokenizer": "0.7.0", - "postcss": "6.0.13" + "postcss": "6.0.14" }, "dependencies": { "ansi-styles": { @@ -3859,18 +6437,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.0" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -3880,14 +6458,14 @@ "dev": true }, "postcss": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", - "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", "dev": true, "requires": { - "chalk": "2.1.0", + "chalk": "2.3.0", "source-map": "0.6.1", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "source-map": { @@ -3897,9 +6475,9 @@ "dev": true }, "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -3914,7 +6492,7 @@ "dev": true, "requires": { "icss-replace-symbols": "1.1.0", - "postcss": "6.0.13" + "postcss": "6.0.14" }, "dependencies": { "ansi-styles": { @@ -3923,18 +6501,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.0" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -3944,14 +6522,14 @@ "dev": true }, "postcss": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", - "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", "dev": true, "requires": { - "chalk": "2.1.0", + "chalk": "2.3.0", "source-map": "0.6.1", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "source-map": { @@ -3961,9 +6539,148 @@ "dev": true }, "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-nested": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-2.1.2.tgz", + "integrity": "sha512-CU7KjbFOZSNrbFwrl8+KJHTj29GjCEhL86kCKyvf+k633fc+FQA6IuhGyPze5e+a4O5d2fP7hDlMOlVDXia1Xg==", + "dev": true, + "requires": { + "postcss": "6.0.14", + "postcss-selector-parser": "2.2.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-nested-ancestors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postcss-nested-ancestors/-/postcss-nested-ancestors-1.0.0.tgz", + "integrity": "sha1-t+Li5K67vBRWqa35KD9spcOmHeM=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1", + "postcss": "5.2.18", + "postcss-resolve-nested-selector": "0.1.1" + } + }, + "postcss-nesting": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-4.2.1.tgz", + "integrity": "sha512-IkyWXICwagCnlaviRexi7qOdwPw3+xVVjgFfGsxmztvRVaNxAlrypOIKqDE5mxY+BVxnId1rnUKBRQoNE2VDaA==", + "dev": true, + "requires": { + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -4002,6 +6719,133 @@ "postcss-value-parser": "3.3.0" } }, + "postcss-pseudo-class-any-link": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-4.0.0.tgz", + "integrity": "sha1-kVKgYT00UHIFE+iJKFS65C0O5o4=", + "dev": true, + "requires": { + "postcss": "6.0.14", + "postcss-selector-parser": "2.2.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-pseudoelements": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-pseudoelements/-/postcss-pseudoelements-5.0.0.tgz", + "integrity": "sha1-7vGU6NUkZFylIKlJ6V5RjoEkAss=", + "dev": true, + "requires": { + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, "postcss-reduce-idents": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", @@ -4032,6 +6876,289 @@ "postcss-value-parser": "3.3.0" } }, + "postcss-replace-overflow-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-2.0.0.tgz", + "integrity": "sha1-eU22+qVPjbEAhUOSqTr0V2i04ls=", + "dev": true, + "requires": { + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "dev": true + }, + "postcss-sass": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.1.0.tgz", + "integrity": "sha1-DSplW10kHsj0Gbs9o43lyhF0bds=", + "dev": true, + "requires": { + "gonzales-pe": "4.2.3", + "mathjs": "3.17.0", + "postcss": "5.2.18" + } + }, + "postcss-scss": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-1.0.2.tgz", + "integrity": "sha1-/0XPM1S4ee6JpOtoaA9GrJuxT5Q=", + "dev": true, + "requires": { + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-selector-matches": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-3.0.1.tgz", + "integrity": "sha1-5WNAEeE5UIgYYbvdWMLQER/8lqs=", + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-selector-not": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-3.0.1.tgz", + "integrity": "sha1-Lk2y8JZTNsAefOx9tsYN/3ZzNdk=", + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, "postcss-selector-parser": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", @@ -4043,6 +7170,79 @@ "uniq": "1.0.1" } }, + "postcss-smart-import": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/postcss-smart-import/-/postcss-smart-import-0.7.5.tgz", + "integrity": "sha512-Bs9wAFxH5irGpenBg9a65jTcydZLh7VBTX6NYwMXvVXO6y9CQ83kRmfpQDs5lHhl6IODeIeQfJep5HBMd9UVCQ==", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "lodash": "4.17.4", + "object-assign": "4.1.1", + "postcss": "6.0.14", + "postcss-sass": "0.1.0", + "postcss-scss": "1.0.2", + "postcss-value-parser": "3.3.0", + "promise-each": "2.2.0", + "read-cache": "1.0.0", + "resolve": "1.5.0", + "sugarss": "1.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, "postcss-svgo": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", @@ -4120,17 +7320,45 @@ "dev": true }, "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", "dev": true }, + "promise-each": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/promise-each/-/promise-each-2.2.0.tgz", + "integrity": "sha1-M1MXTv8mlEgQN+BOAfd6oPttG2A=", + "dev": true, + "requires": { + "any-promise": "0.1.0" + } + }, "prr": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", "dev": true }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", + "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "parse-asn1": "5.1.0", + "randombytes": "2.0.5" + } + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -4138,9 +7366,9 @@ "dev": true }, "q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", - "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", "dev": true }, "query-string": { @@ -4190,7 +7418,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -4201,7 +7429,75 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" + } + } + } + }, + "randombytes": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", + "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "randomfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz", + "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==", + "dev": true, + "requires": { + "randombytes": "2.0.5", + "safe-buffer": "5.1.1" + } + }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", + "dev": true, + "requires": { + "pify": "2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" } } } @@ -4233,26 +7529,6 @@ "set-immediate-shim": "1.0.1" } }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "mute-stream": "0.0.5" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "1.4.0" - } - }, "reduce-css-calc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", @@ -4382,6 +7658,24 @@ "is-finite": "1.0.2" } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, "require-uncached": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", @@ -4393,9 +7687,9 @@ } }, "resolve": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", - "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", "dev": true, "requires": { "path-parse": "1.0.5" @@ -4408,15 +7702,27 @@ "dev": true }, "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" + "onetime": "2.0.1", + "signal-exit": "3.0.2" } }, + "rgb": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/rgb/-/rgb-0.1.0.tgz", + "integrity": "sha1-vieykej+/+rBvZlylyG/pA/AN7U=", + "dev": true + }, + "rgb-hex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/rgb-hex/-/rgb-hex-2.1.0.tgz", + "integrity": "sha1-x3PF/iJoolV42SU5qCp6XOU77aY=", + "dev": true + }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", @@ -4436,26 +7742,39 @@ } }, "ripemd160": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-0.2.0.tgz", - "integrity": "sha1-K/GYveFnys+lHAqSjoS2i74XH84=", - "dev": true - }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", "dev": true, "requires": { - "once": "1.4.0" + "hash-base": "2.0.2", + "inherits": "2.0.3" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "2.1.0" } }, "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", "dev": true }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "4.0.8" + } + }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", @@ -4468,6 +7787,45 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, + "schema-utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", + "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "requires": { + "ajv": "5.5.0" + }, + "dependencies": { + "ajv": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.0.tgz", + "integrity": "sha1-6yhAdG6dxIvV4GOjbj/UAMXqtak=", + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + } + } + }, + "seed-random": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/seed-random/-/seed-random-2.2.0.tgz", + "integrity": "sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ=", + "dev": true + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, "set-immediate-shim": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", @@ -4481,20 +7839,43 @@ "dev": true }, "sha.js": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.2.6.tgz", - "integrity": "sha1-F93t3F9yL7ZlAWWIlUYZd4ZzFbo=", - "dev": true - }, - "shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", + "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==", "dev": true, "requires": { - "glob": "7.1.2", - "interpret": "1.0.4", - "rechoir": "0.6.2" + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dev": true, + "requires": { + "is-arrayish": "0.3.1" } }, "slash": { @@ -4504,10 +7885,13 @@ "dev": true }, "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0" + } }, "sort-keys": { "version": "1.1.2", @@ -4519,9 +7903,9 @@ } }, "source-list-map": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", - "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", "dev": true }, "source-map": { @@ -4539,6 +7923,27 @@ "source-map": "0.5.7" } }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -4575,14 +7980,30 @@ "dev": true }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } } }, "string_decoder": { @@ -4609,12 +8030,102 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, + "style-loader": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.0.tgz", + "integrity": "sha512-9mx9sC9nX1dgP96MZOODpGC6l1RzQBITI2D5WJhu+wnbrSYVKLGuy14XJSLVQih/0GFrPpjelt+s//VcZQ2Evw==", + "requires": { + "loader-utils": "1.1.0", + "schema-utils": "0.3.0" + }, + "dependencies": { + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "requires": { + "big.js": "3.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1" + } + } + } + }, + "sugarss": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-1.0.1.tgz", + "integrity": "sha512-3qgLZytikQQEVn1/FrhY7B68gPUUGY3R1Q1vTiD5xT+Ti1DP/8iZuwFet9ONs5+bmL8pZoDQ6JrQHVgrNlK6mA==", + "dev": true, + "requires": { + "postcss": "6.0.14" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -4637,56 +8148,60 @@ } }, "table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", + "ajv": "5.5.0", + "ajv-keywords": "2.1.1", + "chalk": "2.3.0", "lodash": "4.17.4", - "slice-ansi": "0.0.4", + "slice-ansi": "1.0.0", "string-width": "2.1.1" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" + "color-convert": "1.9.1" } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" } } } }, "tapable": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", - "integrity": "sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=", + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", + "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=", "dev": true }, "text-table": { @@ -4710,6 +8225,21 @@ "setimmediate": "1.0.5" } }, + "tiny-emitter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.0.tgz", + "integrity": "sha1-utMnrbGAS0KiMa+nQVMr2ITNCa0=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" + } + }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -4749,6 +8279,12 @@ "prelude-ls": "1.1.2" } }, + "typed-function": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-0.10.6.tgz", + "integrity": "sha512-PYtsDjxyW3vq7Itn2RMz0cn6CrbybIY6XC2i9c1q1o/H94QW8B1Pf3wSsbBDOCMpN1i5jDRrlDsLXFaqXBpfHQ==", + "dev": true + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -4756,22 +8292,27 @@ "dev": true }, "uglify-js": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.7.5.tgz", - "integrity": "sha1-RhLAx7qu4rp8SH3kkErhIgefLKg=", + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", "dev": true, "requires": { - "async": "0.2.10", "source-map": "0.5.7", "uglify-to-browserify": "1.0.2", "yargs": "3.10.0" }, "dependencies": { - "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", - "dev": true + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } } } }, @@ -4779,7 +8320,19 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "dev": true + "dev": true, + "optional": true + }, + "uglifyjs-webpack-plugin": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", + "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", + "dev": true, + "requires": { + "source-map": "0.5.7", + "uglify-js": "2.8.29", + "webpack-sources": "1.1.0" + } }, "uniq": { "version": "1.0.1", @@ -4802,6 +8355,16 @@ "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", "dev": true }, + "units-css": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/units-css/-/units-css-0.4.0.tgz", + "integrity": "sha1-1iKGU6UZg9fBb/KPi53Dsf/tOgc=", + "dev": true, + "requires": { + "isnumeric": "0.2.0", + "viewport-dimensions": "0.2.0" + } + }, "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", @@ -4820,15 +8383,6 @@ } } }, - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", - "dev": true, - "requires": { - "os-homedir": "1.0.2" - } - }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", @@ -4852,12 +8406,28 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, "vendors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz", "integrity": "sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=", "dev": true }, + "viewport-dimensions": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/viewport-dimensions/-/viewport-dimensions-0.2.0.tgz", + "integrity": "sha1-3nQHR9tTh/0XJfUXXpG6x2r982w=", + "dev": true + }, "vm-browserify": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", @@ -4868,99 +8438,79 @@ } }, "watchpack": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-0.2.9.tgz", - "integrity": "sha1-Yuqkq15bo1/fwBgnVibjwPXj+ws=", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz", + "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", "dev": true, "requires": { - "async": "0.9.2", + "async": "2.6.0", "chokidar": "1.7.0", "graceful-fs": "4.1.11" - }, - "dependencies": { - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", - "dev": true - } } }, "webpack": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-1.15.0.tgz", - "integrity": "sha1-T/MfU9sDM55VFkqdRo7gMklo/pg=", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.9.0.tgz", + "integrity": "sha512-SlBO3yUIhSohW7uCA5c0v03V32DsaXU3vDyUtHB8rubgTgfwl1nv+I+BQIScuQ6exu74wWT6brF/GDXxGLStuA==", "dev": true, "requires": { - "acorn": "3.3.0", - "async": "1.5.2", - "clone": "1.0.2", - "enhanced-resolve": "0.9.1", - "interpret": "0.6.6", - "loader-utils": "0.2.17", - "memory-fs": "0.3.0", + "acorn": "5.2.1", + "acorn-dynamic-import": "2.0.2", + "ajv": "5.5.0", + "ajv-keywords": "2.1.1", + "async": "2.6.0", + "enhanced-resolve": "3.4.1", + "escope": "3.6.0", + "interpret": "1.1.0", + "json-loader": "0.5.7", + "json5": "0.5.1", + "loader-runner": "2.3.0", + "loader-utils": "1.1.0", + "memory-fs": "0.4.1", "mkdirp": "0.5.1", - "node-libs-browser": "0.7.0", - "optimist": "0.6.1", - "supports-color": "3.2.3", - "tapable": "0.1.10", - "uglify-js": "2.7.5", - "watchpack": "0.2.9", - "webpack-core": "0.6.9" + "node-libs-browser": "2.1.0", + "source-map": "0.5.7", + "supports-color": "4.5.0", + "tapable": "0.2.8", + "uglifyjs-webpack-plugin": "0.4.6", + "watchpack": "1.4.0", + "webpack-sources": "1.1.0", + "yargs": "8.0.2" }, "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - }, - "interpret": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-0.6.6.tgz", - "integrity": "sha1-/s16GOfOXKar+5U+H4YhOknxYls=", + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { - "has-flag": "1.0.0" - } - } - } - }, - "webpack-core": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz", - "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=", - "dev": true, - "requires": { - "source-list-map": "0.1.8", - "source-map": "0.4.4" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": "1.0.1" + "has-flag": "2.0.0" } } } }, "webpack-sources": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-0.1.5.tgz", - "integrity": "sha1-qh86vw8NdNtxEcQOUAuE+WZkB1A=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", + "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", "dev": true, "requires": { - "source-list-map": "0.1.8", - "source-map": "0.5.7" + "source-list-map": "2.0.0", + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "whet.extend": { @@ -4969,6 +8519,21 @@ "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=", "dev": true }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", @@ -4981,6 +8546,38 @@ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", "dev": true }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -5002,16 +8599,95 @@ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", "dev": true }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", "dev": true, "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", + "camelcase": "4.1.0", + "cliui": "3.2.0", "decamelize": "1.2.0", - "window-size": "0.1.0" + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "read-pkg-up": "2.0.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "7.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + } + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } } } } diff --git a/package.json b/package.json index 8627987d..89c868c2 100644 --- a/package.json +++ b/package.json @@ -4,22 +4,41 @@ "description": "Codex Editor. Native JS, based on API and Open Source", "main": "index.js", "scripts": { - "build": "webpack" + "build": "webpack --progress --display-error-details --display-entrypoints --display-reasons" }, "author": "Codex Team", "license": "ISC", "devDependencies": { - "babel-core": "^6.21.0", - "babel-loader": "^6.2.10", - "babel-polyfill": "^6.20.0", - "babel-preset-es2015": "^6.22.0", - "babel-runtime": "^6.20.0", - "css-loader": "^0.26.1", - "eslint": "^3.12.2", - "eslint-loader": "^1.6.1", - "extract-text-webpack-plugin": "^1.0.1", + "babel-core": "^6.26.0", + "babel-loader": "^7.1.2", + "babel-plugin-class-display-name": "^2.1.0", + "babel-polyfill": "^6.26.0", + "babel-preset-es2015": "^6.24.1", + "babel-runtime": "^6.26.0", + "css-loader": "^0.28.7", + "eslint": "^4.11.0", + "eslint-loader": "^1.9.0", + "extract-text-webpack-plugin": "^3.0.2", "html-janitor": "^2.0.2", "path": "^0.12.7", - "webpack": "^1.14.0" + "postcss-apply": "^0.8.0", + "postcss-color-function": "^4.0.1", + "postcss-color-hex-alpha": "^3.0.0", + "postcss-cssnext": "^3.0.2", + "postcss-custom-media": "^6.0.0", + "postcss-custom-properties": "^6.2.0", + "postcss-custom-selectors": "^4.0.1", + "postcss-font-family-system-ui": "^2.1.1", + "postcss-font-variant": "^3.0.0", + "postcss-loader": "^2.0.9", + "postcss-media-minmax": "^3.0.0", + "postcss-nested": "^2.1.2", + "postcss-nested-ancestors": "^1.0.0", + "postcss-nesting": "^4.2.1", + "postcss-smart-import": "^0.7.5", + "webpack": "^3.8.1" + }, + "dependencies": { + "style-loader": "^0.19.0" } } diff --git a/src/codex.js b/src/codex.js index 51370331..e1e8156c 100644 --- a/src/codex.js +++ b/src/codex.js @@ -54,6 +54,7 @@ /** * Require Editor modules places in components/modules dir */ +// eslint-disable-next-line let modules = editorModules.map( module => { return require('./components/modules/' + module ); @@ -174,7 +175,15 @@ module.exports = class CodexEditor { try { - this.moduleInstances[Module.name] = new Module({ + /** + * 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 + */ + + this.moduleInstances[Module.displayName] = new Module({ config : this.configuration }); @@ -211,7 +220,7 @@ module.exports = class CodexEditor { */ getModulesDiff( name ) { - let modules = {}; + let diff = {}; for(let moduleName in this.moduleInstances) { @@ -223,11 +232,11 @@ module.exports = class CodexEditor { continue; } - modules[moduleName] = this.moduleInstances[moduleName]; + diff[moduleName] = this.moduleInstances[moduleName]; } - return modules; + return diff; } @@ -241,7 +250,7 @@ module.exports = class CodexEditor { let prepareDecorator = module => module.prepare(); return Promise.resolve() - .then(prepareDecorator(this.moduleInstances.ui)) + .then(prepareDecorator(this.moduleInstances.UI)) .then(prepareDecorator(this.moduleInstances.Tools)) .then(prepareDecorator(this.moduleInstances.BlockManager)) diff --git a/src/components/dom.js b/src/components/dom.js index 978b007c..42f930f1 100644 --- a/src/components/dom.js +++ b/src/components/dom.js @@ -91,4 +91,5 @@ export default class Dom { return node && typeof node === 'object' && node.nodeType && node.nodeType === Node.ELEMENT_NODE; } + }; \ No newline at end of file diff --git a/src/components/modules/_callbacks.js b/src/components/modules/_callbacks.js index 443759ba..534e0705 100644 --- a/src/components/modules/_callbacks.js +++ b/src/components/modules/_callbacks.js @@ -18,7 +18,9 @@ module.exports = (function (callbacks) { callbacks.globalKeydown = function (event) { switch (event.keyCode) { + case editor.core.keys.ENTER : enterKeyPressed_(event); break; + } }; @@ -31,10 +33,12 @@ module.exports = (function (callbacks) { 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; + } }; @@ -47,10 +51,12 @@ module.exports = (function (callbacks) { 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; + } }; diff --git a/src/components/modules/_saver.js b/src/components/modules/_saver.js index d3358931..024a11a0 100644 --- a/src/components/modules/_saver.js +++ b/src/components/modules/_saver.js @@ -52,12 +52,12 @@ module.exports = (function (saver) { let getBlockData = function (block) { return saveBlockData(block) - .then(validateBlockData) - .catch(editor.core.log); + .then(validateBlockData) + .catch(editor.core.log); }; - /** + /** * @private * Call block`s plugin save method and return saved data * @@ -102,7 +102,7 @@ module.exports = (function (saver) { }; - /** + /** * Call plugin`s validate method. Return false if validation failed * * @param data @@ -137,7 +137,7 @@ module.exports = (function (saver) { }; - /** + /** * Compile article output * * @param savedData diff --git a/src/components/modules/blockManager.js b/src/components/modules/blockManager.js index 44fbf259..8aaa69c4 100644 --- a/src/components/modules/blockManager.js +++ b/src/components/modules/blockManager.js @@ -1,14 +1,12 @@ /** * @class BlockManager * @classdesc Manage editor`s blocks storage and appearance - * - * */ import Block from '../block'; import Util from '../util'; -module.exports = class BlockManager { +class BlockManager { /** * @constructor @@ -20,7 +18,7 @@ module.exports = class BlockManager { this.config = config; this.Editor = null; this._blocks = null; - this._currentBloсkIndex = -1; + this._currentBlockIndex = -1; } @@ -36,7 +34,7 @@ module.exports = class BlockManager { } /** - * Should be called after Editor.ui preparation + * Should be called after Editor.UI preparation * Define this._blocks property * * @returns {Promise} @@ -45,7 +43,7 @@ module.exports = class BlockManager { return new Promise(resolve => { - let blocks = new Blocks(this.Editor.ui.nodes.redactor); + let blocks = new Blocks(this.Editor.UI.nodes.redactor); /** * We need to use Proxy to overload set/get [] operator. @@ -83,7 +81,7 @@ module.exports = class BlockManager { let toolInstance = this.Editor.Tools.construct(toolName, data), block = new Block(toolInstance); - this._blocks[++this._currentBloсkIndex] = block; + this._blocks[++this._currentBlockIndex] = block; } @@ -115,7 +113,7 @@ module.exports = class BlockManager { */ get currentBlock() { - return this._blocks[this._currentBloсkIndex]; + return this._blocks[this._currentBlockIndex]; } @@ -126,7 +124,7 @@ module.exports = class BlockManager { */ get currentNode() { - return this._blocks.nodes[this._currentBloсkIndex]; + return this._blocks.nodes[this._currentBlockIndex]; } @@ -141,7 +139,7 @@ module.exports = class BlockManager { let nodes = this._blocks.nodes; - this._currentBloсkIndex = nodes.indexOf(element); + this._currentBlockIndex = nodes.indexOf(element); } @@ -350,4 +348,6 @@ class Blocks { } -} \ No newline at end of file +} + +module.exports = BlockManager; \ No newline at end of file diff --git a/src/components/modules/eventDispatcher.js b/src/components/modules/events.js similarity index 90% rename from src/components/modules/eventDispatcher.js rename to src/components/modules/events.js index b673a988..67e42563 100644 --- a/src/components/modules/eventDispatcher.js +++ b/src/components/modules/events.js @@ -7,17 +7,7 @@ * * @version 1.0.0 */ -module.exports = class Events { - - /** - * Module key name - * @returns {string} - */ - static get name() { - - return 'Events'; - - } +class Events { /** * @param Editor @@ -85,4 +75,6 @@ module.exports = class Events { } -}; +} + +module.exports = Events; diff --git a/src/components/modules/renderer.js b/src/components/modules/renderer.js index 6b29cb09..c54d6583 100644 --- a/src/components/modules/renderer.js +++ b/src/components/modules/renderer.js @@ -7,7 +7,7 @@ import Util from '../util'; -module.exports = class Renderer { +class Renderer { /** * @constructor @@ -74,7 +74,9 @@ module.exports = class Renderer { } -}; +} + +module.exports = Renderer; // module.exports = (function (renderer) { // diff --git a/src/components/modules/toolbar.js b/src/components/modules/toolbar.js index 1bba3192..97b3fb54 100644 --- a/src/components/modules/toolbar.js +++ b/src/components/modules/toolbar.js @@ -55,12 +55,6 @@ import $ from '../dom'; */ class Toolbar { - static get name() { - - return 'Toolbar'; - - } - /** * @constructor */ @@ -167,7 +161,7 @@ class Toolbar { /** * Append toolbar to the Editor */ - $.append(this.Editor.ui.nodes.wrapper, this.nodes.wrapper); + $.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper); } diff --git a/src/components/modules/toolbar/inline.js b/src/components/modules/toolbar/inline.js index 0ba41a62..e785f0c1 100644 --- a/src/components/modules/toolbar/inline.js +++ b/src/components/modules/toolbar/inline.js @@ -121,8 +121,10 @@ module.exports = (function (inline) { * 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; + } /** diff --git a/src/components/modules/tools.js b/src/components/modules/tools.js index ed53f43b..d63e0541 100644 --- a/src/components/modules/tools.js +++ b/src/components/modules/tools.js @@ -36,13 +36,7 @@ */ let util = require('../util'); -module.exports = class Tools { - - static get name() { - - return 'Tools'; - - } +class Tools { /** * Returns available Tools @@ -110,8 +104,6 @@ module.exports = class Tools { */ prepare() { - let self = this; - if (!this.config.hasOwnProperty('tools')) { return Promise.reject("Can't start without tools"); @@ -230,4 +222,6 @@ module.exports = class Tools { } -}; +} + +module.exports = Tools; diff --git a/src/components/modules/ui.js b/src/components/modules/ui.js index 0c0b2fbb..dd522db9 100644 --- a/src/components/modules/ui.js +++ b/src/components/modules/ui.js @@ -5,30 +5,30 @@ */ // let className = { - /** +/** * @const {string} BLOCK_CLASSNAME - redactor blocks name */ - // BLOCK_CLASSNAME : 'ce-block', +// BLOCK_CLASSNAME : 'ce-block', - /** +/** * @const {String} wrapper for plugins content */ - // BLOCK_CONTENT : 'ce-block__content', +// BLOCK_CONTENT : 'ce-block__content', - /** +/** * @const {String} BLOCK_STRETCHED - makes block stretched */ - // BLOCK_STRETCHED : 'ce-block--stretched', +// BLOCK_STRETCHED : 'ce-block--stretched', - /** +/** * @const {String} BLOCK_HIGHLIGHTED - adds background */ - // BLOCK_HIGHLIGHTED : 'ce-block--focused', +// BLOCK_HIGHLIGHTED : 'ce-block--focused', - /** +/** * @const {String} - for all default settings */ - // SETTINGS_ITEM : 'ce-settings__item' +// SETTINGS_ITEM : 'ce-settings__item' // }; let CSS = { @@ -57,17 +57,7 @@ import $ from '../dom'; * @property {Element} nodes.wrapper - * @property {Element} nodes.redactor - */ -module.exports = class UI { - - /** - * Module key name - * @returns {string} - */ - static get name() { - - return 'ui'; - - } +class UI { /** * @constructor @@ -134,6 +124,11 @@ module.exports = class UI { */ this.Editor.Toolbar.make(); + /** + * Load and append CSS + */ + this.loadStyles(); + resolve(); }) @@ -153,17 +148,42 @@ module.exports = class UI { /** Add eventlisteners to redactor elements */ // .then(bindEvents_) - .catch(e => { + .catch(e => { - console.error(e); + console.error(e); // editor.core.log("Can't draw editor interface"); - }); + }); } -}; + loadStyles() { + + /** + * Load CSS + */ + let styles = require('../../styles/main.css'); + + /** + * Make tag + */ + let tag = $.make('style', null, { + textContent: styles.toString() + }); + + /** + * Append styles + */ + $.append(document.head, tag); + + } + +} + +module.exports = UI; + + // /** // * Codex Editor UI module // * diff --git a/src/components/util.js b/src/components/util.js index 26b33a18..fb902e7c 100644 --- a/src/components/util.js +++ b/src/components/util.js @@ -20,7 +20,7 @@ module.exports = class Util { */ static sequence(chains, success = () => {}, fallback = () => {}) { - return new Promise(function (resolve, reject) { + return new Promise(function (resolve) { /** * pluck each element from queue @@ -60,7 +60,7 @@ module.exports = class Util { */ function waitNextBlock(chainData, success, fallback) { - return new Promise(function (resolve, reject) { + return new Promise(function (resolve) { chainData.function() .then(() => { diff --git a/src/styles/_legacy.css b/src/styles/_legacy.css new file mode 100644 index 00000000..6b72d89e --- /dev/null +++ b/src/styles/_legacy.css @@ -0,0 +1,628 @@ +/** +* Editor wrapper +*/ +.codex-editor{ + position: relative; + border: 1px solid #ccc; + padding: 10px; + + .hide { + display: none; + } +} + + + +/** +* Working zone - redactor +*/ +.ce-redactor{ + position: relative; + padding-bottom: 120px; + min-height: 350px; + border: 1px dotted #ccc; +} + +.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-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-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/src/styles/main.css b/src/styles/main.css index e69de29b..fcb4a15f 100644 --- a/src/styles/main.css +++ b/src/styles/main.css @@ -0,0 +1,2 @@ +@import url('variables.css'); +@import url('ui.css'); diff --git a/src/styles/ui.css b/src/styles/ui.css new file mode 100644 index 00000000..b9f48b47 --- /dev/null +++ b/src/styles/ui.css @@ -0,0 +1,12 @@ +/** +* Editor wrapper +*/ +.codex-editor{ + position: relative; + border: 1px solid #ccc; + padding: 10px; + + .hide { + display: none; + } +} diff --git a/src/styles/variables.css b/src/styles/variables.css new file mode 100644 index 00000000..a626836b --- /dev/null +++ b/src/styles/variables.css @@ -0,0 +1,8 @@ +:root { + + /** + * Toolbar buttons + */ + --bg-light: #eff2f5; + +} \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index 38b8b226..d908d136 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -20,8 +20,8 @@ const VERSION = process.env.VERSION || pkg.version; * Plugins for bundle * @type {webpack} */ -var webpack = require('webpack'); -var ExtractTextWebpackPlugin = require('extract-text-webpack-plugin'); +var webpack = require('webpack'); +var ExtractTextPlugin = require('extract-text-webpack-plugin'); var fs = require('fs'); @@ -52,22 +52,25 @@ module.exports = { watch: true, watchOptions: { - aggregateTimeOut: 50 + aggregateTimeout: 50 }, devtool: NODE_ENV == 'development' ? 'source-map' : null, + /** + * Tell webpack what directories should be searched when resolving modules. + */ resolve : { - fallback: path.join(__dirname, 'node_modules'), - modulesDirectories : [ './modules' ], - extensions : ['', '.js', '.json'] + // fallback: path.join(__dirname, 'node_modules'), + modules : [ path.join(__dirname, "src"), "node_modules"] }, + // - resolveLoader : { - modulesDirectories: [ './node_modules' ], - moduleTemplates: ['*-webpack-loader', '*-web-loader', '*-loader', '*'], - extensions: ['', '.js'] - }, + // resolveLoader : { + // modules: [ path.resolve(__dirname, "src"), "node_modules" ], + // moduleTemplates: ['*-webpack-loader', '*-web-loader', '*-loader', '*'], + // extensions: ['.js'] + // }, plugins: [ @@ -92,24 +95,47 @@ module.exports = { ], module : { - - loaders : [ { - test : /\.js$/, - exclude: /node_modules/, - loader : 'babel', - query: { - presets: [ __dirname + '/node_modules/babel-preset-es2015' ] + rules : [ + { + test : /\.js$/, + exclude: /node_modules/, + use : { + loader: 'babel-loader', + options: { + presets: [ __dirname + '/node_modules/babel-preset-es2015' ], + plugins: ['class-display-name'] + } + } + }, + { + test : /\.js$/, + use: 'eslint-loader?fix=true', + exclude: /node_modules/ + }, + { + test: /\.css$/, + exclude: /node_modules/, + use: [ + { + loader: 'css-loader', + options: { + // minimize: 1, + importLoaders: 1 + } + }, + 'postcss-loader' + ] + // use: ExtractTextPlugin.extract([ + // { + // loader: 'css-loader', + // options: { + // // minimize: 1, + // importLoaders: 1 + // } + // }, + // 'postcss-loader' + // ]) } - }, - { - test : /\.js$/, - loader: 'eslint-loader?fix=true', - exclude: /node_modules/ - }, - { - test : /\.css$/, - exclude: /node_modules/, - loader: ExtractTextWebpackPlugin.extract('style-loader', 'css-loader') - } ] + ] } }; \ No newline at end of file