diff --git a/editor/libeditor/CSSEditUtils.cpp b/editor/libeditor/CSSEditUtils.cpp index 68dcec57effd..0e3f366359a8 100644 --- a/editor/libeditor/CSSEditUtils.cpp +++ b/editor/libeditor/CSSEditUtils.cpp @@ -443,74 +443,61 @@ nsresult CSSEditUtils::RemoveCSSProperty(Element& aElement, nsAtom& aProperty, } // static -nsresult CSSEditUtils::GetSpecifiedProperty(nsIContent& aContent, - nsAtom& aCSSProperty, +nsresult CSSEditUtils::GetSpecifiedProperty(nsINode& aNode, nsAtom& aProperty, nsAString& aValue) { nsresult rv = - GetSpecifiedCSSInlinePropertyBase(aContent, aCSSProperty, aValue); - NS_WARNING_ASSERTION( - NS_SUCCEEDED(rv), - "CSSEditUtils::GeSpecifiedCSSInlinePropertyBase() failed"); + GetCSSInlinePropertyBase(&aNode, &aProperty, aValue, eSpecified); + NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), + "CSSEditUtils::GetCSSInlinePropertyBase() failed"); return rv; } // static -nsresult CSSEditUtils::GetComputedProperty(nsIContent& aContent, - nsAtom& aCSSProperty, +nsresult CSSEditUtils::GetComputedProperty(nsINode& aNode, nsAtom& aProperty, nsAString& aValue) { - nsresult rv = - GetComputedCSSInlinePropertyBase(aContent, aCSSProperty, aValue); - NS_WARNING_ASSERTION( - NS_SUCCEEDED(rv), - "CSSEditUtils::GetComputedCSSInlinePropertyBase() failed"); + nsresult rv = GetCSSInlinePropertyBase(&aNode, &aProperty, aValue, eComputed); + NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), + "CSSEditUtils::GetCSSInlinePropertyBase() failed"); return rv; } // static -nsresult CSSEditUtils::GetComputedCSSInlinePropertyBase(nsIContent& aContent, - nsAtom& aCSSProperty, - nsAString& aValue) { +nsresult CSSEditUtils::GetCSSInlinePropertyBase(nsINode* aNode, + nsAtom* aProperty, + nsAString& aValue, + StyleType aStyleType) { + MOZ_ASSERT(aNode && aProperty); aValue.Truncate(); - RefPtr element = aContent.GetAsElementOrParentElement(); + RefPtr element = aNode->GetAsElementOrParentElement(); if (NS_WARN_IF(!element)) { return NS_ERROR_INVALID_ARG; } - // Get the all the computed css styles attached to the element node - RefPtr computedDOMStyle = GetComputedStyle(element); - if (NS_WARN_IF(!computedDOMStyle)) { - return NS_ERROR_INVALID_ARG; - } - - // from these declarations, get the one we want and that one only - // - // FIXME(bug 1606994): nsAtomCString copies, we should just keep around the - // property id. - MOZ_ALWAYS_SUCCEEDS( - computedDOMStyle->GetPropertyValue(nsAtomCString(&aCSSProperty), aValue)); - - return NS_OK; -} - -// static -nsresult CSSEditUtils::GetSpecifiedCSSInlinePropertyBase(nsIContent& aContent, - nsAtom& aCSSProperty, - nsAString& aValue) { - aValue.Truncate(); - - RefPtr element = aContent.GetAsElementOrParentElement(); - if (NS_WARN_IF(!element)) { - return NS_ERROR_INVALID_ARG; + if (aStyleType == eComputed) { + // Get the all the computed css styles attached to the element node + RefPtr computedDOMStyle = GetComputedStyle(element); + if (NS_WARN_IF(!computedDOMStyle)) { + return NS_ERROR_INVALID_ARG; + } + + // from these declarations, get the one we want and that one only + // + // FIXME(bug 1606994): nsAtomCString copies, we should just keep around the + // property id. + MOZ_ALWAYS_SUCCEEDS( + computedDOMStyle->GetPropertyValue(nsAtomCString(aProperty), aValue)); + + return NS_OK; } + MOZ_ASSERT(aStyleType == eSpecified); RefPtr decl = element->GetInlineStyleDeclaration(); if (!decl) { return NS_OK; } - nsCSSPropertyID prop = - nsCSSProps::LookupProperty(nsAtomCString(&aCSSProperty)); + nsCSSPropertyID prop = nsCSSProps::LookupProperty(nsAtomCString(aProperty)); MOZ_ASSERT(prop != eCSSProperty_UNKNOWN); decl->GetPropertyValueByID(prop, aValue); @@ -654,65 +641,85 @@ void CSSEditUtils::ParseLength(const nsAString& aString, float* aValue, } // static -nsStaticAtom* CSSEditUtils::GetCSSPropertyAtom( - nsCSSEditableProperty aProperty) { +void CSSEditUtils::GetCSSPropertyAtom(nsCSSEditableProperty aProperty, + nsAtom** aAtom) { + *aAtom = nullptr; switch (aProperty) { case eCSSEditableProperty_background_color: - return nsGkAtoms::backgroundColor; + *aAtom = nsGkAtoms::backgroundColor; + break; case eCSSEditableProperty_background_image: - return nsGkAtoms::background_image; + *aAtom = nsGkAtoms::background_image; + break; case eCSSEditableProperty_border: - return nsGkAtoms::border; + *aAtom = nsGkAtoms::border; + break; case eCSSEditableProperty_caption_side: - return nsGkAtoms::caption_side; + *aAtom = nsGkAtoms::caption_side; + break; case eCSSEditableProperty_color: - return nsGkAtoms::color; + *aAtom = nsGkAtoms::color; + break; case eCSSEditableProperty_float: - return nsGkAtoms::_float; + *aAtom = nsGkAtoms::_float; + break; case eCSSEditableProperty_font_family: - return nsGkAtoms::font_family; + *aAtom = nsGkAtoms::font_family; + break; case eCSSEditableProperty_font_size: - return nsGkAtoms::font_size; + *aAtom = nsGkAtoms::font_size; + break; case eCSSEditableProperty_font_style: - return nsGkAtoms::font_style; + *aAtom = nsGkAtoms::font_style; + break; case eCSSEditableProperty_font_weight: - return nsGkAtoms::fontWeight; + *aAtom = nsGkAtoms::fontWeight; + break; case eCSSEditableProperty_height: - return nsGkAtoms::height; + *aAtom = nsGkAtoms::height; + break; case eCSSEditableProperty_list_style_type: - return nsGkAtoms::list_style_type; + *aAtom = nsGkAtoms::list_style_type; + break; case eCSSEditableProperty_margin_left: - return nsGkAtoms::marginLeft; + *aAtom = nsGkAtoms::marginLeft; + break; case eCSSEditableProperty_margin_right: - return nsGkAtoms::marginRight; + *aAtom = nsGkAtoms::marginRight; + break; case eCSSEditableProperty_text_align: - return nsGkAtoms::textAlign; + *aAtom = nsGkAtoms::textAlign; + break; case eCSSEditableProperty_text_decoration: - return nsGkAtoms::text_decoration; + *aAtom = nsGkAtoms::text_decoration; + break; case eCSSEditableProperty_vertical_align: - return nsGkAtoms::vertical_align; + *aAtom = nsGkAtoms::vertical_align; + break; case eCSSEditableProperty_whitespace: - return nsGkAtoms::white_space; + *aAtom = nsGkAtoms::white_space; + break; case eCSSEditableProperty_width: - return nsGkAtoms::width; + *aAtom = nsGkAtoms::width; + break; case eCSSEditableProperty_NONE: // intentionally empty - return nullptr; + break; } } -// Populate aOutArrayOfCSSProperty and aOutArrayOfCSSValue with the CSS -// declarations equivalent to the value aValue according to the equivalence -// table aEquivTable +// Populate aProperty and aValueArray with the CSS declarations equivalent to +// the value aValue according to the equivalence table aEquivTable // static -void CSSEditUtils::BuildCSSDeclarations( - nsTArray& aOutArrayOfCSSProperty, - nsTArray& aOutArrayOfCSSValue, const CSSEquivTable* aEquivTable, - const nsAString* aValue, bool aGetOrRemoveRequest) { +void CSSEditUtils::BuildCSSDeclarations(nsTArray& aPropertyArray, + nsTArray& aValueArray, + const CSSEquivTable* aEquivTable, + const nsAString* aValue, + bool aGetOrRemoveRequest) { // clear arrays - aOutArrayOfCSSProperty.Clear(); - aOutArrayOfCSSValue.Clear(); + aPropertyArray.Clear(); + aValueArray.Clear(); // if we have an input value, let's use it nsAutoString value, lowerCasedValue; @@ -727,6 +734,7 @@ void CSSEditUtils::BuildCSSDeclarations( while (cssProperty) { if (!aGetOrRemoveRequest || aEquivTable[index].gettable) { nsAutoString cssValue, cssPropertyString; + nsAtom* cssPropertyAtom; // find the equivalent css value for the index-th property in // the equivalence table (*aEquivTable[index].processValueFunctor)( @@ -735,22 +743,24 @@ void CSSEditUtils::BuildCSSDeclarations( : &lowerCasedValue, cssValue, aEquivTable[index].defaultValue, aEquivTable[index].prependValue, aEquivTable[index].appendValue); - aOutArrayOfCSSProperty.AppendElement(GetCSSPropertyAtom(cssProperty)); - aOutArrayOfCSSValue.AppendElement(cssValue); + GetCSSPropertyAtom(cssProperty, &cssPropertyAtom); + aPropertyArray.AppendElement(cssPropertyAtom); + aValueArray.AppendElement(cssValue); } index++; cssProperty = aEquivTable[index].cssProperty; } } -// Populate aOutArrayOfCSSProperty and aOutArrayOfCSSValue with the declarations -// equivalent to aHTMLProperty/aAttribute/aValue for the node aNode +// Populate cssPropertyArray and cssValueArray with the declarations equivalent +// to aHTMLProperty/aAttribute/aValue for the node aNode // static void CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle( - Element& aElement, nsAtom* aHTMLProperty, nsAtom* aAttribute, - const nsAString* aValue, nsTArray& aOutArrayOfCSSProperty, - nsTArray& aOutArrayOfCSSValue, bool aGetOrRemoveRequest) { + Element* aElement, nsAtom* aHTMLProperty, nsAtom* aAttribute, + const nsAString* aValue, nsTArray& cssPropertyArray, + nsTArray& cssValueArray, bool aGetOrRemoveRequest) { + MOZ_ASSERT(aElement); const CSSEditUtils::CSSEquivTable* equivTable = nullptr; if (nsGkAtoms::b == aHTMLProperty) { @@ -778,12 +788,12 @@ void CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle( } else if (aAttribute == nsGkAtoms::border) { equivTable = borderEquivTable; } else if (aAttribute == nsGkAtoms::align) { - if (aElement.IsHTMLElement(nsGkAtoms::table)) { + if (aElement->IsHTMLElement(nsGkAtoms::table)) { equivTable = tableAlignEquivTable; - } else if (aElement.IsHTMLElement(nsGkAtoms::hr)) { + } else if (aElement->IsHTMLElement(nsGkAtoms::hr)) { equivTable = hrAlignEquivTable; - } else if (aElement.IsAnyOfHTMLElements(nsGkAtoms::legend, - nsGkAtoms::caption)) { + } else if (aElement->IsAnyOfHTMLElements(nsGkAtoms::legend, + nsGkAtoms::caption)) { equivTable = captionAlignEquivTable; } else { equivTable = textAlignEquivTable; @@ -795,18 +805,18 @@ void CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle( } else if (aAttribute == nsGkAtoms::width) { equivTable = widthEquivTable; } else if (aAttribute == nsGkAtoms::height || - (aElement.IsHTMLElement(nsGkAtoms::hr) && + (aElement->IsHTMLElement(nsGkAtoms::hr) && aAttribute == nsGkAtoms::size)) { equivTable = heightEquivTable; } else if (aAttribute == nsGkAtoms::type && - aElement.IsAnyOfHTMLElements(nsGkAtoms::ol, nsGkAtoms::ul, - nsGkAtoms::li)) { + aElement->IsAnyOfHTMLElements(nsGkAtoms::ol, nsGkAtoms::ul, + nsGkAtoms::li)) { equivTable = listStyleTypeEquivTable; } } if (equivTable) { - BuildCSSDeclarations(aOutArrayOfCSSProperty, aOutArrayOfCSSValue, - equivTable, aValue, aGetOrRemoveRequest); + BuildCSSDeclarations(cssPropertyArray, cssValueArray, equivTable, aValue, + aGetOrRemoveRequest); } } @@ -828,9 +838,9 @@ int32_t CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement, // an equivalence for the requested HTML style in this implementation // Find the CSS equivalence to the HTML style - nsTArray cssPropertyArray; + nsTArray cssPropertyArray; nsTArray cssValueArray; - GenerateCSSDeclarationsFromHTMLStyle(*aElement, aHTMLProperty, aAttribute, + GenerateCSSDeclarationsFromHTMLStyle(aElement, aHTMLProperty, aAttribute, aValue, cssPropertyArray, cssValueArray, false); @@ -865,9 +875,9 @@ nsresult CSSEditUtils::RemoveCSSEquivalentToHTMLStyle( // an equivalence for the requested HTML style in this implementation // Find the CSS equivalence to the HTML style - nsTArray cssPropertyArray; + nsTArray cssPropertyArray; nsTArray cssValueArray; - GenerateCSSDeclarationsFromHTMLStyle(*aElement, aHTMLProperty, aAttribute, + GenerateCSSDeclarationsFromHTMLStyle(aElement, aHTMLProperty, aAttribute, aValue, cssPropertyArray, cssValueArray, true); @@ -885,19 +895,17 @@ nsresult CSSEditUtils::RemoveCSSEquivalentToHTMLStyle( return NS_OK; } -// returns in aValue the list of values for the CSS equivalences to -// the HTML style aHTMLProperty/aAttribute/aValue for the node aNode; +// 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. // static -nsresult CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSetInternal( - nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute, - nsAString& aValue, StyleType aStyleType) { - MOZ_ASSERT(aHTMLProperty || aAttribute); - - aValue.Truncate(); - RefPtr theElement = aContent.GetAsElementOrParentElement(); +nsresult CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet( + nsINode* aNode, nsAtom* aHTMLProperty, nsAtom* aAttribute, + nsAString& aValueString, StyleType aStyleType) { + aValueString.Truncate(); + RefPtr theElement = aNode->GetAsElementOrParentElement(); if (NS_WARN_IF(!theElement)) { return NS_ERROR_INVALID_ARG; } @@ -908,121 +916,128 @@ nsresult CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSetInternal( } // Yes, the requested HTML style has a CSS equivalence in this implementation - nsTArray cssPropertyArray; + nsTArray cssPropertyArray; nsTArray cssValueArray; // get the CSS equivalence with last param true indicating we want only the // "gettable" properties - GenerateCSSDeclarationsFromHTMLStyle(*theElement, aHTMLProperty, aAttribute, + 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 - if (aStyleType == StyleType::Computed) { - nsresult rv = GetComputedCSSInlinePropertyBase( - *theElement, MOZ_KnownLive(*cssPropertyArray[index]), valueString); - if (NS_FAILED(rv)) { - NS_WARNING("CSSEditUtils::GetComputedCSSInlinePropertyBase() failed"); - return rv; - } - } else { - nsresult rv = GetSpecifiedCSSInlinePropertyBase( - *theElement, *cssPropertyArray[index], valueString); - if (NS_FAILED(rv)) { - NS_WARNING("CSSEditUtils::GetSpecifiedCSSInlinePropertyBase() failed"); - return rv; - } + nsresult rv = GetCSSInlinePropertyBase(theElement, cssPropertyArray[index], + valueString, aStyleType); + if (NS_FAILED(rv)) { + NS_WARNING("CSSEditUtils::GetCSSInlinePropertyBase() failed"); + return rv; } - // append the value to aValue (possibly with a leading whitespace) + // append the value to aValueString (possibly with a leading whitespace) if (index) { - aValue.Append(char16_t(' ')); + aValueString.Append(char16_t(' ')); } - aValue.Append(valueString); + aValueString.Append(valueString); } return NS_OK; } -// Does the node aContent (or its parent, if it's not an element node) have a -// CSS style equivalent to the HTML style -// aHTMLProperty/aAttribute/valueString? The value of aStyleType controls -// the styles we retrieve: specified or computed. The return value aIsSet is -// true if the CSS styles are set. +// Does the node aNode (or its parent, if it's not an element node) have a CSS +// style equivalent to the HTML style aHTMLProperty/aHTMLAttribute/valueString? +// The value of aStyleType controls the styles we retrieve: specified or +// computed. The return value aIsSet is true if the CSS styles are set. // // The nsIContent variant returns aIsSet instead of using an out parameter, and // does not modify aValue. // static -bool CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSetInternal( - nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute, - nsAString& aValue, StyleType aStyleType) { - MOZ_ASSERT(aHTMLProperty || aAttribute); +bool CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode, + nsAtom* aProperty, + nsAtom* aAttribute, + const nsAString& aValue, + StyleType aStyleType) { + // Use aValue as only an in param, not in-out + nsAutoString value(aValue); + return IsCSSEquivalentToHTMLInlineStyleSet(aNode, aProperty, aAttribute, + value, aStyleType); +} - nsAutoString htmlValueString(aValue); +// static +bool CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet( + nsINode* aNode, nsAtom* aProperty, const nsAString* aAttribute, + nsAString& aValue, StyleType aStyleType) { + MOZ_ASSERT(aNode && aProperty); + RefPtr attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr; + return IsCSSEquivalentToHTMLInlineStyleSet(aNode, aProperty, attribute, + aValue, aStyleType); +} + +// static +bool CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode, + nsAtom* aHTMLProperty, + nsAtom* aHTMLAttribute, + nsAString& valueString, + StyleType aStyleType) { + if (NS_WARN_IF(!aNode)) { + return false; + } + + nsAutoString htmlValueString(valueString); bool isSet = false; - // FYI: Cannot use InclusiveAncestorsOfType here because - // GetCSSEquivalentToHTMLInlineStyleSetInternal() may flush pending - // notifications. - for (nsCOMPtr content = &aContent; content; - content = content->GetParentElement()) { - nsCOMPtr parentNode = content->GetParentNode(); - aValue.Assign(htmlValueString); + do { + valueString.Assign(htmlValueString); // get the value of the CSS equivalent styles - nsresult rv = GetCSSEquivalentToHTMLInlineStyleSetInternal( - *content, aHTMLProperty, aAttribute, aValue, aStyleType); + nsresult rv = GetCSSEquivalentToHTMLInlineStyleSet( + aNode, aHTMLProperty, aHTMLAttribute, valueString, aStyleType); if (NS_FAILED(rv)) { - NS_WARNING( - "CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSetInternal() " - "failed"); - return false; - } - if (NS_WARN_IF(parentNode != content->GetParentNode())) { + NS_WARNING("CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet() failed"); return false; } // early way out if we can - if (aValue.IsEmpty()) { + if (valueString.IsEmpty()) { return isSet; } if (nsGkAtoms::b == aHTMLProperty) { - if (aValue.EqualsLiteral("bold")) { + if (valueString.EqualsLiteral("bold")) { isSet = true; - } else if (aValue.EqualsLiteral("normal")) { + } else if (valueString.EqualsLiteral("normal")) { isSet = false; - } else if (aValue.EqualsLiteral("bolder")) { + } else if (valueString.EqualsLiteral("bolder")) { isSet = true; - aValue.AssignLiteral("bold"); + valueString.AssignLiteral("bold"); } else { int32_t weight = 0; nsresult rvIgnored; - nsAutoString value(aValue); + nsAutoString value(valueString); weight = value.ToInteger(&rvIgnored); NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored), "nsAString::ToInteger() failed, but ignored"); if (400 < weight) { isSet = true; - aValue.AssignLiteral("bold"); + valueString.AssignLiteral("bold"); } else { isSet = false; - aValue.AssignLiteral("normal"); + valueString.AssignLiteral("normal"); } } } else if (nsGkAtoms::i == aHTMLProperty) { - if (aValue.EqualsLiteral("italic") || aValue.EqualsLiteral("oblique")) { + if (valueString.EqualsLiteral("italic") || + valueString.EqualsLiteral("oblique")) { isSet = true; } } else if (nsGkAtoms::u == aHTMLProperty) { nsAutoString val; val.AssignLiteral("underline"); - isSet = ChangeStyleTransaction::ValueIncludes(aValue, val); + isSet = ChangeStyleTransaction::ValueIncludes(valueString, val); } else if (nsGkAtoms::strike == aHTMLProperty) { nsAutoString val; val.AssignLiteral("line-through"); - isSet = ChangeStyleTransaction::ValueIncludes(aValue, val); + isSet = ChangeStyleTransaction::ValueIncludes(valueString, val); } else if ((nsGkAtoms::font == aHTMLProperty && - aAttribute == nsGkAtoms::color) || - aAttribute == nsGkAtoms::bgcolor) { + aHTMLAttribute == nsGkAtoms::color) || + aHTMLAttribute == nsGkAtoms::bgcolor) { if (htmlValueString.IsEmpty()) { isSet = true; } else { @@ -1058,21 +1073,22 @@ bool CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSetInternal( htmlColor.Append(char16_t(')')); } - isSet = htmlColor.Equals(aValue, nsCaseInsensitiveStringComparator()); + isSet = htmlColor.Equals(valueString, + nsCaseInsensitiveStringComparator()); } else { - isSet = htmlValueString.Equals(aValue, + isSet = htmlValueString.Equals(valueString, nsCaseInsensitiveStringComparator()); } } } else if (nsGkAtoms::tt == aHTMLProperty) { - isSet = StringBeginsWith(aValue, NS_LITERAL_STRING("monospace")); - } else if (nsGkAtoms::font == aHTMLProperty && aAttribute && - aAttribute == nsGkAtoms::face) { + isSet = StringBeginsWith(valueString, NS_LITERAL_STRING("monospace")); + } else if (nsGkAtoms::font == aHTMLProperty && aHTMLAttribute && + 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(aValue); + nsAutoString valueStringNorm(valueString); valueStringNorm.ReplaceSubstring(commaSpace, comma); isSet = htmlValueString.Equals(valueStringNorm, nsCaseInsensitiveStringComparator()); @@ -1080,14 +1096,15 @@ bool CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSetInternal( isSet = true; } return isSet; - } else if (aAttribute == nsGkAtoms::align) { + } else if (aHTMLAttribute == nsGkAtoms::align) { isSet = true; } else { return false; } if (!htmlValueString.IsEmpty() && - htmlValueString.Equals(aValue, nsCaseInsensitiveStringComparator())) { + htmlValueString.Equals(valueString, + nsCaseInsensitiveStringComparator())) { isSet = true; } @@ -1095,44 +1112,31 @@ bool CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSetInternal( isSet = !isSet; } - if (isSet) { - return true; + 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 + aNode = + aNode->GetParentElement(); // set to null if it's not a dom element } - - if (nsGkAtoms::u != aHTMLProperty && nsGkAtoms::strike != aHTMLProperty) { - return isSet; - } - - // 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. - } + } while ( + (nsGkAtoms::u == aHTMLProperty || nsGkAtoms::strike == aHTMLProperty) && + !isSet && aNode); return isSet; } -bool CSSEditUtils::HaveCSSEquivalentStylesInternal(nsIContent& aContent, - nsAtom* aHTMLProperty, - nsAtom* aAttribute, - StyleType aStyleType) { - MOZ_ASSERT(aHTMLProperty || aAttribute); - - // FYI: Unfortunately, we cannot use InclusiveAncestorsOfType here - // because GetCSSEquivalentToHTMLInlineStyleSetInternal() may flush - // pending notifications. +bool CSSEditUtils::HaveCSSEquivalentStyles(nsINode& aNode, + nsAtom* aHTMLProperty, + nsAtom* aHTMLAttribute, + StyleType aStyleType) { nsAutoString valueString; - for (nsCOMPtr content = &aContent; content; - content = content->GetParentElement()) { - nsCOMPtr parentNode = content->GetParentNode(); + nsCOMPtr node = &aNode; + do { // get the value of the CSS equivalent styles - nsresult rv = GetCSSEquivalentToHTMLInlineStyleSetInternal( - *content, aHTMLProperty, aAttribute, valueString, aStyleType); + nsresult rv = GetCSSEquivalentToHTMLInlineStyleSet( + node, aHTMLProperty, aHTMLAttribute, valueString, aStyleType); if (NS_FAILED(rv)) { - NS_WARNING( - "CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSetInternal() " - "failed"); - return false; - } - if (NS_WARN_IF(parentNode != content->GetParentNode())) { + NS_WARNING("CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet() failed"); return false; } @@ -1144,11 +1148,14 @@ bool CSSEditUtils::HaveCSSEquivalentStylesInternal(nsIContent& aContent, return false; } - // 'nfortunately, the value of the text-decoration property is not + // 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. - } + // are underlined + + // set to null if it's not a dom element + node = node->GetParentElement(); + } while (node); return false; } diff --git a/editor/libeditor/CSSEditUtils.h b/editor/libeditor/CSSEditUtils.h index 15eb70f7698d..60690ab440b4 100644 --- a/editor/libeditor/CSSEditUtils.h +++ b/editor/libeditor/CSSEditUtils.h @@ -17,7 +17,6 @@ class nsAtom; class nsIContent; class nsICSSDeclaration; class nsINode; -class nsStaticAtom; namespace mozilla { @@ -59,6 +58,8 @@ class CSSEditUtils final { eCSSEditableProperty_width }; + enum StyleType { eSpecified, eComputed }; + struct CSSEquivTable { nsCSSEditableProperty cssProperty; nsProcessValueFunc processValueFunctor; @@ -110,15 +111,14 @@ class CSSEditUtils final { * Gets the specified/computed style value of a CSS property for a given * node (or its element ancestor if it is not an element). * - * @param aContent [IN] A DOM node. + * @param aNode [IN] A DOM node. * @param aProperty [IN] An atom containing the CSS property to get. * @param aPropertyValue [OUT] The retrieved value of the property. */ - static nsresult GetSpecifiedProperty(nsIContent& aContent, - nsAtom& aCSSProperty, nsAString& aValue); - MOZ_CAN_RUN_SCRIPT static nsresult GetComputedProperty(nsIContent& aContent, - nsAtom& aCSSProperty, - nsAString& aValue); + static nsresult GetSpecifiedProperty(nsINode& aNode, nsAtom& aProperty, + nsAString& aValue); + static nsresult GetComputedProperty(nsINode& aNode, nsAtom& aProperty, + nsAString& aValue); /** * Removes a CSS property from the specified declarations in STYLE attribute @@ -165,50 +165,50 @@ class CSSEditUtils final { * Returns the list of values for the CSS equivalences to * the passed HTML style for the passed node. * - * @param aContent [IN] A DOM node. + * @param aNode [IN] A DOM node. * @param aHTMLProperty [IN] An atom containing an HTML property. * @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. */ - MOZ_CAN_RUN_SCRIPT static nsresult - GetComputedCSSEquivalentToHTMLInlineStyleSet(nsIContent& aContent, - nsAtom* aHTMLProperty, - nsAtom* aAttribute, - nsAString& aValue) { - return GetCSSEquivalentToHTMLInlineStyleSetInternal( - aContent, aHTMLProperty, aAttribute, aValue, StyleType::Computed); - } + static nsresult GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode, + nsAtom* aHTMLProperty, + nsAtom* 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 aContent [IN] A DOM node. + * @param aNode [IN] A DOM node. * @param aHTMLProperty [IN] An atom containing an HTML property. * @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. * @return A boolean being true if the css properties are * not same as initial value. */ - MOZ_CAN_RUN_SCRIPT static bool IsComputedCSSEquivalentToHTMLInlineStyleSet( - nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute, - nsAString& aValue) { - MOZ_ASSERT(aHTMLProperty || aAttribute); - return IsCSSEquivalentToHTMLInlineStyleSetInternal( - aContent, aHTMLProperty, aAttribute, aValue, StyleType::Computed); - } - MOZ_CAN_RUN_SCRIPT_BOUNDARY static bool - IsSpecifiedCSSEquivalentToHTMLInlineStyleSet(nsIContent& aContent, - nsAtom* aHTMLProperty, - nsAtom* aAttribute, - nsAString& aValue) { - MOZ_ASSERT(aHTMLProperty || aAttribute); - return IsCSSEquivalentToHTMLInlineStyleSetInternal( - aContent, aHTMLProperty, aAttribute, aValue, StyleType::Specified); - } + static bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent, + nsAtom* aProperty, + nsAtom* aAttribute, + nsAString& aValue, + StyleType aStyleType); + + static bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent, + nsAtom* aProperty, + nsAtom* aAttribute, + const nsAString& aValue, + StyleType aStyleType); + + static bool IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aContent, + nsAtom* aProperty, + const nsAString* aAttribute, + nsAString& aValue, + StyleType aStyleType); /** * This is a kind of IsCSSEquivalentToHTMLInlineStyleSet. @@ -216,28 +216,20 @@ class CSSEditUtils final { * aren't same as initial value. But this method returns whether the * properties aren't set. * If node is , - * - Is(Computed|Specified)CSSEquivalentToHTMLInlineStyleSet returns false. - * - Have(Computed|Specified)CSSEquivalentStyles returns true. + * - IsCSSEquivalentToHTMLInlineStyleSet returns false. + * - HaveCSSEquivalentStyles returns true. * - * @param aContent [IN] A DOM node. + * @param aNode [IN] A DOM node. * @param aHTMLProperty [IN] An atom containing an HTML property. * @param aAttribute [IN] An atom to an attribute name or nullptr * if irrelevant. + * @param aStyleType [IN] eSpecified or eComputed. * @return A boolean being true if the css properties are * not set. */ - MOZ_CAN_RUN_SCRIPT static bool HaveComputedCSSEquivalentStyles( - nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute) { - MOZ_ASSERT(aHTMLProperty || aAttribute); - return HaveCSSEquivalentStylesInternal(aContent, aHTMLProperty, aAttribute, - StyleType::Computed); - } - MOZ_CAN_RUN_SCRIPT_BOUNDARY static bool HaveSpecifiedCSSEquivalentStyles( - nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute) { - MOZ_ASSERT(aHTMLProperty || aAttribute); - return HaveCSSEquivalentStylesInternal(aContent, aHTMLProperty, aAttribute, - StyleType::Specified); - } + + static bool HaveCSSEquivalentStyles(nsINode& aNode, nsAtom* aProperty, + nsAtom* aAttribute, StyleType aStyleType); /** * Adds to the node the CSS inline styles equivalent to the HTML style @@ -332,57 +324,56 @@ class CSSEditUtils final { dom::Element* aElement); private: - enum class StyleType { Specified, Computed }; - /** * Retrieves the CSS property atom from an enum. * - * @param aProperty The enum value for the property. - * @return The corresponding atom. + * @param aProperty [IN] The enum value for the property. + * @param aAtom [OUT] The corresponding atom. */ - static nsStaticAtom* GetCSSPropertyAtom(nsCSSEditableProperty aProperty); + static void GetCSSPropertyAtom(nsCSSEditableProperty aProperty, + nsAtom** aAtom); /** * Retrieves the CSS declarations equivalent to a HTML style value for * a given equivalence table. * - * @param aOutArrayOfCSSProperty [OUT] The array of css properties. - * @param aOutArrayOfCSSValue [OUT] The array of values for the CSS - * properties above. - * @param aEquivTable The equivalence table. - * @param aValue The HTML style value. - * @param aGetOrRemoveRequest A boolean value being true if the call to - * the current method is made for - * Get*CSSEquivalentToHTMLInlineStyleSet() - * or - * RemoveCSSEquivalentToHTMLInlineStyleSet(). + * @param aPropertyArray [OUT] The array of css properties. + * @param aValueArray [OUT] The array of values for the CSS properties + * above. + * @param aEquivTable [IN] The equivalence table. + * @param aValue [IN] The HTML style value. + * @param aGetOrRemoveRequest [IN] A boolean value being true if the call to + * the current method is made for + * GetCSSEquivalentToHTMLInlineStyleSet() or + * RemoveCSSEquivalentToHTMLInlineStyleSet(). */ - static void BuildCSSDeclarations( - nsTArray& aOutArrayOfCSSProperty, - nsTArray& aOutArrayOfCSSValue, const CSSEquivTable* aEquivTable, - const nsAString* aValue, bool aGetOrRemoveRequest); + static void BuildCSSDeclarations(nsTArray& aPropertyArray, + nsTArray& cssValueArray, + const CSSEquivTable* aEquivTable, + const nsAString* aValue, + bool aGetOrRemoveRequest); /** * Retrieves the CSS declarations equivalent to the given HTML * property/attribute/value for a given node. * - * @param aElement The DOM node. - * @param aHTMLProperty An atom containing an HTML property. - * @param aAttribute An atom to an attribute name or nullptr + * @param aNode [IN] The DOM node. + * @param aHTMLProperty [IN] An atom containing an HTML property. + * @param aAttribute [IN] An atom to an attribute name or nullptr * if irrelevant - * @param aValue The attribute value. - * @param aOutArrayOfCSSProperty [OUT] The array of CSS properties. - * @param aOutArrayOfCSSValue [OUT] The array of values for the CSS - * properties above. - * @param aGetOrRemoveRequest A boolean value being true if the call to - * the current method is made for - * Get*CSSEquivalentToHTMLInlineStyleSet() or - * RemoveCSSEquivalentToHTMLInlineStyleSet(). + * @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(). */ static void GenerateCSSDeclarationsFromHTMLStyle( - dom::Element& aElement, nsAtom* aHTMLProperty, nsAtom* aAttribute, - const nsAString* aValue, nsTArray& aOutArrayOfCSSProperty, - nsTArray& aOutArrayOfCSSValue, bool aGetOrRemoveRequest); + dom::Element* aNode, nsAtom* aHTMLProperty, nsAtom* aAttribute, + const nsAString* aValue, nsTArray& aPropertyArray, + nsTArray& aValueArray, bool aGetOrRemoveRequest); /** * Back-end for GetSpecifiedProperty and GetComputedProperty. @@ -390,31 +381,11 @@ class CSSEditUtils final { * @param aNode [IN] A DOM node. * @param aProperty [IN] A CSS property. * @param aValue [OUT] The retrieved value for this property. + * @param aStyleType [IN] eSpecified or eComputed. */ - MOZ_CAN_RUN_SCRIPT static nsresult GetComputedCSSInlinePropertyBase( - nsIContent& aContent, nsAtom& aCSSProperty, nsAString& aValue); - static nsresult GetSpecifiedCSSInlinePropertyBase(nsIContent& aContent, - nsAtom& aCSSProperty, - nsAString& aValue); - - /** - * Those methods are wrapped with corresponding methods which do not have - * "Internal" in their names. Don't use these methods directly even if - * you want to use one of them in this class. - * Note that these methods may run scrip only when StyleType is Computed. - */ - MOZ_CAN_RUN_SCRIPT static nsresult - GetCSSEquivalentToHTMLInlineStyleSetInternal(nsIContent& aContent, - nsAtom* aHTMLProperty, - nsAtom* aAttribute, - nsAString& aValue, - StyleType aStyleType); - MOZ_CAN_RUN_SCRIPT static bool IsCSSEquivalentToHTMLInlineStyleSetInternal( - nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute, - nsAString& aValue, StyleType aStyleType); - MOZ_CAN_RUN_SCRIPT static bool HaveCSSEquivalentStylesInternal( - nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute, - StyleType aStyleType); + static nsresult GetCSSInlinePropertyBase(nsINode* aNode, nsAtom* aProperty, + nsAString& aValue, + StyleType aStyleType); private: HTMLEditor* mHTMLEditor; diff --git a/editor/libeditor/EditorCommands.h b/editor/libeditor/EditorCommands.h index 588344d93ec8..d4b1f595977a 100644 --- a/editor/libeditor/EditorCommands.h +++ b/editor/libeditor/EditorCommands.h @@ -20,7 +20,6 @@ class nsCommandParams; class nsICommandParams; class nsIEditingSession; class nsITransferable; -class nsStaticAtom; namespace mozilla { @@ -580,10 +579,10 @@ class StateUpdatingCommandBase : public EditorCommand { // add/remove the style MOZ_CAN_RUN_SCRIPT virtual nsresult ToggleState( - nsStaticAtom& aTagName, HTMLEditor& aHTMLEditor, + nsAtom* aTagName, HTMLEditor* aHTMLEditor, nsIPrincipal* aPrincipal) const = 0; - static nsStaticAtom* GetTagName(Command aCommand) { + static nsAtom* GetTagName(Command aCommand) { switch (aCommand) { case Command::FormatBold: return nsGkAtoms::b; @@ -652,8 +651,8 @@ class StyleUpdatingCommand final : public StateUpdatingCommandBase { nsCommandParams& aParams) const final; // add/remove the style - MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsStaticAtom& aTagName, - HTMLEditor& aHTMLEditor, + MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsAtom* aTagName, + HTMLEditor* aHTMLEditor, nsIPrincipal* aPrincipal) const final; }; @@ -698,8 +697,8 @@ class ListCommand final : public StateUpdatingCommandBase { nsCommandParams& aParams) const final; // add/remove the style - MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsStaticAtom& aTagName, - HTMLEditor& aHTMLEditor, + MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsAtom* aTagName, + HTMLEditor* aHTMLEditor, nsIPrincipal* aPrincipal) const final; }; @@ -717,8 +716,8 @@ class ListItemCommand final : public StateUpdatingCommandBase { nsCommandParams& aParams) const final; // add/remove the style - MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsStaticAtom& aTagName, - HTMLEditor& aHTMLEditor, + MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsAtom* aTagName, + HTMLEditor* aHTMLEditor, nsIPrincipal* aPrincipal) const final; }; @@ -857,8 +856,8 @@ class AbsolutePositioningCommand final : public StateUpdatingCommandBase { MOZ_CAN_RUN_SCRIPT nsresult GetCurrentState(nsAtom* aTagName, HTMLEditor* aHTMLEditor, nsCommandParams& aParams) const final; - MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsStaticAtom& aTagName, - HTMLEditor& aHTMLEditor, + MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsAtom* aTagName, + HTMLEditor* aHTMLEditor, nsIPrincipal* aPrincipal) const final; }; diff --git a/editor/libeditor/EditorUtils.h b/editor/libeditor/EditorUtils.h index a5cae3588b7d..909a1139564a 100644 --- a/editor/libeditor/EditorUtils.h +++ b/editor/libeditor/EditorUtils.h @@ -14,13 +14,12 @@ #include "mozilla/RangeBoundary.h" #include "mozilla/dom/Selection.h" #include "mozilla/dom/StaticRange.h" -#include "nsAtom.h" -#include "nscore.h" #include "nsCOMPtr.h" #include "nsDebug.h" #include "nsRange.h" -#include "nsString.h" +#include "nscore.h" +class nsAtom; class nsISimpleEnumerator; class nsITransferable; @@ -803,13 +802,6 @@ class EditorUtils final { static void MaskString(nsString& aString, dom::Text* aText, uint32_t aStartOffsetInString, uint32_t aStartOffsetInText); - - static nsStaticAtom* GetAttributeAtom(const nsAString& aAttribute) { - if (aAttribute.IsEmpty()) { - return nullptr; // Don't use nsGkAtoms::_empty for attribute. - } - return NS_GetStaticAtom(aAttribute); - } }; } // namespace mozilla diff --git a/editor/libeditor/HTMLAbsPositionEditor.cpp b/editor/libeditor/HTMLAbsPositionEditor.cpp index a7b2cc8679b8..7f0c99d756be 100644 --- a/editor/libeditor/HTMLAbsPositionEditor.cpp +++ b/editor/libeditor/HTMLAbsPositionEditor.cpp @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "HTMLEditor.h" +#include "mozilla/HTMLEditor.h" #include @@ -78,35 +78,24 @@ HTMLEditor::GetAbsolutelyPositionedSelectionContainer() const { return nullptr; } - AutoTArray, 24> arrayOfParentElements; + nsAutoString positionValue; for (Element* element : InclusiveAncestorsOfType(*selectionContainerElement)) { - arrayOfParentElements.AppendElement(element); - } - - nsAutoString positionValue; - for (RefPtr element = selectionContainerElement; element; - element = element->GetParentElement()) { if (element->IsHTMLElement(nsGkAtoms::html)) { NS_WARNING( "HTMLEditor::GetAbsolutelyPositionedSelectionContainer() reached " " element"); return nullptr; } - nsCOMPtr parentNode = element->GetParentNode(); nsresult rv = CSSEditUtils::GetComputedProperty( - MOZ_KnownLive(*element), *nsGkAtoms::position, positionValue); + *element, *nsGkAtoms::position, positionValue); if (NS_FAILED(rv)) { NS_WARNING( "CSSEditUtils::GetComputedProperty(nsGkAtoms::position) failed"); return nullptr; } - if (NS_WARN_IF(Destroyed()) || - NS_WARN_IF(parentNode != element->GetParentNode())) { - return nullptr; - } if (positionValue.EqualsLiteral("absolute")) { - return element.forget(); + return do_AddRef(element); } } return nullptr; @@ -134,14 +123,11 @@ nsresult HTMLEditor::RelativeChangeElementZIndex(Element& aElement, } int32_t zIndex = GetZIndex(aElement); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } zIndex = std::max(zIndex + aChange, 0); SetZIndex(aElement, zIndex); *aReturn = zIndex; - return NS_WARN_IF(Destroyed()) ? NS_ERROR_EDITOR_DESTROYED : NS_OK; + return NS_OK; } void HTMLEditor::SetZIndex(Element& aElement, int32_t aZIndex) { @@ -196,12 +182,11 @@ int32_t HTMLEditor::GetZIndex(Element& aElement) { // we have to look at the positioned ancestors // cf. CSS 2 spec section 9.9.1 nsAutoString positionValue; - for (RefPtr element = aElement.GetParentElement(); element; - element = element->GetParentElement()) { + for (Element* element : + InclusiveAncestorsOfType(*aElement.GetParentElement())) { if (element->IsHTMLElement(nsGkAtoms::body)) { return 0; } - nsCOMPtr parentNode = element->GetParentElement(); nsresult rv = CSSEditUtils::GetComputedProperty( *element, *nsGkAtoms::position, positionValue); if (NS_FAILED(rv)) { @@ -209,10 +194,6 @@ int32_t HTMLEditor::GetZIndex(Element& aElement) { "CSSEditUtils::GetComputedProperty(nsGkAtoms::position) failed"); return 0; } - if (NS_WARN_IF(Destroyed()) || - NS_WARN_IF(parentNode != element->GetParentNode())) { - return 0; - } if (!positionValue.EqualsLiteral("absolute")) { continue; } @@ -225,10 +206,6 @@ int32_t HTMLEditor::GetZIndex(Element& aElement) { "CSSEditUtils::GetComputedProperty(nsGkAtoms::z_index) failed"); return 0; } - if (NS_WARN_IF(Destroyed()) || - NS_WARN_IF(parentNode != element->GetParentNode())) { - return 0; - } if (!zIndexValue.EqualsLiteral("auto")) { break; } @@ -292,10 +269,8 @@ nsresult HTMLEditor::RefreshGrabberInternal() { if (!mAbsolutelyPositionedObject) { return NS_OK; } - OwningNonNull absolutelyPositionedObject = - *mAbsolutelyPositionedObject; nsresult rv = GetPositionAndDimensions( - absolutelyPositionedObject, mPositionedObjectX, mPositionedObjectY, + *mAbsolutelyPositionedObject, mPositionedObjectX, mPositionedObjectY, mPositionedObjectWidth, mPositionedObjectHeight, mPositionedObjectBorderLeft, mPositionedObjectBorderTop, mPositionedObjectMarginLeft, mPositionedObjectMarginTop); @@ -303,20 +278,11 @@ nsresult HTMLEditor::RefreshGrabberInternal() { NS_WARNING("HTMLEditor::GetPositionAndDimensions() failed"); return rv; } - if (NS_WARN_IF(absolutelyPositionedObject != mAbsolutelyPositionedObject)) { - return NS_ERROR_FAILURE; - } RefPtr grabber = mGrabber.get(); MOZ_ASSERT(grabber); SetAnonymousElementPosition(mPositionedObjectX + 12, mPositionedObjectY - 14, grabber); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } - if (NS_WARN_IF(grabber != mGrabber.get())) { - return NS_ERROR_FAILURE; - } return NS_OK; } @@ -758,9 +724,6 @@ nsresult HTMLEditor::GetTemporaryStyleForFocusedPositionedElement( RefPtr style = nsComputedDOMStyle::GetComputedStyle(&aElement, nullptr); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } if (!style) { NS_WARNING("nsComputedDOMStyle::GetComputedStyle() failed"); return NS_ERROR_FAILURE; diff --git a/editor/libeditor/HTMLAnonymousNodeEditor.cpp b/editor/libeditor/HTMLAnonymousNodeEditor.cpp index 0ffdb54895fb..705a2d7cb3bd 100644 --- a/editor/libeditor/HTMLAnonymousNodeEditor.cpp +++ b/editor/libeditor/HTMLAnonymousNodeEditor.cpp @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "HTMLEditor.h" +#include "mozilla/HTMLEditor.h" #include "mozilla/Attributes.h" #include "mozilla/PresShell.h" @@ -361,9 +361,6 @@ nsresult HTMLEditor::RefreshEditingUI() { // Absolute Positioning support is enabled, is the selection contained // in an absolutely positioned element ? absPosElement = GetAbsolutelyPositionedSelectionContainer(); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } } RefPtr cellElement; @@ -508,9 +505,6 @@ nsresult HTMLEditor::GetPositionAndDimensions(Element& aElement, int32_t& aX, nsAutoString positionValue; DebugOnly rvIgnored = CSSEditUtils::GetComputedProperty( aElement, *nsGkAtoms::position, positionValue); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored), "CSSEditUtils::GetComputedProperty(nsGkAtoms::" "position) failed, but ignored"); diff --git a/editor/libeditor/HTMLEditSubActionHandler.cpp b/editor/libeditor/HTMLEditSubActionHandler.cpp index 8a5f9dc1f366..7d105d9d42d4 100644 --- a/editor/libeditor/HTMLEditSubActionHandler.cpp +++ b/editor/libeditor/HTMLEditSubActionHandler.cpp @@ -4,12 +4,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "HTMLEditor.h" - #include #include #include "HTMLEditUtils.h" +#include "HTMLEditor.h" #include "WSRunObject.h" #include "mozilla/Assertions.h" #include "mozilla/CSSEditUtils.h" @@ -26,7 +25,6 @@ #include "mozilla/TextComposition.h" #include "mozilla/UniquePtr.h" #include "mozilla/Unused.h" -#include "mozilla/dom/AncestorIterator.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/HTMLBRElement.h" #include "mozilla/dom/RangeBinding.h" @@ -262,6 +260,10 @@ void HTMLEditor::OnStartToHandleTopLevelEditSubAction( TopLevelEditSubActionDataRef().mSelectedRange->StoreRange(*range); } } + nsCOMPtr selStartNode = + TopLevelEditSubActionDataRef().mSelectedRange->mStartContainer; + nsCOMPtr selEndNode = + TopLevelEditSubActionDataRef().mSelectedRange->mEndContainer; // Register with range updater to track this as we perturb the doc RangeUpdaterRef().RegisterRangeItem( @@ -281,15 +283,14 @@ void HTMLEditor::OnStartToHandleTopLevelEditSubAction( break; } if (cacheInlineStyles) { - nsCOMPtr containerContent = nsIContent::FromNodeOrNull( - aDirectionOfTopLevelEditSubAction == nsIEditor::eNext - ? TopLevelEditSubActionDataRef().mSelectedRange->mEndContainer - : TopLevelEditSubActionDataRef().mSelectedRange->mStartContainer); - if (NS_WARN_IF(!containerContent)) { + nsCOMPtr selNode = + aDirectionOfTopLevelEditSubAction == nsIEditor::eNext ? selEndNode + : selStartNode; + if (NS_WARN_IF(!selNode)) { aRv.Throw(NS_ERROR_FAILURE); return; } - nsresult rv = CacheInlineStyles(*containerContent); + nsresult rv = CacheInlineStyles(*selNode); if (NS_FAILED(rv)) { NS_WARNING("HTMLEditor::CacheInlineStyles() failed"); aRv.Throw(rv); @@ -949,8 +950,7 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor, editTargetContent = arrayOfContents[0]; } - RefPtr blockElementAtEditTarget = - HTMLEditor::GetBlock(*editTargetContent); + Element* blockElementAtEditTarget = HTMLEditor::GetBlock(*editTargetContent); if (NS_WARN_IF(!blockElementAtEditTarget)) { aRv.Throw(NS_ERROR_FAILURE); return; @@ -963,16 +963,12 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor, nsAutoString value; // Let's get the value(s) of text-align or margin-left/margin-right DebugOnly rvIgnored = - CSSEditUtils::GetComputedCSSEquivalentToHTMLInlineStyleSet( - *blockElementAtEditTarget, nullptr, nsGkAtoms::align, value); - if (NS_WARN_IF(aHTMLEditor.Destroyed())) { - aRv.Throw(NS_ERROR_EDITOR_DESTROYED); - return; - } + CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet( + blockElementAtEditTarget, nullptr, nsGkAtoms::align, value, + CSSEditUtils::eComputed); NS_WARNING_ASSERTION( NS_SUCCEEDED(rvIgnored), - "CSSEditUtils::GetComputedCSSEquivalentToHTMLInlineStyleSet(nsGkAtoms::" - "align, " + "CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsGkAtoms::align, " "eComputed) failed, but ignored"); if (value.EqualsLiteral("center") || value.EqualsLiteral("-moz-center") || value.EqualsLiteral("auto auto")) { @@ -993,21 +989,21 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor, return; } - for (nsIContent* containerContent : - InclusiveAncestorsOfType(*editTargetContent)) { + for (nsINode* containerNode = editTargetContent; containerNode; + containerNode = containerNode->GetParentNode()) { // If the node is a parent `` element of edit target, let's break // here to materialize the 'inline-block' behaviour of html tables // regarding to text alignment. - if (containerContent != editTargetContent && - containerContent->IsHTMLElement(nsGkAtoms::table)) { + if (containerNode != editTargetContent && + containerNode->IsHTMLElement(nsGkAtoms::table)) { return; } - if (CSSEditUtils::IsCSSEditableProperty(containerContent, nullptr, + if (CSSEditUtils::IsCSSEditableProperty(containerNode, nullptr, nsGkAtoms::align)) { nsAutoString value; DebugOnly rvIgnored = CSSEditUtils::GetSpecifiedProperty( - *containerContent, *nsGkAtoms::textAlign, value); + *containerNode, *nsGkAtoms::textAlign, value); NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored), "CSSEditUtils::GetSpecifiedProperty(nsGkAtoms::" "textAlign) failed, but ignored"); @@ -1033,13 +1029,13 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor, } } - if (!HTMLEditUtils::SupportsAlignAttr(*containerContent)) { + if (!HTMLEditUtils::SupportsAlignAttr(*containerNode)) { continue; } nsAutoString alignAttributeValue; - containerContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::align, - alignAttributeValue); + containerNode->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::align, + alignAttributeValue); if (alignAttributeValue.IsEmpty()) { continue; } @@ -1063,11 +1059,10 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor, } } -MOZ_CAN_RUN_SCRIPT static nsStaticAtom& MarginPropertyAtomForIndent( - nsIContent& aContent) { +static nsStaticAtom& MarginPropertyAtomForIndent(nsINode& aNode) { nsAutoString direction; DebugOnly rvIgnored = CSSEditUtils::GetComputedProperty( - aContent, *nsGkAtoms::direction, direction); + aNode, *nsGkAtoms::direction, direction); NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored), "CSSEditUtils::GetComputedProperty(nsGkAtoms::direction)" " failed, but ignored"); @@ -6002,7 +5997,7 @@ SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal() { RefPtr indentedParentElement; nsCOMPtr firstContentToBeOutdented, lastContentToBeOutdented; BlockIndentedWith indentedParentIndentedWith = BlockIndentedWith::HTML; - for (OwningNonNull& content : arrayOfContents) { + for (auto& content : arrayOfContents) { // Here's where we actually figure out what to do EditorDOMPoint atContent(content); if (!atContent.IsSet()) { @@ -6045,11 +6040,7 @@ SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal() { // If we're using CSS and the node is a block element, check its start // margin whether it's indented with CSS. if (useCSS && HTMLEditor::NodeIsBlockStatic(content)) { - nsStaticAtom& marginProperty = - MarginPropertyAtomForIndent(MOZ_KnownLive(content)); - if (NS_WARN_IF(Destroyed())) { - return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); - } + nsStaticAtom& marginProperty = MarginPropertyAtomForIndent(content); nsAutoString value; DebugOnly rvIgnored = CSSEditUtils::GetSpecifiedProperty(content, marginProperty, value); @@ -6141,16 +6132,16 @@ SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal() { indentedParentIndentedWith = BlockIndentedWith::HTML; RefPtr editingHost = GetActiveEditingHost(); - for (nsCOMPtr parentContent = content->GetParent(); - parentContent && !parentContent->IsHTMLElement(nsGkAtoms::body) && - parentContent != editingHost && - (parentContent->IsHTMLElement(nsGkAtoms::table) || - !HTMLEditUtils::IsTableElement(parentContent)); - parentContent = parentContent->GetParent()) { + for (nsCOMPtr parentNode = content->GetParentNode(); + parentNode && !parentNode->IsHTMLElement(nsGkAtoms::body) && + parentNode != editingHost && + (parentNode->IsHTMLElement(nsGkAtoms::table) || + !HTMLEditUtils::IsTableElement(parentNode)); + parentNode = parentNode->GetParentNode()) { // If we reach a `
` ancestor, it should be split at next // time at least for outdenting current node. - if (parentContent->IsHTMLElement(nsGkAtoms::blockquote)) { - indentedParentElement = parentContent->AsElement(); + if (parentNode->IsHTMLElement(nsGkAtoms::blockquote)) { + indentedParentElement = parentNode->AsElement(); firstContentToBeOutdented = content; lastContentToBeOutdented = content; break; @@ -6160,18 +6151,10 @@ SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal() { continue; } - nsCOMPtr grandParentNode = parentContent->GetParentNode(); - nsStaticAtom& marginProperty = - MarginPropertyAtomForIndent(MOZ_KnownLive(content)); - if (NS_WARN_IF(Destroyed())) { - return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); - } - if (NS_WARN_IF(grandParentNode != parentContent->GetParentNode())) { - return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE); - } + nsStaticAtom& marginProperty = MarginPropertyAtomForIndent(content); nsAutoString value; DebugOnly rvIgnored = CSSEditUtils::GetSpecifiedProperty( - *parentContent, marginProperty, value); + *parentNode, marginProperty, value); if (NS_WARN_IF(Destroyed())) { return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); } @@ -6188,7 +6171,7 @@ SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal() { if (startMargin > 0 && !(HTMLEditUtils::IsList(atContent.GetContainer()) && HTMLEditUtils::IsList(content))) { - indentedParentElement = parentContent->AsElement(); + indentedParentElement = parentNode->AsElement(); firstContentToBeOutdented = content; lastContentToBeOutdented = content; indentedParentIndentedWith = BlockIndentedWith::CSS; @@ -9834,17 +9817,17 @@ Element* HTMLEditor::GetMostAncestorMailCiteElement(nsINode& aNode) const { return mailCiteElement; } -nsresult HTMLEditor::CacheInlineStyles(nsIContent& aContent) { +nsresult HTMLEditor::CacheInlineStyles(nsINode& aNode) { MOZ_ASSERT(IsTopLevelEditSubActionDataAvailable()); nsresult rv = GetInlineStyles( - aContent, *TopLevelEditSubActionDataRef().mCachedInlineStyles); + aNode, *TopLevelEditSubActionDataRef().mCachedInlineStyles); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::GetInlineStyles() failed"); return rv; } -nsresult HTMLEditor::GetInlineStyles(nsIContent& aContent, +nsresult HTMLEditor::GetInlineStyles(nsINode& aNode, AutoStyleCacheArray& aStyleCacheArray) { MOZ_ASSERT(IsEditActionDataAvailable()); MOZ_ASSERT(aStyleCacheArray.IsEmpty()); @@ -9877,11 +9860,11 @@ nsresult HTMLEditor::GetInlineStyles(nsIContent& aContent, // at creating new StyleCache instance. // Don't use CSS for , we don't support it usefully (bug 780035) if (!useCSS || (property == nsGkAtoms::size)) { - isSet = IsTextPropertySetByContent(&aContent, tag, attribute, nullptr, - &value); + isSet = + IsTextPropertySetByContent(&aNode, tag, attribute, nullptr, &value); } else { - isSet = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet( - aContent, MOZ_KnownLive(tag), MOZ_KnownLive(attribute), value); + isSet = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet( + &aNode, tag, attribute, value, CSSEditUtils::eComputed); if (NS_WARN_IF(Destroyed())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -9910,18 +9893,17 @@ nsresult HTMLEditor::ReapplyCachedStyles() { const RangeBoundary& atStartOfSelection = SelectionRefPtr()->GetRangeAt(0)->StartRef(); - nsCOMPtr startContainerContent = + nsCOMPtr selNode = atStartOfSelection.Container() && atStartOfSelection.Container()->IsContent() ? atStartOfSelection.Container()->AsContent() : nullptr; - if (NS_WARN_IF(!startContainerContent)) { + if (NS_WARN_IF(!selNode)) { return NS_OK; } AutoStyleCacheArray styleCacheArrayAtInsertionPoint; - nsresult rv = - GetInlineStyles(*startContainerContent, styleCacheArrayAtInsertionPoint); + nsresult rv = GetInlineStyles(*selNode, styleCacheArrayAtInsertionPoint); if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) { return NS_ERROR_EDITOR_DESTROYED; } @@ -9936,9 +9918,10 @@ nsresult HTMLEditor::ReapplyCachedStyles() { nsAutoString currentValue; if (useCSS) { // check computed style first in css case - isAny = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet( - *startContainerContent, MOZ_KnownLive(styleCacheBeforeEdit.Tag()), - MOZ_KnownLive(styleCacheBeforeEdit.GetAttribute()), currentValue); + isAny = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet( + selNode, styleCacheBeforeEdit.Tag(), + styleCacheBeforeEdit.GetAttribute(), currentValue, + CSSEditUtils::eComputed); if (NS_WARN_IF(Destroyed())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -9946,10 +9929,12 @@ nsresult HTMLEditor::ReapplyCachedStyles() { if (!isAny) { // then check typeinstate and html style nsresult rv = GetInlinePropertyBase( - MOZ_KnownLive(*styleCacheBeforeEdit.Tag()), - MOZ_KnownLive(styleCacheBeforeEdit.GetAttribute()), + *styleCacheBeforeEdit.Tag(), styleCacheBeforeEdit.GetAttribute(), &styleCacheBeforeEdit.Value(), &isFirst, &isAny, &isAll, ¤tValue); + if (NS_WARN_IF(Destroyed())) { + return NS_ERROR_EDITOR_DESTROYED; + } if (NS_FAILED(rv)) { NS_WARNING("HTMLEditor::GetInlinePropertyBase() failed"); return rv; @@ -11082,9 +11067,6 @@ nsresult HTMLEditor::ChangeMarginStart(Element& aElement, MOZ_ASSERT(IsEditActionDataAvailable()); nsStaticAtom& marginProperty = MarginPropertyAtomForIndent(aElement); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } nsAutoString value; DebugOnly rvIgnored = CSSEditUtils::GetSpecifiedProperty(aElement, marginProperty, value); @@ -11600,9 +11582,6 @@ EditActionResult HTMLEditor::SetSelectionToStaticAsSubAction() { RefPtr element = GetAbsolutelyPositionedSelectionContainer(); if (!element) { - if (NS_WARN_IF(Destroyed())) { - return EditActionHandled(NS_ERROR_EDITOR_DESTROYED); - } NS_WARNING( "HTMLEditor::GetAbsolutelyPositionedSelectionContainer() returned " "nullptr"); @@ -11681,9 +11660,6 @@ EditActionResult HTMLEditor::AddZIndexAsSubAction(int32_t aChange) { RefPtr absolutelyPositionedElement = GetAbsolutelyPositionedSelectionContainer(); if (!absolutelyPositionedElement) { - if (NS_WARN_IF(Destroyed())) { - return EditActionHandled(NS_ERROR_EDITOR_DESTROYED); - } NS_WARNING( "HTMLEditor::GetAbsolutelyPositionedSelectionContainer() returned " "nullptr"); @@ -11696,6 +11672,9 @@ EditActionResult HTMLEditor::AddZIndexAsSubAction(int32_t aChange) { int32_t zIndex; nsresult rv = RelativeChangeElementZIndex(*absolutelyPositionedElement, aChange, &zIndex); + if (NS_WARN_IF(Destroyed())) { + return EditActionHandled(NS_ERROR_EDITOR_DESTROYED); + } if (NS_FAILED(rv)) { NS_WARNING("HTMLEditor::RelativeChangeElementZIndex() failed"); return EditActionHandled(rv); diff --git a/editor/libeditor/HTMLEditor.cpp b/editor/libeditor/HTMLEditor.cpp index db3156601ad0..b355bcce22b8 100644 --- a/editor/libeditor/HTMLEditor.cpp +++ b/editor/libeditor/HTMLEditor.cpp @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "HTMLEditor.h" +#include "mozilla/HTMLEditor.h" #include "mozilla/ComposerCommandsUpdater.h" #include "mozilla/ContentIterator.h" @@ -2049,13 +2049,13 @@ nsresult HTMLEditor::GetBackgroundColorState(bool* aMixed, nsresult rv = GetCSSBackgroundColorState(aMixed, aOutColor, true); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::GetCSSBackgroundColorState() failed"); - return EditorBase::ToGenericNSResult(rv); + return rv; } // in HTML mode, we look only at page's background nsresult rv = GetHTMLBackgroundColorState(aMixed, aOutColor); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::GetCSSBackgroundColorState() failed"); - return EditorBase::ToGenericNSResult(rv); + return rv; } NS_IMETHODIMP HTMLEditor::GetHighlightColorState(bool* aMixed, @@ -2103,56 +2103,43 @@ nsresult HTMLEditor::GetCSSBackgroundColorState(bool* aMixed, } nsCOMPtr startContainer = firstRange->GetStartContainer(); - if (NS_WARN_IF(!startContainer) || NS_WARN_IF(!startContainer->IsContent())) { + if (NS_WARN_IF(!startContainer)) { return NS_ERROR_FAILURE; } // is the selection collapsed? - nsIContent* contentToExamine; + nsCOMPtr nodeToExamine; if (SelectionRefPtr()->IsCollapsed() || IsTextNode(startContainer)) { // we want to look at the startContainer and ancestors - contentToExamine = startContainer->AsContent(); + nodeToExamine = startContainer; } else { // otherwise we want to look at the first editable node after // {startContainer,offset} and its ancestors for divs with alignment on them - contentToExamine = firstRange->GetChildAtStartOffset(); - // GetNextNode(startContainer, offset, true, address_of(contentToExamine)); + nodeToExamine = firstRange->GetChildAtStartOffset(); + // GetNextNode(startContainer, offset, true, address_of(nodeToExamine)); } - if (NS_WARN_IF(!contentToExamine)) { + if (NS_WARN_IF(!nodeToExamine)) { return NS_ERROR_FAILURE; } if (aBlockLevel) { // we are querying the block background (and not the text background), let's // climb to the block container - Element* blockParent = GetBlock(*contentToExamine); + nsCOMPtr blockParent = GetBlock(*nodeToExamine); if (NS_WARN_IF(!blockParent)) { return NS_OK; } - for (RefPtr element = blockParent; element; - element = element->GetParentElement()) { - nsCOMPtr parentNode = element->GetParentNode(); + // Make sure to not walk off onto the Document node + do { // retrieve the computed style of background-color for blockParent - DebugOnly rvIgnored = CSSEditUtils::GetComputedProperty( - *element, *nsGkAtoms::backgroundColor, aOutColor); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } - if (NS_WARN_IF(parentNode != element->GetParentNode())) { - return NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE; - } - NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored), - "CSSEditUtils::GetComputedProperty(nsGkAtoms::" - "backgroundColor) failed, but ignored"); + CSSEditUtils::GetComputedProperty(*blockParent, + *nsGkAtoms::backgroundColor, aOutColor); + blockParent = blockParent->GetParentElement(); // look at parent if the queried color is transparent and if the node to // examine is not the root of the document - if (!aOutColor.EqualsLiteral("transparent")) { - break; - } - } - + } while (aOutColor.EqualsLiteral("transparent") && blockParent); if (aOutColor.EqualsLiteral("transparent")) { // we have hit the root of the document and the color is still transparent // ! Grumble... Let's look at the default background color because that's @@ -2161,44 +2148,32 @@ nsresult HTMLEditor::GetCSSBackgroundColorState(bool* aMixed, } } else { // no, we are querying the text background for the Text Highlight button - if (IsTextNode(contentToExamine)) { + if (IsTextNode(nodeToExamine)) { // if the node of interest is a text node, let's climb a level - contentToExamine = contentToExamine->GetParent(); + nodeToExamine = nodeToExamine->GetParentNode(); } // Return default value due to no parent node - if (!contentToExamine) { + if (!nodeToExamine) { return NS_OK; } - - for (RefPtr element = - contentToExamine->GetAsElementOrParentElement(); - element; element = element->GetParentElement()) { + do { // is the node to examine a block ? - if (HTMLEditor::NodeIsBlockStatic(*element)) { + if (HTMLEditor::NodeIsBlockStatic(*nodeToExamine)) { // yes it is a block; in that case, the text background color is // transparent aOutColor.AssignLiteral("transparent"); break; + } else { + // no, it's not; let's retrieve the computed style of background-color + // for the node to examine + CSSEditUtils::GetComputedProperty( + *nodeToExamine, *nsGkAtoms::backgroundColor, aOutColor); + if (!aOutColor.EqualsLiteral("transparent")) { + break; + } } - - // no, it's not; let's retrieve the computed style of background-color - // for the node to examine - nsCOMPtr parentNode = element->GetParentNode(); - DebugOnly rvIgnored = CSSEditUtils::GetComputedProperty( - *element, *nsGkAtoms::backgroundColor, aOutColor); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } - if (NS_WARN_IF(parentNode != element->GetParentNode())) { - return NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE; - } - NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored), - "CSSEditUtils::GetComputedProperty(nsGkAtoms::" - "backgroundColor) failed, but ignored"); - if (!aOutColor.EqualsLiteral("transparent")) { - break; - } - } + nodeToExamine = nodeToExamine->GetParentNode(); + } while (aOutColor.EqualsLiteral("transparent") && nodeToExamine); } return NS_OK; } diff --git a/editor/libeditor/HTMLEditor.h b/editor/libeditor/HTMLEditor.h index a2352f895696..a58ef2f14160 100644 --- a/editor/libeditor/HTMLEditor.h +++ b/editor/libeditor/HTMLEditor.h @@ -36,9 +36,8 @@ class nsDocumentFragment; class nsHTMLDocument; class nsITransferable; class nsIClipboard; -class nsRange; -class nsStaticAtom; class nsTableWrapperFrame; +class nsRange; namespace mozilla { class AlignStateAtSelection; @@ -183,8 +182,7 @@ class HTMLEditor final : public TextEditor, * @param aMixed true if there is more than one font color * @param aOutColor Color string. "" is returned for none. */ - MOZ_CAN_RUN_SCRIPT nsresult GetBackgroundColorState(bool* aMixed, - nsAString& aOutColor); + nsresult GetBackgroundColorState(bool* aMixed, nsAString& aOutColor); /** * PasteNoFormatting() pastes content in clipboard without any style @@ -418,8 +416,7 @@ class HTMLEditor final : public TextEditor, * returns the deepest absolutely positioned container of the selection * if it exists or null. */ - MOZ_CAN_RUN_SCRIPT already_AddRefed - GetAbsolutelyPositionedSelectionContainer() const; + already_AddRefed GetAbsolutelyPositionedSelectionContainer() const; Element* GetPositionedElement() const { return mAbsolutelyPositionedObject; } @@ -441,7 +438,7 @@ class HTMLEditor final : public TextEditor, * @return the z-index of the element * @param aElement [IN] the element. */ - MOZ_CAN_RUN_SCRIPT int32_t GetZIndex(Element& aElement); + int32_t GetZIndex(Element& aElement); /** * adds aChange to the z-index of the currently positioned element. @@ -471,33 +468,34 @@ class HTMLEditor final : public TextEditor, nsAtom& aProperty, nsAtom* aAttribute, const nsAString& aValue, nsIPrincipal* aPrincipal = nullptr); - [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult GetInlineProperty( - nsAtom* aHTMLProperty, nsAtom* aAttribute, const nsAString& aValue, - bool* aFirst, bool* aAny, bool* aAll) const; - [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult GetInlinePropertyWithAttrValue( - nsAtom* aHTMLProperty, nsAtom* aAttribute, const nsAString& aValue, - bool* aFirst, bool* aAny, bool* aAll, nsAString& outValue); + nsresult GetInlineProperty(nsAtom* aProperty, nsAtom* aAttribute, + const nsAString& aValue, bool* aFirst, bool* aAny, + bool* aAll) const; + nsresult GetInlinePropertyWithAttrValue(nsAtom* aProperty, nsAtom* aAttr, + const nsAString& aValue, bool* aFirst, + bool* aAny, bool* aAll, + nsAString& outValue); /** * RemoveInlinePropertyAsAction() removes a property which changes inline * style of text. E.g., bold, italic, super and sub. * - * @param aHTMLProperty Tag name whcih represents the inline style you want - * to remove. E.g., nsGkAtoms::strong, nsGkAtoms::b, - * etc. If nsGkAtoms::href, element which has - * href attribute will be removed. - * If nsGkAtoms::name, element which has non-empty - * name attribute will be removed. - * @param aAttribute If aHTMLProperty is nsGkAtoms::font, aAttribute should - * be nsGkAtoms::fase, nsGkAtoms::size, nsGkAtoms::color - * or nsGkAtoms::bgcolor. Otherwise, set nullptr. + * @param aProperty Tag name whcih represents the inline style you want to + * remove. E.g., nsGkAtoms::strong, nsGkAtoms::b, etc. + * If nsGkAtoms::href, element which has href + * attribute will be removed. + * If nsGkAtoms::name, element which has non-empty + * name attribute will be removed. + * @param aAttribute If aProperty is nsGkAtoms::font, aAttribute should be + * nsGkAtoms::fase, nsGkAtoms::size, nsGkAtoms::color or + * nsGkAtoms::bgcolor. Otherwise, set nullptr. * Must not use nsGkAtoms::_empty here. * @param aPrincipal Set subject principal if it may be called by JS. If * set to nullptr, will be treated as called by system. */ - MOZ_CAN_RUN_SCRIPT nsresult RemoveInlinePropertyAsAction( - nsStaticAtom& aHTMLProperty, nsStaticAtom* aAttribute, - nsIPrincipal* aPrincipal = nullptr); + MOZ_CAN_RUN_SCRIPT nsresult + RemoveInlinePropertyAsAction(nsAtom& aProperty, nsAtom* aAttribute, + nsIPrincipal* aPrincipal = nullptr); MOZ_CAN_RUN_SCRIPT nsresult RemoveAllInlinePropertiesAsAction(nsIPrincipal* aPrincipal = nullptr); @@ -533,8 +531,7 @@ class HTMLEditor final : public TextEditor, * Selection instance has gone, first range * Selection is broken. */ - [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult - GetFontColorState(bool* aIsMixed, nsAString& aColor); + nsresult GetFontColorState(bool* aIsMixed, nsAString& aColor); /** * SetComposerCommandsUpdater() sets or unsets mComposerCommandsUpdater. @@ -892,8 +889,9 @@ class HTMLEditor final : public TextEditor, * the element * @param aReturn [OUT] the new z-index of the element */ - [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult RelativeChangeElementZIndex( - Element& aElement, int32_t aChange, int32_t* aReturn); + MOZ_CAN_RUN_SCRIPT nsresult RelativeChangeElementZIndex(Element& aElement, + int32_t aChange, + int32_t* aReturn); virtual bool IsBlockNode(nsINode* aNode) const override; using EditorBase::IsBlockNode; @@ -1201,9 +1199,10 @@ class HTMLEditor final : public TextEditor, nsIContent* GetFirstEditableLeaf(nsINode& aNode); nsIContent* GetLastEditableLeaf(nsINode& aNode); - [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult GetInlinePropertyBase( - nsAtom& aHTMLProperty, nsAtom* aAttribute, const nsAString* aValue, - bool* aFirst, bool* aAny, bool* aAll, nsAString* outValue) const; + nsresult GetInlinePropertyBase(nsAtom& aProperty, nsAtom* aAttribute, + const nsAString* aValue, bool* aFirst, + bool* aAny, bool* aAll, + nsAString* outValue) const; /** * ClearStyleAt() splits parent elements to remove the specified style. @@ -1278,15 +1277,14 @@ class HTMLEditor final : public TextEditor, * values of CSS properties. */ [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult - GetInlineStyles(nsIContent& aContent, AutoStyleCacheArray& aStyleCacheArray); + GetInlineStyles(nsINode& aNode, AutoStyleCacheArray& aStyleCacheArray); /** - * CacheInlineStyles() caches style of aContent into mCachedInlineStyles of + * CacheInlineStyles() caches style of aNode into mCachedInlineStyles of * TopLevelEditSubAction. This may cause flushing layout at retrieving * computed value of CSS properties. */ - [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult - CacheInlineStyles(nsIContent& aContent); + [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult CacheInlineStyles(nsINode& aNode); /** * ReapplyCachedStyles() restores some styles which are disappeared during @@ -3428,21 +3426,21 @@ class HTMLEditor final : public TextEditor, * RemoveInlinePropertyInternal() removes specified style from `mTypeInState` * if `Selection` is collapsed. Otherwise, removing the style. * - * @param aHTMLProperty nullptr if you want to remove all inline styles. + * @param aProperty nullptr if you want to remove all inline styles. * Otherwise, one of the presentation tag names * which we support in style editor. - * @param aAttribute For some aHTMLProperty values, need to be set to + * @param aAttribute For some aProperty values, need to be set to * its attribute name. Otherwise, nullptr. * @param aRemoveRelatedElements If Yes, this method removes different * name's elements in the block if - * necessary. For example, if - * aHTMLProperty is nsGkAtoms::b, - * `` elements are also removed. + * necessary. For example, if aProperty + * is nsGkAtoms::b, `` elements + * are also removed. */ enum class RemoveRelatedElements { Yes, No }; - [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult RemoveInlinePropertyInternal( - nsStaticAtom* aHTMLProperty, nsStaticAtom* aAttribute, - RemoveRelatedElements aRemoveRelatedElements); + [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult + RemoveInlinePropertyInternal(nsAtom* aProperty, nsAtom* aAttribute, + RemoveRelatedElements aRemoveRelatedElements); /** * ReplaceHeadContentsWithSourceWithTransaction() replaces all children of @@ -3454,8 +3452,8 @@ class HTMLEditor final : public TextEditor, MOZ_CAN_RUN_SCRIPT nsresult ReplaceHeadContentsWithSourceWithTransaction( const nsAString& aSourceToInsert); - [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult GetCSSBackgroundColorState( - bool* aMixed, nsAString& aOutColor, bool aBlockLevel); + nsresult GetCSSBackgroundColorState(bool* aMixed, nsAString& aOutColor, + bool aBlockLevel); nsresult GetHTMLBackgroundColorState(bool* aMixed, nsAString& outColor); nsresult GetLastCellInRow(nsINode* aRowNode, nsINode** aCellNode); @@ -4126,14 +4124,10 @@ class HTMLEditor final : public TextEditor, * aProperty/aAttribute of parent block can be removed from aContent with * creating `` element. Note that this does NOT check whether the * specified style comes from parent block or not. - * XXX This may destroy the editor, but using `Result` - * is not reasonable because code for accessing the result becomes - * messy. However, anybody must forget to check `Destroyed()` after - * calling this. Which is the way to smart to make every caller - * must check the editor state? */ - MOZ_CAN_RUN_SCRIPT bool IsRemovableParentStyleWithNewSpanElement( - nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute) const; + static bool IsRemovableParentStyleWithNewSpanElement(nsIContent& aContent, + nsAtom* aProperty, + nsAtom* aAttribute); /** * XXX These methods seem odd and except the only caller, @@ -4227,10 +4221,10 @@ class HTMLEditor final : public TextEditor, * Returns the offset of an element's frame to its absolute containing block. */ nsresult GetElementOrigin(Element& aElement, int32_t& aX, int32_t& aY); - [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult GetPositionAndDimensions( - Element& aElement, int32_t& aX, int32_t& aY, int32_t& aW, int32_t& aH, - int32_t& aBorderLeft, int32_t& aBorderTop, int32_t& aMarginLeft, - int32_t& aMarginTop); + nsresult GetPositionAndDimensions(Element& aElement, int32_t& aX, int32_t& aY, + int32_t& aW, int32_t& aH, + int32_t& aBorderLeft, int32_t& aBorderTop, + int32_t& aMarginLeft, int32_t& aMarginTop); bool IsInObservedSubtree(nsIContent* aChild); @@ -4242,7 +4236,7 @@ class HTMLEditor final : public TextEditor, * while this is running, this returns error. So, callers shouldn't * keep handling the resizers if this returns error. */ - [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult SetAllResizersPosition(); + MOZ_CAN_RUN_SCRIPT nsresult SetAllResizersPosition(); /** * Shows active resizers around an element's frame @@ -4277,9 +4271,10 @@ class HTMLEditor final : public TextEditor, * @param aElementX Left of aElement. * @param aElementY Top of aElement. */ - [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult - SetShadowPosition(Element& aShadowElement, Element& aElement, - int32_t aElementLeft, int32_t aElementTop); + MOZ_CAN_RUN_SCRIPT nsresult SetShadowPosition(Element& aShadowElement, + Element& aElement, + int32_t aElementLeft, + int32_t aElementTop); ManualNACPtr CreateResizingInfo(nsIContent& aParentContent); MOZ_CAN_RUN_SCRIPT nsresult SetResizingInfoPosition(int32_t aX, int32_t aY, @@ -4358,9 +4353,8 @@ class HTMLEditor final : public TextEditor, void SnapToGrid(int32_t& newX, int32_t& newY); nsresult GrabberClicked(); MOZ_CAN_RUN_SCRIPT nsresult EndMoving(); - [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult - GetTemporaryStyleForFocusedPositionedElement(Element& aElement, - nsAString& aReturn); + nsresult GetTemporaryStyleForFocusedPositionedElement(Element& aElement, + nsAString& aReturn); /** * Shows inline table editing UI around a
element which contains @@ -4659,8 +4653,7 @@ class MOZ_STACK_CLASS ListItemElementSelectionState final { class MOZ_STACK_CLASS AlignStateAtSelection final { public: AlignStateAtSelection() = delete; - MOZ_CAN_RUN_SCRIPT AlignStateAtSelection(HTMLEditor& aHTMLEditor, - ErrorResult& aRv); + AlignStateAtSelection(HTMLEditor& aHTMLEditor, ErrorResult& aRv); nsIHTMLEditor::EAlignment AlignmentAtSelectionStart() const { return mFirstAlign; diff --git a/editor/libeditor/HTMLEditorCommands.cpp b/editor/libeditor/HTMLEditorCommands.cpp index 87c50db7a232..88069000d565 100644 --- a/editor/libeditor/HTMLEditorCommands.cpp +++ b/editor/libeditor/HTMLEditorCommands.cpp @@ -71,11 +71,11 @@ nsresult StateUpdatingCommandBase::DoCommand(Command aCommand, if (NS_WARN_IF(!htmlEditor)) { return NS_ERROR_FAILURE; } - nsStaticAtom* tagName = GetTagName(aCommand); + nsAtom* tagName = GetTagName(aCommand); if (NS_WARN_IF(!tagName)) { return NS_ERROR_UNEXPECTED; } - nsresult rv = ToggleState(MOZ_KnownLive(*tagName), MOZ_KnownLive(*htmlEditor), + nsresult rv = ToggleState(MOZ_KnownLive(tagName), MOZ_KnownLive(htmlEditor), aPrincipal); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "StateUpdatingCommandBase::ToggleState() failed"); @@ -176,20 +176,24 @@ nsresult StyleUpdatingCommand::GetCurrentState(nsAtom* aTagName, return NS_OK; } -nsresult StyleUpdatingCommand::ToggleState(nsStaticAtom& aTagName, - HTMLEditor& aHTMLEditor, +nsresult StyleUpdatingCommand::ToggleState(nsAtom* aTagName, + HTMLEditor* aHTMLEditor, nsIPrincipal* aPrincipal) const { + if (NS_WARN_IF(!aTagName) || NS_WARN_IF(!aHTMLEditor)) { + return NS_ERROR_INVALID_ARG; + } + RefPtr params = new nsCommandParams(); // tags "href" and "name" are special cases in the core editor // they are used to remove named anchor/link and shouldn't be used for // insertion bool doTagRemoval; - if (&aTagName == nsGkAtoms::href || &aTagName == nsGkAtoms::name) { + if (aTagName == nsGkAtoms::href || aTagName == nsGkAtoms::name) { doTagRemoval = true; } else { // check current selection; set doTagRemoval if formatting should be removed - nsresult rv = GetCurrentState(&aTagName, &aHTMLEditor, *params); + nsresult rv = GetCurrentState(aTagName, aHTMLEditor, *params); if (NS_FAILED(rv)) { NS_WARNING("StyleUpdatingCommand::GetCurrentState() failed"); return rv; @@ -202,15 +206,15 @@ nsresult StyleUpdatingCommand::ToggleState(nsStaticAtom& aTagName, } if (doTagRemoval) { - nsresult rv = - aHTMLEditor.RemoveInlinePropertyAsAction(aTagName, nullptr, aPrincipal); + nsresult rv = aHTMLEditor->RemoveInlinePropertyAsAction(*aTagName, nullptr, + aPrincipal); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::RemoveInlinePropertyAsAction() failed"); return rv; } - nsresult rv = aHTMLEditor.SetInlinePropertyAsAction( - aTagName, nullptr, EmptyString(), aPrincipal); + nsresult rv = aHTMLEditor->SetInlinePropertyAsAction( + *aTagName, nullptr, EmptyString(), aPrincipal); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::SetInlinePropertyAsAction() failed"); return rv; @@ -243,11 +247,14 @@ nsresult ListCommand::GetCurrentState(nsAtom* aTagName, HTMLEditor* aHTMLEditor, return NS_OK; } -nsresult ListCommand::ToggleState(nsStaticAtom& aTagName, - HTMLEditor& aHTMLEditor, +nsresult ListCommand::ToggleState(nsAtom* aTagName, HTMLEditor* aHTMLEditor, nsIPrincipal* aPrincipal) const { + if (NS_WARN_IF(!aTagName) || NS_WARN_IF(!aHTMLEditor)) { + return NS_ERROR_INVALID_ARG; + } + RefPtr params = new nsCommandParams(); - nsresult rv = GetCurrentState(&aTagName, &aHTMLEditor, *params); + nsresult rv = GetCurrentState(aTagName, aHTMLEditor, *params); if (NS_FAILED(rv)) { NS_WARNING("ListCommand::GetCurrentState() failed"); return rv; @@ -259,16 +266,16 @@ nsresult ListCommand::ToggleState(nsStaticAtom& aTagName, return error.StealNSResult(); } - nsDependentAtomString listType(&aTagName); + nsDependentAtomString listType(aTagName); if (inList) { - nsresult rv = aHTMLEditor.RemoveListAsAction(listType, aPrincipal); + rv = aHTMLEditor->RemoveListAsAction(listType, aPrincipal); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::RemoveListAsAction() failed"); return rv; } - rv = aHTMLEditor.MakeOrChangeListAsAction( - aTagName, EmptyString(), HTMLEditor::SelectAllOfCurrentList::No, + rv = aHTMLEditor->MakeOrChangeListAsAction( + *aTagName, EmptyString(), HTMLEditor::SelectAllOfCurrentList::No, aPrincipal); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::MakeOrChangeListAsAction() failed"); @@ -314,12 +321,15 @@ nsresult ListItemCommand::GetCurrentState(nsAtom* aTagName, return NS_OK; } -nsresult ListItemCommand::ToggleState(nsStaticAtom& aTagName, - HTMLEditor& aHTMLEditor, +nsresult ListItemCommand::ToggleState(nsAtom* aTagName, HTMLEditor* aHTMLEditor, nsIPrincipal* aPrincipal) const { + if (NS_WARN_IF(!aTagName) || NS_WARN_IF(!aHTMLEditor)) { + return NS_ERROR_INVALID_ARG; + } + // Need to use aTagName???? RefPtr params = new nsCommandParams(); - GetCurrentState(&aTagName, &aHTMLEditor, *params); + GetCurrentState(aTagName, aHTMLEditor, *params); ErrorResult error; bool inList = params->GetBool(STATE_ALL, error); if (NS_WARN_IF(error.Failed())) { @@ -330,7 +340,7 @@ nsresult ListItemCommand::ToggleState(nsStaticAtom& aTagName, // To remove a list, first get what kind of list we're in bool bMixed; nsAutoString localName; - nsresult rv = GetListState(&aHTMLEditor, &bMixed, localName); + nsresult rv = GetListState(aHTMLEditor, &bMixed, localName); if (NS_FAILED(rv)) { NS_WARNING("GetListState() failed"); return rv; @@ -338,7 +348,7 @@ nsresult ListItemCommand::ToggleState(nsStaticAtom& aTagName, if (localName.IsEmpty() || bMixed) { return NS_OK; } - rv = aHTMLEditor.RemoveListAsAction(localName, aPrincipal); + rv = aHTMLEditor->RemoveListAsAction(localName, aPrincipal); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::RemoveListAsAction() failed"); return rv; @@ -348,8 +358,8 @@ nsresult ListItemCommand::ToggleState(nsStaticAtom& aTagName, // XXX Note: This actually doesn't work for "LI", // but we currently don't use this for non DL lists anyway. // Problem: won't this replace any current block paragraph style? - nsresult rv = aHTMLEditor.SetParagraphFormatAsAction( - nsDependentAtomString(&aTagName), aPrincipal); + nsresult rv = aHTMLEditor->SetParagraphFormatAsAction( + nsDependentAtomString(aTagName), aPrincipal); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::SetParagraphFormatAsAction() failed"); return rv; @@ -924,12 +934,15 @@ nsresult AbsolutePositioningCommand::GetCurrentState( } nsresult AbsolutePositioningCommand::ToggleState( - nsStaticAtom& aTagName, HTMLEditor& aHTMLEditor, - nsIPrincipal* aPrincipal) const { + nsAtom* aTagName, HTMLEditor* aHTMLEditor, nsIPrincipal* aPrincipal) const { + if (NS_WARN_IF(!aHTMLEditor)) { + return NS_ERROR_INVALID_ARG; + } + RefPtr container = - aHTMLEditor.GetAbsolutelyPositionedSelectionContainer(); - nsresult rv = aHTMLEditor.SetSelectionToAbsoluteOrStaticAsAction(!container, - aPrincipal); + aHTMLEditor->GetAbsolutelyPositionedSelectionContainer(); + nsresult rv = aHTMLEditor->SetSelectionToAbsoluteOrStaticAsAction(!container, + aPrincipal); NS_WARNING_ASSERTION( NS_SUCCEEDED(rv), "HTMLEditor::SetSelectionToAbsoluteOrStaticAsAction() failed"); @@ -947,7 +960,7 @@ bool DecreaseZIndexCommand::IsCommandEnabled(Command aCommand, if (!aTextEditor) { return false; } - RefPtr htmlEditor = aTextEditor->AsHTMLEditor(); + HTMLEditor* htmlEditor = aTextEditor->AsHTMLEditor(); if (!htmlEditor) { return false; } diff --git a/editor/libeditor/HTMLEditorObjectResizer.cpp b/editor/libeditor/HTMLEditorObjectResizer.cpp index a58ef16fefc4..964408dafe24 100644 --- a/editor/libeditor/HTMLEditorObjectResizer.cpp +++ b/editor/libeditor/HTMLEditorObjectResizer.cpp @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "HTMLEditor.h" +#include "mozilla/HTMLEditor.h" #include "HTMLEditorEventListener.h" #include "HTMLEditUtils.h" @@ -141,28 +141,13 @@ nsresult HTMLEditor::SetAllResizersPosition() { float resizerWidth, resizerHeight; RefPtr dummyUnit; DebugOnly rvIgnored = NS_OK; - OwningNonNull topLeftHandle = *mTopLeftHandle.get(); - // XXX Do we really need to computed value rather than specified value? - // Because it's an anonymous node. - rvIgnored = CSSEditUtils::GetComputedProperty(*topLeftHandle, + rvIgnored = CSSEditUtils::GetComputedProperty(*mTopLeftHandle, *nsGkAtoms::width, value); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } - if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) { - return NS_ERROR_FAILURE; - } NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored), "CSSEditUtils::GetComputedProperty(nsGkAtoms::width) " "failed, but ignored"); - rvIgnored = CSSEditUtils::GetComputedProperty(*topLeftHandle, + rvIgnored = CSSEditUtils::GetComputedProperty(*mTopLeftHandle, *nsGkAtoms::height, value); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } - if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) { - return NS_ERROR_FAILURE; - } NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored), "CSSEditUtils::GetComputedProperty(nsGkAtoms::height) " "failed, but ignored"); @@ -179,69 +164,46 @@ nsresult HTMLEditor::SetAllResizersPosition() { // FYI: Note that only checking if mTopLeftHandle is replaced is enough. // We're may be in hot path if user resizes an element a lot. So, // we should just add-ref mTopLeftHandle. + RefPtr topLeftHandle = mTopLeftHandle.get(); SetAnonymousElementPosition(x - rw, y - rh, topLeftHandle); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) { return NS_ERROR_FAILURE; } RefPtr topHandle = mTopHandle.get(); SetAnonymousElementPosition(x + w / 2 - rw, y - rh, topHandle); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) { return NS_ERROR_FAILURE; } RefPtr topRightHandle = mTopRightHandle.get(); SetAnonymousElementPosition(x + w - rw - 1, y - rh, topRightHandle); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) { return NS_ERROR_FAILURE; } RefPtr leftHandle = mLeftHandle.get(); SetAnonymousElementPosition(x - rw, y + h / 2 - rh, leftHandle); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) { return NS_ERROR_FAILURE; } RefPtr rightHandle = mRightHandle.get(); SetAnonymousElementPosition(x + w - rw - 1, y + h / 2 - rh, rightHandle); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) { return NS_ERROR_FAILURE; } RefPtr bottomLeftHandle = mBottomLeftHandle.get(); SetAnonymousElementPosition(x - rw, y + h - rh - 1, bottomLeftHandle); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) { return NS_ERROR_FAILURE; } RefPtr bottomHandle = mBottomHandle.get(); SetAnonymousElementPosition(x + w / 2 - rw, y + h - rh - 1, bottomHandle); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) { return NS_ERROR_FAILURE; } RefPtr bottomRightHandle = mBottomRightHandle.get(); SetAnonymousElementPosition(x + w - rw - 1, y + h - rh - 1, bottomRightHandle); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) { return NS_ERROR_FAILURE; } @@ -269,37 +231,28 @@ nsresult HTMLEditor::RefreshResizersInternal() { return NS_OK; } - OwningNonNull resizedObject = *mResizedObject; nsresult rv = GetPositionAndDimensions( - resizedObject, mResizedObjectX, mResizedObjectY, mResizedObjectWidth, + *mResizedObject, mResizedObjectX, mResizedObjectY, mResizedObjectWidth, mResizedObjectHeight, mResizedObjectBorderLeft, mResizedObjectBorderTop, mResizedObjectMarginLeft, mResizedObjectMarginTop); if (NS_FAILED(rv)) { NS_WARNING("HTMLEditor::GetPositionAndDimensions() failed"); return rv; } - if (NS_WARN_IF(resizedObject != mResizedObject)) { - return NS_ERROR_FAILURE; - } rv = SetAllResizersPosition(); if (NS_FAILED(rv)) { NS_WARNING("HTMLEditor::SetAllResizersPosition() failed"); return rv; } - if (NS_WARN_IF(resizedObject != mResizedObject)) { - return NS_ERROR_FAILURE; - } MOZ_ASSERT( mResizingShadow, "SetAllResizersPosition() should return error if resizers are hidden"); RefPtr resizingShadow = mResizingShadow.get(); - rv = SetShadowPosition(*resizingShadow, resizedObject, mResizedObjectX, + RefPtr resizedObject = mResizedObject; + rv = SetShadowPosition(*resizingShadow, *resizedObject, mResizedObjectX, mResizedObjectY); - if (NS_WARN_IF(resizedObject != mResizedObject)) { - return NS_ERROR_FAILURE; - } NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::SetShadowPosition() failed"); return rv; @@ -945,9 +898,6 @@ nsresult HTMLEditor::SetShadowPosition(Element& aShadowElement, : mPositioningShadow.get(); SetAnonymousElementPosition(aElementX, aElementY, &aShadowElement); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } if (NS_WARN_IF(&aShadowElement != handlingShadowElement)) { return NS_ERROR_FAILURE; } @@ -960,9 +910,6 @@ nsresult HTMLEditor::SetShadowPosition(Element& aShadowElement, aElement.GetAttr(kNameSpaceID_None, nsGkAtoms::src, imageSource); nsresult rv = aShadowElement.SetAttr(kNameSpaceID_None, nsGkAtoms::src, imageSource, true); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } if (NS_FAILED(rv)) { NS_WARNING("Element::SetAttr(nsGkAtoms::src) failed"); return NS_ERROR_FAILURE; diff --git a/editor/libeditor/HTMLStyleEditor.cpp b/editor/libeditor/HTMLStyleEditor.cpp index 56363cafaa78..ecabd7c4ecee 100644 --- a/editor/libeditor/HTMLStyleEditor.cpp +++ b/editor/libeditor/HTMLStyleEditor.cpp @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "HTMLEditor.h" +#include "mozilla/HTMLEditor.h" #include "HTMLEditUtils.h" #include "TypeInState.h" @@ -46,6 +46,13 @@ namespace mozilla { using namespace dom; +static already_AddRefed AtomizeAttribute(const nsAString& aAttribute) { + if (aAttribute.IsEmpty()) { + return nullptr; // Don't use nsGkAtoms::_empty for attribute. + } + return NS_Atomize(aAttribute); +} + nsresult HTMLEditor::SetInlinePropertyAsAction(nsAtom& aProperty, nsAtom* aAttribute, const nsAString& aValue, @@ -137,7 +144,7 @@ NS_IMETHODIMP HTMLEditor::SetInlineProperty(const nsAString& aProperty, if (NS_WARN_IF(!property)) { return NS_ERROR_INVALID_ARG; } - nsStaticAtom* attribute = EditorUtils::GetAttributeAtom(aAttribute); + RefPtr attribute = AtomizeAttribute(aAttribute); AutoEditActionDataSetter editActionData( *this, HTMLEditUtils::GetEditActionForFormatText(*property, attribute, true)); @@ -160,7 +167,7 @@ NS_IMETHODIMP HTMLEditor::SetInlineProperty(const nsAString& aProperty, "CanHandleAndMaybeDispatchBeforeInputEvent(), failed"); return EditorBase::ToGenericNSResult(rv); } - rv = SetInlinePropertyInternal(*property, MOZ_KnownLive(attribute), aValue); + rv = SetInlinePropertyInternal(*property, attribute, aValue); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::SetInlinePropertyInternal() failed"); return EditorBase::ToGenericNSResult(rv); @@ -399,9 +406,8 @@ nsresult HTMLEditor::SetInlinePropertyOnTextNode( if (CSSEditUtils::IsCSSEditableProperty(&aText, &aProperty, aAttribute)) { // The HTML styles defined by aProperty/aAttribute have a CSS equivalence // for node; let's check if it carries those CSS styles - nsAutoString value(aValue); - if (CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet( - aText, &aProperty, aAttribute, value)) { + if (CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet( + &aText, &aProperty, aAttribute, aValue, CSSEditUtils::eComputed)) { return NS_OK; } } else if (IsTextPropertySetByContent(&aText, &aProperty, aAttribute, @@ -484,18 +490,18 @@ nsresult HTMLEditor::SetInlinePropertyOnTextNode( return rv; } -nsresult HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aContent, +nsresult HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode, nsAtom& aProperty, nsAtom* aAttribute, const nsAString& aValue) { // If this is an element that can't be contained in a span, we have to // recurse to its children. - if (!TagCanContain(*nsGkAtoms::span, aContent)) { - if (aContent.HasChildren()) { + if (!TagCanContain(*nsGkAtoms::span, aNode)) { + if (aNode.HasChildren()) { nsTArray> arrayOfNodes; // Populate the list. - for (nsCOMPtr child = aContent.GetFirstChild(); child; + for (nsCOMPtr child = aNode.GetFirstChild(); child; child = child->GetNextSibling()) { if (IsEditable(child) && !IsEmptyTextNode(*child)) { arrayOfNodes.AppendElement(*child); @@ -518,11 +524,11 @@ nsresult HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aContent, } // First check if there's an adjacent sibling we can put our node into. - nsCOMPtr previousSibling = GetPriorHTMLSibling(&aContent); - nsCOMPtr nextSibling = GetNextHTMLSibling(&aContent); + nsCOMPtr previousSibling = GetPriorHTMLSibling(&aNode); + nsCOMPtr nextSibling = GetNextHTMLSibling(&aNode); if (IsSimpleModifiableNode(previousSibling, &aProperty, aAttribute, &aValue)) { - nsresult rv = MoveNodeToEndWithTransaction(aContent, *previousSibling); + nsresult rv = MoveNodeToEndWithTransaction(aNode, *previousSibling); if (NS_FAILED(rv)) { NS_WARNING("EditorBase::MoveNodeToEndWithTransaction() failed"); return rv; @@ -537,26 +543,25 @@ nsresult HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aContent, } if (IsSimpleModifiableNode(nextSibling, &aProperty, aAttribute, &aValue)) { nsresult rv = - MoveNodeWithTransaction(aContent, EditorDOMPoint(nextSibling, 0)); + MoveNodeWithTransaction(aNode, EditorDOMPoint(nextSibling, 0)); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "EditorBase::MoveNodeWithTransaction() failed"); return rv; } // Don't need to do anything if property already set on node - if (CSSEditUtils::IsCSSEditableProperty(&aContent, &aProperty, aAttribute)) { - nsAutoString value(aValue); - if (CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet( - aContent, &aProperty, aAttribute, value)) { + if (CSSEditUtils::IsCSSEditableProperty(&aNode, &aProperty, aAttribute)) { + if (CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet( + &aNode, &aProperty, aAttribute, aValue, CSSEditUtils::eComputed)) { return NS_OK; } - } else if (IsTextPropertySetByContent(&aContent, &aProperty, aAttribute, + } else if (IsTextPropertySetByContent(&aNode, &aProperty, aAttribute, &aValue)) { return NS_OK; } bool useCSS = (IsCSSEnabled() && CSSEditUtils::IsCSSEditableProperty( - &aContent, &aProperty, aAttribute)) || + &aNode, &aProperty, aAttribute)) || // bgcolor is always done using CSS aAttribute == nsGkAtoms::bgcolor || // called for removing parent style, we should use CSS with @@ -567,11 +572,11 @@ nsresult HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aContent, RefPtr spanElement; // We only add style="" to s with no attributes (bug 746515). If we // don't have one, we need to make one. - if (aContent.IsHTMLElement(nsGkAtoms::span) && - !aContent.AsElement()->GetAttrCount()) { - spanElement = aContent.AsElement(); + if (aNode.IsHTMLElement(nsGkAtoms::span) && + !aNode.AsElement()->GetAttrCount()) { + spanElement = aNode.AsElement(); } else { - spanElement = InsertContainerWithTransaction(aContent, *nsGkAtoms::span); + spanElement = InsertContainerWithTransaction(aNode, *nsGkAtoms::span); if (!spanElement) { NS_WARNING( "EditorBase::InsertContainerWithTransaction(nsGkAtoms::span) " @@ -587,13 +592,13 @@ nsresult HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aContent, } // is it already the right kind of node, but with wrong attribute? - if (aContent.IsHTMLElement(&aProperty)) { + if (aNode.IsHTMLElement(&aProperty)) { if (NS_WARN_IF(!aAttribute)) { return NS_ERROR_INVALID_ARG; } // Just set the attribute on it. - nsresult rv = SetAttributeWithTransaction( - MOZ_KnownLive(*aContent.AsElement()), *aAttribute, aValue); + nsresult rv = SetAttributeWithTransaction(MOZ_KnownLive(*aNode.AsElement()), + *aAttribute, aValue); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "EditorBase::SetAttributeWithTransaction() failed"); return rv; @@ -601,8 +606,7 @@ nsresult HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aContent, // ok, chuck it in its very own container RefPtr newContainerElement = InsertContainerWithTransaction( - aContent, aProperty, aAttribute ? *aAttribute : *nsGkAtoms::_empty, - aValue); + aNode, aProperty, aAttribute ? *aAttribute : *nsGkAtoms::_empty, aValue); NS_WARNING_ASSERTION(newContainerElement, "EditorBase::InsertContainerWithTransaction() failed"); return newContainerElement ? NS_OK : NS_ERROR_FAILURE; @@ -761,8 +765,8 @@ SplitNodeResult HTMLEditor::SplitAncestorStyledInlineElementsAt( // in this implementation for the node; let's check if it carries those // CSS styles nsAutoString firstValue; - isSetByCSS = CSSEditUtils::IsSpecifiedCSSEquivalentToHTMLInlineStyleSet( - *content, aProperty, aAttribute, firstValue); + isSetByCSS = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet( + content, aProperty, aAttribute, firstValue, CSSEditUtils::eSpecified); } if (!isSetByCSS) { if (!content->IsElement()) { @@ -1091,8 +1095,8 @@ nsresult HTMLEditor::RemoveStyleInside(Element& aElement, nsAtom* aProperty, // XXX aElement may have already been removed from the DOM tree. Why // do we keep handling aElement here?? if (CSSEditUtils::IsCSSEditableProperty(&aElement, aProperty, aAttribute) && - CSSEditUtils::HaveSpecifiedCSSEquivalentStyles(aElement, aProperty, - aAttribute)) { + CSSEditUtils::HaveCSSEquivalentStyles(aElement, aProperty, aAttribute, + CSSEditUtils::eSpecified)) { // If aElement has CSS declaration of the given style, remove it. DebugOnly rvIgnored = mCSSEditUtils->RemoveCSSEquivalentToHTMLStyle( @@ -1303,7 +1307,7 @@ bool HTMLEditor::IsEndOfContainerOrEqualsOrAfterLastEditableChild( return EditorRawDOMPoint(lastEditableChild).Offset() < aPoint.Offset(); } -nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aHTMLProperty, +nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aProperty, nsAtom* aAttribute, const nsAString* aValue, bool* aFirst, bool* aAny, bool* aAll, @@ -1331,40 +1335,36 @@ nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aHTMLProperty, bool isSet, theSetting; nsString tOutString; if (aAttribute) { - mTypeInState->GetTypingState(isSet, theSetting, &aHTMLProperty, - aAttribute, &tOutString); + mTypeInState->GetTypingState(isSet, theSetting, &aProperty, aAttribute, + &tOutString); if (outValue) { outValue->Assign(tOutString); } } else { - mTypeInState->GetTypingState(isSet, theSetting, &aHTMLProperty); + mTypeInState->GetTypingState(isSet, theSetting, &aProperty); } if (isSet) { *aFirst = *aAny = *aAll = theSetting; return NS_OK; } - if (collapsedNode->IsContent() && - CSSEditUtils::IsCSSEditableProperty(collapsedNode, &aHTMLProperty, + if (CSSEditUtils::IsCSSEditableProperty(collapsedNode, &aProperty, aAttribute)) { if (aValue) { tOutString.Assign(*aValue); } *aFirst = *aAny = *aAll = - CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet( - MOZ_KnownLive(*collapsedNode->AsContent()), &aHTMLProperty, - aAttribute, tOutString); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } + CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet( + collapsedNode, &aProperty, aAttribute, tOutString, + CSSEditUtils::eComputed); if (outValue) { outValue->Assign(tOutString); } return NS_OK; } - isSet = IsTextPropertySetByContent(collapsedNode, &aHTMLProperty, - aAttribute, aValue, outValue); + isSet = IsTextPropertySetByContent(collapsedNode, &aProperty, aAttribute, + aValue, outValue); *aFirst = *aAny = *aAll = isSet; return NS_OK; } @@ -1412,24 +1412,22 @@ nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aHTMLProperty, bool isSet = false; bool useTextDecoration = - &aHTMLProperty == nsGkAtoms::u || &aHTMLProperty == nsGkAtoms::strike; + &aProperty == nsGkAtoms::u || &aProperty == nsGkAtoms::strike; if (first) { - if (CSSEditUtils::IsCSSEditableProperty(content, &aHTMLProperty, + if (CSSEditUtils::IsCSSEditableProperty(content, &aProperty, aAttribute)) { - // The HTML styles defined by aHTMLProperty/aAttribute have a CSS + // The HTML styles defined by aProperty/aAttribute have a CSS // equivalence in this implementation for node; let's check if it // carries those CSS styles if (aValue) { firstValue.Assign(*aValue); } - isSet = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet( - *content, &aHTMLProperty, aAttribute, firstValue); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } + isSet = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet( + content, &aProperty, aAttribute, firstValue, + CSSEditUtils::eComputed); } else { - isSet = IsTextPropertySetByContent(content, &aHTMLProperty, - aAttribute, aValue, &firstValue); + isSet = IsTextPropertySetByContent(content, &aProperty, aAttribute, + aValue, &firstValue); } *aFirst = isSet; first = false; @@ -1437,22 +1435,20 @@ nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aHTMLProperty, *outValue = firstValue; } } else { - if (CSSEditUtils::IsCSSEditableProperty(content, &aHTMLProperty, + if (CSSEditUtils::IsCSSEditableProperty(content, &aProperty, aAttribute)) { - // The HTML styles defined by aHTMLProperty/aAttribute have a CSS + // The HTML styles defined by aProperty/aAttribute have a CSS // equivalence in this implementation for node; let's check if it // carries those CSS styles if (aValue) { theValue.Assign(*aValue); } - isSet = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet( - *content, &aHTMLProperty, aAttribute, theValue); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } + isSet = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet( + content, &aProperty, aAttribute, theValue, + CSSEditUtils::eComputed); } else { - isSet = IsTextPropertySetByContent(content, &aHTMLProperty, - aAttribute, aValue, &theValue); + isSet = IsTextPropertySetByContent(content, &aProperty, aAttribute, + aValue, &theValue); } if (firstValue != theValue && @@ -1491,25 +1487,24 @@ nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aHTMLProperty, return NS_OK; } -NS_IMETHODIMP HTMLEditor::GetInlineProperty(const nsAString& aHTMLProperty, +NS_IMETHODIMP HTMLEditor::GetInlineProperty(const nsAString& aProperty, const nsAString& aAttribute, const nsAString& aValue, bool* aFirst, bool* aAny, bool* aAll) { - RefPtr property = NS_Atomize(aHTMLProperty); - nsStaticAtom* attribute = EditorUtils::GetAttributeAtom(aAttribute); - nsresult rv = GetInlineProperty(property, MOZ_KnownLive(attribute), aValue, - aFirst, aAny, aAll); + RefPtr property = NS_Atomize(aProperty); + RefPtr attribute = AtomizeAttribute(aAttribute); + nsresult rv = + GetInlineProperty(property, attribute, aValue, aFirst, aAny, aAll); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::GetInlineProperty() failed"); return rv; } -nsresult HTMLEditor::GetInlineProperty(nsAtom* aHTMLProperty, - nsAtom* aAttribute, +nsresult HTMLEditor::GetInlineProperty(nsAtom* aProperty, nsAtom* aAttribute, const nsAString& aValue, bool* aFirst, bool* aAny, bool* aAll) const { - if (NS_WARN_IF(!aHTMLProperty) || NS_WARN_IF(!aFirst) || NS_WARN_IF(!aAny) || + if (NS_WARN_IF(!aProperty) || NS_WARN_IF(!aFirst) || NS_WARN_IF(!aAny) || NS_WARN_IF(!aAll)) { return NS_ERROR_INVALID_ARG; } @@ -1520,30 +1515,30 @@ nsresult HTMLEditor::GetInlineProperty(nsAtom* aHTMLProperty, } const nsAString* val = !aValue.IsEmpty() ? &aValue : nullptr; - nsresult rv = GetInlinePropertyBase(*aHTMLProperty, aAttribute, val, aFirst, - aAny, aAll, nullptr); + nsresult rv = GetInlinePropertyBase(*aProperty, aAttribute, val, aFirst, aAny, + aAll, nullptr); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::GetInlinePropertyBase() failed"); return EditorBase::ToGenericNSResult(rv); } NS_IMETHODIMP HTMLEditor::GetInlinePropertyWithAttrValue( - const nsAString& aHTMLProperty, const nsAString& aAttribute, + const nsAString& aProperty, const nsAString& aAttribute, const nsAString& aValue, bool* aFirst, bool* aAny, bool* aAll, nsAString& outValue) { - RefPtr property = NS_Atomize(aHTMLProperty); - nsStaticAtom* attribute = EditorUtils::GetAttributeAtom(aAttribute); - nsresult rv = GetInlinePropertyWithAttrValue( - property, MOZ_KnownLive(attribute), aValue, aFirst, aAny, aAll, outValue); + RefPtr property = NS_Atomize(aProperty); + RefPtr attribute = AtomizeAttribute(aAttribute); + nsresult rv = GetInlinePropertyWithAttrValue(property, attribute, aValue, + aFirst, aAny, aAll, outValue); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::GetInlinePropertyWithAttrValue() failed"); return rv; } nsresult HTMLEditor::GetInlinePropertyWithAttrValue( - nsAtom* aHTMLProperty, nsAtom* aAttribute, const nsAString& aValue, + nsAtom* aProperty, nsAtom* aAttribute, const nsAString& aValue, bool* aFirst, bool* aAny, bool* aAll, nsAString& outValue) { - if (NS_WARN_IF(!aHTMLProperty) || NS_WARN_IF(!aFirst) || NS_WARN_IF(!aAny) || + if (NS_WARN_IF(!aProperty) || NS_WARN_IF(!aFirst) || NS_WARN_IF(!aAny) || NS_WARN_IF(!aAll)) { return NS_ERROR_INVALID_ARG; } @@ -1554,8 +1549,8 @@ nsresult HTMLEditor::GetInlinePropertyWithAttrValue( } const nsAString* val = !aValue.IsEmpty() ? &aValue : nullptr; - nsresult rv = GetInlinePropertyBase(*aHTMLProperty, aAttribute, val, aFirst, - aAny, aAll, &outValue); + nsresult rv = GetInlinePropertyBase(*aProperty, aAttribute, val, aFirst, aAny, + aAll, &outValue); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::GetInlinePropertyBase() failed"); return EditorBase::ToGenericNSResult(rv); @@ -1592,13 +1587,12 @@ nsresult HTMLEditor::RemoveAllInlinePropertiesAsAction( return EditorBase::ToGenericNSResult(rv); } -nsresult HTMLEditor::RemoveInlinePropertyAsAction(nsStaticAtom& aHTMLProperty, - nsStaticAtom* aAttribute, +nsresult HTMLEditor::RemoveInlinePropertyAsAction(nsAtom& aProperty, + nsAtom* aAttribute, nsIPrincipal* aPrincipal) { AutoEditActionDataSetter editActionData( *this, - HTMLEditUtils::GetEditActionForFormatText(aHTMLProperty, aAttribute, - false), + HTMLEditUtils::GetEditActionForFormatText(aProperty, aAttribute, false), aPrincipal); switch (editActionData.GetEditAction()) { case EditAction::eRemoveFontFamilyProperty: @@ -1619,7 +1613,7 @@ nsresult HTMLEditor::RemoveInlinePropertyAsAction(nsStaticAtom& aHTMLProperty, return EditorBase::ToGenericNSResult(rv); } - rv = RemoveInlinePropertyInternal(&aHTMLProperty, aAttribute, + rv = RemoveInlinePropertyInternal(&aProperty, aAttribute, RemoveRelatedElements::Yes); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::RemoveInlinePropertyInternal(" @@ -1629,8 +1623,8 @@ nsresult HTMLEditor::RemoveInlinePropertyAsAction(nsStaticAtom& aHTMLProperty, NS_IMETHODIMP HTMLEditor::RemoveInlineProperty(const nsAString& aProperty, const nsAString& aAttribute) { - nsStaticAtom* property = NS_GetStaticAtom(aProperty); - nsStaticAtom* attribute = EditorUtils::GetAttributeAtom(aAttribute); + RefPtr property = NS_Atomize(aProperty); + RefPtr attribute = AtomizeAttribute(aAttribute); AutoEditActionDataSetter editActionData( *this, @@ -1654,8 +1648,7 @@ NS_IMETHODIMP HTMLEditor::RemoveInlineProperty(const nsAString& aProperty, return EditorBase::ToGenericNSResult(rv); } - rv = RemoveInlinePropertyInternal(MOZ_KnownLive(property), - MOZ_KnownLive(attribute), + rv = RemoveInlinePropertyInternal(property, attribute, RemoveRelatedElements::No); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::RemoveInlinePropertyInternal(" @@ -1664,7 +1657,7 @@ NS_IMETHODIMP HTMLEditor::RemoveInlineProperty(const nsAString& aProperty, } nsresult HTMLEditor::RemoveInlinePropertyInternal( - nsStaticAtom* aProperty, nsStaticAtom* aAttribute, + nsAtom* aProperty, nsAtom* aAttribute, RemoveRelatedElements aRemoveRelatedElements) { MOZ_ASSERT(IsEditActionDataAvailable()); MOZ_ASSERT(aAttribute != nsGkAtoms::_empty); @@ -1680,12 +1673,11 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal( // Also remove equivalent properties (bug 317093) struct HTMLStyle final { // HTML tag name or nsGkAtoms::href or nsGkAtoms::name. - nsStaticAtom* mProperty = nullptr; + nsAtom* mProperty = nullptr; // HTML attribute like nsGkAtom::color for nsGkAtoms::font. - nsStaticAtom* mAttribute = nullptr; + nsAtom* mAttribute = nullptr; - explicit HTMLStyle(nsStaticAtom* aProperty, - nsStaticAtom* aAttribute = nullptr) + explicit HTMLStyle(nsAtom* aProperty, nsAtom* aAttribute = nullptr) : mProperty(aProperty), mAttribute(aAttribute) {} }; AutoTArray removeStyles; @@ -1874,7 +1866,7 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal( } } - for (OwningNonNull& content : arrayOfContents) { + for (auto& content : arrayOfContents) { if (content->IsElement()) { nsresult rv = RemoveStyleInside(MOZ_KnownLive(*content->AsElement()), @@ -1886,13 +1878,8 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal( } } - bool isRemovable = IsRemovableParentStyleWithNewSpanElement( - MOZ_KnownLive(content), MOZ_KnownLive(style.mProperty), - MOZ_KnownLive(style.mAttribute)); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } - if (!isRemovable) { + if (!HTMLEditor::IsRemovableParentStyleWithNewSpanElement( + content, style.mProperty, style.mAttribute)) { continue; } @@ -1945,20 +1932,15 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal( // Finally, we should remove the style from all leaf text nodes if // they still have the style. AutoTArray, 32> leafTextNodes; - for (OwningNonNull& content : arrayOfContents) { + for (auto& content : arrayOfContents) { if (content->IsElement()) { CollectEditableLeafTextNodes(*content->AsElement(), leafTextNodes); } } - for (OwningNonNull& textNode : leafTextNodes) { - bool isRemovable = IsRemovableParentStyleWithNewSpanElement( - MOZ_KnownLive(textNode), MOZ_KnownLive(style.mProperty), - MOZ_KnownLive(style.mAttribute)); - if (NS_WARN_IF(Destroyed())) { - return NS_ERROR_EDITOR_DESTROYED; - } - if (!isRemovable) { + for (auto& textNode : leafTextNodes) { + if (!HTMLEditor::IsRemovableParentStyleWithNewSpanElement( + textNode, style.mProperty, style.mAttribute)) { continue; } // MOZ_KnownLive because 'leafTextNodes' is guaranteed to @@ -1984,23 +1966,24 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal( return NS_WARN_IF(Destroyed()) ? NS_ERROR_EDITOR_DESTROYED : NS_OK; } -bool HTMLEditor::IsRemovableParentStyleWithNewSpanElement( - nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute) const { +// static +bool HTMLEditor::IsRemovableParentStyleWithNewSpanElement(nsIContent& aContent, + nsAtom* aProperty, + nsAtom* aAttribute) { // We don't support to remove all inline styles with this path. - if (!aHTMLProperty) { + if (!aProperty) { return false; } // First check whether the style is invertible since this is the fastest // check. - if (!CSSEditUtils::IsCSSInvertible(*aHTMLProperty, aAttribute)) { + if (!CSSEditUtils::IsCSSInvertible(*aProperty, aAttribute)) { return false; } // If parent block has the removing style, we should create `` // element to remove the style even in HTML mode since Chrome does it. - if (!CSSEditUtils::IsCSSEditableProperty(&aContent, aHTMLProperty, - aAttribute)) { + if (!CSSEditUtils::IsCSSEditableProperty(&aContent, aProperty, aAttribute)) { return false; } @@ -2009,10 +1992,8 @@ bool HTMLEditor::IsRemovableParentStyleWithNewSpanElement( // in the ancestors of aContent carrying specified styles; // assume it comes from a rule and let's try to insert a span // "inverting" the style - nsAutoString emptyString; - bool isSet = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet( - aContent, aHTMLProperty, aAttribute, emptyString); - return NS_WARN_IF(Destroyed()) ? false : isSet; + return CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet( + &aContent, aProperty, aAttribute, EmptyString(), CSSEditUtils::eComputed); } void HTMLEditor::CollectEditableLeafTextNodes( @@ -2496,10 +2477,7 @@ nsresult HTMLEditor::GetFontColorState(bool* aMixed, nsAString& aOutColor) { bool first, any, all; nsresult rv = GetInlinePropertyBase(*nsGkAtoms::font, nsGkAtoms::color, nullptr, &first, &any, &all, &aOutColor); - if (NS_FAILED(rv)) { - NS_WARNING( - "HTMLEditor::GetInlinePropertyBase(nsGkAtoms::font, nsGkAtoms::color) " - "failed"); + if (NS_WARN_IF(NS_FAILED(rv))) { return EditorBase::ToGenericNSResult(rv); } diff --git a/editor/nsIHTMLEditor.idl b/editor/nsIHTMLEditor.idl index 5a4c98258feb..478d5eacd54f 100644 --- a/editor/nsIHTMLEditor.idl +++ b/editor/nsIHTMLEditor.idl @@ -66,7 +66,6 @@ interface nsIHTMLEditor : nsISupports * @param aAll [OUT] PR_TRUE if all of the text nodes in the * selection have the property */ - [can_run_script] void getInlineProperty(in AString aProperty, in AString aAttribute, in AString aValue, @@ -74,7 +73,6 @@ interface nsIHTMLEditor : nsISupports out boolean aAny, out boolean aAll); - [can_run_script] AString getInlinePropertyWithAttrValue(in AString aProperty, in AString aAttribute, in AString aValue, @@ -198,7 +196,6 @@ interface nsIHTMLEditor : nsISupports * @return Name of face. Note: "tt" is returned for * tt tag. "" is returned for none. */ - [can_run_script] AString getFontFaceState(out boolean aMixed); /** @@ -206,7 +203,6 @@ interface nsIHTMLEditor : nsISupports * @param aMixed True if there is more than one font color * @return Color string. "" is returned for none. */ - [can_run_script] AString getHighlightColorState(out boolean aMixed); /** @@ -241,7 +237,6 @@ interface nsIHTMLEditor : nsISupports * @param aAlign enum value for first encountered alignment * (left/center/right) */ - [can_run_script] void getAlignment(out boolean aMixed, out short aAlign); /**