michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: michael@0: #include "nsISupports.idl" michael@0: michael@0: interface nsIDOMNode; michael@0: interface nsIDOMElement; michael@0: interface nsIDOMRange; michael@0: michael@0: [scriptable, uuid(4805e684-49b9-11d3-9ce4-ed60bd6cb5bc)] michael@0: michael@0: interface nsITableEditor : nsISupports michael@0: { michael@0: const short eNoSearch = 0; michael@0: const short ePreviousColumn = 1; michael@0: const short ePreviousRow = 2; michael@0: michael@0: /* ------------ Table editing Methods -------------- */ michael@0: michael@0: /** Insert table methods michael@0: * Insert relative to the selected cell or the michael@0: * cell enclosing the selection anchor michael@0: * The selection is collapsed and is left in the new cell michael@0: * at the same row,col location as the original anchor cell michael@0: * michael@0: * @param aNumber Number of items to insert michael@0: * @param aAfter If TRUE, insert after the current cell, michael@0: * else insert before current cell michael@0: */ michael@0: void insertTableCell(in long aNumber, in boolean aAfter); michael@0: void insertTableColumn(in long aNumber, in boolean aAfter); michael@0: void insertTableRow(in long aNumber, in boolean aAfter); michael@0: michael@0: /** Delete table methods michael@0: * Delete starting at the selected cell or the michael@0: * cell (or table) enclosing the selection anchor michael@0: * The selection is collapsed and is left in the michael@0: * cell at the same row,col location as michael@0: * the previous selection anchor, if possible, michael@0: * else in the closest neigboring cell michael@0: * michael@0: * @param aNumber Number of items to insert/delete michael@0: */ michael@0: void deleteTable(); michael@0: michael@0: /** Delete just the cell contents michael@0: * This is what should happen when Delete key is used michael@0: * for selected cells, to minimize upsetting the table layout michael@0: */ michael@0: void deleteTableCellContents(); michael@0: michael@0: /** Delete cell elements as well as contents michael@0: * @param aNumber Number of contiguous cells, rows, or columns michael@0: * michael@0: * When there are more than 1 selected cells, aNumber is ignored. michael@0: * For Delete Rows or Columns, the complete columns or rows are michael@0: * determined by the selected cells. E.g., to delete 2 complete rows, michael@0: * user simply selects a cell in each, and they don't michael@0: * have to be contiguous. michael@0: */ michael@0: void deleteTableCell(in long aNumber); michael@0: void deleteTableColumn(in long aNumber); michael@0: void deleteTableRow(in long aNumber); michael@0: michael@0: /** Table Selection methods michael@0: * Selecting a row or column actually michael@0: * selects all cells (not TR in the case of rows) michael@0: */ michael@0: void selectTableCell(); michael@0: michael@0: /** Select a rectangular block of cells: michael@0: * all cells falling within the row/column index of aStartCell michael@0: * to through the row/column index of the aEndCell michael@0: * aStartCell can be any location relative to aEndCell, michael@0: * as long as they are in the same table michael@0: * @param aStartCell starting cell in block michael@0: * @param aEndCell ending cell in block michael@0: */ michael@0: void selectBlockOfCells(in nsIDOMElement aStartCell, michael@0: in nsIDOMElement aEndCell); michael@0: michael@0: void selectTableRow(); michael@0: void selectTableColumn(); michael@0: void selectTable(); michael@0: void selectAllTableCells(); michael@0: michael@0: /** Create a new TD or TH element, the opposite type of the supplied aSourceCell michael@0: * 1. Copy all attributes from aSourceCell to the new cell michael@0: * 2. Move all contents of aSourceCell to the new cell michael@0: * 3. Replace aSourceCell in the table with the new cell michael@0: * michael@0: * @param aSourceCell The cell to be replaced michael@0: * @return The new cell that replaces aSourceCell michael@0: */ michael@0: nsIDOMElement switchTableCellHeaderType(in nsIDOMElement aSourceCell); michael@0: michael@0: /** Merges contents of all selected cells michael@0: * for selected cells that are adjacent, michael@0: * this will result in a larger cell with appropriate michael@0: * rowspan and colspan, and original cells are deleted michael@0: * The resulting cell is in the location of the michael@0: * cell at the upper-left corner of the adjacent michael@0: * block of selected cells michael@0: * michael@0: * @param aMergeNonContiguousContents: michael@0: * If true: michael@0: * Non-contiguous cells are not deleted, michael@0: * but their contents are still moved michael@0: * to the upper-left cell michael@0: * If false: contiguous cells are ignored michael@0: * michael@0: * If there are no selected cells, michael@0: * and selection or caret is in a cell, michael@0: * that cell and the one to the right michael@0: * are merged michael@0: */ michael@0: void joinTableCells(in boolean aMergeNonContiguousContents); michael@0: michael@0: /** Split a cell that has rowspan and/or colspan > 0 michael@0: * into cells such that all new cells have michael@0: * rowspan = 1 and colspan = 1 michael@0: * All of the contents are not touched -- michael@0: * they will appear to be in the upper-left cell michael@0: */ michael@0: void splitTableCell(); michael@0: michael@0: /** Scan through all rows and add cells as needed so michael@0: * all locations in the cellmap are occupied. michael@0: * Used after inserting single cells or pasting michael@0: * a collection of cells that extend past the michael@0: * previous size of the table michael@0: * If aTable is null, it uses table enclosing the selection anchor michael@0: * This doesn't doesn't change the selection, michael@0: * thus it can be used to fixup all tables michael@0: * in a page independent of the selection michael@0: */ michael@0: void normalizeTable(in nsIDOMElement aTable); michael@0: michael@0: /** Get the row an column index from the layout's cellmap michael@0: * If aCell is null, it will try to find enclosing table of selection anchor michael@0: * michael@0: */ michael@0: void getCellIndexes(in nsIDOMElement aCell, michael@0: out long aRowIndex, out long aColIndex); michael@0: michael@0: /** Get the number of rows and columns in a table from the layout's cellmap michael@0: * If aTable is null, it will try to find enclosing table of selection ancho michael@0: * Note that all rows in table will not have this many because of michael@0: * ROWSPAN effects or if table is not "rectangular" (has short rows) michael@0: */ michael@0: void getTableSize(in nsIDOMElement aTable, michael@0: out long aRowCount, out long aColCount); michael@0: michael@0: /** Get a cell element at cellmap grid coordinates michael@0: * A cell that spans across multiple cellmap locations will michael@0: * be returned multiple times, once for each location it occupies michael@0: * michael@0: * @param aTable A table in the document michael@0: * @param aRowIndex, aColIndex The 0-based cellmap indexes michael@0: * michael@0: * (in C++ returns: NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found michael@0: * passes NS_SUCCEEDED macro) michael@0: * michael@0: * You can scan for all cells in a row or column michael@0: * by iterating through the appropriate indexes michael@0: * until the returned aCell is null michael@0: */ michael@0: nsIDOMElement getCellAt(in nsIDOMElement aTable, michael@0: in long aRowIndex, in long aColIndex); michael@0: michael@0: /** Get a cell at cellmap grid coordinates and associated data michael@0: * A cell that spans across multiple cellmap locations will michael@0: * be returned multiple times, once for each location it occupies michael@0: * Examine the returned aStartRowIndex and aStartColIndex to see michael@0: * if it is in the same layout column or layout row: michael@0: * A "layout row" is all cells sharing the same top edge michael@0: * A "layout column" is all cells sharing the same left edge michael@0: * This is important to determine what to do when inserting or deleting a column or row michael@0: * michael@0: * @param aTable A table in the document michael@0: * @param aRowIndex, aColIndex The 0-based cellmap indexes michael@0: * returns values: michael@0: * @param aCell The cell at this cellmap location michael@0: * @param aStartRowIndex The row index where cell starts michael@0: * @param aStartColIndex The col index where cell starts michael@0: * @param aRowSpan May be 0 (to span down entire table) or number of cells spanned michael@0: * @param aColSpan May be 0 (to span across entire table) or number of cells spanned michael@0: * @param aActualRowSpan The actual number of cellmap locations (rows) spanned by the cell michael@0: * @param aActualColSpan The actual number of cellmap locations (columns) spanned by the cell michael@0: * @param aIsSelected michael@0: * @param michael@0: * michael@0: * (in C++ returns: NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found michael@0: * passes NS_SUCCEEDED macro) michael@0: */ michael@0: void getCellDataAt(in nsIDOMElement aTable, michael@0: in long aRowIndex, in long aColIndex, michael@0: out nsIDOMElement aCell, michael@0: out long aStartRowIndex, out long aStartColIndex, michael@0: out long aRowSpan, out long aColSpan, michael@0: out long aActualRowSpan, out long aActualColSpan, michael@0: out boolean aIsSelected); michael@0: michael@0: /** Get the first row element in a table michael@0: * michael@0: * @return The row at the requested index michael@0: * Returns null if there are no rows in table michael@0: * (in C++ returns: NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found michael@0: * passes NS_SUCCEEDED macro) michael@0: */ michael@0: nsIDOMNode getFirstRow(in nsIDOMElement aTableElement); michael@0: michael@0: /** Get the next row element starting the search from aTableElement michael@0: * michael@0: * @param aTableElement Any TR or child-of-TR element in the document michael@0: * michael@0: * @return The row to start search from michael@0: * and the row returned from the search michael@0: * Returns null if there isn't another row michael@0: * (in C++ returns: NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found michael@0: * passes NS_SUCCEEDED macro) michael@0: */ michael@0: nsIDOMNode getNextRow(in nsIDOMNode aTableElement); michael@0: michael@0: /** Preferred direction to search for neighboring cell michael@0: * when trying to locate a cell to place caret in after michael@0: * a table editing action. michael@0: * Used for aDirection param in SetSelectionAfterTableEdit michael@0: */ michael@0: michael@0: /** Reset a selected cell or collapsed selection (the caret) after table editing michael@0: * michael@0: * @param aTable A table in the document michael@0: * @param aRow The row ... michael@0: * @param aCol ... and column defining the cell michael@0: * where we will try to place the caret michael@0: * @param aSelected If true, we select the whole cell instead of setting caret michael@0: * @param aDirection If cell at (aCol, aRow) is not found, michael@0: * search for previous cell in the same michael@0: * column (aPreviousColumn) or row (ePreviousRow) michael@0: * or don't search for another cell (aNoSearch) michael@0: * If no cell is found, caret is place just before table; michael@0: * and if that fails, at beginning of document. michael@0: * Thus we generally don't worry about the return value michael@0: * and can use the nsSetSelectionAfterTableEdit stack-based michael@0: * object to insure we reset the caret in a table-editing method. michael@0: */ michael@0: void setSelectionAfterTableEdit(in nsIDOMElement aTable, michael@0: in long aRow, in long aCol, michael@0: in long aDirection, in boolean aSelected); michael@0: michael@0: /** Examine the current selection and find michael@0: * a selected TABLE, TD or TH, or TR element. michael@0: * or return the parent TD or TH if selection is inside a table cell michael@0: * Returns null if no table element is found. michael@0: * michael@0: * @param aTagName The tagname of returned element michael@0: * Note that "td" will be returned if name michael@0: * is actually "th" michael@0: * @param aCount How many table elements were selected michael@0: * This tells us if we have multiple cells selected michael@0: * (0 if element is a parent cell of selection) michael@0: * @return The table element (table, row, or first selected cell) michael@0: * michael@0: */ michael@0: nsIDOMElement getSelectedOrParentTableElement(out AString aTagName, out long aCount); michael@0: michael@0: /** Generally used after GetSelectedOrParentTableElement michael@0: * to test if selected cells are complete rows or columns michael@0: * michael@0: * @param aElement Any table or cell element or any element michael@0: * inside a table michael@0: * Used to get enclosing table. michael@0: * If null, selection's anchorNode is used michael@0: * michael@0: * @return michael@0: * 0 aCellElement was not a cell michael@0: * (returned result = NS_ERROR_FAILURE) michael@0: * TABLESELECTION_CELL There are 1 or more cells selected but michael@0: * complete rows or columns are not selected michael@0: * TABLESELECTION_ROW All cells are in 1 or more rows michael@0: * and in each row, all cells selected michael@0: * Note: This is the value if all rows michael@0: * (thus all cells) are selected michael@0: * TABLESELECTION_COLUMN All cells are in 1 or more columns michael@0: * and in each column, all cells are selected michael@0: */ michael@0: uint32_t getSelectedCellsType(in nsIDOMElement aElement); michael@0: michael@0: /** Get first selected element from first selection range. michael@0: * (If multiple cells were selected this is the first in the order they were selected) michael@0: * Assumes cell-selection model where each cell michael@0: * is in a separate range (selection parent node is table row) michael@0: * @param aCell [OUT] Selected cell or null if ranges don't contain michael@0: * cell selections michael@0: * @param aRange [OUT] Optional: if not null, return the selection range michael@0: * associated with the cell michael@0: * Returns the DOM cell element michael@0: * (in C++: returns NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found michael@0: * passes NS_SUCCEEDED macro) michael@0: */ michael@0: nsIDOMElement getFirstSelectedCell(out nsIDOMRange aRange); michael@0: michael@0: /** Get first selected element in the table michael@0: * This is the upper-left-most selected cell in table, michael@0: * ignoring the order that the user selected them (order in the selection ranges) michael@0: * Assumes cell-selection model where each cell michael@0: * is in a separate range (selection parent node is table row) michael@0: * @param aCell Selected cell or null if ranges don't contain michael@0: * cell selections michael@0: * @param aRowIndex Optional: if not null, return row index of 1st cell michael@0: * @param aColIndex Optional: if not null, return column index of 1st cell michael@0: * michael@0: * Returns the DOM cell element michael@0: * (in C++: returns NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found michael@0: * passes NS_SUCCEEDED macro) michael@0: */ michael@0: nsIDOMElement getFirstSelectedCellInTable(out long aRowIndex, out long aColIndex); michael@0: michael@0: /** Get next selected cell element from first selection range. michael@0: * Assumes cell-selection model where each cell michael@0: * is in a separate range (selection parent node is table row) michael@0: * Always call GetFirstSelectedCell() to initialize stored index of "next" cell michael@0: * @param aCell Selected cell or null if no more selected cells michael@0: * or ranges don't contain cell selections michael@0: * @param aRange Optional: if not null, return the selection range michael@0: * associated with the cell michael@0: * michael@0: * Returns the DOM cell element michael@0: * (in C++: returns NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found michael@0: * passes NS_SUCCEEDED macro) michael@0: */ michael@0: nsIDOMElement getNextSelectedCell(out nsIDOMRange aRange); michael@0: };