diff --git a/codex-editor.css b/build/codex-editor.css
similarity index 100%
rename from codex-editor.css
rename to build/codex-editor.css
diff --git a/codex-editor.js b/build/codex-editor.js
similarity index 100%
rename from codex-editor.js
rename to build/codex-editor.js
diff --git a/codex-editor.js.map b/codex-editor.js.map
deleted file mode 100644
index 229e585c..00000000
--- a/codex-editor.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["webpack:///webpack/bootstrap b300a85287826b8d9e89","webpack:///./codex.js","webpack:///./src/modules/dom.js","webpack:///./src/modules/core.js","webpack:///./src/modules/ui.js"],"names":["modules","require","module","exports","config","moduleInstances","Promise","resolve","then","configuration","init","start","console","log","catch","error","constructModules","configureModules","forEach","Module","name","state","getModulesDiff","moduleName","prepareDecorator","prepare","holderId","placeholder","sanitizer","p","b","a","hideToolbar","el","classList","properties","element","document","createElement","className","add","property","selector","querySelector","querySelectorAll","Editor","ui","wrapper","msg","type","args","window","e","settings","url","XMLHTTP","XMLHttpRequest","ActiveXObject","encodedString","isFormData","prop","async","data","test","encodeURIComponent","withCredentials","responseContext","beforeSendResult","beforeSend","call","open","isFormData_","setRequestHeader","progress","upload","onprogress","bind","onreadystatechange","readyState","status","success","responseText","send","BLOCK_CLASSNAME","BLOCK_CONTENT","BLOCK_STRETCHED","BLOCK_HIGHLIGHTED","SETTINGS_ITEM","CSS_","editorWrapper","editorZone","reject","dom","make","redactor","toolbar","makeToolBar_","appendChild","editor","nodes","holder","addTools_","makeInlineToolbar_","addInlineToolbarTools_","makeNotificationHolder_","bindEvents_","core"],"mappings":"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AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,W;;;;;;;;;;;;ACnWAF,QAAOC,OAAP;AAAA;AAAA;AAAA;;AAAA;AAAA;;;AAyBI;;;;;;;;;AAzBJ,8BAkCS8B,EAlCT,EAkCaC,SAlCb,EAkCwBC,UAlCxB,EAkCoC;;AAE5B,iBAAIC,UAAUC,SAASC,aAAT,CAAuBL,EAAvB,CAAd;;AAEAC,uBAAUhB,OAAV,CAAkB,UAAUqB,SAAV,EAAqB;;AAEnCH,yBAAQF,SAAR,CAAkBM,GAAlB,CAAsBD,SAAtB;AAEH,cAJD;;AAMA,kBAAIE,QAAJ,IAAgBN,UAAhB,EAA4B;;AAExBC,yBAAQK,QAAR,GAAmBN,WAAWM,QAAX,CAAnB;AAEH;;AAED,oBAAOL,OAAP;AAEH;;AAED;;;;;;;;;;;AAtDJ;AAAA;AAAA,gCAgEkC;AAAA,iBAAzBH,EAAyB,uEAApBI,QAAoB;AAAA,iBAAVK,QAAU;;;AAE1B,oBAAOT,GAAGU,aAAH,CAAiBD,QAAjB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A;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,W;;;;;;;;;;;;ACrbA;;;;;AAKA,KAAIN,YAAY;;AAEZ;;;AAGA4C,sBAAkB,UALN;;AAOZ;;;AAGAC,oBAAgB,mBAVJ;;AAYZ;;;AAGAC,sBAAkB,qBAfN;;AAiBZ;;;AAGAC,wBAAoB,mBApBR;;AAsBZ;;;AAGAC,oBAAgB;AAzBJ,EAAhB;;AA4BA,KAAIC,OAAO;AACPC,oBAAgB,cADT;AAEPC,iBAAgB;AAFT,EAAX;;AAKAxF,QAAOC,OAAP;AAAA;AAAA;;;AAEI;;;;AAFJ,6BAMsB;;AAEd,oBAAO,IAAP;AAEH;AAVL;;AAYI,iBAAY0C,MAAZ,EAAoB;AAAA;;AAEhB,cAAKE,OAAL,GAAe,IAAf;;AAEA;AACA;AACA;;AAIH;;AAGD;;;;;;;;AAzBJ;AAAA;;;AAqCI;;;;;AArCJ,mCA0Cc;;AAINnC,qBAAQC,GAAR,CAAY,kBAAZ;;AAEA,kBAAKkC,OAAL,GAAeV,SAASC,aAAT,CAAuB,KAAvB,CAAf;;AAEA;;AAEA,oBAAO,IAAIhC,OAAJ,CAAY,UAAUC,OAAV,EAAmBoF,MAAnB,EAA2B;;AAE1C,qBAAI5C,UAAW,KAAK/C,OAAL,CAAa4F,GAAb,CAAiBC,IAAjB,CAAsB,KAAtB,EAA6B,CAAEL,KAAKC,aAAP,CAA7B,EAAqD,EAArD,CAAf;AAAA,qBACIK,WAAW,KAAK9F,OAAL,CAAa4F,GAAb,CAAiBC,IAAjB,CAAsB,KAAtB,EAA6B,CAAEL,KAAKE,UAAP,CAA7B,EAAkD,EAAlD,CADf;AAAA,qBAEIK,UAAWC,cAFf;;AAIAjD,yBAAQkD,WAAR,CAAoBF,OAApB;AACAhD,yBAAQkD,WAAR,CAAoBH,QAApB;;AAEA;AACAI,wBAAOC,KAAP,CAAapD,OAAb,GAAwBA,OAAxB;AACAmD,wBAAOC,KAAP,CAAaL,QAAb,GAAwBA,QAAxB;;AAEA;AACAI,wBAAOC,KAAP,CAAaC,MAAb,CAAoBH,WAApB,CAAgClD,OAAhC;;AAEAxC;AAEH,cAlBM;;AAoBP;AApBO,cAqBNC,IArBM,CAqBD6F,SArBC;;AAuBP;AAvBO,cAwBN7F,IAxBM,CAwBD8F,kBAxBC;;AA0BP;AA1BO,cA2BN9F,IA3BM,CA2BD+F,sBA3BC;;AA6BP;AA7BO,cA8BN/F,IA9BM,CA8BDgG,uBA9BC;;AAgCP;AAhCO,cAiCNhG,IAjCM,CAiCDiG,WAjCC,EAmCN3F,KAnCM,CAmCC,YAAY;;AAEhBoF,wBAAOQ,IAAP,CAAY7F,GAAZ,CAAgB,6BAAhB;AAEH,cAvCM,CAAP;AAyCH;AA7FL;AAAA;AAAA,2BA+BcgC,MA/Bd,EA+BsB;;AAEd,kBAAKA,MAAL,GAAcA,MAAd;AAEH;AAnCL;;AAAA;AAAA;AAgGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,W","file":"codex-editor.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap b300a85287826b8d9e89","/**\n * Codex Editor\n *\n *\n *\n *\n * @author CodeX Team\n */\n\n/**\n * @typedef {CodexEditor} CodexEditor - editor class\n */\n\n/**\n * @typedef {Object} EditorConfig\n * @property {String} holderId - Element to append Editor\n * ...\n */\n\n/**\n * All Editor components\n */\nconst modules = [\n require('./src/modules/dom'),\n require('./src/modules/core'),\n require('./src/modules/ui')\n];\n\n/**\n * @class\n *\n * @classdesc CodeX Editor base class\n *\n * @property this.config - all settings\n * @property this.moduleInstances - constructed editor components\n *\n * @type {CodexEditor}\n */\nmodule.exports = class CodexEditor {\n\n /** Editor version */\n static get version() {\n\n return VERSION;\n\n }\n\n /**\n * @param {EditorConfig} config - user configuration\n *\n */\n constructor(config) {\n\n 'use strict';\n\n\n /**\n * Configuration object\n */\n this.config = {};\n\n /**\n * Editor Components\n */\n this.moduleInstances = {};\n\n Promise.resolve()\n .then(() => {\n\n this.configuration = config;\n\n })\n .then(() => this.init())\n .then(() => this.start())\n .then(() => {\n\n console.log('CodeX Editor is ready');\n\n })\n .catch(error => {\n\n console.log('CodeX Editor does not ready beecause of %o', error);\n\n });\n\n }\n\n /**\n * Setting for configuration\n * @param {object} config\n */\n set configuration(config = {}) {\n\n this.config.holderId = config.holderId;\n this.config.placeholder = config.placeholder || 'write your story...';\n this.config.sanitizer = config.sanitizer || {\n p: true,\n b: true,\n a: true\n };\n\n this.config.hideToolbar = config.hideToolbar ? config.hideToolbar : false;\n\n }\n\n /**\n * Returns private property\n * @returns {{}|*}\n */\n get configuration() {\n\n return this.config;\n\n }\n\n /**\n * Initializes modules:\n * - make and save instances\n * - configure\n */\n init() {\n\n /**\n * Make modules instances and save it to the @property this.moduleInstances\n */\n this.constructModules();\n\n /**\n * Modules configuration\n */\n this.configureModules();\n\n }\n\n /**\n * Make modules instances and save it to the @property this.moduleInstances\n */\n constructModules() {\n\n modules.forEach( Module => {\n\n this.moduleInstances[Module.name] = new Module({\n config : this.configuration\n });\n\n });\n\n }\n\n /**\n * Modules instances configuration:\n * - pass other modules to the 'state' property\n * - ...\n */\n configureModules() {\n\n for(let name in this.moduleInstances) {\n\n /**\n * Module does not need self-instance\n */\n this.moduleInstances[name].state = this.getModulesDiff( name );\n\n }\n\n }\n\n /**\n * Return modules without passed name\n */\n getModulesDiff( name ) {\n\n let modules = {};\n\n for(let moduleName in this.moduleInstances) {\n\n /**\n * Skip module with passed name\n */\n if (moduleName == name) {\n\n continue;\n\n }\n modules[moduleName] = this.moduleInstances[moduleName];\n\n }\n\n return modules;\n\n }\n\n\n\n /**\n * Start Editor!\n *\n * @return {Promise}\n */\n start() {\n\n let prepareDecorator = module => module.prepare();\n\n return Promise.resolve()\n .then(prepareDecorator(this.moduleInstances['core']))\n .then(prepareDecorator(this.moduleInstances['ui']))\n .catch(function (error) {\n\n console.log('Error occured', error);\n\n });\n\n\n }\n\n};\n\n// module.exports = (function (editor) {\n//\n// 'use strict';\n//\n// editor.version = VERSION;\n// editor.scriptPrefix = 'cdx-script-';\n//\n// var init = function () {\n//\n// editor.core = require('./modules/core');\n// editor.tools = require('./modules/tools');\n// editor.ui = require('./modules/ui');\n// editor.transport = require('./modules/transport');\n// editor.renderer = require('./modules/renderer');\n// editor.saver = require('./modules/saver');\n// editor.content = require('./modules/content');\n// editor.toolbar = require('./modules/toolbar/toolbar');\n// editor.callback = require('./modules/callbacks');\n// editor.draw = require('./modules/draw');\n// editor.caret = require('./modules/caret');\n// editor.notifications = require('./modules/notifications');\n// editor.parser = require('./modules/parser');\n// editor.sanitizer = require('./modules/sanitizer');\n// editor.listeners = require('./modules/listeners');\n// editor.destroyer = require('./modules/destroyer');\n// editor.paste = require('./modules/paste');\n//\n// };\n//\n// /**\n// * @public\n// * holds initial settings\n// */\n// editor.settings = {\n// tools : ['paragraph', 'header', 'picture', 'list', 'quote', 'code', 'twitter', 'instagram', 'smile'],\n// holderId : 'codex-editor',\n//\n// // Type of block showing on empty editor\n// initialBlockPlugin: 'paragraph'\n// };\n//\n// /**\n// * public\n// *\n// * Static nodes\n// */\n// editor.nodes = {\n// holder : null,\n// wrapper : null,\n// toolbar : null,\n// inlineToolbar : {\n// wrapper : null,\n// buttons : null,\n// actions : null\n// },\n// toolbox : null,\n// notifications : null,\n// plusButton : null,\n// showSettingsButton: null,\n// showTrashButton : null,\n// blockSettings : null,\n// pluginSettings : null,\n// defaultSettings : null,\n// toolbarButtons : {}, // { type : DomEl, ... }\n// redactor : null\n// };\n//\n// /**\n// * @public\n// *\n// * Output state\n// */\n// editor.state = {\n// jsonOutput : [],\n// blocks : [],\n// inputs : []\n// };\n//\n// /**\n// * @public\n// * Editor plugins\n// */\n// editor.tools = {};\n//\n// /**\n// * Initialization\n// * @uses Promise cEditor.core.prepare\n// * @param {Object} userSettings\n// * @param {Array} userSettings.tools list of plugins\n// * @param {String} userSettings.holderId Element's id to append editor\n// *\n// * Load user defined tools\n// * Tools must contain this important objects :\n// * @param {String} type - this is a type of plugin. It can be used as plugin name\n// * @param {String} iconClassname - this a icon in toolbar\n// * @param {Object} make - what should plugin do, when it is clicked\n// * @param {Object} appendCallback - callback after clicking\n// * @param {Element} settings - what settings does it have\n// * @param {Object} render - plugin get JSON, and should return HTML\n// * @param {Object} save - plugin gets HTML content, returns JSON\n// * @param {Boolean} displayInToolbox - will be displayed in toolbox. Default value is TRUE\n// * @param {Boolean} enableLineBreaks - inserts new block or break lines. Default value is FALSE\n// *\n// * @example\n// * - type : 'header',\n// * - iconClassname : 'ce-icon-header',\n// * - make : headerTool.make,\n// * - appendCallback : headerTool.appendCallback,\n// * - settings : headerTool.makeSettings(),\n// * - render : headerTool.render,\n// * - save : headerTool.save,\n// * - displayInToolbox : true,\n// * - enableLineBreaks : false\n// */\n// editor.start = function (userSettings) {\n//\n// init();\n//\n// editor.core.prepare(userSettings)\n//\n// // If all ok, make UI, bind events and parse initial-content\n// .then(editor.ui.prepare)\n// .then(editor.tools.prepare)\n// .then(editor.sanitizer.prepare)\n// .then(editor.paste.prepare)\n// .then(editor.transport.prepare)\n// .then(editor.renderer.makeBlocksFromData)\n// .then(editor.ui.saveInputs)\n// .catch(function (error) {\n//\n// editor.core.log('Initialization failed with error: %o', 'warn', error);\n//\n// });\n//\n// };\n//\n// return editor;\n//\n// })({});\n\n\n\n// WEBPACK FOOTER //\n// ./codex.js","module.exports = class Dom {\n\n /**\n * Module key name\n * @returns {string}\n */\n static get name() {\n\n return 'dom';\n\n };\n\n\n /**\n * @param Editor\n * @param Editor.modules {@link Tools#list}\n * @param Editor.config {@link CodexEditor#configuration}\n * @param Editor\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * Draws element with class and properties\n *\n * @param {String} el - Element name\n * @param {Array} classList - array of CSS classes\n * @param {Object} properties - list of objects/properties\n *\n * @returns {Element}\n */\n make(el, classList, properties) {\n\n let element = document.createElement(el);\n\n classList.forEach(function (className) {\n\n element.classList.add(className);\n\n });\n\n for(property in properties) {\n\n element.property = properties[property];\n\n }\n\n return element;\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 find(el = document, selector) {\n\n return el.querySelector(selector);\n\n }\n\n /**\n * Selector Decorator.\n *\n * Returns all matches\n *\n * @param {Element} el - element we searching inside. Default - DOM Document\n * @param {String} selector - searching string\n * @returns {NodeList}\n */\n findAll(el = document, selector) {\n\n return el.querySelectorAll(selector);\n\n }\n\n};\n\n\n// WEBPACK FOOTER //\n// ./src/modules/dom.js","/**\n * Codex Editor Core\n *\n * @author Codex Team\n * @version 1.1.3\n */\nmodule.exports = class Core {\n\n /**\n * Module key name\n * @returns {string}\n */\n static get name() {\n\n return 'core';\n\n };\n\n /** Editor script prefixes */\n static get scriptPrefix() {\n\n return 'cdx-script-';\n\n }\n\n\n\n /**\n *\n * @param Editor\n * @param Editor.modules {@link Tools#list}\n * @param Editor.config {@link CodexEditor#configuration}\n */\n constructor(config) {\n\n // this.Editor.modules.toolbar;\n\n this.Editor = null;\n\n // console.log(this.Editor);\n\n\n // this.toolbar = modules.toolbar;\n\n // this.sanitizer = null;\n // this.state = {};\n\n }\n\n /**\n * @param Editor\n * @param Editor.modules {@link Tools#list}\n * @param Editor.config {@link CodexEditor#configuration}\n * @param Editor\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * @public\n *\n * Editor preparing method\n * @return Promise\n */\n prepare() {\n\n // let self = this;\n\n console.log('Core prepare fired');\n\n /**\n * Обращение к другому модулю\n */\n console.log(this.Editor.ui.wrapper);\n\n\n return;\n\n /**\n\n return new Promise(function (resolve, reject) {\n\n if (typeof self.Editor.config.holderId === undefined ) {\n\n reject(Error(\"Holder wasn't found by ID: #\" + userSettings.holderId));\n\n } else {\n\n resolve();\n\n }\n\n resolve();\n\n });\n\n */\n\n }\n\n /**\n * Core custom logger\n *\n * @param msg\n * @param type\n * @param args\n */\n log(msg, type, args) {\n\n type = type || 'log';\n\n if (!args) {\n\n args = msg || 'undefined';\n msg = '[codex-editor]: %o';\n\n } else {\n\n msg = '[codex-editor]: ' + msg;\n\n }\n\n try{\n\n if ( 'console' in window && window.console[ type ] ) {\n\n if ( args ) window.console[ type ]( msg, args );\n else window.console[ type ]( msg );\n\n }\n\n } catch(e) {\n // do nothing\n }\n\n }\n\n /**\n * Native Ajax\n * @param {String} settings.url - request URL\n * @param {function} settings.beforeSend - returned value will be passed as context to the Success, Error and Progress callbacks\n * @param {function} settings.success\n * @param {function} settings.progress\n */\n ajax(settings) {\n\n if (!settings || !settings.url) {\n\n return;\n\n }\n\n var XMLHTTP = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'),\n encodedString,\n isFormData,\n prop;\n\n\n settings.async = true;\n settings.type = settings.type || 'GET';\n settings.data = settings.data || '';\n settings['content-type'] = settings['content-type'] || 'application/json; charset=utf-8';\n\n if (settings.type == 'GET' && settings.data) {\n\n settings.url = /\\?/.test(settings.url) ? settings.url + '&' + settings.data : settings.url + '?' + settings.data;\n\n } else {\n\n encodedString = '';\n for(prop in settings.data) {\n\n encodedString += (prop + '=' + encodeURIComponent(settings.data[prop]) + '&');\n\n }\n\n }\n\n if (settings.withCredentials) {\n\n XMLHTTP.withCredentials = true;\n\n }\n\n /**\n * Value returned in beforeSend funtion will be passed as context to the other response callbacks\n * If beforeSend returns false, AJAX will be blocked\n */\n let responseContext,\n beforeSendResult;\n\n if (typeof settings.beforeSend === 'function') {\n\n beforeSendResult = settings.beforeSend.call();\n\n if (beforeSendResult === false) {\n\n return;\n\n }\n\n }\n\n XMLHTTP.open( settings.type, settings.url, settings.async );\n\n /**\n * If we send FormData, we need no content-type header\n */\n isFormData = isFormData_(settings.data);\n\n if (!isFormData) {\n\n if (settings.type !== 'POST') {\n\n XMLHTTP.setRequestHeader('Content-type', settings['content-type']);\n\n } else {\n\n XMLHTTP.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');\n\n }\n\n }\n\n XMLHTTP.setRequestHeader('X-Requested-With', 'XMLHttpRequest');\n\n responseContext = beforeSendResult || XMLHTTP;\n\n if (typeof settings.progress === 'function') {\n\n XMLHTTP.upload.onprogress = settings.progress.bind(responseContext);\n\n }\n\n XMLHTTP.onreadystatechange = function () {\n\n if (XMLHTTP.readyState === 4) {\n\n if (XMLHTTP.status === 200) {\n\n if (typeof settings.success === 'function') {\n\n settings.success.call(responseContext, XMLHTTP.responseText);\n\n }\n\n } else {\n\n if (typeof settings.error === 'function') {\n\n settings.error.call(responseContext, XMLHTTP.responseText, XMLHTTP.status);\n\n }\n\n }\n\n }\n\n };\n\n if (isFormData) {\n\n // Sending FormData\n XMLHTTP.send(settings.data);\n\n } else {\n\n // POST requests\n XMLHTTP.send(encodedString);\n\n }\n\n return XMLHTTP;\n\n }\n\n};\n// module.exports = (function (core) {\n//\n// let editor = codex.editor;\n//\n//\n// /**\n// * @protected\n// *\n// * Helper for insert one element after another\n// */\n// core.insertAfter = function (target, element) {\n//\n// target.parentNode.insertBefore(element, target.nextSibling);\n//\n// };\n//\n// /**\n// * @const\n// *\n// * Readable DOM-node types map\n// */\n// core.nodeTypes = {\n// TAG : 1,\n// TEXT : 3,\n// COMMENT : 8,\n// DOCUMENT_FRAGMENT: 11\n// };\n//\n// /**\n// * @const\n// * Readable keys map\n// */\n// core.keys = { 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 };\n//\n// /**\n// * @protected\n// *\n// * Check object for DOM node\n// */\n// core.isDomNode = function (el) {\n//\n// return el && typeof el === 'object' && el.nodeType && el.nodeType == this.nodeTypes.TAG;\n//\n// };\n//\n// /**\n// * Checks passed object for emptiness\n// * @require ES5 - Object.keys\n// * @param {object}\n// */\n// core.isEmpty = function ( obj ) {\n//\n// return Object.keys(obj).length === 0;\n//\n// };\n//\n// /**\n// * Appends script to head of document\n// * @return Promise\n// */\n// core.importScript = function (scriptPath, instanceName) {\n//\n// return new Promise(function (resolve, reject) {\n//\n// let script;\n//\n// /** Script is already loaded */\n// if ( !instanceName ) {\n//\n// reject('Instance name is missed');\n//\n// } else if ( document.getElementById(editor.scriptPrefix + instanceName) ) {\n//\n// resolve(scriptPath);\n//\n// }\n//\n// script = document.createElement('SCRIPT');\n// script.async = true;\n// script.defer = true;\n// script.id = editor.scriptPrefix + instanceName;\n//\n// script.onload = function () {\n//\n// resolve(scriptPath);\n//\n// };\n//\n// script.onerror = function () {\n//\n// reject(scriptPath);\n//\n// };\n//\n// script.src = scriptPath;\n// document.head.appendChild(script);\n//\n// });\n//\n// };\n//\n// /**\n// * Function for checking is it FormData object to send.\n// * @param {Object} object to check\n// * @return boolean\n// */\n// var isFormData_ = function (object) {\n//\n// return object instanceof FormData;\n//\n// };\n//\n// /**\n// * Check block\n// * @param target\n// * @description Checks target is it native input\n// */\n// core.isNativeInput = function (target) {\n//\n// var nativeInputAreas = ['INPUT', 'TEXTAREA'];\n//\n// return nativeInputAreas.indexOf(target.tagName) != -1;\n//\n// };\n//\n// /**\n// * Check if block is empty\n// * We should check block textContent, child native inputs and some exceptions like IMG and IFRAME\n// *\n// * @param block\n// * @returns {boolean}\n// */\n// core.isBlockEmpty = function (block) {\n//\n// const EXCEPTION_TAGS = ['IMG', 'IFRAME'];\n//\n// var nativeInputs = block.querySelectorAll('textarea, input'),\n// nativeInputsAreEmpty = true,\n// textContentIsEmpty = !block.textContent.trim();\n//\n// Array.prototype.forEach.call(nativeInputs, function (input) {\n//\n// if (input.type == 'textarea' || input.type == 'text') {\n//\n// nativeInputsAreEmpty = nativeInputsAreEmpty && !input.value.trim();\n//\n// }\n//\n// });\n//\n// return textContentIsEmpty && nativeInputsAreEmpty && !EXCEPTION_TAGS.includes(block.tagName);\n//\n// };\n//\n//\n// return core;\n//\n// })({});\n\n\n\n// WEBPACK FOOTER //\n// ./src/modules/core.js","/**\n * Module UI\n *\n * @type {UI}\n */\nlet className = {\n\n /**\n * @const {string} BLOCK_CLASSNAME - redactor blocks name\n */\n BLOCK_CLASSNAME : 'ce-block',\n\n /**\n * @const {String} wrapper for plugins content\n */\n BLOCK_CONTENT : 'ce-block__content',\n\n /**\n * @const {String} BLOCK_STRETCHED - makes block stretched\n */\n BLOCK_STRETCHED : 'ce-block--stretched',\n\n /**\n * @const {String} BLOCK_HIGHLIGHTED - adds background\n */\n BLOCK_HIGHLIGHTED : 'ce-block--focused',\n\n /**\n * @const {String} - for all default settings\n */\n SETTINGS_ITEM : 'ce-settings__item'\n};\n\nlet CSS_ = {\n editorWrapper : 'codex-editor',\n editorZone : 'ce-redactor'\n};\n\nmodule.exports = class UI {\n\n /**\n * Module key name\n * @returns {string}\n */\n static get name() {\n\n return 'ui';\n\n };\n\n constructor(Editor) {\n\n this.wrapper = null;\n\n // this.Editor = Editor;\n //\n // this.modules = this.Editor.modules;\n\n\n\n }\n\n\n /**\n * @param Editor\n * @param Editor.modules {@link Tools#list}\n * @param Editor.config {@link CodexEditor#configuration}\n * @param Editor\n */\n set state(Editor) {\n\n this.Editor = Editor;\n\n }\n\n /**\n * @protected\n *\n * Making main interface\n */\n prepare() {\n\n\n\n console.log('ui prepare fired');\n\n this.wrapper = document.createElement('div');\n\n return;\n\n return new Promise(function (resolve, reject) {\n\n let wrapper = this.modules.dom.make('DIV', [ CSS_.editorWrapper ], {}),\n redactor = this.modules.dom.make('DIV', [ CSS_.editorZone ], {}),\n toolbar = makeToolBar_();\n\n wrapper.appendChild(toolbar);\n wrapper.appendChild(redactor);\n\n /** Save created ui-elements to static nodes state */\n editor.nodes.wrapper = wrapper;\n editor.nodes.redactor = redactor;\n\n /** Append editor wrapper with redactor zone into holder */\n editor.nodes.holder.appendChild(wrapper);\n\n resolve();\n\n })\n\n /** Add toolbox tools */\n .then(addTools_)\n\n /** Make container for inline toolbar */\n .then(makeInlineToolbar_)\n\n /** Add inline toolbar tools */\n .then(addInlineToolbarTools_)\n\n /** Draw wrapper for notifications */\n .then(makeNotificationHolder_)\n\n /** Add eventlisteners to redactor elements */\n .then(bindEvents_)\n\n .catch( function () {\n\n editor.core.log(\"Can't draw editor interface\");\n\n });\n\n }\n\n};\n// /**\n// * Codex Editor UI module\n// *\n// * @author Codex Team\n// * @version 1.2.0\n// */\n//\n// module.exports = (function (ui) {\n//\n// let editor = codex.editor;\n//\n// /**\n// * Basic editor classnames\n// */\n// ui.prepare = function () {\n//\n\n//\n// };\n//\n// /**\n// * @private\n// * Draws inline toolbar zone\n// */\n// var makeInlineToolbar_ = function () {\n//\n// var container = editor.draw.inlineToolbar();\n//\n// /** Append to redactor new inline block */\n// editor.nodes.inlineToolbar.wrapper = container;\n//\n// /** Draw toolbar buttons */\n// editor.nodes.inlineToolbar.buttons = editor.draw.inlineToolbarButtons();\n//\n// /** Buttons action or settings */\n// editor.nodes.inlineToolbar.actions = editor.draw.inlineToolbarActions();\n//\n// /** Append to inline toolbar buttons as part of it */\n// editor.nodes.inlineToolbar.wrapper.appendChild(editor.nodes.inlineToolbar.buttons);\n// editor.nodes.inlineToolbar.wrapper.appendChild(editor.nodes.inlineToolbar.actions);\n//\n// editor.nodes.wrapper.appendChild(editor.nodes.inlineToolbar.wrapper);\n//\n// };\n//\n// var makeToolBar_ = function () {\n//\n// let toolbar = editor.draw.toolbar(),\n// blockButtons = makeToolbarSettings_(),\n// toolbarContent = makeToolbarContent_();\n//\n// /** Appending first-level block buttons */\n// toolbar.appendChild(blockButtons);\n//\n// /** Append toolbarContent to toolbar */\n// toolbar.appendChild(toolbarContent);\n//\n// /** Make toolbar global */\n// editor.nodes.toolbar = toolbar;\n//\n// return toolbar;\n//\n// };\n//\n// var makeToolbarContent_ = function () {\n//\n// let toolbarContent = editor.draw.toolbarContent(),\n// toolbox = editor.draw.toolbox(),\n// plusButton = editor.draw.plusButton();\n//\n// /** Append plus button */\n// toolbarContent.appendChild(plusButton);\n//\n// /** Appending toolbar tools */\n// toolbarContent.appendChild(toolbox);\n//\n// /** Make Toolbox and plusButton global */\n// editor.nodes.toolbox = toolbox;\n// editor.nodes.plusButton = plusButton;\n//\n// return toolbarContent;\n//\n// };\n//\n// var makeToolbarSettings_ = function () {\n//\n// let blockSettings = editor.draw.blockSettings(),\n// blockButtons = editor.draw.blockButtons(),\n// defaultSettings = editor.draw.defaultSettings(),\n// showSettingsButton = editor.draw.settingsButton(),\n// showTrashButton = editor.toolbar.settings.makeRemoveBlockButton(),\n// pluginSettings = editor.draw.pluginsSettings();\n//\n// /** Add default and plugins settings */\n// blockSettings.appendChild(pluginSettings);\n// blockSettings.appendChild(defaultSettings);\n//\n// /**\n// * Make blocks buttons\n// * This block contains settings button and remove block button\n// */\n// blockButtons.appendChild(showSettingsButton);\n// blockButtons.appendChild(showTrashButton);\n// blockButtons.appendChild(blockSettings);\n//\n// /** Make BlockSettings, PluginSettings, DefaultSettings global */\n// editor.nodes.blockSettings = blockSettings;\n// editor.nodes.pluginSettings = pluginSettings;\n// editor.nodes.defaultSettings = defaultSettings;\n// editor.nodes.showSettingsButton = showSettingsButton;\n// editor.nodes.showTrashButton = showTrashButton;\n//\n// return blockButtons;\n//\n// };\n//\n// /** Draw notifications holder */\n// var makeNotificationHolder_ = function () {\n//\n// /** Append block with notifications to the document */\n// editor.nodes.notifications = editor.notifications.createHolder();\n//\n// };\n//\n// /**\n// * @private\n// * Append tools passed in editor.tools\n// */\n// var addTools_ = function () {\n//\n// var tool,\n// toolName,\n// toolButton;\n//\n// for ( toolName in editor.settings.tools ) {\n//\n// tool = editor.settings.tools[toolName];\n//\n// editor.tools[toolName] = tool;\n//\n// if (!tool.iconClassname && tool.displayInToolbox) {\n//\n// editor.core.log('Toolbar icon classname missed. Tool %o skipped', 'warn', toolName);\n// continue;\n//\n// }\n//\n// if (typeof tool.render != 'function') {\n//\n// editor.core.log('render method missed. Tool %o skipped', 'warn', toolName);\n// continue;\n//\n// }\n//\n// if (!tool.displayInToolbox) {\n//\n// continue;\n//\n// } else {\n//\n// /** if tools is for toolbox */\n// toolButton = editor.draw.toolbarButton(toolName, tool.iconClassname);\n//\n// editor.nodes.toolbox.appendChild(toolButton);\n//\n// editor.nodes.toolbarButtons[toolName] = toolButton;\n//\n// }\n//\n// }\n//\n// };\n//\n// var addInlineToolbarTools_ = function () {\n//\n// var tools = {\n//\n// bold: {\n// icon : 'ce-icon-bold',\n// command : 'bold'\n// },\n//\n// italic: {\n// icon : 'ce-icon-italic',\n// command : 'italic'\n// },\n//\n// link: {\n// icon : 'ce-icon-link',\n// command : 'createLink'\n// }\n// };\n//\n// var toolButton,\n// tool;\n//\n// for(var name in tools) {\n//\n// tool = tools[name];\n//\n// toolButton = editor.draw.toolbarButtonInline(name, tool.icon);\n//\n// editor.nodes.inlineToolbar.buttons.appendChild(toolButton);\n// /**\n// * Add callbacks to this buttons\n// */\n// editor.ui.setInlineToolbarButtonBehaviour(toolButton, tool.command);\n//\n// }\n//\n// };\n//\n// /**\n// * @private\n// * Bind editor UI events\n// */\n// var bindEvents_ = function () {\n//\n// editor.core.log('ui.bindEvents fired', 'info');\n//\n// // window.addEventListener('error', function (errorMsg, url, lineNumber) {\n// // editor.notifications.errorThrown(errorMsg, event);\n// // }, false );\n//\n// /** All keydowns on Document */\n// editor.listeners.add(document, 'keydown', editor.callback.globalKeydown, false);\n//\n// /** All keydowns on Redactor zone */\n// editor.listeners.add(editor.nodes.redactor, 'keydown', editor.callback.redactorKeyDown, false);\n//\n// /** All keydowns on Document */\n// editor.listeners.add(document, 'keyup', editor.callback.globalKeyup, false );\n//\n// /**\n// * Mouse click to radactor\n// */\n// editor.listeners.add(editor.nodes.redactor, 'click', editor.callback.redactorClicked, false );\n//\n// /**\n// * Clicks to the Plus button\n// */\n// editor.listeners.add(editor.nodes.plusButton, 'click', editor.callback.plusButtonClicked, false);\n//\n// /**\n// * Clicks to SETTINGS button in toolbar\n// */\n// editor.listeners.add(editor.nodes.showSettingsButton, 'click', editor.callback.showSettingsButtonClicked, false );\n//\n// /** Bind click listeners on toolbar buttons */\n// for (var button in editor.nodes.toolbarButtons) {\n//\n// editor.listeners.add(editor.nodes.toolbarButtons[button], 'click', editor.callback.toolbarButtonClicked, false);\n//\n// }\n//\n// };\n//\n// ui.addBlockHandlers = function (block) {\n//\n// if (!block) return;\n//\n// /**\n// * Block keydowns\n// */\n// editor.listeners.add(block, 'keydown', editor.callback.blockKeydown, false);\n//\n// /**\n// * Pasting content from another source\n// * We have two type of sanitization\n// * First - uses deep-first search algorithm to get sub nodes,\n// * sanitizes whole Block_content and replaces cleared nodes\n// * This method is deprecated\n// * Method is used in editor.callback.blockPaste(event)\n// *\n// * Secont - uses Mutation observer.\n// * Observer \"observe\" DOM changes and send changings to callback.\n// * Callback gets changed node, not whole Block_content.\n// * Inserted or changed node, which we've gotten have been cleared and replaced with diry node\n// *\n// * Method is used in editor.callback.blockPasteViaSanitize(event)\n// *\n// * @uses html-janitor\n// * @example editor.callback.blockPasteViaSanitize(event), the second method.\n// *\n// */\n// editor.listeners.add(block, 'paste', editor.paste.blockPasteCallback, false);\n//\n// /**\n// * Show inline toolbar for selected text\n// */\n// editor.listeners.add(block, 'mouseup', editor.toolbar.inline.show, false);\n// editor.listeners.add(block, 'keyup', editor.toolbar.inline.show, false);\n//\n// };\n//\n// /** getting all contenteditable elements */\n// ui.saveInputs = function () {\n//\n// var redactor = editor.nodes.redactor;\n//\n// editor.state.inputs = [];\n//\n// /** Save all inputs in global variable state */\n// var inputs = redactor.querySelectorAll('[contenteditable], input, textarea');\n//\n// Array.prototype.map.call(inputs, function (current) {\n//\n// if (!current.type || current.type == 'text' || current.type == 'textarea') {\n//\n// editor.state.inputs.push(current);\n//\n// }\n//\n// });\n//\n// };\n//\n// /**\n// * Adds first initial block on empty redactor\n// */\n// ui.addInitialBlock = function () {\n//\n// var initialBlockType = editor.settings.initialBlockPlugin,\n// initialBlock;\n//\n// if ( !editor.tools[initialBlockType] ) {\n//\n// editor.core.log('Plugin %o was not implemented and can\\'t be used as initial block', 'warn', initialBlockType);\n// return;\n//\n// }\n//\n// initialBlock = editor.tools[initialBlockType].render();\n//\n// initialBlock.setAttribute('data-placeholder', editor.settings.placeholder);\n//\n// editor.content.insertBlock({\n// type : initialBlockType,\n// block : initialBlock\n// });\n//\n// editor.content.workingNodeChanged(initialBlock);\n//\n// };\n//\n// ui.setInlineToolbarButtonBehaviour = function (button, type) {\n//\n// editor.listeners.add(button, 'mousedown', function (event) {\n//\n// editor.toolbar.inline.toolClicked(event, type);\n//\n// }, false);\n//\n// };\n//\n// return ui;\n//\n// })({});\n\n\n\n// WEBPACK FOOTER //\n// ./src/modules/ui.js"],"sourceRoot":""}
\ No newline at end of file
diff --git a/example.html b/example/example.html
similarity index 100%
rename from example.html
rename to example/example.html
diff --git a/plugins/code/code.css b/example/plugins/code/code.css
similarity index 100%
rename from plugins/code/code.css
rename to example/plugins/code/code.css
diff --git a/plugins/code/code.js b/example/plugins/code/code.js
similarity index 100%
rename from plugins/code/code.js
rename to example/plugins/code/code.js
diff --git a/plugins/embed/embed.css b/example/plugins/embed/embed.css
similarity index 100%
rename from plugins/embed/embed.css
rename to example/plugins/embed/embed.css
diff --git a/plugins/embed/embed.js b/example/plugins/embed/embed.js
similarity index 100%
rename from plugins/embed/embed.js
rename to example/plugins/embed/embed.js
diff --git a/plugins/embed/loading.gif b/example/plugins/embed/loading.gif
similarity index 100%
rename from plugins/embed/loading.gif
rename to example/plugins/embed/loading.gif
diff --git a/plugins/header/header.css b/example/plugins/header/header.css
similarity index 100%
rename from plugins/header/header.css
rename to example/plugins/header/header.css
diff --git a/plugins/header/header.js b/example/plugins/header/header.js
similarity index 100%
rename from plugins/header/header.js
rename to example/plugins/header/header.js
diff --git a/plugins/image/image.css b/example/plugins/image/image.css
similarity index 100%
rename from plugins/image/image.css
rename to example/plugins/image/image.css
diff --git a/plugins/image/image.js b/example/plugins/image/image.js
similarity index 100%
rename from plugins/image/image.js
rename to example/plugins/image/image.js
diff --git a/plugins/instagram/instagram.css b/example/plugins/instagram/instagram.css
similarity index 100%
rename from plugins/instagram/instagram.css
rename to example/plugins/instagram/instagram.css
diff --git a/plugins/instagram/instagram.js b/example/plugins/instagram/instagram.js
similarity index 100%
rename from plugins/instagram/instagram.js
rename to example/plugins/instagram/instagram.js
diff --git a/plugins/instagram/loading.gif b/example/plugins/instagram/loading.gif
similarity index 100%
rename from plugins/instagram/loading.gif
rename to example/plugins/instagram/loading.gif
diff --git a/plugins/link/link.css b/example/plugins/link/link.css
similarity index 100%
rename from plugins/link/link.css
rename to example/plugins/link/link.css
diff --git a/plugins/link/link.js b/example/plugins/link/link.js
similarity index 100%
rename from plugins/link/link.js
rename to example/plugins/link/link.js
diff --git a/plugins/list/list.css b/example/plugins/list/list.css
similarity index 100%
rename from plugins/list/list.css
rename to example/plugins/list/list.css
diff --git a/plugins/list/list.js b/example/plugins/list/list.js
similarity index 100%
rename from plugins/list/list.js
rename to example/plugins/list/list.js
diff --git a/plugins/paragraph/paragraph.css b/example/plugins/paragraph/paragraph.css
similarity index 100%
rename from plugins/paragraph/paragraph.css
rename to example/plugins/paragraph/paragraph.css
diff --git a/plugins/paragraph/paragraph.js b/example/plugins/paragraph/paragraph.js
similarity index 100%
rename from plugins/paragraph/paragraph.js
rename to example/plugins/paragraph/paragraph.js
diff --git a/plugins/quote/img/codex.png b/example/plugins/quote/img/codex.png
similarity index 100%
rename from plugins/quote/img/codex.png
rename to example/plugins/quote/img/codex.png
diff --git a/plugins/quote/img/upload.png b/example/plugins/quote/img/upload.png
similarity index 100%
rename from plugins/quote/img/upload.png
rename to example/plugins/quote/img/upload.png
diff --git a/plugins/quote/quote.css b/example/plugins/quote/quote.css
similarity index 100%
rename from plugins/quote/quote.css
rename to example/plugins/quote/quote.css
diff --git a/plugins/quote/quote.js b/example/plugins/quote/quote.js
similarity index 100%
rename from plugins/quote/quote.js
rename to example/plugins/quote/quote.js
diff --git a/plugins/raw/raw-icon-black.svg b/example/plugins/raw/raw-icon-black.svg
similarity index 100%
rename from plugins/raw/raw-icon-black.svg
rename to example/plugins/raw/raw-icon-black.svg
diff --git a/plugins/raw/raw-icon-white.svg b/example/plugins/raw/raw-icon-white.svg
similarity index 100%
rename from plugins/raw/raw-icon-white.svg
rename to example/plugins/raw/raw-icon-white.svg
diff --git a/plugins/raw/raw.css b/example/plugins/raw/raw.css
similarity index 100%
rename from plugins/raw/raw.css
rename to example/plugins/raw/raw.css
diff --git a/plugins/raw/raw.js b/example/plugins/raw/raw.js
similarity index 100%
rename from plugins/raw/raw.js
rename to example/plugins/raw/raw.js
diff --git a/plugins/twitter/twitter.css b/example/plugins/twitter/twitter.css
similarity index 100%
rename from plugins/twitter/twitter.css
rename to example/plugins/twitter/twitter.css
diff --git a/plugins/twitter/twitter.js b/example/plugins/twitter/twitter.js
similarity index 100%
rename from plugins/twitter/twitter.js
rename to example/plugins/twitter/twitter.js
diff --git a/fonts/codex_editor/codex-editor.eot b/fonts/codex_editor/codex-editor.eot
deleted file mode 100755
index 723ad6ab..00000000
Binary files a/fonts/codex_editor/codex-editor.eot and /dev/null differ
diff --git a/fonts/codex_editor/codex-editor.svg b/fonts/codex_editor/codex-editor.svg
deleted file mode 100755
index 1ae6cabc..00000000
--- a/fonts/codex_editor/codex-editor.svg
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/fonts/codex_editor/codex-editor.ttf b/fonts/codex_editor/codex-editor.ttf
deleted file mode 100755
index e6c70265..00000000
Binary files a/fonts/codex_editor/codex-editor.ttf and /dev/null differ
diff --git a/fonts/codex_editor/codex-editor.woff b/fonts/codex_editor/codex-editor.woff
deleted file mode 100755
index 5ad5eaa5..00000000
Binary files a/fonts/codex_editor/codex-editor.woff and /dev/null differ
diff --git a/fonts/codex_editor/codex-editor.woff2 b/fonts/codex_editor/codex-editor.woff2
deleted file mode 100755
index 15066535..00000000
Binary files a/fonts/codex_editor/codex-editor.woff2 and /dev/null differ
diff --git a/icons.css b/icons.css
deleted file mode 100644
index b8914486..00000000
--- a/icons.css
+++ /dev/null
@@ -1,63 +0,0 @@
-@font-face {
- font-family: 'codex_editor';
- src: url('fonts/codex_editor/codex-editor.eot?20895205');
- src: url('fonts/codex_editor/codex-editor.eot?20895205#iefix') format('embedded-opentype'),
- url('fonts/codex_editor/codex-editor.woff?20895205') format('woff'),
- url('fonts/codex_editor/codex-editor.ttf?20895205') format('truetype'),
- url('fonts/codex_editor/codex-editor.svg?20895205#codex_editor') format('svg');
- font-weight: normal;
- font-style: normal;
-}
-[class^="ce-icon-"]:before,
-[class*="ce-icon-"]:before {
- font-family: "codex_editor";
- font-style: normal;
- font-weight: normal;
- speak: none;
-
- display: inline-block;
- text-decoration: inherit;
- width: 1em;
- margin-right: .2em;
- text-align: center;
- font-variant: normal;
- text-transform: none;
-
- line-height: 1em;
-
- /* Animation center compensation - margins should be symmetric */
- margin-left: .2em;
-
- -moz-osx-font-smoothing: grayscale;
-}
-.ce-icon-instagram:before { content: '\e800'; } /* '' */
-.ce-icon-picture:before { content: '\e801'; } /* '' */
-.ce-icon-cog:before { content: '\e802'; } /* '' */
-.ce-icon-link:before { content: '\e803'; } /* '' */
-.ce-icon-unlink:before { content: '\e804'; } /* '' */
-.ce-icon-code:before { content: '\e805'; } /* '' */
-.ce-icon-quote:before { content: '\e806'; } /* '' */
-.ce-icon-trash:before { content: '\e807'; } /* '' */
-.ce-icon-down-big:before { content: '\e808'; } /* '' */
-.ce-icon-up-big:before { content: '\e809'; } /* '' */
-.ce-icon-header:before { content: '\e80a'; } /* '' */
-.ce-icon-paragraph:before { content: '\e80b'; } /* '' */
-.ce-icon-align-left:before { content: '\e80c'; } /* '' */
-.ce-icon-align-center:before { content: '\e80d'; } /* '' */
-.ce-icon-align-right:before { content: '\e80e'; } /* '' */
-.ce-icon-font:before { content: '\e80f'; } /* '' */
-.ce-icon-bold:before { content: '\e810'; } /* '' */
-.ce-icon-medium:before { content: '\e811'; } /* '' */
-.ce-icon-italic:before { content: '\e812'; } /* '' */
-.ce-icon-list-bullet:before { content: '\e813'; } /* '' */
-.ce-icon-list-numbered:before { content: '\e814'; } /* '' */
-.ce-icon-strike:before { content: '\e815'; } /* '' */
-.ce-icon-underline:before { content: '\e816'; } /* '' */
-.ce-icon-table:before { content: '\e817'; } /* '' */
-.ce-icon-ellipsis-vert:before { content: '\e818'; } /* '' */
-.ce-icon-columns:before { content: '\e819'; } /* '' */
-.ce-icon-smile:before { content: '\e81a'; } /* '' */
-.ce-icon-newspaper:before { content: '\e81b'; } /* '' */
-.ce-icon-twitter:before { content: '\e81c'; } /* '' */
-.ce-icon-facebook-squared:before { content: '\e81d'; } /* '' */
-.ce-icon-vkontakte:before { content: '\e81e'; } /* '' */
diff --git a/plugins/attaches/attaches.css b/plugins/attaches/attaches.css
deleted file mode 100644
index 8082a356..00000000
--- a/plugins/attaches/attaches.css
+++ /dev/null
@@ -1,130 +0,0 @@
-.cdx-attaches__default-wrapper {
- margin: 15px 0;
- padding: 15px;
- background: #fff;
- border: 1px solid #ebecec;
- box-shadow: 0 1px 2px 0 rgba(34, 36, 44, 0.03);
- border-radius: 3px;
- text-align: center;
-}
-
-.cdx-attaches__default-button {
- color: #8990aa;
- cursor: pointer;
-}
-
-.cdx-attaches__default-button:hover {
- color: #393f52;
-}
-
-.cdx-attaches__wrapper {
- display: -ms-flexbox;
- display: flex;
- -ms-flex-flow: row nowrap;
- flex-flow: row nowrap;
- -ms-flex-pack: start;
- justify-content: flex-start;
- -ms-flex-align: center;
- align-items: center;
- margin: 10px 0;
- padding: 15px 20px;
- background: #fff;
- border: 1px solid #ebecec;
- box-shadow: 0 1px 2px 0 rgba(34, 36, 44, 0.03);
- border-radius: 3px;
- font-size: 15px;
-}
-
-.cdx-attaches__file-name {
- -ms-flex-positive: 8;
- flex-grow: 8;
- width: 100%;
- outline: none;
- border: 0;
- font-size: inherit;
-}
-
-.cdx-attaches__file-name--collapsed {
- width: 30%;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.cdx-attaches__extension,
-.cdx-attaches__size {
- color: #8f9298;
- white-space: nowrap;
-}
-
-.cdx-attaches__extension::after {
- content: ',';
- margin-right: 0.2em;
-}
-
-.cdx-attaches__size::after {
- content: 'KB';
- margin-left: 0.2em;
-}
-
-.cdx-attaches__icon {
- display: inline-block;
- width: 16px;
- height: 32px;
- background: url(file-icon-black.svg) no-repeat center center;
- background-size: contain;
-}
-
-li:hover .cdx-attaches__icon,
-.selected .cdx-attaches__icon {
- background: url(file-icon-white.svg) no-repeat center center;
- background-size: contain;
-}
-
-.cdx-attaches__icon--inline {
- height: 16px;
- vertical-align: text-bottom;
-}
-
-.cdx-attaches__loader {
- background-color: transparent;
- background-image: repeating-linear-gradient(-45deg, transparent, transparent 4px, #f5f9ff 4px, #eaedef 8px) !important;
- background-size: 56px 56px;
- animation: loading-bar 5s infinite linear;
-}
-
-@keyframes loading-bar {
- 100% { background-position: -56% 0; }
-}
-
-.cdx-attaches__progress-bar {
- width: 100%;
- height: 3px;
- margin: 0 15px;
- background: #e1e3eb;
- border: 0;
- border-radius: 5px;
-}
-
-.cdx-attaches__progress-bar::-webkit-progress-bar {
- background: #e0e1e3;
- border-radius: 5px;
-}
-
-.cdx-attaches__progress-bar::-webkit-progress-value {
- background: #414957;
- border-radius: 5px;
- transition: all 100ms ease-in;
-}
-
-progress::-moz-progress-bar {
- background: #414957;
- border-radius: 5px;
-}
-
-.cdx-attaches__cross-button {
- width: 18px;
- height: 18px;
- background: url(cross.svg) no-repeat center center;
- background-size: contain;
- cursor: pointer;
-}
diff --git a/plugins/attaches/attaches.js b/plugins/attaches/attaches.js
deleted file mode 100644
index 52268411..00000000
--- a/plugins/attaches/attaches.js
+++ /dev/null
@@ -1,430 +0,0 @@
-/**
- * Attache-file Plugin for CodeX Editor
- *
- * @param {String} config.fetchUrl - Route for file uploding
- * @param {Nubmer} config.maxSize - Maximum allowed file size in KB
- * @param {String} config.accept - Accepted MIME-types. By default, accepts all
- *
- * Backend should return response with
- * 'url' - Full path to the uploaded file
- * 'title' - File title,
- * 'name' - File name without extension,
- * 'extension' - File extension,
- * 'size' - File size
- *
- * @author @gohabereg
- * @version 1.0.0
- */
-var cdxAttaches = function () {
-
- /**
- * Private methods and props
- */
-
- var KBYTE = 1024,
- fileWrapper = null;
-
- /**
- * Default config
- * Can be redefined with prepare method
- *
- * @var sting config.fetchUrl -- url to your fetch script
- * @var int config.maxSize -- max size of file in kilobytes
- * @var accept config.accept -- valid MIME-types. By default, accepts all
- *
- */
- var config = {
-
- fetchUrl: '',
- maxSize: 2,
- accept: ''
-
- };
-
- var elementsClasses = {
-
- defaultFormWrapper : 'cdx-attaches__default-wrapper',
- defaultFormButton : 'cdx-attaches__default-button',
-
- progressBar : 'cdx-attaches__progress-bar',
- wrapper : 'cdx-attaches__wrapper',
- loader : 'cdx-attaches__loader',
- crossButton : 'cdx-attaches__cross-button',
-
- file: {
- title : 'cdx-attaches__file-name',
- collapsedName : 'cdx-attaches__file-name--collapsed',
- extension : 'cdx-attaches__extension',
- size : 'cdx-attaches__size'
- }
-
- };
-
- var ui = {
-
- defaultForm: function () {
-
- var wrapper = codex.editor.draw.node('div', elementsClasses.defaultFormWrapper),
- button = codex.editor.draw.node('div', elementsClasses.defaultFormButton);
-
- button.addEventListener('click', upload.fire);
- button.innerHTML = ' Загрузить файл';
-
- wrapper.appendChild(button);
-
- return wrapper;
-
- },
-
- uploadedFile: function (data) {
-
- var wrapper = codex.editor.draw.node('div', elementsClasses.wrapper),
- name = codex.editor.draw.node('input', elementsClasses.file.title),
- extension = codex.editor.draw.node('span', elementsClasses.file.extension),
- size = codex.editor.draw.node('span', elementsClasses.file.size);
-
- wrapper.dataset.url = data.url;
- wrapper.dataset.name = data.name;
- name.value = data.title || '';
- extension.textContent = data.extension.toUpperCase();
- size.textContent = data.size;
-
- wrapper.appendChild(name);
- wrapper.appendChild(extension);
- wrapper.appendChild(size);
-
- return wrapper;
-
- },
-
- progressBar: {
-
- bar: null,
-
- draw: function () {
-
- var wrapper = codex.editor.draw.node('div', elementsClasses.wrapper),
- progress = codex.editor.draw.node('progress', elementsClasses.progressBar),
- name = codex.editor.draw.node('span', elementsClasses.file.title),
- crossButton = codex.editor.draw.node('span', elementsClasses.crossButton);
-
- progress.max = 100;
- progress.value = 0;
-
- name.textContent = codex.editor.transport.input.files[0].name;
- name.classList.add(elementsClasses.file.collapsedName);
-
- crossButton.addEventListener('click', upload.abort);
-
- ui.progressBar.bar = progress;
-
- wrapper.appendChild(name);
- wrapper.appendChild(progress);
- wrapper.appendChild(crossButton);
-
- return wrapper;
-
- },
-
- change: function (value) {
-
- console.assert( !isNaN(value), 'CodeX Editor Attaches: passed value is not a Number');
-
- ui.progressBar.bar.value = value;
-
- }
-
- }
-
- };
-
- /**
- * Notify about upload errors via codex.editor.notifications
- *
- * @param Object error can have `message` property with error message
- */
- var notifyError = function (error) {
-
- error = error || {};
-
- codex.editor.notifications.notification({
- type: 'error',
- message: 'Ошибка во время загрузки файла' + ( error.message ? ': ' + error.message : '' )
- });
-
- };
-
- /**
- * Contains validation methods
- *
- * TODO: MIME-type validation
- *
- */
- var validation = {
-
- size: function () {
-
- var file = codex.editor.transport.input.files[0];
-
- return Math.ceil(file.size / KBYTE) <= config.maxSize;
-
- },
-
- };
-
- var upload = {
-
- current: null,
-
- aborted: false,
-
- /**
- * Fired codex.editor.transport selectAndUpload methods
- */
- fire: function () {
-
- codex.editor.transport.selectAndUpload({
- url: config.fetchUrl,
- success: upload.success,
- beforeSend: upload.start,
- progress: upload.progress,
- error: upload.error,
- accept: config.accept
- });
-
- },
-
- /**
- * Will be called before upload
- * Draws load animation and progress bar
- */
- start: function () {
-
- if (!validation.size()) {
-
- notifyError({message: 'Файл слишком большой'});
- return false;
-
- }
-
- if (upload.current) {
-
- notifyError({message: 'Дождитесь окончания предыдущей загрузки'});
- return;
-
- }
-
- var progress = ui.progressBar.draw();
-
- upload.current = progress;
-
- codex.editor.content.switchBlock(fileWrapper, progress, 'attaches');
-
- },
-
- /**
- * Handler for XmlHttpRequest.upload.onprogress event
- * Changes progress bar status
- *
- * @param event
- */
- progress: function (event) {
-
- /** Prevents isNaN value assignment */
- if (!event.total) {
- return;
- }
-
- var value = parseInt(event.loaded / event.total * 100);
-
- ui.progressBar.change(value);
-
- },
-
- /**
- * Will be called after success upload
- * Try to decode JSON response and draws ui or fires error handler
- *
- * @param response
- */
- success: function (response) {
-
- var data,
- uploadedFile;
-
- try {
-
- response = JSON.parse(response);
-
- if (response.success) {
-
- data = response.data;
- data.size = Math.ceil(data.size / KBYTE) || 1;
-
- uploadedFile = ui.uploadedFile(data);
- codex.editor.content.switchBlock(upload.current, uploadedFile, 'attaches');
-
- uploadedFile.querySelector('input').focus();
-
- } else {
-
- upload.error(response);
-
- }
-
- } catch (e) {
-
- upload.error();
-
- }
-
- upload.current = null;
-
- },
-
- /**
- * Upload errors handler
- *
- * @param error
- */
- error: function (error) {
-
- var defaultFrom = ui.defaultForm();
-
- codex.editor.content.switchBlock(upload.current, defaultFrom, 'attaches');
-
- if (!upload.aborted) {
-
- notifyError(error);
-
- }
-
- upload.aborted = false;
-
- upload.current = null;
-
- },
-
- abort: function () {
-
- codex.editor.transport.abort();
-
- upload.aborted = true;
-
- upload.current = null;
-
- }
-
- };
-
-
-
- /*
- * Public methods
- * @param {String} _config.fetchUrl Required
- */
- var prepare = function (_config) {
-
- return new Promise(function(resolve, reject){
-
- if ( !_config.fetchUrl ){
-
- reject(Error('fetchUrl is missed'));
- return;
-
- }
-
- config.fetchUrl = _config.fetchUrl;
- config.accept = _config.accept || config.accept;
-
- if ( !isNaN(_config.maxSize)){
- config.maxSize = _config.maxSize;
- }
-
- resolve();
-
- });
-
- };
-
- var render = function (data) {
-
- if (!data) {
-
- fileWrapper = ui.defaultForm();
- return fileWrapper;
-
- }
-
- return ui.uploadedFile(data);
-
- };
-
- var save = function (block) {
-
- var data = {
-
- url: block.dataset.url,
- name: block.dataset.name,
- title: block.querySelector('.' + elementsClasses.file.title).value,
- extension: block.querySelector('.' + elementsClasses.file.extension).textContent,
- size: block.querySelector('.' + elementsClasses.file.size).textContent,
-
- };
-
- return data;
-
- };
-
- var validate = function (data) {
-
- if (!data.url || !data.url.trim()) {
-
- return false;
-
- }
-
- if (!data.title || !data.title.trim()) {
-
- return false;
-
- }
-
- if (!data.extension || !data.extension.trim()) {
-
- return false;
-
- }
-
- if (!data.size || !data.size.trim()) {
-
- return false;
-
- }
-
- return true;
-
- };
-
- var destroy = function () {
-
- cdxAttaches = null;
-
- };
-
- var appendCallback = function () {
-
- upload.fire();
-
- };
-
- return {
- prepare: prepare,
- render: render,
- save: save,
- validate: validate,
- destroy: destroy,
- appendCallback: appendCallback
- };
-
-}();
\ No newline at end of file
diff --git a/plugins/attaches/cross.svg b/plugins/attaches/cross.svg
deleted file mode 100644
index 1cbdeac8..00000000
--- a/plugins/attaches/cross.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
\ No newline at end of file
diff --git a/plugins/attaches/file-icon-black.svg b/plugins/attaches/file-icon-black.svg
deleted file mode 100644
index 0a559b7e..00000000
--- a/plugins/attaches/file-icon-black.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/plugins/attaches/file-icon-white.svg b/plugins/attaches/file-icon-white.svg
deleted file mode 100644
index 87a6039e..00000000
--- a/plugins/attaches/file-icon-white.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/server/index.php b/server/index.php
deleted file mode 100644
index e6286c87..00000000
--- a/server/index.php
+++ /dev/null
@@ -1,95 +0,0 @@
-loadHTML($html);
- $nodes = $doc->getElementsByTagName('title');
-
- $title = $nodes->item(0)->nodeValue;
- $description = "";
- $keywords = "";
- $image = "";
-
- $metas = $doc->getElementsByTagName('meta');
-
- for ($i = 0; $i < $metas->length; $i++)
- {
- $meta = $metas->item($i);
- if($meta->getAttribute('name') == 'description')
- $description = $meta->getAttribute('content');
- if($meta->getAttribute('name') == 'keywords')
- $keywords = $meta->getAttribute('content');
- if($meta->getAttribute('property')=='og:image'){
- $image = $meta->getAttribute('content');
- }
- }
-
- return [
- 'image' => $image,
- 'title' => $title,
- 'description' => $description
- ];
-}
-
-$url = get_url();
-
-$url_params = parse_url($url);
-
-if (!$url)
-{
- exit(0);
-}
-
-$html = file_get_contents_curl($url);
-
-$result = get_meta_from_html($html);
-
-$result = array_merge(
-
- get_meta_from_html($html),
-
- array(
- 'linkUrl' => $url,
- 'linkText' => $url_params["host"] . isset($url_params["path"])?$url_params["path"]:"",
- )
-
-);
-
-echo json_encode($result);
-
-?>
diff --git a/fonts/codex_editor/icon-hash.svg b/src/assets/icon-hash.svg
similarity index 100%
rename from fonts/codex_editor/icon-hash.svg
rename to src/assets/icon-hash.svg
diff --git a/fonts/codex_editor/icon-plus.svg b/src/assets/icon-plus.svg
similarity index 100%
rename from fonts/codex_editor/icon-plus.svg
rename to src/assets/icon-plus.svg
diff --git a/codex.js b/src/codex.js
similarity index 100%
rename from codex.js
rename to src/codex.js
diff --git a/src/styles/main.css b/src/styles/main.css
new file mode 100644
index 00000000..e69de29b