Bug 1627573 - part 2: Split public methods of CSSEditUtils which work with both specified values and computed values r=m_kato

Some methods take `StyleType` to work them with specified values or computed
values.  This method hides `StyleType` into `CSSEditUtils` and splits the
public methods which took `StyleType` to 2 methods, one is for working with
specified values, the other is for working with computed values.

Additionally, this patch fixes some argument name and type.

Differential Revision: https://phabricator.services.mozilla.com/D70149

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Masayuki Nakano 2020-04-09 10:08:37 +00:00
parent ac60892e7d
commit ea92dfc783
6 changed files with 335 additions and 268 deletions

View File

@ -443,61 +443,74 @@ nsresult CSSEditUtils::RemoveCSSProperty(Element& aElement, nsAtom& aProperty,
}
// static
nsresult CSSEditUtils::GetSpecifiedProperty(nsINode& aNode, nsAtom& aProperty,
nsresult CSSEditUtils::GetSpecifiedProperty(nsIContent& aContent,
nsAtom& aCSSProperty,
nsAString& aValue) {
nsresult rv =
GetCSSInlinePropertyBase(&aNode, &aProperty, aValue, eSpecified);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"CSSEditUtils::GetCSSInlinePropertyBase() failed");
GetSpecifiedCSSInlinePropertyBase(aContent, aCSSProperty, aValue);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rv),
"CSSEditUtils::GeSpecifiedCSSInlinePropertyBase() failed");
return rv;
}
// static
nsresult CSSEditUtils::GetComputedProperty(nsINode& aNode, nsAtom& aProperty,
nsresult CSSEditUtils::GetComputedProperty(nsIContent& aContent,
nsAtom& aCSSProperty,
nsAString& aValue) {
nsresult rv = GetCSSInlinePropertyBase(&aNode, &aProperty, aValue, eComputed);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"CSSEditUtils::GetCSSInlinePropertyBase() failed");
nsresult rv =
GetComputedCSSInlinePropertyBase(aContent, aCSSProperty, aValue);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rv),
"CSSEditUtils::GetComputedCSSInlinePropertyBase() failed");
return rv;
}
// static
nsresult CSSEditUtils::GetCSSInlinePropertyBase(nsINode* aNode,
nsAtom* aProperty,
nsAString& aValue,
StyleType aStyleType) {
MOZ_ASSERT(aNode && aProperty);
nsresult CSSEditUtils::GetComputedCSSInlinePropertyBase(nsIContent& aContent,
nsAtom& aCSSProperty,
nsAString& aValue) {
aValue.Truncate();
RefPtr<Element> element = aNode->GetAsElementOrParentElement();
RefPtr<Element> 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<nsComputedDOMStyle> 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;
// Get the all the computed css styles attached to the element node
RefPtr<nsComputedDOMStyle> 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> element = aContent.GetAsElementOrParentElement();
if (NS_WARN_IF(!element)) {
return NS_ERROR_INVALID_ARG;
}
MOZ_ASSERT(aStyleType == eSpecified);
RefPtr<DeclarationBlock> decl = element->GetInlineStyleDeclaration();
if (!decl) {
return NS_OK;
}
nsCSSPropertyID prop = nsCSSProps::LookupProperty(nsAtomCString(aProperty));
nsCSSPropertyID prop =
nsCSSProps::LookupProperty(nsAtomCString(&aCSSProperty));
MOZ_ASSERT(prop != eCSSProperty_UNKNOWN);
decl->GetPropertyValueByID(prop, aValue);
@ -895,17 +908,19 @@ nsresult CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(
return NS_OK;
}
// returns in aValueString the list of values for the CSS equivalences to
// the HTML style aHTMLProperty/aAttribute/aValueString for the node aNode;
// returns in aValue the list of values for the CSS equivalences to
// the HTML style aHTMLProperty/aAttribute/aValue for the node aNode;
// the value of aStyleType controls the styles we retrieve : specified or
// computed.
// static
nsresult CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(
nsINode* aNode, nsAtom* aHTMLProperty, nsAtom* aAttribute,
nsAString& aValueString, StyleType aStyleType) {
aValueString.Truncate();
RefPtr<Element> theElement = aNode->GetAsElementOrParentElement();
nsresult CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSetInternal(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute,
nsAString& aValue, StyleType aStyleType) {
MOZ_ASSERT(aHTMLProperty || aAttribute);
aValue.Truncate();
RefPtr<Element> theElement = aContent.GetAsElementOrParentElement();
if (NS_WARN_IF(!theElement)) {
return NS_ERROR_INVALID_ARG;
}
@ -927,107 +942,110 @@ nsresult CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(
for (int32_t index = 0; index < count; index++) {
nsAutoString valueString;
// retrieve the specified/computed value of the property
nsresult rv = GetCSSInlinePropertyBase(theElement, cssPropertyArray[index],
valueString, aStyleType);
if (NS_FAILED(rv)) {
NS_WARNING("CSSEditUtils::GetCSSInlinePropertyBase() failed");
return rv;
if (aStyleType == StyleType::Computed) {
nsresult rv = GetComputedCSSInlinePropertyBase(
*theElement, *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;
}
}
// append the value to aValueString (possibly with a leading whitespace)
// append the value to aValue (possibly with a leading whitespace)
if (index) {
aValueString.Append(char16_t(' '));
aValue.Append(char16_t(' '));
}
aValueString.Append(valueString);
aValue.Append(valueString);
}
return NS_OK;
}
// 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.
// 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.
//
// The nsIContent variant returns aIsSet instead of using an out parameter, and
// does not modify aValue.
// static
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);
}
bool CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSetInternal(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute,
nsAString& aValue, StyleType aStyleType) {
MOZ_ASSERT(aHTMLProperty || aAttribute);
// static
bool CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
nsAtom* aHTMLProperty,
nsAtom* aHTMLAttribute,
nsAString& valueString,
StyleType aStyleType) {
if (NS_WARN_IF(!aNode)) {
return false;
}
nsAutoString htmlValueString(valueString);
nsAutoString htmlValueString(aValue);
bool isSet = false;
do {
valueString.Assign(htmlValueString);
// FYI: Cannot use InclusiveAncestorsOfType here because
// GetCSSEquivalentToHTMLInlineStyleSetInternal() may flush pending
// notifications.
for (nsCOMPtr<nsIContent> content = &aContent; content;
content = content->GetParentElement()) {
nsCOMPtr<nsINode> parentNode = content->GetParentNode();
aValue.Assign(htmlValueString);
// get the value of the CSS equivalent styles
nsresult rv = GetCSSEquivalentToHTMLInlineStyleSet(
aNode, aHTMLProperty, aHTMLAttribute, valueString, aStyleType);
nsresult rv = GetCSSEquivalentToHTMLInlineStyleSetInternal(
*content, aHTMLProperty, aAttribute, aValue, aStyleType);
if (NS_FAILED(rv)) {
NS_WARNING("CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet() failed");
NS_WARNING(
"CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSetInternal() "
"failed");
return false;
}
if (NS_WARN_IF(parentNode != content->GetParentNode())) {
return false;
}
// early way out if we can
if (valueString.IsEmpty()) {
if (aValue.IsEmpty()) {
return isSet;
}
if (nsGkAtoms::b == aHTMLProperty) {
if (valueString.EqualsLiteral("bold")) {
if (aValue.EqualsLiteral("bold")) {
isSet = true;
} else if (valueString.EqualsLiteral("normal")) {
} else if (aValue.EqualsLiteral("normal")) {
isSet = false;
} else if (valueString.EqualsLiteral("bolder")) {
} else if (aValue.EqualsLiteral("bolder")) {
isSet = true;
valueString.AssignLiteral("bold");
aValue.AssignLiteral("bold");
} else {
int32_t weight = 0;
nsresult rvIgnored;
nsAutoString value(valueString);
nsAutoString value(aValue);
weight = value.ToInteger(&rvIgnored);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"nsAString::ToInteger() failed, but ignored");
if (400 < weight) {
isSet = true;
valueString.AssignLiteral("bold");
aValue.AssignLiteral("bold");
} else {
isSet = false;
valueString.AssignLiteral("normal");
aValue.AssignLiteral("normal");
}
}
} else if (nsGkAtoms::i == aHTMLProperty) {
if (valueString.EqualsLiteral("italic") ||
valueString.EqualsLiteral("oblique")) {
if (aValue.EqualsLiteral("italic") || aValue.EqualsLiteral("oblique")) {
isSet = true;
}
} else if (nsGkAtoms::u == aHTMLProperty) {
nsAutoString val;
val.AssignLiteral("underline");
isSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
isSet = ChangeStyleTransaction::ValueIncludes(aValue, val);
} else if (nsGkAtoms::strike == aHTMLProperty) {
nsAutoString val;
val.AssignLiteral("line-through");
isSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
isSet = ChangeStyleTransaction::ValueIncludes(aValue, val);
} else if ((nsGkAtoms::font == aHTMLProperty &&
aHTMLAttribute == nsGkAtoms::color) ||
aHTMLAttribute == nsGkAtoms::bgcolor) {
aAttribute == nsGkAtoms::color) ||
aAttribute == nsGkAtoms::bgcolor) {
if (htmlValueString.IsEmpty()) {
isSet = true;
} else {
@ -1063,22 +1081,21 @@ bool CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
htmlColor.Append(char16_t(')'));
}
isSet = htmlColor.Equals(valueString,
nsCaseInsensitiveStringComparator());
isSet = htmlColor.Equals(aValue, nsCaseInsensitiveStringComparator());
} else {
isSet = htmlValueString.Equals(valueString,
isSet = htmlValueString.Equals(aValue,
nsCaseInsensitiveStringComparator());
}
}
} else if (nsGkAtoms::tt == aHTMLProperty) {
isSet = StringBeginsWith(valueString, NS_LITERAL_STRING("monospace"));
} else if (nsGkAtoms::font == aHTMLProperty && aHTMLAttribute &&
aHTMLAttribute == nsGkAtoms::face) {
isSet = StringBeginsWith(aValue, NS_LITERAL_STRING("monospace"));
} else if (nsGkAtoms::font == aHTMLProperty && aAttribute &&
aAttribute == nsGkAtoms::face) {
if (!htmlValueString.IsEmpty()) {
const char16_t commaSpace[] = {char16_t(','), char16_t(' '), 0};
const char16_t comma[] = {char16_t(','), 0};
htmlValueString.ReplaceSubstring(commaSpace, comma);
nsAutoString valueStringNorm(valueString);
nsAutoString valueStringNorm(aValue);
valueStringNorm.ReplaceSubstring(commaSpace, comma);
isSet = htmlValueString.Equals(valueStringNorm,
nsCaseInsensitiveStringComparator());
@ -1086,15 +1103,14 @@ bool CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
isSet = true;
}
return isSet;
} else if (aHTMLAttribute == nsGkAtoms::align) {
} else if (aAttribute == nsGkAtoms::align) {
isSet = true;
} else {
return false;
}
if (!htmlValueString.IsEmpty() &&
htmlValueString.Equals(valueString,
nsCaseInsensitiveStringComparator())) {
htmlValueString.Equals(aValue, nsCaseInsensitiveStringComparator())) {
isSet = true;
}
@ -1102,31 +1118,44 @@ bool CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
isSet = !isSet;
}
if (nsGkAtoms::u == aHTMLProperty || nsGkAtoms::strike == aHTMLProperty) {
// unfortunately, the value of the text-decoration property is not
// inherited. that means that we have to look at ancestors of node to see
// if they are underlined
aNode =
aNode->GetParentElement(); // set to null if it's not a dom element
if (isSet) {
return true;
}
} while (
(nsGkAtoms::u == aHTMLProperty || nsGkAtoms::strike == aHTMLProperty) &&
!isSet && aNode);
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.
}
return isSet;
}
bool CSSEditUtils::HaveCSSEquivalentStyles(nsINode& aNode,
nsAtom* aHTMLProperty,
nsAtom* aHTMLAttribute,
StyleType aStyleType) {
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.
nsAutoString valueString;
nsCOMPtr<nsINode> node = &aNode;
do {
for (nsCOMPtr<nsIContent> content = &aContent; content;
content = content->GetParentElement()) {
nsCOMPtr<nsINode> parentNode = content->GetParentNode();
// get the value of the CSS equivalent styles
nsresult rv = GetCSSEquivalentToHTMLInlineStyleSet(
node, aHTMLProperty, aHTMLAttribute, valueString, aStyleType);
nsresult rv = GetCSSEquivalentToHTMLInlineStyleSetInternal(
*content, aHTMLProperty, aAttribute, valueString, aStyleType);
if (NS_FAILED(rv)) {
NS_WARNING("CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet() failed");
NS_WARNING(
"CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSetInternal() "
"failed");
return false;
}
if (NS_WARN_IF(parentNode != content->GetParentNode())) {
return false;
}
@ -1138,14 +1167,11 @@ bool CSSEditUtils::HaveCSSEquivalentStyles(nsINode& aNode,
return false;
}
// unfortunately, the value of the text-decoration property is not
// 'nfortunately, 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
// set to null if it's not a dom element
node = node->GetParentElement();
} while (node);
// are underlined.
}
return false;
}

View File

@ -58,8 +58,6 @@ class CSSEditUtils final {
eCSSEditableProperty_width
};
enum StyleType { eSpecified, eComputed };
struct CSSEquivTable {
nsCSSEditableProperty cssProperty;
nsProcessValueFunc processValueFunctor;
@ -111,14 +109,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 aNode [IN] A DOM node.
* @param aContent [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(nsINode& aNode, nsAtom& aProperty,
nsAString& aValue);
static nsresult GetComputedProperty(nsINode& aNode, nsAtom& aProperty,
nsAString& aValue);
static nsresult GetSpecifiedProperty(nsIContent& aContent,
nsAtom& aCSSProperty, nsAString& aValue);
static nsresult GetComputedProperty(nsIContent& aContent,
nsAtom& aCSSProperty, nsAString& aValue);
/**
* Removes a CSS property from the specified declarations in STYLE attribute
@ -165,44 +163,53 @@ class CSSEditUtils final {
* Returns the list of values for the CSS equivalences to
* the passed HTML style for the passed node.
*
* @param aNode [IN] A DOM node.
* @param aContent [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.
*/
static nsresult GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
nsAtom* aHTMLProperty,
nsAtom* aAttribute,
nsAString& aValueString,
StyleType aStyleType);
static nsresult GetComputedCSSEquivalentToHTMLInlineStyleSet(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute,
nsAString& aValue) {
return GetCSSEquivalentToHTMLInlineStyleSetInternal(
aContent, aHTMLProperty, aAttribute, aValue, StyleType::Computed);
}
static nsresult GetSpecifiedCSSEquivalentToHTMLInlineStyleSet(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute,
nsAString& aValue) {
return GetCSSEquivalentToHTMLInlineStyleSetInternal(
aContent, aHTMLProperty, aAttribute, aValue, StyleType::Specified);
}
/**
* Does the node aNode (or his parent if it is not an element node) carries
* the CSS equivalent styles to the HTML style for this node ?
*
* @param aNode [IN] A DOM node.
* @param aContent [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.
*/
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 IsComputedCSSEquivalentToHTMLInlineStyleSet(nsIContent& aContent,
nsAtom* aHTMLProperty,
nsAtom* aAttribute,
nsAString& aValue) {
MOZ_ASSERT(aHTMLProperty || aAttribute);
return IsCSSEquivalentToHTMLInlineStyleSetInternal(
aContent, aHTMLProperty, aAttribute, aValue, StyleType::Computed);
}
static bool IsSpecifiedCSSEquivalentToHTMLInlineStyleSet(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute,
nsAString& aValue) {
MOZ_ASSERT(aHTMLProperty || aAttribute);
return IsCSSEquivalentToHTMLInlineStyleSetInternal(
aContent, aHTMLProperty, aAttribute, aValue, StyleType::Specified);
}
/**
* This is a kind of IsCSSEquivalentToHTMLInlineStyleSet.
@ -210,20 +217,30 @@ class CSSEditUtils final {
* aren't same as initial value. But this method returns whether the
* properties aren't set.
* If node is <span style="font-weight: normal"/>,
* - IsCSSEquivalentToHTMLInlineStyleSet returns false.
* - HaveCSSEquivalentStyles returns true.
* - Is(Computed|Specified)CSSEquivalentToHTMLInlineStyleSet returns false.
* - Have(Computed|Specified)CSSEquivalentStyles returns true.
*
* @param aNode [IN] A DOM node.
* @param aContent [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.
*/
static bool HaveCSSEquivalentStyles(nsINode& aNode, nsAtom* aProperty,
nsAtom* aAttribute, StyleType aStyleType);
static bool HaveComputedCSSEquivalentStyles(nsIContent& aContent,
nsAtom* aHTMLProperty,
nsAtom* aAttribute) {
MOZ_ASSERT(aHTMLProperty || aAttribute);
return HaveCSSEquivalentStylesInternal(aContent, aHTMLProperty, aAttribute,
StyleType::Computed);
}
static bool HaveSpecifiedCSSEquivalentStyles(nsIContent& aContent,
nsAtom* aHTMLProperty,
nsAtom* aAttribute) {
MOZ_ASSERT(aHTMLProperty || aAttribute);
return HaveCSSEquivalentStylesInternal(aContent, aHTMLProperty, aAttribute,
StyleType::Specified);
}
/**
* Adds to the node the CSS inline styles equivalent to the HTML style
@ -318,6 +335,8 @@ class CSSEditUtils final {
dom::Element* aElement);
private:
enum class StyleType { Specified, Computed };
/**
* Retrieves the CSS property atom from an enum.
*
@ -338,7 +357,7 @@ class CSSEditUtils final {
* @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
* Get*CSSEquivalentToHTMLInlineStyleSet() or
* RemoveCSSEquivalentToHTMLInlineStyleSet().
*/
static void BuildCSSDeclarations(nsTArray<nsAtom*>& aPropertyArray,
@ -361,7 +380,7 @@ class CSSEditUtils final {
* above.
* @param aGetOrRemoveRequest [IN] A boolean value being true if the call to
* the current method is made for
* GetCSSEquivalentToHTMLInlineStyleSet() or
* Get*CSSEquivalentToHTMLInlineStyleSet() or
* RemoveCSSEquivalentToHTMLInlineStyleSet().
*/
static void GenerateCSSDeclarationsFromHTMLStyle(
@ -375,11 +394,31 @@ 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.
*/
static nsresult GetCSSInlinePropertyBase(nsINode* aNode, nsAtom* aProperty,
nsAString& aValue,
StyleType aStyleType);
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.
*/
static nsresult GetCSSEquivalentToHTMLInlineStyleSetInternal(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute,
nsAString& aValue, StyleType aStyleType);
static bool IsCSSEquivalentToHTMLInlineStyleSetInternal(nsIContent& aContent,
nsAtom* aHTMLProperty,
nsAtom* aAttribute,
nsAString& aValue,
StyleType aStyleType);
static bool HaveCSSEquivalentStylesInternal(nsIContent& aContent,
nsAtom* aHTMLProperty,
nsAtom* aAttribute,
StyleType aStyleType);
private:
HTMLEditor* mHTMLEditor;

View File

@ -25,6 +25,7 @@
#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"
@ -260,10 +261,6 @@ void HTMLEditor::OnStartToHandleTopLevelEditSubAction(
TopLevelEditSubActionDataRef().mSelectedRange->StoreRange(*range);
}
}
nsCOMPtr<nsINode> selStartNode =
TopLevelEditSubActionDataRef().mSelectedRange->mStartContainer;
nsCOMPtr<nsINode> selEndNode =
TopLevelEditSubActionDataRef().mSelectedRange->mEndContainer;
// Register with range updater to track this as we perturb the doc
RangeUpdaterRef().RegisterRangeItem(
@ -283,14 +280,15 @@ void HTMLEditor::OnStartToHandleTopLevelEditSubAction(
break;
}
if (cacheInlineStyles) {
nsCOMPtr<nsINode> selNode =
aDirectionOfTopLevelEditSubAction == nsIEditor::eNext ? selEndNode
: selStartNode;
if (NS_WARN_IF(!selNode)) {
nsCOMPtr<nsIContent> containerContent = nsIContent::FromNodeOrNull(
aDirectionOfTopLevelEditSubAction == nsIEditor::eNext
? TopLevelEditSubActionDataRef().mSelectedRange->mEndContainer
: TopLevelEditSubActionDataRef().mSelectedRange->mStartContainer);
if (NS_WARN_IF(!containerContent)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsresult rv = CacheInlineStyles(*selNode);
nsresult rv = CacheInlineStyles(*containerContent);
if (NS_FAILED(rv)) {
NS_WARNING("HTMLEditor::CacheInlineStyles() failed");
aRv.Throw(rv);
@ -963,12 +961,12 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor,
nsAutoString value;
// Let's get the value(s) of text-align or margin-left/margin-right
DebugOnly<nsresult> rvIgnored =
CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(
blockElementAtEditTarget, nullptr, nsGkAtoms::align, value,
CSSEditUtils::eComputed);
CSSEditUtils::GetComputedCSSEquivalentToHTMLInlineStyleSet(
*blockElementAtEditTarget, nullptr, nsGkAtoms::align, value);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsGkAtoms::align, "
"CSSEditUtils::GetComputedCSSEquivalentToHTMLInlineStyleSet(nsGkAtoms::"
"align, "
"eComputed) failed, but ignored");
if (value.EqualsLiteral("center") || value.EqualsLiteral("-moz-center") ||
value.EqualsLiteral("auto auto")) {
@ -989,21 +987,21 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor,
return;
}
for (nsINode* containerNode = editTargetContent; containerNode;
containerNode = containerNode->GetParentNode()) {
for (nsIContent* containerContent :
InclusiveAncestorsOfType<nsIContent>(*editTargetContent)) {
// If the node is a parent `<table>` element of edit target, let's break
// here to materialize the 'inline-block' behaviour of html tables
// regarding to text alignment.
if (containerNode != editTargetContent &&
containerNode->IsHTMLElement(nsGkAtoms::table)) {
if (containerContent != editTargetContent &&
containerContent->IsHTMLElement(nsGkAtoms::table)) {
return;
}
if (CSSEditUtils::IsCSSEditableProperty(containerNode, nullptr,
if (CSSEditUtils::IsCSSEditableProperty(containerContent, nullptr,
nsGkAtoms::align)) {
nsAutoString value;
DebugOnly<nsresult> rvIgnored = CSSEditUtils::GetSpecifiedProperty(
*containerNode, *nsGkAtoms::textAlign, value);
*containerContent, *nsGkAtoms::textAlign, value);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"CSSEditUtils::GetSpecifiedProperty(nsGkAtoms::"
"textAlign) failed, but ignored");
@ -1029,13 +1027,13 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor,
}
}
if (!HTMLEditUtils::SupportsAlignAttr(*containerNode)) {
if (!HTMLEditUtils::SupportsAlignAttr(*containerContent)) {
continue;
}
nsAutoString alignAttributeValue;
containerNode->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::align,
alignAttributeValue);
containerContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::align,
alignAttributeValue);
if (alignAttributeValue.IsEmpty()) {
continue;
}
@ -1059,10 +1057,10 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor,
}
}
static nsStaticAtom& MarginPropertyAtomForIndent(nsINode& aNode) {
static nsStaticAtom& MarginPropertyAtomForIndent(nsIContent& aContent) {
nsAutoString direction;
DebugOnly<nsresult> rvIgnored = CSSEditUtils::GetComputedProperty(
aNode, *nsGkAtoms::direction, direction);
aContent, *nsGkAtoms::direction, direction);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"CSSEditUtils::GetComputedProperty(nsGkAtoms::direction)"
" failed, but ignored");
@ -6132,16 +6130,16 @@ SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal() {
indentedParentIndentedWith = BlockIndentedWith::HTML;
RefPtr<Element> editingHost = GetActiveEditingHost();
for (nsCOMPtr<nsINode> parentNode = content->GetParentNode();
parentNode && !parentNode->IsHTMLElement(nsGkAtoms::body) &&
parentNode != editingHost &&
(parentNode->IsHTMLElement(nsGkAtoms::table) ||
!HTMLEditUtils::IsTableElement(parentNode));
parentNode = parentNode->GetParentNode()) {
for (nsCOMPtr<nsIContent> parentContent = content->GetParent();
parentContent && !parentContent->IsHTMLElement(nsGkAtoms::body) &&
parentContent != editingHost &&
(parentContent->IsHTMLElement(nsGkAtoms::table) ||
!HTMLEditUtils::IsTableElement(parentContent));
parentContent = parentContent->GetParent()) {
// If we reach a `<blockquote>` ancestor, it should be split at next
// time at least for outdenting current node.
if (parentNode->IsHTMLElement(nsGkAtoms::blockquote)) {
indentedParentElement = parentNode->AsElement();
if (parentContent->IsHTMLElement(nsGkAtoms::blockquote)) {
indentedParentElement = parentContent->AsElement();
firstContentToBeOutdented = content;
lastContentToBeOutdented = content;
break;
@ -6154,7 +6152,7 @@ SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal() {
nsStaticAtom& marginProperty = MarginPropertyAtomForIndent(content);
nsAutoString value;
DebugOnly<nsresult> rvIgnored = CSSEditUtils::GetSpecifiedProperty(
*parentNode, marginProperty, value);
*parentContent, marginProperty, value);
if (NS_WARN_IF(Destroyed())) {
return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED);
}
@ -6171,7 +6169,7 @@ SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal() {
if (startMargin > 0 &&
!(HTMLEditUtils::IsList(atContent.GetContainer()) &&
HTMLEditUtils::IsList(content))) {
indentedParentElement = parentNode->AsElement();
indentedParentElement = parentContent->AsElement();
firstContentToBeOutdented = content;
lastContentToBeOutdented = content;
indentedParentIndentedWith = BlockIndentedWith::CSS;
@ -9817,17 +9815,17 @@ Element* HTMLEditor::GetMostAncestorMailCiteElement(nsINode& aNode) const {
return mailCiteElement;
}
nsresult HTMLEditor::CacheInlineStyles(nsINode& aNode) {
nsresult HTMLEditor::CacheInlineStyles(nsIContent& aContent) {
MOZ_ASSERT(IsTopLevelEditSubActionDataAvailable());
nsresult rv = GetInlineStyles(
aNode, *TopLevelEditSubActionDataRef().mCachedInlineStyles);
aContent, *TopLevelEditSubActionDataRef().mCachedInlineStyles);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::GetInlineStyles() failed");
return rv;
}
nsresult HTMLEditor::GetInlineStyles(nsINode& aNode,
nsresult HTMLEditor::GetInlineStyles(nsIContent& aContent,
AutoStyleCacheArray& aStyleCacheArray) {
MOZ_ASSERT(IsEditActionDataAvailable());
MOZ_ASSERT(aStyleCacheArray.IsEmpty());
@ -9860,11 +9858,11 @@ nsresult HTMLEditor::GetInlineStyles(nsINode& aNode,
// at creating new StyleCache instance.
// Don't use CSS for <font size>, we don't support it usefully (bug 780035)
if (!useCSS || (property == nsGkAtoms::size)) {
isSet =
IsTextPropertySetByContent(&aNode, tag, attribute, nullptr, &value);
isSet = IsTextPropertySetByContent(&aContent, tag, attribute, nullptr,
&value);
} else {
isSet = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
&aNode, tag, attribute, value, CSSEditUtils::eComputed);
isSet = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
aContent, tag, attribute, value);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
@ -9893,17 +9891,18 @@ nsresult HTMLEditor::ReapplyCachedStyles() {
const RangeBoundary& atStartOfSelection =
SelectionRefPtr()->GetRangeAt(0)->StartRef();
nsCOMPtr<nsIContent> selNode =
nsCOMPtr<nsIContent> startContainerContent =
atStartOfSelection.Container() &&
atStartOfSelection.Container()->IsContent()
? atStartOfSelection.Container()->AsContent()
: nullptr;
if (NS_WARN_IF(!selNode)) {
if (NS_WARN_IF(!startContainerContent)) {
return NS_OK;
}
AutoStyleCacheArray styleCacheArrayAtInsertionPoint;
nsresult rv = GetInlineStyles(*selNode, styleCacheArrayAtInsertionPoint);
nsresult rv =
GetInlineStyles(*startContainerContent, styleCacheArrayAtInsertionPoint);
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
return NS_ERROR_EDITOR_DESTROYED;
}
@ -9918,10 +9917,9 @@ nsresult HTMLEditor::ReapplyCachedStyles() {
nsAutoString currentValue;
if (useCSS) {
// check computed style first in css case
isAny = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
selNode, styleCacheBeforeEdit.Tag(),
styleCacheBeforeEdit.GetAttribute(), currentValue,
CSSEditUtils::eComputed);
isAny = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
*startContainerContent, styleCacheBeforeEdit.Tag(),
styleCacheBeforeEdit.GetAttribute(), currentValue);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}

View File

@ -2103,30 +2103,30 @@ nsresult HTMLEditor::GetCSSBackgroundColorState(bool* aMixed,
}
nsCOMPtr<nsINode> startContainer = firstRange->GetStartContainer();
if (NS_WARN_IF(!startContainer)) {
if (NS_WARN_IF(!startContainer) || NS_WARN_IF(!startContainer->IsContent())) {
return NS_ERROR_FAILURE;
}
// is the selection collapsed?
nsCOMPtr<nsINode> nodeToExamine;
nsCOMPtr<nsIContent> contentToExamine;
if (SelectionRefPtr()->IsCollapsed() || IsTextNode(startContainer)) {
// we want to look at the startContainer and ancestors
nodeToExamine = startContainer;
contentToExamine = startContainer->AsContent();
} else {
// otherwise we want to look at the first editable node after
// {startContainer,offset} and its ancestors for divs with alignment on them
nodeToExamine = firstRange->GetChildAtStartOffset();
// GetNextNode(startContainer, offset, true, address_of(nodeToExamine));
contentToExamine = firstRange->GetChildAtStartOffset();
// GetNextNode(startContainer, offset, true, address_of(contentToExamine));
}
if (NS_WARN_IF(!nodeToExamine)) {
if (NS_WARN_IF(!contentToExamine)) {
return NS_ERROR_FAILURE;
}
if (aBlockLevel) {
// we are querying the block background (and not the text background), let's
// climb to the block container
nsCOMPtr<Element> blockParent = GetBlock(*nodeToExamine);
nsCOMPtr<Element> blockParent = GetBlock(*contentToExamine);
if (NS_WARN_IF(!blockParent)) {
return NS_OK;
}
@ -2148,17 +2148,17 @@ nsresult HTMLEditor::GetCSSBackgroundColorState(bool* aMixed,
}
} else {
// no, we are querying the text background for the Text Highlight button
if (IsTextNode(nodeToExamine)) {
if (IsTextNode(contentToExamine)) {
// if the node of interest is a text node, let's climb a level
nodeToExamine = nodeToExamine->GetParentNode();
contentToExamine = contentToExamine->GetParent();
}
// Return default value due to no parent node
if (!nodeToExamine) {
if (!contentToExamine) {
return NS_OK;
}
do {
// is the node to examine a block ?
if (HTMLEditor::NodeIsBlockStatic(*nodeToExamine)) {
if (HTMLEditor::NodeIsBlockStatic(*contentToExamine)) {
// yes it is a block; in that case, the text background color is
// transparent
aOutColor.AssignLiteral("transparent");
@ -2167,13 +2167,13 @@ nsresult HTMLEditor::GetCSSBackgroundColorState(bool* aMixed,
// no, it's not; let's retrieve the computed style of background-color
// for the node to examine
CSSEditUtils::GetComputedProperty(
*nodeToExamine, *nsGkAtoms::backgroundColor, aOutColor);
*contentToExamine, *nsGkAtoms::backgroundColor, aOutColor);
if (!aOutColor.EqualsLiteral("transparent")) {
break;
}
}
nodeToExamine = nodeToExamine->GetParentNode();
} while (aOutColor.EqualsLiteral("transparent") && nodeToExamine);
contentToExamine = contentToExamine->GetParent();
} while (aOutColor.EqualsLiteral("transparent") && contentToExamine);
}
return NS_OK;
}

View File

@ -1277,14 +1277,15 @@ class HTMLEditor final : public TextEditor,
* values of CSS properties.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
GetInlineStyles(nsINode& aNode, AutoStyleCacheArray& aStyleCacheArray);
GetInlineStyles(nsIContent& aContent, AutoStyleCacheArray& aStyleCacheArray);
/**
* CacheInlineStyles() caches style of aNode into mCachedInlineStyles of
* CacheInlineStyles() caches style of aContent into mCachedInlineStyles of
* TopLevelEditSubAction. This may cause flushing layout at retrieving
* computed value of CSS properties.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult CacheInlineStyles(nsINode& aNode);
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
CacheInlineStyles(nsIContent& aContent);
/**
* ReapplyCachedStyles() restores some styles which are disappeared during

View File

@ -406,8 +406,9 @@ 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
if (CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
&aText, &aProperty, aAttribute, aValue, CSSEditUtils::eComputed)) {
nsAutoString value(aValue);
if (CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
aText, &aProperty, aAttribute, value)) {
return NS_OK;
}
} else if (IsTextPropertySetByContent(&aText, &aProperty, aAttribute,
@ -490,18 +491,18 @@ nsresult HTMLEditor::SetInlinePropertyOnTextNode(
return rv;
}
nsresult HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
nsresult HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aContent,
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, aNode)) {
if (aNode.HasChildren()) {
if (!TagCanContain(*nsGkAtoms::span, aContent)) {
if (aContent.HasChildren()) {
nsTArray<OwningNonNull<nsIContent>> arrayOfNodes;
// Populate the list.
for (nsCOMPtr<nsIContent> child = aNode.GetFirstChild(); child;
for (nsCOMPtr<nsIContent> child = aContent.GetFirstChild(); child;
child = child->GetNextSibling()) {
if (IsEditable(child) && !IsEmptyTextNode(*child)) {
arrayOfNodes.AppendElement(*child);
@ -524,11 +525,11 @@ nsresult HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
}
// First check if there's an adjacent sibling we can put our node into.
nsCOMPtr<nsIContent> previousSibling = GetPriorHTMLSibling(&aNode);
nsCOMPtr<nsIContent> nextSibling = GetNextHTMLSibling(&aNode);
nsCOMPtr<nsIContent> previousSibling = GetPriorHTMLSibling(&aContent);
nsCOMPtr<nsIContent> nextSibling = GetNextHTMLSibling(&aContent);
if (IsSimpleModifiableNode(previousSibling, &aProperty, aAttribute,
&aValue)) {
nsresult rv = MoveNodeToEndWithTransaction(aNode, *previousSibling);
nsresult rv = MoveNodeToEndWithTransaction(aContent, *previousSibling);
if (NS_FAILED(rv)) {
NS_WARNING("EditorBase::MoveNodeToEndWithTransaction() failed");
return rv;
@ -543,25 +544,26 @@ nsresult HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
}
if (IsSimpleModifiableNode(nextSibling, &aProperty, aAttribute, &aValue)) {
nsresult rv =
MoveNodeWithTransaction(aNode, EditorDOMPoint(nextSibling, 0));
MoveNodeWithTransaction(aContent, 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(&aNode, &aProperty, aAttribute)) {
if (CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
&aNode, &aProperty, aAttribute, aValue, CSSEditUtils::eComputed)) {
if (CSSEditUtils::IsCSSEditableProperty(&aContent, &aProperty, aAttribute)) {
nsAutoString value(aValue);
if (CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
aContent, &aProperty, aAttribute, value)) {
return NS_OK;
}
} else if (IsTextPropertySetByContent(&aNode, &aProperty, aAttribute,
} else if (IsTextPropertySetByContent(&aContent, &aProperty, aAttribute,
&aValue)) {
return NS_OK;
}
bool useCSS = (IsCSSEnabled() && CSSEditUtils::IsCSSEditableProperty(
&aNode, &aProperty, aAttribute)) ||
&aContent, &aProperty, aAttribute)) ||
// bgcolor is always done using CSS
aAttribute == nsGkAtoms::bgcolor ||
// called for removing parent style, we should use CSS with
@ -572,11 +574,11 @@ nsresult HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
RefPtr<Element> spanElement;
// We only add style="" to <span>s with no attributes (bug 746515). If we
// don't have one, we need to make one.
if (aNode.IsHTMLElement(nsGkAtoms::span) &&
!aNode.AsElement()->GetAttrCount()) {
spanElement = aNode.AsElement();
if (aContent.IsHTMLElement(nsGkAtoms::span) &&
!aContent.AsElement()->GetAttrCount()) {
spanElement = aContent.AsElement();
} else {
spanElement = InsertContainerWithTransaction(aNode, *nsGkAtoms::span);
spanElement = InsertContainerWithTransaction(aContent, *nsGkAtoms::span);
if (!spanElement) {
NS_WARNING(
"EditorBase::InsertContainerWithTransaction(nsGkAtoms::span) "
@ -592,13 +594,13 @@ nsresult HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
}
// is it already the right kind of node, but with wrong attribute?
if (aNode.IsHTMLElement(&aProperty)) {
if (aContent.IsHTMLElement(&aProperty)) {
if (NS_WARN_IF(!aAttribute)) {
return NS_ERROR_INVALID_ARG;
}
// Just set the attribute on it.
nsresult rv = SetAttributeWithTransaction(MOZ_KnownLive(*aNode.AsElement()),
*aAttribute, aValue);
nsresult rv = SetAttributeWithTransaction(
MOZ_KnownLive(*aContent.AsElement()), *aAttribute, aValue);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"EditorBase::SetAttributeWithTransaction() failed");
return rv;
@ -606,7 +608,8 @@ nsresult HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
// ok, chuck it in its very own container
RefPtr<Element> newContainerElement = InsertContainerWithTransaction(
aNode, aProperty, aAttribute ? *aAttribute : *nsGkAtoms::_empty, aValue);
aContent, aProperty, aAttribute ? *aAttribute : *nsGkAtoms::_empty,
aValue);
NS_WARNING_ASSERTION(newContainerElement,
"EditorBase::InsertContainerWithTransaction() failed");
return newContainerElement ? NS_OK : NS_ERROR_FAILURE;
@ -765,8 +768,8 @@ SplitNodeResult HTMLEditor::SplitAncestorStyledInlineElementsAt(
// in this implementation for the node; let's check if it carries those
// CSS styles
nsAutoString firstValue;
isSetByCSS = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
content, aProperty, aAttribute, firstValue, CSSEditUtils::eSpecified);
isSetByCSS = CSSEditUtils::IsSpecifiedCSSEquivalentToHTMLInlineStyleSet(
*content, aProperty, aAttribute, firstValue);
}
if (!isSetByCSS) {
if (!content->IsElement()) {
@ -1095,8 +1098,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::HaveCSSEquivalentStyles(aElement, aProperty, aAttribute,
CSSEditUtils::eSpecified)) {
CSSEditUtils::HaveSpecifiedCSSEquivalentStyles(aElement, aProperty,
aAttribute)) {
// If aElement has CSS declaration of the given style, remove it.
DebugOnly<nsresult> rvIgnored =
mCSSEditUtils->RemoveCSSEquivalentToHTMLStyle(
@ -1348,15 +1351,16 @@ nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aProperty,
return NS_OK;
}
if (CSSEditUtils::IsCSSEditableProperty(collapsedNode, &aProperty,
if (collapsedNode->IsContent() &&
CSSEditUtils::IsCSSEditableProperty(collapsedNode, &aProperty,
aAttribute)) {
if (aValue) {
tOutString.Assign(*aValue);
}
*aFirst = *aAny = *aAll =
CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
collapsedNode, &aProperty, aAttribute, tOutString,
CSSEditUtils::eComputed);
CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
*collapsedNode->AsContent(), &aProperty, aAttribute,
tOutString);
if (outValue) {
outValue->Assign(tOutString);
}
@ -1422,9 +1426,8 @@ nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aProperty,
if (aValue) {
firstValue.Assign(*aValue);
}
isSet = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
content, &aProperty, aAttribute, firstValue,
CSSEditUtils::eComputed);
isSet = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
*content, &aProperty, aAttribute, firstValue);
} else {
isSet = IsTextPropertySetByContent(content, &aProperty, aAttribute,
aValue, &firstValue);
@ -1443,9 +1446,8 @@ nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aProperty,
if (aValue) {
theValue.Assign(*aValue);
}
isSet = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
content, &aProperty, aAttribute, theValue,
CSSEditUtils::eComputed);
isSet = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
*content, &aProperty, aAttribute, theValue);
} else {
isSet = IsTextPropertySetByContent(content, &aProperty, aAttribute,
aValue, &theValue);
@ -1992,8 +1994,9 @@ bool HTMLEditor::IsRemovableParentStyleWithNewSpanElement(nsIContent& aContent,
// 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
return CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
&aContent, aProperty, aAttribute, EmptyString(), CSSEditUtils::eComputed);
nsAutoString emptyString;
return CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
aContent, aProperty, aAttribute, emptyString);
}
void HTMLEditor::CollectEditableLeafTextNodes(