From baa4b609d9ca417295d262bd398812e2941bb77d Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Fri, 22 May 2020 17:13:33 -0400 Subject: Issue #1621 - Part 1: CSSEditUtils should use atom for CSS property if possible. There is a lot of string compare when using CSS property name. We should use nsGkAtoms instead. Ref: Bug 1323138 --- editor/libeditor/CSSEditUtils.cpp | 259 +++++++++++++++++++---------------- editor/libeditor/CSSEditUtils.h | 65 +++++---- editor/libeditor/HTMLEditRules.cpp | 13 +- editor/libeditor/HTMLEditor.cpp | 53 ++++--- editor/libeditor/HTMLStyleEditor.cpp | 22 +-- 5 files changed, 224 insertions(+), 188 deletions(-) diff --git a/editor/libeditor/CSSEditUtils.cpp b/editor/libeditor/CSSEditUtils.cpp index dd15a8730..e15bc278f 100644 --- a/editor/libeditor/CSSEditUtils.cpp +++ b/editor/libeditor/CSSEditUtils.cpp @@ -322,6 +322,15 @@ bool CSSEditUtils::IsCSSEditableProperty(nsINode* aNode, nsIAtom* aProperty, const nsAString* aAttribute) +{ + nsCOMPtr attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr; + return IsCSSEditableProperty(aNode, aProperty, attribute); +} + +bool +CSSEditUtils::IsCSSEditableProperty(nsINode* aNode, + nsIAtom* aProperty, + nsIAtom* aAttribute) { MOZ_ASSERT(aNode); @@ -339,13 +348,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, @@ -368,7 +376,7 @@ CSSEditUtils::IsCSSEditableProperty(nsINode* aNode, return true; } - if (aAttribute && (aAttribute->EqualsLiteral("valign")) && + if (aAttribute == nsGkAtoms::valign && node->IsAnyOfHTMLElements(nsGkAtoms::col, nsGkAtoms::colgroup, nsGkAtoms::tbody, @@ -381,59 +389,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, @@ -818,7 +819,7 @@ void CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle( Element* aElement, nsIAtom* aHTMLProperty, - const nsAString* aAttribute, + nsIAtom* aAttribute, const nsAString* aValue, nsTArray& cssPropertyArray, nsTArray& cssValueArray, @@ -838,21 +839,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)) { @@ -863,17 +863,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)) { @@ -890,40 +890,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 = 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 = do_QueryInterface(aNode); - *aCount = 0; - if (!element || !IsCSSEditableProperty(element, aHTMLProperty, aAttribute)) { - return NS_OK; + nsCOMPtr 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 @@ -932,18 +938,20 @@ CSSEditUtils::SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode, // Find the CSS equivalence to the HTML style nsTArray cssPropertyArray; nsTArray 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 @@ -955,20 +963,22 @@ CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(nsIDOMNode* aNode, bool aSuppressTransaction) { nsCOMPtr element = do_QueryInterface(aNode); - NS_ENSURE_TRUE(element, NS_OK); + nsCOMPtr 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; @@ -1003,7 +1013,7 @@ CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(Element* aElement, nsresult CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode, nsIAtom* aHTMLProperty, - const nsAString* aAttribute, + nsIAtom* aAttribute, nsAString& aValueString, StyleType aStyleType) { @@ -1020,7 +1030,8 @@ CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode, nsTArray 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++) { @@ -1066,48 +1077,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 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 node = do_QueryInterface(aNode); + nsCOMPtr 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 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; @@ -1115,32 +1136,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; @@ -1174,54 +1194,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 diff --git a/editor/libeditor/CSSEditUtils.h b/editor/libeditor/CSSEditUtils.h index 0b9a12952..5129ab88d 100644 --- a/editor/libeditor/CSSEditUtils.h +++ b/editor/libeditor/CSSEditUtils.h @@ -90,6 +90,8 @@ public: */ 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 @@ -188,14 +190,14 @@ public: * * @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); @@ -205,16 +207,20 @@ public: * * @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, @@ -227,12 +233,11 @@ public: 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 @@ -240,27 +245,29 @@ public: * * @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); + int32_t SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode, + nsIAtom* aHTMLProperty, 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); /** * Removes from the node the CSS inline styles equivalent to the HTML style. @@ -284,7 +291,7 @@ public: * * @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, @@ -292,7 +299,7 @@ public: */ nsresult RemoveCSSEquivalentToHTMLStyle(dom::Element* aElement, nsIAtom* aHTMLProperty, - const nsAString* aAttribute, + nsIAtom* aAttribute, const nsAString* aValue, bool aSuppressTransaction); @@ -409,7 +416,7 @@ private: * * @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. @@ -422,7 +429,7 @@ private: */ void GenerateCSSDeclarationsFromHTMLStyle(dom::Element* aNode, nsIAtom* aHTMLProperty, - const nsAString* aAttribute, + nsIAtom* aAttribute, const nsAString* aValue, nsTArray& aPropertyArray, nsTArray& aValueArray, diff --git a/editor/libeditor/HTMLEditRules.cpp b/editor/libeditor/HTMLEditRules.cpp index af4a43ab9..14f6cfe11 100644 --- a/editor/libeditor/HTMLEditRules.cpp +++ b/editor/libeditor/HTMLEditRules.cpp @@ -840,19 +840,18 @@ HTMLEditRules::GetAlignment(bool* aMixed, NS_ENSURE_TRUE(nodeToExamine, NS_ERROR_NULL_POINTER); - NS_NAMED_LITERAL_STRING(typeAttrName, "align"); nsCOMPtr 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")) { @@ -4756,7 +4755,7 @@ HTMLEditRules::WillAlign(Selection& aSelection, 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; @@ -7143,9 +7142,9 @@ HTMLEditRules::CacheInlineStyles(nsIDOMNode* aNode) 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; diff --git a/editor/libeditor/HTMLEditor.cpp b/editor/libeditor/HTMLEditor.cpp index c2f0bdc6d..82ef92042 100644 --- a/editor/libeditor/HTMLEditor.cpp +++ b/editor/libeditor/HTMLEditor.cpp @@ -4398,30 +4398,35 @@ HTMLEditor::SetAttributeOrEquivalent(nsIDOMElement* aElement, nsAutoScriptBlocker scriptBlocker; if (IsCSSEnabled() && mCSSEditUtils) { - int32_t count; - nsresult rv = - mCSSEditUtils->SetCSSEquivalentToHTMLStyle(aElement, nullptr, - &aAttribute, &aValue, - &count, + nsCOMPtr element = do_QueryInterface(aElement); + MOZ_ASSERT(element); + + nsCOMPtr 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; @@ -4432,14 +4437,15 @@ HTMLEditor::SetAttributeOrEquivalent(nsIDOMElement* aElement, 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 @@ -4461,7 +4467,7 @@ HTMLEditor::RemoveAttributeOrEquivalent(nsIDOMElement* aElement, if (IsCSSEnabled() && mCSSEditUtils) { nsresult rv = mCSSEditUtils->RemoveCSSEquivalentToHTMLStyle( - element, nullptr, &aAttribute, nullptr, aSuppressTransaction); + element, nullptr, attribute, nullptr, aSuppressTransaction); NS_ENSURE_SUCCESS(rv, rv); } @@ -4523,7 +4529,6 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor) 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 range = selection->GetRangeAt(i); NS_ENSURE_TRUE(range, NS_ERROR_FAILURE); @@ -4542,13 +4547,15 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor) 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))) { @@ -4559,7 +4566,8 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor) 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 @@ -4602,7 +4610,8 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor) if (blockParent && cachedBlockParent != blockParent) { cachedBlockParent = blockParent; mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr, - &bgcolor, &aColor, + nsGkAtoms::bgcolor, + &aColor, false); } } @@ -4613,7 +4622,8 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor) if (blockParent && cachedBlockParent != blockParent) { cachedBlockParent = blockParent; mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr, - &bgcolor, &aColor, + nsGkAtoms::bgcolor, + &aColor, false); } } @@ -4627,7 +4637,8 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor) if (blockParent && cachedBlockParent != blockParent) { cachedBlockParent = blockParent; mCSSEditUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr, - &bgcolor, &aColor, + nsGkAtoms::bgcolor, + &aColor, false); } } diff --git a/editor/libeditor/HTMLStyleEditor.cpp b/editor/libeditor/HTMLStyleEditor.cpp index 72eb1d690..d3eabba1d 100644 --- a/editor/libeditor/HTMLStyleEditor.cpp +++ b/editor/libeditor/HTMLStyleEditor.cpp @@ -429,7 +429,7 @@ HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode, mCSSEditUtils->IsCSSEditableProperty(&aNode, &aProperty, aAttribute)) || // bgcolor is always done using CSS - aAttribute->EqualsLiteral("bgcolor"); + attrAtom == nsGkAtoms::bgcolor; if (useCSS) { nsCOMPtr tmp; @@ -444,12 +444,9 @@ HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode, } // 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; } @@ -576,8 +573,9 @@ HTMLEditor::SplitStyleAbovePoint(nsCOMPtr* aNode, // 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)) || @@ -796,15 +794,17 @@ HTMLEditor::RemoveStyleInside(nsIContent& aNode, // 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 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 -- cgit v1.2.3 From 1c0c7cf583e6adda168cf59cad3aad3e38e7c058 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Fri, 22 May 2020 18:25:26 -0400 Subject: Issue #1621 - Part 2: Implement nsIAtom version of SetAttribute/RemoveAttribute/CloneAttirubte. Add nsIAtom version of the following. - CloneAttribute - RemoveAttribute - RemoveAttributeOrEquivalent - SetAttribute - SetAttributeOrEquivalent Ref: Bug 1324996 --- editor/libeditor/EditorBase.cpp | 75 +++++++++++++++++++-------- editor/libeditor/EditorBase.h | 13 +++++ editor/libeditor/HTMLEditor.cpp | 110 ++++++++++++++++++---------------------- editor/libeditor/HTMLEditor.h | 18 ++++--- editor/libeditor/TextEditor.cpp | 8 +-- editor/libeditor/TextEditor.h | 19 ++++--- 6 files changed, 143 insertions(+), 100 deletions(-) diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index 3f419a74e..7212e7c93 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -1235,12 +1235,23 @@ EditorBase::SetAttribute(nsIDOMElement* aElement, const nsAString& aAttribute, const nsAString& aValue) { + if (NS_WARN_IF(aAttribute.IsEmpty())) { + return NS_ERROR_FAILURE; + } nsCOMPtr element = do_QueryInterface(aElement); NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER); nsCOMPtr attribute = NS_Atomize(aAttribute); + return SetAttribute(element, attribute, aValue); +} + +nsresult +EditorBase::SetAttribute(Element* aElement, + nsIAtom* aAttribute, + const nsAString& aValue) +{ RefPtr transaction = - CreateTxnForSetAttribute(*element, *attribute, aValue); + CreateTxnForSetAttribute(*aElement, *aAttribute, aValue); return DoTransaction(transaction); } @@ -1269,12 +1280,22 @@ NS_IMETHODIMP EditorBase::RemoveAttribute(nsIDOMElement* aElement, const nsAString& aAttribute) { + if (NS_WARN_IF(aAttribute.IsEmpty())) { + return NS_ERROR_FAILURE; + } nsCOMPtr element = do_QueryInterface(aElement); NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER); nsCOMPtr attribute = NS_Atomize(aAttribute); + return RemoveAttribute(element, attribute); +} + +nsresult +EditorBase::RemoveAttribute(Element* aElement, + nsIAtom* aAttribute) +{ RefPtr transaction = - CreateTxnForRemoveAttribute(*element, *attribute); + CreateTxnForRemoveAttribute(*aElement, *aAttribute); return DoTransaction(transaction); } @@ -2249,25 +2270,28 @@ EditorBase::CloneAttribute(const nsAString& aAttribute, nsIDOMNode* aSourceNode) { NS_ENSURE_TRUE(aDestNode && aSourceNode, NS_ERROR_NULL_POINTER); + if (NS_WARN_IF(aAttribute.IsEmpty())) { + return NS_ERROR_FAILURE; + } - nsCOMPtr destElement = do_QueryInterface(aDestNode); - nsCOMPtr sourceElement = do_QueryInterface(aSourceNode); + nsCOMPtr destElement = do_QueryInterface(aDestNode); + nsCOMPtr sourceElement = do_QueryInterface(aSourceNode); NS_ENSURE_TRUE(destElement && sourceElement, NS_ERROR_NO_INTERFACE); + nsCOMPtr attribute = NS_Atomize(aAttribute); + return CloneAttribute(attribute, destElement, sourceElement); +} + +nsresult +EditorBase::CloneAttribute(nsIAtom* aAttribute, + Element* aDestElement, + Element* aSourceElement) +{ nsAutoString attrValue; - bool isAttrSet; - nsresult rv = GetAttributeValue(sourceElement, - aAttribute, - attrValue, - &isAttrSet); - NS_ENSURE_SUCCESS(rv, rv); - if (isAttrSet) { - rv = SetAttribute(destElement, aAttribute, attrValue); - } else { - rv = RemoveAttribute(destElement, aAttribute); + if (aSourceElement->GetAttr(kNameSpaceID_None, aAttribute, attrValue)) { + return SetAttribute(aDestElement, aAttribute, attrValue); } - - return rv; + return RemoveAttribute(aDestElement, aAttribute); } /** @@ -4678,21 +4702,32 @@ EditorBase::CreateHTMLContent(nsIAtom* aTag) kNameSpaceID_XHTML); } -nsresult +NS_IMETHODIMP EditorBase::SetAttributeOrEquivalent(nsIDOMElement* aElement, const nsAString& aAttribute, const nsAString& aValue, bool aSuppressTransaction) { - return SetAttribute(aElement, aAttribute, aValue); + nsCOMPtr element = do_QueryInterface(aElement); + if (NS_WARN_IF(!element)) { + return NS_ERROR_NULL_POINTER; + } + nsCOMPtr attribute = NS_Atomize(aAttribute); + return SetAttributeOrEquivalent(element, attribute, aValue, + aSuppressTransaction); } -nsresult +NS_IMETHODIMP EditorBase::RemoveAttributeOrEquivalent(nsIDOMElement* aElement, const nsAString& aAttribute, bool aSuppressTransaction) { - return RemoveAttribute(aElement, aAttribute); + nsCOMPtr element = do_QueryInterface(aElement); + if (NS_WARN_IF(!element)) { + return NS_ERROR_NULL_POINTER; + } + nsCOMPtr attribute = NS_Atomize(aAttribute); + return RemoveAttributeOrEquivalent(element, attribute, aSuppressTransaction); } nsresult diff --git a/editor/libeditor/EditorBase.h b/editor/libeditor/EditorBase.h index 618da12a8..08a895dcd 100644 --- a/editor/libeditor/EditorBase.h +++ b/editor/libeditor/EditorBase.h @@ -291,6 +291,19 @@ public: nsresult JoinNodes(nsINode& aLeftNode, nsINode& aRightNode); nsresult MoveNode(nsIContent* aNode, nsINode* aParent, int32_t aOffset); + nsresult CloneAttribute(nsIAtom* aAttribute, Element* aDestElement, + Element* aSourceElement); + nsresult RemoveAttribute(Element* aElement, nsIAtom* aAttribute); + virtual nsresult RemoveAttributeOrEquivalent(Element* aElement, + nsIAtom* aAttribute, + bool aSuppressTransaction) = 0; + nsresult SetAttribute(Element* aElement, nsIAtom* aAttribute, + const nsAString& aValue); + virtual nsresult SetAttributeOrEquivalent(Element* aElement, + nsIAtom* aAttribute, + const nsAString& aValue, + bool aSuppressTransaction) = 0; + /** * Method to replace certain CreateElementNS() calls. * diff --git a/editor/libeditor/HTMLEditor.cpp b/editor/libeditor/HTMLEditor.cpp index 82ef92042..4cda49ab5 100644 --- a/editor/libeditor/HTMLEditor.cpp +++ b/editor/libeditor/HTMLEditor.cpp @@ -4390,93 +4390,83 @@ HTMLEditor::IsEmptyNodeImpl(nsINode* aNode, // add to aElement the CSS inline styles corresponding to the HTML attribute // aAttribute with its value aValue nsresult -HTMLEditor::SetAttributeOrEquivalent(nsIDOMElement* aElement, - const nsAString& aAttribute, +HTMLEditor::SetAttributeOrEquivalent(Element* aElement, + nsIAtom* aAttribute, const nsAString& aValue, bool aSuppressTransaction) { + MOZ_ASSERT(aElement); + MOZ_ASSERT(aAttribute); + nsAutoScriptBlocker scriptBlocker; - if (IsCSSEnabled() && mCSSEditUtils) { - nsCOMPtr element = do_QueryInterface(aElement); - MOZ_ASSERT(element); - - nsCOMPtr attribute = NS_Atomize(aAttribute); - MOZ_ASSERT(attribute); - - int32_t count = - mCSSEditUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, - attribute, &aValue, - aSuppressTransaction); - if (count) { - // we found an equivalence ; let's remove the HTML attribute itself if it is set - nsAutoString existingValue; - bool wasSet = false; - nsresult rv = - GetAttributeValue(aElement, aAttribute, existingValue, &wasSet); - NS_ENSURE_SUCCESS(rv, rv); - if (!wasSet) { - return NS_OK; - } - return aSuppressTransaction ? - element->UnsetAttr(kNameSpaceID_None, attribute, true) : - RemoveAttribute(aElement, aAttribute); - } + if (!IsCSSEnabled() || !mCSSEditUtils) { + // we are not in an HTML+CSS editor; let's set the attribute the HTML way + return aSuppressTransaction ? + aElement->SetAttr(kNameSpaceID_None, aAttribute, aValue, true) : + SetAttribute(aElement, aAttribute, aValue); + } - // 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 (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 ? - element->SetAttr(kNameSpaceID_None, attribute, existingValue, true) : - SetAttribute(aElement, aAttribute, existingValue); + 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; } - // 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 ? - element->SetAttr(kNameSpaceID_None, attribute, aValue, true) : - SetAttribute(aElement, aAttribute, aValue); + aElement->UnsetAttr(kNameSpaceID_None, aAttribute, 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 == nsGkAtoms::style) { + // if it is the style attribute, just add the new value to the existing + // style attribute's value + nsAutoString existingValue; + aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::style, existingValue); + existingValue.Append(' '); + existingValue.Append(aValue); + return aSuppressTransaction ? + aElement->SetAttr(kNameSpaceID_None, aAttribute, existingValue, true) : + SetAttribute(aElement, aAttribute, existingValue); } - // 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); + // 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->SetAttr(kNameSpaceID_None, aAttribute, aValue, true) : + SetAttribute(aElement, aAttribute, aValue); } nsresult -HTMLEditor::RemoveAttributeOrEquivalent(nsIDOMElement* aElement, - const nsAString& aAttribute, +HTMLEditor::RemoveAttributeOrEquivalent(Element* aElement, + nsIAtom* aAttribute, bool aSuppressTransaction) { - nsCOMPtr element = do_QueryInterface(aElement); - NS_ENSURE_TRUE(element, NS_OK); - - nsCOMPtr attribute = NS_Atomize(aAttribute); - MOZ_ASSERT(attribute); + MOZ_ASSERT(aElement); + MOZ_ASSERT(aAttribute); if (IsCSSEnabled() && mCSSEditUtils) { nsresult rv = mCSSEditUtils->RemoveCSSEquivalentToHTMLStyle( - element, nullptr, attribute, nullptr, aSuppressTransaction); + aElement, nullptr, aAttribute, nullptr, aSuppressTransaction); NS_ENSURE_SUCCESS(rv, rv); } - if (!element->HasAttr(kNameSpaceID_None, attribute)) { + if (!aElement->HasAttr(kNameSpaceID_None, aAttribute)) { return NS_OK; } return aSuppressTransaction ? - element->UnsetAttr(kNameSpaceID_None, attribute, /* aNotify = */ true) : + aElement->UnsetAttr(kNameSpaceID_None, aAttribute, /* aNotify = */ true) : RemoveAttribute(aElement, aAttribute); } diff --git a/editor/libeditor/HTMLEditor.h b/editor/libeditor/HTMLEditor.h index dc1a41b70..494e7c383 100644 --- a/editor/libeditor/HTMLEditor.h +++ b/editor/libeditor/HTMLEditor.h @@ -118,6 +118,16 @@ public: virtual already_AddRefed GetInputEventTargetContent() override; virtual bool IsEditable(nsINode* aNode) override; using EditorBase::IsEditable; + virtual nsresult RemoveAttributeOrEquivalent( + Element* aElement, + nsIAtom* aAttribute, + bool aSuppressTransaction) override; + virtual nsresult SetAttributeOrEquivalent(Element* aElement, + nsIAtom* aAttribute, + const nsAString& aValue, + bool aSuppressTransaction) override; + using EditorBase::RemoveAttributeOrEquivalent; + using EditorBase::SetAttributeOrEquivalent; // nsStubMutationObserver overrides NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED @@ -329,14 +339,6 @@ public: */ virtual nsresult SelectEntireDocument(Selection* aSelection) override; - NS_IMETHOD SetAttributeOrEquivalent(nsIDOMElement* aElement, - const nsAString& aAttribute, - const nsAString& aValue, - bool aSuppressTransaction) override; - NS_IMETHOD RemoveAttributeOrEquivalent(nsIDOMElement* aElement, - const nsAString& aAttribute, - bool aSuppressTransaction) override; - /** * Join together any adjacent editable text nodes in the range. */ diff --git a/editor/libeditor/TextEditor.cpp b/editor/libeditor/TextEditor.cpp index 07b06a96a..545e3a3d1 100644 --- a/editor/libeditor/TextEditor.cpp +++ b/editor/libeditor/TextEditor.cpp @@ -1622,8 +1622,8 @@ TextEditor::GetDOMEventTarget() nsresult -TextEditor::SetAttributeOrEquivalent(nsIDOMElement* aElement, - const nsAString& aAttribute, +TextEditor::SetAttributeOrEquivalent(Element* aElement, + nsIAtom* aAttribute, const nsAString& aValue, bool aSuppressTransaction) { @@ -1631,8 +1631,8 @@ TextEditor::SetAttributeOrEquivalent(nsIDOMElement* aElement, } nsresult -TextEditor::RemoveAttributeOrEquivalent(nsIDOMElement* aElement, - const nsAString& aAttribute, +TextEditor::RemoveAttributeOrEquivalent(Element* aElement, + nsIAtom* aAttribute, bool aSuppressTransaction) { return EditorBase::RemoveAttribute(aElement, aAttribute); diff --git a/editor/libeditor/TextEditor.h b/editor/libeditor/TextEditor.h index 31c551f85..7bb594931 100644 --- a/editor/libeditor/TextEditor.h +++ b/editor/libeditor/TextEditor.h @@ -63,14 +63,17 @@ public: // nsIEditorMailSupport overrides NS_DECL_NSIEDITORMAILSUPPORT - // Overrides of EditorBase interface methods - NS_IMETHOD SetAttributeOrEquivalent(nsIDOMElement* aElement, - const nsAString& aAttribute, - const nsAString& aValue, - bool aSuppressTransaction) override; - NS_IMETHOD RemoveAttributeOrEquivalent(nsIDOMElement* aElement, - const nsAString& aAttribute, - bool aSuppressTransaction) override; + // Overrides of EditorBase + virtual nsresult RemoveAttributeOrEquivalent( + Element* aElement, + nsIAtom* aAttribute, + bool aSuppressTransaction) override; + virtual nsresult SetAttributeOrEquivalent(Element* aElement, + nsIAtom* aAttribute, + const nsAString& aValue, + bool aSuppressTransaction) override; + using EditorBase::RemoveAttributeOrEquivalent; + using EditorBase::SetAttributeOrEquivalent; NS_IMETHOD Init(nsIDOMDocument* aDoc, nsIContent* aRoot, nsISelectionController* aSelCon, uint32_t aFlags, -- cgit v1.2.3 From 1115c63bf788dad121f65cf465ebf73562b4d029 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Fri, 22 May 2020 18:38:33 -0400 Subject: Issue #1621 - Part 3: Use nsIAtom to change attirbute if possible. We can replace old nsIEditor API with nsIAtom version. Ref: Bug 1324996 --- editor/libeditor/EditorBase.cpp | 14 ++++---- editor/libeditor/HTMLEditRules.cpp | 51 +++++++++++++--------------- editor/libeditor/HTMLEditor.cpp | 5 ++- editor/libeditor/HTMLEditorObjectResizer.cpp | 29 +++++++--------- editor/libeditor/HTMLStyleEditor.cpp | 8 ++--- editor/libeditor/TextEditRules.cpp | 4 +-- editor/libeditor/TextEditor.cpp | 4 +-- 7 files changed, 51 insertions(+), 64 deletions(-) diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index 7212e7c93..60df3571e 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -2330,11 +2330,9 @@ EditorBase::CloneAttributes(Element* aDest, RefPtr destAttributes = aDest->Attributes(); while (RefPtr attr = destAttributes->Item(0)) { if (destInBody) { - RemoveAttribute(static_cast(GetAsDOMNode(aDest)), - attr->NodeName()); + RemoveAttribute(aDest, attr->NodeInfo()->NameAtom()); } else { - ErrorResult ignored; - aDest->RemoveAttribute(attr->NodeName(), ignored); + aDest->UnsetAttr(kNameSpaceID_None, attr->NodeInfo()->NameAtom(), true); } } @@ -2346,13 +2344,13 @@ EditorBase::CloneAttributes(Element* aDest, nsAutoString value; attr->GetValue(value); if (destInBody) { - SetAttributeOrEquivalent(static_cast(GetAsDOMNode(aDest)), - attr->NodeName(), value, false); + SetAttributeOrEquivalent(aDest, attr->NodeInfo()->NameAtom(), value, + false); } else { // The element is not inserted in the document yet, we don't want to put // a transaction on the UndoStack - SetAttributeOrEquivalent(static_cast(GetAsDOMNode(aDest)), - attr->NodeName(), value, true); + SetAttributeOrEquivalent(aDest, attr->NodeInfo()->NameAtom(), value, + true); } } } diff --git a/editor/libeditor/HTMLEditRules.cpp b/editor/libeditor/HTMLEditRules.cpp index 14f6cfe11..fe5e6c2bf 100644 --- a/editor/libeditor/HTMLEditRules.cpp +++ b/editor/libeditor/HTMLEditRules.cpp @@ -3302,15 +3302,15 @@ HTMLEditRules::WillMakeList(Selection* aSelection, } } NS_ENSURE_STATE(mHTMLEditor); - nsCOMPtr curElement = do_QueryInterface(curNode); - NS_NAMED_LITERAL_STRING(typestr, "type"); + nsCOMPtr curElement = do_QueryInterface(curNode); if (aBulletType && !aBulletType->IsEmpty()) { - rv = mHTMLEditor->SetAttribute(curElement, typestr, *aBulletType); + rv = mHTMLEditor->SetAttribute(curElement, nsGkAtoms::type, + *aBulletType); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } else { - rv = mHTMLEditor->RemoveAttribute(curElement, typestr); + rv = mHTMLEditor->RemoveAttribute(curElement, nsGkAtoms::type); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -4836,7 +4836,6 @@ HTMLEditRules::AlignBlockContents(nsIDOMNode* aNode, nsCOMPtr node = do_QueryInterface(aNode); NS_ENSURE_TRUE(node && alignType, NS_ERROR_NULL_POINTER); nsCOMPtr firstChild, lastChild; - nsCOMPtr divNode; bool useCSS = mHTMLEditor->IsCSSEnabled(); @@ -4844,24 +4843,25 @@ HTMLEditRules::AlignBlockContents(nsIDOMNode* aNode, firstChild = mHTMLEditor->GetFirstEditableChild(*node); NS_ENSURE_STATE(mHTMLEditor); lastChild = mHTMLEditor->GetLastEditableChild(*node); - NS_NAMED_LITERAL_STRING(attr, "align"); if (!firstChild) { // this cell has no content, nothing to align } else if (firstChild == lastChild && firstChild->IsHTMLElement(nsGkAtoms::div)) { // the cell already has a div containing all of its content: just // act on this div. - nsCOMPtr divElem = do_QueryInterface(firstChild); + RefPtr divElem = firstChild->AsElement(); if (useCSS) { NS_ENSURE_STATE(mHTMLEditor); - nsresult rv = mHTMLEditor->SetAttributeOrEquivalent(divElem, attr, + nsresult rv = mHTMLEditor->SetAttributeOrEquivalent(divElem, + nsGkAtoms::align, *alignType, false); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } else { NS_ENSURE_STATE(mHTMLEditor); - nsresult rv = mHTMLEditor->SetAttribute(divElem, attr, *alignType); + nsresult rv = mHTMLEditor->SetAttribute(divElem, nsGkAtoms::align, + *alignType); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -4869,28 +4869,29 @@ HTMLEditRules::AlignBlockContents(nsIDOMNode* aNode, } else { // else we need to put in a div, set the alignment, and toss in all the children NS_ENSURE_STATE(mHTMLEditor); - divNode = mHTMLEditor->CreateNode(nsGkAtoms::div, node, 0); - NS_ENSURE_STATE(divNode); + RefPtr divElem = mHTMLEditor->CreateNode(nsGkAtoms::div, node, 0); + NS_ENSURE_STATE(divElem); // set up the alignment on the div - nsCOMPtr divElem = do_QueryInterface(divNode); if (useCSS) { NS_ENSURE_STATE(mHTMLEditor); nsresult rv = - mHTMLEditor->SetAttributeOrEquivalent(divElem, attr, *alignType, false); + mHTMLEditor->SetAttributeOrEquivalent(divElem, nsGkAtoms::align, + *alignType, false); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } else { NS_ENSURE_STATE(mHTMLEditor); - nsresult rv = mHTMLEditor->SetAttribute(divElem, attr, *alignType); + nsresult rv = + mHTMLEditor->SetAttribute(divElem, nsGkAtoms::align, *alignType); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } // tuck the children into the end of the active div - while (lastChild && (lastChild != divNode)) { + while (lastChild && (lastChild != divElem)) { NS_ENSURE_STATE(mHTMLEditor); - nsresult rv = mHTMLEditor->MoveNode(lastChild, divNode, 0); + nsresult rv = mHTMLEditor->MoveNode(lastChild, divElem, 0); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_STATE(mHTMLEditor); lastChild = mHTMLEditor->GetLastEditableChild(*node); @@ -6510,9 +6511,9 @@ HTMLEditRules::SplitParagraph(nsIDOMNode *aPara, } // remove ID attribute on the paragraph we just created - nsCOMPtr rightElt = do_QueryInterface(rightPara); + RefPtr rightElt = rightPara->AsElement(); NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->RemoveAttribute(rightElt, NS_LITERAL_STRING("id")); + rv = mHTMLEditor->RemoveAttribute(rightElt, nsGkAtoms::id); NS_ENSURE_SUCCESS(rv, rv); // check both halves of para to see if we need mozBR @@ -8387,18 +8388,18 @@ HTMLEditRules::RemoveAlignment(nsIDOMNode* aNode, NS_ENSURE_SUCCESS(rv, rv); } else if (isBlock || HTMLEditUtils::IsHR(child)) { // the current node is a block element - nsCOMPtr curElem = do_QueryInterface(child); + nsCOMPtr curElem = do_QueryInterface(child); if (HTMLEditUtils::SupportsAlignAttr(child)) { // remove the ALIGN attribute if this element can have it NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->RemoveAttribute(curElem, NS_LITERAL_STRING("align")); + rv = mHTMLEditor->RemoveAttribute(curElem, nsGkAtoms::align); NS_ENSURE_SUCCESS(rv, rv); } if (useCSS) { if (HTMLEditUtils::IsTable(child) || HTMLEditUtils::IsHR(child)) { NS_ENSURE_STATE(mHTMLEditor); rv = mHTMLEditor->SetAttributeOrEquivalent(curElem, - NS_LITERAL_STRING("align"), + nsGkAtoms::align, aAlignType, false); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; @@ -8518,21 +8519,17 @@ HTMLEditRules::AlignBlock(Element& aElement, nsresult rv = RemoveAlignment(aElement.AsDOMNode(), aAlignType, aContentsOnly == ContentsOnly::yes); NS_ENSURE_SUCCESS(rv, rv); - NS_NAMED_LITERAL_STRING(attr, "align"); if (htmlEditor->IsCSSEnabled()) { // Let's use CSS alignment; we use margin-left and margin-right for tables // and text-align for other block-level elements rv = htmlEditor->SetAttributeOrEquivalent( - static_cast(aElement.AsDOMNode()), - attr, aAlignType, false); + &aElement, nsGkAtoms::align, aAlignType, false); NS_ENSURE_SUCCESS(rv, rv); } else { // HTML case; this code is supposed to be called ONLY if the element // supports the align attribute but we'll never know... if (HTMLEditUtils::SupportsAlignAttr(aElement.AsDOMNode())) { - rv = htmlEditor->SetAttribute( - static_cast(aElement.AsDOMNode()), - attr, aAlignType); + rv = htmlEditor->SetAttribute(&aElement, nsGkAtoms::align, aAlignType); NS_ENSURE_SUCCESS(rv, rv); } } diff --git a/editor/libeditor/HTMLEditor.cpp b/editor/libeditor/HTMLEditor.cpp index 4cda49ab5..6a630cb1c 100644 --- a/editor/libeditor/HTMLEditor.cpp +++ b/editor/libeditor/HTMLEditor.cpp @@ -2529,7 +2529,7 @@ HTMLEditor::CreateElementWithDefaults(const nsAString& aTagName) // New call to use instead to get proper HTML element, bug 39919 nsCOMPtr realTagAtom = NS_Atomize(realTagName); - nsCOMPtr newElement = CreateHTMLContent(realTagAtom); + RefPtr newElement = CreateHTMLContent(realTagAtom); if (!newElement) { return nullptr; } @@ -2561,8 +2561,7 @@ HTMLEditor::CreateElementWithDefaults(const nsAString& aTagName) } else if (tagName.EqualsLiteral("td")) { nsresult rv = SetAttributeOrEquivalent( - static_cast(newElement->AsDOMNode()), - NS_LITERAL_STRING("valign"), NS_LITERAL_STRING("top"), true); + newElement, nsGkAtoms::valign, NS_LITERAL_STRING("top"), true); NS_ENSURE_SUCCESS(rv, nullptr); } // ADD OTHER TAGS HERE diff --git a/editor/libeditor/HTMLEditorObjectResizer.cpp b/editor/libeditor/HTMLEditorObjectResizer.cpp index 111a3f975..8ed5b6e4d 100644 --- a/editor/libeditor/HTMLEditorObjectResizer.cpp +++ b/editor/libeditor/HTMLEditorObjectResizer.cpp @@ -926,35 +926,30 @@ HTMLEditor::SetFinalSize(int32_t aX, // we want one transaction only from a user's point of view AutoEditBatch batchIt(this); - NS_NAMED_LITERAL_STRING(widthStr, "width"); - NS_NAMED_LITERAL_STRING(heightStr, "height"); - - nsCOMPtr resizedObject = do_QueryInterface(mResizedObject); - NS_ENSURE_TRUE(resizedObject, ); if (mResizedObjectIsAbsolutelyPositioned) { if (setHeight) { - mCSSEditUtils->SetCSSPropertyPixels(*resizedObject, *nsGkAtoms::top, y); + mCSSEditUtils->SetCSSPropertyPixels(*mResizedObject, *nsGkAtoms::top, y); } if (setWidth) { - mCSSEditUtils->SetCSSPropertyPixels(*resizedObject, *nsGkAtoms::left, x); + mCSSEditUtils->SetCSSPropertyPixels(*mResizedObject, *nsGkAtoms::left, x); } } if (IsCSSEnabled() || mResizedObjectIsAbsolutelyPositioned) { if (setWidth && mResizedObject->HasAttr(kNameSpaceID_None, nsGkAtoms::width)) { - RemoveAttribute(static_cast(GetAsDOMNode(mResizedObject)), widthStr); + RemoveAttribute(mResizedObject, nsGkAtoms::width); } if (setHeight && mResizedObject->HasAttr(kNameSpaceID_None, nsGkAtoms::height)) { - RemoveAttribute(static_cast(GetAsDOMNode(mResizedObject)), heightStr); + RemoveAttribute(mResizedObject, nsGkAtoms::height); } if (setWidth) { - mCSSEditUtils->SetCSSPropertyPixels(*resizedObject, *nsGkAtoms::width, + mCSSEditUtils->SetCSSPropertyPixels(*mResizedObject, *nsGkAtoms::width, width); } if (setHeight) { - mCSSEditUtils->SetCSSPropertyPixels(*resizedObject, *nsGkAtoms::height, + mCSSEditUtils->SetCSSPropertyPixels(*mResizedObject, *nsGkAtoms::height, height); } } else { @@ -964,30 +959,30 @@ HTMLEditor::SetFinalSize(int32_t aX, // triggering an immediate reflow; otherwise, we have problems // with asynchronous reflow if (setWidth) { - mCSSEditUtils->SetCSSPropertyPixels(*resizedObject, *nsGkAtoms::width, + mCSSEditUtils->SetCSSPropertyPixels(*mResizedObject, *nsGkAtoms::width, width); } if (setHeight) { - mCSSEditUtils->SetCSSPropertyPixels(*resizedObject, *nsGkAtoms::height, + mCSSEditUtils->SetCSSPropertyPixels(*mResizedObject, *nsGkAtoms::height, height); } if (setWidth) { nsAutoString w; w.AppendInt(width); - SetAttribute(static_cast(GetAsDOMNode(mResizedObject)), widthStr, w); + SetAttribute(mResizedObject, nsGkAtoms::width, w); } if (setHeight) { nsAutoString h; h.AppendInt(height); - SetAttribute(static_cast(GetAsDOMNode(mResizedObject)), heightStr, h); + SetAttribute(mResizedObject, nsGkAtoms::height, h); } if (setWidth) { - mCSSEditUtils->RemoveCSSProperty(*resizedObject, *nsGkAtoms::width, + mCSSEditUtils->RemoveCSSProperty(*mResizedObject, *nsGkAtoms::width, EmptyString()); } if (setHeight) { - mCSSEditUtils->RemoveCSSProperty(*resizedObject, *nsGkAtoms::height, + mCSSEditUtils->RemoveCSSProperty(*mResizedObject, *nsGkAtoms::height, EmptyString()); } } diff --git a/editor/libeditor/HTMLStyleEditor.cpp b/editor/libeditor/HTMLStyleEditor.cpp index d3eabba1d..c41f0a05c 100644 --- a/editor/libeditor/HTMLStyleEditor.cpp +++ b/editor/libeditor/HTMLStyleEditor.cpp @@ -744,8 +744,6 @@ HTMLEditor::RemoveStyleInside(nsIContent& aNode, // if we weren't passed an attribute, then we want to // remove any matching inlinestyles entirely if (!aAttribute || aAttribute->IsEmpty()) { - NS_NAMED_LITERAL_STRING(styleAttr, "style"); - NS_NAMED_LITERAL_STRING(classAttr, "class"); bool hasStyleAttr = aNode.HasAttr(kNameSpaceID_None, nsGkAtoms::style); bool hasClassAttr = aNode.HasAttr(kNameSpaceID_None, nsGkAtoms::_class); @@ -754,14 +752,14 @@ HTMLEditor::RemoveStyleInside(nsIContent& aNode, // just remove the element... We need to create above the element // a span that will carry those styles or class, then we can delete // the node. - nsCOMPtr spanNode = + RefPtr spanNode = InsertContainerAbove(&aNode, nsGkAtoms::span); NS_ENSURE_STATE(spanNode); nsresult rv = - CloneAttribute(styleAttr, spanNode->AsDOMNode(), aNode.AsDOMNode()); + CloneAttribute(nsGkAtoms::style, spanNode, aNode.AsElement()); NS_ENSURE_SUCCESS(rv, rv); rv = - CloneAttribute(classAttr, spanNode->AsDOMNode(), aNode.AsDOMNode()); + CloneAttribute(nsGkAtoms::_class, spanNode, aNode.AsElement()); NS_ENSURE_SUCCESS(rv, rv); } nsresult rv = RemoveContainer(&aNode); diff --git a/editor/libeditor/TextEditRules.cpp b/editor/libeditor/TextEditRules.cpp index 4ecaff722..e98d36dd3 100644 --- a/editor/libeditor/TextEditRules.cpp +++ b/editor/libeditor/TextEditRules.cpp @@ -1422,9 +1422,9 @@ TextEditRules::CreateMozBR(nsIDOMNode* inParent, NS_ENSURE_SUCCESS(rv, rv); // give it special moz attr - nsCOMPtr brElem = do_QueryInterface(brNode); + nsCOMPtr brElem = do_QueryInterface(brNode); if (brElem) { - rv = mTextEditor->SetAttribute(brElem, NS_LITERAL_STRING("type"), + rv = mTextEditor->SetAttribute(brElem, nsGkAtoms::type, NS_LITERAL_STRING("_moz")); NS_ENSURE_SUCCESS(rv, rv); } diff --git a/editor/libeditor/TextEditor.cpp b/editor/libeditor/TextEditor.cpp index 545e3a3d1..3bee7843c 100644 --- a/editor/libeditor/TextEditor.cpp +++ b/editor/libeditor/TextEditor.cpp @@ -311,9 +311,9 @@ TextEditor::UpdateMetaCharset(nsIDOMDocument* aDocument, } // set attribute to charset=text/html - nsCOMPtr metaElement = do_QueryInterface(metaNode); + RefPtr metaElement = metaNode->AsElement(); MOZ_ASSERT(metaElement); - rv = EditorBase::SetAttribute(metaElement, NS_LITERAL_STRING("content"), + rv = EditorBase::SetAttribute(metaElement, nsGkAtoms::content, Substring(originalStart, start) + charsetEquals + NS_ConvertASCIItoUTF16(aCharacterSet)); -- cgit v1.2.3 From 5f6ecd756b06e40c889ddab70356d7033336763b Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Fri, 22 May 2020 22:26:28 -0400 Subject: Issue #1621 - Part 4: Check whether node can be splited. At first, HTMLEditor::GetActiveEditingHost might return null in this situation, we should check whether nullptr is returned. At second, SplitNodeDeep returns error since curent is design mode and selection node has no parent. So we should check error. Ref: Bug 1350772 --- editor/libeditor/HTMLEditRules.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/editor/libeditor/HTMLEditRules.cpp b/editor/libeditor/HTMLEditRules.cpp index fe5e6c2bf..f24d0131d 100644 --- a/editor/libeditor/HTMLEditRules.cpp +++ b/editor/libeditor/HTMLEditRules.cpp @@ -1509,10 +1509,11 @@ HTMLEditRules::WillInsertBreak(Selection& aSelection, nsCOMPtr blockParent = htmlEditor->GetBlock(node); NS_ENSURE_TRUE(blockParent, NS_ERROR_FAILURE); - // If the active editing host is an inline element, or if the active editing - // host is the block parent itself, just append a br. + // When there is an active editing host (the if it's in designMode) + // and a block which becomes the parent of line breaker is in it, do the + // standard thing. nsCOMPtr host = htmlEditor->GetActiveEditingHost(); - if (!EditorUtils::IsDescendantOf(blockParent, host)) { + if (host && !EditorUtils::IsDescendantOf(blockParent, host)) { nsresult rv = StandardBreakImpl(node, offset, aSelection); NS_ENSURE_SUCCESS(rv, rv); *aHandled = true; @@ -6498,10 +6499,14 @@ HTMLEditRules::SplitParagraph(nsIDOMNode *aPara, // split the paragraph NS_ENSURE_STATE(mHTMLEditor); NS_ENSURE_STATE(selNode->IsContent()); - mHTMLEditor->SplitNodeDeep(*para, *selNode->AsContent(), *aOffset, - HTMLEditor::EmptyContainers::yes, - getter_AddRefs(leftPara), - getter_AddRefs(rightPara)); + int32_t offset = + mHTMLEditor->SplitNodeDeep(*para, *selNode->AsContent(), *aOffset, + HTMLEditor::EmptyContainers::yes, + getter_AddRefs(leftPara), + getter_AddRefs(rightPara)); + if (NS_WARN_IF(offset == -1)) { + return NS_ERROR_FAILURE; + } // get rid of the break, if it is visible (otherwise it may be needed to prevent an empty p) NS_ENSURE_STATE(mHTMLEditor); if (mHTMLEditor->IsVisBreak(aBRNode)) { -- cgit v1.2.3