Bug 1323138 - CSSEditUtils should use atom for CSS property if possible. r?masayuki draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Mon, 12 Dec 2016 00:03:36 -1000
changeset 448876 2710e469cc1ec1fcb81782020d63a35cb09ea333
parent 448717 f46f85dcfbc2b3098ea758825d18be6fab33cbc6
child 539404 3e54b0636fd639b971cc01cab881d797147dcb58
push id38466
push userm_kato@ga2.so-net.ne.jp
push dateTue, 13 Dec 2016 07:01:50 +0000
reviewersmasayuki
bugs1323138
milestone53.0a1
Bug 1323138 - CSSEditUtils should use atom for CSS property if possible. r?masayuki There is a lot of string compare when using CSS property name. We should use nsGkAtoms instead. MozReview-Commit-ID: JvpWRTkM8U
editor/libeditor/CSSEditUtils.cpp
editor/libeditor/CSSEditUtils.h
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLStyleEditor.cpp
--- a/editor/libeditor/CSSEditUtils.cpp
+++ b/editor/libeditor/CSSEditUtils.cpp
@@ -315,39 +315,47 @@ CSSEditUtils::~CSSEditUtils()
 
 // Answers true if we have some CSS equivalence for the HTML style defined
 // by aProperty and/or aAttribute for the node aNode
 bool
 CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
                                     nsIAtom* aProperty,
                                     const nsAString* aAttribute)
 {
+  nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
+  return IsCSSEditableProperty(aNode, aProperty, attribute);
+}
+
+bool
+CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
+                                    nsIAtom* aProperty,
+                                    nsIAtom* aAttribute)
+{
   MOZ_ASSERT(aNode);
 
   nsINode* node = aNode;
   // we need an element node here
   if (node->NodeType() == nsIDOMNode::TEXT_NODE) {
     node = node->GetParentNode();
     NS_ENSURE_TRUE(node, false);
   }
 
   // html inline styles B I TT U STRIKE and COLOR/FACE on FONT
   if (nsGkAtoms::b == aProperty ||
       nsGkAtoms::i == aProperty ||
       nsGkAtoms::tt == aProperty ||
       nsGkAtoms::u == aProperty ||
       nsGkAtoms::strike == aProperty ||
       (nsGkAtoms::font == aProperty && aAttribute &&
-       (aAttribute->EqualsLiteral("color") ||
-        aAttribute->EqualsLiteral("face")))) {
+       (aAttribute == nsGkAtoms::color || aAttribute == nsGkAtoms::face))) {
     return true;
   }
 
   // ALIGN attribute on elements supporting it
