Skip to content

Instantly share code, notes, and snippets.

@leo-souza
Last active June 30, 2023 03:23
Show Gist options
  • Save leo-souza/9004424 to your computer and use it in GitHub Desktop.
Save leo-souza/9004424 to your computer and use it in GitHub Desktop.
Table plugin for tinymce 4.0.16
/**
* Compiled inline version. (Library mode)
*/
/*jshint smarttabs:true, undef:true, latedef:true, curly:true, bitwise:true, camelcase:true */
/*globals $code */
(function(exports, undefined) {
"use strict";
var modules = {};
function require(ids, callback) {
var module, defs = [];
for (var i = 0; i < ids.length; ++i) {
module = modules[ids[i]] || resolve(ids[i]);
if (!module) {
throw 'module definition dependecy not found: ' + ids[i];
}
defs.push(module);
}
callback.apply(null, defs);
}
function define(id, dependencies, definition) {
if (typeof id !== 'string') {
throw 'invalid module definition, module id must be defined and be a string';
}
if (dependencies === undefined) {
throw 'invalid module definition, dependencies must be specified';
}
if (definition === undefined) {
throw 'invalid module definition, definition function must be specified';
}
require(dependencies, function() {
modules[id] = definition.apply(null, arguments);
});
}
function defined(id) {
return !!modules[id];
}
function resolve(id) {
var target = exports;
var fragments = id.split(/[.\/]/);
for (var fi = 0; fi < fragments.length; ++fi) {
if (!target[fragments[fi]]) {
return;
}
target = target[fragments[fi]];
}
return target;
}
function expose(ids) {
for (var i = 0; i < ids.length; i++) {
var target = exports;
var id = ids[i];
var fragments = id.split(/[.\/]/);
for (var fi = 0; fi < fragments.length - 1; ++fi) {
if (target[fragments[fi]] === undefined) {
target[fragments[fi]] = {};
}
target = target[fragments[fi]];
}
target[fragments[fragments.length - 1]] = modules[id];
}
}
// Included from: js/tinymce/plugins/table/classes/TableGrid.js
/**
* TableGrid.js
*
* Copyright, Moxiecode Systems AB
* Released under LGPL License.
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
/**
* This class creates a grid out of a table element. This
* makes it a whole lot easier to handle complex tables with
* col/row spans.
*
* @class tinymce.tableplugin.TableGrid
* @private
*/
define("tinymce/tableplugin/TableGrid", [
"tinymce/util/Tools",
"tinymce/Env"
], function(Tools, Env) {
var each = Tools.each;
function getSpanVal(td, name) {
return parseInt(td.getAttribute(name) || 1, 10);
}
return function(editor, table) {
var grid, startPos, endPos, selectedCell, selection = editor.selection, dom = selection.dom;
function buildGrid() {
var startY = 0;
grid = [];
each(['thead', 'tbody', 'tfoot'], function(part) {
var rows = dom.select('> ' + part + ' tr', table);
each(rows, function(tr, y) {
y += startY;
each(dom.select('> td, > th', tr), function(td, x) {
var x2, y2, rowspan, colspan;
// Skip over existing cells produced by rowspan
if (grid[y]) {
while (grid[y][x]) {
x++;
}
}
// Get col/rowspan from cell
rowspan = getSpanVal(td, 'rowspan');
colspan = getSpanVal(td, 'colspan');
// Fill out rowspan/colspan right and down
for (y2 = y; y2 < y + rowspan; y2++) {
if (!grid[y2]) {
grid[y2] = [];
}
for (x2 = x; x2 < x + colspan; x2++) {
grid[y2][x2] = {
part: part,
real: y2 == y && x2 == x,
elm: td,
rowspan: rowspan,
colspan: colspan
};
}
}
});
});
startY += rows.length;
});
}
function cloneNode(node, children) {
node = node.cloneNode(children);
node.removeAttribute('id');
return node;
}
function getCell(x, y) {
var row;
row = grid[y];
if (row) {
return row[x];
}
}
function setSpanVal(td, name, val) {
if (td) {
val = parseInt(val, 10);
if (val === 1) {
td.removeAttribute(name, 1);
} else {
td.setAttribute(name, val, 1);
}
}
}
function isCellSelected(cell) {
return cell && (dom.hasClass(cell.elm, 'mce-item-selected') || cell == selectedCell);
}
function getSelectedRows() {
var rows = [];
each(table.rows, function(row) {
each(row.cells, function(cell) {
if (dom.hasClass(cell, 'mce-item-selected') || cell == selectedCell.elm) {
rows.push(row);
return false;
}
});
});
return rows;
}
function deleteTable() {
var rng = dom.createRng();
rng.setStartAfter(table);
rng.setEndAfter(table);
selection.setRng(rng);
dom.remove(table);
}
function cloneCell(cell) {
var formatNode, cloneFormats = {};
if (editor.settings.table_clone_elements !== false) {
cloneFormats = Tools.makeMap(
(editor.settings.table_clone_elements || 'strong em b i span font h1 h2 h3 h4 h5 h6 p div').toUpperCase(),
/[ ,]/
);
}
// Clone formats
Tools.walk(cell, function(node) {
var curNode;
if (node.nodeType == 3) {
each(dom.getParents(node.parentNode, null, cell).reverse(), function(node) {
if (!cloneFormats[node.nodeName]) {
return;
}
node = cloneNode(node, false);
if (!formatNode) {
formatNode = curNode = node;
} else if (curNode) {
curNode.appendChild(node);
}
curNode = node;
});
// Add something to the inner node
if (curNode) {
curNode.innerHTML = Env.ie ? '&nbsp;' : '<br data-mce-bogus="1" />';
}
return false;
}
}, 'childNodes');
cell = cloneNode(cell, false);
setSpanVal(cell, 'rowSpan', 1);
setSpanVal(cell, 'colSpan', 1);
if (formatNode) {
cell.appendChild(formatNode);
} else {
if (!Env.ie) {
cell.innerHTML = '<br data-mce-bogus="1" />';
}
}
return cell;
}
function cleanup() {
var rng = dom.createRng(), row;
// Empty rows
each(dom.select('tr', table), function(tr) {
if (tr.cells.length === 0) {
dom.remove(tr);
}
});
// Empty table
if (dom.select('tr', table).length === 0) {
rng.setStartBefore(table);
rng.setEndBefore(table);
selection.setRng(rng);
dom.remove(table);
return;
}
// Empty header/body/footer
each(dom.select('thead,tbody,tfoot', table), function(part) {
if (part.rows.length === 0) {
dom.remove(part);
}
});
// Restore selection to start position if it still exists
buildGrid();
// Restore the selection to the closest table position
row = grid[Math.min(grid.length - 1, startPos.y)];
if (row) {
selection.select(row[Math.min(row.length - 1, startPos.x)].elm, true);
selection.collapse(true);
}
}
function fillLeftDown(x, y, rows, cols) {
var tr, x2, r, c, cell;
tr = grid[y][x].elm.parentNode;
for (r = 1; r <= rows; r++) {
tr = dom.getNext(tr, 'tr');
if (tr) {
// Loop left to find real cell
for (x2 = x; x2 >= 0; x2--) {
cell = grid[y + r][x2].elm;
if (cell.parentNode == tr) {
// Append clones after
for (c = 1; c <= cols; c++) {
dom.insertAfter(cloneCell(cell), cell);
}
break;
}
}
if (x2 == -1) {
// Insert nodes before first cell
for (c = 1; c <= cols; c++) {
tr.insertBefore(cloneCell(tr.cells[0]), tr.cells[0]);
}
}
}
}
}
function split() {
each(grid, function(row, y) {
each(row, function(cell, x) {
var colSpan, rowSpan, i;
if (isCellSelected(cell)) {
cell = cell.elm;
colSpan = getSpanVal(cell, 'colspan');
rowSpan = getSpanVal(cell, 'rowspan');
if (colSpan > 1 || rowSpan > 1) {
setSpanVal(cell, 'rowSpan', 1);
setSpanVal(cell, 'colSpan', 1);
// Insert cells right
for (i = 0; i < colSpan - 1; i++) {
dom.insertAfter(cloneCell(cell), cell);
}
fillLeftDown(x, y, rowSpan - 1, colSpan);
}
}
});
});
}
function merge(cell, cols, rows) {
var pos, startX, startY, endX, endY, x, y, startCell, endCell, children, count;
// Use specified cell and cols/rows
if (cell) {
pos = getPos(cell);
startX = pos.x;
startY = pos.y;
endX = startX + (cols - 1);
endY = startY + (rows - 1);
} else {
startPos = endPos = null;
// Calculate start/end pos by checking for selected cells in grid works better with context menu
each(grid, function(row, y) {
each(row, function(cell, x) {
if (isCellSelected(cell)) {
if (!startPos) {
startPos = {x: x, y: y};
}
endPos = {x: x, y: y};
}
});
});
// Use selection
startX = startPos.x;
startY = startPos.y;
endX = endPos.x;
endY = endPos.y;
}
// Find start/end cells
startCell = getCell(startX, startY);
endCell = getCell(endX, endY);
// Check if the cells exists and if they are of the same part for example tbody = tbody
if (startCell && endCell && startCell.part == endCell.part) {
// Split and rebuild grid
split();
buildGrid();
// Set row/col span to start cell
startCell = getCell(startX, startY).elm;
setSpanVal(startCell, 'colSpan', (endX - startX) + 1);
setSpanVal(startCell, 'rowSpan', (endY - startY) + 1);
// Remove other cells and add it's contents to the start cell
for (y = startY; y <= endY; y++) {
for (x = startX; x <= endX; x++) {
if (!grid[y] || !grid[y][x]) {
continue;
}
cell = grid[y][x].elm;
/*jshint loopfunc:true */
if (cell != startCell) {
// Move children to startCell
children = Tools.grep(cell.childNodes);
each(children, function(node) {
startCell.appendChild(node);
});
// Remove bogus nodes if there is children in the target cell
if (children.length) {
children = Tools.grep(startCell.childNodes);
count = 0;
each(children, function(node) {
if (node.nodeName == 'BR' && dom.getAttrib(node, 'data-mce-bogus') && count++ < children.length - 1) {
startCell.removeChild(node);
}
});
}
dom.remove(cell);
}
}
}
// Remove empty rows etc and restore caret location
cleanup();
}
}
function insertRow(before) {
var posY, cell, lastCell, x, rowElm, newRow, newCell, otherCell, rowSpan;
// Find first/last row
each(grid, function(row, y) {
each(row, function(cell) {
if (isCellSelected(cell)) {
cell = cell.elm;
rowElm = cell.parentNode;
newRow = cloneNode(rowElm, false);
posY = y;
if (before) {
return false;
}
}
});
if (before) {
return !posY;
}
});
for (x = 0; x < grid[0].length; x++) {
// Cell not found could be because of an invalid table structure
if (!grid[posY][x]) {
continue;
}
cell = grid[posY][x].elm;
if (cell != lastCell) {
if (!before) {
rowSpan = getSpanVal(cell, 'rowspan');
if (rowSpan > 1) {
setSpanVal(cell, 'rowSpan', rowSpan + 1);
continue;
}
} else {
// Check if cell above can be expanded
if (posY > 0 && grid[posY - 1][x]) {
otherCell = grid[posY - 1][x].elm;
rowSpan = getSpanVal(otherCell, 'rowSpan');
if (rowSpan > 1) {
setSpanVal(otherCell, 'rowSpan', rowSpan + 1);
continue;
}
}
}
// Insert new cell into new row
newCell = cloneCell(cell);
setSpanVal(newCell, 'colSpan', cell.colSpan);
newRow.appendChild(newCell);
lastCell = cell;
}
}
if (newRow.hasChildNodes()) {
if (!before) {
dom.insertAfter(newRow, rowElm);
} else {
rowElm.parentNode.insertBefore(newRow, rowElm);
}
}
}
function insertCol(before) {
var posX, lastCell;
// Find first/last column
each(grid, function(row) {
each(row, function(cell, x) {
if (isCellSelected(cell)) {
posX = x;
if (before) {
return false;
}
}
});
if (before) {
return !posX;
}
});
each(grid, function(row, y) {
var cell, rowSpan, colSpan;
if (!row[posX]) {
return;
}
cell = row[posX].elm;
if (cell != lastCell) {
colSpan = getSpanVal(cell, 'colspan');
rowSpan = getSpanVal(cell, 'rowspan');
if (colSpan == 1) {
if (!before) {
dom.insertAfter(cloneCell(cell), cell);
fillLeftDown(posX, y, rowSpan - 1, colSpan);
} else {
cell.parentNode.insertBefore(cloneCell(cell), cell);
fillLeftDown(posX, y, rowSpan - 1, colSpan);
}
} else {
setSpanVal(cell, 'colSpan', cell.colSpan + 1);
}
lastCell = cell;
}
});
}
function deleteCols() {
var cols = [];
// Get selected column indexes
each(grid, function(row) {
each(row, function(cell, x) {
if (isCellSelected(cell) && Tools.inArray(cols, x) === -1) {
each(grid, function(row) {
var cell = row[x].elm, colSpan;
colSpan = getSpanVal(cell, 'colSpan');
if (colSpan > 1) {
setSpanVal(cell, 'colSpan', colSpan - 1);
} else {
dom.remove(cell);
}
});
cols.push(x);
}
});
});
cleanup();
}
function deleteRows() {
var rows;
function deleteRow(tr) {
var nextTr, pos, lastCell;
nextTr = dom.getNext(tr, 'tr');
// Move down row spanned cells
each(tr.cells, function(cell) {
var rowSpan = getSpanVal(cell, 'rowSpan');
if (rowSpan > 1) {
setSpanVal(cell, 'rowSpan', rowSpan - 1);
pos = getPos(cell);
fillLeftDown(pos.x, pos.y, 1, 1);
}
});
// Delete cells
pos = getPos(tr.cells[0]);
each(grid[pos.y], function(cell) {
var rowSpan;
cell = cell.elm;
if (cell != lastCell) {
rowSpan = getSpanVal(cell, 'rowSpan');
if (rowSpan <= 1) {
dom.remove(cell);
} else {
setSpanVal(cell, 'rowSpan', rowSpan - 1);
}
lastCell = cell;
}
});
}
// Get selected rows and move selection out of scope
rows = getSelectedRows();
// Delete all selected rows
each(rows.reverse(), function(tr) {
deleteRow(tr);
});
cleanup();
}
function cutRows() {
var rows = getSelectedRows();
dom.remove(rows);
cleanup();
return rows;
}
function copyRows() {
var rows = getSelectedRows();
each(rows, function(row, i) {
rows[i] = cloneNode(row, true);
});
return rows;
}
function pasteRows(rows, before) {
var selectedRows = getSelectedRows(),
targetRow = selectedRows[before ? 0 : selectedRows.length - 1],
targetCellCount = targetRow.cells.length;
// Nothing to paste
if (!rows) {
return;
}
// Calc target cell count
each(grid, function(row) {
var match;
targetCellCount = 0;
each(row, function(cell) {
if (cell.real) {
targetCellCount += cell.colspan;
}
if (cell.elm.parentNode == targetRow) {
match = 1;
}
});
if (match) {
return false;
}
});
if (!before) {
rows.reverse();
}
each(rows, function(row) {
var i, cellCount = row.cells.length, cell;
// Remove col/rowspans
for (i = 0; i < cellCount; i++) {
cell = row.cells[i];
setSpanVal(cell, 'colSpan', 1);
setSpanVal(cell, 'rowSpan', 1);
}
// Needs more cells
for (i = cellCount; i < targetCellCount; i++) {
row.appendChild(cloneCell(row.cells[cellCount - 1]));
}
// Needs less cells
for (i = targetCellCount; i < cellCount; i++) {
dom.remove(row.cells[i]);
}
// Add before/after
if (before) {
targetRow.parentNode.insertBefore(row, targetRow);
} else {
dom.insertAfter(row, targetRow);
}
});
// Remove current selection
dom.removeClass(dom.select('td.mce-item-selected,th.mce-item-selected'), 'mce-item-selected');
}
function getPos(target) {
var pos;
each(grid, function(row, y) {
each(row, function(cell, x) {
if (cell.elm == target) {
pos = {x : x, y : y};
return false;
}
});
return !pos;
});
return pos;
}
function setStartCell(cell) {
startPos = getPos(cell);
}
function findEndPos() {
var maxX, maxY;
maxX = maxY = 0;
each(grid, function(row, y) {
each(row, function(cell, x) {
var colSpan, rowSpan;
if (isCellSelected(cell)) {
cell = grid[y][x];
if (x > maxX) {
maxX = x;
}
if (y > maxY) {
maxY = y;
}
if (cell.real) {
colSpan = cell.colspan - 1;
rowSpan = cell.rowspan - 1;
if (colSpan) {
if (x + colSpan > maxX) {
maxX = x + colSpan;
}
}
if (rowSpan) {
if (y + rowSpan > maxY) {
maxY = y + rowSpan;
}
}
}
}
});
});
return {x : maxX, y : maxY};
}
function setEndCell(cell) {
var startX, startY, endX, endY, maxX, maxY, colSpan, rowSpan, x, y;
endPos = getPos(cell);
if (startPos && endPos) {
// Get start/end positions
startX = Math.min(startPos.x, endPos.x);
startY = Math.min(startPos.y, endPos.y);
endX = Math.max(startPos.x, endPos.x);
endY = Math.max(startPos.y, endPos.y);
// Expand end positon to include spans
maxX = endX;
maxY = endY;
// Expand startX
for (y = startY; y <= maxY; y++) {
cell = grid[y][startX];
if (!cell.real) {
if (startX - (cell.colspan - 1) < startX) {
startX -= cell.colspan - 1;
}
}
}
// Expand startY
for (x = startX; x <= maxX; x++) {
cell = grid[startY][x];
if (!cell.real) {
if (startY - (cell.rowspan - 1) < startY) {
startY -= cell.rowspan - 1;
}
}
}
// Find max X, Y
for (y = startY; y <= endY; y++) {
for (x = startX; x <= endX; x++) {
cell = grid[y][x];
if (cell.real) {
colSpan = cell.colspan - 1;
rowSpan = cell.rowspan - 1;
if (colSpan) {
if (x + colSpan > maxX) {
maxX = x + colSpan;
}
}
if (rowSpan) {
if (y + rowSpan > maxY) {
maxY = y + rowSpan;
}
}
}
}
}
// Remove current selection
dom.removeClass(dom.select('td.mce-item-selected,th.mce-item-selected'), 'mce-item-selected');
// Add new selection
for (y = startY; y <= maxY; y++) {
for (x = startX; x <= maxX; x++) {
if (grid[y][x]) {
dom.addClass(grid[y][x].elm, 'mce-item-selected');
}
}
}
}
}
table = table || dom.getParent(selection.getStart(), 'table');
buildGrid();
selectedCell = dom.getParent(selection.getStart(), 'th,td');
if (selectedCell) {
startPos = getPos(selectedCell);
endPos = findEndPos();
selectedCell = getCell(startPos.x, startPos.y);
}
Tools.extend(this, {
deleteTable: deleteTable,
split: split,
merge: merge,
insertRow: insertRow,
insertCol: insertCol,
deleteCols: deleteCols,
deleteRows: deleteRows,
cutRows: cutRows,
copyRows: copyRows,
pasteRows: pasteRows,
getPos: getPos,
setStartCell: setStartCell,
setEndCell: setEndCell
});
};
});
// Included from: js/tinymce/plugins/table/classes/Quirks.js
/**
* Quirks.js
*
* Copyright, Moxiecode Systems AB
* Released under LGPL License.
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
/**
* This class includes fixes for various browser quirks.
*
* @class tinymce.tableplugin.Quirks
* @private
*/
define("tinymce/tableplugin/Quirks", [
"tinymce/util/VK",
"tinymce/Env",
"tinymce/util/Tools"
], function(VK, Env, Tools) {
var each = Tools.each;
function getSpanVal(td, name) {
return parseInt(td.getAttribute(name) || 1, 10);
}
return function(editor) {
/**
* Fixed caret movement around tables on WebKit.
*/
function moveWebKitSelection() {
function eventHandler(e) {
var key = e.keyCode;
function handle(upBool, sourceNode) {
var siblingDirection = upBool ? 'previousSibling' : 'nextSibling';
var currentRow = editor.dom.getParent(sourceNode, 'tr');
var siblingRow = currentRow[siblingDirection];
if (siblingRow) {
moveCursorToRow(editor, sourceNode, siblingRow, upBool);
e.preventDefault();
return true;
} else {
var tableNode = editor.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);
}
}
return escapeTable(upBool, currentRow, siblingDirection, tableNode);
}
}
function getTargetParent(upBool, topNode, secondNode, nodeName) {
var tbodies = editor.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 getFirstHeadOrFoot(upBool, parent) {
var tagName = upBool ? 'thead' : 'tfoot';
var headOrFoot = editor.dom.select('>' + tagName, parent);
return headOrFoot.length !== 0 ? headOrFoot[0] : null;
}
function moveToRowInTarget(upBool, targetParent, sourceNode) {
var targetRow = getChildForDirection(targetParent, upBool);
if (targetRow) {
moveCursorToRow(editor, sourceNode, targetRow, upBool);
}
e.preventDefault();
return true;
}
function escapeTable(upBool, currentRow, siblingDirection, table) {
var tableSibling = table[siblingDirection];
if (tableSibling) {
moveCursorToStartOfElement(tableSibling);
return true;
} else {
var parentCell = editor.dom.getParent(table, 'td,th');
if (parentCell) {
return handle(upBool, parentCell, e);
} else {
var backUpSibling = getChildForDirection(currentRow, !upBool);
moveCursorToStartOfElement(backUpSibling);
e.preventDefault();
return false;
}
}
}
function getChildForDirection(parent, up) {
var child = parent && parent[up ? 'lastChild' : 'firstChild'];
// BR is not a valid table child to return in this case we return the table cell
return child && child.nodeName === 'BR' ? editor.dom.getParent(child, 'td,th') : child;
}
function moveCursorToStartOfElement(n) {
editor.selection.setCursorLocation(n, 0);
}
function isVerticalMovement() {
return key == VK.UP || key == VK.DOWN;
}
function isInTable(editor) {
var node = editor.selection.getNode();
var currentRow = editor.dom.getParent(node, 'tr');
return currentRow !== null;
}
function columnIndex(column) {
var colIndex = 0;
var c = column;
while (c.previousSibling) {
c = c.previousSibling;
colIndex = colIndex + getSpanVal(c, "colspan");
}
return colIndex;
}
function findColumn(rowElement, columnIndex) {
var c = 0, r = 0;
each(rowElement.children, function(cell, i) {
c = c + getSpanVal(cell, "colspan");
r = i;
if (c > columnIndex) {
return false;
}
});
return r;
}
function moveCursorToRow(ed, node, row, upBool) {
var srcColumnIndex = columnIndex(editor.dom.getParent(node, 'td,th'));
var tgtColumnIndex = findColumn(row, srcColumnIndex);
var tgtNode = row.childNodes[tgtColumnIndex];
var rowCellTarget = getChildForDirection(tgtNode, upBool);
moveCursorToStartOfElement(rowCellTarget || tgtNode);
}
function shouldFixCaret(preBrowserNode) {
var newNode = editor.selection.getNode();
var newParent = editor.dom.getParent(newNode, 'td,th');
var oldParent = editor.dom.getParent(preBrowserNode, 'td,th');
return newParent && newParent !== oldParent && checkSameParentTable(newParent, oldParent);
}
function checkSameParentTable(nodeOne, NodeTwo) {
return editor.dom.getParent(nodeOne, 'TABLE') === editor.dom.getParent(NodeTwo, 'TABLE');
}
if (isVerticalMovement() && isInTable(editor)) {
var preBrowserNode = editor.selection.getNode();
setTimeout(function() {
if (shouldFixCaret(preBrowserNode)) {
handle(!e.shiftKey && key === VK.UP, preBrowserNode, e);
}
}, 0);
}
}
editor.on('KeyDown', function(e) {
eventHandler(e);
});
}
function fixBeforeTableCaretBug() {
// Checks if the selection/caret is at the start of the specified block element
function isAtStart(rng, par) {
var doc = par.ownerDocument, rng2 = doc.createRange(), elm;
rng2.setStartBefore(par);
rng2.setEnd(rng.endContainer, rng.endOffset);
elm = doc.createElement('body');
elm.appendChild(rng2.cloneContents());
// Check for text characters of other elements that should be treated as content
return elm.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi, '-').replace(/<[^>]+>/g, '').length === 0;
}
// Fixes an bug where it's impossible to place the caret before a table in Gecko
// this fix solves it by detecting when the caret is at the beginning of such a table
// and then manually moves the caret infront of the table
editor.on('KeyDown', function(e) {
var rng, table, dom = editor.dom;
// On gecko it's not possible to place the caret before a table
if (e.keyCode == 37 || e.keyCode == 38) {
rng = editor.selection.getRng();
table = dom.getParent(rng.startContainer, 'table');
if (table && editor.getBody().firstChild == table) {
if (isAtStart(rng, table)) {
rng = dom.createRng();
rng.setStartBefore(table);
rng.setEndBefore(table);
editor.selection.setRng(rng);
e.preventDefault();
}
}
}
});
}
// Fixes an issue on Gecko where it's impossible to place the caret behind a table
// This fix will force a paragraph element after the table but only when the forced_root_block setting is enabled
function fixTableCaretPos() {
editor.on('KeyDown SetContent VisualAid', function() {
var last;
// Skip empty text nodes from the end
for (last = editor.getBody().lastChild; last; last = last.previousSibling) {
if (last.nodeType == 3) {
if (last.nodeValue.length > 0) {
break;
}
} else if (last.nodeType == 1 && !last.getAttribute('data-mce-bogus')) {
break;
}
}
if (last && last.nodeName == 'TABLE') {
if (editor.settings.forced_root_block) {
editor.dom.add(
editor.getBody(),
editor.settings.forced_root_block,
editor.settings.forced_root_block_attrs,
Env.ie && Env.ie < 11 ? '&nbsp;' : '<br data-mce-bogus="1" />'
);
} else {
editor.dom.add(editor.getBody(), 'br', {'data-mce-bogus': '1'});
}
}
});
editor.on('PreProcess', function(o) {
var last = o.node.lastChild;
if (last && (last.nodeName == "BR" || (last.childNodes.length == 1 &&
(last.firstChild.nodeName == 'BR' || last.firstChild.nodeValue == '\u00a0'))) &&
last.previousSibling && last.previousSibling.nodeName == "TABLE") {
editor.dom.remove(last);
}
});
}
// this nasty hack is here to work around some WebKit selection bugs.
function fixTableCellSelection() {
function tableCellSelected(ed, rng, n, currentCell) {
// The decision of when a table cell is selected is somewhat involved. The fact that this code is
// required is actually a pointer to the root cause of this bug. A cell is selected when the start
// and end offsets are 0, the start container is a text, and the selection node is either a TR (most cases)
// or the parent of the table (in the case of the selection containing the last cell of a table).
var TEXT_NODE = 3, table = ed.dom.getParent(rng.startContainer, 'TABLE');
var tableParent, allOfCellSelected, tableCellSelection;
if (table) {
tableParent = table.parentNode;
}
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;
return allOfCellSelected || tableCellSelection;
}
function fixSelection() {
var rng = editor.selection.getRng();
var n = editor.selection.getNode();
var currentCell = editor.dom.getParent(rng.startContainer, 'TD,TH');
if (!tableCellSelected(editor, rng, n, currentCell)) {
return;
}
if (!currentCell) {
currentCell=n;
}
// 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);
editor.selection.setRng(rng);
}
editor.on('KeyDown', function() {
fixSelection();
});
editor.on('MouseDown', function(e) {
if (e.button != 2) {
fixSelection();
}
});
}
/**
* Delete table if all cells are selected.
*/
function deleteTable() {
editor.on('keydown', function(e) {
if ((e.keyCode == VK.DELETE || e.keyCode == VK.BACKSPACE) && !e.isDefaultPrevented()) {
var table = editor.dom.getParent(editor.selection.getStart(), 'table');
if (table) {
var cells = editor.dom.select('td,th', table), i = cells.length;
while (i--) {
if (!editor.dom.hasClass(cells[i], 'mce-item-selected')) {
return;
}
}
e.preventDefault();
editor.execCommand('mceTableDelete');
}
}
});
}
deleteTable();
if (Env.webkit) {
moveWebKitSelection();
fixTableCellSelection();
}
if (Env.gecko) {
fixBeforeTableCaretBug();
fixTableCaretPos();
}
if (Env.ie > 10) {
fixBeforeTableCaretBug();
fixTableCaretPos();
}
};
});
// Included from: js/tinymce/plugins/table/classes/CellSelection.js
/**
* 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) {
var dom = editor.dom, tableGrid, startCell, startTable, hasCellSelection = true;
function clear() {
// Restore selection possibilities
editor.getBody().style.webkitUserSelect = '';
if (hasCellSelection) {
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;
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) {
if (e.button != 2) {
clear();
startCell = dom.getParent(e.target, 'td,th');
startTable = dom.getParent(startCell, 'table');
}
});
dom.bind(editor.getDoc(), 'mouseover', cellSelectionHandler);
editor.on('remove', function() {
dom.unbind(editor.getDoc(), 'mouseover', cellSelectionHandler);
});
editor.on('MouseUp', function() {
var rng, sel = editor.selection, selectedCells, walker, node, lastNode, endNode;
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];
endNode = selectedCells[selectedCells.length - 1];
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;
}
});
editor.on('KeyUp', function() {
clear();
});
return {
clear: clear
};
};
});
// Included from: js/tinymce/plugins/table/classes/Plugin.js
/**
* Plugin.js
*
* Copyright, Moxiecode Systems AB
* Released under LGPL License.
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
/**
* This class contains all core logic for the table plugin.
*
* @class tinymce.tableplugin.Plugin
* @private
*/
define("tinymce/tableplugin/Plugin", [
"tinymce/tableplugin/TableGrid",
"tinymce/tableplugin/Quirks",
"tinymce/tableplugin/CellSelection",
"tinymce/util/Tools",
"tinymce/dom/TreeWalker",
"tinymce/Env",
"tinymce/PluginManager"
], function(TableGrid, Quirks, CellSelection, Tools, TreeWalker, Env, PluginManager) {
var each = Tools.each;
function Plugin(editor) {
var winMan, clipboardRows, self = this; // Might be selected cells on reload
function removePxSuffix(size) {
return size ? size.replace(/px$/, '') : "";
}
function addSizeSuffix(size) {
if (/^[0-9]+$/.test(size)) {
size += "px";
}
return size;
}
function unApplyAlign(elm) {
each('left center right'.split(' '), function(name) {
editor.formatter.remove('align' + name, {}, elm);
});
}
function tableDialog() {
var dom = editor.dom, tableElm, data;
tableElm = dom.getParent(editor.selection.getStart(), 'table');
data = {
width: removePxSuffix(dom.getStyle(tableElm, 'width') || dom.getAttrib(tableElm, 'width')),
height: removePxSuffix(dom.getStyle(tableElm, 'height') || dom.getAttrib(tableElm, 'height')),
cellspacing: dom.getAttrib(tableElm, 'cellspacing'),
cellpadding: dom.getAttrib(tableElm, 'cellpadding'),
border: dom.getAttrib(tableElm, 'border'),
caption: !!dom.select('caption', tableElm)[0]
};
each('left center right'.split(' '), function(name) {
if (editor.formatter.matchNode(tableElm, 'align' + name)) {
data.align = name;
}
});
editor.windowManager.open({
title: "Table properties",
items: {
type: 'form',
layout: 'grid',
columns: 2,
data: data,
defaults: {
type: 'textbox',
maxWidth: 50
},
items: [
{label: 'Width', name: 'width'},
{label: 'Height', name: 'height'},
{label: 'Cell spacing', name: 'cellspacing'},
{label: 'Cell padding', name: 'cellpadding'},
{label: 'Border', name: 'border'},
{label: 'Caption', name: 'caption', type: 'checkbox'},
{
label: 'Alignment',
minWidth: 90,
name: 'align',
type: 'listbox',
text: 'None',
maxWidth: null,
values: [
{text: 'None', value: ''},
{text: 'Left', value: 'left'},
{text: 'Center', value: 'center'},
{text: 'Right', value: 'right'}
]
}
]
},
onsubmit: function() {
var data = this.toJSON(), captionElm;
editor.undoManager.transact(function() {
editor.dom.setAttribs(tableElm, {
cellspacing: data.cellspacing,
cellpadding: data.cellpadding,
border: data.border
});
editor.dom.setStyles(tableElm, {
width: addSizeSuffix(data.width),
height: addSizeSuffix(data.height)
});
// Toggle caption on/off
captionElm = dom.select('caption', tableElm)[0];
if (captionElm && !data.caption) {
dom.remove(captionElm);
}
if (!captionElm && data.caption) {
captionElm = dom.create('caption');
captionElm.innerHTML = !Env.ie ? '<br data-mce-bogus="1"/>' : '\u00a0';
tableElm.insertBefore(captionElm, tableElm.firstChild);
}
unApplyAlign(tableElm);
if (data.align) {
editor.formatter.apply('align' + data.align, {}, tableElm);
}
editor.focus();
editor.addVisual();
});
}
});
}
function mergeDialog(grid, cell) {
editor.windowManager.open({
title: "Merge cells",
body: [
{label: 'Cols', name: 'cols', type: 'textbox', size: 10},
{label: 'Rows', name: 'rows', type: 'textbox', size: 10}
],
onsubmit: function() {
var data = this.toJSON();
editor.undoManager.transact(function() {
grid.merge(cell, data.cols, data.rows);
});
}
});
}
function mapColors() {
var i, colors = [], colorMap;
colorMap = editor.settings.textcolor_map || [
"000000", "Black",
"993300", "Burnt orange",
"333300", "Dark olive",
"003300", "Dark green",
"003366", "Dark azure",
"000080", "Navy Blue",
"333399", "Indigo",
"333333", "Very dark gray",
"800000", "Maroon",
"FF6600", "Orange",
"808000", "Olive",
"008000", "Green",
"008080", "Teal",
"0000FF", "Blue",
"666699", "Grayish blue",
"808080", "Gray",
"FF0000", "Red",
"FF9900", "Amber",
"99CC00", "Yellow green",
"339966", "Sea green",
"33CCCC", "Turquoise",
"3366FF", "Royal blue",
"800080", "Purple",
"999999", "Medium gray",
"FF00FF", "Magenta",
"FFCC00", "Gold",
"FFFF00", "Yellow",
"00FF00", "Lime",
"00FFFF", "Aqua",
"00CCFF", "Sky blue",
"993366", "Brown",
"C0C0C0", "Silver",
"FF99CC", "Pink",
"FFCC99", "Peach",
"FFFF99", "Light yellow",
"CCFFCC", "Pale green",
"CCFFFF", "Pale cyan",
"99CCFF", "Light sky blue",
"CC99FF", "Plum",
"FFFFFF", "White"
];
for (i = 0; i < colorMap.length; i += 2) {
colors.push({
text: colorMap[i + 1],
color: colorMap[i]
});
}
return colors;
}
function renderColorPicker() {
var ctrl = this, colors, color, html, last, rows, cols, x, y, i;
colors = mapColors();
html = '<table class="mce-grid mce-grid-border mce-colorbutton-grid" role="presentation" cellspacing="0"><tbody>';
last = colors.length - 1;
rows = editor.settings.textcolor_rows || 5;
cols = editor.settings.textcolor_cols || 8;
for (y = 0; y < rows; y++) {
html += '<tr>';
for (x = 0; x < cols; x++) {
i = y * cols + x;
if (i > last) {
html += '<td></td>';
} else {
color = colors[i];
html += (
'<td>' +
'<div id="' + ctrl._id + '-' + i + '"' +
' data-mce-color="' + color.color + '"' +
' role="option"' +
' tabIndex="-1"' +
' style="' + (color ? 'background-color: #' + color.color : '') + '"' +
' title="' + color.text + '">' +
'</div>' +
'</td>'
);
}
}
html += '</tr>';
}
html += '</tbody></table>';
return html;
}
function cellDialog() {
var dom = editor.dom, cellElm, data, cells = [];
// Get selected cells or the current cell
cells = editor.dom.select('td.mce-item-selected,th.mce-item-selected');
cellElm = editor.dom.getParent(editor.selection.getStart(), 'td,th');
if (!cells.length && cellElm) {
cells.push(cellElm);
}
cellElm = cellElm || cells[0];
data = {
width: removePxSuffix(dom.getStyle(cellElm, 'width') || dom.getAttrib(cellElm, 'width')),
height: removePxSuffix(dom.getStyle(cellElm, 'height') || dom.getAttrib(cellElm, 'height')),
background: dom.toHex(dom.getStyle(cellElm, 'background-color')),
border: dom.toHex(dom.getStyle(cellElm, 'border-color')),
valign: dom.getStyle(cellElm, 'vertical-align'),
scope: dom.getAttrib(cellElm, 'scope')
};
data.type = cellElm.nodeName.toLowerCase();
each('left center right'.split(' '), function(name) {
if (editor.formatter.matchNode(cellElm, 'align' + name)) {
data.align = name;
}
});
var colorMenu = {
type: 'floatpanel',
popover: true,
autohide: true,
html: renderColorPicker,
onclick: function(e){
var comboBox = this.parent(), value;
if ((value = e.target.getAttribute('data-mce-color'))) {
this.hide();
value = '#' + value;
comboBox.value(value);
}
}
}
editor.windowManager.open({
title: "Cell properties",
items: {
type: 'form',
data: data,
layout: 'grid',
columns: 2,
defaults: {
type: 'textbox',
maxWidth: 50
},
items: [
{label: 'Width', name: 'width'},
{label: 'Height', name: 'height'},
{
label: 'Cell type',
name: 'type',
type: 'listbox',
text: 'None',
minWidth: 90,
maxWidth: null,
menu: [
{text: 'Cell', value: 'td'},
{text: 'Header cell', value: 'th'}
]
},
{
label: 'Scope',
name: 'scope',
type: 'listbox',
text: 'None',
minWidth: 90,
maxWidth: null,
menu: [
{text: 'None', value: ''},
{text: 'Row', value: 'row'},
{text: 'Column', value: 'col'},
{text: 'Row group', value: 'rowgroup'},
{text: 'Column group', value: 'colgroup'}
]
},
{
label: 'Alignment',
name: 'align',
type: 'listbox',
text: 'None',
minWidth: 90,
maxWidth: null,
values: [
{text: 'None', value: ''},
{text: 'Left', value: 'left'},
{text: 'Center', value: 'center'},
{text: 'Right', value: 'right'}
]
},
{
label: 'Vertical alignment',
name: 'valign',
type: 'listbox',
text: 'None',
minWidth: 90,
maxWidth: null,
values: [
{text: 'None', value: ''},
{text: 'Top', value: 'top'},
{text: 'Middle', value: 'middle'},
{text: 'Bottom', value: 'bottom'}
]
},
{
label: "Background color",
name: 'background',
type: 'combobox',
minWidth: 90,
maxWidth: null,
tooltip: 'Background color',
menu: colorMenu
},
{
label: "Border color",
name: "border",
type: 'combobox',
minWidth: 90,
maxWidth: null,
tooltip: 'Border color',
menu: colorMenu
}
]
},
onsubmit: function() {
var data = this.toJSON();
editor.undoManager.transact(function() {
each(cells, function(cellElm) {
editor.dom.setAttrib(cellElm, 'scope', data.scope);
editor.dom.setStyles(cellElm, {
width: addSizeSuffix(data.width),
height: addSizeSuffix(data.height),
'background-color': data.background,
'border-color': data.border,
'vertical-align': data.valign
});
// Switch cell type
if (data.type && cellElm.nodeName.toLowerCase() != data.type) {
cellElm = dom.rename(cellElm, data.type);
}
// Apply/remove alignment
unApplyAlign(cellElm);
if (data.align) {
editor.formatter.apply('align' + data.align, {}, cellElm);
}
});
editor.focus();
});
}
});
}
function rowDialog() {
var dom = editor.dom, tableElm, cellElm, rowElm, data, rows = [];
tableElm = editor.dom.getParent(editor.selection.getStart(), 'table');
cellElm = editor.dom.getParent(editor.selection.getStart(), 'td,th');
each(tableElm.rows, function(row) {
each(row.cells, function(cell) {
if (dom.hasClass(cell, 'mce-item-selected') || cell == cellElm) {
rows.push(row);
return false;
}
});
});
rowElm = rows[0];
data = {
height: removePxSuffix(dom.getStyle(rowElm, 'height') || dom.getAttrib(rowElm, 'height')),
scope: dom.getAttrib(rowElm, 'scope')
};
data.type = rowElm.parentNode.nodeName.toLowerCase();
each('left center right'.split(' '), function(name) {
if (editor.formatter.matchNode(rowElm, 'align' + name)) {
data.align = name;
}
});
editor.windowManager.open({
title: "Row properties",
items: {
type: 'form',
data: data,
columns: 2,
defaults: {
type: 'textbox'
},
items: [
{
type: 'listbox',
name: 'type',
label: 'Row type',
text: 'None',
maxWidth: null,
menu: [
{text: 'Header', value: 'thead'},
{text: 'Body', value: 'tbody'},
{text: 'Footer', value: 'tfoot'}
]
},
{
type: 'listbox',
name: 'align',
label: 'Alignment',
text: 'None',
maxWidth: null,
menu: [
{text: 'None', value: ''},
{text: 'Left', value: 'left'},
{text: 'Center', value: 'center'},
{text: 'Right', value: 'right'}
]
},
{label: 'Height', name: 'height'}
]
},
onsubmit: function() {
var data = this.toJSON(), tableElm, oldParentElm, parentElm;
editor.undoManager.transact(function() {
var toType = data.type;
each(rows, function(rowElm) {
editor.dom.setAttrib(rowElm, 'scope', data.scope);
editor.dom.setStyles(rowElm, {
height: addSizeSuffix(data.height)
});
if (toType != rowElm.parentNode.nodeName.toLowerCase()) {
tableElm = dom.getParent(rowElm, 'table');
oldParentElm = rowElm.parentNode;
parentElm = dom.select(toType, tableElm)[0];
if (!parentElm) {
parentElm = dom.create(toType);
if (tableElm.firstChild) {
tableElm.insertBefore(parentElm, tableElm.firstChild);
} else {
tableElm.appendChild(parentElm);
}
}
parentElm.appendChild(rowElm);
if (!oldParentElm.hasChildNodes()) {
dom.remove(oldParentElm);
}
}
// Apply/remove alignment
unApplyAlign(rowElm);
if (data.align) {
editor.formatter.apply('align' + data.align, {}, rowElm);
}
});
editor.focus();
});
}
});
}
function cmd(command) {
return function() {
editor.execCommand(command);
};
}
function insertTable(cols, rows) {
var y, x, html;
html = '<table><tbody>';
for (y = 0; y < rows; y++) {
html += '<tr>';
for (x = 0; x < cols; x++) {
html += '<td>' + (Env.ie ? " " : '<br>') + '</td>';
}
html += '</tr>';
}
html += '</tbody></table>';
editor.insertContent(html);
}
function handleDisabledState(ctrl, selector) {
function bindStateListener() {
ctrl.disabled(!editor.dom.getParent(editor.selection.getStart(), selector));
editor.selection.selectorChanged(selector, function(state) {
ctrl.disabled(!state);
});
}
if (editor.initialized) {
bindStateListener();
} else {
editor.on('init', bindStateListener);
}
}
function postRender() {
/*jshint validthis:true*/
handleDisabledState(this, 'table');
}
function postRenderCell() {
/*jshint validthis:true*/
handleDisabledState(this, 'td,th');
}
function generateTableGrid() {
var html = '';
html = '<table role="presentation" class="mce-grid mce-grid-border">';
for (var y = 0; y < 10; y++) {
html += '<tr>';
for (var x = 0; x < 10; x++) {
html += '<td><a href="#" data-mce-index="' + x + ',' + y + '"></a></td>';
}
html += '</tr>';
}
html += '</table>';
html += '<div class="mce-text-center">0 x 0</div>';
return html;
}
editor.addMenuItem('inserttable', {
text: 'Insert table',
icon: 'table',
context: 'table',
onhide: function() {
editor.dom.removeClass(this.menu.items()[0].getEl().getElementsByTagName('a'), 'mce-active');
},
menu: [
{
type: 'container',
html: generateTableGrid(),
onmousemove: function(e) {
var x, y, target = e.target;
if (target.nodeName == 'A') {
var table = editor.dom.getParent(target, 'table');
var pos = target.getAttribute('data-mce-index');
var rel = e.control.parent().rel;
if (pos != this.lastPos) {
pos = pos.split(',');
pos[0] = parseInt(pos[0], 10);
pos[1] = parseInt(pos[1], 10);
if (e.control.isRtl() || rel == 'tl-tr') {
for (y = 9; y >= 0; y--) {
for (x = 0; x < 10; x++) {
editor.dom.toggleClass(
table.rows[y].childNodes[x].firstChild,
'mce-active',
x >= pos[0] && y <= pos[1]
);
}
}
pos[0] = 9 - pos[0];
table.nextSibling.innerHTML = pos[0] + ' x '+ (pos[1] + 1);
} else {
for (y = 0; y < 10; y++) {
for (x = 0; x < 10; x++) {
editor.dom.toggleClass(
table.rows[y].childNodes[x].firstChild,
'mce-active',
x <= pos[0] && y <= pos[1]
);
}
}
table.nextSibling.innerHTML = (pos[0] + 1) + ' x '+ (pos[1] + 1);
}
this.lastPos = pos;
}
}
},
onclick: function(e) {
if (e.target.nodeName == 'A' && this.lastPos) {
e.preventDefault();
insertTable(this.lastPos[0] + 1, this.lastPos[1] + 1);
// TODO: Maybe rework this?
this.parent().cancel(); // Close parent menu as if it was a click
}
}
}
]
});
editor.addMenuItem('tableprops', {
text: 'Table properties',
context: 'table',
onPostRender: postRender,
onclick: tableDialog
});
editor.addMenuItem('deletetable', {
text: 'Delete table',
context: 'table',
onPostRender: postRender,
cmd: 'mceTableDelete'
});
editor.addMenuItem('cell', {
separator: 'before',
text: 'Cell',
context: 'table',
menu: [
{text: 'Cell properties', onclick: cmd('mceTableCellProps'), onPostRender: postRenderCell},
{text: 'Merge cells', onclick: cmd('mceTableMergeCells'), onPostRender: postRenderCell},
{text: 'Split cell', onclick: cmd('mceTableSplitCells'), onPostRender: postRenderCell}
]
});
editor.addMenuItem('row', {
text: 'Row',
context: 'table',
menu: [
{text: 'Insert row before', onclick: cmd('mceTableInsertRowBefore'), onPostRender: postRenderCell},
{text: 'Insert row after', onclick: cmd('mceTableInsertRowAfter'), onPostRender: postRenderCell},
{text: 'Delete row', onclick: cmd('mceTableDeleteRow'), onPostRender: postRenderCell},
{text: 'Row properties', onclick: cmd('mceTableRowProps'), onPostRender: postRenderCell},
{text: '-'},
{text: 'Cut row', onclick: cmd('mceTableCutRow'), onPostRender: postRenderCell},
{text: 'Copy row', onclick: cmd('mceTableCopyRow'), onPostRender: postRenderCell},
{text: 'Paste row before', onclick: cmd('mceTablePasteRowBefore'), onPostRender: postRenderCell},
{text: 'Paste row after', onclick: cmd('mceTablePasteRowAfter'), onPostRender: postRenderCell}
]
});
editor.addMenuItem('column', {
text: 'Column',
context: 'table',
menu: [
{text: 'Insert column before', onclick: cmd('mceTableInsertColBefore'), onPostRender: postRenderCell},
{text: 'Insert column after', onclick: cmd('mceTableInsertColAfter'), onPostRender: postRenderCell},
{text: 'Delete column', onclick: cmd('mceTableDeleteCol'), onPostRender: postRenderCell}
]
});
var menuItems = [];
each("inserttable tableprops deletetable | cell row column".split(' '), function(name) {
if (name == '|') {
menuItems.push({text: '-'});
} else {
menuItems.push(editor.menuItems[name]);
}
});
editor.addButton("table", {
type: "menubutton",
title: "Table",
menu: menuItems
});
// Select whole table is a table border is clicked
if (!Env.isIE) {
editor.on('click', function(e) {
e = e.target;
if (e.nodeName === 'TABLE') {
editor.selection.select(e);
editor.nodeChanged();
}
});
}
self.quirks = new Quirks(editor);
editor.on('Init', function() {
winMan = editor.windowManager;
self.cellSelection = new CellSelection(editor);
});
// Register action commands
each({
mceTableSplitCells: function(grid) {
grid.split();
},
mceTableMergeCells: function(grid) {
var rowSpan, colSpan, cell;
cell = editor.dom.getParent(editor.selection.getStart(), 'th,td');
if (cell) {
rowSpan = cell.rowSpan;
colSpan = cell.colSpan;
}
if (!editor.dom.select('td.mce-item-selected,th.mce-item-selected').length) {
mergeDialog(grid, cell);
} else {
grid.merge();
}
},
mceTableInsertRowBefore: function(grid) {
grid.insertRow(true);
},
mceTableInsertRowAfter: function(grid) {
grid.insertRow();
},
mceTableInsertColBefore: function(grid) {
grid.insertCol(true);
},
mceTableInsertColAfter: function(grid) {
grid.insertCol();
},
mceTableDeleteCol: function(grid) {
grid.deleteCols();
},
mceTableDeleteRow: function(grid) {
grid.deleteRows();
},
mceTableCutRow: function(grid) {
clipboardRows = grid.cutRows();
},
mceTableCopyRow: function(grid) {
clipboardRows = grid.copyRows();
},
mceTablePasteRowBefore: function(grid) {
grid.pasteRows(clipboardRows, true);
},
mceTablePasteRowAfter: function(grid) {
grid.pasteRows(clipboardRows);
},
mceTableDelete: function(grid) {
grid.deleteTable();
}
}, function(func, name) {
editor.addCommand(name, function() {
var grid = new TableGrid(editor);
if (grid) {
func(grid);
editor.execCommand('mceRepaint');
self.cellSelection.clear();
}
});
});
// Register dialog commands
each({
mceInsertTable: function() {
tableDialog();
},
mceTableRowProps: rowDialog,
mceTableCellProps: cellDialog
}, function(func, name) {
editor.addCommand(name, function(ui, val) {
func(val);
});
});
}
PluginManager.add('table', Plugin);
});
expose(["tinymce/tableplugin/TableGrid","tinymce/tableplugin/Quirks","tinymce/tableplugin/CellSelection","tinymce/tableplugin/Plugin"]);
})(this);
!function(a,b){"use strict";function d(a,b){for(var d,e=[],f=0;f<a.length;++f){if(d=c[a[f]]||g(a[f]),!d)throw"module definition dependecy not found: "+a[f];e.push(d)}b.apply(null,e)}function e(a,e,f){if("string"!=typeof a)throw"invalid module definition, module id must be defined and be a string";if(e===b)throw"invalid module definition, dependencies must be specified";if(f===b)throw"invalid module definition, definition function must be specified";d(e,function(){c[a]=f.apply(null,arguments)})}function g(b){for(var c=a,d=b.split(/[.\/]/),e=0;e<d.length;++e){if(!c[d[e]])return;c=c[d[e]]}return c}function h(d){for(var e=0;e<d.length;e++){for(var f=a,g=d[e],h=g.split(/[.\/]/),i=0;i<h.length-1;++i)f[h[i]]===b&&(f[h[i]]={}),f=f[h[i]];f[h[h.length-1]]=c[g]}}var c={};e("tinymce/tableplugin/TableGrid",["tinymce/util/Tools","tinymce/Env"],function(a,b){function d(a,b){return parseInt(a.getAttribute(b)||1,10)}var c=a.each;return function(e,f){function m(){var a=0;g=[],c(["thead","tbody","tfoot"],function(b){var e=l.select("> "+b+" tr",f);c(e,function(e,f){f+=a,c(l.select("> td, > th",e),function(a,c){var e,h,i,j;if(g[f])for(;g[f][c];)c++;for(i=d(a,"rowspan"),j=d(a,"colspan"),h=f;f+i>h;h++)for(g[h]||(g[h]=[]),e=c;c+j>e;e++)g[h][e]={part:b,real:h==f&&e==c,elm:a,rowspan:i,colspan:j}})}),a+=e.length})}function n(a,b){return a=a.cloneNode(b),a.removeAttribute("id"),a}function o(a,b){var c;return c=g[b],c?c[a]:void 0}function p(a,b,c){a&&(c=parseInt(c,10),1===c?a.removeAttribute(b,1):a.setAttribute(b,c,1))}function q(a){return a&&(l.hasClass(a.elm,"mce-item-selected")||a==j)}function r(){var a=[];return c(f.rows,function(b){c(b.cells,function(c){return l.hasClass(c,"mce-item-selected")||c==j.elm?(a.push(b),!1):void 0})}),a}function s(){var a=l.createRng();a.setStartAfter(f),a.setEndAfter(f),k.setRng(a),l.remove(f)}function t(d){var f,g={};return e.settings.table_clone_elements!==!1&&(g=a.makeMap((e.settings.table_clone_elements||"strong em b i span font h1 h2 h3 h4 h5 h6 p div").toUpperCase(),/[ ,]/)),a.walk(d,function(a){var e;return 3==a.nodeType?(c(l.getParents(a.parentNode,null,d).reverse(),function(a){g[a.nodeName]&&(a=n(a,!1),f?e&&e.appendChild(a):f=e=a,e=a)}),e&&(e.innerHTML=b.ie?"&nbsp;":'<br data-mce-bogus="1" />'),!1):void 0},"childNodes"),d=n(d,!1),p(d,"rowSpan",1),p(d,"colSpan",1),f?d.appendChild(f):b.ie||(d.innerHTML='<br data-mce-bogus="1" />'),d}function u(){var b,a=l.createRng();return c(l.select("tr",f),function(a){0===a.cells.length&&l.remove(a)}),0===l.select("tr",f).length?(a.setStartBefore(f),a.setEndBefore(f),k.setRng(a),l.remove(f),void 0):(c(l.select("thead,tbody,tfoot",f),function(a){0===a.rows.length&&l.remove(a)}),m(),b=g[Math.min(g.length-1,h.y)],b&&(k.select(b[Math.min(b.length-1,h.x)].elm,!0),k.collapse(!0)),void 0)}function v(a,b,c,d){var e,f,h,i,j;for(e=g[b][a].elm.parentNode,h=1;c>=h;h++)if(e=l.getNext(e,"tr")){for(f=a;f>=0;f--)if(j=g[b+h][f].elm,j.parentNode==e){for(i=1;d>=i;i++)l.insertAfter(t(j),j);break}if(-1==f)for(i=1;d>=i;i++)e.insertBefore(t(e.cells[0]),e.cells[0])}}function w(){c(g,function(a,b){c(a,function(a,c){var e,f,g;if(q(a)&&(a=a.elm,e=d(a,"colspan"),f=d(a,"rowspan"),e>1||f>1)){for(p(a,"rowSpan",1),p(a,"colSpan",1),g=0;e-1>g;g++)l.insertAfter(t(a),a);v(c,b,f-1,e)}})})}function x(b,d,e){var f,j,k,n,r,s,t,v,x,y,z;if(b?(f=F(b),j=f.x,k=f.y,n=j+(d-1),r=k+(e-1)):(h=i=null,c(g,function(a,b){c(a,function(a,c){q(a)&&(h||(h={x:c,y:b}),i={x:c,y:b})})}),j=h.x,k=h.y,n=i.x,r=i.y),v=o(j,k),x=o(n,r),v&&x&&v.part==x.part){for(w(),m(),v=o(j,k).elm,p(v,"colSpan",n-j+1),p(v,"rowSpan",r-k+1),t=k;r>=t;t++)for(s=j;n>=s;s++)g[t]&&g[t][s]&&(b=g[t][s].elm,b!=v&&(y=a.grep(b.childNodes),c(y,function(a){v.appendChild(a)}),y.length&&(y=a.grep(v.childNodes),z=0,c(y,function(a){"BR"==a.nodeName&&l.getAttrib(a,"data-mce-bogus")&&z++<y.length-1&&v.removeChild(a)})),l.remove(b)));u()}}function y(a){var b,e,f,h,i,j,k,m,o;for(c(g,function(d,e){return c(d,function(c){return q(c)&&(c=c.elm,i=c.parentNode,j=n(i,!1),b=e,a)?!1:void 0}),a?!b:void 0}),h=0;h<g[0].length;h++)if(g[b][h]&&(e=g[b][h].elm,e!=f)){if(a){if(b>0&&g[b-1][h]&&(m=g[b-1][h].elm,o=d(m,"rowSpan"),o>1)){p(m,"rowSpan",o+1);continue}}else if(o=d(e,"rowspan"),o>1){p(e,"rowSpan",o+1);continue}k=t(e),p(k,"colSpan",e.colSpan),j.appendChild(k),f=e}j.hasChildNodes()&&(a?i.parentNode.insertBefore(j,i):l.insertAfter(j,i))}function z(a){var b,e;c(g,function(d){return c(d,function(c,d){return q(c)&&(b=d,a)?!1:void 0}),a?!b:void 0}),c(g,function(c,f){var g,h,i;c[b]&&(g=c[b].elm,g!=e&&(i=d(g,"colspan"),h=d(g,"rowspan"),1==i?a?(g.parentNode.insertBefore(t(g),g),v(b,f,h-1,i)):(l.insertAfter(t(g),g),v(b,f,h-1,i)):p(g,"colSpan",g.colSpan+1),e=g))})}function A(){var b=[];c(g,function(e){c(e,function(e,f){q(e)&&-1===a.inArray(b,f)&&(c(g,function(a){var c,b=a[f].elm;c=d(b,"colSpan"),c>1?p(b,"colSpan",c-1):l.remove(b)}),b.push(f))})}),u()}function B(){function b(a){var b,e,f;b=l.getNext(a,"tr"),c(a.cells,function(a){var b=d(a,"rowSpan");b>1&&(p(a,"rowSpan",b-1),e=F(a),v(e.x,e.y,1,1))}),e=F(a.cells[0]),c(g[e.y],function(a){var b;a=a.elm,a!=f&&(b=d(a,"rowSpan"),1>=b?l.remove(a):p(a,"rowSpan",b-1),f=a)})}var a;a=r(),c(a.reverse(),function(a){b(a)}),u()}function C(){var a=r();return l.remove(a),u(),a}function D(){var a=r();return c(a,function(b,c){a[c]=n(b,!0)}),a}function E(a,b){var d=r(),e=d[b?0:d.length-1],f=e.cells.length;a&&(c(g,function(a){var b;return f=0,c(a,function(a){a.real&&(f+=a.colspan),a.elm.parentNode==e&&(b=1)}),b?!1:void 0}),b||a.reverse(),c(a,function(a){var c,g,d=a.cells.length;for(c=0;d>c;c++)g=a.cells[c],p(g,"colSpan",1),p(g,"rowSpan",1);for(c=d;f>c;c++)a.appendChild(t(a.cells[d-1]));for(c=f;d>c;c++)l.remove(a.cells[c]);b?e.parentNode.insertBefore(a,e):l.insertAfter(a,e)}),l.removeClass(l.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"))}function F(a){var b;return c(g,function(d,e){return c(d,function(c,d){return c.elm==a?(b={x:d,y:e},!1):void 0}),!b}),b}function G(a){h=F(a)}function H(){var a,b;return a=b=0,c(g,function(d,e){c(d,function(c,d){var f,h;q(c)&&(c=g[e][d],d>a&&(a=d),e>b&&(b=e),c.real&&(f=c.colspan-1,h=c.rowspan-1,f&&d+f>a&&(a=d+f),h&&e+h>b&&(b=e+h)))})}),{x:a,y:b}}function I(a){var b,c,d,e,f,j,k,m,n,o;if(i=F(a),h&&i){for(b=Math.min(h.x,i.x),c=Math.min(h.y,i.y),d=Math.max(h.x,i.x),e=Math.max(h.y,i.y),f=d,j=e,o=c;j>=o;o++)a=g[o][b],a.real||b-(a.colspan-1)<b&&(b-=a.colspan-1);for(n=b;f>=n;n++)a=g[c][n],a.real||c-(a.rowspan-1)<c&&(c-=a.rowspan-1);for(o=c;e>=o;o++)for(n=b;d>=n;n++)a=g[o][n],a.real&&(k=a.colspan-1,m=a.rowspan-1,k&&n+k>f&&(f=n+k),m&&o+m>j&&(j=o+m));for(l.removeClass(l.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"),o=c;j>=o;o++)for(n=b;f>=n;n++)g[o][n]&&l.addClass(g[o][n].elm,"mce-item-selected")}}var g,h,i,j,k=e.selection,l=k.dom;f=f||l.getParent(k.getStart(),"table"),m(),j=l.getParent(k.getStart(),"th,td"),j&&(h=F(j),i=H(),j=o(h.x,h.y)),a.extend(this,{deleteTable:s,split:w,merge:x,insertRow:y,insertCol:z,deleteCols:A,deleteRows:B,cutRows:C,copyRows:D,pasteRows:E,getPos:F,setStartCell:G,setEndCell:I})}}),e("tinymce/tableplugin/Quirks",["tinymce/util/VK","tinymce/Env","tinymce/util/Tools"],function(a,b,c){function e(a,b){return parseInt(a.getAttribute(b)||1,10)}var d=c.each;return function(c){function f(){function b(b){function g(a,d){var e=a?"previousSibling":"nextSibling",f=c.dom.getParent(d,"tr"),g=f[e];if(g)return r(c,d,g,a),b.preventDefault(),!0;var i=c.dom.getParent(f,"table"),l=f.parentNode,m=l.nodeName.toLowerCase();if("tbody"===m||m===(a?"tfoot":"thead")){var n=h(a,i,l,"tbody");if(null!==n)return j(a,n,d)}return k(a,f,e,i)}function h(a,b,d,e){var f=c.dom.select(">"+e,b),g=f.indexOf(d);if(a&&0===g||!a&&g===f.length-1)return i(a,b);if(-1===g){var h="thead"===d.tagName.toLowerCase()?0:f.length-1;return f[h]}return f[g+(a?-1:1)]}function i(a,b){var d=a?"thead":"tfoot",e=c.dom.select(">"+d,b);return 0!==e.length?e[0]:null}function j(a,d,e){var f=l(d,a);return f&&r(c,e,f,a),b.preventDefault(),!0}function k(a,d,e,f){var h=f[e];if(h)return m(h),!0;var i=c.dom.getParent(f,"td,th");if(i)return g(a,i,b);var j=l(d,!a);return m(j),b.preventDefault(),!1}function l(a,b){var d=a&&a[b?"lastChild":"firstChild"];return d&&"BR"===d.nodeName?c.dom.getParent(d,"td,th"):d}function m(a){c.selection.setCursorLocation(a,0)}function n(){return f==a.UP||f==a.DOWN}function o(a){var b=a.selection.getNode(),c=a.dom.getParent(b,"tr");return null!==c}function p(a){for(var b=0,c=a;c.previousSibling;)c=c.previousSibling,b+=e(c,"colspan");return b}function q(a,b){var c=0,f=0;return d(a.children,function(a,d){return c+=e(a,"colspan"),f=d,c>b?!1:void 0}),f}function r(a,b,d,e){var f=p(c.dom.getParent(b,"td,th")),g=q(d,f),h=d.childNodes[g],i=l(h,e);m(i||h)}function s(a){var b=c.selection.getNode(),d=c.dom.getParent(b,"td,th"),e=c.dom.getParent(a,"td,th");return d&&d!==e&&t(d,e)}function t(a,b){return c.dom.getParent(a,"TABLE")===c.dom.getParent(b,"TABLE")}var f=b.keyCode;if(n()&&o(c)){var u=c.selection.getNode();setTimeout(function(){s(u)&&g(!b.shiftKey&&f===a.UP,u,b)},0)}}c.on("KeyDown",function(a){b(a)})}function g(){function a(a,b){var e,c=b.ownerDocument,d=c.createRange();return d.setStartBefore(b),d.setEnd(a.endContainer,a.endOffset),e=c.createElement("body"),e.appendChild(d.cloneContents()),0===e.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi,"-").replace(/<[^>]+>/g,"").length}c.on("KeyDown",function(b){var d,e,f=c.dom;(37==b.keyCode||38==b.keyCode)&&(d=c.selection.getRng(),e=f.getParent(d.startContainer,"table"),e&&c.getBody().firstChild==e&&a(d,e)&&(d=f.createRng(),d.setStartBefore(e),d.setEndBefore(e),c.selection.setRng(d),b.preventDefault()))})}function h(){c.on("KeyDown SetContent VisualAid",function(){var a;for(a=c.getBody().lastChild;a;a=a.previousSibling)if(3==a.nodeType){if(a.nodeValue.length>0)break}else if(1==a.nodeType&&!a.getAttribute("data-mce-bogus"))break;a&&"TABLE"==a.nodeName&&(c.settings.forced_root_block?c.dom.add(c.getBody(),c.settings.forced_root_block,c.settings.forced_root_block_attrs,b.ie&&b.ie<11?"&nbsp;":'<br data-mce-bogus="1" />'):c.dom.add(c.getBody(),"br",{"data-mce-bogus":"1"}))}),c.on("PreProcess",function(a){var b=a.node.lastChild;b&&("BR"==b.nodeName||1==b.childNodes.length&&("BR"==b.firstChild.nodeName||"\xa0"==b.firstChild.nodeValue))&&b.previousSibling&&"TABLE"==b.previousSibling.nodeName&&c.dom.remove(b)})}function i(){function a(a,b,c,d){var g,h,i,e=3,f=a.dom.getParent(b.startContainer,"TABLE");return f&&(g=f.parentNode),h=b.startContainer.nodeType==e&&0===b.startOffset&&0===b.endOffset&&d&&("TR"==c.nodeName||c==g),i=("TD"==c.nodeName||"TH"==c.nodeName)&&!d,h||i}function b(){var b=c.selection.getRng(),d=c.selection.getNode(),e=c.dom.getParent(b.startContainer,"TD,TH");if(a(c,b,d,e)){e||(e=d);for(var f=e.lastChild;f.lastChild;)f=f.lastChild;b.setEnd(f,f.nodeValue.length),c.selection.setRng(b)}}c.on("KeyDown",function(){b()}),c.on("MouseDown",function(a){2!=a.button&&b()})}function j(){c.on("keydown",function(b){if((b.keyCode==a.DELETE||b.keyCode==a.BACKSPACE)&&!b.isDefaultPrevented()){var d=c.dom.getParent(c.selection.getStart(),"table");if(d){for(var e=c.dom.select("td,th",d),f=e.length;f--;)if(!c.dom.hasClass(e[f],"mce-item-selected"))return;b.preventDefault(),c.execCommand("mceTableDelete")}}})}j(),b.webkit&&(f(),i()),b.gecko&&(g(),h()),b.ie>10&&(g(),h())}}),e("tinymce/tableplugin/CellSelection",["tinymce/tableplugin/TableGrid","tinymce/dom/TreeWalker","tinymce/util/Tools"],function(a,b,c){return function(d){function j(){d.getBody().style.webkitUserSelect="",i&&(d.dom.removeClass(d.dom.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"),i=!1)}function k(b){var c,j,k=b.target;if(g&&(f||k!=g)&&("TD"==k.nodeName||"TH"==k.nodeName)){j=e.getParent(k,"table"),j==h&&(f||(f=new a(d,j),f.setStartCell(g),d.getBody().style.webkitUserSelect="none"),f.setEndCell(k),i=!0),c=d.selection.getSel();try{c.removeAllRanges?c.removeAllRanges():c.empty()}catch(l){}b.preventDefault()}}var f,g,h,e=d.dom,i=!0;return d.on("MouseDown",function(a){2!=a.button&&(j(),g=e.getParent(a.target,"td,th"),h=e.getParent(g,"table"))}),e.bind(d.getDoc(),"mouseover",k),d.on("remove",function(){e.unbind(d.getDoc(),"mouseover",k)}),d.on("MouseUp",function(){function o(d,e){var f=new b(d,d);do{if(3==d.nodeType&&0!==c.trim(d.nodeValue).length)return e?a.setStart(d,0):a.setEnd(d,d.nodeValue.length),void 0;if("BR"==d.nodeName)return e?a.setStartBefore(d):a.setEndBefore(d),void 0}while(d=e?f.next():f.prev())}var a,j,k,l,m,n,i=d.selection;if(g){if(f&&(d.getBody().style.webkitUserSelect=""),j=e.select("td.mce-item-selected,th.mce-item-selected"),j.length>0){a=e.createRng(),l=j[0],n=j[j.length-1],a.setStartBefore(l),a.setEndAfter(l),o(l,1),k=new b(l,e.getParent(j[0],"table"));do if("TD"==l.nodeName||"TH"==l.nodeName){if(!e.hasClass(l,"mce-item-selected"))break;m=l}while(l=k.next());o(m),i.setRng(a)}d.nodeChanged(),g=f=h=null}}),d.on("KeyUp",function(){j()}),{clear:j}}}),e("tinymce/tableplugin/Plugin",["tinymce/tableplugin/TableGrid","tinymce/tableplugin/Quirks","tinymce/tableplugin/CellSelection","tinymce/util/Tools","tinymce/dom/TreeWalker","tinymce/Env","tinymce/PluginManager"],function(a,b,c,d,e,f,g){function i(d){function j(a){return a?a.replace(/px$/,""):""}function k(a){return/^[0-9]+$/.test(a)&&(a+="px"),a}function l(a){h("left center right".split(" "),function(b){d.formatter.remove("align"+b,{},a)})}function m(){var b,c,a=d.dom;b=a.getParent(d.selection.getStart(),"table"),c={width:j(a.getStyle(b,"width")||a.getAttrib(b,"width")),height:j(a.getStyle(b,"height")||a.getAttrib(b,"height")),cellspacing:a.getAttrib(b,"cellspacing"),cellpadding:a.getAttrib(b,"cellpadding"),border:a.getAttrib(b,"border"),caption:!!a.select("caption",b)[0]},h("left center right".split(" "),function(a){d.formatter.matchNode(b,"align"+a)&&(c.align=a)}),d.windowManager.open({title:"Table properties",items:{type:"form",layout:"grid",columns:2,data:c,defaults:{type:"textbox",maxWidth:50},items:[{label:"Width",name:"width"},{label:"Height",name:"height"},{label:"Cell spacing",name:"cellspacing"},{label:"Cell padding",name:"cellpadding"},{label:"Border",name:"border"},{label:"Caption",name:"caption",type:"checkbox"},{label:"Alignment",minWidth:90,name:"align",type:"listbox",text:"None",maxWidth:null,values:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]}]},onsubmit:function(){var e,c=this.toJSON();d.undoManager.transact(function(){d.dom.setAttribs(b,{cellspacing:c.cellspacing,cellpadding:c.cellpadding,border:c.border}),d.dom.setStyles(b,{width:k(c.width),height:k(c.height)}),e=a.select("caption",b)[0],e&&!c.caption&&a.remove(e),!e&&c.caption&&(e=a.create("caption"),e.innerHTML=f.ie?"\xa0":'<br data-mce-bogus="1"/>',b.insertBefore(e,b.firstChild)),l(b),c.align&&d.formatter.apply("align"+c.align,{},b),d.focus(),d.addVisual()})}})}function n(a,b){d.windowManager.open({title:"Merge cells",body:[{label:"Cols",name:"cols",type:"textbox",size:10},{label:"Rows",name:"rows",type:"textbox",size:10}],onsubmit:function(){var c=this.toJSON();d.undoManager.transact(function(){a.merge(b,c.cols,c.rows)})}})}function o(){var a,c,b=[];for(c=d.settings.textcolor_map||["000000","Black","993300","Burnt orange","333300","Dark olive","003300","Dark green","003366","Dark azure","000080","Navy Blue","333399","Indigo","333333","Very dark gray","800000","Maroon","FF6600","Orange","808000","Olive","008000","Green","008080","Teal","0000FF","Blue","666699","Grayish blue","808080","Gray","FF0000","Red","FF9900","Amber","99CC00","Yellow green","339966","Sea green","33CCCC","Turquoise","3366FF","Royal blue","800080","Purple","999999","Medium gray","FF00FF","Magenta","FFCC00","Gold","FFFF00","Yellow","00FF00","Lime","00FFFF","Aqua","00CCFF","Sky blue","993366","Brown","C0C0C0","Silver","FF99CC","Pink","FFCC99","Peach","FFFF99","Light yellow","CCFFCC","Pale green","CCFFFF","Pale cyan","99CCFF","Light sky blue","CC99FF","Plum","FFFFFF","White"],a=0;a<c.length;a+=2)b.push({text:c[a+1],color:c[a]});return b}function p(){var b,c,e,f,g,h,i,j,k,a=this;for(b=o(),e='<table class="mce-grid mce-grid-border mce-colorbutton-grid" role="presentation" cellspacing="0"><tbody>',f=b.length-1,g=d.settings.textcolor_rows||5,h=d.settings.textcolor_cols||8,j=0;g>j;j++){for(e+="<tr>",i=0;h>i;i++)k=j*h+i,k>f?e+="<td></td>":(c=b[k],e+='<td><div id="'+a._id+"-"+k+'"'+' data-mce-color="'+c.color+'"'+' role="option"'+' tabIndex="-1"'+' style="'+(c?"background-color: #"+c.color:"")+'"'+' title="'+c.text+'">'+"</div>"+"</td>");e+="</tr>"}return e+="</tbody></table>"}function q(){var b,c,a=d.dom,e=[];e=d.dom.select("td.mce-item-selected,th.mce-item-selected"),b=d.dom.getParent(d.selection.getStart(),"td,th"),!e.length&&b&&e.push(b),b=b||e[0],c={width:j(a.getStyle(b,"width")||a.getAttrib(b,"width")),height:j(a.getStyle(b,"height")||a.getAttrib(b,"height")),background:a.toHex(a.getStyle(b,"background-color")),border:a.toHex(a.getStyle(b,"border-color")),valign:a.getStyle(b,"vertical-align"),scope:a.getAttrib(b,"scope")},c.type=b.nodeName.toLowerCase(),h("left center right".split(" "),function(a){d.formatter.matchNode(b,"align"+a)&&(c.align=a)});var f={type:"floatpanel",popover:!0,autohide:!0,html:p,onclick:function(a){var c,b=this.parent();(c=a.target.getAttribute("data-mce-color"))&&(this.hide(),c="#"+c,b.value(c))}};d.windowManager.open({title:"Cell properties",items:{type:"form",data:c,layout:"grid",columns:2,defaults:{type:"textbox",maxWidth:50},items:[{label:"Width",name:"width"},{label:"Height",name:"height"},{label:"Cell type",name:"type",type:"listbox",text:"None",minWidth:90,maxWidth:null,menu:[{text:"Cell",value:"td"},{text:"Header cell",value:"th"}]},{label:"Scope",name:"scope",type:"listbox",text:"None",minWidth:90,maxWidth:null,menu:[{text:"None",value:""},{text:"Row",value:"row"},{text:"Column",value:"col"},{text:"Row group",value:"rowgroup"},{text:"Column group",value:"colgroup"}]},{label:"Alignment",name:"align",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]},{label:"Vertical alignment",name:"valign",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"None",value:""},{text:"Top",value:"top"},{text:"Middle",value:"middle"},{text:"Bottom",value:"bottom"}]},{label:"Background color",name:"background",type:"combobox",minWidth:90,maxWidth:null,tooltip:"Background color",menu:f},{label:"Border color",name:"border",type:"combobox",minWidth:90,maxWidth:null,tooltip:"Border color",menu:f}]},onsubmit:function(){var b=this.toJSON();d.undoManager.transact(function(){h(e,function(c){d.dom.setAttrib(c,"scope",b.scope),d.dom.setStyles(c,{width:k(b.width),height:k(b.height),"background-color":b.background,"border-color":b.border,"vertical-align":b.valign}),b.type&&c.nodeName.toLowerCase()!=b.type&&(c=a.rename(c,b.type)),l(c),b.align&&d.formatter.apply("align"+b.align,{},c)}),d.focus()})}})}function r(){var b,c,e,f,a=d.dom,g=[];b=d.dom.getParent(d.selection.getStart(),"table"),c=d.dom.getParent(d.selection.getStart(),"td,th"),h(b.rows,function(b){h(b.cells,function(d){return a.hasClass(d,"mce-item-selected")||d==c?(g.push(b),!1):void 0})}),e=g[0],f={height:j(a.getStyle(e,"height")||a.getAttrib(e,"height")),scope:a.getAttrib(e,"scope")},f.type=e.parentNode.nodeName.toLowerCase(),h("left center right".split(" "),function(a){d.formatter.matchNode(e,"align"+a)&&(f.align=a)}),d.windowManager.open({title:"Row properties",items:{type:"form",data:f,columns:2,defaults:{type:"textbox"},items:[{type:"listbox",name:"type",label:"Row type",text:"None",maxWidth:null,menu:[{text:"Header",value:"thead"},{text:"Body",value:"tbody"},{text:"Footer",value:"tfoot"}]},{type:"listbox",name:"align",label:"Alignment",text:"None",maxWidth:null,menu:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]},{label:"Height",name:"height"}]},onsubmit:function(){var c,e,f,b=this.toJSON();d.undoManager.transact(function(){var i=b.type;h(g,function(g){d.dom.setAttrib(g,"scope",b.scope),d.dom.setStyles(g,{height:k(b.height)}),i!=g.parentNode.nodeName.toLowerCase()&&(c=a.getParent(g,"table"),e=g.parentNode,f=a.select(i,c)[0],f||(f=a.create(i),c.firstChild?c.insertBefore(f,c.firstChild):c.appendChild(f)),f.appendChild(g),e.hasChildNodes()||a.remove(e)),l(g),b.align&&d.formatter.apply("align"+b.align,{},g)}),d.focus()})}})}function s(a){return function(){d.execCommand(a)}}function t(a,b){var c,e,g;for(g="<table><tbody>",c=0;b>c;c++){for(g+="<tr>",e=0;a>e;e++)g+="<td>"+(f.ie?" ":"<br>")+"</td>";g+="</tr>"}g+="</tbody></table>",d.insertContent(g)}function u(a,b){function c(){a.disabled(!d.dom.getParent(d.selection.getStart(),b)),d.selection.selectorChanged(b,function(b){a.disabled(!b)})}d.initialized?c():d.on("init",c)}function v(){u(this,"table")}function w(){u(this,"td,th")}function x(){var a="";a='<table role="presentation" class="mce-grid mce-grid-border">';for(var b=0;10>b;b++){a+="<tr>";for(var c=0;10>c;c++)a+='<td><a href="#" data-mce-index="'+c+","+b+'"></a></td>';a+="</tr>"}return a+="</table>",a+='<div class="mce-text-center">0 x 0</div>'}var e,g,i=this;d.addMenuItem("inserttable",{text:"Insert table",icon:"table",context:"table",onhide:function(){d.dom.removeClass(this.menu.items()[0].getEl().getElementsByTagName("a"),"mce-active")},menu:[{type:"container",html:x(),onmousemove:function(a){var b,c,e=a.target;if("A"==e.nodeName){var f=d.dom.getParent(e,"table"),g=e.getAttribute("data-mce-index"),h=a.control.parent().rel;if(g!=this.lastPos){if(g=g.split(","),g[0]=parseInt(g[0],10),g[1]=parseInt(g[1],10),a.control.isRtl()||"tl-tr"==h){for(c=9;c>=0;c--)for(b=0;10>b;b++)d.dom.toggleClass(f.rows[c].childNodes[b].firstChild,"mce-active",b>=g[0]&&c<=g[1]);g[0]=9-g[0],f.nextSibling.innerHTML=g[0]+" x "+(g[1]+1)}else{for(c=0;10>c;c++)for(b=0;10>b;b++)d.dom.toggleClass(f.rows[c].childNodes[b].firstChild,"mce-active",b<=g[0]&&c<=g[1]);f.nextSibling.innerHTML=g[0]+1+" x "+(g[1]+1)}this.lastPos=g}}},onclick:function(a){"A"==a.target.nodeName&&this.lastPos&&(a.preventDefault(),t(this.lastPos[0]+1,this.lastPos[1]+1),this.parent().cancel())}}]}),d.addMenuItem("tableprops",{text:"Table properties",context:"table",onPostRender:v,onclick:m}),d.addMenuItem("deletetable",{text:"Delete table",context:"table",onPostRender:v,cmd:"mceTableDelete"}),d.addMenuItem("cell",{separator:"before",text:"Cell",context:"table",menu:[{text:"Cell properties",onclick:s("mceTableCellProps"),onPostRender:w},{text:"Merge cells",onclick:s("mceTableMergeCells"),onPostRender:w},{text:"Split cell",onclick:s("mceTableSplitCells"),onPostRender:w}]}),d.addMenuItem("row",{text:"Row",context:"table",menu:[{text:"Insert row before",onclick:s("mceTableInsertRowBefore"),onPostRender:w},{text:"Insert row after",onclick:s("mceTableInsertRowAfter"),onPostRender:w},{text:"Delete row",onclick:s("mceTableDeleteRow"),onPostRender:w},{text:"Row properties",onclick:s("mceTableRowProps"),onPostRender:w},{text:"-"},{text:"Cut row",onclick:s("mceTableCutRow"),onPostRender:w},{text:"Copy row",onclick:s("mceTableCopyRow"),onPostRender:w},{text:"Paste row before",onclick:s("mceTablePasteRowBefore"),onPostRender:w},{text:"Paste row after",onclick:s("mceTablePasteRowAfter"),onPostRender:w}]}),d.addMenuItem("column",{text:"Column",context:"table",menu:[{text:"Insert column before",onclick:s("mceTableInsertColBefore"),onPostRender:w},{text:"Insert column after",onclick:s("mceTableInsertColAfter"),onPostRender:w},{text:"Delete column",onclick:s("mceTableDeleteCol"),onPostRender:w}]});var y=[];h("inserttable tableprops deletetable | cell row column".split(" "),function(a){"|"==a?y.push({text:"-"}):y.push(d.menuItems[a])}),d.addButton("table",{type:"menubutton",title:"Table",menu:y}),f.isIE||d.on("click",function(a){a=a.target,"TABLE"===a.nodeName&&(d.selection.select(a),d.nodeChanged())}),i.quirks=new b(d),d.on("Init",function(){e=d.windowManager,i.cellSelection=new c(d)}),h({mceTableSplitCells:function(a){a.split()},mceTableMergeCells:function(a){var b,c,e;e=d.dom.getParent(d.selection.getStart(),"th,td"),e&&(b=e.rowSpan,c=e.colSpan),d.dom.select("td.mce-item-selected,th.mce-item-selected").length?a.merge():n(a,e)},mceTableInsertRowBefore:function(a){a.insertRow(!0)},mceTableInsertRowAfter:function(a){a.insertRow()},mceTableInsertColBefore:function(a){a.insertCol(!0)},mceTableInsertColAfter:function(a){a.insertCol()},mceTableDeleteCol:function(a){a.deleteCols()},mceTableDeleteRow:function(a){a.deleteRows()},mceTableCutRow:function(a){g=a.cutRows()},mceTableCopyRow:function(a){g=a.copyRows()},mceTablePasteRowBefore:function(a){a.pasteRows(g,!0)},mceTablePasteRowAfter:function(a){a.pasteRows(g)},mceTableDelete:function(a){a.deleteTable()}},function(b,c){d.addCommand(c,function(){var c=new a(d);c&&(b(c),d.execCommand("mceRepaint"),i.cellSelection.clear())})}),h({mceInsertTable:function(){m()},mceTableRowProps:r,mceTableCellProps:q},function(a,b){d.addCommand(b,function(b,c){a(c)})})}var h=d.each;g.add("table",i)}),h(["tinymce/tableplugin/TableGrid","tinymce/tableplugin/Quirks","tinymce/tableplugin/CellSelection","tinymce/tableplugin/Plugin"])}(this);
@josmanaba
Copy link

How do I use or call this code from tinymce.min.js or from my HTML code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment