mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1484111 - part 1: Create HTMLEditor::InsertTableCellsWithTransaction() for internal use of nsITableEditor::InsertTableCell() r=m_kato
nsITableEditor::InsertTableCell() is an XPCOM method but used internally. So, HTMLEditor should implement it with a non-virtual method and all internal users should use it instead. Differential Revision: https://phabricator.services.mozilla.com/D6259 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
3a48cf1623
commit
20d1804f6b
@ -1568,6 +1568,28 @@ protected: // Shouldn't be used by friend classes
|
||||
eAfterSelectedCell,
|
||||
};
|
||||
|
||||
/**
|
||||
* InsertTableCellsWithTransaction() inserts <td> elements before or after
|
||||
* a cell element containing first selection range. I.e., if the cell
|
||||
* spans columns and aInsertPosition is eAfterSelectedCell, new columns
|
||||
* will be inserted after the right-most column which contains the cell.
|
||||
* Note that this simply inserts <td> elements, i.e., colspan and rowspan
|
||||
* around the cell containing selection are not modified. So, for example,
|
||||
* adding a cell to rectangular table changes non-rectangular table.
|
||||
* And if the cell containing selection is at left of row-spanning cell,
|
||||
* it may be moved to right side of the row-spanning cell after inserting
|
||||
* some cell elements before it. Similarly, colspan won't be adjusted
|
||||
* for keeping table rectangle.
|
||||
* If first selection range is not in table cell element, this does nothing
|
||||
* but does not return error.
|
||||
*
|
||||
* @param aNumberOfCellssToInsert Number of cells to insert.
|
||||
* @param aInsertPosition Before or after the target cell which
|
||||
* contains first selection range.
|
||||
*/
|
||||
nsresult InsertTableCellsWithTransaction(int32_t aNumberOfCellsToInsert,
|
||||
InsertPosition aInsertPosition);
|
||||
|
||||
/**
|
||||
* InsertTableColumnsWithTransaction() inserts columns before or after
|
||||
* a cell element containing first selection range. I.e., if the cell
|
||||
|
@ -167,8 +167,22 @@ HTMLEditor::SetRowSpan(Element* aCell,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLEditor::InsertTableCell(int32_t aNumber,
|
||||
bool aAfter)
|
||||
HTMLEditor::InsertTableCell(int32_t aNumberOfCellsToInsert,
|
||||
bool aInsertAfterSelectedCell)
|
||||
{
|
||||
nsresult rv =
|
||||
InsertTableCellsWithTransaction(aNumberOfCellsToInsert,
|
||||
aInsertAfterSelectedCell ? InsertPosition::eAfterSelectedCell :
|
||||
InsertPosition::eBeforeSelectedCell);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLEditor::InsertTableCellsWithTransaction(int32_t aNumberOfCellsToInsert,
|
||||
InsertPosition aInsertPosition)
|
||||
{
|
||||
RefPtr<Element> table;
|
||||
RefPtr<Element> curCell;
|
||||
@ -179,45 +193,71 @@ HTMLEditor::InsertTableCell(int32_t aNumber,
|
||||
getter_AddRefs(curCell),
|
||||
getter_AddRefs(cellParent), &cellOffset,
|
||||
&startRowIndex, &startColIndex);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// Don't fail if no cell found
|
||||
NS_ENSURE_TRUE(curCell, NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (NS_WARN_IF(!curCell)) {
|
||||
// Don't fail if no cell found.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get more data for current cell in row we are inserting at (we need COLSPAN)
|
||||
int32_t curStartRowIndex, curStartColIndex, rowSpan, colSpan, actualRowSpan, actualColSpan;
|
||||
bool isSelected;
|
||||
// Get more data for current cell in row we are inserting at since we need
|
||||
// colspan value.
|
||||
int32_t curStartRowIndex = 0, curStartColIndex = 0;
|
||||
int32_t rowSpan = 0, colSpan = 0;
|
||||
int32_t actualRowSpan = 0, actualColSpan = 0;
|
||||
bool isSelected = false;
|
||||
rv = GetCellDataAt(table, startRowIndex, startColIndex,
|
||||
getter_AddRefs(curCell),
|
||||
&curStartRowIndex, &curStartColIndex, &rowSpan, &colSpan,
|
||||
&actualRowSpan, &actualColSpan, &isSelected);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(curCell, NS_ERROR_FAILURE);
|
||||
int32_t newCellIndex = aAfter ? (startColIndex+colSpan) : startColIndex;
|
||||
//We control selection resetting after the insert...
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (NS_WARN_IF(!curCell)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
int32_t newCellIndex;
|
||||
switch (aInsertPosition) {
|
||||
case InsertPosition::eBeforeSelectedCell:
|
||||
newCellIndex = startColIndex;
|
||||
break;
|
||||
case InsertPosition::eAfterSelectedCell:
|
||||
newCellIndex = startColIndex + colSpan;
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid InsertPosition");
|
||||
}
|
||||
|
||||
// We control selection resetting after the insert.
|
||||
AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex,
|
||||
newCellIndex, ePreviousColumn,
|
||||
false);
|
||||
//...so suppress Rules System selection munging
|
||||
// So, suppress Rules System selection munging.
|
||||
AutoTransactionsConserveSelection dontChangeSelection(*this);
|
||||
|
||||
for (int32_t i = 0; i < aNumber; i++) {
|
||||
EditorDOMPoint pointToInsert(cellParent, cellOffset);
|
||||
if (NS_WARN_IF(!pointToInsert.IsSet())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (aInsertPosition == InsertPosition::eAfterSelectedCell) {
|
||||
DebugOnly<bool> advanced = pointToInsert.AdvanceOffset();
|
||||
NS_WARNING_ASSERTION(advanced,
|
||||
"Faild to move insertion point after the cell");
|
||||
}
|
||||
for (int32_t i = 0; i < aNumberOfCellsToInsert; i++) {
|
||||
RefPtr<Element> newCell = CreateElementWithDefaults(*nsGkAtoms::td);
|
||||
if (newCell) {
|
||||
if (aAfter) {
|
||||
cellOffset++;
|
||||
}
|
||||
rv = InsertNodeWithTransaction(*newCell,
|
||||
EditorRawDOMPoint(cellParent, cellOffset));
|
||||
if (NS_FAILED(rv)) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
if (NS_WARN_IF(!newCell)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
AutoEditorDOMPointChildInvalidator lockOffset(pointToInsert);
|
||||
rv = InsertNodeWithTransaction(*newCell, pointToInsert);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
// XXX This is perhaps the result of the last call of
|
||||
// InsertNodeWithTransaction() or CreateElementWithDefaults().
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -503,12 +543,14 @@ HTMLEditor::InsertTableColumnsWithTransaction(int32_t aNumberOfColumnsToInsert,
|
||||
}
|
||||
|
||||
// Simply set selection to the current cell. So, we can let
|
||||
// InsertTableCell() do the work. Insert a new cell before current one.
|
||||
// InsertTableCellsWithTransaction() do the work. Insert a new cell
|
||||
// before current one.
|
||||
IgnoredErrorResult ignoredError;
|
||||
selection->Collapse(RawRangeBoundary(curCell, 0), ignoredError);
|
||||
NS_WARNING_ASSERTION(!ignoredError.Failed(),
|
||||
"Failed to collapse Selection into the cell");
|
||||
rv = InsertTableCell(aNumberOfColumnsToInsert, false);
|
||||
rv = InsertTableCellsWithTransaction(aNumberOfColumnsToInsert,
|
||||
InsertPosition::eBeforeSelectedCell);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to insert a cell element");
|
||||
continue;
|
||||
}
|
||||
@ -555,10 +597,12 @@ HTMLEditor::InsertTableColumnsWithTransaction(int32_t aNumberOfColumnsToInsert,
|
||||
selection->Collapse(RawRangeBoundary(curCell, 0), ignoredError);
|
||||
NS_WARNING_ASSERTION(!ignoredError.Failed(),
|
||||
"Failed to collapse Selection into the cell");
|
||||
rv = InsertTableCell(aNumberOfColumnsToInsert, true);
|
||||
rv = InsertTableCellsWithTransaction(aNumberOfColumnsToInsert,
|
||||
InsertPosition::eAfterSelectedCell);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to insert a cell element");
|
||||
}
|
||||
// XXX This is perhaps the result of the last call of InsertTableCell().
|
||||
// XXX This is perhaps the result of the last call of
|
||||
// InsertTableCellsWithTransaction().
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -17,19 +17,28 @@ interface nsITableEditor : nsISupports
|
||||
const short ePreviousColumn = 1;
|
||||
const short ePreviousRow = 2;
|
||||
|
||||
/* ------------ Table editing Methods -------------- */
|
||||
|
||||
/** Insert table methods
|
||||
* Insert relative to the selected cell or the
|
||||
* cell enclosing the selection anchor
|
||||
* The selection is collapsed and is left in the new cell
|
||||
* at the same row,col location as the original anchor cell
|
||||
*
|
||||
* @param aNumber Number of items to insert
|
||||
* @param aAfter If TRUE, insert after the current cell,
|
||||
* else insert before current cell
|
||||
*/
|
||||
void insertTableCell(in long aNumber, in boolean aAfter);
|
||||
/**
|
||||
* insertTableCell() inserts <td> elements before or after a cell element
|
||||
* containing first selection range. I.e., if the cell spans columns and
|
||||
* aInsertPosition is true, new columns will be inserted after the
|
||||
* right-most column which contains the cell. Note that this simply
|
||||
* inserts <td> elements, i.e., colspan and rowspan around the cell
|
||||
* containing selection are not modified. So, for example, adding a cell
|
||||
* to rectangular table changes non-rectangular table. And if a cell
|
||||
* containing selection is at left of row-spanning cell, it may be moved to
|
||||
* right side of the row-spanning cell after inserting some cell elements
|
||||
* before it. Similarly, colspan won't be adjusted for keeping table
|
||||
* rectangle.
|
||||
* If first selection range is not in table cell element, this does nothing
|
||||
* without exception.
|
||||
*
|
||||
* @param aNumberOfCellssToInsert Number of cells to insert.
|
||||
* @param aInsertAfterSelectedCell true if new cells should be inserted
|
||||
* before current cell. Otherwise, will
|
||||
* be inserted after the cell.
|
||||
*/
|
||||
void insertTableCell(in long aNumberOfColumnsToInsert,
|
||||
in boolean aInsertAfterSelectedCell);
|
||||
|
||||
/**
|
||||
* insertTableColumn() inserts columns before or after a cell element
|
||||
|
Loading…
Reference in New Issue
Block a user