📄 advanced-table-operations.js
字号:
function AdvancedTableOperations(editor) {
this.editor = editor;
var cfg = editor.config;
var buttonList = AdvancedTableOperations.btnList;
var self = this;
// register the toolbar buttons provided by this plugin
var toolbar = ["linebreak"];
for (var i = 0; i < buttonList.length; ++i)
{
var btn = buttonList[i];
if (!btn)
{
toolbar.push("separator");
}
else
{
var id = "TO-" + btn[0];
cfg.registerButton(id, HTMLArea._lc(btn[2], "AdvancedTableOperations"), editor.imgURL(btn[0] + ".gif", "AdvancedTableOperations"), false,
function(editor, id)
{
self.buttonPress(editor, id);
}, btn[1]);
toolbar.push(id);
}
}
cfg.toolbar.push(toolbar);
}
AdvancedTableOperations._pluginInfo = {
name : "AdvancedTableOperations",
version : "0.1",
developer : "Jeroen Reijn",
developer_url : "http://www.hippo.nl",
c_owner : "Jeroen Reijn",
license : "Apache 2.0"
};
/*
* Advanced Table operations.
*/
AdvancedTableOperations.prototype._lc = function(string) {
return HTMLArea._lc(string, 'AdvancedTableOperations');
};
AdvancedTableOperations.prototype.getElementNearby = function(tagName) {
var editor = this.editor;
var ancestorsElements = editor.getAllAncestors();
var returnElement = null;
tagName = ("" + tagName).toLowerCase();
for (var i = 0; i < ancestorsElements.length; ++i) {
var el = ancestorsElements[i];
if (el.tagName.toLowerCase() == tagName) {
returnElement = el;
break;
}
}
return returnElement;
};
// the list of buttons added by this plugin
AdvancedTableOperations.btnList = [
// table properties button
["table-prop", "table", "Table properties"],
null, // separator
// ROWS
["row-prop", "tr", "Row properties"],
["row-insert-above", "tr", "Insert row before"],
["row-insert-under", "tr", "Insert row after"],
["row-delete", "tr", "Delete row"],
["row-split", "td[rowSpan!=1]", "Split row"],
null,
// COLS
["col-insert-before", "td", "Insert column before"],
["col-insert-after", "td", "Insert column after"],
["col-delete", "td", "Delete column"],
["col-split", "td[colSpan!=1]", "Split column"],
["col-prop", "td|th","Col properties"],
null,
// CELLS
["cell-prop", "td|th", "Cell properties"],
["cell-insert-before", "td|th", "Insert cell before"],
["cell-insert-after", "td|th", "Insert cell after"],
["cell-delete", "td|th", "Delete cell"],
["cell-merge", "tr", "Merge cells"],
["cell-split", "td[colSpan!=1,rowSpan!=1]|th", "Split cell"]
];
// this function gets called when some button from the TableOperations toolbar
// was pressed.
AdvancedTableOperations.prototype.buttonPress = function(editor, button_id) {
this.editor = editor;
switch(button_id) {
case "TO-row-insert-above":
case "TO-row-insert-under":
var tr = this.getElementNearby("tr");
if (!tr) {
break;
}
this.rowActionInsert(tr,button_id);
break;
case "TO-row-delete":
var tr = this.getElementNearby("tr");
if (!tr) {
break;
}
var par = tr.parentNode;
if (par.rows.length == 1) {
alert(HTMLArea._lc("HTMLArea refuses to delete the last row in table.", "AdvancedTableOperations"));
break;
}
this.rowActionDelete(tr,button_id);
break;
case "TO-row-split":
var td = this.getElementNearby("td");
if (!td) {
break;
}
this.rowActionSplitRow(td);
break;
case "TO-col-insert-before":
case "TO-col-insert-after":
var td = this.getElementNearby("td");
if (!td) {
break;
}
this.collumnActionInsert(td,button_id);
break;
case "TO-col-split":
var td = this.getElementNearby("td");
if (!td) {
break;
}
this.collumnActionSplitCol(td);
break;
case "TO-col-delete":
var td = this.getElementNearby("td");
if (!td) {
break;
}
if (td.parentNode.cells.length == 1)
{
alert(HTMLArea._lc("HTMLArea refuses to delete the last column in table.", "AdvancedTableOperations"));
break;
}
this.collumnActionDelete(td);
break;
case "TO-cell-insert-before":
case "TO-cell-insert-after":
var td = this.getElementNearby("td");
if (!td) {
break;
}
this.cellActionInsert(td,button_id);
break;
case "TO-cell-split":
var td = this.getElementNearby("td");
if (!td) {
break;
}
this.cellActionSplitCell(td);
break;
case "TO-cell-delete":
var td = this.getElementNearby("td");
if (!td) {
break;
}
if (td.parentNode.cells.length == 1) {
alert(HTMLArea._lc("HTMLArea refuses to delete the last cell in row.", "TableOperations"));
break;
}
this.cellActionDelete(td);
break;
case "TO-cell-merge":
// [JR] TODO: Function is to large.. need to refactor
var sel = editor._getSelection();
var range, i = 0;
var rows = [];
var row = null;
var cells = null;
// !! FIXME: Mozilla specific !!
if (!HTMLArea.is_ie) {
var mergeCells = this.cellActionMergeNonIE(sel);
rows.push(mergeCells);
}
else
{
// Internet Explorer "browser"
var td = this.getElementNearby("td");
if (!td) {
alert(HTMLArea._lc("Please click into some cell", "AdvancedTableOperations"));
break;
}
var tr = td.parentElement;
var no_cols = prompt(HTMLArea._lc("How many columns would you like to merge?", "TableOperations"), 2);
if (!no_cols) {
// cancelled
break;
}
var no_rows = prompt(HTMLArea._lc("How many rows would you like to merge?", "TableOperations"), 2);
if (!no_rows){
// cancelled
break;
}
var cell_index = td.cellIndex;
while (no_rows-- > 0)
{
td = tr.cells[cell_index];
cells = [td];
for (var i = 1; i < no_cols; ++i)
{
td = td.nextSibling;
if (!td) {
break;
}
cells.push(td);
}
rows.push(cells);
tr = tr.nextSibling;
if (!tr) {
break;
}
}
}
this.cellActionMergeCreateHTML(td,rows);
break;
// PROPERTIES
case "TO-table-prop":
this.dialogTableProperties();
break;
case "TO-row-prop":
this.dialogRowProperties();
break;
case "TO-cell-prop":
this.dialogCellProperties();
break;
case "TO-col-prop":
this.dialogColProperties();
break;
default:
alert("Button [" + button_id + "] not yet implemented");
}
};
// TableRow actions
AdvancedTableOperations.prototype.rowActionInsert = function(tr,button_id) {
var editor = this.editor;
var mozbr = HTMLArea.is_gecko ? "<br />" : "";
// helper function that clears the content in a table row
function clearRow(tr)
{
var tds = tr.getElementsByTagName("td");
for (var i = tds.length; --i >= 0;)
{
var td = tds[i];
td.rowSpan = 1;
td.innerHTML = mozbr;
}
}
var otr = tr.cloneNode(true);
clearRow(tr);
tr.parentNode.insertBefore(otr, /under/.test(button_id) ? tr : tr.nextSibling);
//tr.parentNode.insertBefore(otr, /under/.test(button_id) ? tr.nextSibling : tr);
editor.forceRedraw();
editor.focusEditor();
};
AdvancedTableOperations.prototype.rowActionDelete = function(tr,button_id) {
var editor = this.editor;
var par = tr.parentNode;
this.selectNextNode(tr);
par.removeChild(tr);
editor.forceRedraw();
editor.focusEditor();
editor.updateToolbar();
};
AdvancedTableOperations.prototype.rowActionSplitRow = function(td)
{
var editor = this.editor;
var n = parseInt("" + td.rowSpan);
var nc = parseInt("" + td.colSpan);
td.rowSpan = 1;
tr = td.parentNode;
var itr = tr.rowIndex;
var trs = tr.parentNode.rows;
var index = td.cellIndex;
while (--n > 0)
{
tr = trs[++itr];
var otd = editor._doc.createElement("td");
otd.colSpan = td.colSpan;
otd.innerHTML = mozbr;
tr.insertBefore(otd, tr.cells[index]);
}
editor.forceRedraw();
editor.updateToolbar();
};
AdvancedTableOperations.prototype.selectNextNode = function (el)
{
var editor = this.editor;
var node = el.nextSibling;
while (node && node.nodeType != 1)
{
node = node.nextSibling;
}
if (!node)
{
node = el.previousSibling;
while (node && node.nodeType != 1)
{
node = node.previousSibling;
}
}
if (!node)
{
node = el.parentNode;
}
editor.selectNodeContents(node);
};
//Table collumn actions
AdvancedTableOperations.prototype.collumnActionInsert = function(td,button_id) {
var editor = this.editor;
var mozbr = HTMLArea.is_gecko ? "<br />" : "";
var rows = td.parentNode.parentNode.rows;
var index = td.cellIndex;
var lastColumn = (td.parentNode.cells.length == index + 1);
for (var i = rows.length; --i >= 0;) {
var tr = rows[i];
var otd = editor._doc.createElement("td");
otd.innerHTML = mozbr;
if (lastColumn && HTMLArea.is_ie)
{
tr.insertBefore(otd);
}
else
{
var ref = tr.cells[index + (/after/.test(button_id) ? 1 : 0)];
tr.insertBefore(otd, ref);
}
}
editor.focusEditor();
};
AdvancedTableOperations.prototype.collumnActionSplitCol = function (td)
{
var nc = parseInt("" + td.colSpan);
td.colSpan = 1;
tr = td.parentNode;
var ref = td.nextSibling;
while (--nc > 0) {
var otd = editor._doc.createElement("td");
otd.rowSpan = td.rowSpan;
otd.innerHTML = mozbr;
tr.insertBefore(otd, ref);
}
editor.forceRedraw();
editor.updateToolbar();
};
AdvancedTableOperations.prototype.collumnActionDelete = function (td)
{
var editor = this.editor;
var index = td.cellIndex;
// set the caret first to a position that doesn't disappear
this.selectNextNode(td);
var rows = td.parentNode.parentNode.rows;
for (var i = rows.length; --i >= 0;)
{
var tr = rows[i];
tr.removeChild(tr.cells[index]);
}
editor.forceRedraw();
editor.focusEditor();
editor.updateToolbar();
};
AdvancedTableOperations.prototype.cellActionInsert = function (td,button_id)
{
var editor = this.editor;
var mozbr = HTMLArea.is_gecko ? "<br />" : "";
var tr = td.parentNode;
var otd = editor._doc.createElement("td");
otd.innerHTML = mozbr;
tr.insertBefore(otd, /after/.test(button_id) ? td.nextSibling : td);
editor.forceRedraw();
editor.focusEditor();
};
AdvancedTableOperations.prototype.cellActionSplitCell = function(td)
{
var nc = parseInt("" + td.colSpan);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -