From 2ac3245dec84b6ab2b24a0e3818c251eed09c2ab Mon Sep 17 00:00:00 2001 From: "bryner%brianryner.com" Date: Sun, 22 Aug 2004 07:10:50 +0000 Subject: [PATCH] Backing out 253888 again due to Tp regression plus another problem I noticed (frame properties not getting destroyed on frame destruction) git-svn-id: svn://10.0.0.236/trunk@161116 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/public/nsContentErrors.h | 6 - mozilla/content/base/public/nsIContent.h | 22 -- mozilla/content/base/public/nsIDocument.h | 6 - mozilla/content/base/src/nsGenericElement.cpp | 55 +--- mozilla/content/base/src/nsGenericElement.h | 20 +- mozilla/content/base/src/nsPropertyTable.cpp | 263 ------------------ mozilla/content/base/src/nsPropertyTable.h | 138 --------- mozilla/content/events/src/nsDOMUIEvent.h | 1 - mozilla/content/shared/public/Makefile.in | 1 - .../content/shared/public/nsFrameManager.h | 69 +++++ .../shared/public/nsFrameManagerBase.h | 4 + .../content/shared/public/nsPropertyTable.h | 138 --------- mozilla/content/shared/src/Makefile.in | 1 - .../content/shared/src/nsPropertyTable.cpp | 263 ------------------ .../content/xul/content/src/nsXULElement.cpp | 55 +--- .../content/xul/content/src/nsXULElement.h | 11 +- mozilla/layout/base/nsBidiPresUtils.cpp | 11 +- mozilla/layout/base/nsCSSFrameConstructor.cpp | 37 ++- mozilla/layout/base/nsFrameManager.cpp | 239 +++++++++++++++- mozilla/layout/base/nsFrameManager.h | 69 +++++ mozilla/layout/base/nsFrameManagerBase.h | 4 + mozilla/layout/base/nsLayoutErrors.h | 9 + mozilla/layout/base/nsPresContext.cpp | 1 - mozilla/layout/base/nsPresContext.h | 6 - mozilla/layout/base/nsPresShell.cpp | 16 +- mozilla/layout/base/public/nsIFrame.h | 25 +- mozilla/layout/base/public/nsLayoutErrors.h | 9 + mozilla/layout/base/public/nsPresContext.h | 6 - mozilla/layout/base/src/nsBidiPresUtils.cpp | 11 +- mozilla/layout/base/src/nsPresContext.cpp | 1 - mozilla/layout/generic/nsBlockFrame.cpp | 45 ++- .../layout/generic/nsBlockReflowContext.cpp | 15 +- mozilla/layout/generic/nsBlockReflowState.cpp | 3 +- mozilla/layout/generic/nsContainerFrame.cpp | 23 +- mozilla/layout/generic/nsFrame.cpp | 56 ++-- mozilla/layout/generic/nsFrameFrame.cpp | 5 +- mozilla/layout/generic/nsIFrame.h | 25 +- mozilla/layout/html/base/src/nsBlockFrame.cpp | 45 ++- .../html/base/src/nsBlockReflowContext.cpp | 15 +- .../html/base/src/nsBlockReflowState.cpp | 3 +- .../layout/html/base/src/nsContainerFrame.cpp | 23 +- mozilla/layout/html/base/src/nsFrame.cpp | 56 ++-- .../layout/html/base/src/nsFrameManager.cpp | 239 +++++++++++++++- mozilla/layout/html/base/src/nsPresShell.cpp | 16 +- .../layout/html/document/src/nsFrameFrame.cpp | 5 +- .../html/style/src/nsCSSFrameConstructor.cpp | 37 ++- .../layout/html/table/src/nsTableFrame.cpp | 26 +- .../mathml/base/src/nsMathMLmtableFrame.cpp | 13 +- mozilla/layout/tables/nsTableFrame.cpp | 26 +- mozilla/layout/xul/base/src/nsBox.cpp | 3 +- 50 files changed, 943 insertions(+), 1233 deletions(-) delete mode 100644 mozilla/content/base/src/nsPropertyTable.cpp delete mode 100644 mozilla/content/base/src/nsPropertyTable.h delete mode 100644 mozilla/content/shared/public/nsPropertyTable.h delete mode 100644 mozilla/content/shared/src/nsPropertyTable.cpp diff --git a/mozilla/content/base/public/nsContentErrors.h b/mozilla/content/base/public/nsContentErrors.h index 77982c289fc..5c458649e0f 100644 --- a/mozilla/content/base/public/nsContentErrors.h +++ b/mozilla/content/base/public/nsContentErrors.h @@ -94,10 +94,4 @@ #define NS_CONTENT_BLOCKED_SHOW_ALT \ NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_CONTENT, 13) -#define NS_PROPTABLE_PROP_NOT_THERE \ - NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_CONTENT, 14) - -#define NS_PROPTABLE_PROP_OVERWRITTEN \ - NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_CONTENT, 15) - #endif // nsContentErrors_h___ diff --git a/mozilla/content/base/public/nsIContent.h b/mozilla/content/base/public/nsIContent.h index c5c963cc64d..ce4a81ae738 100644 --- a/mozilla/content/base/public/nsIContent.h +++ b/mozilla/content/base/public/nsIContent.h @@ -43,7 +43,6 @@ #include "nsEvent.h" #include "nsAString.h" #include "nsContentErrors.h" -#include "nsPropertyTable.h" // Forward declarations class nsIAtom; @@ -612,27 +611,6 @@ public: return PR_TRUE; } - /* Methods for manipulating content node properties. For documentation on - * properties, see nsPropertyTable.h. - */ - - virtual void* GetProperty(nsIAtom *aPropertyName, - nsresult *aStatus = nsnull) const - { if (aStatus) *aStatus = NS_ERROR_NOT_IMPLEMENTED; return nsnull; } - - virtual nsresult SetProperty(nsIAtom *aPropertyName, - void *aValue, - NSPropertyDtorFunc aDtor = nsnull) - { return NS_ERROR_NOT_IMPLEMENTED; } - - virtual nsresult DeleteProperty(nsIAtom *aPropertyName) - { return NS_ERROR_NOT_IMPLEMENTED; } - - virtual void* UnsetProperty(nsIAtom *aPropertyName, - nsresult *aStatus = nsnull) - { if (aStatus) *aStatus = NS_ERROR_NOT_IMPLEMENTED; return nsnull; } - - #ifdef DEBUG /** * List the content (and anything it contains) out to the given diff --git a/mozilla/content/base/public/nsIDocument.h b/mozilla/content/base/public/nsIDocument.h index 90481652fe2..726471b6f0f 100644 --- a/mozilla/content/base/public/nsIDocument.h +++ b/mozilla/content/base/public/nsIDocument.h @@ -51,7 +51,6 @@ #include "nsReadableUtils.h" #include "nsCRT.h" #include "mozFlushType.h" -#include "nsPropertyTable.h" class nsIAtom; class nsIContent; @@ -627,8 +626,6 @@ public: */ virtual PRInt32 GetDefaultNamespaceID() const = 0; - nsPropertyTable* PropertyTable() { return &mPropertyTable; } - protected: nsString mDocumentTitle; nsCOMPtr mDocumentURI; @@ -655,9 +652,6 @@ protected: nsCOMPtr mBindingManager; nsNodeInfoManager* mNodeInfoManager; // [STRONG] - // Table of element properties for this document. - nsPropertyTable mPropertyTable; - // True if BIDI is enabled. PRBool mBidiEnabled; diff --git a/mozilla/content/base/src/nsGenericElement.cpp b/mozilla/content/base/src/nsGenericElement.cpp index 56806403ed1..de34946f457 100644 --- a/mozilla/content/base/src/nsGenericElement.cpp +++ b/mozilla/content/base/src/nsGenericElement.cpp @@ -1731,13 +1731,7 @@ nsGenericElement::SetDocument(nsIDocument* aDocument, PRBool aDeep, // check the document on the nodeinfo to see whether we need a // new nodeinfo - nsIDocument *ownerDocument = GetOwnerDoc(); - if (aDocument != ownerDocument) { - - if (HasProperties()) { - ownerDocument->PropertyTable()->DeleteAllPropertiesFor(this); - } - + if (aDocument != GetOwnerDoc()) { // get a new nodeinfo nsNodeInfoManager* nodeInfoManager = aDocument->NodeInfoManager(); if (nodeInfoManager) { @@ -3646,50 +3640,3 @@ nsGenericElement::GetContentsAsText(nsAString& aText) } } } - -void* -nsGenericElement::GetProperty(nsIAtom *aPropertyName, nsresult *aStatus) const -{ - nsIDocument *doc = GetDocument(); - if (!doc) - return nsnull; - - return doc->PropertyTable()->GetProperty(this, aPropertyName, aStatus); -} - -nsresult -nsGenericElement::SetProperty(nsIAtom *aPropertyName, - void *aValue, - NSPropertyDtorFunc aDtor) -{ - nsIDocument *doc = GetDocument(); - if (!doc) - return NS_ERROR_FAILURE; - - nsresult rv = doc->PropertyTable()->SetProperty(this, aPropertyName, - aValue, aDtor, nsnull); - if (NS_SUCCEEDED(rv)) - SetFlags(GENERIC_ELEMENT_HAS_PROPERTIES); - - return rv; -} - -nsresult -nsGenericElement::DeleteProperty(nsIAtom *aPropertyName) -{ - nsIDocument *doc = GetDocument(); - if (!doc) - return nsnull; - - return doc->PropertyTable()->DeleteProperty(this, aPropertyName); -} - -void* -nsGenericElement::UnsetProperty(nsIAtom *aPropertyName, nsresult *aStatus) -{ - nsIDocument *doc = GetDocument(); - if (!doc) - return nsnull; - - return doc->PropertyTable()->UnsetProperty(this, aPropertyName, aStatus); -} diff --git a/mozilla/content/base/src/nsGenericElement.h b/mozilla/content/base/src/nsGenericElement.h index fd6f5702a0f..5ae62efbb46 100644 --- a/mozilla/content/base/src/nsGenericElement.h +++ b/mozilla/content/base/src/nsGenericElement.h @@ -85,11 +85,8 @@ typedef unsigned long PtrBits; /** Whether this content is anonymous */ #define GENERIC_ELEMENT_IS_ANONYMOUS 0x00000008U -/** Whether this content has had any properties set on it */ -#define GENERIC_ELEMENT_HAS_PROPERTIES 0x00000010U - /** The number of bits to shift the bit field to get at the content ID */ -#define GENERIC_ELEMENT_CONTENT_ID_BITS_OFFSET 5 +#define GENERIC_ELEMENT_CONTENT_ID_BITS_OFFSET 4 /** This mask masks out the bits that are used for the content ID */ #define GENERIC_ELEMENT_CONTENT_ID_MASK \ @@ -415,14 +412,6 @@ public: virtual PRBool IsContentOfType(PRUint32 aFlags) const; virtual nsresult GetListenerManager(nsIEventListenerManager** aResult); virtual already_AddRefed GetBaseURI() const; - virtual void* GetProperty(nsIAtom *aPropertyName, - nsresult *aStatus = nsnull) const; - virtual nsresult SetProperty(nsIAtom *aPropertyName, - void *aValue, - NSPropertyDtorFunc aDtor); - virtual nsresult DeleteProperty(nsIAtom *aPropertyName); - virtual void* UnsetProperty(nsIAtom *aPropertyName, - nsresult *aStatus = nsnull); #ifdef DEBUG virtual void List(FILE* out, PRInt32 aIndent) const; virtual void DumpContent(FILE* out, PRInt32 aIndent,PRBool aDumpAll) const; @@ -747,13 +736,6 @@ protected: sEventListenerManagersHash.ops); } - PRBool HasProperties() const - { - PtrBits flags = GetFlags(); - - return (flags & GENERIC_ELEMENT_HAS_PROPERTIES) != 0; - } - /** * GetContentsAsText will take all the textnodes that are children * of |this| and concatenate the text in them into aText. It diff --git a/mozilla/content/base/src/nsPropertyTable.cpp b/mozilla/content/base/src/nsPropertyTable.cpp deleted file mode 100644 index b0b18f6e16f..00000000000 --- a/mozilla/content/base/src/nsPropertyTable.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim:cindent:ts=2:et:sw=2: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** - * - * This Original Code has been modified by IBM Corporation. Modifications made by IBM - * described herein are Copyright (c) International Business Machines Corporation, 2000. - * Modifications to Mozilla code or documentation identified per MPL Section 3.3 - * - * Date Modified by Description of modification - * 04/20/2000 IBM Corp. OS/2 VisualAge build. - */ - -#include "nsPropertyTable.h" -#include "pldhash.h" -#include "nsContentErrors.h" -#include "nsIAtom.h" - -struct PropertyListMapEntry : public PLDHashEntryHdr { - const void *key; - void *value; -}; - -//---------------------------------------------------------------------- - -struct nsPropertyTable::PropertyList { - nsCOMPtr mName; // property name - PLDHashTable mObjectValueMap; // map of object/value pairs - NSPropertyDtorFunc mDtorFunc; // property specific value dtor function - void* mDtorData; - PropertyList* mNext; - - PropertyList(nsIAtom* aName, - NSPropertyDtorFunc aDtorFunc) NS_HIDDEN; - ~PropertyList() NS_HIDDEN; - - // Removes the property associated with the given object, and destroys - // the property value - NS_HIDDEN_(PRBool) DeletePropertyFor(const void * aObject); - - // Destroy all remaining properties (without removing them) - NS_HIDDEN_(void) Destroy(); -}; - -nsPropertyTable::~nsPropertyTable() -{ - if (mPropertyList) { - while (mPropertyList) { - PropertyList* tmp = mPropertyList; - - mPropertyList = mPropertyList->mNext; - tmp->Destroy(); - delete tmp; - } - } -} - -void -nsPropertyTable::DeleteAllPropertiesFor(const void *aObject) -{ - for (PropertyList* prop = mPropertyList; prop; prop = prop->mNext) { - prop->DeletePropertyFor(aObject); - } -} - -void* -nsPropertyTable::GetPropertyInternal(const void *aObject, - nsIAtom *aPropertyName, - PRBool aRemove, - nsresult *aResult) -{ - NS_PRECONDITION(aPropertyName && aObject, "unexpected null param"); - nsresult rv = NS_PROPTABLE_PROP_NOT_THERE; - void *propValue = nsnull; - - PropertyList* propertyList = GetPropertyListFor(aPropertyName); - if (propertyList) { - PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*, - PL_DHashTableOperate(&propertyList->mObjectValueMap, aObject, - PL_DHASH_LOOKUP)); - if (PL_DHASH_ENTRY_IS_BUSY(entry)) { - propValue = entry->value; - if (aRemove) { - // don't call propertyList->mDtorFunc. That's the caller's job now. - PL_DHashTableRawRemove(&propertyList->mObjectValueMap, entry); - } - rv = NS_OK; - } - } - - if (aResult) - *aResult = rv; - - return propValue; -} - -nsresult -nsPropertyTable::SetProperty(const void *aObject, - nsIAtom *aPropertyName, - void *aPropertyValue, - NSPropertyDtorFunc aPropDtorFunc, - void *aPropDtorData) -{ - NS_PRECONDITION(aPropertyName && aObject, "unexpected null param"); - - PropertyList* propertyList = GetPropertyListFor(aPropertyName); - - if (propertyList) { - // Make sure the dtor function matches - if (aPropDtorFunc != propertyList->mDtorFunc) { - return NS_ERROR_INVALID_ARG; - } - - } else { - propertyList = new PropertyList(aPropertyName, aPropDtorFunc); - if (!propertyList) - return NS_ERROR_OUT_OF_MEMORY; - if (!propertyList->mObjectValueMap.ops) { - delete propertyList; - return NS_ERROR_OUT_OF_MEMORY; - } - - propertyList->mNext = mPropertyList; - mPropertyList = propertyList; - } - - // The current property value (if there is one) is replaced and the current - // value is destroyed - nsresult result = NS_OK; - PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*, - PL_DHashTableOperate(&propertyList->mObjectValueMap, aObject, PL_DHASH_ADD)); - if (!entry) - return NS_ERROR_OUT_OF_MEMORY; - // A NULL entry->key is the sign that the entry has just been allocated - // for us. If it's non-NULL then we have an existing entry. - if (entry->key && propertyList->mDtorFunc) { - propertyList->mDtorFunc(NS_CONST_CAST(void*, entry->key), aPropertyName, - entry->value, propertyList->mDtorData); - result = NS_PROPTABLE_PROP_OVERWRITTEN; - } - entry->key = aObject; - entry->value = aPropertyValue; - - return result; -} - -nsresult -nsPropertyTable::DeleteProperty(const void *aObject, - nsIAtom *aPropertyName) -{ - NS_PRECONDITION(aPropertyName && aObject, "unexpected null param"); - - PropertyList* propertyList = GetPropertyListFor(aPropertyName); - if (propertyList) { - if (propertyList->DeletePropertyFor(aObject)) - return NS_OK; - } - - return NS_PROPTABLE_PROP_NOT_THERE; -} - -nsPropertyTable::PropertyList* -nsPropertyTable::GetPropertyListFor(nsIAtom* aPropertyName) const -{ - PropertyList* result; - - for (result = mPropertyList; result; result = result->mNext) { - if (result->mName.get() == aPropertyName) { - break; - } - } - - return result; -} - -//---------------------------------------------------------------------- - -nsPropertyTable::PropertyList::PropertyList(nsIAtom *aName, - NSPropertyDtorFunc aDtorFunc) - : mName(aName), mDtorFunc(aDtorFunc), mDtorData(nsnull), mNext(nsnull) -{ - PL_DHashTableInit(&mObjectValueMap, PL_DHashGetStubOps(), this, - sizeof(PropertyListMapEntry), 16); -} - -nsPropertyTable::PropertyList::~PropertyList() -{ - PL_DHashTableFinish(&mObjectValueMap); -} - - -PR_STATIC_CALLBACK(PLDHashOperator) -DestroyPropertyEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr, - PRUint32 number, void *arg) -{ - nsPropertyTable::PropertyList *propList = - NS_STATIC_CAST(nsPropertyTable::PropertyList*, table->data); - PropertyListMapEntry* entry = NS_STATIC_CAST(PropertyListMapEntry*, hdr); - - propList->mDtorFunc(NS_CONST_CAST(void*, entry->key), propList->mName, - entry->value, propList->mDtorData); - return PL_DHASH_NEXT; -} - -void -nsPropertyTable::PropertyList::Destroy() -{ - // Enumerate any remaining frame/value pairs and destroy the value object - if (mDtorFunc) - PL_DHashTableEnumerate(&mObjectValueMap, DestroyPropertyEnumerator, - nsnull); -} - -PRBool -nsPropertyTable::PropertyList::DeletePropertyFor(const void* aObject) -{ - PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*, - PL_DHashTableOperate(&mObjectValueMap, aObject, PL_DHASH_LOOKUP)); - if (!PL_DHASH_ENTRY_IS_BUSY(entry)) - return PR_FALSE; - - if (mDtorFunc) - mDtorFunc(NS_CONST_CAST(void*, aObject), mName, - entry->value, mDtorData); - - PL_DHashTableRawRemove(&mObjectValueMap, entry); - - return PR_TRUE; -} diff --git a/mozilla/content/base/src/nsPropertyTable.h b/mozilla/content/base/src/nsPropertyTable.h deleted file mode 100644 index 96e4d1b1178..00000000000 --- a/mozilla/content/base/src/nsPropertyTable.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim:cindent:ts=2:et:sw=2: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** - * - * This Original Code has been modified by IBM Corporation. Modifications made by IBM - * described herein are Copyright (c) International Business Machines Corporation, 2000. - * Modifications to Mozilla code or documentation identified per MPL Section 3.3 - * - * Date Modified by Description of modification - * 04/20/2000 IBM Corp. OS/2 VisualAge build. - */ - -/** - * nsPropertyTable allows a set of arbitrary key/value pairs to be stored - * for any number of nodes, in a global hashtable rather than on the nodes - * themselves. Nodes can be any type of object; the hashtable keys are - * nsIAtom pointers, and the values are void pointers. - */ - -#ifndef nsPropertyTable_h_ -#define nsPropertyTable_h_ - -#include "nscore.h" - -class nsIAtom; - -/** - * Callback type for property destructors. |aObject| is the object - * the property is being removed for, |aPropertyName| is the property - * being removed, |aPropertyValue| is the value of the property, and |aData| - * is the opaque destructor data that was passed to SetProperty(). - **/ -typedef void -(*NSPropertyDtorFunc)(void *aObject, - nsIAtom *aPropertyName, - void *aPropertyValue, - void *aData); - -class nsPropertyTable -{ - public: - /** - * Get the value of the property |aPropertyName| for node |aObject|. - * |aResult|, if supplied, is filled in with a return status code. - **/ - void* GetProperty(const void *aObject, - nsIAtom *aPropertyName, - nsresult *aResult = nsnull) - { return GetPropertyInternal(aObject, aPropertyName, PR_FALSE, aResult); } - - /** - * 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 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). - **/ - NS_HIDDEN_(nsresult) SetProperty(const void *aObject, - nsIAtom *aPropertyName, - void *aPropertyValue, - NSPropertyDtorFunc aDtor, - void *aDtorData); - - /** - * Delete the property |aPropertyName| for object |aObject|. - * The property's destructor function will be called. - **/ - NS_HIDDEN_(nsresult) DeleteProperty(const void *aObject, - nsIAtom *aPropertyName); - - /** - * Unset the property |aPropertyName| for object |aObject|, but do not - * call the property's destructor function. The property value is returned. - **/ - void* UnsetProperty(const void *aObject, - nsIAtom *aPropertyName, - nsresult *aStatus = nsnull) - { return GetPropertyInternal(aObject, aPropertyName, PR_TRUE, aStatus); } - - /** - * Deletes all of the properties for object |aObject|, calling the - * destructor function for each property. - **/ - NS_HIDDEN_(void) DeleteAllPropertiesFor(const void *aObject); - - ~nsPropertyTable() NS_HIDDEN; - - struct PropertyList; - - private: - NS_HIDDEN_(void) DestroyPropertyList(); - NS_HIDDEN_(PropertyList*) GetPropertyListFor(nsIAtom *aPropertyName) const; - NS_HIDDEN_(void*) GetPropertyInternal(const void *aObject, - nsIAtom *aPropertyName, - PRBool aRemove, - nsresult *aStatus); - - PropertyList *mPropertyList; -}; -#endif diff --git a/mozilla/content/events/src/nsDOMUIEvent.h b/mozilla/content/events/src/nsDOMUIEvent.h index 05f83c2cb87..e2b4a167081 100644 --- a/mozilla/content/events/src/nsDOMUIEvent.h +++ b/mozilla/content/events/src/nsDOMUIEvent.h @@ -45,7 +45,6 @@ #include "nsIDOMAbstractView.h" #include "nsIPrivateCompositionEvent.h" #include "nsDOMEvent.h" -#include "nsIDOMAbstractView.h" class nsDOMUIEvent : public nsIDOMUIEvent, public nsIDOMNSUIEvent, diff --git a/mozilla/content/shared/public/Makefile.in b/mozilla/content/shared/public/Makefile.in index 892f1d66d52..ee3c2c0bfd6 100644 --- a/mozilla/content/shared/public/Makefile.in +++ b/mozilla/content/shared/public/Makefile.in @@ -68,7 +68,6 @@ nsHTMLValue.h \ nsImageMapUtils.h \ nsLayoutAtomList.h \ nsLayoutAtoms.h \ -nsPropertyTable.h \ nsRuleNode.h \ nsRuleWalker.h \ nsStyleContext.h \ diff --git a/mozilla/content/shared/public/nsFrameManager.h b/mozilla/content/shared/public/nsFrameManager.h index 4901804b884..20706d74976 100644 --- a/mozilla/content/shared/public/nsFrameManager.h +++ b/mozilla/content/shared/public/nsFrameManager.h @@ -55,6 +55,9 @@ #include "nsChangeHint.h" #include "nsFrameManagerBase.h" +// Option flags for GetFrameProperty() member function +#define NS_IFRAME_MGR_REMOVE_PROP 0x0001 + /** * Frame manager interface. The frame manager serves two purposes: *
  • provides a service for mapping from content to frame and from @@ -219,6 +222,68 @@ public: nsIStatefulFrame::SpecialStateID aID = nsIStatefulFrame::eNoID); + /** + * Gets a property value for a given frame. + * + * @param aFrame the frame with the property + * @param aPropertyName property name as an atom + * @param aOptions optional flags + * NS_IFRAME_MGR_REMOVE_PROP removes the property + * @param aResult NS_OK if the property is set, + * NS_IFRAME_MGR_PROP_NOT_THERE is it is not set + * @param aPropertyValue the property value or 0 if the + property is not set + * @return The property value or 0 if the property is not set + */ + + NS_HIDDEN_(void*) GetFrameProperty(const nsIFrame* aFrame, + nsIAtom* aPropertyName, + PRUint32 aOptions, + nsresult* aResult = nsnull); + + /** + * Sets the property value for a given frame. + * + * A frame may only have one property value at a time for a given property + * name. The existing property value (if there is one) is overwritten, and + * the old value destroyed + * + * @param aFrame the frame to set the property on + * @param aPropertyName property name as an atom + * @param aPropertyValue the property value + * @param aPropertyDtorFunc when setting a property you can specify the + * dtor function (can be NULL) that will be used + * to destroy the property value. There can be + * only one dtor function for a given property + * name + * @return NS_OK if successful, + * NS_IFRAME_MGR_PROP_OVERWRITTEN if there is an existing property + * value that was overwritten, + * NS_ERROR_INVALID_ARG if the dtor function does not match the + * existing dtor function + */ + + NS_HIDDEN_(nsresult) SetFrameProperty(const nsIFrame* aFrame, + nsIAtom* aPropertyName, + void* aPropertyValue, + NSFramePropertyDtorFunc aPropDtorFunc); + + /** + * Removes a property and destroys its property value by calling the dtor + * function associated with the property name. + * + * When a frame is destroyed any remaining properties are automatically + * removed. + * + * @param aFrame the frame to set the property on + * @param aPropertyName property name as an atom + * @return NS_OK if the property is successfully removed, + * NS_IFRAME_MGR_PROP_NOT_THERE if the property is not set + */ + + NS_HIDDEN_(nsresult) RemoveFrameProperty(const nsIFrame* aFrame, + nsIAtom* aPropertyName); + #ifdef NS_DEBUG /** * DEBUG ONLY method to verify integrity of style tree versus frame tree @@ -247,6 +312,10 @@ private: FindPostedEventFor(nsIFrame* aFrame); NS_HIDDEN_(void) DequeuePostedEventFor(nsIFrame* aFrame); + NS_HIDDEN_(void) DestroyPropertyList(nsPresContext* aPresContext); + NS_HIDDEN_(PropertyList*) GetPropertyListFor(nsIAtom* aPropertyName) const; + NS_HIDDEN_(void) RemoveAllPropertiesFor(nsPresContext *aPresContext, + nsIFrame *aFrame); static NS_HIDDEN_(void) HandlePLEvent(CantRenderReplacedElementEvent* aEvent); diff --git a/mozilla/content/shared/public/nsFrameManagerBase.h b/mozilla/content/shared/public/nsFrameManagerBase.h index 834ac770f4c..eccba380a6f 100644 --- a/mozilla/content/shared/public/nsFrameManagerBase.h +++ b/mozilla/content/shared/public/nsFrameManagerBase.h @@ -67,6 +67,9 @@ struct CantRenderReplacedElementEvent; class nsFrameManagerBase { +public: + struct PropertyList; + protected: class UndisplayedMap; @@ -79,6 +82,7 @@ protected: PLDHashTable mPlaceholderMap; UndisplayedMap* mUndisplayedMap; CantRenderReplacedElementEvent* mPostedEvents; + PropertyList* mPropertyList; PRBool mIsDestroyingFrames; }; diff --git a/mozilla/content/shared/public/nsPropertyTable.h b/mozilla/content/shared/public/nsPropertyTable.h deleted file mode 100644 index 96e4d1b1178..00000000000 --- a/mozilla/content/shared/public/nsPropertyTable.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim:cindent:ts=2:et:sw=2: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** - * - * This Original Code has been modified by IBM Corporation. Modifications made by IBM - * described herein are Copyright (c) International Business Machines Corporation, 2000. - * Modifications to Mozilla code or documentation identified per MPL Section 3.3 - * - * Date Modified by Description of modification - * 04/20/2000 IBM Corp. OS/2 VisualAge build. - */ - -/** - * nsPropertyTable allows a set of arbitrary key/value pairs to be stored - * for any number of nodes, in a global hashtable rather than on the nodes - * themselves. Nodes can be any type of object; the hashtable keys are - * nsIAtom pointers, and the values are void pointers. - */ - -#ifndef nsPropertyTable_h_ -#define nsPropertyTable_h_ - -#include "nscore.h" - -class nsIAtom; - -/** - * Callback type for property destructors. |aObject| is the object - * the property is being removed for, |aPropertyName| is the property - * being removed, |aPropertyValue| is the value of the property, and |aData| - * is the opaque destructor data that was passed to SetProperty(). - **/ -typedef void -(*NSPropertyDtorFunc)(void *aObject, - nsIAtom *aPropertyName, - void *aPropertyValue, - void *aData); - -class nsPropertyTable -{ - public: - /** - * Get the value of the property |aPropertyName| for node |aObject|. - * |aResult|, if supplied, is filled in with a return status code. - **/ - void* GetProperty(const void *aObject, - nsIAtom *aPropertyName, - nsresult *aResult = nsnull) - { return GetPropertyInternal(aObject, aPropertyName, PR_FALSE, aResult); } - - /** - * 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 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). - **/ - NS_HIDDEN_(nsresult) SetProperty(const void *aObject, - nsIAtom *aPropertyName, - void *aPropertyValue, - NSPropertyDtorFunc aDtor, - void *aDtorData); - - /** - * Delete the property |aPropertyName| for object |aObject|. - * The property's destructor function will be called. - **/ - NS_HIDDEN_(nsresult) DeleteProperty(const void *aObject, - nsIAtom *aPropertyName); - - /** - * Unset the property |aPropertyName| for object |aObject|, but do not - * call the property's destructor function. The property value is returned. - **/ - void* UnsetProperty(const void *aObject, - nsIAtom *aPropertyName, - nsresult *aStatus = nsnull) - { return GetPropertyInternal(aObject, aPropertyName, PR_TRUE, aStatus); } - - /** - * Deletes all of the properties for object |aObject|, calling the - * destructor function for each property. - **/ - NS_HIDDEN_(void) DeleteAllPropertiesFor(const void *aObject); - - ~nsPropertyTable() NS_HIDDEN; - - struct PropertyList; - - private: - NS_HIDDEN_(void) DestroyPropertyList(); - NS_HIDDEN_(PropertyList*) GetPropertyListFor(nsIAtom *aPropertyName) const; - NS_HIDDEN_(void*) GetPropertyInternal(const void *aObject, - nsIAtom *aPropertyName, - PRBool aRemove, - nsresult *aStatus); - - PropertyList *mPropertyList; -}; -#endif diff --git a/mozilla/content/shared/src/Makefile.in b/mozilla/content/shared/src/Makefile.in index a86a5cae45e..0525ea11326 100644 --- a/mozilla/content/shared/src/Makefile.in +++ b/mozilla/content/shared/src/Makefile.in @@ -73,7 +73,6 @@ CPPSRCS = \ nsStyleCoord.cpp \ nsStyleStruct.cpp \ nsBidiUtils.cpp \ - nsPropertyTable.cpp \ $(NULL) ifdef MOZ_SVG diff --git a/mozilla/content/shared/src/nsPropertyTable.cpp b/mozilla/content/shared/src/nsPropertyTable.cpp deleted file mode 100644 index b0b18f6e16f..00000000000 --- a/mozilla/content/shared/src/nsPropertyTable.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim:cindent:ts=2:et:sw=2: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** - * - * This Original Code has been modified by IBM Corporation. Modifications made by IBM - * described herein are Copyright (c) International Business Machines Corporation, 2000. - * Modifications to Mozilla code or documentation identified per MPL Section 3.3 - * - * Date Modified by Description of modification - * 04/20/2000 IBM Corp. OS/2 VisualAge build. - */ - -#include "nsPropertyTable.h" -#include "pldhash.h" -#include "nsContentErrors.h" -#include "nsIAtom.h" - -struct PropertyListMapEntry : public PLDHashEntryHdr { - const void *key; - void *value; -}; - -//---------------------------------------------------------------------- - -struct nsPropertyTable::PropertyList { - nsCOMPtr mName; // property name - PLDHashTable mObjectValueMap; // map of object/value pairs - NSPropertyDtorFunc mDtorFunc; // property specific value dtor function - void* mDtorData; - PropertyList* mNext; - - PropertyList(nsIAtom* aName, - NSPropertyDtorFunc aDtorFunc) NS_HIDDEN; - ~PropertyList() NS_HIDDEN; - - // Removes the property associated with the given object, and destroys - // the property value - NS_HIDDEN_(PRBool) DeletePropertyFor(const void * aObject); - - // Destroy all remaining properties (without removing them) - NS_HIDDEN_(void) Destroy(); -}; - -nsPropertyTable::~nsPropertyTable() -{ - if (mPropertyList) { - while (mPropertyList) { - PropertyList* tmp = mPropertyList; - - mPropertyList = mPropertyList->mNext; - tmp->Destroy(); - delete tmp; - } - } -} - -void -nsPropertyTable::DeleteAllPropertiesFor(const void *aObject) -{ - for (PropertyList* prop = mPropertyList; prop; prop = prop->mNext) { - prop->DeletePropertyFor(aObject); - } -} - -void* -nsPropertyTable::GetPropertyInternal(const void *aObject, - nsIAtom *aPropertyName, - PRBool aRemove, - nsresult *aResult) -{ - NS_PRECONDITION(aPropertyName && aObject, "unexpected null param"); - nsresult rv = NS_PROPTABLE_PROP_NOT_THERE; - void *propValue = nsnull; - - PropertyList* propertyList = GetPropertyListFor(aPropertyName); - if (propertyList) { - PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*, - PL_DHashTableOperate(&propertyList->mObjectValueMap, aObject, - PL_DHASH_LOOKUP)); - if (PL_DHASH_ENTRY_IS_BUSY(entry)) { - propValue = entry->value; - if (aRemove) { - // don't call propertyList->mDtorFunc. That's the caller's job now. - PL_DHashTableRawRemove(&propertyList->mObjectValueMap, entry); - } - rv = NS_OK; - } - } - - if (aResult) - *aResult = rv; - - return propValue; -} - -nsresult -nsPropertyTable::SetProperty(const void *aObject, - nsIAtom *aPropertyName, - void *aPropertyValue, - NSPropertyDtorFunc aPropDtorFunc, - void *aPropDtorData) -{ - NS_PRECONDITION(aPropertyName && aObject, "unexpected null param"); - - PropertyList* propertyList = GetPropertyListFor(aPropertyName); - - if (propertyList) { - // Make sure the dtor function matches - if (aPropDtorFunc != propertyList->mDtorFunc) { - return NS_ERROR_INVALID_ARG; - } - - } else { - propertyList = new PropertyList(aPropertyName, aPropDtorFunc); - if (!propertyList) - return NS_ERROR_OUT_OF_MEMORY; - if (!propertyList->mObjectValueMap.ops) { - delete propertyList; - return NS_ERROR_OUT_OF_MEMORY; - } - - propertyList->mNext = mPropertyList; - mPropertyList = propertyList; - } - - // The current property value (if there is one) is replaced and the current - // value is destroyed - nsresult result = NS_OK; - PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*, - PL_DHashTableOperate(&propertyList->mObjectValueMap, aObject, PL_DHASH_ADD)); - if (!entry) - return NS_ERROR_OUT_OF_MEMORY; - // A NULL entry->key is the sign that the entry has just been allocated - // for us. If it's non-NULL then we have an existing entry. - if (entry->key && propertyList->mDtorFunc) { - propertyList->mDtorFunc(NS_CONST_CAST(void*, entry->key), aPropertyName, - entry->value, propertyList->mDtorData); - result = NS_PROPTABLE_PROP_OVERWRITTEN; - } - entry->key = aObject; - entry->value = aPropertyValue; - - return result; -} - -nsresult -nsPropertyTable::DeleteProperty(const void *aObject, - nsIAtom *aPropertyName) -{ - NS_PRECONDITION(aPropertyName && aObject, "unexpected null param"); - - PropertyList* propertyList = GetPropertyListFor(aPropertyName); - if (propertyList) { - if (propertyList->DeletePropertyFor(aObject)) - return NS_OK; - } - - return NS_PROPTABLE_PROP_NOT_THERE; -} - -nsPropertyTable::PropertyList* -nsPropertyTable::GetPropertyListFor(nsIAtom* aPropertyName) const -{ - PropertyList* result; - - for (result = mPropertyList; result; result = result->mNext) { - if (result->mName.get() == aPropertyName) { - break; - } - } - - return result; -} - -//---------------------------------------------------------------------- - -nsPropertyTable::PropertyList::PropertyList(nsIAtom *aName, - NSPropertyDtorFunc aDtorFunc) - : mName(aName), mDtorFunc(aDtorFunc), mDtorData(nsnull), mNext(nsnull) -{ - PL_DHashTableInit(&mObjectValueMap, PL_DHashGetStubOps(), this, - sizeof(PropertyListMapEntry), 16); -} - -nsPropertyTable::PropertyList::~PropertyList() -{ - PL_DHashTableFinish(&mObjectValueMap); -} - - -PR_STATIC_CALLBACK(PLDHashOperator) -DestroyPropertyEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr, - PRUint32 number, void *arg) -{ - nsPropertyTable::PropertyList *propList = - NS_STATIC_CAST(nsPropertyTable::PropertyList*, table->data); - PropertyListMapEntry* entry = NS_STATIC_CAST(PropertyListMapEntry*, hdr); - - propList->mDtorFunc(NS_CONST_CAST(void*, entry->key), propList->mName, - entry->value, propList->mDtorData); - return PL_DHASH_NEXT; -} - -void -nsPropertyTable::PropertyList::Destroy() -{ - // Enumerate any remaining frame/value pairs and destroy the value object - if (mDtorFunc) - PL_DHashTableEnumerate(&mObjectValueMap, DestroyPropertyEnumerator, - nsnull); -} - -PRBool -nsPropertyTable::PropertyList::DeletePropertyFor(const void* aObject) -{ - PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*, - PL_DHashTableOperate(&mObjectValueMap, aObject, PL_DHASH_LOOKUP)); - if (!PL_DHASH_ENTRY_IS_BUSY(entry)) - return PR_FALSE; - - if (mDtorFunc) - mDtorFunc(NS_CONST_CAST(void*, aObject), mName, - entry->value, mDtorData); - - PL_DHashTableRawRemove(&mObjectValueMap, entry); - - return PR_TRUE; -} diff --git a/mozilla/content/xul/content/src/nsXULElement.cpp b/mozilla/content/xul/content/src/nsXULElement.cpp index 7a88ade5dbf..b28112c0f2c 100644 --- a/mozilla/content/xul/content/src/nsXULElement.cpp +++ b/mozilla/content/xul/content/src/nsXULElement.cpp @@ -1616,10 +1616,6 @@ nsXULElement::SetDocument(nsIDocument* aDocument, PRBool aDeep, nsCOMPtr nsDoc(do_QueryInterface(mDocument)); nsDoc->SetBoxObjectFor(this, nsnull); - - if (mSlots && mSlots->mHasProperties) { - mDocument->PropertyTable()->DeleteAllPropertiesFor(this); - } } // mControllers can own objects that are implemented @@ -2932,55 +2928,6 @@ nsXULElement::GetRangeList() const } -void* -nsXULElement::GetProperty(nsIAtom *aPropertyName, nsresult *aStatus) const -{ - nsIDocument *doc = GetDocument(); - if (!doc) - return nsnull; - - return doc->PropertyTable()->GetProperty(this, aPropertyName, aStatus); -} - -nsresult -nsXULElement::SetProperty(nsIAtom *aPropertyName, - void *aValue, - NSPropertyDtorFunc aDtor) -{ - nsIDocument *doc = GetDocument(); - if (!doc) - return NS_ERROR_FAILURE; - - nsresult rv = doc->PropertyTable()->SetProperty(this, aPropertyName, - aValue, aDtor, nsnull); - if (NS_SUCCEEDED(rv)) { - EnsureSlots(); - mSlots->mHasProperties = PR_TRUE; - } - - return rv; -} - -nsresult -nsXULElement::DeleteProperty(nsIAtom *aPropertyName) -{ - nsIDocument *doc = GetDocument(); - if (!doc) - return nsnull; - - return doc->PropertyTable()->DeleteProperty(this, aPropertyName); -} - -void* -nsXULElement::UnsetProperty(nsIAtom *aPropertyName, nsresult *aStatus) -{ - nsIDocument *doc = GetDocument(); - if (!doc) - return nsnull; - - return doc->PropertyTable()->UnsetProperty(this, aPropertyName, aStatus); -} - // XXX This _should_ be an implementation method, _not_ publicly exposed :-( NS_IMETHODIMP nsXULElement::GetResource(nsIRDFResource** aResource) @@ -4097,8 +4044,8 @@ nsXULElement::HideWindowChrome(PRBool aShouldHide) // nsXULElement::Slots::Slots() + : mLazyState(0) { - mLazyState = mHasProperties = 0; MOZ_COUNT_CTOR(nsXULElement::Slots); } diff --git a/mozilla/content/xul/content/src/nsXULElement.h b/mozilla/content/xul/content/src/nsXULElement.h index 71931fd97fa..430644d37c8 100644 --- a/mozilla/content/xul/content/src/nsXULElement.h +++ b/mozilla/content/xul/content/src/nsXULElement.h @@ -506,14 +506,6 @@ public: virtual already_AddRefed GetBaseURI() const; virtual nsresult GetListenerManager(nsIEventListenerManager** aResult); virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull); - virtual void* GetProperty(nsIAtom *aPropertyName, - nsresult *aStatus = nsnull) const; - virtual nsresult SetProperty(nsIAtom *aPropertyName, - void *aValue, - NSPropertyDtorFunc aDtor); - virtual nsresult DeleteProperty(nsIAtom *aPropertyName); - virtual void* UnsetProperty(nsIAtom *aPropertyName, - nsresult *aStatus = nsnull); // nsIXMLContent NS_IMETHOD MaybeTriggerAutoLink(nsIDocShell *aShell); @@ -615,8 +607,7 @@ protected: nsRefPtr mDOMStyle; // [OWNER] nsRefPtr mAttributeMap; // [OWNER] nsRefPtr mChildNodes; // [OWNER] - unsigned mLazyState : 3; - unsigned mHasProperties : 1; + PRUint32 mLazyState; }; friend struct Slots; diff --git a/mozilla/layout/base/nsBidiPresUtils.cpp b/mozilla/layout/base/nsBidiPresUtils.cpp index 23078de301a..2273d9e4144 100644 --- a/mozilla/layout/base/nsBidiPresUtils.cpp +++ b/mozilla/layout/base/nsBidiPresUtils.cpp @@ -787,21 +787,22 @@ nsBidiPresUtils::RemoveBidiContinuation(nsPresContext* aPresContext, nsIFrame* thisFramesNextBidiFrame; nsIFrame* previousFramesNextBidiFrame; - thisFramesNextBidiFrame = - NS_STATIC_CAST(nsIFrame*, aFrame->GetProperty(nsLayoutAtoms::nextBidi)); + nsFrameManager* frameManager = presShell->FrameManager(); + thisFramesNextBidiFrame = NS_STATIC_CAST(nsIFrame*, + frameManager->GetFrameProperty(aFrame, nsLayoutAtoms::nextBidi, 0)); if (thisFramesNextBidiFrame) { // Remove nextBidi property, associated with the current frame // and with all of its prev-in-flow. frame = aFrame; do { - frame->DeleteProperty(nsLayoutAtoms::nextBidi); + frameManager->RemoveFrameProperty(frame, nsLayoutAtoms::nextBidi); frame->GetPrevInFlow(&frame); if (!frame) { break; } - previousFramesNextBidiFrame = - NS_STATIC_CAST(nsIFrame*, frame->GetProperty(nsLayoutAtoms::nextBidi)); + previousFramesNextBidiFrame = NS_STATIC_CAST(nsIFrame*, + frameManager->GetFrameProperty(frame, nsLayoutAtoms::nextBidi, 0)); } while (thisFramesNextBidiFrame == previousFramesNextBidiFrame); } // if (thisFramesNextBidiFrame) } diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index 9ac64f7a448..67d95f253b0 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -384,7 +384,9 @@ GetSpecialSibling(nsFrameManager* aFrameManager, nsIFrame* aFrame, nsIFrame** aR // frame in the flow. Walk back to find that frame now. aFrame = aFrame->GetFirstInFlow(); - void* value = aFrame->GetProperty(nsLayoutAtoms::IBSplitSpecialSibling); + void* value = + aFrameManager->GetFrameProperty(aFrame, + nsLayoutAtoms::IBSplitSpecialSibling, 0); *aResult = NS_STATIC_CAST(nsIFrame*, value); } @@ -436,8 +438,9 @@ SetFrameIsSpecial(nsFrameManager* aFrameManager, nsIFrame* aFrame, nsIFrame* aSp // Store the "special sibling" (if we were given one) with the // first frame in the flow. - aFrame->SetProperty(nsLayoutAtoms::IBSplitSpecialSibling, - aSpecialSibling, nsnull); + aFrameManager->SetFrameProperty(aFrame, + nsLayoutAtoms::IBSplitSpecialSibling, + aSpecialSibling, nsnull); } } @@ -568,8 +571,10 @@ MarkIBSpecialPrevSibling(nsPresContext* aPresContext, nsIFrame *aAnonymousFrame, nsIFrame *aSpecialParent) { - aAnonymousFrame->SetProperty(nsLayoutAtoms::IBSplitSpecialPrevSibling, - aSpecialParent, nsnull); + aFrameManager->SetFrameProperty(aAnonymousFrame, + nsLayoutAtoms::IBSplitSpecialPrevSibling, + aSpecialParent, + nsnull); } // ----------------------------------------------------------- @@ -4744,9 +4749,9 @@ nsCSSFrameConstructor::ConstructHTMLFrame(nsIPresShell* aPresShell, // there is no reasonable way to get the value there. // so we store it as a frame property. nsCOMPtr contentParentAtom = do_GetAtom("contentParent"); - aPresContext->PropertyTable()->SetProperty(newFrame, contentParentAtom, - aParentFrame, nsnull, - nsnull); + aState.mFrameManager->SetFrameProperty(newFrame, + contentParentAtom, + aParentFrame, nsnull); } } } @@ -9821,6 +9826,8 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList, if (!count) return NS_OK; + nsFrameManager *frameManager = aPresContext->FrameManager(); + // Mark frames so that we skip frames that die along the way, bug 123049. // A frame can be in the list multiple times with different hints. Further // optmization is possible if nsStyleChangeList::AppendChange could coalesce @@ -9829,8 +9836,8 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList, const nsStyleChangeData* changeData; aChangeList.ChangeAt(index, &changeData); if (changeData->mFrame) { - changeData->mFrame->SetProperty(nsLayoutAtoms::changeListProperty, - nsnull, nsnull); + frameManager->SetFrameProperty(changeData->mFrame, + nsLayoutAtoms::changeListProperty, nsnull, nsnull); } } @@ -9845,9 +9852,12 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList, if (frame) { nsresult res; - void* dummy = frame->GetProperty(nsLayoutAtoms::changeListProperty, &res); + void* dummy = + frameManager->GetFrameProperty(frame, + nsLayoutAtoms::changeListProperty, 0, + &res); - if (NS_PROPTABLE_PROP_NOT_THERE == res) + if (NS_IFRAME_MGR_PROP_NOT_THERE == res) continue; } @@ -9883,7 +9893,8 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList, const nsStyleChangeData* changeData; aChangeList.ChangeAt(index, &changeData); if (changeData->mFrame) { - changeData->mFrame->DeleteProperty(nsLayoutAtoms::changeListProperty); + frameManager->RemoveFrameProperty(changeData->mFrame, + nsLayoutAtoms::changeListProperty); } } diff --git a/mozilla/layout/base/nsFrameManager.cpp b/mozilla/layout/base/nsFrameManager.cpp index 0f5cad39c71..d565eedf6ad 100644 --- a/mozilla/layout/base/nsFrameManager.cpp +++ b/mozilla/layout/base/nsFrameManager.cpp @@ -154,6 +154,13 @@ static PLDHashTableOps PlaceholderMapOps = { //---------------------------------------------------------------------- +struct PropertyListMapEntry : public PLDHashEntryHdr { + const nsIFrame *key; + void *value; +}; + +//---------------------------------------------------------------------- + struct PrimaryFrameMapEntry : public PLDHashEntryHdr { // key (the content node) can almost always be obtained through the // frame. If it weren't for the way image maps (mis)used the primary @@ -270,6 +277,26 @@ struct CantRenderReplacedElementEvent : public PLEvent { nsWeakPtr mPresShell; // for removing load group request later }; +struct nsFrameManagerBase::PropertyList { + nsCOMPtr mName; // property name + PLDHashTable mFrameValueMap; // map of frame/value pairs + NSFramePropertyDtorFunc mDtorFunc; // property specific value dtor function + PropertyList* mNext; + + PropertyList(nsIAtom* aName, + NSFramePropertyDtorFunc aDtorFunc) NS_HIDDEN; + ~PropertyList() NS_HIDDEN; + + // Removes the property associated with the given frame, and destroys + // the property value + NS_HIDDEN_(PRBool) RemovePropertyForFrame(nsPresContext* aPresContext, + const nsIFrame* aFrame); + + // Destroy all remaining properties (without removing them) + NS_HIDDEN_(void) Destroy(nsPresContext* aPresContext); +}; + + //---------------------------------------------------------------------- nsFrameManager::nsFrameManager() @@ -307,7 +334,9 @@ nsFrameManager::Destroy() nsPresContext *presContext = mPresShell->GetPresContext(); - // Destroy the frame hierarchy. + // Destroy the frame hierarchy. Don't destroy the property lists until after + // we've destroyed the frame hierarchy because some frames may expect to be + // able to retrieve their properties during destruction mPresShell->SetIgnoreFrameDestruction(PR_TRUE); mIsDestroyingFrames = PR_TRUE; // This flag prevents GetPrimaryFrameFor from returning pointers to destroyed frames @@ -326,6 +355,7 @@ nsFrameManager::Destroy() mPlaceholderMap.ops = nsnull; } delete mUndisplayedMap; + DestroyPropertyList(presContext); // If we're not going to be used anymore, we should revoke the // pending |CantRenderReplacedElementEvent|s being sent to us. @@ -705,8 +735,10 @@ nsFrameManager::InsertFrames(nsIFrame* aParentFrame, // Insert aFrameList after the last bidi continuation of aPrevFrame. nsIFrame* nextBidi; for (; ;) { - nextBidi = NS_STATIC_CAST(nsIFrame*, - aPrevFrame->GetProperty(nsLayoutAtoms::nextBidi)); + nextBidi = + NS_STATIC_CAST(nsIFrame*, GetFrameProperty(aPrevFrame, + nsLayoutAtoms::nextBidi, + 0)); if (!nextBidi) { break; } @@ -727,7 +759,8 @@ nsFrameManager::RemoveFrame(nsIFrame* aParentFrame, #ifdef IBMBIDI // Don't let the parent remove next bidi. In the other cases the it should NOT be removed. nsIFrame* nextBidi = - NS_STATIC_CAST(nsIFrame*, aOldFrame->GetProperty(nsLayoutAtoms::nextBidi)); + NS_STATIC_CAST(nsIFrame*, GetFrameProperty(aOldFrame, + nsLayoutAtoms::nextBidi, 0)); if (nextBidi) { RemoveFrame(aParentFrame, aListName, nextBidi); } @@ -745,6 +778,10 @@ nsFrameManager::NotifyDestroyingFrame(nsIFrame* aFrame) // Dequeue and destroy and posted events for this frame DequeuePostedEventFor(aFrame); + // Remove all properties associated with the frame + nsPresContext *presContext = mPresShell->GetPresContext(); + RemoveAllPropertiesFor(presContext, aFrame); + #ifdef DEBUG if (mPrimaryFrameMap.ops) { PrimaryFrameMapEntry *entry = NS_STATIC_CAST(PrimaryFrameMapEntry*, @@ -1662,8 +1699,8 @@ nsFrameManager::ComputeStyleChangeFor(nsIFrame *aFrame, return topLevelChange; } - frame2 = NS_STATIC_CAST(nsIFrame*, - frame2->GetProperty(nsLayoutAtoms::IBSplitSpecialSibling)); + frame2 = NS_STATIC_CAST(nsIFrame*, GetFrameProperty(frame2, + nsLayoutAtoms::IBSplitSpecialSibling, 0)); frame = frame2; } while (frame2); return topLevelChange; @@ -1839,6 +1876,140 @@ CompareKeys(void* key1, void* key2) return key1 == key2; } +void +nsFrameManager::DestroyPropertyList(nsPresContext* aPresContext) +{ + if (mPropertyList) { + while (mPropertyList) { + PropertyList* tmp = mPropertyList; + + mPropertyList = mPropertyList->mNext; + tmp->Destroy(aPresContext); + delete tmp; + } + } +} + +nsFrameManagerBase::PropertyList* +nsFrameManager::GetPropertyListFor(nsIAtom* aPropertyName) const +{ + PropertyList* result; + + for (result = mPropertyList; result; result = result->mNext) { + if (result->mName.get() == aPropertyName) { + break; + } + } + + return result; +} + +void +nsFrameManager::RemoveAllPropertiesFor(nsPresContext* aPresContext, + nsIFrame* aFrame) +{ + for (PropertyList* prop = mPropertyList; prop; prop = prop->mNext) { + prop->RemovePropertyForFrame(aPresContext, aFrame); + } +} + +void* +nsFrameManager::GetFrameProperty(const nsIFrame* aFrame, + nsIAtom* aPropertyName, + PRUint32 aOptions, + nsresult* aResult) +{ + NS_PRECONDITION(aPropertyName && aFrame, "unexpected null param"); + nsresult rv = NS_IFRAME_MGR_PROP_NOT_THERE; + void *propValue = nsnull; + + PropertyList* propertyList = GetPropertyListFor(aPropertyName); + if (propertyList) { + PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*, + PL_DHashTableOperate(&propertyList->mFrameValueMap, aFrame, + PL_DHASH_LOOKUP)); + if (PL_DHASH_ENTRY_IS_BUSY(entry)) { + propValue = entry->value; + if (aOptions & NS_IFRAME_MGR_REMOVE_PROP) { + // don't call propertyList->mDtorFunc. That's the caller's job now. + PL_DHashTableRawRemove(&propertyList->mFrameValueMap, entry); + } + rv = NS_OK; + } + } + + if (aResult) + *aResult = rv; + + return propValue; +} + +nsresult +nsFrameManager::SetFrameProperty(const nsIFrame* aFrame, + nsIAtom* aPropertyName, + void* aPropertyValue, + NSFramePropertyDtorFunc aPropDtorFunc) +{ + NS_PRECONDITION(aPropertyName && aFrame, "unexpected null param"); + + PropertyList* propertyList = GetPropertyListFor(aPropertyName); + + if (propertyList) { + // Make sure the dtor function matches + if (aPropDtorFunc != propertyList->mDtorFunc) { + return NS_ERROR_INVALID_ARG; + } + + } else { + propertyList = new PropertyList(aPropertyName, aPropDtorFunc); + if (!propertyList) + return NS_ERROR_OUT_OF_MEMORY; + if (!propertyList->mFrameValueMap.ops) { + delete propertyList; + return NS_ERROR_OUT_OF_MEMORY; + } + + propertyList->mNext = mPropertyList; + mPropertyList = propertyList; + } + + // The current property value (if there is one) is replaced and the current + // value is destroyed + nsresult result = NS_OK; + PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*, + PL_DHashTableOperate(&propertyList->mFrameValueMap, aFrame, PL_DHASH_ADD)); + if (!entry) + return NS_ERROR_OUT_OF_MEMORY; + // A NULL entry->key is the sign that the entry has just been allocated + // for us. If it's non-NULL then we have an existing entry. + if (entry->key && propertyList->mDtorFunc) { + propertyList->mDtorFunc(mPresShell->GetPresContext(), + NS_CONST_CAST(nsIFrame*, entry->key), + aPropertyName, entry->value); + result = NS_IFRAME_MGR_PROP_OVERWRITTEN; + } + entry->key = aFrame; + entry->value = aPropertyValue; + + return result; +} + +nsresult +nsFrameManager::RemoveFrameProperty(const nsIFrame* aFrame, + nsIAtom* aPropertyName) +{ + NS_PRECONDITION(aPropertyName && aFrame, "unexpected null param"); + + PropertyList* propertyList = GetPropertyListFor(aPropertyName); + if (propertyList) { + if (propertyList->RemovePropertyForFrame(mPresShell->GetPresContext(), + aFrame)) + return NS_OK; + } + + return NS_IFRAME_MGR_PROP_NOT_THERE; +} + //---------------------------------------------------------------------- MOZ_DECL_CTOR_COUNTER(UndisplayedMap) @@ -1986,3 +2157,59 @@ nsFrameManagerBase::UndisplayedMap::Clear(void) mLastLookup = nsnull; PL_HashTableEnumerateEntries(mTable, RemoveUndisplayedEntry, 0); } + +//---------------------------------------------------------------------- + +nsFrameManagerBase::PropertyList::PropertyList(nsIAtom* aName, + NSFramePropertyDtorFunc aDtorFunc) + : mName(aName), mDtorFunc(aDtorFunc), mNext(nsnull) +{ + PL_DHashTableInit(&mFrameValueMap, PL_DHashGetStubOps(), this, + sizeof(PropertyListMapEntry), 16); +} + +nsFrameManagerBase::PropertyList::~PropertyList() +{ + PL_DHashTableFinish(&mFrameValueMap); +} + +PR_STATIC_CALLBACK(PLDHashOperator) +DestroyPropertyEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) +{ + nsFrameManagerBase::PropertyList *propList = + NS_STATIC_CAST(nsFrameManagerBase::PropertyList*, table->data); + nsPresContext *presContext = NS_STATIC_CAST(nsPresContext*, arg); + PropertyListMapEntry* entry = NS_STATIC_CAST(PropertyListMapEntry*, hdr); + + propList->mDtorFunc(presContext, NS_CONST_CAST(nsIFrame*, entry->key), + propList->mName, entry->value); + return PL_DHASH_NEXT; +} + +void +nsFrameManagerBase::PropertyList::Destroy(nsPresContext* aPresContext) +{ + // Enumerate any remaining frame/value pairs and destroy the value object + if (mDtorFunc) + PL_DHashTableEnumerate(&mFrameValueMap, DestroyPropertyEnumerator, + aPresContext); +} + +PRBool +nsFrameManagerBase::PropertyList::RemovePropertyForFrame(nsPresContext* aPresContext, + const nsIFrame* aFrame) +{ + PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*, + PL_DHashTableOperate(&mFrameValueMap, aFrame, PL_DHASH_LOOKUP)); + if (!PL_DHASH_ENTRY_IS_BUSY(entry)) + return PR_FALSE; + + if (mDtorFunc) + mDtorFunc(aPresContext, NS_CONST_CAST(nsIFrame*, aFrame), + mName, entry->value); + + PL_DHashTableRawRemove(&mFrameValueMap, entry); + + return PR_TRUE; +} diff --git a/mozilla/layout/base/nsFrameManager.h b/mozilla/layout/base/nsFrameManager.h index 4901804b884..20706d74976 100644 --- a/mozilla/layout/base/nsFrameManager.h +++ b/mozilla/layout/base/nsFrameManager.h @@ -55,6 +55,9 @@ #include "nsChangeHint.h" #include "nsFrameManagerBase.h" +// Option flags for GetFrameProperty() member function +#define NS_IFRAME_MGR_REMOVE_PROP 0x0001 + /** * Frame manager interface. The frame manager serves two purposes: *
  • provides a service for mapping from content to frame and from @@ -219,6 +222,68 @@ public: nsIStatefulFrame::SpecialStateID aID = nsIStatefulFrame::eNoID); + /** + * Gets a property value for a given frame. + * + * @param aFrame the frame with the property + * @param aPropertyName property name as an atom + * @param aOptions optional flags + * NS_IFRAME_MGR_REMOVE_PROP removes the property + * @param aResult NS_OK if the property is set, + * NS_IFRAME_MGR_PROP_NOT_THERE is it is not set + * @param aPropertyValue the property value or 0 if the + property is not set + * @return The property value or 0 if the property is not set + */ + + NS_HIDDEN_(void*) GetFrameProperty(const nsIFrame* aFrame, + nsIAtom* aPropertyName, + PRUint32 aOptions, + nsresult* aResult = nsnull); + + /** + * Sets the property value for a given frame. + * + * A frame may only have one property value at a time for a given property + * name. The existing property value (if there is one) is overwritten, and + * the old value destroyed + * + * @param aFrame the frame to set the property on + * @param aPropertyName property name as an atom + * @param aPropertyValue the property value + * @param aPropertyDtorFunc when setting a property you can specify the + * dtor function (can be NULL) that will be used + * to destroy the property value. There can be + * only one dtor function for a given property + * name + * @return NS_OK if successful, + * NS_IFRAME_MGR_PROP_OVERWRITTEN if there is an existing property + * value that was overwritten, + * NS_ERROR_INVALID_ARG if the dtor function does not match the + * existing dtor function + */ + + NS_HIDDEN_(nsresult) SetFrameProperty(const nsIFrame* aFrame, + nsIAtom* aPropertyName, + void* aPropertyValue, + NSFramePropertyDtorFunc aPropDtorFunc); + + /** + * Removes a property and destroys its property value by calling the dtor + * function associated with the property name. + * + * When a frame is destroyed any remaining properties are automatically + * removed. + * + * @param aFrame the frame to set the property on + * @param aPropertyName property name as an atom + * @return NS_OK if the property is successfully removed, + * NS_IFRAME_MGR_PROP_NOT_THERE if the property is not set + */ + + NS_HIDDEN_(nsresult) RemoveFrameProperty(const nsIFrame* aFrame, + nsIAtom* aPropertyName); + #ifdef NS_DEBUG /** * DEBUG ONLY method to verify integrity of style tree versus frame tree @@ -247,6 +312,10 @@ private: FindPostedEventFor(nsIFrame* aFrame); NS_HIDDEN_(void) DequeuePostedEventFor(nsIFrame* aFrame); + NS_HIDDEN_(void) DestroyPropertyList(nsPresContext* aPresContext); + NS_HIDDEN_(PropertyList*) GetPropertyListFor(nsIAtom* aPropertyName) const; + NS_HIDDEN_(void) RemoveAllPropertiesFor(nsPresContext *aPresContext, + nsIFrame *aFrame); static NS_HIDDEN_(void) HandlePLEvent(CantRenderReplacedElementEvent* aEvent); diff --git a/mozilla/layout/base/nsFrameManagerBase.h b/mozilla/layout/base/nsFrameManagerBase.h index 834ac770f4c..eccba380a6f 100644 --- a/mozilla/layout/base/nsFrameManagerBase.h +++ b/mozilla/layout/base/nsFrameManagerBase.h @@ -67,6 +67,9 @@ struct CantRenderReplacedElementEvent; class nsFrameManagerBase { +public: + struct PropertyList; + protected: class UndisplayedMap; @@ -79,6 +82,7 @@ protected: PLDHashTable mPlaceholderMap; UndisplayedMap* mUndisplayedMap; CantRenderReplacedElementEvent* mPostedEvents; + PropertyList* mPropertyList; PRBool mIsDestroyingFrames; }; diff --git a/mozilla/layout/base/nsLayoutErrors.h b/mozilla/layout/base/nsLayoutErrors.h index 924e3f77e2c..68ef2e6f4fb 100644 --- a/mozilla/layout/base/nsLayoutErrors.h +++ b/mozilla/layout/base/nsLayoutErrors.h @@ -43,6 +43,15 @@ #define NS_TABLELAYOUT_CELL_NOT_FOUND \ NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 0) + +/** Error codes for frame property functions */ +#define NS_IFRAME_MGR_PROP_NOT_THERE \ + NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 1) + +#define NS_IFRAME_MGR_PROP_OVERWRITTEN \ + NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 2) + + /** Error codes for nsFrame::GetNextPrevLineFromeBlockFrame */ #define NS_POSITION_BEFORE_TABLE \ NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 3) diff --git a/mozilla/layout/base/nsPresContext.cpp b/mozilla/layout/base/nsPresContext.cpp index 5507d35fcb7..e3626a5629f 100644 --- a/mozilla/layout/base/nsPresContext.cpp +++ b/mozilla/layout/base/nsPresContext.cpp @@ -68,7 +68,6 @@ #include "nsIDOMDocument.h" #include "nsAutoPtr.h" #include "nsEventStateManager.h" -#include "nsPropertyTable.h" #ifdef IBMBIDI #include "nsBidiPresUtils.h" #endif // IBMBIDI diff --git a/mozilla/layout/base/nsPresContext.h b/mozilla/layout/base/nsPresContext.h index 9427646f649..729575b94ca 100644 --- a/mozilla/layout/base/nsPresContext.h +++ b/mozilla/layout/base/nsPresContext.h @@ -54,7 +54,6 @@ #include "nsIObserver.h" #include "nsCRT.h" #include "nsIPrintSettings.h" -#include "nsPropertyTable.h" #ifdef IBMBIDI class nsBidiPresUtils; #endif // IBMBIDI @@ -573,9 +572,6 @@ public: nsIPrintSettings* GetPrintSettings() { return mPrintSettings; } - /* Accessor for table of frame properties */ - nsPropertyTable* PropertyTable() { return &mPropertyTable; } - #ifdef MOZ_REFLOW_PERF NS_HIDDEN_(void) CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame); @@ -625,8 +621,6 @@ protected: nsCOMPtr mLangService; nsCOMPtr mPrintSettings; - nsPropertyTable mPropertyTable; - nsLanguageSpecificTransformType mLanguageSpecificTransformType; PRInt32 mFontScaler; nscoord mMinimumFontSize; diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index 59ca6dbe038..d2c1860f227 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -6808,12 +6808,20 @@ CompareTrees(nsPresContext* aFirstPresContext, nsIFrame* aFirstFrame, // verify that neither frame has a space manager, // or they both do and the space managers are equivalent - nsSpaceManager *sm1 = NS_STATIC_CAST(nsSpaceManager*, - k1->GetProperty(nsLayoutAtoms::spaceManagerProperty)); + nsFrameManager *fm1 = aFirstPresContext->FrameManager(); + NS_ASSERTION(fm1, "no frame manager for primary tree!"); + + nsSpaceManager *sm1 = + NS_STATIC_CAST(nsSpaceManager*, fm1->GetFrameProperty(k1, + nsLayoutAtoms::spaceManagerProperty, 0)); // look at the test frame - nsSpaceManager *sm2 = NS_STATIC_CAST(nsSpaceManager*, - k2->GetProperty(nsLayoutAtoms::spaceManagerProperty)); + nsFrameManager *fm2 = aSecondPresContext->FrameManager(); + NS_ASSERTION(fm2, "no frame manager for test tree!"); + + nsSpaceManager *sm2 = + NS_STATIC_CAST(nsSpaceManager*, fm2->GetFrameProperty(k2, + nsLayoutAtoms::spaceManagerProperty, 0)); // now compare the space managers if (((nsnull == sm1) && (nsnull != sm2)) || diff --git a/mozilla/layout/base/public/nsIFrame.h b/mozilla/layout/base/public/nsIFrame.h index 071002b162c..1b90993524d 100644 --- a/mozilla/layout/base/public/nsIFrame.h +++ b/mozilla/layout/base/public/nsIFrame.h @@ -89,6 +89,13 @@ struct nsRect; struct nsSize; struct nsMargin; +// Calback function used to destroy the value associated with a property. +typedef void +(*NSFramePropertyDtorFunc)(nsPresContext* aPresContext, + nsIFrame* aFrame, + nsIAtom* aPropertyName, + void* aPropertyValue); + // IID for the nsIFrame interface // a6cf9050-15b3-11d2-932e-00805f8add32 #define NS_IFRAME_IID \ @@ -1208,17 +1215,13 @@ public: } - NS_HIDDEN_(void*) GetProperty(nsIAtom* aPropertyName, - nsresult* aStatus = nsnull) const; - virtual NS_HIDDEN_(void*) GetPropertyExternal(nsIAtom* aPropertyName, - nsresult* aStatus) const; - NS_HIDDEN_(nsresult) SetProperty(nsIAtom* aPropertyName, - void* aValue, - NSPropertyDtorFunc aDestructor = nsnull, - void* aDtorData = nsnull); - NS_HIDDEN_(nsresult) DeleteProperty(nsIAtom* aPropertyName) const; - NS_HIDDEN_(void*) UnsetProperty(nsIAtom* aPropertyName, - nsresult* aStatus = nsnull) const; + void* GetProperty(nsIAtom* aPropertyName, nsresult* aStatus = nsnull) const; + virtual void* GetPropertyExternal(nsIAtom* aPropertyName, + nsresult* aStatus) const; + void* RemoveProperty(nsIAtom* aPropertyName, nsresult* aStatus = nsnull) const; + nsresult SetProperty(nsIAtom* aPropertyName, + void* aValue, + NSFramePropertyDtorFunc aDestructor = nsnull); #define NS_GET_BASE_LEVEL(frame) \ NS_PTR_TO_INT32(frame->GetProperty(nsLayoutAtoms::baseLevel)) diff --git a/mozilla/layout/base/public/nsLayoutErrors.h b/mozilla/layout/base/public/nsLayoutErrors.h index 924e3f77e2c..68ef2e6f4fb 100644 --- a/mozilla/layout/base/public/nsLayoutErrors.h +++ b/mozilla/layout/base/public/nsLayoutErrors.h @@ -43,6 +43,15 @@ #define NS_TABLELAYOUT_CELL_NOT_FOUND \ NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 0) + +/** Error codes for frame property functions */ +#define NS_IFRAME_MGR_PROP_NOT_THERE \ + NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 1) + +#define NS_IFRAME_MGR_PROP_OVERWRITTEN \ + NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 2) + + /** Error codes for nsFrame::GetNextPrevLineFromeBlockFrame */ #define NS_POSITION_BEFORE_TABLE \ NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT, 3) diff --git a/mozilla/layout/base/public/nsPresContext.h b/mozilla/layout/base/public/nsPresContext.h index 9427646f649..729575b94ca 100644 --- a/mozilla/layout/base/public/nsPresContext.h +++ b/mozilla/layout/base/public/nsPresContext.h @@ -54,7 +54,6 @@ #include "nsIObserver.h" #include "nsCRT.h" #include "nsIPrintSettings.h" -#include "nsPropertyTable.h" #ifdef IBMBIDI class nsBidiPresUtils; #endif // IBMBIDI @@ -573,9 +572,6 @@ public: nsIPrintSettings* GetPrintSettings() { return mPrintSettings; } - /* Accessor for table of frame properties */ - nsPropertyTable* PropertyTable() { return &mPropertyTable; } - #ifdef MOZ_REFLOW_PERF NS_HIDDEN_(void) CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame); @@ -625,8 +621,6 @@ protected: nsCOMPtr mLangService; nsCOMPtr mPrintSettings; - nsPropertyTable mPropertyTable; - nsLanguageSpecificTransformType mLanguageSpecificTransformType; PRInt32 mFontScaler; nscoord mMinimumFontSize; diff --git a/mozilla/layout/base/src/nsBidiPresUtils.cpp b/mozilla/layout/base/src/nsBidiPresUtils.cpp index 23078de301a..2273d9e4144 100644 --- a/mozilla/layout/base/src/nsBidiPresUtils.cpp +++ b/mozilla/layout/base/src/nsBidiPresUtils.cpp @@ -787,21 +787,22 @@ nsBidiPresUtils::RemoveBidiContinuation(nsPresContext* aPresContext, nsIFrame* thisFramesNextBidiFrame; nsIFrame* previousFramesNextBidiFrame; - thisFramesNextBidiFrame = - NS_STATIC_CAST(nsIFrame*, aFrame->GetProperty(nsLayoutAtoms::nextBidi)); + nsFrameManager* frameManager = presShell->FrameManager(); + thisFramesNextBidiFrame = NS_STATIC_CAST(nsIFrame*, + frameManager->GetFrameProperty(aFrame, nsLayoutAtoms::nextBidi, 0)); if (thisFramesNextBidiFrame) { // Remove nextBidi property, associated with the current frame // and with all of its prev-in-flow. frame = aFrame; do { - frame->DeleteProperty(nsLayoutAtoms::nextBidi); + frameManager->RemoveFrameProperty(frame, nsLayoutAtoms::nextBidi); frame->GetPrevInFlow(&frame); if (!frame) { break; } - previousFramesNextBidiFrame = - NS_STATIC_CAST(nsIFrame*, frame->GetProperty(nsLayoutAtoms::nextBidi)); + previousFramesNextBidiFrame = NS_STATIC_CAST(nsIFrame*, + frameManager->GetFrameProperty(frame, nsLayoutAtoms::nextBidi, 0)); } while (thisFramesNextBidiFrame == previousFramesNextBidiFrame); } // if (thisFramesNextBidiFrame) } diff --git a/mozilla/layout/base/src/nsPresContext.cpp b/mozilla/layout/base/src/nsPresContext.cpp index 5507d35fcb7..e3626a5629f 100644 --- a/mozilla/layout/base/src/nsPresContext.cpp +++ b/mozilla/layout/base/src/nsPresContext.cpp @@ -68,7 +68,6 @@ #include "nsIDOMDocument.h" #include "nsAutoPtr.h" #include "nsEventStateManager.h" -#include "nsPropertyTable.h" #ifdef IBMBIDI #include "nsBidiPresUtils.h" #endif // IBMBIDI diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index ea54e0d55ed..64bc1892e02 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -927,9 +927,10 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, nsIPresShell *shell = aPresContext->GetPresShell(); if (shell) { nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState; - rv = SetProperty(nsLayoutAtoms::spaceManagerProperty, - reflowState.mSpaceManager, - nsnull /* should be nsSpaceManagerDestroyer*/); + rv = shell->FrameManager()->SetFrameProperty( + this, nsLayoutAtoms::spaceManagerProperty, + reflowState.mSpaceManager, + nsnull /* should be nsSpaceManagerDestroyer*/); autoSpaceManager.DebugOrphanSpaceManager(); } @@ -4305,22 +4306,21 @@ nsBlockFrame::RemoveOverflowLines() const { nsLineList* lines = NS_STATIC_CAST(nsLineList*, - UnsetProperty(nsLayoutAtoms::overflowLinesProperty)); + RemoveProperty(nsLayoutAtoms::overflowLinesProperty)); NS_ASSERTION(!lines || !lines->empty(), "value should never be stored as empty"); return lines; } // Destructor function for the overflowLines frame property static void -DestroyOverflowLines(void* aFrame, +DestroyOverflowLines(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { if (aPropertyValue) { nsLineList* lines = NS_STATIC_CAST(nsLineList*, aPropertyValue); - nsPresContext *context = NS_STATIC_CAST(nsPresContext*, aDtorData); - nsLineBox::DeleteLineList(context, *lines); + nsLineBox::DeleteLineList(aPresContext, *lines); delete lines; } } @@ -4334,10 +4334,9 @@ nsBlockFrame::SetOverflowLines(nsLineList* aOverflowLines) NS_ASSERTION(!aOverflowLines->empty(), "empty lines"); nsresult rv = SetProperty(nsLayoutAtoms::overflowLinesProperty, - aOverflowLines, DestroyOverflowLines, - GetPresContext()); + aOverflowLines, DestroyOverflowLines); // Verify that we didn't overwrite an existing overflow list - NS_ASSERTION(rv != NS_PROPTABLE_PROP_OVERWRITTEN, "existing overflow list"); + NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow list"); return rv; } @@ -4352,15 +4351,15 @@ nsFrameList* nsBlockFrame::RemoveOverflowOutOfFlows() const { return NS_STATIC_CAST(nsFrameList*, - UnsetProperty(nsLayoutAtoms::overflowOutOfFlowsProperty)); + RemoveProperty(nsLayoutAtoms::overflowOutOfFlowsProperty)); } // Destructor function for the overflowPlaceholders frame property static void -DestroyOverflowOOFs(void* aFrame, +DestroyOverflowOOFs(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { NS_NOTREACHED("This helper method should never be called!"); delete NS_STATIC_CAST(nsFrameList*, aPropertyValue); @@ -4373,7 +4372,7 @@ nsBlockFrame::SetOverflowOutOfFlows(nsFrameList* aOOFs) nsresult rv = SetProperty(nsLayoutAtoms::overflowOutOfFlowsProperty, aOOFs, DestroyOverflowOOFs); // Verify that we didn't overwrite an existing overflow list - NS_ASSERTION(rv != NS_PROPTABLE_PROP_OVERWRITTEN, "existing overflow float list"); + NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow float list"); return rv; } @@ -4390,15 +4389,15 @@ nsBlockFrame::RemoveOverflowPlaceholders() const { return NS_STATIC_CAST(nsFrameList*, - UnsetProperty(nsLayoutAtoms::overflowPlaceholdersProperty)); + RemoveProperty(nsLayoutAtoms::overflowPlaceholdersProperty)); } // Destructor function for the overflowPlaceholders frame property static void -DestroyOverflowPlaceholders(void* aFrame, +DestroyOverflowPlaceholders(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { nsFrameList* overflowPlace = NS_STATIC_CAST(nsFrameList*, aPropertyValue); delete overflowPlace; @@ -4412,7 +4411,7 @@ nsBlockFrame::SetOverflowPlaceholders(nsFrameList* aOverflowPlaceholders) nsresult rv = SetProperty(nsLayoutAtoms::overflowPlaceholdersProperty, aOverflowPlaceholders, DestroyOverflowPlaceholders); // Verify that we didn't overwrite an existing overflow list - NS_ASSERTION(rv != NS_PROPTABLE_PROP_OVERWRITTEN, "existing overflow placeholder list"); + NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow placeholder list"); return rv; } @@ -5727,7 +5726,7 @@ void nsBlockFrame::ClearLineCursor() { return; } - UnsetProperty(nsLayoutAtoms::lineCursorProperty); + RemoveProperty(nsLayoutAtoms::lineCursorProperty); RemoveStateBits(NS_BLOCK_HAS_LINE_CURSOR); } diff --git a/mozilla/layout/generic/nsBlockReflowContext.cpp b/mozilla/layout/generic/nsBlockReflowContext.cpp index 867f3dae843..bc628d73875 100644 --- a/mozilla/layout/generic/nsBlockReflowContext.cpp +++ b/mozilla/layout/generic/nsBlockReflowContext.cpp @@ -292,8 +292,8 @@ ComputeShrinkwrapMargins(const nsStyleMargin* aStyleMargin, nscoord aWidth, } static void -nsPointDtor(void *aFrame, nsIAtom *aPropertyName, - void *aPropertyValue, void *aDtorData) +nsPointDtor(nsPresContext *aPresContext, nsIFrame *aFrame, + nsIAtom *aPropertyName, void *aPropertyValue) { nsPoint *point = NS_STATIC_CAST(nsPoint*, aPropertyValue); delete point; @@ -382,16 +382,21 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace, aComputedOffsets = aFrameRS.mComputedOffsets; if (NS_STYLE_POSITION_RELATIVE == display->mPosition) { + nsFrameManager *frameManager = mPresContext->FrameManager(); + nsPoint *offsets = NS_STATIC_CAST(nsPoint*, - mFrame->GetProperty(nsLayoutAtoms::computedOffsetProperty)); + frameManager->GetFrameProperty(mFrame, + nsLayoutAtoms::computedOffsetProperty, + 0)); if (offsets) offsets->MoveTo(aComputedOffsets.left, aComputedOffsets.top); else { offsets = new nsPoint(aComputedOffsets.left, aComputedOffsets.top); if (offsets) - mFrame->SetProperty(nsLayoutAtoms::computedOffsetProperty, - offsets, nsPointDtor); + frameManager->SetFrameProperty(mFrame, + nsLayoutAtoms::computedOffsetProperty, + offsets, nsPointDtor); } } diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index 1c78f7eb954..83fb2739484 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -495,7 +495,8 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine, // at their original position. if (NS_STYLE_POSITION_RELATIVE == kid->GetStyleDisplay()->mPosition) { nsPoint *offsets = NS_STATIC_CAST(nsPoint*, - kid->GetProperty(nsLayoutAtoms::computedOffsetProperty)); + mPresContext->FrameManager()->GetFrameProperty(kid, + nsLayoutAtoms::computedOffsetProperty, 0)); if (offsets) { tx -= offsets->x; diff --git a/mozilla/layout/generic/nsContainerFrame.cpp b/mozilla/layout/generic/nsContainerFrame.cpp index 99a4922508e..0efbd37a72a 100644 --- a/mozilla/layout/generic/nsContainerFrame.cpp +++ b/mozilla/layout/generic/nsContainerFrame.cpp @@ -1166,24 +1166,27 @@ nsIFrame* nsContainerFrame::GetOverflowFrames(nsPresContext* aPresContext, PRBool aRemoveProperty) const { + PRUint32 options = 0; + if (aRemoveProperty) { - return (nsIFrame*) UnsetProperty(nsLayoutAtoms::overflowProperty); + options |= NS_IFRAME_MGR_REMOVE_PROP; } - return (nsIFrame*) GetProperty(nsLayoutAtoms::overflowProperty); + return (nsIFrame*) aPresContext->FrameManager()-> + GetFrameProperty(this, nsLayoutAtoms::overflowProperty, options); } // Destructor function for the overflow frame property static void -DestroyOverflowFrames(void* aFrame, +DestroyOverflowFrames(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { if (aPropertyValue) { nsFrameList frames((nsIFrame*)aPropertyValue); - frames.DestroyFrames(NS_STATIC_CAST(nsPresContext*, aDtorData)); + frames.DestroyFrames(aPresContext); } } @@ -1191,12 +1194,12 @@ nsresult nsContainerFrame::SetOverflowFrames(nsPresContext* aPresContext, nsIFrame* aOverflowFrames) { - nsresult rv = SetProperty(nsLayoutAtoms::overflowProperty, - aOverflowFrames, DestroyOverflowFrames, - aPresContext); + nsresult rv = aPresContext->FrameManager()-> + SetFrameProperty(this, nsLayoutAtoms::overflowProperty, + aOverflowFrames, DestroyOverflowFrames); // Verify that we didn't overwrite an existing overflow list - NS_ASSERTION(rv != NS_PROPTABLE_PROP_OVERWRITTEN, "existing overflow list"); + NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow list"); return rv; } diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index 1b3ce922d3c..ed9fcce34cc 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -2269,7 +2269,8 @@ nsIFrame::GetView() const // Check for a property on the frame nsresult rv; - void *value = GetProperty(nsLayoutAtoms::viewProperty, &rv); + void* value = GetPresContext()->FrameManager()-> + GetFrameProperty(this, nsLayoutAtoms::viewProperty, 0, &rv); NS_ENSURE_SUCCESS(rv, nsnull); NS_ASSERTION(value, "frame state bit was set but frame has no view"); @@ -2289,7 +2290,8 @@ nsIFrame::SetView(nsIView* aView) aView->SetClientData(this); // Set a property on the frame - nsresult rv = SetProperty(nsLayoutAtoms::viewProperty, aView, nsnull); + nsresult rv = GetPresContext()->FrameManager()-> + SetFrameProperty(this, nsLayoutAtoms::viewProperty, aView, nsnull); NS_ENSURE_SUCCESS(rv, rv); // Set the frame state bit that says the frame has a view @@ -4207,10 +4209,10 @@ nsFrame::GetAccessible(nsIAccessible** aAccessible) // Destructor function for the overflow area property static void -DestroyRectFunc(void* aFrame, +DestroyRectFunc(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { delete (nsRect*)aPropertyValue; } @@ -4222,7 +4224,11 @@ nsIFrame::GetOverflowAreaProperty(PRBool aCreateIfNecessary) return nsnull; } - void *value = GetProperty(nsLayoutAtoms::overflowAreaProperty); + nsFrameManager *frameManager = GetPresContext()->FrameManager(); + + void *value = + frameManager->GetFrameProperty(this, nsLayoutAtoms::overflowAreaProperty, + 0); if (value) { return (nsRect*)value; // the property already exists @@ -4230,8 +4236,9 @@ nsIFrame::GetOverflowAreaProperty(PRBool aCreateIfNecessary) // The property isn't set yet, so allocate a new rect, set the property, // and return the newly allocated rect nsRect* overflow = new nsRect(0, 0, 0, 0); - SetProperty(nsLayoutAtoms::overflowAreaProperty, - overflow, DestroyRectFunc); + + frameManager->SetFrameProperty(this, nsLayoutAtoms::overflowAreaProperty, + overflow, DestroyRectFunc); return overflow; } @@ -4264,7 +4271,8 @@ nsIFrame::FinishAndStoreOverflow(nsRect* aOverflowArea, nsSize aNewSize) else { if (mState & NS_FRAME_OUTSIDE_CHILDREN) { // remove the previously stored overflow area - DeleteProperty(nsLayoutAtoms::overflowAreaProperty); + GetPresContext()->FrameManager()-> + RemoveFrameProperty(this, nsLayoutAtoms::overflowAreaProperty); } mState &= ~NS_FRAME_OUTSIDE_CHILDREN; } @@ -4330,7 +4338,8 @@ GetIBSpecialSibling(nsPresContext* aPresContext, */ nsresult rv; nsIFrame *specialSibling = NS_STATIC_CAST(nsIFrame*, - aFrame->GetProperty(nsLayoutAtoms::IBSplitSpecialPrevSibling, &rv)); + aPresContext->FrameManager()->GetFrameProperty(aFrame, + nsLayoutAtoms::IBSplitSpecialPrevSibling, 0, &rv)); if (NS_OK == rv) { NS_ASSERTION(specialSibling, "null special sibling"); @@ -4536,20 +4545,19 @@ nsFrame::IsMouseCaptured(nsPresContext* aPresContext) } nsresult -nsIFrame::SetProperty(nsIAtom* aPropName, - void* aPropValue, - NSPropertyDtorFunc aPropDtorFunc, - void* aDtorData) +nsIFrame::SetProperty(nsIAtom* aPropName, + void* aPropValue, + NSFramePropertyDtorFunc aPropDtorFunc) { - return GetPresContext()->PropertyTable()-> - SetProperty(this, aPropName, aPropValue, aPropDtorFunc, aDtorData); + return GetPresContext()->FrameManager()-> + SetFrameProperty(this, aPropName, aPropValue, aPropDtorFunc); } void* nsIFrame::GetProperty(nsIAtom* aPropName, nsresult* aStatus) const { - return GetPresContext()->PropertyTable()->GetProperty(this, aPropName, - aStatus); + return GetPresContext()->FrameManager()-> + GetFrameProperty(this, aPropName, 0, aStatus); } /* virtual */ void* @@ -4558,17 +4566,11 @@ nsIFrame::GetPropertyExternal(nsIAtom* aPropName, nsresult* aStatus) const return GetProperty(aPropName, aStatus); } -nsresult -nsIFrame::DeleteProperty(nsIAtom* aPropName) const -{ - return GetPresContext()->PropertyTable()->DeleteProperty(this, aPropName); -} - void* -nsIFrame::UnsetProperty(nsIAtom* aPropName, nsresult* aStatus) const +nsIFrame::RemoveProperty(nsIAtom* aPropName, nsresult* aStatus) const { - return GetPresContext()->PropertyTable()->UnsetProperty(this, aPropName, - aStatus); + return GetPresContext()->FrameManager()-> + GetFrameProperty(this, aPropName, NS_IFRAME_MGR_REMOVE_PROP, aStatus); } /* virtual */ const nsStyleStruct* diff --git a/mozilla/layout/generic/nsFrameFrame.cpp b/mozilla/layout/generic/nsFrameFrame.cpp index 426d78cd558..c4a2764c12d 100644 --- a/mozilla/layout/generic/nsFrameFrame.cpp +++ b/mozilla/layout/generic/nsFrameFrame.cpp @@ -240,7 +240,10 @@ nsSubDocumentFrame::Init(nsPresContext* aPresContext, nsCOMPtr contentParentAtom = do_GetAtom("contentParent"); nsIFrame* contentParent = nsnull; - void *value = UnsetProperty(contentParentAtom, &rv); + void *value = + aPresContext->FrameManager()->GetFrameProperty(this, contentParentAtom, + NS_IFRAME_MGR_REMOVE_PROP, + &rv); if (NS_SUCCEEDED(rv)) { contentParent = (nsIFrame*)value; } diff --git a/mozilla/layout/generic/nsIFrame.h b/mozilla/layout/generic/nsIFrame.h index 071002b162c..1b90993524d 100644 --- a/mozilla/layout/generic/nsIFrame.h +++ b/mozilla/layout/generic/nsIFrame.h @@ -89,6 +89,13 @@ struct nsRect; struct nsSize; struct nsMargin; +// Calback function used to destroy the value associated with a property. +typedef void +(*NSFramePropertyDtorFunc)(nsPresContext* aPresContext, + nsIFrame* aFrame, + nsIAtom* aPropertyName, + void* aPropertyValue); + // IID for the nsIFrame interface // a6cf9050-15b3-11d2-932e-00805f8add32 #define NS_IFRAME_IID \ @@ -1208,17 +1215,13 @@ public: } - NS_HIDDEN_(void*) GetProperty(nsIAtom* aPropertyName, - nsresult* aStatus = nsnull) const; - virtual NS_HIDDEN_(void*) GetPropertyExternal(nsIAtom* aPropertyName, - nsresult* aStatus) const; - NS_HIDDEN_(nsresult) SetProperty(nsIAtom* aPropertyName, - void* aValue, - NSPropertyDtorFunc aDestructor = nsnull, - void* aDtorData = nsnull); - NS_HIDDEN_(nsresult) DeleteProperty(nsIAtom* aPropertyName) const; - NS_HIDDEN_(void*) UnsetProperty(nsIAtom* aPropertyName, - nsresult* aStatus = nsnull) const; + void* GetProperty(nsIAtom* aPropertyName, nsresult* aStatus = nsnull) const; + virtual void* GetPropertyExternal(nsIAtom* aPropertyName, + nsresult* aStatus) const; + void* RemoveProperty(nsIAtom* aPropertyName, nsresult* aStatus = nsnull) const; + nsresult SetProperty(nsIAtom* aPropertyName, + void* aValue, + NSFramePropertyDtorFunc aDestructor = nsnull); #define NS_GET_BASE_LEVEL(frame) \ NS_PTR_TO_INT32(frame->GetProperty(nsLayoutAtoms::baseLevel)) diff --git a/mozilla/layout/html/base/src/nsBlockFrame.cpp b/mozilla/layout/html/base/src/nsBlockFrame.cpp index ea54e0d55ed..64bc1892e02 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.cpp +++ b/mozilla/layout/html/base/src/nsBlockFrame.cpp @@ -927,9 +927,10 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, nsIPresShell *shell = aPresContext->GetPresShell(); if (shell) { nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState; - rv = SetProperty(nsLayoutAtoms::spaceManagerProperty, - reflowState.mSpaceManager, - nsnull /* should be nsSpaceManagerDestroyer*/); + rv = shell->FrameManager()->SetFrameProperty( + this, nsLayoutAtoms::spaceManagerProperty, + reflowState.mSpaceManager, + nsnull /* should be nsSpaceManagerDestroyer*/); autoSpaceManager.DebugOrphanSpaceManager(); } @@ -4305,22 +4306,21 @@ nsBlockFrame::RemoveOverflowLines() const { nsLineList* lines = NS_STATIC_CAST(nsLineList*, - UnsetProperty(nsLayoutAtoms::overflowLinesProperty)); + RemoveProperty(nsLayoutAtoms::overflowLinesProperty)); NS_ASSERTION(!lines || !lines->empty(), "value should never be stored as empty"); return lines; } // Destructor function for the overflowLines frame property static void -DestroyOverflowLines(void* aFrame, +DestroyOverflowLines(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { if (aPropertyValue) { nsLineList* lines = NS_STATIC_CAST(nsLineList*, aPropertyValue); - nsPresContext *context = NS_STATIC_CAST(nsPresContext*, aDtorData); - nsLineBox::DeleteLineList(context, *lines); + nsLineBox::DeleteLineList(aPresContext, *lines); delete lines; } } @@ -4334,10 +4334,9 @@ nsBlockFrame::SetOverflowLines(nsLineList* aOverflowLines) NS_ASSERTION(!aOverflowLines->empty(), "empty lines"); nsresult rv = SetProperty(nsLayoutAtoms::overflowLinesProperty, - aOverflowLines, DestroyOverflowLines, - GetPresContext()); + aOverflowLines, DestroyOverflowLines); // Verify that we didn't overwrite an existing overflow list - NS_ASSERTION(rv != NS_PROPTABLE_PROP_OVERWRITTEN, "existing overflow list"); + NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow list"); return rv; } @@ -4352,15 +4351,15 @@ nsFrameList* nsBlockFrame::RemoveOverflowOutOfFlows() const { return NS_STATIC_CAST(nsFrameList*, - UnsetProperty(nsLayoutAtoms::overflowOutOfFlowsProperty)); + RemoveProperty(nsLayoutAtoms::overflowOutOfFlowsProperty)); } // Destructor function for the overflowPlaceholders frame property static void -DestroyOverflowOOFs(void* aFrame, +DestroyOverflowOOFs(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { NS_NOTREACHED("This helper method should never be called!"); delete NS_STATIC_CAST(nsFrameList*, aPropertyValue); @@ -4373,7 +4372,7 @@ nsBlockFrame::SetOverflowOutOfFlows(nsFrameList* aOOFs) nsresult rv = SetProperty(nsLayoutAtoms::overflowOutOfFlowsProperty, aOOFs, DestroyOverflowOOFs); // Verify that we didn't overwrite an existing overflow list - NS_ASSERTION(rv != NS_PROPTABLE_PROP_OVERWRITTEN, "existing overflow float list"); + NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow float list"); return rv; } @@ -4390,15 +4389,15 @@ nsBlockFrame::RemoveOverflowPlaceholders() const { return NS_STATIC_CAST(nsFrameList*, - UnsetProperty(nsLayoutAtoms::overflowPlaceholdersProperty)); + RemoveProperty(nsLayoutAtoms::overflowPlaceholdersProperty)); } // Destructor function for the overflowPlaceholders frame property static void -DestroyOverflowPlaceholders(void* aFrame, +DestroyOverflowPlaceholders(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { nsFrameList* overflowPlace = NS_STATIC_CAST(nsFrameList*, aPropertyValue); delete overflowPlace; @@ -4412,7 +4411,7 @@ nsBlockFrame::SetOverflowPlaceholders(nsFrameList* aOverflowPlaceholders) nsresult rv = SetProperty(nsLayoutAtoms::overflowPlaceholdersProperty, aOverflowPlaceholders, DestroyOverflowPlaceholders); // Verify that we didn't overwrite an existing overflow list - NS_ASSERTION(rv != NS_PROPTABLE_PROP_OVERWRITTEN, "existing overflow placeholder list"); + NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow placeholder list"); return rv; } @@ -5727,7 +5726,7 @@ void nsBlockFrame::ClearLineCursor() { return; } - UnsetProperty(nsLayoutAtoms::lineCursorProperty); + RemoveProperty(nsLayoutAtoms::lineCursorProperty); RemoveStateBits(NS_BLOCK_HAS_LINE_CURSOR); } diff --git a/mozilla/layout/html/base/src/nsBlockReflowContext.cpp b/mozilla/layout/html/base/src/nsBlockReflowContext.cpp index 867f3dae843..bc628d73875 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowContext.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowContext.cpp @@ -292,8 +292,8 @@ ComputeShrinkwrapMargins(const nsStyleMargin* aStyleMargin, nscoord aWidth, } static void -nsPointDtor(void *aFrame, nsIAtom *aPropertyName, - void *aPropertyValue, void *aDtorData) +nsPointDtor(nsPresContext *aPresContext, nsIFrame *aFrame, + nsIAtom *aPropertyName, void *aPropertyValue) { nsPoint *point = NS_STATIC_CAST(nsPoint*, aPropertyValue); delete point; @@ -382,16 +382,21 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace, aComputedOffsets = aFrameRS.mComputedOffsets; if (NS_STYLE_POSITION_RELATIVE == display->mPosition) { + nsFrameManager *frameManager = mPresContext->FrameManager(); + nsPoint *offsets = NS_STATIC_CAST(nsPoint*, - mFrame->GetProperty(nsLayoutAtoms::computedOffsetProperty)); + frameManager->GetFrameProperty(mFrame, + nsLayoutAtoms::computedOffsetProperty, + 0)); if (offsets) offsets->MoveTo(aComputedOffsets.left, aComputedOffsets.top); else { offsets = new nsPoint(aComputedOffsets.left, aComputedOffsets.top); if (offsets) - mFrame->SetProperty(nsLayoutAtoms::computedOffsetProperty, - offsets, nsPointDtor); + frameManager->SetFrameProperty(mFrame, + nsLayoutAtoms::computedOffsetProperty, + offsets, nsPointDtor); } } diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.cpp b/mozilla/layout/html/base/src/nsBlockReflowState.cpp index 1c78f7eb954..83fb2739484 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowState.cpp @@ -495,7 +495,8 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine, // at their original position. if (NS_STYLE_POSITION_RELATIVE == kid->GetStyleDisplay()->mPosition) { nsPoint *offsets = NS_STATIC_CAST(nsPoint*, - kid->GetProperty(nsLayoutAtoms::computedOffsetProperty)); + mPresContext->FrameManager()->GetFrameProperty(kid, + nsLayoutAtoms::computedOffsetProperty, 0)); if (offsets) { tx -= offsets->x; diff --git a/mozilla/layout/html/base/src/nsContainerFrame.cpp b/mozilla/layout/html/base/src/nsContainerFrame.cpp index 99a4922508e..0efbd37a72a 100644 --- a/mozilla/layout/html/base/src/nsContainerFrame.cpp +++ b/mozilla/layout/html/base/src/nsContainerFrame.cpp @@ -1166,24 +1166,27 @@ nsIFrame* nsContainerFrame::GetOverflowFrames(nsPresContext* aPresContext, PRBool aRemoveProperty) const { + PRUint32 options = 0; + if (aRemoveProperty) { - return (nsIFrame*) UnsetProperty(nsLayoutAtoms::overflowProperty); + options |= NS_IFRAME_MGR_REMOVE_PROP; } - return (nsIFrame*) GetProperty(nsLayoutAtoms::overflowProperty); + return (nsIFrame*) aPresContext->FrameManager()-> + GetFrameProperty(this, nsLayoutAtoms::overflowProperty, options); } // Destructor function for the overflow frame property static void -DestroyOverflowFrames(void* aFrame, +DestroyOverflowFrames(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { if (aPropertyValue) { nsFrameList frames((nsIFrame*)aPropertyValue); - frames.DestroyFrames(NS_STATIC_CAST(nsPresContext*, aDtorData)); + frames.DestroyFrames(aPresContext); } } @@ -1191,12 +1194,12 @@ nsresult nsContainerFrame::SetOverflowFrames(nsPresContext* aPresContext, nsIFrame* aOverflowFrames) { - nsresult rv = SetProperty(nsLayoutAtoms::overflowProperty, - aOverflowFrames, DestroyOverflowFrames, - aPresContext); + nsresult rv = aPresContext->FrameManager()-> + SetFrameProperty(this, nsLayoutAtoms::overflowProperty, + aOverflowFrames, DestroyOverflowFrames); // Verify that we didn't overwrite an existing overflow list - NS_ASSERTION(rv != NS_PROPTABLE_PROP_OVERWRITTEN, "existing overflow list"); + NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow list"); return rv; } diff --git a/mozilla/layout/html/base/src/nsFrame.cpp b/mozilla/layout/html/base/src/nsFrame.cpp index 1b3ce922d3c..ed9fcce34cc 100644 --- a/mozilla/layout/html/base/src/nsFrame.cpp +++ b/mozilla/layout/html/base/src/nsFrame.cpp @@ -2269,7 +2269,8 @@ nsIFrame::GetView() const // Check for a property on the frame nsresult rv; - void *value = GetProperty(nsLayoutAtoms::viewProperty, &rv); + void* value = GetPresContext()->FrameManager()-> + GetFrameProperty(this, nsLayoutAtoms::viewProperty, 0, &rv); NS_ENSURE_SUCCESS(rv, nsnull); NS_ASSERTION(value, "frame state bit was set but frame has no view"); @@ -2289,7 +2290,8 @@ nsIFrame::SetView(nsIView* aView) aView->SetClientData(this); // Set a property on the frame - nsresult rv = SetProperty(nsLayoutAtoms::viewProperty, aView, nsnull); + nsresult rv = GetPresContext()->FrameManager()-> + SetFrameProperty(this, nsLayoutAtoms::viewProperty, aView, nsnull); NS_ENSURE_SUCCESS(rv, rv); // Set the frame state bit that says the frame has a view @@ -4207,10 +4209,10 @@ nsFrame::GetAccessible(nsIAccessible** aAccessible) // Destructor function for the overflow area property static void -DestroyRectFunc(void* aFrame, +DestroyRectFunc(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { delete (nsRect*)aPropertyValue; } @@ -4222,7 +4224,11 @@ nsIFrame::GetOverflowAreaProperty(PRBool aCreateIfNecessary) return nsnull; } - void *value = GetProperty(nsLayoutAtoms::overflowAreaProperty); + nsFrameManager *frameManager = GetPresContext()->FrameManager(); + + void *value = + frameManager->GetFrameProperty(this, nsLayoutAtoms::overflowAreaProperty, + 0); if (value) { return (nsRect*)value; // the property already exists @@ -4230,8 +4236,9 @@ nsIFrame::GetOverflowAreaProperty(PRBool aCreateIfNecessary) // The property isn't set yet, so allocate a new rect, set the property, // and return the newly allocated rect nsRect* overflow = new nsRect(0, 0, 0, 0); - SetProperty(nsLayoutAtoms::overflowAreaProperty, - overflow, DestroyRectFunc); + + frameManager->SetFrameProperty(this, nsLayoutAtoms::overflowAreaProperty, + overflow, DestroyRectFunc); return overflow; } @@ -4264,7 +4271,8 @@ nsIFrame::FinishAndStoreOverflow(nsRect* aOverflowArea, nsSize aNewSize) else { if (mState & NS_FRAME_OUTSIDE_CHILDREN) { // remove the previously stored overflow area - DeleteProperty(nsLayoutAtoms::overflowAreaProperty); + GetPresContext()->FrameManager()-> + RemoveFrameProperty(this, nsLayoutAtoms::overflowAreaProperty); } mState &= ~NS_FRAME_OUTSIDE_CHILDREN; } @@ -4330,7 +4338,8 @@ GetIBSpecialSibling(nsPresContext* aPresContext, */ nsresult rv; nsIFrame *specialSibling = NS_STATIC_CAST(nsIFrame*, - aFrame->GetProperty(nsLayoutAtoms::IBSplitSpecialPrevSibling, &rv)); + aPresContext->FrameManager()->GetFrameProperty(aFrame, + nsLayoutAtoms::IBSplitSpecialPrevSibling, 0, &rv)); if (NS_OK == rv) { NS_ASSERTION(specialSibling, "null special sibling"); @@ -4536,20 +4545,19 @@ nsFrame::IsMouseCaptured(nsPresContext* aPresContext) } nsresult -nsIFrame::SetProperty(nsIAtom* aPropName, - void* aPropValue, - NSPropertyDtorFunc aPropDtorFunc, - void* aDtorData) +nsIFrame::SetProperty(nsIAtom* aPropName, + void* aPropValue, + NSFramePropertyDtorFunc aPropDtorFunc) { - return GetPresContext()->PropertyTable()-> - SetProperty(this, aPropName, aPropValue, aPropDtorFunc, aDtorData); + return GetPresContext()->FrameManager()-> + SetFrameProperty(this, aPropName, aPropValue, aPropDtorFunc); } void* nsIFrame::GetProperty(nsIAtom* aPropName, nsresult* aStatus) const { - return GetPresContext()->PropertyTable()->GetProperty(this, aPropName, - aStatus); + return GetPresContext()->FrameManager()-> + GetFrameProperty(this, aPropName, 0, aStatus); } /* virtual */ void* @@ -4558,17 +4566,11 @@ nsIFrame::GetPropertyExternal(nsIAtom* aPropName, nsresult* aStatus) const return GetProperty(aPropName, aStatus); } -nsresult -nsIFrame::DeleteProperty(nsIAtom* aPropName) const -{ - return GetPresContext()->PropertyTable()->DeleteProperty(this, aPropName); -} - void* -nsIFrame::UnsetProperty(nsIAtom* aPropName, nsresult* aStatus) const +nsIFrame::RemoveProperty(nsIAtom* aPropName, nsresult* aStatus) const { - return GetPresContext()->PropertyTable()->UnsetProperty(this, aPropName, - aStatus); + return GetPresContext()->FrameManager()-> + GetFrameProperty(this, aPropName, NS_IFRAME_MGR_REMOVE_PROP, aStatus); } /* virtual */ const nsStyleStruct* diff --git a/mozilla/layout/html/base/src/nsFrameManager.cpp b/mozilla/layout/html/base/src/nsFrameManager.cpp index 0f5cad39c71..d565eedf6ad 100644 --- a/mozilla/layout/html/base/src/nsFrameManager.cpp +++ b/mozilla/layout/html/base/src/nsFrameManager.cpp @@ -154,6 +154,13 @@ static PLDHashTableOps PlaceholderMapOps = { //---------------------------------------------------------------------- +struct PropertyListMapEntry : public PLDHashEntryHdr { + const nsIFrame *key; + void *value; +}; + +//---------------------------------------------------------------------- + struct PrimaryFrameMapEntry : public PLDHashEntryHdr { // key (the content node) can almost always be obtained through the // frame. If it weren't for the way image maps (mis)used the primary @@ -270,6 +277,26 @@ struct CantRenderReplacedElementEvent : public PLEvent { nsWeakPtr mPresShell; // for removing load group request later }; +struct nsFrameManagerBase::PropertyList { + nsCOMPtr mName; // property name + PLDHashTable mFrameValueMap; // map of frame/value pairs + NSFramePropertyDtorFunc mDtorFunc; // property specific value dtor function + PropertyList* mNext; + + PropertyList(nsIAtom* aName, + NSFramePropertyDtorFunc aDtorFunc) NS_HIDDEN; + ~PropertyList() NS_HIDDEN; + + // Removes the property associated with the given frame, and destroys + // the property value + NS_HIDDEN_(PRBool) RemovePropertyForFrame(nsPresContext* aPresContext, + const nsIFrame* aFrame); + + // Destroy all remaining properties (without removing them) + NS_HIDDEN_(void) Destroy(nsPresContext* aPresContext); +}; + + //---------------------------------------------------------------------- nsFrameManager::nsFrameManager() @@ -307,7 +334,9 @@ nsFrameManager::Destroy() nsPresContext *presContext = mPresShell->GetPresContext(); - // Destroy the frame hierarchy. + // Destroy the frame hierarchy. Don't destroy the property lists until after + // we've destroyed the frame hierarchy because some frames may expect to be + // able to retrieve their properties during destruction mPresShell->SetIgnoreFrameDestruction(PR_TRUE); mIsDestroyingFrames = PR_TRUE; // This flag prevents GetPrimaryFrameFor from returning pointers to destroyed frames @@ -326,6 +355,7 @@ nsFrameManager::Destroy() mPlaceholderMap.ops = nsnull; } delete mUndisplayedMap; + DestroyPropertyList(presContext); // If we're not going to be used anymore, we should revoke the // pending |CantRenderReplacedElementEvent|s being sent to us. @@ -705,8 +735,10 @@ nsFrameManager::InsertFrames(nsIFrame* aParentFrame, // Insert aFrameList after the last bidi continuation of aPrevFrame. nsIFrame* nextBidi; for (; ;) { - nextBidi = NS_STATIC_CAST(nsIFrame*, - aPrevFrame->GetProperty(nsLayoutAtoms::nextBidi)); + nextBidi = + NS_STATIC_CAST(nsIFrame*, GetFrameProperty(aPrevFrame, + nsLayoutAtoms::nextBidi, + 0)); if (!nextBidi) { break; } @@ -727,7 +759,8 @@ nsFrameManager::RemoveFrame(nsIFrame* aParentFrame, #ifdef IBMBIDI // Don't let the parent remove next bidi. In the other cases the it should NOT be removed. nsIFrame* nextBidi = - NS_STATIC_CAST(nsIFrame*, aOldFrame->GetProperty(nsLayoutAtoms::nextBidi)); + NS_STATIC_CAST(nsIFrame*, GetFrameProperty(aOldFrame, + nsLayoutAtoms::nextBidi, 0)); if (nextBidi) { RemoveFrame(aParentFrame, aListName, nextBidi); } @@ -745,6 +778,10 @@ nsFrameManager::NotifyDestroyingFrame(nsIFrame* aFrame) // Dequeue and destroy and posted events for this frame DequeuePostedEventFor(aFrame); + // Remove all properties associated with the frame + nsPresContext *presContext = mPresShell->GetPresContext(); + RemoveAllPropertiesFor(presContext, aFrame); + #ifdef DEBUG if (mPrimaryFrameMap.ops) { PrimaryFrameMapEntry *entry = NS_STATIC_CAST(PrimaryFrameMapEntry*, @@ -1662,8 +1699,8 @@ nsFrameManager::ComputeStyleChangeFor(nsIFrame *aFrame, return topLevelChange; } - frame2 = NS_STATIC_CAST(nsIFrame*, - frame2->GetProperty(nsLayoutAtoms::IBSplitSpecialSibling)); + frame2 = NS_STATIC_CAST(nsIFrame*, GetFrameProperty(frame2, + nsLayoutAtoms::IBSplitSpecialSibling, 0)); frame = frame2; } while (frame2); return topLevelChange; @@ -1839,6 +1876,140 @@ CompareKeys(void* key1, void* key2) return key1 == key2; } +void +nsFrameManager::DestroyPropertyList(nsPresContext* aPresContext) +{ + if (mPropertyList) { + while (mPropertyList) { + PropertyList* tmp = mPropertyList; + + mPropertyList = mPropertyList->mNext; + tmp->Destroy(aPresContext); + delete tmp; + } + } +} + +nsFrameManagerBase::PropertyList* +nsFrameManager::GetPropertyListFor(nsIAtom* aPropertyName) const +{ + PropertyList* result; + + for (result = mPropertyList; result; result = result->mNext) { + if (result->mName.get() == aPropertyName) { + break; + } + } + + return result; +} + +void +nsFrameManager::RemoveAllPropertiesFor(nsPresContext* aPresContext, + nsIFrame* aFrame) +{ + for (PropertyList* prop = mPropertyList; prop; prop = prop->mNext) { + prop->RemovePropertyForFrame(aPresContext, aFrame); + } +} + +void* +nsFrameManager::GetFrameProperty(const nsIFrame* aFrame, + nsIAtom* aPropertyName, + PRUint32 aOptions, + nsresult* aResult) +{ + NS_PRECONDITION(aPropertyName && aFrame, "unexpected null param"); + nsresult rv = NS_IFRAME_MGR_PROP_NOT_THERE; + void *propValue = nsnull; + + PropertyList* propertyList = GetPropertyListFor(aPropertyName); + if (propertyList) { + PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*, + PL_DHashTableOperate(&propertyList->mFrameValueMap, aFrame, + PL_DHASH_LOOKUP)); + if (PL_DHASH_ENTRY_IS_BUSY(entry)) { + propValue = entry->value; + if (aOptions & NS_IFRAME_MGR_REMOVE_PROP) { + // don't call propertyList->mDtorFunc. That's the caller's job now. + PL_DHashTableRawRemove(&propertyList->mFrameValueMap, entry); + } + rv = NS_OK; + } + } + + if (aResult) + *aResult = rv; + + return propValue; +} + +nsresult +nsFrameManager::SetFrameProperty(const nsIFrame* aFrame, + nsIAtom* aPropertyName, + void* aPropertyValue, + NSFramePropertyDtorFunc aPropDtorFunc) +{ + NS_PRECONDITION(aPropertyName && aFrame, "unexpected null param"); + + PropertyList* propertyList = GetPropertyListFor(aPropertyName); + + if (propertyList) { + // Make sure the dtor function matches + if (aPropDtorFunc != propertyList->mDtorFunc) { + return NS_ERROR_INVALID_ARG; + } + + } else { + propertyList = new PropertyList(aPropertyName, aPropDtorFunc); + if (!propertyList) + return NS_ERROR_OUT_OF_MEMORY; + if (!propertyList->mFrameValueMap.ops) { + delete propertyList; + return NS_ERROR_OUT_OF_MEMORY; + } + + propertyList->mNext = mPropertyList; + mPropertyList = propertyList; + } + + // The current property value (if there is one) is replaced and the current + // value is destroyed + nsresult result = NS_OK; + PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*, + PL_DHashTableOperate(&propertyList->mFrameValueMap, aFrame, PL_DHASH_ADD)); + if (!entry) + return NS_ERROR_OUT_OF_MEMORY; + // A NULL entry->key is the sign that the entry has just been allocated + // for us. If it's non-NULL then we have an existing entry. + if (entry->key && propertyList->mDtorFunc) { + propertyList->mDtorFunc(mPresShell->GetPresContext(), + NS_CONST_CAST(nsIFrame*, entry->key), + aPropertyName, entry->value); + result = NS_IFRAME_MGR_PROP_OVERWRITTEN; + } + entry->key = aFrame; + entry->value = aPropertyValue; + + return result; +} + +nsresult +nsFrameManager::RemoveFrameProperty(const nsIFrame* aFrame, + nsIAtom* aPropertyName) +{ + NS_PRECONDITION(aPropertyName && aFrame, "unexpected null param"); + + PropertyList* propertyList = GetPropertyListFor(aPropertyName); + if (propertyList) { + if (propertyList->RemovePropertyForFrame(mPresShell->GetPresContext(), + aFrame)) + return NS_OK; + } + + return NS_IFRAME_MGR_PROP_NOT_THERE; +} + //---------------------------------------------------------------------- MOZ_DECL_CTOR_COUNTER(UndisplayedMap) @@ -1986,3 +2157,59 @@ nsFrameManagerBase::UndisplayedMap::Clear(void) mLastLookup = nsnull; PL_HashTableEnumerateEntries(mTable, RemoveUndisplayedEntry, 0); } + +//---------------------------------------------------------------------- + +nsFrameManagerBase::PropertyList::PropertyList(nsIAtom* aName, + NSFramePropertyDtorFunc aDtorFunc) + : mName(aName), mDtorFunc(aDtorFunc), mNext(nsnull) +{ + PL_DHashTableInit(&mFrameValueMap, PL_DHashGetStubOps(), this, + sizeof(PropertyListMapEntry), 16); +} + +nsFrameManagerBase::PropertyList::~PropertyList() +{ + PL_DHashTableFinish(&mFrameValueMap); +} + +PR_STATIC_CALLBACK(PLDHashOperator) +DestroyPropertyEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) +{ + nsFrameManagerBase::PropertyList *propList = + NS_STATIC_CAST(nsFrameManagerBase::PropertyList*, table->data); + nsPresContext *presContext = NS_STATIC_CAST(nsPresContext*, arg); + PropertyListMapEntry* entry = NS_STATIC_CAST(PropertyListMapEntry*, hdr); + + propList->mDtorFunc(presContext, NS_CONST_CAST(nsIFrame*, entry->key), + propList->mName, entry->value); + return PL_DHASH_NEXT; +} + +void +nsFrameManagerBase::PropertyList::Destroy(nsPresContext* aPresContext) +{ + // Enumerate any remaining frame/value pairs and destroy the value object + if (mDtorFunc) + PL_DHashTableEnumerate(&mFrameValueMap, DestroyPropertyEnumerator, + aPresContext); +} + +PRBool +nsFrameManagerBase::PropertyList::RemovePropertyForFrame(nsPresContext* aPresContext, + const nsIFrame* aFrame) +{ + PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*, + PL_DHashTableOperate(&mFrameValueMap, aFrame, PL_DHASH_LOOKUP)); + if (!PL_DHASH_ENTRY_IS_BUSY(entry)) + return PR_FALSE; + + if (mDtorFunc) + mDtorFunc(aPresContext, NS_CONST_CAST(nsIFrame*, aFrame), + mName, entry->value); + + PL_DHashTableRawRemove(&mFrameValueMap, entry); + + return PR_TRUE; +} diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index 59ca6dbe038..d2c1860f227 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -6808,12 +6808,20 @@ CompareTrees(nsPresContext* aFirstPresContext, nsIFrame* aFirstFrame, // verify that neither frame has a space manager, // or they both do and the space managers are equivalent - nsSpaceManager *sm1 = NS_STATIC_CAST(nsSpaceManager*, - k1->GetProperty(nsLayoutAtoms::spaceManagerProperty)); + nsFrameManager *fm1 = aFirstPresContext->FrameManager(); + NS_ASSERTION(fm1, "no frame manager for primary tree!"); + + nsSpaceManager *sm1 = + NS_STATIC_CAST(nsSpaceManager*, fm1->GetFrameProperty(k1, + nsLayoutAtoms::spaceManagerProperty, 0)); // look at the test frame - nsSpaceManager *sm2 = NS_STATIC_CAST(nsSpaceManager*, - k2->GetProperty(nsLayoutAtoms::spaceManagerProperty)); + nsFrameManager *fm2 = aSecondPresContext->FrameManager(); + NS_ASSERTION(fm2, "no frame manager for test tree!"); + + nsSpaceManager *sm2 = + NS_STATIC_CAST(nsSpaceManager*, fm2->GetFrameProperty(k2, + nsLayoutAtoms::spaceManagerProperty, 0)); // now compare the space managers if (((nsnull == sm1) && (nsnull != sm2)) || diff --git a/mozilla/layout/html/document/src/nsFrameFrame.cpp b/mozilla/layout/html/document/src/nsFrameFrame.cpp index 426d78cd558..c4a2764c12d 100644 --- a/mozilla/layout/html/document/src/nsFrameFrame.cpp +++ b/mozilla/layout/html/document/src/nsFrameFrame.cpp @@ -240,7 +240,10 @@ nsSubDocumentFrame::Init(nsPresContext* aPresContext, nsCOMPtr contentParentAtom = do_GetAtom("contentParent"); nsIFrame* contentParent = nsnull; - void *value = UnsetProperty(contentParentAtom, &rv); + void *value = + aPresContext->FrameManager()->GetFrameProperty(this, contentParentAtom, + NS_IFRAME_MGR_REMOVE_PROP, + &rv); if (NS_SUCCEEDED(rv)) { contentParent = (nsIFrame*)value; } diff --git a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp index 9ac64f7a448..67d95f253b0 100644 --- a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -384,7 +384,9 @@ GetSpecialSibling(nsFrameManager* aFrameManager, nsIFrame* aFrame, nsIFrame** aR // frame in the flow. Walk back to find that frame now. aFrame = aFrame->GetFirstInFlow(); - void* value = aFrame->GetProperty(nsLayoutAtoms::IBSplitSpecialSibling); + void* value = + aFrameManager->GetFrameProperty(aFrame, + nsLayoutAtoms::IBSplitSpecialSibling, 0); *aResult = NS_STATIC_CAST(nsIFrame*, value); } @@ -436,8 +438,9 @@ SetFrameIsSpecial(nsFrameManager* aFrameManager, nsIFrame* aFrame, nsIFrame* aSp // Store the "special sibling" (if we were given one) with the // first frame in the flow. - aFrame->SetProperty(nsLayoutAtoms::IBSplitSpecialSibling, - aSpecialSibling, nsnull); + aFrameManager->SetFrameProperty(aFrame, + nsLayoutAtoms::IBSplitSpecialSibling, + aSpecialSibling, nsnull); } } @@ -568,8 +571,10 @@ MarkIBSpecialPrevSibling(nsPresContext* aPresContext, nsIFrame *aAnonymousFrame, nsIFrame *aSpecialParent) { - aAnonymousFrame->SetProperty(nsLayoutAtoms::IBSplitSpecialPrevSibling, - aSpecialParent, nsnull); + aFrameManager->SetFrameProperty(aAnonymousFrame, + nsLayoutAtoms::IBSplitSpecialPrevSibling, + aSpecialParent, + nsnull); } // ----------------------------------------------------------- @@ -4744,9 +4749,9 @@ nsCSSFrameConstructor::ConstructHTMLFrame(nsIPresShell* aPresShell, // there is no reasonable way to get the value there. // so we store it as a frame property. nsCOMPtr contentParentAtom = do_GetAtom("contentParent"); - aPresContext->PropertyTable()->SetProperty(newFrame, contentParentAtom, - aParentFrame, nsnull, - nsnull); + aState.mFrameManager->SetFrameProperty(newFrame, + contentParentAtom, + aParentFrame, nsnull); } } } @@ -9821,6 +9826,8 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList, if (!count) return NS_OK; + nsFrameManager *frameManager = aPresContext->FrameManager(); + // Mark frames so that we skip frames that die along the way, bug 123049. // A frame can be in the list multiple times with different hints. Further // optmization is possible if nsStyleChangeList::AppendChange could coalesce @@ -9829,8 +9836,8 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList, const nsStyleChangeData* changeData; aChangeList.ChangeAt(index, &changeData); if (changeData->mFrame) { - changeData->mFrame->SetProperty(nsLayoutAtoms::changeListProperty, - nsnull, nsnull); + frameManager->SetFrameProperty(changeData->mFrame, + nsLayoutAtoms::changeListProperty, nsnull, nsnull); } } @@ -9845,9 +9852,12 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList, if (frame) { nsresult res; - void* dummy = frame->GetProperty(nsLayoutAtoms::changeListProperty, &res); + void* dummy = + frameManager->GetFrameProperty(frame, + nsLayoutAtoms::changeListProperty, 0, + &res); - if (NS_PROPTABLE_PROP_NOT_THERE == res) + if (NS_IFRAME_MGR_PROP_NOT_THERE == res) continue; } @@ -9883,7 +9893,8 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList, const nsStyleChangeData* changeData; aChangeList.ChangeAt(index, &changeData); if (changeData->mFrame) { - changeData->mFrame->DeleteProperty(nsLayoutAtoms::changeListProperty); + frameManager->RemoveFrameProperty(changeData->mFrame, + nsLayoutAtoms::changeListProperty); } } diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index d81d4c3688c..c2b71791795 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -7375,30 +7375,30 @@ PRBool nsTableFrame::ColIsSpannedInto(PRInt32 aColIndex) // Destructor function for nscoord properties static void -DestroyCoordFunc(void* aFrame, +DestroyCoordFunc(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { delete (nscoord*)aPropertyValue; } // Destructor function point properties static void -DestroyPointFunc(void* aFrame, +DestroyPointFunc(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { delete (nsPoint*)aPropertyValue; } // Destructor function for nscoord properties static void -DestroyBCPropertyDataFunc(void* aFrame, +DestroyBCPropertyDataFunc(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { delete (BCPropertyData*)aPropertyValue; } @@ -7409,14 +7409,16 @@ nsTableFrame::GetProperty(nsPresContext* aPresContext, nsIAtom* aPropertyName, PRBool aCreateIfNecessary) { - void *value = aFrame->GetProperty(aPropertyName); + nsFrameManager *frameManager = aPresContext->FrameManager(); + + void *value = frameManager->GetFrameProperty(aFrame, aPropertyName, 0); if (value) { return (nsPoint*)value; // the property already exists } else if (aCreateIfNecessary) { // The property isn't set yet, so allocate a new value, set the property, // and return the newly allocated value void* value = nsnull; - NSPropertyDtorFunc dtorFunc = nsnull; + NSFramePropertyDtorFunc dtorFunc = nsnull; if (aPropertyName == nsLayoutAtoms::collapseOffsetProperty) { value = new nsPoint(0, 0); dtorFunc = DestroyPointFunc; @@ -7431,7 +7433,7 @@ nsTableFrame::GetProperty(nsPresContext* aPresContext, } if (!value) return nsnull; - aFrame->SetProperty(aPropertyName, value, dtorFunc); + frameManager->SetFrameProperty(aFrame, aPropertyName, value, dtorFunc); return value; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp index e923107acee..3f7c7809c87 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp @@ -116,10 +116,10 @@ struct nsValueList // The code doesn't include hooks for AttributeChanged() notifications. static void -DestroyValueListFunc(void* aFrame, +DestroyValueListFunc(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { delete NS_STATIC_CAST(nsValueList*, aPropertyValue); } @@ -133,8 +133,9 @@ GetValueAt(nsPresContext* aPresContext, PRUnichar* result = nsnull; nsValueList* valueList; + nsFrameManager *frameManager = aPresContext->FrameManager(); valueList = NS_STATIC_CAST(nsValueList*, - aTableOrRowFrame->GetProperty(aAttributeAtom)); + frameManager->GetFrameProperty(aTableOrRowFrame, aAttributeAtom, 0)); if (!valueList) { // The property isn't there yet, so set it @@ -143,8 +144,8 @@ GetValueAt(nsPresContext* aPresContext, aTableOrRowFrame->GetContent()->GetAttr(kNameSpaceID_None, aAttributeAtom, values)) { valueList = new nsValueList(values); if (valueList) { - aTableOrRowFrame->SetProperty(aAttributeAtom, - valueList, DestroyValueListFunc); + frameManager->SetFrameProperty(aTableOrRowFrame, aAttributeAtom, + valueList, DestroyValueListFunc); } } } diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index d81d4c3688c..c2b71791795 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -7375,30 +7375,30 @@ PRBool nsTableFrame::ColIsSpannedInto(PRInt32 aColIndex) // Destructor function for nscoord properties static void -DestroyCoordFunc(void* aFrame, +DestroyCoordFunc(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { delete (nscoord*)aPropertyValue; } // Destructor function point properties static void -DestroyPointFunc(void* aFrame, +DestroyPointFunc(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { delete (nsPoint*)aPropertyValue; } // Destructor function for nscoord properties static void -DestroyBCPropertyDataFunc(void* aFrame, +DestroyBCPropertyDataFunc(nsPresContext* aPresContext, + nsIFrame* aFrame, nsIAtom* aPropertyName, - void* aPropertyValue, - void* aDtorData) + void* aPropertyValue) { delete (BCPropertyData*)aPropertyValue; } @@ -7409,14 +7409,16 @@ nsTableFrame::GetProperty(nsPresContext* aPresContext, nsIAtom* aPropertyName, PRBool aCreateIfNecessary) { - void *value = aFrame->GetProperty(aPropertyName); + nsFrameManager *frameManager = aPresContext->FrameManager(); + + void *value = frameManager->GetFrameProperty(aFrame, aPropertyName, 0); if (value) { return (nsPoint*)value; // the property already exists } else if (aCreateIfNecessary) { // The property isn't set yet, so allocate a new value, set the property, // and return the newly allocated value void* value = nsnull; - NSPropertyDtorFunc dtorFunc = nsnull; + NSFramePropertyDtorFunc dtorFunc = nsnull; if (aPropertyName == nsLayoutAtoms::collapseOffsetProperty) { value = new nsPoint(0, 0); dtorFunc = DestroyPointFunc; @@ -7431,7 +7433,7 @@ nsTableFrame::GetProperty(nsPresContext* aPresContext, } if (!value) return nsnull; - aFrame->SetProperty(aPropertyName, value, dtorFunc); + frameManager->SetFrameProperty(aFrame, aPropertyName, value, dtorFunc); return value; } diff --git a/mozilla/layout/xul/base/src/nsBox.cpp b/mozilla/layout/xul/base/src/nsBox.cpp index cf99ea61a93..6f6c3285a1c 100644 --- a/mozilla/layout/xul/base/src/nsBox.cpp +++ b/mozilla/layout/xul/base/src/nsBox.cpp @@ -570,7 +570,8 @@ nsBox::SetBounds(nsBoxLayoutState& aState, const nsRect& aRect, PRBool aRemoveOv // it if necessary. if (aRemoveOverflowArea && (frame->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN)) { // remove the previously stored overflow area - frame->DeleteProperty(nsLayoutAtoms::overflowAreaProperty); + frame->GetPresContext()->FrameManager()-> + RemoveFrameProperty(frame, nsLayoutAtoms::overflowAreaProperty); frame->RemoveStateBits(NS_FRAME_OUTSIDE_CHILDREN); }