editor.js/modules/saver.js
2017-08-30 05:22:35 +03:00

166 lines
3.6 KiB
JavaScript

/**
* Codex Editor Saver
*
* @author Codex Team
* @version 1.1.0
*/
module.exports = (function (saver) {
let editor = codex.editor;
/**
* @public
* Save blocks
*/
saver.save = function () {
/** Save html content of redactor to memory */
editor.state.html = editor.nodes.redactor.innerHTML;
/** Clean jsonOutput state */
editor.state.jsonOutput = [];
return saveBlocks(editor.nodes.redactor.childNodes);
};
/**
* @private
* Save each block data
*
* @param blocks
* @returns {Promise.<TResult>}
*/
let saveBlocks = function (blocks) {
let data = [];
for(let index = 0; index < blocks.length; index++) {
data.push(getBlockData(blocks[index]));
}
return Promise.all(data)
.then(makeOutput)
.catch(editor.core.log);
};
/** Save and validate block data */
let getBlockData = function (block) {
return saveBlockData(block)
.then(validateBlockData)
.catch(editor.core.log);
};
/**
* @private
* Call block`s plugin save method and return saved data
*
* @param block
* @returns {Object}
*/
let saveBlockData = function (block) {
let pluginName = block.dataset.tool;
/** Check for plugin existence */
if (!editor.tools[pluginName]) {
editor.core.log(`Plugin «${pluginName}» not found`, 'error');
return {data: null, pluginName: null};
}
/** Check for plugin having save method */
if (typeof editor.tools[pluginName].save !== 'function') {
editor.core.log(`Plugin «${pluginName}» must have save method`, 'error');
return {data: null, pluginName: null};
}
/** Result saver */
let blockContent = block.childNodes[0],
pluginsContent = blockContent.childNodes[0],
position = pluginsContent.dataset.inputPosition;
/** If plugin wasn't available then return data from cache */
if ( editor.tools[pluginName].available === false ) {
return Promise.resolve({data: codex.editor.state.blocks.items[position].data, pluginName});
}
return Promise.resolve(pluginsContent)
.then(editor.tools[pluginName].save)
.then(data => Object({data, pluginName}));
};
/**
* Call plugin`s validate method. Return false if validation failed
*
* @param data
* @param pluginName
* @returns {Object|Boolean}
*/
let validateBlockData = function ({data, pluginName}) {
if (!data || !pluginName) {
return false;
}
if (editor.tools[pluginName].validate) {
let result = editor.tools[pluginName].validate(data);
/**
* Do not allow invalid data
*/
if (!result) {
return false;
}
}
return {data, pluginName};
};
/**
* Compile article output
*
* @param savedData
* @returns {{time: number, version, items: (*|Array)}}
*/
let makeOutput = function (savedData) {
savedData = savedData.filter(blockData => blockData);
let items = savedData.map(blockData => Object({type: blockData.pluginName, data: blockData.data}));
editor.state.jsonOutput = items;
return {
id: editor.state.blocks.id || null,
time: +new Date(),
version: editor.version,
items
};
};
return saver;
})({});