mirror of
https://github.com/codex-team/editor.js
synced 2024-05-26 18:42:30 +02:00
add new paragrath by pressing enter key
add new line by pressing shift + enter key add editor settings make add buttons by one instance and move it through DOM some css changes
This commit is contained in:
parent
3b57d72c4d
commit
cda692edec
138
ce_interface.js
138
ce_interface.js
|
@ -3,21 +3,40 @@
|
|||
* @author Savchenko Peter (vk.com/specc)
|
||||
*/
|
||||
|
||||
var ce = function(textareaId) {
|
||||
var ce = function(settings) {
|
||||
|
||||
this.resultTextarea = document.getElementById(textareaId);
|
||||
this.textareaId = "codex_editor";
|
||||
this.resultTextarea = document.getElementById(this.textareaId);
|
||||
|
||||
if (typeof this.resultTextarea == undefined || this.resultTextarea == null ){
|
||||
|
||||
console.warn('Textarea not found with ID %o', textareaId);
|
||||
console.warn('Textarea not found with ID %o', this.textareaId);
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
this.toolbarOpened = false;
|
||||
this.tools = ['header', 'picture', 'list', 'quote', 'code', 'twitter', 'instagram', 'smile'];
|
||||
// prepare settings
|
||||
this.allTools = ['header', 'picture', 'list', 'quote', 'code', 'twitter', 'instagram', 'smile'];
|
||||
|
||||
var defaultSettings = {
|
||||
|
||||
};
|
||||
|
||||
|
||||
if ("undefined" == typeof settings || "object" != typeof settings)
|
||||
settings = defaultSettings;
|
||||
else {
|
||||
// todo just merge settings with defaults
|
||||
}
|
||||
|
||||
if ("undefined" == typeof settings.tools || !Array.isArray(settings.tools))
|
||||
settings.tools = this.allTools;
|
||||
|
||||
this.settings = settings;
|
||||
|
||||
/** Some configurations */
|
||||
this.toolbarOpened = false;
|
||||
|
||||
this.BUTTONS_TOGGLED_CLASSNANE = 'buttons_toggled';
|
||||
this.key = { TAB: 9, ENTER: 13, BACKSPACE: 8, DELETE: 46, DOWN: 40, SPACE: 32, ESC: 27, CTRL: 17, META: 91, SHIFT: 16, ALT: 18 };
|
||||
|
||||
|
@ -27,34 +46,43 @@ var ce = function(textareaId) {
|
|||
/** Bind all events */
|
||||
this.bindEvents();
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Editor interface drawing
|
||||
* @use this.tools to get necessary items
|
||||
* @todo get tools from user inital-settings
|
||||
*/
|
||||
ce.prototype.makeInterface = function () {
|
||||
|
||||
var wrapper = this.make.editorWrapper(),
|
||||
firstNode = this.make.node(null, 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Porro quia nihil repellendus aut cupiditate reprehenderit sapiente magnam nobis doloremque eaque! Sint nobis assumenda nisi ducimus minima illo tenetur, cumque facilis.' ),
|
||||
firstNode = this.make.textNode('Lorem ipsum dolor sit amet, consectetur adipisicing elit. Porro quia nihil repellendus aut cupiditate reprehenderit sapiente magnam nobis doloremque eaque! Sint nobis assumenda nisi ducimus minima illo tenetur, cumque facilis.' ),
|
||||
toolbar = this.make.toolbar(),
|
||||
button;
|
||||
button,
|
||||
tool;
|
||||
|
||||
for (var i = 0; i < this.tools.length; i++) {
|
||||
button = this.make.toolbarButton(this.tools[i]);
|
||||
toolbar.appendChild(button);
|
||||
};
|
||||
this.wrapper = wrapper;
|
||||
this.toolbar = toolbar;
|
||||
|
||||
this.toolbarButtons = document.createElement("span");
|
||||
this.toolbarButtons.classList.add("buttons");
|
||||
|
||||
// îáõîäèì áàçîâûé ñïèñîê, ÷òîáû ñîõðàíèòü îðèãèíàëüíóþ ïîñëåäîâàòåëüíîñòü êíîïîê
|
||||
for (var i = 0; i < this.allTools.length; i++) {
|
||||
tool = this.allTools[i];
|
||||
|
||||
if (this.settings.tools.indexOf(tool) < 0)
|
||||
continue;
|
||||
|
||||
button = this.make.toolbarButton(tool);
|
||||
this.toolbarButtons.appendChild(button);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add toolbar to node
|
||||
* @todo make toolbar rendering once
|
||||
*/
|
||||
firstNode.appendChild(toolbar);
|
||||
|
||||
/** Add first node */
|
||||
wrapper.appendChild(firstNode);
|
||||
|
||||
/** Add toolbar to node */
|
||||
wrapper.appendChild(toolbar);
|
||||
|
||||
/** Insert Editor after initial textarea. Hide textarea */
|
||||
this.resultTextarea.parentNode.insertBefore(wrapper, this.resultTextarea.nextSibling);
|
||||
this.resultTextarea.hidden = true;
|
||||
|
@ -63,7 +91,7 @@ ce.prototype.makeInterface = function () {
|
|||
var contentEditable = firstNode.getElementsByClassName('ce_node_content');
|
||||
contentEditable.length && contentEditable[0].focus();
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* All events binds in one place
|
||||
|
@ -77,7 +105,7 @@ ce.prototype.bindEvents = function () {
|
|||
_this.globalKeydownCallback(event);
|
||||
}, false );
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* All window keydowns handles here
|
||||
|
@ -89,40 +117,70 @@ ce.prototype.globalKeydownCallback = function (event) {
|
|||
case this.key.ENTER : this.enterKeyPressed(event); break; // Enter
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @todo: check if currently focused in contenteditable element
|
||||
*
|
||||
*/
|
||||
ce.prototype.tabKeyPressed = function(event) {
|
||||
|
||||
var toolbar = document.getElementsByClassName('add_buttons');
|
||||
// check if currently focused in contenteditable element
|
||||
if ("BODY" == event.target.tagName)
|
||||
return;
|
||||
|
||||
if ( !toolbar[0].className.includes(this.BUTTONS_TOGGLED_CLASSNANE) ){
|
||||
toolbar[0].className += ' ' + this.BUTTONS_TOGGLED_CLASSNANE;
|
||||
this.toolbarOpened = true;
|
||||
} else {
|
||||
toolbar[0].className = toolbar[0].className.replace(this.BUTTONS_TOGGLED_CLASSNANE, '');
|
||||
this.toolbarOpened = false
|
||||
}
|
||||
var toolbar = event.target.parentNode.nextSibling,
|
||||
_this = this;
|
||||
|
||||
toolbar.appendChild(this.toolbarButtons);
|
||||
|
||||
// repair buttons animation
|
||||
setTimeout(function () {
|
||||
|
||||
if ( !toolbar.className.includes(_this.BUTTONS_TOGGLED_CLASSNANE) ){
|
||||
toolbar.className += ' ' + _this.BUTTONS_TOGGLED_CLASSNANE;
|
||||
_this.toolbarOpened = true;
|
||||
} else {
|
||||
toolbar.className = toolbar.className.replace(_this.BUTTONS_TOGGLED_CLASSNANE, '');
|
||||
_this.toolbarOpened = false
|
||||
}
|
||||
|
||||
}, 10);
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle Enter key. Adds new Node;
|
||||
*/
|
||||
ce.prototype.enterKeyPressed = function(event) {
|
||||
|
||||
console.log('ENTER');
|
||||
if (event.shiftKey){
|
||||
document.execCommand('insertHTML', false, '<br><br>');
|
||||
} else {
|
||||
var
|
||||
newNode = this.make.textNode(),
|
||||
toolbar = this.make.toolbar();
|
||||
|
||||
}
|
||||
|
||||
/** Add node */
|
||||
this.wrapper.insertBefore(newNode, event.target.parentNode.nextSibling);
|
||||
|
||||
/** Add toolbar to node */
|
||||
this.wrapper.insertBefore(toolbar, newNode);
|
||||
|
||||
/** Set auto focus */
|
||||
var contentEditable = newNode.getElementsByClassName('ce_node_content');
|
||||
contentEditable.length && contentEditable[0].focus();
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates HTML elements
|
||||
*/
|
||||
ce.prototype.make = function (window) {
|
||||
ce.prototype.make = function () {
|
||||
|
||||
/** Empty toolbar with toggler */
|
||||
function toolbar () {
|
||||
|
@ -133,7 +191,7 @@ ce.prototype.make = function (window) {
|
|||
|
||||
/** Toggler button*/
|
||||
bar.innerHTML = '<span class="toggler">' +
|
||||
'<i class="ce_icon-plus-circled-1"></i>'+
|
||||
'<i class="plus_btn ce_icon-plus-circled-1"></i>'+
|
||||
'</span>';
|
||||
return bar;
|
||||
|
||||
|
@ -153,7 +211,7 @@ ce.prototype.make = function (window) {
|
|||
* Paragraph node
|
||||
* @todo set unique id with prefix
|
||||
*/
|
||||
function node (id, content){
|
||||
function textNode (content){
|
||||
|
||||
var node = document.createElement('div');
|
||||
|
||||
|
@ -175,13 +233,13 @@ ce.prototype.make = function (window) {
|
|||
var ceMake = function () {
|
||||
this.toolbar = toolbar;
|
||||
this.toolbarButton = toolbarButton;
|
||||
this.node = node;
|
||||
this.textNode = textNode;
|
||||
this.editorWrapper = editorWrapper;
|
||||
}
|
||||
};
|
||||
|
||||
return new ceMake();
|
||||
|
||||
}(this)
|
||||
}();
|
||||
|
||||
|
||||
|
||||
|
|
110
editor.css
110
editor.css
|
@ -1,34 +1,34 @@
|
|||
@font-face {
|
||||
font-family: 'codex_editor';
|
||||
src: url('fonts/codex_editor/codex_editor.eot?52438661');
|
||||
src: url('fonts/codex_editor/codex_editor.eot?52438661#iefix') format('embedded-opentype'),
|
||||
url('fonts/codex_editor/codex_editor.woff?52438661') format('woff'),
|
||||
url('fonts/codex_editor/codex_editor.ttf?52438661') format('truetype'),
|
||||
url('fonts/codex_editor/codex_editor.svg?52438661#codex_editor') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-family: 'codex_editor';
|
||||
src: url('fonts/codex_editor/codex_editor.eot?52438661');
|
||||
src: url('fonts/codex_editor/codex_editor.eot?52438661#iefix') format('embedded-opentype'),
|
||||
url('fonts/codex_editor/codex_editor.woff?52438661') format('woff'),
|
||||
url('fonts/codex_editor/codex_editor.ttf?52438661') format('truetype'),
|
||||
url('fonts/codex_editor/codex_editor.svg?52438661#codex_editor') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
[class^="ce_icon-"]:before, [class*="ce_icon-"]:before {
|
||||
font-family: "codex_editor";
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
speak: none;
|
||||
font-family: "codex_editor";
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
speak: none;
|
||||
|
||||
display: inline-block;
|
||||
text-decoration: inherit;
|
||||
width: 1em;
|
||||
margin-right: .2em;
|
||||
text-align: center;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
text-decoration: inherit;
|
||||
width: 1em;
|
||||
margin-right: .2em;
|
||||
text-align: center;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
|
||||
line-height: 1em;
|
||||
line-height: 1em;
|
||||
|
||||
/* Animation center compensation - margins should be symmetric */
|
||||
margin-left: .2em;
|
||||
/* Animation center compensation - margins should be symmetric */
|
||||
margin-left: .2em;
|
||||
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.ce_icon-instagram:before { content: '\e800'; } /* '' */
|
||||
|
@ -87,41 +87,55 @@
|
|||
}
|
||||
|
||||
.codex_editor .add_buttons{
|
||||
position: relative;
|
||||
/* position: relative; */
|
||||
/* left: -42px; */
|
||||
/* top: -30px; */
|
||||
color: #3b4352;
|
||||
font-size: 16px;
|
||||
margin-left: -42px;
|
||||
margin-top: -20px;
|
||||
margin-bottom: -25px;
|
||||
}
|
||||
|
||||
.add_buttons .buttons {
|
||||
position: absolute;
|
||||
}
|
||||
.codex_editor .add_buttons button:hover,
|
||||
.codex_editor .add_buttons .focused{
|
||||
color: #3770ef;
|
||||
}
|
||||
.codex_editor .add_buttons button{
|
||||
transition: all 150ms ease-in;
|
||||
transform: translate3d(-50px, 0 , 0);
|
||||
opacity: 0;
|
||||
font-size: 14px;
|
||||
/*display: none;*/
|
||||
}
|
||||
.codex_editor .buttons_toggled{
|
||||
background: #fff;
|
||||
}
|
||||
.codex_editor .buttons_toggled button{
|
||||
opacity: 1;
|
||||
transform: translate3d(0,0,0);
|
||||
}
|
||||
.codex_editor .add_buttons button:hover,
|
||||
.codex_editor .add_buttons .focused{
|
||||
color: #3770ef;
|
||||
}
|
||||
.codex_editor .add_buttons button{
|
||||
transition: all 150ms ease-in;
|
||||
transform: translate3d(-50px, 0 , 0);
|
||||
opacity: 0;
|
||||
font-size: 14px;
|
||||
/*display: none;*/
|
||||
}
|
||||
.codex_editor .buttons_toggled{
|
||||
background: #fff;
|
||||
}
|
||||
.codex_editor .buttons_toggled button{
|
||||
opacity: 1;
|
||||
transform: translate3d(0,0,0);
|
||||
}
|
||||
|
||||
|
||||
.codex_editor .toggler{
|
||||
position: absolute;
|
||||
left: -42px;
|
||||
/* position: relative; */
|
||||
/* left: -42px; */
|
||||
display: inline-block;
|
||||
font-size: 23px;
|
||||
color: #387ff5;
|
||||
transition: transform 100ms ease-in;
|
||||
}
|
||||
.codex_editor .buttons_toggled .toggler{
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.codex_editor .toggler .buttons {
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
.codex_editor .buttons_toggled .plus_btn{
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
12
example.html
12
example.html
|
@ -12,7 +12,7 @@
|
|||
|
||||
<form action="">
|
||||
|
||||
<textarea name="" id="html_result" cols="30" rows="10"></textarea>
|
||||
<textarea name="" id="codex_editor" cols="30" rows="10"></textarea>
|
||||
|
||||
</form>
|
||||
|
||||
|
@ -48,14 +48,18 @@
|
|||
</body>
|
||||
</html>
|
||||
|
||||
<script src="ce_interface.js?v=<?= filemtime("public/js/ce_interface.js") ?>"></script>
|
||||
<script src="ce_interface.js"></script>
|
||||
<script>
|
||||
|
||||
function ready(f){/in/.test(document.readyState) ? setTimeout(ready,9,f) : f();}
|
||||
function ready(f){
|
||||
/in/.test(document.readyState) ? setTimeout(ready,9,f) : f();
|
||||
}
|
||||
|
||||
/** Document is ready */
|
||||
ready(function() {
|
||||
window.cEditor = new ce('html_result');
|
||||
window.cEditor = new ce({
|
||||
tools : ['header', 'picture']
|
||||
});
|
||||
})
|
||||
|
||||
</script>
|
||||
|
|
Loading…
Reference in a new issue