Bug 1762115 - part 13: Make EditorBase::InsertNodeWithTransaction stop touching Selection directly r=m_kato
Differential Revision: https://phabricator.services.mozilla.com/D144656
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include "mozilla/EditorDOMPoint.h"
|
||||
#include "mozilla/EditorUtils.h"
|
||||
#include "mozilla/FlushType.h"
|
||||
#include "mozilla/IntegerRange.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
@@ -135,12 +136,21 @@ nsresult HTMLEditor::InsertCell(Element* aCell, int32_t aRowSpan,
|
||||
"Failed to advance offset to after the old cell");
|
||||
}
|
||||
|
||||
// Don't let Rules System change the selection.
|
||||
// TODO: Remove AutoTransactionsConserveSelection here. It's not necessary
|
||||
// in normal cases. However, it may be required for nested edit
|
||||
// actions which may be caused by legacy mutation event listeners or
|
||||
// chrome script.
|
||||
AutoTransactionsConserveSelection dontChangeSelection(*this);
|
||||
nsresult rv = InsertNodeWithTransaction(*newCell, pointToInsert);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"EditorBase::InsertNodeWithTransaction() failed");
|
||||
return rv;
|
||||
CreateElementResult insertNewCellResult =
|
||||
InsertNodeWithTransaction<Element>(*newCell, pointToInsert);
|
||||
if (insertNewCellResult.isErr()) {
|
||||
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
|
||||
return insertNewCellResult.unwrapErr();
|
||||
}
|
||||
// Because of dontChangeSelection, we've never allowed to transactions to
|
||||
// update selection here.
|
||||
insertNewCellResult.IgnoreCaretPointSuggestion();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::SetColSpan(Element* aCell, int32_t aColSpan) {
|
||||
@@ -254,7 +264,10 @@ nsresult HTMLEditor::InsertTableCellsWithTransaction(
|
||||
AutoSelectionSetterAfterTableEdit setCaret(
|
||||
*this, table, cellDataAtSelection.mCurrent.mRow, newCellIndex,
|
||||
ePreviousColumn, false);
|
||||
// So, suppress Rules System selection munging.
|
||||
// TODO: Remove AutoTransactionsConserveSelection here. It's not necessary
|
||||
// in normal cases. However, it may be required for nested edit
|
||||
// actions which may be caused by legacy mutation event listeners or
|
||||
// chrome script.
|
||||
AutoTransactionsConserveSelection dontChangeSelection(*this);
|
||||
|
||||
EditorDOMPoint pointToInsert(cellParent, cellOffset);
|
||||
@@ -266,18 +279,23 @@ nsresult HTMLEditor::InsertTableCellsWithTransaction(
|
||||
NS_WARNING_ASSERTION(advanced,
|
||||
"Failed to move insertion point after the cell");
|
||||
}
|
||||
for (int32_t i = 0; i < aNumberOfCellsToInsert; i++) {
|
||||
for ([[maybe_unused]] const auto i :
|
||||
IntegerRange<uint32_t>(aNumberOfCellsToInsert)) {
|
||||
RefPtr<Element> newCell = CreateElementWithDefaults(*nsGkAtoms::td);
|
||||
if (!newCell) {
|
||||
if (MOZ_UNLIKELY(!newCell)) {
|
||||
NS_WARNING("HTMLEditor::CreateElementWithDefaults(nsGkAtoms::td) failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
AutoEditorDOMPointChildInvalidator lockOffset(pointToInsert);
|
||||
nsresult rv = InsertNodeWithTransaction(*newCell, pointToInsert);
|
||||
if (NS_FAILED(rv)) {
|
||||
CreateElementResult insertNewCellResult =
|
||||
InsertNodeWithTransaction<Element>(*newCell, pointToInsert);
|
||||
if (insertNewCellResult.isErr()) {
|
||||
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
|
||||
return rv;
|
||||
return insertNewCellResult.unwrapErr();
|
||||
}
|
||||
// Because of dontChangeSelection, we've never allowed to transactions to
|
||||
// update selection here.
|
||||
insertNewCellResult.IgnoreCaretPointSuggestion();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -762,7 +780,10 @@ nsresult HTMLEditor::InsertTableRowsWithTransaction(
|
||||
AutoSelectionSetterAfterTableEdit setCaret(
|
||||
*this, table, startRowIndex, cellDataAtSelection.mCurrent.mColumn,
|
||||
ePreviousColumn, false);
|
||||
// Suppress Rules System selection munging.
|
||||
// TODO: Remove AutoTransactionsConserveSelection here. It's not necessary
|
||||
// in normal cases. However, it may be required for nested edit
|
||||
// actions which may be caused by legacy mutation event listeners or
|
||||
// chrome script.
|
||||
AutoTransactionsConserveSelection dontChangeSelection(*this);
|
||||
|
||||
RefPtr<Element> cellForRowParent;
|
||||
@@ -890,11 +911,15 @@ nsresult HTMLEditor::InsertTableRowsWithTransaction(
|
||||
}
|
||||
|
||||
AutoEditorDOMPointChildInvalidator lockOffset(pointToInsert);
|
||||
nsresult rv = InsertNodeWithTransaction(*newRow, pointToInsert);
|
||||
if (NS_FAILED(rv)) {
|
||||
CreateElementResult insertNewRowResult =
|
||||
InsertNodeWithTransaction<Element>(*newRow, pointToInsert);
|
||||
if (insertNewRowResult.isErr()) {
|
||||
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
|
||||
return rv;
|
||||
return insertNewRowResult.unwrapErr();
|
||||
}
|
||||
// Because of dontChangeSelection, we've never allowed to transactions to
|
||||
// update selection here.
|
||||
insertNewRowResult.IgnoreCaretPointSuggestion();
|
||||
}
|
||||
|
||||
// SetSelectionAfterTableEdit from AutoSelectionSetterAfterTableEdit will
|
||||
@@ -3110,6 +3135,7 @@ nsresult HTMLEditor::MergeCells(RefPtr<Element> aTargetCell,
|
||||
}
|
||||
|
||||
// Move the contents
|
||||
EditorDOMPoint pointToPutCaret;
|
||||
while (aCellToMerge->HasChildren()) {
|
||||
nsCOMPtr<nsIContent> cellChild = aCellToMerge->GetLastChild();
|
||||
if (NS_WARN_IF(!cellChild)) {
|
||||
@@ -3120,12 +3146,27 @@ nsresult HTMLEditor::MergeCells(RefPtr<Element> aTargetCell,
|
||||
NS_WARNING("HTMLEditor::DeleteNodeWithTransaction() failed");
|
||||
return rv;
|
||||
}
|
||||
rv = InsertNodeWithTransaction(*cellChild,
|
||||
EditorDOMPoint(aTargetCell, insertIndex));
|
||||
if (NS_FAILED(rv)) {
|
||||
CreateContentResult insertChildContentResult = InsertNodeWithTransaction(
|
||||
*cellChild, EditorDOMPoint(aTargetCell, insertIndex));
|
||||
if (insertChildContentResult.isErr()) {
|
||||
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
|
||||
return rv;
|
||||
return insertChildContentResult.unwrapErr();
|
||||
}
|
||||
insertChildContentResult.MoveCaretPointTo(
|
||||
pointToPutCaret, *this,
|
||||
{SuggestCaret::OnlyIfHasSuggestion,
|
||||
SuggestCaret::OnlyIfTransactionsAllowedToDoIt});
|
||||
}
|
||||
if (pointToPutCaret.IsSet()) {
|
||||
nsresult rv = CollapseSelectionTo(pointToPutCaret);
|
||||
if (MOZ_UNLIKELY(rv == NS_ERROR_EDITOR_DESTROYED)) {
|
||||
NS_WARNING(
|
||||
"EditorBase::CollapseSelectionTo() caused destroying the editor");
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rv),
|
||||
"EditorBase::CollapseSelectionTo() failed, but ignored");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user