From 1cabbb443fa71122eba8706d871524bd8e96a951 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 23 Apr 2010 14:41:38 +1200 Subject: [PATCH] Bug 534566. Use separate nsPropertyTables for different categories so we don't pollute the property name list with unrelated names. r=sicking --- content/base/public/nsIDocument.h | 14 +++- content/base/public/nsINode.h | 8 ++ content/base/src/nsDOMAttribute.cpp | 2 +- content/base/src/nsDocument.cpp | 67 +++++++++++---- content/base/src/nsGenericElement.cpp | 16 ++-- content/base/src/nsNodeUtils.cpp | 20 ++--- content/base/src/nsPropertyTable.cpp | 55 ++++--------- content/base/src/nsPropertyTable.h | 100 ++--------------------- content/svg/content/src/nsSVGElement.cpp | 5 +- layout/generic/nsGfxScrollFrame.cpp | 27 ++++-- 10 files changed, 137 insertions(+), 177 deletions(-) diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index 56907a751f97..2c97ca00b230 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -816,7 +816,16 @@ public: */ virtual PRInt32 GetDefaultNamespaceID() const = 0; - nsPropertyTable* PropertyTable() { return &mPropertyTable; } + void DeleteAllProperties(); + void DeleteAllPropertiesFor(nsINode* aNode); + + nsPropertyTable* PropertyTable(PRUint16 aCategory) { + if (aCategory == 0) + return &mPropertyTable; + return GetExtraPropertyTable(aCategory); + } + PRUint32 GetPropertyTableCount() + { return mExtraPropertyTables.Length() + 1; } /** * Sets the ID used to identify this part of the multipart document @@ -1356,6 +1365,8 @@ protected: // want to expose to users of the nsIDocument API outside of Gecko. } + nsPropertyTable* GetExtraPropertyTable(PRUint16 aCategory); + // Never ever call this. Only call GetInnerWindow! virtual nsPIDOMWindow *GetInnerWindowInternal() = 0; @@ -1405,6 +1416,7 @@ protected: // Table of element properties for this document. nsPropertyTable mPropertyTable; + nsTArray > mExtraPropertyTables; // Compatibility mode nsCompatibility mCompatMode; diff --git a/content/base/public/nsINode.h b/content/base/public/nsINode.h index 30d57e84aa5e..b9cab81cb0e0 100644 --- a/content/base/public/nsINode.h +++ b/content/base/public/nsINode.h @@ -249,6 +249,14 @@ private: static PRUint32 sMutationCount; }; +// Categories of node properties +// 0 is global. +#define DOM_USER_DATA 1 +#define DOM_USER_DATA_HANDLER 2 +#ifdef MOZ_SMIL +#define SMIL_MAPPED_ATTR_ANIMVAL 3 +#endif // MOZ_SMIL + // IID for the nsINode interface #define NS_INODE_IID \ { 0xbc347b50, 0xa9b8, 0x419e, \ diff --git a/content/base/src/nsDOMAttribute.cpp b/content/base/src/nsDOMAttribute.cpp index bb2d3ad10135..abc14790aba4 100644 --- a/content/base/src/nsDOMAttribute.cpp +++ b/content/base/src/nsDOMAttribute.cpp @@ -160,7 +160,7 @@ nsDOMAttribute::SetOwnerDocument(nsIDocument* aDocument) nsIDocument *doc = GetOwnerDoc(); NS_ASSERTION(doc != aDocument, "bad call to nsDOMAttribute::SetOwnerDocument"); if (doc) { - doc->PropertyTable()->DeleteAllPropertiesFor(this); + doc->DeleteAllPropertiesFor(this); } nsCOMPtr newNodeInfo; diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index c4e1d2edc02d..f5f42858e4b5 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -1786,6 +1786,32 @@ nsDocument::Init() return NS_OK; } +void +nsIDocument::DeleteAllProperties() +{ + for (PRUint32 i = 0; i < GetPropertyTableCount(); ++i) { + PropertyTable(i)->DeleteAllProperties(); + } +} + +void +nsIDocument::DeleteAllPropertiesFor(nsINode* aNode) +{ + for (PRUint32 i = 0; i < GetPropertyTableCount(); ++i) { + PropertyTable(i)->DeleteAllPropertiesFor(aNode); + } +} + +nsPropertyTable* +nsIDocument::GetExtraPropertyTable(PRUint16 aCategory) +{ + NS_ASSERTION(aCategory > 0, "Category 0 should have already been handled"); + while (aCategory - 1 >= mExtraPropertyTables.Length()) { + mExtraPropertyTables.AppendElement(new nsPropertyTable()); + } + return mExtraPropertyTables[aCategory - 1]; +} + nsresult nsDocument::AddXMLEventsContent(nsIContent *aXMLEventsElement) { @@ -6120,35 +6146,40 @@ nsDocument::AdoptNode(nsIDOMNode *aAdoptedNode, nsIDOMNode **aResult) BlastSubtreeToPieces(adoptedNode); if (!sameDocument && oldDocument) { - PRUint32 i, count = nodesWithProperties.Count(); - for (i = 0; i < count; ++i) { - // Remove all properties. - oldDocument->PropertyTable()-> - DeleteAllPropertiesFor(nodesWithProperties[i]); + PRUint32 count = nodesWithProperties.Count(); + for (PRUint32 j = 0; j < oldDocument->GetPropertyTableCount(); ++j) { + for (PRUint32 i = 0; i < count; ++i) { + // Remove all properties. + oldDocument->PropertyTable(j)-> + DeleteAllPropertiesFor(nodesWithProperties[i]); + } } } return rv; } - PRUint32 i, count = nodesWithProperties.Count(); + PRUint32 count = nodesWithProperties.Count(); if (!sameDocument && oldDocument) { - nsPropertyTable *oldTable = oldDocument->PropertyTable(); - nsPropertyTable *newTable = PropertyTable(); - for (i = 0; i < count; ++i) { - rv = oldTable->TransferOrDeleteAllPropertiesFor(nodesWithProperties[i], - newTable); - if (NS_FAILED(rv)) { - while (++i < count) { + for (PRUint32 j = 0; j < oldDocument->GetPropertyTableCount(); ++j) { + nsPropertyTable *oldTable = oldDocument->PropertyTable(j); + nsPropertyTable *newTable = PropertyTable(j); + for (PRUint32 i = 0; i < count; ++i) { + if (NS_SUCCEEDED(rv)) { + rv = oldTable->TransferOrDeleteAllPropertiesFor(nodesWithProperties[i], + newTable); + } else { oldTable->DeleteAllPropertiesFor(nodesWithProperties[i]); } - - // Disconnect all nodes from their parents. - BlastSubtreeToPieces(adoptedNode); - - return rv; } } + + if (NS_FAILED(rv)) { + // Disconnect all nodes from their parents. + BlastSubtreeToPieces(adoptedNode); + + return rv; + } } rv = nsNodeUtils::CallUserDataHandlers(nodesWithProperties, this, diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index 976f8ba4642a..9244f05d8a33 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -209,8 +209,8 @@ nsINode::GetProperty(PRUint16 aCategory, nsIAtom *aPropertyName, if (!doc) return nsnull; - return doc->PropertyTable()->GetProperty(this, aCategory, aPropertyName, - aStatus); + return doc->PropertyTable(aCategory)->GetProperty(this, aPropertyName, + aStatus); } nsresult @@ -222,9 +222,9 @@ nsINode::SetProperty(PRUint16 aCategory, nsIAtom *aPropertyName, void *aValue, if (!doc) return NS_ERROR_FAILURE; - nsresult rv = doc->PropertyTable()->SetProperty(this, aCategory, - aPropertyName, aValue, aDtor, - nsnull, aTransfer, aOldValue); + nsresult rv = doc->PropertyTable(aCategory)->SetProperty(this, + aPropertyName, aValue, aDtor, + nsnull, aTransfer, aOldValue); if (NS_SUCCEEDED(rv)) { SetFlags(NODE_HAS_PROPERTIES); } @@ -239,7 +239,7 @@ nsINode::DeleteProperty(PRUint16 aCategory, nsIAtom *aPropertyName) if (!doc) return nsnull; - return doc->PropertyTable()->DeleteProperty(this, aCategory, aPropertyName); + return doc->PropertyTable(aCategory)->DeleteProperty(this, aPropertyName); } void* @@ -250,8 +250,8 @@ nsINode::UnsetProperty(PRUint16 aCategory, nsIAtom *aPropertyName, if (!doc) return nsnull; - return doc->PropertyTable()->UnsetProperty(this, aCategory, aPropertyName, - aStatus); + return doc->PropertyTable(aCategory)->UnsetProperty(this, aPropertyName, + aStatus); } nsIEventListenerManager* diff --git a/content/base/src/nsNodeUtils.cpp b/content/base/src/nsNodeUtils.cpp index 8e69ade3ab8c..81d7d96cab28 100644 --- a/content/base/src/nsNodeUtils.cpp +++ b/content/base/src/nsNodeUtils.cpp @@ -223,7 +223,7 @@ nsNodeUtils::LastRelease(nsINode* aNode) // Delete all properties before tearing down the document. Some of the // properties are bound to nsINode objects and the destructor functions of // the properties may want to use the owner document of the nsINode. - static_cast(aNode)->PropertyTable()->DeleteAllProperties(); + static_cast(aNode)->DeleteAllProperties(); } else { if (aNode->HasProperties()) { @@ -231,7 +231,7 @@ nsNodeUtils::LastRelease(nsINode* aNode) // delete the document. nsCOMPtr document = aNode->GetOwnerDoc(); if (document) { - document->PropertyTable()->DeleteAllPropertiesFor(aNode); + document->DeleteAllPropertiesFor(aNode); } } @@ -386,7 +386,7 @@ nsNodeUtils::CallUserDataHandlers(nsCOMArray &aNodesWithProperties, "Expected aNodesWithProperties to contain original and " "cloned nodes."); - nsPropertyTable *table = aOwnerDocument->PropertyTable(); + nsPropertyTable *table = aOwnerDocument->PropertyTable(DOM_USER_DATA_HANDLER); // Keep the document alive, just in case one of the handlers causes it to go // away. @@ -408,8 +408,7 @@ nsNodeUtils::CallUserDataHandlers(nsCOMArray &aNodesWithProperties, NS_ENSURE_SUCCESS(rv, rv); } - table->Enumerate(nodeWithProperties, DOM_USER_DATA_HANDLER, CallHandler, - &handlerData); + table->Enumerate(nodeWithProperties, CallHandler, &handlerData); } return NS_OK; @@ -434,10 +433,8 @@ nsNodeUtils::TraverseUserData(nsINode* aNode, return; } - nsPropertyTable *table = ownerDoc->PropertyTable(); - - table->Enumerate(aNode, DOM_USER_DATA, NoteUserData, &aCb); - table->Enumerate(aNode, DOM_USER_DATA_HANDLER, NoteUserData, &aCb); + ownerDoc->PropertyTable(DOM_USER_DATA)->Enumerate(aNode, NoteUserData, &aCb); + ownerDoc->PropertyTable(DOM_USER_DATA_HANDLER)->Enumerate(aNode, NoteUserData, &aCb); } /* static */ @@ -755,8 +752,7 @@ nsNodeUtils::UnlinkUserData(nsINode *aNode) // delete the document. nsCOMPtr document = aNode->GetOwnerDoc(); if (document) { - document->PropertyTable()->DeleteAllPropertiesFor(aNode, DOM_USER_DATA); - document->PropertyTable()->DeleteAllPropertiesFor(aNode, - DOM_USER_DATA_HANDLER); + document->PropertyTable(DOM_USER_DATA)->DeleteAllPropertiesFor(aNode); + document->PropertyTable(DOM_USER_DATA_HANDLER)->DeleteAllPropertiesFor(aNode); } } diff --git a/content/base/src/nsPropertyTable.cpp b/content/base/src/nsPropertyTable.cpp index 56d2043b9097..408077edc8d6 100644 --- a/content/base/src/nsPropertyTable.cpp +++ b/content/base/src/nsPropertyTable.cpp @@ -66,8 +66,7 @@ struct PropertyListMapEntry : public PLDHashEntryHdr { class nsPropertyTable::PropertyList { public: - PropertyList(PRUint16 aCategory, - nsIAtom* aName, + PropertyList(nsIAtom* aName, NSPropertyDtorFunc aDtorFunc, void* aDtorData, PRBool aTransfer) NS_HIDDEN; @@ -80,16 +79,15 @@ public: // Destroy all remaining properties (without removing them) NS_HIDDEN_(void) Destroy(); - NS_HIDDEN_(PRBool) Equals(PRUint16 aCategory, nsIAtom *aPropertyName) + NS_HIDDEN_(PRBool) Equals(nsIAtom *aPropertyName) { - return mCategory == aCategory && mName == aPropertyName; + return mName == aPropertyName; } nsCOMPtr mName; // property name PLDHashTable mObjectValueMap; // map of object/value pairs NSPropertyDtorFunc mDtorFunc; // property specific value dtor function void* mDtorData; // pointer to pass to dtor - PRUint16 mCategory; // category PRPackedBool mTransfer; // whether to transfer in // TransferOrDeleteAllPropertiesFor @@ -116,16 +114,6 @@ nsPropertyTable::DeleteAllPropertiesFor(nsPropertyOwner aObject) } } -void -nsPropertyTable::DeleteAllPropertiesFor(nsPropertyOwner aObject, - PRUint16 aCategory) -{ - for (PropertyList* prop = mPropertyList; prop; prop = prop->mNext) { - if (prop->mCategory == aCategory) - prop->DeletePropertyFor(aObject); - } -} - nsresult nsPropertyTable::TransferOrDeleteAllPropertiesFor(nsPropertyOwner aObject, nsPropertyTable *aOtherTable) @@ -137,7 +125,7 @@ nsPropertyTable::TransferOrDeleteAllPropertiesFor(nsPropertyOwner aObject, (PL_DHashTableOperate(&prop->mObjectValueMap, aObject, PL_DHASH_LOOKUP)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { - rv = aOtherTable->SetProperty(aObject, prop->mCategory, prop->mName, + rv = aOtherTable->SetProperty(aObject, prop->mName, entry->value, prop->mDtorFunc, prop->mDtorData, prop->mTransfer); if (NS_FAILED(rv)) { @@ -159,26 +147,22 @@ nsPropertyTable::TransferOrDeleteAllPropertiesFor(nsPropertyOwner aObject, } void -nsPropertyTable::Enumerate(nsPropertyOwner aObject, PRUint16 aCategory, +nsPropertyTable::Enumerate(nsPropertyOwner aObject, NSPropertyFunc aCallback, void *aData) { PropertyList* prop; for (prop = mPropertyList; prop; prop = prop->mNext) { - if (prop->mCategory == aCategory) { - PropertyListMapEntry *entry = static_cast - (PL_DHashTableOperate(&prop->mObjectValueMap, aObject, - PL_DHASH_LOOKUP)); - if (PL_DHASH_ENTRY_IS_BUSY(entry)) { - aCallback(const_cast(aObject.get()), prop->mName, entry->value, - aData); - } + PropertyListMapEntry *entry = static_cast + (PL_DHashTableOperate(&prop->mObjectValueMap, aObject, PL_DHASH_LOOKUP)); + if (PL_DHASH_ENTRY_IS_BUSY(entry)) { + aCallback(const_cast(aObject.get()), prop->mName, entry->value, + aData); } } } void* nsPropertyTable::GetPropertyInternal(nsPropertyOwner aObject, - PRUint16 aCategory, nsIAtom *aPropertyName, PRBool aRemove, nsresult *aResult) @@ -187,7 +171,7 @@ nsPropertyTable::GetPropertyInternal(nsPropertyOwner aObject, nsresult rv = NS_PROPTABLE_PROP_NOT_THERE; void *propValue = nsnull; - PropertyList* propertyList = GetPropertyListFor(aCategory, aPropertyName); + PropertyList* propertyList = GetPropertyListFor(aPropertyName); if (propertyList) { PropertyListMapEntry *entry = static_cast (PL_DHashTableOperate(&propertyList->mObjectValueMap, aObject, @@ -210,7 +194,6 @@ nsPropertyTable::GetPropertyInternal(nsPropertyOwner aObject, nsresult nsPropertyTable::SetPropertyInternal(nsPropertyOwner aObject, - PRUint16 aCategory, nsIAtom *aPropertyName, void *aPropertyValue, NSPropertyDtorFunc aPropDtorFunc, @@ -220,7 +203,7 @@ nsPropertyTable::SetPropertyInternal(nsPropertyOwner aObject, { NS_PRECONDITION(aPropertyName && aObject, "unexpected null param"); - PropertyList* propertyList = GetPropertyListFor(aCategory, aPropertyName); + PropertyList* propertyList = GetPropertyListFor(aPropertyName); if (propertyList) { // Make sure the dtor function and data and the transfer flag match @@ -232,7 +215,7 @@ nsPropertyTable::SetPropertyInternal(nsPropertyOwner aObject, } } else { - propertyList = new PropertyList(aCategory, aPropertyName, aPropDtorFunc, + propertyList = new PropertyList(aPropertyName, aPropDtorFunc, aPropDtorData, aTransfer); if (!propertyList || !propertyList->mObjectValueMap.ops) { delete propertyList; @@ -271,12 +254,11 @@ nsPropertyTable::SetPropertyInternal(nsPropertyOwner aObject, nsresult nsPropertyTable::DeleteProperty(nsPropertyOwner aObject, - PRUint16 aCategory, nsIAtom *aPropertyName) { NS_PRECONDITION(aPropertyName && aObject, "unexpected null param"); - PropertyList* propertyList = GetPropertyListFor(aCategory, aPropertyName); + PropertyList* propertyList = GetPropertyListFor(aPropertyName); if (propertyList) { if (propertyList->DeletePropertyFor(aObject)) return NS_OK; @@ -286,13 +268,12 @@ nsPropertyTable::DeleteProperty(nsPropertyOwner aObject, } nsPropertyTable::PropertyList* -nsPropertyTable::GetPropertyListFor(PRUint16 aCategory, - nsIAtom* aPropertyName) const +nsPropertyTable::GetPropertyListFor(nsIAtom* aPropertyName) const { PropertyList* result; for (result = mPropertyList; result; result = result->mNext) { - if (result->Equals(aCategory, aPropertyName)) { + if (result->Equals(aPropertyName)) { break; } } @@ -302,15 +283,13 @@ nsPropertyTable::GetPropertyListFor(PRUint16 aCategory, //---------------------------------------------------------------------- -nsPropertyTable::PropertyList::PropertyList(PRUint16 aCategory, - nsIAtom *aName, +nsPropertyTable::PropertyList::PropertyList(nsIAtom *aName, NSPropertyDtorFunc aDtorFunc, void *aDtorData, PRBool aTransfer) : mName(aName), mDtorFunc(aDtorFunc), mDtorData(aDtorData), - mCategory(aCategory), mTransfer(aTransfer), mNext(nsnull) { diff --git a/content/base/src/nsPropertyTable.h b/content/base/src/nsPropertyTable.h index c8bbe4916142..f729e10e2295 100644 --- a/content/base/src/nsPropertyTable.h +++ b/content/base/src/nsPropertyTable.h @@ -94,14 +94,6 @@ private: const void* mObject; }; -// Categories of properties -// 0 is global. -#define DOM_USER_DATA 1 -#define DOM_USER_DATA_HANDLER 2 -#ifdef MOZ_SMIL -#define SMIL_MAPPED_ATTR_ANIMVAL 3 -#endif // MOZ_SMIL - class nsPropertyTable { public: @@ -113,20 +105,11 @@ class nsPropertyTable nsIAtom *aPropertyName, nsresult *aResult = nsnull) { - return GetPropertyInternal(aObject, 0, aPropertyName, PR_FALSE, aResult); - } - - void* GetProperty(nsPropertyOwner aObject, - PRUint16 aCategory, - nsIAtom *aPropertyName, - nsresult *aResult = nsnull) - { - return GetPropertyInternal(aObject, aCategory, aPropertyName, PR_FALSE, - aResult); + return GetPropertyInternal(aObject, aPropertyName, PR_FALSE, aResult); } /** - * Set the value of the property |aPropertyName| in the global category to + * Set the value of the property |aPropertyName| to * |aPropertyValue| for node |aObject|. |aDtor| is a destructor for the * property value to be called if the property is removed. It can be null * if no destructor is required. |aDtorData| is an optional pointer to an @@ -150,57 +133,15 @@ class nsPropertyTable PRBool aTransfer = PR_FALSE, void **aOldValue = nsnull) { - return SetPropertyInternal(aObject, 0, aPropertyName, aPropertyValue, + return SetPropertyInternal(aObject, aPropertyName, aPropertyValue, aDtor, aDtorData, aTransfer, aOldValue); } - /** - * Set the value of the property |aPropertyName| in the category |aCategory| - * to |aPropertyValue| for node |aObject|. |aDtor| is a destructor for the - * property value to be called if the property is removed. It can be null - * if no destructor is required. |aDtorData| is an optional pointer to an - * opaque context to be passed to the property destructor. Note that the - * destructor is global for each property name regardless of node; it is an - * error to set a given property with a different destructor than was used - * before (this will return NS_ERROR_INVALID_ARG). If aOldValue is non-null - * it will contain the old value after the function returns (the destructor - * for the old value will not be run in that case). If aTransfer is PR_TRUE - * the property will be transfered to the new table when the property table - * for |aObject| changes (currently the tables for nodes are owned by their - * ownerDocument, so if the ownerDocument for a node changes, its property - * table changes too). If |aTransfer| is PR_FALSE the property will just be - * deleted instead. - */ - NS_HIDDEN_(nsresult) SetProperty(nsPropertyOwner aObject, - PRUint16 aCategory, - nsIAtom *aPropertyName, - void *aPropertyValue, - NSPropertyDtorFunc aDtor, - void *aDtorData, - PRBool aTransfer = PR_FALSE, - void **aOldValue = nsnull) - { - return SetPropertyInternal(aObject, aCategory, aPropertyName, - aPropertyValue, aDtor, aDtorData, aTransfer, - aOldValue); - } - /** * Delete the property |aPropertyName| in the global category for object * |aObject|. The property's destructor function will be called. */ NS_HIDDEN_(nsresult) DeleteProperty(nsPropertyOwner aObject, - nsIAtom *aPropertyName) - { - return DeleteProperty(aObject, 0, aPropertyName); - } - - /** - * Delete the property |aPropertyName| in category |aCategory| for object - * |aObject|. The property's destructor function will be called. - */ - NS_HIDDEN_(nsresult) DeleteProperty(nsPropertyOwner aObject, - PRUint16 aCategory, nsIAtom *aPropertyName); /** @@ -212,21 +153,7 @@ class nsPropertyTable nsIAtom *aPropertyName, nsresult *aStatus = nsnull) { - return GetPropertyInternal(aObject, 0, aPropertyName, PR_TRUE, aStatus); - } - - /** - * Unset the property |aPropertyName| in category |aCategory| for object - * |aObject|, but do not call the property's destructor function. The - * property value is returned. - */ - void* UnsetProperty(nsPropertyOwner aObject, - PRUint16 aCategory, - nsIAtom *aPropertyName, - nsresult *aStatus = nsnull) - { - return GetPropertyInternal(aObject, aCategory, aPropertyName, PR_TRUE, - aStatus); + return GetPropertyInternal(aObject, aPropertyName, PR_TRUE, aStatus); } /** @@ -235,13 +162,6 @@ class nsPropertyTable */ NS_HIDDEN_(void) DeleteAllPropertiesFor(nsPropertyOwner aObject); - /** - * Deletes all of the properties in category |aCategory| for object |aObject|, - * calling the destructor function for each property. - */ - NS_HIDDEN_(void) DeleteAllPropertiesFor(nsPropertyOwner aObject, - PRUint16 aCategory); - /** * Transfers all properties for object |aObject| that were set with the * |aTransfer| argument as PR_TRUE to |aTable|. Deletes the other properties @@ -254,11 +174,11 @@ class nsPropertyTable nsPropertyTable *aOtherTable); /** - * Enumerate the properties in category |aCategory| for object |aObject|. + * Enumerate the properties for object |aObject|. * For every property |aCallback| will be called with as arguments |aObject|, * the property name, the property value and |aData|. */ - NS_HIDDEN_(void) Enumerate(nsPropertyOwner aObject, PRUint16 aCategory, + NS_HIDDEN_(void) Enumerate(nsPropertyOwner aObject, NSPropertyFunc aCallback, void *aData); /** @@ -266,7 +186,8 @@ class nsPropertyTable * table, calling the destructor function for each property. */ NS_HIDDEN_(void) DeleteAllProperties(); - + + nsPropertyTable() : mPropertyList(nsnull) {} ~nsPropertyTable() { DeleteAllProperties(); } @@ -283,15 +204,12 @@ class nsPropertyTable private: NS_HIDDEN_(void) DestroyPropertyList(); - NS_HIDDEN_(PropertyList*) GetPropertyListFor(PRUint16 aCategory, - nsIAtom *aPropertyName) const; + NS_HIDDEN_(PropertyList*) GetPropertyListFor(nsIAtom *aPropertyName) const; NS_HIDDEN_(void*) GetPropertyInternal(nsPropertyOwner aObject, - PRUint16 aCategory, nsIAtom *aPropertyName, PRBool aRemove, nsresult *aStatus); NS_HIDDEN_(nsresult) SetPropertyInternal(nsPropertyOwner aObject, - PRUint16 aCategory, nsIAtom *aPropertyName, void *aPropertyValue, NSPropertyDtorFunc aDtor, diff --git a/content/svg/content/src/nsSVGElement.cpp b/content/svg/content/src/nsSVGElement.cpp index 0241e2cb855c..86b2861a5167 100644 --- a/content/svg/content/src/nsSVGElement.cpp +++ b/content/svg/content/src/nsSVGElement.cpp @@ -1250,9 +1250,8 @@ nsSVGElement::UpdateAnimatedContentStyleRule() MappedAttrParser mappedAttrParser(doc->CSSLoader(), doc->GetDocumentURI(), GetBaseURI(), NodePrincipal()); - doc->PropertyTable()->Enumerate(this, SMIL_MAPPED_ATTR_ANIMVAL, - ParseMappedAttrAnimValueCallback, - &mappedAttrParser); + doc->PropertyTable(SMIL_MAPPED_ATTR_ANIMVAL)-> + Enumerate(this, ParseMappedAttrAnimValueCallback, &mappedAttrParser); nsRefPtr animContentStyleRule(mappedAttrParser.CreateStyleRule()); diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 36a01a21e061..bb4f8ccb5c94 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1620,9 +1620,13 @@ SortBlitRectsForCopy(nsIntPoint aPixDelta, nsTArray* aRects) } static PRBool -CanScrollWithBlitting(nsIFrame* aFrame) +CanScrollWithBlitting(nsIFrame* aFrame, nsIFrame* aDisplayRoot, nsRect* aClippedScrollPort) { - for (nsIFrame* f = aFrame; f; f = nsLayoutUtils::GetCrossDocParentFrame(f)) { + nsPoint offset(0, 0); + *aClippedScrollPort = nsRect(nsPoint(0, 0), aFrame->GetSize()); + + for (nsIFrame* f = aFrame; f; + f = nsLayoutUtils::GetCrossDocParentFrame(f, &offset)) { if (f->GetStyleDisplay()->HasTransform()) { return PR_FALSE; } @@ -1632,6 +1636,18 @@ CanScrollWithBlitting(nsIFrame* aFrame) return PR_FALSE; } #endif + + nsIScrollableFrame* sf = do_QueryFrame(f); + if (sf) { + // Note that this will always happen on the first iteration of the loop, + // ensuring that we clip to our own scrollframe's scrollport + aClippedScrollPort->IntersectRect(*aClippedScrollPort, + sf->GetScrollPortRect() - offset); + } + + offset += f->GetPosition(); + if (f == aDisplayRoot) + break; } return PR_TRUE; } @@ -1658,9 +1674,11 @@ void nsGfxScrollFrameInner::ScrollVisual(nsIntPoint aPixDelta) rootPresContext->GetPluginGeometryUpdates(mOuter, &configurations); } + nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(mOuter); + nsRect clippedScrollPort; if (!nearestWidget || nearestWidget->GetTransparencyMode() == eTransparencyTransparent || - !CanScrollWithBlitting(mOuter)) { + !CanScrollWithBlitting(mOuter, displayRoot, &clippedScrollPort)) { // Just invalidate the frame and adjust child widgets // Recall that our widget's origin is at our bounds' top-left if (nearestWidget) { @@ -1672,7 +1690,6 @@ void nsGfxScrollFrameInner::ScrollVisual(nsIntPoint aPixDelta) mOuter->InvalidateWithFlags(mScrollPort, nsIFrame::INVALIDATE_REASON_SCROLL_REPAINT); } else { - nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(mOuter); nsRegion blitRegion; nsRegion repaintRegion; nsPresContext* presContext = mOuter->PresContext(); @@ -1681,7 +1698,7 @@ void nsGfxScrollFrameInner::ScrollVisual(nsIntPoint aPixDelta) nsPoint offsetToDisplayRoot = mOuter->GetOffsetTo(displayRoot); nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel(); nsRect scrollPort = - (mScrollPort + offsetToDisplayRoot).ToNearestPixels(appUnitsPerDevPixel). + (clippedScrollPort + offsetToDisplayRoot).ToNearestPixels(appUnitsPerDevPixel). ToAppUnits(appUnitsPerDevPixel); nsresult rv = nsLayoutUtils::ComputeRepaintRegionForCopy(displayRoot, mScrolledFrame,