/* global rangy */
"use strict";
// Fugue icons by Yusuke Kamiyamane http://p.yusukekamiyamane.com/
// and licensed under Creative Commons Attribution
/**
* A Table editing plugin that gives the user ability to add and remove
* rows and columns as well as merge rows and columns.
*
* @param options A configuration object.
* @param wym The WYMeditor instance to which the TableEditor should attach.
* @class
*/
function TableEditor(options, wym) {
var tableEditor = this;
options = jQuery.extend({
sMergeRowButtonHtml: String() +
'
).
*
* @param elmnt The node whose parent tr will be removed.
*/
TableEditor.prototype.removeRow = function (elmnt) {
var tableEditor = this,
wym = tableEditor._wym,
tr = wym.findUp(elmnt, 'tr'),
table;
if (tr === null) {
return false;
}
table = wym.findUp(elmnt, 'table');
if (
wym.hasSelection() === true &&
wym.doesElementContainSelection(elmnt) === true
) {
wym.deselect();
}
jQuery(tr).remove();
tableEditor.removeEmptyTable(table);
wym.registerModification();
return false;
};
/**
* Add a column to the given elmnt (representing a or a child of a | ).
*
* @param elmnt The node which will have a column appended afterward.
*/
TableEditor.prototype.addColumn = function (elmnt) {
var tableEditor = this,
wym = tableEditor._wym,
td = wym.findUp(elmnt, ['td', 'th']),
prevTds,
tdIndex,
tr,
newTd = ' | | ',
newTh = ' | ',
insertionElement;
if (td === null) {
return false;
}
prevTds = jQuery(td).prevAll();
tdIndex = prevTds.length;
tr = wym.findUp(td, 'tr');
jQuery(tr).siblings('tr').andSelf().each(function (index, element) {
insertionElement = newTd;
if (jQuery(element).find('th').length > 0) {
// The row has a TH, so insert a th
insertionElement = newTh;
}
jQuery(element).find('td,th').eq(tdIndex).after(insertionElement);
});
wym.registerModification();
return false;
};
/**
* Remove the column to the right of the given elmnt (representing a or a
* child of a | ).
*/
TableEditor.prototype.removeColumn = function (elmnt) {
var tableEditor = this,
wym = tableEditor._wym,
td = wym.findUp(elmnt, ['td', 'th']),
table,
prevTds,
tdIndex,
tr;
if (td === null) {
return false;
}
table = wym.findUp(elmnt, 'table');
prevTds = jQuery(td).prevAll();
tdIndex = prevTds.length;
tr = wym.findUp(td, 'tr');
jQuery(tr).siblings('tr').addBack().each(function (index, element) {
var $cell = jQuery(element).find("td, th").eq(tdIndex);
if (
wym.hasSelection() === true &&
wym.doesElementContainSelection($cell[0]) === true
) {
wym.deselect();
}
$cell.remove();
});
tableEditor.removeEmptyTable(table);
wym.registerModification();
return false;
};
/**
* keyDown event handler used for consistent tab key cell movement.
*/
TableEditor.prototype.keyDown = function (evt) {
var doc = this,
wym = WYMeditor.INSTANCES[doc.title],
tableEditor = wym.tableEditor;
if (evt.which === WYMeditor.KEY_CODE.TAB) {
return tableEditor.selectNextCell(wym.selectedContainer());
}
return null;
};
/**
* Move the focus to the next cell.
*/
TableEditor.prototype.selectNextCell = function (elmnt) {
var tableEditor = this,
wym = tableEditor._wym,
cell = wym.findUp(elmnt, ['td', 'th']),
nextCells,
tr,
nextRows;
if (cell === null) {
return null;
}
// Try moving to the next cell to the right
nextCells = jQuery(cell).next('td,th');
if (nextCells.length > 0) {
tableEditor.selectElement(nextCells[0]);
return false;
}
// There was no cell to the right, use the first cell in the next row
tr = wym.findUp(cell, 'tr');
nextRows = jQuery(tr).next('tr');
if (nextRows.length !== 0) {
nextCells = jQuery(nextRows).children('td,th');
if (nextCells.length > 0) {
tableEditor.selectElement(nextCells[0]);
return false;
}
}
// There is no next row. Do a normal tab
return null;
};
/**
* Select the given element using rangy selectors.
*/
TableEditor.prototype.selectElement = function (elmnt) {
var tableEditor = this,
wym = tableEditor._wym,
sel = wym.selection(),
range = rangy.createRange(wym._doc);
range.setStart(elmnt, 0);
range.setEnd(elmnt, 0);
range.collapse(false);
try {
sel.setSingleRange(range);
} catch (err) {
// ie8 can raise an "unkown runtime error" trying to empty the range
}
// Old IE selection hack
if (WYMeditor.isInternetExplorerPre11()) {
wym._saveCaret();
}
};
/**
* Get the common parent tr for the given table cell nodes. If the closest
* parent tr for each cell isn't the same, returns null.
*/
TableEditor.prototype.getCommonParentTr = function (cells) {
var firstCell,
parentTrList,
rootTr;
cells = jQuery(cells).filter('td,th');
if (cells.length === 0) {
return null;
}
firstCell = cells[0];
parentTrList = jQuery(firstCell).parent('tr');
if (parentTrList.length === 0) {
return null;
}
rootTr = parentTrList[0];
// Ensure that all of the cells have the same parent tr
jQuery(cells).each(function (index, elmnt) {
parentTrList = jQuery(elmnt).parent('tr');
if (parentTrList.length === 0 || parentTrList[0] !== rootTr) {
return null;
}
});
return rootTr;
};
|