Bug 978833 patch 2 - Make css::Declaration reference-counted. r=heycam

This is done in preparation for making it implement nsIStyleRule, which
happens in patch 3, and which is used in patch 12.
This commit is contained in:
L. David Baron 2015-11-05 16:44:08 +08:00
parent e5c3180195
commit 22f54fdb0f
11 changed files with 59 additions and 72 deletions

View File

@ -22,7 +22,6 @@ namespace css {
Declaration::Declaration()
: mImmutable(false)
{
MOZ_COUNT_CTOR(mozilla::css::Declaration);
}
Declaration::Declaration(const Declaration& aCopy)
@ -39,12 +38,10 @@ Declaration::Declaration(const Declaration& aCopy)
nullptr),
mImmutable(false)
{
MOZ_COUNT_CTOR(mozilla::css::Declaration);
}
Declaration::~Declaration()
{
MOZ_COUNT_DTOR(mozilla::css::Declaration);
}
void
@ -1381,15 +1378,17 @@ Declaration::InitializeEmpty()
mData = nsCSSCompressedDataBlock::CreateEmptyBlock();
}
Declaration*
already_AddRefed<Declaration>
Declaration::EnsureMutable()
{
MOZ_ASSERT(mData, "should only be called when not expanded");
RefPtr<Declaration> result;
if (!IsMutable()) {
return new Declaration(*this);
result = new Declaration(*this);
} else {
return this;
result = this;
}
return result.forget();
}
size_t

View File

