raw plugin added (#163)

* raw plugin added

* Try to paste raw html to raw plugin

* insert text/plain to native area instead of contenteditable element

* styles updated

* rename variable

* fixed raw backspace click handler

* paste code

* Replace mask with two svg icons

* Toolbox leaf fix

* Remove data in example.html

* Toolbar and caret behavior improvments

* upd

* Upd

* new bundle due the local merge
This commit is contained in:
George Berezhnoy 2017-02-27 14:44:22 +03:00 committed by Peter Savchenko
parent 3cbe8faaa6
commit c87eddc7c3
14 changed files with 205 additions and 25 deletions

View file

@ -112,6 +112,7 @@
margin-right: 17px;
border-radius: 16px;
text-align: center;
vertical-align: top;
cursor: pointer;
font-size: 14px;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -51,6 +51,9 @@
<script src="plugins/embed/embed.js"></script>
<link rel="stylesheet" href="plugins/embed/embed.css">
<script src="plugins/raw/raw.js"></script>
<link rel="stylesheet" href="plugins/raw/raw.css">
<script>
codex.editor.start({
textareaId : "codex_area",
@ -186,6 +189,17 @@
destroy: embed.destroy,
validate: embed.validate,
renderOnPastePatterns: embed.pastePatterns,
},
raw: {
type: 'raw',
displayInToolbox: true,
iconClassname: 'raw-plugin-icon',
render: rawPlugin.render,
save: rawPlugin.save,
validate: rawPlugin.validate,
destroy: rawPlugin.destroy,
enableLineBreaks: true,
allowPasteHTML: true
}
},
data : {
@ -209,11 +223,10 @@
type : 'OL',
items : [1,3,4]
},
},
}
],
count: 3
}
});
</script>
</html>

View file

