Bug 1294299 part 10 - Implement DeclarationBlock.EnsureMutable. r=heycam

MozReview-Commit-ID: KpaypyY5moC
This commit is contained in:
Xidorn Quan
2016-11-03 14:41:02 +11:00
parent 513ef91f62
commit cb21569555
5 changed files with 39 additions and 35 deletions

View File

@@ -1813,19 +1813,6 @@ Declaration::InitializeEmpty()
mData = nsCSSCompressedDataBlock::CreateEmptyBlock();
}
already_AddRefed<Declaration>
Declaration::EnsureMutable()
{
MOZ_ASSERT(mData, "should only be called when not expanded");
RefPtr<Declaration> result;
if (!IsMutable()) {
result = new Declaration(*this);
} else {
result = this;
}
return result.forget();
}
size_t
Declaration::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{

View File

@@ -188,6 +188,10 @@ public:
nsCSSCompressedDataBlock* GetNormalBlock() const { return mData; }
nsCSSCompressedDataBlock* GetImportantBlock() const { return mImportantData; }
void AssertNotExpanded() const {
MOZ_ASSERT(mData, "should only be called when not expanded");
}
/**
* Initialize this declaration as holding no data. Cannot fail.
*/
@@ -223,7 +227,7 @@ public:
}
void MapImportantRuleInfoInto(nsRuleData *aRuleData) const {
MOZ_ASSERT(mData, "called while expanded");
AssertNotExpanded();
MOZ_ASSERT(mImportantData || mImportantVariables,
"must have important data or variables");
if (mImportantData) {
@@ -251,7 +255,7 @@ public:
bool* aChanged)
{
AssertMutable();
MOZ_ASSERT(mData, "called while expanded");
AssertNotExpanded();
if (nsCSSProps::IsShorthand(aProperty)) {
*aChanged = false;
@@ -280,11 +284,6 @@ public:
return !!mData->ValueFor(aProperty);
}
/**
* Copy |this|, if necessary to ensure that it can be modified.
*/
already_AddRefed<Declaration> EnsureMutable();
/**
* Clear the data, in preparation for its replacement with entirely
* new data by a call to |CompressFrom|.

View File

@@ -63,6 +63,11 @@ public:
*/
void SetImmutable() const { mImmutable = true; }
/**
* Copy |this|, if necessary to ensure that it can be modified.
*/
inline already_AddRefed<DeclarationBlock> EnsureMutable();
void SetOwningRule(css::Rule* aRule) {
MOZ_ASSERT(!mContainer.mOwningRule || !aRule,
"should never overwrite one rule with another");

View File

@@ -38,6 +38,20 @@ DeclarationBlock::Clone() const
return result.forget();
}
already_AddRefed<DeclarationBlock>
DeclarationBlock::EnsureMutable()
{
#ifdef DEBUG
if (IsGecko()) {
AsGecko()->AssertNotExpanded();
}
#endif
if (!IsMutable()) {
return Clone();
}
return do_AddRef(this);
}
void
DeclarationBlock::ToString(nsAString& aString) const
{

View File

@@ -279,7 +279,7 @@ nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSPropertyID aPropID,
const nsAString& aPropValue,
bool aIsImportant)
{
css::Declaration* olddecl = GetCSSDeclaration(eOperation_Modify)->AsGecko();
DeclarationBlock* olddecl = GetCSSDeclaration(eOperation_Modify);
if (!olddecl) {
return NS_ERROR_NOT_AVAILABLE;
}
@@ -296,12 +296,13 @@ nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSPropertyID aPropID,
// between when we mutate the declaration and when we set the new
// rule (see stack in bug 209575).
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
RefPtr<css::Declaration> decl = olddecl->EnsureMutable();
RefPtr<DeclarationBlock> decl = olddecl->EnsureMutable();
nsCSSParser cssParser(env.mCSSLoader);
bool changed;
cssParser.ParseProperty(aPropID, aPropValue, env.mSheetURI, env.mBaseURI,
env.mPrincipal, decl, &changed, aIsImportant);
cssParser.ParseProperty(aPropID, aPropValue,
env.mSheetURI, env.mBaseURI, env.mPrincipal,
decl->AsGecko(), &changed, aIsImportant);
if (!changed) {
// Parsing failed -- but we don't throw an exception for that.
return NS_OK;
@@ -317,7 +318,7 @@ nsDOMCSSDeclaration::ParseCustomPropertyValue(const nsAString& aPropertyName,
{
MOZ_ASSERT(nsCSSProps::IsCustomPropertyName(aPropertyName));
css::Declaration* olddecl = GetCSSDeclaration(eOperation_Modify)->AsGecko();
DeclarationBlock* olddecl = GetCSSDeclaration(eOperation_Modify);
if (!olddecl) {
return NS_ERROR_NOT_AVAILABLE;
}
@@ -334,14 +335,14 @@ 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);
RefPtr<css::Declaration> decl = olddecl->EnsureMutable();
RefPtr<DeclarationBlock> decl = olddecl->EnsureMutable();
nsCSSParser cssParser(env.mCSSLoader);
bool changed;
cssParser.ParseVariable(Substring(aPropertyName,
CSS_CUSTOM_NAME_PREFIX_LENGTH),
aPropValue, env.mSheetURI,
env.mBaseURI, env.mPrincipal, decl,
env.mBaseURI, env.mPrincipal, decl->AsGecko(),
&changed, aIsImportant);
if (!changed) {
// Parsing failed -- but we don't throw an exception for that.
@@ -354,8 +355,7 @@ nsDOMCSSDeclaration::ParseCustomPropertyValue(const nsAString& aPropertyName,
nsresult
nsDOMCSSDeclaration::RemovePropertyInternal(nsCSSPropertyID aPropID)
{
css::Declaration* olddecl =
GetCSSDeclaration(eOperation_RemoveProperty)->AsGecko();
DeclarationBlock* olddecl = GetCSSDeclaration(eOperation_RemoveProperty);
if (!olddecl) {
return NS_OK; // no decl, so nothing to remove
}
@@ -367,16 +367,15 @@ nsDOMCSSDeclaration::RemovePropertyInternal(nsCSSPropertyID aPropID)
// rule (see stack in bug 209575).
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
RefPtr<css::Declaration> decl = olddecl->EnsureMutable();
decl->RemovePropertyByID(aPropID);
RefPtr<DeclarationBlock> decl = olddecl->EnsureMutable();
decl->AsGecko()->RemovePropertyByID(aPropID);
return SetCSSDeclaration(decl);
}
nsresult
nsDOMCSSDeclaration::RemovePropertyInternal(const nsAString& aPropertyName)
{
css::Declaration* olddecl =
GetCSSDeclaration(eOperation_RemoveProperty)->AsGecko();
DeclarationBlock* olddecl = GetCSSDeclaration(eOperation_RemoveProperty);
if (!olddecl) {
return NS_OK; // no decl, so nothing to remove
}
@@ -388,7 +387,7 @@ nsDOMCSSDeclaration::RemovePropertyInternal(const nsAString& aPropertyName)
// rule (see stack in bug 209575).
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
RefPtr<css::Declaration> decl = olddecl->EnsureMutable();
decl->RemoveProperty(aPropertyName);
RefPtr<DeclarationBlock> decl = olddecl->EnsureMutable();
decl->AsGecko()->RemoveProperty(aPropertyName);
return SetCSSDeclaration(decl);
}