mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-26 04:09:50 +00:00
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:
parent
b07119c5f5
commit
024ef5568b
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
Loading…
x
Reference in New Issue
Block a user