mirror of
https://github.com/codex-team/editor.js
synced 2026-03-17 08:05:47 +01:00
Merge branch 'rewriting-version2.0' into module-tools-v2
# Conflicts: # src/codex.js # src/components/modules/tools.js
This commit is contained in:
commit
2aac4b45ba
8 changed files with 564 additions and 393 deletions
|
|
@ -247,7 +247,7 @@ var CodexEditor =
|
|||
return module.prepare();
|
||||
};
|
||||
|
||||
return Promise.resolve().then(prepareDecorator(this.moduleInstances['ui'])).then(prepareDecorator(this.moduleInstances['tools'])).catch(function (error) {
|
||||
return Promise.resolve().then(prepareDecorator(this.moduleInstances.ui)).then(prepareDecorator(this.moduleInstances.tools)).catch(function (error) {
|
||||
|
||||
console.log('Error occured', error);
|
||||
});
|
||||
|
|
@ -5045,7 +5045,6 @@ var CodexEditor =
|
|||
_classCallCheck(this, Tools);
|
||||
|
||||
this.config = config;
|
||||
this.availabPlugins = {};
|
||||
this.toolInstances = [];
|
||||
|
||||
this.util = __webpack_require__(23);
|
||||
|
|
@ -5063,70 +5062,24 @@ var CodexEditor =
|
|||
|
||||
if (!this.config.hasOwnProperty('tools')) {
|
||||
|
||||
return false;
|
||||
return Promise.reject("Can't start without tools");
|
||||
}
|
||||
|
||||
var plugins = this.getListOfPrepareFunctions();
|
||||
|
||||
/**
|
||||
* Preparation Decorator
|
||||
*
|
||||
* @param toolBindedPreparationFunction
|
||||
* @return {Promise}
|
||||
*/
|
||||
function waitNextToolPreparation(toolBindedPreparationFunction) {
|
||||
return this.util.sequence(plugins, this.success, this.fallback);
|
||||
}
|
||||
}, {
|
||||
key: 'success',
|
||||
value: function success(tool) {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
console.log('Success!', tool);
|
||||
}
|
||||
}, {
|
||||
key: 'fallback',
|
||||
value: function fallback(tool) {
|
||||
|
||||
toolBindedPreparationFunction().then(resolve).catch(function (error) {
|
||||
|
||||
console.log('Plugin is not available because of ', error);
|
||||
|
||||
// anyway, go ahead even plugin is not available
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return new Promise(function (resolvePreparation, rejectPreparation) {
|
||||
|
||||
// continue editor initialization if non of tools doesn't need preparation
|
||||
if (toolPreparationList.length === 0) {
|
||||
|
||||
resolvePreparation();
|
||||
} else {
|
||||
|
||||
toolPreparationList.reduce(function (previousToolPrepared, currentToolReadyToPreparation, iteration) {
|
||||
|
||||
return previousToolPrepared.then(function () {
|
||||
return waitNextToolPreparation(currentToolReadyToPreparation);
|
||||
}).then(function () {
|
||||
|
||||
if (iteration == toolPreparationList.length - 1) {
|
||||
|
||||
resolvePreparation();
|
||||
}
|
||||
});
|
||||
}, Promise.resolve());
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* - getting class and config
|
||||
* - push to the toolinstnaces property created instances
|
||||
*/
|
||||
// for(let tool in this.config.tools) {
|
||||
// let toolClass = this.config.tools[tool],
|
||||
// toolConfig;
|
||||
//
|
||||
// if (tool in this.config.toolConfig) {
|
||||
// toolConfig = this.config.toolConfig[tool];
|
||||
// } else {
|
||||
// toolConfig = this.defaultConfig;
|
||||
// }
|
||||
//
|
||||
// this.toolInstances.push(new toolClass(toolConfig));
|
||||
// }
|
||||
console.log('Module is not available', tool);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -5258,15 +5211,6 @@ var CodexEditor =
|
|||
// */
|
||||
// return new Promise (function (allPluginsProcessed__) {
|
||||
//
|
||||
// /**
|
||||
// * pluck each element from queue
|
||||
// * First, send resolved Promise as previous value
|
||||
// * Each plugins "prepare" method returns a Promise, that's why
|
||||
// * reduce current element will not be able to continue while can't get
|
||||
// * a resolved Promise
|
||||
// *
|
||||
// * If last plugin is "prepared" then go to the next stage of initialization
|
||||
// */
|
||||
// plugins.reduce(function (previousValue, plugin, iteration) {
|
||||
//
|
||||
// return previousValue.then(function () {
|
||||
|
|
@ -5332,50 +5276,56 @@ var CodexEditor =
|
|||
|
||||
/***/ }),
|
||||
/* 22 */
|
||||
/***/ (function(module, exports) {
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
var _dom = __webpack_require__(24);
|
||||
|
||||
var _dom2 = _interopRequireDefault(_dom);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
/**
|
||||
* Module UI
|
||||
*
|
||||
* @type {UI}
|
||||
*/
|
||||
var className = {
|
||||
* Module UI
|
||||
*
|
||||
* @type {UI}
|
||||
*/
|
||||
// let className = {
|
||||
|
||||
/**
|
||||
* @const {string} BLOCK_CLASSNAME - redactor blocks name
|
||||
*/
|
||||
BLOCK_CLASSNAME: 'ce-block',
|
||||
/**
|
||||
* @const {string} BLOCK_CLASSNAME - redactor blocks name
|
||||
*/
|
||||
// BLOCK_CLASSNAME : 'ce-block',
|
||||
|
||||
/**
|
||||
* @const {String} wrapper for plugins content
|
||||
*/
|
||||
BLOCK_CONTENT: 'ce-block__content',
|
||||
/**
|
||||
* @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_STRETCHED - makes block stretched
|
||||
*/
|
||||
// BLOCK_STRETCHED : 'ce-block--stretched',
|
||||
|
||||
/**
|
||||
* @const {String} BLOCK_HIGHLIGHTED - adds background
|
||||
*/
|
||||
BLOCK_HIGHLIGHTED: 'ce-block--focused',
|
||||
/**
|
||||
* @const {String} BLOCK_HIGHLIGHTED - adds background
|
||||
*/
|
||||
// BLOCK_HIGHLIGHTED : 'ce-block--focused',
|
||||
|
||||
/**
|
||||
* @const {String} - for all default settings
|
||||
*/
|
||||
SETTINGS_ITEM: 'ce-settings__item'
|
||||
};
|
||||
/**
|
||||
* @const {String} - for all default settings
|
||||
*/
|
||||
// SETTINGS_ITEM : 'ce-settings__item'
|
||||
// };
|
||||
|
||||
var CSS_ = {
|
||||
editorWrapper: 'codex-editor',
|
||||
editorZone: 'ce-redactor'
|
||||
var CSS = {
|
||||
editorWrapper: 'codex-editor',
|
||||
editorZone: 'ce-redactor'
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -5390,103 +5340,127 @@ var CodexEditor =
|
|||
*
|
||||
* @property {EditorConfig} config - editor configuration {@link CodexEditor#configuration}
|
||||
* @property {Object} Editor - available editor modules {@link CodexEditor#moduleInstances}
|
||||
* @property {Object} nodes -
|
||||
* @property {Element} nodes.wrapper - element where we need to append redactor
|
||||
* @property {Element} nodes.wrapper - <codex-editor>
|
||||
* @property {Element} nodes.redactor - <ce-redactor>
|
||||
*/
|
||||
module.exports = function () {
|
||||
_createClass(UI, null, [{
|
||||
key: 'name',
|
||||
_createClass(UI, null, [{
|
||||
key: 'name',
|
||||
|
||||
|
||||
/**
|
||||
* Module key name
|
||||
* @returns {string}
|
||||
*/
|
||||
get: function get() {
|
||||
/**
|
||||
* Module key name
|
||||
* @returns {string}
|
||||
*/
|
||||
get: function get() {
|
||||
|
||||
return 'ui';
|
||||
}
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @param {EditorConfig} config
|
||||
*/
|
||||
|
||||
}]);
|
||||
|
||||
function UI(config) {
|
||||
_classCallCheck(this, UI);
|
||||
|
||||
this.config = config;
|
||||
this.Editor = null;
|
||||
return 'ui';
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor modules setter
|
||||
* @param {object} Editor - available editor modules
|
||||
* @constructor
|
||||
*
|
||||
* @param {EditorConfig} config
|
||||
*/
|
||||
|
||||
}]);
|
||||
|
||||
_createClass(UI, [{
|
||||
key: 'prepare',
|
||||
function UI(_ref) {
|
||||
var config = _ref.config;
|
||||
|
||||
_classCallCheck(this, UI);
|
||||
|
||||
this.config = config;
|
||||
this.Editor = null;
|
||||
|
||||
this.nodes = {
|
||||
holder: null,
|
||||
wrapper: null,
|
||||
redactor: null
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor modules setter
|
||||
* @param {object} Editor - available editor modules
|
||||
*/
|
||||
|
||||
|
||||
_createClass(UI, [{
|
||||
key: 'prepare',
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*
|
||||
* Making main interface
|
||||
*/
|
||||
value: function prepare() {
|
||||
var _this = this;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*
|
||||
* Making main interface
|
||||
* Element where we need to append CodeX Editor
|
||||
* @type {Element}
|
||||
*/
|
||||
value: function prepare() {
|
||||
_this.nodes.holder = document.getElementById(_this.config.holderId);
|
||||
|
||||
console.log('ui prepare fired');
|
||||
if (!_this.nodes.holder) {
|
||||
|
||||
return;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
var wrapper = this.modules.dom.make('DIV', [CSS_.editorWrapper], {}),
|
||||
redactor = this.modules.dom.make('DIV', [CSS_.editorZone], {}),
|
||||
toolbar = makeToolBar_();
|
||||
|
||||
wrapper.appendChild(toolbar);
|
||||
wrapper.appendChild(redactor);
|
||||
|
||||
/** Save created ui-elements to static nodes state */
|
||||
editor.nodes.wrapper = wrapper;
|
||||
editor.nodes.redactor = redactor;
|
||||
|
||||
/** Append editor wrapper with redactor zone into holder */
|
||||
editor.nodes.holder.appendChild(wrapper);
|
||||
|
||||
resolve();
|
||||
})
|
||||
|
||||
/** Add toolbox tools */
|
||||
.then(addTools_)
|
||||
|
||||
/** Make container for inline toolbar */
|
||||
.then(makeInlineToolbar_)
|
||||
|
||||
/** Add inline toolbar tools */
|
||||
.then(addInlineToolbarTools_)
|
||||
|
||||
/** Draw wrapper for notifications */
|
||||
.then(makeNotificationHolder_)
|
||||
|
||||
/** Add eventlisteners to redactor elements */
|
||||
.then(bindEvents_).catch(function () {
|
||||
|
||||
editor.core.log("Can't draw editor interface");
|
||||
});
|
||||
reject(Error("Holder wasn't found by ID: #" + _this.config.holderId));
|
||||
return;
|
||||
}
|
||||
}, {
|
||||
key: 'state',
|
||||
set: function set(Editor) {
|
||||
|
||||
this.Editor = Editor;
|
||||
}
|
||||
}]);
|
||||
/**
|
||||
* Create and save main UI elements
|
||||
*/
|
||||
_this.nodes.wrapper = _dom2.default.make('div', CSS.editorWrapper);
|
||||
_this.nodes.redactor = _dom2.default.make('div', CSS.editorZone);
|
||||
// toolbar = makeToolBar_();
|
||||
|
||||
return UI;
|
||||
// wrapper.appendChild(toolbar);
|
||||
_this.nodes.wrapper.appendChild(_this.nodes.redactor);
|
||||
/**
|
||||
* Append editor wrapper with redactor zone into holder
|
||||
*/
|
||||
_this.nodes.holder.appendChild(_this.nodes.wrapper);
|
||||
|
||||
resolve();
|
||||
})
|
||||
|
||||
/** Add toolbox tools */
|
||||
// .then(addTools_)
|
||||
|
||||
/** Make container for inline toolbar */
|
||||
// .then(makeInlineToolbar_)
|
||||
|
||||
/** Add inline toolbar tools */
|
||||
// .then(addInlineToolbarTools_)
|
||||
|
||||
/** Draw wrapper for notifications */
|
||||
// .then(makeNotificationHolder_)
|
||||
|
||||
/** Add eventlisteners to redactor elements */
|
||||
// .then(bindEvents_)
|
||||
|
||||
.catch(function () {
|
||||
|
||||
// editor.core.log("Can't draw editor interface");
|
||||
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'state',
|
||||
set: function set(Editor) {
|
||||
|
||||
this.Editor = Editor;
|
||||
}
|
||||
}]);
|
||||
|
||||
return UI;
|
||||
}();
|
||||
// /**
|
||||
// * Codex Editor UI module
|
||||
|
|
@ -5861,18 +5835,190 @@ var CodexEditor =
|
|||
* Codex Editor Util
|
||||
*/
|
||||
module.exports = function () {
|
||||
function Util() {
|
||||
_classCallCheck(this, Util);
|
||||
}
|
||||
function Util() {
|
||||
_classCallCheck(this, Util);
|
||||
}
|
||||
|
||||
_createClass(Util, null, [{
|
||||
key: "sequence",
|
||||
value: function sequence(chain, success, fallback) {}
|
||||
}]);
|
||||
_createClass(Util, null, [{
|
||||
key: "sequence",
|
||||
|
||||
return Util;
|
||||
|
||||
/**
|
||||
* Fires a promise sequence asyncronically
|
||||
*
|
||||
* @param chain
|
||||
* @param success
|
||||
* @param fallback
|
||||
* @return {Promise}
|
||||
*/
|
||||
value: function sequence(chain, success, fallback) {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
if (chain.length === 0) {
|
||||
|
||||
resolve();
|
||||
} else {
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
chain.reduce(function (previousBlock, currentBlock, iteration) {
|
||||
|
||||
return previousBlock.then(function () {
|
||||
return waitNextBlock(currentBlock, success, fallback);
|
||||
}).then(function () {
|
||||
|
||||
// finished
|
||||
if (iteration == chain.length - 1) {
|
||||
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}, Promise.resolve());
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Decorator
|
||||
*
|
||||
* @param {Function} block
|
||||
* @param {Function} success
|
||||
* @param {Function} fallback
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
function waitNextBlock(block, success, fallback) {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
block().then(function () {
|
||||
|
||||
success.call(null, block);
|
||||
}).then(resolve).catch(function (error) {
|
||||
|
||||
fallback(error);
|
||||
|
||||
// anyway, go ahead even plugin is not available
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}]);
|
||||
|
||||
return Util;
|
||||
}();
|
||||
|
||||
/***/ }),
|
||||
/* 24 */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
/**
|
||||
* DOM manupulations helper
|
||||
*/
|
||||
var Dom = function () {
|
||||
function Dom() {
|
||||
_classCallCheck(this, Dom);
|
||||
}
|
||||
|
||||
_createClass(Dom, null, [{
|
||||
key: "make",
|
||||
|
||||
|
||||
/**
|
||||
* Helper for making Elements with classname and attributes
|
||||
*
|
||||
* @param {string} tagName - new Element tag name
|
||||
* @param {array|string} classNames - list or name of CSS classname(s)
|
||||
* @param {Object} attributes - any attributes
|
||||
* @return {Element}
|
||||
*/
|
||||
value: function make(tagName, classNames, attributes) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}]);
|
||||
|
||||
return Dom;
|
||||
}();
|
||||
|
||||
exports.default = Dom;
|
||||
;
|
||||
|
||||
/***/ })
|
||||
/******/ ]);
|
||||
//# sourceMappingURL=codex-editor.js.map
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,115 +1,125 @@
|
|||
/**
|
||||
* Paragraph Plugin
|
||||
* Creates DIV tag and adds content to this tag
|
||||
*/
|
||||
* @class Paragraph
|
||||
* @classdesc Paragraph plugin for CodexEditor
|
||||
*
|
||||
* @author CodeX Team (team@ifmo.su)
|
||||
* @copyright CodeX Team 2017
|
||||
* @license The MIT License (MIT)
|
||||
* @version 2.0.0
|
||||
*
|
||||
*
|
||||
* @typedef {Object} ParagraphData
|
||||
* @property {String} text — HTML content to insert to paragraph element
|
||||
*
|
||||
*/
|
||||
|
||||
var paragraph = (function(paragraph_plugin) {
|
||||
export default class Paragraph {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* Get the name of the plugin
|
||||
*
|
||||
* Make initial paragraph block
|
||||
* @param {object} JSON with block data
|
||||
* @return {Element} element to append
|
||||
* @returns {string} The plugin name
|
||||
*/
|
||||
static get name() {
|
||||
|
||||
var make_ = function (data) {
|
||||
return 'paragraph';
|
||||
|
||||
/** Create Empty DIV */
|
||||
var tag = codex.editor.draw.node('DIV', ['ce-paragraph'], {});
|
||||
|
||||
if (data && data.text) {
|
||||
tag.innerHTML = data.text;
|
||||
}
|
||||
|
||||
tag.contentEditable = true;
|
||||
|
||||
return tag;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* Render plugin`s html and set initial content
|
||||
*
|
||||
* Handles input data for save
|
||||
* @param data
|
||||
* @param {ParagraphData} data — initial plugin content
|
||||
*/
|
||||
var prepareDataForSave_ = function(data) {
|
||||
constructor(data = {}) {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @public
|
||||
*
|
||||
* Plugins should have prepare method
|
||||
* @param config
|
||||
*/
|
||||
paragraph_plugin.prepare = function(config) {
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* @public
|
||||
*
|
||||
* Method to render HTML block from JSON
|
||||
*/
|
||||
paragraph_plugin.render = function (data) {
|
||||
|
||||
return make_(data);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @public
|
||||
*
|
||||
* Check output data for validity.
|
||||
* Should be defined by developer
|
||||
*/
|
||||
paragraph_plugin.validate = function(output) {
|
||||
|
||||
if (output.text === '')
|
||||
return;
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
/**
|
||||
* @public
|
||||
*
|
||||
* Method to extract JSON data from HTML block
|
||||
*/
|
||||
paragraph_plugin.save = function (blockContent){
|
||||
|
||||
var wrappedText = codex.editor.content.wrapTextWithParagraphs(blockContent.innerHTML),
|
||||
sanitizerConfig = {
|
||||
tags : {
|
||||
p : {},
|
||||
a: {
|
||||
href: true,
|
||||
target: '_blank',
|
||||
rel: 'nofollow'
|
||||
},
|
||||
i: {},
|
||||
b: {},
|
||||
}
|
||||
};
|
||||
|
||||
var data = {
|
||||
"text": codex.editor.sanitizer.clean(wrappedText, sanitizerConfig),
|
||||
"format": "html",
|
||||
"introText": '<<same>>'
|
||||
this._CSS = {
|
||||
wrapper: 'ce-paragraph'
|
||||
};
|
||||
|
||||
return data;
|
||||
this._data = {};
|
||||
|
||||
};
|
||||
this.data = data;
|
||||
|
||||
paragraph_plugin.destroy = function () {
|
||||
this._element = this._render();
|
||||
|
||||
paragraph = null;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
return paragraph_plugin;
|
||||
/**
|
||||
* Create div element and add needed css classes
|
||||
*
|
||||
* @returns {HTMLDivElement} Created DIV element
|
||||
* @private
|
||||
*/
|
||||
_render() {
|
||||
|
||||
})({});
|
||||
let div = document.createElement('DIV');
|
||||
|
||||
div.classList.add(this._CSS.wrapper);
|
||||
div.contentEditable = true;
|
||||
|
||||
return div;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if saved text is empty
|
||||
*
|
||||
* @param {ParagraphData} savedData — data received from plugins`s element
|
||||
* @returns {boolean} false if saved text is empty, true otherwise
|
||||
*/
|
||||
validate(savedData) {
|
||||
|
||||
if (savedData.text.trim() === '') {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plugin`s element HTMLDivElement
|
||||
*
|
||||
* @returns {HTMLDivElement} Plugin`s element
|
||||
*/
|
||||
get html() {
|
||||
|
||||
return this._element;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current plugin`s data
|
||||
*
|
||||
* @todo sanitize data while saving
|
||||
*
|
||||
* @returns {ParagraphData} Current data
|
||||
*/
|
||||
get data() {
|
||||
|
||||
let text = this._element.innerHTML;
|
||||
|
||||
this._data.text = text;
|
||||
|
||||
return this._data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new data for plugin
|
||||
*
|
||||
* @param {ParagraphData} data — data to set
|
||||
*/
|
||||
set data(data) {
|
||||
|
||||
Object.assign(this._data, data);
|
||||
|
||||
this._element.innerHTML = this._data.text || '';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -209,8 +209,9 @@ module.exports = class CodexEditor {
|
|||
let prepareDecorator = module => module.prepare();
|
||||
|
||||
return Promise.resolve()
|
||||
.then(prepareDecorator(this.moduleInstances['ui']))
|
||||
.then(prepareDecorator(this.moduleInstances['tools']))
|
||||
.then(prepareDecorator(this.moduleInstances.ui))
|
||||
.then(prepareDecorator(this.moduleInstances.tools))
|
||||
|
||||
.catch(function (error) {
|
||||
|
||||
console.log('Error occured', error);
|
||||
|
|
|
|||
|
|
@ -1,54 +1,37 @@
|
|||
module.exports = class Dom {
|
||||
/**
|
||||
* DOM manupulations helper
|
||||
*/
|
||||
export default class Dom {
|
||||
|
||||
/**
|
||||
* Module key name
|
||||
* @returns {string}
|
||||
*/
|
||||
static get name() {
|
||||
|
||||
return 'dom';
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param Editor
|
||||
* @param Editor.modules {@link Tools#list}
|
||||
* @param Editor.config {@link CodexEditor#configuration}
|
||||
* @param Editor
|
||||
*/
|
||||
set state(Editor) {
|
||||
|
||||
this.Editor = Editor;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws element with class and properties
|
||||
* Helper for making Elements with classname and attributes
|
||||
*
|
||||
* @param {String} el - Element name
|
||||
* @param {Array} classList - array of CSS classes
|
||||
* @param {Object} properties - list of objects/properties
|
||||
*
|
||||
* @returns {Element}
|
||||
* @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}
|
||||
*/
|
||||
make(el, classList, properties) {
|
||||
static make(tagName, classNames, attributes) {
|
||||
|
||||
let element = document.createElement(el);
|
||||
var el = document.createElement(tagName);
|
||||
|
||||
classList.forEach(function (className) {
|
||||
if ( Array.isArray(classNames) ) {
|
||||
|
||||
element.classList.add(className);
|
||||
el.classList.add(...classNames);
|
||||
|
||||
});
|
||||
} else if( classNames ) {
|
||||
|
||||
for(property in properties) {
|
||||
|
||||
element.property = properties[property];
|
||||
el.classList.add(classNames);
|
||||
|
||||
}
|
||||
|
||||
return element;
|
||||
for (let attrName in attributes) {
|
||||
|
||||
el[attrName] = attributes[attrName];
|
||||
|
||||
}
|
||||
|
||||
return el;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +45,7 @@ module.exports = class Dom {
|
|||
*
|
||||
* @returns {Element}
|
||||
*/
|
||||
find(el = document, selector) {
|
||||
static find(el = document, selector) {
|
||||
|
||||
return el.querySelector(selector);
|
||||
|
||||
|
|
@ -77,7 +60,7 @@ module.exports = class Dom {
|
|||
* @param {String} selector - searching string
|
||||
* @returns {NodeList}
|
||||
*/
|
||||
findAll(el = document, selector) {
|
||||
static findAll(el = document, selector) {
|
||||
|
||||
return el.querySelectorAll(selector);
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ module.exports = class Tools {
|
|||
constructor({ config }) {
|
||||
|
||||
this.config = config;
|
||||
this.availabPlugins = {};
|
||||
this.toolInstances = [];
|
||||
|
||||
this.util = require('../util');
|
||||
|
|
@ -78,83 +77,25 @@ module.exports = class Tools {
|
|||
|
||||
if (!this.config.hasOwnProperty('tools')) {
|
||||
|
||||
return false;
|
||||
return Promise.reject("Can't start without tools");
|
||||
|
||||
}
|
||||
|
||||
let plugins = this.getListOfPrepareFunctions();
|
||||
|
||||
/**
|
||||
* Preparation Decorator
|
||||
*
|
||||
* @param toolBindedPreparationFunction
|
||||
* @return {Promise}
|
||||
*/
|
||||
function waitNextToolPreparation(toolBindedPreparationFunction) {
|
||||
return this.util.sequence(plugins, this.success, this.fallback);
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
}
|
||||
|
||||
toolBindedPreparationFunction()
|
||||
success(tool) {
|
||||
|
||||
.then(resolve)
|
||||
.catch(function (error) {
|
||||
console.log('Success!', tool);
|
||||
|
||||
console.log('Plugin is not available because of ', error);
|
||||
}
|
||||
|
||||
// anyway, go ahead even plugin is not available
|
||||
resolve();
|
||||
fallback(tool) {
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return new Promise(function (resolvePreparation, rejectPreparation) {
|
||||
|
||||
// continue editor initialization if non of tools doesn't need preparation
|
||||
if (toolPreparationList.length === 0) {
|
||||
|
||||
resolvePreparation();
|
||||
|
||||
} else {
|
||||
|
||||
toolPreparationList.reduce(function (previousToolPrepared, currentToolReadyToPreparation, iteration) {
|
||||
|
||||
return previousToolPrepared
|
||||
.then(() => waitNextToolPreparation(currentToolReadyToPreparation))
|
||||
.then(() => {
|
||||
|
||||
if (iteration == toolPreparationList.length - 1) {
|
||||
|
||||
resolvePreparation();
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}, Promise.resolve());
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* - getting class and config
|
||||
* - push to the toolinstnaces property created instances
|
||||
*/
|
||||
// for(let tool in this.config.tools) {
|
||||
// let toolClass = this.config.tools[tool],
|
||||
// toolConfig;
|
||||
//
|
||||
// if (tool in this.config.toolConfig) {
|
||||
// toolConfig = this.config.toolConfig[tool];
|
||||
// } else {
|
||||
// toolConfig = this.defaultConfig;
|
||||
// }
|
||||
//
|
||||
// this.toolInstances.push(new toolClass(toolConfig));
|
||||
// }
|
||||
console.log('Module is not available', tool);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -284,15 +225,6 @@ module.exports = class Tools {
|
|||
// */
|
||||
// return new Promise (function (allPluginsProcessed__) {
|
||||
//
|
||||
// /**
|
||||
// * pluck each element from queue
|
||||
// * First, send resolved Promise as previous value
|
||||
// * Each plugins "prepare" method returns a Promise, that's why
|
||||
// * reduce current element will not be able to continue while can't get
|
||||
// * a resolved Promise
|
||||
// *
|
||||
// * If last plugin is "prepared" then go to the next stage of initialization
|
||||
// */
|
||||
// plugins.reduce(function (previousValue, plugin, iteration) {
|
||||
//
|
||||
// return previousValue.then(function () {
|
||||
|
|
|
|||
|
|
@ -1,42 +1,45 @@
|
|||
/**
|
||||
/**
|
||||
* Module UI
|
||||
*
|
||||
* @type {UI}
|
||||
*/
|
||||
let className = {
|
||||
// let className = {
|
||||
|
||||
/**
|
||||
* @const {string} BLOCK_CLASSNAME - redactor blocks name
|
||||
*/
|
||||
BLOCK_CLASSNAME : 'ce-block',
|
||||
// BLOCK_CLASSNAME : 'ce-block',
|
||||
|
||||
/**
|
||||
* @const {String} wrapper for plugins content
|
||||
*/
|
||||
BLOCK_CONTENT : 'ce-block__content',
|
||||
// BLOCK_CONTENT : 'ce-block__content',
|
||||
|
||||
/**
|
||||
* @const {String} BLOCK_STRETCHED - makes block stretched
|
||||
*/
|
||||
BLOCK_STRETCHED : 'ce-block--stretched',
|
||||
// BLOCK_STRETCHED : 'ce-block--stretched',
|
||||
|
||||
/**
|
||||
* @const {String} BLOCK_HIGHLIGHTED - adds background
|
||||
*/
|
||||
BLOCK_HIGHLIGHTED : 'ce-block--focused',
|
||||
// BLOCK_HIGHLIGHTED : 'ce-block--focused',
|
||||
|
||||
/**
|
||||
* @const {String} - for all default settings
|
||||
*/
|
||||
SETTINGS_ITEM : 'ce-settings__item'
|
||||
};
|
||||
// SETTINGS_ITEM : 'ce-settings__item'
|
||||
// };
|
||||
|
||||
let CSS_ = {
|
||||
let CSS = {
|
||||
editorWrapper : 'codex-editor',
|
||||
editorZone : 'ce-redactor'
|
||||
};
|
||||
|
||||
|
||||
import $ from '../dom';
|
||||
|
||||
|
||||
/**
|
||||
* @class
|
||||
*
|
||||
|
|
@ -49,6 +52,10 @@ let CSS_ = {
|
|||
*
|
||||
* @property {EditorConfig} config - editor configuration {@link CodexEditor#configuration}
|
||||
* @property {Object} Editor - available editor modules {@link CodexEditor#moduleInstances}
|
||||
* @property {Object} nodes -
|
||||
* @property {Element} nodes.wrapper - element where we need to append redactor
|
||||
* @property {Element} nodes.wrapper - <codex-editor>
|
||||
* @property {Element} nodes.redactor - <ce-redactor>
|
||||
*/
|
||||
module.exports = class UI {
|
||||
|
||||
|
|
@ -67,11 +74,17 @@ module.exports = class UI {
|
|||
*
|
||||
* @param {EditorConfig} config
|
||||
*/
|
||||
constructor( config ) {
|
||||
constructor({ config }) {
|
||||
|
||||
this.config = config;
|
||||
this.Editor = null;
|
||||
|
||||
this.nodes = {
|
||||
holder: null,
|
||||
wrapper: null,
|
||||
redactor: null
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -92,48 +105,57 @@ module.exports = class UI {
|
|||
*/
|
||||
prepare() {
|
||||
|
||||
console.log('ui prepare fired');
|
||||
return new Promise( (resolve, reject) => {
|
||||
|
||||
return;
|
||||
/**
|
||||
* Element where we need to append CodeX Editor
|
||||
* @type {Element}
|
||||
*/
|
||||
this.nodes.holder = document.getElementById(this.config.holderId);
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (!this.nodes.holder) {
|
||||
|
||||
let wrapper = this.modules.dom.make('DIV', [ CSS_.editorWrapper ], {}),
|
||||
redactor = this.modules.dom.make('DIV', [ CSS_.editorZone ], {}),
|
||||
toolbar = makeToolBar_();
|
||||
reject(Error("Holder wasn't found by ID: #" + this.config.holderId));
|
||||
return;
|
||||
|
||||
wrapper.appendChild(toolbar);
|
||||
wrapper.appendChild(redactor);
|
||||
}
|
||||
|
||||
/** Save created ui-elements to static nodes state */
|
||||
editor.nodes.wrapper = wrapper;
|
||||
editor.nodes.redactor = redactor;
|
||||
/**
|
||||
* Create and save main UI elements
|
||||
*/
|
||||
this.nodes.wrapper = $.make('div', CSS.editorWrapper);
|
||||
this.nodes.redactor = $.make('div', CSS.editorZone);
|
||||
// toolbar = makeToolBar_();
|
||||
|
||||
/** Append editor wrapper with redactor zone into holder */
|
||||
editor.nodes.holder.appendChild(wrapper);
|
||||
// wrapper.appendChild(toolbar);
|
||||
this.nodes.wrapper.appendChild(this.nodes.redactor);
|
||||
/**
|
||||
* Append editor wrapper with redactor zone into holder
|
||||
*/
|
||||
this.nodes.holder.appendChild(this.nodes.wrapper);
|
||||
|
||||
resolve();
|
||||
|
||||
})
|
||||
|
||||
/** Add toolbox tools */
|
||||
.then(addTools_)
|
||||
// .then(addTools_)
|
||||
|
||||
/** Make container for inline toolbar */
|
||||
.then(makeInlineToolbar_)
|
||||
// .then(makeInlineToolbar_)
|
||||
|
||||
/** Add inline toolbar tools */
|
||||
.then(addInlineToolbarTools_)
|
||||
// .then(addInlineToolbarTools_)
|
||||
|
||||
/** Draw wrapper for notifications */
|
||||
.then(makeNotificationHolder_)
|
||||
// .then(makeNotificationHolder_)
|
||||
|
||||
/** Add eventlisteners to redactor elements */
|
||||
.then(bindEvents_)
|
||||
// .then(bindEvents_)
|
||||
|
||||
.catch( function () {
|
||||
|
||||
editor.core.log("Can't draw editor interface");
|
||||
// editor.core.log("Can't draw editor interface");
|
||||
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,85 @@
|
|||
*/
|
||||
module.exports = class Util {
|
||||
|
||||
/**
|
||||
* Fires a promise sequence asyncronically
|
||||
*
|
||||
* @param chain
|
||||
* @param success
|
||||
* @param fallback
|
||||
* @return {Promise}
|
||||
*/
|
||||
static sequence(chain, success, fallback) {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
if (chain.length === 0) {
|
||||
|
||||
resolve();
|
||||
|
||||
} else {
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
chain.reduce(function (previousBlock, currentBlock, iteration) {
|
||||
|
||||
return previousBlock
|
||||
.then(() => waitNextBlock(currentBlock, success, fallback))
|
||||
.then(() => {
|
||||
|
||||
// finished
|
||||
if (iteration == chain.length - 1) {
|
||||
|
||||
resolve();
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}, Promise.resolve());
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Decorator
|
||||
*
|
||||
* @param {Function} block
|
||||
* @param {Function} success
|
||||
* @param {Function} fallback
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
function waitNextBlock(block, success, fallback) {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
block()
|
||||
.then(() => {
|
||||
|
||||
success.call(null, block);
|
||||
|
||||
})
|
||||
.then(resolve)
|
||||
.catch(function (error) {
|
||||
|
||||
fallback(error);
|
||||
|
||||
// anyway, go ahead even plugin is not available
|
||||
resolve();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue