diff options
Diffstat (limited to 'editor/libeditor/CSSEditUtils.cpp')
-rw-r--r-- | editor/libeditor/CSSEditUtils.cpp | 259 |
1 files changed, 139 insertions, 120 deletions
diff --git a/editor/libeditor/CSSEditUtils.cpp b/editor/libeditor/CSSEditUtils.cpp index d8146ca65..dfce858a5 100644 --- a/editor/libeditor/CSSEditUtils.cpp +++ b/editor/libeditor/CSSEditUtils.cpp @@ -320,6 +320,15 @@ 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; @@ -336,13 +345,12 @@ CSSEditUtils::IsCSSEditableProperty(nsINode* aNode, 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, @@ -365,7 +373,7 @@ CSSEditUtils::IsCSSEditableProperty(nsINode* aNode, return true; } - if (aAttribute && (aAttribute->EqualsLiteral("valign")) && + if (aAttribute == nsGkAtoms::valign && node->IsAnyOfHTMLElements(nsGkAtoms::col, nsGkAtoms::colgroup, nsGkAtoms::tbody, @@ -378,59 +386,52 @@ CSSEditUtils::IsCSSEditableProperty(nsINode* aNode, } // 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, @@ -815,7 +816,7 @@ void CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle( Element* aElement, nsIAtom* aHTMLProperty, - const nsAString* aAttribute, + nsIAtom* aAttribute, const nsAString* aValue, nsTArray<nsIAtom*>& cssPropertyArray, nsTArray<nsString>& cssValueArray, @@ -835,21 +836,20 @@ CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle( } 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)) { @@ -860,17 +860,17 @@ CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle( } 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)) { @@ -887,40 +887,46 @@ CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle( // 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 @@ -929,18 +935,20 @@ CSSEditUtils::SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode, // 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], + size_t count = cssPropertyArray.Length(); + for (size_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 @@ -952,20 +960,22 @@ CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(nsIDOMNode* aNode, 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 (NS_WARN_IF(!aElement)) { + return NS_OK; + } if (!IsCSSEditableProperty(aElement, aHTMLProperty, aAttribute)) { return NS_OK; @@ -1000,7 +1010,7 @@ CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(Element* aElement, nsresult CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode, nsIAtom* aHTMLProperty, - const nsAString* aAttribute, + nsIAtom* aAttribute, nsAString& aValueString, StyleType aStyleType) { @@ -1017,7 +1027,8 @@ CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode, 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++) { @@ -1063,48 +1074,58 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode, 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; @@ -1112,32 +1133,31 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet( 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; @@ -1171,54 +1191,53 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet( 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 |