diff --git a/build/codex-editor.js b/build/codex-editor.js
index 3d467aff..e69de29b 100644
--- a/build/codex-editor.js
+++ b/build/codex-editor.js
@@ -1,6551 +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] = {
-/******/ 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.l = 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;
-/******/
-/******/ // define getter function for harmony exports
-/******/ __webpack_require__.d = function(exports, name, getter) {
-/******/ if(!__webpack_require__.o(exports, name)) {
-/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
-/******/ }
-/******/ };
-/******/
-/******/ // define __esModule on exports
-/******/ __webpack_require__.r = function(exports) {
-/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
-/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
-/******/ }
-/******/ Object.defineProperty(exports, '__esModule', { value: true });
-/******/ };
-/******/
-/******/ // create a fake namespace object
-/******/ // mode & 1: value is a module id, require it
-/******/ // mode & 2: merge all properties of value into the ns
-/******/ // mode & 4: return value when already ns object
-/******/ // mode & 8|1: behave like require
-/******/ __webpack_require__.t = function(value, mode) {
-/******/ if(mode & 1) value = __webpack_require__(value);
-/******/ if(mode & 8) return value;
-/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
-/******/ var ns = Object.create(null);
-/******/ __webpack_require__.r(ns);
-/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
-/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
-/******/ return ns;
-/******/ };
-/******/
-/******/ // 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__(__webpack_require__.s = "./src/codex.js");
-/******/ })
-/************************************************************************/
-/******/ ({
-
-/***/ "./node_modules/css-loader/lib/css-base.js":
-/*!*************************************************!*\
- !*** ./node_modules/css-loader/lib/css-base.js ***!
- \*************************************************/
-/*! no static exports found */
-/***/ (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("");
- };
-
- // 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 + ' */';
-}
-
-
-/***/ }),
-
-/***/ "./node_modules/html-janitor/src/html-janitor.js":
-/*!*******************************************************!*\
- !*** ./node_modules/html-janitor/src/html-janitor.js ***!
- \*******************************************************/
-/*! no static exports found */
-/***/ (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 {}
-}(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;
-
-}));
-
-
-/***/ }),
-
-/***/ "./src/codex.js":
-/*!**********************!*\
- !*** ./src/codex.js ***!
- \**********************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(_) {/**
- * Codex Editor
- *
- * Short Description (눈_눈;)
- * @version 2.0.0
- *
- * How to start?
- * Example:
- * new CodexEditor({
- * holderId : 'codex-editor',
- * initialBlock : 'text',
- * 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
- * @property {Array} data - Blocks list in JSON-format
- * @property {Object} tools - Map for used Tools in format { name : Class, ... }
- * @property {String} initialBlock - This Tool will be added by default
- * @property {String} placeholder - First Block placeholder
- * @property {Object} sanitizer - @todo fill desc
- * @property {Boolean} hideToolbar - @todo fill desc
- * @property {Object} toolsConfig - tools configuration {@link tools#ToolConfig}
- */
-
-/**
- * Dynamically imported utils
- *
- * @typedef {Dom} $ - {@link components/dom.js}
- * @typedef {Util} _ - {@link components/utils.js}
- */
-
-
-
-/**
- * Apply polyfills
- */
-
-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; }; }();
-
-__webpack_require__(/*! components/polyfills */ "./src/components/polyfills.js");
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-/**
- * Require Editor modules places in components/modules dir
- */
-// eslint-disable-next-line
-var modules = ["api-blocks.ts","api-sanitizer.ts","api.ts","blockManager.js","caret.js","events.js","keyboard.js","listeners.js","renderer.js","sanitizer.js","saver.js","toolbar-blockSettings.js","toolbar-inline.ts","toolbar-toolbox.js","toolbar.js","tools.js","ui.js"].map(function (module) {
- return __webpack_require__("./src/components/modules sync [^_](api-blocks.ts|api-sanitizer.ts|api.ts|blockManager.js|caret.js|events.js|keyboard.js|listeners.js|renderer.js|sanitizer.js|saver.js|toolbar-blockSettings.js|toolbar-inline.ts|toolbar-toolbox.js|toolbar.js|tools.js|ui.js)$")("./" + module);
-});
-
-/**
- * @class
- *
- * @classdesc CodeX Editor base class
- *
- * @property this.config - all settings
- * @property this.moduleInstances - constructed editor components
- *
- * @type {CodexEditor}
- */
-
-var CodexEditor = 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
- * @type {EditorConfig}
- */
- this.config = {};
-
- /**
- * @typedef {Object} EditorComponents
- * @property {BlockManager} BlockManager
- * @property {Tools} Tools
- * @property {Events} Events
- * @property {UI} UI
- * @property {Toolbar} Toolbar
- * @property {Toolbox} Toolbox
- * @property {BlockSettings} BlockSettings
- * @property {Renderer} Renderer
- * @property {InlineToolbar} InlineToolbar
- */
- 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 because of %o', error);
- });
- }
-
- /**
- * Setting for configuration
- * @param {EditorConfig} 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!
- *
- * Get list of modules that needs to be prepared and return a sequence (Promise)
- * @return {Promise}
- */
-
- }, {
- key: 'start',
- value: function start() {
- var _this3 = this;
-
- var prepareDecorator = function prepareDecorator(module) {
- return module.prepare();
- };
-
- return Promise.resolve().then(prepareDecorator(this.moduleInstances.Tools)).then(prepareDecorator(this.moduleInstances.UI)).then(prepareDecorator(this.moduleInstances.BlockManager)).then(function () {
- return _this3.moduleInstances.Renderer.render(_this3.config.data.items);
- });
- }
- }, {
- key: 'configuration',
- set: function set(config) {
- /**
- * Initlai block type
- * Uses in case when there is no items passed
- * @type {{type: (*), data: {text: null}}}
- */
- var initialBlock = {
- type: config.initialBlock,
- data: {}
- };
-
- 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 || {};
- this.config.data = config.data || {};
-
- /**
- * Initialize items to pass data to the Renderer
- */
- if (_.isEmpty(this.config.data)) {
- this.config.data = {};
- this.config.data.items = [initialBlock];
- } else {
- if (!this.config.data.items || this.config.data.items.length === 0) {
- this.config.data.items = [initialBlock];
- }
- }
-
- /**
- * If initial Block's Tool was not passed, use the first Tool in config.tools
- */
- if (!config.initialBlock) {
- for (this.config.initialBlock in this.config.tools) {
- break;
- }
- } else {
- this.config.initialBlock = config.initialBlock;
- }
- }
-
- /**
- * Returns private property
- * @returns {EditorConfig}
- */
- ,
- get: function get() {
- return this.config;
- }
- }]);
-
- return CodexEditor;
-}();
-
-CodexEditor.displayName = 'CodexEditor';
-exports.default = 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 : ['text', 'header', 'picture', 'list', 'quote', 'code', 'twitter', 'instagram', 'smile'],
-// holderId : 'codex-editor',
-//
-// // Type of block showing on empty editor
-// initialBlockPlugin: 'text'
-// };
-//
-// /**
-// * 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;
-//
-// })({});
-
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! utils */ "./src/components/utils.js")))
-
-/***/ }),
-
-/***/ "./src/components/__module.ts":
-/*!************************************!*\
- !*** ./src/components/__module.ts ***!
- \************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-/**
- * @abstract
- * @class Module
- * @classdesc All modules inherits from this class.
- *
- * @typedef {Module} Module
- * @property {Object} config - Editor user settings
- * @property {Object} Editor - List of Editor modules
- */
-var Module = function () {
- /**
- * @constructor
- *
- * @param {EditorConfig} config
- */
- function Module(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, Module);
-
- /**
- * Editor modules list
- * @type {EditorComponents}
- */
- this.Editor = null;
- /**
- * Editor configuration object
- * @type {EditorConfig}
- */
- this.config = {};
- if (new.target === Module) {
- throw new TypeError('Constructors for abstract class Module are not allowed.');
- }
- this.config = config;
- }
- /**
- * Editor modules setter
- *
- * @param Editor
- * @param Editor.modules {@link CodexEditor#moduleInstances}
- * @param Editor.config {@link CodexEditor#configuration}
- */
-
-
- _createClass(Module, [{
- key: 'state',
- set: function set(Editor) {
- this.Editor = Editor;
- }
- }]);
-
- return Module;
-}();
-
-Module.displayName = 'Module';
-exports.default = Module;
-module.exports = exports['default'];
-
-/***/ }),
-
-/***/ "./src/components/block-tunes/block-tune-move-up.ts":
-/*!**********************************************************!*\
- !*** ./src/components/block-tunes/block-tune-move-up.ts ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function($) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var MoveUpTune = function () {
- /**
- * MoveUpTune constructor
- *
- * @param {Object} api
- * @param {Object} settings
- */
- function MoveUpTune(_ref) {
- var api = _ref.api,
- settings = _ref.settings;
-
- _classCallCheck(this, MoveUpTune);
-
- /**
- * Styles
- * @type {{wrapper: string}}
- */
- this.CSS = {
- wrapper: 'ass'
- };
- this.api = api;
- this.settings = settings;
- }
- /**
- * Create "MoveUp" button and add click event listener
- * @returns [Element}
- */
-
-
- _createClass(MoveUpTune, [{
- key: 'render',
- value: function render() {
- var _this = this;
-
- var moveUpButton = $.make('div', ['ce-settings-move-up'], {});
- moveUpButton.addEventListener('click', function (event) {
- return _this.handleClick(event);
- }, false);
- return moveUpButton;
- }
- /**
- * Move current block up
- * @param {MouseEvent} event
- */
-
- }, {
- key: 'handleClick',
- value: function handleClick(event) {
- this.api.blocks.moveUp();
- }
- }]);
-
- return MoveUpTune;
-}();
-
-MoveUpTune.displayName = 'MoveUpTune';
-exports.default = MoveUpTune;
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! dom */ "./src/components/dom.js")))
-
-/***/ }),
-
-/***/ "./src/components/block.js":
-/*!*********************************!*\
- !*** ./src/components/block.js ***!
- \*********************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function($, _) {
-
-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
- *
- */
-
-/** Import default tunes */
-
-
-var _blockTuneMoveUp = __webpack_require__(/*! ./block-tunes/block-tune-move-up */ "./src/components/block-tunes/block-tune-move-up.ts");
-
-var _blockTuneMoveUp2 = _interopRequireDefault(_blockTuneMoveUp);
-
-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"); } }
-
-/**
- * @classdesc Abstract Block class that contains Block information, Tool name and Tool class instance
- *
- * @property tool - Tool instance
- * @property html - Returns HTML content of plugin
- * @property wrapper - Div element that wraps block content with Tool's content. Has `ce-block` CSS class
- * @property contentNode - Div element that wraps Tool's content. Has `ce-block__content` CSS class
- * @property pluginsContent - HTML content that returns by Tool's render function
- */
-var Block = function () {
- /**
- * @constructor
- * @param {String} toolName - Tool name that passed on initialization
- * @param {Object} toolInstance — passed Tool`s instance that rendered the Block
- * @param {Object} settings - default settings
- * @param {Object} apiMethods - Editor API
- */
- function Block(toolName, toolInstance, settings, apiMethods) {
- _classCallCheck(this, Block);
-
- this.name = toolName;
- this.tool = toolInstance;
- this.settings = settings;
- this.api = apiMethods;
- this._html = this.compose();
-
- /**
- * @type {IBlockTune[]}
- */
- this.tunes = this.makeTunes();
- }
-
- /**
- * CSS classes for the Block
- * @return {{wrapper: string, content: string}}
- */
-
-
- _createClass(Block, [{
- key: 'compose',
-
-
- /**
- * Make default Block wrappers and put Tool`s content there
- * @returns {HTMLDivElement}
- */
- value: function compose() {
- this.wrapper = $.make('div', Block.CSS.wrapper);
- this.contentNode = $.make('div', Block.CSS.content);
- this.pluginsContent = this.tool.render();
-
- this.contentNode.appendChild(this.pluginsContent);
- this.wrapper.appendChild(this.contentNode);
-
- return this.wrapper;
- }
-
- /**
- * Calls Tool's method
- *
- * Method checks tool property {MethodName}. Fires method with passes params If it is instance of Function
- *
- * @param {String} methodName
- * @param {Object} params
- */
-
- }, {
- key: 'call',
- value: function call(methodName, params) {
- /**
- * call Tool's method with the instance context
- */
- if (this.tool[methodName] && this.tool[methodName] instanceof Function) {
- this.tool[methodName].call(this.tool, params);
- }
- }
-
- /**
- * Get Block`s HTML
- * @returns {HTMLElement}
- */
-
- }, {
- key: 'mergeWith',
-
-
- /**
- * Call plugins merge method
- * @param {Object} data
- */
- value: function mergeWith(data) {
- var _this = this;
-
- return Promise.resolve().then(function () {
- _this.tool.merge(data);
- });
- }
- /**
- * Extracts data from Block
- * Groups Tool's save processing time
- * @return {Object}
- */
-
- }, {
- key: 'save',
- value: function save() {
- var _this2 = this;
-
- var extractedBlock = this.tool.save(this.pluginsContent);
-
- /** Measuring execution time*/
- var measuringStart = window.performance.now(),
- measuringEnd = void 0;
-
- return Promise.resolve(extractedBlock).then(function (finishedExtraction) {
- /** measure promise execution */
- measuringEnd = window.performance.now();
-
- return {
- tool: _this2.name,
- data: finishedExtraction,
- time: measuringEnd - measuringStart
- };
- }).catch(function (error) {
- _.log('Saving proccess for ' + this.tool.name + ' tool failed due to the ' + error, 'log', 'red');
- });
- }
-
- /**
- * Uses Tool's validation method to check the correctness of output data
- * Tool's validation method is optional
- *
- * @description Method also can return data if it passed the validation
- *
- * @param {Object} data
- * @returns {Boolean|Object} valid
- */
-
- }, {
- key: 'validateData',
- value: function validateData(data) {
- var isValid = true;
-
- if (this.tool.validate instanceof Function) {
- isValid = this.tool.validate(data);
- }
-
- if (!isValid) {
- return false;
- }
-
- return data;
- }
-
- /**
- * Make an array with default settings
- * Each block has default tune instance that have states
- * @return {IBlockTune[]}
- */
-
- }, {
- key: 'makeTunes',
- value: function makeTunes() {
- var _this3 = this;
-
- var tunesList = [_blockTuneMoveUp2.default];
-
- // Pluck tunes list and return tune instances with passed Editor API and settings
- return tunesList.map(function (tune) {
- return new tune({
- api: _this3.api,
- settings: _this3.settings
- });
- });
- }
-
- /**
- * Enumerates initialized tunes and returns fragment that can be appended to the toolbars area
- * @return {DocumentFragment}
- */
-
- }, {
- key: 'renderTunes',
- value: function renderTunes() {
- var tunesElement = document.createDocumentFragment();
-
- this.tunes.forEach(function (tune) {
- $.append(tunesElement, tune.render());
- });
-
- return tunesElement;
- }
-
- /**
- * Check block for emptiness
- * @return {Boolean}
- */
-
- }, {
- key: 'html',
- get: function get() {
- return this._html;
- }
-
- /**
- * Get Block's JSON data
- * @return {Object}
- */
-
- }, {
- key: 'data',
- get: function get() {
- return this.save();
- }
-
- /**
- * is block mergeable
- * We plugin have merge function then we call it mergable
- * @return {boolean}
- */
-
- }, {
- key: 'mergeable',
- get: function get() {
- return typeof this.tool.merge === 'function';
- }
- }, {
- key: 'isEmpty',
- get: function get() {
- /**
- * Allow Tool to represent decorative contentless blocks: for example "* * *"-tool
- * That Tools are not empty
- */
- if (this.tool.contentless) {
- return false;
- }
-
- var emptyText = $.isEmpty(this.pluginsContent),
- emptyMedia = !this.hasMedia;
-
- return emptyText && emptyMedia;
- }
-
- /**
- * Check if block has a media content such as images, iframes and other
- * @return {Boolean}
- */
-
- }, {
- key: 'hasMedia',
- get: function get() {
- /**
- * This tags represents media-content
- * @type {string[]}
- */
- var mediaTags = ['img', 'iframe', 'video', 'audio', 'source', 'input', 'textarea', 'twitterwidget'];
-
- return !!this._html.querySelector(mediaTags.join(','));
- }
-
- /**
- * Set selected state
- * @param {Boolean} state - 'true' to select, 'false' to remove selection
- */
-
- }, {
- key: 'selected',
- set: function set(state) {
- /**
- * We don't need to mark Block as Selected when it is not empty
- */
- if (state === true && !this.isEmpty) {
- this._html.classList.add(Block.CSS.selected);
- } else {
- this._html.classList.remove(Block.CSS.selected);
- }
- }
- }], [{
- key: 'CSS',
- get: function get() {
- return {
- wrapper: 'ce-block',
- content: 'ce-block__content',
- selected: 'ce-block--selected'
- };
- }
- }]);
-
- return Block;
-}();
-
-Block.displayName = 'Block';
-exports.default = Block;
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! dom */ "./src/components/dom.js"), __webpack_require__(/*! utils */ "./src/components/utils.js")))
-
-/***/ }),
-
-/***/ "./src/components/dom.js":
-/*!*******************************!*\
- !*** ./src/components/dom.js ***!
- \*******************************/
-/*! no static exports found */
-/***/ (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 manipulations helper
- */
-var Dom = function () {
- function Dom() {
- _classCallCheck(this, Dom);
- }
-
- _createClass(Dom, null, [{
- key: 'isSingleTag',
-
- /**
- * Check if passed tag has no closed tag
- * @param {Element} tag
- * @return {Boolean}
- */
- value: function isSingleTag(tag) {
- return tag.tagName && ['AREA', 'BASE', 'BR', 'COL', 'COMMAND', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR'].includes(tag.tagName);
- }
- }, {
- 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;
- }
-
- /**
- * Creates Text Node with the passed content
- * @param {String} content - text content
- * @return {Text}
- */
-
- }, {
- key: 'text',
- value: function text(content) {
- return document.createTextNode(content);
- }
-
- /**
- * 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);
- }
-
- /**
- * Search for deepest node which is Leaf.
- * Leaf is the vertex that doesn't have any child nodes
- *
- * @description Method recursively goes throw the all Node until it finds the Leaf
- *
- * @param {Node} node - root Node. From this vertex we start Deep-first search {@link https://en.wikipedia.org/wiki/Depth-first_search}
- * @param {Boolean} atLast - find last text node
- * @return {Node} - it can be text Node or Element Node, so that caret will able to work with it
- */
-
- }, {
- key: 'getDeepestNode',
- value: function getDeepestNode(node) {
- var atLast = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
-
- /**
- * Current function have two directions:
- * - starts from first child and every time gets first or nextSibling in special cases
- * - starts from last child and gets last or previousSibling
- * @type {string}
- */
- var child = atLast ? 'lastChild' : 'firstChild',
- sibling = atLast ? 'previousSibling' : 'nextSibling';
-
- if (node && node.nodeType === Node.ELEMENT_NODE && node[child]) {
- var nodeChild = node[child];
-
- /**
- * special case when child is single tag that can't contain any content
- */
- if (Dom.isSingleTag(nodeChild)) {
- /**
- * 1) We need to check the next sibling. If it is Node Element then continue searching for deepest
- * from sibling
- *
- * 2) If single tag's next sibling is null, then go back to parent and check his sibling
- * In case of Node Element continue searching
- *
- * 3) If none of conditions above happened return parent Node Element
- */
- if (nodeChild[sibling]) {
- nodeChild = nodeChild[sibling];
- } else if (nodeChild.parentNode[sibling]) {
- nodeChild = nodeChild.parentNode[sibling];
- } else {
- return nodeChild.parentNode;
- }
- }
-
- return this.getDeepestNode(nodeChild, atLast);
- }
-
- return node;
- }
-
- /**
- * Check if object is DOM node
- *
- * @param {Object} node
- * @returns {boolean}
- */
-
- }, {
- key: 'isElement',
- value: function isElement(node) {
- return node && (typeof node === 'undefined' ? 'undefined' : _typeof(node)) === 'object' && node.nodeType && node.nodeType === Node.ELEMENT_NODE;
- }
-
- /**
- * Checks target if it is native input
- * @param {Element|String} target - HTML element or string
- * @return {Boolean}
- */
-
- }, {
- key: 'isNativeInput',
- value: function isNativeInput(target) {
- var nativeInputs = ['INPUT', 'TEXTAREA'];
-
- return target ? nativeInputs.includes(target.tagName) : false;
- }
-
- /**
- * Checks node if it is empty
- *
- * @description Method checks simple Node without any childs for emptiness
- * If you have Node with 2 or more children id depth, you better use {@link Dom#isEmpty} method
- *
- * @param {Node} node
- * @return {Boolean} true if it is empty
- */
-
- }, {
- key: 'isNodeEmpty',
- value: function isNodeEmpty(node) {
- var nodeText = void 0;
-
- if (this.isElement(node) && this.isNativeInput(node)) {
- nodeText = node.value;
- } else {
- nodeText = node.textContent.replace('\u200B', '');
- }
-
- return nodeText.trim().length === 0;
- }
-
- /**
- * checks node if it is doesn't have any child nodes
- * @param {Node} node
- * @return {boolean}
- */
-
- }, {
- key: 'isLeaf',
- value: function isLeaf(node) {
- if (!node) {
- return false;
- }
-
- return node.childNodes.length === 0;
- }
-
- /**
- * breadth-first search (BFS)
- * {@link https://en.wikipedia.org/wiki/Breadth-first_search}
- *
- * @description Pushes to stack all DOM leafs and checks for emptiness
- *
- * @param {Node} node
- * @return {boolean}
- */
-
- }, {
- key: 'isEmpty',
- value: function isEmpty(node) {
- var _this = this;
-
- var treeWalker = [],
- leafs = [];
-
- if (!node) {
- return true;
- }
-
- if (!node.childNodes.length) {
- return this.isNodeEmpty(node);
- }
-
- treeWalker.push(node.firstChild);
-
- while (treeWalker.length > 0) {
- node = treeWalker.shift();
-
- if (!node) continue;
-
- if (this.isLeaf(node)) {
- leafs.push(node);
- } else {
- treeWalker.push(node.firstChild);
- }
-
- while (node && node.nextSibling) {
- node = node.nextSibling;
-
- if (!node) continue;
-
- treeWalker.push(node);
- }
-
- /**
- * If one of childs is not empty, checked Node is not empty too
- */
- if (node && !this.isNodeEmpty(node)) {
- return false;
- }
- }
-
- return leafs.every(function (leaf) {
- return _this.isNodeEmpty(leaf);
- });
- }
- }]);
-
- return Dom;
-}();
-
-Dom.displayName = 'Dom';
-exports.default = Dom;
-;
-module.exports = exports['default'];
-
-/***/ }),
-
-/***/ "./src/components/inline-tools/inline-tool-bold.ts":
-/*!*********************************************************!*\
- !*** ./src/components/inline-tools/inline-tool-bold.ts ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-/**
- * Bold Tool
- *
- * Inline Toolbar Tool
- *
- * Makes selected text bolder
- */
-var BoldInlineTool = function () {
- function BoldInlineTool() {
- _classCallCheck(this, BoldInlineTool);
-
- /**
- * Native Document's command that uses for Bold
- */
- this.commandName = 'bold';
- /**
- * Styles
- */
- this.CSS = {
- button: 'ce-inline-tool',
- buttonActive: 'ce-inline-tool--active',
- buttonModifier: 'ce-inline-tool--bold'
- };
- /**
- * Elements
- */
- this.nodes = {
- button: null
- };
- console.log('Bold Inline Tool is ready');
- }
- /**
- * Create button for Inline Toolbar
- */
-
-
- _createClass(BoldInlineTool, [{
- key: 'render',
- value: function render() {
- this.nodes.button = document.createElement('button');
- this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier);
- return this.nodes.button;
- }
- /**
- * Wrap range with tag
- * @param {Range} range
- */
-
- }, {
- key: 'surround',
- value: function surround(range) {
- document.execCommand(this.commandName);
- }
- /**
- * Check selection and set activated state to button if there are tag
- * @param {Selection} selection
- */
-
- }, {
- key: 'checkState',
- value: function checkState(selection) {
- var isActive = document.queryCommandState(this.commandName);
- this.nodes.button.classList.toggle(this.CSS.buttonActive, isActive);
- return isActive;
- }
- }]);
-
- return BoldInlineTool;
-}();
-
-BoldInlineTool.displayName = 'BoldInlineTool';
-exports.default = BoldInlineTool;
-module.exports = exports['default'];
-
-/***/ }),
-
-/***/ "./src/components/modules sync [^_](api-blocks.ts|api-sanitizer.ts|api.ts|blockManager.js|caret.js|events.js|keyboard.js|listeners.js|renderer.js|sanitizer.js|saver.js|toolbar-blockSettings.js|toolbar-inline.ts|toolbar-toolbox.js|toolbar.js|tools.js|ui.js)$":
-/*!*************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./src/components/modules sync nonrecursive [^_](api-blocks.ts|api-sanitizer.ts|api.ts|blockManager.js|caret.js|events.js|keyboard.js|listeners.js|renderer.js|sanitizer.js|saver.js|toolbar-blockSettings.js|toolbar-inline.ts|toolbar-toolbox.js|toolbar.js|tools.js|ui.js)$ ***!
- \*************************************************************************************************************************************************************************************************************************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-var map = {
- "./api-blocks.ts": "./src/components/modules/api-blocks.ts",
- "./api-sanitizer.ts": "./src/components/modules/api-sanitizer.ts",
- "./api.ts": "./src/components/modules/api.ts",
- "./blockManager.js": "./src/components/modules/blockManager.js",
- "./caret.js": "./src/components/modules/caret.js",
- "./events.js": "./src/components/modules/events.js",
- "./keyboard.js": "./src/components/modules/keyboard.js",
- "./listeners.js": "./src/components/modules/listeners.js",
- "./renderer.js": "./src/components/modules/renderer.js",
- "./sanitizer.js": "./src/components/modules/sanitizer.js",
- "./saver.js": "./src/components/modules/saver.js",
- "./toolbar-blockSettings.js": "./src/components/modules/toolbar-blockSettings.js",
- "./toolbar-inline.ts": "./src/components/modules/toolbar-inline.ts",
- "./toolbar-toolbox.js": "./src/components/modules/toolbar-toolbox.js",
- "./toolbar.js": "./src/components/modules/toolbar.js",
- "./tools.js": "./src/components/modules/tools.js",
- "./ui.js": "./src/components/modules/ui.js"
-};
-
-
-function webpackContext(req) {
- var id = webpackContextResolve(req);
- return __webpack_require__(id);
-}
-function webpackContextResolve(req) {
- var id = map[req];
- if(!(id + 1)) { // check for number or string
- var e = new Error("Cannot find module '" + req + "'");
- e.code = 'MODULE_NOT_FOUND';
- throw e;
- }
- return id;
-}
-webpackContext.keys = function webpackContextKeys() {
- return Object.keys(map);
-};
-webpackContext.resolve = webpackContextResolve;
-module.exports = webpackContext;
-webpackContext.id = "./src/components/modules sync [^_](api-blocks.ts|api-sanitizer.ts|api.ts|blockManager.js|caret.js|events.js|keyboard.js|listeners.js|renderer.js|sanitizer.js|saver.js|toolbar-blockSettings.js|toolbar-inline.ts|toolbar-toolbox.js|toolbar.js|tools.js|ui.js)$";
-
-/***/ }),
-
-/***/ "./src/components/modules/api-blocks.ts":
-/*!**********************************************!*\
- !*** ./src/components/modules/api-blocks.ts ***!
- \**********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- *
- */
-var BlocksAPI = function (_Module) {
- _inherits(BlocksAPI, _Module);
-
- /**
- * Save Editor config. API provides passed configuration to the Blocks
- * @param {EditorsConfig} config
- */
- function BlocksAPI(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, BlocksAPI);
-
- return _possibleConstructorReturn(this, (BlocksAPI.__proto__ || Object.getPrototypeOf(BlocksAPI)).call(this, { config: config }));
- }
-
- _createClass(BlocksAPI, [{
- key: 'moveDown',
- value: function moveDown() {
- console.log('moving down', this.Editor.BlockManager);
- }
- /**
- * Moves block up
- */
-
- }, {
- key: 'moveUp',
- value: function moveUp() {
- console.log('moving up', this.Editor.BlockManager);
- }
- }]);
-
- return BlocksAPI;
-}(Module);
-
-BlocksAPI.displayName = 'BlocksAPI';
-exports.default = BlocksAPI;
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts")))
-
-/***/ }),
-
-/***/ "./src/components/modules/api-sanitizer.ts":
-/*!*************************************************!*\
- !*** ./src/components/modules/api-sanitizer.ts ***!
- \*************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * @class API
- */
-var SanitizerAPI = function (_Module) {
- _inherits(SanitizerAPI, _Module);
-
- /**
- * Save Editor config. API provides passed configuration to the Blocks
- * @param {EditorsConfig} config
- */
- function SanitizerAPI(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, SanitizerAPI);
-
- return _possibleConstructorReturn(this, (SanitizerAPI.__proto__ || Object.getPrototypeOf(SanitizerAPI)).call(this, { config: config }));
- }
-
- _createClass(SanitizerAPI, [{
- key: "clean",
- value: function clean(taintString, config) {
- return this.Editor.Sanitizer.clean(taintString, config);
- }
- }]);
-
- return SanitizerAPI;
-}(Module);
-
-SanitizerAPI.displayName = "SanitizerAPI";
-exports.default = SanitizerAPI;
-module.exports = exports["default"];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts")))
-
-/***/ }),
-
-/***/ "./src/components/modules/api.ts":
-/*!***************************************!*\
- !*** ./src/components/modules/api.ts ***!
- \***************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * @class API
- */
-var API = function (_Module) {
- _inherits(API, _Module);
-
- /**
- * Save Editor config. API provides passed configuration to the Blocks
- * @param {EditorsConfig} config
- */
- function API(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, API);
-
- return _possibleConstructorReturn(this, (API.__proto__ || Object.getPrototypeOf(API)).call(this, { config: config }));
- }
-
- _createClass(API, [{
- key: "methods",
- get: function get() {
- return {
- blocks: this.Editor.BlocksAPI,
- caret: {},
- sanitizer: this.Editor.SanitizerAPI,
- toolbar: {}
- };
- }
- }]);
-
- return API;
-}(Module);
-
-API.displayName = "API";
-exports.default = API;
-module.exports = exports["default"];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts")))
-
-/***/ }),
-
-/***/ "./src/components/modules/blockManager.js":
-/*!************************************************!*\
- !*** ./src/components/modules/blockManager.js ***!
- \************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module, $, _) {
-
-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; }; }();
-
-var _block = __webpack_require__(/*! ../block */ "./src/components/block.js");
-
-var _block2 = _interopRequireDefault(_block);
-
-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"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
- * @class BlockManager
- * @classdesc Manage editor`s blocks storage and appearance
- *
- * @module BlockManager
- *
- * @version 2.0.0
- */
-
-/**
- * @typedef {BlockManager} BlockManager
- * @property {Number} currentBlockIndex - Index of current working block
- * @property {Proxy} _blocks - Proxy for Blocks instance {@link Blocks}
- */
-var BlockManager = function (_Module) {
- _inherits(BlockManager, _Module);
-
- /**
- * @constructor
- * @param {EditorConfig} config
- */
- function BlockManager(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, BlockManager);
-
- /**
- * Proxy for Blocks instance {@link Blocks}
- *
- * @type {Proxy}
- * @private
- */
- var _this = _possibleConstructorReturn(this, (BlockManager.__proto__ || Object.getPrototypeOf(BlockManager)).call(this, { config: config }));
-
- _this._blocks = null;
-
- /**
- * Index of current working block
- *
- * @type {number}
- * @private
- */
- _this.currentBlockIndex = -1;
- return _this;
- }
-
- /**
- * Should be called after Editor.UI preparation
- * Define this._blocks property
- *
- * @returns {Promise}
- */
-
-
- _createClass(BlockManager, [{
- key: 'prepare',
- value: function prepare() {
- var _this2 = this;
-
- return new Promise(function (resolve) {
- var blocks = new Blocks(_this2.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
- */
- _this2._blocks = new Proxy(blocks, {
- set: Blocks.set,
- get: Blocks.get
- });
-
- resolve();
- });
- }
-
- /**
- * Creates Block instance by tool name
- *
- * @param {String} toolName - tools passed in editor config {@link EditorConfig#tools}
- * @param {Object} data - constructor params
- * @param {Object} settings - block settings
- *
- * @return {Block}
- */
-
- }, {
- key: 'composeBlock',
- value: function composeBlock(toolName, data, settings) {
- var toolInstance = this.Editor.Tools.construct(toolName, data),
- block = new _block2.default(toolName, toolInstance, settings, this.Editor.API.methods);
-
- this.bindEvents(block);
- /**
- * Apply callback before inserting html
- */
- block.call('appendCallback', {});
-
- return block;
- }
-
- /**
- * Bind Events
- * @param {Object} block
- */
-
- }, {
- key: 'bindEvents',
- value: function bindEvents(block) {
- var _this3 = this;
-
- this.Editor.Listeners.on(block.pluginsContent, 'keydown', function (event) {
- return _this3.Editor.Keyboard.blockKeydownsListener(event);
- });
- this.Editor.Listeners.on(block.pluginsContent, 'mouseup', function (event) {
- _this3.Editor.InlineToolbar.handleShowingEvent(event);
- });
- }
-
- /**
- * Set's caret to the next Block
- * Before moving caret, we should check if caret position is at the end of Plugins node
- * Using {@link Dom#getDeepestNode} to get a last node and match with current selection
- */
-
- }, {
- key: 'navigateNext',
- value: function navigateNext() {
- var caretAtEnd = this.Editor.Caret.isAtEnd;
-
- if (!caretAtEnd) {
- return;
- }
-
- var nextBlock = this.nextBlock;
-
- if (!nextBlock) {
- return;
- }
-
- this.Editor.Caret.setToBlock(nextBlock);
- }
-
- /**
- * Set's caret to the previous Block
- * Before moving caret, we should check if caret position is start of the Plugins node
- * Using {@link Dom#getDeepestNode} to get a last node and match with current selection
- */
-
- }, {
- key: 'navigatePrevious',
- value: function navigatePrevious() {
- var caretAtStart = this.Editor.Caret.isAtStart;
-
- if (!caretAtStart) {
- return;
- }
-
- var previousBlock = this.previousBlock;
-
- if (!previousBlock) {
- return;
- }
-
- this.Editor.Caret.setToBlock(previousBlock, 0, true);
- }
-
- /**
- * Insert new block into _blocks
- *
- * @param {String} toolName — plugin name
- * @param {Object} data — plugin data
- * @param {Object} settings - default settings
- */
-
- }, {
- key: 'insert',
- value: function insert(toolName) {
- var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- var settings = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-
- var block = this.composeBlock(toolName, data, settings);
-
- this._blocks[++this.currentBlockIndex] = block;
- this.Editor.Caret.setToBlock(block);
- }
-
- /**
- * Merge two blocks
- * @param {Block} targetBlock - previous block will be append to this block
- * @param {Block} blockToMerge - block that will be merged with target block
- *
- * @return {Promise} - the sequence that can be continued
- */
-
- }, {
- key: 'mergeBlocks',
- value: function mergeBlocks(targetBlock, blockToMerge) {
- var _this4 = this;
-
- var blockToMergeIndex = this._blocks.indexOf(blockToMerge);
-
- return Promise.resolve().then(function () {
- if (blockToMerge.isEmpty) {
- return;
- }
-
- return blockToMerge.data.then(function (blockToMergeInfo) {
- targetBlock.mergeWith(blockToMergeInfo.data);
- });
- }).then(function () {
- _this4.removeBlock(blockToMergeIndex);
- _this4.currentBlockIndex = _this4._blocks.indexOf(targetBlock);
- });
- }
-
- /**
- * Remove block with passed index or remove last
- * @param {Number|null} index
- */
-
- }, {
- key: 'removeBlock',
- value: function removeBlock(index) {
- this._blocks.remove(index);
- }
- /**
- * Split current Block
- * 1. Extract content from Caret position to the Block`s end
- * 2. Insert a new Block below current one with extracted content
- */
-
- }, {
- key: 'split',
- value: function split() {
- var extractedFragment = this.Editor.Caret.extractFragmentFromCaretPosition(),
- wrapper = $.make('div');
-
- wrapper.append(extractedFragment);
-
- /**
- * @todo make object in accordance with Tool
- */
- var data = {
- text: $.isEmpty(wrapper) ? '' : wrapper.innerHTML
- };
-
- this.insert(this.config.initialBlock, data);
- }
-
- /**
- * Replace current working block
- *
- * @param {String} toolName — plugin name
- * @param {Object} data — plugin data
- */
-
- }, {
- key: 'replace',
- value: function replace(toolName) {
- var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- var block = this.composeBlock(toolName, data);
-
- this._blocks.insert(this.currentBlockIndex, block, true);
- }
-
- /**
- * returns last Block
- * @return {Block}
- */
-
- }, {
- key: 'getBlockByIndex',
-
-
- /**
- * Returns Block by passed index
- * @param {Number} index
- * @return {Block}
- */
- value: function getBlockByIndex(index) {
- return this._blocks[index];
- }
-
- /**
- * Get Block instance by html element
- * @param {Node} element
- * @returns {Block}
- */
-
- }, {
- key: 'getBlock',
- value: function getBlock(element) {
- if (!$.isElement(element)) {
- element = element.parentNode;
- }
-
- var nodes = this._blocks.nodes,
- firstLevelBlock = element.closest('.' + _block2.default.CSS.wrapper),
- index = nodes.indexOf(firstLevelBlock);
-
- if (index >= 0) {
- return this._blocks[index];
- }
- }
-
- /**
- * Get current Block instance
- *
- * @return {Block}
- */
-
- }, {
- key: 'setCurrentBlockByChildNode',
-
-
- /**
- * 1) Find first-level Block from passed child Node
- * 2) Mark it as current
- *
- * @param {Element|Text} childNode - look ahead from this node.
- * @throws Error - when passed Node is not included at the Block
- */
- value: function setCurrentBlockByChildNode(childNode) {
- /**
- * If node is Text TextNode
- */
- if (!$.isElement(childNode)) {
- childNode = childNode.parentNode;
- }
-
- var parentFirstLevelBlock = childNode.closest('.' + _block2.default.CSS.wrapper);
-
- if (parentFirstLevelBlock) {
- this.currentNode = parentFirstLevelBlock;
- } else {
- throw new Error('Can not find a Block from this child Node');
- }
- }
- }, {
- key: 'lastBlock',
- get: function get() {
- return this._blocks[this._blocks.length - 1];
- }
- }, {
- key: 'currentBlock',
- get: function get() {
- return this._blocks[this.currentBlockIndex];
- }
-
- /**
- * Returns next Block instance
- * @return {Block|null}
- */
-
- }, {
- key: 'nextBlock',
- get: function get() {
- var isLastBlock = this.currentBlockIndex === this._blocks.length - 1;
-
- if (isLastBlock) {
- return null;
- }
-
- return this._blocks[this.currentBlockIndex + 1];
- }
-
- /**
- * Returns previous Block instance
- * @return {Block|null}
- */
-
- }, {
- key: 'previousBlock',
- get: function get() {
- var isFirstBlock = this.currentBlockIndex === 0;
-
- if (isFirstBlock) {
- return null;
- }
-
- return this._blocks[this.currentBlockIndex - 1];
- }
-
- /**
- * Get working html element
- *
- * @return {HTMLElement}
- */
-
- }, {
- key: 'currentNode',
- get: function get() {
- return this._blocks.nodes[this.currentBlockIndex];
- }
-
- /**
- * Set currentBlockIndex to passed block
- * @param {HTMLElement} element
- */
- ,
- set: function set(element) {
- var nodes = this._blocks.nodes,
- firstLevelBlock = element.closest('.' + _block2.default.CSS.wrapper);
-
- /**
- * Update current Block's index
- * @type {number}
- */
- this.currentBlockIndex = nodes.indexOf(firstLevelBlock);
-
- /**
- * Remove previous selected Block's state
- */
- this._blocks.array.forEach(function (block) {
- return block.selected = false;
- });
-
- /**
- * Mark current Block as selected
- * @type {boolean}
- */
- this.currentBlock.selected = true;
- }
-
- /**
- * Get array of Block instances
- *
- * @returns {Block[]} {@link Blocks#array}
- */
-
- }, {
- key: 'blocks',
- get: function get() {
- return this._blocks.array;
- }
- }]);
-
- return BlockManager;
-}(Module);
-
-BlockManager.displayName = 'BlockManager';
-exports.default = 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
- * @param {Boolean} replace — it true, replace block on given index
- */
-
- }, {
- key: 'insert',
- value: function insert(index, block) {
- var replace = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
-
- if (!this.length) {
- this.push(block);
- return;
- }
-
- if (index > this.length) {
- index = this.length;
- }
-
- if (replace) {
- this.blocks[index].html.remove();
- }
-
- var deleteCount = replace ? 1 : 0;
-
- this.blocks.splice(index, deleteCount, block);
-
- if (index > 0) {
- var previousBlock = this.blocks[index - 1];
-
- previousBlock.html.insertAdjacentElement('afterend', block.html);
- } else {
- var nextBlock = this.blocks[index + 1];
-
- if (nextBlock) {
- nextBlock.html.insertAdjacentElement('beforebegin', block.html);
- } else {
- this.workingArea.appendChild(block.html);
- }
- }
- }
-
- /**
- * Remove block
- * @param {Number|null} index
- */
-
- }, {
- key: 'remove',
- value: function remove(index) {
- if (!index) {
- index = this.length - 1;
- }
-
- this.blocks[index].html.remove();
- this.blocks.splice(index, 1);
- }
-
- /**
- * 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 _.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 = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts"), __webpack_require__(/*! dom */ "./src/components/dom.js"), __webpack_require__(/*! utils */ "./src/components/utils.js")))
-
-/***/ }),
-
-/***/ "./src/components/modules/caret.js":
-/*!*****************************************!*\
- !*** ./src/components/modules/caret.js ***!
- \*****************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module, $, _) {
-
-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; }; }();
-
-var _selection = __webpack_require__(/*! ../selection */ "./src/components/selection.js");
-
-var _selection2 = _interopRequireDefault(_selection);
-
-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"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
- * @class Caret
- * @classdesc Contains methods for working Caret
- *
- * Uses Range methods to manipulate with caret
- *
- * @module Caret
- *
- * @version 2.0.0
- */
-
-/**
- * @typedef {Caret} Caret
- */
-var Caret = function (_Module) {
- _inherits(Caret, _Module);
-
- /**
- * @constructor
- */
- function Caret(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, Caret);
-
- return _possibleConstructorReturn(this, (Caret.__proto__ || Object.getPrototypeOf(Caret)).call(this, { config: config }));
- }
-
- /**
- * Method gets Block instance and puts caret to the text node with offset
- * There two ways that method applies caret position:
- * - first found text node: sets at the beginning, but you can pass an offset
- * - last found text node: sets at the end of the node. Also, you can customize the behaviour
- *
- * @param {Block} block - Block class
- * @param {Number} offset - caret offset regarding to the text node
- * @param {Boolean} atEnd - put caret at the end of the text node or not
- */
-
-
- _createClass(Caret, [{
- key: 'setToBlock',
- value: function setToBlock(block) {
- var _this2 = this;
-
- var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
- var atEnd = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
-
- var element = block.pluginsContent;
-
- /** If Element is INPUT */
- if ($.isNativeInput(element)) {
- element.focus();
- return;
- }
-
- var nodeToSet = $.getDeepestNode(element, atEnd);
-
- if (atEnd || offset > nodeToSet.length) {
- offset = nodeToSet.length;
- }
-
- /** if found deepest node is native input */
- if ($.isNativeInput(nodeToSet)) {
- nodeToSet.focus();
- return;
- }
-
- /**
- * @todo try to fix via Promises or use querySelectorAll to not to use timeout
- */
- _.delay(function () {
- _this2.set(nodeToSet, offset);
- }, 20)();
-
- this.Editor.BlockManager.currentNode = block.wrapper;
- }
-
- /**
- * Creates Document Range and sets caret to the element with offset
- * @param {Element} element - target node.
- * @param {Number} offset - offset
- */
-
- }, {
- key: 'set',
- value: function set(element) {
- var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
-
- var range = document.createRange(),
- selection = _selection2.default.get();
-
- range.setStart(element, offset);
- range.setEnd(element, offset);
-
- selection.removeAllRanges();
- selection.addRange(range);
- }
- }, {
- key: 'setToTheLastBlock',
-
-
- /**
- * Set Caret to the last Block
- * If last block is not empty, append another empty block
- */
- value: function setToTheLastBlock() {
- var lastBlock = this.Editor.BlockManager.lastBlock;
-
- if (!lastBlock) return;
-
- /**
- * If last block is empty and it is an initialBlock, set to that.
- * Otherwise, append new empty block and set to that
- */
- if (lastBlock.isEmpty) {
- this.setToBlock(lastBlock);
- } else {
- this.Editor.BlockManager.insert(this.config.initialBlock);
- }
- }
-
- /**
- * Extract content fragment of current Block from Caret position to the end of the Block
- */
-
- }, {
- key: 'extractFragmentFromCaretPosition',
- value: function extractFragmentFromCaretPosition() {
- var selection = _selection2.default.get();
-
- if (selection.rangeCount) {
- var selectRange = selection.getRangeAt(0),
- blockElem = this.Editor.BlockManager.currentBlock.pluginsContent;
-
- selectRange.deleteContents();
-
- if (blockElem) {
- var range = selectRange.cloneRange(true);
-
- range.selectNodeContents(blockElem);
- range.setStart(selectRange.endContainer, selectRange.endOffset);
- return range.extractContents();
- }
- }
- }
-
- /**
- * Get all first-level (first child of [contenteditabel]) siblings from passed node
- * Then you can check it for emptiness
- *
- * @example
- *
- *
- * @return {Element[]}
- */
-
- }, {
- key: 'getHigherLevelSiblings',
- value: function getHigherLevelSiblings(from, direction) {
- var current = from,
- siblings = [];
-
- /**
- * Find passed node's firs-level parent (in example - blockquote)
- */
- while (current.parentNode && current.parentNode.contentEditable !== 'true') {
- current = current.parentNode;
- }
-
- var sibling = direction === 'left' ? 'previousSibling' : 'nextSibling';
-
- /**
- * Find all left/right siblings
- */
- while (current[sibling]) {
- current = current[sibling];
- siblings.push(current);
- }
-
- return siblings;
- }
-
- /**
- * Get's deepest first node and checks if offset is zero
- * @return {boolean}
- */
-
- }, {
- key: 'isAtStart',
- get: function get() {
- /**
- * Don't handle ranges
- */
- if (!_selection2.default.isCollapsed) {
- return false;
- }
-
- var selection = _selection2.default.get(),
- anchorNode = selection.anchorNode,
- firstNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.pluginsContent);
-
- /**
- * Workaround case when caret in the text like " |Hello!"
- * selection.anchorOffset is 1, but real caret visible position is 0
- * @type {number}
- */
- var firstLetterPosition = anchorNode.textContent.search(/\S/);
-
- if (firstLetterPosition === -1) {
- // empty text
- firstLetterPosition = 0;
- }
-
- /**
- * In case of
- *
- *
<-- first (and deepest) node is
- * |adaddad <-- anchor node
- *
- */
- if ($.isEmpty(firstNode)) {
- var leftSiblings = this.getHigherLevelSiblings(anchorNode, 'left'),
- nothingAtLeft = leftSiblings.every(function (node) {
- return $.isEmpty(node);
- });
-
- if (nothingAtLeft && selection.anchorOffset === firstLetterPosition) {
- return true;
- }
- }
-
- return firstNode === null || anchorNode === firstNode && selection.anchorOffset === firstLetterPosition;
- }
-
- /**
- * Get's deepest last node and checks if offset is last node text length
- * @return {boolean}
- */
-
- }, {
- key: 'isAtEnd',
- get: function get() {
- /**
- * Don't handle ranges
- */
- if (!_selection2.default.isCollapsed) {
- return false;
- }
-
- var selection = _selection2.default.get(),
- anchorNode = selection.anchorNode,
- lastNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.pluginsContent, true);
-
- /**
- * In case of
- *
- * adaddad| <-- anchor node
- *
<-- first (and deepest) node is
- *
- */
- if ($.isEmpty(lastNode)) {
- var leftSiblings = this.getHigherLevelSiblings(anchorNode, 'right'),
- nothingAtRight = leftSiblings.every(function (node) {
- return $.isEmpty(node);
- });
-
- if (nothingAtRight && selection.anchorOffset === anchorNode.textContent.length) {
- return true;
- }
- }
-
- return anchorNode === lastNode && selection.anchorOffset === lastNode.textContent.length;
- }
- }]);
-
- return Caret;
-}(Module);
-
-Caret.displayName = 'Caret';
-exports.default = Caret;
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts"), __webpack_require__(/*! dom */ "./src/components/dom.js"), __webpack_require__(/*! utils */ "./src/components/utils.js")))
-
-/***/ }),
-
-/***/ "./src/components/modules/events.js":
-/*!******************************************!*\
- !*** ./src/components/modules/events.js ***!
- \******************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * @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
- *
- * @typedef {Events} Events
- * @property {Object} subscribers - all subscribers grouped by event name
- */
-var Events = function (_Module) {
- _inherits(Events, _Module);
-
- /**
- * @constructor
- */
- function Events(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, Events);
-
- var _this = _possibleConstructorReturn(this, (Events.__proto__ || Object.getPrototypeOf(Events)).call(this, { config: config }));
-
- _this.subscribers = {};
- return _this;
- }
-
- /**
- * @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
- * clears subsribers list
- */
-
- }, {
- key: "destroy",
- value: function destroy() {
- this.subscribers = null;
- }
- }]);
-
- return Events;
-}(Module);
-
-Events.displayName = "Events";
-exports.default = Events;
-module.exports = exports["default"];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts")))
-
-/***/ }),
-
-/***/ "./src/components/modules/keyboard.js":
-/*!********************************************!*\
- !*** ./src/components/modules/keyboard.js ***!
- \********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module, _) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * @class Keyboard
- * @classdesc Сlass to handle the keydowns
- *
- * @author CodeX Team (team@ifmo.su)
- * @copyright CodeX Team 2017
- * @license The MIT License (MIT)
- * @version 1.0.0
- */
-
-/**
- * @typedef {Keyboard} Keyboard
- */
-var Keyboard = function (_Module) {
- _inherits(Keyboard, _Module);
-
- /**
- * @constructor
- */
- function Keyboard(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, Keyboard);
-
- return _possibleConstructorReturn(this, (Keyboard.__proto__ || Object.getPrototypeOf(Keyboard)).call(this, { config: config }));
- }
-
- /**
- * Handler on Block for keyboard keys at keydown event
- *
- * @param {KeyboardEvent} event
- */
-
-
- _createClass(Keyboard, [{
- key: 'blockKeydownsListener',
- value: function blockKeydownsListener(event) {
- switch (event.keyCode) {
- case _.keyCodes.BACKSPACE:
-
- _.log('Backspace key pressed');
- this.backspacePressed(event);
- break;
-
- case _.keyCodes.ENTER:
-
- _.log('Enter key pressed');
- this.enterPressed(event);
- break;
-
- case _.keyCodes.DOWN:
- case _.keyCodes.RIGHT:
-
- _.log('Right/Down key pressed');
- this.arrowRightAndDownPressed();
- break;
-
- case _.keyCodes.UP:
- case _.keyCodes.LEFT:
-
- _.log('Left/Up key pressed');
- this.arrowLeftAndUpPressed();
- break;
-
- default:
-
- break;
- }
- }
-
- /**
- * Handle pressing enter key
- *
- * @param {KeyboardEvent} event
- */
-
- }, {
- key: 'enterPressed',
- value: function enterPressed(event) {
- var currentBlock = this.Editor.BlockManager.currentBlock,
- toolsConfig = this.config.toolsConfig[currentBlock.name];
-
- /**
- * Don't handle Enter keydowns when Tool sets enableLineBreaks to true.
- * Uses for Tools like where line breaks should be handled by default behaviour.
- */
- if (toolsConfig && toolsConfig[this.Editor.Tools.apiSettings.IS_ENABLED_LINE_BREAKS]) {
- return;
- }
-
- /**
- * Allow to create linebreaks by Shift+Enter
- */
- if (event.shiftKey) {
- return;
- }
-
- /**
- * Split the Current Block into two blocks
- */
- this.Editor.BlockManager.split();
- event.preventDefault();
- }
-
- /**
- * Handle backspace keypress on block
- * @param {KeyboardEvent} event - keydown
- */
-
- }, {
- key: 'backspacePressed',
- value: function backspacePressed(event) {
- var _this2 = this;
-
- var BM = this.Editor.BlockManager;
-
- var isFirstBlock = BM.currentBlockIndex === 0,
- canMergeBlocks = this.Editor.Caret.isAtStart && !isFirstBlock;
-
- if (!canMergeBlocks) {
- return;
- }
-
- // preventing browser default behaviour
- event.preventDefault();
-
- var targetBlock = BM.getBlockByIndex(BM.currentBlockIndex - 1),
- blockToMerge = BM.currentBlock;
-
- /**
- * Blocks that can be merged:
- * 1) with the same Name
- * 2) Tool has 'merge' method
- *
- * other case will handle as usual ARROW LEFT behaviour
- */
- if (blockToMerge.name !== targetBlock.name || !targetBlock.mergeable) {
- BM.navigatePrevious();
- }
-
- var setCaretToTheEnd = !targetBlock.isEmpty ? true : false;
-
- BM.mergeBlocks(targetBlock, blockToMerge).then(function () {
- window.setTimeout(function () {
- // set caret to the block without offset at the end
- _this2.Editor.Caret.setToBlock(BM.currentBlock, 0, setCaretToTheEnd);
- _this2.Editor.Toolbar.close();
- }, 10);
- });
- }
-
- /**
- * Handle right and down keyboard keys
- */
-
- }, {
- key: 'arrowRightAndDownPressed',
- value: function arrowRightAndDownPressed() {
- this.Editor.BlockManager.navigateNext();
- }
-
- /**
- * Handle left and up keyboard keys
- */
-
- }, {
- key: 'arrowLeftAndUpPressed',
- value: function arrowLeftAndUpPressed() {
- this.Editor.BlockManager.navigatePrevious();
- }
- }]);
-
- return Keyboard;
-}(Module);
-
-Keyboard.displayName = 'Keyboard';
-exports.default = Keyboard;
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts"), __webpack_require__(/*! utils */ "./src/components/utils.js")))
-
-/***/ }),
-
-/***/ "./src/components/modules/listeners.js":
-/*!*********************************************!*\
- !*** ./src/components/modules/listeners.js ***!
- \*********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * Codex Editor Listeners module
- *
- * @module Listeners
- *
- * Module-decorator for event listeners assignment
- *
- * @author Codex Team
- * @version 2.0.0
- */
-
-/**
- * @typedef {Listeners} Listeners
- * @property {Array} allListeners
- */
-
-var Listeners = function (_Module) {
- _inherits(Listeners, _Module);
-
- /**
- * @constructor
- * @param {EditorConfig} config
- */
- function Listeners(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, Listeners);
-
- var _this = _possibleConstructorReturn(this, (Listeners.__proto__ || Object.getPrototypeOf(Listeners)).call(this, { config: config }));
-
- _this.allListeners = [];
- return _this;
- }
-
- /**
- * Assigns event listener on element
- *
- * @param {Element} element - DOM element that needs to be listened
- * @param {String} eventType - event type
- * @param {Function} handler - method that will be fired on event
- * @param {Boolean} useCapture - use event bubbling
- */
-
-
- _createClass(Listeners, [{
- key: "on",
- value: function on(element, eventType, handler) {
- var useCapture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
-
- var assignedEventData = {
- element: element,
- eventType: eventType,
- handler: handler,
- useCapture: useCapture
- };
-
- var alreadyExist = this.findOne(element, eventType, handler);
-
- if (alreadyExist) return;
-
- this.allListeners.push(assignedEventData);
- element.addEventListener(eventType, handler, useCapture);
- }
-
- /**
- * Removes event listener from element
- *
- * @param {Element} element - DOM element that we removing listener
- * @param {String} eventType - event type
- * @param {Function} handler - remove handler, if element listens several handlers on the same event type
- * @param {Boolean} useCapture - use event bubbling
- */
-
- }, {
- key: "off",
- value: function off(element, eventType, handler) {
- var useCapture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
-
- var existingListeners = this.findAll(element, eventType, handler);
-
- for (var i = 0; i < existingListeners.length; i++) {
- var index = this.allListeners.indexOf(existingListeners[i]);
-
- if (index > 0) {
- this.allListeners.splice(index, 1);
- }
- }
-
- element.removeEventListener(eventType, handler, useCapture);
- }
-
- /**
- * Search method: looks for listener by passed element
- * @param {Element} element - searching element
- * @returns {Array} listeners that found on element
- */
-
- }, {
- key: "findByElement",
- value: function findByElement(element) {
- var listenersOnElement = [];
-
- for (var i = 0; i < this.allListeners.length; i++) {
- var listener = this.allListeners[i];
-
- if (listener.element === element) {
- listenersOnElement.push(listener);
- }
- }
-
- return listenersOnElement;
- }
-
- /**
- * Search method: looks for listener by passed event type
- * @param {String} eventType
- * @return {Array} listeners that found on element
- */
-
- }, {
- key: "findByType",
- value: function findByType(eventType) {
- var listenersWithType = [];
-
- for (var i = 0; i < this.allListeners.length; i++) {
- var listener = this.allListeners[i];
-
- if (listener.type === eventType) {
- listenersWithType.push(listener);
- }
- }
-
- return listenersWithType;
- }
-
- /**
- * Search method: looks for listener by passed handler
- * @param {Function} handler
- * @return {Array} listeners that found on element
- */
-
- }, {
- key: "findByHandler",
- value: function findByHandler(handler) {
- var listenersWithHandler = [];
-
- for (var i = 0; i < this.allListeners.length; i++) {
- var listener = this.allListeners[i];
-
- if (listener.handler === handler) {
- listenersWithHandler.push(listener);
- }
- }
-
- return listenersWithHandler;
- }
-
- /**
- * @param {Element} element
- * @param {String} eventType
- * @param {Function} handler
- * @return {Element|null}
- */
-
- }, {
- key: "findOne",
- value: function findOne(element, eventType, handler) {
- var foundListeners = this.findAll(element, eventType, handler);
-
- return foundListeners.length > 0 ? foundListeners[0] : null;
- }
-
- /**
- * @param {Element} element
- * @param {String} eventType
- * @param {Function} handler
- * @return {Array}
- */
-
- }, {
- key: "findAll",
- value: function findAll(element, eventType, handler) {
- var found = void 0,
- foundByElements = element ? this.findByElement(element) : [];
- // foundByEventType = eventType ? this.findByType(eventType) : [],
- // foundByHandler = handler ? this.findByHandler(handler) : [];
-
- if (element && eventType && handler) {
- found = foundByElements.filter(function (event) {
- return event.eventType === eventType && event.handler === handler;
- });
- } else if (element && eventType) {
- found = foundByElements.filter(function (event) {
- return event.eventType === eventType;
- });
- } else {
- found = foundByElements;
- }
-
- return found;
- }
-
- /**
- * Removes all listeners
- */
-
- }, {
- key: "removeAll",
- value: function removeAll() {
- this.allListeners.map(function (current) {
- current.element.removeEventListener(current.eventType, current.handler);
- });
-
- this.allListeners = [];
- }
- }]);
-
- return Listeners;
-}(Module);
-
-Listeners.displayName = "Listeners";
-exports.default = Listeners;
-module.exports = exports["default"];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts")))
-
-/***/ }),
-
-/***/ "./src/components/modules/renderer.js":
-/*!********************************************!*\
- !*** ./src/components/modules/renderer.js ***!
- \********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module, _) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * Codex Editor Renderer Module
- *
- * @module Renderer
- * @author CodeX Team
- *
- * @version 2.0.0
- */
-var Renderer = function (_Module) {
- _inherits(Renderer, _Module);
-
- /**
- * @constructor
- * @param {EditorConfig} config
- */
- function Renderer(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, Renderer);
-
- return _possibleConstructorReturn(this, (Renderer.__proto__ || Object.getPrototypeOf(Renderer)).call(this, { config: config }));
- }
-
- /**
- * @typedef {Object} RendererItems
- * @property {String} type - tool name
- * @property {Object} data - tool data
- */
-
- /**
- * @example
- *
- * items: [
- * {
- * type : 'paragraph',
- * data : {
- * text : 'Hello from Codex!'
- * }
- * },
- * {
- * type : 'paragraph',
- * data : {
- * text : 'Leave feedback if you like it!'
- * }
- * },
- * ]
- *
- */
-
- /**
- * Make plugin blocks from array of plugin`s data
- * @param {RendererItems[]} items
- */
-
-
- _createClass(Renderer, [{
- key: "render",
- value: function render(items) {
- var _this2 = this;
-
- var chainData = [];
-
- var _loop = function _loop(i) {
- chainData.push({
- function: function _function() {
- return _this2.insertBlock(items[i]);
- }
- });
- };
-
- for (var i = 0; i < items.length; i++) {
- _loop(i);
- }
-
- return _.sequence(chainData);
- }
-
- /**
- * Get plugin instance
- * Add plugin instance to BlockManager
- * Insert block to working zone
- *
- * @param {Object} item
- * @returns {Promise.}
- * @private
- */
-
- }, {
- key: "insertBlock",
- value: function insertBlock(item) {
- var tool = item.type,
- data = item.data,
- settings = item.settings;
-
- this.Editor.BlockManager.insert(tool, data, settings);
-
- return Promise.resolve();
- }
- }]);
-
- return Renderer;
-}(Module);
-
-Renderer.displayName = "Renderer";
-exports.default = Renderer;
-module.exports = exports["default"];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts"), __webpack_require__(/*! utils */ "./src/components/utils.js")))
-
-/***/ }),
-
-/***/ "./src/components/modules/sanitizer.js":
-/*!*********************************************!*\
- !*** ./src/components/modules/sanitizer.js ***!
- \*********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module, _) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * CodeX Sanitizer
- *
- * @module Sanitizer
- * Clears HTML from taint tags
- *
- * @version 2.0.0
- *
- * @example
- * Module can be used within two ways:
- * 1) When you have an instance
- * - this.Editor.Sanitizer.clean(yourTaintString);
- * 2) As static method
- * - CodexEditor.Sanitizer.clean(yourTaintString, yourCustomConfiguration);
- *
- * {@link SanitizerConfig}
- */
-
-/**
- * @typedef {Object} SanitizerConfig
- * @property {Object} tags - define tags restrictions
- *
- * @example
- *
- * tags : {
- * p: true,
- * a: {
- * href: true,
- * rel: "nofollow",
- * target: "_blank"
- * }
- * }
- */
-var Sanitizer = function (_Module) {
- _inherits(Sanitizer, _Module);
-
- /**
- * Initializes Sanitizer module
- * Sets default configuration if custom not exists
- *
- * @property {SanitizerConfig} this.defaultConfig
- * @property {HTMLJanitor} this._sanitizerInstance - Sanitizer library
- *
- * @param {SanitizerConfig} config
- */
- function Sanitizer(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, Sanitizer);
-
- // default config
- var _this = _possibleConstructorReturn(this, (Sanitizer.__proto__ || Object.getPrototypeOf(Sanitizer)).call(this, { config: config }));
-
- _this.defaultConfig = null;
- _this._sanitizerInstance = null;
-
- /** Custom configuration */
- _this.sanitizerConfig = config.settings ? config.settings.sanitizer : {};
-
- /** HTML Janitor library */
- _this.sanitizerInstance = __webpack_require__(/*! html-janitor */ "./node_modules/html-janitor/src/html-janitor.js");
- return _this;
- }
-
- /**
- * If developer uses editor's API, then he can customize sanitize restrictions.
- * Or, sanitizing 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 Default configuration
- *
- * @uses https://www.npmjs.com/package/html-janitor
- *
- * @param {HTMLJanitor} library - sanitizer extension
- */
-
-
- _createClass(Sanitizer, [{
- key: 'clean',
-
-
- /**
- * Cleans string from unwanted tags
- * @param {String} taintString - HTML string
- * @param {Object} customConfig - custom sanitizer configuration. Method uses default if param is empty
- * @return {String} clean HTML
- */
- value: function clean(taintString) {
- var customConfig = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- if (_.isEmpty(customConfig)) {
- return this._sanitizerInstance.clean(taintString);
- } else {
- return Sanitizer.clean(taintString, customConfig);
- }
- }
-
- /**
- * Cleans string from unwanted tags
- * @static
- *
- * Method allows to use default config
- *
- * @param {String} taintString - taint string
- * @param {SanitizerConfig} customConfig - allowed tags
- *
- * @return {String} clean HTML
- */
-
- }, {
- key: 'sanitizerInstance',
- set: function set(library) {
- this._sanitizerInstance = new library(this.defaultConfig);
- }
-
- /**
- * Sets sanitizer configuration. Uses default config if user didn't pass the restriction
- * @param {SanitizerConfig} config
- */
-
- }, {
- key: 'sanitizerConfig',
- set: function set(config) {
- if (_.isEmpty(config)) {
- this.defaultConfig = {
- tags: {
- p: {},
- a: {
- href: true,
- target: '_blank',
- rel: 'nofollow'
- }
- }
- };
- } else {
- this.defaultConfig = config;
- }
- }
- }], [{
- key: 'clean',
- value: function clean(taintString, customConfig) {
- var newInstance = Sanitizer(customConfig);
-
- return newInstance.clean(taintString);
- }
- }]);
-
- return Sanitizer;
-}(Module);
-
-Sanitizer.displayName = 'Sanitizer';
-exports.default = Sanitizer;
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts"), __webpack_require__(/*! utils */ "./src/components/utils.js")))
-
-/***/ }),
-
-/***/ "./src/components/modules/saver.js":
-/*!*****************************************!*\
- !*** ./src/components/modules/saver.js ***!
- \*****************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * Codex Editor Saver
- *
- * @module Saver
- * @author Codex Team
- * @version 2.0.0
- */
-
-/**
- * @typedef {Object} SavedData
- * @property {Date} time - saving proccess time
- * @property {Object} items - extracted data
- * @property {String} version - CodexEditor version
- */
-
-/**
- * @classdesc This method reduces all Blocks asyncronically and calls Block's save method to extract data
- *
- * @typedef {Saver} Saver
- * @property {Element} html - Editor HTML content
- * @property {String} json - Editor JSON output
- */
-
-var Saver = function (_Module) {
- _inherits(Saver, _Module);
-
- /**
- * @constructor
- * @param config
- */
- function Saver(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, Saver);
-
- var _this = _possibleConstructorReturn(this, (Saver.__proto__ || Object.getPrototypeOf(Saver)).call(this, { config: config }));
-
- _this.output = null;
- _this.blocksData = [];
- return _this;
- }
-
- /**
- * Composes new chain of Promises to fire them alternatelly
- * @return {SavedData}
- */
-
-
- _createClass(Saver, [{
- key: 'save',
- value: function save() {
- var _this2 = this;
-
- var blocks = this.Editor.BlockManager.blocks,
- chainData = [];
-
- blocks.forEach(function (block) {
- chainData.push(block.data);
- });
-
- return Promise.all(chainData).then(function (allExtractedData) {
- return _this2.makeOutput(allExtractedData);
- }).then(function (outputData) {
- return outputData;
- });
- }
-
- /**
- * Creates output object with saved data, time and version of editor
- * @param {Object} allExtractedData
- * @return {SavedData}
- */
-
- }, {
- key: 'makeOutput',
- value: function makeOutput(allExtractedData) {
- var items = [],
- totalTime = 0;
-
- console.groupCollapsed('[CodexEditor saving]:');
-
- allExtractedData.forEach(function (extraction) {
- /** Group process info */
- console.log('\xAB' + extraction.tool + '\xBB saving info', extraction);
- totalTime += extraction.time;
- items.push(extraction.data);
- });
-
- console.log('Total', totalTime);
- console.groupEnd();
-
- return {
- time: +new Date(),
- items: items,
- version: "2.0.0"
- };
- }
- }]);
-
- return Saver;
-}(Module);
-
-// module.exports = (function (saver) {
-//
-// let 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.}
-// */
-// let saveBlocks = function (blocks) {
-//
-// let data = [];
-//
-// for(let 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 */
-// let getBlockData = function (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}
-// */
-// let saveBlockData = function (block) {
-//
-// let pluginName = block.dataset.tool;
-//
-// /** Check for plugin existence */
-// if (!editor.tools[pluginName]) {
-//
-// editor.core.log(`Plugin «${pluginName}» 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 «${pluginName}» must have save method`, 'error');
-// return {data: null, pluginName: null};
-//
-// }
-//
-// /** Result saver */
-// let 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});
-//
-// }
-//
-// return Promise.resolve(pluginsContent)
-// .then(editor.tools[pluginName].save)
-// .then(data => Object({data, pluginName}));
-//
-// };
-//
-// /**
-// * Call plugin`s validate method. Return false if validation failed
-// *
-// * @param data
-// * @param pluginName
-// * @returns {Object|Boolean}
-// */
-// let validateBlockData = function ({data, pluginName}) {
-//
-// if (!data || !pluginName) {
-//
-// return false;
-//
-// }
-//
-// if (editor.tools[pluginName].validate) {
-//
-// let result = editor.tools[pluginName].validate(data);
-//
-// /**
-// * Do not allow invalid data
-// */
-// if (!result) {
-//
-// return false;
-//
-// }
-//
-// }
-//
-// return {data, pluginName};
-//
-//
-// };
-//
-// /**
-// * Compile article output
-// *
-// * @param savedData
-// * @returns {{time: number, version, items: (*|Array)}}
-// */
-// let makeOutput = function (savedData) {
-//
-// savedData = savedData.filter(blockData => blockData);
-//
-// let items = savedData.map(blockData => 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
-// };
-//
-// };
-//
-// return saver;
-//
-// })({});
-
-
-Saver.displayName = 'Saver';
-exports.default = Saver;
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts")))
-
-/***/ }),
-
-/***/ "./src/components/modules/toolbar-blockSettings.js":
-/*!*********************************************************!*\
- !*** ./src/components/modules/toolbar-blockSettings.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module, $) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * Block Settings
- *
- * ____ Settings Panel ____
- * | ...................... |
- * | . Tool Settings . |
- * | ...................... |
- * | . Default Settings . |
- * | ...................... |
- * |________________________|
- */
-var BlockSettings = function (_Module) {
- _inherits(BlockSettings, _Module);
-
- function BlockSettings(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, BlockSettings);
-
- var _this = _possibleConstructorReturn(this, (BlockSettings.__proto__ || Object.getPrototypeOf(BlockSettings)).call(this, { config: config }));
-
- _this.nodes = {
- wrapper: null,
- toolSettings: null,
- defaultSettings: null
- };
- return _this;
- }
-
- /**
- * Block Settings CSS
- * @return {{wrapper, wrapperOpened, toolSettings, defaultSettings, button}}
- */
-
-
- _createClass(BlockSettings, [{
- key: 'make',
-
-
- /**
- * Panel with block settings with 2 sections:
- * - Tool's Settings
- * - Default Settings [Move, Remove, etc]
- *
- * @return {Element}
- */
- value: function make() {
- this.nodes.wrapper = $.make('div', BlockSettings.CSS.wrapper);
-
- this.nodes.toolSettings = $.make('div', BlockSettings.CSS.toolSettings);
- this.nodes.defaultSettings = $.make('div', BlockSettings.CSS.defaultSettings);
-
- $.append(this.nodes.wrapper, [this.nodes.toolSettings, this.nodes.defaultSettings]);
- }
-
- /**
- * Add Tool's settings
- */
-
- }, {
- key: 'addToolSettings',
- value: function addToolSettings() {
- if (typeof this.Editor.BlockManager.currentBlock.tool.makeSettings === 'function') {
- $.append(this.nodes.toolSettings, this.Editor.BlockManager.currentBlock.tool.makeSettings());
- }
- }
-
- /**
- * Add default settings
- */
-
- }, {
- key: 'addDefaultSettings',
- value: function addDefaultSettings() {
- $.append(this.nodes.defaultSettings, this.Editor.BlockManager.currentBlock.renderTunes());
- }
-
- /**
- * Is Block Settings opened or not
- * @returns {boolean}
- */
-
- }, {
- key: 'open',
-
-
- /**
- * Open Block Settings pane
- */
- value: function open() {
- this.nodes.wrapper.classList.add(BlockSettings.CSS.wrapperOpened);
-
- /**
- * Fill Tool's settings
- */
- this.addToolSettings();
-
- /**
- * Add default settings that presents for all Blocks
- */
- this.addDefaultSettings();
- }
-
- /**
- * Close Block Settings pane
- */
-
- }, {
- key: 'close',
- value: function close() {
- this.nodes.wrapper.classList.remove(BlockSettings.CSS.wrapperOpened);
- }
- }, {
- key: 'opened',
- get: function get() {
- return this.nodes.wrapper.classList.contains(BlockSettings.CSS.wrapperOpened);
- }
- }], [{
- key: 'CSS',
- get: function get() {
- return {
- // Settings Panel
- wrapper: 'ce-settings',
- wrapperOpened: 'ce-settings--opened',
- toolSettings: 'ce-settings__plugin-zone',
- defaultSettings: 'ce-settings__default-zone',
-
- button: 'ce-settings__button'
- };
- }
- }]);
-
- return BlockSettings;
-}(Module);
-
-BlockSettings.displayName = 'BlockSettings';
-exports.default = BlockSettings;
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts"), __webpack_require__(/*! dom */ "./src/components/dom.js")))
-
-/***/ }),
-
-/***/ "./src/components/modules/toolbar-inline.ts":
-/*!**************************************************!*\
- !*** ./src/components/modules/toolbar-inline.ts ***!
- \**************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module, $) {
-
-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; }; }();
-
-var _inlineToolBold = __webpack_require__(/*! ../inline-tools/inline-tool-bold */ "./src/components/inline-tools/inline-tool-bold.ts");
-
-var _inlineToolBold2 = _interopRequireDefault(_inlineToolBold);
-
-var _selection = __webpack_require__(/*! ../selection */ "./src/components/selection.js");
-
-var _selection2 = _interopRequireDefault(_selection);
-
-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"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var InlineToolbar = function (_Module) {
- _inherits(InlineToolbar, _Module);
-
- /**
- * @constructor
- */
- function InlineToolbar(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, InlineToolbar);
-
- /**
- * Inline Toolbar elements
- */
- var _this = _possibleConstructorReturn(this, (InlineToolbar.__proto__ || Object.getPrototypeOf(InlineToolbar)).call(this, { config: config }));
-
- _this.nodes = {
- wrapper: null
- };
- /**
- * CSS styles
- */
- _this.CSS = {
- inlineToolbar: 'ce-inline-toolbar',
- inlineToolbarShowed: 'ce-inline-toolbar--showed'
- };
- /**
- * Margin above/below the Toolbar
- */
- _this.toolbarVerticalMargin = 20;
- /**
- * Available Tools classes
- */
- _this.tools = [];
- /**
- * @todo Merge internal tools with external
- */
- _this.tools = [new _inlineToolBold2.default()];
- return _this;
- }
- /**
- * Making DOM
- */
-
-
- _createClass(InlineToolbar, [{
- key: 'make',
- value: function make() {
- this.nodes.wrapper = $.make('div', this.CSS.inlineToolbar);
- /**
- * Append Inline Toolbar to the Editor
- */
- $.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);
- /**
- * Append Inline Toolbar Tools
- */
- this.addTools();
- }
- /**
- *
- *
- * Moving / appearance
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- */
- /**
- * Shows Inline Toolbar by keyup/mouseup
- * @param {KeyboardEvent|MouseEvent} event
- */
-
- }, {
- key: 'handleShowingEvent',
- value: function handleShowingEvent(event) {
- if (!this.allowedToShow(event)) {
- this.close();
- return;
- }
- this.move();
- this.open();
- /** Check Tools state for selected fragment */
- this.checkToolsState();
- }
- /**
- * Move Toolbar to the selected text
- */
-
- }, {
- key: 'move',
- value: function move() {
- var selectionRect = _selection2.default.rect;
- var wrapperOffset = this.Editor.UI.nodes.wrapper.getBoundingClientRect();
- var newCoords = {
- x: selectionRect.x - wrapperOffset.left,
- y: selectionRect.y + selectionRect.height
- // + window.scrollY
- - wrapperOffset.top + this.toolbarVerticalMargin
- };
- /**
- * If we know selections width, place InlineToolbar to center
- */
- if (selectionRect.width) {
- newCoords.x += Math.floor(selectionRect.width / 2);
- }
- this.nodes.wrapper.style.left = Math.floor(newCoords.x) + 'px';
- this.nodes.wrapper.style.top = Math.floor(newCoords.y) + 'px';
- }
- /**
- * Shows Inline Toolbar
- */
-
- }, {
- key: 'open',
- value: function open() {
- this.nodes.wrapper.classList.add(this.CSS.inlineToolbarShowed);
- }
- /**
- * Hides Inline Toolbar
- */
-
- }, {
- key: 'close',
- value: function close() {
- this.nodes.wrapper.classList.remove(this.CSS.inlineToolbarShowed);
- }
- /**
- * Need to show Inline Toolbar or not
- * @param {KeyboardEvent|MouseEvent} event
- */
-
- }, {
- key: 'allowedToShow',
- value: function allowedToShow(event) {
- /**
- * Tags conflicts with window.selection function.
- * Ex. IMG tag returns null (Firefox) or Redactors wrapper (Chrome)
- */
- var tagsConflictsWithSelection = ['IMG', 'INPUT'];
- if (event && tagsConflictsWithSelection.includes(event.target.tagName)) {
- return false;
- }
- var currentSelection = _selection2.default.get(),
- selectedText = _selection2.default.text;
- // old browsers
- if (!currentSelection || !currentSelection.anchorNode) {
- return false;
- }
- // empty selection
- if (currentSelection.isCollapsed || selectedText.length < 1) {
- return false;
- }
- // is enabled by current Block's Tool
- var currentBlock = this.Editor.BlockManager.getBlock(currentSelection.anchorNode);
- if (!currentBlock) {
- return false;
- }
- var toolConfig = this.config.toolsConfig[currentBlock.name];
- return toolConfig && toolConfig[this.Editor.Tools.apiSettings.IS_ENABLED_INLINE_TOOLBAR];
- }
- /**
- *
- *
- * Working with Tools
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- */
- /**
- * Fill Inline Toolbar with Tools
- */
-
- }, {
- key: 'addTools',
- value: function addTools() {
- var _this2 = this;
-
- this.tools.forEach(function (tool) {
- _this2.addTool(tool);
- });
- }
- /**
- * Add tool button and activate clicks
- * @param {InlineTool} tool - Tool's instance
- */
-
- }, {
- key: 'addTool',
- value: function addTool(tool) {
- var _this3 = this;
-
- var button = tool.render();
- this.nodes.wrapper.appendChild(button);
- this.Editor.Listeners.on(button, 'click', function () {
- _this3.toolClicked(tool);
- });
- }
- /**
- * Inline Tool button clicks
- * @param {InlineTool} tool - Tool's instance
- */
-
- }, {
- key: 'toolClicked',
- value: function toolClicked(tool) {
- var range = _selection2.default.range;
- if (!range) {
- return;
- }
- tool.surround(range);
- this.checkToolsState();
- }
- /**
- * Check Tools` state by selection
- */
-
- }, {
- key: 'checkToolsState',
- value: function checkToolsState() {
- this.tools.forEach(function (tool) {
- tool.checkState(_selection2.default.get);
- });
- }
- }]);
-
- return InlineToolbar;
-}(Module);
-
-InlineToolbar.displayName = 'InlineToolbar';
-exports.default = InlineToolbar;
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts"), __webpack_require__(/*! dom */ "./src/components/dom.js")))
-
-/***/ }),
-
-/***/ "./src/components/modules/toolbar-toolbox.js":
-/*!***************************************************!*\
- !*** ./src/components/modules/toolbar-toolbox.js ***!
- \***************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module, $, _) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * @class Toolbox
- * @classdesc Holder for Tools
- *
- * @typedef {Toolbox} Toolbox
- * @property {Boolean} opened - opening state
- * @property {Object} nodes - Toolbox nodes
- * @property {Object} CSS - CSS class names
- *
- */
-var Toolbox = function (_Module) {
- _inherits(Toolbox, _Module);
-
- /**
- * @constructor
- */
- function Toolbox(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, Toolbox);
-
- var _this = _possibleConstructorReturn(this, (Toolbox.__proto__ || Object.getPrototypeOf(Toolbox)).call(this, { config: config }));
-
- _this.nodes = {
- toolbox: null,
- buttons: []
- };
-
- /**
- * Opening state
- * @type {boolean}
- */
- _this.opened = false;
- return _this;
- }
-
- /**
- * CSS styles
- * @return {{toolbox: string, toolboxButton: string, toolboxOpened: string}}
- */
-
-
- _createClass(Toolbox, [{
- key: 'make',
-
-
- /**
- * Makes the Toolbox
- */
- value: function make() {
- this.nodes.toolbox = $.make('div', Toolbox.CSS.toolbox);
- $.append(this.Editor.Toolbar.nodes.content, this.nodes.toolbox);
-
- this.addTools();
- }
-
- /**
- * Iterates available tools and appends them to the Toolbox
- */
-
- }, {
- key: 'addTools',
- value: function addTools() {
- var tools = this.Editor.Tools.toolsAvailable;
-
- for (var toolName in tools) {
- this.addTool(toolName, tools[toolName]);
- }
- }
-
- /**
- * Append Tool to the Toolbox
- *
- * @param {string} toolName - tool name
- * @param {Tool} tool - tool class
- */
-
- }, {
- key: 'addTool',
- value: function addTool(toolName, tool) {
- var _this2 = this;
-
- var api = this.Editor.Tools.apiSettings;
-
- if (tool[api.IS_DISPLAYED_IN_TOOLBOX] && !tool[api.TOOLBAR_ICON_CLASS]) {
- _.log('Toolbar icon class name is missed. Tool %o skipped', 'warn', toolName);
- return;
- }
-
- /**
- * @todo Add checkup for the render method
- */
- // if (typeof tool.render !== 'function') {
- //
- // _.log('render method missed. Tool %o skipped', 'warn', tool);
- // return;
- //
- // }
-
- /**
- * Skip tools that pass 'displayInToolbox=false'
- */
- if (!tool[api.IS_DISPLAYED_IN_TOOLBOX]) {
- return;
- }
-
- var button = $.make('li', [Toolbox.CSS.toolboxButton, tool[api.TOOLBAR_ICON_CLASS]], {
- title: toolName
- });
-
- /**
- * Save tool's name in the button data-name
- */
- button.dataset.name = toolName;
-
- $.append(this.nodes.toolbox, button);
-
- this.nodes.toolbox.appendChild(button);
- this.nodes.buttons.push(button);
-
- /**
- * @todo add event with module Listeners
- */
- // this.Editor.Listeners.add();
- button.addEventListener('click', function (event) {
- _this2.buttonClicked(event);
- }, false);
- }
-
- /**
- * Toolbox button click listener
- * 1) if block is empty -> replace
- * 2) if block is not empty -> add new block below
- *
- * @param {MouseEvent} event
- */
-
- }, {
- key: 'buttonClicked',
- value: function buttonClicked(event) {
- var toolButton = event.target,
- toolName = toolButton.dataset.name,
- tool = this.Editor.Tools.toolClasses[toolName];
-
- /**
- * @type {Block}
- */
- var currentBlock = this.Editor.BlockManager.currentBlock;
-
- /**
- * We do replace if:
- * - block is empty
- * - block is not irreplaceable
- * @type {Array}
- */
- if (!tool[this.Editor.Tools.apiSettings.IS_IRREPLACEBLE_TOOL] && currentBlock.isEmpty) {
- this.Editor.BlockManager.replace(toolName);
- } else {
- this.Editor.BlockManager.insert(toolName);
- }
-
- /**
- * @todo set caret to the new block
- */
-
- // window.setTimeout(function () {
-
- /** Set caret to current block */
- // editor.caret.setToBlock(currentInputIndex);
-
- // }, 10);
-
- /**
- * Move toolbar when node is changed
- */
- this.Editor.Toolbar.move();
- }
-
- /**
- * Open Toolbox with Tools
- */
-
- }, {
- key: 'open',
- value: function open() {
- this.nodes.toolbox.classList.add(Toolbox.CSS.toolboxOpened);
- this.opened = true;
- }
-
- /**
- * Close Toolbox
- */
-
- }, {
- key: 'close',
- value: function close() {
- this.nodes.toolbox.classList.remove(Toolbox.CSS.toolboxOpened);
- this.opened = false;
- }
-
- /**
- * Close Toolbox
- */
-
- }, {
- key: 'toggle',
- value: function toggle() {
- if (!this.opened) {
- this.open();
- } else {
- this.close();
- }
- }
- }], [{
- key: 'CSS',
- get: function get() {
- return {
- toolbox: 'ce-toolbox',
- toolboxButton: 'ce-toolbox__button',
- toolboxOpened: 'ce-toolbox--opened'
- };
- }
- }]);
-
- return Toolbox;
-}(Module);
-
-Toolbox.displayName = 'Toolbox';
-exports.default = Toolbox;
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts"), __webpack_require__(/*! dom */ "./src/components/dom.js"), __webpack_require__(/*! utils */ "./src/components/utils.js")))
-
-/***/ }),
-
-/***/ "./src/components/modules/toolbar.js":
-/*!*******************************************!*\
- !*** ./src/components/modules/toolbar.js ***!
- \*******************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module, $) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- *
- * «Toolbar» is the node that moves up/down over current block
- *
- * ______________________________________ Toolbar ____________________________________________
- * | |
- * | ..................... Content .................... ......... Block Actions .......... |
- * | . . . . |
- * | . . . [Open Settings] . |
- * | . [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
- *
- * @typedef {Toolbar} Toolbar
- * @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.blockActionsButtons - Zone with Block Buttons: [Settings]
- * @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.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 (_Module) {
- _inherits(Toolbar, _Module);
-
- /**
- * @constructor
- */
- function Toolbar(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, Toolbar);
-
- var _this = _possibleConstructorReturn(this, (Toolbar.__proto__ || Object.getPrototypeOf(Toolbar)).call(this, { config: config }));
-
- _this.nodes = {
- wrapper: null,
- content: null,
- actions: null,
-
- // Content Zone
- plusButton: null,
-
- // Actions Zone
- blockActionsButtons: null,
- settingsToggler: null
- };
- return _this;
- }
-
- /**
- * CSS styles
- * @return {Object}
- * @constructor
- */
-
-
- _createClass(Toolbar, [{
- key: 'make',
-
-
- /**
- * Makes toolbar
- */
- value: function make() {
- var _this2 = this;
-
- this.nodes.wrapper = $.make('div', Toolbar.CSS.toolbar);
-
- /**
- * Make Content Zone and Actions Zone
- */
- ['content', 'actions'].forEach(function (el) {
- _this2.nodes[el] = $.make('div', Toolbar.CSS[el]);
- $.append(_this2.nodes.wrapper, _this2.nodes[el]);
- });
-
- /**
- * Fill Content Zone:
- * - Plus Button
- * - Toolbox
- */
- this.nodes.plusButton = $.make('div', Toolbar.CSS.plusButton);
- $.append(this.nodes.content, this.nodes.plusButton);
- this.nodes.plusButton.addEventListener('click', function (event) {
- return _this2.plusButtonClicked(event);
- }, false);
-
- /**
- * Make a Toolbox
- */
- this.Editor.Toolbox.make();
-
- /**
- * Fill Actions Zone:
- * - Settings Toggler
- * - Remove Block Button
- * - Settings Panel
- */
- this.nodes.blockActionsButtons = $.make('div', Toolbar.CSS.blockActionsButtons);
- this.nodes.settingsToggler = $.make('span', Toolbar.CSS.settingsToggler);
-
- $.append(this.nodes.blockActionsButtons, this.nodes.settingsToggler);
- $.append(this.nodes.actions, this.nodes.blockActionsButtons);
-
- /**
- * Make and append Settings Panel
- */
- this.Editor.BlockSettings.make();
- $.append(this.nodes.actions, this.Editor.BlockSettings.nodes.wrapper);
-
- /**
- * Append toolbar to the Editor
- */
- $.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);
-
- /**
- * Bind events on the Toolbar elements
- */
- this.bindEvents();
- }
-
- /**
- * Move Toolbar to the Current Block
- */
-
- }, {
- key: 'move',
- value: function move() {
- /** Close Toolbox when we move toolbar */
- this.Editor.Toolbox.close();
-
- var currentNode = this.Editor.BlockManager.currentNode;
-
- /**
- * If no one Block selected as a Current
- */
- if (!currentNode) {
- return;
- }
-
- /**
- * @todo Compute dynamically on prepare
- * @type {number}
- */
- var defaultToolbarHeight = 49;
- var defaultOffset = 34;
-
- var newYCoordinate = currentNode.offsetTop - defaultToolbarHeight / 2 + defaultOffset;
-
- this.nodes.wrapper.style.transform = 'translate3D(0, ' + Math.floor(newYCoordinate) + 'px, 0)';
-
- /** Close trash actions */
- // editor.toolbar.settings.hideRemoveActions();
- }
-
- /**
- * Open Toolbar with Plus Button
- */
-
- }, {
- key: 'open',
- value: function open() {
- this.nodes.wrapper.classList.add(Toolbar.CSS.toolbarOpened);
- }
-
- /**
- * Close the Toolbar
- */
-
- }, {
- key: 'close',
- value: function close() {
- this.nodes.wrapper.classList.remove(Toolbar.CSS.toolbarOpened);
- }
-
- /**
- * Plus Button public methods
- * @return {{hide: function(): void, show: function(): void}}
- */
-
- }, {
- key: 'plusButtonClicked',
-
-
- /**
- * Handler for Plus Button
- * @param {MouseEvent} event
- */
- value: function plusButtonClicked() {
- this.Editor.Toolbox.toggle();
- }
-
- /**
- * Bind events on the Toolbar Elements:
- * - Block Settings
- */
-
- }, {
- key: 'bindEvents',
- value: function bindEvents() {
- var _this3 = this;
-
- /**
- * Settings toggler
- */
- this.Editor.Listeners.on(this.nodes.settingsToggler, 'click', function (event) {
- _this3.settingsTogglerClicked(event);
- });
- }
-
- /**
- * Clicks on the Block Settings toggler
- */
-
- }, {
- key: 'settingsTogglerClicked',
- value: function settingsTogglerClicked() {
- if (this.Editor.BlockSettings.opened) {
- this.Editor.BlockSettings.close();
- } else {
- this.Editor.BlockSettings.open();
- }
- }
- }, {
- key: 'plusButton',
- get: function get() {
- var _this4 = this;
-
- return {
- hide: function hide() {
- return _this4.nodes.plusButton.classList.add(Toolbar.CSS.plusButtonHidden);
- },
- show: function show() {
- return _this4.nodes.plusButton.classList.remove(Toolbar.CSS.plusButtonHidden);
- }
- };
- }
- }], [{
- key: 'CSS',
- get: function get() {
- return {
- toolbar: 'ce-toolbar',
- content: 'ce-toolbar__content',
- actions: 'ce-toolbar__actions',
-
- toolbarOpened: 'ce-toolbar--opened',
-
- // Content Zone
- plusButton: 'ce-toolbar__plus',
- plusButtonHidden: 'ce-toolbar__plus--hidden',
-
- // Actions Zone
- blockActionsButtons: 'ce-toolbar__actions-buttons',
- settingsToggler: 'ce-toolbar__settings-btn'
- };
- }
- }]);
-
- return Toolbar;
-}(Module);
-
-Toolbar.displayName = 'Toolbar';
-exports.default = Toolbar;
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts"), __webpack_require__(/*! dom */ "./src/components/dom.js")))
-
-/***/ }),
-
-/***/ "./src/components/modules/tools.js":
-/*!*****************************************!*\
- !*** ./src/components/modules/tools.js ***!
- \*****************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module, _) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * @module Codex Editor Tools Submodule
- *
- * Creates Instances from Plugins and binds external config to the instances
- */
-
-/**
- * Each Tool must contain the following important objects:
- *
- * @typedef {Object} ToolConfig {@link docs/tools.md}
- * @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
- * @property {Boolean|String[]} inlineToolbar - Pass `true` to enable the Inline Toolbar with all Tools, all pass an array with specified Tools list |
- * @property render @todo add description
- * @property save @todo add description
- * @property settings @todo add description
- * @property validate - method that validates output data before saving
- */
-
-/**
- * @typedef {Function} Tool {@link docs/tools.md}
- * @property {Boolean} displayInToolbox - By default, tools won't be added in the Toolbox. Pass true to add.
- * @property {String} iconClassName - CSS class name for the Toolbox button
- * @property {Boolean} irreplaceable - Toolbox behaviour: replace or add new block below
- * @property render
- * @property save
- * @property settings
- * @property validate
- *
- * @todo update according to current API
- * @todo describe Tool in the {@link docs/tools.md}
- */
-
-/**
- * Class properties:
- *
- * @typedef {Tools} Tools
- * @property {Tools[]} toolsAvailable - available Tools
- * @property {Tools[]} toolsUnavailable - unavailable Tools
- * @property {Object} toolsClasses - all classes
- * @property {EditorConfig} config - Editor config
- */
-var Tools = function (_Module) {
- _inherits(Tools, _Module);
-
- _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;
- }
-
- /**
- * Constant for available Tools Settings
- * @return {object}
- */
-
- }, {
- key: 'apiSettings',
- get: function get() {
- return {
- TOOLBAR_ICON_CLASS: 'iconClassName',
- IS_DISPLAYED_IN_TOOLBOX: 'displayInToolbox',
- IS_ENABLED_LINE_BREAKS: 'enableLineBreaks',
- IS_IRREPLACEBLE_TOOL: 'irreplaceable',
- IS_ENABLED_INLINE_TOOLBAR: 'inlineToolbar'
- };
- }
-
- /**
- * Static getter for default Tool config fields
- * @return {ToolConfig}
- */
-
- }, {
- key: 'defaultConfig',
- get: function get() {
- var _ref;
-
- return _ref = {}, _defineProperty(_ref, this.apiSettings.TOOLBAR_ICON_CLASS, false), _defineProperty(_ref, this.apiSettings.IS_DISPLAYED_IN_TOOLBOX, false), _defineProperty(_ref, this.apiSettings.IS_ENABLED_LINE_BREAKS, false), _defineProperty(_ref, this.apiSettings.IS_IRREPLACEBLE_TOOL, false), _defineProperty(_ref, this.apiSettings.IS_ENABLED_INLINE_TOOLBAR, false), _ref;
- }
-
- /**
- * @constructor
- *
- * @param {EditorConfig} config
- */
-
- }]);
-
- function Tools(_ref2) {
- var config = _ref2.config;
-
- _classCallCheck(this, Tools);
-
- /**
- * Map {name: Class, ...} where:
- * name — block type name in JSON. Got from EditorConfig.tools keys
- * @type {Object}
- */
- var _this = _possibleConstructorReturn(this, (Tools.__proto__ || Object.getPrototypeOf(Tools)).call(this, { config: config }));
-
- _this.toolClasses = {};
-
- /**
- * Available tools list
- * {name: Class, ...}
- * @type {Object}
- */
- _this.toolsAvailable = {};
-
- /**
- * Tools that rejected a prepare method
- * {name: Class, ... }
- * @type {Object}
- */
- _this.toolsUnavailable = {};
- return _this;
- }
-
- /**
- * Creates instances via passed or default configuration
- * @return {Promise}
- */
-
-
- _createClass(Tools, [{
- key: 'prepare',
- value: function prepare() {
- var _this2 = 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 _.sequence(sequenceData, function (data) {
- _this2.success(data);
- }, function (data) {
- _this2.fallback(data);
- });
- }
-
- /**
- * Binds prepare function of plugins with user or default config
- * @return {Array} list of functions that needs to be fired sequentially
- */
-
- }, {
- 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
- }
- });
- } else {
- /**
- * If Tool hasn't a prepare method, mark it as available
- */
- this.toolsAvailable[toolName] = toolClass;
- }
- }
-
- 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];
- }
-
- /**
- * 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;
- }
-
- /**
- * Check if passed Tool is an instance of Initial Block Tool
- * @param {Tool} tool - Tool to check
- * @return {Boolean}
- */
-
- }, {
- key: 'isInitial',
- value: function isInitial(tool) {
- return tool instanceof this.available[this.config.initialBlock];
- }
- }]);
-
- return Tools;
-}(Module);
-
-Tools.displayName = 'Tools';
-exports.default = Tools;
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts"), __webpack_require__(/*! utils */ "./src/components/utils.js")))
-
-/***/ }),
-
-/***/ "./src/components/modules/ui.js":
-/*!**************************************!*\
- !*** ./src/components/modules/ui.js ***!
- \**************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(Module, $) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-/**
- * 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'
-// };
-
-// import Block from '../block';
-
-/**
- * @class
- *
- * @classdesc Makes CodeX Editor UI:
- *
- *
- *
- *
- *
- *
- * @typedef {UI} UI
- * @property {EditorConfig} config - editor configuration {@link CodexEditor#configuration}
- * @property {Object} Editor - available editor modules {@link CodexEditor#moduleInstances}
- * @property {Object} nodes -
- * @property {Element} nodes.holder - element where we need to append redactor
- * @property {Element} nodes.wrapper -
- * @property {Element} nodes.redactor -
- */
-var UI = function (_Module) {
- _inherits(UI, _Module);
-
- /**
- * @constructor
- *
- * @param {EditorConfig} config
- */
- function UI(_ref) {
- var config = _ref.config;
-
- _classCallCheck(this, UI);
-
- var _this = _possibleConstructorReturn(this, (UI.__proto__ || Object.getPrototypeOf(UI)).call(this, { config: config }));
-
- _this.nodes = {
- holder: null,
- wrapper: null,
- redactor: null
- };
- return _this;
- }
-
- /**
- * Making main interface
- */
-
-
- _createClass(UI, [{
- key: 'prepare',
- value: function prepare() {
- var _this2 = this;
-
- return this.make()
- /**
- * Make toolbar
- */
- .then(function () {
- return _this2.Editor.Toolbar.make();
- })
- /**
- * Make the Inline toolbar
- */
- .then(function () {
- return _this2.Editor.InlineToolbar.make();
- })
- /**
- * Load and append CSS
- */
- .then(function () {
- return _this2.loadStyles();
- })
- /**
- * Bind events for the UI elements
- */
- .then(function () {
- return _this2.bindEvents();
- })
-
- /** 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");
- });
- }
-
- /**
- * CodeX Editor UI CSS class names
- * @return {{editorWrapper: string, editorZone: string, block: string}}
- */
-
- }, {
- key: 'make',
-
-
- /**
- * Makes CodeX Editor interface
- * @return {Promise}
- */
- value: function make() {
- var _this3 = this;
-
- return new Promise(function (resolve, reject) {
- /**
- * Element where we need to append CodeX Editor
- * @type {Element}
- */
- _this3.nodes.holder = document.getElementById(_this3.config.holderId);
-
- if (!_this3.nodes.holder) {
- reject(Error("Holder wasn't found by ID: #" + _this3.config.holderId));
- return;
- }
-
- /**
- * Create and save main UI elements
- */
- _this3.nodes.wrapper = $.make('div', _this3.CSS.editorWrapper);
- _this3.nodes.redactor = $.make('div', _this3.CSS.editorZone);
-
- _this3.nodes.wrapper.appendChild(_this3.nodes.redactor);
- _this3.nodes.holder.appendChild(_this3.nodes.wrapper);
-
- resolve();
- });
- }
-
- /**
- * Appends CSS
- */
-
- }, {
- key: 'loadStyles',
- value: function loadStyles() {
- /**
- * Load CSS
- */
- var styles = __webpack_require__(/*! ../../styles/main.css */ "./src/styles/main.css");
-
- /**
- * Make tag
- */
- var tag = $.make('style', null, {
- textContent: styles.toString()
- });
-
- /**
- * Append styles
- */
- $.append(document.head, tag);
- }
-
- /**
- * Bind events on the CodeX Editor interface
- */
-
- }, {
- key: 'bindEvents',
- value: function bindEvents() {
- var _this4 = this;
-
- /**
- * @todo bind events with the Listeners module
- */
- this.Editor.Listeners.on(this.nodes.redactor, 'click', function (event) {
- return _this4.redactorClicked(event);
- }, false);
- }
-
- /**
- * All clicks on the redactor zone
- *
- * @param {MouseEvent} event
- *
- * @description
- * 1. Save clicked Block as a current {@link BlockManager#currentNode}
- * it uses for the following:
- * - add CSS modifier for the selected Block
- * - on Enter press, we make a new Block under that
- *
- * 2. Move and show the Toolbar
- *
- * 3. Set a Caret
- *
- * 4. By clicks on the Editor's bottom zone:
- * - if last Block is empty, set a Caret to this
- * - otherwise, add a new empty Block and set a Caret to that
- *
- * 5. Hide the Inline Toolbar
- *
- * @see selectClickedBlock
- *
- */
-
- }, {
- key: 'redactorClicked',
- value: function redactorClicked(event) {
- var clickedNode = event.target;
-
- /**
- * Select clicked Block as Current
- */
- try {
- this.Editor.BlockManager.setCurrentBlockByChildNode(clickedNode);
- } catch (e) {
- /**
- * If clicked outside first-level Blocks, set Caret to the last empty Block
- */
- this.Editor.Caret.setToTheLastBlock();
- }
-
- /**
- * Close Inline Toolbar when nothing selected
- */
- this.Editor.InlineToolbar.handleShowingEvent(event);
-
- /**
- *
- /** 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
- */
- this.Editor.Toolbar.move();
- this.Editor.Toolbar.open();
- //
- // var inputIsEmpty = !editor.content.currentNode.textContent.trim(),
- // currentNodeType = editor.content.currentNode.dataset.tool,
- // isInitialType = currentNodeType == editor.settings.initialBlockPlugin;
- //
- //
-
- /**
- * Hide the Plus Button
- * */
- this.Editor.Toolbar.plusButton.hide();
-
- /**
- * Show the Plus Button if:
- * - Block is an initial-block (Text)
- * - Block is empty
- */
- var isInitialBlock = this.Editor.Tools.isInitial(this.Editor.BlockManager.currentBlock.tool),
- isEmptyBlock = this.Editor.BlockManager.currentBlock.isEmpty;
-
- if (isInitialBlock && isEmptyBlock) {
- this.Editor.Toolbar.plusButton.show();
- }
- }
- }, {
- key: 'CSS',
- get: function get() {
- return {
- editorWrapper: 'codex-editor',
- editorZone: 'codex-editor__redactor'
- };
- }
- }]);
-
- return UI;
-}(Module);
-
-// /**
-// * 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();
-//
-// };
-//
-//
-// 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;
-//
-// })({});
-
-
-UI.displayName = 'UI';
-exports.default = UI;
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../__module.ts */ "./src/components/__module.ts"), __webpack_require__(/*! dom */ "./src/components/dom.js")))
-
-/***/ }),
-
-/***/ "./src/components/polyfills.js":
-/*!*************************************!*\
- !*** ./src/components/polyfills.js ***!
- \*************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-/**
- * Element.closest()
- *
- * https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
- */
-if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
-
-if (!Element.prototype.closest) Element.prototype.closest = function (s) {
- var el = this;
-
- if (!document.documentElement.contains(el)) return null;
- do {
- if (el.matches(s)) return el;
- el = el.parentElement || el.parentNode;
- } while (el !== null);
- return null;
-};
-
-/***/ }),
-
-/***/ "./src/components/selection.js":
-/*!*************************************!*\
- !*** ./src/components/selection.js ***!
- \*************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* WEBPACK VAR INJECTION */(function(_) {
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-/**
- * Working with selection
- * @typedef {Selection} Selection
- */
-var Selection = function () {
- /**
- * @constructor
- */
- function Selection() {
- _classCallCheck(this, Selection);
-
- this.instance = null;
- this.selection = null;
- }
-
- /**
- * Returns window Selection
- * {@link https://developer.mozilla.org/ru/docs/Web/API/Window/getSelection}
- * @return {Selection}
- */
-
-
- _createClass(Selection, null, [{
- key: 'get',
- value: function get() {
- return window.getSelection();
- }
-
- /**
- * Returns selected anchor
- * {@link https://developer.mozilla.org/ru/docs/Web/API/Selection/anchorNode}
- * @return {Node|null}
- */
-
- }, {
- key: 'anchorNode',
- get: function get() {
- var selection = window.getSelection();
-
- return selection ? selection.anchorNode : null;
- }
-
- /**
- * Returns selection offset according to the anchor node
- * {@link https://developer.mozilla.org/ru/docs/Web/API/Selection/anchorOffset}
- * @return {Number|null}
- */
-
- }, {
- key: 'anchorOffset',
- get: function get() {
- var selection = window.getSelection();
-
- return selection ? selection.anchorOffset : null;
- }
-
- /**
- * Is current selection range collapsed
- * @return {boolean|null}
- */
-
- }, {
- key: 'isCollapsed',
- get: function get() {
- var selection = window.getSelection();
-
- return selection ? selection.isCollapsed : null;
- }
-
- /**
- * Return first range
- * @return {Range|null}
- */
-
- }, {
- key: 'range',
- get: function get() {
- var selection = window.getSelection();
-
- return selection ? selection.getRangeAt(0) : null;
- }
-
- /**
- * Calculates position and size of selected text
- * @return {{x, y, width, height, top?, left?, bottom?, right?}}
- */
-
- }, {
- key: 'rect',
- get: function get() {
- var sel = document.selection,
- range = void 0;
- var rect = {
- x: 0,
- y: 0,
- width: 0,
- height: 0
- };
-
- if (sel && sel.type !== 'Control') {
- range = sel.createRange();
- rect.x = range.boundingLeft;
- rect.y = range.boundingTop;
- rect.width = range.boundingWidth;
- rect.height = range.boundingHeight;
-
- return rect;
- }
-
- if (!window.getSelection) {
- _.log('Method window.getSelection is not supported', 'warn');
- return rect;
- }
-
- sel = window.getSelection();
-
- if (!sel.rangeCount) {
- _.log('Method Selection.rangeCount() is not supported', 'warn');
- return rect;
- }
-
- range = sel.getRangeAt(0).cloneRange();
-
- if (range.getBoundingClientRect) {
- rect = range.getBoundingClientRect();
- }
- // Fall back to inserting a temporary element
- if (rect.x === 0 && rect.y === 0) {
- var span = document.createElement('span');
-
- if (span.getBoundingClientRect) {
- // Ensure span has dimensions and position by
- // adding a zero-width space character
- span.appendChild(document.createTextNode('\u200B'));
- range.insertNode(span);
- rect = span.getBoundingClientRect();
-
- var spanParent = span.parentNode;
-
- spanParent.removeChild(span);
-
- // Glue any broken text nodes back together
- spanParent.normalize();
- }
- }
-
- return rect;
- }
-
- /**
- * Returns selected text as String
- * @returns {string}
- */
-
- }, {
- key: 'text',
- get: function get() {
- return window.getSelection ? window.getSelection().toString() : '';
- }
- }]);
-
- return Selection;
-}();
-
-Selection.displayName = 'Selection';
-exports.default = Selection;
-module.exports = exports['default'];
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! utils */ "./src/components/utils.js")))
-
-/***/ }),
-
-/***/ "./src/components/utils.js":
-/*!*********************************!*\
- !*** ./src/components/utils.js ***!
- \*********************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-/**
- * Codex Editor Util
- */
-var Util = function () {
- function Util() {
- _classCallCheck(this, Util);
- }
-
- _createClass(Util, null, [{
- key: 'log',
-
- /**
- * Custom logger
- *
- * @param {string} msg - message
- * @param {string} type - logging type 'log'|'warn'|'error'|'info'
- * @param {*} args - argument to log with a message
- */
- value: function log(msg, type, args) {
- type = type || 'log';
-
- if (!args) {
- args = msg || 'undefined';
- msg = '[codex-editor]: %o';
- } else {
- msg = '[codex-editor]: ' + msg;
- }
-
- try {
- if ('console' in window && window.console[type]) {
- if (args) window.console[type](msg, args);else window.console[type](msg);
- }
- } catch (e) {
- // do nothing
- }
- }
-
- /**
- * Returns basic keycodes as constants
- * @return {{}}
- */
-
- }, {
- 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} successCallback
- * @param {Function} fallbackCallback
- *
- * @return {Promise}
- */
- function waitNextBlock(chainData, successCallback, fallbackCallback) {
- return new Promise(function (resolve) {
- chainData.function().then(function () {
- successCallback(chainData.data || {});
- }).then(resolve).catch(function () {
- fallbackCallback(chainData.data || {});
-
- // anyway, go ahead even it falls
- resolve();
- });
- });
- }
- }
-
- /**
- * Make array from array-like collection
- *
- * @param {*} collection
- *
- * @return {Array}
- */
-
- }, {
- key: 'array',
- value: function array(collection) {
- return Array.prototype.slice.call(collection);
- }
-
- /**
- * Checks if object is empty
- *
- * @param {Object} object
- * @return {boolean}
- */
-
- }, {
- key: 'isEmpty',
- value: function isEmpty(object) {
- return Object.keys(object).length === 0 && object.constructor === Object;
- }
-
- /**
- * Check if passed object is a Promise
- * @param {*} object - object to check
- * @return {Boolean}
- */
-
- }, {
- key: 'isPromise',
- value: function isPromise(object) {
- return Promise.resolve(object) === object;
- }
-
- /**
- * Check if passed element is contenteditable
- * @param element
- * @return {boolean}
- */
-
- }, {
- key: 'isContentEditable',
- value: function isContentEditable(element) {
- return element.contentEditable === 'true';
- }
-
- /**
- * Delays method execution
- *
- * @param method
- * @param timeout
- */
-
- }, {
- key: 'delay',
- value: function delay(method, timeout) {
- return function () {
- var context = this,
- args = arguments;
-
- window.setTimeout(function () {
- return method.apply(context, args);
- }, timeout);
- };
- }
- }, {
- key: 'keyCodes',
- get: function get() {
- return {
- BACKSPACE: 8,
- TAB: 9,
- ENTER: 13,
- SHIFT: 16,
- CTRL: 17,
- ALT: 18,
- ESC: 27,
- SPACE: 32,
- LEFT: 37,
- UP: 38,
- DOWN: 40,
- RIGHT: 39,
- DELETE: 46,
- META: 91
- };
- }
- }]);
-
- return Util;
-}();
-
-Util.displayName = 'Util';
-exports.default = Util;
-;
-module.exports = exports['default'];
-
-/***/ }),
-
-/***/ "./src/styles/main.css":
-/*!*****************************!*\
- !*** ./src/styles/main.css ***!
- \*****************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-exports = module.exports = __webpack_require__(/*! ../../node_modules/css-loader/lib/css-base.js */ "./node_modules/css-loader/lib/css-base.js")(false);
-// imports
-
-
-// module
-exports.push([module.i, ":root {\n /**\n * Toolbar buttons\n */\n --bg-light: #eff2f5;\n\n /**\n * All gray texts: placeholders, settings\n */\n --grayText: #707684;\n\n /** Blue icons */\n --color-active-icon: #388AE5;\n\n /**\n * Block content width\n */\n --content-width: 650px;\n\n /**\n * Toolbar Plus Button and Toolbox buttons height and width\n */\n --toolbar-buttons-size: 34px\n}\n/**\n* Editor wrapper\n*/\n.codex-editor {\n position: relative;\n border: 1px solid #ccc;\n padding: 2px;\n box-sizing: border-box;\n}\n.codex-editor .hide {\n display: none;\n }\n.codex-editor__redactor {\n padding-bottom: 300px;\n }\n.ce-toolbar {\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n /*opacity: 0;*/\n /*visibility: hidden;*/\n transition: opacity 100ms ease;\n will-change: opacity, transform;\n display: none;\n}\n.ce-toolbar--opened {\n display: block;\n /*opacity: 1;*/\n /*visibility: visible;*/\n }\n.ce-toolbar__content {\n max-width: 650px;\n max-width: var(--content-width);\n margin: 0 auto;\n position: relative;\n }\n.ce-toolbar__plus {\n position: absolute;\n left: calc(-var(--toolbar-buttons-size) - 10px);\n left: calc(-var(--toolbar-buttons-size) - 10px);\n display: inline-block;\n background-color: #eff2f5;\n background-color: var(--bg-light);\n width: 34px;\n width: var(--toolbar-buttons-size);\n height: 34px;\n height: var(--toolbar-buttons-size);\n line-height: 34px;\n text-align: center;\n border-radius: 50%\n }\n.ce-toolbar__plus::after {\n content: '+';\n font-size: 26px;\n display: block;\n margin-top: -2px;\n margin-right: -2px;\n }\n.ce-toolbar__plus--hidden {\n display: none;\n }\n/**\n * Block actions Zone\n * -------------------------\n */\n.ce-toolbar__actions {\n position: absolute;\n right: 0;\n top: 0;\n border: 1px dotted #ccc;\n padding: 2px;\n }\n.ce-toolbar__actions-buttons {\n border: 1px dotted #ccc;\n padding: 2px;\n text-align: right;\n margin-bottom: 2px;\n }\n.ce-toolbar__settings-btn {\n display: inline-block;\n width: 24px;\n height: 24px;\n border: 1px dotted #ccc\n }\n.ce-toolbar__settings-btn::before {\n content: 'STN';\n font-size: 10px;\n opacity: .4;\n }\n.ce-toolbox {\n position: absolute;\n visibility: hidden;\n transition: opacity 100ms ease;\n will-change: opacity;\n}\n.ce-toolbox--opened {\n opacity: 1;\n visibility: visible;\n }\n.ce-toolbox__button {\n display: inline-block;\n list-style: none;\n margin: 0;\n background: #eff2f5;\n background: var(--bg-light);\n width: 34px;\n width: var(--toolbar-buttons-size);\n height: 34px;\n height: var(--toolbar-buttons-size);\n border-radius: 30px;\n overflow: hidden;\n text-align: center;\n line-height: 34px;\n line-height: var(--toolbar-buttons-size)\n }\n.ce-toolbox__button::before {\n content: attr(title);\n font-size: 22px;\n font-weight: 500;\n letter-spacing: 1em;\n -webkit-font-feature-settings: \"smcp\", \"c2sc\";\n font-feature-settings: \"smcp\", \"c2sc\";\n font-variant-caps: all-small-caps;\n padding-left: 11.5px;\n margin-top: -1px;\n display: inline-block;\n }\n.ce-inline-toolbar {\n position: absolute;\n background: #FFFFFF;\n box-shadow: 0 8px 23px -6px rgba(21,40,54,0.31), 22px -14px 34px -18px rgba(33,48,73,0.26);\n border-radius: 4px;\n z-index: 2\n}\n.ce-inline-toolbar::before {\n content: '';\n width: 15px;\n height: 15px;\n position: absolute;\n top: -7px;\n left: 50%;\n margin-left: -7px;\n transform: rotate(-45deg);\n background: #fff;\n z-index: -1;\n }\n.ce-inline-toolbar {\n padding: 6px;\n transform: translateX(-50%);\n display: none;\n}\n.ce-inline-toolbar--showed {\n display: block;\n }\n.ce-inline-tool {\n display: inline-block;\n width: 34px;\n height: 34px;\n border-radius: 3px;\n cursor: pointer;\n border: 0;\n outline: none;\n background: transparent;\n vertical-align: bottom\n}\n.ce-inline-tool:hover {\n background: #eff2f5;\n background: var(--bg-light);\n }\n.ce-inline-tool--active {\n color: #388AE5;\n color: var(--color-active-icon);\n }\n.ce-inline-tool--bold::before {\n font-weight: bold;\n content: 'B'\n }\n.ce-settings {\n border: 1px dotted #ccc;\n padding: 2px;\n display: none;\n}\n.ce-settings--opened {\n display: block;\n }\n.ce-settings__plugin-zone {\n border: 1px dotted #ccc;\n padding: 2px;\n margin-bottom: 2px\n }\n.ce-settings__plugin-zone::before {\n content: 'PLUGIN SETTINGS';\n opacity: .4;\n font-size: 12px;\n }\n.ce-settings__default-zone {\n border: 1px dotted #ccc;\n padding: 2px\n }\n.ce-settings__default-zone::before {\n /*content: 'DEFAULT SETTINGS';*/\n opacity: .4;\n font-size: 12px;\n }\n.ce-settings__button {\n padding: 10px 15px;\n color: #707684;\n color: var(--grayText)\n }\n.ce-settings__button:hover {\n background: #eff2f5;\n background: var(--bg-light);\n }\n.ce-settings-move-up:hover {\n cursor: pointer;\n }\n.ce-settings-move-up::before {\n display: inline-block;\n content: 'up';\n }\n.ce-block {\n border: 1px dotted #ccc;\n margin: 2px 0\n}\n.ce-block:first-of-type {\n margin-top: 0;\n }\n.ce-block--selected {\n background-color: #eff2f5;\n background-color: var(--bg-light);\n }\n.ce-block__content {\n max-width: 650px;\n max-width: var(--content-width);\n margin: 0 auto;\n }\n", ""]);
-
-// exports
-
-
-/***/ })
-
-/******/ });
-//# sourceMappingURL=codex-editor.js.map
\ No newline at end of file
diff --git a/build/codex-editor.js.map b/build/codex-editor.js.map
index bb51240d..e69de29b 100644
--- a/build/codex-editor.js.map
+++ b/build/codex-editor.js.map
@@ -1 +0,0 @@
-{"version":3,"sources":["webpack://CodexEditor/webpack/bootstrap","webpack://CodexEditor/./node_modules/css-loader/lib/css-base.js","webpack://CodexEditor/./node_modules/html-janitor/src/html-janitor.js","webpack://CodexEditor/./src/codex.js","webpack://CodexEditor/./src/components/__module.ts","webpack://CodexEditor/./src/components/block-tunes/block-tune-move-up.ts","webpack://CodexEditor/./src/components/block.js","webpack://CodexEditor/./src/components/dom.js","webpack://CodexEditor/./src/components/inline-tools/inline-tool-bold.ts","webpack://CodexEditor/./src/components/modules sync nonrecursive [^_](api-blocks.ts|api-sanitizer.ts|api.ts|blockManager.js|caret.js|events.js|keyboard.js|listeners.js|renderer.js|sanitizer.js|saver.js|toolbar-blockSettings.js|toolbar-inline.ts|toolbar-toolbox.js|toolbar.js|tools.js|ui.js)$","webpack://CodexEditor/./src/components/modules/api-blocks.ts","webpack://CodexEditor/./src/components/modules/api-sanitizer.ts","webpack://CodexEditor/./src/components/modules/api.ts","webpack://CodexEditor/./src/components/modules/blockManager.js","webpack://CodexEditor/./src/components/modules/caret.js","webpack://CodexEditor/./src/components/modules/events.js","webpack://CodexEditor/./src/components/modules/keyboard.js","webpack://CodexEditor/./src/components/modules/listeners.js","webpack://CodexEditor/./src/components/modules/renderer.js","webpack://CodexEditor/./src/components/modules/sanitizer.js","webpack://CodexEditor/./src/components/modules/saver.js","webpack://CodexEditor/./src/components/modules/toolbar-blockSettings.js","webpack://CodexEditor/./src/components/modules/toolbar-inline.ts","webpack://CodexEditor/./src/components/modules/toolbar-toolbox.js","webpack://CodexEditor/./src/components/modules/toolbar.js","webpack://CodexEditor/./src/components/modules/tools.js","webpack://CodexEditor/./src/components/modules/ui.js","webpack://CodexEditor/./src/components/polyfills.js","webpack://CodexEditor/./src/components/selection.js","webpack://CodexEditor/./src/components/utils.js","webpack://CodexEditor/./src/styles/main.css"],"names":["modules","editorModules","map","module","CodexEditor","config","moduleInstances","Promise","resolve","then","configuration","init","start","console","log","catch","error","constructModules","configureModules","forEach","Module","displayName","e","name","state","getModulesDiff","diff","moduleName","prepareDecorator","prepare","Tools","UI","BlockManager","Renderer","render","data","items","initialBlock","type","holderId","placeholder","sanitizer","p","b","a","hideToolbar","tools","toolsConfig","_","isEmpty","length","Editor","new","target","TypeError","MoveUpTune","api","settings","CSS","wrapper","moveUpButton","$","make","addEventListener","event","handleClick","blocks","moveUp","Block","toolName","toolInstance","apiMethods","tool","_html","compose","tunes","makeTunes","contentNode","content","pluginsContent","appendChild","methodName","params","Function","call","merge","extractedBlock","save","measuringStart","window","performance","now","measuringEnd","finishedExtraction","time","isValid","validate","tunesList","tune","tunesElement","document","createDocumentFragment","append","contentless","emptyText","emptyMedia","hasMedia","mediaTags","querySelector","join","classList","add","selected","remove","Dom","tag","tagName","includes","classNames","attributes","el","createElement","Array","isArray","attrName","createTextNode","parent","elements","selector","querySelectorAll","node","atLast","child","sibling","nodeType","Node","ELEMENT_NODE","nodeChild","isSingleTag","parentNode","getDeepestNode","nativeInputs","nodeText","isElement","isNativeInput","value","textContent","replace","trim","childNodes","treeWalker","leafs","isNodeEmpty","push","firstChild","shift","isLeaf","nextSibling","every","leaf","BoldInlineTool","commandName","button","buttonActive","buttonModifier","nodes","range","execCommand","selection","isActive","queryCommandState","toggle","BlocksAPI","SanitizerAPI","taintString","Sanitizer","clean","API","caret","toolbar","_blocks","currentBlockIndex","Blocks","redactor","Proxy","set","get","construct","block","methods","bindEvents","Listeners","on","Keyboard","blockKeydownsListener","InlineToolbar","handleShowingEvent","caretAtEnd","Caret","isAtEnd","nextBlock","setToBlock","caretAtStart","isAtStart","previousBlock","composeBlock","targetBlock","blockToMerge","blockToMergeIndex","indexOf","blockToMergeInfo","mergeWith","removeBlock","index","extractedFragment","extractFragmentFromCaretPosition","text","innerHTML","insert","element","firstLevelBlock","closest","childNode","parentFirstLevelBlock","currentNode","Error","isLastBlock","isFirstBlock","array","currentBlock","workingArea","html","deleteCount","splice","insertAdjacentElement","newBlock","children","instance","isNaN","Number","offset","atEnd","focus","nodeToSet","delay","createRange","Selection","setStart","setEnd","removeAllRanges","addRange","lastBlock","rangeCount","selectRange","getRangeAt","blockElem","deleteContents","cloneRange","selectNodeContents","endContainer","endOffset","extractContents","from","direction","current","siblings","contentEditable","isCollapsed","anchorNode","firstNode","firstLetterPosition","search","leftSiblings","getHigherLevelSiblings","nothingAtLeft","anchorOffset","lastNode","nothingAtRight","Events","subscribers","eventName","callback","reduce","previousData","currentHandler","newData","keyCode","keyCodes","BACKSPACE","backspacePressed","ENTER","enterPressed","DOWN","RIGHT","arrowRightAndDownPressed","UP","LEFT","arrowLeftAndUpPressed","apiSettings","IS_ENABLED_LINE_BREAKS","shiftKey","split","preventDefault","BM","canMergeBlocks","getBlockByIndex","mergeable","navigatePrevious","setCaretToTheEnd","mergeBlocks","setTimeout","Toolbar","close","navigateNext","allListeners","eventType","handler","useCapture","assignedEventData","alreadyExist","findOne","existingListeners","findAll","i","removeEventListener","listenersOnElement","listener","listenersWithType","listenersWithHandler","foundListeners","found","foundByElements","findByElement","filter","chainData","function","insertBlock","sequence","item","defaultConfig","_sanitizerInstance","sanitizerConfig","sanitizerInstance","require","customConfig","library","tags","href","rel","newInstance","Saver","output","blocksData","all","allExtractedData","makeOutput","outputData","totalTime","groupCollapsed","extraction","groupEnd","Date","version","VERSION","BlockSettings","toolSettings","defaultSettings","makeSettings","renderTunes","wrapperOpened","addToolSettings","addDefaultSettings","contains","inlineToolbar","inlineToolbarShowed","toolbarVerticalMargin","addTools","allowedToShow","move","open","checkToolsState","selectionRect","rect","wrapperOffset","getBoundingClientRect","newCoords","x","left","y","height","top","width","Math","floor","style","tagsConflictsWithSelection","currentSelection","selectedText","getBlock","toolConfig","IS_ENABLED_INLINE_TOOLBAR","addTool","toolClicked","surround","checkState","Toolbox","toolbox","buttons","opened","toolsAvailable","IS_DISPLAYED_IN_TOOLBOX","TOOLBAR_ICON_CLASS","toolboxButton","title","dataset","buttonClicked","toolButton","toolClasses","IS_IRREPLACEBLE_TOOL","toolboxOpened","actions","plusButton","blockActionsButtons","settingsToggler","plusButtonClicked","defaultToolbarHeight","defaultOffset","newYCoordinate","offsetTop","transform","toolbarOpened","settingsTogglerClicked","hide","plusButtonHidden","show","toolsUnavailable","hasOwnProperty","reject","sequenceData","getListOfPrepareFunctions","success","fallback","toolPreparationList","toolClass","plugin","available","holder","loadStyles","getElementById","editorWrapper","editorZone","styles","toString","head","redactorClicked","clickedNode","setCurrentBlockByChildNode","setToTheLastBlock","isInitialBlock","isInitial","isEmptyBlock","Element","prototype","matches","msMatchesSelector","webkitMatchesSelector","s","documentElement","parentElement","getSelection","sel","boundingLeft","boundingTop","boundingWidth","boundingHeight","span","insertNode","spanParent","removeChild","normalize","Util","msg","args","chains","previousValue","currentValue","iteration","waitNextBlock","successCallback","fallbackCallback","collection","slice","object","Object","keys","constructor","method","timeout","context","arguments","apply","TAB","SHIFT","CTRL","ALT","ESC","SPACE","DELETE","META"],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kDAA0C,gCAAgC;AAC1E;AACA;;AAEA;AACA;AACA;AACA,gEAAwD,kBAAkB;AAC1E;AACA,yDAAiD,cAAc;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAyC,iCAAiC;AAC1E,wHAAgH,mBAAmB,EAAE;AACrI;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;;AAGA;AACA;;;;;;;;;;;;AClFA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,mCAAmC,gBAAgB;AACnD,IAAI;AACJ;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,gBAAgB,iBAAiB;AACjC;AACA;AACA;AACA;AACA,YAAY,oBAAoB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oDAAoD,cAAc;;AAElE;AACA;;;;;;;;;;;;AC3EA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA,GAAG,QAIH;AACA,CAAC;;AAED;AACA,aAAa,OAAO;AACpB,aAAa,QAAQ;AACrB;AACA;;AAEA;AACA;;AAEA;AACA,wBAAwB,iCAAiC,EAAE;AAC3D,6BAA6B,uEAAuE,EAAE;;AAEtG;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;A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AOgC,YAAZ,EAA0B;AACxB,aAAK,KAAKhC,MAAL,CAAYgC,YAAjB,IAAiC,KAAKhC,MAAL,CAAYyC,KAA7C;AAAoD;AAApD;AACD,OAFD,MAEO;AACL,aAAKzC,MAAL,CAAYgC,YAAZ,GAA2BhC,OAAOgC,YAAlC;AACD;AACF;;AAED;;;;;wBAIoB;AAClB,aAAO,KAAKhC,MAAZ;AACD;;;;;;;kBArGkBD,W;AAgMpB;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;ACrYA;;;;;;;;;IASqBgB,M;AACjB;;;;;AAKA,wBAAwB;AAAA,QAAVf,MAAU,QAAVA,MAAU;;AAAA;;AACpB;;;;AAIA,SAAK8C,MAAL,GAAc,IAAd;AACA;;;;AAIA,SAAK9C,MAAL,GAAc,EAAd;AACA,QAAI+C,IAAIC,MAAJ,KAAejC,MAAnB,EAA2B;AACvB,YAAM,IAAIkC,SAAJ,CAAc,yDAAd,CAAN;AACH;AACD,SAAKjD,MAAL,GAAcA,MAAd;AACH;AACD;;;;;;;;;;;sBAOU8C,M,EAAQ;AACd,WAAKA,MAAL,GAAcA,MAAd;AACH;;;;;;;kBA/BgB/B,M;;;;;;;;;;;;;;;;;;;;;;;ICTAmC,U;AACjB;;;;;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rB;AACD,OAFD;;AAIA,aAAO5B,QAAQ0V,GAAR,CAAYnB,SAAZ,EACJrU,IADI,CACC,UAACyV,gBAAD;AAAA,eAAsB,OAAKC,UAAL,CAAgBD,gBAAhB,CAAtB;AAAA,OADD,EAEJzV,IAFI,CAEC,UAAC2V,UAAD,EAAgB;AACpB,eAAOA,UAAP;AACD,OAJI,CAAP;AAKD;;AAED;;;;;;;;+BAKWF,gB,EAAkB;AAC3B,UAAI9T,QAAQ,EAAZ;AAAA,UACEiU,YAAY,CADd;;AAGAxV,cAAQyV,cAAR,CAAuB,uBAAvB;;AAEAJ,uBAAiB/U,OAAjB,CAAyB,UAACoV,UAAD,EAAgB;AACvC;AACA1V,gBAAQC,GAAR,UAAgByV,WAAW/R,IAA3B,uBAAgD+R,UAAhD;AACAF,qBAAaE,WAAWzQ,IAAxB;AACA1D,cAAMqH,IAAN,CAAW8M,WAAWpU,IAAtB;AACD,OALD;;AAOAtB,cAAQC,GAAR,CAAY,OAAZ,EAAqBuV,SAArB;AACAxV,cAAQ2V,QAAR;;AAEA,aAAO;AACL1Q,cAAU,CAAC,IAAI2Q,IAAJ,EADN;AAELrU,eAAUA,KAFL;AAGLsU,iBAAU,OAAAC;AAHL,OAAP;AAKD;;;;EAzDgCvV,M;;AA4DnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A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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;;;AAGA,WAAKb,MAAL,CAAYoQ,OAAZ,CAAoBmE,IAApB;AACA,WAAKvU,MAAL,CAAYoQ,OAAZ,CAAoBoE,IAApB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;AAGA,WAAKxU,MAAL,CAAYoQ,OAAZ,CAAoB8G,UAApB,CAA+BW,IAA/B;;AAEA;;;;;AAKA,UAAI0B,iBAAiB,KAAKvZ,MAAL,CAAYrB,KAAZ,CAAkB6a,SAAlB,CAA4B,KAAKxZ,MAAL,CAAYnB,YAAZ,CAAyBqM,YAAzB,CAAsC7J,IAAlE,CAArB;AAAA,UACEoY,eAAe,KAAKzZ,MAAL,CAAYnB,YAAZ,CAAyBqM,YAAzB,CAAsCpL,OADvD;;AAGA,UAAIyZ,kBAAkBE,YAAtB,EAAoC;AAClC,aAAKzZ,MAAL,CAAYoQ,OAAZ,CAAoB8G,UAApB,CAA+Ba,IAA/B;AACD;AACF;;;wBA5MS;AACR,aAAO;AACLe,uBAAgB,cADX;AAELC,oBAAgB;AAFX,OAAP;AAID;;;;EAlE6B9a,M;;AA4QhC;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;;;;kBAjeqBW,E;;;;;;;;;;;;;;;;ACrDrB;;;;;AAKA,IAAI,CAAC8a,QAAQC,SAAR,CAAkBC,OAAvB,EACEF,QAAQC,SAAR,CAAkBC,OAAlB,GAA4BF,QAAQC,SAAR,CAAkBE,iBAAlB,IACtBH,QAAQC,SAAR,CAAkBG,qBADxB;;AAGF,IAAI,CAACJ,QAAQC,SAAR,CAAkBjP,OAAvB,EACEgP,QAAQC,SAAR,CAAkBjP,OAAlB,GAA4B,UAAUqP,CAAV,EAAa;AACvC,MAAI1V,KAAK,IAAT;;AAEA,MAAI,CAACpB,SAAS+W,eAAT,CAAyB/F,QAAzB,CAAkC5P,EAAlC,CAAL,EAA4C,OAAO,IAAP;AAC5C,KAAG;AACD,QAAIA,GAAGuV,OAAH,CAAWG,CAAX,CAAJ,EAAmB,OAAO1V,EAAP;AACnBA,SAAKA,GAAG4V,aAAH,IAAoB5V,GAAGmB,UAA5B;AACD,GAHD,QAGSnB,OAAO,IAHhB;AAIA,SAAO,IAAP;AACD,CATD,C;;;;;;;;;;;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","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, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/codex.js\");\n","/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\nmodule.exports = function(useSourceMap) {\n\tvar list = [];\n\n\t// return the list of modules as css string\n\tlist.toString = function toString() {\n\t\treturn this.map(function (item) {\n\t\t\tvar content = cssWithMappingToString(item, useSourceMap);\n\t\t\tif(item[2]) {\n\t\t\t\treturn \"@media \" + item[2] + \"{\" + content + \"}\";\n\t\t\t} else {\n\t\t\t\treturn content;\n\t\t\t}\n\t\t}).join(\"\");\n\t};\n\n\t// import a list of modules into the list\n\tlist.i = function(modules, mediaQuery) {\n\t\tif(typeof modules === \"string\")\n\t\t\tmodules = [[null, modules, \"\"]];\n\t\tvar alreadyImportedModules = {};\n\t\tfor(var i = 0; i < this.length; i++) {\n\t\t\tvar id = this[i][0];\n\t\t\tif(typeof id === \"number\")\n\t\t\t\talreadyImportedModules[id] = true;\n\t\t}\n\t\tfor(i = 0; i < modules.length; i++) {\n\t\t\tvar item = modules[i];\n\t\t\t// skip already imported module\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\n\t\t\t// when a module is imported multiple times with different media queries.\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\n\t\t\t\tif(mediaQuery && !item[2]) {\n\t\t\t\t\titem[2] = mediaQuery;\n\t\t\t\t} else if(mediaQuery) {\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\n\t\t\t\t}\n\t\t\t\tlist.push(item);\n\t\t\t}\n\t\t}\n\t};\n\treturn list;\n};\n\nfunction cssWithMappingToString(item, useSourceMap) {\n\tvar content = item[1] || '';\n\tvar cssMapping = item[3];\n\tif (!cssMapping) {\n\t\treturn content;\n\t}\n\n\tif (useSourceMap && typeof btoa === 'function') {\n\t\tvar sourceMapping = toComment(cssMapping);\n\t\tvar sourceURLs = cssMapping.sources.map(function (source) {\n\t\t\treturn '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'\n\t\t});\n\n\t\treturn [content].concat(sourceURLs).concat([sourceMapping]).join('\\n');\n\t}\n\n\treturn [content].join('\\n');\n}\n\n// Adapted from convert-source-map (MIT)\nfunction toComment(sourceMap) {\n\t// eslint-disable-next-line no-undef\n\tvar base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));\n\tvar data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;\n\n\treturn '/*# ' + data + ' */';\n}\n","(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n define('html-janitor', factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.HTMLJanitor = factory();\n }\n}(this, function () {\n\n /**\n * @param {Object} config.tags Dictionary of allowed tags.\n * @param {boolean} config.keepNestedBlockElements Default false.\n */\n function HTMLJanitor(config) {\n\n var tagDefinitions = config['tags'];\n var tags = Object.keys(tagDefinitions);\n\n var validConfigValues = tags\n .map(function(k) { return typeof tagDefinitions[k]; })\n .every(function(type) { return type === 'object' || type === 'boolean' || type === 'function'; });\n\n if(!validConfigValues) {\n throw new Error(\"The configuration was invalid\");\n }\n\n this.config = config;\n }\n\n // TODO: not exhaustive?\n var blockElementNames = ['P', 'LI', 'TD', 'TH', 'DIV', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'PRE'];\n function isBlockElement(node) {\n return blockElementNames.indexOf(node.nodeName) !== -1;\n }\n\n var inlineElementNames = ['A', 'B', 'STRONG', 'I', 'EM', 'SUB', 'SUP', 'U', 'STRIKE'];\n function isInlineElement(node) {\n return inlineElementNames.indexOf(node.nodeName) !== -1;\n }\n\n HTMLJanitor.prototype.clean = function (html) {\n var sandbox = document.createElement('div');\n sandbox.innerHTML = html;\n\n this._sanitize(sandbox);\n\n return sandbox.innerHTML;\n };\n\n HTMLJanitor.prototype._sanitize = function (parentNode) {\n var treeWalker = createTreeWalker(parentNode);\n var node = treeWalker.firstChild();\n if (!node) { return; }\n\n do {\n // Ignore nodes that have already been sanitized\n if (node._sanitized) {\n continue;\n }\n\n if (node.nodeType === Node.TEXT_NODE) {\n // If this text node is just whitespace and the previous or next element\n // sibling is a block element, remove it\n // N.B.: This heuristic could change. Very specific to a bug with\n // `contenteditable` in Firefox: http://jsbin.com/EyuKase/1/edit?js,output\n // FIXME: make this an option?\n if (node.data.trim() === ''\n && ((node.previousElementSibling && isBlockElement(node.previousElementSibling))\n || (node.nextElementSibling && isBlockElement(node.nextElementSibling)))) {\n parentNode.removeChild(node);\n this._sanitize(parentNode);\n break;\n } else {\n continue;\n }\n }\n\n // Remove all comments\n if (node.nodeType === Node.COMMENT_NODE) {\n parentNode.removeChild(node);\n this._sanitize(parentNode);\n break;\n }\n\n var isInline = isInlineElement(node);\n var containsBlockElement;\n if (isInline) {\n containsBlockElement = Array.prototype.some.call(node.childNodes, isBlockElement);\n }\n\n // Block elements should not be nested (e.g. ...); if\n // they are, we want to unwrap the inner block element.\n var isNotTopContainer = !! parentNode.parentNode;\n var isNestedBlockElement =\n isBlockElement(parentNode) &&\n isBlockElement(node) &&\n isNotTopContainer;\n\n var nodeName = node.nodeName.toLowerCase();\n\n var allowedAttrs = getAllowedAttrs(this.config, nodeName, node);\n\n var isInvalid = isInline && containsBlockElement;\n\n // Drop tag entirely according to the whitelist *and* if the markup\n // is invalid.\n if (isInvalid || shouldRejectNode(node, allowedAttrs)\n || (!this.config.keepNestedBlockElements && isNestedBlockElement)) {\n // Do not keep the inner text of SCRIPT/STYLE elements.\n if (! (node.nodeName === 'SCRIPT' || node.nodeName === 'STYLE')) {\n while (node.childNodes.length > 0) {\n parentNode.insertBefore(node.childNodes[0], node);\n }\n }\n parentNode.removeChild(node);\n\n this._sanitize(parentNode);\n break;\n }\n\n // Sanitize attributes\n for (var a = 0; a < node.attributes.length; a += 1) {\n var attr = node.attributes[a];\n\n if (shouldRejectAttr(attr, allowedAttrs, node)) {\n node.removeAttribute(attr.name);\n // Shift the array to continue looping.\n a = a - 1;\n }\n }\n\n // Sanitize children\n this._sanitize(node);\n\n // Mark node as sanitized so it's ignored in future runs\n node._sanitized = true;\n } while ((node = treeWalker.nextSibling()));\n };\n\n function createTreeWalker(node) {\n return document.createTreeWalker(node,\n NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT,\n null, false);\n }\n\n function getAllowedAttrs(config, nodeName, node){\n if (typeof config.tags[nodeName] === 'function') {\n return config.tags[nodeName](node);\n } else {\n return config.tags[nodeName];\n }\n }\n\n function shouldRejectNode(node, allowedAttrs){\n if (typeof allowedAttrs === 'undefined') {\n return true;\n } else if (typeof allowedAttrs === 'boolean') {\n return !allowedAttrs;\n }\n\n return false;\n }\n\n function shouldRejectAttr(attr, allowedAttrs, node){\n var attrName = attr.name.toLowerCase();\n\n if (allowedAttrs === true){\n return false;\n } else if (typeof allowedAttrs[attrName] === 'function'){\n return !allowedAttrs[attrName](attr.value, node);\n } else if (typeof allowedAttrs[attrName] === 'undefined'){\n return true;\n } else if (allowedAttrs[attrName] === false) {\n return true;\n } else if (typeof allowedAttrs[attrName] === 'string') {\n return (allowedAttrs[attrName] !== attr.value);\n }\n\n return false;\n }\n\n return HTMLJanitor;\n\n}));\n","/**\n * Codex Editor\n *\n * Short Description (눈_눈;)\n * @version 2.0.0\n *\n * How to start?\n * Example:\n * new CodexEditor({\n * holderId : 'codex-editor',\n * initialBlock : 'text',\n * placeholder : 'Write your story....',\n * tools: {\n * quote: Quote,\n * anotherTool : AnotherTool\n * },\n * toolsConfig: {\n * quote: {\n * iconClassname : 'quote-icon',\n * displayInToolbox : true,\n * enableLineBreaks : true\n * },\n * anotherTool: {\n * iconClassname : 'tool-icon'\n * }\n * }\n * });\n *\n * - tools is an object: {\n * pluginName: PluginClass,\n * .....\n * }\n * - toolsConfig is an additional configuration that uses Codex Editor API\n * iconClassname - CSS classname of toolbox icon\n * displayInToolbox - if you want to see your Tool in toolbox hided in \"plus\" button, than set \"True\". By default : \"False\"\n * enableLineBreaks - by default enter creates new block that set as initialblock, but if you set this property \"True\", enter will break the lines in current block\n *\n * @author CodeX-Team \n *\n */\n\n/**\n * @typedef {CodexEditor} CodexEditor - editor class\n */\n\n/**\n * @typedef {Object} EditorConfig\n * @property {String} holderId - Element to append Editor\n * @property {Array} data - Blocks list in JSON-format\n * @property {Object} tools - Map for used Tools in format { name : Class, ... }\n * @property {String} initialBlock - This Tool will be added by default\n * @property {String} placeholder - First Block placeholder\n * @property {Object} sanitizer - @todo fill desc\n * @property {Boolean} hideToolbar - @todo fill desc\n * @property {Object} toolsConfig - tools configuration {@link tools#ToolConfig}\n */\n\n/**\n * Dynamically imported utils\n *\n * @typedef {Dom} $ - {@link components/dom.js}\n * @typedef {Util} _ - {@link components/utils.js}\n */\n\n'use strict';\n\n/**\n * Apply polyfills\n */\nimport 'components/polyfills';\n\n/**\n * Require Editor modules places in components/modules dir\n */\n// eslint-disable-next-line\nlet modules = editorModules.map( module => require('./components/modules/' + module ));\n\n/**\n * @class\n *\n * @classdesc CodeX Editor base class\n *\n * @property this.config - all settings\n * @property this.moduleInstances - constructed editor components\n *\n * @type {CodexEditor}\n */\nexport default class CodexEditor {\n /** Editor version */\n static get version() {\n return VERSION;\n }\n\n /**\n * @param {EditorConfig} config - user configuration\n *\n */\n constructor(config) {\n /**\n * Configuration object\n * @type {EditorConfig}\n */\n this.config = {};\n\n /**\n * @typedef {Object} EditorComponents\n * @property {BlockManager} BlockManager\n * @property {Tools} Tools\n * @property {Events} Events\n * @property {UI} UI\n * @property {Toolbar} Toolbar\n * @property {Toolbox} Toolbox\n * @property {BlockSettings} BlockSettings\n * @property {Renderer} Renderer\n * @property {InlineToolbar} InlineToolbar\n */\n this.moduleInstances = {};\n\n Promise.resolve()\n .then(() => {\n this.configuration = config;\n })\n .then(() => this.init())\n .then(() => this.start())\n .then(() => {\n console.log('CodeX Editor is ready!');\n })\n .catch(error => {\n console.log('CodeX Editor does not ready because of %o', error);\n });\n }\n\n /**\n * Setting for configuration\n * @param {EditorConfig} config\n */\n set configuration(config) {\n /**\n * Initlai block type\n * Uses in case when there is no items passed\n * @type {{type: (*), data: {text: null}}}\n */\n let initialBlock = {\n type : config.initialBlock,\n data : {}\n };\n\n this.config.holderId = config.holderId;\n this.config.placeholder = config.placeholder || 'write your story...';\n this.config.sanitizer = config.sanitizer || {\n p: true,\n b: true,\n a: true\n };\n\n this.config.hideToolbar = config.hideToolbar ? config.hideToolbar : false;\n this.config.tools = config.tools || {};\n this.config.toolsConfig = config.toolsConfig || {};\n this.config.data = config.data || {};\n\n /**\n * Initialize items to pass data to the Renderer\n */\n if (_.isEmpty(this.config.data)) {\n this.config.data = {};\n this.config.data.items = [ initialBlock ];\n } else {\n if (!this.config.data.items || this.config.data.items.length === 0) {\n this.config.data.items = [ initialBlock ];\n }\n }\n\n /**\n * If initial Block's Tool was not passed, use the first Tool in config.tools\n */\n if (!config.initialBlock) {\n for (this.config.initialBlock in this.config.tools) break;\n } else {\n this.config.initialBlock = config.initialBlock;\n }\n }\n\n /**\n * Returns private property\n * @returns {EditorConfig}\n */\n get configuration() {\n return this.config;\n }\n\n /**\n * Initializes modules:\n * - make and save instances\n * - configure\n */\n init() {\n /**\n * Make modules instances and save it to the @property this.moduleInstances\n */\n this.constructModules();\n\n /**\n * Modules configuration\n */\n this.configureModules();\n }\n\n /**\n * Make modules instances and save it to the @property this.moduleInstances\n */\n constructModules() {\n modules.forEach( Module => {\n try {\n /**\n * We use class name provided by displayName property\n *\n * On build, Babel will transform all Classes to the Functions so, name will always be 'Function'\n * To prevent this, we use 'babel-plugin-class-display-name' plugin\n * @see https://www.npmjs.com/package/babel-plugin-class-display-name\n */\n this.moduleInstances[Module.displayName] = new Module({\n config : this.configuration\n });\n } catch ( e ) {\n console.log('Module %o skipped because %o', Module, e);\n }\n });\n }\n\n /**\n * Modules instances configuration:\n * - pass other modules to the 'state' property\n * - ...\n */\n configureModules() {\n for(let name in this.moduleInstances) {\n /**\n * Module does not need self-instance\n */\n this.moduleInstances[name].state = this.getModulesDiff( name );\n }\n }\n\n /**\n * Return modules without passed name\n */\n getModulesDiff( name ) {\n let diff = {};\n\n for(let moduleName in this.moduleInstances) {\n /**\n * Skip module with passed name\n */\n if (moduleName === name) {\n continue;\n }\n diff[moduleName] = this.moduleInstances[moduleName];\n }\n\n return diff;\n }\n\n /**\n * Start Editor!\n *\n * Get list of modules that needs to be prepared and return a sequence (Promise)\n * @return {Promise}\n */\n start() {\n let prepareDecorator = module => module.prepare();\n\n return Promise.resolve()\n .then(prepareDecorator(this.moduleInstances.Tools))\n .then(prepareDecorator(this.moduleInstances.UI))\n .then(prepareDecorator(this.moduleInstances.BlockManager))\n .then(() => {\n return this.moduleInstances.Renderer.render(this.config.data.items);\n });\n }\n};\n\n// module.exports = (function (editor) {\n//\n// 'use strict';\n//\n// editor.version = VERSION;\n// editor.scriptPrefix = 'cdx-script-';\n//\n// var init = function () {\n//\n// editor.core = require('./modules/core');\n// editor.tools = require('./modules/tools');\n// editor.ui = require('./modules/ui');\n// editor.transport = require('./modules/transport');\n// editor.renderer = require('./modules/renderer');\n// editor.saver = require('./modules/saver');\n// editor.content = require('./modules/content');\n// editor.toolbar = require('./modules/toolbar/toolbar');\n// editor.callback = require('./modules/callbacks');\n// editor.draw = require('./modules/draw');\n// editor.caret = require('./modules/caret');\n// editor.notifications = require('./modules/notifications');\n// editor.parser = require('./modules/parser');\n// editor.sanitizer = require('./modules/sanitizer');\n// editor.listeners = require('./modules/listeners');\n// editor.destroyer = require('./modules/destroyer');\n// editor.paste = require('./modules/paste');\n//\n// };\n//\n// /**\n// * @public\n// * holds initial settings\n// */\n// editor.settings = {\n// tools : ['text', 'header', 'picture', 'list', 'quote', 'code', 'twitter', 'instagram', 'smile'],\n// holderId : 'codex-editor',\n//\n// // Type of block showing on empty editor\n// initialBlockPlugin: 'text'\n// };\n//\n// /**\n// * public\n// *\n// * Static nodes\n// */\n// editor.nodes = {\n// holder : null,\n// wrapper : null,\n// toolbar : null,\n// inlineToolbar : {\n// wrapper : null,\n// buttons : null,\n// actions : null\n// },\n// toolbox : null,\n// notifications : null,\n// plusButton : null,\n// showSettingsButton: null,\n// showTrashButton : null,\n// blockSettings : null,\n// pluginSettings : null,\n// defaultSettings : null,\n// toolbarButtons : {}, // { type : DomEl, ... }\n// redactor : null\n// };\n//\n// /**\n// * @public\n// *\n// * Output state\n// */\n// editor.state = {\n// jsonOutput : [],\n// blocks : [],\n// inputs : []\n// };\n//\n// /**\n// * @public\n// * Editor plugins\n// */\n// editor.tools = {};\n//\n// editor.start = function (userSettings) {\n//\n// init();\n//\n// editor.core.prepare(userSettings)\n//\n// // If all ok, make UI, bind events and parse initial-content\n// .then(editor.ui.prepare)\n// .then(editor.tools.prepare)\n// .then(editor.sanitizer.prepare)\n// .then(editor.paste.prepare)\n// .then(editor.transport.prepare)\n// .then(editor.renderer.makeBlocksFromData)\n// .then(editor.ui.saveInputs)\n// .catch(function (error) {\n//\n// editor.core.log('Initialization failed with error: %o', 'warn', error);\n//\n// });\n//\n// };\n//\n// return editor;\n//\n// })({});\n","/**\n * @abstract\n * @class Module\n * @classdesc All modules inherits from this class.\n *\n * @typedef {Module} Module\n * @property {Object} config - Editor user settings\n * @property {Object} Editor - List of Editor modules\n */\nexport default class Module {\n /**\n * @constructor\n *\n * @param {EditorConfig} config\n */\n constructor({ config }) {\n /**\n * Editor modules list\n * @type {EditorComponents}\n */\n this.Editor = null;\n /**\n * Editor configuration object\n * @type {EditorConfig}\n */\n this.config = {};\n if (new.target === Module) {\n throw new TypeError('Constructors for abstract class Module are not allowed.');\n }\n this.config = config;\n }\n /**\n * Editor modules setter\n *\n * @param Editor\n * @param Editor.modules {@link CodexEditor#moduleInstances}\n * @param Editor.config {@link CodexEditor#configuration}\n */\n set state(Editor) {\n this.Editor = Editor;\n }\n}\n","export default class MoveUpTune {\n /**\n * MoveUpTune constructor\n *\n * @param {Object} api\n * @param {Object} settings\n */\n constructor({ api, settings }) {\n /**\n * Styles\n * @type {{wrapper: string}}\n */\n this.CSS = {\n wrapper: 'ass',\n };\n this.api = api;\n this.settings = settings;\n }\n /**\n * Create \"MoveUp\" button and add click event listener\n * @returns [Element}\n */\n render() {\n const moveUpButton = $.make('div', ['ce-settings-move-up'], {});\n moveUpButton.addEventListener('click', (event) => this.handleClick(event), false);\n return moveUpButton;\n }\n /**\n * Move current block up\n * @param {MouseEvent} event\n */\n handleClick(event) {\n this.api.blocks.moveUp();\n }\n}\n","/**\n * @class Block\n * @classdesc This class describes editor`s block, including block`s HTMLElement, data and tool\n *\n * @property {Tool} tool — current block tool (Paragraph, for example)\n * @property {Object} CSS — block`s css classes\n *\n */\n\n/** Import default tunes */\nimport MoveUpTune from './block-tunes/block-tune-move-up';\n\n/**\n * @classdesc Abstract Block class that contains Block information, Tool name and Tool class instance\n *\n * @property tool - Tool instance\n * @property html - Returns HTML content of plugin\n * @property wrapper - Div element that wraps block content with Tool's content. Has `ce-block` CSS class\n * @property contentNode - Div element that wraps Tool's content. Has `ce-block__content` CSS class\n * @property pluginsContent - HTML content that returns by Tool's render function\n */\nexport default class Block {\n /**\n * @constructor\n * @param {String} toolName - Tool name that passed on initialization\n * @param {Object} toolInstance — passed Tool`s instance that rendered the Block\n * @param {Object} settings - default settings\n * @param {Object} apiMethods - Editor API\n */\n constructor(toolName, toolInstance, settings, apiMethods) {\n this.name = toolName;\n this.tool = toolInstance;\n this.settings = settings;\n this.api = apiMethods;\n this._html = this.compose();\n\n /**\n * @type {IBlockTune[]}\n */\n this.tunes = this.makeTunes();\n }\n\n /**\n * CSS classes for the Block\n * @return {{wrapper: string, content: string}}\n */\n static get CSS() {\n return {\n wrapper: 'ce-block',\n content: 'ce-block__content',\n selected: 'ce-block--selected'\n };\n }\n\n /**\n * Make default Block wrappers and put Tool`s content there\n * @returns {HTMLDivElement}\n */\n compose() {\n this.wrapper = $.make('div', Block.CSS.wrapper);\n this.contentNode = $.make('div', Block.CSS.content);\n this.pluginsContent = this.tool.render();\n\n this.contentNode.appendChild(this.pluginsContent);\n this.wrapper.appendChild(this.contentNode);\n\n return this.wrapper;\n }\n\n /**\n * Calls Tool's method\n *\n * Method checks tool property {MethodName}. Fires method with passes params If it is instance of Function\n *\n * @param {String} methodName\n * @param {Object} params\n */\n call(methodName, params) {\n /**\n * call Tool's method with the instance context\n */\n if (this.tool[methodName] && this.tool[methodName] instanceof Function) {\n this.tool[methodName].call(this.tool, params);\n }\n }\n\n /**\n * Get Block`s HTML\n * @returns {HTMLElement}\n */\n get html() {\n return this._html;\n }\n\n /**\n * Get Block's JSON data\n * @return {Object}\n */\n get data() {\n return this.save();\n }\n\n /**\n * is block mergeable\n * We plugin have merge function then we call it mergable\n * @return {boolean}\n */\n get mergeable() {\n return typeof this.tool.merge === 'function';\n }\n\n /**\n * Call plugins merge method\n * @param {Object} data\n */\n mergeWith(data) {\n return Promise.resolve()\n .then(() => {\n this.tool.merge(data);\n });\n }\n /**\n * Extracts data from Block\n * Groups Tool's save processing time\n * @return {Object}\n */\n save() {\n let extractedBlock = this.tool.save(this.pluginsContent);\n\n /** Measuring execution time*/\n let measuringStart = window.performance.now(),\n measuringEnd;\n\n return Promise.resolve(extractedBlock)\n .then((finishedExtraction) => {\n /** measure promise execution */\n measuringEnd = window.performance.now();\n\n return {\n tool: this.name,\n data: finishedExtraction,\n time : measuringEnd - measuringStart\n };\n })\n .catch(function (error) {\n _.log(`Saving proccess for ${this.tool.name} tool failed due to the ${error}`, 'log', 'red');\n });\n }\n\n /**\n * Uses Tool's validation method to check the correctness of output data\n * Tool's validation method is optional\n *\n * @description Method also can return data if it passed the validation\n *\n * @param {Object} data\n * @returns {Boolean|Object} valid\n */\n validateData(data) {\n let isValid = true;\n\n if (this.tool.validate instanceof Function) {\n isValid = this.tool.validate(data);\n }\n\n if (!isValid) {\n return false;\n }\n\n return data;\n }\n\n /**\n * Make an array with default settings\n * Each block has default tune instance that have states\n * @return {IBlockTune[]}\n */\n makeTunes() {\n let tunesList = [ MoveUpTune ];\n\n // Pluck tunes list and return tune instances with passed Editor API and settings\n return tunesList.map( (tune) => {\n return new tune({\n api: this.api,\n settings: this.settings,\n });\n });\n }\n\n /**\n * Enumerates initialized tunes and returns fragment that can be appended to the toolbars area\n * @return {DocumentFragment}\n */\n renderTunes() {\n let tunesElement = document.createDocumentFragment();\n\n this.tunes.forEach( tune => {\n $.append(tunesElement, tune.render());\n });\n\n return tunesElement;\n }\n\n /**\n * Check block for emptiness\n * @return {Boolean}\n */\n get isEmpty() {\n /**\n * Allow Tool to represent decorative contentless blocks: for example \"* * *\"-tool\n * That Tools are not empty\n */\n if (this.tool.contentless) {\n return false;\n }\n\n let emptyText = $.isEmpty(this.pluginsContent),\n emptyMedia = !this.hasMedia;\n\n return emptyText && emptyMedia;\n }\n\n /**\n * Check if block has a media content such as images, iframes and other\n * @return {Boolean}\n */\n get hasMedia() {\n /**\n * This tags represents media-content\n * @type {string[]}\n */\n const mediaTags = [\n 'img',\n 'iframe',\n 'video',\n 'audio',\n 'source',\n 'input',\n 'textarea',\n 'twitterwidget'\n ];\n\n return !!this._html.querySelector(mediaTags.join(','));\n }\n\n /**\n * Set selected state\n * @param {Boolean} state - 'true' to select, 'false' to remove selection\n */\n set selected(state) {\n /**\n * We don't need to mark Block as Selected when it is not empty\n */\n if (state === true && !this.isEmpty) {\n this._html.classList.add(Block.CSS.selected);\n } else {\n this._html.classList.remove(Block.CSS.selected);\n }\n }\n}\n","/**\n * DOM manipulations helper\n */\nexport default class Dom {\n /**\n * Check if passed tag has no closed tag\n * @param {Element} tag\n * @return {Boolean}\n */\n static isSingleTag(tag) {\n return tag.tagName && ['AREA', 'BASE', 'BR', 'COL', 'COMMAND', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR'].includes(tag.tagName);\n };\n\n\n /**\n * Helper for making Elements with classname and attributes\n *\n * @param {string} tagName - new Element tag name\n * @param {array|string} classNames - list or name of CSS classname(s)\n * @param {Object} attributes - any attributes\n * @return {Element}\n */\n static make(tagName, classNames = null, attributes = {}) {\n let el = document.createElement(tagName);\n\n if ( Array.isArray(classNames) ) {\n el.classList.add(...classNames);\n } else if( classNames ) {\n el.classList.add(classNames);\n }\n\n for (let attrName in attributes) {\n el[attrName] = attributes[attrName];\n }\n\n return el;\n }\n\n /**\n * Creates Text Node with the passed content\n * @param {String} content - text content\n * @return {Text}\n */\n static text(content) {\n return document.createTextNode(content);\n }\n\n /**\n * Append one or several elements to the parent\n *\n * @param {Element} parent - where to append\n * @param {Element|Element[]} - element ore elements list\n */\n static append(parent, elements) {\n if ( Array.isArray(elements) ) {\n elements.forEach( el => parent.appendChild(el) );\n } else {\n parent.appendChild(elements);\n }\n }\n\n /**\n * Selector Decorator\n *\n * Returns first match\n *\n * @param {Element} el - element we searching inside. Default - DOM Document\n * @param {String} selector - searching string\n *\n * @returns {Element}\n */\n static find(el = document, selector) {\n return el.querySelector(selector);\n }\n\n /**\n * Selector Decorator.\n *\n * Returns all matches\n *\n * @param {Element} el - element we searching inside. Default - DOM Document\n * @param {String} selector - searching string\n * @returns {NodeList}\n */\n static findAll(el = document, selector) {\n return el.querySelectorAll(selector);\n }\n\n /**\n * Search for deepest node which is Leaf.\n * Leaf is the vertex that doesn't have any child nodes\n *\n * @description Method recursively goes throw the all Node until it finds the Leaf\n *\n * @param {Node} node - root Node. From this vertex we start Deep-first search {@link https://en.wikipedia.org/wiki/Depth-first_search}\n * @param {Boolean} atLast - find last text node\n * @return {Node} - it can be text Node or Element Node, so that caret will able to work with it\n */\n static getDeepestNode(node, atLast = false) {\n /**\n * Current function have two directions:\n * - starts from first child and every time gets first or nextSibling in special cases\n * - starts from last child and gets last or previousSibling\n * @type {string}\n */\n let child = atLast ? 'lastChild' : 'firstChild',\n sibling = atLast ? 'previousSibling' : 'nextSibling';\n\n if (node && node.nodeType === Node.ELEMENT_NODE && node[child]) {\n let nodeChild = node[child];\n\n /**\n * special case when child is single tag that can't contain any content\n */\n if (Dom.isSingleTag(nodeChild)) {\n /**\n * 1) We need to check the next sibling. If it is Node Element then continue searching for deepest\n * from sibling\n *\n * 2) If single tag's next sibling is null, then go back to parent and check his sibling\n * In case of Node Element continue searching\n *\n * 3) If none of conditions above happened return parent Node Element\n */\n if (nodeChild[sibling]) {\n nodeChild = nodeChild[sibling];\n } else if (nodeChild.parentNode[sibling]) {\n nodeChild = nodeChild.parentNode[sibling];\n } else {\n return nodeChild.parentNode;\n }\n }\n\n return this.getDeepestNode(nodeChild, atLast);\n }\n\n return node;\n }\n\n /**\n * Check if object is DOM node\n *\n * @param {Object} node\n * @returns {boolean}\n */\n static isElement(node) {\n return node && typeof node === 'object' && node.nodeType && node.nodeType === Node.ELEMENT_NODE;\n }\n\n /**\n * Checks target if it is native input\n * @param {Element|String} target - HTML element or string\n * @return {Boolean}\n */\n static isNativeInput(target) {\n let nativeInputs = [\n 'INPUT',\n 'TEXTAREA'\n ];\n\n return target ? nativeInputs.includes(target.tagName) : false;\n }\n\n /**\n * Checks node if it is empty\n *\n * @description Method checks simple Node without any childs for emptiness\n * If you have Node with 2 or more children id depth, you better use {@link Dom#isEmpty} method\n *\n * @param {Node} node\n * @return {Boolean} true if it is empty\n */\n static isNodeEmpty(node) {\n let nodeText;\n\n if ( this.isElement(node) && this.isNativeInput(node) ) {\n nodeText = node.value;\n } else {\n nodeText = node.textContent.replace('\\u200B', '');\n }\n\n return nodeText.trim().length === 0;\n }\n\n /**\n * checks node if it is doesn't have any child nodes\n * @param {Node} node\n * @return {boolean}\n */\n static isLeaf(node) {\n if (!node) {\n return false;\n }\n\n return node.childNodes.length === 0;\n }\n\n /**\n * breadth-first search (BFS)\n * {@link https://en.wikipedia.org/wiki/Breadth-first_search}\n *\n * @description Pushes to stack all DOM leafs and checks for emptiness\n *\n * @param {Node} node\n * @return {boolean}\n */\n static isEmpty(node) {\n let treeWalker = [],\n leafs = [];\n\n if (!node) {\n return true;\n }\n\n if (!node.childNodes.length) {\n return this.isNodeEmpty(node);\n }\n\n treeWalker.push(node.firstChild);\n\n while ( treeWalker.length > 0 ) {\n node = treeWalker.shift();\n\n if (!node) continue;\n\n if ( this.isLeaf(node) ) {\n leafs.push(node);\n } else {\n treeWalker.push(node.firstChild);\n }\n\n while ( node && node.nextSibling ) {\n node = node.nextSibling;\n\n if (!node) continue;\n\n treeWalker.push(node);\n }\n\n /**\n * If one of childs is not empty, checked Node is not empty too\n */\n if (node && !this.isNodeEmpty(node)) {\n return false;\n }\n }\n\n return leafs.every( leaf => this.isNodeEmpty(leaf) );\n }\n};","/**\n * Bold Tool\n *\n * Inline Toolbar Tool\n *\n * Makes selected text bolder\n */\nexport default class BoldInlineTool {\n constructor() {\n /**\n * Native Document's command that uses for Bold\n */\n this.commandName = 'bold';\n /**\n * Styles\n */\n this.CSS = {\n button: 'ce-inline-tool',\n buttonActive: 'ce-inline-tool--active',\n buttonModifier: 'ce-inline-tool--bold',\n };\n /**\n * Elements\n */\n this.nodes = {\n button: null,\n };\n console.log('Bold Inline Tool is ready');\n }\n /**\n * Create button for Inline Toolbar\n */\n render() {\n this.nodes.button = document.createElement('button');\n this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier);\n return this.nodes.button;\n }\n /**\n * Wrap range with tag\n * @param {Range} range\n */\n surround(range) {\n document.execCommand(this.commandName);\n }\n /**\n * Check selection and set activated state to button if there are tag\n * @param {Selection} selection\n */\n checkState(selection) {\n const isActive = document.queryCommandState(this.commandName);\n this.nodes.button.classList.toggle(this.CSS.buttonActive, isActive);\n return isActive;\n }\n}\n","var map = {\n\t\"./api-blocks.ts\": \"./src/components/modules/api-blocks.ts\",\n\t\"./api-sanitizer.ts\": \"./src/components/modules/api-sanitizer.ts\",\n\t\"./api.ts\": \"./src/components/modules/api.ts\",\n\t\"./blockManager.js\": \"./src/components/modules/blockManager.js\",\n\t\"./caret.js\": \"./src/components/modules/caret.js\",\n\t\"./events.js\": \"./src/components/modules/events.js\",\n\t\"./keyboard.js\": \"./src/components/modules/keyboard.js\",\n\t\"./listeners.js\": \"./src/components/modules/listeners.js\",\n\t\"./renderer.js\": \"./src/components/modules/renderer.js\",\n\t\"./sanitizer.js\": \"./src/components/modules/sanitizer.js\",\n\t\"./saver.js\": \"./src/components/modules/saver.js\",\n\t\"./toolbar-blockSettings.js\": \"./src/components/modules/toolbar-blockSettings.js\",\n\t\"./toolbar-inline.ts\": \"./src/components/modules/toolbar-inline.ts\",\n\t\"./toolbar-toolbox.js\": \"./src/components/modules/toolbar-toolbox.js\",\n\t\"./toolbar.js\": \"./src/components/modules/toolbar.js\",\n\t\"./tools.js\": \"./src/components/modules/tools.js\",\n\t\"./ui.js\": \"./src/components/modules/ui.js\"\n};\n\n\nfunction webpackContext(req) {\n\tvar id = webpackContextResolve(req);\n\treturn __webpack_require__(id);\n}\nfunction webpackContextResolve(req) {\n\tvar id = map[req];\n\tif(!(id + 1)) { // check for number or string\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\treturn id;\n}\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = \"./src/components/modules sync [^_](api-blocks.ts|api-sanitizer.ts|api.ts|blockManager.js|caret.js|events.js|keyboard.js|listeners.js|renderer.js|sanitizer.js|saver.js|toolbar-blockSettings.js|toolbar-inline.ts|toolbar-toolbox.js|toolbar.js|tools.js|ui.js)$\";","/**\n *\n */\nexport default class BlocksAPI extends Module {\n /**\n * Save Editor config. API provides passed configuration to the Blocks\n * @param {EditorsConfig} config\n */\n constructor({ config }) {\n super({ config });\n }\n moveDown() {\n console.log('moving down', this.Editor.BlockManager);\n }\n /**\n * Moves block up\n */\n moveUp() {\n console.log('moving up', this.Editor.BlockManager);\n }\n}\n","/**\n * @class API\n */\nexport default class SanitizerAPI extends Module {\n /**\n * Save Editor config. API provides passed configuration to the Blocks\n * @param {EditorsConfig} config\n */\n constructor({ config }) {\n super({ config });\n }\n clean(taintString, config) {\n return this.Editor.Sanitizer.clean(taintString, config);\n }\n}\n","/**\n * @class API\n */\nexport default class API extends Module {\n /**\n * Save Editor config. API provides passed configuration to the Blocks\n * @param {EditorsConfig} config\n */\n constructor({ config }) {\n super({ config });\n }\n get methods() {\n return {\n blocks: this.Editor.BlocksAPI,\n caret: {},\n sanitizer: this.Editor.SanitizerAPI,\n toolbar: {},\n };\n }\n}\n","/**\n * @class BlockManager\n * @classdesc Manage editor`s blocks storage and appearance\n *\n * @module BlockManager\n *\n * @version 2.0.0\n */\n\nimport Block from '../block';\n\n/**\n * @typedef {BlockManager} BlockManager\n * @property {Number} currentBlockIndex - Index of current working block\n * @property {Proxy} _blocks - Proxy for Blocks instance {@link Blocks}\n */\nexport default class BlockManager extends Module {\n /**\n * @constructor\n * @param {EditorConfig} config\n */\n constructor({config}) {\n super({config});\n\n /**\n * Proxy for Blocks instance {@link Blocks}\n *\n * @type {Proxy}\n * @private\n */\n this._blocks = null;\n\n /**\n * Index of current working block\n *\n * @type {number}\n * @private\n */\n this.currentBlockIndex = -1;\n }\n\n /**\n * Should be called after Editor.UI preparation\n * Define this._blocks property\n *\n * @returns {Promise}\n */\n prepare() {\n return new Promise(resolve => {\n let blocks = new Blocks(this.Editor.UI.nodes.redactor);\n\n /**\n * We need to use Proxy to overload set/get [] operator.\n * So we can use array-like syntax to access blocks\n *\n * @example\n * this._blocks[0] = new Block(...);\n *\n * block = this._blocks[0];\n *\n * @todo proxy the enumerate method\n *\n * @type {Proxy}\n * @private\n */\n this._blocks = new Proxy(blocks, {\n set: Blocks.set,\n get: Blocks.get\n });\n\n resolve();\n });\n }\n\n /**\n * Creates Block instance by tool name\n *\n * @param {String} toolName - tools passed in editor config {@link EditorConfig#tools}\n * @param {Object} data - constructor params\n * @param {Object} settings - block settings\n *\n * @return {Block}\n */\n composeBlock(toolName, data, settings) {\n let toolInstance = this.Editor.Tools.construct(toolName, data),\n block = new Block(toolName, toolInstance, settings, this.Editor.API.methods);\n\n this.bindEvents(block);\n /**\n * Apply callback before inserting html\n */\n block.call('appendCallback', {});\n\n return block;\n }\n\n /**\n * Bind Events\n * @param {Object} block\n */\n bindEvents(block) {\n this.Editor.Listeners.on(block.pluginsContent, 'keydown', (event) => this.Editor.Keyboard.blockKeydownsListener(event));\n this.Editor.Listeners.on(block.pluginsContent, 'mouseup', (event) => {\n this.Editor.InlineToolbar.handleShowingEvent(event);\n });\n }\n\n /**\n * Set's caret to the next Block\n * Before moving caret, we should check if caret position is at the end of Plugins node\n * Using {@link Dom#getDeepestNode} to get a last node and match with current selection\n */\n navigateNext() {\n let caretAtEnd = this.Editor.Caret.isAtEnd;\n\n if (!caretAtEnd) {\n return;\n }\n\n let nextBlock = this.nextBlock;\n\n if (!nextBlock) {\n return;\n }\n\n this.Editor.Caret.setToBlock( nextBlock );\n }\n\n /**\n * Set's caret to the previous Block\n * Before moving caret, we should check if caret position is start of the Plugins node\n * Using {@link Dom#getDeepestNode} to get a last node and match with current selection\n */\n navigatePrevious() {\n let caretAtStart = this.Editor.Caret.isAtStart;\n\n if (!caretAtStart) {\n return;\n }\n\n let previousBlock = this.previousBlock;\n\n if (!previousBlock) {\n return;\n }\n\n this.Editor.Caret.setToBlock( previousBlock, 0, true );\n }\n\n /**\n * Insert new block into _blocks\n *\n * @param {String} toolName — plugin name\n * @param {Object} data — plugin data\n * @param {Object} settings - default settings\n */\n insert(toolName, data = {}, settings = {}) {\n let block = this.composeBlock(toolName, data, settings);\n\n this._blocks[++this.currentBlockIndex] = block;\n this.Editor.Caret.setToBlock(block);\n }\n\n /**\n * Merge two blocks\n * @param {Block} targetBlock - previous block will be append to this block\n * @param {Block} blockToMerge - block that will be merged with target block\n *\n * @return {Promise} - the sequence that can be continued\n */\n mergeBlocks(targetBlock, blockToMerge) {\n let blockToMergeIndex = this._blocks.indexOf(blockToMerge);\n\n return Promise.resolve()\n .then( () => {\n if (blockToMerge.isEmpty) {\n return;\n }\n\n return blockToMerge.data\n .then((blockToMergeInfo) => {\n targetBlock.mergeWith(blockToMergeInfo.data);\n });\n })\n .then( () => {\n this.removeBlock(blockToMergeIndex);\n this.currentBlockIndex = this._blocks.indexOf(targetBlock);\n });\n }\n\n /**\n * Remove block with passed index or remove last\n * @param {Number|null} index\n */\n removeBlock(index) {\n this._blocks.remove(index);\n }\n /**\n * Split current Block\n * 1. Extract content from Caret position to the Block`s end\n * 2. Insert a new Block below current one with extracted content\n */\n split() {\n let extractedFragment = this.Editor.Caret.extractFragmentFromCaretPosition(),\n wrapper = $.make('div');\n\n wrapper.append(extractedFragment);\n\n /**\n * @todo make object in accordance with Tool\n */\n let data = {\n text: $.isEmpty(wrapper) ? '' : wrapper.innerHTML,\n };\n\n this.insert(this.config.initialBlock, data);\n }\n\n /**\n * Replace current working block\n *\n * @param {String} toolName — plugin name\n * @param {Object} data — plugin data\n */\n replace(toolName, data = {}) {\n let block = this.composeBlock(toolName, data);\n\n this._blocks.insert(this.currentBlockIndex, block, true);\n }\n\n /**\n * returns last Block\n * @return {Block}\n */\n get lastBlock() {\n return this._blocks[this._blocks.length - 1];\n }\n\n /**\n * Returns Block by passed index\n * @param {Number} index\n * @return {Block}\n */\n getBlockByIndex(index) {\n return this._blocks[index];\n }\n\n /**\n * Get Block instance by html element\n * @param {Node} element\n * @returns {Block}\n */\n getBlock(element) {\n if (!$.isElement(element)) {\n element = element.parentNode;\n }\n\n let nodes = this._blocks.nodes,\n firstLevelBlock = element.closest(`.${Block.CSS.wrapper}`),\n index = nodes.indexOf(firstLevelBlock);\n\n if (index >= 0) {\n return this._blocks[index];\n }\n }\n\n /**\n * Get current Block instance\n *\n * @return {Block}\n */\n get currentBlock() {\n return this._blocks[this.currentBlockIndex];\n }\n\n /**\n * Returns next Block instance\n * @return {Block|null}\n */\n get nextBlock() {\n let isLastBlock = this.currentBlockIndex === (this._blocks.length - 1);\n\n if (isLastBlock) {\n return null;\n }\n\n return this._blocks[this.currentBlockIndex + 1];\n }\n\n /**\n * Returns previous Block instance\n * @return {Block|null}\n */\n get previousBlock() {\n let isFirstBlock = this.currentBlockIndex === 0;\n\n if (isFirstBlock) {\n return null;\n }\n\n return this._blocks[this.currentBlockIndex - 1];\n }\n\n /**\n * Get working html element\n *\n * @return {HTMLElement}\n */\n get currentNode() {\n return this._blocks.nodes[this.currentBlockIndex];\n }\n\n /**\n * Set currentBlockIndex to passed block\n * @param {HTMLElement} element\n */\n set currentNode(element) {\n let nodes = this._blocks.nodes,\n firstLevelBlock = element.closest(`.${Block.CSS.wrapper}`);\n\n /**\n * Update current Block's index\n * @type {number}\n */\n this.currentBlockIndex = nodes.indexOf(firstLevelBlock);\n\n /**\n * Remove previous selected Block's state\n */\n this._blocks.array.forEach( block => block.selected = false);\n\n /**\n * Mark current Block as selected\n * @type {boolean}\n */\n this.currentBlock.selected = true;\n }\n\n /**\n * Get array of Block instances\n *\n * @returns {Block[]} {@link Blocks#array}\n */\n get blocks() {\n return this._blocks.array;\n }\n\n /**\n * 1) Find first-level Block from passed child Node\n * 2) Mark it as current\n *\n * @param {Element|Text} childNode - look ahead from this node.\n * @throws Error - when passed Node is not included at the Block\n */\n setCurrentBlockByChildNode(childNode) {\n /**\n * If node is Text TextNode\n */\n if (!$.isElement(childNode)) {\n childNode = childNode.parentNode;\n }\n\n let parentFirstLevelBlock = childNode.closest(`.${Block.CSS.wrapper}`);\n\n if (parentFirstLevelBlock) {\n this.currentNode = parentFirstLevelBlock;\n } else {\n throw new Error('Can not find a Block from this child Node');\n }\n }\n};\n\n/**\n * @class Blocks\n * @classdesc Class to work with Block instances array\n *\n * @private\n *\n * @property {HTMLElement} workingArea — editor`s working node\n *\n */\nclass Blocks {\n /**\n * @constructor\n *\n * @param {HTMLElement} workingArea — editor`s working node\n */\n constructor(workingArea) {\n this.blocks = [];\n this.workingArea = workingArea;\n }\n\n /**\n * Push back new Block\n *\n * @param {Block} block\n */\n push(block) {\n this.blocks.push(block);\n this.workingArea.appendChild(block.html);\n }\n\n /**\n * Insert new Block at passed index\n *\n * @param {Number} index — index to insert Block\n * @param {Block} block — Block to insert\n * @param {Boolean} replace — it true, replace block on given index\n */\n insert(index, block, replace = false) {\n if (!this.length) {\n this.push(block);\n return;\n }\n\n if (index > this.length) {\n index = this.length;\n }\n\n if (replace) {\n this.blocks[index].html.remove();\n }\n\n let deleteCount = replace ? 1 : 0;\n\n this.blocks.splice(index, deleteCount, block);\n\n if (index > 0) {\n let previousBlock = this.blocks[index - 1];\n\n previousBlock.html.insertAdjacentElement('afterend', block.html);\n } else {\n let nextBlock = this.blocks[index + 1];\n\n if (nextBlock) {\n nextBlock.html.insertAdjacentElement('beforebegin', block.html);\n } else {\n this.workingArea.appendChild(block.html);\n }\n }\n }\n\n /**\n * Remove block\n * @param {Number|null} index\n */\n remove(index) {\n if (!index) {\n index = this.length - 1;\n }\n\n this.blocks[index].html.remove();\n this.blocks.splice(index, 1);\n }\n\n /**\n * Insert Block after passed target\n *\n * @todo decide if this method is necessary\n *\n * @param {Block} targetBlock — target after wich Block should be inserted\n * @param {Block} newBlock — Block to insert\n */\n insertAfter(targetBlock, newBlock) {\n let index = this.blocks.indexOf(targetBlock);\n\n this.insert(index + 1, newBlock);\n }\n\n /**\n * Get Block by index\n *\n * @param {Number} index — Block index\n * @returns {Block}\n */\n get(index) {\n return this.blocks[index];\n }\n\n /**\n * Return index of passed Block\n *\n * @param {Block} block\n * @returns {Number}\n */\n indexOf(block) {\n return this.blocks.indexOf(block);\n }\n\n /**\n * Get length of Block instances array\n *\n * @returns {Number}\n */\n get length() {\n return this.blocks.length;\n }\n\n /**\n * Get Block instances array\n *\n * @returns {Block[]}\n */\n get array() {\n return this.blocks;\n }\n\n /**\n * Get blocks html elements array\n *\n * @returns {HTMLElement[]}\n */\n get nodes() {\n return _.array(this.workingArea.children);\n }\n\n /**\n * Proxy trap to implement array-like setter\n *\n * @example\n * blocks[0] = new Block(...)\n *\n * @param {Blocks} instance — Blocks instance\n * @param {Number|String} index — block index\n * @param {Block} block — Block to set\n * @returns {Boolean}\n */\n static set(instance, index, block) {\n if (isNaN(Number(index))) {\n return false;\n }\n\n instance.insert(index, block);\n\n return true;\n }\n\n /**\n * Proxy trap to implement array-like getter\n *\n * @param {Blocks} instance — Blocks instance\n * @param {Number|String} index — Block index\n * @returns {Block|*}\n */\n static get(instance, index) {\n if (isNaN(Number(index))) {\n return instance[index];\n }\n\n return instance.get(index);\n }\n}\n","/**\n * @class Caret\n * @classdesc Contains methods for working Caret\n *\n * Uses Range methods to manipulate with caret\n *\n * @module Caret\n *\n * @version 2.0.0\n */\n\nimport Selection from '../selection';\n\n/**\n * @typedef {Caret} Caret\n */\nexport default class Caret extends Module {\n /**\n * @constructor\n */\n constructor({config}) {\n super({config});\n }\n\n /**\n * Method gets Block instance and puts caret to the text node with offset\n * There two ways that method applies caret position:\n * - first found text node: sets at the beginning, but you can pass an offset\n * - last found text node: sets at the end of the node. Also, you can customize the behaviour\n *\n * @param {Block} block - Block class\n * @param {Number} offset - caret offset regarding to the text node\n * @param {Boolean} atEnd - put caret at the end of the text node or not\n */\n setToBlock(block, offset = 0, atEnd = false) {\n let element = block.pluginsContent;\n\n /** If Element is INPUT */\n if ($.isNativeInput(element)) {\n element.focus();\n return;\n }\n\n let nodeToSet = $.getDeepestNode(element, atEnd);\n\n if (atEnd || offset > nodeToSet.length) {\n offset = nodeToSet.length;\n }\n\n /** if found deepest node is native input */\n if ($.isNativeInput(nodeToSet)) {\n nodeToSet.focus();\n return;\n }\n\n /**\n * @todo try to fix via Promises or use querySelectorAll to not to use timeout\n */\n _.delay( () => {\n this.set(nodeToSet, offset);\n }, 20)();\n\n this.Editor.BlockManager.currentNode = block.wrapper;\n }\n\n /**\n * Creates Document Range and sets caret to the element with offset\n * @param {Element} element - target node.\n * @param {Number} offset - offset\n */\n set( element, offset = 0) {\n let range = document.createRange(),\n selection = Selection.get();\n\n range.setStart(element, offset);\n range.setEnd(element, offset);\n\n selection.removeAllRanges();\n selection.addRange(range);\n };\n\n /**\n * Set Caret to the last Block\n * If last block is not empty, append another empty block\n */\n setToTheLastBlock() {\n let lastBlock = this.Editor.BlockManager.lastBlock;\n\n if (!lastBlock) return;\n\n /**\n * If last block is empty and it is an initialBlock, set to that.\n * Otherwise, append new empty block and set to that\n */\n if (lastBlock.isEmpty) {\n this.setToBlock(lastBlock);\n } else {\n this.Editor.BlockManager.insert(this.config.initialBlock);\n }\n }\n\n /**\n * Extract content fragment of current Block from Caret position to the end of the Block\n */\n extractFragmentFromCaretPosition() {\n let selection = Selection.get();\n\n if (selection.rangeCount) {\n let selectRange = selection.getRangeAt(0),\n blockElem = this.Editor.BlockManager.currentBlock.pluginsContent;\n\n selectRange.deleteContents();\n\n if (blockElem) {\n let range = selectRange.cloneRange(true);\n\n range.selectNodeContents(blockElem);\n range.setStart(selectRange.endContainer, selectRange.endOffset);\n return range.extractContents();\n }\n }\n }\n\n /**\n * Get all first-level (first child of [contenteditabel]) siblings from passed node\n * Then you can check it for emptiness\n *\n * @example\n * \n *\n * @return {Element[]}\n */\n getHigherLevelSiblings(from, direction ) {\n let current = from,\n siblings = [];\n\n /**\n * Find passed node's firs-level parent (in example - blockquote)\n */\n while (current.parentNode && current.parentNode.contentEditable !== 'true') {\n current = current.parentNode;\n }\n\n let sibling = direction === 'left' ? 'previousSibling' : 'nextSibling';\n\n /**\n * Find all left/right siblings\n */\n while (current[sibling]) {\n current = current[sibling];\n siblings.push(current);\n }\n\n return siblings;\n }\n\n /**\n * Get's deepest first node and checks if offset is zero\n * @return {boolean}\n */\n get isAtStart() {\n /**\n * Don't handle ranges\n */\n if (!Selection.isCollapsed) {\n return false;\n }\n\n let selection = Selection.get(),\n anchorNode = selection.anchorNode,\n firstNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.pluginsContent);\n\n /**\n * Workaround case when caret in the text like \" |Hello!\"\n * selection.anchorOffset is 1, but real caret visible position is 0\n * @type {number}\n */\n let firstLetterPosition = anchorNode.textContent.search(/\\S/);\n\n if (firstLetterPosition === -1) { // empty text\n firstLetterPosition = 0;\n }\n\n /**\n * In case of\n * \n *
<-- first (and deepest) node is
\n * |adaddad <-- anchor node\n *
\n */\n if ($.isEmpty(firstNode)) {\n let leftSiblings = this.getHigherLevelSiblings(anchorNode, 'left'),\n nothingAtLeft = leftSiblings.every( node => $.isEmpty(node) );\n\n\n\n if (nothingAtLeft && selection.anchorOffset === firstLetterPosition) {\n return true;\n }\n }\n\n return firstNode === null || anchorNode === firstNode && selection.anchorOffset === firstLetterPosition;\n }\n\n /**\n * Get's deepest last node and checks if offset is last node text length\n * @return {boolean}\n */\n get isAtEnd() {\n /**\n * Don't handle ranges\n */\n if (!Selection.isCollapsed) {\n return false;\n }\n\n let selection = Selection.get(),\n anchorNode = selection.anchorNode,\n lastNode = $.getDeepestNode(this.Editor.BlockManager.currentBlock.pluginsContent, true);\n\n /**\n * In case of\n * \n * adaddad| <-- anchor node\n *
<-- first (and deepest) node is
\n *
\n */\n if ($.isEmpty(lastNode)) {\n let leftSiblings = this.getHigherLevelSiblings(anchorNode, 'right'),\n nothingAtRight = leftSiblings.every( node => $.isEmpty(node) );\n\n if (nothingAtRight && selection.anchorOffset === anchorNode.textContent.length) {\n return true;\n }\n }\n\n return anchorNode === lastNode && selection.anchorOffset === lastNode.textContent.length;\n }\n}\n","/**\n * @module eventDispatcher\n *\n * Has two important methods:\n * - {Function} on - appends subscriber to the event. If event doesn't exist - creates new one\n * - {Function} emit - fires all subscribers with data\n *\n * @version 1.0.0\n *\n * @typedef {Events} Events\n * @property {Object} subscribers - all subscribers grouped by event name\n */\nexport default class Events extends Module {\n /**\n * @constructor\n */\n constructor({config}) {\n super({config});\n this.subscribers = {};\n }\n\n /**\n * @param {String} eventName - event name\n * @param {Function} callback - subscriber\n */\n on(eventName, callback) {\n if (!(eventName in this.subscribers)) {\n this.subscribers[eventName] = [];\n }\n\n // group by events\n this.subscribers[eventName].push(callback);\n }\n\n /**\n * @param {String} eventName - event name\n * @param {Object} data - subscribers get this data when they were fired\n */\n emit(eventName, data) {\n this.subscribers[eventName].reduce(function (previousData, currentHandler) {\n let newData = currentHandler(previousData);\n\n return newData ? newData : previousData;\n }, data);\n }\n\n /**\n * Destroyer\n * clears subsribers list\n */\n destroy() {\n this.subscribers = null;\n }\n}","/**\n * @class Keyboard\n * @classdesc Сlass to handle the keydowns\n *\n * @author CodeX Team (team@ifmo.su)\n * @copyright CodeX Team 2017\n * @license The MIT License (MIT)\n * @version 1.0.0\n */\n\n/**\n * @typedef {Keyboard} Keyboard\n */\nexport default class Keyboard extends Module {\n /**\n * @constructor\n */\n constructor({config}) {\n super({config});\n }\n\n /**\n * Handler on Block for keyboard keys at keydown event\n *\n * @param {KeyboardEvent} event\n */\n blockKeydownsListener(event) {\n switch(event.keyCode) {\n case _.keyCodes.BACKSPACE:\n\n _.log('Backspace key pressed');\n this.backspacePressed(event);\n break;\n\n case _.keyCodes.ENTER:\n\n _.log('Enter key pressed');\n this.enterPressed(event);\n break;\n\n case _.keyCodes.DOWN:\n case _.keyCodes.RIGHT:\n\n _.log('Right/Down key pressed');\n this.arrowRightAndDownPressed();\n break;\n\n case _.keyCodes.UP:\n case _.keyCodes.LEFT:\n\n _.log('Left/Up key pressed');\n this.arrowLeftAndUpPressed();\n break;\n\n default:\n\n break;\n }\n }\n\n /**\n * Handle pressing enter key\n *\n * @param {KeyboardEvent} event\n */\n enterPressed(event) {\n let currentBlock = this.Editor.BlockManager.currentBlock,\n toolsConfig = this.config.toolsConfig[currentBlock.name];\n\n /**\n * Don't handle Enter keydowns when Tool sets enableLineBreaks to true.\n * Uses for Tools like where line breaks should be handled by default behaviour.\n */\n if (toolsConfig && toolsConfig[this.Editor.Tools.apiSettings.IS_ENABLED_LINE_BREAKS]) {\n return;\n }\n\n /**\n * Allow to create linebreaks by Shift+Enter\n */\n if (event.shiftKey) {\n return;\n }\n\n\n /**\n * Split the Current Block into two blocks\n */\n this.Editor.BlockManager.split();\n event.preventDefault();\n }\n\n /**\n * Handle backspace keypress on block\n * @param {KeyboardEvent} event - keydown\n */\n backspacePressed(event) {\n const BM = this.Editor.BlockManager;\n\n let isFirstBlock = BM.currentBlockIndex === 0,\n canMergeBlocks = this.Editor.Caret.isAtStart && !isFirstBlock;\n\n if (!canMergeBlocks) {\n return;\n }\n\n // preventing browser default behaviour\n event.preventDefault();\n\n let targetBlock = BM.getBlockByIndex(BM.currentBlockIndex - 1),\n blockToMerge = BM.currentBlock;\n\n /**\n * Blocks that can be merged:\n * 1) with the same Name\n * 2) Tool has 'merge' method\n *\n * other case will handle as usual ARROW LEFT behaviour\n */\n if (blockToMerge.name !== targetBlock.name || !targetBlock.mergeable) {\n BM.navigatePrevious();\n }\n\n let setCaretToTheEnd = !targetBlock.isEmpty ? true : false;\n\n BM.mergeBlocks(targetBlock, blockToMerge)\n .then( () => {\n window.setTimeout( () => {\n // set caret to the block without offset at the end\n this.Editor.Caret.setToBlock(BM.currentBlock, 0, setCaretToTheEnd);\n this.Editor.Toolbar.close();\n }, 10);\n });\n }\n\n /**\n * Handle right and down keyboard keys\n */\n arrowRightAndDownPressed() {\n this.Editor.BlockManager.navigateNext();\n }\n\n /**\n * Handle left and up keyboard keys\n */\n arrowLeftAndUpPressed() {\n this.Editor.BlockManager.navigatePrevious();\n }\n}\n","/**\n * Codex Editor Listeners module\n *\n * @module Listeners\n *\n * Module-decorator for event listeners assignment\n *\n * @author Codex Team\n * @version 2.0.0\n */\n\n/**\n * @typedef {Listeners} Listeners\n * @property {Array} allListeners\n */\n\nexport default class Listeners extends Module {\n /**\n * @constructor\n * @param {EditorConfig} config\n */\n constructor({config}) {\n super({config});\n this.allListeners = [];\n }\n\n /**\n * Assigns event listener on element\n *\n * @param {Element} element - DOM element that needs to be listened\n * @param {String} eventType - event type\n * @param {Function} handler - method that will be fired on event\n * @param {Boolean} useCapture - use event bubbling\n */\n on(element, eventType, handler, useCapture = false) {\n let assignedEventData = {\n element,\n eventType,\n handler,\n useCapture\n };\n\n let alreadyExist = this.findOne(element, eventType, handler);\n\n if (alreadyExist) return;\n\n this.allListeners.push(assignedEventData);\n element.addEventListener(eventType, handler, useCapture);\n }\n\n /**\n * Removes event listener from element\n *\n * @param {Element} element - DOM element that we removing listener\n * @param {String} eventType - event type\n * @param {Function} handler - remove handler, if element listens several handlers on the same event type\n * @param {Boolean} useCapture - use event bubbling\n */\n off(element, eventType, handler, useCapture = false) {\n let existingListeners = this.findAll(element, eventType, handler);\n\n for (let i = 0; i < existingListeners.length; i++) {\n let index = this.allListeners.indexOf(existingListeners[i]);\n\n if (index > 0) {\n this.allListeners.splice(index, 1);\n }\n }\n\n element.removeEventListener(eventType, handler, useCapture);\n }\n\n /**\n * Search method: looks for listener by passed element\n * @param {Element} element - searching element\n * @returns {Array} listeners that found on element\n */\n findByElement(element) {\n let listenersOnElement = [];\n\n for (let i = 0; i < this.allListeners.length; i++) {\n let listener = this.allListeners[i];\n\n if (listener.element === element) {\n listenersOnElement.push(listener);\n }\n }\n\n return listenersOnElement;\n }\n\n /**\n * Search method: looks for listener by passed event type\n * @param {String} eventType\n * @return {Array} listeners that found on element\n */\n findByType(eventType) {\n let listenersWithType = [];\n\n for (let i = 0; i < this.allListeners.length; i++) {\n let listener = this.allListeners[i];\n\n if (listener.type === eventType) {\n listenersWithType.push(listener);\n }\n }\n\n return listenersWithType;\n }\n\n /**\n * Search method: looks for listener by passed handler\n * @param {Function} handler\n * @return {Array} listeners that found on element\n */\n findByHandler(handler) {\n let listenersWithHandler = [];\n\n for (let i = 0; i < this.allListeners.length; i++) {\n let listener = this.allListeners[i];\n\n if (listener.handler === handler) {\n listenersWithHandler.push(listener);\n }\n }\n\n return listenersWithHandler;\n }\n\n /**\n * @param {Element} element\n * @param {String} eventType\n * @param {Function} handler\n * @return {Element|null}\n */\n findOne(element, eventType, handler) {\n let foundListeners = this.findAll(element, eventType, handler);\n\n return foundListeners.length > 0 ? foundListeners[0] : null;\n }\n\n /**\n * @param {Element} element\n * @param {String} eventType\n * @param {Function} handler\n * @return {Array}\n */\n findAll(element, eventType, handler) {\n let found,\n foundByElements = element ? this.findByElement(element) : [];\n // foundByEventType = eventType ? this.findByType(eventType) : [],\n // foundByHandler = handler ? this.findByHandler(handler) : [];\n\n if (element && eventType && handler) {\n found = foundByElements.filter( event => event.eventType === eventType && event.handler === handler );\n } else if (element && eventType) {\n found = foundByElements.filter( event => event.eventType === eventType);\n } else {\n found = foundByElements;\n }\n\n return found;\n }\n\n /**\n * Removes all listeners\n */\n removeAll() {\n this.allListeners.map( (current) => {\n current.element.removeEventListener(current.eventType, current.handler);\n });\n\n this.allListeners = [];\n }\n}\n","/**\n * Codex Editor Renderer Module\n *\n * @module Renderer\n * @author CodeX Team\n *\n * @version 2.0.0\n */\nexport default class Renderer extends Module {\n /**\n * @constructor\n * @param {EditorConfig} config\n */\n constructor({config}) {\n super({config});\n }\n\n /**\n * @typedef {Object} RendererItems\n * @property {String} type - tool name\n * @property {Object} data - tool data\n */\n\n /**\n * @example\n *\n * items: [\n * {\n * type : 'paragraph',\n * data : {\n * text : 'Hello from Codex!'\n * }\n * },\n * {\n * type : 'paragraph',\n * data : {\n * text : 'Leave feedback if you like it!'\n * }\n * },\n * ]\n *\n */\n\n /**\n * Make plugin blocks from array of plugin`s data\n * @param {RendererItems[]} items\n */\n render(items) {\n let chainData = [];\n\n for (let i = 0; i < items.length; i++) {\n chainData.push({\n function: () => this.insertBlock(items[i])\n });\n }\n\n return _.sequence(chainData);\n }\n\n /**\n * Get plugin instance\n * Add plugin instance to BlockManager\n * Insert block to working zone\n *\n * @param {Object} item\n * @returns {Promise.}\n * @private\n */\n insertBlock(item) {\n let tool = item.type,\n data = item.data,\n settings = item.settings;\n\n this.Editor.BlockManager.insert(tool, data, settings);\n\n return Promise.resolve();\n }\n}\n","/**\n * CodeX Sanitizer\n *\n * @module Sanitizer\n * Clears HTML from taint tags\n *\n * @version 2.0.0\n *\n * @example\n * Module can be used within two ways:\n * 1) When you have an instance\n * - this.Editor.Sanitizer.clean(yourTaintString);\n * 2) As static method\n * - CodexEditor.Sanitizer.clean(yourTaintString, yourCustomConfiguration);\n *\n * {@link SanitizerConfig}\n */\n\n\n/**\n * @typedef {Object} SanitizerConfig\n * @property {Object} tags - define tags restrictions\n *\n * @example\n *\n * tags : {\n * p: true,\n * a: {\n * href: true,\n * rel: \"nofollow\",\n * target: \"_blank\"\n * }\n * }\n */\nexport default class Sanitizer extends Module {\n /**\n * Initializes Sanitizer module\n * Sets default configuration if custom not exists\n *\n * @property {SanitizerConfig} this.defaultConfig\n * @property {HTMLJanitor} this._sanitizerInstance - Sanitizer library\n *\n * @param {SanitizerConfig} config\n */\n constructor({config}) {\n super({config});\n\n // default config\n this.defaultConfig = null;\n this._sanitizerInstance = null;\n\n /** Custom configuration */\n this.sanitizerConfig = config.settings ? config.settings.sanitizer : {};\n\n /** HTML Janitor library */\n this.sanitizerInstance = require('html-janitor');\n }\n\n /**\n * If developer uses editor's API, then he can customize sanitize restrictions.\n * Or, sanitizing config can be defined globally in editors initialization. That config will be used everywhere\n * At least, if there is no config overrides, that API uses Default configuration\n *\n * @uses https://www.npmjs.com/package/html-janitor\n *\n * @param {HTMLJanitor} library - sanitizer extension\n */\n set sanitizerInstance(library) {\n this._sanitizerInstance = new library(this.defaultConfig);\n }\n\n /**\n * Sets sanitizer configuration. Uses default config if user didn't pass the restriction\n * @param {SanitizerConfig} config\n */\n set sanitizerConfig(config) {\n if (_.isEmpty(config)) {\n this.defaultConfig = {\n tags: {\n p: {},\n a: {\n href: true,\n target: '_blank',\n rel: 'nofollow'\n }\n }\n };\n } else {\n this.defaultConfig = config;\n }\n }\n\n /**\n * Cleans string from unwanted tags\n * @param {String} taintString - HTML string\n * @param {Object} customConfig - custom sanitizer configuration. Method uses default if param is empty\n * @return {String} clean HTML\n */\n clean(taintString, customConfig = {}) {\n if (_.isEmpty(customConfig)) {\n return this._sanitizerInstance.clean(taintString);\n } else {\n return Sanitizer.clean(taintString, customConfig);\n }\n }\n\n /**\n * Cleans string from unwanted tags\n * @static\n *\n * Method allows to use default config\n *\n * @param {String} taintString - taint string\n * @param {SanitizerConfig} customConfig - allowed tags\n *\n * @return {String} clean HTML\n */\n static clean(taintString, customConfig) {\n let newInstance = Sanitizer(customConfig);\n\n return newInstance.clean(taintString);\n }\n}\n","/**\n * Codex Editor Saver\n *\n * @module Saver\n * @author Codex Team\n * @version 2.0.0\n */\n\n/**\n * @typedef {Object} SavedData\n * @property {Date} time - saving proccess time\n * @property {Object} items - extracted data\n * @property {String} version - CodexEditor version\n */\n\n/**\n * @classdesc This method reduces all Blocks asyncronically and calls Block's save method to extract data\n *\n * @typedef {Saver} Saver\n * @property {Element} html - Editor HTML content\n * @property {String} json - Editor JSON output\n */\n\nexport default class Saver extends Module {\n /**\n * @constructor\n * @param config\n */\n constructor({config}) {\n super({config});\n\n this.output = null;\n this.blocksData = [];\n }\n\n /**\n * Composes new chain of Promises to fire them alternatelly\n * @return {SavedData}\n */\n save() {\n let blocks = this.Editor.BlockManager.blocks,\n chainData = [];\n\n blocks.forEach((block) => {\n chainData.push(block.data);\n });\n\n return Promise.all(chainData)\n .then((allExtractedData) => this.makeOutput(allExtractedData))\n .then((outputData) => {\n return outputData;\n });\n }\n\n /**\n * Creates output object with saved data, time and version of editor\n * @param {Object} allExtractedData\n * @return {SavedData}\n */\n makeOutput(allExtractedData) {\n let items = [],\n totalTime = 0;\n\n console.groupCollapsed('[CodexEditor saving]:');\n\n allExtractedData.forEach((extraction) => {\n /** Group process info */\n console.log(`«${extraction.tool}» saving info`, extraction);\n totalTime += extraction.time;\n items.push(extraction.data);\n });\n\n console.log('Total', totalTime);\n console.groupEnd();\n\n return {\n time : +new Date(),\n items : items,\n version : VERSION,\n };\n }\n}\n\n// module.exports = (function (saver) {\n//\n// let editor = codex.editor;\n//\n// /**\n// * @public\n// * Save blocks\n// */\n// saver.save = function () {\n//\n// /** Save html content of redactor to memory */\n// editor.state.html = editor.nodes.redactor.innerHTML;\n//\n// /** Clean jsonOutput state */\n// editor.state.jsonOutput = [];\n//\n// return saveBlocks(editor.nodes.redactor.childNodes);\n//\n// };\n//\n// /**\n// * @private\n// * Save each block data\n// *\n// * @param blocks\n// * @returns {Promise.}\n// */\n// let saveBlocks = function (blocks) {\n//\n// let data = [];\n//\n// for(let index = 0; index < blocks.length; index++) {\n//\n// data.push(getBlockData(blocks[index]));\n//\n// }\n//\n// return Promise.all(data)\n// .then(makeOutput)\n// .catch(editor.core.log);\n//\n// };\n//\n// /** Save and validate block data */\n// let getBlockData = function (block) {\n//\n// return saveBlockData(block)\n// .then(validateBlockData)\n// .catch(editor.core.log);\n//\n// };\n//\n// /**\n// * @private\n// * Call block`s plugin save method and return saved data\n// *\n// * @param block\n// * @returns {Object}\n// */\n// let saveBlockData = function (block) {\n//\n// let pluginName = block.dataset.tool;\n//\n// /** Check for plugin existence */\n// if (!editor.tools[pluginName]) {\n//\n// editor.core.log(`Plugin «${pluginName}» not found`, 'error');\n// return {data: null, pluginName: null};\n//\n// }\n//\n// /** Check for plugin having save method */\n// if (typeof editor.tools[pluginName].save !== 'function') {\n//\n// editor.core.log(`Plugin «${pluginName}» must have save method`, 'error');\n// return {data: null, pluginName: null};\n//\n// }\n//\n// /** Result saver */\n// let blockContent = block.childNodes[0],\n// pluginsContent = blockContent.childNodes[0],\n// position = pluginsContent.dataset.inputPosition;\n//\n// /** If plugin wasn't available then return data from cache */\n// if ( editor.tools[pluginName].available === false ) {\n//\n// return Promise.resolve({data: codex.editor.state.blocks.items[position].data, pluginName});\n//\n// }\n//\n// return Promise.resolve(pluginsContent)\n// .then(editor.tools[pluginName].save)\n// .then(data => Object({data, pluginName}));\n//\n// };\n//\n// /**\n// * Call plugin`s validate method. Return false if validation failed\n// *\n// * @param data\n// * @param pluginName\n// * @returns {Object|Boolean}\n// */\n// let validateBlockData = function ({data, pluginName}) {\n//\n// if (!data || !pluginName) {\n//\n// return false;\n//\n// }\n//\n// if (editor.tools[pluginName].validate) {\n//\n// let result = editor.tools[pluginName].validate(data);\n//\n// /**\n// * Do not allow invalid data\n// */\n// if (!result) {\n//\n// return false;\n//\n// }\n//\n// }\n//\n// return {data, pluginName};\n//\n//\n// };\n//\n// /**\n// * Compile article output\n// *\n// * @param savedData\n// * @returns {{time: number, version, items: (*|Array)}}\n// */\n// let makeOutput = function (savedData) {\n//\n// savedData = savedData.filter(blockData => blockData);\n//\n// let items = savedData.map(blockData => Object({type: blockData.pluginName, data: blockData.data}));\n//\n// editor.state.jsonOutput = items;\n//\n// return {\n// id: editor.state.blocks.id || null,\n// time: +new Date(),\n// version: editor.version,\n// items\n// };\n//\n// };\n//\n// return saver;\n//\n// })({});\n","/**\n * Block Settings\n *\n * ____ Settings Panel ____\n * | ...................... |\n * | . Tool Settings . |\n * | ...................... |\n * | . Default Settings . |\n * | ...................... |\n * |________________________|\n */\nexport default class BlockSettings extends Module {\n constructor({config}) {\n super({config});\n\n this.nodes = {\n wrapper: null,\n toolSettings: null,\n defaultSettings: null\n };\n }\n\n /**\n * Block Settings CSS\n * @return {{wrapper, wrapperOpened, toolSettings, defaultSettings, button}}\n */\n static get CSS() {\n return {\n // Settings Panel\n wrapper: 'ce-settings',\n wrapperOpened: 'ce-settings--opened',\n toolSettings: 'ce-settings__plugin-zone',\n defaultSettings: 'ce-settings__default-zone',\n\n button: 'ce-settings__button'\n };\n }\n\n /**\n * Panel with block settings with 2 sections:\n * - Tool's Settings\n * - Default Settings [Move, Remove, etc]\n *\n * @return {Element}\n */\n make() {\n this.nodes.wrapper = $.make('div', BlockSettings.CSS.wrapper);\n\n this.nodes.toolSettings = $.make('div', BlockSettings.CSS.toolSettings);\n this.nodes.defaultSettings = $.make('div', BlockSettings.CSS.defaultSettings);\n\n $.append(this.nodes.wrapper, [this.nodes.toolSettings, this.nodes.defaultSettings]);\n }\n\n /**\n * Add Tool's settings\n */\n addToolSettings() {\n if (typeof this.Editor.BlockManager.currentBlock.tool.makeSettings === 'function') {\n $.append(this.nodes.toolSettings, this.Editor.BlockManager.currentBlock.tool.makeSettings());\n }\n }\n\n /**\n * Add default settings\n */\n addDefaultSettings() {\n $.append(this.nodes.defaultSettings, this.Editor.BlockManager.currentBlock.renderTunes());\n }\n\n /**\n * Is Block Settings opened or not\n * @returns {boolean}\n */\n get opened() {\n return this.nodes.wrapper.classList.contains(BlockSettings.CSS.wrapperOpened);\n }\n\n /**\n * Open Block Settings pane\n */\n open() {\n this.nodes.wrapper.classList.add(BlockSettings.CSS.wrapperOpened);\n\n /**\n * Fill Tool's settings\n */\n this.addToolSettings();\n\n /**\n * Add default settings that presents for all Blocks\n */\n this.addDefaultSettings();\n }\n\n /**\n * Close Block Settings pane\n */\n close() {\n this.nodes.wrapper.classList.remove(BlockSettings.CSS.wrapperOpened);\n }\n}\n","import BoldInlineTool from '../inline-tools/inline-tool-bold';\nimport Selection from '../selection';\nexport default class InlineToolbar extends Module {\n /**\n * @constructor\n */\n constructor({ config }) {\n super({ config });\n /**\n * Inline Toolbar elements\n */\n this.nodes = {\n wrapper: null,\n };\n /**\n * CSS styles\n */\n this.CSS = {\n inlineToolbar: 'ce-inline-toolbar',\n inlineToolbarShowed: 'ce-inline-toolbar--showed',\n };\n /**\n * Margin above/below the Toolbar\n */\n this.toolbarVerticalMargin = 20;\n /**\n * Available Tools classes\n */\n this.tools = [];\n /**\n * @todo Merge internal tools with external\n */\n this.tools = [\n new BoldInlineTool(),\n ];\n }\n /**\n * Making DOM\n */\n make() {\n this.nodes.wrapper = $.make('div', this.CSS.inlineToolbar);\n /**\n * Append Inline Toolbar to the Editor\n */\n $.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);\n /**\n * Append Inline Toolbar Tools\n */\n this.addTools();\n }\n /**\n *\n *\n * Moving / appearance\n * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n *\n */\n /**\n * Shows Inline Toolbar by keyup/mouseup\n * @param {KeyboardEvent|MouseEvent} event\n */\n handleShowingEvent(event) {\n if (!this.allowedToShow(event)) {\n this.close();\n return;\n }\n this.move();\n this.open();\n /** Check Tools state for selected fragment */\n this.checkToolsState();\n }\n /**\n * Move Toolbar to the selected text\n */\n move() {\n const selectionRect = Selection.rect;\n const wrapperOffset = this.Editor.UI.nodes.wrapper.getBoundingClientRect();\n const newCoords = {\n x: selectionRect.x - wrapperOffset.left,\n y: selectionRect.y\n + selectionRect.height\n // + window.scrollY\n - wrapperOffset.top\n + this.toolbarVerticalMargin,\n };\n /**\n * If we know selections width, place InlineToolbar to center\n */\n if (selectionRect.width) {\n newCoords.x += Math.floor(selectionRect.width / 2);\n }\n this.nodes.wrapper.style.left = Math.floor(newCoords.x) + 'px';\n this.nodes.wrapper.style.top = Math.floor(newCoords.y) + 'px';\n }\n /**\n * Shows Inline Toolbar\n */\n open() {\n this.nodes.wrapper.classList.add(this.CSS.inlineToolbarShowed);\n }\n /**\n * Hides Inline Toolbar\n */\n close() {\n this.nodes.wrapper.classList.remove(this.CSS.inlineToolbarShowed);\n }\n /**\n * Need to show Inline Toolbar or not\n * @param {KeyboardEvent|MouseEvent} event\n */\n allowedToShow(event) {\n /**\n * Tags conflicts with window.selection function.\n * Ex. IMG tag returns null (Firefox) or Redactors wrapper (Chrome)\n */\n const tagsConflictsWithSelection = ['IMG', 'INPUT'];\n if (event && tagsConflictsWithSelection.includes(event.target.tagName)) {\n return false;\n }\n const currentSelection = Selection.get(), selectedText = Selection.text;\n // old browsers\n if (!currentSelection || !currentSelection.anchorNode) {\n return false;\n }\n // empty selection\n if (currentSelection.isCollapsed || selectedText.length < 1) {\n return false;\n }\n // is enabled by current Block's Tool\n const currentBlock = this.Editor.BlockManager.getBlock(currentSelection.anchorNode);\n if (!currentBlock) {\n return false;\n }\n const toolConfig = this.config.toolsConfig[currentBlock.name];\n return toolConfig && toolConfig[this.Editor.Tools.apiSettings.IS_ENABLED_INLINE_TOOLBAR];\n }\n /**\n *\n *\n * Working with Tools\n * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n *\n */\n /**\n * Fill Inline Toolbar with Tools\n */\n addTools() {\n this.tools.forEach((tool) => {\n this.addTool(tool);\n });\n }\n /**\n * Add tool button and activate clicks\n * @param {InlineTool} tool - Tool's instance\n */\n addTool(tool) {\n const button = tool.render();\n this.nodes.wrapper.appendChild(button);\n this.Editor.Listeners.on(button, 'click', () => {\n this.toolClicked(tool);\n });\n }\n /**\n * Inline Tool button clicks\n * @param {InlineTool} tool - Tool's instance\n */\n toolClicked(tool) {\n const range = Selection.range;\n if (!range) {\n return;\n }\n tool.surround(range);\n this.checkToolsState();\n }\n /**\n * Check Tools` state by selection\n */\n checkToolsState() {\n this.tools.forEach((tool) => {\n tool.checkState(Selection.get);\n });\n }\n}\n","/**\n * @class Toolbox\n * @classdesc Holder for Tools\n *\n * @typedef {Toolbox} Toolbox\n * @property {Boolean} opened - opening state\n * @property {Object} nodes - Toolbox nodes\n * @property {Object} CSS - CSS class names\n *\n */\nexport default class Toolbox extends Module {\n /**\n * @constructor\n */\n constructor({config}) {\n super({config});\n\n this.nodes = {\n toolbox: null,\n buttons: []\n };\n\n /**\n * Opening state\n * @type {boolean}\n */\n this.opened = false;\n }\n\n /**\n * CSS styles\n * @return {{toolbox: string, toolboxButton: string, toolboxOpened: string}}\n */\n static get CSS() {\n return {\n toolbox: 'ce-toolbox',\n toolboxButton: 'ce-toolbox__button',\n toolboxOpened: 'ce-toolbox--opened',\n };\n }\n\n /**\n * Makes the Toolbox\n */\n make() {\n this.nodes.toolbox = $.make('div', Toolbox.CSS.toolbox);\n $.append(this.Editor.Toolbar.nodes.content, this.nodes.toolbox);\n\n this.addTools();\n }\n\n /**\n * Iterates available tools and appends them to the Toolbox\n */\n addTools() {\n let tools = this.Editor.Tools.toolsAvailable;\n\n for (let toolName in tools) {\n this.addTool(toolName, tools[toolName]);\n }\n }\n\n /**\n * Append Tool to the Toolbox\n *\n * @param {string} toolName - tool name\n * @param {Tool} tool - tool class\n */\n addTool(toolName, tool) {\n const api = this.Editor.Tools.apiSettings;\n\n if (tool[api.IS_DISPLAYED_IN_TOOLBOX] && !tool[api.TOOLBAR_ICON_CLASS]) {\n _.log('Toolbar icon class name is missed. Tool %o skipped', 'warn', toolName);\n return;\n }\n\n /**\n * @todo Add checkup for the render method\n */\n // if (typeof tool.render !== 'function') {\n //\n // _.log('render method missed. Tool %o skipped', 'warn', tool);\n // return;\n //\n // }\n\n /**\n * Skip tools that pass 'displayInToolbox=false'\n */\n if (!tool[api.IS_DISPLAYED_IN_TOOLBOX]) {\n return;\n }\n\n let button = $.make('li', [Toolbox.CSS.toolboxButton, tool[api.TOOLBAR_ICON_CLASS]], {\n title: toolName\n });\n\n /**\n * Save tool's name in the button data-name\n */\n button.dataset.name = toolName;\n\n $.append(this.nodes.toolbox, button);\n\n this.nodes.toolbox.appendChild(button);\n this.nodes.buttons.push(button);\n\n /**\n * @todo add event with module Listeners\n */\n // this.Editor.Listeners.add();\n button.addEventListener('click', event => {\n this.buttonClicked(event);\n }, false);\n }\n\n /**\n * Toolbox button click listener\n * 1) if block is empty -> replace\n * 2) if block is not empty -> add new block below\n *\n * @param {MouseEvent} event\n */\n buttonClicked(event) {\n let toolButton = event.target,\n toolName = toolButton.dataset.name,\n tool = this.Editor.Tools.toolClasses[toolName];\n\n /**\n * @type {Block}\n */\n let currentBlock = this.Editor.BlockManager.currentBlock;\n\n /**\n * We do replace if:\n * - block is empty\n * - block is not irreplaceable\n * @type {Array}\n */\n if (!tool[this.Editor.Tools.apiSettings.IS_IRREPLACEBLE_TOOL] && currentBlock.isEmpty) {\n this.Editor.BlockManager.replace(toolName);\n } else {\n this.Editor.BlockManager.insert(toolName);\n }\n\n /**\n * @todo set caret to the new block\n */\n\n // window.setTimeout(function () {\n\n /** Set caret to current block */\n // editor.caret.setToBlock(currentInputIndex);\n\n // }, 10);\n\n /**\n * Move toolbar when node is changed\n */\n this.Editor.Toolbar.move();\n }\n\n /**\n * Open Toolbox with Tools\n */\n open() {\n this.nodes.toolbox.classList.add(Toolbox.CSS.toolboxOpened);\n this.opened = true;\n }\n\n /**\n * Close Toolbox\n */\n close() {\n this.nodes.toolbox.classList.remove(Toolbox.CSS.toolboxOpened);\n this.opened = false;\n }\n\n /**\n * Close Toolbox\n */\n toggle() {\n if (!this.opened) {\n this.open();\n } else {\n this.close();\n }\n }\n}\n","/**\n *\n * «Toolbar» is the node that moves up/down over current block\n *\n * ______________________________________ Toolbar ____________________________________________\n * | |\n * | ..................... Content .................... ......... Block Actions .......... |\n * | . . . . |\n * | . . . [Open Settings] . |\n * | . [Plus Button] [Toolbox: {Tool1}, {Tool2}] . . . |\n * | . . . [Settings Panel] . |\n * | .................................................. .................................. |\n * | |\n * |___________________________________________________________________________________________|\n *\n *\n * Toolbox — its an Element contains tools buttons. Can be shown by Plus Button.\n *\n * _______________ Toolbox _______________\n * | |\n * | [Header] [Image] [List] [Quote] ... |\n * |_______________________________________|\n *\n *\n * Settings Panel — is an Element with block settings:\n *\n * ____ Settings Panel ____\n * | ...................... |\n * | . Tool Settings . |\n * | ...................... |\n * | . Default Settings . |\n * | ...................... |\n * |________________________|\n *\n *\n * @class\n * @classdesc Toolbar module\n *\n * @typedef {Toolbar} Toolbar\n * @property {Object} nodes\n * @property {Element} nodes.wrapper - Toolbar main element\n * @property {Element} nodes.content - Zone with Plus button and toolbox.\n * @property {Element} nodes.actions - Zone with Block Settings and Remove Button\n * @property {Element} nodes.blockActionsButtons - Zone with Block Buttons: [Settings]\n * @property {Element} nodes.plusButton - Button that opens or closes Toolbox\n * @property {Element} nodes.toolbox - Container for tools\n * @property {Element} nodes.settingsToggler - open/close Settings Panel button\n * @property {Element} nodes.settings - Settings Panel\n * @property {Element} nodes.pluginSettings - Plugin Settings section of Settings Panel\n * @property {Element} nodes.defaultSettings - Default Settings section of Settings Panel\n */\nexport default class Toolbar extends Module {\n /**\n * @constructor\n */\n constructor({config}) {\n super({config});\n\n this.nodes = {\n wrapper : null,\n content : null,\n actions : null,\n\n // Content Zone\n plusButton : null,\n\n // Actions Zone\n blockActionsButtons: null,\n settingsToggler : null,\n };\n }\n\n /**\n * CSS styles\n * @return {Object}\n * @constructor\n */\n static get CSS() {\n return {\n toolbar: 'ce-toolbar',\n content: 'ce-toolbar__content',\n actions: 'ce-toolbar__actions',\n\n toolbarOpened: 'ce-toolbar--opened',\n\n // Content Zone\n plusButton: 'ce-toolbar__plus',\n plusButtonHidden: 'ce-toolbar__plus--hidden',\n\n // Actions Zone\n blockActionsButtons: 'ce-toolbar__actions-buttons',\n settingsToggler: 'ce-toolbar__settings-btn',\n };\n }\n\n /**\n * Makes toolbar\n */\n make() {\n this.nodes.wrapper = $.make('div', Toolbar.CSS.toolbar);\n\n /**\n * Make Content Zone and Actions Zone\n */\n ['content', 'actions'].forEach( el => {\n this.nodes[el] = $.make('div', Toolbar.CSS[el]);\n $.append(this.nodes.wrapper, this.nodes[el]);\n });\n\n\n /**\n * Fill Content Zone:\n * - Plus Button\n * - Toolbox\n */\n this.nodes.plusButton = $.make('div', Toolbar.CSS.plusButton);\n $.append(this.nodes.content, this.nodes.plusButton);\n this.nodes.plusButton.addEventListener('click', event => this.plusButtonClicked(event), false);\n\n\n /**\n * Make a Toolbox\n */\n this.Editor.Toolbox.make();\n\n /**\n * Fill Actions Zone:\n * - Settings Toggler\n * - Remove Block Button\n * - Settings Panel\n */\n this.nodes.blockActionsButtons = $.make('div', Toolbar.CSS.blockActionsButtons);\n this.nodes.settingsToggler = $.make('span', Toolbar.CSS.settingsToggler);\n\n $.append(this.nodes.blockActionsButtons, this.nodes.settingsToggler);\n $.append(this.nodes.actions, this.nodes.blockActionsButtons);\n\n /**\n * Make and append Settings Panel\n */\n this.Editor.BlockSettings.make();\n $.append(this.nodes.actions, this.Editor.BlockSettings.nodes.wrapper);\n\n /**\n * Append toolbar to the Editor\n */\n $.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);\n\n /**\n * Bind events on the Toolbar elements\n */\n this.bindEvents();\n }\n\n /**\n * Move Toolbar to the Current Block\n */\n move() {\n /** Close Toolbox when we move toolbar */\n this.Editor.Toolbox.close();\n\n let currentNode = this.Editor.BlockManager.currentNode;\n\n /**\n * If no one Block selected as a Current\n */\n if (!currentNode) {\n return;\n }\n\n /**\n * @todo Compute dynamically on prepare\n * @type {number}\n */\n const defaultToolbarHeight = 49;\n const defaultOffset = 34;\n\n var newYCoordinate = currentNode.offsetTop - (defaultToolbarHeight / 2) + defaultOffset;\n\n this.nodes.wrapper.style.transform = `translate3D(0, ${Math.floor(newYCoordinate)}px, 0)`;\n\n /** Close trash actions */\n // editor.toolbar.settings.hideRemoveActions();\n }\n\n /**\n * Open Toolbar with Plus Button\n */\n open() {\n this.nodes.wrapper.classList.add(Toolbar.CSS.toolbarOpened);\n }\n\n /**\n * Close the Toolbar\n */\n close() {\n this.nodes.wrapper.classList.remove(Toolbar.CSS.toolbarOpened);\n }\n\n /**\n * Plus Button public methods\n * @return {{hide: function(): void, show: function(): void}}\n */\n get plusButton() {\n return {\n hide: () => this.nodes.plusButton.classList.add(Toolbar.CSS.plusButtonHidden),\n show: () => this.nodes.plusButton.classList.remove(Toolbar.CSS.plusButtonHidden)\n };\n }\n\n /**\n * Handler for Plus Button\n * @param {MouseEvent} event\n */\n plusButtonClicked() {\n this.Editor.Toolbox.toggle();\n }\n\n /**\n * Bind events on the Toolbar Elements:\n * - Block Settings\n */\n bindEvents() {\n /**\n * Settings toggler\n */\n this.Editor.Listeners.on(this.nodes.settingsToggler, 'click', (event) => {\n this.settingsTogglerClicked(event);\n });\n }\n\n /**\n * Clicks on the Block Settings toggler\n */\n settingsTogglerClicked() {\n if (this.Editor.BlockSettings.opened) {\n this.Editor.BlockSettings.close();\n } else {\n this.Editor.BlockSettings.open();\n }\n }\n}\n","/**\n * @module Codex Editor Tools Submodule\n *\n * Creates Instances from Plugins and binds external config to the instances\n */\n\n/**\n * Each Tool must contain the following important objects:\n *\n * @typedef {Object} ToolConfig {@link docs/tools.md}\n * @property {String} iconClassname - this a icon in toolbar\n * @property {Boolean} displayInToolbox - will be displayed in toolbox. Default value is TRUE\n * @property {Boolean} enableLineBreaks - inserts new block or break lines. Default value is FALSE\n * @property {Boolean|String[]} inlineToolbar - Pass `true` to enable the Inline Toolbar with all Tools, all pass an array with specified Tools list |\n * @property render @todo add description\n * @property save @todo add description\n * @property settings @todo add description\n * @property validate - method that validates output data before saving\n */\n\n/**\n * @typedef {Function} Tool {@link docs/tools.md}\n * @property {Boolean} displayInToolbox - By default, tools won't be added in the Toolbox. Pass true to add.\n * @property {String} iconClassName - CSS class name for the Toolbox button\n * @property {Boolean} irreplaceable - Toolbox behaviour: replace or add new block below\n * @property render\n * @property save\n * @property settings\n * @property validate\n *\n * @todo update according to current API\n * @todo describe Tool in the {@link docs/tools.md}\n */\n\n/**\n * Class properties:\n *\n * @typedef {Tools} Tools\n * @property {Tools[]} toolsAvailable - available Tools\n * @property {Tools[]} toolsUnavailable - unavailable Tools\n * @property {Object} toolsClasses - all classes\n * @property {EditorConfig} config - Editor config\n */\nexport default class Tools extends Module {\n /**\n * Returns available Tools\n * @return {Tool[]}\n */\n get available() {\n return this.toolsAvailable;\n }\n\n /**\n * Returns unavailable Tools\n * @return {Tool[]}\n */\n get unavailable() {\n return this.toolsUnavailable;\n }\n\n /**\n * Constant for available Tools Settings\n * @return {object}\n */\n get apiSettings() {\n return {\n TOOLBAR_ICON_CLASS: 'iconClassName',\n IS_DISPLAYED_IN_TOOLBOX: 'displayInToolbox',\n IS_ENABLED_LINE_BREAKS: 'enableLineBreaks',\n IS_IRREPLACEBLE_TOOL: 'irreplaceable',\n IS_ENABLED_INLINE_TOOLBAR: 'inlineToolbar',\n };\n }\n\n /**\n * Static getter for default Tool config fields\n * @return {ToolConfig}\n */\n get defaultConfig() {\n return {\n [this.apiSettings.TOOLBAR_ICON_CLASS] : false,\n [this.apiSettings.IS_DISPLAYED_IN_TOOLBOX] : false,\n [this.apiSettings.IS_ENABLED_LINE_BREAKS] : false,\n [this.apiSettings.IS_IRREPLACEBLE_TOOL] : false,\n [this.apiSettings.IS_ENABLED_INLINE_TOOLBAR]: false,\n };\n }\n\n /**\n * @constructor\n *\n * @param {EditorConfig} config\n */\n constructor({config}) {\n super({config});\n\n /**\n * Map {name: Class, ...} where:\n * name — block type name in JSON. Got from EditorConfig.tools keys\n * @type {Object}\n */\n this.toolClasses = {};\n\n /**\n * Available tools list\n * {name: Class, ...}\n * @type {Object}\n */\n this.toolsAvailable = {};\n\n /**\n * Tools that rejected a prepare method\n * {name: Class, ... }\n * @type {Object}\n */\n this.toolsUnavailable = {};\n }\n\n /**\n * Creates instances via passed or default configuration\n * @return {Promise}\n */\n prepare() {\n if (!this.config.hasOwnProperty('tools')) {\n return Promise.reject(\"Can't start without tools\");\n }\n\n for(let toolName in this.config.tools) {\n this.toolClasses[toolName] = this.config.tools[toolName];\n }\n\n /**\n * getting classes that has prepare method\n */\n let sequenceData = this.getListOfPrepareFunctions();\n\n /**\n * if sequence data contains nothing then resolve current chain and run other module prepare\n */\n if (sequenceData.length === 0) {\n return Promise.resolve();\n }\n\n /**\n * to see how it works {@link Util#sequence}\n */\n return _.sequence(sequenceData, (data) => {\n this.success(data);\n }, (data) => {\n this.fallback(data);\n });\n }\n\n /**\n * Binds prepare function of plugins with user or default config\n * @return {Array} list of functions that needs to be fired sequentially\n */\n getListOfPrepareFunctions() {\n let toolPreparationList = [];\n\n for(let toolName in this.toolClasses) {\n let toolClass = this.toolClasses[toolName];\n\n if (typeof toolClass.prepare === 'function') {\n toolPreparationList.push({\n function : toolClass.prepare,\n data : {\n toolName\n }\n });\n } else {\n /**\n * If Tool hasn't a prepare method, mark it as available\n */\n this.toolsAvailable[toolName] = toolClass;\n }\n }\n\n return toolPreparationList;\n }\n\n /**\n * @param {ChainData.data} data - append tool to available list\n */\n success(data) {\n this.toolsAvailable[data.toolName] = this.toolClasses[data.toolName];\n }\n\n /**\n * @param {ChainData.data} data - append tool to unavailable list\n */\n fallback(data) {\n this.toolsUnavailable[data.toolName] = this.toolClasses[data.toolName];\n }\n\n /**\n * Return tool`a instance\n *\n * @param {String} tool — tool name\n * @param {Object} data — initial data\n *\n * @todo throw exceptions if tool doesnt exist\n *\n */\n construct(tool, data) {\n let plugin = this.toolClasses[tool],\n config = this.config.toolsConfig[tool];\n\n let instance = new plugin(data, config || {});\n\n return instance;\n }\n\n /**\n * Check if passed Tool is an instance of Initial Block Tool\n * @param {Tool} tool - Tool to check\n * @return {Boolean}\n */\n isInitial(tool) {\n return tool instanceof this.available[this.config.initialBlock];\n }\n}\n","/**\n * Module UI\n *\n * @type {UI}\n */\n// 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\n// import Block from '../block';\n\n/**\n * @class\n *\n * @classdesc Makes CodeX Editor UI:\n * \n * \n * \n * \n * \n *\n * @typedef {UI} UI\n * @property {EditorConfig} config - editor configuration {@link CodexEditor#configuration}\n * @property {Object} Editor - available editor modules {@link CodexEditor#moduleInstances}\n * @property {Object} nodes -\n * @property {Element} nodes.holder - element where we need to append redactor\n * @property {Element} nodes.wrapper - \n * @property {Element} nodes.redactor - \n */\nexport default class UI extends Module {\n /**\n * @constructor\n *\n * @param {EditorConfig} config\n */\n constructor({config}) {\n super({config});\n\n this.nodes = {\n holder: null,\n wrapper: null,\n redactor: null\n };\n }\n\n /**\n * Making main interface\n */\n prepare() {\n return this.make()\n /**\n * Make toolbar\n */\n .then(() => this.Editor.Toolbar.make())\n /**\n * Make the Inline toolbar\n */\n .then(() => this.Editor.InlineToolbar.make())\n /**\n * Load and append CSS\n */\n .then(() => this.loadStyles())\n /**\n * Bind events for the UI elements\n */\n .then(() => this.bindEvents())\n\n /** Make container for inline toolbar */\n // .then(makeInlineToolbar_)\n\n /** Add inline toolbar tools */\n // .then(addInlineToolbarTools_)\n\n /** Draw wrapper for notifications */\n // .then(makeNotificationHolder_)\n\n /** Add eventlisteners to redactor elements */\n // .then(bindEvents_)\n\n .catch(e => {\n console.error(e);\n\n // editor.core.log(\"Can't draw editor interface\");\n });\n }\n\n /**\n * CodeX Editor UI CSS class names\n * @return {{editorWrapper: string, editorZone: string, block: string}}\n */\n get CSS() {\n return {\n editorWrapper : 'codex-editor',\n editorZone : 'codex-editor__redactor',\n };\n }\n\n /**\n * Makes CodeX Editor interface\n * @return {Promise}\n */\n make() {\n return new Promise( (resolve, reject) => {\n /**\n * Element where we need to append CodeX Editor\n * @type {Element}\n */\n this.nodes.holder = document.getElementById(this.config.holderId);\n\n if (!this.nodes.holder) {\n reject(Error(\"Holder wasn't found by ID: #\" + this.config.holderId));\n return;\n }\n\n /**\n * Create and save main UI elements\n */\n this.nodes.wrapper = $.make('div', this.CSS.editorWrapper);\n this.nodes.redactor = $.make('div', this.CSS.editorZone);\n\n this.nodes.wrapper.appendChild(this.nodes.redactor);\n this.nodes.holder.appendChild(this.nodes.wrapper);\n\n resolve();\n });\n }\n\n /**\n * Appends CSS\n */\n loadStyles() {\n /**\n * Load CSS\n */\n let styles = require('../../styles/main.css');\n\n /**\n * Make tag\n */\n let tag = $.make('style', null, {\n textContent: styles.toString()\n });\n\n /**\n * Append styles\n */\n $.append(document.head, tag);\n }\n\n /**\n * Bind events on the CodeX Editor interface\n */\n bindEvents() {\n /**\n * @todo bind events with the Listeners module\n */\n this.Editor.Listeners.on(this.nodes.redactor, 'click', event => this.redactorClicked(event), false );\n }\n\n /**\n * All clicks on the redactor zone\n *\n * @param {MouseEvent} event\n *\n * @description\n * 1. Save clicked Block as a current {@link BlockManager#currentNode}\n * it uses for the following:\n * - add CSS modifier for the selected Block\n * - on Enter press, we make a new Block under that\n *\n * 2. Move and show the Toolbar\n *\n * 3. Set a Caret\n *\n * 4. By clicks on the Editor's bottom zone:\n * - if last Block is empty, set a Caret to this\n * - otherwise, add a new empty Block and set a Caret to that\n *\n * 5. Hide the Inline Toolbar\n *\n * @see selectClickedBlock\n *\n */\n redactorClicked(event) {\n let clickedNode = event.target;\n\n /**\n * Select clicked Block as Current\n */\n try {\n this.Editor.BlockManager.setCurrentBlockByChildNode(clickedNode);\n } catch (e) {\n /**\n * If clicked outside first-level Blocks, set Caret to the last empty Block\n */\n this.Editor.Caret.setToTheLastBlock();\n }\n\n\n /**\n * Close Inline Toolbar when nothing selected\n */\n this.Editor.InlineToolbar.handleShowingEvent(event);\n\n /**\n *\n\n /** Update current input index in memory when caret focused into existed input */\n // if (event.target.contentEditable == 'true') {\n //\n // editor.caret.saveCurrentInputIndex();\n //\n // }\n\n // if (editor.content.currentNode === null) {\n //\n // /**\n // * If inputs in redactor does not exits, then we put input index 0 not -1\n // */\n // var indexOfLastInput = editor.state.inputs.length > 0 ? editor.state.inputs.length - 1 : 0;\n //\n // /** If we have any inputs */\n // if (editor.state.inputs.length) {\n //\n // /** getting firstlevel parent of input */\n // firstLevelBlock = editor.content.getFirstLevelBlock(editor.state.inputs[indexOfLastInput]);\n //\n // }\n //\n // /** If input is empty, then we set caret to the last input */\n // if (editor.state.inputs.length && editor.state.inputs[indexOfLastInput].textContent === '' && firstLevelBlock.dataset.tool == editor.settings.initialBlockPlugin) {\n //\n // editor.caret.setToBlock(indexOfLastInput);\n //\n // } else {\n //\n // /** Create new input when caret clicked in redactors area */\n // var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin;\n //\n // editor.content.insertBlock({\n // type : NEW_BLOCK_TYPE,\n // block : editor.tools[NEW_BLOCK_TYPE].render()\n // });\n //\n // /** If there is no inputs except inserted */\n // if (editor.state.inputs.length === 1) {\n //\n // editor.caret.setToBlock(indexOfLastInput);\n //\n // } else {\n //\n // /** Set caret to this appended input */\n // editor.caret.setToNextBlock(indexOfLastInput);\n //\n // }\n //\n // }\n //\n // } else {\n //\n // /** Close all panels */\n // editor.toolbar.settings.close();\n // editor.toolbar.toolbox.close();\n //\n // }\n //\n /**\n * Move toolbar and open\n */\n this.Editor.Toolbar.move();\n this.Editor.Toolbar.open();\n //\n // var inputIsEmpty = !editor.content.currentNode.textContent.trim(),\n // currentNodeType = editor.content.currentNode.dataset.tool,\n // isInitialType = currentNodeType == editor.settings.initialBlockPlugin;\n //\n //\n\n /**\n * Hide the Plus Button\n * */\n this.Editor.Toolbar.plusButton.hide();\n\n /**\n * Show the Plus Button if:\n * - Block is an initial-block (Text)\n * - Block is empty\n */\n let isInitialBlock = this.Editor.Tools.isInitial(this.Editor.BlockManager.currentBlock.tool),\n isEmptyBlock = this.Editor.BlockManager.currentBlock.isEmpty;\n\n if (isInitialBlock && isEmptyBlock) {\n this.Editor.Toolbar.plusButton.show();\n }\n }\n}\n\n// /**\n// * Codex Editor UI module\n// *\n// * @author Codex Team\n// * @version 1.2.0\n// */\n//\n// module.exports = (function (ui) {\n//\n// let editor = codex.editor;\n//\n// /**\n// * Basic editor classnames\n// */\n// ui.prepare = function () {\n//\n\n//\n// };\n//\n// /** Draw notifications holder */\n// var makeNotificationHolder_ = function () {\n//\n// /** Append block with notifications to the document */\n// editor.nodes.notifications = editor.notifications.createHolder();\n//\n// };\n//\n//\n// var addInlineToolbarTools_ = function () {\n//\n// var tools = {\n//\n// bold: {\n// icon : 'ce-icon-bold',\n// command : 'bold'\n// },\n//\n// italic: {\n// icon : 'ce-icon-italic',\n// command : 'italic'\n// },\n//\n// link: {\n// icon : 'ce-icon-link',\n// command : 'createLink'\n// }\n// };\n//\n// var toolButton,\n// tool;\n//\n// for(var name in tools) {\n//\n// tool = tools[name];\n//\n// toolButton = editor.draw.toolbarButtonInline(name, tool.icon);\n//\n// editor.nodes.inlineToolbar.buttons.appendChild(toolButton);\n// /**\n// * Add callbacks to this buttons\n// */\n// editor.ui.setInlineToolbarButtonBehaviour(toolButton, tool.command);\n//\n// }\n//\n// };\n//\n// /**\n// * @private\n// * Bind editor UI events\n// */\n// var bindEvents_ = function () {\n//\n// editor.core.log('ui.bindEvents fired', 'info');\n//\n// // window.addEventListener('error', function (errorMsg, url, lineNumber) {\n// // editor.notifications.errorThrown(errorMsg, event);\n// // }, false );\n//\n// /** All keydowns on Document */\n// editor.listeners.add(document, 'keydown', editor.callback.globalKeydown, false);\n//\n// /** All keydowns on Redactor zone */\n// editor.listeners.add(editor.nodes.redactor, 'keydown', editor.callback.redactorKeyDown, false);\n//\n// /** All keydowns on Document */\n// editor.listeners.add(document, 'keyup', editor.callback.globalKeyup, false );\n//\n// /**\n// * Mouse click to radactor\n// */\n// editor.listeners.add(editor.nodes.redactor, 'click', editor.callback.redactorClicked, false );\n//\n// /**\n// * Clicks to the Plus button\n// */\n// editor.listeners.add(editor.nodes.plusButton, 'click', editor.callback.plusButtonClicked, false);\n//\n// /**\n// * Clicks to SETTINGS button in toolbar\n// */\n// editor.listeners.add(editor.nodes.showSettingsButton, 'click', editor.callback.showSettingsButtonClicked, false );\n//\n// /** Bind click listeners on toolbar buttons */\n// for (var button in editor.nodes.toolbarButtons) {\n//\n// editor.listeners.add(editor.nodes.toolbarButtons[button], 'click', editor.callback.toolbarButtonClicked, false);\n//\n// }\n//\n// };\n//\n// ui.addBlockHandlers = function (block) {\n//\n// if (!block) return;\n//\n// /**\n// * Block keydowns\n// */\n// editor.listeners.add(block, 'keydown', editor.callback.blockKeydown, false);\n//\n// /**\n// * Pasting content from another source\n// * We have two type of sanitization\n// * First - uses deep-first search algorithm to get sub nodes,\n// * sanitizes whole Block_content and replaces cleared nodes\n// * This method is deprecated\n// * Method is used in editor.callback.blockPaste(event)\n// *\n// * Secont - uses Mutation observer.\n// * Observer \"observe\" DOM changes and send changings to callback.\n// * Callback gets changed node, not whole Block_content.\n// * Inserted or changed node, which we've gotten have been cleared and replaced with diry node\n// *\n// * Method is used in editor.callback.blockPasteViaSanitize(event)\n// *\n// * @uses html-janitor\n// * @example editor.callback.blockPasteViaSanitize(event), the second method.\n// *\n// */\n// editor.listeners.add(block, 'paste', editor.paste.blockPasteCallback, false);\n//\n// /**\n// * Show inline toolbar for selected text\n// */\n// editor.listeners.add(block, 'mouseup', editor.toolbar.inline.show, false);\n// editor.listeners.add(block, 'keyup', editor.toolbar.inline.show, false);\n//\n// };\n//\n// /** getting all contenteditable elements */\n// ui.saveInputs = function () {\n//\n// var redactor = editor.nodes.redactor;\n//\n// editor.state.inputs = [];\n//\n// /** Save all inputs in global variable state */\n// var inputs = redactor.querySelectorAll('[contenteditable], input, textarea');\n//\n// Array.prototype.map.call(inputs, function (current) {\n//\n// if (!current.type || current.type == 'text' || current.type == 'textarea') {\n//\n// editor.state.inputs.push(current);\n//\n// }\n//\n// });\n//\n// };\n//\n// /**\n// * Adds first initial block on empty redactor\n// */\n// ui.addInitialBlock = function () {\n//\n// var initialBlockType = editor.settings.initialBlockPlugin,\n// initialBlock;\n//\n// if ( !editor.tools[initialBlockType] ) {\n//\n// editor.core.log('Plugin %o was not implemented and can\\'t be used as initial block', 'warn', initialBlockType);\n// return;\n//\n// }\n//\n// initialBlock = editor.tools[initialBlockType].render();\n//\n// initialBlock.setAttribute('data-placeholder', editor.settings.placeholder);\n//\n// editor.content.insertBlock({\n// type : initialBlockType,\n// block : initialBlock\n// });\n//\n// editor.content.workingNodeChanged(initialBlock);\n//\n// };\n//\n// ui.setInlineToolbarButtonBehaviour = function (button, type) {\n//\n// editor.listeners.add(button, 'mousedown', function (event) {\n//\n// editor.toolbar.inline.toolClicked(event, type);\n//\n// }, false);\n//\n// };\n//\n// return ui;\n//\n// })({});\n","/**\n * Element.closest()\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/Element/closest\n */\nif (!Element.prototype.matches)\n Element.prototype.matches = Element.prototype.msMatchesSelector ||\n Element.prototype.webkitMatchesSelector;\n\nif (!Element.prototype.closest)\n Element.prototype.closest = function (s) {\n var el = this;\n\n if (!document.documentElement.contains(el)) return null;\n do {\n if (el.matches(s)) return el;\n el = el.parentElement || el.parentNode;\n } while (el !== null);\n return null;\n };\n","/**\n * Working with selection\n * @typedef {Selection} Selection\n */\nexport default class Selection {\n /**\n * @constructor\n */\n constructor() {\n this.instance = null;\n this.selection = null;\n }\n\n /**\n * Returns window Selection\n * {@link https://developer.mozilla.org/ru/docs/Web/API/Window/getSelection}\n * @return {Selection}\n */\n static get() {\n return window.getSelection();\n }\n\n /**\n * Returns selected anchor\n * {@link https://developer.mozilla.org/ru/docs/Web/API/Selection/anchorNode}\n * @return {Node|null}\n */\n static get anchorNode() {\n const selection = window.getSelection();\n\n return selection ? selection.anchorNode : null;\n }\n\n /**\n * Returns selection offset according to the anchor node\n * {@link https://developer.mozilla.org/ru/docs/Web/API/Selection/anchorOffset}\n * @return {Number|null}\n */\n static get anchorOffset() {\n const selection = window.getSelection();\n\n return selection ? selection.anchorOffset : null;\n }\n\n /**\n * Is current selection range collapsed\n * @return {boolean|null}\n */\n static get isCollapsed() {\n const selection = window.getSelection();\n\n return selection ? selection.isCollapsed : null;\n }\n\n /**\n * Return first range\n * @return {Range|null}\n */\n static get range() {\n const selection = window.getSelection();\n\n return selection ? selection.getRangeAt(0) : null;\n }\n\n /**\n * Calculates position and size of selected text\n * @return {{x, y, width, height, top?, left?, bottom?, right?}}\n */\n static get rect() {\n let sel = document.selection, range;\n let rect = {\n x: 0,\n y: 0,\n width: 0,\n height: 0\n };\n\n if (sel && sel.type !== 'Control') {\n range = sel.createRange();\n rect.x = range.boundingLeft;\n rect.y = range.boundingTop;\n rect.width = range.boundingWidth;\n rect.height = range.boundingHeight;\n\n return rect;\n }\n\n if (!window.getSelection) {\n _.log('Method window.getSelection is not supported', 'warn');\n return rect;\n }\n\n sel = window.getSelection();\n\n if (!sel.rangeCount) {\n _.log('Method Selection.rangeCount() is not supported', 'warn');\n return rect;\n }\n\n range = sel.getRangeAt(0).cloneRange();\n\n if (range.getBoundingClientRect) {\n rect = range.getBoundingClientRect();\n }\n // Fall back to inserting a temporary element\n if (rect.x === 0 && rect.y === 0) {\n let span = document.createElement('span');\n\n if (span.getBoundingClientRect) {\n // Ensure span has dimensions and position by\n // adding a zero-width space character\n span.appendChild( document.createTextNode('\\u200b') );\n range.insertNode(span);\n rect = span.getBoundingClientRect();\n\n let spanParent = span.parentNode;\n\n spanParent.removeChild(span);\n\n // Glue any broken text nodes back together\n spanParent.normalize();\n }\n }\n\n return rect;\n }\n\n /**\n * Returns selected text as String\n * @returns {string}\n */\n static get text() {\n return window.getSelection ? window.getSelection().toString() : '';\n };\n}\n","/**\n * Codex Editor Util\n */\nexport default class Util {\n /**\n * Custom logger\n *\n * @param {string} msg - message\n * @param {string} type - logging type 'log'|'warn'|'error'|'info'\n * @param {*} args - argument to log with a message\n */\n static log(msg, type, args) {\n type = type || 'log';\n\n if (!args) {\n args = msg || 'undefined';\n msg = '[codex-editor]: %o';\n } else {\n msg = '[codex-editor]: ' + msg;\n }\n\n try{\n if ( 'console' in window && window.console[ type ] ) {\n if ( args ) window.console[ type ]( msg, args );\n else window.console[ type ]( msg );\n }\n } catch(e) {\n // do nothing\n }\n }\n\n /**\n * Returns basic keycodes as constants\n * @return {{}}\n */\n static get keyCodes() {\n return {\n BACKSPACE: 8,\n TAB: 9,\n ENTER: 13,\n SHIFT: 16,\n CTRL: 17,\n ALT: 18,\n ESC: 27,\n SPACE: 32,\n LEFT: 37,\n UP: 38,\n DOWN: 40,\n RIGHT: 39,\n DELETE: 46,\n META: 91\n };\n }\n\n /**\n * @typedef {Object} ChainData\n * @property {Object} data - data that will be passed to the success or fallback\n * @property {Function} function - function's that must be called asynchronically\n */\n\n /**\n * Fires a promise sequence asyncronically\n *\n * @param {Object[]} chains - list or ChainData's\n * @param {Function} success - success callback\n * @param {Function} fallback - callback that fires in case of errors\n *\n * @return {Promise}\n */\n static sequence(chains, success = () => {}, fallback = () => {}) {\n return new Promise(function (resolve) {\n /**\n * pluck each element from queue\n * First, send resolved Promise as previous value\n * Each plugins \"prepare\" method returns a Promise, that's why\n * reduce current element will not be able to continue while can't get\n * a resolved Promise\n */\n chains.reduce(function (previousValue, currentValue, iteration) {\n return previousValue\n .then(() => waitNextBlock(currentValue, success, fallback))\n .then(() => {\n // finished\n if (iteration === chains.length - 1) {\n resolve();\n }\n });\n }, Promise.resolve());\n });\n\n /**\n * Decorator\n *\n * @param {ChainData} chainData\n *\n * @param {Function} successCallback\n * @param {Function} fallbackCallback\n *\n * @return {Promise}\n */\n function waitNextBlock(chainData, successCallback, fallbackCallback) {\n return new Promise(function (resolve) {\n chainData.function()\n .then(() => {\n successCallback(chainData.data || {});\n })\n .then(resolve)\n .catch(function () {\n fallbackCallback(chainData.data || {});\n\n // anyway, go ahead even it falls\n resolve();\n });\n });\n }\n }\n\n /**\n * Make array from array-like collection\n *\n * @param {*} collection\n *\n * @return {Array}\n */\n static array(collection) {\n return Array.prototype.slice.call(collection);\n }\n\n /**\n * Checks if object is empty\n *\n * @param {Object} object\n * @return {boolean}\n */\n static isEmpty(object) {\n return Object.keys(object).length === 0 && object.constructor === Object;\n }\n\n /**\n * Check if passed object is a Promise\n * @param {*} object - object to check\n * @return {Boolean}\n */\n static isPromise(object) {\n return Promise.resolve(object) === object;\n }\n\n /**\n * Check if passed element is contenteditable\n * @param element\n * @return {boolean}\n */\n static isContentEditable(element) {\n return element.contentEditable === 'true';\n }\n\n /**\n * Delays method execution\n *\n * @param method\n * @param timeout\n */\n static delay(method, timeout) {\n return function () {\n let context = this,\n args = arguments;\n\n window.setTimeout(() => method.apply(context, args), timeout);\n };\n }\n};\n","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \":root {\\n /**\\n * Toolbar buttons\\n */\\n --bg-light: #eff2f5;\\n\\n /**\\n * All gray texts: placeholders, settings\\n */\\n --grayText: #707684;\\n\\n /** Blue icons */\\n --color-active-icon: #388AE5;\\n\\n /**\\n * Block content width\\n */\\n --content-width: 650px;\\n\\n /**\\n * Toolbar Plus Button and Toolbox buttons height and width\\n */\\n --toolbar-buttons-size: 34px\\n}\\n/**\\n* Editor wrapper\\n*/\\n.codex-editor {\\n position: relative;\\n border: 1px solid #ccc;\\n padding: 2px;\\n box-sizing: border-box;\\n}\\n.codex-editor .hide {\\n display: none;\\n }\\n.codex-editor__redactor {\\n padding-bottom: 300px;\\n }\\n.ce-toolbar {\\n position: absolute;\\n left: 0;\\n right: 0;\\n top: 0;\\n /*opacity: 0;*/\\n /*visibility: hidden;*/\\n transition: opacity 100ms ease;\\n will-change: opacity, transform;\\n display: none;\\n}\\n.ce-toolbar--opened {\\n display: block;\\n /*opacity: 1;*/\\n /*visibility: visible;*/\\n }\\n.ce-toolbar__content {\\n max-width: 650px;\\n max-width: var(--content-width);\\n margin: 0 auto;\\n position: relative;\\n }\\n.ce-toolbar__plus {\\n position: absolute;\\n left: calc(-var(--toolbar-buttons-size) - 10px);\\n left: calc(-var(--toolbar-buttons-size) - 10px);\\n display: inline-block;\\n background-color: #eff2f5;\\n background-color: var(--bg-light);\\n width: 34px;\\n width: var(--toolbar-buttons-size);\\n height: 34px;\\n height: var(--toolbar-buttons-size);\\n line-height: 34px;\\n text-align: center;\\n border-radius: 50%\\n }\\n.ce-toolbar__plus::after {\\n content: '+';\\n font-size: 26px;\\n display: block;\\n margin-top: -2px;\\n margin-right: -2px;\\n }\\n.ce-toolbar__plus--hidden {\\n display: none;\\n }\\n/**\\n * Block actions Zone\\n * -------------------------\\n */\\n.ce-toolbar__actions {\\n position: absolute;\\n right: 0;\\n top: 0;\\n border: 1px dotted #ccc;\\n padding: 2px;\\n }\\n.ce-toolbar__actions-buttons {\\n border: 1px dotted #ccc;\\n padding: 2px;\\n text-align: right;\\n margin-bottom: 2px;\\n }\\n.ce-toolbar__settings-btn {\\n display: inline-block;\\n width: 24px;\\n height: 24px;\\n border: 1px dotted #ccc\\n }\\n.ce-toolbar__settings-btn::before {\\n content: 'STN';\\n font-size: 10px;\\n opacity: .4;\\n }\\n.ce-toolbox {\\n position: absolute;\\n visibility: hidden;\\n transition: opacity 100ms ease;\\n will-change: opacity;\\n}\\n.ce-toolbox--opened {\\n opacity: 1;\\n visibility: visible;\\n }\\n.ce-toolbox__button {\\n display: inline-block;\\n list-style: none;\\n margin: 0;\\n background: #eff2f5;\\n background: var(--bg-light);\\n width: 34px;\\n width: var(--toolbar-buttons-size);\\n height: 34px;\\n height: var(--toolbar-buttons-size);\\n border-radius: 30px;\\n overflow: hidden;\\n text-align: center;\\n line-height: 34px;\\n line-height: var(--toolbar-buttons-size)\\n }\\n.ce-toolbox__button::before {\\n content: attr(title);\\n font-size: 22px;\\n font-weight: 500;\\n letter-spacing: 1em;\\n -webkit-font-feature-settings: \\\"smcp\\\", \\\"c2sc\\\";\\n font-feature-settings: \\\"smcp\\\", \\\"c2sc\\\";\\n font-variant-caps: all-small-caps;\\n padding-left: 11.5px;\\n margin-top: -1px;\\n display: inline-block;\\n }\\n.ce-inline-toolbar {\\n position: absolute;\\n background: #FFFFFF;\\n box-shadow: 0 8px 23px -6px rgba(21,40,54,0.31), 22px -14px 34px -18px rgba(33,48,73,0.26);\\n border-radius: 4px;\\n z-index: 2\\n}\\n.ce-inline-toolbar::before {\\n content: '';\\n width: 15px;\\n height: 15px;\\n position: absolute;\\n top: -7px;\\n left: 50%;\\n margin-left: -7px;\\n transform: rotate(-45deg);\\n background: #fff;\\n z-index: -1;\\n }\\n.ce-inline-toolbar {\\n padding: 6px;\\n transform: translateX(-50%);\\n display: none;\\n}\\n.ce-inline-toolbar--showed {\\n display: block;\\n }\\n.ce-inline-tool {\\n display: inline-block;\\n width: 34px;\\n height: 34px;\\n border-radius: 3px;\\n cursor: pointer;\\n border: 0;\\n outline: none;\\n background: transparent;\\n vertical-align: bottom\\n}\\n.ce-inline-tool:hover {\\n background: #eff2f5;\\n background: var(--bg-light);\\n }\\n.ce-inline-tool--active {\\n color: #388AE5;\\n color: var(--color-active-icon);\\n }\\n.ce-inline-tool--bold::before {\\n font-weight: bold;\\n content: 'B'\\n }\\n.ce-settings {\\n border: 1px dotted #ccc;\\n padding: 2px;\\n display: none;\\n}\\n.ce-settings--opened {\\n display: block;\\n }\\n.ce-settings__plugin-zone {\\n border: 1px dotted #ccc;\\n padding: 2px;\\n margin-bottom: 2px\\n }\\n.ce-settings__plugin-zone::before {\\n content: 'PLUGIN SETTINGS';\\n opacity: .4;\\n font-size: 12px;\\n }\\n.ce-settings__default-zone {\\n border: 1px dotted #ccc;\\n padding: 2px\\n }\\n.ce-settings__default-zone::before {\\n /*content: 'DEFAULT SETTINGS';*/\\n opacity: .4;\\n font-size: 12px;\\n }\\n.ce-settings__button {\\n padding: 10px 15px;\\n color: #707684;\\n color: var(--grayText)\\n }\\n.ce-settings__button:hover {\\n background: #eff2f5;\\n background: var(--bg-light);\\n }\\n.ce-settings-move-up:hover {\\n cursor: pointer;\\n }\\n.ce-settings-move-up::before {\\n display: inline-block;\\n content: 'up';\\n }\\n.ce-block {\\n border: 1px dotted #ccc;\\n margin: 2px 0\\n}\\n.ce-block:first-of-type {\\n margin-top: 0;\\n }\\n.ce-block--selected {\\n background-color: #eff2f5;\\n background-color: var(--bg-light);\\n }\\n.ce-block__content {\\n max-width: 650px;\\n max-width: var(--content-width);\\n margin: 0 auto;\\n }\\n\", \"\"]);\n\n// exports\n"],"sourceRoot":""}
\ No newline at end of file
diff --git a/build/sprite.svg b/build/sprite.svg
new file mode 100644
index 00000000..3b9cc8aa
--- /dev/null
+++ b/build/sprite.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 29fe8fc1..722d2a98 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1180,6 +1180,12 @@
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
"dev": true
},
+ "boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
+ "dev": true
+ },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -1454,6 +1460,118 @@
"integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
"dev": true
},
+ "cheerio": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz",
+ "integrity": "sha1-dy5wFfLuKZZQltcepBdbdas1SSU=",
+ "dev": true,
+ "requires": {
+ "css-select": "1.0.0",
+ "dom-serializer": "0.1.0",
+ "entities": "1.1.1",
+ "htmlparser2": "3.8.3",
+ "lodash": "3.10.1"
+ },
+ "dependencies": {
+ "css-select": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz",
+ "integrity": "sha1-sRIcpRhI3SZOIkTQWM7iVN7rRLA=",
+ "dev": true,
+ "requires": {
+ "boolbase": "1.0.0",
+ "css-what": "1.0.0",
+ "domutils": "1.4.3",
+ "nth-check": "1.0.1"
+ }
+ },
+ "css-what": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-1.0.0.tgz",
+ "integrity": "sha1-18wt9FGAZm+Z0rFEYmOUaeAPc2w=",
+ "dev": true
+ },
+ "domhandler": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
+ "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1.3.0"
+ }
+ },
+ "domutils": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.4.3.tgz",
+ "integrity": "sha1-CGVRN5bGswYDGFDhdVFrr4C3Km8=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1.3.0"
+ }
+ },
+ "htmlparser2": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
+ "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1.3.0",
+ "domhandler": "2.3.0",
+ "domutils": "1.5.1",
+ "entities": "1.0.0",
+ "readable-stream": "1.1.14"
+ },
+ "dependencies": {
+ "domutils": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+ "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
+ "dev": true,
+ "requires": {
+ "dom-serializer": "0.1.0",
+ "domelementtype": "1.3.0"
+ }
+ },
+ "entities": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
+ "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=",
+ "dev": true
+ }
+ }
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "lodash": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "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
+ }
+ }
+ },
"chokidar": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz",
@@ -2136,12 +2254,36 @@
"esutils": "2.0.2"
}
},
+ "dom-serializer": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
+ "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1.1.3",
+ "entities": "1.1.1"
+ },
+ "dependencies": {
+ "domelementtype": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
+ "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=",
+ "dev": true
+ }
+ }
+ },
"domain-browser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
"integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
"dev": true
},
+ "domelementtype": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
+ "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=",
+ "dev": true
+ },
"dot-prop": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
@@ -2210,6 +2352,12 @@
"tapable": "1.0.0"
}
},
+ "entities": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
+ "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=",
+ "dev": true
+ },
"errno": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
@@ -2838,24 +2986,28 @@
"dependencies": {
"abbrev": {
"version": "1.1.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"dev": true,
"optional": true
},
"ansi-regex": {
"version": "2.1.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
},
"aproba": {
"version": "1.2.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
"dev": true,
"optional": true
},
"are-we-there-yet": {
"version": "1.1.4",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
+ "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
"dev": true,
"optional": true,
"requires": {
@@ -2865,12 +3017,14 @@
},
"balanced-match": {
"version": "1.0.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "1.0.0",
@@ -2879,34 +3033,40 @@
},
"chownr": {
"version": "1.0.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
+ "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
"dev": true,
"optional": true
},
"code-point-at": {
"version": "1.1.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true
},
"concat-map": {
"version": "0.0.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"console-control-strings": {
"version": "1.1.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
"dev": true
},
"core-util-is": {
"version": "1.0.2",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true,
"optional": true
},
"debug": {
"version": "2.6.9",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"optional": true,
"requires": {
@@ -2915,25 +3075,29 @@
},
"deep-extend": {
"version": "0.5.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz",
+ "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==",
"dev": true,
"optional": true
},
"delegates": {
"version": "1.0.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
"dev": true,
"optional": true
},
"detect-libc": {
"version": "1.0.3",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
"dev": true,
"optional": true
},
"fs-minipass": {
"version": "1.2.5",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz",
+ "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
"dev": true,
"optional": true,
"requires": {
@@ -2942,13 +3106,15 @@
},
"fs.realpath": {
"version": "1.0.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true,
"optional": true
},
"gauge": {
"version": "2.7.4",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
"dev": true,
"optional": true,
"requires": {
@@ -2964,7 +3130,8 @@
},
"glob": {
"version": "7.1.2",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"dev": true,
"optional": true,
"requires": {
@@ -2978,13 +3145,15 @@
},
"has-unicode": {
"version": "2.0.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
"dev": true,
"optional": true
},
"iconv-lite": {
"version": "0.4.21",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz",
+ "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==",
"dev": true,
"optional": true,
"requires": {
@@ -2993,7 +3162,8 @@
},
"ignore-walk": {
"version": "3.0.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz",
+ "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
"dev": true,
"optional": true,
"requires": {
@@ -3002,7 +3172,8 @@
},
"inflight": {
"version": "1.0.6",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"optional": true,
"requires": {
@@ -3012,18 +3183,21 @@
},
"inherits": {
"version": "2.0.3",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
},
"ini": {
"version": "1.3.5",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
"dev": true,
"optional": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
- "bundled": true,
+ "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"
@@ -3031,13 +3205,15 @@
},
"isarray": {
"version": "1.0.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"dev": true,
"optional": true
},
"minimatch": {
"version": "3.0.4",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "1.1.11"
@@ -3045,12 +3221,14 @@
},
"minimist": {
"version": "0.0.8",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
},
"minipass": {
"version": "2.2.4",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz",
+ "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
"dev": true,
"requires": {
"safe-buffer": "5.1.1",
@@ -3059,7 +3237,8 @@
},
"minizlib": {
"version": "1.1.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz",
+ "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==",
"dev": true,
"optional": true,
"requires": {
@@ -3068,7 +3247,8 @@
},
"mkdirp": {
"version": "0.5.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
"requires": {
"minimist": "0.0.8"
@@ -3076,13 +3256,15 @@
},
"ms": {
"version": "2.0.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true,
"optional": true
},
"needle": {
"version": "2.2.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.0.tgz",
+ "integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==",
"dev": true,
"optional": true,
"requires": {
@@ -3093,7 +3275,8 @@
},
"node-pre-gyp": {
"version": "0.10.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.0.tgz",
+ "integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==",
"dev": true,
"optional": true,
"requires": {
@@ -3111,7 +3294,8 @@
},
"nopt": {
"version": "4.0.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
+ "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
"dev": true,
"optional": true,
"requires": {
@@ -3121,13 +3305,15 @@
},
"npm-bundled": {
"version": "1.0.3",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.3.tgz",
+ "integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==",
"dev": true,
"optional": true
},
"npm-packlist": {
"version": "1.1.10",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.10.tgz",
+ "integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==",
"dev": true,
"optional": true,
"requires": {
@@ -3137,7 +3323,8 @@
},
"npmlog": {
"version": "4.1.2",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+ "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
"dev": true,
"optional": true,
"requires": {
@@ -3149,18 +3336,21 @@
},
"number-is-nan": {
"version": "1.0.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"dev": true
},
"object-assign": {
"version": "4.1.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
"dev": true,
"optional": true
},
"once": {
"version": "1.4.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1.0.2"
@@ -3168,19 +3358,22 @@
},
"os-homedir": {
"version": "1.0.2",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
"dev": true,
"optional": true
},
"os-tmpdir": {
"version": "1.0.2",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
"dev": true,
"optional": true
},
"osenv": {
"version": "0.1.5",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
+ "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
"dev": true,
"optional": true,
"requires": {
@@ -3190,19 +3383,22 @@
},
"path-is-absolute": {
"version": "1.0.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true,
"optional": true
},
"process-nextick-args": {
"version": "2.0.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
"dev": true,
"optional": true
},
"rc": {
"version": "1.2.7",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz",
+ "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==",
"dev": true,
"optional": true,
"requires": {
@@ -3214,7 +3410,8 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true,
"optional": true
}
@@ -3222,7 +3419,8 @@
},
"readable-stream": {
"version": "2.3.6",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"optional": true,
"requires": {
@@ -3237,7 +3435,8 @@
},
"rimraf": {
"version": "2.6.2",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
"dev": true,
"optional": true,
"requires": {
@@ -3246,42 +3445,49 @@
},
"safe-buffer": {
"version": "5.1.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
"dev": true
},
"safer-buffer": {
"version": "2.1.2",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true,
"optional": true
},
"sax": {
"version": "1.2.4",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"dev": true,
"optional": true
},
"semver": {
"version": "5.5.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
+ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
"dev": true,
"optional": true
},
"set-blocking": {
"version": "2.0.0",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
"dev": true,
"optional": true
},
"signal-exit": {
"version": "3.0.2",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
"dev": true,
"optional": true
},
"string-width": {
"version": "1.0.2",
- "bundled": true,
+ "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",
@@ -3291,7 +3497,8 @@
},
"string_decoder": {
"version": "1.1.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"optional": true,
"requires": {
@@ -3300,7 +3507,8 @@
},
"strip-ansi": {
"version": "3.0.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
"ansi-regex": "2.1.1"
@@ -3308,13 +3516,15 @@
},
"strip-json-comments": {
"version": "2.0.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
"dev": true,
"optional": true
},
"tar": {
"version": "4.4.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz",
+ "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==",
"dev": true,
"optional": true,
"requires": {
@@ -3329,13 +3539,15 @@
},
"util-deprecate": {
"version": "1.0.2",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"dev": true,
"optional": true
},
"wide-align": {
"version": "1.1.2",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
+ "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
"dev": true,
"optional": true,
"requires": {
@@ -3344,12 +3556,14 @@
},
"wrappy": {
"version": "1.0.2",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
"yallist": {
"version": "3.0.2",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz",
+ "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
"dev": true
}
}
@@ -4651,6 +4865,15 @@
"path-key": "2.0.1"
}
},
+ "nth-check": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
+ "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=",
+ "dev": true,
+ "requires": {
+ "boolbase": "1.0.0"
+ }
+ },
"num2fraction": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
@@ -8111,6 +8334,12 @@
"safe-buffer": "5.1.2"
}
},
+ "raw-loader": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz",
+ "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=",
+ "dev": true
+ },
"read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -8972,6 +9201,32 @@
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
},
+ "svg-sprite-generator": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/svg-sprite-generator/-/svg-sprite-generator-0.0.7.tgz",
+ "integrity": "sha1-FZd3zj6D6ADyVc7dMR2nYUkhY+k=",
+ "dev": true,
+ "requires": {
+ "async": "1.5.2",
+ "cheerio": "0.19.0",
+ "commander": "2.13.0",
+ "es6-promise": "2.3.0"
+ },
+ "dependencies": {
+ "async": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+ "dev": true
+ },
+ "es6-promise": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz",
+ "integrity": "sha1-lu258v2wGZWCKyY92KratnSBgbw=",
+ "dev": true
+ }
+ }
+ },
"svgo": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz",
diff --git a/package.json b/package.json
index f8e4d1cc..cf0b95f4 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,8 @@
"description": "Codex Editor. Native JS, based on API and Open Source",
"main": "index.js",
"scripts": {
- "build": "rimraf dist && npm run build:dev",
+ "build": "rimraf dist && npm run svg && npm run build:dev",
+ "svg": "svg-sprite-generate -d src/assets/ -o build/sprite.svg",
"build:dev": "webpack --mode development --progress --display-error-details --display-entrypoints"
},
"author": "Codex Team",
@@ -42,7 +43,9 @@
"postcss-nested-ancestors": "^2.0.0",
"postcss-nesting": "^6.0.0",
"postcss-smart-import": "^0.7.6",
+ "raw-loader": "^0.5.1",
"rimraf": "^2.6.2",
+ "svg-sprite-generator": "0.0.7",
"ts-loader": "^4.4.1",
"tslint": "^5.10.0",
"tslint-loader": "^3.6.0",
diff --git a/src/assets/icon-bold.svg b/src/assets/icon-bold.svg
new file mode 100644
index 00000000..f10a3d6d
--- /dev/null
+++ b/src/assets/icon-bold.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/icon-hash.svg b/src/assets/icon-hash.svg
deleted file mode 100644
index 60790072..00000000
--- a/src/assets/icon-hash.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/assets/icon-plus.svg b/src/assets/icon-plus.svg
index fdc0776c..89a0f6b9 100644
--- a/src/assets/icon-plus.svg
+++ b/src/assets/icon-plus.svg
@@ -1,16 +1,3 @@
-
-
-
- Combined Shape
- Created with Sketch.
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
diff --git a/src/components/dom.js b/src/components/dom.js
index c623e6f2..c3445ac0 100644
--- a/src/components/dom.js
+++ b/src/components/dom.js
@@ -45,6 +45,24 @@ export default class Dom {
return document.createTextNode(content);
}
+ /**
+ * Creates SVG icon linked to the sprite
+ * @param {string} name - name (id) of icon from sprite
+ * @param {number} width
+ * @param {number} height
+ * @return {SVGElement}
+ */
+ static svg(name, width = 14, height = 14) {
+ let icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+
+ icon.classList.add('icon', 'icon--' + name);
+ icon.setAttribute('width', width + 'px');
+ icon.setAttribute('height', height + 'px');
+ icon.innerHTML = ` `;
+
+ return icon;
+ }
+
/**
* Append one or several elements to the parent
*
@@ -247,4 +265,4 @@ export default class Dom {
return leafs.every( leaf => this.isNodeEmpty(leaf) );
}
-};
\ No newline at end of file
+};
diff --git a/src/components/inline-tools/inline-tool-bold.ts b/src/components/inline-tools/inline-tool-bold.ts
index 44e5eaf0..4277bf8e 100644
--- a/src/components/inline-tools/inline-tool-bold.ts
+++ b/src/components/inline-tools/inline-tool-bold.ts
@@ -1,5 +1,7 @@
import InlineTool from '../interfaces/inline-tool';
+declare var $: any;
+
/**
* Bold Tool
*
@@ -40,6 +42,7 @@ export default class BoldInlineTool implements InlineTool {
public render(): HTMLElement {
this.nodes.button = document.createElement('button');
this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier);
+ this.nodes.button.appendChild($.svg('icon-bold', 13, 15));
return this.nodes.button;
}
diff --git a/src/components/modules/ui.js b/src/components/modules/ui.js
index c72a5408..888542d5 100644
--- a/src/components/modules/ui.js
+++ b/src/components/modules/ui.js
@@ -3,6 +3,12 @@
*
* @type {UI}
*/
+
+/**
+ * Prebuilded sprite of SVG icons
+ */
+import sprite from '../../../build/sprite.svg';
+
// let className = {
/**
@@ -72,6 +78,10 @@ export default class UI extends Module {
*/
prepare() {
return this.make()
+ /**
+ * Append SVG sprite
+ */
+ .then(() => this.appendSVGSprite())
/**
* Make toolbar
*/
@@ -317,6 +327,17 @@ export default class UI extends Module {
this.Editor.Toolbar.plusButton.show();
}
}
+
+ /**
+ * Append prebuilded sprite with SVG icons
+ */
+ appendSVGSprite() {
+ let spriteHolder = $.make('div');
+
+ spriteHolder.innerHTML = sprite;
+
+ $.append(this.nodes.wrapper, spriteHolder);
+ }
}
// /**
diff --git a/src/styles/inline-toolbar.css b/src/styles/inline-toolbar.css
index 16881c5b..8b4bf350 100644
--- a/src/styles/inline-toolbar.css
+++ b/src/styles/inline-toolbar.css
@@ -19,6 +19,7 @@
outline: none;
background: transparent;
vertical-align: bottom;
+ color: var(--grayText);
&:hover {
background: var(--bg-light);
@@ -29,9 +30,5 @@
}
&--bold {
- &::before {
- font-weight: bold;
- content: 'B'
- }
}
}
diff --git a/src/styles/ui.css b/src/styles/ui.css
index 2582df4e..5507f89a 100644
--- a/src/styles/ui.css
+++ b/src/styles/ui.css
@@ -2,16 +2,23 @@
* Editor wrapper
*/
.codex-editor {
- position: relative;
- border: 1px solid #ccc;
- padding: 2px;
- box-sizing: border-box;
+ position: relative;
+ border: 1px solid #ccc;
+ padding: 2px;
+ box-sizing: border-box;
- .hide {
- display: none;
- }
+ .hide {
+ display: none;
+ }
- &__redactor {
- padding-bottom: 300px;
- }
+ &__redactor {
+ padding-bottom: 300px;
+ }
+
+ svg {
+ fill: currentColor;
+ vertical-align: middle;
+ margin-top: -2px;
+ max-height: 100%;
+ }
}
diff --git a/webpack.config.js b/webpack.config.js
index 10c7233a..5beef349 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -143,7 +143,6 @@ module.exports = {
'Module': './../__module.ts',
}),
-
/** Минифицируем CSS и JS */
// new webpack.optimize.UglifyJsPlugin({
/** Disable warning messages. Cant disable uglify for 3rd party libs such as html-janitor */
@@ -194,6 +193,14 @@ module.exports = {
},
'postcss-loader'
]
+ },
+ {
+ test: /\.(svg)$/,
+ use: [
+ {
+ loader: 'raw-loader',
+ }
+ ]
}
]
},