summaryrefslogtreecommitdiffstats
path: root/editor/libeditor/CSSEditUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/libeditor/CSSEditUtils.cpp')
-rw-r--r--editor/libeditor/CSSEditUtils.cpp259
1 files changed, 139 insertions, 120 deletions
diff --git a/editor/libeditor/CSSEditUtils.cpp b/editor/libeditor/CSSEditUtils.cpp
index d8146ca65..dfce858a5 100644
--- a/editor/libeditor/CSSEditUtils.cpp
+++ b/editor/libeditor/CSSEditUtils.cpp
@@ -320,6 +320,15 @@ CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
nsIAtom* aProperty,
const nsAString* aAttribute)
{
+ nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
+ return IsCSSEditableProperty(aNode, aProperty, attribute);
+}
+
+bool
+CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
+ nsIAtom* aProperty,
+ nsIAtom* aAttribute)
+{
MOZ_ASSERT(aNode);
nsINode* node = aNode;
@@ -336,13 +345,12 @@ CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
nsGkAtoms::u == aProperty ||
nsGkAtoms::strike == aProperty ||
(nsGkAtoms::font == aProperty && aAttribute &&
- (aAttribute->EqualsLiteral("color") ||
- aAttribute->EqualsLiteral("face")))) {
+ (aAttribute == nsGkAtoms::color || aAttribute == nsGkAtoms::face))) {
return true;
}
// ALIGN attribute on elements supporting it
- if (aAttribute && (aAttribute->EqualsLiteral("align")) &&
+ if (aAttribute == nsGkAtoms::align &&
node->IsAnyOfHTMLElements(nsGkAtoms::div,
nsGkAtoms::p,
nsGkAtoms::h1,
@@ -365,7 +373,7 @@ CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
return true;
}
- if (aAttribute && (aAttribute->EqualsLiteral("valign")) &&
+ if (aAttribute == nsGkAtoms::valign &&
node->IsAnyOfHTMLElements(nsGkAtoms::col,
nsGkAtoms::colgroup,
nsGkAtoms::tbody,
@@ -378,59 +386,52 @@ CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
}
// attributes TEXT, BACKGROUND and BGCOLOR on BODY
- if (aAttribute && node->IsHTMLElement(nsGkAtoms::body) &&
- (aAttribute->EqualsLiteral("text")
- || aAttribute->EqualsLiteral("background")
- || aAttribute->EqualsLiteral("bgcolor"))) {
+ if (node->IsHTMLElement(nsGkAtoms::body) &&
+ (aAttribute == nsGkAtoms::text || aAttribute == nsGkAtoms::background ||
+ aAttribute == nsGkAtoms::bgcolor)) {
return true;
}
// attribute BGCOLOR on other elements
- if (aAttribute && aAttribute->EqualsLiteral("bgcolor")) {
+ if (aAttribute == nsGkAtoms::bgcolor) {
return true;
}
// attributes HEIGHT, WIDTH and NOWRAP on TD and TH
- if (aAttribute &&
- node->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th) &&
- (aAttribute->EqualsLiteral("height")
- || aAttribute->EqualsLiteral("width")
- || aAttribute->EqualsLiteral("nowrap"))) {
+ if (node->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th) &&
+ (aAttribute == nsGkAtoms::height || aAttribute == nsGkAtoms::width ||
+ aAttribute == nsGkAtoms::nowrap)) {
return true;
}
// attributes HEIGHT and WIDTH on TABLE
- if (aAttribute && node->IsHTMLElement(nsGkAtoms::table) &&
- (aAttribute->EqualsLiteral("height")
- || aAttribute->EqualsLiteral("width"))) {
+ if (node->IsHTMLElement(nsGkAtoms::table) &&
+ (aAttribute == nsGkAtoms::height || aAttribute == nsGkAtoms::width)) {
return true;
}
// attributes SIZE and WIDTH on HR
- if (aAttribute && node->IsHTMLElement(nsGkAtoms::hr) &&
- (aAttribute->EqualsLiteral("size")
- || aAttribute->EqualsLiteral("width"))) {
+ if (node->IsHTMLElement(nsGkAtoms::hr) &&
+ (aAttribute == nsGkAtoms::size || aAttribute == nsGkAtoms::width)) {
return true;
}
// attribute TYPE on OL UL LI
- if (aAttribute &&
- node->IsAnyOfHTMLElements(nsGkAtoms::ol, nsGkAtoms::ul,
+ if (node->IsAnyOfHTMLElements(nsGkAtoms::ol, nsGkAtoms::ul,
nsGkAtoms::li) &&
- aAttribute->EqualsLiteral("type")) {
+ aAttribute == nsGkAtoms::type) {
return true;
}
- if (aAttribute && node->IsHTMLElement(nsGkAtoms::img) &&
- (aAttribute->EqualsLiteral("border")
- || aAttribute->EqualsLiteral("width")
- || aAttribute->EqualsLiteral("height"))) {
+ if (node->IsHTMLElement(nsGkAtoms::img) &&
+ (aAttribute == nsGkAtoms::border || aAttribute == nsGkAtoms::width ||
+ aAttribute == nsGkAtoms::height)) {
return true;
}
// other elements that we can align using CSS even if they
// can't carry the html ALIGN attribute
- if (aAttribute && aAttribute->EqualsLiteral("align") &&
+ if (aAttribute == nsGkAtoms::align &&
node->IsAnyOfHTMLElements(nsGkAtoms::ul,
nsGkAtoms::ol,
nsGkAtoms::dl,
@@ -815,7 +816,7 @@ void
CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
Element* aElement,
nsIAtom* aHTMLProperty,
- const nsAString* aAttribute,
+ nsIAtom* aAttribute,
const nsAString* aValue,
nsTArray<nsIAtom*>& cssPropertyArray,
nsTArray<nsString>& cssValueArray,
@@ -835,21 +836,20 @@ CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
} else if (nsGkAtoms::tt == aHTMLProperty) {
equivTable = ttEquivTable;
} else if (aAttribute) {
- if (nsGkAtoms::font == aHTMLProperty &&
- aAttribute->EqualsLiteral("color")) {
+ if (nsGkAtoms::font == aHTMLProperty && aAttribute == nsGkAtoms::color) {
equivTable = fontColorEquivTable;
} else if (nsGkAtoms::font == aHTMLProperty &&
- aAttribute->EqualsLiteral("face")) {
+ aAttribute == nsGkAtoms::face) {
equivTable = fontFaceEquivTable;
- } else if (aAttribute->EqualsLiteral("bgcolor")) {
+ } else if (aAttribute == nsGkAtoms::bgcolor) {
equivTable = bgcolorEquivTable;
- } else if (aAttribute->EqualsLiteral("background")) {
+ } else if (aAttribute == nsGkAtoms::background) {
equivTable = backgroundImageEquivTable;
- } else if (aAttribute->EqualsLiteral("text")) {
+ } else if (aAttribute == nsGkAtoms::text) {
equivTable = textColorEquivTable;
- } else if (aAttribute->EqualsLiteral("border")) {
+ } else if (aAttribute == nsGkAtoms::border) {
equivTable = borderEquivTable;
- } else if (aAttribute->EqualsLiteral("align")) {
+ } else if (aAttribute == nsGkAtoms::align) {
if (aElement->IsHTMLElement(nsGkAtoms::table)) {
equivTable = tableAlignEquivTable;
} else if (aElement->IsHTMLElement(nsGkAtoms::hr)) {
@@ -860,17 +860,17 @@ CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
} else {
equivTable = textAlignEquivTable;
}
- } else if (aAttribute->EqualsLiteral("valign")) {
+ } else if (aAttribute == nsGkAtoms::valign) {
equivTable = verticalAlignEquivTable;
- } else if (aAttribute->EqualsLiteral("nowrap")) {
+ } else if (aAttribute == nsGkAtoms::nowrap) {
equivTable = nowrapEquivTable;
- } else if (aAttribute->EqualsLiteral("width")) {
+ } else if (aAttribute == nsGkAtoms::width) {
equivTable = widthEquivTable;
- } else if (aAttribute->EqualsLiteral("height") ||
+ } else if (aAttribute == nsGkAtoms::height ||
(aElement->IsHTMLElement(nsGkAtoms::hr) &&
- aAttribute->EqualsLiteral("size"))) {
+ aAttribute == nsGkAtoms::size)) {
equivTable = heightEquivTable;
- } else if (aAttribute->EqualsLiteral("type") &&
+ } else if (aAttribute == nsGkAtoms::type &&
aElement->IsAnyOfHTMLElements(nsGkAtoms::ol,
nsGkAtoms::ul,
nsGkAtoms::li)) {
@@ -887,40 +887,46 @@ CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
// aValue for the node, and return in aCount the number of CSS properties set
// by the call. The Element version returns aCount instead.
int32_t
-CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
+CSSEditUtils::SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
nsIAtom* aProperty,
const nsAString* aAttribute,
const nsAString* aValue,
bool aSuppressTransaction)
{
- MOZ_ASSERT(aElement && aProperty);
MOZ_ASSERT_IF(aAttribute, aValue);
- int32_t count;
// This can only fail if SetCSSProperty fails, which should only happen if
// something is pretty badly wrong. In this case we assert so that hopefully
// someone will notice, but there's nothing more sensible to do than just
// return the count and carry on.
- nsresult rv = SetCSSEquivalentToHTMLStyle(aElement->AsDOMNode(),
- aProperty, aAttribute,
- aValue, &count,
- aSuppressTransaction);
- NS_ASSERTION(NS_SUCCEEDED(rv), "SetCSSEquivalentToHTMLStyle failed");
- NS_ENSURE_SUCCESS(rv, count);
- return count;
+ nsCOMPtr<Element> element = do_QueryInterface(aNode);
+ return SetCSSEquivalentToHTMLStyle(element,
+ aProperty, aAttribute,
+ aValue, aSuppressTransaction);
}
-nsresult
-CSSEditUtils::SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
+int32_t
+CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
nsIAtom* aHTMLProperty,
const nsAString* aAttribute,
const nsAString* aValue,
- int32_t* aCount,
bool aSuppressTransaction)
{
- nsCOMPtr<Element> element = do_QueryInterface(aNode);
- *aCount = 0;
- if (!element || !IsCSSEditableProperty(element, aHTMLProperty, aAttribute)) {
- return NS_OK;
+ nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
+ return SetCSSEquivalentToHTMLStyle(aElement, aHTMLProperty, attribute,
+ aValue, aSuppressTransaction);
+}
+
+int32_t
+CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
+ nsIAtom* aHTMLProperty,
+ nsIAtom* aAttribute,
+ const nsAString* aValue,
+ bool aSuppressTransaction)
+{
+ MOZ_ASSERT(aElement);
+
+ if (!IsCSSEditableProperty(aElement, aHTMLProperty, aAttribute)) {
+ return 0;
}
// we can apply the styles only if the node is an element and if we have
@@ -929,18 +935,20 @@ CSSEditUtils::SetCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
// Find the CSS equivalence to the HTML style
nsTArray<nsIAtom*> cssPropertyArray;
nsTArray<nsString> cssValueArray;
- GenerateCSSDeclarationsFromHTMLStyle(element, aHTMLProperty, aAttribute,
+ GenerateCSSDeclarationsFromHTMLStyle(aElement, aHTMLProperty, aAttribute,
aValue, cssPropertyArray, cssValueArray,
false);
// set the individual CSS inline styles
- *aCount = cssPropertyArray.Length();
- for (int32_t index = 0; index < *aCount; index++) {
- nsresult rv = SetCSSProperty(*element, *cssPropertyArray[index],
+ size_t count = cssPropertyArray.Length();
+ for (size_t index = 0; index < count; index++) {
+ nsresult rv = SetCSSProperty(*aElement, *cssPropertyArray[index],
cssValueArray[index], aSuppressTransaction);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return 0;
+ }
}
- return NS_OK;
+ return count;
}
// Remove from aNode the CSS inline style equivalent to HTMLProperty/aAttribute/aValue for the node
@@ -952,20 +960,22 @@ CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
bool aSuppressTransaction)
{
nsCOMPtr<Element> element = do_QueryInterface(aNode);
- NS_ENSURE_TRUE(element, NS_OK);
+ nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
- return RemoveCSSEquivalentToHTMLStyle(element, aHTMLProperty, aAttribute,
+ return RemoveCSSEquivalentToHTMLStyle(element, aHTMLProperty, attribute,
aValue, aSuppressTransaction);
}
nsresult
CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(Element* aElement,
nsIAtom* aHTMLProperty,
- const nsAString* aAttribute,
+ nsIAtom* aAttribute,
const nsAString* aValue,
bool aSuppressTransaction)
{
- MOZ_ASSERT(aElement);
+ if (NS_WARN_IF(!aElement)) {
+ return NS_OK;
+ }
if (!IsCSSEditableProperty(aElement, aHTMLProperty, aAttribute)) {
return NS_OK;
@@ -1000,7 +1010,7 @@ CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(Element* aElement,
nsresult
CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
nsIAtom* aHTMLProperty,
- const nsAString* aAttribute,
+ nsIAtom* aAttribute,
nsAString& aValueString,
StyleType aStyleType)
{
@@ -1017,7 +1027,8 @@ CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
nsTArray<nsString> cssValueArray;
// get the CSS equivalence with last param true indicating we want only the
// "gettable" properties
- GenerateCSSDeclarationsFromHTMLStyle(theElement, aHTMLProperty, aAttribute, nullptr,
+ GenerateCSSDeclarationsFromHTMLStyle(theElement, aHTMLProperty, aAttribute,
+ nullptr,
cssPropertyArray, cssValueArray, true);
int32_t count = cssPropertyArray.Length();
for (int32_t index = 0; index < count; index++) {
@@ -1063,48 +1074,58 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
StyleType aStyleType)
{
MOZ_ASSERT(aNode && aProperty);
- bool isSet;
- nsresult rv = IsCSSEquivalentToHTMLInlineStyleSet(aNode->AsDOMNode(),
- aProperty, aAttribute,
- isSet, aValue, aStyleType);
- NS_ENSURE_SUCCESS(rv, false);
- return isSet;
+ nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
+ return IsCSSEquivalentToHTMLInlineStyleSet(aNode,
+ aProperty, attribute,
+ aValue, aStyleType);
}
-nsresult
+bool
+CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode* aNode,
+ nsIAtom* aProperty,
+ const nsAString* aAttribute,
+ nsAString& aValue,
+ StyleType aStyleType)
+{
+ MOZ_ASSERT(aNode && aProperty);
+ nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+ nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
+ return IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty, attribute,
+ aValue, aStyleType);
+}
+
+bool
CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
- nsIDOMNode* aNode,
+ nsINode* aNode,
nsIAtom* aHTMLProperty,
- const nsAString* aHTMLAttribute,
- bool& aIsSet,
+ nsIAtom* aHTMLAttribute,
nsAString& valueString,
StyleType aStyleType)
{
- NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
+ NS_ENSURE_TRUE(aNode, false);
nsAutoString htmlValueString(valueString);
- aIsSet = false;
- nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+ bool isSet = false;
do {
valueString.Assign(htmlValueString);
// get the value of the CSS equivalent styles
nsresult rv =
- GetCSSEquivalentToHTMLInlineStyleSet(node, aHTMLProperty, aHTMLAttribute,
+ GetCSSEquivalentToHTMLInlineStyleSet(aNode, aHTMLProperty, aHTMLAttribute,
valueString, aStyleType);
- NS_ENSURE_SUCCESS(rv, rv);
+ NS_ENSURE_SUCCESS(rv, false);
// early way out if we can
if (valueString.IsEmpty()) {
- return NS_OK;
+ return isSet;
}
if (nsGkAtoms::b == aHTMLProperty) {
if (valueString.EqualsLiteral("bold")) {
- aIsSet = true;
+ isSet = true;
} else if (valueString.EqualsLiteral("normal")) {
- aIsSet = false;
+ isSet = false;
} else if (valueString.EqualsLiteral("bolder")) {
- aIsSet = true;
+ isSet = true;
valueString.AssignLiteral("bold");
} else {
int32_t weight = 0;
@@ -1112,32 +1133,31 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
nsAutoString value(valueString);
weight = value.ToInteger(&errorCode);
if (400 < weight) {
- aIsSet = true;
+ isSet = true;
valueString.AssignLiteral("bold");
} else {
- aIsSet = false;
+ isSet = false;
valueString.AssignLiteral("normal");
}
}
} else if (nsGkAtoms::i == aHTMLProperty) {
if (valueString.EqualsLiteral("italic") ||
valueString.EqualsLiteral("oblique")) {
- aIsSet = true;
+ isSet = true;
}
} else if (nsGkAtoms::u == aHTMLProperty) {
nsAutoString val;
val.AssignLiteral("underline");
- aIsSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
+ isSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
} else if (nsGkAtoms::strike == aHTMLProperty) {
nsAutoString val;
val.AssignLiteral("line-through");
- aIsSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
- } else if (aHTMLAttribute &&
- ((nsGkAtoms::font == aHTMLProperty &&
- aHTMLAttribute->EqualsLiteral("color")) ||
- aHTMLAttribute->EqualsLiteral("bgcolor"))) {
+ isSet = ChangeStyleTransaction::ValueIncludes(valueString, val);
+ } else if ((nsGkAtoms::font == aHTMLProperty &&
+ aHTMLAttribute == nsGkAtoms::color) ||
+ aHTMLAttribute == nsGkAtoms::bgcolor) {
if (htmlValueString.IsEmpty()) {
- aIsSet = true;
+ isSet = true;
} else {
nscolor rgba;
nsAutoString subStr;
@@ -1171,54 +1191,53 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
htmlColor.Append(char16_t(')'));
}
- aIsSet = htmlColor.Equals(valueString,
- nsCaseInsensitiveStringComparator());
+ isSet = htmlColor.Equals(valueString,
+ nsCaseInsensitiveStringComparator());
} else {
- aIsSet = htmlValueString.Equals(valueString,
- nsCaseInsensitiveStringComparator());
+ isSet = htmlValueString.Equals(valueString,
+ nsCaseInsensitiveStringComparator());
}
}
} else if (nsGkAtoms::tt == aHTMLProperty) {
- aIsSet = StringBeginsWith(valueString, NS_LITERAL_STRING("monospace"));
+ isSet = StringBeginsWith(valueString, NS_LITERAL_STRING("monospace"));
} else if (nsGkAtoms::font == aHTMLProperty && aHTMLAttribute &&
- aHTMLAttribute->EqualsLiteral("face")) {
+ aHTMLAttribute == nsGkAtoms::face) {
if (!htmlValueString.IsEmpty()) {
const char16_t commaSpace[] = { char16_t(','), char16_t(' '), 0 };
const char16_t comma[] = { char16_t(','), 0 };
htmlValueString.ReplaceSubstring(commaSpace, comma);
nsAutoString valueStringNorm(valueString);
valueStringNorm.ReplaceSubstring(commaSpace, comma);
- aIsSet = htmlValueString.Equals(valueStringNorm,
- nsCaseInsensitiveStringComparator());
+ isSet = htmlValueString.Equals(valueStringNorm,
+ nsCaseInsensitiveStringComparator());
} else {
- aIsSet = true;
+ isSet = true;
}
- return NS_OK;
- } else if (aHTMLAttribute && aHTMLAttribute->EqualsLiteral("align")) {
- aIsSet = true;
+ return isSet;
+ } else if (aHTMLAttribute == nsGkAtoms::align) {
+ isSet = true;
} else {
- aIsSet = false;
- return NS_OK;
+ return false;
}
if (!htmlValueString.IsEmpty() &&
htmlValueString.Equals(valueString,
nsCaseInsensitiveStringComparator())) {
- aIsSet = true;
+ isSet = true;
}
if (htmlValueString.EqualsLiteral("-moz-editor-invert-value")) {
- aIsSet = !aIsSet;
+ isSet = !isSet;
}
if (nsGkAtoms::u == aHTMLProperty || nsGkAtoms::strike == aHTMLProperty) {
// unfortunately, the value of the text-decoration property is not inherited.
// that means that we have to look at ancestors of node to see if they are underlined
- node = node->GetParentElement(); // set to null if it's not a dom element
+ aNode = aNode->GetParentElement(); // set to null if it's not a dom element
}
} while ((nsGkAtoms::u == aHTMLProperty ||
- nsGkAtoms::strike == aHTMLProperty) && !aIsSet && node);
- return NS_OK;
+ nsGkAtoms::strike == aHTMLProperty) && !isSet && aNode);
+ return isSet;
}
void