assets/precompiled/tinymce/plugins/table/editor_plugin_src.js in tinymce-rails-3.4.6 vs assets/precompiled/tinymce/plugins/table/editor_plugin_src.js in tinymce-rails-3.4.7

- old
+ new

@@ -986,11 +986,11 @@ allOfCellSelected =rng.startContainer.nodeType == TEXT_NODE && rng.startOffset == 0 && rng.endOffset == 0 && currentCell && (n.nodeName=="TR" || n==tableParent); - tableCellSelection = (n.nodeName=="TD"||n.nodeName=="TH")&& !currentCell; + tableCellSelection = (n.nodeName=="TD"||n.nodeName=="TH")&& !currentCell; return allOfCellSelected || tableCellSelection; // return false; } // this nasty hack is here to work around some WebKit selection bugs. @@ -998,11 +998,11 @@ if (!tinymce.isWebKit) return; var rng = ed.selection.getRng(); var n = ed.selection.getNode(); - var currentCell = ed.dom.getParent(rng.startContainer, 'TD'); + var currentCell = ed.dom.getParent(rng.startContainer, 'TD,TH'); if (!tableCellSelected(ed, rng, n, currentCell)) return; if (!currentCell) { currentCell=n; @@ -1010,11 +1010,11 @@ // Get the very last node inside the table cell var end = currentCell.lastChild; while (end.lastChild) end = end.lastChild; - + // Select the entire table cell. Nothing outside of the table cell should be selected. rng.setEnd(end, end.nodeValue.length); ed.selection.setRng(rng); } ed.plugins.table.fixTableCellSelection=fixTableCellSelection; @@ -1072,37 +1072,91 @@ } // Fix to allow navigating up and down in a table in WebKit browsers. if (tinymce.isWebKit) { function moveSelection(ed, e) { + var VK = tinymce.VK; + var key = e.keyCode; - function moveCursorToStartOfElement(n) { - ed.selection.setCursorLocation(n, 0); + function handle(upBool, sourceNode, event) { + var siblingDirection = upBool ? 'previousSibling' : 'nextSibling'; + var currentRow = ed.dom.getParent(sourceNode, 'tr'); + var siblingRow = currentRow[siblingDirection]; + + if (siblingRow) { + moveCursorToRow(ed, sourceNode, siblingRow, upBool); + tinymce.dom.Event.cancel(event); + return true; + } else { + var tableNode = ed.dom.getParent(currentRow, 'table'); + var middleNode = currentRow.parentNode; + var parentNodeName = middleNode.nodeName.toLowerCase(); + if (parentNodeName === 'tbody' || parentNodeName === (upBool ? 'tfoot' : 'thead')) { + var targetParent = getTargetParent(upBool, tableNode, middleNode, 'tbody'); + if (targetParent !== null) { + return moveToRowInTarget(upBool, targetParent, sourceNode, event); + } + } + return escapeTable(upBool, currentRow, siblingDirection, tableNode, event); + } } - function getSibling(event, element) { - return event.keyCode == UP_ARROW ? element.previousSibling : element.nextSibling; + function getTargetParent(upBool, topNode, secondNode, nodeName) { + var tbodies = ed.dom.select('>' + nodeName, topNode); + var position = tbodies.indexOf(secondNode); + if (upBool && position === 0 || !upBool && position === tbodies.length - 1) { + return getFirstHeadOrFoot(upBool, topNode); + } else if (position === -1) { + var topOrBottom = secondNode.tagName.toLowerCase() === 'thead' ? 0 : tbodies.length - 1; + return tbodies[topOrBottom]; + } else { + return tbodies[position + (upBool ? -1 : 1)]; + } } - function getNextRow(e, row) { - var sibling = getSibling(e, row); - return sibling !== null && sibling.tagName === 'TR' ? sibling : null; + function getFirstHeadOrFoot(upBool, parent) { + var tagName = upBool ? 'thead' : 'tfoot'; + var headOrFoot = ed.dom.select('>' + tagName, parent); + return headOrFoot.length !== 0 ? headOrFoot[0] : null; } - function getTable(ed, currentRow) { - return ed.dom.getParent(currentRow, 'table'); + function moveToRowInTarget(upBool, targetParent, sourceNode, event) { + var targetRow = getChildForDirection(targetParent, upBool); + targetRow && moveCursorToRow(ed, sourceNode, targetRow, upBool); + tinymce.dom.Event.cancel(event); + return true; } - function getTableSibling(currentRow) { - var table = getTable(ed, currentRow); - return getSibling(e, table); + function escapeTable(upBool, currentRow, siblingDirection, table, event) { + var tableSibling = table[siblingDirection]; + if (tableSibling) { + moveCursorToStartOfElement(tableSibling); + return true; + } else { + var parentCell = ed.dom.getParent(table, 'td,th'); + if (parentCell) { + return handle(upBool, parentCell, event); + } else { + var backUpSibling = getChildForDirection(currentRow, !upBool); + moveCursorToStartOfElement(backUpSibling); + return tinymce.dom.Event.cancel(event); + } + } } - function isVerticalMovement(event) { - return event.keyCode == UP_ARROW || event.keyCode == DOWN_ARROW; + function getChildForDirection(parent, up) { + return parent && parent[up ? 'lastChild' : 'firstChild']; } + function moveCursorToStartOfElement(n) { + ed.selection.setCursorLocation(n, 0); + } + + function isVerticalMovement() { + return key == VK.UP || key == VK.DOWN; + } + function isInTable(ed) { var node = ed.selection.getNode(); var currentRow = ed.dom.getParent(node, 'tr'); return currentRow !== null; } @@ -1127,45 +1181,35 @@ return false; }); return r; } - function moveCursorToRow(ed, node, row) { + function moveCursorToRow(ed, node, row, upBool) { var srcColumnIndex = columnIndex(ed.dom.getParent(node, 'td,th')); - var tgtColumnIndex = findColumn(row, srcColumnIndex) + var tgtColumnIndex = findColumn(row, srcColumnIndex); var tgtNode = row.childNodes[tgtColumnIndex]; - moveCursorToStartOfElement(tgtNode); + var rowCellTarget = getChildForDirection(tgtNode, upBool); + moveCursorToStartOfElement(rowCellTarget || tgtNode); } - function escapeTable(currentRow, e) { - var tableSiblingElement = getTableSibling(currentRow); - if (tableSiblingElement !== null) { - moveCursorToStartOfElement(tableSiblingElement); - return tinymce.dom.Event.cancel(e); - } else { - var element = e.keyCode == UP_ARROW ? currentRow.firstChild : currentRow.lastChild; - // rely on default behaviour to escape table after we are in the last cell of the last row - moveCursorToStartOfElement(element); - return true; - } + function shouldFixCaret(preBrowserNode) { + var newNode = ed.selection.getNode(); + var newParent = ed.dom.getParent(newNode, 'td,th'); + var oldParent = ed.dom.getParent(preBrowserNode, 'td,th'); + return newParent && newParent !== oldParent && checkSameParentTable(newParent, oldParent) } - var UP_ARROW = 38; - var DOWN_ARROW = 40; + function checkSameParentTable(nodeOne, NodeTwo) { + return ed.dom.getParent(nodeOne, 'TABLE') === ed.dom.getParent(NodeTwo, 'TABLE'); + } - if (isVerticalMovement(e) && isInTable(ed)) { - var node = ed.selection.getNode(); - var currentRow = ed.dom.getParent(node, 'tr'); - var nextRow = getNextRow(e, currentRow); - - // If we're at the first or last row in the table, we should move the caret outside of the table - if (nextRow == null) { - return escapeTable(currentRow, e); - } else { - moveCursorToRow(ed, node, nextRow); - tinymce.dom.Event.cancel(e); - return true; - } + if (isVerticalMovement() && isInTable(ed)) { + var preBrowserNode = ed.selection.getNode(); + setTimeout(function() { + if (shouldFixCaret(preBrowserNode)) { + handle(!e.shiftKey && key === VK.UP, preBrowserNode, e); + } + }, 0); } } ed.onKeyDown.add(moveSelection); }