@ -49,8 +49,12 @@ public:
Declaration(const Declaration& aCopy);
NS_INLINE_DECL_REFCOUNTING(Declaration)
private:
~Declaration();
public:
/**
* |ValueAppended| must be called to maintain this declaration's
* |mOrder| whenever a property is parsed into an expanded data block
@ -243,7 +247,7 @@ public:
/**
* Copy |this|, if necessary to ensure that it can be modified.
*/
Declaration* EnsureMutable();
already_AddRefed<Declaration> EnsureMutable();
/**
* Crash if |this| cannot be modified.

View File

@ -173,8 +173,8 @@ FontFaceSet::ParseFontShorthandForMatching(
ErrorResult& aRv)
{
// Parse aFont as a 'font' property value.
Declaration declaration;
declaration.InitializeEmpty();
RefPtr<Declaration> declaration = new Declaration;
declaration->InitializeEmpty();
bool changed = false;
nsCSSParser parser;
@ -183,23 +183,23 @@ FontFaceSet::ParseFontShorthandForMatching(
mDocument->GetDocumentURI(),
mDocument->GetDocumentURI(),
mDocument->NodePrincipal(),
&declaration,
declaration,
&changed,
/* aIsImportant */ false);
// All of the properties we are interested in should have been set at once.
MOZ_ASSERT(changed == (declaration.HasProperty(eCSSProperty_font_family) &&
declaration.HasProperty(eCSSProperty_font_style) &&
declaration.HasProperty(eCSSProperty_font_weight) &&
declaration.HasProperty(eCSSProperty_font_stretch)));
MOZ_ASSERT(changed == (declaration->HasProperty(eCSSProperty_font_family) &&
declaration->HasProperty(eCSSProperty_font_style) &&
declaration->HasProperty(eCSSProperty_font_weight) &&
declaration->HasProperty(eCSSProperty_font_stretch)));
if (!changed) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
nsCSSCompressedDataBlock* data = declaration.GetNormalBlock();
MOZ_ASSERT(!declaration.GetImportantBlock());
nsCSSCompressedDataBlock* data = declaration->GetNormalBlock();
MOZ_ASSERT(!declaration->GetImportantBlock());
const nsCSSValue* family = data->ValueFor(eCSSProperty_font_family);
if (family->GetUnit() != eCSSUnit_FontFamilyList) {

View File

@ -2491,7 +2491,7 @@ BuildStyleRule(nsCSSProperty aProperty,
bool aUseSVGMode)
{
// Set up an empty CSS Declaration
nsAutoPtr<css::Declaration> declaration(new css::Declaration());
RefPtr<css::Declaration> declaration(new css::Declaration());
declaration->InitializeEmpty();
bool changed; // ignored, but needed as outparam for ParseProperty
@ -2514,7 +2514,7 @@ BuildStyleRule(nsCSSProperty aProperty,
}
RefPtr<css::StyleRule> rule = new css::StyleRule(nullptr,
declaration.forget(),
declaration,
0, 0);
return rule.forget();
}

View File

@ -1458,7 +1458,6 @@ StyleRule::StyleRule(StyleRule& aCopy,
StyleRule::~StyleRule()
{
delete mSelector;
delete mDeclaration;
if (mDOMRule) {
mDOMRule->DOMDeclaration()->DropReference();
}

View File

@ -309,10 +309,7 @@ public:
protected:
virtual ~ImportantRule();
// Not an owning reference; the StyleRule that owns this
// ImportantRule also owns the mDeclaration, and any rule node
// pointing to this rule keeps that StyleRule alive as well.
Declaration* mDeclaration;
RefPtr<Declaration> mDeclaration;
friend class StyleRule;
};
@ -387,7 +384,7 @@ private:
private:
nsCSSSelectorList* mSelector; // null for style attribute
Declaration* mDeclaration;
RefPtr<Declaration> mDeclaration;
RefPtr<ImportantRule> mImportantRule; // initialized by RuleMatched
RefPtr<DOMCSSStyleRule> mDOMRule;

View File

@ -752,8 +752,9 @@ protected:
eCSSContext_Page
};
css::Declaration* ParseDeclarationBlock(uint32_t aFlags,
nsCSSContextType aContext = eCSSContext_General);
already_AddRefed<css::Declaration>
ParseDeclarationBlock(uint32_t aFlags,
nsCSSContextType aContext = eCSSContext_General);
bool ParseDeclaration(css::Declaration* aDeclaration,
uint32_t aFlags,
bool aMustCallValueAppended,
@ -1662,7 +1663,7 @@ CSSParserImpl::ParseStyleAttribute(const nsAString& aAttributeValue,
uint32_t parseFlags = eParseDeclaration_AllowImportant;
css::Declaration* declaration = ParseDeclarationBlock(parseFlags);
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));
@ -1781,17 +1782,17 @@ CSSParserImpl::ParseLonghandProperty(const nsCSSProperty aPropID,
MOZ_ASSERT(aPropID < eCSSProperty_COUNT_no_shorthands,
"ParseLonghandProperty must only take a longhand property");
Declaration declaration;
declaration.InitializeEmpty();
RefPtr<Declaration> declaration = new Declaration;
declaration->InitializeEmpty();
bool changed;
ParseProperty(aPropID, aPropValue, aSheetURL, aBaseURL, aSheetPrincipal,
&declaration, &changed,
declaration, &changed,
/* aIsImportant */ false,
/* aIsSVGMode */ false);
if (changed) {
aValue = *declaration.GetNormalBlock()->ValueFor(aPropID);
aValue = *declaration->GetNormalBlock()->ValueFor(aPropID);
} else {
aValue.Reset();
}
@ -4196,18 +4197,16 @@ CSSParserImpl::ParsePageRule(RuleAppendFunc aAppendFunc, void* aData)
MOZ_ASSERT(mViewportUnitsEnabled,
"Viewport units should be enabled outside of @page rules.");
mViewportUnitsEnabled = false;
nsAutoPtr<css::Declaration> declaration(
ParseDeclarationBlock(parseFlags,
eCSSContext_Page));
RefPtr<css::Declaration> declaration =
ParseDeclarationBlock(parseFlags, eCSSContext_Page);
mViewportUnitsEnabled = true;
if (!declaration) {
return false;
}
// Takes ownership of declaration.
RefPtr<nsCSSPageRule> rule = new nsCSSPageRule(Move(declaration),
linenum, colnum);
RefPtr<nsCSSPageRule> rule =
new nsCSSPageRule(declaration, linenum, colnum);
(*aAppendFunc)(rule, aData);
return true;
@ -4226,14 +4225,14 @@ CSSParserImpl::ParseKeyframeRule()
// Ignore !important in keyframe rules
uint32_t parseFlags = eParseDeclaration_InBraces;
nsAutoPtr<css::Declaration> declaration(ParseDeclarationBlock(parseFlags));
RefPtr<css::Declaration> declaration(ParseDeclarationBlock(parseFlags));
if (!declaration) {
return nullptr;
}
// Takes ownership of declaration, and steals contents of selectorList.
RefPtr<nsCSSKeyframeRule> rule =
new nsCSSKeyframeRule(selectorList, Move(declaration), linenum, colnum);
new nsCSSKeyframeRule(selectorList, declaration, linenum, colnum);
return rule.forget();
}
@ -5151,7 +5150,7 @@ CSSParserImpl::ParseRuleSet(RuleAppendFunc aAppendFunc, void* aData,
// Next parse the declaration block
uint32_t parseFlags = eParseDeclaration_InBraces |
eParseDeclaration_AllowImportant;
css::Declaration* declaration = ParseDeclarationBlock(parseFlags);
RefPtr<css::Declaration> declaration = ParseDeclarationBlock(parseFlags);
if (nullptr == declaration) {
delete slist;
return false;
@ -6362,7 +6361,7 @@ CSSParserImpl::ParseSelector(nsCSSSelectorList* aList,
return true;
}
css::Declaration*
already_AddRefed<css::Declaration>
CSSParserImpl::ParseDeclarationBlock(uint32_t aFlags, nsCSSContextType aContext)
{
bool checkForBraces = (aFlags & eParseDeclaration_InBraces) != 0;
@ -6379,7 +6378,7 @@ CSSParserImpl::ParseDeclarationBlock(uint32_t aFlags, nsCSSContextType aContext)
return nullptr;
}
}
css::Declaration* declaration = new css::Declaration();
RefPtr<css::Declaration> declaration = new css::Declaration();
mData.AssertInitialState();
for (;;) {
bool changed;
@ -6397,7 +6396,7 @@ CSSParserImpl::ParseDeclarationBlock(uint32_t aFlags, nsCSSContextType aContext)
}
}
declaration->CompressFrom(&mData);
return declaration;
return declaration.forget();
}
CSSParseResult

