Bug 1660378 - part 7: Make `CSSEditUtils::SetCSSEquivalentToHTMLStyle()` take `nsStyledElement&` instead of `Element*` r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 26 Aug 2020 04:48:32 +0000
changeset 546255 06759e45f873228dba3c01c7dd15bbd2b44cd622
parent 546254 5e5fa801260fcd17b224bfa5d6e087c572ac7e51
child 546256 ee4715363f7004e72ea5f12a8d95f1fd81e2d21d
push id124997
push usermasayuki@d-toybox.com
push dateWed, 26 Aug 2020 06:09:10 +0000
treeherderautoland@d1a42f86dd61 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1660378
milestone82.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1660378 - part 7: Make `CSSEditUtils::SetCSSEquivalentToHTMLStyle()` take `nsStyledElement&` instead of `Element*` r=m_kato Differential Revision: https://phabricator.services.mozilla.com/D87988
editor/libeditor/CSSEditUtils.cpp
editor/libeditor/CSSEditUtils.h
editor/libeditor/EditorDOMPoint.h
editor/libeditor/HTMLEditSubActionHandler.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLStyleEditor.cpp
--- a/editor/libeditor/CSSEditUtils.cpp
+++ b/editor/libeditor/CSSEditUtils.cpp
@@ -814,53 +814,42 @@ void CSSEditUtils::GenerateCSSDeclaratio
     BuildCSSDeclarations(aOutArrayOfCSSProperty, aOutArrayOfCSSValue,
                          equivTable, aValue, aGetOrRemoveRequest);
   }
 }
 
 // Add to aNode the CSS inline style equivalent to HTMLProperty/aAttribute/
 // aValue for the node, and return in aCount the number of CSS properties set
 // by the call.  The Element version returns aCount instead.