@ -2,7 +2,7 @@
* Codex Editor callbacks module
*
* @author Codex Team
* @version 1.3.7
* @version 1.3.10
*/
module.exports = (function (callbacks) {
@ -41,7 +41,23 @@ module.exports = (function (callbacks) {
callbacks.tabKeyPressed = function (event) {
var blockIsEmpty = !editor.content.currentNode.textContent.trim();
var inputs = editor.content.currentNode.querySelectorAll('textarea, input'),
inputsAreEmpty = true,
textContentIsEmpty = !editor.content.currentNode.textContent.trim();
Array.prototype.map.call(inputs, function (input) {
if (input.type == 'textarea' || input.type == 'text') {
inputsAreEmpty = inputsAreEmpty && !input.value.trim();
}
});
var blockIsEmpty = textContentIsEmpty && inputsAreEmpty;
if (!blockIsEmpty) {
@ -691,6 +707,21 @@ module.exports = (function (callbacks) {
selectionLength,
firstLevelBlocksCount;
if (isNativeInput(event.target)) {
/** If input value is empty - remove block */
if (event.target.value.trim() == '') {
block.remove();
} else {
return;
}
}
if (block.textContent.trim()) {
range = editor.content.getRange();
@ -818,11 +849,18 @@ module.exports = (function (callbacks) {
*/
callbacks.blockPasteCallback = function (event) {
/** If area is input or textarea then allow default behaviour */
if ( isNativeInput(event.target) ) {
return;
}
/** Prevent default behaviour */
event.preventDefault();
var editableParent = editor.content.getEditableParent(event.target),
firstLevelBlock = editor.content.getFirstLevelBlock(event.target);
currentNode = editor.content.currentNode;
/** Allow paste when event target placed in Editable element */
if (!editableParent) {
@ -832,7 +870,8 @@ module.exports = (function (callbacks) {
}
/** get html pasted data - dirty data */
var data = event.clipboardData.getData('text/html') || event.clipboardData.getData('text/plain');
var htmlData = event.clipboardData.getData('text/html'),
plainData = event.clipboardData.getData('text/plain');
/** Temporary DIV that is used to work with childs as arrays item */
var div = editor.draw.node('DIV', '', {}),
@ -843,9 +882,16 @@ module.exports = (function (callbacks) {
/** Create fragment, that we paste to range after proccesing */
fragment = document.createDocumentFragment();
cleanData = cleaner.clean(data);
if ( htmlData.trim() != '' ) {
div.innerHTML = cleanData;
cleanData = cleaner.clean(htmlData);
div.innerHTML = cleanData;
} else {
div.innerText = plainData.toString();
}
var node, lastNode;
@ -859,7 +905,7 @@ module.exports = (function (callbacks) {
}
if (editor.tools[firstLevelBlock.dataset.tool].allowRenderOnPaste) {
if (editor.tools[currentNode.dataset.tool].allowRenderOnPaste) {
if (editor.paste.pasted(event)) return;
@ -933,6 +979,18 @@ module.exports = (function (callbacks) {
};
/**
* Check block for
* @param target
*/
var isNativeInput = function (target) {
var nativeInputAreas = ['INPUT', 'TEXTAREA'];
return (nativeInputAreas.indexOf(target.tagName) != -1);
};
return callbacks;
})({});

View file

@ -49,7 +49,7 @@ module.exports = (function (caret) {
}
/** If Element is INPUT */
if (el.tagName == 'INPUT') {
if (el.contentEditable != 'true') {
el.focus();
return;

View file

@ -46,6 +46,8 @@ module.exports = (function (toolbox) {
/** toolbox state */
editor.toolbar.toolbox.opened = false;
editor.toolbar.current = null;
};
toolbox.leaf = function () {
@ -75,21 +77,14 @@ module.exports = (function (toolbox) {
} else {
nextToolIndex = tools.indexOf(currentTool) + 1;
nextToolIndex = (tools.indexOf(currentTool) + 1) % tools.length;
visibleTool = tools[nextToolIndex];
while (!editor.tools[visibleTool].displayInToolbox) {
nextToolIndex++;
nextToolIndex = (nextToolIndex + 1) % tools.length;
visibleTool = tools[nextToolIndex];
if ( nextToolIndex == tools.length ) {
nextToolIndex = 0;
visibleTool = tools[nextToolIndex];
}
}
}

View file

@ -351,8 +351,20 @@ module.exports = (function (ui) {
var redactor = editor.nodes.redactor;
editor.state.inputs = [];
/** Save all inputs in global variable state */
editor.state.inputs = redactor.querySelectorAll('[contenteditable], input');
var inputs = redactor.querySelectorAll('[contenteditable], input, textarea');
Array.prototype.map.call(inputs, function (current) {
if (!current.type || current.type == 'text' || current.type == 'textarea') {
editor.state.inputs.push(current);
}
});
};

View file

@ -1,6 +1,6 @@
{
"name": "codex.editor",
"version": "1.5.3",
"version": "1.5.4",
"description": "Codex Editor. Native JS, based on API and Open Source",
"main": "index.js",
"scripts": {

View file

@ -0,0 +1,7 @@
<svg class="raw-plugin-icon-svg" width="19px" height="6px" viewBox="0 0 19 6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>RAW</title>
<defs></defs>
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M3.17724609,0.00146484375 C4.53955078,0.00146484375 5.31298828,0.766113281 5.31298828,1.93505859 C5.31298828,2.84033203 4.75048828,3.42480469 4.22753906,3.62255859 L5.43164062,6 L4.01660156,6 L2.97509766,3.81591797 L1.98632812,3.81591797 L1.98632812,6 L0.733886719,6 L0.733886719,0.00146484375 L3.17724609,0.00146484375 Z M1.98632812,2.84912109 L2.97509766,2.84912109 C3.59912109,2.84912109 4.00341797,2.55029297 4.00341797,1.95263672 C4.00341797,1.34179688 3.5859375,1.01660156 2.99267578,1.01660156 L1.98632812,1.01660156 L1.98632812,2.84912109 Z M6.85976562,6 L5.58095703,6 L7.56728515,0.00146484375 L9.0790039,0.00146484375 L11.056543,6 L9.70302734,6 L9.26357421,4.54541016 L7.30800781,4.54541016 L6.85976562,6 Z M8.31874999,1.22753906 L8.26162109,1.22753906 L7.55849609,3.57421875 L9.01748046,3.57421875 L8.31874999,1.22753906 Z M13.7107422,6 L12.5374023,6 L10.9641601,0.00146484375 L12.3308594,0.00146484375 L13.187793,4.20263672 L13.2493164,4.20263672 L14.2820312,0.00146484375 L15.3542969,0.00146484375 L16.3914062,4.20263672 L16.4529297,4.20263672 L17.3054687,0.00146484375 L18.6677734,0.00146484375 L17.0989258,6 L15.9255859,6 L14.8445312,2.00537109 L14.7961914,2.00537109 L13.7107422,6 Z" id="RAW" fill="#000000"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,7 @@
<svg class="raw-plugin-icon-svg" width="19px" height="6px" viewBox="0 0 19 6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>RAW</title>
<defs></defs>
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M3.17724609,0.00146484375 C4.53955078,0.00146484375 5.31298828,0.766113281 5.31298828,1.93505859 C5.31298828,2.84033203 4.75048828,3.42480469 4.22753906,3.62255859 L5.43164062,6 L4.01660156,6 L2.97509766,3.81591797 L1.98632812,3.81591797 L1.98632812,6 L0.733886719,6 L0.733886719,0.00146484375 L3.17724609,0.00146484375 Z M1.98632812,2.84912109 L2.97509766,2.84912109 C3.59912109,2.84912109 4.00341797,2.55029297 4.00341797,1.95263672 C4.00341797,1.34179688 3.5859375,1.01660156 2.99267578,1.01660156 L1.98632812,1.01660156 L1.98632812,2.84912109 Z M6.85976562,6 L5.58095703,6 L7.56728515,0.00146484375 L9.0790039,0.00146484375 L11.056543,6 L9.70302734,6 L9.26357421,4.54541016 L7.30800781,4.54541016 L6.85976562,6 Z M8.31874999,1.22753906 L8.26162109,1.22753906 L7.55849609,3.57421875 L9.01748046,3.57421875 L8.31874999,1.22753906 Z M13.7107422,6 L12.5374023,6 L10.9641601,0.00146484375 L12.3308594,0.00146484375 L13.187793,4.20263672 L13.2493164,4.20263672 L14.2820312,0.00146484375 L15.3542969,0.00146484375 L16.3914062,4.20263672 L16.4529297,4.20263672 L17.3054687,0.00146484375 L18.6677734,0.00146484375 L17.0989258,6 L15.9255859,6 L14.8445312,2.00537109 L14.7961914,2.00537109 L13.7107422,6 Z" id="RAW" fill="#ffffff"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

36
plugins/raw/raw.css Normal file
View file

@ -0,0 +1,36 @@
.raw-plugin__input {
display: block;
width: 100%;
min-height: 200px;
border: 0;
background: #fdfdfd;
box-shadow: inset 0 2px 8px rgba(23, 32, 74, 0.06);
border-radius: 3px;
margin: 1em auto;
padding: 1em;
box-sizing: border-box;
white-space: pre;
outline: none;
resize: vertical;
font-family: 'monospace', 'monaco', 'consolas', 'courier';
line-height: 1.7em;
font-size: 12px;
color: #152b48;
overflow: auto;
letter-spacing: 0.015em;
}
.raw-plugin-icon {
display: inline-block;
width: 16px;
height: 32px;
background: url(raw-icon-black.svg) no-repeat center center;
background-size: contain;
}
li:hover .raw-plugin-icon,
.selected .raw-plugin-icon{
background: url(raw-icon-white.svg) no-repeat center center;
background-size: contain;
}

51
plugins/raw/raw.js Normal file
View file

@ -0,0 +1,51 @@
/**
* Plugin for CodeX.Editor
* Implements RAW-data block
*/
var rawPlugin = function (plugin) {
var editor = codex.editor;
plugin.render = function (data) {
var input = editor.draw.node('TEXTAREA', 'raw-plugin__input', {});
input.placeholder = 'Вставьте HTML код';
if (data && data.html) {
input.value = data.html;
}
return input;
};
plugin.save = function (block) {
return {
html: block.value
};
};
plugin.validate = function (data) {
if (data.html.trim() === '') {
return;
}
return true;
};
plugin.destroy = function () {
rawPlugin = null;
};
return plugin;
}({});

File diff suppressed because one or more lines are too long