-  if (aAttribute && (aAttribute->EqualsLiteral("align")) &&
+  if (aAttribute == nsGkAtoms::align &&
       node->IsAnyOfHTMLElements(nsGkAtoms::div,
                                 nsGkAtoms::p,
                                 nsGkAtoms::h1,
                                 nsGkAtoms::h2,
                                 nsGkAtoms::h3,
                                 nsGkAtoms::h4,
                                 nsGkAtoms::h5,
                                 nsGkAtoms::h6,
@@ -360,82 +368,75 @@ CSSEditUtils::IsCSSEditableProperty(nsIN
                                 // It also checks for tbody, tfoot, thead.
                                 // Let's add the following elements here even
                                 // if "align" has a different meaning for them
                                 nsGkAtoms::legend,
                                 nsGkAtoms::caption)) {
     return true;
   }
 
-  if (aAttribute && (aAttribute->EqualsLiteral("valign")) &&
+  if (aAttribute == nsGkAtoms::valign &&
       node->IsAnyOfHTMLElements(nsGkAtoms::col,
                                 nsGkAtoms::colgroup,
                                 nsGkAtoms::tbody,
                                 nsGkAtoms::td,
                                 nsGkAtoms::th,
                                 nsGkAtoms::tfoot,
                                 nsGkAtoms::thead,
                                 nsGkAtoms::tr)) {
     return true;
   }
 
   // attributes TEXT, BACKGROUND and BGCOLOR on BODY
-  if (aAttribute && node->IsHTMLElement(nsGkAtoms::body) &&
-      (aAttribute->EqualsLiteral("text")
-       || aAttribute->EqualsLiteral("background")
-       || aAttribute->EqualsLiteral("bgcolor"))) {
+  if (node->IsHTMLElement(nsGkAtoms::body) &&
+      (aAttribute == nsGkAtoms::text || aAttribute == nsGkAtoms::background ||
+       aAttribute == nsGkAtoms::bgcolor)) {
     return true;
   }
 
   // attribute BGCOLOR on other elements
-  if (aAttribute && aAttribute->EqualsLiteral("bgcolor")) {
+  if (aAttribute == nsGkAtoms::bgcolor) {
     return true;
   }
 
   // attributes HEIGHT, WIDTH and NOWRAP on TD and TH
-  if (aAttribute &&
-      node->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th) &&
-      (aAttribute->EqualsLiteral("height")
-       || aAttribute->EqualsLiteral("width")
-       || aAttribute->EqualsLiteral("nowrap"))) {
+  if (node->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th) &&
+      (aAttribute == nsGkAtoms::height || aAttribute == nsGkAtoms::width ||
+       aAttribute == nsGkAtoms::nowrap)) {
     return true;
   }
 
   // attributes HEIGHT and WIDTH on TABLE
-  if (aAttribute && node->IsHTMLElement(nsGkAtoms::table) &&
-      (aAttribute->EqualsLiteral("height")
-       || aAttribute->EqualsLiteral("width"))) {
+  if (node->IsHTMLElement(nsGkAtoms::table) &&
+      (aAttribute == nsGkAtoms::height || aAttribute == nsGkAtoms::width)) {
     return true;
   }
 
   // attributes SIZE and WIDTH on HR
-  if (aAttribute && node->IsHTMLElement(nsGkAtoms::hr) &&
-      (aAttribute->EqualsLiteral("size")
-       || aAttribute->EqualsLiteral("width"))) {
+  if (node->IsHTMLElement(nsGkAtoms::hr) &&
+      (aAttribute == nsGkAtoms::size || aAttribute == nsGkAtoms::width)) {
     return true;
   }
 
   // attribute TYPE on OL UL LI
-  if (aAttribute &&
-      node->IsAnyOfHTMLElements(nsGkAtoms::ol, nsGkAtoms::ul,
+  if (node->IsAnyOfHTMLElements(nsGkAtoms::ol, nsGkAtoms::ul,
                                 nsGkAtoms::li) &&
-      aAttribute->EqualsLiteral("type")) {
+      aAttribute == nsGkAtoms::type) {
     return true;
   }
 
-  if (aAttribute && node->IsHTMLElement(nsGkAtoms::img) &&
-      (aAttribute->EqualsLiteral("border")
-       || aAttribute->EqualsLiteral("width")
-       || aAttribute->EqualsLiteral("height"))) {
+  if (node->IsHTMLElement(nsGkAtoms::img) &&
+      (aAttribute == nsGkAtoms::border || aAttribute == nsGkAtoms::width ||
+       aAttribute == nsGkAtoms::height)) {
     return true;
   }
 
   // other elements that we can align using CSS even if they
   // can't carry the html ALIGN attribute
-  if (aAttribute && aAttribute->EqualsLiteral("align") &&
+  if (aAttribute == nsGkAtoms::align &&
       node->IsAnyOfHTMLElements(nsGkAtoms::ul,
                                 nsGkAtoms::ol,
                                 nsGkAtoms::dl,
                                 nsGkAtoms::li,
                                 nsGkAtoms::dd,
                                 nsGkAtoms::dt,
                                 nsGkAtoms::address,
                                 nsGkAtoms::pre)) {
@@ -813,17 +814,17 @@ CSSEditUtils::BuildCSSDeclarations(nsTAr
 }
 
 // Populate cssPropertyArray and cssValueArray with the declarations equivalent
 // to aHTMLProperty/aAttribute/aValue for the node aNode
 void
 CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
                 Element* aElement,
                 nsIAtom* aHTMLProperty,
-                const nsAString* aAttribute,
+                nsIAtom* aAttribute,
                 const nsAString* aValue,
                 nsTArray<nsIAtom*>& cssPropertyArray,
                 nsTArray<nsString>& cssValueArray,
                 bool aGetOrRemoveRequest)
 {
   MOZ_ASSERT(aElement);
   const CSSEditUtils::CSSEquivTable* equivTable = nullptr;
 
@@ -833,147 +834,156 @@ CSSEditUtils::GenerateCSSDeclarationsFro
     equivTable = italicEquivTable;
   } else if (nsGkAtoms::u == aHTMLProperty) {
     equivTable = underlineEquivTable;
   } else if (nsGkAtoms::strike == aHTMLProperty) {
     equivTable = strikeEquivTable;
   } else if (nsGkAtoms::tt == aHTMLProperty) {
     equivTable = ttEquivTable;
   } else if (aAttribute) {
-    if (nsGkAtoms::font == aHTMLProperty &&
-        aAttribute->EqualsLiteral("color")) {
+    if (nsGkAtoms::font == aHTMLProperty && aAttribute == nsGkAtoms::color) {
       equivTable = fontColorEquivTable;
     } else if (nsGkAtoms::font == aHTMLProperty &&
-               aAttribute->EqualsLiteral("face")) {
+               aAttribute == nsGkAtoms::face) {
       equivTable = fontFaceEquivTable;
-    } else if (aAttribute->EqualsLiteral("bgcolor")) {
+    } else if (aAttribute == nsGkAtoms::bgcolor) {
       equivTable = bgcolorEquivTable;
-    } else if (aAttribute->EqualsLiteral("background")) {
+    } else if (aAttribute == nsGkAtoms::background) {
       equivTable = backgroundImageEquivTable;
-    } else if (aAttribute->EqualsLiteral("text")) {
+    } else if (aAttribute == nsGkAtoms::text) {
       equivTable = textColorEquivTable;
-    } else if (aAttribute->EqualsLiteral("border")) {
+    } else if (aAttribute == nsGkAtoms::border) {
       equivTable = borderEquivTable;
-    } else if (aAttribute->EqualsLiteral("align")) {
+    } else if (aAttribute == nsGkAtoms::align) {
       if (aElement->IsHTMLElement(nsGkAtoms::table)) {
         equivTable = tableAlignEquivTable;
       } else if (aElement->IsHTMLElement(nsGkAtoms::hr)) {
         equivTable = hrAlignEquivTable;
       } else if (aElement->IsAnyOfHTMLElements(nsGkAtoms::legend,
                                                nsGkAtoms::caption)) {
         equivTable = captionAlignEquivTable;
       } else {
         equivTable = textAlignEquivTable;
       }
-    } else if (aAttribute->EqualsLiteral("valign")) {
+    } else if (aAttribute == nsGkAtoms::valign) {
       equivTable = verticalAlignEquivTable;
-    } else if (aAttribute->EqualsLiteral("nowrap")) {
+    } else if (aAttribute == nsGkAtoms::nowrap) {
       equivTable = nowrapEquivTable;
-    } else if (aAttribute->EqualsLiteral("width")) {
+    } else if (aAttribute == nsGkAtoms::width) {
       equivTable = widthEquivTable;
-    } else if (aAttribute->EqualsLiteral("height") ||
+    } else if (aAttribute == nsGkAtoms::height ||
                (aElement->IsHTMLElement(nsGkAtoms::hr) &&
-                aAttribute->EqualsLiteral("size"))) {
+                aAttribute == nsGkAtoms::size)) {
       equivTable = heightEquivTable;
-    } else if (aAttribute->EqualsLiteral("type") &&
+    } else if (aAttribute == nsGkAtoms::type &&
                aElement->IsAnyOfHTMLElements(nsGkAtoms::ol,
                                              nsGkAtoms::ul,
                                              nsGkAtoms::li)) {
       equivTable = listStyleTypeEquivTable;
     }
   }
   if (equivTable) {
     BuildCSSDeclarations(cssPropertyArray, cssValueArray, 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,
+CSSEditUtils::SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
                                           nsIAtom* aProperty,
                                           const nsAString* aAttribute,
                                           const nsAString* aValue,
                                           bool aSuppressTransaction)
 {
-  MOZ_ASSERT(aElement && aProperty);
   MOZ_ASSERT_IF(aAttribute, aValue);
-  int32_t count;
   // This can only fail if SetCSSProperty fails, which should only happen if
   // something is pretty badly wrong.  In this case we assert so that hopefully
   // someone will notice, but there's nothing more sensible to do than just
   // return the count and carry on.
-  nsresult rv = SetCSSEquivalentToHTMLStyle(aElement->AsDOMNode(),
-                                            aProperty, aAttribute,
-                                            aValue, &count,
-                                            aSuppressTransaction);
-  NS_ASSERTION(NS_SUCCEEDED(rv), "SetCSSEquivalentToHTMLStyle failed");
-  NS_ENSURE_SUCCESS(rv, count);
-  return count;
+  nsCOMPtr<Element> element = do_QueryInterface(aNode);
+  return SetCSSEquivalentToHTMLStyle(element,
+                                     aProperty, aAttribute,
+                                     aValue, aSuppressTransaction);
 }
 
-nsresult
-CSSEditUtils::SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
+int32_t
+CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
                                           nsIAtom* aHTMLProperty,
                                           const nsAString* aAttribute,
                                           const nsAString* aValue,
-                                          int32_t* aCount,
                                           bool aSuppressTransaction)
 {
-  nsCOMPtr<Element> element = do_QueryInterface(aNode);
-  *aCount = 0;
-  if (!element || !IsCSSEditableProperty(element, aHTMLProperty, aAttribute)) {
-    return NS_OK;
+  nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
+  return SetCSSEquivalentToHTMLStyle(aElement, aHTMLProperty, attribute,
+                                     aValue, aSuppressTransaction);
+}
+
+int32_t
+CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
+                                          nsIAtom* aHTMLProperty,
+                                          nsIAtom* aAttribute,
+                                          const nsAString* aValue,
+                                          bool aSuppressTransaction)
+{
+  MOZ_ASSERT(aElement);
+
+  if (!IsCSSEditableProperty(aElement, 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<nsIAtom*> cssPropertyArray;
   nsTArray<nsString> cssValueArray;
-  GenerateCSSDeclarationsFromHTMLStyle(element, aHTMLProperty, aAttribute,
+  GenerateCSSDeclarationsFromHTMLStyle(aElement, aHTMLProperty, aAttribute,
                                        aValue, cssPropertyArray, cssValueArray,
                                        false);
 
   // set the individual CSS inline styles
-  *aCount = cssPropertyArray.Length();
-  for (int32_t index = 0; index < *aCount; index++) {
-    nsresult rv = SetCSSProperty(*element, *cssPropertyArray[index],
+  int32_t count = cssPropertyArray.Length();
+  for (int32_t index = 0; index < count; index++) {
+    nsresult rv = SetCSSProperty(*aElement, *cssPropertyArray[index],
                                  cssValueArray[index], aSuppressTransaction);
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return 0;
+    }
   }
-  return NS_OK;
+  return count;
 }
 
 // Remove from aNode the CSS inline style equivalent to HTMLProperty/aAttribute/aValue for the node
 nsresult
 CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
                                              nsIAtom* aHTMLProperty,
                                              const nsAString* aAttribute,
                                              const nsAString* aValue,
                                              bool aSuppressTransaction)
 {
   nsCOMPtr<Element> element = do_QueryInterface(aNode);
-  NS_ENSURE_TRUE(element, NS_OK);
+  nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
 
-  return RemoveCSSEquivalentToHTMLStyle(element, aHTMLProperty, aAttribute,
+  return RemoveCSSEquivalentToHTMLStyle(element, aHTMLProperty, attribute,
                                         aValue, aSuppressTransaction);
 }
 
 nsresult
 CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(Element* aElement,
                                              nsIAtom* aHTMLProperty,
-                                             const nsAString* aAttribute,
+                                             nsIAtom* aAttribute,
                                              const nsAString* aValue,
                                              bool aSuppressTransaction)
 {
-  MOZ_ASSERT(aElement);
+  if (!aElement) {
+    return NS_OK;
+  }
 
   if (!IsCSSEditableProperty(aElement, aHTMLProperty, aAttribute)) {
     return NS_OK;
   }
 
   // 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
 
@@ -998,34 +1008,35 @@ CSSEditUtils::RemoveCSSEquivalentToHTMLS
 
 // returns in aValueString the list of values for the CSS equivalences to
 // the HTML style aHTMLProperty/aAttribute/aValueString for the node aNode;
 // the value of aStyleType controls the styles we retrieve : specified or
 // computed.
 nsresult
 CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
                                                    nsIAtom* aHTMLProperty,
-                                                   const nsAString* aAttribute,
+                                                   nsIAtom* aAttribute,
                                                    nsAString& aValueString,
                                                    StyleType aStyleType)
 {
   aValueString.Truncate();
   nsCOMPtr<Element> theElement = GetElementContainerOrSelf(aNode);
   NS_ENSURE_TRUE(theElement, NS_ERROR_NULL_POINTER);
 
   if (!theElement || !IsCSSEditableProperty(theElement, aHTMLProperty, aAttribute)) {
     return NS_OK;
   }
 
   // Yes, the requested HTML style has a CSS equivalence in this implementation
   nsTArray<nsIAtom*> cssPropertyArray;
   nsTArray<nsString> cssValueArray;
   // get the CSS equivalence with last param true indicating we want only the
   // "gettable" properties
-  GenerateCSSDeclarationsFromHTMLStyle(theElement, aHTMLProperty, aAttribute, nullptr,
+  GenerateCSSDeclarationsFromHTMLStyle(theElement, aHTMLProperty, aAttribute,
+                                       nullptr,
                                        cssPropertyArray, cssValueArray, true);
   int32_t count = cssPropertyArray.Length();
   for (int32_t index = 0; index < count; index++) {
     nsAutoString valueString;
     // retrieve the specified/computed value of the property
     nsresult rv = GetCSSInlinePropertyBase(theElement, cssPropertyArray[index],
                                            valueString, aStyleType);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -1061,91 +1072,100 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlin
 bool
 CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
                                                   nsIAtom* aProperty,
                                                   const nsAString* aAttribute,
                                                   nsAString& aValue,
                                                   StyleType aStyleType)
 {
   MOZ_ASSERT(aNode && aProperty);
-  bool isSet;
-  nsresult rv = IsCSSEquivalentToHTMLInlineStyleSet(aNode->AsDOMNode(),
-                                                    aProperty, aAttribute,
-                                                    isSet, aValue, aStyleType);
-  NS_ENSURE_SUCCESS(rv, false);
-  return isSet;
+  nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
+  return IsCSSEquivalentToHTMLInlineStyleSet(aNode,
+                                             aProperty, attribute,
+                                             aValue, aStyleType);
 }
 
-nsresult
+bool
+CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode* aNode,
+                                                  nsIAtom* aProperty,
+                                                  const nsAString* aAttribute,
+                                                  nsAString& aValue,
+                                                  StyleType aStyleType)
+{
+  MOZ_ASSERT(aNode && aProperty);
+  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+  nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
+  return IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty, attribute,
+                                             aValue, aStyleType);
+}
+
+bool
 CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
-                nsIDOMNode* aNode,
+                nsINode* aNode,
                 nsIAtom* aHTMLProperty,
-                const nsAString* aHTMLAttribute,
-                bool& aIsSet,
+                nsIAtom* aHTMLAttribute,
                 nsAString& valueString,
                 StyleType aStyleType)
 {
-  NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
+  NS_ENSURE_TRUE(aNode, false);
 
   nsAutoString htmlValueString(valueString);
-  aIsSet = false;
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+  bool isSet = false;
   do {
     valueString.Assign(htmlValueString);
     // get the value of the CSS equivalent styles
     nsresult rv =
-      GetCSSEquivalentToHTMLInlineStyleSet(node, aHTMLProperty, aHTMLAttribute,
+      GetCSSEquivalentToHTMLInlineStyleSet(aNode, aHTMLProperty, aHTMLAttribute,
                                            valueString, aStyleType);
-    NS_ENSURE_SUCCESS(rv, rv);
+    NS_ENSURE_SUCCESS(rv, false);
 
     // early way out if we can
     if (valueString.IsEmpty()) {
-      return NS_OK;
+      return isSet;
     }
 
     if (nsGkAtoms::b == aHTMLProperty) {
       if (valueString.EqualsLiteral("bold")) {
-        aIsSet = true;
+        isSet = true;
       } else if (valueString.EqualsLiteral("normal")) {
-        aIsSet = false;
+        isSet = false;
       } else if (valueString.EqualsLiteral("bolder")) {
-        aIsSet = true;
+        isSet = true;
         valueString.AssignLiteral("bold");
       } else {
         int32_t weight = 0;
         nsresult errorCode;
         nsAutoString value(valueString);
         weight = value.ToInteger(&errorCode);
         if (400 < weight) {
-          aIsSet = true;
+          isSet = true;
           valueString.AssignLiteral("bold");
         } else {
-          aIsSet = false;
+          isSet = false;
           valueString.AssignLiteral("normal");
         }
       }
     } else if (nsGkAtoms::i == aHTMLProperty) {
       if (valueString.EqualsLiteral("italic") ||
           valueString.EqualsLiteral("oblique")) {
-        aIsSet = true;
+        isSet = true;
       }
     } else if (nsGkAtoms::u == aHTMLProperty) {
       nsAutoString val;
       val.AssignLiteral("underline");
-      aIsSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
+      isSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
     } else if (nsGkAtoms::strike == aHTMLProperty) {
       nsAutoString val;
       val.AssignLiteral("line-through");
-      aIsSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
-    } else if (aHTMLAttribute &&
-               ((nsGkAtoms::font == aHTMLProperty &&
-                 aHTMLAttribute->EqualsLiteral("color")) ||
-                aHTMLAttribute->EqualsLiteral("bgcolor"))) {
+      isSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
+    } else if ((nsGkAtoms::font == aHTMLProperty &&
+                 aHTMLAttribute == nsGkAtoms::color) ||
+                aHTMLAttribute == nsGkAtoms::bgcolor) {
       if (htmlValueString.IsEmpty()) {
-        aIsSet = true;
+        isSet = true;
       } else {
         nscolor rgba;
         nsAutoString subStr;
         htmlValueString.Right(subStr, htmlValueString.Length() - 1);
         if (NS_ColorNameToRGB(htmlValueString, &rgba) ||
             NS_HexToRGBA(subStr, nsHexColorType::NoAlpha, &rgba)) {
           nsAutoString htmlColor, tmpStr;
 
@@ -1169,64 +1189,63 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlin
 
             tmpStr.Truncate();
             tmpStr.AppendInt(NS_GET_B(rgba), 10);
             htmlColor.Append(tmpStr);
 
             htmlColor.Append(char16_t(')'));
           }
 
-          aIsSet = htmlColor.Equals(valueString,
-                                    nsCaseInsensitiveStringComparator());
+          isSet = htmlColor.Equals(valueString,
+                                   nsCaseInsensitiveStringComparator());
         } else {
-          aIsSet = htmlValueString.Equals(valueString,
-                                    nsCaseInsensitiveStringComparator());
+          isSet = htmlValueString.Equals(valueString,
+                                         nsCaseInsensitiveStringComparator());
         }
       }
     } else if (nsGkAtoms::tt == aHTMLProperty) {
-      aIsSet = StringBeginsWith(valueString, NS_LITERAL_STRING("monospace"));
+      isSet = StringBeginsWith(valueString, NS_LITERAL_STRING("monospace"));
     } else if (nsGkAtoms::font == aHTMLProperty && aHTMLAttribute &&
-               aHTMLAttribute->EqualsLiteral("face")) {
+               aHTMLAttribute == nsGkAtoms::face) {
       if (!htmlValueString.IsEmpty()) {
         const char16_t commaSpace[] = { char16_t(','), char16_t(' '), 0 };
         const char16_t comma[] = { char16_t(','), 0 };
         htmlValueString.ReplaceSubstring(commaSpace, comma);
         nsAutoString valueStringNorm(valueString);
         valueStringNorm.ReplaceSubstring(commaSpace, comma);
-        aIsSet = htmlValueString.Equals(valueStringNorm,
-                                        nsCaseInsensitiveStringComparator());
+        isSet = htmlValueString.Equals(valueStringNorm,
+                                       nsCaseInsensitiveStringComparator());
       } else {
-        aIsSet = true;
+        isSet = true;
       }
-      return NS_OK;
-    } else if (aHTMLAttribute && aHTMLAttribute->EqualsLiteral("align")) {
-      aIsSet = true;
+      return isSet;
+    } else if (aHTMLAttribute == nsGkAtoms::align) {
+      isSet = true;
     } else {
-      aIsSet = false;
-      return NS_OK;
+      return false;
     }
 
     if (!htmlValueString.IsEmpty() &&
         htmlValueString.Equals(valueString,
                                nsCaseInsensitiveStringComparator())) {
-      aIsSet = true;
+      isSet = true;
     }
 
     if (htmlValueString.EqualsLiteral("-moz-editor-invert-value")) {
-      aIsSet = !aIsSet;
+      isSet = !isSet;
     }
 
     if (nsGkAtoms::u == aHTMLProperty || nsGkAtoms::strike == aHTMLProperty) {
       // unfortunately, the value of the text-decoration property is not inherited.
       // that means that we have to look at ancestors of node to see if they are underlined
-      node = node->GetParentElement();  // set to null if it's not a dom element
+      aNode = aNode->GetParentElement(); // set to null if it's not a dom element
     }
   } while ((nsGkAtoms::u == aHTMLProperty ||
-            nsGkAtoms::strike == aHTMLProperty) && !aIsSet && node);
-  return NS_OK;
+            nsGkAtoms::strike == aHTMLProperty) && !isSet && aNode);
+  return isSet;
 }
 
 void
 CSSEditUtils::SetCSSEnabled(bool aIsCSSPrefChecked)
 {
   mIsCSSPrefChecked = aIsCSSPrefChecked;
 }
 
--- a/editor/libeditor/CSSEditUtils.h
+++ b/editor/libeditor/CSSEditUtils.h
@@ -85,16 +85,18 @@ public:
    * @param aProperty      [IN] An atom containing a HTML tag name.
    * @param aAttribute     [IN] A string containing the name of a HTML
    *                            attribute carried by the element above.
    * @return               A boolean saying if the tag/attribute has a CSS
    *                       equiv.
    */
   bool IsCSSEditableProperty(nsINode* aNode, nsIAtom* aProperty,
                              const nsAString* aAttribute);
+  bool IsCSSEditableProperty(nsINode* aNode, nsIAtom* aProperty,
+                             nsIAtom* aAttribute);
 
   /**
    * Adds/remove a CSS declaration to the STYLE atrribute carried by a given
    * element.
    *
    * @param aElement       [IN] A DOM element.
    * @param aProperty      [IN] An atom containing the CSS property to set.
    * @param aValue         [IN] A string containing the value of the CSS
@@ -183,89 +185,94 @@ public:
   void GetDefaultLengthUnit(nsAString & aLengthUnit);
 
   /**
    * Returns the list of values for the CSS equivalences to
    * the passed HTML style for the passed node.
    *
    * @param aNode          [IN] A DOM node.
    * @param aHTMLProperty  [IN] An atom containing an HTML property.
-   * @param aAttribute     [IN] A pointer to an attribute name or nullptr if
+   * @param aAttribute     [IN] An atom of attribute name or nullptr if
    *                            irrelevant.
    * @param aValueString   [OUT] The list of CSS values.
    * @param aStyleType     [IN] eSpecified or eComputed.
    */
   nsresult GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
                                                 nsIAtom* aHTMLProperty,
-                                                const nsAString* aAttribute,
+                                                nsIAtom* aAttribute,
                                                 nsAString& aValueString,
                                                 StyleType aStyleType);
 
   /**
    * Does the node aNode (or his parent if it is not an element node) carries
    * the CSS equivalent styles to the HTML style for this node ?
    *
    * @param aNode          [IN] A DOM node.
    * @param aHTMLProperty  [IN] An atom containing an HTML property.
-   * @param aAttribute     [IN] A pointer to an attribute name or nullptr if
-   *                            irrelevant.
-   * @param aIsSet         [OUT] A boolean being true if the css properties are
-   *                             set.
+   * @param aAttribute     [IN] A pointer/atom to an attribute name or nullptr
+   *                            if irrelevant.
    * @param aValueString   [IN/OUT] The attribute value (in) the list of CSS
    *                                values (out).
    * @param aStyleType     [IN] eSpecified or eComputed.
-   *
-   * The nsIContent variant returns aIsSet instead of using an out parameter.
+   * @return               A boolean being true if the css properties are
+   *                       set.
    */
   bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent,
                                            nsIAtom* aProperty,
+                                           nsIAtom* aAttribute,
+                                           nsAString& aValue,
+                                           StyleType aStyleType);
+
+  bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent,
+                                           nsIAtom* aProperty,
                                            const nsAString* aAttribute,
                                            const nsAString& aValue,
                                            StyleType aStyleType);
 
   bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent,
                                            nsIAtom* aProperty,
                                            const nsAString* aAttribute,
                                            nsAString& aValue,
                                            StyleType aStyleType);
 
-  nsresult IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode* aNode,
-                                               nsIAtom* aHTMLProperty,
-                                               const nsAString* aAttribute,
-                                               bool& aIsSet,
-                                               nsAString& aValueString,
-                                               StyleType aStyleType);
+  bool IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode* aNode,
+                                           nsIAtom* aProperty,
+                                           const nsAString* aAttribute,
+                                           nsAString& aValue,
+                                           StyleType aStyleType);
 
   /**
    * 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] A pointer to an attribute name or nullptr if
-   *                            irrelevant.
+   * @param aAttribute     [IN] A pointer/atom to an attribute name or nullptr
+   *                            if irrelevant.
    * @param aValue         [IN] The attribute value.
-   * @param aCount         [OUT] The number of CSS properties set by the call.
    * @param aSuppressTransaction [IN] A boolean indicating, when true,
    *                                  that no transaction should be recorded.
    *
-   * aCount is returned by the dom::Element variant instead of being an out
-   * parameter.
+   * @return               The number of CSS properties set by the call.
    */
   int32_t SetCSSEquivalentToHTMLStyle(dom::Element* aElement,
                                       nsIAtom* aProperty,
+                                      nsIAtom* aAttribute,
+                                      const nsAString* aValue,
+                                      bool aSuppressTransaction);
+  int32_t SetCSSEquivalentToHTMLStyle(dom::Element* aElement,
+                                      nsIAtom* aProperty,
                                       const nsAString* aAttribute,
                                       const nsAString* aValue,
                                       bool aSuppressTransaction);
-  nsresult SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
-                                       nsIAtom* aHTMLProperty,
-                                       const nsAString* aAttribute,
-                                       const nsAString* aValue,
-                                       int32_t* aCount,
-                                       bool aSuppressTransaction);
+  int32_t SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
+                                      nsIAtom* aHTMLProperty,
+                                      const nsAString* aAttribute,
+                                      const nsAString* aValue,
+                                      bool aSuppressTransaction);
 
   /**
    * Removes from the node the CSS inline styles equivalent to the HTML style.
    *
    * @param aNode          [IN] A DOM node.
    * @param aHTMLProperty  [IN] An atom containing an HTML property.
    * @param aAttribute     [IN] A pointer to an attribute name or nullptr if
    *                            irrelevant.
@@ -279,25 +286,25 @@ public:
                                           const nsAString* aValue,
                                           bool aSuppressTransaction);
 
   /**
    * Removes from the node the CSS inline styles equivalent to the HTML style.
    *
    * @param aElement       [IN] A DOM Element (must not be null).
    * @param aHTMLProperty  [IN] An atom containing an HTML property.
-   * @param aAttribute     [IN] A pointer to an attribute name or nullptr if
+   * @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.
    */
   nsresult RemoveCSSEquivalentToHTMLStyle(dom::Element* aElement,
                                           nsIAtom* aHTMLProperty,
-                                          const nsAString* aAttribute,
+                                          nsIAtom* aAttribute,
                                           const nsAString* aValue,
                                           bool aSuppressTransaction);
 
   /**
    * Parses a "xxxx.xxxxxuuu" string where x is a digit and u an alpha char
    * we need such a parser because
    * nsIDOMCSSStyleDeclaration::GetPropertyCSSValue() is not implemented.
    *
@@ -404,30 +411,30 @@ private:
                             bool aGetOrRemoveRequest);
 
   /**
    * Retrieves the CSS declarations equivalent to the given HTML
    * property/attribute/value for a given node.
    *
    * @param aNode              [IN] The DOM node.
    * @param aHTMLProperty      [IN] An atom containing an HTML property.
-   * @param aAttribute         [IN] A pointer to an attribute name or nullptr
+   * @param aAttribute         [IN] An atom to an attribute name or nullptr
    *                                if irrelevant
    * @param aValue             [IN] The attribute value.
    * @param aPropertyArray     [OUT] The array of CSS properties.
    * @param aValueArray        [OUT] The array of values for the CSS properties
    *                                 above.
    * @param aGetOrRemoveRequest [IN] A boolean value being true if the call to
    *                                 the current method is made for
    *                                 GetCSSEquivalentToHTMLInlineStyleSet() or
    *                                 RemoveCSSEquivalentToHTMLInlineStyleSet().
    */
   void GenerateCSSDeclarationsFromHTMLStyle(dom::Element* aNode,
                                             nsIAtom* aHTMLProperty,
-                                            const nsAString* aAttribute,
+                                            nsIAtom* aAttribute,
                                             const nsAString* aValue,
                                             nsTArray<nsIAtom*>& aPropertyArray,
                                             nsTArray<nsString>& aValueArray,
                                             bool aGetOrRemoveRequest);
 
   /**
    * Creates a Transaction for setting or removing a CSS property.  Never
    * returns null.
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -833,29 +833,28 @@ HTMLEditRules::GetAlignment(bool* aMixed
     nsresult rv = GetNodesForOperation(arrayOfRanges, arrayOfNodes,
                                        EditAction::align, TouchContent::no);
     NS_ENSURE_SUCCESS(rv, rv);
     nodeToExamine = arrayOfNodes.SafeElementAt(0);
   }
 
   NS_ENSURE_TRUE(nodeToExamine, NS_ERROR_NULL_POINTER);
 
-  NS_NAMED_LITERAL_STRING(typeAttrName, "align");
   nsCOMPtr<Element> blockParent = htmlEditor->GetBlock(*nodeToExamine);
 
   NS_ENSURE_TRUE(blockParent, NS_ERROR_FAILURE);
 
   if (htmlEditor->IsCSSEnabled() &&
       htmlEditor->mCSSEditUtils->IsCSSEditableProperty(blockParent, nullptr,
-                                                        &typeAttrName)) {
+                                                       nsGkAtoms::align)) {
     // We are in CSS mode and we know how to align this element with CSS
     nsAutoString value;
     // Let's get the value(s) of text-align or margin-left/margin-right
     htmlEditor->mCSSEditUtils->GetCSSEquivalentToHTMLInlineStyleSet(
-        blockParent, nullptr, &typeAttrName, value, CSSEditUtils::eComputed);
+        blockParent, nullptr, nsGkAtoms::align, value, CSSEditUtils::eComputed);
     if (value.EqualsLiteral("center") ||
         value.EqualsLiteral("-moz-center") ||
         value.EqualsLiteral("auto auto")) {
       *aAlign = nsIHTMLEditor::eCenter;
       return NS_OK;
     }
     if (value.EqualsLiteral("right") ||
         value.EqualsLiteral("-moz-right") ||
@@ -4722,17 +4721,17 @@ HTMLEditRules::WillAlign(Selection& aSel
     // If it's a list item, or a list inside a list, forget any "current" div,
     // and instead put divs inside the appropriate block (td, li, etc.)
     if (HTMLEditUtils::IsListItem(curNode) ||
         HTMLEditUtils::IsList(curNode)) {
       rv = RemoveAlignment(GetAsDOMNode(curNode), aAlignType, true);
       NS_ENSURE_SUCCESS(rv, rv);
       if (useCSS) {
         htmlEditor->mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
-            curNode->AsElement(), nullptr, &NS_LITERAL_STRING("align"),
+            curNode->AsElement(), nullptr, nsGkAtoms::align,
             &aAlignType, false);
         curDiv = nullptr;
         continue;
       }
       if (HTMLEditUtils::IsList(curParent)) {
         // If we don't use CSS, add a contraint to list element: they have to
         // be inside another list, i.e., >= second level of nesting
         rv = AlignInnerBlocks(*curNode, &aAlignType);
@@ -7088,19 +7087,19 @@ HTMLEditRules::CacheInlineStyles(nsIDOMN
     if (!useCSS || (mCachedStyles[j].tag == nsGkAtoms::font &&
                     mCachedStyles[j].attr.EqualsLiteral("size"))) {
       NS_ENSURE_STATE(mHTMLEditor);
       mHTMLEditor->IsTextPropertySetByContent(aNode, mCachedStyles[j].tag,
                                               &(mCachedStyles[j].attr), nullptr,
                                               isSet, &outValue);
     } else {
       NS_ENSURE_STATE(mHTMLEditor);
-      mHTMLEditor->mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(aNode,
-        mCachedStyles[j].tag, &(mCachedStyles[j].attr), isSet, outValue,
-        CSSEditUtils::eComputed);
+      isSet = mHTMLEditor->mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(
+                aNode, mCachedStyles[j].tag, &(mCachedStyles[j].attr), outValue,
+                CSSEditUtils::eComputed);
     }
     if (isSet) {
       mCachedStyles[j].mPresent = true;
       mCachedStyles[j].value.Assign(outValue);
     }
   }
   return NS_OK;
 }
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -4450,58 +4450,64 @@ nsresult
 HTMLEditor::SetAttributeOrEquivalent(nsIDOMElement* aElement,
                                      const nsAString& aAttribute,
                                      const nsAString& aValue,
                                      bool aSuppressTransaction)
 {
   nsAutoScriptBlocker scriptBlocker;
 
   if (IsCSSEnabled() && mCSSEditUtils) {
-    int32_t count;
-    nsresult rv =
-      mCSSEditUtils->SetCSSEquivalentToHTMLStyle(aElement, nullptr,
-                                                 &aAttribute, &aValue,
-                                                 &count,
+    nsCOMPtr<dom::Element> element = do_QueryInterface(aElement);
+    MOZ_ASSERT(element);
+
+    nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
+    MOZ_ASSERT(attribute);
+
+    int32_t count =
+      mCSSEditUtils->SetCSSEquivalentToHTMLStyle(element, nullptr,
+                                                 attribute, &aValue,
                                                  aSuppressTransaction);
-    NS_ENSURE_SUCCESS(rv, rv);
     if (count) {
       // we found an equivalence ; let's remove the HTML attribute itself if it is set
       nsAutoString existingValue;
       bool wasSet = false;
-      rv = GetAttributeValue(aElement, aAttribute, existingValue, &wasSet);
+      nsresult rv =
+        GetAttributeValue(aElement, aAttribute, existingValue, &wasSet);
       NS_ENSURE_SUCCESS(rv, rv);
       if (!wasSet) {
         return NS_OK;
       }
-      return aSuppressTransaction ? aElement->RemoveAttribute(aAttribute) :
-                                    RemoveAttribute(aElement, aAttribute);
+      return aSuppressTransaction ?
+               element->UnsetAttr(kNameSpaceID_None, attribute, true) :
+               RemoveAttribute(aElement, aAttribute);
     }
 
     // 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.EqualsLiteral("style")) {
+    if (attribute == nsGkAtoms::style) {
       // if it is the style attribute, just add the new value to the existing style
       // attribute's value
       nsAutoString existingValue;
       bool wasSet = false;
       nsresult rv = GetAttributeValue(aElement, NS_LITERAL_STRING("style"),
                                       existingValue, &wasSet);
       NS_ENSURE_SUCCESS(rv, rv);
       existingValue.Append(' ');
       existingValue.Append(aValue);
       return aSuppressTransaction ?
-        aElement->SetAttribute(aAttribute, existingValue) :
+        element->SetAttr(kNameSpaceID_None, attribute, existingValue, true) :
         SetAttribute(aElement, aAttribute, existingValue);
     }
 
     // we have no CSS equivalence for this attribute and it is not the style
     // attribute; let's set it the good'n'old HTML way
-    return aSuppressTransaction ? aElement->SetAttribute(aAttribute, aValue) :
-                                  SetAttribute(aElement, aAttribute, aValue);
+    return aSuppressTransaction ?
+             element->SetAttr(kNameSpaceID_None, attribute, aValue, true) :
+             SetAttribute(aElement, aAttribute, aValue);
   }
 
   // we are not in an HTML+CSS editor; let's set the attribute the HTML way
   return aSuppressTransaction ? aElement->SetAttribute(aAttribute, aValue) :
                                 SetAttribute(aElement, aAttribute, aValue);
 }
 
 nsresult
@@ -4513,17 +4519,17 @@ HTMLEditor::RemoveAttributeOrEquivalent(
   NS_ENSURE_TRUE(element, NS_OK);
 
   nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
   MOZ_ASSERT(attribute);
 
   if (IsCSSEnabled() && mCSSEditUtils) {
     nsresult rv =
       mCSSEditUtils->RemoveCSSEquivalentToHTMLStyle(
-        element, nullptr, &aAttribute, nullptr, aSuppressTransaction);
+        element, nullptr, attribute, nullptr, aSuppressTransaction);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (!element->HasAttr(kNameSpaceID_None, attribute)) {
     return NS_OK;
   }
 
   return aSuppressTransaction ?
@@ -4575,17 +4581,16 @@ HTMLEditor::SetCSSBackgroundColor(const 
   AutoTransactionsConserveSelection dontSpazMySelection(this);
 
   bool cancel, handled;
   TextRulesInfo ruleInfo(EditAction::setTextProperty);
   nsresult rv = rules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!cancel && !handled) {
     // Loop through the ranges in the selection
-    NS_NAMED_LITERAL_STRING(bgcolor, "bgcolor");
     for (uint32_t i = 0; i < selection->RangeCount(); i++) {
       RefPtr<nsRange> range = selection->GetRangeAt(i);
       NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
 
       nsCOMPtr<Element> cachedBlockParent;
 
       // Check for easy case: both range endpoints in same text node
       nsCOMPtr<nsINode> startNode = range->GetStartParent();
@@ -4594,34 +4599,37 @@ HTMLEditor::SetCSSBackgroundColor(const 
       int32_t endOffset = range->EndOffset();
       if (startNode == endNode && IsTextNode(startNode)) {
         // Let's find the block container of the text node
         nsCOMPtr<Element> blockParent = GetBlockNodeParent(startNode);
         // And apply the background color to that block container
         if (blockParent && cachedBlockParent != blockParent) {
           cachedBlockParent = blockParent;
           mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
-                                                     &bgcolor, &aColor, false);
+                                                     nsGkAtoms::bgcolor,
+                                                     &aColor, false);
         }
       } else if (startNode == endNode &&
                  startNode->IsHTMLElement(nsGkAtoms::body) && isCollapsed) {
         // No block in the document, let's apply the background to the body
         mCSSEditUtils->SetCSSEquivalentToHTMLStyle(startNode->AsElement(),
-                                                   nullptr, &bgcolor, &aColor,
+                                                   nullptr, nsGkAtoms::bgcolor,
+                                                   &aColor,
                                                    false);
       } else if (startNode == endNode && (endOffset - startOffset == 1 ||
                                           (!startOffset && !endOffset))) {
         // A unique node is selected, let's also apply the background color to
         // the containing block, possibly the node itself
         nsCOMPtr<nsIContent> selectedNode = startNode->GetChildAt(startOffset);
         nsCOMPtr<Element> blockParent = GetBlock(*selectedNode);
         if (blockParent && cachedBlockParent != blockParent) {
           cachedBlockParent = blockParent;
           mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
-                                                     &bgcolor, &aColor, false);
+                                                     nsGkAtoms::bgcolor,
+                                                     &aColor, false);
         }
       } else {
         // Not the easy case.  Range not contained in single text node.  There
         // are up to three phases here.  There are all the nodes reported by
         // the subtree iterator to be processed.  And there are potentially a
         // starting textnode and an ending textnode which are only partially
         // contained by the range.
 
@@ -4654,42 +4662,45 @@ HTMLEditor::SetCSSBackgroundColor(const 
         // First check the start parent of the range to see if it needs to be
         // separately handled (it does if it's a text node, due to how the
         // subtree iterator works - it will not have reported it).
         if (IsTextNode(startNode) && IsEditable(startNode)) {
           nsCOMPtr<Element> blockParent = GetBlockNodeParent(startNode);
           if (blockParent && cachedBlockParent != blockParent) {
             cachedBlockParent = blockParent;
             mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
-                                                       &bgcolor, &aColor,
+                                                       nsGkAtoms::bgcolor,
+                                                       &aColor,
                                                        false);
           }
         }
 
         // Then loop through the list, set the property on each node
         for (auto& node : arrayOfNodes) {
           nsCOMPtr<Element> blockParent = GetBlock(node);
           if (blockParent && cachedBlockParent != blockParent) {
             cachedBlockParent = blockParent;
             mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
-                                                       &bgcolor, &aColor,
+                                                       nsGkAtoms::bgcolor,
+                                                       &aColor,
                                                        false);
           }
         }
         arrayOfNodes.Clear();
 
         // Last, check the end parent of the range to see if it needs to be
         // separately handled (it does if it's a text node, due to how the
         // subtree iterator works - it will not have reported it).
         if (IsTextNode(endNode) && IsEditable(endNode)) {
           nsCOMPtr<Element> blockParent = GetBlockNodeParent(endNode);
           if (blockParent && cachedBlockParent != blockParent) {
             cachedBlockParent = blockParent;
             mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
-                                                       &bgcolor, &aColor,
+                                                       nsGkAtoms::bgcolor,
+                                                       &aColor,
                                                        false);
           }
         }
       }
     }
   }
   if (!cancel) {
     // Post-process
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -422,37 +422,34 @@ HTMLEditor::SetInlinePropertyOnNodeImpl(
                                         aAttribute, &aValue)) {
     return NS_OK;
   }
 
   bool useCSS = (IsCSSEnabled() &&
                  mCSSEditUtils->IsCSSEditableProperty(&aNode, &aProperty,
                                                       aAttribute)) ||
                 // bgcolor is always done using CSS
-                aAttribute->EqualsLiteral("bgcolor");
+                attrAtom == nsGkAtoms::bgcolor;
 
   if (useCSS) {
     nsCOMPtr<dom::Element> tmp;
     // We only add style="" to <span>s with no attributes (bug 746515).  If we
     // don't have one, we need to make one.
     if (aNode.IsHTMLElement(nsGkAtoms::span) &&
         !aNode.AsElement()->GetAttrCount()) {
       tmp = aNode.AsElement();
     } else {
       tmp = InsertContainerAbove(&aNode, nsGkAtoms::span);
       NS_ENSURE_STATE(tmp);
     }
 
     // Add the CSS styles corresponding to the HTML style request
-    int32_t count;
-    nsresult rv =
-      mCSSEditUtils->SetCSSEquivalentToHTMLStyle(tmp->AsDOMNode(),
-                                                 &aProperty, aAttribute,
-                                                 &aValue, &count, false);
-    NS_ENSURE_SUCCESS(rv, rv);
+    mCSSEditUtils->SetCSSEquivalentToHTMLStyle(tmp,
+                                               &aProperty, attrAtom,
+                                               &aValue, false);
     return NS_OK;
   }
 
   // is it already the right kind of node, but with wrong attribute?
   if (aNode.IsHTMLElement(&aProperty)) {
     // Just set the attribute on it.
     nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(&aNode);
     return SetAttribute(elem, *aAttribute, aValue);
@@ -567,18 +564,19 @@ HTMLEditor::SplitStyleAbovePoint(nsCOMPt
          IsEditable(node->GetParent())) {
     isSet = false;
     if (useCSS && mCSSEditUtils->IsCSSEditableProperty(node, aProperty,
                                                        aAttribute)) {
       // The HTML style defined by aProperty/aAttribute has a CSS equivalence
       // in this implementation for the node; let's check if it carries those
       // CSS styles
       nsAutoString firstValue;
-      mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(GetAsDOMNode(node),
-        aProperty, aAttribute, isSet, firstValue, CSSEditUtils::eSpecified);
+      isSet = mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(
+                node, aProperty, aAttribute, firstValue,
+                CSSEditUtils::eSpecified);
     }
     if (// node is the correct inline prop
         (aProperty && node->IsHTMLElement(aProperty)) ||
         // node is href - test if really <a href=...
         (aProperty == nsGkAtoms::href && HTMLEditUtils::IsLink(node)) ||
         // or node is any prop, and we asked to split them all
         (!aProperty && NodeIsProperty(node)) ||
         // or the style is specified in the style attribute
@@ -779,25 +777,27 @@ HTMLEditor::RemoveStyleInside(nsIContent
     }
   }
 
   if (!aChildrenOnly &&
       mCSSEditUtils->IsCSSEditableProperty(&aNode, aProperty, aAttribute)) {
     // the HTML style defined by aProperty/aAttribute has a CSS equivalence in
     // this implementation for the node aNode; let's check if it carries those
     // css styles
+    nsCOMPtr<nsIAtom> attribute =
+      aAttribute ? NS_Atomize(*aAttribute) : nullptr;
     nsAutoString propertyValue;
     bool isSet = mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(&aNode,
-      aProperty, aAttribute, propertyValue, CSSEditUtils::eSpecified);
+      aProperty, attribute, propertyValue, CSSEditUtils::eSpecified);
     if (isSet && aNode.IsElement()) {
       // yes, tmp has the corresponding css declarations in its style attribute
       // let's remove them
       mCSSEditUtils->RemoveCSSEquivalentToHTMLStyle(aNode.AsElement(),
                                                     aProperty,
-                                                    aAttribute,
+                                                    attribute,
                                                     &propertyValue,
                                                     false);
       // remove the node if it is a span or font, if its style attribute is
       // empty or absent, and if it does not have a class nor an id
       RemoveElementIfNoStyleOrIdOrClass(*aNode.AsElement());
     }
   }