Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Переход курсора на следующий и предыдущий блоки при нажатии на кнопки вверх/вниз #32

Merged
merged 16 commits into from
Jun 10, 2016
Prev Previous commit
Next Next commit
arrows keydows handlers
Продолжить дебажить изменения каретки
  • Loading branch information
neSpecc committed Jun 8, 2016
commit 6cf05475c26aa17f47409ba20ac87abc26fd6889
269 changes: 188 additions & 81 deletions codex-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,7 @@ cEditor.ui = {

block.addEventListener('keydown', function(event) {

cEditor.caret.save();
cEditor.callback.blockTransition(event, block);
cEditor.callback.blockKeydown(event, block);

}, false);

Expand Down Expand Up @@ -368,25 +367,107 @@ cEditor.callback = {

},

blockTransition : function(event, block) {
blockKeydown : function(event, block) {

switch (event.keyCode){

case cEditor.core.keys.DOWN:
case cEditor.core.keys.RIGHT:
cEditor.callback.blockRightOrDownArrowPressed(block);
break;

case cEditor.core.keys.UP:
case cEditor.core.keys.LEFT:
cEditor.callback.blockLeftOrUpArrowPressed(block);

break;

if (event.keyCode == cEditor.core.keys.DOWN || event.keyCode == cEditor.core.keys.RIGHT ) {
}

},

/**
* RIGHT or DOWN keydowns on block
*/
blockRightOrDownArrowPressed : function (block) {

if ( block.nextSibling == null )
return ;
var selection = window.getSelection(),
focusedNode = selection.anchorNode,
focusedNodeHolder;

cEditor.caret.setToNextBlock( block );
/** Check for caret exists */
if (!focusedNode){
return false;
}

else if (event.keyCode == cEditor.core.keys.UP || event.keyCode == cEditor.core.keys.LEFT ) {
focusedNodeHolder = focusedNode.parentNode;

if ( block.previousSibling == null )
return ;
/**
* Find deepest child node
* Iterate child nodes and find LAST and DEEPEST node (
* We need it to check caret positon (it must be at the end)
*/
var focusedTextNode = '';

if (focusedNodeHolder.childNodes){
/** Looking from the END of node */
focusedTextNode = cEditor.content.getDeepestTextNodeFromPosition(focusedNodeHolder, focusedNodeHolder.childNodes.length);
}

cEditor.caret.setToPreviousBlock( block );
/**
* Stop transition when caret is not at the end of Text node
* When we click "DOWN", caret moves to the end of node.
* We should check check caret position before we transmit/switch the block.
*/
if ( focusedTextNode.length != selection.anchorOffset ) {
return false;
}

cEditor.caret.setToNextBlock(block);

},

/**
* LEFT or UP keydowns on block
*/
blockLeftOrUpArrowPressed : function (block) {

var selection = window.getSelection(),
focusedNode = selection.anchorNode,
focusedNodeHolder;

/** Check for caret exists */
if (!focusedNode){
return false;
}

focusedNodeHolder = focusedNode.parentNode;

/**
* Find deepest child node
* Iterate child nodes and find LAST and DEEPEST node (
* We need it to check caret positon (it must be at the end)
*/
var focusedTextNode = '';

if (focusedNodeHolder.childNodes){
/** Looking from the END of node */
focusedTextNode = cEditor.content.getDeepestTextNodeFromPosition(focusedNodeHolder, 0);
}

/**
* Stop transition when caret is not at the end of Text node
* When we click "DOWN", caret moves to the end of node.
* We should check check caret position before we transmit/switch the block.
*/
if ( selection.anchorOffset !== 0) {
return false;
}

cEditor.caret.setToPreviousBlock(block);

}

};


Expand Down Expand Up @@ -521,6 +602,50 @@ cEditor.content = {
cEditor.caret.set(nodeCreated);
},


/**
* Iterates between child noted and looking for #text node on deepest level
* @param {Element} block - node where find
* @param {int} postiton - starting postion
* Example: childNodex.length to find from the end
* or 0 to find from the start
* @return {TextNode} block
* @uses DFS
*/
getDeepestTextNodeFromPosition : function (block, position) {

var looking_from_start = false;

/** For looking from START */
if (position === 0) {
looking_from_start = true;
position = 1;
}

while ( position ) {

/** @todo comment */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

напиши тут полноценный комментарий, пока не забыли

if ( looking_from_start ) {
block = block.childNodes[0];
} else {
block = block.childNodes[position-1];
}


if ( block.nodeType == cEditor.core.nodeTypes.TAG ){

position = block.childNodes.length;

} else {

position = 0;
}

}

return block;
}

}

cEditor.caret = {
Expand Down Expand Up @@ -561,108 +686,90 @@ cEditor.caret = {
},

/**
* Creates Documnt Range and sets caret to the NodeElement.
* @param {Element} NodeElement - Changed Node.
* Creates Documnt Range and sets caret to the element.
* @uses caret.save — if you need to save caret position
* @param {Element} el - Changed Node.
* @todo remove saving positon
* @todo - Check nodeToSet for type: if TAG -> look for nearest TextNode
*/
set : function(NodeElement) {

var nodeIndex = this.focusedNodeIndex || 0,
caretOffset = this.offset || 0,
childs = NodeElement.childNodes,
nodeChild = childs[nodeIndex];
set : function( el , index, offset) {

var range = document.createRange();
offset = offset || this.offset || 0;
index = index || this.focusedNodeIndex || 0;

if ( NodeElement.childNodes.length == 0 ) {
console.log('el %o', el);
console.log('el.childs %o', el.childs);
console.log('offset %o', offset);
console.log('index %o', index);

nodeChild = NodeElement;
caretOffset = 0;

}
var childs = el.childNodes,
nodeToSet;

var range = document.createRange(),
selection = window.getSelection();
if ( childs.length === 0 ) {

console.log(nodeChild, caretOffset);
nodeToSet = el;
offset = 0;

range.setStart(nodeChild, caretOffset);
range.setEnd(nodeChild, caretOffset);
} else{

selection.removeAllRanges();
selection.addRange(range);
},
nodeToSet = childs[index];

setToNextBlock : function(block) {

var selection = window.getSelection(),
focusedElement = selection.anchorNode.parentNode;
}

/** Stop transition when caret is not at the end of Text node
* When we click "DOWN", caret moves to the end of node.
* We should check check caret position before we transmit/switch the block.
*/
var range = document.createRange(),
selection = window.getSelection();

if ( cEditor.caret.offset != selection.anchorNode.length
&& typeof( selection.anchorNode.length ) != 'undefined') {
cEditor.caret.save();
return ;
setTimeout(function() {

}
range.setStart(nodeToSet, offset);
range.setEnd(nodeToSet, offset);

/* Setting Caret to the first child of next node */
else if ( selection.focusNode.length == cEditor.caret.Offset ) {
selection.removeAllRanges();
selection.addRange(range);

/** Firstchild of block */
cEditor.caret.offset = 0;
cEditor.caret.focusedNodeIndex = 0;
}, 0);

cEditor.caret.set(block.nextSibling);
},

} else {
/**
* @param {Element} - block element where we should find caret position
*/
get : function (el) {

/** Firstchild of block */
cEditor.caret.offset = 0;
cEditor.caret.focusedNodeIndex = 0;
cEditor.caret.set(block.nextSibling);
}
},

setToPreviousBlock : function(block) {

var selection = window.getSelection(),
focusedElement = selection.anchorNode.parentNode;

/** Stop transition when caret is not at the beggining of Text node
* When we click "UP", caret moves to the end of node.
* We should check check caret position before we transmit/switch the block.
*/

if ( cEditor.caret.offset != 0
&& typeof( selection.anchorNode.length ) != 'undefined') {
},

cEditor.caret.save();
return ;
/**
* @param {Element} block - element from which we take next block
*/
setToNextBlock : function(block) {

if ( !block.nextSibling ) {
return false;
}

/* Setting Caret to the first child of previous node */
else if ( selection.anchorOffset == 0
&& cEditor.caret.focusedNodeIndex == 0
&& typeof( block.previousSibling.childNodes.length ) != 'undefined') {

cEditor.caret.focusedNodeIndex = (block.previousSibling.childNodes.length == 0) ? 0 : block.previousSibling.childNodes.length - 1;
cEditor.caret.offset = (block.previousSibling.childNodes.length == 0) ? 0 : block.previousSibling.childNodes[cEditor.caret.focusedNodeIndex].length;
cEditor.caret.set(block.nextSibling, 0, 0);

cEditor.caret.set(block.previousSibling);
},

} else {
setToPreviousBlock : function(block) {

cEditor.caret.offset = 0;
cEditor.caret.focusedNodeIndex = 0;
if ( !block.previousSibling ) {
return false;
}

cEditor.caret.set(block.previousSibling);
var lastChildOfPreiviousBlockIndex = block.previousSibling.childNodes.length;

/** Index in childs Array */
if (lastChildOfPreiviousBlockIndex !== 0) {
lastChildOfPreiviousBlockIndex--;
}

cEditor.caret.set(block.previousSibling, lastChildOfPreiviousBlockIndex , 0);
},
};

Expand Down