View File

@ -2225,8 +2225,6 @@ nsCSSKeyframeRule::ChangeDeclaration(css::Declaration* aDeclaration)
nsIDocument* doc = GetDocument();
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
// Be careful to not assign to an nsAutoPtr if we would be assigning
// the thing it already holds.
if (aDeclaration != mDeclaration) {
mDeclaration = aDeclaration;
}
@ -2729,8 +2727,6 @@ void
nsCSSPageRule::ChangeDeclaration(css::Declaration* aDeclaration)
{
mImportantRule = nullptr;
// Be careful to not assign to an nsAutoPtr if we would be assigning
// the thing it already holds.
if (aDeclaration != mDeclaration) {
mDeclaration = aDeclaration;
}

View File

@ -388,12 +388,12 @@ class nsCSSKeyframeRule final : public mozilla::css::Rule,
public nsIDOMMozCSSKeyframeRule
{
public:
// WARNING: Steals the contents of aKeys *and* aDeclaration
// WARNING: Steals the contents of aKeys
nsCSSKeyframeRule(InfallibleTArray<float>& aKeys,
nsAutoPtr<mozilla::css::Declaration>&& aDeclaration,
mozilla::css::Declaration* aDeclaration,
uint32_t aLineNumber, uint32_t aColumnNumber)
: mozilla::css::Rule(aLineNumber, aColumnNumber)
, mDeclaration(mozilla::Move(aDeclaration))
, mDeclaration(aDeclaration)
{
mKeys.SwapElements(aKeys);
}
@ -431,7 +431,7 @@ public:
private:
nsTArray<float> mKeys;
nsAutoPtr<mozilla::css::Declaration> mDeclaration;
RefPtr<mozilla::css::Declaration> mDeclaration;
// lazily created when needed:
RefPtr<nsCSSKeyframeStyleDeclaration> mDOMDeclaration;
};
@ -521,11 +521,10 @@ class nsCSSPageRule final : public mozilla::css::Rule,
public nsIDOMCSSPageRule
{
public:
// WARNING: Steals the contents of aDeclaration
nsCSSPageRule(nsAutoPtr<mozilla::css::Declaration>&& aDeclaration,
nsCSSPageRule(mozilla::css::Declaration* aDeclaration,
uint32_t aLineNumber, uint32_t aColumnNumber)
: mozilla::css::Rule(aLineNumber, aColumnNumber)
, mDeclaration(mozilla::Move(aDeclaration))
, mDeclaration(aDeclaration)
, mImportantRule(nullptr)
{
}
@ -560,7 +559,7 @@ public:
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
private:
nsAutoPtr<mozilla::css::Declaration> mDeclaration;
RefPtr<mozilla::css::Declaration> mDeclaration;
// lazily created when needed:
RefPtr<nsCSSPageStyleDeclaration> mDOMDeclaration;
RefPtr<mozilla::css::ImportantRule> mImportantRule;

View File

@ -138,7 +138,7 @@ nsDOMCSSAttributeDeclaration::GetCSSDeclaration(Operation aOperation)
}
// cannot fail
css::Declaration *decl = new css::Declaration();
RefPtr<css::Declaration> decl = new css::Declaration();
decl->InitializeEmpty();
RefPtr<css::StyleRule> newRule = new css::StyleRule(nullptr, decl, 0, 0);

View File

@ -123,7 +123,7 @@ nsDOMCSSDeclaration::SetCssText(const nsAString& aCssText)
// rule (see stack in bug 209575).
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
nsAutoPtr<css::Declaration> decl(new css::Declaration());
RefPtr<css::Declaration> decl(new css::Declaration());
decl->InitializeEmpty();
nsCSSParser cssParser(env.mCSSLoader);
bool changed;
@ -134,7 +134,7 @@ nsDOMCSSDeclaration::SetCssText(const nsAString& aCssText)
return result;
}
return SetCSSDeclaration(decl.forget());
return SetCSSDeclaration(decl);
}
NS_IMETHODIMP
@ -328,16 +328,13 @@ nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSProperty aPropID,
// between when we mutate the declaration and when we set the new
// rule (see stack in bug 209575).
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
css::Declaration* decl = olddecl->EnsureMutable();
RefPtr<css::Declaration> decl = olddecl->EnsureMutable();
nsCSSParser cssParser(env.mCSSLoader);
bool changed;
cssParser.ParseProperty(aPropID, aPropValue, env.mSheetURI, env.mBaseURI,
env.mPrincipal, decl, &changed, aIsImportant);
if (!changed) {
if (decl != olddecl) {
delete decl;
}
// Parsing failed -- but we don't throw an exception for that.
return NS_OK;
}
@ -369,7 +366,7 @@ nsDOMCSSDeclaration::ParseCustomPropertyValue(const nsAString& aPropertyName,
// between when we mutate the declaration and when we set the new
// rule (see stack in bug 209575).
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
css::Declaration* decl = olddecl->EnsureMutable();
RefPtr<css::Declaration> decl = olddecl->EnsureMutable();
nsCSSParser cssParser(env.mCSSLoader);
bool changed;
@ -379,9 +376,6 @@ nsDOMCSSDeclaration::ParseCustomPropertyValue(const nsAString& aPropertyName,
env.mBaseURI, env.mPrincipal, decl,
&changed, aIsImportant);
if (!changed) {
if (decl != olddecl) {
delete decl;
}
// Parsing failed -- but we don't throw an exception for that.
return NS_OK;
}
@ -392,8 +386,8 @@ nsDOMCSSDeclaration::ParseCustomPropertyValue(const nsAString& aPropertyName,
nsresult
nsDOMCSSDeclaration::RemoveProperty(const nsCSSProperty aPropID)
{
css::Declaration* decl = GetCSSDeclaration(eOperation_RemoveProperty);
if (!decl) {
css::Declaration* olddecl = GetCSSDeclaration(eOperation_RemoveProperty);
if (!olddecl) {
return NS_OK; // no decl, so nothing to remove
}
@ -404,7 +398,7 @@ nsDOMCSSDeclaration::RemoveProperty(const nsCSSProperty aPropID)
// rule (see stack in bug 209575).
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
decl = decl->EnsureMutable();
RefPtr<css::Declaration> decl = olddecl->EnsureMutable();
decl->RemoveProperty(aPropID);
return SetCSSDeclaration(decl);
}
@ -415,8 +409,8 @@ nsDOMCSSDeclaration::RemoveCustomProperty(const nsAString& aPropertyName)
MOZ_ASSERT(Substring(aPropertyName, 0,
CSS_CUSTOM_NAME_PREFIX_LENGTH).EqualsLiteral("--"));
css::Declaration* decl = GetCSSDeclaration(eOperation_RemoveProperty);
if (!decl) {
css::Declaration* olddecl = GetCSSDeclaration(eOperation_RemoveProperty);
if (!olddecl) {
return NS_OK; // no decl, so nothing to remove
}
@ -427,7 +421,7 @@ nsDOMCSSDeclaration::RemoveCustomProperty(const nsAString& aPropertyName)
// rule (see stack in bug 209575).
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
decl = decl->EnsureMutable();
RefPtr<css::Declaration> decl = olddecl->EnsureMutable();
decl->RemoveVariableDeclaration(Substring(aPropertyName,
CSS_CUSTOM_NAME_PREFIX_LENGTH));
return SetCSSDeclaration(decl);