-int32_t CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
-                                                  nsAtom* aHTMLProperty,
-                                                  nsAtom* aAttribute,
-                                                  const nsAString* aValue,
-                                                  bool aSuppressTransaction) {
-  MOZ_ASSERT(aElement);
-
-  if (!IsCSSEditableProperty(aElement, aHTMLProperty, aAttribute)) {
+Result<int32_t, nsresult> CSSEditUtils::SetCSSEquivalentToHTMLStyleInternal(
+    nsStyledElement& aStyledElement, nsAtom* aHTMLProperty, nsAtom* aAttribute,
+    const nsAString* aValue, bool aSuppressTransaction) {
+  if (!IsCSSEditableProperty(&aStyledElement, aHTMLProperty, aAttribute)) {
     return 0;
   }
 
   // we can apply the styles only if the node is an element and if we have
   // an equivalence for the requested HTML style in this implementation
 
   // Find the CSS equivalence to the HTML style
   nsTArray<nsStaticAtom*> cssPropertyArray;
   nsTArray<nsString> cssValueArray;
-  GenerateCSSDeclarationsFromHTMLStyle(*aElement, aHTMLProperty, aAttribute,
-                                       aValue, cssPropertyArray, cssValueArray,
-                                       false);
+  GenerateCSSDeclarationsFromHTMLStyle(aStyledElement, aHTMLProperty,
+                                       aAttribute, aValue, cssPropertyArray,
+                                       cssValueArray, false);
 
   // set the individual CSS inline styles
   const size_t count = cssPropertyArray.Length();
-  if (!count) {
-    return 0;
-  }
-  nsCOMPtr<nsStyledElement> styledElement = do_QueryInterface(aElement);
-  if (NS_WARN_IF(!styledElement)) {
-    return 0;
-  }
   for (size_t index = 0; index < count; index++) {
     nsresult rv = SetCSSPropertyInternal(
-        *styledElement, MOZ_KnownLive(*cssPropertyArray[index]),
+        aStyledElement, MOZ_KnownLive(*cssPropertyArray[index]),
         cssValueArray[index], aSuppressTransaction);
     if (NS_FAILED(rv)) {
       NS_WARNING("CSSEditUtils::SetCSSPropertyInternal() failed");
-      return 0;
+      return Err(rv);
     }
   }
   return count;
 }
 
 // Remove from aNode the CSS inline style equivalent to
 // HTMLProperty/aAttribute/aValue for the node
 nsresult CSSEditUtils::RemoveCSSEquivalentToHTMLStyleInternal(
--- a/editor/libeditor/CSSEditUtils.h
+++ b/editor/libeditor/CSSEditUtils.h
@@ -245,24 +245,35 @@ class CSSEditUtils final {
    * Adds to the node the CSS inline styles equivalent to the HTML style
    * and return the number of CSS properties set by the call.
    *
    * @param aNode          [IN] A DOM node.
    * @param aHTMLProperty  [IN] An atom containing an HTML property.
    * @param aAttribute     [IN] An atom to an attribute name or nullptr
    *                            if irrelevant.
    * @param aValue         [IN] The attribute value.
-   * @param aSuppressTransaction [IN] A boolean indicating, when true,
-   *                                  that no transaction should be recorded.
    *
    * @return               The number of CSS properties set by the call.
    */
-  MOZ_CAN_RUN_SCRIPT int32_t SetCSSEquivalentToHTMLStyle(
-      dom::Element* aElement, nsAtom* aProperty, nsAtom* aAttribute,
-      const nsAString* aValue, bool aSuppressTransaction);
+  [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<int32_t, nsresult>
+  SetCSSEquivalentToHTMLStyleWithTransaction(nsStyledElement& aStyledElement,
+                                             nsAtom* aProperty,
+                                             nsAtom* aAttribute,
+                                             const nsAString* aValue) {
+    return SetCSSEquivalentToHTMLStyleInternal(aStyledElement, aProperty,
+                                               aAttribute, aValue, false);
+  }
+  [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<int32_t, nsresult>
+  SetCSSEquivalentToHTMLStyleWithoutTransaction(nsStyledElement& aStyledElement,
+                                                nsAtom* aProperty,
+                                                nsAtom* aAttribute,
+                                                const nsAString* aValue) {
+    return SetCSSEquivalentToHTMLStyleInternal(aStyledElement, aProperty,
+                                               aAttribute, aValue, true);
+  }
 
   /**
    * Removes from the node the CSS inline styles equivalent to the HTML style.
    *
    * @param aStyledElement [IN] A DOM Element (must not be null).
    * @param aHTMLProperty  [IN] An atom containing an HTML property.
    * @param aAttribute     [IN] An atom to an attribute name or nullptr if
    *                            irrelevant.
@@ -422,16 +433,21 @@ class CSSEditUtils final {
   RemoveCSSEquivalentToHTMLStyleInternal(nsStyledElement& aStyledElement,
                                          nsAtom* aHTMLProperty,
                                          nsAtom* aAttribute,
                                          const nsAString* aValue,
                                          bool aSuppressTransaction);
   [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
   SetCSSPropertyInternal(nsStyledElement& aStyledElement, nsAtom& aProperty,
                          const nsAString& aValue, bool aSuppressTxn = false);
+  [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<int32_t, nsresult>
+  SetCSSEquivalentToHTMLStyleInternal(nsStyledElement& aStyledElement,
+                                      nsAtom* aProperty, nsAtom* aAttribute,
+                                      const nsAString* aValue,
+                                      bool aSuppressTransaction);
 
  private:
   HTMLEditor* mHTMLEditor;
   bool mIsCSSPrefChecked;
 };
 
 #define NS_EDITOR_INDENT_INCREMENT_IN 0.4134f
 #define NS_EDITOR_INDENT_INCREMENT_CM 1.05f
--- a/editor/libeditor/EditorDOMPoint.h
+++ b/editor/libeditor/EditorDOMPoint.h
@@ -15,16 +15,17 @@
 #include "mozilla/dom/Text.h"
 #include "nsAtom.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsCRT.h"
 #include "nsGkAtoms.h"
 #include "nsIContent.h"
 #include "nsINode.h"
+#include "nsStyledElement.h"
 
 namespace mozilla {
 
 template <typename ParentType, typename ChildType>
 class EditorDOMPointBase;
 
 /**
  * EditorDOMPoint and EditorRawDOMPoint are simple classes which refers
@@ -173,16 +174,21 @@ class EditorDOMPointBase final {
   }
 
   MOZ_NEVER_INLINE_DEBUG dom::Element* ContainerAsElement() const {
     MOZ_ASSERT(mParent);
     MOZ_ASSERT(mParent->IsElement());
     return mParent->AsElement();
   }
 
+  already_AddRefed<nsStyledElement> GetContainerAsStyledElement() const {
+    nsCOMPtr<nsStyledElement> styledElement = do_QueryInterface(mParent);
+    return styledElement.forget();
+  }
+
   dom::Text* GetContainerAsText() const {
     return dom::Text::FromNodeOrNull(mParent);
   }
 
   MOZ_NEVER_INLINE_DEBUG dom::Text* ContainerAsText() const {
     MOZ_ASSERT(mParent);
     MOZ_ASSERT(IsInTextNode());
     return mParent->AsText();
--- a/editor/libeditor/HTMLEditSubActionHandler.cpp
+++ b/editor/libeditor/HTMLEditSubActionHandler.cpp
@@ -8669,21 +8669,33 @@ nsresult HTMLEditor::AlignNodesAndDescen
       if (NS_FAILED(rv)) {
         NS_WARNING(
             "HTMLEditor::RemoveAlignFromDescendants(EditTarget::"
             "OnlyDescendantsExceptTable) failed");
         return rv;
       }
 
       if (useCSS) {
-        mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
-            MOZ_KnownLive(listOrListItemElement), nullptr, nsGkAtoms::align,
-            &aAlignType, false);
-        if (NS_WARN_IF(Destroyed())) {
-          return NS_ERROR_EDITOR_DESTROYED;
+        if (nsCOMPtr<nsStyledElement> styledListOrListItemElement =
+                do_QueryInterface(listOrListItemElement)) {
+          Result<int32_t, nsresult> result =
+              mCSSEditUtils->SetCSSEquivalentToHTMLStyleWithTransaction(
+                  *styledListOrListItemElement, nullptr, nsGkAtoms::align,
+                  &aAlignType);
+          if (result.isErr()) {
+            if (result.inspectErr() == NS_ERROR_EDITOR_DESTROYED) {
+              NS_WARNING(
+                  "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction("
+                  "nsGkAtoms::align) destroyed the editor");
+              return NS_ERROR_EDITOR_DESTROYED;
+            }
+            NS_WARNING(
+                "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction("
+                "nsGkAtoms::align) failed, but ignored");
+          }
         }
         createdDivElement = nullptr;
         continue;
       }
 
       if (HTMLEditUtils::IsAnyListElement(atContent.GetContainer())) {
         // 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.
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -5171,72 +5171,83 @@ bool HTMLEditor::IsEmptyNodeImpl(nsINode
 nsresult HTMLEditor::SetAttributeOrEquivalent(Element* aElement,
                                               nsAtom* aAttribute,
                                               const nsAString& aValue,
                                               bool aSuppressTransaction) {
   MOZ_ASSERT(aElement);
   MOZ_ASSERT(aAttribute);
 
   nsAutoScriptBlocker scriptBlocker;
-
+  nsCOMPtr<nsStyledElement> styledElement = do_QueryInterface(aElement);
   if (!IsCSSEnabled() || !mCSSEditUtils) {
     // we are not in an HTML+CSS editor; let's set the attribute the HTML way
-    if (mCSSEditUtils) {
-      if (nsCOMPtr<nsStyledElement> styledElement =
-              do_QueryInterface(aElement)) {
-        nsresult rv =
-            aSuppressTransaction
-                ? mCSSEditUtils
-                      ->RemoveCSSEquivalentToHTMLStyleWithoutTransaction(
-                          *styledElement, nullptr, aAttribute, nullptr)
-                : mCSSEditUtils->RemoveCSSEquivalentToHTMLStyleWithTransaction(
-                      *styledElement, nullptr, aAttribute, nullptr);
-        if (rv == NS_ERROR_EDITOR_DESTROYED) {
-          NS_WARNING(
-              "CSSEditUtils::RemoveCSSEquivalentToHTMLStyle*Transaction() "
-              "destroyed the editor");
-          return NS_ERROR_EDITOR_DESTROYED;
-        }
-        NS_WARNING_ASSERTION(
-            NS_SUCCEEDED(rv),
+    if (mCSSEditUtils && styledElement) {
+      nsresult rv =
+          aSuppressTransaction
+              ? mCSSEditUtils->RemoveCSSEquivalentToHTMLStyleWithoutTransaction(
+                    *styledElement, nullptr, aAttribute, nullptr)
+              : mCSSEditUtils->RemoveCSSEquivalentToHTMLStyleWithTransaction(
+                    *styledElement, nullptr, aAttribute, nullptr);
+      if (rv == NS_ERROR_EDITOR_DESTROYED) {
+        NS_WARNING(
             "CSSEditUtils::RemoveCSSEquivalentToHTMLStyle*Transaction() "
-            "failed, but ignored");
+            "destroyed the editor");
+        return NS_ERROR_EDITOR_DESTROYED;
       }
+      NS_WARNING_ASSERTION(
+          NS_SUCCEEDED(rv),
+          "CSSEditUtils::RemoveCSSEquivalentToHTMLStyle*Transaction() "
+          "failed, but ignored");
     }
     if (aSuppressTransaction) {
       nsresult rv =
           aElement->SetAttr(kNameSpaceID_None, aAttribute, aValue, true);
       NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Element::SetAttr() failed");
       return rv;
     }
     nsresult rv = SetAttributeWithTransaction(*aElement, *aAttribute, aValue);
     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
                          "EditorBase::SetAttributeWithTransaction() failed");
     return rv;
   }
 
-  int32_t count = mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
-      aElement, nullptr, aAttribute, &aValue, aSuppressTransaction);
-  if (count) {
-    // we found an equivalence ; let's remove the HTML attribute itself if it
-    // is set
-    nsAutoString existingValue;
-    if (!aElement->GetAttr(kNameSpaceID_None, aAttribute, existingValue)) {
-      return NS_OK;
-    }
-
-    if (aSuppressTransaction) {
-      nsresult rv = aElement->UnsetAttr(kNameSpaceID_None, aAttribute, true);
-      NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Element::UnsetAttr() failed");
+  if (styledElement) {
+    Result<int32_t, nsresult> count =
+        aSuppressTransaction
+            ? mCSSEditUtils->SetCSSEquivalentToHTMLStyleWithoutTransaction(
+                  *styledElement, nullptr, aAttribute, &aValue)
+            : mCSSEditUtils->SetCSSEquivalentToHTMLStyleWithTransaction(
+                  *styledElement, nullptr, aAttribute, &aValue);
+    if (count.isErr()) {
+      if (count.inspectErr() == NS_ERROR_EDITOR_DESTROYED) {
+        return NS_ERROR_EDITOR_DESTROYED;
+      }
+      NS_WARNING(
+          "CSSEditUtils::SetCSSEquivalentToHTMLStyle*Transaction() failed, but "
+          "ignored");
+    }
+    if (count.inspect()) {
+      // we found an equivalence ; let's remove the HTML attribute itself if it
+      // is set
+      nsAutoString existingValue;
+      if (!aElement->GetAttr(kNameSpaceID_None, aAttribute, existingValue)) {
+        return NS_OK;
+      }
+
+      if (aSuppressTransaction) {
+        nsresult rv = aElement->UnsetAttr(kNameSpaceID_None, aAttribute, true);
+        NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Element::UnsetAttr() failed");
+        return rv;
+      }
+      nsresult rv = RemoveAttributeWithTransaction(*aElement, *aAttribute);
+      NS_WARNING_ASSERTION(
+          NS_SUCCEEDED(rv),
+          "EditorBase::RemoveAttributeWithTransaction() failed");
       return rv;
     }
-    nsresult rv = RemoveAttributeWithTransaction(*aElement, *aAttribute);
-    NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
-                         "EditorBase::RemoveAttributeWithTransaction() failed");
-    return rv;
   }
 
   // count is an integer that represents the number of CSS declarations
   // applied to the element. If it is zero, we found no equivalence in this
   // implementation for the attribute
   if (aAttribute == nsGkAtoms::style) {
     // if it is the style attribute, just add the new value to the existing
     // style attribute's value
@@ -5401,57 +5412,86 @@ nsresult HTMLEditor::SetCSSBackgroundCol
           NS_WARN_IF(!endOfRange.IsSet())) {
         continue;
       }
 
       if (startOfRange.GetContainer() == endOfRange.GetContainer()) {
         // If the range is in a text node, set background color of its parent
         // block.
         if (startOfRange.IsInTextNode()) {
-          if (RefPtr<Element> blockElement =
-                  HTMLEditUtils::GetAncestorBlockElement(
-                      *startOfRange.ContainerAsText())) {
-            mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
-                blockElement, nullptr, nsGkAtoms::bgcolor, &aColor, false);
-            if (NS_WARN_IF(Destroyed())) {
-              return NS_ERROR_EDITOR_DESTROYED;
+          if (nsCOMPtr<nsStyledElement> blockStyledElement =
+                  do_QueryInterface(HTMLEditUtils::GetAncestorBlockElement(
+                      *startOfRange.ContainerAsText()))) {
+            Result<int32_t, nsresult> result =
+                mCSSEditUtils->SetCSSEquivalentToHTMLStyleWithTransaction(
+                    *blockStyledElement, nullptr, nsGkAtoms::bgcolor, &aColor);
+            if (result.isErr()) {
+              if (result.inspectErr() == NS_ERROR_EDITOR_DESTROYED) {
+                NS_WARNING(
+                    "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction("
+                    "nsGkAtoms::bgcolor) destroyed the editor");
+                return NS_ERROR_EDITOR_DESTROYED;
+              }
+              NS_WARNING(
+                  "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction("
+                  "nsGkAtoms::bgcolor) failed, but ignored");
             }
           }
           continue;
         }
 
         // If `Selection` is collapsed in a `<body>` element, set background
         // color of the `<body>` element.
         // XXX Why do we refer whether the `Selection` is collapsed rather
         //     than the `nsRange` is collapsed?
         if (startOfRange.GetContainer()->IsHTMLElement(nsGkAtoms::body) &&
             selectionIsCollapsed) {
-          mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
-              MOZ_KnownLive(startOfRange.GetContainerAsElement()), nullptr,
-              nsGkAtoms::bgcolor, &aColor, false);
-          if (NS_WARN_IF(Destroyed())) {
-            return NS_ERROR_EDITOR_DESTROYED;
+          if (nsCOMPtr<nsStyledElement> styledElement =
+                  startOfRange.GetContainerAsStyledElement()) {
+            Result<int32_t, nsresult> result =
+                mCSSEditUtils->SetCSSEquivalentToHTMLStyleWithTransaction(
+                    *styledElement, nullptr, nsGkAtoms::bgcolor, &aColor);
+            if (result.isErr()) {
+              if (result.inspectErr() == NS_ERROR_EDITOR_DESTROYED) {
+                NS_WARNING(
+                    "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction("
+                    "nsGkAtoms::bgcolor) destroyed the editor");
+                return NS_ERROR_EDITOR_DESTROYED;
+              }
+              NS_WARNING(
+                  "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction("
+                  "nsGkAtoms::bgcolor) failed, but ignored");
+            }
           }
           continue;
         }
         // If one node is selected, set background color of it if it's a
         // block, or of its parent block otherwise.
         if ((startOfRange.IsStartOfContainer() &&
              endOfRange.IsStartOfContainer()) ||
             startOfRange.Offset() + 1 == endOfRange.Offset()) {
           if (NS_WARN_IF(startOfRange.IsInDataNode())) {
             continue;
           }
-          if (RefPtr<Element> blockElement =
+          if (nsCOMPtr<nsStyledElement> blockStyledElement = do_QueryInterface(
                   HTMLEditUtils::GetInclusiveAncestorBlockElement(
-                      *startOfRange.GetChild())) {
-            mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
-                blockElement, nullptr, nsGkAtoms::bgcolor, &aColor, false);
-            if (NS_WARN_IF(Destroyed())) {
-              return NS_ERROR_EDITOR_DESTROYED;
+                      *startOfRange.GetChild()))) {
+            Result<int32_t, nsresult> result =
+                mCSSEditUtils->SetCSSEquivalentToHTMLStyleWithTransaction(
+                    *blockStyledElement, nullptr, nsGkAtoms::bgcolor, &aColor);
+            if (result.isErr()) {
+              if (result.inspectErr() == NS_ERROR_EDITOR_DESTROYED) {
+                NS_WARNING(
+                    "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction("
+                    "nsGkAtoms::bgcolor) destroyed the editor");
+                return NS_ERROR_EDITOR_DESTROYED;
+              }
+              NS_WARNING(
+                  "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction("
+                  "nsGkAtoms::bgcolor) failed, but ignored");
             }
           }
           continue;
         }
       }
 
       // Collect editable nodes which are entirely contained in the range.
       AutoTArray<OwningNonNull<nsIContent>, 64> arrayOfContents;
@@ -5483,51 +5523,87 @@ nsresult HTMLEditor::SetCSSBackgroundCol
       // block.
       if (startOfRange.IsInTextNode() &&
           EditorUtils::IsEditableContent(*startOfRange.ContainerAsText(),
                                          EditorType::HTML)) {
         RefPtr<Element> blockElement = HTMLEditUtils::GetAncestorBlockElement(
             *startOfRange.ContainerAsText());
         if (blockElement && handledBlockParent != blockElement) {
           handledBlockParent = blockElement;
-          mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
-              blockElement, nullptr, nsGkAtoms::bgcolor, &aColor, false);
-          if (NS_WARN_IF(Destroyed())) {
-            return NS_ERROR_EDITOR_DESTROYED;
+          if (nsCOMPtr<nsStyledElement> blockStyledElement =
+                  do_QueryInterface(blockElement)) {
+            Result<int32_t, nsresult> result =
+                mCSSEditUtils->SetCSSEquivalentToHTMLStyleWithTransaction(
+                    *blockStyledElement, nullptr, nsGkAtoms::bgcolor, &aColor);
+            if (result.isErr()) {
+              if (result.inspectErr() == NS_ERROR_EDITOR_DESTROYED) {
+                NS_WARNING(
+                    "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction("
+                    "nsGkAtoms::bgcolor) destroyed the editor");
+                return NS_ERROR_EDITOR_DESTROYED;
+              }
+              NS_WARNING(
+                  "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction("
+                  "nsGkAtoms::bgcolor) failed, but ignored");
+            }
           }
         }
       }
 
       // Then, set background color of each block or block parent of all nodes
       // in the range entirely.
       for (OwningNonNull<nsIContent>& content : arrayOfContents) {
         RefPtr<Element> blockElement =
             HTMLEditUtils::GetInclusiveAncestorBlockElement(content);
         if (blockElement && handledBlockParent != blockElement) {
           handledBlockParent = blockElement;
-          mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
-              blockElement, nullptr, nsGkAtoms::bgcolor, &aColor, false);
-          if (NS_WARN_IF(Destroyed())) {
-            return NS_ERROR_EDITOR_DESTROYED;
+          if (nsCOMPtr<nsStyledElement> blockStyledElement =
+                  do_QueryInterface(blockElement)) {
+            Result<int32_t, nsresult> result =
+                mCSSEditUtils->SetCSSEquivalentToHTMLStyleWithTransaction(
+                    *blockStyledElement, nullptr, nsGkAtoms::bgcolor, &aColor);
+            if (result.isErr()) {
+              if (result.inspectErr() == NS_ERROR_EDITOR_DESTROYED) {
+                NS_WARNING(
+                    "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction("
+                    "nsGkAtoms::bgcolor) destroyed the editor");
+                return NS_ERROR_EDITOR_DESTROYED;
+              }
+              NS_WARNING(
+                  "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction("
+                  "nsGkAtoms::bgcolor) failed, but ignored");
+            }
           }
         }
       }
 
       // Finally, if end node is a text node, set background color of its
       // parent block.
       if (endOfRange.IsInTextNode() &&
           EditorUtils::IsEditableContent(*endOfRange.ContainerAsText(),
                                          EditorType::HTML)) {
         RefPtr<Element> blockElement = HTMLEditUtils::GetAncestorBlockElement(
             *endOfRange.ContainerAsText());
         if (blockElement && handledBlockParent != blockElement) {
-          mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
-              blockElement, nullptr, nsGkAtoms::bgcolor, &aColor, false);
-          if (NS_WARN_IF(Destroyed())) {
-            return NS_ERROR_EDITOR_DESTROYED;
+          if (nsCOMPtr<nsStyledElement> blockStyledElement =
+                  do_QueryInterface(blockElement)) {
+            Result<int32_t, nsresult> result =
+                mCSSEditUtils->SetCSSEquivalentToHTMLStyleWithTransaction(
+                    *blockStyledElement, nullptr, nsGkAtoms::bgcolor, &aColor);
+            if (result.isErr()) {
+              if (result.inspectErr() == NS_ERROR_EDITOR_DESTROYED) {
+                NS_WARNING(
+                    "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction("
+                    "nsGkAtoms::bgcolor) destroyed the editor");
+                return NS_ERROR_EDITOR_DESTROYED;
+              }
+              NS_WARNING(
+                  "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction("
+                  "nsGkAtoms::bgcolor) failed, but ignored");
+            }
           }
         }
       }
     }
   }
 
   // Restoring `Selection` may cause destroying us.
   return NS_WARN_IF(Destroyed()) ? NS_ERROR_EDITOR_DESTROYED : NS_OK;
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -402,24 +402,27 @@ bool HTMLEditor::IsSimpleModifiableNode(
   // "text-decoration: underline", which decomposes into four different text-*
   // properties.  So for now, we just create a span, add the desired style, and
   // see if it matches.
   RefPtr<Element> newSpanElement = CreateHTMLContent(nsGkAtoms::span);
   if (!newSpanElement) {
     NS_WARNING("EditorBase::CreateHTMLContent(nsGkAtoms::span) failed");
     return false;
   }
-  mCSSEditUtils->SetCSSEquivalentToHTMLStyle(newSpanElement, aProperty,
-                                             aAttribute, aValue,
-                                             /*suppress transaction*/ true);
   nsCOMPtr<nsStyledElement> styledNewSpanElement =
       do_QueryInterface(newSpanElement);
   if (!styledNewSpanElement) {
     return false;
   }
+  Result<int32_t, nsresult> result =
+      mCSSEditUtils->SetCSSEquivalentToHTMLStyleWithoutTransaction(
+          *styledNewSpanElement, aProperty, aAttribute, aValue);
+  if (result.isErr()) {
+    return false;  // TODO: Return error if editor is destroyed.
+  }
   nsCOMPtr<nsStyledElement> styledElement = do_QueryInterface(element);
   if (!styledElement) {
     return false;
   }
   return CSSEditUtils::DoStyledElementsHaveSameStyle(*styledNewSpanElement,
                                                      *styledElement);
 }
 
@@ -618,18 +621,34 @@ nsresult HTMLEditor::SetInlinePropertyOn
         NS_WARNING(
             "HTMLEditor::InsertContainerWithTransaction(nsGkAtoms::span) "
             "failed");
         return NS_ERROR_FAILURE;
       }
     }
 
     // Add the CSS styles corresponding to the HTML style request
-    mCSSEditUtils->SetCSSEquivalentToHTMLStyle(spanElement, &aProperty,
-                                               aAttribute, &aValue, false);
+    if (nsCOMPtr<nsStyledElement> spanStyledElement =
+            do_QueryInterface(spanElement)) {
+      Result<int32_t, nsresult> result =
+          mCSSEditUtils->SetCSSEquivalentToHTMLStyleWithTransaction(
+              *spanStyledElement, &aProperty, aAttribute, &aValue);
+      if (result.isErr()) {
+        if (result.inspectErr() == NS_ERROR_EDITOR_DESTROYED) {
+          NS_WARNING(
+              "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction() "
+              "destroyed the editor");
+          return NS_ERROR_EDITOR_DESTROYED;
+        }
+        NS_WARNING(
+            "CSSEditUtils::SetCSSEquivalentToHTMLStyleWithTransaction() "
+            "failed, "
+            "but ignored");
+      }
+    }
     return NS_OK;
   }
 
   // is it already the right kind of node, but with wrong attribute?
   if (aContent.IsHTMLElement(&aProperty)) {
     if (NS_WARN_IF(!aAttribute)) {
       return NS_ERROR_INVALID_ARG;
     }