author | Masayuki Nakano <masayuki@d-toybox.com> |
Mon, 03 Oct 2022 07:52:45 +0000 | |
changeset 636798 | eb8ec4af521311b93b08fb992ab818446b20f7df |
parent 636797 | 12df9b383a32e415c0940fdbdd5d27f408d831ac |
child 636799 | 5fb7c60ced1b752486b6c8ab0ce4649a6b5f670a |
push id | 170514 |
push user | masayuki@d-toybox.com |
push date | Mon, 03 Oct 2022 07:55:12 +0000 |
treeherder | autoland@eb8ec4af5213 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | m_kato |
bugs | 1792639 |
milestone | 107.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
|
--- a/editor/libeditor/HTMLEditHelpers.h +++ b/editor/libeditor/HTMLEditHelpers.h @@ -695,84 +695,84 @@ class MOZ_STACK_CLASS JoinNodesResult fi nsCOMPtr<nsIContent> mRemovedContent; nsresult mRv; }; /***************************************************************************** * SplitRangeOffFromNodeResult class is a simple class for methods which split a * node at 2 points for making part of the node split off from the node. - * TODO: Perhaps, we can make this inherits mozilla::Result for guaranteeing - * same API. Then, changing to/from Result<*, nsresult> can be easier. - * For now, we should give same API name rather than same as - * mozilla::ErrorResult. *****************************************************************************/ class MOZ_STACK_CLASS SplitRangeOffFromNodeResult final { public: - // FYI: NS_SUCCEEDED and NS_FAILED contain MOZ_(UN)LIKELY so that isOk() and - // isErr() must not required to wrap with them. - bool isOk() const { return NS_SUCCEEDED(mRv); } - bool isErr() const { return NS_FAILED(mRv); } - constexpr nsresult inspectErr() const { return mRv; } - constexpr nsresult unwrapErr() const { return inspectErr(); } - constexpr bool EditorDestroyed() const { - return MOZ_UNLIKELY(mRv == NS_ERROR_EDITOR_DESTROYED); - } - /** * GetLeftContent() returns new created node before the part of quarried out. * This may return nullptr if the method didn't split at start edge of * the node. */ MOZ_KNOWN_LIVE nsIContent* GetLeftContent() const { return mLeftContent; } template <typename ContentNodeType> MOZ_KNOWN_LIVE ContentNodeType* GetLeftContentAs() const { return ContentNodeType::FromNodeOrNull(GetLeftContent()); } + constexpr nsCOMPtr<nsIContent>&& UnwrapLeftContent() { + mMovedContent = true; + return std::move(mLeftContent); + } /** * GetMiddleContent() returns new created node between left node and right * node. I.e., this is quarried out from the node. This may return nullptr * if the method unwrapped the middle node. */ MOZ_KNOWN_LIVE nsIContent* GetMiddleContent() const { return mMiddleContent; } template <typename ContentNodeType> MOZ_KNOWN_LIVE ContentNodeType* GetMiddleContentAs() const { return ContentNodeType::FromNodeOrNull(GetMiddleContent()); } + constexpr nsCOMPtr<nsIContent>&& UnwrapMiddleContent() { + mMovedContent = true; + return std::move(mMiddleContent); + } /** * GetRightContent() returns the right node after the part of quarried out. * This may return nullptr it the method didn't split at end edge of the * node. */ MOZ_KNOWN_LIVE nsIContent* GetRightContent() const { return mRightContent; } template <typename ContentNodeType> MOZ_KNOWN_LIVE ContentNodeType* GetRightContentAs() const { return ContentNodeType::FromNodeOrNull(GetRightContent()); } + constexpr nsCOMPtr<nsIContent>&& UnwrapRightContent() { + mMovedContent = true; + return std::move(mRightContent); + } /** * GetLeftmostContent() returns the leftmost content after trying to * split twice. If the node was not split, this returns the original node. */ MOZ_KNOWN_LIVE nsIContent* GetLeftmostContent() const { + MOZ_ASSERT(!mMovedContent); return mLeftContent ? mLeftContent : (mMiddleContent ? mMiddleContent : mRightContent); } template <typename ContentNodeType> MOZ_KNOWN_LIVE ContentNodeType* GetLeftmostContentAs() const { return ContentNodeType::FromNodeOrNull(GetLeftmostContent()); } /** * GetRightmostContent() returns the rightmost content after trying to * split twice. If the node was not split, this returns the original node. */ MOZ_KNOWN_LIVE nsIContent* GetRightmostContent() const { + MOZ_ASSERT(!mMovedContent); return mRightContent ? mRightContent : (mMiddleContent ? mMiddleContent : mLeftContent); } template <typename ContentNodeType> MOZ_KNOWN_LIVE ContentNodeType* GetRightmostContentAs() const { return ContentNodeType::FromNodeOrNull(GetRightmostContent()); } @@ -811,59 +811,58 @@ class MOZ_STACK_CLASS SplitRangeOffFromN SplitRangeOffFromNodeResult() = delete; SplitRangeOffFromNodeResult(nsIContent* aLeftContent, nsIContent* aMiddleContent, nsIContent* aRightContent) : mLeftContent(aLeftContent), mMiddleContent(aMiddleContent), - mRightContent(aRightContent), - mRv(NS_OK) {} + mRightContent(aRightContent) {} SplitRangeOffFromNodeResult(nsIContent* aLeftContent, nsIContent* aMiddleContent, nsIContent* aRightContent, EditorDOMPoint&& aPointToPutCaret) : mLeftContent(aLeftContent), mMiddleContent(aMiddleContent), mRightContent(aRightContent), - mCaretPoint(std::move(aPointToPutCaret)), - mRv(NS_OK) {} - - explicit SplitRangeOffFromNodeResult(nsresult aRv) : mRv(aRv) { - MOZ_DIAGNOSTIC_ASSERT(NS_FAILED(mRv)); - } + mCaretPoint(std::move(aPointToPutCaret)) {} SplitRangeOffFromNodeResult(const SplitRangeOffFromNodeResult& aOther) = delete; SplitRangeOffFromNodeResult& operator=( const SplitRangeOffFromNodeResult& aOther) = delete; - SplitRangeOffFromNodeResult(SplitRangeOffFromNodeResult&& aOther) = default; + SplitRangeOffFromNodeResult(SplitRangeOffFromNodeResult&& aOther) noexcept + : mLeftContent(std::move(aOther.mLeftContent)), + mMiddleContent(std::move(aOther.mMiddleContent)), + mRightContent(std::move(aOther.mRightContent)), + mCaretPoint(std::move(aOther.mCaretPoint)) { + MOZ_ASSERT(!aOther.mMovedContent); + } SplitRangeOffFromNodeResult& operator=(SplitRangeOffFromNodeResult&& aOther) = - default; + delete; // due to bug 1792638 #ifdef DEBUG ~SplitRangeOffFromNodeResult() { - MOZ_ASSERT_IF(isOk(), !mCaretPoint.IsSet() || mHandledCaretPoint); + MOZ_ASSERT(!mCaretPoint.IsSet() || mHandledCaretPoint); } #endif private: MOZ_KNOWN_LIVE nsCOMPtr<nsIContent> mLeftContent; MOZ_KNOWN_LIVE nsCOMPtr<nsIContent> mMiddleContent; MOZ_KNOWN_LIVE nsCOMPtr<nsIContent> mRightContent; // The point which is a good point to put caret from point of view the // splitter. EditorDOMPoint mCaretPoint; - nsresult mRv; - bool mutable mHandledCaretPoint = false; + bool mutable mMovedContent = false; }; /***************************************************************************** * SplitRangeOffResult class is a simple class for methods which splits * specific ancestor elements at 2 DOM points. *****************************************************************************/ class MOZ_STACK_CLASS SplitRangeOffResult final { public:
--- a/editor/libeditor/HTMLEditSubActionHandler.cpp +++ b/editor/libeditor/HTMLEditSubActionHandler.cpp @@ -17,16 +17,17 @@ #include "HTMLEditHelpers.h" #include "HTMLEditUtils.h" #include "PendingStyles.h" // for SpecifiedStyle #include "WSRunObject.h" #include "mozilla/Assertions.h" #include "mozilla/CheckedInt.h" #include "mozilla/ContentIterator.h" +#include "mozilla/HTMLEditHelpers.h" #include "mozilla/IntegerRange.h" #include "mozilla/InternalMutationEvent.h" #include "mozilla/MathAlgorithms.h" #include "mozilla/Maybe.h" #include "mozilla/OwningNonNull.h" #include "mozilla/Preferences.h" #include "mozilla/RangeUtils.h" #include "mozilla/StaticPrefs_editor.h" // for StaticPrefs::editor_* @@ -5198,94 +5199,103 @@ Result<EditActionResult, nsresult> HTMLE NS_WARNING("Selection::SetBaseAndExtentInLimiter() failed"); return Err(error.StealNSResult()); } } // HandleOutdentAtSelectionInternal() creates AutoSelectionRestorer. // Therefore, even if it returns NS_OK, the editor might have been destroyed // at restoring Selection. - SplitRangeOffFromNodeResult outdentResult = + Result<SplitRangeOffFromNodeResult, nsresult> outdentResult = HandleOutdentAtSelectionInternal(aEditingHost); if (NS_WARN_IF(Destroyed())) { + if (outdentResult.isOk()) { + outdentResult.inspect().IgnoreCaretPointSuggestion(); + } return Err(NS_ERROR_EDITOR_DESTROYED); } - if (outdentResult.isErr()) { + if (MOZ_UNLIKELY(outdentResult.isErr())) { NS_WARNING("HTMLEditor::HandleOutdentAtSelectionInternal() failed"); - return Err(outdentResult.unwrapErr()); - } + return outdentResult.propagateErr(); + } + SplitRangeOffFromNodeResult unwrappedOutdentResult = outdentResult.unwrap(); // Make sure selection didn't stick to last piece of content in old bq (only // a problem for collapsed selections) - if (!outdentResult.GetLeftContent() && !outdentResult.GetRightContent()) { + if (!unwrappedOutdentResult.GetLeftContent() && + !unwrappedOutdentResult.GetRightContent()) { return EditActionResult::HandledResult(); } if (!SelectionRef().IsCollapsed()) { return EditActionResult::HandledResult(); } // Push selection past end of left element of last split indented element. - if (outdentResult.GetLeftContent()) { + if (unwrappedOutdentResult.GetLeftContent()) { const nsRange* firstRange = SelectionRef().GetRangeAt(0); if (NS_WARN_IF(!firstRange)) { return EditActionResult::HandledResult(); } const RangeBoundary& atStartOfSelection = firstRange->StartRef(); if (NS_WARN_IF(!atStartOfSelection.IsSet())) { return Err(NS_ERROR_FAILURE); } - if (atStartOfSelection.Container() == outdentResult.GetLeftContent() || + if (atStartOfSelection.Container() == + unwrappedOutdentResult.GetLeftContent() || EditorUtils::IsDescendantOf(*atStartOfSelection.Container(), - *outdentResult.GetLeftContent())) { + *unwrappedOutdentResult.GetLeftContent())) { // Selection is inside the left node - push it past it. EditorRawDOMPoint afterRememberedLeftBQ( - EditorRawDOMPoint::After(*outdentResult.GetLeftContent())); + EditorRawDOMPoint::After(*unwrappedOutdentResult.GetLeftContent())); NS_WARNING_ASSERTION( afterRememberedLeftBQ.IsSet(), "Failed to set after remembered left blockquote element"); nsresult rv = CollapseSelectionTo(afterRememberedLeftBQ); if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) { return Err(NS_ERROR_EDITOR_DESTROYED); } NS_WARNING_ASSERTION( NS_SUCCEEDED(rv), "EditorBase::CollapseSelectionTo() failed, but ignored"); } } // And pull selection before beginning of right element of last split // indented element. - if (outdentResult.GetRightContent()) { + if (unwrappedOutdentResult.GetRightContent()) { const nsRange* firstRange = SelectionRef().GetRangeAt(0); if (NS_WARN_IF(!firstRange)) { return EditActionResult::HandledResult(); } const RangeBoundary& atStartOfSelection = firstRange->StartRef(); if (NS_WARN_IF(!atStartOfSelection.IsSet())) { return Err(NS_ERROR_FAILURE); } - if (atStartOfSelection.Container() == outdentResult.GetRightContent() || - EditorUtils::IsDescendantOf(*atStartOfSelection.Container(), - *outdentResult.GetRightContent())) { + if (atStartOfSelection.Container() == + unwrappedOutdentResult.GetRightContent() || + EditorUtils::IsDescendantOf( + *atStartOfSelection.Container(), + *unwrappedOutdentResult.GetRightContent())) { // Selection is inside the right element - push it before it. - EditorRawDOMPoint atRememberedRightBQ(outdentResult.GetRightContent()); + EditorRawDOMPoint atRememberedRightBQ( + unwrappedOutdentResult.GetRightContent()); nsresult rv = CollapseSelectionTo(atRememberedRightBQ); if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) { return Err(NS_ERROR_EDITOR_DESTROYED); } NS_WARNING_ASSERTION( NS_SUCCEEDED(rv), "EditorBase::CollapseSelectionTo() failed, but ignored"); } } return EditActionResult::HandledResult(); } -SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal( - const Element& aEditingHost) { +Result<SplitRangeOffFromNodeResult, nsresult> +HTMLEditor::HandleOutdentAtSelectionInternal(const Element& aEditingHost) { MOZ_ASSERT(IsEditActionDataAvailable()); AutoSelectionRestorer restoreSelectionLater(*this); bool useCSS = IsCSSEnabled(); // Convert the selection ranges into "promoted" selection ranges: this // basically just expands the range to include the immediate block parent, @@ -5298,33 +5308,33 @@ SplitRangeOffFromNodeResult HTMLEditor:: EditSubAction::eOutdent, aEditingHost); nsresult rv = extendedSelectionRanges.CollectEditTargetNodes( *this, arrayOfContents, EditSubAction::eOutdent, AutoRangeArray::CollectNonEditableNodes::Yes); if (NS_FAILED(rv)) { NS_WARNING( "AutoRangeArray::CollectEditTargetNodes(EditSubAction::eOutdent, " "CollectNonEditableNodes::Yes) failed"); - return SplitRangeOffFromNodeResult(rv); - } - const Result<EditorDOMPoint, nsresult> splitAtBRElementsResult = + return Err(rv); + } + Result<EditorDOMPoint, nsresult> splitAtBRElementsResult = MaybeSplitElementsAtEveryBRElement(arrayOfContents, EditSubAction::eOutdent); if (MOZ_UNLIKELY(splitAtBRElementsResult.isErr())) { NS_WARNING( "HTMLEditor::MaybeSplitElementsAtEveryBRElement(EditSubAction::" "eOutdent) failed"); - return SplitRangeOffFromNodeResult(splitAtBRElementsResult.inspectErr()); + return splitAtBRElementsResult.propagateErr(); } if (AllowsTransactionsToChangeSelection() && splitAtBRElementsResult.inspect().IsSet()) { nsresult rv = CollapseSelectionTo(splitAtBRElementsResult.inspect()); if (NS_FAILED(rv)) { NS_WARNING("EditorBase::CollapseSelectionTo() failed"); - return SplitRangeOffFromNodeResult(rv); + return Err(rv); } } } nsCOMPtr<nsIContent> leftContentOfLastOutdented; nsCOMPtr<nsIContent> middleContentOfLastOutdented; nsCOMPtr<nsIContent> rightContentOfLastOutdented; RefPtr<Element> indentedParentElement; @@ -5339,154 +5349,170 @@ SplitRangeOffFromNodeResult HTMLEditor:: // If it's a `<blockquote>`, remove it to outdent its children. if (content->IsHTMLElement(nsGkAtoms::blockquote)) { // If we've already found an ancestor block element indented, we need to // split it and remove the block element first. if (indentedParentElement) { NS_WARNING_ASSERTION(indentedParentElement == content, "Indented parent element is not the <blockquote>"); - SplitRangeOffFromNodeResult outdentResult = OutdentPartOfBlock( - *indentedParentElement, *firstContentToBeOutdented, - *lastContentToBeOutdented, indentedParentIndentedWith, - aEditingHost); - if (outdentResult.isErr()) { + Result<SplitRangeOffFromNodeResult, nsresult> outdentResult = + OutdentPartOfBlock(*indentedParentElement, + *firstContentToBeOutdented, + *lastContentToBeOutdented, + indentedParentIndentedWith, aEditingHost); + if (MOZ_UNLIKELY(outdentResult.isErr())) { NS_WARNING("HTMLEditor::OutdentPartOfBlock() failed"); return outdentResult; } - leftContentOfLastOutdented = outdentResult.GetLeftContent(); - middleContentOfLastOutdented = outdentResult.GetMiddleContent(); - rightContentOfLastOutdented = outdentResult.GetRightContent(); + SplitRangeOffFromNodeResult unwrappedOutdentResult = + outdentResult.unwrap(); + unwrappedOutdentResult.IgnoreCaretPointSuggestion(); + leftContentOfLastOutdented = unwrappedOutdentResult.UnwrapLeftContent(); + middleContentOfLastOutdented = + unwrappedOutdentResult.UnwrapMiddleContent(); + rightContentOfLastOutdented = + unwrappedOutdentResult.UnwrapRightContent(); indentedParentElement = nullptr; firstContentToBeOutdented = nullptr; lastContentToBeOutdented = nullptr; indentedParentIndentedWith = BlockIndentedWith::HTML; } - const Result<EditorDOMPoint, nsresult> unwrapBlockquoteElementResult = + Result<EditorDOMPoint, nsresult> unwrapBlockquoteElementResult = RemoveBlockContainerWithTransaction( MOZ_KnownLive(*content->AsElement())); if (MOZ_UNLIKELY(unwrapBlockquoteElementResult.isErr())) { NS_WARNING("HTMLEditor::RemoveBlockContainerWithTransaction() failed"); - return SplitRangeOffFromNodeResult( - unwrapBlockquoteElementResult.inspectErr()); + return unwrapBlockquoteElementResult.propagateErr(); } const EditorDOMPoint& pointToPutCaret = unwrapBlockquoteElementResult.inspect(); if (AllowsTransactionsToChangeSelection() && pointToPutCaret.IsSet()) { nsresult rv = CollapseSelectionTo(pointToPutCaret); if (NS_FAILED(rv)) { NS_WARNING("EditorBase::CollapseSelectionTo() failed"); - return SplitRangeOffFromNodeResult(rv); + return Err(rv); } } continue; } // If we're using CSS and the node is a block element, check its start // margin whether it's indented with CSS. if (useCSS && HTMLEditUtils::IsBlockElement(content)) { nsStaticAtom& marginProperty = MarginPropertyAtomForIndent(MOZ_KnownLive(content)); if (NS_WARN_IF(Destroyed())) { - return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); + return Err(NS_ERROR_EDITOR_DESTROYED); } nsAutoString value; DebugOnly<nsresult> rvIgnored = CSSEditUtils::GetSpecifiedProperty(content, marginProperty, value); if (NS_WARN_IF(Destroyed())) { - return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); + return Err(NS_ERROR_EDITOR_DESTROYED); } NS_WARNING_ASSERTION( NS_SUCCEEDED(rvIgnored), "CSSEditUtils::GetSpecifiedProperty() failed, but ignored"); float startMargin = 0; RefPtr<nsAtom> unit; CSSEditUtils::ParseLength(value, &startMargin, getter_AddRefs(unit)); // If indented with CSS, we should decrease the start margin. if (startMargin > 0) { const Result<EditorDOMPoint, nsresult> pointToPutCaretOrError = ChangeMarginStart(MOZ_KnownLive(*content->AsElement()), ChangeMargin::Decrease, aEditingHost); if (MOZ_UNLIKELY(pointToPutCaretOrError.isErr())) { if (NS_WARN_IF(pointToPutCaretOrError.inspectErr() == NS_ERROR_EDITOR_DESTROYED)) { - return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); + return Err(NS_ERROR_EDITOR_DESTROYED); } NS_WARNING( "HTMLEditor::ChangeMarginStart(ChangeMargin::Decrease) failed, " "but ignored"); } else if (AllowsTransactionsToChangeSelection() && pointToPutCaretOrError.inspect().IsSet()) { nsresult rv = CollapseSelectionTo(pointToPutCaretOrError.inspect()); if (NS_FAILED(rv)) { NS_WARNING("EditorBase::CollapseSelectionTo() failed"); - return SplitRangeOffFromNodeResult(rv); + return Err(rv); } } continue; } } // If it's a list item, we should treat as that it "indents" its children. if (HTMLEditUtils::IsListItem(content)) { // If it is a list item, that means we are not outdenting whole list. // XXX I don't understand this sentence... We may meet parent list // element, no? if (indentedParentElement) { - SplitRangeOffFromNodeResult outdentResult = OutdentPartOfBlock( - *indentedParentElement, *firstContentToBeOutdented, - *lastContentToBeOutdented, indentedParentIndentedWith, - aEditingHost); - if (outdentResult.isErr()) { + Result<SplitRangeOffFromNodeResult, nsresult> outdentResult = + OutdentPartOfBlock(*indentedParentElement, + *firstContentToBeOutdented, + *lastContentToBeOutdented, + indentedParentIndentedWith, aEditingHost); + if (MOZ_UNLIKELY(outdentResult.isErr())) { NS_WARNING("HTMLEditor::OutdentPartOfBlock() failed"); return outdentResult; } - leftContentOfLastOutdented = outdentResult.GetLeftContent(); - middleContentOfLastOutdented = outdentResult.GetMiddleContent(); - rightContentOfLastOutdented = outdentResult.GetRightContent(); + SplitRangeOffFromNodeResult unwrappedOutdentResult = + outdentResult.unwrap(); + unwrappedOutdentResult.IgnoreCaretPointSuggestion(); + leftContentOfLastOutdented = unwrappedOutdentResult.UnwrapLeftContent(); + middleContentOfLastOutdented = + unwrappedOutdentResult.UnwrapMiddleContent(); + rightContentOfLastOutdented = + unwrappedOutdentResult.UnwrapRightContent(); indentedParentElement = nullptr; firstContentToBeOutdented = nullptr; lastContentToBeOutdented = nullptr; indentedParentIndentedWith = BlockIndentedWith::HTML; } // XXX `content` could become different element since // `OutdentPartOfBlock()` may run mutation event listeners. nsresult rv = LiftUpListItemElement(MOZ_KnownLive(*content->AsElement()), LiftUpFromAllParentListElements::No); if (NS_FAILED(rv)) { NS_WARNING( "HTMLEditor::LiftUpListItemElement(LiftUpFromAllParentListElements:" ":No) failed"); - return SplitRangeOffFromNodeResult(rv); + return Err(rv); } continue; } // If we've found an ancestor block element which indents its children // and the current node is NOT a descendant of it, we should remove it to // outdent its children. Otherwise, i.e., current node is a descendant of // it, we meet new node which should be outdented when the indented parent // is removed. if (indentedParentElement) { if (EditorUtils::IsDescendantOf(*content, *indentedParentElement)) { // Extend the range to be outdented at removing the // indentedParentElement. lastContentToBeOutdented = content; continue; } - SplitRangeOffFromNodeResult outdentResult = OutdentPartOfBlock( - *indentedParentElement, *firstContentToBeOutdented, - *lastContentToBeOutdented, indentedParentIndentedWith, aEditingHost); - if (outdentResult.isErr()) { + Result<SplitRangeOffFromNodeResult, nsresult> outdentResult = + OutdentPartOfBlock(*indentedParentElement, *firstContentToBeOutdented, + *lastContentToBeOutdented, + indentedParentIndentedWith, aEditingHost); + if (MOZ_UNLIKELY(outdentResult.isErr())) { NS_WARNING("HTMLEditor::OutdentPartOfBlock() failed"); return outdentResult; } - leftContentOfLastOutdented = outdentResult.GetLeftContent(); - middleContentOfLastOutdented = outdentResult.GetMiddleContent(); - rightContentOfLastOutdented = outdentResult.GetRightContent(); + SplitRangeOffFromNodeResult unwrappedOutdentResult = + outdentResult.unwrap(); + unwrappedOutdentResult.IgnoreCaretPointSuggestion(); + leftContentOfLastOutdented = unwrappedOutdentResult.UnwrapLeftContent(); + middleContentOfLastOutdented = + unwrappedOutdentResult.UnwrapMiddleContent(); + rightContentOfLastOutdented = unwrappedOutdentResult.UnwrapRightContent(); indentedParentElement = nullptr; firstContentToBeOutdented = nullptr; lastContentToBeOutdented = nullptr; // curBlockIndentedWith = HTMLEditor::BlockIndentedWith::HTML; // Then, we need to look for next indentedParentElement. } @@ -5509,26 +5535,26 @@ SplitRangeOffFromNodeResult HTMLEditor:: if (!useCSS) { continue; } nsCOMPtr<nsINode> grandParentNode = parentContent->GetParentNode(); nsStaticAtom& marginProperty = MarginPropertyAtomForIndent(MOZ_KnownLive(content)); if (NS_WARN_IF(Destroyed())) { - return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); + return Err(NS_ERROR_EDITOR_DESTROYED); } if (NS_WARN_IF(grandParentNode != parentContent->GetParentNode())) { - return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE); + return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE); } nsAutoString value; DebugOnly<nsresult> rvIgnored = CSSEditUtils::GetSpecifiedProperty( *parentContent, marginProperty, value); if (NS_WARN_IF(Destroyed())) { - return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); + return Err(NS_ERROR_EDITOR_DESTROYED); } NS_WARNING_ASSERTION( NS_SUCCEEDED(rvIgnored), "CSSEditUtils::GetSpecifiedProperty() failed, but ignored"); // XXX Now, editing host may become different element. If so, shouldn't // we stop this handling? float startMargin; RefPtr<nsAtom> unit; @@ -5556,33 +5582,32 @@ SplitRangeOffFromNodeResult HTMLEditor:: // XXX This is buggy. When both lists' item types are different, // we create invalid tree. E.g., `<ul>` may have `<dd>` as its // list item element. if (HTMLEditUtils::IsAnyListElement(atContent.GetContainer())) { if (!HTMLEditUtils::IsAnyListElement(content)) { continue; } // Just unwrap this sublist - const Result<EditorDOMPoint, nsresult> unwrapSubListElementResult = + Result<EditorDOMPoint, nsresult> unwrapSubListElementResult = RemoveBlockContainerWithTransaction( MOZ_KnownLive(*content->AsElement())); if (MOZ_UNLIKELY(unwrapSubListElementResult.isErr())) { NS_WARNING("HTMLEditor::RemoveBlockContainerWithTransaction() failed"); - return SplitRangeOffFromNodeResult( - unwrapSubListElementResult.inspectErr()); + return unwrapSubListElementResult.propagateErr(); } const EditorDOMPoint& pointToPutCaret = unwrapSubListElementResult.inspect(); if (!AllowsTransactionsToChangeSelection() || !pointToPutCaret.IsSet()) { continue; } nsresult rv = CollapseSelectionTo(pointToPutCaret); if (NS_FAILED(rv)) { NS_WARNING("EditorBase::CollapseSelectionTo() failed"); - return SplitRangeOffFromNodeResult(rv); + return Err(rv); } continue; } // If current content is a list element but its parent is not a list // element, move children to where it is and remove it from the tree. if (HTMLEditUtils::IsAnyListElement(content)) { // XXX If mutation event listener appends new children forever, this @@ -5593,186 +5618,190 @@ SplitRangeOffFromNodeResult HTMLEditor:: if (HTMLEditUtils::IsListItem(lastChildContent)) { nsresult rv = LiftUpListItemElement( MOZ_KnownLive(*lastChildContent->AsElement()), LiftUpFromAllParentListElements::No); if (NS_FAILED(rv)) { NS_WARNING( "HTMLEditor::LiftUpListItemElement(" "LiftUpFromAllParentListElements::No) failed"); - return SplitRangeOffFromNodeResult(rv); + return Err(rv); } continue; } if (HTMLEditUtils::IsAnyListElement(lastChildContent)) { // We have an embedded list, so move it out from under the parent // list. Be sure to put it after the parent list because this // loop iterates backwards through the parent's list of children. EditorDOMPoint afterCurrentList(EditorDOMPoint::After(atContent)); NS_WARNING_ASSERTION( afterCurrentList.IsSet(), "Failed to set it to after current list element"); Result<MoveNodeResult, nsresult> moveListElementResult = MoveNodeWithTransaction(*lastChildContent, afterCurrentList); if (MOZ_UNLIKELY(moveListElementResult.isErr())) { NS_WARNING("HTMLEditor::MoveNodeWithTransaction() failed"); - return SplitRangeOffFromNodeResult( - moveListElementResult.unwrapErr()); + return moveListElementResult.propagateErr(); } nsresult rv = moveListElementResult.inspect().SuggestCaretPointTo( *this, {SuggestCaret::OnlyIfHasSuggestion, SuggestCaret::OnlyIfTransactionsAllowedToDoIt, SuggestCaret::AndIgnoreTrivialError}); if (NS_FAILED(rv)) { NS_WARNING("MoveNodeResult::SuggestCaretPointTo() failed"); - return SplitRangeOffFromNodeResult(rv); + return Err(rv); } NS_WARNING_ASSERTION( rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR, "MoveNodeResult::SuggestCaretPointTo() failed, but ignored"); continue; } // Delete any non-list items for now // XXX Chrome moves it from the list element. We should follow it. nsresult rv = DeleteNodeWithTransaction(*lastChildContent); if (NS_FAILED(rv)) { NS_WARNING("EditorBase::DeleteNodeWithTransaction() failed"); - return SplitRangeOffFromNodeResult(rv); + return Err(rv); } } // Delete the now-empty list - const Result<EditorDOMPoint, nsresult> unwrapListElementResult = + Result<EditorDOMPoint, nsresult> unwrapListElementResult = RemoveBlockContainerWithTransaction( MOZ_KnownLive(*content->AsElement())); if (MOZ_UNLIKELY(unwrapListElementResult.isErr())) { NS_WARNING("HTMLEditor::RemoveBlockContainerWithTransaction() failed"); - return SplitRangeOffFromNodeResult( - unwrapListElementResult.inspectErr()); + return unwrapListElementResult.propagateErr(); } const EditorDOMPoint& pointToPutCaret = unwrapListElementResult.inspect(); if (!AllowsTransactionsToChangeSelection() || !pointToPutCaret.IsSet()) { continue; } nsresult rv = CollapseSelectionTo(pointToPutCaret); if (NS_FAILED(rv)) { NS_WARNING("EditorBase::CollapseSelectionTo() failed"); - return SplitRangeOffFromNodeResult(rv); + return Err(rv); } continue; } if (useCSS) { if (RefPtr<Element> element = content->GetAsElementOrParentElement()) { const Result<EditorDOMPoint, nsresult> pointToPutCaretOrError = ChangeMarginStart(*element, ChangeMargin::Decrease, aEditingHost); if (MOZ_UNLIKELY(pointToPutCaretOrError.isErr())) { if (NS_WARN_IF(pointToPutCaretOrError.inspectErr() == NS_ERROR_EDITOR_DESTROYED)) { - return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); + return Err(NS_ERROR_EDITOR_DESTROYED); } NS_WARNING( "HTMLEditor::ChangeMarginStart(ChangeMargin::Decrease) failed, " "but ignored"); } else if (AllowsTransactionsToChangeSelection() && pointToPutCaretOrError.inspect().IsSet()) { nsresult rv = CollapseSelectionTo(pointToPutCaretOrError.inspect()); if (NS_FAILED(rv)) { NS_WARNING("EditorBase::CollapseSelectionTo() failed"); - return SplitRangeOffFromNodeResult(rv); + return Err(rv); } } } continue; } } if (!indentedParentElement) { return SplitRangeOffFromNodeResult(leftContentOfLastOutdented, middleContentOfLastOutdented, rightContentOfLastOutdented); } // We have a <blockquote> we haven't finished handling. - SplitRangeOffFromNodeResult outdentResult = OutdentPartOfBlock( - *indentedParentElement, *firstContentToBeOutdented, - *lastContentToBeOutdented, indentedParentIndentedWith, aEditingHost); + Result<SplitRangeOffFromNodeResult, nsresult> outdentResult = + OutdentPartOfBlock(*indentedParentElement, *firstContentToBeOutdented, + *lastContentToBeOutdented, indentedParentIndentedWith, + aEditingHost); NS_WARNING_ASSERTION(outdentResult.isOk(), "HTMLEditor::OutdentPartOfBlock() failed"); return outdentResult; } -SplitRangeOffFromNodeResult +Result<SplitRangeOffFromNodeResult, nsresult> HTMLEditor::RemoveBlockContainerElementWithTransactionBetween( Element& aBlockContainerElement, nsIContent& aStartOfRange, nsIContent& aEndOfRange) { MOZ_ASSERT(IsEditActionDataAvailable()); EditorDOMPoint pointToPutCaret; - SplitRangeOffFromNodeResult splitResult = SplitRangeOffFromBlock( - aBlockContainerElement, aStartOfRange, aEndOfRange); - if (splitResult.EditorDestroyed()) { - NS_WARNING("HTMLEditor::SplitRangeOffFromBlock() failed"); - return splitResult; - } - if (splitResult.isOk()) { - splitResult.MoveCaretPointTo(pointToPutCaret, - {SuggestCaret::OnlyIfHasSuggestion}); - } else { + Result<SplitRangeOffFromNodeResult, nsresult> splitResult = + SplitRangeOffFromBlock(aBlockContainerElement, aStartOfRange, + aEndOfRange); + if (MOZ_UNLIKELY(splitResult.isErr())) { + if (splitResult.inspectErr() == NS_ERROR_EDITOR_DESTROYED) { + NS_WARNING("HTMLEditor::SplitRangeOffFromBlock() failed"); + return splitResult; + } NS_WARNING( "HTMLEditor::SplitRangeOffFromBlock() failed, but might be ignored"); - } + return SplitRangeOffFromNodeResult(nullptr, nullptr, nullptr); + } + SplitRangeOffFromNodeResult unwrappedSplitResult = splitResult.unwrap(); + unwrappedSplitResult.MoveCaretPointTo(pointToPutCaret, + {SuggestCaret::OnlyIfHasSuggestion}); // Even if either split aBlockContainerElement or did not split it, we should // unwrap the right most element which is split from aBlockContainerElement // (or aBlockContainerElement itself if it was not split without errors). - if (Element* rightmostElement = - splitResult.GetRightmostContentAs<Element>()) { - MOZ_DIAGNOSTIC_ASSERT(splitResult.isOk()); - MOZ_ASSERT_IF( - GetSplitNodeDirection() == SplitNodeDirection::LeftNodeIsNewOne, - rightmostElement == &aBlockContainerElement); - // MOZ_KnownLive(rightmostElement) because it's grabbed by splitResult. + Element* rightmostElement = + unwrappedSplitResult.GetRightmostContentAs<Element>(); + MOZ_ASSERT(rightmostElement); + if (NS_WARN_IF(!rightmostElement)) { + return Err(NS_ERROR_FAILURE); + } + MOZ_ASSERT_IF(GetSplitNodeDirection() == SplitNodeDirection::LeftNodeIsNewOne, + rightmostElement == &aBlockContainerElement); + { + // MOZ_KnownLive(rightmostElement) because it's grabbed by + // unwrappedSplitResult. Result<EditorDOMPoint, nsresult> unwrapBlockElementResult = RemoveBlockContainerWithTransaction(MOZ_KnownLive(*rightmostElement)); - if (unwrapBlockElementResult.isErr()) { + if (MOZ_UNLIKELY(unwrapBlockElementResult.isErr())) { NS_WARNING("HTMLEditor::RemoveBlockContainerWithTransaction() failed"); - return SplitRangeOffFromNodeResult(unwrapBlockElementResult.inspectErr()); + return unwrapBlockElementResult.propagateErr(); } if (unwrapBlockElementResult.inspect().IsSet()) { pointToPutCaret = unwrapBlockElementResult.unwrap(); } - } else { - MOZ_DIAGNOSTIC_ASSERT(splitResult.isErr()); - } - - return SplitRangeOffFromNodeResult(splitResult.GetLeftContent(), nullptr, - splitResult.GetRightContent(), - std::move(pointToPutCaret)); + } + + return SplitRangeOffFromNodeResult( + unwrappedSplitResult.GetLeftContent(), nullptr, + unwrappedSplitResult.GetRightContent(), std::move(pointToPutCaret)); } -SplitRangeOffFromNodeResult HTMLEditor::SplitRangeOffFromBlock( - Element& aBlockElement, nsIContent& aStartOfMiddleElement, - nsIContent& aEndOfMiddleElement) { +Result<SplitRangeOffFromNodeResult, nsresult> +HTMLEditor::SplitRangeOffFromBlock(Element& aBlockElement, + nsIContent& aStartOfMiddleElement, + nsIContent& aEndOfMiddleElement) { MOZ_ASSERT(IsEditActionDataAvailable()); // aStartOfMiddleElement and aEndOfMiddleElement must be exclusive // descendants of aBlockElement. MOZ_ASSERT(EditorUtils::IsDescendantOf(aStartOfMiddleElement, aBlockElement)); MOZ_ASSERT(EditorUtils::IsDescendantOf(aEndOfMiddleElement, aBlockElement)); EditorDOMPoint pointToPutCaret; // Split at the start. SplitNodeResult splitAtStartResult = SplitNodeDeepWithTransaction( aBlockElement, EditorDOMPoint(&aStartOfMiddleElement), SplitAtEdges::eDoNotCreateEmptyContainer); if (splitAtStartResult.EditorDestroyed()) { NS_WARNING("HTMLEditor::SplitNodeDeepWithTransaction() failed (at left)"); - return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); + return Err(NS_ERROR_EDITOR_DESTROYED); } NS_WARNING_ASSERTION( splitAtStartResult.isOk(), "HTMLEditor::SplitNodeDeepWithTransaction(SplitAtEdges::" "eDoNotCreateEmptyContainer) at start of middle element failed"); splitAtStartResult.MoveCaretPointTo(pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion}); @@ -5784,17 +5813,17 @@ SplitRangeOffFromNodeResult HTMLEditor:: : &aBlockElement; // MOZ_KnownLive(rightElement) because it's grabbed by splitAtStartResult or // aBlockElement whose lifetime is guaranteed by the caller. SplitNodeResult splitAtEndResult = SplitNodeDeepWithTransaction(MOZ_KnownLive(*rightElement), atAfterEnd, SplitAtEdges::eDoNotCreateEmptyContainer); if (splitAtEndResult.EditorDestroyed()) { NS_WARNING("HTMLEditor::SplitNodeDeepWithTransaction() failed (at right)"); - return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); + return Err(NS_ERROR_EDITOR_DESTROYED); } NS_WARNING_ASSERTION( splitAtEndResult.isOk(), "HTMLEditor::SplitNodeDeepWithTransaction(SplitAtEdges::" "eDoNotCreateEmptyContainer) after end of middle element failed"); splitAtEndResult.MoveCaretPointTo(pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion}); @@ -5815,96 +5844,87 @@ SplitRangeOffFromNodeResult HTMLEditor:: return SplitRangeOffFromNodeResult( nullptr, splitAtEndResult.GetPreviousContent(), splitAtEndResult.GetNextContent(), std::move(pointToPutCaret)); } return SplitRangeOffFromNodeResult(nullptr, &aBlockElement, nullptr, std::move(pointToPutCaret)); } -SplitRangeOffFromNodeResult HTMLEditor::OutdentPartOfBlock( +Result<SplitRangeOffFromNodeResult, nsresult> HTMLEditor::OutdentPartOfBlock( Element& aBlockElement, nsIContent& aStartOfOutdent, nsIContent& aEndOfOutdent, BlockIndentedWith aBlockIndentedWith, const Element& aEditingHost) { MOZ_ASSERT(IsEditActionDataAvailable()); - SplitRangeOffFromNodeResult splitResult = + Result<SplitRangeOffFromNodeResult, nsresult> splitResult = SplitRangeOffFromBlock(aBlockElement, aStartOfOutdent, aEndOfOutdent); - if (splitResult.EditorDestroyed()) { + if (MOZ_UNLIKELY(splitResult.isErr())) { NS_WARNING("HTMLEditor::SplitRangeOffFromBlock() failed"); - return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); - } - - if (!splitResult.GetMiddleContentAs<Element>()) { + return splitResult; + } + + SplitRangeOffFromNodeResult unwrappedSplitResult = splitResult.unwrap(); + Element* middleElement = unwrappedSplitResult.GetMiddleContentAs<Element>(); + if (MOZ_UNLIKELY(!middleElement)) { NS_WARNING( "HTMLEditor::SplitRangeOffFromBlock() didn't return middle content"); - splitResult.IgnoreCaretPointSuggestion(); - return SplitRangeOffFromNodeResult(NS_ERROR_FAILURE); - } - - if (splitResult.isOk()) { - nsresult rv = splitResult.SuggestCaretPointTo( - *this, {SuggestCaret::OnlyIfHasSuggestion, - SuggestCaret::OnlyIfTransactionsAllowedToDoIt, - SuggestCaret::AndIgnoreTrivialError}); - if (NS_FAILED(rv)) { - NS_WARNING("SplitRangeOffFromNodeResult::SuggestCaretPointTo() failed"); - return SplitRangeOffFromNodeResult(rv); - } - NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), - "SplitRangeOffFromNodeResult::SuggestCaretPointTo() " - "failed, but ignored"); - } else { - NS_WARNING( - "HTMLEditor::SplitRangeOffFromBlock() failed, but might be ignored"); - } + unwrappedSplitResult.IgnoreCaretPointSuggestion(); + return Err(NS_ERROR_FAILURE); + } + + nsresult rv = unwrappedSplitResult.SuggestCaretPointTo( + *this, {SuggestCaret::OnlyIfHasSuggestion, + SuggestCaret::OnlyIfTransactionsAllowedToDoIt, + SuggestCaret::AndIgnoreTrivialError}); + if (NS_FAILED(rv)) { + NS_WARNING("SplitRangeOffFromNodeResult::SuggestCaretPointTo() failed"); + return Err(rv); + } + NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), + "SplitRangeOffFromNodeResult::SuggestCaretPointTo() " + "failed, but ignored"); if (aBlockIndentedWith == BlockIndentedWith::HTML) { - // MOZ_KnownLive: perhaps, it does not work with template methods. + // MOZ_KnownLive(middleElement) because of grabbed by unwrappedSplitResult. Result<EditorDOMPoint, nsresult> unwrapBlockElementResult = - RemoveBlockContainerWithTransaction( - MOZ_KnownLive(*splitResult.GetMiddleContentAs<Element>())); + RemoveBlockContainerWithTransaction(MOZ_KnownLive(*middleElement)); if (MOZ_UNLIKELY(unwrapBlockElementResult.isErr())) { NS_WARNING("HTMLEditor::RemoveBlockContainerWithTransaction() failed"); - return SplitRangeOffFromNodeResult(unwrapBlockElementResult.inspectErr()); + return unwrapBlockElementResult.propagateErr(); } const EditorDOMPoint& pointToPutCaret = unwrapBlockElementResult.inspect(); if (AllowsTransactionsToChangeSelection() && pointToPutCaret.IsSet()) { nsresult rv = CollapseSelectionTo(pointToPutCaret); if (NS_FAILED(rv)) { NS_WARNING("EditorBase::CollapseSelectionTo() failed"); - return SplitRangeOffFromNodeResult(rv); - } - } - return SplitRangeOffFromNodeResult(splitResult.GetLeftContent(), nullptr, - splitResult.GetRightContent()); - } - - if (!splitResult.GetMiddleContentAs<Element>()) { - return splitResult; - } - - // MOZ_KnownLive: perhaps, it does not work with template methods. - const Result<EditorDOMPoint, nsresult> pointToPutCaretOrError = - ChangeMarginStart( - MOZ_KnownLive(*splitResult.GetMiddleContentAs<Element>()), - ChangeMargin::Decrease, aEditingHost); + return Err(rv); + } + } + return SplitRangeOffFromNodeResult(unwrappedSplitResult.GetLeftContent(), + nullptr, + unwrappedSplitResult.GetRightContent()); + } + + // MOZ_KnownLive(middleElement) because of grabbed by unwrappedSplitResult. + Result<EditorDOMPoint, nsresult> pointToPutCaretOrError = ChangeMarginStart( + MOZ_KnownLive(*middleElement), ChangeMargin::Decrease, aEditingHost); if (MOZ_UNLIKELY(pointToPutCaretOrError.isErr())) { NS_WARNING("HTMLEditor::ChangeMarginStart(ChangeMargin::Decrease) failed"); - return SplitRangeOffFromNodeResult(pointToPutCaretOrError.inspectErr()); + return pointToPutCaretOrError.propagateErr(); } if (AllowsTransactionsToChangeSelection() && pointToPutCaretOrError.inspect().IsSet()) { nsresult rv = CollapseSelectionTo(pointToPutCaretOrError.inspect()); if (NS_FAILED(rv)) { NS_WARNING("EditorBase::CollapseSelectionTo() failed"); - return SplitRangeOffFromNodeResult(rv); - } - } - return splitResult; + return Err(rv); + } + } + return unwrappedSplitResult; } Result<CreateElementResult, nsresult> HTMLEditor::ChangeListElementType( Element& aListElement, nsAtom& aNewListTag, nsAtom& aNewListItemTag) { MOZ_ASSERT(IsEditActionDataAvailable()); EditorDOMPoint pointToPutCaret; @@ -8265,26 +8285,26 @@ HTMLEditor::RemoveBlockContainerElements RefPtr<Element> blockElement; nsCOMPtr<nsIContent> firstContent, lastContent; EditorDOMPoint pointToPutCaret; for (auto& content : aArrayOfContents) { // If curNode is an <address>, <p>, <hn>, or <pre>, remove it. if (HTMLEditUtils::IsFormatNode(content)) { // Process any partial progress saved if (blockElement) { - SplitRangeOffFromNodeResult unwrapBlockElementResult = + Result<SplitRangeOffFromNodeResult, nsresult> unwrapBlockElementResult = RemoveBlockContainerElementWithTransactionBetween( *blockElement, *firstContent, *lastContent); - if (unwrapBlockElementResult.isErr()) { + if (MOZ_UNLIKELY(unwrapBlockElementResult.isErr())) { NS_WARNING( "HTMLEditor::RemoveBlockContainerElementWithTransactionBetween() " "failed"); - return Err(unwrapBlockElementResult.unwrapErr()); - } - unwrapBlockElementResult.MoveCaretPointTo( + return unwrapBlockElementResult.propagateErr(); + } + unwrapBlockElementResult.unwrap().MoveCaretPointTo( pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion}); firstContent = lastContent = blockElement = nullptr; } if (!EditorUtils::IsEditableContent(content, EditorType::HTML)) { continue; } // Remove current block Result<EditorDOMPoint, nsresult> unwrapFormatBlockResult = @@ -8302,26 +8322,26 @@ HTMLEditor::RemoveBlockContainerElements // XXX How about, <th>, <thead>, <tfoot>, <dt>, <dl>? if (content->IsAnyOfHTMLElements( nsGkAtoms::table, nsGkAtoms::tr, nsGkAtoms::tbody, nsGkAtoms::td, nsGkAtoms::li, nsGkAtoms::blockquote, nsGkAtoms::div) || HTMLEditUtils::IsAnyListElement(content)) { // Process any partial progress saved if (blockElement) { - SplitRangeOffFromNodeResult unwrapBlockElementResult = + Result<SplitRangeOffFromNodeResult, nsresult> unwrapBlockElementResult = RemoveBlockContainerElementWithTransactionBetween( *blockElement, *firstContent, *lastContent); - if (unwrapBlockElementResult.isErr()) { + if (MOZ_UNLIKELY(unwrapBlockElementResult.isErr())) { NS_WARNING( "HTMLEditor::RemoveBlockContainerElementWithTransactionBetween() " "failed"); - return Err(unwrapBlockElementResult.unwrapErr()); - } - unwrapBlockElementResult.MoveCaretPointTo( + return unwrapBlockElementResult.propagateErr(); + } + unwrapBlockElementResult.unwrap().MoveCaretPointTo( pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion}); firstContent = lastContent = blockElement = nullptr; } if (!EditorUtils::IsEditableContent(content, EditorType::HTML)) { continue; } // Recursion time AutoTArray<OwningNonNull<nsIContent>, 24> childContents; @@ -8345,26 +8365,26 @@ HTMLEditor::RemoveBlockContainerElements if (EditorUtils::IsDescendantOf(*content, *blockElement)) { // Then we don't need to do anything different for this node lastContent = content; continue; } // Otherwise, we have progressed beyond end of blockElement, so let's // handle it now. We need to remove the portion of blockElement that // contains [firstContent - lastContent]. - SplitRangeOffFromNodeResult unwrapBlockElementResult = + Result<SplitRangeOffFromNodeResult, nsresult> unwrapBlockElementResult = RemoveBlockContainerElementWithTransactionBetween( *blockElement, *firstContent, *lastContent); - if (unwrapBlockElementResult.isErr()) { + if (MOZ_UNLIKELY(unwrapBlockElementResult.isErr())) { NS_WARNING( "HTMLEditor::RemoveBlockContainerElementWithTransactionBetween() " "failed"); - return Err(unwrapBlockElementResult.unwrapErr()); - } - unwrapBlockElementResult.MoveCaretPointTo( + return unwrapBlockElementResult.propagateErr(); + } + unwrapBlockElementResult.unwrap().MoveCaretPointTo( pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion}); firstContent = lastContent = blockElement = nullptr; // Fall out and handle content } blockElement = HTMLEditUtils::GetAncestorElement( content, HTMLEditUtils::ClosestEditableBlockElement); if (!blockElement || !HTMLEditUtils::IsFormatNode(blockElement) || !HTMLEditUtils::IsRemovableNode(*blockElement)) { @@ -8374,43 +8394,43 @@ HTMLEditor::RemoveBlockContainerElements firstContent = lastContent = content; } continue; } if (blockElement) { // Some node that is already sans block style. Skip over it and process // any partial progress saved. - SplitRangeOffFromNodeResult unwrapBlockElementResult = + Result<SplitRangeOffFromNodeResult, nsresult> unwrapBlockElementResult = RemoveBlockContainerElementWithTransactionBetween( *blockElement, *firstContent, *lastContent); - if (unwrapBlockElementResult.isErr()) { + if (MOZ_UNLIKELY(unwrapBlockElementResult.isErr())) { NS_WARNING( "HTMLEditor::RemoveBlockContainerElementWithTransactionBetween() " "failed"); - return Err(unwrapBlockElementResult.unwrapErr()); - } - unwrapBlockElementResult.MoveCaretPointTo( + return unwrapBlockElementResult.propagateErr(); + } + unwrapBlockElementResult.unwrap().MoveCaretPointTo( pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion}); firstContent = lastContent = blockElement = nullptr; continue; } } // Process any partial progress saved if (blockElement) { - SplitRangeOffFromNodeResult unwrapBlockElementResult = + Result<SplitRangeOffFromNodeResult, nsresult> unwrapBlockElementResult = RemoveBlockContainerElementWithTransactionBetween( *blockElement, *firstContent, *lastContent); - if (unwrapBlockElementResult.isErr()) { + if (MOZ_UNLIKELY(unwrapBlockElementResult.isErr())) { NS_WARNING( "HTMLEditor::RemoveBlockContainerElementWithTransactionBetween() " "failed"); - return Err(unwrapBlockElementResult.unwrapErr()); - } - unwrapBlockElementResult.MoveCaretPointTo( + return unwrapBlockElementResult.propagateErr(); + } + unwrapBlockElementResult.unwrap().MoveCaretPointTo( pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion}); firstContent = lastContent = blockElement = nullptr; } return pointToPutCaret; } Result<CreateElementResult, nsresult> HTMLEditor::CreateOrChangeBlockContainerElement(
--- a/editor/libeditor/HTMLEditor.h +++ b/editor/libeditor/HTMLEditor.h @@ -1377,17 +1377,17 @@ class HTMLEditor final : public EditorBa * SplitRangeOffFromBlock() splits aBlockElement at two points, before * aStartOfMiddleElement and after aEndOfMiddleElement. If they are very * start or very end of aBlockElement, this won't create empty block. * * @param aBlockElement A block element which will be split. * @param aStartOfMiddleElement Start node of middle block element. * @param aEndOfMiddleElement End node of middle block element. */ - [[nodiscard]] MOZ_CAN_RUN_SCRIPT SplitRangeOffFromNodeResult + [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<SplitRangeOffFromNodeResult, nsresult> SplitRangeOffFromBlock(Element& aBlockElement, nsIContent& aStartOfMiddleElement, nsIContent& aEndOfMiddleElement); /** * RemoveBlockContainerElementWithTransactionBetween() splits the nodes * at aStartOfRange and aEndOfRange, then, removes the middle element which * was split off from aBlockContainerElement and moves the ex-children to @@ -1402,17 +1402,17 @@ class HTMLEditor final : public EditorBa * aBlockContainerElement. * @return The left content is new created left * element of aBlockContainerElement. * The right content is split element, * i.e., must be aBlockContainerElement. * The middle content is nullptr since * removing it is the job of this method. */ - [[nodiscard]] MOZ_CAN_RUN_SCRIPT SplitRangeOffFromNodeResult + [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<SplitRangeOffFromNodeResult, nsresult> RemoveBlockContainerElementWithTransactionBetween( Element& aBlockContainerElement, nsIContent& aStartOfRange, nsIContent& aEndOfRange); /** * WrapContentsInBlockquoteElementsWithTransaction() inserts at least one * <blockquote> element and moves nodes in aArrayOfContents into new * <blockquote> elements. If aArrayOfContents includes a table related element @@ -2422,19 +2422,19 @@ class HTMLEditor final : public EditorBa * @return The left content is new created element * splitting before aStartOfOutdent. * The right content is existing element. * The middle content is outdented element * if aBlockIndentedWith is `CSS`. * Otherwise, nullptr. */ enum class BlockIndentedWith { CSS, HTML }; - [[nodiscard]] MOZ_CAN_RUN_SCRIPT SplitRangeOffFromNodeResult + [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<SplitRangeOffFromNodeResult, nsresult> OutdentPartOfBlock(Element& aBlockElement, nsIContent& aStartOfOutdent, - nsIContent& aEndOutdent, + nsIContent& aEndOfOutdent, BlockIndentedWith aBlockIndentedWith, const Element& aEditingHost); /** * HandleOutdentAtSelectionInternal() outdents contents around Selection. * This method creates AutoSelectionRestorer. Therefore, each caller * needs to check if the editor is still available even if this returns * NS_OK. @@ -2443,17 +2443,17 @@ class HTMLEditor final : public EditorBa * @param aEditingHost The editing host. * @return The left content is left content of last * outdented element. * The right content is right content of last * outdented element. * The middle content is middle content of last * outdented element. */ - [[nodiscard]] MOZ_CAN_RUN_SCRIPT SplitRangeOffFromNodeResult + [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<SplitRangeOffFromNodeResult, nsresult> HandleOutdentAtSelectionInternal(const Element& aEditingHost); /** * HandleOutdentAtSelection() outdents contents around Selection. * * @param aEditingHost The editing host. */ [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<EditActionResult, nsresult> @@ -3974,17 +3974,17 @@ class HTMLEditor final : public EditorBa * SetInlinePropertyOnTextNode() splits aData if aStartOffset and/or * aEndOffset are not start/end of aData. Then, the text node which was * contained in the range is wrapped into an element which applies the style. * * @return The result of splitting aData. Note that middle text * node may be moved in an element, so left/middle/right * nodes may not be siblings. */ - [[nodiscard]] MOZ_CAN_RUN_SCRIPT SplitRangeOffFromNodeResult + [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<SplitRangeOffFromNodeResult, nsresult> SetInlinePropertyOnTextNode(Text& aData, uint32_t aStartOffset, uint32_t aEndOffset, nsAtom& aProperty, nsAtom* aAttribute, const nsAString& aValue); nsresult PromoteInlineRange(nsRange& aRange); nsresult PromoteRangeIfStartsOrEndsInNamedAnchor(nsRange& aRange); /**
--- a/editor/libeditor/HTMLStyleEditor.cpp +++ b/editor/libeditor/HTMLStyleEditor.cpp @@ -266,30 +266,30 @@ nsresult HTMLEditor::SetInlineProperties if (NS_WARN_IF(!range.IsPositioned())) { continue; } // If range is in a text node, apply new style simply. if (range.InSameContainer() && range.StartRef().IsInTextNode()) { // MOZ_KnownLive(...ContainerAs<Text>()) because of grabbed by `range`. // MOZ_KnownLive(styleToSet.*) due to bug 1622253. - SplitRangeOffFromNodeResult wrapTextInStyledElementResult = - SetInlinePropertyOnTextNode( + Result<SplitRangeOffFromNodeResult, nsresult> + wrapTextInStyledElementResult = SetInlinePropertyOnTextNode( MOZ_KnownLive(*range.StartRef().ContainerAs<Text>()), range.StartRef().Offset(), range.EndRef().Offset(), MOZ_KnownLive(styleToSet.HTMLPropertyRef()), MOZ_KnownLive(styleToSet.mAttribute), styleToSet.mAttributeValue); - if (wrapTextInStyledElementResult.isErr()) { + if (MOZ_UNLIKELY(wrapTextInStyledElementResult.isErr())) { NS_WARNING("HTMLEditor::SetInlinePropertyOnTextNode() failed"); return wrapTextInStyledElementResult.unwrapErr(); } // There is AutoTransactionsConserveSelection, so we don't need to // update selection here. - wrapTextInStyledElementResult.IgnoreCaretPointSuggestion(); + wrapTextInStyledElementResult.inspect().IgnoreCaretPointSuggestion(); continue; } // Collect editable nodes which are entirely contained in the range. AutoTArray<OwningNonNull<nsIContent>, 64> arrayOfContentsAroundRange; { ContentSubtreeIterator subtreeIter; // If there is no node which is entirely in the range, @@ -313,31 +313,31 @@ nsresult HTMLEditor::SetInlineProperties } // If start node is a text node, apply new style to a part of it. if (range.StartRef().IsInTextNode() && EditorUtils::IsEditableContent(*range.StartRef().ContainerAs<Text>(), EditorType::HTML)) { // MOZ_KnownLive(...ContainerAs<Text>()) because of grabbed by `range`. // MOZ_KnownLive(styleToSet.*) due to bug 1622253. - SplitRangeOffFromNodeResult wrapTextInStyledElementResult = - SetInlinePropertyOnTextNode( + Result<SplitRangeOffFromNodeResult, nsresult> + wrapTextInStyledElementResult = SetInlinePropertyOnTextNode( MOZ_KnownLive(*range.StartRef().ContainerAs<Text>()), range.StartRef().Offset(), range.StartRef().ContainerAs<Text>()->TextDataLength(), MOZ_KnownLive(styleToSet.HTMLPropertyRef()), MOZ_KnownLive(styleToSet.mAttribute), styleToSet.mAttributeValue); - if (wrapTextInStyledElementResult.isErr()) { + if (MOZ_UNLIKELY(wrapTextInStyledElementResult.isErr())) { NS_WARNING("HTMLEditor::SetInlinePropertyOnTextNode() failed"); return wrapTextInStyledElementResult.unwrapErr(); } // There is AutoTransactionsConserveSelection, so we don't need to // update selection here. - wrapTextInStyledElementResult.IgnoreCaretPointSuggestion(); + wrapTextInStyledElementResult.inspect().IgnoreCaretPointSuggestion(); } // Then, apply new style to all nodes in the range entirely. for (auto& content : arrayOfContentsAroundRange) { // MOZ_KnownLive due to bug 1622253. Result<EditorDOMPoint, nsresult> setStyleResult = SetInlinePropertyOnNode(MOZ_KnownLive(*content), MOZ_KnownLive(styleToSet.HTMLPropertyRef()), @@ -352,30 +352,30 @@ nsresult HTMLEditor::SetInlineProperties } // Finally, if end node is a text node, apply new style to a part of it. if (range.EndRef().IsInTextNode() && EditorUtils::IsEditableContent(*range.EndRef().ContainerAs<Text>(), EditorType::HTML)) { // MOZ_KnownLive(...ContainerAs<Text>()) because of grabbed by `range`. // MOZ_KnownLive(styleToSet.mAttribute) due to bug 1622253. - SplitRangeOffFromNodeResult wrapTextInStyledElementResult = - SetInlinePropertyOnTextNode( + Result<SplitRangeOffFromNodeResult, nsresult> + wrapTextInStyledElementResult = SetInlinePropertyOnTextNode( MOZ_KnownLive(*range.EndRef().ContainerAs<Text>()), 0, range.EndRef().Offset(), MOZ_KnownLive(styleToSet.HTMLPropertyRef()), MOZ_KnownLive(styleToSet.mAttribute), styleToSet.mAttributeValue); - if (wrapTextInStyledElementResult.isErr()) { + if (MOZ_UNLIKELY(wrapTextInStyledElementResult.isErr())) { NS_WARNING("HTMLEditor::SetInlinePropertyOnTextNode() failed"); return wrapTextInStyledElementResult.unwrapErr(); } // There is AutoTransactionsConserveSelection, so we don't need to // update selection here. - wrapTextInStyledElementResult.IgnoreCaretPointSuggestion(); + wrapTextInStyledElementResult.inspect().IgnoreCaretPointSuggestion(); } } MOZ_ASSERT(selectionRanges.HasSavedRanges()); selectionRanges.RestoreFromSavedRanges(); } MOZ_ASSERT(!selectionRanges.HasSavedRanges()); nsresult rv = selectionRanges.ApplyTo(SelectionRef()); @@ -465,19 +465,21 @@ Result<bool, nsresult> HTMLEditor::Eleme nsStyledElement* styledElement = nsStyledElement::FromNode(&aElement); if (!styledElement) { return false; } return CSSEditUtils::DoStyledElementsHaveSameStyle(*styledNewSpanElement, *styledElement); } -SplitRangeOffFromNodeResult HTMLEditor::SetInlinePropertyOnTextNode( - Text& aText, uint32_t aStartOffset, uint32_t aEndOffset, nsAtom& aProperty, - nsAtom* aAttribute, const nsAString& aValue) { +Result<SplitRangeOffFromNodeResult, nsresult> +HTMLEditor::SetInlinePropertyOnTextNode(Text& aText, uint32_t aStartOffset, + uint32_t aEndOffset, nsAtom& aProperty, + nsAtom* aAttribute, + const nsAString& aValue) { if (!aText.GetParentNode() || !HTMLEditUtils::CanNodeContain(*aText.GetParentNode(), aProperty)) { return SplitRangeOffFromNodeResult(nullptr, &aText, nullptr); } // Don't need to do anything if no characters actually selected if (aStartOffset == aEndOffset) { return SplitRangeOffFromNodeResult(nullptr, &aText, nullptr); @@ -486,21 +488,20 @@ SplitRangeOffFromNodeResult HTMLEditor:: // Don't need to do anything if property already set on node if (CSSEditUtils::IsCSSEditableProperty(&aText, &aProperty, aAttribute)) { // The HTML styles defined by aProperty/aAttribute have a CSS equivalence // for node; let's check if it carries those CSS styles nsAutoString value(aValue); Result<bool, nsresult> isComputedCSSEquivalentToHTMLInlineStyleOrError = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet( *this, aText, &aProperty, aAttribute, value); - if (isComputedCSSEquivalentToHTMLInlineStyleOrError.isErr()) { + if (MOZ_UNLIKELY(isComputedCSSEquivalentToHTMLInlineStyleOrError.isErr())) { NS_WARNING( "CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet() failed"); - return SplitRangeOffFromNodeResult( - isComputedCSSEquivalentToHTMLInlineStyleOrError.unwrapErr()); + return isComputedCSSEquivalentToHTMLInlineStyleOrError.propagateErr(); } if (isComputedCSSEquivalentToHTMLInlineStyleOrError.unwrap()) { return SplitRangeOffFromNodeResult(nullptr, &aText, nullptr); } } else if (HTMLEditUtils::IsInlineStyleSetByElement(aText, aProperty, aAttribute, &aValue)) { return SplitRangeOffFromNodeResult(nullptr, &aText, nullptr); } @@ -521,17 +522,17 @@ SplitRangeOffFromNodeResult HTMLEditor:: NS_WARNING( "HTMLEditor::SplitNodeWithTransaction() didn't suggest caret " "point"); return SplitNodeResult(NS_ERROR_FAILURE); } return splitNodeResult; }(); if (MOZ_UNLIKELY(splitAtEndResult.isErr())) { - return SplitRangeOffFromNodeResult(splitAtEndResult.unwrapErr()); + return Err(splitAtEndResult.unwrapErr()); } EditorDOMPoint pointToPutCaret = splitAtEndResult.UnwrapCaretPoint(); SplitNodeResult splitAtStartResult = [&]() MOZ_CAN_RUN_SCRIPT { EditorDOMPoint atStart(splitAtEndResult.DidSplit() ? splitAtEndResult.GetPreviousContent() : &aText, aStartOffset); if (atStart.IsStartOfContainer()) { @@ -547,17 +548,17 @@ SplitRangeOffFromNodeResult HTMLEditor:: NS_WARNING( "HTMLEditor::SplitNodeWithTransaction() didn't suggest caret " "point"); return SplitNodeResult(NS_ERROR_FAILURE); } return splitNodeResult; }(); if (MOZ_UNLIKELY(splitAtStartResult.isErr())) { - return SplitRangeOffFromNodeResult(splitAtStartResult.unwrapErr()); + return Err(splitAtStartResult.unwrapErr()); } if (splitAtStartResult.HasCaretPointSuggestion()) { pointToPutCaret = splitAtStartResult.UnwrapCaretPoint(); } MOZ_ASSERT_IF(splitAtStartResult.DidSplit(), splitAtStartResult.GetPreviousContent()->IsText()); MOZ_ASSERT_IF(splitAtStartResult.DidSplit(), @@ -588,26 +589,26 @@ SplitRangeOffFromNodeResult HTMLEditor:: nsIContent* sibling = HTMLEditUtils::GetPreviousSibling( *middleTextNode, {WalkTreeOption::IgnoreNonEditableNode}); if (sibling && sibling->IsElement()) { OwningNonNull<Element> element(*sibling->AsElement()); Result<bool, nsresult> result = ElementIsGoodContainerForTheStyle( element, &aProperty, aAttribute, &aValue); if (MOZ_UNLIKELY(result.isErr())) { NS_WARNING("HTMLEditor::ElementIsGoodContainerForTheStyle() failed"); - return SplitRangeOffFromNodeResult(result.unwrapErr()); + return result.propagateErr(); } if (result.inspect()) { // Previous sib is already right kind of inline node; slide this over Result<MoveNodeResult, nsresult> moveTextNodeResult = MoveNodeToEndWithTransaction(MOZ_KnownLive(*middleTextNode), element); if (MOZ_UNLIKELY(moveTextNodeResult.isErr())) { NS_WARNING("HTMLEditor::MoveNodeToEndWithTransaction() failed"); - return SplitRangeOffFromNodeResult(moveTextNodeResult.unwrapErr()); + return moveTextNodeResult.propagateErr(); } MoveNodeResult unwrappedMoveTextNodeResult = moveTextNodeResult.unwrap(); unwrappedMoveTextNodeResult.MoveCaretPointTo( pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion}); return SplitRangeOffFromNodeResult(leftTextNode, middleTextNode, rightTextNode, std::move(pointToPutCaret)); @@ -616,26 +617,26 @@ SplitRangeOffFromNodeResult HTMLEditor:: sibling = HTMLEditUtils::GetNextSibling( *middleTextNode, {WalkTreeOption::IgnoreNonEditableNode}); if (sibling && sibling->IsElement()) { OwningNonNull<Element> element(*sibling->AsElement()); Result<bool, nsresult> result = ElementIsGoodContainerForTheStyle( element, &aProperty, aAttribute, &aValue); if (MOZ_UNLIKELY(result.isErr())) { NS_WARNING("HTMLEditor::ElementIsGoodContainerForTheStyle() failed"); - return SplitRangeOffFromNodeResult(result.unwrapErr()); + return result.propagateErr(); } if (result.inspect()) { // Following sib is already right kind of inline node; slide this over Result<MoveNodeResult, nsresult> moveTextNodeResult = MoveNodeWithTransaction(MOZ_KnownLive(*middleTextNode), EditorDOMPoint(sibling, 0u)); if (MOZ_UNLIKELY(moveTextNodeResult.isErr())) { NS_WARNING("HTMLEditor::MoveNodeWithTransaction() failed"); - return SplitRangeOffFromNodeResult(moveTextNodeResult.unwrapErr()); + return moveTextNodeResult.propagateErr(); } MoveNodeResult unwrappedMoveTextNodeResult = moveTextNodeResult.unwrap(); unwrappedMoveTextNodeResult.MoveCaretPointTo( pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion}); return SplitRangeOffFromNodeResult(leftTextNode, middleTextNode, rightTextNode, std::move(pointToPutCaret)); @@ -643,17 +644,17 @@ SplitRangeOffFromNodeResult HTMLEditor:: } } // Wrap the node inside inline node with appropriate {attribute,value} Result<EditorDOMPoint, nsresult> setStyleResult = SetInlinePropertyOnNode( MOZ_KnownLive(*middleTextNode), aProperty, aAttribute, aValue); if (MOZ_UNLIKELY(setStyleResult.isErr())) { NS_WARNING("HTMLEditor::SetInlinePropertyOnNode() failed"); - return SplitRangeOffFromNodeResult(setStyleResult.unwrapErr()); + return setStyleResult.propagateErr(); } return SplitRangeOffFromNodeResult(leftTextNode, middleTextNode, rightTextNode, setStyleResult.unwrap()); } Result<EditorDOMPoint, nsresult> HTMLEditor::SetInlinePropertyOnNodeImpl( nsIContent& aContent, nsAtom& aProperty, nsAtom* aAttribute, const nsAString& aValue) { @@ -2450,38 +2451,40 @@ nsresult HTMLEditor::RemoveInlinePropert // may be multiple text nodes as adjacent siblings. That's the // reason why we need to handle text nodes in this loop. uint32_t startOffset = content == splitRange.StartRef().GetContainer() ? splitRange.StartRef().Offset() : 0; uint32_t endOffset = content == splitRange.EndRef().GetContainer() ? splitRange.EndRef().Offset() : content->Length(); - SplitRangeOffFromNodeResult wrapTextInStyledElementResult = - SetInlinePropertyOnTextNode( + Result<SplitRangeOffFromNodeResult, nsresult> + wrapTextInStyledElementResult = SetInlinePropertyOnTextNode( MOZ_KnownLive(*content->AsText()), startOffset, endOffset, *styleToRemove.mHTMLProperty, styleToRemove.mAttribute, u"-moz-editor-invert-value"_ns); - if (wrapTextInStyledElementResult.isErr()) { + if (MOZ_UNLIKELY(wrapTextInStyledElementResult.isErr())) { NS_WARNING( "HTMLEditor::SetInlinePropertyOnTextNode(-moz-editor-invert-" "value) failed"); return wrapTextInStyledElementResult.unwrapErr(); } + SplitRangeOffFromNodeResult unwrappedWrapTextInStyledElementResult = + wrapTextInStyledElementResult.unwrap(); // There is AutoTransactionsConserveSelection, so we don't need to // update selection here. - wrapTextInStyledElementResult.IgnoreCaretPointSuggestion(); + unwrappedWrapTextInStyledElementResult.IgnoreCaretPointSuggestion(); // If we've split the content, let's swap content in // arrayOfContentsToInvertStyle with the text node which is applied // the style. if (isCSSInvertibleStyle) { - MOZ_ASSERT( - wrapTextInStyledElementResult.GetMiddleContentAs<Text>()); - if (Text* textNode = - wrapTextInStyledElementResult.GetMiddleContentAs<Text>()) { + MOZ_ASSERT(unwrappedWrapTextInStyledElementResult + .GetMiddleContentAs<Text>()); + if (Text* textNode = unwrappedWrapTextInStyledElementResult + .GetMiddleContentAs<Text>()) { if (textNode != content) { arrayOfContentsToInvertStyle.ReplaceElementAt( arrayOfContentsToInvertStyle.Length() - 1, OwningNonNull<nsIContent>(*textNode)); } } } } @@ -2514,30 +2517,30 @@ nsresult HTMLEditor::RemoveInlinePropert "failed"); return isRemovableParentStyleOrError.unwrapErr(); } if (!isRemovableParentStyleOrError.unwrap()) { continue; } // MOZ_KnownLive because 'leafTextNodes' is guaranteed to // keep it alive. - SplitRangeOffFromNodeResult wrapTextInStyledElementResult = - SetInlinePropertyOnTextNode( + Result<SplitRangeOffFromNodeResult, nsresult> + wrapTextInStyledElementResult = SetInlinePropertyOnTextNode( MOZ_KnownLive(textNode), 0, textNode->TextLength(), *styleToRemove.mHTMLProperty, styleToRemove.mAttribute, u"-moz-editor-invert-value"_ns); - if (wrapTextInStyledElementResult.isErr()) { + if (MOZ_UNLIKELY(wrapTextInStyledElementResult.isErr())) { NS_WARNING( "HTMLEditor::SetInlinePropertyOnTextNode(-moz-editor-invert-" "value) failed"); return wrapTextInStyledElementResult.unwrapErr(); } // There is AutoTransactionsConserveSelection, so we don't need to // update selection here. - wrapTextInStyledElementResult.IgnoreCaretPointSuggestion(); + wrapTextInStyledElementResult.inspect().IgnoreCaretPointSuggestion(); } // for-loop of leafTextNodes } // for-loop of selectionRanges MOZ_ASSERT(selectionRanges.HasSavedRanges()); selectionRanges.RestoreFromSavedRanges(); } // for-loop of styles MOZ_ASSERT(!selectionRanges.HasSavedRanges()); nsresult rv = selectionRanges.ApplyTo(SelectionRef());