toolBar key controlling #9

show on hover near node
show on tab
move focus to next btn by pressing tab again
move focus to prev btn by pressing tab+shift
move focus prev/next by pressing arrow buttons
TODO: process enter press on selected btn
TODO: open toolBar by mouseClick (has troubles with it, need discus)
TODO: process mouse click on any btn
TODO: code refactoring :) its only transitional status. don't be don't be a cruel
This commit is contained in:
Mark Dermanov 2015-12-18 01:41:36 +03:00
parent 767cf626b0
commit 3e17243f17
3 changed files with 193 additions and 30 deletions

View file

@ -45,7 +45,7 @@ ce.prototype.BUTTONS_TOGGLED_CLASSNANE = 'buttons_toggled';
ce.prototype.toolbarOpened = false;
// Key event constants
ce.prototype.key = { TAB: 9, ENTER: 13, BACKSPACE: 8, DELETE: 46, DOWN: 40, SPACE: 32, ESC: 27, CTRL: 17, META: 91, SHIFT: 16, ALT: 18 };
ce.prototype.key = { TAB: 9, ENTER: 13, BACKSPACE: 8, DELETE: 46, SPACE: 32, ESC: 27, CTRL: 17, META: 91, SHIFT: 16, ALT: 18, LEFT: 37, UP: 38, DOWN: 40, RIGHT: 39 };
/**
* Editor interface drawing
@ -64,6 +64,9 @@ ce.prototype.makeInterface = function () {
this.toolbarButtons = this.make.toolbarButtons(this.allTools, this.settings.tools);
toolbar.appendChild(this.toolbarButtons);
/** Add first node and tool bar*/
editableWrapper.appendChild(firstNode);
wrapper.appendChild(toolbar);
@ -90,11 +93,69 @@ ce.prototype.bindEvents = function () {
/** All blur on Window */
document.addEventListener('focus', function (event) {
document.addEventListener('mouseover', function (event) {
// check if currently focused in contenteditable element
if ("BODY" == event.target.tagName) return;
//if ("BODY" == event.target.tagName) return;
event.target.classList.add(selectedNodeClass)
//event.target.classList.add(selectedNodeClass)
var sender = event.target
if (sender.classList.contains("node") && !_this.toolbar.isOpened) {
console.log("hover", sender);
var toolbar = _this.toolbar;
toolbar.style.top = sender.offsetTop + "px";
// repair buttons animation - just add css class async
//setTimeout(function () {
toolbar.classList.add("show");
//});
}
}, false );
/** All blur on Window */
document.addEventListener('mouseout', function (event) {
// check if currently focused in contenteditable element
//if ("BODY" == event.target.tagName) return;
//event.target.classList.add(selectedNodeClass)
var sender = event.target
//
//var sel = window.getSelection();
//var curSelectedNode = sel.anchorNode.tagName ? sel.anchorNode : sel.focusNode.parentElement;
if (!_this.toolbar.isOpened) {
//if (sender.classList.contains("node")) {
//debugger
//if (!curSelectedNode.isEqualNode(sender) && !_this.toolbarButtons.isEqualNode(sender)) {
//debugger
console.log("mouseout", sender);
var toolbar = _this.toolbar;
//
//
//toolbar.style.top = sender.offsetTop + "px";
// repair buttons animation - just add css class async
//setTimeout(function () {
toolbar.classList.remove("show");
//toolbar.classList.remove(_this.BUTTONS_TOGGLED_CLASSNANE);
//if (_this.focusedToolbarBtn) {
// //console.log("has focused btn", _this.focusedToolbarBtn)
//
// _this.focusedToolbarBtn.classList.remove("focused")
// _this.focusedToolbarBtn = false;
//
// event.preventDefault();
// return
//}
//});
}
}, false );
};
@ -104,7 +165,8 @@ ce.prototype.bindEvents = function () {
* todo depending on node type
*/
ce.prototype.focusNode = function (node) {
debugger
//debugger
//if (node.classList.contains('ce_node_content')) node.focus();
//else {
// var contentEditable = node.getElementsByClassName('ce_node_content');
@ -134,11 +196,52 @@ ce.prototype.focusNode = function (node) {
ce.prototype.globalKeydownCallback = function (event) {
console.log("keydown", event);
switch (event.keyCode){
case this.key.TAB : this.tabKeyPressed(event); break; // TAB
case this.key.ENTER : this.enterKeyPressed(event); break; // Enter
var _this = this;
// TODO process key navigation on toolBar then its opened
if (this.toolbar.isOpened) {
if (event.which == this.key.LEFT || event.which == this.key.UP || event.which == this.key.DOWN || event.which == this.key.RIGHT) {
this.moveToolBarButtonFocus(event.which == this.key.LEFT || event.which == this.key.UP )
event.preventDefault();
//return
} else if (event.which == this.key.ENTER) {
// TODO process seleceted toolBtn
//insert new node or change type of current?
//and close toolbar
// TODO do the same by mouse clicking on any toolbar btn
event.preventDefault();
} else if (event.which != this.key.TAB && event.which != this.key.SHIFT) {
var toolbar = this.toolbar;
toolbar.isOpened = false;
this.focusedToolbarBtn.classList.remove("focused");
this.focusedToolbarBtn = false;
// repair buttons animation - just add css class async
setTimeout(function () {
toolbar.classList.remove("show");
toolbar.classList.remove(_this.BUTTONS_TOGGLED_CLASSNANE);
});
//event.preventDefault();
//return
}
}
if (event.which == this.key.TAB)
this.tabKeyPressed(event)
//
//switch (event.keyCode){
// case this.key.TAB : this.tabKeyPressed(event); break; // TAB
// case this.key.ENTER : this.enterKeyPressed(event); break; // Enter
//}
};
/**
@ -149,42 +252,86 @@ ce.prototype.tabKeyPressed = function(event) {
// check if currently focused in contenteditable element
if ("BODY" == event.target.tagName) return;
var toolbar = event.target.nextSibling,
_this = this;
var _this = this;
toolbar.appendChild(this.toolbarButtons);
var toolbar = this.toolbar;
if (!toolbar.isOpened) {
var sel = window.getSelection();
var curNode = sel.anchorNode.tagName ? sel.anchorNode : sel.focusNode.parentElement;
var sel = window.getSelection();
var curNode = sel.anchorNode.tagName ? sel.anchorNode : sel.focusNode.parentElement;
toolbar.style.top = curNode.offsetTop + "px";
//debugger
var posTop =
toolbar.style.top = curNode.offsetTop + "px";
// repair buttons animation - just add css class async
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
if (!toolbar.classList.contains(_this.BUTTONS_TOGGLED_CLASSNANE)) {
// repair buttons animation - just add css class async
setTimeout(function () {
toolbar.classList.add(_this.BUTTONS_TOGGLED_CLASSNANE)
toolbar.isOpened = true;
});
}
});
}
//
this.moveToolBarButtonFocus(event.shiftKey);
event.preventDefault();
};
/*
*
* */
ce.prototype.moveToolBarButtonFocus = function(focusPrev){
var allButtons = this.toolbarButtons;
var focusedQuery = allButtons.getElementsByClassName("focused");//[0] || allButtons.firstChild;
var focused;
//debugger
console.log("focusing", focusedQuery)
if (focusedQuery.length > 0) {
focused = focusedQuery[0]
focused.classList.remove("focused")
if (focusPrev) focused = focused.previousSibling;
else focused = focused.nextSibling;
if (!focused) {
if (focusPrev) focused = allButtons.lastChild;
else focused = allButtons.firstChild;
}
focused.classList.add("focused")
} else {
focused = allButtons.firstChild;
focused.classList.add("focused")
}
this.focusedToolbarBtn = focused;
//return !!focused;
}
/**
* Handle Enter key. Adds new Node;
*/
ce.prototype.enterKeyPressed = function(event) {
var _this = this;
//var _this = this;
if (this.toolbar.isOpened) {
console.log("has focused btn", this.focusedToolbarBtn)
event.preventDefault();
return
}
this.toolbar.classList.remove("show")
this.toolbar.classList.remove(this.BUTTONS_TOGGLED_CLASSNANE)
//if (event.shiftKey){
// document.execCommand('insertHTML', false, '<br><br>');

View file

@ -102,6 +102,13 @@
white-space: nowrap;
}
.add_buttons.show {
background: #fff;
z-index: 10;
opacity: 1;
}
.add_buttons.show .buttons {display:none;}
.codex_editor .node.selected + .add_buttons{visibility:visible;}
.add_buttons .buttons {
@ -110,6 +117,7 @@
background: wheat;
padding: 2px;
border-radius: 3px;
display: none;
}
.codex_editor .add_buttons button:hover,
.codex_editor .add_buttons .focused{
@ -137,6 +145,7 @@
font-size: 23px;
color: #387ff5;
transition: transform 100ms ease-in;
cursor: pointer;
}
.codex_editor .toggler .buttons {
@ -147,6 +156,13 @@
transform: rotate(45deg);
}
.codex_editor .buttons_toggled .buttons{
display: inline;
}
/** Typography styles */
.codex_editor p{
padding: 5px 0;

View file

@ -58,7 +58,7 @@
/** Document is ready */
ready(function() {
window.cEditor = new ce({
tools : ['header', 'picture']
tools : ['header', 'list', 'picture']
});
})