brElement = CreateMozBR(EditorRawDOMPoint(div, 0));
- if (NS_WARN_IF(!brElement)) {
- return NS_ERROR_FAILURE;
+ CreateElementResult createMozBrResult =
+ CreateMozBR(EditorRawDOMPoint(div, 0));
+ if (NS_WARN_IF(createMozBrResult.Failed())) {
+ return createMozBrResult.Rv();
}
EditorRawDOMPoint atStartOfDiv(div, 0);
- ErrorResult error;
- SelectionRef().Collapse(atStartOfDiv, error);
// Don't restore the selection
selectionRestorer.Abort();
+ ErrorResult error;
+ SelectionRef().Collapse(atStartOfDiv, error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
@@ -5632,8 +6357,11 @@
// don't need to nest it, just set the alignment. In CSS, assign the
// corresponding CSS styles in AlignBlock
if (HTMLEditUtils::SupportsAlignAttr(*curNode)) {
- rv = AlignBlock(*curNode->AsElement(), aAlignType, ContentsOnly::no);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = AlignBlock(*curNode->AsElement(), aAlignType,
+ ResetAlignOf::ElementAndDescendants);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
// Clear out curDiv so that we don't put nodes after this one into it
curDiv = nullptr;
continue;
@@ -5663,19 +6391,29 @@
HTMLEditUtils::IsList(curNode)) {
AutoEditorDOMPointOffsetInvalidator lockChild(atCurNode);
rv = RemoveAlignment(*curNode, aAlignType, true);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (useCSS) {
HTMLEditorRef().mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
curNode->AsElement(), nullptr,
nsGkAtoms::align, &aAlignType, false);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
curDiv = nullptr;
continue;
}
if (HTMLEditUtils::IsList(atCurNode.GetContainer())) {
- // If we don't use CSS, add a contraint to list element: they have to
- // be inside another list, i.e., >= second level of nesting
+ // If we don't use CSS, add a content to list element: they have to
+ // be inside another list, i.e., >= second level of nesting.
+ // XXX AlignInnerBlocks() handles list item elements and table cells.
+ // Is it intentional to change alignment of nested other type
+ // descendants too?
rv = AlignInnerBlocks(*curNode, aAlignType);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
curDiv = nullptr;
continue;
}
@@ -5700,18 +6438,28 @@
curDiv =
HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::div,
splitNodeResult.SplitPoint());
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!curDiv)) {
return NS_ERROR_FAILURE;
}
// Remember our new block for postprocessing
mNewBlock = curDiv;
// Set up the alignment on the div
- rv = AlignBlock(*curDiv, aAlignType, ContentsOnly::yes);
+ rv = AlignBlock(*curDiv, aAlignType, ResetAlignOf::OnlyDescendants);
+ if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to align the ");
}
// Tuck the node into the end of the active div
rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
*curDiv);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -5720,10 +6468,6 @@
return NS_OK;
}
-
-/**
- * AlignInnerBlocks() aligns inside table cells or list items.
- */
nsresult
HTMLEditRules::AlignInnerBlocks(nsINode& aNode,
const nsAString& aAlignType)
@@ -5748,9 +6492,6 @@
}
-/**
- * AlignBlockContents() aligns contents of a block element.
- */
nsresult
HTMLEditRules::AlignBlockContents(nsINode& aNode,
const nsAString& aAlignType)
@@ -5768,9 +6509,17 @@
if (firstChild == lastChild && firstChild->IsHTMLElement(nsGkAtoms::div)) {
// the cell already has a div containing all of its content: just
// act on this div.
- return HTMLEditorRef().SetAttributeOrEquivalent(firstChild->AsElement(),
- nsGkAtoms::align,
- aAlignType, false);
+ nsresult rv =
+ HTMLEditorRef().SetAttributeOrEquivalent(firstChild->AsElement(),
+ nsGkAtoms::align,
+ aAlignType, false);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
// else we need to put in a div, set the alignment, and toss in all the
@@ -5778,6 +6527,9 @@
EditorRawDOMPoint atStartOfNode(&aNode, 0);
RefPtr divElem =
HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::div, atStartOfNode);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!divElem)) {
return NS_ERROR_FAILURE;
}
@@ -5785,6 +6537,9 @@
nsresult rv =
HTMLEditorRef().SetAttributeOrEquivalent(divElem, nsGkAtoms::align,
aAlignType, false);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -5793,6 +6548,9 @@
nsresult rv =
HTMLEditorRef().MoveNodeWithTransaction(*lastChild,
EditorRawDOMPoint(divElem, 0));
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -5801,41 +6559,37 @@
return NS_OK;
}
-/**
- * CheckForEmptyBlock() is called by WillDeleteSelection() to detect and handle
- * case of deleting from inside an empty block.
- */
-nsresult
-HTMLEditRules::CheckForEmptyBlock(nsINode* aStartNode,
- Element* aBodyNode,
- nsIEditor::EDirection aAction,
- bool* aHandled)
+nsresult
+HTMLEditRules::MaybeDeleteTopMostEmptyAncestor(nsINode& aStartNode,
+ Element& aEditingHostElement,
+ nsIEditor::EDirection aAction,
+ bool* aHandled)
{
MOZ_ASSERT(IsEditorDataAvailable());
// If the editing host is an inline element, bail out early.
- if (aBodyNode && IsInlineNode(*aBodyNode)) {
+ if (IsInlineNode(aEditingHostElement)) {
return NS_OK;
}
// If we are inside an empty block, delete it. Note: do NOT delete table
// elements this way.
- RefPtr block = HTMLEditorRef().GetBlock(*aStartNode);
- bool bIsEmptyNode;
+ RefPtr block = HTMLEditorRef().GetBlock(aStartNode);
RefPtr emptyBlock;
- if (block && block != aBodyNode) {
+ if (block && block != &aEditingHostElement) {
// Efficiency hack, avoiding IsEmptyNode() call when in body
+ bool isEmptyNode = false;
nsresult rv =
- HTMLEditorRef().IsEmptyNode(block, &bIsEmptyNode, true, false);
+ HTMLEditorRef().IsEmptyNode(block, &isEmptyNode, true, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
- while (block && bIsEmptyNode && !HTMLEditUtils::IsTableElement(block) &&
- block != aBodyNode) {
+ while (block && isEmptyNode && !HTMLEditUtils::IsTableElement(block) &&
+ block != &aEditingHostElement) {
emptyBlock = block;
block = HTMLEditorRef().GetBlockNodeParent(emptyBlock);
if (block) {
- rv = HTMLEditorRef().IsEmptyNode(block, &bIsEmptyNode, true, false);
+ rv = HTMLEditorRef().IsEmptyNode(block, &isEmptyNode, true, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -5843,43 +6597,59 @@
}
}
- if (emptyBlock && emptyBlock->IsEditable()) {
- nsCOMPtr blockParent = emptyBlock->GetParentNode();
- NS_ENSURE_TRUE(blockParent, NS_ERROR_FAILURE);
-
- if (HTMLEditUtils::IsListItem(emptyBlock)) {
- // Are we the first list item in the list?
- if (HTMLEditorRef().IsFirstEditableChild(emptyBlock)) {
- EditorDOMPoint atBlockParent(blockParent);
- if (NS_WARN_IF(!atBlockParent.IsSet())) {
+ if (!emptyBlock || !emptyBlock->IsEditable()) {
+ return NS_OK;
+ }
+
+ nsCOMPtr blockParent = emptyBlock->GetParentNode();
+ if (NS_WARN_IF(!blockParent)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (HTMLEditUtils::IsListItem(emptyBlock)) {
+ // If the found empty block is a list item element and its grand parent
+ // (i.e., parent of list element) is NOT a list element, insert
+ // element before the list element which has the empty list item.
+ // XXX Typically, list element shouldn't have another list element.
+ // So, what's the purpose of this block?
+ if (HTMLEditorRef().IsFirstEditableChild(emptyBlock)) {
+ EditorDOMPoint atBlockParent(blockParent);
+ if (NS_WARN_IF(!atBlockParent.IsSet())) {
+ return NS_ERROR_FAILURE;
+ }
+ // If the grand parent IS a list element, we'll adjust Selection in
+ // AfterEdit().
+ if (!HTMLEditUtils::IsList(atBlockParent.GetContainer())) {
+ RefPtr brElement =
+ HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
+ atBlockParent);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
- // If we are a sublist, skip the br creation
- if (!HTMLEditUtils::IsList(atBlockParent.GetContainer())) {
- // Create a br before list
- RefPtr brElement =
- HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
- atBlockParent);
- if (NS_WARN_IF(!brElement)) {
- return NS_ERROR_FAILURE;
- }
- // Adjust selection to be right before it
- ErrorResult error;
- SelectionRef().Collapse(EditorRawDOMPoint(brElement), error);
- if (NS_WARN_IF(error.Failed())) {
- return error.StealNSResult();
- }
+ ErrorResult error;
+ SelectionRef().Collapse(EditorRawDOMPoint(brElement), error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ if (NS_WARN_IF(error.Failed())) {
+ return error.StealNSResult();
}
- // Else just let selection percolate up. We'll adjust it in
- // AfterEdit()
}
- } else {
- if (aAction == nsIEditor::eNext || aAction == nsIEditor::eNextWord ||
- aAction == nsIEditor::eToEndOfLine) {
- // Move to the start of the next node, if any
+ }
+ } else {
+ switch (aAction) {
+ case nsIEditor::eNext:
+ case nsIEditor::eNextWord:
+ case nsIEditor::eToEndOfLine: {
+ // Collapse Selection to next node of after empty block element
+ // if there is. Otherwise, to just after the empty block.
EditorRawDOMPoint afterEmptyBlock(emptyBlock);
- DebugOnly advanced = afterEmptyBlock.AdvanceOffset();
- NS_WARNING_ASSERTION(advanced,
+ bool advancedFromEmptyBlock = afterEmptyBlock.AdvanceOffset();
+ NS_WARNING_ASSERTION(advancedFromEmptyBlock,
"Failed to set selection to the after the empty block");
nsCOMPtr nextNode =
HTMLEditorRef().GetNextNode(afterEmptyBlock);
@@ -5887,25 +6657,34 @@
EditorDOMPoint pt = GetGoodSelPointForNode(*nextNode, aAction);
ErrorResult error;
SelectionRef().Collapse(pt, error);
- if (NS_WARN_IF(error.Failed())) {
- return error.StealNSResult();
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
}
- } else {
- // Adjust selection to be right after it.
- EditorRawDOMPoint afterEmptyBlock(emptyBlock);
- if (NS_WARN_IF(!afterEmptyBlock.AdvanceOffset())) {
- return NS_ERROR_FAILURE;
- }
- ErrorResult error;
- SelectionRef().Collapse(afterEmptyBlock, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
+ break;
+ }
+ if (NS_WARN_IF(!advancedFromEmptyBlock)) {
+ return NS_ERROR_FAILURE;
+ }
+ ErrorResult error;
+ SelectionRef().Collapse(afterEmptyBlock, error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ if (NS_WARN_IF(error.Failed())) {
+ return error.StealNSResult();
}
- } else if (aAction == nsIEditor::ePrevious ||
- aAction == nsIEditor::ePreviousWord ||
- aAction == nsIEditor::eToBeginningOfLine) {
- // Move to the end of the previous node
+ break;
+ }
+ case nsIEditor::ePrevious:
+ case nsIEditor::ePreviousWord:
+ case nsIEditor::eToBeginningOfLine: {
+ // Collapse Selection to previous editable node of the empty block
+ // if there is. Otherwise, to after the empty block.
EditorRawDOMPoint atEmptyBlock(emptyBlock);
nsCOMPtr priorNode =
HTMLEditorRef().GetPreviousEditableNode(atEmptyBlock);
@@ -5913,29 +6692,43 @@
EditorDOMPoint pt = GetGoodSelPointForNode(*priorNode, aAction);
ErrorResult error;
SelectionRef().Collapse(pt, error);
- if (NS_WARN_IF(error.Failed())) {
- return error.StealNSResult();
- }
- } else {
- EditorRawDOMPoint afterEmptyBlock(emptyBlock);
- if (NS_WARN_IF(!afterEmptyBlock.AdvanceOffset())) {
- return NS_ERROR_FAILURE;
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
}
- ErrorResult error;
- SelectionRef().Collapse(afterEmptyBlock, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
+ break;
}
- } else if (aAction != nsIEditor::eNone) {
- MOZ_CRASH("CheckForEmptyBlock doesn't support this action yet");
+ EditorRawDOMPoint afterEmptyBlock(emptyBlock);
+ if (NS_WARN_IF(!afterEmptyBlock.AdvanceOffset())) {
+ return NS_ERROR_FAILURE;
+ }
+ ErrorResult error;
+ SelectionRef().Collapse(afterEmptyBlock, error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ if (NS_WARN_IF(error.Failed())) {
+ return error.StealNSResult();
+ }
+ break;
}
+ case nsIEditor::eNone:
+ break;
+ default:
+ MOZ_CRASH("CheckForEmptyBlock doesn't support this action yet");
}
- *aHandled = true;
- nsresult rv = HTMLEditorRef().DeleteNodeWithTransaction(*emptyBlock);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
+ }
+ *aHandled = true;
+ nsresult rv = HTMLEditorRef().DeleteNodeWithTransaction(*emptyBlock);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
}
return NS_OK;
}
@@ -5983,13 +6776,6 @@
return nullptr;
}
-/**
- * aLists and aTables allow the caller to specify what kind of content to
- * "look inside". If aTables is Tables::yes, look inside any table content,
- * and insert the inner content into the supplied nsTArray at offset
- * aIndex. Similarly with aLists and list content. aIndex is updated to
- * point past inserted elements.
- */
void
HTMLEditRules::GetInnerContent(
nsINode& aNode,
@@ -6014,9 +6800,6 @@
}
}
-/**
- * Promotes selection to include blocks that have all their children selected.
- */
nsresult
HTMLEditRules::ExpandSelectionForDeletion()
{
@@ -6045,7 +6828,7 @@
int32_t selEndOffset = firstRange->EndOffset();
// Find current selection common block parent
- nsCOMPtr selCommon =
+ RefPtr selCommon =
HTMLEditor::GetBlock(*firstRange->GetCommonAncestor());
if (NS_WARN_IF(!selCommon)) {
return NS_ERROR_FAILURE;
@@ -6061,7 +6844,7 @@
return NS_ERROR_FAILURE;
}
- // Find previous visible thingy before start of selection
+ // Find previous visible things before start of selection
if (selStartNode != selCommon && selStartNode != root) {
while (true) {
WSRunObject wsObj(&HTMLEditorRef(), selStartNode, selStartOffset);
@@ -6083,7 +6866,7 @@
}
}
- // Find next visible thingy after end of selection
+ // Find next visible things after end of selection
if (selEndNode != selCommon && selEndNode != root) {
for (;;) {
WSRunObject wsObj(&HTMLEditorRef(), selEndNode, selEndOffset);
@@ -6118,13 +6901,16 @@
// Now set the selection to the new range
DebugOnly rv =
SelectionRef().Collapse(selStartNode, selStartOffset);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to collapse selection");
- // Expand selection endpoint only if we didn't pass a br, or if we really
- // needed to pass that br (i.e., its block is now totally selected)
+ // Expand selection endpoint only if we didn't pass a
, or if we really
+ // needed to pass that
(i.e., its block is now totally selected).
bool doEndExpansion = true;
if (firstBRParent) {
- // Find block node containing br
+ // Find block node containing
.
nsCOMPtr brBlock = HTMLEditor::GetBlock(*firstBRParent);
bool nodeBefore = false, nodeAfter = false;
@@ -6141,19 +6927,25 @@
nsRange::CompareNodeToRange(brBlock, range, &nodeBefore, &nodeAfter);
}
- // If block isn't contained, forgo grabbing the br in expanded selection
+ // If block isn't contained, forgo grabbing the
in expanded selection.
if (nodeBefore || nodeAfter) {
doEndExpansion = false;
}
}
if (doEndExpansion) {
nsresult rv = SelectionRef().Extend(selEndNode, selEndOffset);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
- // Only expand to just before br
+ // Only expand to just before
.
nsresult rv = SelectionRef().Extend(firstBRParent, firstBROffset);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -6162,24 +6954,25 @@
return NS_OK;
}
-/**
- * NormalizeSelection() tweaks non-collapsed selections to be more "natural".
- * Idea here is to adjust selection endpoint so that they do not cross breaks
- * or block boundaries unless something editable beyond that boundary is also
- * selected. This adjustment makes it much easier for the various block
- * operations to determine what nodes to act on.
- */
nsresult
HTMLEditRules::NormalizeSelection()
{
MOZ_ASSERT(IsEditorDataAvailable());
+ // NormalizeSelection() tweaks non-collapsed selections to be more "natural".
+ // Idea here is to adjust selection endpoint so that they do not cross breaks
+ // or block boundaries unless something editable beyond that boundary is also
+ // selected. This adjustment makes it much easier for the various block
+ // operations to determine what nodes to act on.
+
// don't need to touch collapsed selections
if (SelectionRef().IsCollapsed()) {
return NS_OK;
}
- // we don't need to mess with cell selections, and we assume multirange selections are those.
+ // We don't need to mess with cell selections, and we assume multirange
+ // selections are those.
+ // XXX Why? Even in , user can select 2 or more ranges.
if (SelectionRef().RangeCount() != 1) {
return NS_OK;
}
@@ -6216,12 +7009,12 @@
// let the whitespace code do the heavy lifting
WSRunObject wsEndObj(&HTMLEditorRef(), endNode,
static_cast(endOffset));
- // is there any intervening visible whitespace? if so we can't push selection past that,
- // it would visibly change maening of users selection
+ // Is there any intervening visible whitespace? If so we can't push
+ // selection past that, it would visibly change meaning of users selection.
wsEndObj.PriorVisibleNode(EditorRawDOMPoint(endNode, endOffset),
address_of(unused), &offset, &wsType);
if (wsType != WSType::text && wsType != WSType::normalWS) {
- // eThisBlock and eOtherBlock conveniently distinquish cases
+ // eThisBlock and eOtherBlock conveniently distinguish cases
// of going "down" into a block and "up" out of a block.
if (wsEndObj.mStartReason == WSType::otherBlock) {
// endpoint is just after the close of a block.
@@ -6258,12 +7051,12 @@
// similar dealio for start of range
WSRunObject wsStartObj(&HTMLEditorRef(), startNode,
static_cast(startOffset));
- // is there any intervening visible whitespace? if so we can't push selection past that,
- // it would visibly change maening of users selection
+ // Is there any intervening visible whitespace? If so we can't push
+ // selection past that, it would visibly change meaning of users selection.
wsStartObj.NextVisibleNode(EditorRawDOMPoint(startNode, startOffset),
address_of(unused), &offset, &wsType);
if (wsType != WSType::text && wsType != WSType::normalWS) {
- // eThisBlock and eOtherBlock conveniently distinquish cases
+ // eThisBlock and eOtherBlock conveniently distinguish cases
// of going "down" into a block and "up" out of a block.
if (wsStartObj.mEndReason == WSType::otherBlock) {
// startpoint is just before the start of a block.
@@ -6297,13 +7090,14 @@
}
}
- // there is a demented possiblity we have to check for. We might have a very strange selection
- // that is not collapsed and yet does not contain any editable content, and satisfies some of the
- // above conditions that cause tweaking. In this case we don't want to tweak the selection into
- // a block it was never in, etc. There are a variety of strategies one might use to try to
- // detect these cases, but I think the most straightforward is to see if the adjusted locations
- // "cross" the old values: ie, new end before old start, or new start after old end. If so
- // then just leave things alone.
+ // There is a demented possiblity we have to check for. We might have a very
+ // strange selection that is not collapsed and yet does not contain any
+ // editable content, and satisfies some of the above conditions that cause
+ // tweaking. In this case we don't want to tweak the selection into a block
+ // it was never in, etc. There are a variety of strategies one might use to
+ // try to detect these cases, but I think the most straightforward is to see
+ // if the adjusted locations "cross" the old values: i.e., new end before old
+ // start, or new start after old end. If so then just leave things alone.
int16_t comp;
comp = nsContentUtils::ComparePoints(startNode, startOffset,
@@ -6321,18 +7115,20 @@
// XXX Why don't we use SetBaseAndExtent()?
DebugOnly rv =
SelectionRef().Collapse(newStartNode, newStartOffset);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"Failed to collapse selection");
rv = SelectionRef().Extend(newEndNode, newEndOffset);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"Failed to extend selection");
return NS_OK;
}
-/**
- * GetPromotedPoint() figures out where a start or end point for a block
- * operation really is.
- */
EditorDOMPoint
HTMLEditRules::GetPromotedPoint(RulesEndpoint aWhere,
nsINode& aNode,
@@ -6527,10 +7323,6 @@
return point;
}
-/**
- * GetPromotedRanges() runs all the selection range endpoint through
- * GetPromotedPoint().
- */
void
HTMLEditRules::GetPromotedRanges(nsTArray>& outArrayOfRanges,
EditAction inOperationType)
@@ -6555,15 +7347,12 @@
}
}
-/**
- * PromoteRange() expands a range to include any parents for which all editable
- * children are already in range.
- */
void
HTMLEditRules::PromoteRange(nsRange& aRange,
EditAction aOperationType)
{
MOZ_ASSERT(IsEditorDataAvailable());
+ MOZ_ASSERT(!aRange.IsInSelection());
if (!aRange.IsPositioned()) {
return;
@@ -6656,13 +7445,6 @@
nsTArray>& mArray;
};
-/**
- * GetNodesForOperation() runs through the ranges in the array and construct a
- * new array of nodes to be acted on.
- *
- * XXX This name stats with "Get" but actually this modifies the DOM tree with
- * transaction. We should rename this to making clearer what this does.
- */
nsresult
HTMLEditRules::GetNodesForOperation(
nsTArray>& aArrayOfRanges,
@@ -6687,14 +7469,18 @@
ErrorResult error;
nsCOMPtr newLeftNode =
HTMLEditorRef().SplitNodeWithTransaction(atEnd, error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
// Correct the range.
// The new end parent becomes the parent node of the text.
- // XXX We want nsRange::SetEnd(const RawRangeBoundary&)
EditorRawDOMPoint atContainerOfSplitNode(atEnd.GetContainer());
+ MOZ_ASSERT(!range->IsInSelection());
range->SetEnd(atContainerOfSplitNode, error);
if (NS_WARN_IF(error.Failed())) {
error.SuppressException();
@@ -6705,7 +7491,7 @@
// Bust up any inlines that cross our range endpoints, but only if we are
// allowed to touch content.
-
+ // XXX Why don't we merge this block with the previous block?
if (aTouchContent == TouchContent::yes) {
nsTArray> rangeItemArray;
rangeItemArray.AppendElements(aArrayOfRanges.Length());
@@ -6811,6 +7597,7 @@
aOperationType == EditAction::outdent) {
for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) {
OwningNonNull node = aOutArrayOfNodes[i];
+ // XXX Why do we run this loop even when aTouchContent is "no"?
if (aTouchContent == TouchContent::yes && IsInlineNode(node) &&
HTMLEditorRef().IsContainer(node) && !EditorBase::IsTextNode(node)) {
nsTArray> arrayOfInlines;
@@ -6978,15 +7765,14 @@
nsresult
HTMLEditRules::GetParagraphFormatNodes(
- nsTArray>& outArrayOfNodes,
- TouchContent aTouchContent)
+ nsTArray>& outArrayOfNodes)
{
MOZ_ASSERT(IsEditorDataAvailable());
// Contruct a list of nodes to act on.
nsresult rv =
GetNodesFromSelection(EditAction::makeBasicBlock,
- outArrayOfNodes, aTouchContent);
+ outArrayOfNodes, TouchContent::no);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -7016,14 +7802,15 @@
}
nsresult
-HTMLEditRules::BustUpInlinesAtRangeEndpoints(RangeItem& item)
+HTMLEditRules::BustUpInlinesAtRangeEndpoints(RangeItem& aRangeItem)
{
MOZ_ASSERT(IsEditorDataAvailable());
- bool isCollapsed = item.mStartContainer == item.mEndContainer &&
- item.mStartOffset == item.mEndOffset;
+ bool isCollapsed = aRangeItem.mStartContainer == aRangeItem.mEndContainer &&
+ aRangeItem.mStartOffset == aRangeItem.mEndOffset;
- nsCOMPtr endInline = GetHighestInlineParent(*item.mEndContainer);
+ nsCOMPtr endInline =
+ GetHighestInlineParent(*aRangeItem.mEndContainer);
// XXX Oh, then, if the range is collapsed, we don't need to call
// GetHighestInlineParent(), isn't it?
@@ -7031,32 +7818,42 @@
SplitNodeResult splitEndInlineResult =
HTMLEditorRef().SplitNodeDeepWithTransaction(
*endInline,
- EditorRawDOMPoint(item.mEndContainer, item.mEndOffset),
+ EditorRawDOMPoint(aRangeItem.mEndContainer,
+ aRangeItem.mEndOffset),
SplitAtEdges::eDoNotCreateEmptyContainer);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(splitEndInlineResult.Failed())) {
return splitEndInlineResult.Rv();
}
EditorRawDOMPoint splitPointAtEnd(splitEndInlineResult.SplitPoint());
- item.mEndContainer = splitPointAtEnd.GetContainer();
- item.mEndOffset = splitPointAtEnd.Offset();
+ aRangeItem.mEndContainer = splitPointAtEnd.GetContainer();
+ aRangeItem.mEndOffset = splitPointAtEnd.Offset();
}
nsCOMPtr startInline =
- GetHighestInlineParent(*item.mStartContainer);
+ GetHighestInlineParent(*aRangeItem.mStartContainer);
if (startInline) {
SplitNodeResult splitStartInlineResult =
HTMLEditorRef().SplitNodeDeepWithTransaction(
*startInline,
- EditorRawDOMPoint(item.mStartContainer,
- item.mStartOffset),
+ EditorRawDOMPoint(aRangeItem.mStartContainer,
+ aRangeItem.mStartOffset),
SplitAtEdges::eDoNotCreateEmptyContainer);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(splitStartInlineResult.Failed())) {
return splitStartInlineResult.Rv();
}
+ // XXX If we split only here because of collapsed range, we're modifying
+ // only start point of aRangeItem. Shouldn't we modify end point here
+ // if it's collapsed?
EditorRawDOMPoint splitPointAtStart(splitStartInlineResult.SplitPoint());
- item.mStartContainer = splitPointAtStart.GetContainer();
- item.mStartOffset = splitPointAtStart.Offset();
+ aRangeItem.mStartContainer = splitPointAtStart.GetContainer();
+ aRangeItem.mStartOffset = splitPointAtStart.Offset();
}
return NS_OK;
@@ -7092,6 +7889,9 @@
HTMLEditorRef().SplitNodeDeepWithTransaction(
*nextNode, atBrNode,
SplitAtEdges::eAllowToCreateEmptyContainer);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
@@ -7108,6 +7908,9 @@
EditorRawDOMPoint atNextNode(splitNodeResult.GetNextNode());
nsresult rv =
HTMLEditorRef().MoveNodeWithTransaction(*brNode->AsContent(), atNextNode);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -7159,10 +7962,6 @@
return content;
}
-/**
- * GetNodesFromPoint() constructs a list of nodes from a point that will be
- * operated on.
- */
nsresult
HTMLEditRules::GetNodesFromPoint(
const EditorDOMPoint& aPoint,
@@ -7174,11 +7973,11 @@
return NS_ERROR_INVALID_ARG;
}
RefPtr range = new nsRange(aPoint.GetContainer());
- ErrorResult error;
- range->SetStart(aPoint, error);
+ IgnoredErrorResult ignoredError;
+ range->SetStart(aPoint, ignoredError);
// error will assert on failure, because we are not cleaning it up,
// but we're asserting in that case anyway.
- MOZ_ASSERT(!error.Failed());
+ MOZ_ASSERT(!ignoredError.Failed());
// Expand the range to include adjacent inlines
PromoteRange(*range, aOperation);
@@ -7190,20 +7989,16 @@
arrayOfRanges.AppendElement(range);
// Use these ranges to contruct a list of nodes to act on
- nsresult rv2 =
+ nsresult rv =
GetNodesForOperation(arrayOfRanges, outArrayOfNodes, aOperation,
aTouchContent);
- if (NS_WARN_IF(NS_FAILED(rv2))) {
- return rv2;
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
}
return NS_OK;
}
-/**
- * GetNodesFromSelection() constructs a list of nodes from the selection that
- * will be operated on.
- */
nsresult
HTMLEditRules::GetNodesFromSelection(
EditAction aOperation,
@@ -7226,10 +8021,6 @@
return NS_OK;
}
-/**
- * MakeTransitionList() detects all the transitions in the array, where a
- * transition means that adjacent nodes in the array don't have the same parent.
- */
void
HTMLEditRules::MakeTransitionList(nsTArray>& aNodeArray,
nsTArray& aTransitionArray)
@@ -7249,11 +8040,6 @@
}
}
-/**
- * If aNode is the descendant of a listitem, return that li. But table element
- * boundaries are stoppers on the search. Also stops on the active editor host
- * (contenteditable). Also test if aNode is an li itself.
- */
Element*
HTMLEditRules::IsInListItem(nsINode* aNode)
{
@@ -7284,9 +8070,6 @@
HTMLEditorRef().GetDefaultParagraphSeparator());
}
-/**
- * ReturnInHeader: do the right thing for returns pressed in headers
- */
nsresult
HTMLEditRules::ReturnInHeader(Element& aHeader,
nsINode& aNode,
@@ -7303,6 +8086,9 @@
nsresult rv = WSRunObject::PrepareToSplitAcrossBlocks(&HTMLEditorRef(),
address_of(node),
&aOffset);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -7311,11 +8097,13 @@
}
// Split the header
- ErrorResult error;
SplitNodeResult splitHeaderResult =
HTMLEditorRef().SplitNodeDeepWithTransaction(
aHeader, EditorRawDOMPoint(node, aOffset),
SplitAtEdges::eAllowToCreateEmptyContainer);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
NS_WARNING_ASSERTION(splitHeaderResult.Succeeded(),
"Failed to split aHeader");
@@ -7330,9 +8118,10 @@
return rv;
}
if (isEmptyNode) {
- RefPtr brElement = CreateMozBR(EditorRawDOMPoint(prevItem, 0));
- if (NS_WARN_IF(!brElement)) {
- return NS_ERROR_FAILURE;
+ CreateElementResult createMozBrResult =
+ CreateMozBR(EditorRawDOMPoint(prevItem, 0));
+ if (NS_WARN_IF(createMozBrResult.Failed())) {
+ return createMozBrResult.Rv();
}
}
}
@@ -7340,6 +8129,9 @@
// If the new (righthand) header node is empty, delete it
if (IsEmptyBlockElement(aHeader, IgnoreSingleBR::eYes)) {
rv = HTMLEditorRef().DeleteNodeWithTransaction(aHeader);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -7361,6 +8153,9 @@
HTMLEditorRef().CreateNodeWithTransaction(¶Atom == nsGkAtoms::br ?
*nsGkAtoms::p : paraAtom,
nextToHeader);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!pNode)) {
return NS_ERROR_FAILURE;
}
@@ -7369,6 +8164,9 @@
RefPtr brElement =
HTMLEditorRef().InsertBrElementWithTransaction(
SelectionRef(), EditorRawDOMPoint(pNode, 0));
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
@@ -7376,6 +8174,10 @@
// Set selection to before the break
ErrorResult error;
SelectionRef().Collapse(EditorRawDOMPoint(pNode, 0), error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
@@ -7387,6 +8189,10 @@
// Put selection after break
ErrorResult error;
SelectionRef().Collapse(afterSibling, error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
@@ -7395,6 +8201,10 @@
// Put selection at front of righthand heading
ErrorResult error;
SelectionRef().Collapse(RawRangeBoundary(&aHeader, 0), error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
@@ -7528,6 +8338,10 @@
nsCOMPtr newLeftDivOrP =
HTMLEditorRef().SplitNodeWithTransaction(pointToSplitParentDivOrP,
error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return EditActionResult(NS_ERROR_EDITOR_DESTROYED);
+ }
if (NS_WARN_IF(error.Failed())) {
return EditActionResult(error.StealNSResult());
}
@@ -7561,11 +8375,6 @@
}
}
if (pointToInsertBR.IsSet()) {
- // Don't modify the DOM tree if HTMLEditor is destroyed.
- if (NS_WARN_IF(HTMLEditorRef().Destroyed())) {
- return EditActionResult(NS_ERROR_NOT_AVAILABLE);
- }
-
// if CR does not create a new P, default to BR creation
if (NS_WARN_IF(!doesCRCreateNewP)) {
return EditActionResult(NS_OK);
@@ -7574,6 +8383,9 @@
brContent =
HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
pointToInsertBR);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return EditActionResult(NS_ERROR_EDITOR_DESTROYED);
+ }
NS_WARNING_ASSERTION(brContent, "Failed to create a
element");
if (splitAfterNewBR) {
// We split the parent after the br we've just inserted.
@@ -7608,6 +8420,9 @@
nsresult rv =
WSRunObject::PrepareToSplitAcrossBlocks(&HTMLEditorRef(),
address_of(selNode), &selOffset);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -7621,6 +8436,9 @@
aParentDivOrP,
EditorRawDOMPoint(selNode, selOffset),
SplitAtEdges::eAllowToCreateEmptyContainer);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(splitDivOrPResult.Failed())) {
return splitDivOrPResult.Rv();
}
@@ -7632,6 +8450,9 @@
// prevent an empty p).
if (aNextBRNode && HTMLEditorRef().IsVisibleBRElement(aNextBRNode)) {
rv = HTMLEditorRef().DeleteNodeWithTransaction(*aNextBRNode);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -7640,6 +8461,9 @@
// Remove ID attribute on the paragraph from the existing right node.
rv = HTMLEditorRef().RemoveAttributeWithTransaction(aParentDivOrP,
*nsGkAtoms::id);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -7666,21 +8490,24 @@
EditorRawDOMPoint atStartOfChild(child, 0);
IgnoredErrorResult ignoredError;
SelectionRef().Collapse(atStartOfChild, ignoredError);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
NS_WARNING_ASSERTION(!ignoredError.Failed(),
"Failed to collapse selection at the end of the child");
} else {
EditorRawDOMPoint atChild(child);
IgnoredErrorResult ignoredError;
SelectionRef().Collapse(atChild, ignoredError);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
NS_WARNING_ASSERTION(!ignoredError.Failed(),
"Failed to collapse selection at the child");
}
return NS_OK;
}
-/**
- * ReturnInListItem: do the right thing for returns pressed in list items
- */
nsresult
HTMLEditRules::ReturnInListItem(Element& aListItem,
nsINode& aNode,
@@ -7706,6 +8533,10 @@
ErrorResult error;
leftListNode =
HTMLEditorRef().SplitNodeWithTransaction(atListItem, error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
@@ -7721,17 +8552,27 @@
nsresult rv =
HTMLEditorRef().MoveNodeWithTransaction(aListItem,
atNextSiblingOfLeftList);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
ErrorResult error;
SelectionRef().Collapse(RawRangeBoundary(&aListItem, 0), error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
} else {
// Otherwise kill this item
nsresult rv = HTMLEditorRef().DeleteNodeWithTransaction(aListItem);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -7743,6 +8584,9 @@
HTMLEditorRef().CreateNodeWithTransaction(¶Atom == nsGkAtoms::br ?
*nsGkAtoms::p : paraAtom,
atNextSiblingOfLeftList);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!pNode)) {
return NS_ERROR_FAILURE;
}
@@ -7751,6 +8595,9 @@
RefPtr brElement =
HTMLEditorRef().InsertBrElementWithTransaction(
SelectionRef(), EditorRawDOMPoint(pNode, 0));
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
@@ -7758,6 +8605,10 @@
// Set selection to before the break
ErrorResult error;
SelectionRef().Collapse(EditorRawDOMPoint(pNode, 0), error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
@@ -7771,6 +8622,9 @@
nsresult rv =
WSRunObject::PrepareToSplitAcrossBlocks(&HTMLEditorRef(),
address_of(selNode), &aOffset);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -7783,6 +8637,9 @@
HTMLEditorRef().SplitNodeDeepWithTransaction(
aListItem, EditorRawDOMPoint(selNode, aOffset),
SplitAtEdges::eAllowToCreateEmptyContainer);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
NS_WARNING_ASSERTION(splitListItemResult.Succeeded(),
"Failed to split the list item");
@@ -7798,9 +8655,10 @@
return rv;
}
if (isEmptyNode) {
- RefPtr brElement = CreateMozBR(EditorRawDOMPoint(prevItem, 0));
- if (NS_WARN_IF(!brElement)) {
- return NS_ERROR_FAILURE;
+ CreateElementResult createMozBrResult =
+ CreateMozBR(EditorRawDOMPoint(prevItem, 0));
+ if (NS_WARN_IF(createMozBrResult.Failed())) {
+ return createMozBrResult.Rv();
}
} else {
rv = HTMLEditorRef().IsEmptyNode(&aListItem, &isEmptyNode, true);
@@ -7821,15 +8679,25 @@
RefPtr newListItem =
HTMLEditorRef().CreateNodeWithTransaction(*listAtom,
atNextListItem);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!newListItem)) {
return NS_ERROR_FAILURE;
}
rv = HTMLEditorRef().DeleteNodeWithTransaction(aListItem);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
ErrorResult error;
SelectionRef().Collapse(EditorRawDOMPoint(newListItem, 0), error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
@@ -7841,6 +8709,9 @@
HTMLEditorRef().CopyLastEditableChildStylesWithTransaction(
*prevItem->AsElement(), aListItem,
address_of(brElement));
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_FAILURE;
}
@@ -7851,6 +8722,10 @@
}
ErrorResult error;
SelectionRef().Collapse(atBrNode, error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
@@ -7871,6 +8746,10 @@
}
ErrorResult error;
SelectionRef().Collapse(atVisNode, error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
@@ -7878,6 +8757,9 @@
}
rv = SelectionRef().Collapse(visNode, visOffset);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -7888,15 +8770,16 @@
ErrorResult error;
SelectionRef().Collapse(EditorRawDOMPoint(&aListItem, 0), error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
return NS_OK;
}
-/**
- * MakeBlockquote() puts the list of nodes into one or more blockquotes.
- */
nsresult
HTMLEditRules::MakeBlockquote(nsTArray>& aNodeArray)
{
@@ -7906,12 +8789,14 @@
// When the user blockquotes something, they expect one blockquote. That may
// not be possible (for instance, if they have two table cells selected, you
// need two blockquotes inside the cells).
- nsCOMPtr curBlock;
+ RefPtr curBlock;
nsCOMPtr prevParent;
for (auto& curNode : aNodeArray) {
// Get the node to act on, and its location
- NS_ENSURE_STATE(curNode->IsContent());
+ if (NS_WARN_IF(!curNode->IsContent())) {
+ return NS_ERROR_FAILURE;
+ }
// If the node is a table element or list item, dive inside
if (HTMLEditUtils::IsTableElementButNotTable(curNode) ||
@@ -7922,7 +8807,9 @@
nsTArray> childArray;
GetChildNodesForOperation(*curNode, childArray);
nsresult rv = MakeBlockquote(childArray);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
// If the node has different parent than previous node, further nodes in a
@@ -7949,6 +8836,9 @@
curBlock =
HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::blockquote,
splitNodeResult.SplitPoint());
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!curBlock)) {
return NS_ERROR_FAILURE;
}
@@ -7960,6 +8850,9 @@
nsresult rv =
HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
*curBlock);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -7967,9 +8860,6 @@
return NS_OK;
}
-/**
- * RemoveBlockStyle() makes the nodes have no special block type.
- */
nsresult
HTMLEditRules::RemoveBlockStyle(nsTArray>& aNodeArray)
{
@@ -7981,13 +8871,15 @@
nsCOMPtr