2014-05-07 13:06:24 +08:00
|
|
|
/**
|
|
|
|
* CellSelection.js
|
|
|
|
*
|
|
|
|
* Copyright, Moxiecode Systems AB
|
|
|
|
* Released under LGPL License.
|
|
|
|
*
|
|
|
|
* License: http://www.tinymce.com/license
|
|
|
|
* Contributing: http://www.tinymce.com/contributing
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This class handles table cell selection by faking it using a css class that gets applied
|
|
|
|
* to cells when dragging the mouse from one cell to another.
|
|
|
|
*
|
|
|
|
* @class tinymce.tableplugin.CellSelection
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
define("tinymce/tableplugin/CellSelection", [
|
|
|
|
"tinymce/tableplugin/TableGrid",
|
|
|
|
"tinymce/dom/TreeWalker",
|
|
|
|
"tinymce/util/Tools"
|
|
|
|
], function(TableGrid, TreeWalker, Tools) {
|
|
|
|
return function(editor) {
|
2015-06-15 18:01:48 +08:00
|
|
|
var dom = editor.dom, tableGrid, startCell, startTable, hasCellSelection = true, resizing;
|
2014-05-07 13:06:24 +08:00
|
|
|
|
2015-06-15 18:01:48 +08:00
|
|
|
function clear(force) {
|
2014-05-07 13:06:24 +08:00
|
|
|
// Restore selection possibilities
|
|
|
|
editor.getBody().style.webkitUserSelect = '';
|
|
|
|
|
2015-06-15 18:01:48 +08:00
|
|
|
if (force || hasCellSelection) {
|
2014-05-07 13:06:24 +08:00
|
|
|
editor.dom.removeClass(
|
|
|
|
editor.dom.select('td.mce-item-selected,th.mce-item-selected'),
|
|
|
|
'mce-item-selected'
|
|
|
|
);
|
|
|
|
|
|
|
|
hasCellSelection = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function cellSelectionHandler(e) {
|
|
|
|
var sel, table, target = e.target;
|
|
|
|
|
2015-06-15 18:01:48 +08:00
|
|
|
if (resizing) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-05-07 13:06:24 +08:00
|
|
|
if (startCell && (tableGrid || target != startCell) && (target.nodeName == 'TD' || target.nodeName == 'TH')) {
|
|
|
|
table = dom.getParent(target, 'table');
|
|
|
|
if (table == startTable) {
|
|
|
|
if (!tableGrid) {
|
|
|
|
tableGrid = new TableGrid(editor, table);
|
|
|
|
tableGrid.setStartCell(startCell);
|
|
|
|
|
|
|
|
editor.getBody().style.webkitUserSelect = 'none';
|
|
|
|
}
|
|
|
|
|
|
|
|
tableGrid.setEndCell(target);
|
|
|
|
hasCellSelection = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove current selection
|
|
|
|
sel = editor.selection.getSel();
|
|
|
|
|
|
|
|
try {
|
|
|
|
if (sel.removeAllRanges) {
|
|
|
|
sel.removeAllRanges();
|
|
|
|
} else {
|
|
|
|
sel.empty();
|
|
|
|
}
|
|
|
|
} catch (ex) {
|
|
|
|
// IE9 might throw errors here
|
|
|
|
}
|
|
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add cell selection logic
|
|
|
|
editor.on('MouseDown', function(e) {
|
2015-06-15 18:01:48 +08:00
|
|
|
if (e.button != 2 && !resizing) {
|
2014-05-07 13:06:24 +08:00
|
|
|
clear();
|
|
|
|
|
|
|
|
startCell = dom.getParent(e.target, 'td,th');
|
|
|
|
startTable = dom.getParent(startCell, 'table');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-06-15 18:01:48 +08:00
|
|
|
editor.on('mouseover', cellSelectionHandler);
|
2014-05-07 13:06:24 +08:00
|
|
|
|
|
|
|
editor.on('remove', function() {
|
|
|
|
dom.unbind(editor.getDoc(), 'mouseover', cellSelectionHandler);
|
|
|
|
});
|
|
|
|
|
|
|
|
editor.on('MouseUp', function() {
|
2015-06-15 18:01:48 +08:00
|
|
|
var rng, sel = editor.selection, selectedCells, walker, node, lastNode;
|
2014-05-07 13:06:24 +08:00
|
|
|
|
|
|
|
function setPoint(node, start) {
|
|
|
|
var walker = new TreeWalker(node, node);
|
|
|
|
|
|
|
|
do {
|
|
|
|
// Text node
|
|
|
|
if (node.nodeType == 3 && Tools.trim(node.nodeValue).length !== 0) {
|
|
|
|
if (start) {
|
|
|
|
rng.setStart(node, 0);
|
|
|
|
} else {
|
|
|
|
rng.setEnd(node, node.nodeValue.length);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// BR element
|
|
|
|
if (node.nodeName == 'BR') {
|
|
|
|
if (start) {
|
|
|
|
rng.setStartBefore(node);
|
|
|
|
} else {
|
|
|
|
rng.setEndBefore(node);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} while ((node = (start ? walker.next() : walker.prev())));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Move selection to startCell
|
|
|
|
if (startCell) {
|
|
|
|
if (tableGrid) {
|
|
|
|
editor.getBody().style.webkitUserSelect = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try to expand text selection as much as we can only Gecko supports cell selection
|
|
|
|
selectedCells = dom.select('td.mce-item-selected,th.mce-item-selected');
|
|
|
|
if (selectedCells.length > 0) {
|
|
|
|
rng = dom.createRng();
|
|
|
|
node = selectedCells[0];
|
|
|
|
rng.setStartBefore(node);
|
|
|
|
rng.setEndAfter(node);
|
|
|
|
|
|
|
|
setPoint(node, 1);
|
|
|
|
walker = new TreeWalker(node, dom.getParent(selectedCells[0], 'table'));
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (node.nodeName == 'TD' || node.nodeName == 'TH') {
|
|
|
|
if (!dom.hasClass(node, 'mce-item-selected')) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
lastNode = node;
|
|
|
|
}
|
|
|
|
} while ((node = walker.next()));
|
|
|
|
|
|
|
|
setPoint(lastNode);
|
|
|
|
|
|
|
|
sel.setRng(rng);
|
|
|
|
}
|
|
|
|
|
|
|
|
editor.nodeChanged();
|
|
|
|
startCell = tableGrid = startTable = null;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-06-15 18:01:48 +08:00
|
|
|
editor.on('KeyUp Drop SetContent', function(e) {
|
|
|
|
clear(e.type == 'setcontent');
|
|
|
|
startCell = tableGrid = startTable = null;
|
|
|
|
resizing = false;
|
|
|
|
});
|
|
|
|
|
|
|
|
editor.on('ObjectResizeStart ObjectResized', function(e) {
|
|
|
|
resizing = e.type != 'objectresized';
|
2014-05-07 13:06:24 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
return {
|
|
|
|
clear: clear
|
|
|
|
};
|
|
|
|
};
|
|
|
|
});
|