Refactoring (#144)

* codex -> codex.editor

* ESlint code style

* Code lint

* fix inline module 'this' call

* fixed toolbox leaf

* removed empty spaces

* caret module code improved
This commit is contained in:
Peter Savchenko 2017-02-01 20:25:59 +03:00 committed by GitHub
parent 70df6b20b0
commit e71a12401a
37 changed files with 1437 additions and 6386 deletions

114
.eslintrc
View file

@ -1,49 +1,75 @@
{
"rules": {
/** Enable ES6 features */
"parserOptions": {
"ecmaVersion": 6,
},
"rules": {
"arrow-spacing": [2, { "before": true, "after": true }],
"arrow-spacing": [2, {
"before": true,
"after": true
}],
/** Variables */
"no-catch-shadow": 2,
"no-delete-var": 2,
"no-label-var": 2,
"no-shadow-restricted-names": 2,
"no-shadow": 2,
"no-undef-init": 2,
"no-undef": 2,
"no-unused-vars": 2,
/** Variables */
"no-catch-shadow": 2,
"no-delete-var": 2,
"no-label-var": 2,
"no-shadow-restricted-names": 2,
"no-shadow": 2,
"no-undef-init": 2,
"no-undef": 2,
"no-unused-vars": 1,
/** Style */
"array-bracket-spacing": [2, "never", {
"singleValue": true,
"objectsInArrays": true,
"arraysInArrays": true
}],
"quotes": [2, "single", "avoid-escape"],
"eqeqeq": 0,
"brace-style": [2, "stroustrup"],
"comma-spacing": [2, { "before": false, "after": true }],
"comma-style": [2, "last"],
"eol-last": 0,
"no-nested-ternary": 1,
"no-trailing-spaces": 2,
"no-mixed-spaces-and-tabs": 2,
"padded-blocks": [2, "never"],
"space-before-blocks": 2,
"space-before-function-paren": [2, { "anonymous": "always", "named": "never" }],
"spaced-comment": [2, "always", {
"exceptions": ["-", "+"],
"markers": ["=", "!"]
}],
"semi": [2, "always"],
"indent": [2, 4, { "SwitchCase": 1 }],
"camelcase": [2, { "properties": "always" }],
"newline-after-var": [1, "always"]
},
"globals":{
"document": true,
"require": true,
"module": true,
"codex": true
}
/** Style */
"array-bracket-spacing": [2, "never", {
"singleValue": true,
"objectsInArrays": true,
"arraysInArrays": true
}],
"quotes": [2, "single", "avoid-escape"],
"eqeqeq": 0,
"brace-style": [2, "1tbs"],
"comma-spacing": [2, {
"before": false,
"after": true
}],
"comma-style": [2, "last"],
"eol-last": 0,
"no-nested-ternary": 1,
"no-trailing-spaces": 2,
"no-mixed-spaces-and-tabs": 2,
"padded-blocks": [2, "always"],
"space-before-blocks": 2,
"space-before-function-paren": [2, {
"anonymous": "always",
"named": "never"
}],
"spaced-comment": [2, "always", {
"exceptions": ["-", "+"],
"markers": ["=", "!"]
}],
"semi": [2, "always"],
"indent": [2, 4, {
"SwitchCase": 1
}],
"camelcase": [2, {
"properties": "always"
}],
"newline-after-var": [1, "always"],
},
"globals":{
"document": true,
"module": true,
"require": true,
"window": true,
"codex": true,
"VERSION" : true,
"Promise" : true,
"MutationObserver": true,
"FormData": true,
"XMLHttpRequest": true,
"ActiveXObject": true
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -3,43 +3,44 @@
* Codex Editor
*
* @author Codex Team
* @version 1.3.0
*/
var codex = (function(codex){
module.exports = (function (editor) {
var init = function() {
'use strict';
editor.version = VERSION;
var init = function () {
editor.core = require('./modules/core');
editor.ui = require('./modules/ui');
editor.transport = require('./modules/transport');
editor.renderer = require('./modules/renderer');
editor.saver = require('./modules/saver');
editor.content = require('./modules/content');
editor.toolbar = require('./modules/toolbar/toolbar');
editor.callback = require('./modules/callbacks');
editor.draw = require('./modules/draw');
editor.caret = require('./modules/caret');
editor.notifications = require('./modules/notifications');
editor.parser = require('./modules/parser');
editor.sanitizer = require('./modules/sanitizer');
codex.core = require('./modules/core');
codex.ui = require('./modules/ui');
codex.transport = require('./modules/transport');
codex.renderer = require('./modules/renderer');
codex.saver = require('./modules/saver');
codex.content = require('./modules/content');
codex.toolbar = require('./modules/toolbar/toolbar');
codex.tools = require('./modules/tools');
codex.callback = require('./modules/callbacks');
codex.draw = require('./modules/draw');
codex.caret = require('./modules/caret');
codex.notifications = require('./modules/notifications');
codex.parser = require('./modules/parser');
codex.sanitizer = require('./modules/sanitizer');
};
codex.version = VERSION;
/**
* @public
*
* holds initial settings
*/
codex.settings = {
editor.settings = {
tools : ['paragraph', 'header', 'picture', 'list', 'quote', 'code', 'twitter', 'instagram', 'smile'],
textareaId: 'codex-editor',
uploadImagesUrl: '/editor/transport/',
// Type of block showing on empty editor
initialBlockPlugin: "paragraph"
initialBlockPlugin: 'paragraph'
};
/**
@ -47,7 +48,7 @@ var codex = (function(codex){
*
* Static nodes
*/
codex.nodes = {
editor.nodes = {
textarea : null,
wrapper : null,
toolbar : null,
@ -73,12 +74,18 @@ var codex = (function(codex){
*
* Output state
*/
codex.state = {
editor.state = {
jsonOutput: [],
blocks : [],
inputs : []
};
/**
* @public
* Editor plugins
*/
editor.tools = {};
/**
* Initialization
* @uses Promise cEditor.core.prepare
@ -110,31 +117,28 @@ var codex = (function(codex){
* - displayInToolbox : true,
* - enableLineBreaks : false
*/
codex.start = function (userSettings) {
editor.start = function (userSettings) {
init();
this.core.prepare(userSettings)
editor.core.prepare(userSettings)
// If all ok, make UI, bind events and parse initial-content
.then(this.ui.make)
.then(this.ui.addTools)
.then(this.ui.bindEvents)
.then(this.ui.preparePlugins)
.then(this.transport.prepare)
.then(this.renderer.makeBlocksFromData)
.then(this.ui.saveInputs)
.then(editor.ui.make)
.then(editor.ui.addTools)
.then(editor.ui.bindEvents)
.then(editor.ui.preparePlugins)
.then(editor.transport.prepare)
.then(editor.renderer.makeBlocksFromData)
.then(editor.ui.saveInputs)
.catch(function (error) {
codex.core.log('Initialization failed with error: %o', 'warn', error);
editor.core.log('Initialization failed with error: %o', 'warn', error);
});
};
return codex;
})({});
module.exports = codex;
return editor;
})({});

View file

@ -49,7 +49,7 @@
<link rel="stylesheet" href="plugins/paste/paste.css">
<script>
codex.start({
codex.editor.start({
textareaId : "codex_area",
initialBlockPlugin : 'paragraph',
tools : {

View file

@ -1,8 +0,0 @@
/**
*
*/
'use strict';
var editor = require('./editor');
module.exports = editor;

File diff suppressed because it is too large Load diff

View file

@ -4,8 +4,9 @@
* @author Codex Team
* @version 1.0
*/
let editor = codex.editor;
var caret = (function(caret) {
module.exports = (function (caret) {
/**
* @var {int} InputIndex - editable element in DOM
@ -28,10 +29,10 @@ var caret = (function(caret) {
* @uses caret.save if you need to save caret position
* @param {Element} el - Changed Node.
*/
caret.set = function( el , index, offset) {
caret.set = function ( el, index, offset) {
offset = offset || this.offset || 0;
index = index || this.focusedNodeIndex || 0;
offset = offset || caret.offset || 0;
index = index || caret.focusedNodeIndex || 0;
var childs = el.childNodes,
nodeToSet;
@ -48,19 +49,22 @@ var caret = (function(caret) {
/** If Element is INPUT */
if (el.tagName == 'INPUT') {
el.focus();
return;
}
if (codex.core.isDomNode(nodeToSet)) {
if (editor.core.isDomNode(nodeToSet)) {
nodeToSet = editor.content.getDeepestTextNodeFromPosition(nodeToSet, nodeToSet.childNodes.length);
nodeToSet = codex.content.getDeepestTextNodeFromPosition(nodeToSet, nodeToSet.childNodes.length);
}
var range = document.createRange(),
selection = window.getSelection();
setTimeout(function() {
window.setTimeout(function () {
range.setStart(nodeToSet, offset);
range.setEnd(nodeToSet, offset);
@ -68,9 +72,10 @@ var caret = (function(caret) {
selection.removeAllRanges();
selection.addRange(range);
codex.caret.saveCurrentInputIndex();
editor.caret.saveCurrentInputIndex();
}, 20);
};
/**
@ -81,48 +86,59 @@ var caret = (function(caret) {
/** Index of Input that we paste sanitized content */
var selection = window.getSelection(),
inputs = codex.state.inputs,
inputs = editor.state.inputs,
focusedNode = selection.anchorNode,
focusedNodeHolder;
if (!focusedNode){
if (!focusedNode) {
return;
}
/** Looking for parent contentEditable block */
while (focusedNode.contentEditable != 'true') {
focusedNodeHolder = focusedNode.parentNode;
focusedNode = focusedNodeHolder;
}
/** Input index in DOM level */
var editableElementIndex = 0;
while (focusedNode != inputs[editableElementIndex]) {
editableElementIndex ++;
}
this.inputIndex = editableElementIndex;
caret.inputIndex = editableElementIndex;
};
/**
* Returns current input index (caret object)
*/
caret.getCurrentInputIndex = function() {
return this.inputIndex;
caret.getCurrentInputIndex = function () {
return caret.inputIndex;
};
/**
* @param {int} index - index of first-level block after that we set caret into next input
*/
caret.setToNextBlock = function(index) {
caret.setToNextBlock = function (index) {
var inputs = codex.state.inputs,
var inputs = editor.state.inputs,
nextInput = inputs[index + 1];
if (!nextInput) {
codex.core.log('We are reached the end');
editor.core.log('We are reached the end');
return;
}
/**
@ -130,13 +146,16 @@ var caret = (function(caret) {
* We should add some text node to set caret
*/
if (!nextInput.childNodes.length) {
var emptyTextElement = document.createTextNode('');
nextInput.appendChild(emptyTextElement);
}
codex.caret.inputIndex = index + 1;
codex.caret.set(nextInput, 0, 0);
codex.content.workingNodeChanged(nextInput);
editor.caret.inputIndex = index + 1;
editor.caret.set(nextInput, 0, 0);
editor.content.workingNodeChanged(nextInput);
};
@ -144,15 +163,15 @@ var caret = (function(caret) {
* @param {int} index - index of target input.
* Sets caret to input with this index
*/
caret.setToBlock = function(index) {
caret.setToBlock = function (index) {
var inputs = codex.state.inputs,
var inputs = editor.state.inputs,
targetInput = inputs[index];
console.assert( targetInput , 'caret.setToBlock: target input does not exists');
if ( !targetInput ) {
return;
}
/**
@ -160,24 +179,27 @@ var caret = (function(caret) {
* We should add some text node to set caret
*/
if (!targetInput.childNodes.length) {
var emptyTextElement = document.createTextNode('');
targetInput.appendChild(emptyTextElement);
}
codex.caret.inputIndex = index;
codex.caret.set(targetInput, 0, 0);
codex.content.workingNodeChanged(targetInput);
editor.caret.inputIndex = index;
editor.caret.set(targetInput, 0, 0);
editor.content.workingNodeChanged(targetInput);
};
/**
* @param {int} index - index of input
*/
caret.setToPreviousBlock = function(index) {
caret.setToPreviousBlock = function (index) {
index = index || 0;
var inputs = codex.state.inputs,
var inputs = editor.state.inputs,
previousInput = inputs[index - 1],
lastChildNode,
lengthOfLastChildNode,
@ -185,11 +207,13 @@ var caret = (function(caret) {
if (!previousInput) {
codex.core.log('We are reached first node');
editor.core.log('We are reached first node');
return;
}
lastChildNode = codex.content.getDeepestTextNodeFromPosition(previousInput, previousInput.childNodes.length);
lastChildNode = editor.content.getDeepestTextNodeFromPosition(previousInput, previousInput.childNodes.length);
lengthOfLastChildNode = lastChildNode.length;
/**
@ -200,24 +224,28 @@ var caret = (function(caret) {
emptyTextElement = document.createTextNode('');
previousInput.appendChild(emptyTextElement);
}
codex.caret.inputIndex = index - 1;
codex.caret.set(previousInput, previousInput.childNodes.length - 1, lengthOfLastChildNode);
codex.content.workingNodeChanged(inputs[index - 1]);
editor.caret.inputIndex = index - 1;
editor.caret.set(previousInput, previousInput.childNodes.length - 1, lengthOfLastChildNode);
editor.content.workingNodeChanged(inputs[index - 1]);
};
caret.position = {
atStart : function() {
atStart : function () {
var selection = window.getSelection(),
anchorOffset = selection.anchorOffset,
anchorNode = selection.anchorNode,
firstLevelBlock = codex.content.getFirstLevelBlock(anchorNode),
firstLevelBlock = editor.content.getFirstLevelBlock(anchorNode),
pluginsRender = firstLevelBlock.childNodes[0];
if (!codex.core.isDomNode(anchorNode)) {
if (!editor.core.isDomNode(anchorNode)) {
anchorNode = anchorNode.parentNode;
}
var isFirstNode = anchorNode === pluginsRender.childNodes[0],
@ -227,7 +255,7 @@ var caret = (function(caret) {
},
atTheEnd : function() {
atTheEnd : function () {
var selection = window.getSelection(),
anchorOffset = selection.anchorOffset,
@ -235,11 +263,10 @@ var caret = (function(caret) {
/** Caret is at the end of input */
return !anchorNode || !anchorNode.length || anchorOffset === anchorNode.length;
}
};
return caret;
})({});
module.exports = caret;
})({});

View file

@ -5,8 +5,9 @@
* @author Codex Team
* @version 1.3.11
*/
let editor = codex.editor;
var content = (function(content) {
module.exports = (function (content) {
/**
* Links to current active block
@ -25,47 +26,58 @@ var content = (function(content) {
*/
content.sync = function () {
codex.core.log('syncing...');
editor.core.log('syncing...');
/**
* Save redactor content to codex.state
* Save redactor content to editor.state
*/
codex.state.html = codex.nodes.redactor.innerHTML;
editor.state.html = editor.nodes.redactor.innerHTML;
};
/**
* @deprecated
*/
content.getNodeFocused = function() {
content.getNodeFocused = function () {
var selection = window.getSelection(),
focused;
if (selection.anchorNode === null) {
return null;
}
if ( selection.anchorNode.nodeType == codex.core.nodeTypes.TAG ) {
if ( selection.anchorNode.nodeType == editor.core.nodeTypes.TAG ) {
focused = selection.anchorNode;
} else {
focused = selection.focusNode.parentElement;
}
if ( !codex.parser.isFirstLevelBlock(focused) ) {
if ( !editor.parser.isFirstLevelBlock(focused) ) {
/** Iterate with parent nodes to find first-level*/
var parent = focused.parentNode;
while (parent && !codex.parser.isFirstLevelBlock(parent)){
while (parent && !editor.parser.isFirstLevelBlock(parent)) {
parent = parent.parentNode;
}
focused = parent;
}
if (focused != codex.nodes.redactor){
if (focused != editor.nodes.redactor) {
return focused;
}
return null;
@ -75,18 +87,21 @@ var content = (function(content) {
/**
* Appends background to the block
*/
content.markBlock = function() {
content.markBlock = function () {
editor.content.currentNode.classList.add(editor.ui.className.BLOCK_HIGHLIGHTED);
codex.content.currentNode.classList.add(codex.ui.className.BLOCK_HIGHLIGHTED);
};
/**
* Clear background
*/
content.clearMark = function() {
content.clearMark = function () {
if (editor.content.currentNode) {
editor.content.currentNode.classList.remove(editor.ui.className.BLOCK_HIGHLIGHTED);
if (codex.content.currentNode) {
codex.content.currentNode.classList.remove(codex.ui.className.BLOCK_HIGHLIGHTED);
}
};
@ -97,23 +112,28 @@ var content = (function(content) {
* Finds first-level block
* @param {Element} node - selected or clicked in redactors area node
*/
content.getFirstLevelBlock = function(node) {
content.getFirstLevelBlock = function (node) {
if (!editor.core.isDomNode(node)) {
if (!codex.core.isDomNode(node)) {
node = node.parentNode;
}
if (node === codex.nodes.redactor || node === document.body) {
if (node === editor.nodes.redactor || node === document.body) {
return null;
} else {
while(!node.classList.contains(codex.ui.className.BLOCK_CLASSNAME)) {
while(!node.classList.contains(editor.ui.className.BLOCK_CLASSNAME)) {
node = node.parentNode;
}
return node;
}
};
@ -126,10 +146,12 @@ var content = (function(content) {
content.workingNodeChanged = function (targetNode) {
/** Clear background from previous marked block before we change */
codex.content.clearMark();
editor.content.clearMark();
if (!targetNode) {
return;
}
this.currentNode = this.getFirstLevelBlock(targetNode);
@ -146,43 +168,49 @@ var content = (function(content) {
* [!] Function does not saves old block content.
* You can get it manually and pass with newBlock.innerHTML
*/
content.replaceBlock = function function_name(targetBlock, newBlock) {
content.replaceBlock = function (targetBlock, newBlock) {
if (!targetBlock || !newBlock){
codex.core.log('replaceBlock: missed params');
if (!targetBlock || !newBlock) {
editor.core.log('replaceBlock: missed params');
return;
}
/** If target-block is not a frist-level block, then we iterate parents to find it */
while(!targetBlock.classList.contains(codex.ui.className.BLOCK_CLASSNAME)) {
while(!targetBlock.classList.contains(editor.ui.className.BLOCK_CLASSNAME)) {
targetBlock = targetBlock.parentNode;
}
/**
* Check is this block was in feed
* If true, than set switched block also covered
*/
if (targetBlock.classList.contains(codex.ui.className.BLOCK_IN_FEED_MODE)) {
newBlock.classList.add(codex.ui.className.BLOCK_IN_FEED_MODE);
if (targetBlock.classList.contains(editor.ui.className.BLOCK_IN_FEED_MODE)) {
newBlock.classList.add(editor.ui.className.BLOCK_IN_FEED_MODE);
}
/** Replacing */
codex.nodes.redactor.replaceChild(newBlock, targetBlock);
editor.nodes.redactor.replaceChild(newBlock, targetBlock);
/**
* Set new node as current
*/
codex.content.workingNodeChanged(newBlock);
editor.content.workingNodeChanged(newBlock);
/**
* Add block handlers
*/
codex.ui.addBlockHandlers(newBlock);
editor.ui.addBlockHandlers(newBlock);
/**
* Save changes
*/
codex.ui.saveInputs();
editor.ui.saveInputs();
};
@ -198,46 +226,49 @@ var content = (function(content) {
* @param needPlaceCaret {bool} pass true to set caret in new block
*
*/
content.insertBlock = function( blockData, needPlaceCaret ) {
content.insertBlock = function ( blockData, needPlaceCaret ) {
var workingBlock = codex.content.currentNode,
var workingBlock = editor.content.currentNode,
newBlockContent = blockData.block,
blockType = blockData.type,
cover = blockData.cover,
isStretched = blockData.stretched;
var newBlock = codex.content.composeNewBlock(newBlockContent, blockType, isStretched);
var newBlock = editor.content.composeNewBlock(newBlockContent, blockType, isStretched);
if (cover === true) {
newBlock.classList.add(codex.ui.className.BLOCK_IN_FEED_MODE);
newBlock.classList.add(editor.ui.className.BLOCK_IN_FEED_MODE);
}
if (workingBlock) {
codex.core.insertAfter(workingBlock, newBlock);
editor.core.insertAfter(workingBlock, newBlock);
} else {
/**
* If redactor is empty, append as first child
*/
codex.nodes.redactor.appendChild(newBlock);
editor.nodes.redactor.appendChild(newBlock);
}
/**
* Block handler
*/
codex.ui.addBlockHandlers(newBlock);
editor.ui.addBlockHandlers(newBlock);
/**
* Set new node as current
*/
codex.content.workingNodeChanged(newBlock);
editor.content.workingNodeChanged(newBlock);
/**
* Save changes
*/
codex.ui.saveInputs();
editor.ui.saveInputs();
if ( needPlaceCaret ) {
@ -245,7 +276,7 @@ var content = (function(content) {
/**
* If we don't know input index then we set default value -1
*/
var currentInputIndex = codex.caret.getCurrentInputIndex() || -1;
var currentInputIndex = editor.caret.getCurrentInputIndex() || -1;
if (currentInputIndex == -1) {
@ -255,24 +286,24 @@ var content = (function(content) {
emptyText = document.createTextNode('');
editableElement.appendChild(emptyText);
codex.caret.set(editableElement, 0, 0);
editor.caret.set(editableElement, 0, 0);
codex.toolbar.move();
codex.toolbar.showPlusButton();
editor.toolbar.move();
editor.toolbar.showPlusButton();
} else {
if (currentInputIndex === codex.state.inputs.length - 1)
if (currentInputIndex === editor.state.inputs.length - 1)
return;
/** Timeout for browsers execution */
setTimeout(function () {
window.setTimeout(function () {
/** Setting to the new input */
codex.caret.setToNextBlock(currentInputIndex);
codex.toolbar.move();
codex.toolbar.open();
editor.caret.setToNextBlock(currentInputIndex);
editor.toolbar.move();
editor.toolbar.open();
}, 10);
@ -295,15 +326,16 @@ var content = (function(content) {
* @param {Element} newNode
* @param {Element} blockType
*/
content.switchBlock = function(blockToReplace, newBlock, tool){
content.switchBlock = function (blockToReplace, newBlock, tool) {
var newBlockComposed = codex.content.composeNewBlock(newBlock, tool);
var newBlockComposed = editor.content.composeNewBlock(newBlock, tool);
/** Replacing */
codex.content.replaceBlock(blockToReplace, newBlockComposed);
editor.content.replaceBlock(blockToReplace, newBlockComposed);
/** Save new Inputs when block is changed */
codex.ui.saveInputs();
editor.ui.saveInputs();
};
/**
@ -327,11 +359,11 @@ var content = (function(content) {
node,
text;
for(index = 0; index < blockChilds.length; index++)
{
for(index = 0; index < blockChilds.length; index++) {
node = blockChilds[index];
if (node.nodeType == codex.core.nodeTypes.TEXT) {
if (node.nodeType == editor.core.nodeTypes.TEXT) {
text = node.textContent.trim();
@ -342,47 +374,60 @@ var content = (function(content) {
block.removeChild(node);
position--;
}
}
}
if (block.childNodes.length === 0) {
return document.createTextNode('');
}
/** Setting default position when we deleted all empty nodes */
if ( position < 0 )
position = 1;
var looking_from_start = false;
var lookingFromStart = false;
/** For looking from START */
if (position === 0) {
looking_from_start = true;
lookingFromStart = true;
position = 1;
}
while ( position ) {
/** initial verticle of node. */
if ( looking_from_start ) {
if ( lookingFromStart ) {
block = block.childNodes[0];
} else {
block = block.childNodes[position - 1];
}
if ( block.nodeType == codex.core.nodeTypes.TAG ){
if ( block.nodeType == editor.core.nodeTypes.TAG ) {
position = block.childNodes.length;
} else if (block.nodeType == codex.core.nodeTypes.TEXT ){
} else if (block.nodeType == editor.core.nodeTypes.TEXT ) {
position = 0;
}
}
return block;
};
/**
@ -390,28 +435,32 @@ var content = (function(content) {
*/
content.composeNewBlock = function (block, tool, isStretched) {
var newBlock = codex.draw.node('DIV', codex.ui.className.BLOCK_CLASSNAME, {}),
blockContent = codex.draw.node('DIV', codex.ui.className.BLOCK_CONTENT, {});
var newBlock = editor.draw.node('DIV', editor.ui.className.BLOCK_CLASSNAME, {}),
blockContent = editor.draw.node('DIV', editor.ui.className.BLOCK_CONTENT, {});
blockContent.appendChild(block);
newBlock.appendChild(blockContent);
if (isStretched) {
blockContent.classList.add(codex.ui.className.BLOCK_STRETCHED);
blockContent.classList.add(editor.ui.className.BLOCK_STRETCHED);
}
newBlock.dataset.tool = tool;
return newBlock;
};
/**
* Returns Range object of current selection
*/
content.getRange = function() {
content.getRange = function () {
var selection = window.getSelection().getRangeAt(0);
return selection;
};
/**
@ -419,7 +468,7 @@ var content = (function(content) {
* @private
* @param {Int} inputIndex - target input index
*/
content.splitBlock = function(inputIndex) {
content.splitBlock = function (inputIndex) {
var selection = window.getSelection(),
anchorNode = selection.anchorNode,
@ -430,7 +479,7 @@ var content = (function(content) {
textAfterCaret,
textNodeAfterCaret;
var currentBlock = codex.content.currentNode.querySelector('[contentEditable]');
var currentBlock = editor.content.currentNode.querySelector('[contentEditable]');
textBeforeCaret = anchorNodeText.substring(0, caretOffset);
@ -439,7 +488,9 @@ var content = (function(content) {
textNodeBeforeCaret = document.createTextNode(textBeforeCaret);
if (textAfterCaret) {
textNodeAfterCaret = document.createTextNode(textAfterCaret);
}
var previousChilds = [],
@ -447,25 +498,35 @@ var content = (function(content) {
reachedCurrent = false;
if (textNodeAfterCaret) {
nextChilds.push(textNodeAfterCaret);
}
for ( var i = 0, child; !!(child = currentBlock.childNodes[i]); i++) {
if ( child != anchorNode ) {
if ( !reachedCurrent ){
if ( !reachedCurrent ) {
previousChilds.push(child);
} else {
nextChilds.push(child);
}
} else {
reachedCurrent = true;
}
}
/** Clear current input */
codex.state.inputs[inputIndex].innerHTML = '';
editor.state.inputs[inputIndex].innerHTML = '';
/**
* Append all childs founded before anchorNode
@ -473,10 +534,12 @@ var content = (function(content) {
var previousChildsLength = previousChilds.length;
for(i = 0; i < previousChildsLength; i++) {
codex.state.inputs[inputIndex].appendChild(previousChilds[i]);
editor.state.inputs[inputIndex].appendChild(previousChilds[i]);
}
codex.state.inputs[inputIndex].appendChild(textNodeBeforeCaret);
editor.state.inputs[inputIndex].appendChild(textNodeBeforeCaret);
/**
* Append text node which is after caret
@ -485,20 +548,22 @@ var content = (function(content) {
newNode = document.createElement('div');
for(i = 0; i < nextChildsLength; i++) {
newNode.appendChild(nextChilds[i]);
}
newNode = newNode.innerHTML;
/** This type of block creates when enter is pressed */
var NEW_BLOCK_TYPE = codex.settings.initialBlockPlugin;
var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin;
/**
* Make new paragraph with text after caret
*/
codex.content.insertBlock({
editor.content.insertBlock({
type : NEW_BLOCK_TYPE,
block : codex.tools[NEW_BLOCK_TYPE].render({
block : editor.tools[NEW_BLOCK_TYPE].render({
text : newNode
})
}, true );
@ -509,27 +574,30 @@ var content = (function(content) {
* Merges two blocks current and target
* If target index is not exist, then previous will be as target
*/
content.mergeBlocks = function(currentInputIndex, targetInputIndex) {
content.mergeBlocks = function (currentInputIndex, targetInputIndex) {
/** If current input index is zero, then prevent method execution */
if (currentInputIndex === 0) {
return;
}
var targetInput,
currentInputContent = codex.state.inputs[currentInputIndex].innerHTML;
currentInputContent = editor.state.inputs[currentInputIndex].innerHTML;
if (!targetInputIndex) {
targetInput = codex.state.inputs[currentInputIndex - 1];
targetInput = editor.state.inputs[currentInputIndex - 1];
} else {
targetInput = codex.state.inputs[targetInputIndex];
targetInput = editor.state.inputs[targetInputIndex];
}
targetInput.innerHTML += currentInputContent;
};
/**
@ -538,15 +606,19 @@ var content = (function(content) {
* Callback for HTML Mutations
* @param {Array} mutation - Mutation Record
*/
content.paste = function(mutation) {
content.paste = function (mutation) {
var workingNode = codex.content.currentNode,
var workingNode = editor.content.currentNode,
tool = workingNode.dataset.tool;
if (codex.tools[tool].allowedToPaste) {
codex.content.sanitize.call(this, mutation.target);
if (editor.tools[tool].allowedToPaste) {
editor.content.sanitize.call(this, mutation.target);
} else {
codex.content.pasteTextContent(mutation.addedNodes);
editor.content.pasteTextContent(mutation.addedNodes);
}
};
@ -557,24 +629,33 @@ var content = (function(content) {
* gets only text/plain content of node
* @param {Element} target - HTML node
*/
content.pasteTextContent = function(nodes) {
content.pasteTextContent = function (nodes) {
var node = nodes[0],
textNode;
if (!node) {
return;
}
if (node.nodeType == codex.core.nodeTypes.TEXT) {
if (node.nodeType == editor.core.nodeTypes.TEXT) {
textNode = document.createTextNode(node);
} else {
textNode = document.createTextNode(node.textContent);
}
if (codex.core.isDomNode(node)) {
if (editor.core.isDomNode(node)) {
node.parentNode.replaceChild(textNode, node);
}
};
/**
@ -584,16 +665,20 @@ var content = (function(content) {
* @param {Element} target - inserted element
* @uses Sanitize library html-janitor
*/
content.sanitize = function(target) {
content.sanitize = function (target) {
if (!target) {
return;
}
var node = target[0];
if (!node) {
return;
}
/**
@ -605,17 +690,20 @@ var content = (function(content) {
/**
* Don't sanitize text node
*/
if (node.nodeType == codex.core.nodeTypes.TEXT) {
if (node.nodeType == editor.core.nodeTypes.TEXT) {
return;
}
/**
* Clear dirty content
*/
var cleaner = codex.sanitizer.init(codex.satinizer.Config.BASIC),
var cleaner = editor.sanitizer.init(editor.satinizer.Config.BASIC),
clean = cleaner.clean(target.outerHTML);
var div = codex.draw.node('DIV', [], { innerHTML: clean });
var div = editor.draw.node('DIV', [], { innerHTML: clean });
node.replaceWith(div.childNodes[0]);
@ -628,7 +716,7 @@ var content = (function(content) {
* @param {Element} node
* @return {boolean}
*/
content.isLastNode = function(node) {
content.isLastNode = function (node) {
// console.log('погнали перебор родителей');
@ -639,7 +727,7 @@ var content = (function(content) {
// console.log('Смотрим на %o', node);
// console.log('Проверим, пустые ли соседи справа');
if ( !allSiblingsEmpty_(node) ){
if ( !allSiblingsEmpty_(node) ) {
// console.log('Есть непустые соседи. Узел не последний. Выходим.');
return false;
@ -651,8 +739,10 @@ var content = (function(content) {
/**
* Проверяем родителей до тех пор, пока не найдем блок первого уровня
*/
if ( node.classList.contains(codex.ui.className.BLOCK_CONTENT) ){
if ( node.classList.contains(editor.ui.className.BLOCK_CONTENT) ) {
allChecked = true;
}
}
@ -674,7 +764,7 @@ var content = (function(content) {
while ( sibling ) {
if (sibling.textContent.length){
if (sibling.textContent.length) {
return false;
@ -694,7 +784,7 @@ var content = (function(content) {
* @param [String] htmlString - html content as string
* @return {string} - html content as string
*/
content.wrapTextWithParagraphs = function(htmlString) {
content.wrapTextWithParagraphs = function (htmlString) {
var wrapper = document.createElement('DIV'),
newWrapper = document.createElement('DIV'),
@ -726,7 +816,7 @@ var content = (function(content) {
/**
* If we had splitted inline nodes to paragraph before
*/
if ( paragraph.childNodes.length ){
if ( paragraph.childNodes.length ) {
newWrapper.appendChild(paragraph.cloneNode(true));
@ -744,10 +834,14 @@ var content = (function(content) {
paragraph.appendChild(node.cloneNode(true));
/** if node is last we should append this node to paragraph and paragraph to new wrapper */
if ( i == wrapper.childNodes.length - 1 ){
if ( i == wrapper.childNodes.length - 1 ) {
newWrapper.appendChild(paragraph.cloneNode(true));
}
}
}
return newWrapper.innerHTML;
@ -756,6 +850,4 @@ var content = (function(content) {
return content;
})({});
module.exports = content;
})({});

View file

@ -5,7 +5,9 @@
* @version 1.1.2
*/
var core = (function(core) {
let editor = codex.editor;
module.exports = (function (core) {
/**
* @public
@ -15,32 +17,42 @@ var core = (function(core) {
*/
core.prepare = function (userSettings) {
return new Promise(function(resolve, reject) {
return new Promise(function (resolve, reject) {
if ( userSettings ){
if ( userSettings ) {
codex.settings.tools = userSettings.tools || codex.settings.tools;
editor.settings.tools = userSettings.tools || editor.settings.tools;
}
if (userSettings.data) {
codex.state.blocks = userSettings.data;
editor.state.blocks = userSettings.data;
}
if (userSettings.initialBlockPlugin) {
codex.settings.initialBlockPlugin = userSettings.initialBlockPlugin;
editor.settings.initialBlockPlugin = userSettings.initialBlockPlugin;
}
if (userSettings.uploadImagesUrl) {
codex.settings.uploadImagesUrl = userSettings.uploadImagesUrl;
editor.settings.uploadImagesUrl = userSettings.uploadImagesUrl;
}
codex.nodes.textarea = document.getElementById(userSettings.textareaId || codex.settings.textareaId);
editor.nodes.textarea = document.getElementById(userSettings.textareaId || editor.settings.textareaId);
if (typeof editor.nodes.textarea === undefined || editor.nodes.textarea === null) {
if (typeof codex.nodes.textarea === undefined || codex.nodes.textarea === null) {
reject(Error("Textarea wasn't found by ID: #" + userSettings.textareaId));
} else {
resolve();
}
});
@ -56,19 +68,26 @@ var core = (function(core) {
type = type || 'log';
if (!arg) {
arg = msg || 'undefined';
msg = '[codex-editor]: %o';
} else {
msg = '[codex-editor]: ' + msg;
}
try{
if ( 'console' in window && console[ type ] ){
if ( arg ) console[ type ]( msg , arg );
else console[ type ]( msg );
if ( 'console' in window && window.console[ type ] ) {
if ( arg ) window.console[ type ]( msg, arg );
else window.console[ type ]( msg );
}
}catch(e){}
}catch(e) {}
};
@ -78,7 +97,9 @@ var core = (function(core) {
* Helper for insert one element after another
*/
core.insertAfter = function (target, element) {
target.parentNode.insertBefore(element, target.nextSibling);
};
/**
@ -104,7 +125,9 @@ var core = (function(core) {
* Check object for DOM node
*/
core.isDomNode = function (el) {
return el && typeof el === 'object' && el.nodeType && el.nodeType == this.nodeTypes.TAG;
};
/**
@ -112,12 +135,14 @@ var core = (function(core) {
*/
core.ajax = function (data) {
if (!data || !data.url){
if (!data || !data.url) {
return;
}
var XMLHTTP = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"),
success_function = function(){},
var XMLHTTP = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'),
successFunction = function () {},
params = '',
obj;
@ -125,7 +150,7 @@ var core = (function(core) {
data.type = data.type || 'GET';
data.data = data.data || '';
data['content-type'] = data['content-type'] || 'application/json; charset=utf-8';
success_function = data.success || success_function ;
successFunction = data.success || successFunction ;
if (data.type == 'GET' && data.data) {
@ -134,48 +159,64 @@ var core = (function(core) {
} else {
for(obj in data.data) {
params += (obj + '=' + encodeURIComponent(data.data[obj]) + '&');
}
}
if (data.withCredentials) {
XMLHTTP.withCredentials = true;
}
if (data.beforeSend && typeof data.beforeSend == 'function') {
data.beforeSend.call();
}
XMLHTTP.open( data.type, data.url, data.async );
XMLHTTP.setRequestHeader("X-Requested-With", "XMLHttpRequest");
XMLHTTP.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
XMLHTTP.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
XMLHTTP.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
XMLHTTP.onreadystatechange = function () {
XMLHTTP.onreadystatechange = function() {
if (XMLHTTP.readyState == 4 && XMLHTTP.status == 200) {
success_function(XMLHTTP.responseText);
successFunction(XMLHTTP.responseText);
}
};
XMLHTTP.send(params);
};
/**
* Appends script to head of document
* @return Promise
*/
core.importScript = function(scriptPath, instanceName) {
core.importScript = function (scriptPath, instanceName) {
return new Promise(function(resolve, reject){
return new Promise(function (resolve, reject) {
const instancePrefix = 'cdx-script-';
let script;
/** Script is already loaded */
if ( !instanceName ){
if ( !instanceName ) {
reject('Instance name is missed');
} else if ( document.getElementById(instancePrefix + instanceName) ) {
resolve(scriptPath);
}
script = document.createElement('SCRIPT');
@ -199,12 +240,9 @@ var core = (function(core) {
document.head.appendChild(script);
});
};
return core;
})({});
module.exports = core;
})({});

View file

@ -5,7 +5,7 @@
* @version 1.0.
*/
var draw = (function(draw) {
module.exports = (function (draw) {
/**
* Base editor wrapper
@ -33,7 +33,7 @@ var draw = (function(draw) {
};
draw.ceBlock = function() {
draw.ceBlock = function () {
var block = document.createElement('DIV');
@ -53,20 +53,23 @@ var draw = (function(draw) {
bar.className += 'ce-toolbar';
return bar;
};
draw.toolbarContent = function() {
draw.toolbarContent = function () {
var wrapper = document.createElement('DIV');
wrapper.classList.add('ce-toolbar__content');
return wrapper;
};
/**
* Inline toolbar
*/
draw.inlineToolbar = function() {
draw.inlineToolbar = function () {
var bar = document.createElement('DIV');
@ -79,19 +82,20 @@ var draw = (function(draw) {
/**
* Wrapper for inline toobar buttons
*/
draw.inlineToolbarButtons = function() {
draw.inlineToolbarButtons = function () {
var wrapper = document.createElement('DIV');
wrapper.className += 'ce-toolbar-inline__buttons';
return wrapper;
};
/**
* For some actions
*/
draw.inlineToolbarActions = function() {
draw.inlineToolbarActions = function () {
var wrapper = document.createElement('DIV');
@ -101,7 +105,7 @@ var draw = (function(draw) {
};
draw.inputForLink = function() {
draw.inputForLink = function () {
var input = document.createElement('INPUT');
@ -119,7 +123,7 @@ var draw = (function(draw) {
/**
* Block with notifications
*/
draw.alertsHolder = function() {
draw.alertsHolder = function () {
var block = document.createElement('div');
@ -132,13 +136,14 @@ var draw = (function(draw) {
/**
* @todo Desc
*/
draw.blockButtons = function() {
draw.blockButtons = function () {
var block = document.createElement('div');
block.className += 'ce-toolbar__actions';
return block;
};
/**
@ -151,18 +156,20 @@ var draw = (function(draw) {
settings.className += 'ce-settings';
return settings;
};
draw.defaultSettings = function() {
draw.defaultSettings = function () {
var div = document.createElement('div');
div.classList.add('ce-settings_default');
return div;
};
draw.pluginsSettings = function() {
draw.pluginsSettings = function () {
var div = document.createElement('div');
@ -172,7 +179,7 @@ var draw = (function(draw) {
};
draw.plusButton = function() {
draw.plusButton = function () {
var button = document.createElement('span');
@ -180,6 +187,7 @@ var draw = (function(draw) {
// button.innerHTML = '<i class="ce-icon-plus"></i>';
return button;
};
/**
@ -195,19 +203,21 @@ var draw = (function(draw) {
toggler.innerHTML = '<i class="ce-icon-cog"></i>';
return toggler;
};
/**
* Redactor tools wrapper
*/
draw.toolbox = function() {
draw.toolbox = function () {
var wrapper = document.createElement('div');
wrapper.className = 'ce-toolbar__tools';
return wrapper;
};
/**
@ -221,19 +231,19 @@ var draw = (function(draw) {
*/
draw.toolbarButton = function (type, classname) {
var button = document.createElement("li"),
tool_icon = document.createElement("i"),
tool_title = document.createElement("span");
var button = document.createElement('li'),
toolIcon = document.createElement('i'),
toolTitle = document.createElement('span');
button.dataset.type = type;
button.setAttribute('title', type);
tool_icon.classList.add(classname);
tool_title.classList.add('ce_toolbar_tools--title');
toolIcon.classList.add(classname);
toolTitle.classList.add('ce_toolbar_tools--title');
button.appendChild(tool_icon);
button.appendChild(tool_title);
button.appendChild(toolIcon);
button.appendChild(toolTitle);
return button;
@ -247,17 +257,19 @@ var draw = (function(draw) {
* @param {String} type
* @param {String} classname
*/
draw.toolbarButtonInline = function(type, classname) {
var button = document.createElement("BUTTON"),
tool_icon = document.createElement("I");
draw.toolbarButtonInline = function (type, classname) {
button.type = "button";
var button = document.createElement('BUTTON'),
toolIcon = document.createElement('I');
button.type = 'button';
button.dataset.type = type;
tool_icon.classList.add(classname);
toolIcon.classList.add(classname);
button.appendChild(tool_icon);
button.appendChild(toolIcon);
return button;
};
/**
@ -279,7 +291,7 @@ var draw = (function(draw) {
* @param {string} className
* @param {object} properties - allow to assign properties
*/
draw.node = function( tagName , className , properties ){
draw.node = function ( tagName, className, properties ) {
var el = document.createElement( tagName );
@ -287,28 +299,18 @@ var draw = (function(draw) {
if ( properties ) {
for (var name in properties){
for (var name in properties) {
el[name] = properties[name];
}
}
return el;
};
draw.pluginsRender = function(type, content) {
return {
type : type,
block : cEditor.tools[type].render({
text : content
})
};
};
return draw;
})({});
module.exports = draw;
})({});

View file

@ -4,16 +4,17 @@
* @author Codex Team
* @version 1.0
*/
let editor = codex.editor;
var notifications = (function(notifications) {
module.exports = (function (notifications) {
/**
* Error notificator. Shows block with message
* @protected
*/
notifications.errorThrown = function(errorMsg, event) {
notifications.errorThrown = function (errorMsg, event) {
codex.notifications.send('This action is not available currently', event.type, false);
editor.notifications.send('This action is not available currently', event.type, false);
};
@ -23,27 +24,29 @@ var notifications = (function(notifications) {
* @param type {string} - Type of message notification. Ex: Error, Warning, Danger ...
* @param append {boolean} - can be True or False when notification should be inserted after
*/
notifications.send = function(message, type, append) {
notifications.send = function (message, type, append) {
var notification = codex.draw.block('div');
var notification = editor.draw.block('div');
notification.textContent = message;
notification.classList.add('ce_notification-item', 'ce_notification-' + type, 'flipInX');
if (!append) {
codex.nodes.notifications.innerHTML = '';
editor.nodes.notifications.innerHTML = '';
}
codex.nodes.notifications.appendChild(notification);
editor.nodes.notifications.appendChild(notification);
window.setTimeout(function () {
setTimeout(function () {
notification.remove();
}, 3000);
};
return notifications;
})({});
module.exports = notifications;
})({});

View file

@ -4,13 +4,14 @@
* @author Codex Team
* @version 1.1
*/
let editor = codex.editor;
var parser = (function(parser) {
module.exports = (function (parser) {
/** inserting text */
parser.insertPastedContent = function(blockType, tag) {
parser.insertPastedContent = function (blockType, tag) {
codex.content.insertBlock({
editor.content.insertBlock({
type : blockType.type,
block : blockType.render({
text : tag.innerHTML
@ -24,13 +25,11 @@ var parser = (function(parser) {
*/
parser.isFirstLevelBlock = function (node) {
return node.nodeType == cEditor.core.nodeTypes.TAG &&
node.classList.contains(cEditor.ui.className.BLOCK_CLASSNAME);
return node.nodeType == editor.core.nodeTypes.TAG &&
node.classList.contains(editor.ui.className.BLOCK_CLASSNAME);
};
return parser;
})({});
module.exports = parser;

View file

@ -5,7 +5,9 @@
* @version 1.0
*/
var renderer = (function(renderer) {
let editor = codex.editor;
module.exports = (function (renderer) {
/**
* Asyncronously parses input JSON to redactor blocks
@ -15,9 +17,9 @@ var renderer = (function(renderer) {
/**
* If redactor is empty, add first paragraph to start writing
*/
if (!codex.state.blocks.items.length) {
if (!editor.state.blocks.items.length) {
codex.ui.addInitialBlock();
editor.ui.addInitialBlock();
return;
}
@ -25,16 +27,20 @@ var renderer = (function(renderer) {
Promise.resolve()
/** First, get JSON from state */
.then(function() {
return codex.state.blocks;
.then(function () {
return editor.state.blocks;
})
/** Then, start to iterate they */
.then(codex.renderer.appendBlocks)
.then(editor.renderer.appendBlocks)
/** Write log if something goes wrong */
.catch(function(error) {
codex.core.log('Error while parsing JSON: %o', 'error', error);
.catch(function (error) {
editor.core.log('Error while parsing JSON: %o', 'error', error);
});
};
@ -57,7 +63,7 @@ var renderer = (function(renderer) {
for (var index = 0; index < blocks.length ; index++ ) {
/** Add node to sequence at specified index */
codex.renderer.appendNodeAtIndex(nodeSequence, blocks, index);
editor.renderer.appendNodeAtIndex(nodeSequence, blocks, index);
}
@ -72,26 +78,26 @@ var renderer = (function(renderer) {
nodeSequence
/** first, get node async-aware */
.then(function() {
.then(function () {
return codex.renderer.getNodeAsync(blocks , index);
return editor.renderer.getNodeAsync(blocks, index);
})
/**
* second, compose editor-block from JSON object
*/
.then(codex.renderer.createBlockFromData)
.then(editor.renderer.createBlockFromData)
/**
* now insert block to redactor
*/
.then(function(blockData){
.then(function (blockData) {
/**
* blockData has 'block', 'type' and 'stretched' information
*/
codex.content.insertBlock(blockData);
editor.content.insertBlock(blockData);
/** Pass created block to next step */
return blockData.block;
@ -99,8 +105,10 @@ var renderer = (function(renderer) {
})
/** Log if something wrong with node */
.catch(function(error) {
codex.core.log('Node skipped while parsing because %o', 'error', error);
.catch(function (error) {
editor.core.log('Node skipped while parsing because %o', 'error', error);
});
};
@ -111,11 +119,12 @@ var renderer = (function(renderer) {
*/
renderer.getNodeAsync = function (blocksList, index) {
return Promise.resolve().then(function() {
return Promise.resolve().then(function () {
return blocksList[index];
});
};
/**
@ -141,21 +150,24 @@ var renderer = (function(renderer) {
// for (var pluginName in blockData) break;
/** Check for plugin existance */
if (!codex.tools[pluginName]) {
if (!editor.tools[pluginName]) {
throw Error(`Plugin «${pluginName}» not found`);
}
/** Check for plugin having render method */
if (typeof codex.tools[pluginName].render != 'function') {
if (typeof editor.tools[pluginName].render != 'function') {
throw Error(`Plugin «${pluginName}» must have «render» method`);
}
/** New Parser */
var block = codex.tools[pluginName].render(blockData.data);
var block = editor.tools[pluginName].render(blockData.data);
/** is first-level block stretched */
var stretched = codex.tools[pluginName].isStretched || false;
var stretched = editor.tools[pluginName].isStretched || false;
/** Retrun type and block */
return {
@ -169,6 +181,4 @@ var renderer = (function(renderer) {
return renderer;
})({});
module.exports = renderer;
})({});

View file

@ -4,7 +4,7 @@
var janitor = require('html-janitor');
var sanitizer = (function(sanitizer) {
module.exports = (function (sanitizer) {
/**
* Basic config
@ -35,8 +35,4 @@ var sanitizer = (function(sanitizer) {
return sanitizer;
})({});
module.exports = sanitizer;
})({});

View file

@ -5,7 +5,9 @@
* @version 1.0.2
*/
var saver = (function(saver) {
let editor = codex.editor;
module.exports = (function (saver) {
/**
* Saves blocks
@ -14,50 +16,56 @@ var saver = (function(saver) {
saver.saveBlocks = function () {
/** Save html content of redactor to memory */
codex.state.html = codex.nodes.redactor.innerHTML;
editor.state.html = editor.nodes.redactor.innerHTML;
/** Empty jsonOutput state */
codex.state.jsonOutput = [];
editor.state.jsonOutput = [];
Promise.resolve()
.then(function() {
return codex.nodes.redactor.childNodes;
.then(function () {
return editor.nodes.redactor.childNodes;
})
/** Making a sequence from separate blocks */
.then(codex.saver.makeQueue)
.then(editor.saver.makeQueue)
.then(function() {
// codex.nodes.textarea.innerHTML = codex.state.html;
.then(function () {
// editor.nodes.textarea.innerHTML = editor.state.html;
})
.catch( function(error) {
console.log('Something happend');
.catch( function (error) {
editor.core.log(error);
});
};
saver.makeQueue = function(blocks) {
saver.makeQueue = function (blocks) {
var queue = Promise.resolve();
for(var index = 0; index < blocks.length; index++) {
/** Add node to sequence at specified index */
codex.saver.getBlockData(queue, blocks, index);
editor.saver.getBlockData(queue, blocks, index);
}
};
/** Gets every block and makes From Data */
saver.getBlockData = function(queue, blocks, index) {
saver.getBlockData = function (queue, blocks, index) {
queue.then(function () {
return editor.saver.getNodeAsync(blocks, index);
queue.then(function() {
return codex.saver.getNodeAsync(blocks, index);
})
.then(codex.saver.makeFormDataFromBlocks);
.then(editor.saver.makeFormDataFromBlocks);
};
@ -68,32 +76,36 @@ var saver = (function(saver) {
*/
saver.getNodeAsync = function (blocksList, index) {
return Promise.resolve().then(function() {
return Promise.resolve().then(function () {
return blocksList[index];
});
};
saver.makeFormDataFromBlocks = function(block) {
saver.makeFormDataFromBlocks = function (block) {
var pluginName = block.dataset.tool;
/** Check for plugin existance */
if (!codex.tools[pluginName]) {
if (!editor.tools[pluginName]) {
throw Error(`Plugin «${pluginName}» not found`);
}
/** Check for plugin having render method */
if (typeof codex.tools[pluginName].save != 'function') {
if (typeof editor.tools[pluginName].save != 'function') {
throw Error(`Plugin «${pluginName}» must have save method`);
}
/** Result saver */
var blockContent = block.childNodes[0],
pluginsContent = blockContent.childNodes[0],
savedData = codex.tools[pluginName].save(pluginsContent),
savedData = editor.tools[pluginName].save(pluginsContent),
output;
@ -102,24 +114,25 @@ var saver = (function(saver) {
data: savedData
};
if (codex.tools[pluginName].validate) {
var result = codex.tools[pluginName].validate(savedData);
if (editor.tools[pluginName].validate) {
var result = editor.tools[pluginName].validate(savedData);
/**
* Do not allow invalid data
*/
if (!result)
return;
}
/** Marks Blocks that will be in main page */
output.cover = block.classList.contains(codex.ui.className.BLOCK_IN_FEED_MODE);
codex.state.jsonOutput.push(output);
}
/** Marks Blocks that will be in main page */
output.cover = block.classList.contains(editor.ui.className.BLOCK_IN_FEED_MODE);
editor.state.jsonOutput.push(output);
};
return saver;
})({});
module.exports = saver;
})({});

View file

@ -7,11 +7,10 @@
* @author Codex Team
* @version 1.0
*/
var inline = (function(inline) {
inline.init = function() {
let editor = codex.editor;
};
module.exports = (function (inline) {
inline.buttonsOpened = null;
inline.actionsOpened = null;
@ -28,34 +27,34 @@ var inline = (function(inline) {
*
* Open inline toobar
*/
inline.show = function() {
inline.show = function () {
var currentNode = codex.content.currentNode,
var currentNode = editor.content.currentNode,
tool = currentNode.dataset.tool,
plugin;
/**
* tool allowed to open inline toolbar
*/
plugin = codex.tools[tool];
plugin = editor.tools[tool];
if (!plugin.showInlineToolbar)
return;
var selectedText = this.getSelectionText(),
toolbar = codex.nodes.inlineToolbar.wrapper,
buttons = codex.nodes.inlineToolbar.buttons;
var selectedText = inline.getSelectionText(),
toolbar = editor.nodes.inlineToolbar.wrapper;
if (selectedText.length > 0) {
/** Move toolbar and open */
codex.toolbar.inline.move();
editor.toolbar.inline.move();
/** Open inline toolbar */
toolbar.classList.add('opened');
/** show buttons of inline toolbar */
codex.toolbar.inline.showButtons();
editor.toolbar.inline.showButtons();
}
};
@ -65,9 +64,12 @@ var inline = (function(inline) {
*
* Closes inline toolbar
*/
inline.close = function() {
var toolbar = codex.nodes.inlineToolbar.wrapper;
inline.close = function () {
var toolbar = editor.nodes.inlineToolbar.wrapper;
toolbar.classList.remove('opened');
};
/**
@ -75,20 +77,24 @@ var inline = (function(inline) {
*
* Moving toolbar
*/
inline.move = function() {
inline.move = function () {
if (!this.wrappersOffset) {
this.wrappersOffset = this.getWrappersOffset();
}
var coords = this.getSelectionCoords(),
defaultOffset = 0,
toolbar = codex.nodes.inlineToolbar.wrapper,
toolbar = editor.nodes.inlineToolbar.wrapper,
newCoordinateX,
newCoordinateY;
if (toolbar.offsetHeight === 0) {
defaultOffset = 40;
}
newCoordinateX = coords.x - this.wrappersOffset.left;
@ -97,8 +103,8 @@ var inline = (function(inline) {
toolbar.style.transform = `translate3D(${Math.floor(newCoordinateX)}px, ${Math.floor(newCoordinateY)}px, 0)`;
/** Close everything */
codex.toolbar.inline.closeButtons();
codex.toolbar.inline.closeAction();
editor.toolbar.inline.closeButtons();
editor.toolbar.inline.closeAction();
};
@ -108,22 +114,23 @@ var inline = (function(inline) {
* Tool Clicked
*/
inline.toolClicked = function(event, type) {
inline.toolClicked = function (event, type) {
/**
* For simple tools we use default browser function
* For more complicated tools, we should write our own behavior
*/
switch (type) {
case 'createLink' : codex.toolbar.inline.createLinkAction(event, type); break;
default : codex.toolbar.inline.defaultToolAction(type); break;
case 'createLink' : editor.toolbar.inline.createLinkAction(event, type); break;
default : editor.toolbar.inline.defaultToolAction(type); break;
}
/**
* highlight buttons
* after making some action
*/
codex.nodes.inlineToolbar.buttons.childNodes.forEach(codex.toolbar.inline.hightlight);
editor.nodes.inlineToolbar.buttons.childNodes.forEach(editor.toolbar.inline.hightlight);
};
/**
@ -131,9 +138,9 @@ var inline = (function(inline) {
*
* Saving wrappers offset in DOM
*/
inline.getWrappersOffset = function() {
inline.getWrappersOffset = function () {
var wrapper = codex.nodes.wrapper,
var wrapper = editor.nodes.wrapper,
offset = this.getOffset(wrapper);
this.wrappersOffset = offset;
@ -155,11 +162,14 @@ var inline = (function(inline) {
var _y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
_x += (el.offsetLeft + el.clientLeft);
_y += (el.offsetTop + el.clientTop);
el = el.offsetParent;
}
return { top: _y, left: _x };
};
/**
@ -168,18 +178,20 @@ var inline = (function(inline) {
* Calculates position of selected text
* @returns {{x: number, y: number}}
*/
inline.getSelectionCoords = function() {
inline.getSelectionCoords = function () {
var sel = document.selection, range;
var x = 0, y = 0;
if (sel) {
if (sel.type != "Control") {
if (sel.type != 'Control') {
range = sel.createRange();
range.collapse(true);
x = range.boundingLeft;
y = range.boundingTop;
}
} else if (window.getSelection) {
@ -190,20 +202,26 @@ var inline = (function(inline) {
range = sel.getRangeAt(0).cloneRange();
if (range.getClientRects) {
range.collapse(true);
var rect = range.getClientRects()[0];
if (!rect) {
return;
}
x = rect.left;
y = rect.top;
}
}
}
return { x: x, y: y };
};
/**
@ -212,68 +230,109 @@ var inline = (function(inline) {
* Returns selected text as String
* @returns {string}
*/
inline.getSelectionText = function getSelectionText(){
inline.getSelectionText = function () {
var selectedText = "";
var selectedText = '';
// all modern browsers and IE9+
if (window.getSelection) {
if (window.getSelection){ // all modern browsers and IE9+
selectedText = window.getSelection().toString();
}
return selectedText;
};
/** Opens buttons block */
inline.showButtons = function() {
inline.showButtons = function () {
var buttons = editor.nodes.inlineToolbar.buttons;
var buttons = codex.nodes.inlineToolbar.buttons;
buttons.classList.add('opened');
codex.toolbar.inline.buttonsOpened = true;
editor.toolbar.inline.buttonsOpened = true;
/** highlight buttons */
codex.nodes.inlineToolbar.buttons.childNodes.forEach(codex.toolbar.inline.hightlight);
editor.nodes.inlineToolbar.buttons.childNodes.forEach(editor.toolbar.inline.hightlight);
};
/** Makes buttons disappear */
inline.closeButtons = function() {
var buttons = codex.nodes.inlineToolbar.buttons;
inline.closeButtons = function () {
var buttons = editor.nodes.inlineToolbar.buttons;
buttons.classList.remove('opened');
codex.toolbar.inline.buttonsOpened = false;
editor.toolbar.inline.buttonsOpened = false;
};
/** Open buttons defined action if exist */
inline.showActions = function() {
var action = codex.nodes.inlineToolbar.actions;
inline.showActions = function () {
var action = editor.nodes.inlineToolbar.actions;
action.classList.add('opened');
codex.toolbar.inline.actionsOpened = true;
editor.toolbar.inline.actionsOpened = true;
};
/** Close actions block */
inline.closeAction = function() {
var action = codex.nodes.inlineToolbar.actions;
inline.closeAction = function () {
var action = editor.nodes.inlineToolbar.actions;
action.innerHTML = '';
action.classList.remove('opened');
codex.toolbar.inline.actionsOpened = false;
editor.toolbar.inline.actionsOpened = false;
};
/**
* Callback for keydowns in inline toolbar "Insert link..." input
*/
let inlineToolbarAnchorInputKeydown_ = function (event) {
if (event.keyCode != editor.core.keys.ENTER) {
return;
}
let editable = editor.content.currentNode,
storedSelection = editor.toolbar.inline.storedSelection;
editor.toolbar.inline.restoreSelection(editable, storedSelection);
editor.toolbar.inline.setAnchor(this.value);
/**
* Preventing events that will be able to happen
*/
event.preventDefault();
event.stopImmediatePropagation();
editor.toolbar.inline.clearRange();
};
/** Action for link creation or for setting anchor */
inline.createLinkAction = function(event, type) {
inline.createLinkAction = function (event) {
var isActive = this.isLinkActive();
var editable = codex.content.currentNode,
storedSelection = codex.toolbar.inline.storedSelection;
var editable = editor.content.currentNode,
storedSelection = editor.toolbar.inline.saveSelection(editable);
/** Save globally selection */
editor.toolbar.inline.storedSelection = storedSelection;
if (isActive) {
var selection = window.getSelection(),
anchorNode = selection.anchorNode;
storedSelection = codex.toolbar.inline.saveSelection(editable);
/**
* Changing stored selection. if we want to remove anchor from word
@ -281,20 +340,19 @@ var inline = (function(inline) {
* The solution is than we get the length of current link
* Change start position to - end of selection minus length of anchor
*/
codex.toolbar.inline.restoreSelection(editable, storedSelection);
editor.toolbar.inline.restoreSelection(editable, storedSelection);
codex.toolbar.inline.defaultToolAction('unlink');
editor.toolbar.inline.defaultToolAction('unlink');
} else {
/** Create input and close buttons */
var action = codex.draw.inputForLink();
codex.nodes.inlineToolbar.actions.appendChild(action);
var action = editor.draw.inputForLink();
codex.toolbar.inline.closeButtons();
codex.toolbar.inline.showActions();
editor.nodes.inlineToolbar.actions.appendChild(action);
storedSelection = codex.toolbar.inline.saveSelection(editable);
editor.toolbar.inline.closeButtons();
editor.toolbar.inline.showActions();
/**
* focus to input
@ -305,44 +363,37 @@ var inline = (function(inline) {
event.preventDefault();
/** Callback to link action */
action.addEventListener('keydown', function(event){
action.addEventListener('keydown', inlineToolbarAnchorInputKeydown_, false);
if (event.keyCode == codex.core.keys.ENTER) {
codex.toolbar.inline.restoreSelection(editable, storedSelection);
codex.toolbar.inline.setAnchor(action.value);
/**
* Preventing events that will be able to happen
*/
event.preventDefault();
event.stopImmediatePropagation();
codex.toolbar.inline.clearRange();
}
}, false);
}
};
inline.isLinkActive = function() {
inline.isLinkActive = function () {
var isActive = false;
codex.nodes.inlineToolbar.buttons.childNodes.forEach(function(tool) {
editor.nodes.inlineToolbar.buttons.childNodes.forEach(function (tool) {
var dataType = tool.dataset.type;
if (dataType == 'link' && tool.classList.contains('hightlighted')) {
isActive = true;
}
});
return isActive;
};
/** default action behavior of tool */
inline.defaultToolAction = function(type) {
inline.defaultToolAction = function (type) {
document.execCommand(type, false, null);
};
/**
@ -352,12 +403,13 @@ var inline = (function(inline) {
*
* @param {String} url - URL
*/
inline.setAnchor = function(url) {
inline.setAnchor = function (url) {
document.execCommand('createLink', false, url);
/** Close after URL inserting */
codex.toolbar.inline.closeAction();
editor.toolbar.inline.closeAction();
};
/**
@ -365,7 +417,7 @@ var inline = (function(inline) {
*
* Saves selection
*/
inline.saveSelection = function(containerEl) {
inline.saveSelection = function (containerEl) {
var range = window.getSelection().getRangeAt(0),
preSelectionRange = range.cloneRange(),
@ -380,6 +432,7 @@ var inline = (function(inline) {
start: start,
end: start + range.toString().length
};
};
/**
@ -390,7 +443,7 @@ var inline = (function(inline) {
* @param {Element} containerEl - editable element where we restore range
* @param {Object} savedSel - range basic information to restore
*/
inline.restoreSelection = function(containerEl, savedSel) {
inline.restoreSelection = function (containerEl, savedSel) {
var range = document.createRange(),
charIndex = 0;
@ -398,7 +451,7 @@ var inline = (function(inline) {
range.setStart(containerEl, 0);
range.collapse(true);
var nodeStack = [containerEl],
var nodeStack = [ containerEl ],
node,
foundStart = false,
stop = false,
@ -411,25 +464,38 @@ var inline = (function(inline) {
nextCharIndex = charIndex + node.length;
if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
range.setStart(node, savedSel.start - charIndex);
foundStart = true;
}
if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
range.setEnd(node, savedSel.end - charIndex);
stop = true;
}
charIndex = nextCharIndex;
} else {
var i = node.childNodes.length;
while (i--) {
nodeStack.push(node.childNodes[i]);
}
}
}
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
};
/**
@ -437,9 +503,12 @@ var inline = (function(inline) {
*
* Removes all ranges from window selection
*/
inline.clearRange = function() {
inline.clearRange = function () {
var selection = window.getSelection();
selection.removeAllRanges();
};
/**
@ -447,13 +516,18 @@ var inline = (function(inline) {
*
* sets or removes hightlight
*/
inline.hightlight = function(tool) {
inline.hightlight = function (tool) {
var dataType = tool.dataset.type;
if (document.queryCommandState(dataType)) {
codex.toolbar.inline.setButtonHighlighted(tool);
editor.toolbar.inline.setButtonHighlighted(tool);
} else {
codex.toolbar.inline.removeButtonsHighLight(tool);
editor.toolbar.inline.removeButtonsHighLight(tool);
}
/**
@ -464,8 +538,11 @@ var inline = (function(inline) {
tag = selection.anchorNode.parentNode;
if (tag.tagName == 'A' && dataType == 'link') {
codex.toolbar.inline.setButtonHighlighted(tool);
editor.toolbar.inline.setButtonHighlighted(tool);
}
};
/**
@ -473,15 +550,20 @@ var inline = (function(inline) {
*
* Mark button if text is already executed
*/
inline.setButtonHighlighted = function(button) {
inline.setButtonHighlighted = function (button) {
button.classList.add('hightlighted');
/** At link tool we also change icon */
if (button.dataset.type == 'link') {
var icon = button.childNodes[0];
icon.classList.remove('ce-icon-link');
icon.classList.add('ce-icon-unlink');
}
};
/**
@ -489,21 +571,23 @@ var inline = (function(inline) {
*
* Removes hightlight
*/
inline.removeButtonsHighLight = function(button) {
inline.removeButtonsHighLight = function (button) {
button.classList.remove('hightlighted');
/** At link tool we also change icon */
if (button.dataset.type == 'link') {
var icon = button.childNodes[0];
icon.classList.remove('ce-icon-unlink');
icon.classList.add('ce-icon-link');
}
};
return inline;
})({});
inline.init();
module.exports = inline;
})({});

View file

@ -4,11 +4,9 @@
* @version 1.0.4
*/
var settings = (function(settings) {
let editor = codex.editor;
settings.init = function() {
require('../content');
};
module.exports = (function (settings) {
settings.opened = false;
@ -20,41 +18,42 @@ var settings = (function(settings) {
/**
* Append and open settings
*/
settings.open = function(toolType){
settings.open = function (toolType) {
/**
* Append settings content
* It's stored in tool.settings
*/
if (!codex.tools[toolType] || !codex.tools[toolType].makeSettings ) {
if (!editor.tools[toolType] || !editor.tools[toolType].makeSettings ) {
codex.core.log(`Plugin «${toolType}» has no settings`, 'warn');
// codex.nodes.pluginSettings.innerHTML = `Плагин «${toolType}» не имеет настроек`;
editor.core.log(`Plugin «${toolType}» has no settings`, 'warn');
// editor.nodes.pluginSettings.innerHTML = `Плагин «${toolType}» не имеет настроек`;
} else {
/**
* Draw settings block
*/
var settingsBlock = codex.tools[toolType].makeSettings();
codex.nodes.pluginSettings.appendChild(settingsBlock);
var settingsBlock = editor.tools[toolType].makeSettings();
editor.nodes.pluginSettings.appendChild(settingsBlock);
}
var currentBlock = codex.content.currentNode;
/** Open settings block */
codex.nodes.blockSettings.classList.add('opened');
codex.toolbar.settings.addDefaultSettings();
editor.nodes.blockSettings.classList.add('opened');
editor.toolbar.settings.addDefaultSettings();
this.opened = true;
};
/**
* Close and clear settings
*/
settings.close = function(){
settings.close = function () {
codex.nodes.blockSettings.classList.remove('opened');
codex.nodes.pluginSettings.innerHTML = '';
editor.nodes.blockSettings.classList.remove('opened');
editor.nodes.pluginSettings.innerHTML = '';
this.opened = false;
@ -63,9 +62,9 @@ var settings = (function(settings) {
/**
* @param {string} toolType - plugin type
*/
settings.toggle = function( toolType ){
settings.toggle = function ( toolType ) {
if ( !this.opened ){
if ( !this.opened ) {
this.open(toolType);
@ -80,17 +79,17 @@ var settings = (function(settings) {
/**
* This function adds default core settings
*/
settings.addDefaultSettings = function() {
settings.addDefaultSettings = function () {
/** list of default settings */
var feedModeToggler;
/** Clear block and append initialized settings */
codex.nodes.defaultSettings.innerHTML = '';
editor.nodes.defaultSettings.innerHTML = '';
/** Init all default setting buttons */
feedModeToggler = codex.toolbar.settings.makeFeedModeToggler();
feedModeToggler = editor.toolbar.settings.makeFeedModeToggler();
/**
* Fill defaultSettings
@ -100,7 +99,7 @@ var settings = (function(settings) {
* Button that enables/disables Feed-mode
* Feed-mode means that block will be showed in articles-feed like cover
*/
codex.nodes.defaultSettings.appendChild(feedModeToggler);
editor.nodes.defaultSettings.appendChild(feedModeToggler);
};
@ -113,9 +112,9 @@ var settings = (function(settings) {
*
* @return {Element} node/button that we place in default settings block
*/
settings.makeFeedModeToggler = function() {
settings.makeFeedModeToggler = function () {
var isFeedModeActivated = codex.toolbar.settings.isFeedModeActivated(),
var isFeedModeActivated = editor.toolbar.settings.isFeedModeActivated(),
setting,
data;
@ -133,51 +132,58 @@ var settings = (function(settings) {
}
setting = codex.draw.node('DIV', codex.ui.className.SETTINGS_ITEM, data);
setting.addEventListener('click', codex.toolbar.settings.updateFeedMode, false);
setting = editor.draw.node('DIV', editor.ui.className.SETTINGS_ITEM, data);
setting.addEventListener('click', editor.toolbar.settings.updateFeedMode, false);
return setting;
};
/**
* Updates Feed-mode
*/
settings.updateFeedMode = function() {
settings.updateFeedMode = function () {
var currentNode = codex.content.currentNode;
var currentNode = editor.content.currentNode;
currentNode.classList.toggle(codex.ui.className.BLOCK_IN_FEED_MODE);
currentNode.classList.toggle(editor.ui.className.BLOCK_IN_FEED_MODE);
editor.toolbar.settings.close();
codex.toolbar.settings.close();
};
settings.isFeedModeActivated = function() {
settings.isFeedModeActivated = function () {
var currentBlock = codex.content.currentNode;
var currentBlock = editor.content.currentNode;
if (currentBlock) {
return currentBlock.classList.contains(codex.ui.className.BLOCK_IN_FEED_MODE);
return currentBlock.classList.contains(editor.ui.className.BLOCK_IN_FEED_MODE);
} else {
return false;
}
};
/**
* Here we will draw buttons and add listeners to components
*/
settings.makeRemoveBlockButton = function() {
settings.makeRemoveBlockButton = function () {
var removeBlockWrapper = codex.draw.node('SPAN', 'ce-toolbar__remove-btn', {}),
settingButton = codex.draw.node('SPAN', 'ce-toolbar__remove-setting', { innerHTML : '<i class="ce-icon-trash"></i>' }),
actionWrapper = codex.draw.node('DIV', 'ce-toolbar__remove-confirmation', {}),
confirmAction = codex.draw.node('DIV', 'ce-toolbar__remove-confirm', { textContent : 'Удалить блок' }),
cancelAction = codex.draw.node('DIV', 'ce-toolbar__remove-cancel', { textContent : 'Отмена' });
var removeBlockWrapper = editor.draw.node('SPAN', 'ce-toolbar__remove-btn', {}),
settingButton = editor.draw.node('SPAN', 'ce-toolbar__remove-setting', { innerHTML : '<i class="ce-icon-trash"></i>' }),
actionWrapper = editor.draw.node('DIV', 'ce-toolbar__remove-confirmation', {}),
confirmAction = editor.draw.node('DIV', 'ce-toolbar__remove-confirm', { textContent : 'Удалить блок' }),
cancelAction = editor.draw.node('DIV', 'ce-toolbar__remove-cancel', { textContent : 'Отмена' });
settingButton.addEventListener('click', codex.toolbar.settings.removeButtonClicked, false);
settingButton.addEventListener('click', editor.toolbar.settings.removeButtonClicked, false);
confirmAction.addEventListener('click', codex.toolbar.settings.confirmRemovingRequest, false);
confirmAction.addEventListener('click', editor.toolbar.settings.confirmRemovingRequest, false);
cancelAction.addEventListener('click', codex.toolbar.settings.cancelRemovingRequest, false);
cancelAction.addEventListener('click', editor.toolbar.settings.cancelRemovingRequest, false);
actionWrapper.appendChild(confirmAction);
actionWrapper.appendChild(cancelAction);
@ -186,41 +192,46 @@ var settings = (function(settings) {
removeBlockWrapper.appendChild(actionWrapper);
/** Save setting */
codex.toolbar.settings.setting = settingButton;
codex.toolbar.settings.actions = actionWrapper;
editor.toolbar.settings.setting = settingButton;
editor.toolbar.settings.actions = actionWrapper;
return removeBlockWrapper;
};
settings.removeButtonClicked = function() {
settings.removeButtonClicked = function () {
var action = codex.toolbar.settings.actions;
var action = editor.toolbar.settings.actions;
if (action.classList.contains('opened')) {
codex.toolbar.settings.hideRemoveActions();
editor.toolbar.settings.hideRemoveActions();
} else {
codex.toolbar.settings.showRemoveActions();
editor.toolbar.settings.showRemoveActions();
}
codex.toolbar.toolbox.close();
codex.toolbar.settings.close();
editor.toolbar.toolbox.close();
editor.toolbar.settings.close();
};
settings.cancelRemovingRequest = function() {
settings.cancelRemovingRequest = function () {
editor.toolbar.settings.actions.classList.remove('opened');
codex.toolbar.settings.actions.classList.remove('opened');
};
settings.confirmRemovingRequest = function() {
settings.confirmRemovingRequest = function () {
var currentBlock = codex.content.currentNode,
var currentBlock = editor.content.currentNode,
firstLevelBlocksCount;
currentBlock.remove();
firstLevelBlocksCount = codex.nodes.redactor.childNodes.length;
firstLevelBlocksCount = editor.nodes.redactor.childNodes.length;
/**
* If all blocks are removed
@ -228,29 +239,31 @@ var settings = (function(settings) {
if (firstLevelBlocksCount === 0) {
/** update currentNode variable */
codex.content.currentNode = null;
editor.content.currentNode = null;
/** Inserting new empty initial block */
codex.ui.addInitialBlock();
editor.ui.addInitialBlock();
}
codex.ui.saveInputs();
editor.ui.saveInputs();
editor.toolbar.close();
codex.toolbar.close();
};
settings.showRemoveActions = function() {
codex.toolbar.settings.actions.classList.add('opened');
settings.showRemoveActions = function () {
editor.toolbar.settings.actions.classList.add('opened');
};
settings.hideRemoveActions = function() {
codex.toolbar.settings.actions.classList.remove('opened');
settings.hideRemoveActions = function () {
editor.toolbar.settings.actions.classList.remove('opened');
};
return settings;
})({});
settings.init();
module.exports = settings;
})({});

View file

@ -9,13 +9,14 @@
* @author Codex Team
* @version 1.0
*/
var toolbar = (function(toolbar) {
toolbar.init = function() {
toolbar.settings = require('./settings');
toolbar.inline = require('./inline');
toolbar.toolbox = require('./toolbox');
};
let editor = codex.editor;
module.exports = (function (toolbar) {
toolbar.settings = require('./settings');
toolbar.inline = require('./inline');
toolbar.toolbox = require('./toolbox');
/**
* Margin between focused node and toolbar
@ -31,9 +32,9 @@ var toolbar = (function(toolbar) {
/**
* @protected
*/
toolbar.open = function (){
toolbar.open = function () {
codex.nodes.toolbar.classList.add('opened');
editor.nodes.toolbar.classList.add('opened');
this.opened = true;
};
@ -41,26 +42,28 @@ var toolbar = (function(toolbar) {
/**
* @protected
*/
toolbar.close = function(){
toolbar.close = function () {
codex.nodes.toolbar.classList.remove('opened');
editor.nodes.toolbar.classList.remove('opened');
toolbar.opened = false;
toolbar.current = null;
for (var button in codex.nodes.toolbarButtons){
codex.nodes.toolbarButtons[button].classList.remove('selected');
for (var button in editor.nodes.toolbarButtons) {
editor.nodes.toolbarButtons[button].classList.remove('selected');
}
/** Close toolbox when toolbar is not displayed */
codex.toolbar.toolbox.close();
codex.toolbar.settings.close();
editor.toolbar.toolbox.close();
editor.toolbar.settings.close();
};
toolbar.toggle = function(){
toolbar.toggle = function () {
if ( !this.opened ){
if ( !this.opened ) {
this.open();
@ -72,41 +75,41 @@ var toolbar = (function(toolbar) {
};
toolbar.hidePlusButton = function() {
codex.nodes.plusButton.classList.add('hide');
toolbar.hidePlusButton = function () {
editor.nodes.plusButton.classList.add('hide');
};
toolbar.showPlusButton = function() {
codex.nodes.plusButton.classList.remove('hide');
toolbar.showPlusButton = function () {
editor.nodes.plusButton.classList.remove('hide');
};
/**
* Moving toolbar to the specified node
*/
toolbar.move = function() {
toolbar.move = function () {
/** Close Toolbox when we move toolbar */
codex.toolbar.toolbox.close();
editor.toolbar.toolbox.close();
if (!editor.content.currentNode) {
if (!codex.content.currentNode) {
return;
}
var toolbarHeight = codex.nodes.toolbar.clientHeight || codex.toolbar.defaultToolbarHeight,
newYCoordinate = codex.content.currentNode.offsetTop - (codex.toolbar.defaultToolbarHeight / 2) + codex.toolbar.defaultOffset;
var newYCoordinate = editor.content.currentNode.offsetTop - (editor.toolbar.defaultToolbarHeight / 2) + editor.toolbar.defaultOffset;
codex.nodes.toolbar.style.transform = `translate3D(0, ${Math.floor(newYCoordinate)}px, 0)`;
editor.nodes.toolbar.style.transform = `translate3D(0, ${Math.floor(newYCoordinate)}px, 0)`;
/** Close trash actions */
codex.toolbar.settings.hideRemoveActions();
editor.toolbar.settings.hideRemoveActions();
};
return toolbar;
})({});
toolbar.init();
module.exports = toolbar;
})({});

View file

@ -6,109 +6,104 @@
* @author Codex Team
* @version 1.0
*/
var toolbox = (function(toolbox) {
toolbox.init = function () {
let editor = codex.editor;
require('./toolbar');
};
module.exports = (function (toolbox) {
toolbox.opened = false;
/** Shows toolbox */
toolbox.open = function() {
toolbox.open = function () {
/** Close setting if toolbox is opened */
if (codex.toolbar.settings.opened) {
if (editor.toolbar.settings.opened) {
codex.toolbar.settings.close();
editor.toolbar.settings.close();
}
/** display toolbox */
codex.nodes.toolbox.classList.add('opened');
editor.nodes.toolbox.classList.add('opened');
/** Animate plus button */
codex.nodes.plusButton.classList.add('clicked');
editor.nodes.plusButton.classList.add('clicked');
/** toolbox state */
codex.toolbar.toolbox.opened = true;
editor.toolbar.toolbox.opened = true;
};
/** Closes toolbox */
toolbox.close = function() {
toolbox.close = function () {
/** Makes toolbox disapear */
codex.nodes.toolbox.classList.remove('opened');
editor.nodes.toolbox.classList.remove('opened');
/** Rotate plus button */
codex.nodes.plusButton.classList.remove('clicked');
editor.nodes.plusButton.classList.remove('clicked');
/** toolbox state */
codex.toolbar.toolbox.opened = false;
editor.toolbar.toolbox.opened = false;
};
toolbox.leaf = function(){
toolbox.leaf = function () {
var currentTool = codex.toolbar.current,
tools = Object.keys(codex.tools),
barButtons = codex.nodes.toolbarButtons,
nextToolIndex,
hiddenToolsAmount = 0,
toolToSelect;
/** Count toolbox hidden tools */
for( var tool in codex.tools ) {
if (!codex.tools[tool].displayInToolbox) {
hiddenToolsAmount ++;
}
}
let currentTool = editor.toolbar.current,
tools = Object.keys(editor.tools),
barButtons = editor.nodes.toolbarButtons,
nextToolIndex = 0,
toolToSelect,
visibleTool,
tool;
if ( !currentTool ) {
/** Get first tool from object*/
for (toolToSelect in barButtons) break;
for(tool in editor.tools) {
if (editor.tools[tool].displayInToolbox) {
break;
}
nextToolIndex ++;
}
} else {
nextToolIndex = tools.indexOf(currentTool) + 1;
visibleTool = tools[nextToolIndex];
var toolIsLastInToolbox = nextToolIndex == tools.length - (hiddenToolsAmount - 2);
while (!editor.tools[visibleTool].displayInToolbox) {
if ( toolIsLastInToolbox ) {
nextToolIndex++;
visibleTool = tools[nextToolIndex];
nextToolIndex = 0;
if ( nextToolIndex == tools.length ) {
/** getting first displayed tool */
for( var tool in codex.tools ) {
nextToolIndex = 0;
visibleTool = tools[nextToolIndex];
if (codex.tools[tool].displayInToolbox){
break;
}
nextToolIndex ++;
}
}
toolToSelect = tools[nextToolIndex];
}
toolToSelect = tools[nextToolIndex];
for ( var button in barButtons ) {
barButtons[button].classList.remove('selected');
}
for (var button in barButtons) barButtons[button].classList.remove('selected');
barButtons[toolToSelect].classList.add('selected');
codex.toolbar.current = toolToSelect;
editor.toolbar.current = toolToSelect;
};
@ -116,15 +111,15 @@ var toolbox = (function(toolbox) {
* Transforming selected node type into selected toolbar element type
* @param {event} event
*/
toolbox.toolClicked = function() {
toolbox.toolClicked = function (event) {
/**
* UNREPLACEBLE_TOOLS this types of tools are forbidden to replace even they are empty
*/
var UNREPLACEBLE_TOOLS = ['image', 'link', 'list', 'instagram', 'twitter', 'embed'],
tool = codex.tools[codex.toolbar.current],
workingNode = codex.content.currentNode,
currentInputIndex = codex.caret.inputIndex,
tool = editor.tools[editor.toolbar.current],
workingNode = editor.content.currentNode,
currentInputIndex = editor.caret.inputIndex,
newBlockContent,
appendCallback,
blockData;
@ -143,15 +138,15 @@ var toolbox = (function(toolbox) {
workingNode &&
UNREPLACEBLE_TOOLS.indexOf(workingNode.dataset.tool) === -1 &&
workingNode.textContent.trim() === ''
){
) {
/** Replace current block */
codex.content.switchBlock(workingNode, newBlockContent, tool.type);
editor.content.switchBlock(workingNode, newBlockContent, tool.type);
} else {
/** Insert new Block from plugin */
codex.content.insertBlock(blockData);
editor.content.insertBlock(blockData);
/** increase input index */
currentInputIndex++;
@ -167,10 +162,10 @@ var toolbox = (function(toolbox) {
}
setTimeout(function() {
window.setTimeout(function () {
/** Set caret to current block */
codex.caret.setToBlock(currentInputIndex);
editor.caret.setToBlock(currentInputIndex);
}, 10);
@ -178,18 +173,15 @@ var toolbox = (function(toolbox) {
/**
* Changing current Node
*/
codex.content.workingNodeChanged();
editor.content.workingNodeChanged();
/**
* Move toolbar when node is changed
*/
codex.toolbar.move();
editor.toolbar.move();
};
return toolbox;
})({});
toolbox.init();
module.exports = toolbox;
})({});

View file

@ -1,15 +0,0 @@
/**
* Codex Editor tools
* This tools will be appended in toolbox
*
* @author Codex Team
* @version 1.0
*/
var tools = (function(tools) {
return tools;
})({});
module.exports = tools;

View file

@ -5,8 +5,9 @@
* @author Codex Team
* @version 1.0
*/
let editor = codex.editor;
var transport = (function(transport){
module.exports = (function (transport) {
transport.input = null;
@ -15,47 +16,47 @@ var transport = (function(transport){
*/
transport.arguments = null;
transport.prepare = function(){
transport.prepare = function () {
var input = document.createElement('INPUT');
input.type = 'file';
input.addEventListener('change', codex.transport.fileSelected);
input.addEventListener('change', editor.transport.fileSelected);
codex.transport.input = input;
editor.transport.input = input;
};
/** Clear input when files is uploaded */
transport.clearInput = function() {
transport.clearInput = function () {
/** Remove old input */
this.input = null;
/** Prepare new one */
this.prepare();
};
/**
* Callback for file selection
* @param {Event} event
*/
transport.fileSelected = function(event){
transport.fileSelected = function () {
var input = this,
files = input.files,
filesLength = files.length,
formdData = new FormData(),
file,
i;
formdData = new FormData();
formdData.append('files', files[0], files[0].name);
codex.transport.ajax({
editor.transport.ajax({
data : formdData,
beforeSend : codex.transport.arguments.beforeSend,
success : codex.transport.arguments.success,
error : codex.transport.arguments.error
beforeSend : editor.transport.arguments.beforeSend,
success : editor.transport.arguments.success,
error : editor.transport.arguments.error
});
};
/**
@ -71,27 +72,34 @@ var transport = (function(transport){
/**
* Ajax requests module
* @todo use core.ajax
*/
transport.ajax = function(params){
transport.ajax = function (params) {
var xhr = new XMLHttpRequest(),
beforeSend = typeof params.beforeSend == 'function' ? params.beforeSend : function(){},
success = typeof params.success == 'function' ? params.success : function(){},
error = typeof params.error == 'function' ? params.error : function(){};
beforeSend = typeof params.beforeSend == 'function' ? params.beforeSend : function () {},
success = typeof params.success == 'function' ? params.success : function () {},
error = typeof params.error == 'function' ? params.error : function () {};
beforeSend();
xhr.open('POST', codex.settings.uploadImagesUrl, true);
xhr.open('POST', editor.settings.uploadImagesUrl, true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onload = function () {
if (xhr.status === 200) {
success(xhr.responseText);
} else {
console.log("request error: %o", xhr);
editor.core.log('request error: %o', xhr);
error();
}
};
xhr.send(params.data);
@ -101,6 +109,4 @@ var transport = (function(transport){
return transport;
})({});
module.exports = transport;
})({});

View file

@ -5,7 +5,9 @@
* @version 1.1
*/
var ui = (function(ui){
let editor = codex.editor;
module.exports = (function (ui) {
/**
* Basic editor classnames
@ -54,9 +56,7 @@ var ui = (function(ui){
var wrapper,
toolbar,
toolbarContent,
inlineToolbar,
redactor,
ceBlock,
notifications,
blockButtons,
blockSettings,
@ -66,30 +66,29 @@ var ui = (function(ui){
plusButton;
/** Make editor wrapper */
wrapper = codex.draw.wrapper();
wrapper = editor.draw.wrapper();
/** Append editor wrapper after initial textarea */
codex.core.insertAfter(codex.nodes.textarea, wrapper);
editor.core.insertAfter(editor.nodes.textarea, wrapper);
/** Append block with notifications to the document */
notifications = codex.draw.alertsHolder();
codex.nodes.notifications = document.body.appendChild(notifications);
notifications = editor.draw.alertsHolder();
editor.nodes.notifications = document.body.appendChild(notifications);
/** Make toolbar and content-editable redactor */
toolbar = codex.draw.toolbar();
toolbarContent = codex.draw.toolbarContent();
inlineToolbar = codex.draw.inlineToolbar();
plusButton = codex.draw.plusButton();
showSettingsButton = codex.draw.settingsButton();
showTrashButton = codex.toolbar.settings.makeRemoveBlockButton();
blockSettings = codex.draw.blockSettings();
blockButtons = codex.draw.blockButtons();
toolbox = codex.draw.toolbox();
redactor = codex.draw.redactor();
toolbar = editor.draw.toolbar();
toolbarContent = editor.draw.toolbarContent();
plusButton = editor.draw.plusButton();
showSettingsButton = editor.draw.settingsButton();
showTrashButton = editor.toolbar.settings.makeRemoveBlockButton();
blockSettings = editor.draw.blockSettings();
blockButtons = editor.draw.blockButtons();
toolbox = editor.draw.toolbox();
redactor = editor.draw.redactor();
/** settings */
var defaultSettings = codex.draw.defaultSettings(),
pluginSettings = codex.draw.pluginsSettings();
var defaultSettings = editor.draw.defaultSettings(),
pluginSettings = editor.draw.pluginsSettings();
/** Add default and plugins settings */
blockSettings.appendChild(pluginSettings);
@ -119,96 +118,103 @@ var ui = (function(ui){
wrapper.appendChild(redactor);
/** Save created ui-elements to static nodes state */
codex.nodes.wrapper = wrapper;
codex.nodes.toolbar = toolbar;
codex.nodes.plusButton = plusButton;
codex.nodes.toolbox = toolbox;
codex.nodes.blockSettings = blockSettings;
codex.nodes.pluginSettings = pluginSettings;
codex.nodes.defaultSettings = defaultSettings;
codex.nodes.showSettingsButton = showSettingsButton;
codex.nodes.showTrashButton = showTrashButton;
editor.nodes.wrapper = wrapper;
editor.nodes.toolbar = toolbar;
editor.nodes.plusButton = plusButton;
editor.nodes.toolbox = toolbox;
editor.nodes.blockSettings = blockSettings;
editor.nodes.pluginSettings = pluginSettings;
editor.nodes.defaultSettings = defaultSettings;
editor.nodes.showSettingsButton = showSettingsButton;
editor.nodes.showTrashButton = showTrashButton;
codex.nodes.redactor = redactor;
editor.nodes.redactor = redactor;
codex.ui.makeInlineToolbar(inlineToolbar);
/** Make container for inline toolbar */
editor.ui.makeInlineToolbar();
/** fill in default settings */
codex.toolbar.settings.addDefaultSettings();
editor.toolbar.settings.addDefaultSettings();
};
ui.makeInlineToolbar = function(container) {
ui.makeInlineToolbar = function () {
var container = editor.draw.inlineToolbar();
/** Append to redactor new inline block */
codex.nodes.inlineToolbar.wrapper = container;
editor.nodes.inlineToolbar.wrapper = container;
/** Draw toolbar buttons */
codex.nodes.inlineToolbar.buttons = codex.draw.inlineToolbarButtons();
editor.nodes.inlineToolbar.buttons = editor.draw.inlineToolbarButtons();
/** Buttons action or settings */
codex.nodes.inlineToolbar.actions = codex.draw.inlineToolbarActions();
editor.nodes.inlineToolbar.actions = editor.draw.inlineToolbarActions();
/** Append to inline toolbar buttons as part of it */
codex.nodes.inlineToolbar.wrapper.appendChild(codex.nodes.inlineToolbar.buttons);
codex.nodes.inlineToolbar.wrapper.appendChild(codex.nodes.inlineToolbar.actions);
editor.nodes.inlineToolbar.wrapper.appendChild(editor.nodes.inlineToolbar.buttons);
editor.nodes.inlineToolbar.wrapper.appendChild(editor.nodes.inlineToolbar.actions);
editor.nodes.wrapper.appendChild(editor.nodes.inlineToolbar.wrapper);
codex.nodes.wrapper.appendChild(codex.nodes.inlineToolbar.wrapper);
};
/**
* @private
* Append tools passed in codex.tools
* Append tools passed in editor.tools
*/
ui.addTools = function () {
var tool,
tool_button;
toolName,
toolButton;
for(var name in codex.settings.tools) {
tool = codex.settings.tools[name];
codex.tools[name] = tool;
}
for ( toolName in editor.settings.tools ) {
/** Make toolbar buttons */
for (var name in codex.tools){
tool = editor.settings.tools[toolName];
tool = codex.tools[name];
if (!tool.displayInToolbox) {
continue;
}
editor.tools[toolName] = tool;
if (!tool.iconClassname) {
codex.core.log('Toolbar icon classname missed. Tool %o skipped', 'warn', name);
editor.core.log('Toolbar icon classname missed. Tool %o skipped', 'warn', toolName);
continue;
}
if (typeof tool.render != 'function') {
codex.core.log('render method missed. Tool %o skipped', 'warn', name);
editor.core.log('render method missed. Tool %o skipped', 'warn', toolName);
continue;
}
/**
* if tools is for toolbox
*/
tool_button = codex.draw.toolbarButton(name, tool.iconClassname);
if (!tool.displayInToolbox) {
codex.nodes.toolbox.appendChild(tool_button);
continue;
} else {
/** if tools is for toolbox */
toolButton = editor.draw.toolbarButton(toolName, tool.iconClassname);
editor.nodes.toolbox.appendChild(toolButton);
editor.nodes.toolbarButtons[toolName] = toolButton;
}
/** Save tools to static nodes */
codex.nodes.toolbarButtons[name] = tool_button;
}
/**
* Add inline toolbar tools
*/
codex.ui.addInlineToolbarTools();
editor.ui.addInlineToolbarTools();
};
ui.addInlineToolbarTools = function() {
ui.addInlineToolbarTools = function () {
var tools = {
@ -240,13 +246,14 @@ var ui = (function(ui){
tool = tools[name];
toolButton = codex.draw.toolbarButtonInline(name, tool.icon);
toolButton = editor.draw.toolbarButtonInline(name, tool.icon);
codex.nodes.inlineToolbar.buttons.appendChild(toolButton);
editor.nodes.inlineToolbar.buttons.appendChild(toolButton);
/**
* Add callbacks to this buttons
*/
codex.ui.setInlineToolbarButtonBehaviour(toolButton, tool.command);
editor.ui.setInlineToolbarButtonBehaviour(toolButton, tool.command);
}
};
@ -257,45 +264,47 @@ var ui = (function(ui){
*/
ui.bindEvents = function () {
codex.core.log('ui.bindEvents fired', 'info');
editor.core.log('ui.bindEvents fired', 'info');
// window.addEventListener('error', function (errorMsg, url, lineNumber) {
// codex.notifications.errorThrown(errorMsg, event);
// editor.notifications.errorThrown(errorMsg, event);
// }, false );
/** All keydowns on Document */
document.addEventListener('keydown', codex.callback.globalKeydown, false );
document.addEventListener('keydown', editor.callback.globalKeydown, false );
/** All keydowns on Redactor zone */
codex.nodes.redactor.addEventListener('keydown', codex.callback.redactorKeyDown, false);
editor.nodes.redactor.addEventListener('keydown', editor.callback.redactorKeyDown, false);
/** All keydowns on Document */
document.addEventListener('keyup', codex.callback.globalKeyup, false );
document.addEventListener('keyup', editor.callback.globalKeyup, false );
/**
* Mouse click to radactor
*/
codex.nodes.redactor.addEventListener('click', codex.callback.redactorClicked, false );
editor.nodes.redactor.addEventListener('click', editor.callback.redactorClicked, false );
/**
* Clicks to the Plus button
*/
codex.nodes.plusButton.addEventListener('click', codex.callback.plusButtonClicked, false);
editor.nodes.plusButton.addEventListener('click', editor.callback.plusButtonClicked, false);
/**
* Clicks to SETTINGS button in toolbar
*/
codex.nodes.showSettingsButton.addEventListener('click', codex.callback.showSettingsButtonClicked, false );
editor.nodes.showSettingsButton.addEventListener('click', editor.callback.showSettingsButtonClicked, false );
/**
* @deprecated ( but now in use for syncronization );
* Any redactor changes: keyboard input, mouse cut/paste, drag-n-drop text
*/
codex.nodes.redactor.addEventListener('input', codex.callback.redactorInputEvent, false );
// editor.nodes.redactor.addEventListener('input', editor.callback.redactorInputEvent, false );
/** Bind click listeners on toolbar buttons */
for (var button in codex.nodes.toolbarButtons){
codex.nodes.toolbarButtons[button].addEventListener('click', codex.callback.toolbarButtonClicked, false);
for (var button in editor.nodes.toolbarButtons) {
editor.nodes.toolbarButtons[button].addEventListener('click', editor.callback.toolbarButtonClicked, false);
}
};
@ -305,42 +314,47 @@ var ui = (function(ui){
* Ex. Load scripts or call some internal methods
* @return Promise
*/
ui.preparePlugins = function() {
ui.preparePlugins = function () {
return new Promise(function(resolve, reject){
return new Promise(function (resolve, reject) {
let pluginName,
plugin;
for ( pluginName in codex.tools ) {
for ( pluginName in editor.tools ) {
plugin = codex.tools[pluginName];
plugin = editor.tools[pluginName];
if (typeof plugin.prepare != 'function') {
if (typeof plugin.prepare != 'function'){
continue;
}
plugin.prepare(plugin.config || {}).then(function(){
plugin.prepare(plugin.config || {}).then(function () {
resolve();
}).catch(function(error){
}).catch(function (error) {
reject(error);
});
}
});
};
ui.addBlockHandlers = function(block) {
ui.addBlockHandlers = function (block) {
if (!block) return;
/**
* Block keydowns
*/
block.addEventListener('keydown', function(event) {
codex.callback.blockKeydown(event, block);
}, false);
block.addEventListener('keydown', editor.callback.blockKeydown, false);
/**
* Pasting content from another source
@ -348,74 +362,73 @@ var ui = (function(ui){
* First - uses deep-first search algorithm to get sub nodes,
* sanitizes whole Block_content and replaces cleared nodes
* This method is deprecated
* Method is used in codex.callback.blockPaste(event)
* Method is used in editor.callback.blockPaste(event)
*
* Secont - uses Mutation observer.
* Observer "observe" DOM changes and send changings to callback.
* Callback gets changed node, not whole Block_content.
* Inserted or changed node, which we've gotten have been cleared and replaced with diry node
*
* Method is used in codex.callback.blockPasteViaSanitize(event)
* Method is used in editor.callback.blockPasteViaSanitize(event)
*
* @uses html-janitor
* @example codex.callback.blockPasteViaSanitize(event), the second method.
* @example editor.callback.blockPasteViaSanitize(event), the second method.
*
*/
block.addEventListener('paste', codex.callback.blockPasteCallback, false);
block.addEventListener('paste', editor.callback.blockPasteCallback, false);
block.addEventListener('mouseup', function(){
codex.toolbar.inline.show();
}, false);
block.addEventListener('mouseup', editor.toolbar.inline.show, false);
};
/** getting all contenteditable elements */
ui.saveInputs = function() {
ui.saveInputs = function () {
var redactor = codex.nodes.redactor,
elements = [];
var redactor = editor.nodes.redactor;
/** Save all inputs in global variable state */
codex.state.inputs = redactor.querySelectorAll('[contenteditable], input');
editor.state.inputs = redactor.querySelectorAll('[contenteditable], input');
};
/**
* Adds first initial block on empty redactor
*/
ui.addInitialBlock = function(){
ui.addInitialBlock = function () {
var initialBlockType = codex.settings.initialBlockPlugin,
var initialBlockType = editor.settings.initialBlockPlugin,
initialBlock;
if ( !codex.tools[initialBlockType] ){
codex.core.log('Plugin %o was not implemented and can\'t be used as initial block', 'warn', initialBlockType);
if ( !editor.tools[initialBlockType] ) {
editor.core.log('Plugin %o was not implemented and can\'t be used as initial block', 'warn', initialBlockType);
return;
}
initialBlock = codex.tools[initialBlockType].render();
initialBlock = editor.tools[initialBlockType].render();
initialBlock.setAttribute('data-placeholder', 'Расскажите свою историю...');
codex.content.insertBlock({
editor.content.insertBlock({
type : initialBlockType,
block : initialBlock
});
codex.content.workingNodeChanged(initialBlock);
editor.content.workingNodeChanged(initialBlock);
};
ui.setInlineToolbarButtonBehaviour = function(button, type) {
ui.setInlineToolbarButtonBehaviour = function (button, type) {
button.addEventListener('mousedown', function(event) {
button.addEventListener('mousedown', function (event) {
codex.toolbar.inline.toolClicked(event, type);
editor.toolbar.inline.toolClicked(event, type);
}, false);
};
return ui;
})({});
module.exports = ui;
})({});

View file

@ -12,9 +12,9 @@ var code = (function(code) {
* @param {object} JSON with block data
* @return {Element} element to append
*/
code.make = function (data) {
var make_ = function (data) {
var tag = codex.draw.node('CODE', [baseClass], {});
var tag = codex.editor.draw.node('CODE', [baseClass], {});
if (data && data.text) {
tag.innerHTML = data.text;
@ -30,7 +30,7 @@ var code = (function(code) {
*/
code.render = function (data) {
return codeTool.make(data);
return make_(data);
};
/**

View file

@ -7,9 +7,9 @@ var embed = function(embed){
var methods = {
addInternal: function (content) {
codex.content.switchBlock(codex.content.currentNode, content, 'video_extended');
codex.editor.content.switchBlock(codex.editor.content.currentNode, content, 'video_extended');
var blockContent = codex.content.currentNode.childNodes[0];
var blockContent = codex.editor.content.currentNode.childNodes[0];
blockContent.classList.add('embed__loader');
setTimeout(function(){

View file

@ -31,18 +31,18 @@ var header = (function(header) {
var old_header, new_header;
/** Now current header stored as a currentNode */
old_header = codex.content.currentNode.querySelector('[contentEditable]');
old_header = codex.editor.content.currentNode.querySelector('[contentEditable]');
/** Making new header */
new_header = codex.draw.node(type, ['ce-header'], { innerHTML : old_header.innerHTML });
new_header = codex.editor.draw.node(type, ['ce-header'], { innerHTML : old_header.innerHTML });
new_header.contentEditable = true;
new_header.setAttribute('data-placeholder', 'Заголовок');
new_header.dataset.headerData = type;
codex.content.switchBlock(old_header, new_header, 'heading_styled');
codex.editor.content.switchBlock(old_header, new_header, 'heading_styled');
/** Close settings after replacing */
codex.toolbar.settings.close();
codex.editor.toolbar.settings.close();
}
};
@ -128,7 +128,7 @@ var header = (function(header) {
*/
header.makeSettings = function () {
var holder = codex.draw.node('DIV', ['ce_plugin_header--settings'], {} ),
var holder = codex.editor.draw.node('DIV', ['ce_plugin_header--settings'], {} ),
types = {
h2: 'Заголовок H2',
h3: 'Заголовок H3',
@ -139,7 +139,7 @@ var header = (function(header) {
/** Now add type selectors */
for (var type in types){
selectTypeButton = codex.draw.node('SPAN', ['ce_plugin_header--select_button'], { textContent : types[type] });
selectTypeButton = codex.editor.draw.node('SPAN', ['ce_plugin_header--select_button'], { textContent : types[type] });
methods_.addSelectTypeClickListener(selectTypeButton, type);
holder.appendChild(selectTypeButton);

View file

@ -225,7 +225,7 @@ var image = (function(image) {
error = uploadingCallbacks_.ByClick.error;
/** Define callbacks */
codex.transport.selectAndUpload({
codex.editor.transport.selectAndUpload({
beforeSend: beforeSend,
success: success,
error: error
@ -254,7 +254,7 @@ var image = (function(image) {
toggleBordered : function(type, clickedSettingsItem ) {
var current = codex.content.currentNode,
var current = codex.editor.content.currentNode,
blockContent = current.childNodes[0],
img = ui_.getImage(current),
wrapper = current.querySelector('.' + elementClasses_.imageWrapper);
@ -279,14 +279,14 @@ var image = (function(image) {
}
setTimeout(function() {
codex.toolbar.settings.close();
codex.editor.toolbar.settings.close();
}, 200);
},
toggleStretched : function( type, clickedSettingsItem ) {
var current = codex.content.currentNode,
var current = codex.editor.content.currentNode,
blockContent = current.childNodes[0],
img = ui_.getImage(current),
wrapper = current.querySelector('.' + elementClasses_.imageWrapper);
@ -313,7 +313,7 @@ var image = (function(image) {
}
setTimeout(function() {
codex.toolbar.settings.close();
codex.editor.toolbar.settings.close();
}, 200);
}
@ -332,7 +332,7 @@ var image = (function(image) {
*/
beforeSend : function() {
var input = codex.transport.input,
var input = codex.editor.transport.input,
files = input.files;
var validFileExtensions = ["jpg", "jpeg", "bmp", "gif", "png"];
@ -369,7 +369,7 @@ var image = (function(image) {
var newImage = make_(data);
codex.content.switchBlock(image.holder, newImage, 'image_extended');
codex.editor.content.switchBlock(image.holder, newImage, 'image_extended');
newImage.classList.add(elementClasses_.imagePreview);
/**
@ -385,7 +385,7 @@ var image = (function(image) {
var parsed = JSON.parse(result),
data,
currentBlock = codex.content.currentNode;
currentBlock = codex.editor.content.currentNode;
/**
* Preparing {Object} data to draw an image
@ -414,7 +414,7 @@ var image = (function(image) {
var oldHolder = image.holder;
var form = ui_.makeForm();
codex.content.switchBlock(oldHolder, form, 'image_extended');
codex.editor.content.switchBlock(oldHolder, form, 'image_extended');
}
},
@ -431,7 +431,7 @@ var image = (function(image) {
var ajaxUrl = image.config.uploadUrl,
file,
image_plugin,
current = codex.content.currentNode,
current = codex.editor.content.currentNode,
beforeSend,
success_callback;
@ -473,13 +473,13 @@ var image = (function(image) {
cover: null
};
image_plugin = codex.tools.image_extended.render(data);
image_plugin = codex.editor.tools.image_extended.render(data);
image_plugin.classList.add(elementClasses_.imagePreview);
var img = image_plugin.querySelector('img');
codex.content.switchBlock(codex.content.currentNode, image_plugin, 'image_extended');
codex.editor.content.switchBlock(codex.editor.content.currentNode, image_plugin, 'image_extended');
};
@ -494,7 +494,7 @@ var image = (function(image) {
success : success_callback
};
codex.core.ajax(data);
codex.editor.core.ajax(data);
}
}
@ -635,7 +635,7 @@ var image = (function(image) {
*/
image.makeSettings = function () {
var currentNode = codex.content.currentNode,
var currentNode = codex.editor.content.currentNode,
wrapper = currentNode.querySelector('.' + elementClasses_.imageWrapper),
holder = document.createElement('DIV'),
types = {

View file

@ -8,7 +8,7 @@ var instagram = (function(instagram) {
render : function(content) {
codex.content.switchBlock(codex.content.currentNode, content, 'instagram');
codex.editor.content.switchBlock(codex.editor.content.currentNode, content, 'instagram');
setTimeout(function() {
window.instgrm.Embeds.process();
@ -24,10 +24,10 @@ var instagram = (function(instagram) {
*/
instagramBlock : function(url) {
var blockquote = codex.draw.node('BLOCKQUOTE', 'instagram-media instagram', {}),
div = codex.draw.node('DIV', '', {}),
paragraph = codex.draw.node('P', 'ce-paste__instagram--p', {}),
anchor = codex.draw.node('A', '', { href : url });
var blockquote = codex.editor.draw.node('BLOCKQUOTE', 'instagram-media instagram', {}),
div = codex.editor.draw.node('DIV', '', {}),
paragraph = codex.editor.draw.node('P', 'ce-paste__instagram--p', {}),
anchor = codex.editor.draw.node('A', '', { href : url });
blockquote.dataset.instgrmVersion = 4;
@ -48,7 +48,7 @@ var instagram = (function(instagram) {
return new Promise(function(resolve, reject){
codex.core.importScript("https://platform.instagram.com/en_US/embeds.js", 'instagram-api').then(function(){
codex.editor.core.importScript("https://platform.instagram.com/en_US/embeds.js", 'instagram-api').then(function(){
resolve();
}).catch(function(){
reject(Error('Instagram API was not loaded'));

View file

@ -206,7 +206,7 @@ var link = (function(link) {
block.classList.add(settings.elementClasses.error);
codex.core.log('Error while doing things with link paste: %o', 'error', error);
codex.editor.core.log('Error while doing things with link paste: %o', 'error', error);
});
},

View file

@ -58,7 +58,7 @@ var list = (function(list) {
*/
changeBlockStyle : function (event, blockType) {
var currentBlock = codex.content.currentNode,
var currentBlock = codex.editor.content.currentNode,
newEditable = ui.make(blockType),
oldEditable = currentBlock.querySelector("[contenteditable]");
@ -66,7 +66,7 @@ var list = (function(list) {
newEditable.innerHTML = oldEditable.innerHTML;
newEditable.classList.add('ce-list');
codex.content.switchBlock(currentBlock, newEditable, 'list');
codex.editor.content.switchBlock(currentBlock, newEditable, 'list');
}
};
@ -163,12 +163,12 @@ var list = (function(list) {
orderedButton.addEventListener('click', function (event) {
methods.changeBlockStyle(event, 'OL');
codex.toolbar.settings.close();
codex.editor.toolbar.settings.close();
});
unorderedButton.addEventListener('click', function (event) {
methods.changeBlockStyle(event, 'UL');
codex.toolbar.settings.close();
codex.editor.toolbar.settings.close();
});
holder.appendChild(orderedButton);

View file

@ -16,7 +16,7 @@ var paragraph = (function(paragraph) {
var make_ = function (data) {
/** Create Empty DIV */
var tag = codex.draw.node('DIV', ['ce-paragraph'], {});
var tag = codex.editor.draw.node('DIV', ['ce-paragraph'], {});
if (data && data.text) {
tag.innerHTML = data.text;
@ -30,7 +30,7 @@ var paragraph = (function(paragraph) {
* If pasted URL from instagram, twitter or Image
* it renders via Social widgets content or uploads image and uses Image tool to render
*/
tag.addEventListener('paste', codex.tools.paste.callbacks, false);
tag.addEventListener('paste', codex.editor.tools.paste.callbacks, false);
return tag;
@ -88,7 +88,7 @@ var paragraph = (function(paragraph) {
*/
paragraph.save = function (blockContent){
var wrappedText = codex.content.wrapTextWithParagraphs(blockContent.innerHTML);
var wrappedText = codex.editor.content.wrapTextWithParagraphs(blockContent.innerHTML);
var data = {
"text": wrappedText,

View file

@ -56,7 +56,7 @@ var quote = (function(quote) {
changeStyleClicked : function() {
var changeStyleButton = this,
quote = codex.content.currentNode.querySelector('.' + elementClasses_.ce_quote),
quote = codex.editor.content.currentNode.querySelector('.' + elementClasses_.ce_quote),
newStyle = changeStyleButton.dataset.style,
styleSelectors = this.parentNode.childNodes;
@ -112,13 +112,13 @@ var quote = (function(quote) {
var parsedOldQuote = methods_.parseBlockQuote(),
newStyledQuote = quoteStyle(parsedOldQuote);
var wrapper = codex.content.composeNewBlock(newStyledQuote, 'quote');
var wrapper = codex.editor.content.composeNewBlock(newStyledQuote, 'quote');
wrapper.appendChild(newStyledQuote);
codex.content.switchBlock(codex.content.currentNode, newStyledQuote, 'quote');
codex.editor.content.switchBlock(codex.editor.content.currentNode, newStyledQuote, 'quote');
/** Close settings after replacing */
codex.toolbar.settings.close();
codex.editor.toolbar.settings.close();
}, false);
@ -227,7 +227,7 @@ var quote = (function(quote) {
parseBlockQuote : function(block) {
var currentNode = block || codex.content.currentNode,
var currentNode = block || codex.editor.content.currentNode,
photo = currentNode.getElementsByTagName('img')[0],
author = currentNode.querySelector('.' + elementClasses_.quoteAuthor),
job = currentNode.querySelector('.' + elementClasses_.authorsJob),
@ -271,7 +271,7 @@ var quote = (function(quote) {
success = photoUploadingCallbacks_.success,
error = photoUploadingCallbacks_.error;
codex.transport.selectAndUpload({
codex.editor.transport.selectAndUpload({
beforeSend: beforeSend,
success: success,
error: error
@ -339,7 +339,7 @@ var quote = (function(quote) {
preview_ : function(e) {
var uploadImageWrapper = codex.content.currentNode.querySelector('.' + elementClasses_.withPhoto.photo),
var uploadImageWrapper = codex.editor.content.currentNode.querySelector('.' + elementClasses_.withPhoto.photo),
authorsPhoto = ui_.img(elementClasses_.authorsPhoto);
/** Appending uploaded image */
@ -355,7 +355,7 @@ var quote = (function(quote) {
beforeSend : function() {
var input = codex.transport.input,
var input = codex.editor.transport.input,
files = input.files,
file = files[0],
fileReader = new FileReader();
@ -374,7 +374,7 @@ var quote = (function(quote) {
var parsed = JSON.parse(result),
filename = parsed.filename,
uploadImageWrapper = codex.content.currentNode.querySelector('.' + elementClasses_.withPhoto.photo);
uploadImageWrapper = codex.editor.content.currentNode.querySelector('.' + elementClasses_.withPhoto.photo);
var img = uploadImageWrapper.querySelector('IMG');
img.src = parsed.data.file.bigUrl;
@ -445,7 +445,7 @@ var quote = (function(quote) {
}
/** Make paragraphs */
data.text = codex.content.wrapTextWithParagraphs(data.text);
data.text = codex.editor.content.wrapTextWithParagraphs(data.text);
return data;
};

View file

@ -43,9 +43,9 @@ var twitter = (function(twitter) {
tweet.classList.add('ce-redactor__loader');
if (codex.content.currentNode) {
if (codex.editor.content.currentNode) {
tweet.dataset.statusUrl = data.status_url;
codex.content.switchBlock(codex.content.currentNode, tweet, 'tweet');
codex.editor.content.switchBlock(codex.editor.content.currentNode, tweet, 'tweet');
}
/**
@ -53,7 +53,7 @@ var twitter = (function(twitter) {
*/
if ( !data.user ) {
codex.core.ajax({
codex.editor.core.ajax({
url : config_.fetchUrl + '?tweetId=' + data.id_str,
type: "GET",
success: function(result) {
@ -99,12 +99,12 @@ var twitter = (function(twitter) {
},
drawTwitterBlock : function() {
var block = codex.draw.node('DIV', '', { height: "20px" });
var block = codex.editor.draw.node('DIV', '', { height: "20px" });
return block;
},
drawTwittersCaptionBlock : function() {
var block = codex.draw.node('DIV', ['ce-twitter__caption'], { contentEditable : true });
var block = codex.editor.draw.node('DIV', ['ce-twitter__caption'], { contentEditable : true });
return block;
},
@ -167,7 +167,7 @@ var twitter = (function(twitter) {
return new Promise(function(resolve, reject){
codex.core.importScript("https://platform.twitter.com/widgets.js", 'twitter-api').then(function(){
codex.editor.core.importScript("https://platform.twitter.com/widgets.js", 'twitter-api').then(function(){
resolve();
}).catch(function(){
reject(Error('Twitter API was not loaded'));

View file

@ -1,116 +0,0 @@
{
"data":[
{
"type":"text",
"data":{
"text":"<p>It's a text. It can be with <a href=\"http:\/\/tj.local\/redirect?url=http%3A%2F%2Fya.ru\" target=\"_blank\">link<\/a>. And <b>bold<\/b> and <i>italic.<\/i><\/p><p>We can use br here.<\/p><p>and paragraphs<\/p>",
"format":"html",
"introText":"<<<same>>>"
}
},
{
"type":"heading_styled",
"data":{
"text":"Header",
"format":"html",
"heading-styles":"h2"
}
},
{
"type":"heading_styled",
"data":{
"text":"little header",
"format":"html",
"heading-styles":"h4"
}
},
{
"type":"link_embed",
"data":{
"title":"",
"description":"",
"image":"",
"url":"https:\/\/new.vk.com\/feed"
}
},
{
"type":"image_extended",
"data":{
"background":false,
"border":false,
"isstretch":false,
"file":{
"url":"https:\/\/static39.cmtt.ru\/club\/66\/13\/cb\/3165d72648b97e.jpg",
"bigUrl":"https:\/\/static35.cmtt.ru\/club\/66\/88\/1b\/d990e3f617eb9b.jpg",
"width":1200,
"height":750,
"additionalData":"null"
},
"caption":"It's a caption. It will have b, i and a tags in future",
"cover":false
}
},
{
"type":"gallery",
"data":{
"background":false,
"border":false,
"isstretch":false,
"files":[
{
"url":"https:\/\/static39.cmtt.ru\/club\/7c\/f1\/ed\/6b139e871d1bce.jpg",
"bigUrl":"https:\/\/static36.cmtt.ru\/club\/4b\/40\/e8\/8c7e9d6941948c.jpg",
"width":1080,
"height":1080,
"caption":"caption1"
},
{
"url":"https:\/\/static35.cmtt.ru\/club\/e7\/ec\/6b\/c43f8f0f694341.jpg",
"bigUrl":"https:\/\/static35.cmtt.ru\/club\/53\/b2\/d2\/a633e11246a1bb.jpg",
"width":1200,
"height":1200,
"caption":"caption2"
}
]
}
},
{
"type":"video_extended",
"data":{
"source":"youtube",
"remote_id":"SqmAjcAPBpA",
"thumbnailUrl":"http:\/\/tj.local\/preview\/youtube\/SqmAjcAPBpA",
"time":0,
"width":800,
"height":450
}
},
{
"type":"quote_styled",
"data":{
"text":"<p>Quote <a href=\"http:\/\/tj.local\/redirect?url=http%3A%2F%2Fya.ru\" target=\"_blank\">text<\/a><\/p><p>Bold <i>etc<\/i><\/p>",
"format":"html",
"cite":"Author",
"size":"small"
}
},
{
"type":"tweet",
"data":{
"media":true,
"conversation":false,
"user":{
"profile_image_url":"http:\/\/pbs.twimg.com\/profile_images\/1817165982\/nikita-likhachev-512_normal.jpg",
"profile_image_url_https":"https:\/\/pbs.twimg.com\/profile_images\/1817165982\/nikita-likhachev-512_normal.jpg",
"screen_name":"Niketas",
"name":"Никита Лихачёв"
},
"id":747793978511101953,
"text":"ВНИМАНИЕ ЧИТАТЬ ВСЕМ НЕ ДАЙ БОГ ПРОПУСТИТЕ НУ ИЛИ ХОТЯ БЫ КЛИКНИ И ПОДОЖДИ 15 СЕКУНД https:\/\/t.co\/iWyOHf4xr2",
"created_at":"Tue Jun 28 14:09:12 +0000 2016",
"status_url":"https:\/\/twitter.com\/Niketas\/status\/747793978511101953",
"caption":"Caption"
}
}
]
}

View file

@ -27,11 +27,11 @@ module.exports = {
entry: {
"whatwg-fetch": "whatwg-fetch",
"codex-editor": "./index"
"codex-editor": "./codex"
},
output: {
filename: "[name].js",
library: ["codex"]
library: ["codex","editor"]
},
watch: true,
@ -55,10 +55,19 @@ module.exports = {
},
plugins: [
/** Pass variables into modules */
new webpack.DefinePlugin({
NODE_ENV: JSON.stringify(NODE_ENV),
VERSION: JSON.stringify(VERSION)
})
}),
/** Минифицируем CSS и JS */
new webpack.optimize.UglifyJsPlugin(),
/** Block biuld if errors found */
new webpack.NoErrorsPlugin(),
],
module : {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long