Bug 1484126 - part 5: Make all CellData users refer CellData::mElement directly r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 15 Oct 2018 04:06:32 +0000
changeset 499830 181c07ae07c598314b76cb5b9b0c700d72c07488
parent 499829 539a4c3e194663e4631be32d1ca304a9e0bd0c1e
child 499831 0f9a168cb7c818b7ed782228cce640699022e64e
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1484126
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1484126 - part 5: Make all CellData users refer CellData::mElement directly r=m_kato Differential Revision: https://phabricator.services.mozilla.com/D8342
editor/libeditor/HTMLTableEditor.cpp
--- a/editor/libeditor/HTMLTableEditor.cpp
+++ b/editor/libeditor/HTMLTableEditor.cpp
@@ -478,17 +478,17 @@ HTMLEditor::InsertTableColumnsWithTransa
     case InsertPosition::eAfterSelectedCell:
       // Use column after current cell.
       startColIndex += actualColSpan;
 
       // Detect when user is adding after a colspan=0 case.
       // Assume they want to stop the "0" behavior and really add a new column.
       // Thus we set the colspan to its true value.
       if (!colSpan) {
-        SetColSpan(curCell, actualColSpan);
+        SetColSpan(cellDataAtSelection.mElement, actualColSpan);
       }
       break;
     default:
       MOZ_ASSERT_UNREACHABLE("Invalid InsertPosition");
   }
 
   // We control selection resetting after the insert.
   AutoSelectionSetterAfterTableEdit setCaret(*this, table,
@@ -515,48 +515,47 @@ HTMLEditor::InsertTableColumnsWithTransa
   for (int32_t rowIndex = 0; rowIndex < tableSize.mRowCount; rowIndex++) {
     if (startColIndex < tableSize.mColumnCount) {
       // We are inserting before an existing column.
       CellData cellData(*this, *table, rowIndex, startColIndex, ignoredError);
       if (NS_WARN_IF(cellData.FailedOrNotFound())) {
         return NS_ERROR_FAILURE;
       }
 
-      RefPtr<Element> curCell = std::move(cellData.mElement);
       // int32_t curStartRowIndex =       cellData.mFirst.mRow;
       int32_t    curStartColIndex =       cellData.mFirst.mColumn;
       // int32_t rowSpan =                cellData.mRowSpan;
       int32_t    colSpan =                cellData.mColSpan;
       // int32_t actualRowSpan =          cellData.mEffectiveRowSpan;
       // int32_t actualColSpan =          cellData.mEffectiveColSpan;
       // bool    isSelected =             cellData.mIsSelected;
 
       // Don't fail entire process if we fail to find a cell (may fail just in
       // particular rows with < adequate cells per row).
       // XXX So, here wants to know whether the CellData actually failed above.
       //     Fix this later.
-      if (!curCell) {
+      if (!cellData.mElement) {
         continue;
       }
 
       if (curStartColIndex < cellData.mCurrent.mColumn) {
         // If we have a cell spanning this location, simply increase its
         // colspan to keep table rectangular.
         // Note: we do nothing if colsspan=0, since it should automatically
         // span the new column.
         if (colSpan > 0) {
-          SetColSpan(curCell, colSpan + aNumberOfColumnsToInsert);
+          SetColSpan(cellData.mElement, colSpan + aNumberOfColumnsToInsert);
         }
         continue;
       }
 
       // Simply set selection to the current cell. So, we can let
       // InsertTableCellsWithTransaction() do the work.  Insert a new cell
       // before current one.
-      selection->Collapse(RawRangeBoundary(curCell, 0), ignoredError);
+      selection->Collapse(RawRangeBoundary(cellData.mElement, 0), ignoredError);
       NS_WARNING_ASSERTION(!ignoredError.Failed(),
         "Failed to collapse Selection into the cell");
       rv = InsertTableCellsWithTransaction(aNumberOfColumnsToInsert,
                                            InsertPosition::eBeforeSelectedCell);
       NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to insert a cell element");
       continue;
     }
 
@@ -579,31 +578,30 @@ HTMLEditor::InsertTableColumnsWithTransa
       if (NS_WARN_IF(error.Failed())) {
         return error.StealNSResult();
       }
       if (NS_WARN_IF(!rowElement)) {
         continue;
       }
     }
 
-    nsCOMPtr<nsINode> lastCell;
-    rv = GetLastCellInRow(rowElement, getter_AddRefs(lastCell));
+    nsCOMPtr<nsINode> lastCellNode;
+    rv = GetLastCellInRow(rowElement, getter_AddRefs(lastCellNode));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
-    if (NS_WARN_IF(!lastCell)) {
+    if (NS_WARN_IF(!lastCellNode)) {
       return NS_ERROR_FAILURE;
     }
 
-    curCell = lastCell->AsElement();
     // Simply add same number of cells to each row.  Although tempted to check
-    // cell indexes for curCell, the effects of colspan > 1 in some cells makes
-    // this futile.  We must use NormalizeTable first to assure that there are
-    // cells in each cellmap location.
-    selection->Collapse(RawRangeBoundary(curCell, 0), ignoredError);
+    // cell indexes for current cell, the effects of colspan > 1 in some cells
+    // makes this futile.  We must use NormalizeTable first to assure that
+    // there are cells in each cellmap location.
+    selection->Collapse(RawRangeBoundary(lastCellNode, 0), ignoredError);
     NS_WARNING_ASSERTION(!ignoredError.Failed(),
       "Failed to collapse Selection into the cell");
     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
   //     InsertTableCellsWithTransaction().
@@ -683,17 +681,17 @@ HTMLEditor::InsertTableRowsWithTransacti
     case InsertPosition::eAfterSelectedCell:
       // Use row after current cell.
       startRowIndex += actualRowSpan;
 
       // Detect when user is adding after a rowspan=0 case.
       // Assume they want to stop the "0" behavior and really add a new row.
       // Thus we set the rowspan to its true value.
       if (!rowSpan) {
-        SetRowSpan(curCell, actualRowSpan);
+        SetRowSpan(cellDataAtSelection.mElement, actualRowSpan);
       }
       break;
     default:
       MOZ_ASSERT_UNREACHABLE("Invalid InsertPosition");
   }
 
   // We control selection resetting after the insert.
   AutoSelectionSetterAfterTableEdit setCaret(
@@ -709,44 +707,43 @@ HTMLEditor::InsertTableRowsWithTransacti
     // row to adjust for colspan effects while we count how many cells are
     // needed.
     for (int32_t colIndex = 0, actualColSpan = 0;; colIndex += actualColSpan) {
       CellData cellData(*this, *table, startRowIndex, colIndex, ignoredError);
       if (cellData.FailedOrNotFound()) {
         break; // Perhaps, we reach end of the row.
       }
 
-      RefPtr<Element> cellElement = std::move(cellData.mElement);
       int32_t    curStartRowIndex =           cellData.mFirst.mRow;
       // int32_t curStartColIndex =           cellData.mFirst.mColumn;
       int32_t    rowSpan =                    cellData.mRowSpan;
       // int32_t colSpan =                    cellData.mColSpan;
       // int32_t actualRowSpan =              cellData.mEffectiveRowSpan;
                  actualColSpan =              cellData.mEffectiveColSpan;
       // bool    isSelected =                 cellData.mIsSelected;
 
       // XXX So, this is impossible case. Will be removed.
-      if (NS_WARN_IF(!cellElement)) {
+      if (NS_WARN_IF(!cellData.mElement)) {
         actualColSpan = 1;
         continue;
       }
 
       if (curStartRowIndex < cellData.mCurrent.mRow) {
         // We have a cell spanning this location.  Increase its rowspan.
         // Note that if rowspan is 0, we do nothing since that cell should
         // automatically extend into the new row.
         if (rowSpan > 0) {
-          SetRowSpan(cellElement, rowSpan + aNumberOfRowsToInsert);
+          SetRowSpan(cellData.mElement, rowSpan + aNumberOfRowsToInsert);
         }
         continue;
       }
 
       cellsInRow += actualColSpan;
       if (!cellForRowParent) {
-        cellForRowParent = std::move(cellElement);
+        cellForRowParent = std::move(cellData.mElement);
       }
     }
   } else {
     // We are adding a new row after all others.  If it weren't for colspan=0
     // effect,  we could simply use tableSize.mColumnCount for number of new
     // cells...
     // XXX colspan=0 support has now been removed in table layout so maybe this
     //     can be cleaned up now? (bug 1243183)
@@ -755,33 +752,32 @@ HTMLEditor::InsertTableRowsWithTransacti
     // but we must compensate for all cells with rowspan = 0 in the last row.
     const int32_t kLastRowIndex = tableSize.mRowCount - 1;
     for (int32_t colIndex = 0, actualColSpan = 0;; colIndex += actualColSpan) {
       CellData cellData(*this, *table, kLastRowIndex, colIndex, ignoredError);
       if (cellData.FailedOrNotFound()) {
         break; // Perhaps, we reach end of the row.
       }
 
-      RefPtr<Element> cellElement = std::move(cellData.mElement);
       int32_t    curStartRowIndex =           cellData.mFirst.mRow;
       // int32_t curStartColIndex =           cellData.mFirst.mColumn;
       int32_t    rowSpan =                    cellData.mRowSpan;
       // int32_t colSpan =                    cellData.mColSpan;
       // int32_t actualRowSpan =              cellData.mEffectiveRowSpan;
                  actualColSpan =              cellData.mEffectiveColSpan;
       // bool    isSelected =                 cellData.mIsSelected;
 
       if (!rowSpan) {
         MOZ_ASSERT(cellsInRow >= actualColSpan);
         cellsInRow -= actualColSpan;
       }
 
       // Save cell from the last row that we will use below
       if (!cellForRowParent && curStartRowIndex == cellData.mCurrent.mRow) {
-        cellForRowParent = std::move(cellElement);
+        cellForRowParent = std::move(cellData.mElement);
       }
     }
   }
 
   if (NS_WARN_IF(!cellsInRow)) {
     // There is no cell element in the last row??
     return NS_OK;
   }
@@ -1410,68 +1406,68 @@ HTMLEditor::DeleteTableColumnWithTransac
     // Failure means that there is no more row in the table.  In this case,
     // we shouldn't return error since we just reach the end of the table.
     // XXX Should distinguish whether CellData returns error or just not found
     //     later.
     if (cellData.FailedOrNotFound()) {
       return NS_OK;
     }
 
-    RefPtr<Element> cell = std::move(cellData.mElement);
     int32_t    startRowIndex =       cellData.mFirst.mRow;
     int32_t    startColIndex =       cellData.mFirst.mColumn;
     // int32_t rowSpan =             cellData.mRowSpan;
     int32_t    colSpan =             cellData.mColSpan;
     int32_t    actualRowSpan =       cellData.mEffectiveRowSpan;
     // int32_t actualColSpan =       cellData.mEffectiveColSpan;
     // bool    isSelected =          cellData.mIsSelected;
 
     // Find cells that don't start in column we are deleting.
     MOZ_ASSERT(colSpan >= 0);
     if (startColIndex < cellData.mCurrent.mColumn || colSpan != 1) {
       // If we have a cell spanning this location, decrease its colspan to
       // keep table rectangular, but if colspan is 0, it'll be adjusted
       // automatically.
       if (colSpan > 0) {
         NS_WARNING_ASSERTION(colSpan > 1, "colspan should be 2 or larger");
-        SetColSpan(cell, colSpan - 1);
+        SetColSpan(cellData.mElement, colSpan - 1);
       }
       if (startColIndex == cellData.mCurrent.mColumn) {
         // Cell is in column to be deleted, but must have colspan > 1,
         // so delete contents of cell instead of cell itself (We must have
         // reset colspan above).
-        DebugOnly<nsresult> rv = DeleteAllChildrenWithTransaction(*cell);
+        DebugOnly<nsresult> rv =
+          DeleteAllChildrenWithTransaction(*cellData.mElement);
         NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
           "Failed to remove all children of the cell element");
       }
       // Skip rows which the removed cell spanned.
       rowIndex += actualRowSpan - 1;
       continue;
     }
 
     // Delete the cell
     int32_t numberOfCellsInRow =
       GetNumberOfCellsInRow(aTableElement, cellData.mCurrent.mRow);
     NS_WARNING_ASSERTION(numberOfCellsInRow > 0,
       "Failed to count existing cells in the row");
     if (numberOfCellsInRow != 1) {
       // If removing cell is not the last cell of the row, we can just remove
       // it.
-      nsresult rv = DeleteNodeWithTransaction(*cell);
+      nsresult rv = DeleteNodeWithTransaction(*cellData.mElement);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
       // Skip rows which the removed cell spanned.
       rowIndex += actualRowSpan - 1;
       continue;
     }
 
     // When the cell is the last cell in the row, remove the row instead.
     Element* parentRow =
-      GetElementOrParentByTagNameInternal(*nsGkAtoms::tr, *cell);
+      GetElementOrParentByTagNameInternal(*nsGkAtoms::tr, *cellData.mElement);
     if (NS_WARN_IF(!parentRow)) {
       return NS_ERROR_FAILURE;
     }
 
     // Check if its the only row left in the table.  If so, we can delete
     // the table instead.
     TableSize tableSize(*this, aTableElement, error);
     if (NS_WARN_IF(error.Failed())) {
@@ -1685,43 +1681,43 @@ HTMLEditor::DeleteTableRowWithTransactio
   while (aRowIndex < tableSize.mRowCount &&
          columnIndex < tableSize.mColumnCount) {
     CellData cellData(*this, aTableElement, aRowIndex, columnIndex,
                       ignoredError);
     if (NS_WARN_IF(cellData.FailedOrNotFound())) {
       return NS_ERROR_FAILURE;
     }
 
-    RefPtr<Element> cell = std::move(cellData.mElement);
     int32_t    startRowIndex =       cellData.mFirst.mRow;
     int32_t    startColIndex =       cellData.mFirst.mColumn;
     int32_t    rowSpan =             cellData.mRowSpan;
     // int32_t colSpan =             cellData.mColSpan;
     int32_t    actualRowSpan =       cellData.mEffectiveRowSpan;
     int32_t    actualColSpan =       cellData.mEffectiveColSpan;
     // bool    isSelected =          cellData.mIsSelected;
 
     // XXX So, we should distinguish if CellDate returns error or just not
     //     found later.
-    if (!cell) {
+    if (!cellData.mElement) {
       break;
     }
 
     // Compensate for cells that don't start or extend below the row we are
     // deleting.
     if (startRowIndex < cellData.mCurrent.mRow) {
       // If a cell starts in row above us, decrease its rowspan to keep table
       // rectangular but we don't need to do this if rowspan=0, since it will
       // be automatically adjusted.
       if (rowSpan > 0) {
         // Build list of cells to change rowspan.  We can't do it now since
         // it upsets cell map, so we will do it after deleting the row.
         int32_t newRowSpanValue =
           std::max(cellData.mCurrent.mRow - startRowIndex, actualRowSpan - 1);
-        spanCellArray.AppendElement(SpanCell(cell, newRowSpanValue));
+        spanCellArray.AppendElement(
+                        SpanCell(cellData.mElement, newRowSpanValue));
       }
     } else {
       if (rowSpan > 1) {
         // Cell spans below row to delete, so we must insert new cells to
         // keep rows below.  Note that we test "rowSpan" so we don't do this
         // if rowSpan = 0 (automatic readjustment).
         int32_t aboveRowToInsertNewCellInto =
           cellData.mCurrent.mRow - startRowIndex + 1;
@@ -1730,17 +1726,18 @@ HTMLEditor::DeleteTableRowWithTransactio
           SplitCellIntoRows(&aTableElement, startRowIndex, startColIndex,
                             aboveRowToInsertNewCellInto,
                             numOfRawSpanRemainingBelow, nullptr);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
       if (!cellInDeleteRow) {
-        cellInDeleteRow = cell; // Reference cell to find row to delete
+        // Reference cell to find row to delete.
+        cellInDeleteRow = std::move(cellData.mElement);
       }
     }
     // Skip over other columns spanned by this cell
     columnIndex += actualColSpan;
   }
 
   // Things are messed up if we didn't find a cell in the row!
   if (NS_WARN_IF(!cellInDeleteRow)) {
@@ -1907,32 +1904,31 @@ HTMLEditor::SelectBlockOfCells(Element* 
     for (int32_t col = minColumn, actualColSpan = 0;
          col <= maxColumn;
          col += std::max(actualColSpan, 1)) {
       CellData cellData(*this, *table, row, col, ignoredError);
       if (cellData.FailedOrNotFound()) {
         return NS_ERROR_FAILURE;
       }
 
-      RefPtr<Element> cell = std::move(cellData.mElement);
       int32_t    currentRowIndex =     cellData.mFirst.mRow;
       int32_t    currentColIndex =     cellData.mFirst.mColumn;
       // int32_t rowSpan =             cellData.mRowSpan;
       // int32_t colSpan =             cellData.mColSpan;
       // int32_t actualRowSpan =       cellData.mEffectiveRowSpan;
                  actualColSpan =       cellData.mEffectiveColSpan;
       bool       isSelected =          cellData.mIsSelected;
 
       // Skip cells that already selected or are spanned from previous locations
       // XXX So, we should distinguish whether CellData returns error or just
       //     not found later.
-      if (!isSelected && cell &&
+      if (!isSelected && cellData.mElement &&
           cellData.mCurrent.mRow == currentRowIndex &&
           cellData.mCurrent.mColumn == currentColIndex) {
-        rv = AppendNodeToSelectionAsRange(cell);
+        rv = AppendNodeToSelectionAsRange(cellData.mElement);
         if (NS_FAILED(rv)) {
           break;
         }
       }
     }
   }
   // NS_OK, otherwise, the last failure of AppendNodeToSelectionAsRange().
   return rv;
@@ -1983,32 +1979,31 @@ HTMLEditor::SelectAllTableCells()
          col < tableSize.mColumnCount;
          col += std::max(actualColSpan, 1)) {
       CellData cellData(*this, *table, row, col, ignoredError);
       if (NS_WARN_IF(cellData.FailedOrNotFound())) {
         rv = NS_ERROR_FAILURE;
         break;
       }
 
-      RefPtr<Element> cell = std::move(cellData.mElement);
       int32_t    currentRowIndex =     cellData.mFirst.mRow;
       int32_t    currentColIndex =     cellData.mFirst.mColumn;
       // int32_t rowSpan =             cellData.mRowSpan;
       // int32_t colSpan =             cellData.mColSpan;
       // int32_t actualRowSpan =       cellData.mEffectiveRowSpan;
                  actualColSpan =       cellData.mEffectiveColSpan;
       // bool    isSelected =          cellData.mIsSelected;
 
       // Skip cells that are spanned from previous rows or columns
       // XXX So, we should distinguish whether CellData returns error or just
       //     not found later.
-      if (cell &&
+      if (cellData.mElement &&
           cellData.mCurrent.mRow == currentRowIndex &&
           cellData.mCurrent.mColumn == currentColIndex) {
-        rv =  AppendNodeToSelectionAsRange(cell);
+        rv =  AppendNodeToSelectionAsRange(cellData.mElement);
         if (NS_FAILED(rv)) {
           break;
         }
         cellSelected = true;
       }
     }
   }
   // Safety code to select starting cell if nothing else was selected
@@ -2078,32 +2073,31 @@ HTMLEditor::SelectTableRow()
        col < tableSize.mColumnCount;
        col += std::max(actualColSpan, 1)) {
     CellData cellData(*this, *table, startRowIndex, col, ignoredError);
     if (NS_WARN_IF(cellData.FailedOrNotFound())) {
       rv = NS_ERROR_FAILURE;
       break;
     }
 
-    RefPtr<Element> cell = std::move(cellData.mElement);
     int32_t    currentRowIndex =     cellData.mFirst.mRow;
     int32_t    currentColIndex =     cellData.mFirst.mColumn;
     // int32_t rowSpan =             cellData.mRowSpan;
     // int32_t colSpan =             cellData.mColSpan;
     // int32_t actualRowSpan =       cellData.mEffectiveRowSpan;
                actualColSpan =       cellData.mEffectiveColSpan;
     // bool    isSelected =          cellData.mIsSelected;
 
     // Skip cells that are spanned from previous rows or columns
     // XXX So, we should distinguish whether CellData returns error or just
     //     not found later.
-    if (cell &&
+    if (cellData.mElement &&
         currentRowIndex == cellData.mCurrent.mRow &&
         currentColIndex == cellData.mCurrent.mColumn) {
-      rv = AppendNodeToSelectionAsRange(cell);
+      rv = AppendNodeToSelectionAsRange(cellData.mElement);
       if (NS_FAILED(rv)) {
         break;
       }
       cellSelected = true;
     }
   }
   // Safety code to select starting cell if nothing else was selected
   if (!cellSelected) {
@@ -2168,32 +2162,31 @@ HTMLEditor::SelectTableColumn()
        row < tableSize.mRowCount;
        row += std::max(actualRowSpan, 1)) {
     CellData cellData(*this, *table, row, startColIndex, ignoredError);
     if (NS_WARN_IF(cellData.FailedOrNotFound())) {
       rv = NS_ERROR_FAILURE;
       break;
     }
 
-    RefPtr<Element> cell = std::move(cellData.mElement);
     int32_t    currentRowIndex =     cellData.mFirst.mRow;
     int32_t    currentColIndex =     cellData.mFirst.mColumn;
     // int32_t rowSpan =             cellData.mRowSpan;
     // int32_t colSpan =             cellData.mColSpan;
                actualRowSpan =       cellData.mEffectiveRowSpan;
     // int32_t actualColSpan =       cellData.mEffectiveColSpan;
     // bool    isSelected =          cellData.mIsSelected;
 
     // Skip cells that are spanned from previous rows or columns
     // XXX So, we should distinguish whether CellData returns error or just
     //     not found later.
-    if (cell &&
+    if (cellData.mElement &&
         currentRowIndex == cellData.mCurrent.mRow &&
         currentColIndex == cellData.mCurrent.mColumn) {
-      rv = AppendNodeToSelectionAsRange(cell);
+      rv = AppendNodeToSelectionAsRange(cellData.mElement);
       if (NS_FAILED(rv)) {
         break;
       }
       cellSelected = true;
     }
   }
   // Safety code to select starting cell if nothing else was selected
   if (!cellSelected) {
@@ -2312,51 +2305,54 @@ HTMLEditor::SplitCellIntoColumns(Element
   }
 
   IgnoredErrorResult ignoredError;
   CellData cellData(*this, *aTable, aRowIndex, aColIndex, ignoredError);
   if (NS_WARN_IF(cellData.FailedOrNotFound())) {
     return NS_ERROR_FAILURE;
   }
 
-  RefPtr<Element> cell = std::move(cellData.mElement);
   // int32_t startRowIndex =       cellData.mFirst.mRow;
   // int32_t startColIndex =       cellData.mFirst.mColumn;
   // int32_t rowSpan =             cellData.mRowSpan;
   // int32_t colSpan =             cellData.mColSpan;
   int32_t    actualRowSpan =       cellData.mEffectiveRowSpan;
   int32_t    actualColSpan =       cellData.mEffectiveColSpan;
   // bool    isSelected =          cellData.mIsSelected;
 
   // We can't split!
   if (actualColSpan <= 1 || (aColSpanLeft + aColSpanRight) > actualColSpan) {
     return NS_OK;
   }
 
   // Reduce colspan of cell to split
-  nsresult rv = SetColSpan(cell, aColSpanLeft);
+  nsresult rv = SetColSpan(cellData.mElement, aColSpanLeft);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   // Insert new cell after using the remaining span
   //  and always get the new cell so we can copy the background color;
-  RefPtr<Element> newCell;
-  rv = InsertCell(cell, actualRowSpan, aColSpanRight, true, false,
-                  getter_AddRefs(newCell));
+  RefPtr<Element> newCellElement;
+  rv = InsertCell(cellData.mElement, actualRowSpan, aColSpanRight, true, false,
+                  getter_AddRefs(newCellElement));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
-  if (!newCell) {
+  if (!newCellElement) {
     return NS_OK;
   }
   if (aNewCell) {
-    NS_ADDREF(*aNewCell = newCell.get());
-  }
-  return CopyCellBackgroundColor(newCell, cell);
+    NS_ADDREF(*aNewCell = newCellElement.get());
+  }
+  rv = CopyCellBackgroundColor(newCellElement, cellData.mElement);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
 }
 
 nsresult
 HTMLEditor::SplitCellIntoRows(Element* aTable,
                               int32_t aRowIndex,
                               int32_t aColIndex,
                               int32_t aRowSpanAbove,
                               int32_t aRowSpanBelow,
@@ -2371,17 +2367,16 @@ HTMLEditor::SplitCellIntoRows(Element* a
   }
 
   IgnoredErrorResult ignoredError;
   CellData cellData(*this, *aTable, aRowIndex, aColIndex, ignoredError);
   if (NS_WARN_IF(cellData.FailedOrNotFound())) {
     return NS_ERROR_FAILURE;
   }
 
-  RefPtr<Element> cell = std::move(cellData.mElement);
   int32_t    startRowIndex =       cellData.mFirst.mRow;
   int32_t    startColIndex =       cellData.mFirst.mColumn;
   // int32_t rowSpan =             cellData.mRowSpan;
   // int32_t colSpan =             cellData.mColSpan;
   int32_t    actualRowSpan =       cellData.mEffectiveRowSpan;
   int32_t    actualColSpan =       cellData.mEffectiveColSpan;
   // bool    isSelected =          cellData.mIsSelected;
 
@@ -2392,17 +2387,17 @@ HTMLEditor::SplitCellIntoRows(Element* a
 
   ErrorResult error;
   TableSize tableSize(*this, *aTable, error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   // Find a cell to insert before or after
-  RefPtr<Element> cell2;
+  RefPtr<Element> cellElementAtInsertionPoint;
   RefPtr<Element> lastCellFound;
   bool insertAfter = (startColIndex > 0);
   for (int32_t colIndex = 0, actualColSpan2 = 0,
                rowBelowIndex = startRowIndex + aRowSpanAbove;
        colIndex <= tableSize.mColumnCount;
        colIndex += std::max(actualColSpan2, 1)) {
     CellData cellDataAtInsertionPoint(*this, *aTable, rowBelowIndex, colIndex,
                                       ignoredError);
@@ -2411,27 +2406,32 @@ HTMLEditor::SplitCellIntoRows(Element* a
     // XXX According to the comment, this does not assume that
     //     FixRowSpan() doesn't work well and user can create non-rectangular
     //     table.  So, we should not return error when CellData cannot find
     //     a cell.
     if (NS_WARN_IF(cellDataAtInsertionPoint.FailedOrNotFound())) {
       return NS_ERROR_FAILURE;
     }
 
-    cell2 =           std::move(cellDataAtInsertionPoint.mElement);
     int32_t    startRowIndex2 = cellDataAtInsertionPoint.mFirst.mRow;
     int32_t    startColIndex2 = cellDataAtInsertionPoint.mFirst.mColumn;
     // int32_t rowSpan2 =       cellDataAtInsertionPoint.mRowSpan;
     // int32_t colSpan2 =       cellDataAtInsertionPoint.mColSpan;
     // int32_t actualRowSpan2 = cellDataAtInsertionPoint.mEffectiveRowSpan;
                actualColSpan2 = cellDataAtInsertionPoint.mEffectiveColSpan;
     // bool    isSelected2 =    cellDataAtInsertionPoint.mIsSelected;
 
+    // FYI: Don't use std::move() here since the following checks will use
+    //      utility methods of cellDataAtInsertionPoint, but some of them
+    //      check whether its mElement is not nullptr.
+    cellElementAtInsertionPoint = cellDataAtInsertionPoint.mElement;
+
     // Skip over cells spanned from above (like the one we are splitting!)
-    if (cell2 && startRowIndex2 == cellDataAtInsertionPoint.mCurrent.mRow) {
+    if (cellDataAtInsertionPoint.mElement &&
+        startRowIndex2 == cellDataAtInsertionPoint.mCurrent.mRow) {
       if (!insertAfter) {
         // Inserting before, so stop at first cell in row we want to insert
         // into.
         break;
       }
       // New cell isn't first in row,
       // so stop after we find the cell just before new cell's column
       if (startColIndex2 + actualColSpan2 == startColIndex) {
@@ -2440,50 +2440,54 @@ HTMLEditor::SplitCellIntoRows(Element* a
       // If cell found is AFTER desired new cell colum,
       //  we have multiple cells with rowspan > 1 that
       //  prevented us from finding a cell to insert after...
       if (startColIndex2 > startColIndex) {
         // ... so instead insert before the cell we found
         insertAfter = false;
         break;
       }
-      lastCellFound = cell2;
+      lastCellFound = std::move(cellDataAtInsertionPoint.mElement);
     }
   }
 
-  if (!cell2 && lastCellFound) {
+  if (!cellElementAtInsertionPoint && lastCellFound) {
     // Edge case where we didn't find a cell to insert after
     //  or before because column(s) before desired column
     //  and all columns after it are spanned from above.
     //  We can insert after the last cell we found
-    cell2 = lastCellFound;
+    cellElementAtInsertionPoint = std::move(lastCellFound);
     insertAfter = true; // Should always be true, but let's be sure
   }
 
   // Reduce rowspan of cell to split
-  nsresult rv = SetRowSpan(cell, aRowSpanAbove);
+  nsresult rv = SetRowSpan(cellData.mElement, aRowSpanAbove);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   // Insert new cell after using the remaining span
   //  and always get the new cell so we can copy the background color;
   RefPtr<Element> newCell;
-  rv = InsertCell(cell2, aRowSpanBelow, actualColSpan, insertAfter, false,
-                  getter_AddRefs(newCell));
+  rv = InsertCell(cellElementAtInsertionPoint, aRowSpanBelow, actualColSpan,
+                  insertAfter, false, getter_AddRefs(newCell));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   if (!newCell) {
     return NS_OK;
   }
   if (aNewCell) {
     NS_ADDREF(*aNewCell = newCell.get());
   }
-  return CopyCellBackgroundColor(newCell, cell2);
+  rv = CopyCellBackgroundColor(newCell, cellElementAtInsertionPoint);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLEditor::SwitchTableCellHeaderType(Element* aSourceCell,
                                       Element** aNewCell)
 {
   if (NS_WARN_IF(!aSourceCell)) {
     return NS_ERROR_INVALID_ARG;
@@ -2627,17 +2631,16 @@ HTMLEditor::JoinTableCells(bool aMergeNo
       for (int32_t actualColSpan2 = 0;
            colIndex < tableSize.mColumnCount;
            colIndex += std::max(actualColSpan2, 1)) {
         CellData cellData(*this, *table, rowIndex, colIndex, ignoredError);
         if (NS_WARN_IF(cellData.FailedOrNotFound())) {
           return NS_ERROR_FAILURE;
         }
 
-        // RefPtr<Element> cell2 = std::move(cellData.mElement);
         // int32_t startRowIndex2 =          cellData.mFirst.mRow;
         // int32_t startColIndex2 =          cellData.mFirst.mColumn;
         // int32_t rowSpan2 =                cellData.mRowSpan;
         // int32_t colSpan2 =                cellData.mColSpan;
         // int32_t actualRowSpan2 =          cellData.mEffectiveRowSpan;
                    actualColSpan2 =          cellData.mEffectiveColSpan;
         bool       isSelected2 =             cellData.mIsSelected;
 
@@ -2711,32 +2714,31 @@ HTMLEditor::JoinTableCells(bool aMergeNo
       for (int32_t colIndex = 0, actualColSpan2 = 0;
            colIndex < tableSize.mColumnCount;
            colIndex += std::max(actualColSpan2, 1)) {
         CellData cellData(*this, *table, rowIndex, colIndex, ignoredError);
         if (NS_WARN_IF(cellData.FailedOrNotFound())) {
           return NS_ERROR_FAILURE;
         }
 
-        RefPtr<Element> cell2 = std::move(cellData.mElement);
         int32_t    startRowIndex2 =       cellData.mFirst.mRow;
         int32_t    startColIndex2 =       cellData.mFirst.mColumn;
         // int32_t rowSpan2 =             cellData.mRowSpan;
         // int32_t colSpan2 =             cellData.mColSpan;
         // int32_t actualRowSpan2 =       cellData.mEffectiveRowSpan;
                    actualColSpan2 =       cellData.mEffectiveColSpan;
         bool       isSelected2 =          cellData.mIsSelected;
 
         // If this is 0, we are past last cell in row, so exit the loop
         if (!actualColSpan2) {
           break;
         }
 
         // Merge only selected cells (skip cell we're merging into, of course)
-        if (isSelected2 && cell2 != firstSelectedCell.mElement) {
+        if (isSelected2 && cellData.mElement != firstSelectedCell.mElement) {
           if (cellData.mCurrent.mRow >= firstSelectedCell.mIndexes.mRow &&
               cellData.mCurrent.mRow <= lastRowIndex &&
               cellData.mCurrent.mColumn >= firstSelectedCell.mIndexes.mColumn &&
               cellData.mCurrent.mColumn <= lastColIndex) {
             // We are within the join region
             // Problem: It is very tricky to delete cells as we merge,
             //  since that will upset the cellmap
             //  Instead, build a list of cells to delete and do it later
@@ -2750,26 +2752,28 @@ HTMLEditor::JoinTableCells(bool aMergeNo
               if ( extraColSpan > 0) {
                 rv = SplitCellIntoColumns(table, startRowIndex2, startColIndex2,
                                           actualColSpan2 - extraColSpan,
                                           extraColSpan, nullptr);
                 NS_ENSURE_SUCCESS(rv, rv);
               }
             }
 
-            rv = MergeCells(firstSelectedCell.mElement, cell2, false);
+            rv =
+              MergeCells(firstSelectedCell.mElement, cellData.mElement, false);
             if (NS_WARN_IF(NS_FAILED(rv))) {
               return rv;
             }
 
             // Add cell to list to delete
-            deleteList.AppendElement(cell2.get());
+            deleteList.AppendElement(cellData.mElement.get());
           } else if (aMergeNonContiguousContents) {
             // Cell is outside join region -- just merge the contents
-            rv = MergeCells(firstSelectedCell.mElement, cell2, false);
+            rv =
+              MergeCells(firstSelectedCell.mElement, cellData.mElement, false);
             if (NS_WARN_IF(NS_FAILED(rv))) {
               return rv;
             }
           }
         }
       }
     }
 
@@ -2828,45 +2832,43 @@ HTMLEditor::JoinTableCells(bool aMergeNo
     // cell.
     IgnoredErrorResult ignoredError;
     CellData leftCellData(*this, *table, startRowIndex, startColIndex,
                           ignoredError);
     if (NS_WARN_IF(leftCellData.FailedOrNotFound())) {
       return NS_ERROR_FAILURE;
     }
 
-    RefPtr<Element> targetCell = std::move(leftCellData.mElement);
                startRowIndex =             leftCellData.mFirst.mRow;
                startColIndex =             leftCellData.mFirst.mColumn;
     // int32_t rowSpan =                   leftCellData.mRowSpan;
     // int32_t colSpan =                   leftCellData.mColSpan;
     int32_t    actualRowSpan =             leftCellData.mEffectiveRowSpan;
     int32_t    actualColSpan =             leftCellData.mEffectiveColSpan;
     // bool    isSelected =                leftCellData.mIsSelected;
 
     // Get data for cell to the right.
     CellData rightCellData(*this, *table,
                            startRowIndex, startColIndex + actualColSpan,
                            ignoredError);
     if (NS_WARN_IF(rightCellData.FailedOrNotFound())) {
       return NS_ERROR_FAILURE;
     }
 
-    RefPtr<Element> cell2 = std::move(rightCellData.mElement);
     int32_t    startRowIndex2 =       rightCellData.mFirst.mRow;
     int32_t    startColIndex2 =       rightCellData.mFirst.mColumn;
     // int32_t rowSpan2 =             rightCellData.mRowSpan;
     // int32_t colSpan2 =             rightCellData.mColSpan;
     int32_t    actualRowSpan2 =       rightCellData.mEffectiveRowSpan;
     int32_t    actualColSpan2 =       rightCellData.mEffectiveColSpan;
     // bool    isSelected2 =          rightCellData.mIsSelected;
 
     // XXX So, this does not assume that CellData returns error when just not
     //     found.  We need to fix this later.
-    if (!cell2) {
+    if (!rightCellData.mElement) {
       return NS_OK; // Don't fail if there's no cell
     }
 
     // sanity check
     NS_ASSERTION(rightCellData.mCurrent.mRow >= startRowIndex2,
                  "JoinCells: rightCellData.mCurrent.mRow < startRowIndex2");
 
     // Figure out span of merged cell starting from target's starting row
@@ -2875,45 +2877,53 @@ HTMLEditor::JoinTableCells(bool aMergeNo
     int32_t effectiveRowSpan2 = actualRowSpan2 - spanAboveMergedCell;
 
     if (effectiveRowSpan2 > actualRowSpan) {
       // Cell to the right spans into row below target
       // Split off portion below target cell's bottom-most row
       rv = SplitCellIntoRows(table, startRowIndex2, startColIndex2,
                              spanAboveMergedCell+actualRowSpan,
                              effectiveRowSpan2-actualRowSpan, nullptr);
-      NS_ENSURE_SUCCESS(rv, rv);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
     }
 
     // Move contents from cell to the right
     // Delete the cell now only if it starts in the same row
     //   and has enough row "height"
-    rv = MergeCells(targetCell, cell2,
+    rv = MergeCells(leftCellData.mElement, rightCellData.mElement,
                     (startRowIndex2 == rightCellData.mCurrent.mRow) &&
                     (effectiveRowSpan2 >= actualRowSpan));
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
 
     if (effectiveRowSpan2 < actualRowSpan) {
       // Merged cell is "shorter"
       // (there are cells(s) below it that are row-spanned by target cell)
       // We could try splitting those cells, but that's REAL messy,
       //  so the safest thing to do is NOT really join the cells
       return NS_OK;
     }
 
     if (spanAboveMergedCell > 0) {
       // Cell we merged started in a row above the target cell
       // Reduce rowspan to give room where target cell will extend its colspan
-      rv = SetRowSpan(cell2, spanAboveMergedCell);
-      NS_ENSURE_SUCCESS(rv, rv);
+      rv = SetRowSpan(rightCellData.mElement, spanAboveMergedCell);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
     }
 
     // Reset target cell's colspan to encompass cell to the right
-    rv = SetColSpan(targetCell, actualColSpan+actualColSpan2);
-    NS_ENSURE_SUCCESS(rv, rv);
+    rv = SetColSpan(leftCellData.mElement, actualColSpan+actualColSpan2);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditor::MergeCells(RefPtr<Element> aTargetCell,
                        RefPtr<Element> aCellToMerge,
                        bool aDeleteCellToMerge)
@@ -3006,28 +3016,27 @@ HTMLEditor::FixBadRowSpan(Element* aTabl
     // CellData passes if cell is missing from cellmap
     // XXX If <table> has large rowspan value or colspan value than actual
     //     cells, we may hit error.  So, this method is always failed to
     //     "fix" the rowspan...
     if (NS_WARN_IF(cellData.FailedOrNotFound())) {
       return NS_ERROR_FAILURE;
     }
 
-    RefPtr<Element> cell = std::move(cellData.mElement);
     int32_t    startRowIndex =       cellData.mFirst.mRow;
     // int32_t startColIndex =       cellData.mFirst.mColumn;
     int32_t    rowSpan =             cellData.mRowSpan;
     // int32_t colSpan =             cellData.mColSpan;
     // int32_t actualRowSpan =       cellData.mEffectiveRowSpan;
                actualColSpan =       cellData.mEffectiveColSpan;
     // bool    isSelected =          cellData.mIsSelected;
 
     // XXX So, this does not assume that CellData returns error when just not
     //     found.  We need to fix this later.
-    if (!cell) {
+    if (!cellData.mElement) {
       break;
     }
 
     if (rowSpan > 0 &&
         startRowIndex == cellData.mCurrent.mRow &&
         (rowSpan < minRowSpan || minRowSpan == -1)) {
       minRowSpan = rowSpan;
     }
@@ -3040,32 +3049,31 @@ HTMLEditor::FixBadRowSpan(Element* aTabl
     for (int32_t colIndex = 0, actualColSpan = 0;
          colIndex < tableSize.mColumnCount;
          colIndex += std::max(actualColSpan, 1)) {
       CellData cellData(*this, *aTable, aRowIndex, colIndex, ignoredError);
       if (NS_WARN_IF(cellData.FailedOrNotFound())) {
         return NS_ERROR_FAILURE;
       }
 
-      RefPtr<Element> cell = std::move(cellData.mElement);
       int32_t    startRowIndex =       cellData.mFirst.mRow;
       int32_t    startColIndex =       cellData.mFirst.mColumn;
       int32_t    rowSpan =             cellData.mRowSpan;
       // int32_t colSpan =             cellData.mColSpan;
       // int32_t actualRowSpan =       cellData.mEffectiveRowSpan;
                  actualColSpan =       cellData.mEffectiveColSpan;
       // bool    isSelected =          cellData.mIsSelected;
 
       // Fixup rowspans only for cells starting in current row
       // XXX So, this does not assume that CellData returns error when just
       //     not found a cell.  Fix this later.
-      if (cell && rowSpan > 0 &&
+      if (cellData.mElement && rowSpan > 0 &&
           startRowIndex == cellData.mCurrent.mRow &&
           startColIndex == cellData.mCurrent.mColumn) {
-        nsresult rv = SetRowSpan(cell, rowSpan-rowsReduced);
+        nsresult rv = SetRowSpan(cellData.mElement, rowSpan-rowsReduced);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
       NS_ASSERTION((actualColSpan > 0),"ActualColSpan = 0 in FixBadRowSpan");
     }
   }
   tableSize.Update(*this, *aTable, error);
@@ -3101,28 +3109,27 @@ HTMLEditor::FixBadColSpan(Element* aTabl
     // CellData passes if cell is missing from cellmap
     // XXX If <table> has large rowspan value or colspan value than actual
     //     cells, we may hit error.  So, this method is always failed to
     //     "fix" the colspan...
     if (NS_WARN_IF(cellData.FailedOrNotFound())) {
       return NS_ERROR_FAILURE;
     }
 
-    RefPtr<Element> cell = std::move(cellData.mElement);
     // int32_t startRowIndex =       cellData.mFirst.mRow;
     int32_t    startColIndex =       cellData.mFirst.mColumn;
     // int32_t rowSpan =             cellData.mRowSpan;
     int32_t    colSpan =             cellData.mColSpan;
                actualRowSpan =       cellData.mEffectiveRowSpan;
     // int32_t actualColSpan =       cellData.mEffectiveColSpan;
     // bool    isSelected =          cellData.mIsSelected;
 
     // XXX So, this does not assume that CellData returns error when just
     //     not found a cell.  Fix this later.
-    if (!cell) {
+    if (!cellData.mElement) {
       break;
     }
     if (colSpan > 0 &&
         startColIndex == cellData.mCurrent.mColumn &&
         (colSpan < minColSpan || minColSpan == -1)) {
       minColSpan = colSpan;
     }
     NS_ASSERTION((actualRowSpan > 0),"ActualRowSpan = 0 in FixBadColSpan");
@@ -3134,32 +3141,31 @@ HTMLEditor::FixBadColSpan(Element* aTabl
     for (int32_t rowIndex = 0, actualRowSpan = 0;
          rowIndex < tableSize.mRowCount;
          rowIndex += std::max(actualRowSpan, 1)) {
       CellData cellData(*this, *aTable, rowIndex, aColIndex, ignoredError);
       if (NS_WARN_IF(cellData.FailedOrNotFound())) {
         return NS_ERROR_FAILURE;
       }
 
-      RefPtr<Element> cell = std::move(cellData.mElement);
       int32_t    startRowIndex =       cellData.mFirst.mRow;
       int32_t    startColIndex =       cellData.mFirst.mColumn;
       // int32_t rowSpan =             cellData.mRowSpan;
       int32_t    colSpan =             cellData.mColSpan;
                  actualRowSpan =       cellData.mEffectiveRowSpan;
       // int32_t actualColSpan =       cellData.mEffectiveColSpan;
       // bool    isSelected =          cellData.mIsSelected;
 
       // Fixup colspans only for cells starting in current column
       // XXX So, this does not assume that CellData returns error when just
       //     not found a cell.  Fix this later.
-      if (cell && colSpan > 0 &&
+      if (cellData.mElement && colSpan > 0 &&
           startColIndex == cellData.mCurrent.mColumn &&
           startRowIndex == cellData.mCurrent.mRow) {
-        nsresult rv = SetColSpan(cell, colSpan-colsReduced);
+        nsresult rv = SetColSpan(cellData.mElement, colSpan-colsReduced);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
       NS_ASSERTION((actualRowSpan > 0),"ActualRowSpan = 0 in FixBadColSpan");
     }
   }
   tableSize.Update(*this, *aTable, error);
@@ -3250,50 +3256,50 @@ HTMLEditor::NormalizeTable(Selection& aS
       // NOTE: This is a *real* failure.
       // CellData passes if cell is missing from cellmap
       // XXX So, this method assumes that CellData won't return error when
       //     just not found.  Fix this later.
       if (NS_WARN_IF(cellData.FailedOrNotFound())) {
         return NS_ERROR_FAILURE;
       }
 
-      RefPtr<Element> cellElement = std::move(cellData.mElement);
       int32_t    startRowIndex =              cellData.mFirst.mRow;
       // int32_t startColIndex =              cellData.mFirst.mColumn;
       // int32_t rowSpan =                    cellData.mRowSpan;
       // int32_t colSpan =                    cellData.mColSpan;
       // int32_t actualRowSpan =              cellData.mEffectiveRowSpan;
       // int32_t actualColSpan =              cellData.mEffectiveColSpan;
       // bool    isSelected =                 cellData.mIsSelected;
 
-      if (!cellElement) {
-        // We are missing a cell at a cellmap location.
-        // Add a cell after the previous cell element in the current row.
-        if (NS_WARN_IF(!previousCellElementInRow)) {
-          // We don't have any cells in this row -- We are really messed up!
-          return NS_ERROR_FAILURE;
+      if (cellData.mElement) {
+        // Save the last cell found in the same row we are scanning
+        if (startRowIndex == cellData.mCurrent.mRow) {
+          previousCellElementInRow = std::move(cellData.mElement);
         }
-
-        // Insert a new cell after (true), and return the new cell to us
-        nsresult rv =
-          InsertCell(previousCellElementInRow, 1, 1, true, false,
-                     getter_AddRefs(cellElement));
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          return rv;
-        }
-
-        // Set this so we use returned new "cell" to set
-        // previousCellElementInRow below.
-        if (cellElement) {
-          startRowIndex = cellData.mCurrent.mRow;
-        }
+        continue;
+      }
+
+      // We are missing a cell at a cellmap location.
+      // Add a cell after the previous cell element in the current row.
+      if (NS_WARN_IF(!previousCellElementInRow)) {
+        // We don't have any cells in this row -- We are really messed up!
+        return NS_ERROR_FAILURE;
       }
-      // Save the last cell found in the same row we are scanning
-      if (startRowIndex == cellData.mCurrent.mRow) {
-        previousCellElementInRow = cellElement;
+
+      // Insert a new cell after (true), and return the new cell to us
+      RefPtr<Element> newCellElement;
+      nsresult rv =
+        InsertCell(previousCellElementInRow, 1, 1, true, false,
+                   getter_AddRefs(newCellElement));
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
+
+      if (newCellElement) {
+        previousCellElementInRow = std::move(newCellElement);
       }
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLEditor::GetCellIndexes(Element* aCellElement,
@@ -3405,26 +3411,25 @@ HTMLEditor::GetNumberOfCellsInRow(Elemen
     // Failure means that there is no more cell in the row.  In this case,
     // we shouldn't return error since we just reach the end of the row.
     // XXX So, this method assumes that CellData won't return error when
     //     just not found.  Fix this later.
     if (cellData.FailedOrNotFound()) {
       break;
     }
 
-    RefPtr<Element> cellElement = std::move(cellData.mElement);
     int32_t    startRowIndex =              cellData.mFirst.mRow;
     // int32_t startColIndex =              cellData.mFirst.mColumn;
     // int32_t rowSpan =                    cellData.mRowSpan;
     // int32_t colSpan =                    cellData.mColSpan;
     // int32_t actualRowSpan =              cellData.mEffectiveRowSpan;
     int32_t    actualColSpan =              cellData.mEffectiveColSpan;
     // bool    isSelected =                 cellData.mIsSelected;
 
-    if (cellElement) {
+    if (cellData.mElement) {
       // Only count cells that start in row we are working with
       if (startRowIndex == cellData.mCurrent.mRow) {
         numberOfCells++;
       }
       // Next possible location for a cell
       columnIndex += actualColSpan;
     } else {
       columnIndex++;
@@ -4393,30 +4398,29 @@ HTMLEditor::AllCellsInRowSelected(Elemen
   for (int32_t col = 0, actualColSpan = 0;
        col < aNumberOfColumns;
        col += std::max(actualColSpan, 1)) {
     CellData cellData(*this, *aTable, aRowIndex, col, ignoredError);
     if (NS_WARN_IF(cellData.FailedOrNotFound())) {
       return false;
     }
 
-    RefPtr<Element> cell = std::move(cellData.mElement);
     // int32_t curStartRowIndex =    cellData.mFirst.mRow;
     // int32_t curStartColIndex =    cellData.mFirst.mColumn;
     // int32_t rowSpan =             cellData.mRowSpan;
     // int32_t colSpan =             cellData.mColSpan;
     // int32_t actualRowSpan =       cellData.mEffectiveRowSpan;
                actualColSpan =       cellData.mEffectiveColSpan;
     bool       isSelected =          cellData.mIsSelected;
 
     // If no cell, we may have a "ragged" right edge, so return TRUE only if
     // we already found a cell in the row.
     // XXX So, this does not assume that CellData returns error when just
     //     not found a cell.  Fix this later.
-    if (NS_WARN_IF(!cell)) {
+    if (NS_WARN_IF(!cellData.mElement)) {
       return cellData.mCurrent.mColumn > 0;
     }
 
     // Return as soon as a non-selected cell is found.
     // XXX Odd, this is testing if each cell element is selected.  Why do
     //     we need to warn if it's false??
     if (NS_WARN_IF(!isSelected)) {
       return false;
@@ -4440,30 +4444,29 @@ HTMLEditor::AllCellsInColumnSelected(Ele
   for (int32_t row = 0, actualRowSpan = 0;
        row < aNumberOfRows;
        row += std::max(actualRowSpan, 1)) {
     CellData cellData(*this, *aTable, row, aColIndex, ignoredError);
     if (NS_WARN_IF(cellData.FailedOrNotFound())) {
       return false;
     }
 
-    RefPtr<Element> cell = std::move(cellData.mElement);
     // int32_t curStartRowIndex =    cellData.mFirst.mRow;
     // int32_t curStartColIndex =    cellData.mFirst.mColumn;
     // int32_t rowSpan =             cellData.mRowSpan;
     // int32_t colSpan =             cellData.mColSpan;
                actualRowSpan =       cellData.mEffectiveRowSpan;
     // int32_t actualColSpan =       cellData.mEffectiveColSpan;
     bool       isSelected =          cellData.mIsSelected;
 
     // If no cell, we must have a "ragged" right edge on the last column so
     // return TRUE only if we already found a cell in the row.
     // XXX So, this does not assume that CellData returns error when just
     //     not found a cell.  Fix this later.
-    if (NS_WARN_IF(!cell)) {
+    if (NS_WARN_IF(!cellData.mElement)) {
       return cellData.mCurrent.mRow > 0;
     }
 
     // Return as soon as a non-selected cell is found.
     // XXX Odd, this is testing if each cell element is selected.  Why do
     //     we need to warn if it's false??
     if (NS_WARN_IF(!isSelected)) {
       return false;