2017-01-10 19:22:40 +01:00
|
|
|
/**
|
|
|
|
* Codex Editor callbacks module
|
|
|
|
*
|
|
|
|
* @author Codex Team
|
2017-02-02 14:58:05 +01:00
|
|
|
* @version 1.3.7
|
2017-01-10 19:22:40 +01:00
|
|
|
*/
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
module.exports = (function (callbacks) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-13 18:54:18 +01:00
|
|
|
let editor = codex.editor;
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.globalKeydown = function (event) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
switch (event.keyCode) {
|
|
|
|
case editor.core.keys.ENTER : editor.callback.enterKeyPressed(event); break;
|
2017-01-10 19:22:40 +01:00
|
|
|
}
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2017-01-10 19:22:40 +01:00
|
|
|
};
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.redactorKeyDown = function (event) {
|
|
|
|
|
|
|
|
switch (event.keyCode) {
|
|
|
|
case editor.core.keys.TAB : editor.callback.tabKeyPressed(event); break;
|
|
|
|
case editor.core.keys.ENTER : editor.callback.enterKeyPressedOnRedactorZone(event); break;
|
|
|
|
case editor.core.keys.ESC : editor.callback.escapeKeyPressed(event); break;
|
|
|
|
default : editor.callback.defaultKeyPressed(event); break;
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
};
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.globalKeyup = function (event) {
|
|
|
|
|
|
|
|
switch (event.keyCode) {
|
|
|
|
case editor.core.keys.UP :
|
|
|
|
case editor.core.keys.LEFT :
|
|
|
|
case editor.core.keys.RIGHT :
|
|
|
|
case editor.core.keys.DOWN : editor.callback.arrowKeyPressed(event); break;
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
};
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.tabKeyPressed = function (event) {
|
|
|
|
|
2017-02-16 23:15:23 +01:00
|
|
|
var blockIsEmpty = !editor.content.currentNode.textContent.trim();
|
|
|
|
|
|
|
|
if (!blockIsEmpty) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !editor.toolbar.opened ) {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
|
|
|
editor.toolbar.open();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
if (editor.toolbar.opened && !editor.toolbar.toolbox.opened) {
|
|
|
|
|
|
|
|
editor.toolbar.toolbox.open();
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
} else {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
|
|
|
editor.toolbar.toolbox.leaf();
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
event.preventDefault();
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
};
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
/**
|
|
|
|
* @param {Event} event
|
|
|
|
*/
|
|
|
|
callbacks.enterKeyPressed = function () {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
if (editor.content.editorAreaHightlighted) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* it means that we lose input index, saved index before is not correct
|
|
|
|
* therefore we need to set caret when we insert new block
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.caret.inputIndex = -1;
|
|
|
|
|
|
|
|
editor.callback.enterPressedOnBlock();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
}
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2017-01-10 19:22:40 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ENTER key handler
|
|
|
|
* Makes new paragraph block
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.enterKeyPressedOnRedactorZone = function (event) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
if (event.target.contentEditable == 'true') {
|
|
|
|
|
|
|
|
/** Update input index */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.caret.saveCurrentInputIndex();
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
var currentInputIndex = editor.caret.getCurrentInputIndex() || 0,
|
|
|
|
workingNode = editor.content.currentNode,
|
2016-12-07 19:25:31 +01:00
|
|
|
tool = workingNode.dataset.tool,
|
2017-02-01 18:25:59 +01:00
|
|
|
isEnterPressedOnToolbar = editor.toolbar.opened &&
|
|
|
|
editor.toolbar.current &&
|
|
|
|
event.target == editor.state.inputs[currentInputIndex];
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** The list of tools which needs the default browser behaviour */
|
2017-02-01 18:25:59 +01:00
|
|
|
var enableLineBreaks = editor.tools[tool].enableLineBreaks;
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** This type of block creates when enter is pressed */
|
2017-02-01 18:25:59 +01:00
|
|
|
var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin;
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* When toolbar is opened, select tool instead of making new paragraph
|
|
|
|
*/
|
|
|
|
if ( isEnterPressedOnToolbar ) {
|
|
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.toolbox.toolClicked(event);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.close();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-01-10 19:22:40 +01:00
|
|
|
/**
|
|
|
|
* Stop other listeners callback executions
|
|
|
|
*/
|
|
|
|
event.stopPropagation();
|
|
|
|
event.stopImmediatePropagation();
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-01-20 19:25:28 +01:00
|
|
|
* Allow paragraph lineBreaks with shift enter
|
|
|
|
* Or if shiftkey pressed and enter and enabledLineBreaks, the let new block creation
|
2016-12-07 19:25:31 +01:00
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
if ( event.shiftKey || enableLineBreaks ) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-01-20 19:25:28 +01:00
|
|
|
event.stopPropagation();
|
|
|
|
event.stopImmediatePropagation();
|
2016-12-07 19:25:31 +01:00
|
|
|
return;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
var currentSelection = window.getSelection(),
|
2016-12-07 19:25:31 +01:00
|
|
|
currentSelectedNode = currentSelection.anchorNode,
|
2017-02-01 18:25:59 +01:00
|
|
|
caretAtTheEndOfText = editor.caret.position.atTheEnd(),
|
2016-12-07 19:25:31 +01:00
|
|
|
isTextNodeHasParentBetweenContenteditable = false;
|
|
|
|
|
2017-01-20 19:25:28 +01:00
|
|
|
/**
|
|
|
|
* Allow making new <p> in same block by SHIFT+ENTER and forbids to prevent default browser behaviour
|
|
|
|
*/
|
2017-01-25 17:32:14 +01:00
|
|
|
if ( event.shiftKey && !enableLineBreaks ) {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
|
|
|
editor.callback.enterPressedOnBlock(editor.content.currentBlock, event);
|
2017-01-20 19:25:28 +01:00
|
|
|
event.preventDefault();
|
|
|
|
return;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2017-01-20 19:25:28 +01:00
|
|
|
}
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
/**
|
|
|
|
* Workaround situation when caret at the Text node that has some wrapper Elements
|
|
|
|
* Split block cant handle this.
|
|
|
|
* We need to save default behavior
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
isTextNodeHasParentBetweenContenteditable = currentSelectedNode && currentSelectedNode.parentNode.contentEditable != 'true';
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Split blocks when input has several nodes and caret placed in textNode
|
|
|
|
*/
|
|
|
|
if (
|
2017-02-01 18:25:59 +01:00
|
|
|
currentSelectedNode.nodeType == editor.core.nodeTypes.TEXT &&
|
2016-12-07 19:25:31 +01:00
|
|
|
!isTextNodeHasParentBetweenContenteditable &&
|
|
|
|
!caretAtTheEndOfText
|
2017-02-01 18:25:59 +01:00
|
|
|
) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.core.log('Splitting Text node...');
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.content.splitBlock(currentInputIndex);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** Show plus button when next input after split is empty*/
|
2017-02-01 18:25:59 +01:00
|
|
|
if (!editor.state.inputs[currentInputIndex + 1].textContent.trim()) {
|
|
|
|
|
|
|
|
editor.toolbar.showPlusButton();
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
var islastNode = editor.content.isLastNode(currentSelectedNode);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-01-20 19:25:28 +01:00
|
|
|
if ( islastNode && caretAtTheEndOfText ) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
event.preventDefault();
|
2017-01-20 19:25:28 +01:00
|
|
|
event.stopPropagation();
|
|
|
|
event.stopImmediatePropagation();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.core.log('ENTER clicked in last textNode. Create new BLOCK');
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.content.insertBlock({
|
2017-01-20 19:25:28 +01:00
|
|
|
type: NEW_BLOCK_TYPE,
|
2017-02-01 18:25:59 +01:00
|
|
|
block: editor.tools[NEW_BLOCK_TYPE].render()
|
2017-01-20 19:25:28 +01:00
|
|
|
}, true);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.move();
|
|
|
|
editor.toolbar.open();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** Show plus button with empty block */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.showPlusButton();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/** get all inputs after new appending block */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.ui.saveInputs();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.escapeKeyPressed = function (event) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** Close all toolbar */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.close();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** Close toolbox */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.toolbox.close();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
/**
|
|
|
|
* @param {Event} event
|
|
|
|
*/
|
|
|
|
callbacks.arrowKeyPressed = function () {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.content.workingNodeChanged();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/* Closing toolbar */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.close();
|
|
|
|
editor.toolbar.move();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
/**
|
|
|
|
* @param {Event} event
|
|
|
|
*/
|
|
|
|
callbacks.defaultKeyPressed = function () {
|
|
|
|
|
|
|
|
editor.toolbar.close();
|
|
|
|
|
|
|
|
if (!editor.toolbar.inline.actionsOpened) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.inline.close();
|
|
|
|
editor.content.clearMark();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
}
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
callbacks.redactorClicked = function (event) {
|
|
|
|
|
2017-01-10 19:22:40 +01:00
|
|
|
callbacks.detectWhenClickedOnFirstLevelBlockArea();
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.content.workingNodeChanged(event.target);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.ui.saveInputs();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
var selectedText = editor.toolbar.inline.getSelectionText(),
|
|
|
|
firstLevelBlock;
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* If selection range took off, then we hide inline toolbar
|
|
|
|
*/
|
|
|
|
if (selectedText.length === 0) {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
|
|
|
editor.toolbar.inline.close();
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Update current input index in memory when caret focused into existed input */
|
|
|
|
if (event.target.contentEditable == 'true') {
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.caret.saveCurrentInputIndex();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
if (editor.content.currentNode === null) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* If inputs in redactor does not exits, then we put input index 0 not -1
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
var indexOfLastInput = editor.state.inputs.length > 0 ? editor.state.inputs.length - 1 : 0;
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** If we have any inputs */
|
2017-02-01 18:25:59 +01:00
|
|
|
if (editor.state.inputs.length) {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @todo Refactor
|
|
|
|
*/
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** getting firstlevel parent of input */
|
2017-02-01 18:25:59 +01:00
|
|
|
firstLevelBlock = editor.content.getFirstLevelBlock(editor.state.inputs[indexOfLastInput]);
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/** If input is empty, then we set caret to the last input */
|
2017-02-01 18:25:59 +01:00
|
|
|
if (editor.state.inputs.length && editor.state.inputs[indexOfLastInput].textContent === '' && firstLevelBlock.dataset.tool == editor.settings.initialBlockPlugin) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.caret.setToBlock(indexOfLastInput);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/** Create new input when caret clicked in redactors area */
|
2017-02-01 18:25:59 +01:00
|
|
|
var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin;
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.content.insertBlock({
|
2016-12-07 19:25:31 +01:00
|
|
|
type : NEW_BLOCK_TYPE,
|
2017-02-01 18:25:59 +01:00
|
|
|
block : editor.tools[NEW_BLOCK_TYPE].render()
|
2016-12-07 19:25:31 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
/** If there is no inputs except inserted */
|
2017-02-01 18:25:59 +01:00
|
|
|
if (editor.state.inputs.length === 1) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.caret.setToBlock(indexOfLastInput);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/** Set caret to this appended input */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.caret.setToNextBlock(indexOfLastInput);
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Move toolbar to the right position and open
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.move();
|
|
|
|
editor.toolbar.open();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Move toolbar to the new position and open
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.move();
|
|
|
|
editor.toolbar.open();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** Close all panels */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.settings.close();
|
|
|
|
editor.toolbar.toolbox.close();
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
var inputIsEmpty = !editor.content.currentNode.textContent.trim(),
|
|
|
|
currentNodeType = editor.content.currentNode.dataset.tool,
|
|
|
|
isInitialType = currentNodeType == editor.settings.initialBlockPlugin;
|
2017-01-27 19:10:04 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-01-28 15:11:03 +01:00
|
|
|
/** Hide plus buttons */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.hidePlusButton();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-16 23:15:23 +01:00
|
|
|
if (!inputIsEmpty) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-16 23:15:23 +01:00
|
|
|
/** Mark current block */
|
|
|
|
editor.content.markBlock();
|
|
|
|
|
|
|
|
}
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-01-28 15:11:03 +01:00
|
|
|
if ( isInitialType && inputIsEmpty ) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-01-28 15:11:03 +01:00
|
|
|
/** Show plus button */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.showPlusButton();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-01-28 15:11:03 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method allows to define, is caret in contenteditable element or not.
|
|
|
|
* Otherwise, if we get TEXT node from range container, that will means we have input index.
|
|
|
|
* In this case we use default browsers behaviour (if plugin allows that) or overwritten action.
|
|
|
|
* Therefore, to be sure that we've clicked first-level block area, we should have currentNode, which always
|
|
|
|
* specifies to the first-level block. Other cases we just ignore.
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.detectWhenClickedOnFirstLevelBlockArea = function () {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
var selection = window.getSelection(),
|
|
|
|
anchorNode = selection.anchorNode,
|
|
|
|
flag = false;
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
if (selection.rangeCount === 0) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.content.editorAreaHightlighted = true;
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
if (!editor.core.isDomNode(anchorNode)) {
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
anchorNode = anchorNode.parentNode;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Already founded, without loop */
|
|
|
|
if (anchorNode.contentEditable == 'true') {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
flag = true;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
while (anchorNode.contentEditable != 'true') {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
anchorNode = anchorNode.parentNode;
|
|
|
|
|
|
|
|
if (anchorNode.contentEditable == 'true') {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
flag = true;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (anchorNode == document.body) {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
break;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/** If editable element founded, flag is "TRUE", Therefore we return "FALSE" */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.content.editorAreaHightlighted = flag ? false : true;
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Toolbar button click handler
|
|
|
|
* @param this - cursor to the button
|
|
|
|
*/
|
|
|
|
callbacks.toolbarButtonClicked = function (event) {
|
|
|
|
|
|
|
|
var button = this;
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.current = button.dataset.type;
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.toolbox.toolClicked(event);
|
|
|
|
editor.toolbar.close();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Show or Hide toolbox when plus button is clicked */
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.plusButtonClicked = function () {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
if (!editor.nodes.toolbox.classList.contains('opened')) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.toolbox.open();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.toolbox.close();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
}
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Block handlers for KeyDown events
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.blockKeydown = function (event) {
|
|
|
|
|
|
|
|
let block = this; // event.target input
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
switch (event.keyCode) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
case editor.core.keys.DOWN:
|
|
|
|
case editor.core.keys.RIGHT:
|
|
|
|
editor.callback.blockRightOrDownArrowPressed();
|
2016-12-07 19:25:31 +01:00
|
|
|
break;
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
case editor.core.keys.BACKSPACE:
|
|
|
|
editor.callback.backspacePressed(block, event);
|
2016-12-07 19:25:31 +01:00
|
|
|
break;
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
case editor.core.keys.UP:
|
|
|
|
case editor.core.keys.LEFT:
|
|
|
|
editor.callback.blockLeftOrUpArrowPressed();
|
2016-12-07 19:25:31 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* RIGHT or DOWN keydowns on block
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.blockRightOrDownArrowPressed = function () {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
var selection = window.getSelection(),
|
2017-02-01 18:25:59 +01:00
|
|
|
inputs = editor.state.inputs,
|
2016-12-07 19:25:31 +01:00
|
|
|
focusedNode = selection.anchorNode,
|
|
|
|
focusedNodeHolder;
|
|
|
|
|
|
|
|
/** Check for caret existance */
|
2017-02-01 18:25:59 +01:00
|
|
|
if (!focusedNode) {
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
return false;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Looking for closest (parent) contentEditable element of focused node */
|
|
|
|
while (focusedNode.contentEditable != 'true') {
|
|
|
|
|
|
|
|
focusedNodeHolder = focusedNode.parentNode;
|
|
|
|
focusedNode = focusedNodeHolder;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Input index in DOM level */
|
|
|
|
var editableElementIndex = 0;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
while (focusedNode != inputs[editableElementIndex]) {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
editableElementIndex ++;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Founded contentEditable element doesn't have childs
|
|
|
|
* Or maybe New created block
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
if (!focusedNode.textContent) {
|
|
|
|
|
|
|
|
editor.caret.setToNextBlock(editableElementIndex);
|
2016-12-07 19:25:31 +01:00
|
|
|
return;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Do nothing when caret doesn not reaches the end of last child
|
|
|
|
*/
|
|
|
|
var caretInLastChild = false,
|
|
|
|
caretAtTheEndOfText = false;
|
|
|
|
|
|
|
|
var lastChild,
|
|
|
|
deepestTextnode;
|
|
|
|
|
|
|
|
lastChild = focusedNode.childNodes[focusedNode.childNodes.length - 1 ];
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
if (editor.core.isDomNode(lastChild)) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
deepestTextnode = editor.content.getDeepestTextNodeFromPosition(lastChild, lastChild.childNodes.length);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
deepestTextnode = lastChild;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
caretInLastChild = selection.anchorNode == deepestTextnode;
|
|
|
|
caretAtTheEndOfText = deepestTextnode.length == selection.anchorOffset;
|
|
|
|
|
|
|
|
if ( !caretInLastChild || !caretAtTheEndOfText ) {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
|
|
|
editor.core.log('arrow [down|right] : caret does not reached the end');
|
2016-12-07 19:25:31 +01:00
|
|
|
return false;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.caret.setToNextBlock(editableElementIndex);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* LEFT or UP keydowns on block
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.blockLeftOrUpArrowPressed = function () {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
var selection = window.getSelection(),
|
2017-02-01 18:25:59 +01:00
|
|
|
inputs = editor.state.inputs,
|
2016-12-07 19:25:31 +01:00
|
|
|
focusedNode = selection.anchorNode,
|
|
|
|
focusedNodeHolder;
|
|
|
|
|
|
|
|
/** Check for caret existance */
|
2017-02-01 18:25:59 +01:00
|
|
|
if (!focusedNode) {
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
return false;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* LEFT or UP not at the beginning
|
|
|
|
*/
|
|
|
|
if ( selection.anchorOffset !== 0) {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
return false;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Looking for parent contentEditable block */
|
|
|
|
while (focusedNode.contentEditable != 'true') {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
focusedNodeHolder = focusedNode.parentNode;
|
|
|
|
focusedNode = focusedNodeHolder;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Input index in DOM level */
|
|
|
|
var editableElementIndex = 0;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
while (focusedNode != inputs[editableElementIndex]) {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
editableElementIndex ++;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Do nothing if caret is not at the beginning of first child
|
|
|
|
*/
|
|
|
|
var caretInFirstChild = false,
|
|
|
|
caretAtTheBeginning = false;
|
|
|
|
|
|
|
|
var firstChild,
|
|
|
|
deepestTextnode;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Founded contentEditable element doesn't have childs
|
|
|
|
* Or maybe New created block
|
|
|
|
*/
|
|
|
|
if (!focusedNode.textContent) {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
|
|
|
editor.caret.setToPreviousBlock(editableElementIndex);
|
2016-12-07 19:25:31 +01:00
|
|
|
return;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
firstChild = focusedNode.childNodes[0];
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
if (editor.core.isDomNode(firstChild)) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
deepestTextnode = editor.content.getDeepestTextNodeFromPosition(firstChild, 0);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
deepestTextnode = firstChild;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
caretInFirstChild = selection.anchorNode == deepestTextnode;
|
|
|
|
caretAtTheBeginning = selection.anchorOffset === 0;
|
|
|
|
|
|
|
|
if ( caretInFirstChild && caretAtTheBeginning ) {
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.caret.setToPreviousBlock(editableElementIndex);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback for enter key pressing in first-level block area
|
2017-02-01 18:25:59 +01:00
|
|
|
* @param {Event} event
|
2016-12-07 19:25:31 +01:00
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.enterPressedOnBlock = function () {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
var NEW_BLOCK_TYPE = editor.settings.initialBlockPlugin;
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.content.insertBlock({
|
2016-12-07 19:25:31 +01:00
|
|
|
type : NEW_BLOCK_TYPE,
|
2017-02-01 18:25:59 +01:00
|
|
|
block : editor.tools[NEW_BLOCK_TYPE].render()
|
2016-12-07 19:25:31 +01:00
|
|
|
}, true );
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.move();
|
|
|
|
editor.toolbar.open();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.backspacePressed = function (block, event) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
var currentInputIndex = editor.caret.getCurrentInputIndex(),
|
2016-12-07 19:25:31 +01:00
|
|
|
range,
|
|
|
|
selectionLength,
|
|
|
|
firstLevelBlocksCount;
|
|
|
|
|
|
|
|
if (block.textContent.trim()) {
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
range = editor.content.getRange();
|
2016-12-07 19:25:31 +01:00
|
|
|
selectionLength = range.endOffset - range.startOffset;
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
if (editor.caret.position.atStart() && !selectionLength && editor.state.inputs[currentInputIndex - 1]) {
|
2016-12-25 15:41:57 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.content.mergeBlocks(currentInputIndex);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!selectionLength) {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
block.remove();
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
firstLevelBlocksCount = editor.nodes.redactor.childNodes.length;
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* If all blocks are removed
|
|
|
|
*/
|
|
|
|
if (firstLevelBlocksCount === 0) {
|
|
|
|
|
|
|
|
/** update currentNode variable */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.content.currentNode = null;
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** Inserting new empty initial block */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.ui.addInitialBlock();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** Updating inputs state after deleting last block */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.ui.saveInputs();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** Set to current appended block */
|
2017-02-01 18:25:59 +01:00
|
|
|
window.setTimeout(function () {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.caret.setToPreviousBlock(1);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
}, 10);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
if (editor.caret.inputIndex !== 0) {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** Target block is not first */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.caret.setToPreviousBlock(editor.caret.inputIndex);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/** If we try to delete first block */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.caret.setToNextBlock(editor.caret.inputIndex);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
}
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
}
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.move();
|
|
|
|
|
|
|
|
if (!editor.toolbar.opened) {
|
|
|
|
|
|
|
|
editor.toolbar.open();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Updating inputs state */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.ui.saveInputs();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** Prevent default browser behaviour */
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2017-01-18 16:06:36 +01:00
|
|
|
/**
|
|
|
|
* This method is used to observe pasted dirty data.
|
|
|
|
*
|
|
|
|
* Mutation handlers send to separate observers each mutation (added, changed and so on), which will be
|
|
|
|
* passed from handler that sanitizes and replaces data.
|
|
|
|
*
|
|
|
|
* Probably won't be used
|
|
|
|
*
|
|
|
|
* @deprecated
|
|
|
|
*
|
|
|
|
* @param event
|
|
|
|
* @private
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks._blockPasteCallback = function () {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
var currentInputIndex = editor.caret.getCurrentInputIndex();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* create an observer instance
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
var observer = new MutationObserver(editor.callback.handleMutationsOnPaste);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* configuration of the observer:
|
|
|
|
*/
|
2017-01-10 19:22:40 +01:00
|
|
|
var config = {
|
|
|
|
attributes: true,
|
2017-01-18 16:06:36 +01:00
|
|
|
childList: false,
|
2017-01-10 19:22:40 +01:00
|
|
|
characterData: false,
|
|
|
|
subtree : true
|
|
|
|
};
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
// pass in the target node, as well as the observer options
|
2017-02-01 18:25:59 +01:00
|
|
|
observer.observe(editor.state.inputs[currentInputIndex], config);
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
};
|
|
|
|
|
2017-01-18 16:06:36 +01:00
|
|
|
/**
|
|
|
|
* This method prevents default behaviour.
|
|
|
|
*
|
|
|
|
* We get from clipboard pasted data, sanitize, make a fragment that contains of this sanitized nodes.
|
|
|
|
* Firstly, we need to memorize the caret position. We can do that by getting the range of selection.
|
|
|
|
* After all, we insert clear fragment into caret placed position. Then, we should move the caret to the last node
|
|
|
|
*
|
|
|
|
* @param event
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.blockPasteCallback = function (event) {
|
2017-01-18 16:06:36 +01:00
|
|
|
|
|
|
|
/** Prevent default behaviour */
|
|
|
|
event.preventDefault();
|
|
|
|
|
2017-02-12 16:25:20 +01:00
|
|
|
var editableParent = editor.content.getEditableParent(event.target),
|
|
|
|
firstLevelBlock = editor.content.getFirstLevelBlock(event.target);
|
|
|
|
|
2017-02-11 11:53:45 +01:00
|
|
|
/** Allow paste when event target placed in Editable element */
|
2017-02-12 16:25:20 +01:00
|
|
|
if (!editableParent) {
|
2017-02-02 14:58:05 +01:00
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-01-18 16:06:36 +01:00
|
|
|
/** get html pasted data - dirty data */
|
2017-01-28 15:14:36 +01:00
|
|
|
var data = event.clipboardData.getData('text/html') || event.clipboardData.getData('text/plain');
|
2017-01-18 16:06:36 +01:00
|
|
|
|
|
|
|
/** Temporary DIV that is used to work with childs as arrays item */
|
2017-02-01 18:25:59 +01:00
|
|
|
var div = editor.draw.node('DIV', '', {}),
|
|
|
|
cleaner = new editor.sanitizer.init(editor.sanitizer.Config.BASIC),
|
2017-01-18 16:06:36 +01:00
|
|
|
cleanData,
|
|
|
|
fragment;
|
|
|
|
|
|
|
|
/** Create fragment, that we paste to range after proccesing */
|
|
|
|
fragment = document.createDocumentFragment();
|
|
|
|
|
|
|
|
cleanData = cleaner.clean(data);
|
|
|
|
|
|
|
|
div.innerHTML = cleanData;
|
|
|
|
|
|
|
|
var node, lastNode;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* and fill in fragment
|
|
|
|
*/
|
|
|
|
while (( node = div.firstChild) ) {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2017-01-18 16:06:36 +01:00
|
|
|
lastNode = fragment.appendChild(node);
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2017-01-18 16:06:36 +01:00
|
|
|
}
|
|
|
|
|
2017-02-12 16:25:20 +01:00
|
|
|
|
|
|
|
if (editor.tools[firstLevelBlock.dataset.tool].allowRenderOnPaste) {
|
|
|
|
|
|
|
|
if (editor.paste.pasted(event)) return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-01-18 16:06:36 +01:00
|
|
|
/**
|
|
|
|
* work with selection and range
|
|
|
|
*/
|
|
|
|
var selection, range;
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2017-01-18 16:06:36 +01:00
|
|
|
selection = window.getSelection();
|
|
|
|
|
|
|
|
range = selection.getRangeAt(0);
|
|
|
|
range.deleteContents();
|
|
|
|
|
|
|
|
range.insertNode(fragment);
|
|
|
|
|
|
|
|
/** Preserve the selection */
|
|
|
|
if (lastNode) {
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2017-01-18 16:06:36 +01:00
|
|
|
range = range.cloneRange();
|
|
|
|
range.setStartAfter(lastNode);
|
|
|
|
range.collapse(true);
|
|
|
|
selection.removeAllRanges();
|
|
|
|
selection.addRange(range);
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2017-01-18 16:06:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
/**
|
|
|
|
* Sends all mutations to paste handler
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.handleMutationsOnPaste = function (mutations) {
|
2017-01-10 19:22:40 +01:00
|
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calling function with context of this function.
|
|
|
|
* Also, we should sanitize pasted or changed data one time and ignore
|
|
|
|
* changings which makes sanitize method.
|
|
|
|
* For that, we need to send Context, MutationObserver.__proto__ that contains
|
|
|
|
* observer disconnect method.
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
mutations.forEach(function (mutation) {
|
|
|
|
|
|
|
|
editor.content.paste.call(self, mutation);
|
|
|
|
|
2017-01-10 19:22:40 +01:00
|
|
|
});
|
2017-02-01 18:25:59 +01:00
|
|
|
|
2016-12-07 19:25:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clicks on block settings button
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
callbacks.showSettingsButtonClicked = function () {
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get type of current block
|
|
|
|
* It uses to append settings from tool.settings property.
|
|
|
|
* ...
|
|
|
|
* Type is stored in data-type attribute on block
|
|
|
|
*/
|
2017-02-01 18:25:59 +01:00
|
|
|
var currentToolType = editor.content.currentNode.dataset.tool;
|
2016-12-07 19:25:31 +01:00
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.settings.toggle(currentToolType);
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
/** Close toolbox when settings button is active */
|
2017-02-01 18:25:59 +01:00
|
|
|
editor.toolbar.toolbox.close();
|
|
|
|
editor.toolbar.settings.hideRemoveActions();
|
2016-12-07 19:25:31 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
return callbacks;
|
|
|
|
|
2017-02-01 18:25:59 +01:00
|
|
|
})({});
|