Bug 1221436 patch 2 - For style attributes, only store a css::Declaration instead of a css::StyleRule. r=heycam

Now that Declaration implements nsIStyleRule, we don't need the memory
overhead of storing a StyleRule object for style attributes.

We also need to change this prior to patch 5, because the changes in
patch 5 that will allow rules to change (but declarations not) would
otherwise break due to style attribute object merging done by
nsAttrValue::ParseStyleAttribute.
This commit is contained in:
L. David Baron 2015-11-09 15:57:16 +08:00
parent aaf6592743
commit 1b093e6db8
22 changed files with 180 additions and 253 deletions

View File

@ -1876,20 +1876,20 @@ Element::GetSMILOverrideStyle()
return slots->mSMILOverrideStyle;
}
css::StyleRule*
Element::GetSMILOverrideStyleRule()
css::Declaration*
Element::GetSMILOverrideStyleDeclaration()
{
Element::nsDOMSlots *slots = GetExistingDOMSlots();
return slots ? slots->mSMILOverrideStyleRule.get() : nullptr;
return slots ? slots->mSMILOverrideStyleDeclaration.get() : nullptr;
}
nsresult
Element::SetSMILOverrideStyleRule(css::StyleRule* aStyleRule,
bool aNotify)
Element::SetSMILOverrideStyleDeclaration(css::Declaration* aDeclaration,
bool aNotify)
{
Element::nsDOMSlots *slots = DOMSlots();
slots->mSMILOverrideStyleRule = aStyleRule;
slots->mSMILOverrideStyleDeclaration = aDeclaration;
if (aNotify) {
nsIDocument* doc = GetComposedDoc();
@ -1924,18 +1924,18 @@ Element::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
return false;
}
css::StyleRule*
Element::GetInlineStyleRule()
css::Declaration*
Element::GetInlineStyleDeclaration()
{
return nullptr;
}
nsresult
Element::SetInlineStyleRule(css::StyleRule* aStyleRule,
const nsAString* aSerialized,
bool aNotify)
Element::SetInlineStyleDeclaration(css::Declaration* aDeclaration,
const nsAString* aSerialized,
bool aNotify)
{
NS_NOTYETIMPLEMENTED("Element::SetInlineStyleRule");
NS_NOTYETIMPLEMENTED("Element::SetInlineStyleDeclaration");
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -222,31 +222,31 @@ public:
void ClearStyleStateLocks();
/**
* Get the inline style rule, if any, for this element.
* Get the inline style declaration, if any, for this element.
*/
virtual css::StyleRule* GetInlineStyleRule();
virtual css::Declaration* GetInlineStyleDeclaration();
/**
* Set the inline style rule for this element. This will send an appropriate
* AttributeChanged notification if aNotify is true.
* Set the inline style declaration for this element. This will send
* an appropriate AttributeChanged notification if aNotify is true.
*/
virtual nsresult SetInlineStyleRule(css::StyleRule* aStyleRule,
const nsAString* aSerialized,
bool aNotify);
virtual nsresult SetInlineStyleDeclaration(css::Declaration* aDeclaration,
const nsAString* aSerialized,
bool aNotify);
/**
* Get the SMIL override style rule for this element. If the rule hasn't been
* created, this method simply returns null.
* Get the SMIL override style declaration for this element. If the
* rule hasn't been created, this method simply returns null.
*/
virtual css::StyleRule* GetSMILOverrideStyleRule();
virtual css::Declaration* GetSMILOverrideStyleDeclaration();
/**
* Set the SMIL override style rule for this element. If aNotify is true, this
* method will notify the document's pres context, so that the style changes
* will be noticed.
* Set the SMIL override style declaration for this element. If
* aNotify is true, this method will notify the document's pres
* context, so that the style changes will be noticed.
*/
virtual nsresult SetSMILOverrideStyleRule(css::StyleRule* aStyleRule,
bool aNotify);
virtual nsresult SetSMILOverrideStyleDeclaration(css::Declaration* aDeclaration,
bool aNotify);
/**
* Returns a new nsISMILAttr that allows the caller to animate the given

View File

@ -614,7 +614,7 @@ FragmentOrElement::nsDOMSlots::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) c
// - mStyle
// - mDataSet
// - mSMILOverrideStyle
// - mSMILOverrideStyleRule
// - mSMILOverrideStyleDeclaration
// - mChildrenList
// - mClassList

View File

@ -286,9 +286,9 @@ public:
nsCOMPtr<nsICSSDeclaration> mSMILOverrideStyle;
/**
* Holds any SMIL override style rules for this element.
* Holds any SMIL override style declaration for this element.
*/
RefPtr<mozilla::css::StyleRule> mSMILOverrideStyleRule;
RefPtr<mozilla::css::Declaration> mSMILOverrideStyleDeclaration;
/**
* An object implementing nsIDOMMozNamedAttrMap for this content (attributes)

View File

@ -17,7 +17,6 @@
#include "nsIAtom.h"
#include "nsUnicharUtils.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/css/StyleRule.h"
#include "mozilla/css/Declaration.h"
#include "nsContentUtils.h"
#include "nsReadableUtils.h"
@ -73,13 +72,13 @@ void
MiscContainer::Cache()
{
// Not implemented for anything else yet.
MOZ_ASSERT(mType == nsAttrValue::eCSSStyleRule);
MOZ_ASSERT(mType == nsAttrValue::eCSSDeclaration);
MOZ_ASSERT(IsRefCounted());
MOZ_ASSERT(mValue.mRefCount > 0);
MOZ_ASSERT(!mValue.mCached);
css::StyleRule* rule = mValue.mCSSStyleRule;
nsHTMLCSSStyleSheet* sheet = rule->GetHTMLCSSStyleSheet();
css::Declaration* declaration = mValue.mCSSDeclaration;
nsHTMLCSSStyleSheet* sheet = declaration->GetHTMLCSSStyleSheet();
if (!sheet) {
return;
}
@ -94,17 +93,14 @@ MiscContainer::Cache()
mValue.mCached = 1;
// This has to be immutable once it goes into the cache.
css::Declaration* decl = rule->GetDeclaration();
if (decl) {
decl->SetImmutable();
}
declaration->SetImmutable();
}
void
MiscContainer::Evict()
{
// Not implemented for anything else yet.
MOZ_ASSERT(mType == nsAttrValue::eCSSStyleRule);
MOZ_ASSERT(mType == nsAttrValue::eCSSDeclaration);
MOZ_ASSERT(IsRefCounted());
MOZ_ASSERT(mValue.mRefCount == 0);
@ -112,8 +108,8 @@ MiscContainer::Evict()
return;
}
css::StyleRule* rule = mValue.mCSSStyleRule;
nsHTMLCSSStyleSheet* sheet = rule->GetHTMLCSSStyleSheet();
css::Declaration* declaration = mValue.mCSSDeclaration;
nsHTMLCSSStyleSheet* sheet = declaration->GetHTMLCSSStyleSheet();
MOZ_ASSERT(sheet);
nsString str;
@ -149,7 +145,7 @@ nsAttrValue::nsAttrValue(nsIAtom* aValue)
SetTo(aValue);
}
nsAttrValue::nsAttrValue(css::StyleRule* aValue, const nsAString* aSerialized)
nsAttrValue::nsAttrValue(css::Declaration* aValue, const nsAString* aSerialized)
: mBits(0)
{
SetTo(aValue, aSerialized);
@ -314,7 +310,7 @@ nsAttrValue::SetTo(const nsAttrValue& aOther)
cont->mValue.mColor = otherCont->mValue.mColor;
break;
}
case eCSSStyleRule:
case eCSSDeclaration:
{
MOZ_CRASH("These should be refcounted!");
}
@ -421,12 +417,12 @@ nsAttrValue::SetTo(double aValue, const nsAString* aSerialized)
}
void
nsAttrValue::SetTo(css::StyleRule* aValue, const nsAString* aSerialized)
nsAttrValue::SetTo(css::Declaration* aValue, const nsAString* aSerialized)
{
MiscContainer* cont = EnsureEmptyMiscContainer();
MOZ_ASSERT(cont->mValue.mRefCount == 0);
NS_ADDREF(cont->mValue.mCSSStyleRule = aValue);
cont->mType = eCSSStyleRule;
NS_ADDREF(cont->mValue.mCSSDeclaration = aValue);
cont->mType = eCSSDeclaration;
NS_ADDREF(cont);
SetMiscAtomOrString(aSerialized);
MOZ_ASSERT(cont->mValue.mRefCount == 1);
@ -639,12 +635,11 @@ nsAttrValue::ToString(nsAString& aResult) const
break;
}
case eCSSStyleRule:
case eCSSDeclaration:
{
aResult.Truncate();
MiscContainer *container = GetMiscContainer();
css::Declaration *decl =
container->mValue.mCSSStyleRule->GetDeclaration();
css::Declaration *decl = container->mValue.mCSSDeclaration;
if (decl) {
decl->ToString(aResult);
}
@ -889,9 +884,9 @@ nsAttrValue::HashValue() const
{
return cont->mValue.mColor;
}
case eCSSStyleRule:
case eCSSDeclaration:
{
return NS_PTR_TO_INT32(cont->mValue.mCSSStyleRule);
return NS_PTR_TO_INT32(cont->mValue.mCSSDeclaration);
}
// Intentionally identical, so that loading the image does not change the
// hash code.
@ -998,9 +993,10 @@ nsAttrValue::Equals(const nsAttrValue& aOther) const
}
break;
}
case eCSSStyleRule:
case eCSSDeclaration:
{
return thisCont->mValue.mCSSStyleRule == otherCont->mValue.mCSSStyleRule;
return thisCont->mValue.mCSSDeclaration ==
otherCont->mValue.mCSSDeclaration;
}
case eURL:
{
@ -1690,14 +1686,12 @@ nsAttrValue::ParseStyleAttribute(const nsAString& aString,
css::Loader* cssLoader = ownerDoc->CSSLoader();
nsCSSParser cssParser(cssLoader);
RefPtr<css::StyleRule> rule;
cssParser.ParseStyleAttribute(aString, docURI, baseURI,
aElement->NodePrincipal(),
getter_AddRefs(rule));
if (rule) {
rule->SetHTMLCSSStyleSheet(sheet);
rule->GetDeclaration()->SetHTMLCSSStyleSheet(sheet);
SetTo(rule, &aString);
RefPtr<css::Declaration> declaration =
cssParser.ParseStyleAttribute(aString, docURI, baseURI,
aElement->NodePrincipal());
if (declaration) {
declaration->SetHTMLCSSStyleSheet(sheet);
SetTo(declaration, &aString);
if (cachingAllowed) {
MiscContainer* cont = GetMiscContainer();
cont->Cache();
@ -1717,13 +1711,13 @@ nsAttrValue::SetMiscAtomOrString(const nsAString* aValue)
"Trying to re-set atom or string!");
if (aValue) {
uint32_t len = aValue->Length();
// * We're allowing eCSSStyleRule attributes to store empty strings as it
// * We're allowing eCSSDeclaration attributes to store empty strings as it
// can be beneficial to store an empty style attribute as a parsed rule.
// * We're allowing enumerated values because sometimes the empty
// string corresponds to a particular enumerated value, especially
// for enumerated values that are not limited enumerated.
// Add other types as needed.
NS_ASSERTION(len || Type() == eCSSStyleRule || Type() == eEnum,
NS_ASSERTION(len || Type() == eCSSDeclaration || Type() == eEnum,
"Empty string?");
MiscContainer* cont = GetMiscContainer();
if (len <= NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM) {
@ -1787,12 +1781,12 @@ nsAttrValue::ClearMiscContainer()
}
else {
switch (cont->mType) {
case eCSSStyleRule:
case eCSSDeclaration:
{
MOZ_ASSERT(cont->mValue.mRefCount == 1);
cont->Release();
cont->Evict();
NS_RELEASE(cont->mValue.mCSSStyleRule);
NS_RELEASE(cont->mValue.mCSSDeclaration);
break;
}
case eURL:
@ -1928,10 +1922,10 @@ nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
n += str ? str->SizeOfIncludingThisIfUnshared(aMallocSizeOf) : 0;
}
if (Type() == eCSSStyleRule && container->mValue.mCSSStyleRule) {
// TODO: mCSSStyleRule might be owned by another object which would
if (Type() == eCSSDeclaration && container->mValue.mCSSDeclaration) {
// TODO: mCSSDeclaration might be owned by another object which would
// make us count them twice, bug 677493.
//n += container->mCSSStyleRule->SizeOfIncludingThis(aMallocSizeOf);
//n += container->mCSSDeclaration->SizeOfIncludingThis(aMallocSizeOf);
} else if (Type() == eAtomArray && container->mValue.mAtomArray) {
// Don't measure each nsIAtom, they are measured separatly.
n += container->mValue.mAtomArray->ShallowSizeOfIncludingThis(aMallocSizeOf);

View File

@ -35,7 +35,7 @@ struct MiscContainer;
namespace mozilla {
namespace css {
class StyleRule;
class Declaration;
struct URLValue;
struct ImageValue;
} // namespace css
@ -94,7 +94,7 @@ public:
ePercent = 0x0F, // 1111
// Values below here won't matter, they'll be always stored in the 'misc'
// struct.
eCSSStyleRule = 0x10
eCSSDeclaration = 0x10
,eURL = 0x11
,eImage = 0x12
,eAtomArray = 0x13
@ -120,7 +120,7 @@ public:
nsAttrValue(const nsAttrValue& aOther);
explicit nsAttrValue(const nsAString& aValue);
explicit nsAttrValue(nsIAtom* aValue);
nsAttrValue(mozilla::css::StyleRule* aValue, const nsAString* aSerialized);
nsAttrValue(mozilla::css::Declaration* aValue, const nsAString* aSerialized);
explicit nsAttrValue(const nsIntMargin& aValue);
~nsAttrValue();
@ -145,7 +145,7 @@ public:
void SetTo(int16_t aInt);
void SetTo(int32_t aInt, const nsAString* aSerialized);
void SetTo(double aValue, const nsAString* aSerialized);
void SetTo(mozilla::css::StyleRule* aValue, const nsAString* aSerialized);
void SetTo(mozilla::css::Declaration* aValue, const nsAString* aSerialized);
void SetTo(mozilla::css::URLValue* aValue, const nsAString* aSerialized);
void SetTo(const nsIntMargin& aValue);
void SetTo(const nsSVGAngle& aValue, const nsAString* aSerialized);
@ -196,7 +196,7 @@ public:
inline int16_t GetEnumValue() const;
inline float GetPercentValue() const;
inline AtomArray* GetAtomArrayValue() const;
inline mozilla::css::StyleRule* GetCSSStyleRuleValue() const;
inline mozilla::css::Declaration* GetCSSDeclarationValue() const;
inline mozilla::css::URLValue* GetURLValue() const;
inline mozilla::css::ImageValue* GetImageValue() const;
inline double GetDoubleValue() const;

View File

@ -20,7 +20,7 @@ struct MiscContainer final
ValueType mType;
// mStringBits points to either nsIAtom* or nsStringBuffer* and is used when
// mType isn't mCSSStyleRule.
// mType isn't eCSSDeclaration.
// Note eStringBase and eAtomBase is used also to handle the type of
// mStringBits.
uintptr_t mStringBits;
@ -31,7 +31,7 @@ struct MiscContainer final
nscolor mColor;
uint32_t mEnumValue;
int32_t mPercent;
mozilla::css::StyleRule* mCSSStyleRule;
mozilla::css::Declaration* mCSSDeclaration;
mozilla::css::URLValue* mURL;
mozilla::css::ImageValue* mImage;
nsAttrValue::AtomArray* mAtomArray;
@ -86,7 +86,7 @@ public:
// Nothing stops us from refcounting (and sharing) other types of
// MiscContainer (except eDoubleValue types) but there's no compelling
// reason to
return mType == nsAttrValue::eCSSStyleRule;
return mType == nsAttrValue::eCSSDeclaration;
}
inline int32_t AddRef() {
@ -146,11 +146,11 @@ nsAttrValue::GetAtomArrayValue() const
return GetMiscContainer()->mValue.mAtomArray;
}
inline mozilla::css::StyleRule*
nsAttrValue::GetCSSStyleRuleValue() const
inline mozilla::css::Declaration*
nsAttrValue::GetCSSDeclarationValue() const
{
NS_PRECONDITION(Type() == eCSSStyleRule, "wrong type");
return GetMiscContainer()->mValue.mCSSStyleRule;
NS_PRECONDITION(Type() == eCSSDeclaration, "wrong type");
return GetMiscContainer()->mValue.mCSSDeclaration;
}
inline mozilla::css::URLValue*
@ -198,7 +198,7 @@ nsAttrValue::StoresOwnData() const
return true;
}
ValueType t = Type();
return t != eCSSStyleRule && !IsSVGType(t);
return t != eCSSDeclaration && !IsSVGType(t);
}
inline void

View File

@ -14,7 +14,7 @@
#include "nsDOMCSSAttrDeclaration.h"
#include "nsServiceManagerUtils.h"
#include "nsIDocument.h"
#include "mozilla/css/StyleRule.h"
#include "mozilla/css/Declaration.h"
#include "nsCSSParser.h"
#include "mozilla/css/Loader.h"
#include "nsIDOMMutationEvent.h"
@ -45,9 +45,9 @@ nsStyledElementNotElementCSSInlineStyle::ParseAttribute(int32_t aNamespaceID,
}
nsresult
nsStyledElementNotElementCSSInlineStyle::SetInlineStyleRule(css::StyleRule* aStyleRule,
const nsAString* aSerialized,
bool aNotify)
nsStyledElementNotElementCSSInlineStyle::SetInlineStyleDeclaration(css::Declaration* aDeclaration,
const nsAString* aSerialized,
bool aNotify)
{
SetMayHaveStyle();
bool modification = false;
@ -77,7 +77,7 @@ nsStyledElementNotElementCSSInlineStyle::SetInlineStyleRule(css::StyleRule* aSty
modification = !!mAttrsAndChildren.GetAttr(nsGkAtoms::style);
}
nsAttrValue attrValue(aStyleRule, aSerialized);
nsAttrValue attrValue(aDeclaration, aSerialized);
// XXXbz do we ever end up with ADDITION here? I doubt it.
uint8_t modType = modification ?
@ -89,16 +89,16 @@ nsStyledElementNotElementCSSInlineStyle::SetInlineStyleRule(css::StyleRule* aSty
aNotify, kDontCallAfterSetAttr);
}
css::StyleRule*
nsStyledElementNotElementCSSInlineStyle::GetInlineStyleRule()
css::Declaration*
nsStyledElementNotElementCSSInlineStyle::GetInlineStyleDeclaration()
{
if (!MayHaveStyle()) {
return nullptr;
}
const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style);
if (attrVal && attrVal->Type() == nsAttrValue::eCSSStyleRule) {
return attrVal->GetCSSStyleRuleValue();
if (attrVal && attrVal->Type() == nsAttrValue::eCSSDeclaration) {
return attrVal->GetCSSDeclarationValue();
}
return nullptr;
@ -131,13 +131,13 @@ nsStyledElementNotElementCSSInlineStyle::ReparseStyleAttribute(bool aForceInData
}
const nsAttrValue* oldVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style);
if (oldVal && oldVal->Type() != nsAttrValue::eCSSStyleRule) {
if (oldVal && oldVal->Type() != nsAttrValue::eCSSDeclaration) {
nsAttrValue attrValue;
nsAutoString stringValue;
oldVal->ToString(stringValue);
ParseStyleAttribute(stringValue, attrValue, aForceInDataDoc);
// Don't bother going through SetInlineStyleRule, we don't want to fire off
// mutation events or document notifications anyway
// Don't bother going through SetInlineStyleDeclaration; we don't
// want to fire off mutation events or document notifications anyway
nsresult rv = mAttrsAndChildren.SetAndSwapAttr(nsGkAtoms::style, attrValue);
NS_ENSURE_SUCCESS(rv, rv);
}

View File

@ -19,7 +19,7 @@
namespace mozilla {
namespace css {
class StyleRule;
class Declaration;
} // namespace css
} // namespace mozilla
@ -35,11 +35,11 @@ protected:
{}
public:
// nsIContent interface methods
virtual mozilla::css::StyleRule* GetInlineStyleRule() override;
virtual nsresult SetInlineStyleRule(mozilla::css::StyleRule* aStyleRule,
const nsAString* aSerialized,
bool aNotify) override;
// Element interface methods
virtual mozilla::css::Declaration* GetInlineStyleDeclaration() override;
virtual nsresult SetInlineStyleDeclaration(mozilla::css::Declaration* aDeclaration,
const nsAString* aSerialized,
bool aNotify) override;
nsICSSDeclaration* Style();

View File

@ -1066,17 +1066,12 @@ nsTreeSanitizer::MustPrune(int32_t aNamespace,
}
bool
nsTreeSanitizer::SanitizeStyleRule(mozilla::css::StyleRule *aRule,
nsAutoString &aRuleText)
nsTreeSanitizer::SanitizeStyleDeclaration(mozilla::css::Declaration* aDeclaration,
nsAutoString& aRuleText)
{
bool didSanitize = false;
aRuleText.Truncate();
mozilla::css::Declaration* style = aRule->GetDeclaration();
if (style) {
didSanitize = style->HasProperty(eCSSProperty_binding);
style->RemoveProperty(eCSSProperty_binding);
style->ToString(aRuleText);
}
bool didSanitize = aDeclaration->HasProperty(eCSSProperty_binding);
aDeclaration->RemoveProperty(eCSSProperty_binding);
aDeclaration->ToString(aRuleText);
return didSanitize;
}
@ -1135,7 +1130,8 @@ nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
RefPtr<mozilla::css::StyleRule> styleRule = do_QueryObject(rule);
NS_ASSERTION(styleRule, "Must be a style rule");
nsAutoString decl;
bool sanitized = SanitizeStyleRule(styleRule, decl);
bool sanitized =
SanitizeStyleDeclaration(styleRule->GetDeclaration(), decl);
didSanitize = sanitized || didSanitize;
if (!sanitized) {
styleRule->GetCssText(decl);
@ -1157,10 +1153,7 @@ nsTreeSanitizer::SanitizeAttributes(mozilla::dom::Element* aElement,
{
uint32_t ac = aElement->GetAttrCount();
nsresult rv;
for (int32_t i = ac - 1; i >= 0; --i) {
rv = NS_OK;
const nsAttrName* attrName = aElement->GetAttrNameAt(i);
int32_t attrNs = attrName->NamespaceID();
nsCOMPtr<nsIAtom> attrLocal = attrName->LocalName();
@ -1172,17 +1165,14 @@ nsTreeSanitizer::SanitizeAttributes(mozilla::dom::Element* aElement,
// Pass the CSS Loader object to the parser, to allow parser error
// reports to include the outer window ID.
nsCSSParser parser(document->CSSLoader());
RefPtr<mozilla::css::StyleRule> rule;
nsAutoString value;
aElement->GetAttr(attrNs, attrLocal, value);
rv = parser.ParseStyleAttribute(value,
document->GetDocumentURI(),
baseURI,
document->NodePrincipal(),
getter_AddRefs(rule));
if (NS_SUCCEEDED(rv)) {
RefPtr<mozilla::css::Declaration> decl =
parser.ParseStyleAttribute(value, document->GetDocumentURI(),
baseURI, document->NodePrincipal());
if (decl) {
nsAutoString cleanValue;
if (SanitizeStyleRule(rule, cleanValue)) {
if (SanitizeStyleDeclaration(decl, cleanValue)) {
aElement->SetAttr(kNameSpaceID_None,
nsGkAtoms::style,
cleanValue,

View File

@ -154,12 +154,12 @@ class MOZ_STACK_CLASS nsTreeSanitizer {
* removes that property from the rule and reserializes in case the
* property was found.
*
* @param aRule The style rule to check
* @param aDeclaration The style declaration to check
* @param aRuleText the serialized mutated rule if the method returns true
* @return true if the rule was modified and false otherwise
*/
bool SanitizeStyleRule(mozilla::css::StyleRule* aRule,
nsAutoString &aRuleText);
bool SanitizeStyleDeclaration(mozilla::css::Declaration* aDeclaration,
nsAutoString& aRuleText);
/**
* Parses a style sheet and reserializes it with the 'binding' property

View File

@ -2138,11 +2138,8 @@ CanvasRenderingContext2D::SetShadowColor(const nsAString& shadowColor)
static already_AddRefed<Declaration>
CreateDeclaration(nsINode* aNode,
const nsCSSProperty aProp1, const nsAString& aValue1, bool* aChanged1,
const nsCSSProperty aProp2, const nsAString& aValue2, bool* aChanged2,
ErrorResult& error)
const nsCSSProperty aProp2, const nsAString& aValue2, bool* aChanged2)
{
RefPtr<StyleRule> rule;
nsIPrincipal* principal = aNode->NodePrincipal();
nsIDocument* document = aNode->OwnerDoc();
@ -2153,23 +2150,19 @@ CreateDeclaration(nsINode* aNode,
// to include the outer window ID.
nsCSSParser parser(document->CSSLoader());
error = parser.ParseStyleAttribute(EmptyString(), docURL, baseURL,
principal, getter_AddRefs(rule));
if (error.Failed()) {
return nullptr;
}
RefPtr<Declaration> declaration =
parser.ParseStyleAttribute(EmptyString(), docURL, baseURL, principal);
if (aProp1 != eCSSProperty_UNKNOWN) {
parser.ParseProperty(aProp1, aValue1, docURL, baseURL, principal,
rule->GetDeclaration(), aChanged1, false);
declaration, aChanged1, false);
}
if (aProp2 != eCSSProperty_UNKNOWN) {
parser.ParseProperty(aProp2, aValue2, docURL, baseURL, principal,
rule->GetDeclaration(), aChanged2, false);
declaration, aChanged2, false);
}
RefPtr<Declaration> declaration = rule->GetDeclaration();
declaration->SetImmutable();
return declaration.forget();
}
@ -2177,14 +2170,12 @@ CreateDeclaration(nsINode* aNode,
static already_AddRefed<Declaration>
CreateFontDeclaration(const nsAString& aFont,
nsINode* aNode,
bool* aOutFontChanged,
ErrorResult& error)
bool* aOutFontChanged)
{
bool lineHeightChanged;
return CreateDeclaration(aNode,
eCSSProperty_font, aFont, aOutFontChanged,
eCSSProperty_line_height, NS_LITERAL_STRING("normal"), &lineHeightChanged,
error);
eCSSProperty_line_height, NS_LITERAL_STRING("normal"), &lineHeightChanged);
}
static already_AddRefed<nsStyleContext>
@ -2207,11 +2198,7 @@ GetFontParentStyleContext(Element* aElement, nsIPresShell* presShell,
bool changed;
RefPtr<css::Declaration> parentRule =
CreateFontDeclaration(NS_LITERAL_STRING("10px sans-serif"),
presShell->GetDocument(), &changed, error);
if (error.Failed()) {
return nullptr;
}
presShell->GetDocument(), &changed);
nsTArray<nsCOMPtr<nsIStyleRule>> parentRules;
parentRules.AppendElement(parentRule);
@ -2246,11 +2233,7 @@ GetFontStyleContext(Element* aElement, const nsAString& aFont,
bool fontParsedSuccessfully = false;
RefPtr<css::Declaration> decl =
CreateFontDeclaration(aFont, presShell->GetDocument(),
&fontParsedSuccessfully, error);
if (error.Failed()) {
return nullptr;
}
&fontParsedSuccessfully);
if (!fontParsedSuccessfully) {
// We got a syntax error. The spec says this value must be ignored.
@ -2302,14 +2285,12 @@ GetFontStyleContext(Element* aElement, const nsAString& aFont,
static already_AddRefed<Declaration>
CreateFilterDeclaration(const nsAString& aFilter,
nsINode* aNode,
bool* aOutFilterChanged,
ErrorResult& error)
bool* aOutFilterChanged)
{
bool dummy;
return CreateDeclaration(aNode,
eCSSProperty_filter, aFilter, aOutFilterChanged,
eCSSProperty_UNKNOWN, EmptyString(), &dummy,
error);
eCSSProperty_UNKNOWN, EmptyString(), &dummy);
}
static already_AddRefed<nsStyleContext>
@ -2321,11 +2302,7 @@ ResolveStyleForFilter(const nsAString& aFilterString,
nsIDocument* document = aPresShell->GetDocument();
bool filterChanged = false;
RefPtr<css::Declaration> decl =
CreateFilterDeclaration(aFilterString, document, &filterChanged, error);
if (error.Failed()) {
return nullptr;
}
CreateFilterDeclaration(aFilterString, document, &filterChanged);
if (!filterChanged) {
// Refuse to accept the filter, but do not throw an error.

View File

@ -20,7 +20,7 @@
#include "nsQueryObject.h"
#include "nsIContentInlines.h"
#include "nsIContentViewer.h"
#include "mozilla/css/StyleRule.h"
#include "mozilla/css/Declaration.h"
#include "nsIDocument.h"
#include "nsIDocumentEncoder.h"
#include "nsIDOMHTMLDocument.h"
@ -35,7 +35,6 @@
#include "nsHTMLStyleSheet.h"
#include "nsIHTMLDocument.h"
#include "nsPIDOMWindow.h"
#include "nsIStyleRule.h"
#include "nsIURL.h"
#include "nsEscape.h"
#include "nsIFrameInlines.h"
@ -226,15 +225,14 @@ nsGenericHTMLElement::CopyInnerTo(Element* aDst)
value->ToString(valStr);
if (name->Equals(nsGkAtoms::style, kNameSpaceID_None) &&
value->Type() == nsAttrValue::eCSSStyleRule) {
value->Type() == nsAttrValue::eCSSDeclaration) {
// We can't just set this as a string, because that will fail
// to reparse the string into style data until the node is
// inserted into the document. Clone the Rule instead.
RefPtr<mozilla::css::Rule> ruleClone = value->GetCSSStyleRuleValue()->Clone();
RefPtr<mozilla::css::StyleRule> styleRule = do_QueryObject(ruleClone);
NS_ENSURE_TRUE(styleRule, NS_ERROR_UNEXPECTED);
RefPtr<css::Declaration> declClone =
new css::Declaration(*value->GetCSSDeclarationValue());
rv = aDst->SetInlineStyleRule(styleRule, &valStr, false);
rv = aDst->SetInlineStyleDeclaration(declClone, &valStr, false);
NS_ENSURE_SUCCESS(rv, rv);
continue;

View File

@ -719,7 +719,7 @@ nsSMILAnimationController::AddStyleUpdatesTo(RestyleTracker& aTracker)
}
// mIsCSS true means that the rules are the ones returned from
// Element::GetSMILOverrideStyleRule (via nsSMILCSSProperty objects),
// Element::GetSMILOverrideStyleDeclaration (via nsSMILCSSProperty objects),
// and mIsCSS false means the rules are nsSMILMappedAttribute objects
// returned from nsSVGElement::GetAnimatedContentStyleRule.
nsRestyleHint rshint = key.mIsCSS ? eRestyle_StyleAttribute_Animations

View File

@ -257,7 +257,7 @@ nsSVGElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
}
const nsAttrValue* oldVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style);
if (oldVal && oldVal->Type() == nsAttrValue::eCSSStyleRule) {
if (oldVal && oldVal->Type() == nsAttrValue::eCSSDeclaration) {
// we need to force a reparse because the baseURI of the document
// may have changed, and in particular because we may be clones of
// XBL anonymous content now being bound to the document we should
@ -269,8 +269,8 @@ nsSVGElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
oldVal->ToString(stringValue);
// Force in data doc, since we already have a style rule
ParseStyleAttribute(stringValue, attrValue, true);
// Don't bother going through SetInlineStyleRule, we don't want to fire off
// mutation events or document notifications anyway
// Don't bother going through SetInlineStyleDeclaration; we don't
// want to fire off mutation events or document notifications anyway
rv = mAttrsAndChildren.SetAndSwapAttr(nsGkAtoms::style, attrValue);
NS_ENSURE_SUCCESS(rv, rv);
}

View File

@ -385,15 +385,14 @@ nsXULElement::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const
nsAttrValue attrValue;
// Style rules need to be cloned.
if (originalValue->Type() == nsAttrValue::eCSSStyleRule) {
RefPtr<css::Rule> ruleClone =
originalValue->GetCSSStyleRuleValue()->Clone();
if (originalValue->Type() == nsAttrValue::eCSSDeclaration) {
RefPtr<css::Declaration> declClone =
new css::Declaration(*originalValue->GetCSSDeclarationValue());
nsString stringValue;
originalValue->ToString(stringValue);
RefPtr<css::StyleRule> styleRule = do_QueryObject(ruleClone);
attrValue.SetTo(styleRule, &stringValue);
attrValue.SetTo(declClone, &stringValue);
} else {
attrValue.SetTo(*originalValue);
}
@ -1863,15 +1862,14 @@ nsXULElement::MakeHeavyweight(nsXULPrototypeElement* aPrototype)
nsAttrValue attrValue;
// Style rules need to be cloned.
if (protoattr->mValue.Type() == nsAttrValue::eCSSStyleRule) {
RefPtr<css::Rule> ruleClone =
protoattr->mValue.GetCSSStyleRuleValue()->Clone();
if (protoattr->mValue.Type() == nsAttrValue::eCSSDeclaration) {
RefPtr<css::Declaration> declClone = new css::Declaration(
*protoattr->mValue.GetCSSDeclarationValue());
nsString stringValue;
protoattr->mValue.ToString(stringValue);
RefPtr<css::StyleRule> styleRule = do_QueryObject(ruleClone);
attrValue.SetTo(styleRule, &stringValue);
attrValue.SetTo(declClone, &stringValue);
} else {
attrValue.SetTo(protoattr->mValue);
}
@ -2438,7 +2436,6 @@ nsXULPrototypeElement::SetAttrAt(uint32_t aPos, const nsAString& aValue,
} else if (mAttributes[aPos].mName.Equals(nsGkAtoms::style)) {
mHasStyleAttribute = true;
// Parse the element's 'style' attribute
RefPtr<css::StyleRule> rule;
nsCSSParser parser;
@ -2446,14 +2443,14 @@ nsXULPrototypeElement::SetAttrAt(uint32_t aPos, const nsAString& aValue,
// TODO: If we implement Content Security Policy for chrome documents
// as has been discussed, the CSP should be checked here to see if
// inline styles are allowed to be applied.
parser.ParseStyleAttribute(aValue, aDocumentURI, aDocumentURI,
// This is basically duplicating what
// nsINode::NodePrincipal() does
mNodeInfo->NodeInfoManager()->
DocumentPrincipal(),
getter_AddRefs(rule));
if (rule) {
mAttributes[aPos].mValue.SetTo(rule, &aValue);
RefPtr<css::Declaration> declaration =
parser.ParseStyleAttribute(aValue, aDocumentURI, aDocumentURI,
// This is basically duplicating what
// nsINode::NodePrincipal() does
mNodeInfo->NodeInfoManager()->
DocumentPrincipal());
if (declaration) {
mAttributes[aPos].mValue.SetTo(declaration, &aValue);
return NS_OK;
}

View File

@ -516,15 +516,15 @@ nsHTMLCSSUtils::GetCSSInlinePropertyBase(nsINode* aNode, nsIAtom* aProperty,
}
MOZ_ASSERT(aStyleType == eSpecified);
RefPtr<css::StyleRule> rule = element->GetInlineStyleRule();
if (!rule) {
RefPtr<css::Declaration> decl = element->GetInlineStyleDeclaration();
if (!decl) {
return NS_OK;
}
nsCSSProperty prop =
nsCSSProps::LookupProperty(nsDependentAtomString(aProperty),
nsCSSProps::eEnabledForAllContent);
MOZ_ASSERT(prop != eCSSProperty_UNKNOWN);
rule->GetDeclaration()->GetValue(prop, aValue);
decl->GetValue(prop, aValue);
return NS_OK;
}

View File

@ -140,11 +140,11 @@ public:
SheetParsingMode aParsingMode,
LoaderReusableStyleSheets* aReusableSheets);
nsresult ParseStyleAttribute(const nsAString& aAttributeValue,
already_AddRefed<css::Declaration>
ParseStyleAttribute(const nsAString& aAttributeValue,
nsIURI* aDocURL,
nsIURI* aBaseURL,
nsIPrincipal* aNodePrincipal,
css::StyleRule** aResult);
nsIPrincipal* aNodePrincipal);
nsresult ParseDeclarations(const nsAString& aBuffer,
nsIURI* aSheetURL,
@ -1627,7 +1627,6 @@ CSSParserImpl::ParseSheet(const nsAString& aInput,
mIsChrome = false;
mReusableSheets = nullptr;
// XXX check for low level errors
return NS_OK;
}
@ -1644,12 +1643,11 @@ NonMozillaVendorIdentifier(const nsAString& ident)
}
nsresult
already_AddRefed<css::Declaration>
CSSParserImpl::ParseStyleAttribute(const nsAString& aAttributeValue,
nsIURI* aDocURI,
nsIURI* aBaseURI,
nsIPrincipal* aNodePrincipal,
css::StyleRule** aResult)
nsIPrincipal* aNodePrincipal)
{
NS_PRECONDITION(aNodePrincipal, "Must have principal here!");
NS_PRECONDITION(aBaseURI, "need base URI");
@ -1664,17 +1662,10 @@ CSSParserImpl::ParseStyleAttribute(const nsAString& aAttributeValue,
uint32_t parseFlags = eParseDeclaration_AllowImportant;
RefPtr<css::Declaration> declaration = ParseDeclarationBlock(parseFlags);
if (declaration) {
// Create a style rule for the declaration
NS_ADDREF(*aResult = new css::StyleRule(nullptr, declaration, 0, 0));
} else {
*aResult = nullptr;
}
ReleaseScanner();
// XXX check for low level errors
return NS_OK;
return declaration.forget();
}
nsresult
@ -16257,16 +16248,14 @@ nsCSSParser::ParseSheet(const nsAString& aInput,
aParsingMode, aReusableSheets);
}
nsresult
already_AddRefed<css::Declaration>
nsCSSParser::ParseStyleAttribute(const nsAString& aAttributeValue,
nsIURI* aDocURI,
nsIURI* aBaseURI,
nsIPrincipal* aNodePrincipal,
css::StyleRule** aResult)
nsIPrincipal* aNodePrincipal)
{
return static_cast<CSSParserImpl*>(mImpl)->
ParseStyleAttribute(aAttributeValue, aDocURI, aBaseURI,
aNodePrincipal, aResult);
ParseStyleAttribute(aAttributeValue, aDocURI, aBaseURI, aNodePrincipal);
}
nsresult

View File

@ -93,11 +93,11 @@ public:
// Parse HTML style attribute or its equivalent in other markup
// languages. aBaseURL is the base url to use for relative links in
// the declaration.
nsresult ParseStyleAttribute(const nsAString& aAttributeValue,
already_AddRefed<mozilla::css::Declaration>
ParseStyleAttribute(const nsAString& aAttributeValue,
nsIURI* aDocURL,
nsIURI* aBaseURL,
nsIPrincipal* aNodePrincipal,
mozilla::css::StyleRule** aResult);
nsIPrincipal* aNodePrincipal);
// Parse the body of a declaration block. Very similar to
// ParseStyleAttribute, but used under different circumstances.

View File

@ -72,20 +72,9 @@ nsresult
nsDOMCSSAttributeDeclaration::SetCSSDeclaration(css::Declaration* aDecl)
{
NS_ASSERTION(mElement, "Must have Element to set the declaration!");
css::StyleRule* oldRule =
mIsSMILOverride ? mElement->GetSMILOverrideStyleRule() :
mElement->GetInlineStyleRule();
NS_ASSERTION(oldRule, "Element must have rule");
RefPtr<css::StyleRule> newRule =
oldRule->DeclarationChanged(aDecl, false);
if (!newRule) {
return NS_ERROR_OUT_OF_MEMORY;
}
return
mIsSMILOverride ? mElement->SetSMILOverrideStyleRule(newRule, true) :
mElement->SetInlineStyleRule(newRule, nullptr, true);
mIsSMILOverride ? mElement->SetSMILOverrideStyleDeclaration(aDecl, true) :
mElement->SetInlineStyleDeclaration(aDecl, nullptr, true);
}
nsIDocument*
@ -102,11 +91,11 @@ nsDOMCSSAttributeDeclaration::GetCSSDeclaration(Operation aOperation)
if (!mElement)
return nullptr;
css::StyleRule* cssRule;
css::Declaration* declaration;
if (mIsSMILOverride)
cssRule = mElement->GetSMILOverrideStyleRule();
declaration = mElement->GetSMILOverrideStyleDeclaration();
else
cssRule = mElement->GetInlineStyleRule();
declaration = mElement->GetInlineStyleDeclaration();
// Notify observers that our style="" attribute is going to change
// unless:
@ -122,15 +111,15 @@ nsDOMCSSAttributeDeclaration::GetCSSDeclaration(Operation aOperation)
// AttributeWillChange if this is inline style.
if (!mIsSMILOverride &&
((aOperation == eOperation_Modify) ||
(aOperation == eOperation_RemoveProperty && cssRule))) {
(aOperation == eOperation_RemoveProperty && declaration))) {
nsNodeUtils::AttributeWillChange(mElement, kNameSpaceID_None,
nsGkAtoms::style,
nsIDOMMutationEvent::MODIFICATION,
nullptr);
}
if (cssRule) {
return cssRule->GetDeclaration();
if (declaration) {
return declaration;
}
if (aOperation != eOperation_Modify) {
@ -140,14 +129,13 @@ nsDOMCSSAttributeDeclaration::GetCSSDeclaration(Operation aOperation)
// cannot fail
RefPtr<css::Declaration> decl = new css::Declaration();
decl->InitializeEmpty();
RefPtr<css::StyleRule> newRule = new css::StyleRule(nullptr, decl, 0, 0);
// this *can* fail (inside SetAttrAndNotify, at least).
nsresult rv;
if (mIsSMILOverride)
rv = mElement->SetSMILOverrideStyleRule(newRule, false);
rv = mElement->SetSMILOverrideStyleDeclaration(decl, false);
else
rv = mElement->SetInlineStyleRule(newRule, nullptr, false);
rv = mElement->SetInlineStyleDeclaration(decl, nullptr, false);
if (NS_FAILED(rv)) {
return nullptr; // the decl will be destroyed along with the style rule

View File

@ -29,14 +29,10 @@ ClearAttrCache(const nsAString& aKey, MiscContainer*& aValue, void*)
{
// Ideally we'd just call MiscContainer::Evict, but we can't do that since
// we're iterating the hashtable.
MOZ_ASSERT(aValue->mType == nsAttrValue::eCSSStyleRule);
MOZ_ASSERT(aValue->mType == nsAttrValue::eCSSDeclaration);
css::StyleRule* styleRule = aValue->mValue.mCSSStyleRule;
styleRule->SetHTMLCSSStyleSheet(nullptr);
css::Declaration* declaration = styleRule->GetDeclaration();
if (declaration) {
declaration->SetHTMLCSSStyleSheet(nullptr);
}
css::Declaration* declaration = aValue->mValue.mCSSDeclaration;
declaration->SetHTMLCSSStyleSheet(nullptr);
aValue->mValue.mCached = 0;
return PL_DHASH_REMOVE;
@ -70,20 +66,18 @@ nsHTMLCSSStyleSheet::ElementRulesMatching(nsPresContext* aPresContext,
nsRuleWalker* aRuleWalker)
{
// just get the one and only style rule from the content's STYLE attribute
css::StyleRule* rule = aElement->GetInlineStyleRule();
if (rule) {
css::Declaration* declaration = rule->GetDeclaration();
css::Declaration* declaration = aElement->GetInlineStyleDeclaration();
if (declaration) {
declaration->SetImmutable();
aRuleWalker->Forward(declaration);
}
rule = aElement->GetSMILOverrideStyleRule();
if (rule) {
declaration = aElement->GetSMILOverrideStyleDeclaration();
if (declaration) {
RestyleManager* restyleManager = aPresContext->RestyleManager();
if (!restyleManager->SkipAnimationRules()) {
// Animation restyle (or non-restyle traversal of rules)
// Now we can walk SMIL overrride style, without triggering transitions.
css::Declaration* declaration = rule->GetDeclaration();
declaration->SetImmutable();
aRuleWalker->Forward(declaration);
}
@ -101,9 +95,8 @@ nsHTMLCSSStyleSheet::PseudoElementRulesMatching(Element* aPseudoElement,
MOZ_ASSERT(aPseudoElement);
// just get the one and only style rule from the content's STYLE attribute
css::StyleRule* rule = aPseudoElement->GetInlineStyleRule();
if (rule) {
css::Declaration* declaration = rule->GetDeclaration();
css::Declaration* declaration = aPseudoElement->GetInlineStyleDeclaration();
if (declaration) {
declaration->SetImmutable();
aRuleWalker->Forward(declaration);
}

View File

@ -13,6 +13,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/MemoryReporting.h"
#include "nsCSSPseudoElements.h"
#include "nsDataHashtable.h"
#include "nsIStyleRuleProcessor.h"