diff options
Diffstat (limited to 'contexts/data/lib/closure-library/closure/goog/editor/plugins/tableeditor.js')
-rw-r--r-- | contexts/data/lib/closure-library/closure/goog/editor/plugins/tableeditor.js | 472 |
1 files changed, 0 insertions, 472 deletions
diff --git a/contexts/data/lib/closure-library/closure/goog/editor/plugins/tableeditor.js b/contexts/data/lib/closure-library/closure/goog/editor/plugins/tableeditor.js deleted file mode 100644 index 927010c..0000000 --- a/contexts/data/lib/closure-library/closure/goog/editor/plugins/tableeditor.js +++ /dev/null @@ -1,472 +0,0 @@ -// Copyright 2008 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Plugin that enables table editing. - * - * @see ../../demos/editor/tableeditor.html - */ - -goog.provide('goog.editor.plugins.TableEditor'); - -goog.require('goog.array'); -goog.require('goog.dom'); -goog.require('goog.dom.TagName'); -goog.require('goog.editor.Plugin'); -goog.require('goog.editor.Table'); -goog.require('goog.editor.node'); -goog.require('goog.editor.range'); -goog.require('goog.object'); - - - -/** - * Plugin that adds support for table creation and editing commands. - * @constructor - * @extends {goog.editor.Plugin} - */ -goog.editor.plugins.TableEditor = function() { - goog.base(this); - - /** - * The array of functions that decide whether a table element could be - * editable by the user or not. - * @type {Array.<function(Element):boolean>} - * @private - */ - this.isTableEditableFunctions_ = []; - - /** - * The pre-bound function that decides whether a table element could be - * editable by the user or not overall. - * @type {function(Node):boolean} - * @private - */ - this.isUserEditableTableBound_ = goog.bind(this.isUserEditableTable_, this); -}; -goog.inherits(goog.editor.plugins.TableEditor, goog.editor.Plugin); - - -/** @override */ -// TODO(user): remove this once there's a sensible default -// implementation in the base Plugin. -goog.editor.plugins.TableEditor.prototype.getTrogClassId = function() { - return String(goog.getUid(this.constructor)); -}; - - -/** - * Commands supported by goog.editor.plugins.TableEditor. - * @enum {string} - */ -goog.editor.plugins.TableEditor.COMMAND = { - TABLE: '+table', - INSERT_ROW_AFTER: '+insertRowAfter', - INSERT_ROW_BEFORE: '+insertRowBefore', - INSERT_COLUMN_AFTER: '+insertColumnAfter', - INSERT_COLUMN_BEFORE: '+insertColumnBefore', - REMOVE_ROWS: '+removeRows', - REMOVE_COLUMNS: '+removeColumns', - SPLIT_CELL: '+splitCell', - MERGE_CELLS: '+mergeCells', - REMOVE_TABLE: '+removeTable' -}; - - -/** - * Inverse map of execCommand strings to - * {@link goog.editor.plugins.TableEditor.COMMAND} constants. Used to - * determine whether a string corresponds to a command this plugin handles - * in O(1) time. - * @type {Object} - * @private - */ -goog.editor.plugins.TableEditor.SUPPORTED_COMMANDS_ = - goog.object.transpose(goog.editor.plugins.TableEditor.COMMAND); - - -/** - * Whether the string corresponds to a command this plugin handles. - * @param {string} command Command string to check. - * @return {boolean} Whether the string corresponds to a command - * this plugin handles. - * @override - */ -goog.editor.plugins.TableEditor.prototype.isSupportedCommand = - function(command) { - return command in goog.editor.plugins.TableEditor.SUPPORTED_COMMANDS_; -}; - - -/** @override */ -goog.editor.plugins.TableEditor.prototype.enable = function(fieldObject) { - goog.base(this, 'enable', fieldObject); - - // enableObjectResizing is supported only for Gecko. - // You can refer to http://qooxdoo.org/contrib/project/htmlarea/html_editing - // for a compatibility chart. - if (goog.userAgent.GECKO) { - var doc = this.getFieldDomHelper().getDocument(); - doc.execCommand('enableObjectResizing', false, 'true'); - } -}; - - -/** - * Returns the currently selected table. - * @return {Element?} The table in which the current selection is - * contained, or null if there isn't such a table. - * @private - */ -goog.editor.plugins.TableEditor.prototype.getCurrentTable_ = function() { - var selectedElement = this.getFieldObject().getRange().getContainer(); - return this.getAncestorTable_(selectedElement); -}; - - -/** - * Finds the first user-editable table element in the input node's ancestors. - * @param {Node?} node The node to start with. - * @return {Element?} The table element that is closest ancestor of the node. - * @private - */ -goog.editor.plugins.TableEditor.prototype.getAncestorTable_ = function(node) { - var ancestor = goog.dom.getAncestor(node, this.isUserEditableTableBound_, - true); - if (goog.editor.node.isEditable(ancestor)) { - return /** @type {Element?} */(ancestor); - } else { - return null; - } -}; - - -/** - * Returns the current value of a given command. Currently this plugin - * only returns a value for goog.editor.plugins.TableEditor.COMMAND.TABLE. - * @override - */ -goog.editor.plugins.TableEditor.prototype.queryCommandValue = - function(command) { - if (command == goog.editor.plugins.TableEditor.COMMAND.TABLE) { - return !!this.getCurrentTable_(); - } -}; - - -/** @override */ -goog.editor.plugins.TableEditor.prototype.execCommandInternal = function( - command, opt_arg) { - var result = null; - // TD/TH in which to place the cursor, if the command destroys the current - // cursor position. - var cursorCell = null; - var range = this.getFieldObject().getRange(); - if (command == goog.editor.plugins.TableEditor.COMMAND.TABLE) { - // Don't create a table if the cursor isn't in an editable region. - if (!goog.editor.range.isEditable(range)) { - return null; - } - // Create the table. - var tableProps = opt_arg || {width: 4, height: 2}; - var doc = this.getFieldDomHelper().getDocument(); - var table = goog.editor.Table.createDomTable( - doc, tableProps.width, tableProps.height); - range.replaceContentsWithNode(table); - // In IE, replaceContentsWithNode uses pasteHTML, so we lose our reference - // to the inserted table. - // TODO(user): use the reference to the table element returned from - // replaceContentsWithNode. - if (!goog.userAgent.IE) { - cursorCell = table.getElementsByTagName('td')[0]; - } - } else { - var cellSelection = new goog.editor.plugins.TableEditor.CellSelection_( - range, goog.bind(this.getAncestorTable_, this)); - var table = cellSelection.getTable(); - if (!table) { - return null; - } - switch (command) { - case goog.editor.plugins.TableEditor.COMMAND.INSERT_ROW_BEFORE: - table.insertRow(cellSelection.getFirstRowIndex()); - break; - case goog.editor.plugins.TableEditor.COMMAND.INSERT_ROW_AFTER: - table.insertRow(cellSelection.getLastRowIndex() + 1); - break; - case goog.editor.plugins.TableEditor.COMMAND.INSERT_COLUMN_BEFORE: - table.insertColumn(cellSelection.getFirstColumnIndex()); - break; - case goog.editor.plugins.TableEditor.COMMAND.INSERT_COLUMN_AFTER: - table.insertColumn(cellSelection.getLastColumnIndex() + 1); - break; - case goog.editor.plugins.TableEditor.COMMAND.REMOVE_ROWS: - var startRow = cellSelection.getFirstRowIndex(); - var endRow = cellSelection.getLastRowIndex(); - if (startRow == 0 && endRow == (table.rows.length - 1)) { - // Instead of deleting all rows, delete the entire table. - return this.execCommandInternal( - goog.editor.plugins.TableEditor.COMMAND.REMOVE_TABLE); - } - var startColumn = cellSelection.getFirstColumnIndex(); - var rowCount = (endRow - startRow) + 1; - for (var i = 0; i < rowCount; i++) { - table.removeRow(startRow); - } - if (table.rows.length > 0) { - // Place cursor in the previous/first row. - var closestRow = Math.min(startRow, table.rows.length - 1); - cursorCell = table.rows[closestRow].columns[startColumn].element; - } - break; - case goog.editor.plugins.TableEditor.COMMAND.REMOVE_COLUMNS: - var startCol = cellSelection.getFirstColumnIndex(); - var endCol = cellSelection.getLastColumnIndex(); - if (startCol == 0 && endCol == (table.rows[0].columns.length - 1)) { - // Instead of deleting all columns, delete the entire table. - return this.execCommandInternal( - goog.editor.plugins.TableEditor.COMMAND.REMOVE_TABLE); - } - var startRow = cellSelection.getFirstRowIndex(); - var removeCount = (endCol - startCol) + 1; - for (var i = 0; i < removeCount; i++) { - table.removeColumn(startCol); - } - var currentRow = table.rows[startRow]; - if (currentRow) { - // Place cursor in the previous/first column. - var closestCol = Math.min(startCol, currentRow.columns.length - 1); - cursorCell = currentRow.columns[closestCol].element; - } - break; - case goog.editor.plugins.TableEditor.COMMAND.MERGE_CELLS: - if (cellSelection.isRectangle()) { - table.mergeCells(cellSelection.getFirstRowIndex(), - cellSelection.getFirstColumnIndex(), - cellSelection.getLastRowIndex(), - cellSelection.getLastColumnIndex()); - } - break; - case goog.editor.plugins.TableEditor.COMMAND.SPLIT_CELL: - if (cellSelection.containsSingleCell()) { - table.splitCell(cellSelection.getFirstRowIndex(), - cellSelection.getFirstColumnIndex()); - } - break; - case goog.editor.plugins.TableEditor.COMMAND.REMOVE_TABLE: - table.element.parentNode.removeChild(table.element); - break; - default: - } - } - if (cursorCell) { - range = goog.dom.Range.createFromNodeContents(cursorCell); - range.collapse(false); - range.select(); - } - return result; -}; - - -/** - * Checks whether the element is a table editable by the user. - * @param {Node} element The element in question. - * @return {boolean} Whether the element is a table editable by the user. - * @private - */ -goog.editor.plugins.TableEditor.prototype.isUserEditableTable_ = - function(element) { - // Default implementation. - if (element.tagName != goog.dom.TagName.TABLE) { - return false; - } - - // Check for extra user-editable filters. - return goog.array.every(this.isTableEditableFunctions_, function(func) { - return func(/** @type {Element} */ (element)); - }); -}; - - -/** - * Adds a function to filter out non-user-editable tables. - * @param {function(Element):boolean} func A function to decide whether the - * table element could be editable by the user or not. - */ -goog.editor.plugins.TableEditor.prototype.addIsTableEditableFunction = - function(func) { - goog.array.insert(this.isTableEditableFunctions_, func); -}; - - - -/** - * Class representing the selected cell objects within a single table. - * @param {goog.dom.AbstractRange} range Selected range from which to calculate - * selected cells. - * @param {function(Element):Element?} getParentTableFunction A function that - * finds the user-editable table from a given element. - * @constructor - * @private - */ -goog.editor.plugins.TableEditor.CellSelection_ = - function(range, getParentTableFunction) { - this.cells_ = []; - - // Mozilla lets users select groups of cells, with each cell showing - // up as a separate range in the selection. goog.dom.Range doesn't - // currently support this. - // TODO(user): support this case in range.js - var selectionContainer = range.getContainerElement(); - var elementInSelection = function(node) { - // TODO(user): revert to the more liberal containsNode(node, true), - // which will match partially-selected cells. We're using - // containsNode(node, false) at the moment because otherwise it's - // broken in WebKit due to a closure range bug. - return selectionContainer == node || - selectionContainer.parentNode == node || - range.containsNode(node, false); - }; - - var parentTableElement = selectionContainer && - getParentTableFunction(selectionContainer); - if (!parentTableElement) { - return; - } - - var parentTable = new goog.editor.Table(parentTableElement); - // It's probably not possible to select a table with no cells, but - // do a sanity check anyway. - if (!parentTable.rows.length || !parentTable.rows[0].columns.length) { - return; - } - // Loop through cells to calculate dimensions for this CellSelection. - for (var i = 0, row; row = parentTable.rows[i]; i++) { - for (var j = 0, cell; cell = row.columns[j]; j++) { - if (elementInSelection(cell.element)) { - // Update dimensions based on cell. - if (!this.cells_.length) { - this.firstRowIndex_ = cell.startRow; - this.lastRowIndex_ = cell.endRow; - this.firstColIndex_ = cell.startCol; - this.lastColIndex_ = cell.endCol; - } else { - this.firstRowIndex_ = Math.min(this.firstRowIndex_, cell.startRow); - this.lastRowIndex_ = Math.max(this.lastRowIndex_, cell.endRow); - this.firstColIndex_ = Math.min(this.firstColIndex_, cell.startCol); - this.lastColIndex_ = Math.max(this.lastColIndex_, cell.endCol); - } - this.cells_.push(cell); - } - } - } - this.parentTable_ = parentTable; -}; - - -/** - * Returns the EditableTable object of which this selection's cells are a - * subset. - * @return {goog.editor.Table?} the table. - */ -goog.editor.plugins.TableEditor.CellSelection_.prototype.getTable = - function() { - return this.parentTable_; -}; - - -/** - * Returns the row index of the uppermost cell in this selection. - * @return {number} The row index. - */ -goog.editor.plugins.TableEditor.CellSelection_.prototype.getFirstRowIndex = - function() { - return this.firstRowIndex_; -}; - - -/** - * Returns the row index of the lowermost cell in this selection. - * @return {number} The row index. - */ -goog.editor.plugins.TableEditor.CellSelection_.prototype.getLastRowIndex = - function() { - return this.lastRowIndex_; -}; - - -/** - * Returns the column index of the farthest left cell in this selection. - * @return {number} The column index. - */ -goog.editor.plugins.TableEditor.CellSelection_.prototype.getFirstColumnIndex = - function() { - return this.firstColIndex_; -}; - - -/** - * Returns the column index of the farthest right cell in this selection. - * @return {number} The column index. - */ -goog.editor.plugins.TableEditor.CellSelection_.prototype.getLastColumnIndex = - function() { - return this.lastColIndex_; -}; - - -/** - * Returns the cells in this selection. - * @return {Array.<Element>} Cells in this selection. - */ -goog.editor.plugins.TableEditor.CellSelection_.prototype.getCells = function() { - return this.cells_; -}; - - -/** - * Returns a boolean value indicating whether or not the cells in this - * selection form a rectangle. - * @return {boolean} Whether the selection forms a rectangle. - */ -goog.editor.plugins.TableEditor.CellSelection_.prototype.isRectangle = - function() { - // TODO(user): check for missing cells. Right now this returns - // whether all cells in the selection are in the rectangle, but doesn't - // verify that every expected cell is present. - if (!this.cells_.length) { - return false; - } - var firstCell = this.cells_[0]; - var lastCell = this.cells_[this.cells_.length - 1]; - return !(this.firstRowIndex_ < firstCell.startRow || - this.lastRowIndex_ > lastCell.endRow || - this.firstColIndex_ < firstCell.startCol || - this.lastColIndex_ > lastCell.endCol); -}; - - -/** - * Returns a boolean value indicating whether or not there is exactly - * one cell in this selection. Note that this may not be the same as checking - * whether getCells().length == 1; if there is a single cell with - * rowSpan/colSpan set it will appear multiple times. - * @return {boolean} Whether there is exatly one cell in this selection. - */ -goog.editor.plugins.TableEditor.CellSelection_.prototype.containsSingleCell = - function() { - var cellCount = this.cells_.length; - return cellCount > 0 && - (this.cells_[0] == this.cells_[cellCount - 1]); -}; |