Part 1 of fix for bug 500850 (Make inline style use wrapper cache and slimwrappers). r/sr=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Mon, 13 Jul 2009 13:14:57 +0200
changeset 30385 0ab9276e2dba4c300e8a3a488d49268737298b11
parent 30384 f2c08c358c8712e00d3d24cfa5a1e0633513e3c2
child 30386 b4e7f7d88a8c012d6e273cfde0f7127cfefec1ee
push idunknown
push userunknown
push dateunknown
bugs500850
milestone1.9.2a1pre
Part 1 of fix for bug 500850 (Make inline style use wrapper cache and slimwrappers). r/sr=bz.
content/base/src/nsGenericElement.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
layout/build/nsLayoutModule.cpp
layout/style/Makefile.in
layout/style/nsCSSStyleRule.cpp
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsDOMCSSAttrDeclaration.cpp
layout/style/nsDOMCSSAttrDeclaration.h
layout/style/nsDOMCSSDeclaration.cpp
layout/style/nsDOMCSSDeclaration.h
layout/style/nsICSSDeclaration.h
layout/style/nsIComputedDOMStyle.h
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -1748,20 +1748,16 @@ nsNodeSelectorTearoff::QuerySelectorAll(
 nsGenericElement::nsDOMSlots::nsDOMSlots(PtrBits aFlags)
   : nsINode::nsSlots(aFlags),
     mBindingParent(nsnull)
 {
 }
 
 nsGenericElement::nsDOMSlots::~nsDOMSlots()
 {
-  if (mStyle) {
-    mStyle->DropReference();
-  }
-
   if (mAttributeMap) {
     mAttributeMap->DropReference();
   }
 }
 
 nsGenericElement::nsGenericElement(nsINodeInfo *aNodeInfo)
   : nsIContent(aNodeInfo)
 {
@@ -4052,17 +4048,22 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   }
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo)
 
   // Traverse any DOM slots of interest.
   {
     nsDOMSlots *slots = tmp->GetExistingDOMSlots();
     if (slots) {
+      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "slots mStyle");
+      cb.NoteXPCOMChild(slots->mStyle.get());
+
+      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "slots mAttributeMap");
       cb.NoteXPCOMChild(slots->mAttributeMap.get());
+
       if (tmp->IsNodeOfType(nsINode::eXUL))
         cb.NoteXPCOMChild(slots->mControllers);
       cb.NoteXPCOMChild(
         static_cast<nsIDOMNodeList*>(slots->mChildrenList.get()));
     }
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -170,16 +170,17 @@
 #include "nsIDOMStyleSheetList.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsIDOMCSSRule.h"
 #include "nsICSSRule.h"
 #include "nsICSSRuleList.h"
 #include "nsIDOMRect.h"
 #include "nsIDOMRGBColor.h"
 #include "nsIDOMNSRGBAColor.h"
+#include "nsDOMCSSAttrDeclaration.h"
 
 // XBL related includes.
 #include "nsIXBLService.h"
 #include "nsXBLBinding.h"
 #include "nsBindingManager.h"
 #include "nsIFrame.h"
 #include "nsIPresShell.h"
 #include "nsIDOMViewCSS.h"
@@ -10035,16 +10036,41 @@ nsCSSValueListSH::GetItemAt(nsISupports 
   nsDOMCSSValueList* list = nsDOMCSSValueList::FromSupports(aNative);
 
   return list->GetItemAt(aIndex);
 }
 
 
 // CSSStyleDeclaration helper
 
+NS_IMETHODIMP
+nsCSSStyleDeclSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
+                            JSObject *globalObj, JSObject **parentObj)
+{
+  nsWrapperCache* cache = nsnull;
+  CallQueryInterface(nativeObj, &cache);
+  if (!cache) {
+    return nsDOMClassInfo::PreCreate(nativeObj, cx, globalObj, parentObj);
+  }
+
+  nsICSSDeclaration *declaration = static_cast<nsICSSDeclaration*>(nativeObj);
+  nsISupports *native_parent = declaration->GetParentObject();
+  if (!native_parent) {
+    return NS_ERROR_FAILURE;
+  }
+
+  jsval v;
+  nsresult rv = WrapNative(cx, globalObj, native_parent, &v);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *parentObj = JSVAL_TO_OBJECT(v);
+
+  return NS_SUCCESS_ALLOW_SLIM_WRAPPERS;
+}
+
 nsresult
 nsCSSStyleDeclSH::GetStringAt(nsISupports *aNative, PRInt32 aIndex,
                               nsAString& aResult)
 {
   if (aIndex < 0) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -1418,16 +1418,19 @@ protected:
   virtual ~nsCSSStyleDeclSH()
   {
   }
 
   virtual nsresult GetStringAt(nsISupports *aNative, PRInt32 aIndex,
                                nsAString& aResult);
 
 public:
+  NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
+                       JSObject *globalObj, JSObject **parentObj);
+
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsCSSStyleDeclSH(aData);
   }
 };
 
 
 // CSSRuleList helper
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -134,17 +134,17 @@
 #include "nsISelection.h"
 #include "nsIPrompt.h"
 #include "nsIWebNavigation.h"
 #include "nsIWebBrowser.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsIWebBrowserFind.h"  // For window.find()
 #include "nsIWebContentHandlerRegistrar.h"
 #include "nsIWindowMediator.h"  // For window.find()
-#include "nsIComputedDOMStyle.h"
+#include "nsComputedDOMStyle.h"
 #include "nsIEntropyCollector.h"
 #include "nsDOMCID.h"
 #include "nsDOMError.h"
 #include "nsDOMWindowUtils.h"
 #include "nsIWindowWatcher.h"
 #include "nsPIWindowWatcher.h"
 #include "nsIContentViewer.h"
 #include "nsDOMClassInfo.h"
@@ -202,17 +202,16 @@
 #define FORCE_PR_LOG 1
 #endif
 #include "prlog.h"
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gDOMLeakPRLog;
 #endif
 
-nsIFactory *nsGlobalWindow::sComputedDOMStyleFactory   = nsnull;
 nsIDOMStorageList *nsGlobalWindow::sGlobalStorageList  = nsnull;
 
 static nsIEntropyCollector *gEntropyCollector          = nsnull;
 static PRInt32              gRefCnt                    = 0;
 static PRInt32              gOpenPopupSpamCount        = 0;
 static PopupControlState    gPopupControlState         = openAbused;
 static PRInt32              gRunningTimeoutDepth       = 0;
 static PRBool               gMouseDown                 = PR_FALSE;
@@ -798,17 +797,16 @@ nsGlobalWindow::~nsGlobalWindow()
 
   nsLayoutStatics::Release();
 }
 
 // static
 void
 nsGlobalWindow::ShutDown()
 {
-  NS_IF_RELEASE(sComputedDOMStyleFactory);
   NS_IF_RELEASE(sGlobalStorageList);
 
   if (gDumpFile && gDumpFile != stdout) {
     fclose(gDumpFile);
   }
   gDumpFile = nsnull;
 }
 
@@ -6894,37 +6892,24 @@ nsGlobalWindow::GetComputedStyle(nsIDOME
 
   nsCOMPtr<nsIPresShell> presShell;
   mDocShell->GetPresShell(getter_AddRefs(presShell));
 
   if (!presShell) {
     return NS_OK;
   }
 
-  nsresult rv = NS_OK;
-  nsCOMPtr<nsIComputedDOMStyle> compStyle;
-
-  if (!sComputedDOMStyleFactory) {
-    rv = CallGetClassObject("@mozilla.org/DOM/Level2/CSS/computedStyleDeclaration;1",
-                            &sComputedDOMStyleFactory);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  rv =
-    sComputedDOMStyleFactory->CreateInstance(nsnull,
-                                             NS_GET_IID(nsIComputedDOMStyle),
-                                             getter_AddRefs(compStyle));
-
+  nsRefPtr<nsComputedDOMStyle> compStyle;
+  nsresult rv = NS_NewComputedDOMStyle(aElt, aPseudoElt, presShell,
+                                       getter_AddRefs(compStyle));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = compStyle->Init(aElt, aPseudoElt, presShell);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return compStyle->QueryInterface(NS_GET_IID(nsIDOMCSSStyleDeclaration),
-                                   (void **) aReturn);
+  *aReturn = compStyle.forget().get();
+
+  return NS_OK;
 }
 
 //*****************************************************************************
 // nsGlobalWindow::nsIDOMAbstractView
 //*****************************************************************************
 
 NS_IMETHODIMP
 nsGlobalWindow::GetDocument(nsIDOMDocumentView ** aDocumentView)
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -776,17 +776,16 @@ protected:
 
   nsDataHashtable<nsVoidPtrHashKey, void*> mCachedXBLPrototypeHandlers;
 
   nsCOMPtr<nsIDocument> mSuspendedDoc;
 
   friend class nsDOMScriptableHelper;
   friend class nsDOMWindowUtils;
   friend class PostMessageEvent;
-  static nsIFactory *sComputedDOMStyleFactory;
   static nsIDOMStorageList* sGlobalStorageList;
 };
 
 /*
  * nsGlobalChromeWindow inherits from nsGlobalWindow. It is the global
  * object created for a Chrome Window only.
  */
 class nsGlobalChromeWindow : public nsGlobalWindow,
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -47,17 +47,16 @@
 #include "nsHTMLContentSerializer.h"
 #include "nsHTMLParts.h"
 #include "nsGenericHTMLElement.h"
 #include "nsICSSLoader.h"
 #include "nsICSSParser.h"
 #include "nsICSSStyleSheet.h"
 #include "nsICategoryManager.h"
 #include "nsIComponentManager.h"
-#include "nsIComputedDOMStyle.h"
 #include "nsIContentIterator.h"
 #include "nsIContentSerializer.h"
 #include "nsIController.h"
 #include "nsIControllers.h"
 #include "nsIDOMDOMImplementation.h"
 #include "nsIDOMEventGroup.h"
 #include "nsIDOMRange.h"
 #include "nsIDocument.h"
@@ -512,17 +511,16 @@ MAKE_CTOR(CreateHTMLFragmentSink,       
 MAKE_CTOR(CreateHTMLFragmentSink2,        nsIFragmentContentSink,      NS_NewHTMLFragmentContentSink2)
 MAKE_CTOR(CreateHTMLParanoidFragmentSink, nsIFragmentContentSink,      NS_NewHTMLParanoidFragmentSink)
 MAKE_CTOR(CreateXMLFragmentSink,          nsIFragmentContentSink,      NS_NewXMLFragmentContentSink)
 MAKE_CTOR(CreateXMLFragmentSink2,         nsIFragmentContentSink,      NS_NewXMLFragmentContentSink2)
 MAKE_CTOR(CreateXHTMLParanoidFragmentSink,nsIFragmentContentSink,      NS_NewXHTMLParanoidFragmentSink)
 MAKE_CTOR(CreateSanitizingHTMLSerializer, nsIContentSerializer,        NS_NewSanitizingHTMLSerializer)
 MAKE_CTOR(CreateXBLService,               nsIXBLService,               NS_NewXBLService)
 MAKE_CTOR(CreateContentPolicy,            nsIContentPolicy,            NS_NewContentPolicy)
-MAKE_CTOR(CreateComputedDOMStyle,         nsIComputedDOMStyle,         NS_NewComputedDOMStyle)
 #ifdef MOZ_XUL
 MAKE_CTOR(CreateXULSortService,           nsIXULSortService,           NS_NewXULSortService)
 // NS_NewXULContentBuilder
 // NS_NewXULTreeBuilder
 MAKE_CTOR(CreateXULDocument,              nsIXULDocument,              NS_NewXULDocument)
 // NS_NewXULControllers
 // NS_NewXULPrototypeCache
 MAKE_CTOR(CreateXULPopupManager,      nsISupports,      NS_NewXULPopupManager)
@@ -1230,21 +1228,16 @@ static const nsModuleComponentInfo gComp
 
   { "No data protocol content policy",
     NS_NODATAPROTOCOLCONTENTPOLICY_CID,
     NS_NODATAPROTOCOLCONTENTPOLICY_CONTRACTID,
     nsNoDataProtocolContentPolicyConstructor,
     RegisterNoDataProtocolContentPolicy,
     UnregisterNoDataProtocolContentPolicy },
 
-  { "DOM CSS Computed Style Declaration",
-    NS_COMPUTEDDOMSTYLE_CID,
-    "@mozilla.org/DOM/Level2/CSS/computedStyleDeclaration;1",
-    CreateComputedDOMStyle },
-
   { "XUL Controllers",
     NS_XULCONTROLLERS_CID,
     "@mozilla.org/xul/xul-controllers;1",
     NS_NewXULControllers },
 
 #ifdef MOZ_XUL
   { "XUL Sort Service",
     NS_XULSORTSERVICE_CID,
--- a/layout/style/Makefile.in
+++ b/layout/style/Makefile.in
@@ -101,17 +101,16 @@ EXPORTS		= \
 		nsICSSNameSpaceRule.h \
 		nsICSSParser.h \
 		nsICSSPseudoComparator.h \
 		nsICSSRule.h \
 		nsICSSRuleList.h \
 		nsICSSStyleRule.h \
 		nsICSSStyleRuleDOMWrapper.h \
 		nsICSSStyleSheet.h \
-		nsIComputedDOMStyle.h \
 		nsIHTMLCSSStyleSheet.h \
 		nsIInspectorCSSUtils.h \
 		nsIStyleRule.h \
 		nsIStyleRuleProcessor.h \
 		nsIStyleSheet.h \
 		nsLayoutStylesheetCache.h \
 		nsRuleData.h \
 		nsRuleNode.h \
--- a/layout/style/nsCSSStyleRule.cpp
+++ b/layout/style/nsCSSStyleRule.cpp
@@ -854,31 +854,36 @@ class DOMCSSStyleRuleImpl;
 
 class DOMCSSDeclarationImpl : public nsDOMCSSDeclaration
 {
 public:
   DOMCSSDeclarationImpl(nsICSSStyleRule *aRule);
   virtual ~DOMCSSDeclarationImpl(void);
 
   NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent);
-  virtual void DropReference(void);
+  void DropReference(void);
   virtual nsresult GetCSSDeclaration(nsCSSDeclaration **aDecl,
                                      PRBool aAllocate);
   virtual nsresult GetCSSParsingEnvironment(nsIURI** aSheetURI,
                                             nsIURI** aBaseURI,
                                             nsIPrincipal** aSheetPrincipal,
                                             nsICSSLoader** aCSSLoader,
                                             nsICSSParser** aCSSParser);
   virtual nsresult DeclarationChanged();
 
   // Override |AddRef| and |Release| for being a member of
   // |DOMCSSStyleRuleImpl|.
   NS_IMETHOD_(nsrefcnt) AddRef(void);
   NS_IMETHOD_(nsrefcnt) Release(void);
 
+  virtual nsISupports *GetParentObject()
+  {
+    return nsnull;
+  }
+
   friend class DOMCSSStyleRuleImpl;
 
 protected:
   // This reference is not reference-counted. The rule object tells us
   // when it's about to go away.
   nsICSSStyleRule *mRule;
 
   inline DOMCSSStyleRuleImpl* DomRule();
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -72,50 +72,58 @@
 #include "imgIRequest.h"
 #include "nsInspectorCSSUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsFrameManager.h"
 #include "prlog.h"
 #include "nsCSSKeywords.h"
 #include "nsStyleCoord.h"
 #include "nsDisplayList.h"
+#include "nsDOMCSSDeclaration.h"
 
 #if defined(DEBUG_bzbarsky) || defined(DEBUG_caillon)
 #define DEBUG_ComputedDOMStyle
 #endif
 
 /*
  * This is the implementation of the readonly CSSStyleDeclaration that is
  * returned by the getComputedStyle() function.
  */
 
 static nsComputedDOMStyle *sCachedComputedDOMStyle;
 
 nsresult
-NS_NewComputedDOMStyle(nsIComputedDOMStyle** aComputedStyle)
+NS_NewComputedDOMStyle(nsIDOMElement *aElement, const nsAString &aPseudoElt,
+                       nsIPresShell *aPresShell,
+                       nsComputedDOMStyle **aComputedStyle)
 {
   NS_ENSURE_ARG_POINTER(aComputedStyle);
 
+  nsRefPtr<nsComputedDOMStyle> computedStyle;
   if (sCachedComputedDOMStyle) {
     // There's an unused nsComputedDOMStyle cached, use it.
     // But before we use it, re-initialize the object.
 
     // Oh yeah baby, placement new!
-    *aComputedStyle = new (sCachedComputedDOMStyle) nsComputedDOMStyle();
+    computedStyle = new (sCachedComputedDOMStyle) nsComputedDOMStyle();
 
     sCachedComputedDOMStyle = nsnull;
   } else {
     // No nsComputedDOMStyle cached, create a new one.
 
-    *aComputedStyle = new nsComputedDOMStyle();
-    NS_ENSURE_TRUE(*aComputedStyle, NS_ERROR_OUT_OF_MEMORY);
+    computedStyle = new nsComputedDOMStyle();
+    NS_ENSURE_TRUE(computedStyle, NS_ERROR_OUT_OF_MEMORY);
   }
 
-  NS_ADDREF(*aComputedStyle);
-
+  nsresult rv = computedStyle->Init(aElement, aPseudoElt, aPresShell);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aComputedStyle = nsnull;
+  computedStyle.swap(*aComputedStyle);
+  
   return NS_OK;
 }
 
 static nsIFrame*
 GetContainingBlockFor(nsIFrame* aFrame) {
   if (!aFrame) {
     return nsnull;
   }
@@ -126,44 +134,56 @@ nsComputedDOMStyle::nsComputedDOMStyle()
   : mInner(this), mDocumentWeak(nsnull), mOuterFrame(nsnull),
     mInnerFrame(nsnull), mPresShell(nsnull), mAppUnitsPerInch(0)
 {
 }
 
 
 nsComputedDOMStyle::~nsComputedDOMStyle()
 {
+  ClearWrapper();
 }
 
 void
 nsComputedDOMStyle::Shutdown()
 {
   // We want to de-allocate without calling the dtor since we
   // already did that manually in doDestroyComputedDOMStyle(),
   // so cast our cached object to something that doesn't know
   // about our dtor.
   delete reinterpret_cast<char*>(sCachedComputedDOMStyle);
   sCachedComputedDOMStyle = nsnull;
 }
 
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsComputedDOMStyle)
+NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsComputedDOMStyle)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_ROOT_END
 NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsComputedDOMStyle)
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsComputedDOMStyle)
+  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsComputedDOMStyle)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContent)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 // QueryInterface implementation for nsComputedDOMStyle
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsComputedDOMStyle)
-  NS_INTERFACE_MAP_ENTRY(nsIComputedDOMStyle)
-  NS_INTERFACE_MAP_ENTRY(nsICSSDeclaration)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration)
+NS_INTERFACE_TABLE_HEAD(nsComputedDOMStyle)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_OFFSET_AND_INTERFACE_TABLE_BEGIN(nsComputedDOMStyle)
+    NS_INTERFACE_TABLE_ENTRY(nsComputedDOMStyle, nsICSSDeclaration)
+    NS_INTERFACE_TABLE_ENTRY(nsComputedDOMStyle,
+                             nsIDOMCSSStyleDeclaration)
+    NS_INTERFACE_TABLE_ENTRY(nsComputedDOMStyle, nsISupports)
+  NS_OFFSET_AND_INTERFACE_TABLE_END
+  NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
+  NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsComputedDOMStyle)
   NS_INTERFACE_MAP_ENTRY_AGGREGATED(nsIDOMCSS2Properties, &mInner)
   NS_INTERFACE_MAP_ENTRY_AGGREGATED(nsIDOMNSCSS2Properties, &mInner)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIComputedDOMStyle)
   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(ComputedCSSStyleDeclaration)
 NS_INTERFACE_MAP_END
 
 
 static void doDestroyComputedDOMStyle(nsComputedDOMStyle *aComputedStyle)
 {
   if (!sCachedComputedDOMStyle) {
     // The cache is empty, store aComputedStyle in the cache.
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -36,51 +36,57 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* DOM object returned from element.getComputedStyle() */
 
 #ifndef nsComputedDOMStyle_h__
 #define nsComputedDOMStyle_h__
 
-#include "nsIComputedDOMStyle.h"
+#include "nsICSSDeclaration.h"
 
 #include "nsROCSSPrimitiveValue.h"
 #include "nsDOMCSSDeclaration.h"
 #include "nsDOMCSSRGBColor.h"
 #include "nsDOMCSSValueList.h"
 #include "nsCSSProps.h"
 
 #include "nsIPresShell.h"
 #include "nsIContent.h"
 #include "nsIFrame.h"
 #include "nsCOMPtr.h"
 #include "nsWeakReference.h"
 #include "nsAutoPtr.h"
 #include "nsStyleStruct.h"
 
-class nsComputedDOMStyle : public nsIComputedDOMStyle
+class nsComputedDOMStyle : public nsICSSDeclaration,
+                           public nsWrapperCache
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS(nsComputedDOMStyle)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsComputedDOMStyle)
 
   NS_IMETHOD Init(nsIDOMElement *aElement,
                   const nsAString& aPseudoElt,
                   nsIPresShell *aPresShell);
 
   NS_DECL_NSICSSDECLARATION
 
   NS_DECL_NSIDOMCSSSTYLEDECLARATION
 
   nsComputedDOMStyle();
   virtual ~nsComputedDOMStyle();
 
   static void Shutdown();
 
+  virtual nsISupports *GetParentObject()
+  {
+    return mContent;
+  }
+
 private:
   void AssertFlushedPendingReflows() {
     NS_ASSERTION(mFlushedPendingReflows,
                  "property getter should have been marked layout-dependent");
   }
   
 #define STYLE_STRUCT(name_, checkdata_cb_, ctor_args_)                  \
   const nsStyle##name_ * GetStyle##name_() {                            \
@@ -443,10 +449,15 @@ private:
 
   PRInt32 mAppUnitsPerInch; /* For unit conversions */
 
 #ifdef DEBUG
   PRBool mFlushedPendingReflows;
 #endif
 };
 
+nsresult 
+NS_NewComputedDOMStyle(nsIDOMElement *aElement, const nsAString &aPseudoElt,
+                       nsIPresShell *aPresShell,
+                       nsComputedDOMStyle **aComputedStyle);
+
 #endif /* nsComputedDOMStyle_h__ */
 
--- a/layout/style/nsDOMCSSAttrDeclaration.cpp
+++ b/layout/style/nsDOMCSSAttrDeclaration.cpp
@@ -47,39 +47,55 @@
 #include "nsIURI.h"
 #include "nsINameSpaceManager.h"
 #include "nsStyleConsts.h"
 #include "nsContentUtils.h"
 #include "nsIContent.h"
 #include "nsIPrincipal.h"
 
 nsDOMCSSAttributeDeclaration::nsDOMCSSAttributeDeclaration(nsIContent *aContent)
+  : mContent(aContent)
 {
   MOZ_COUNT_CTOR(nsDOMCSSAttributeDeclaration);
 
-  // This reference is not reference-counted. The content
-  // object tells us when its about to go away.
   NS_ASSERTION(aContent && aContent->IsNodeOfType(nsINode::eELEMENT),
                "Inline style for non-element content?");
-  mContent = aContent;
 }
 
 nsDOMCSSAttributeDeclaration::~nsDOMCSSAttributeDeclaration()
 {
   MOZ_COUNT_DTOR(nsDOMCSSAttributeDeclaration);
 }
 
-NS_IMPL_ADDREF(nsDOMCSSAttributeDeclaration)
-NS_IMPL_RELEASE(nsDOMCSSAttributeDeclaration)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMCSSAttributeDeclaration)
+
+NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsDOMCSSAttributeDeclaration)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_ROOT_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMCSSAttributeDeclaration)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContent)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-void
-nsDOMCSSAttributeDeclaration::DropReference()
-{
-  mContent = nsnull;
-}
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMCSSAttributeDeclaration)
+  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMCSSAttributeDeclaration)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContent)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_INTERFACE_MAP_BEGIN(nsDOMCSSAttributeDeclaration)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsDOMCSSAttributeDeclaration)
+NS_IMPL_QUERY_TAIL_INHERITING(nsDOMCSSDeclaration)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMCSSAttributeDeclaration)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMCSSAttributeDeclaration)
 
 nsresult
 nsDOMCSSAttributeDeclaration::DeclarationChanged()
 {
   NS_ASSERTION(mContent, "Must have content node to set the decl!");
   nsICSSStyleRule* oldRule = mContent->GetInlineStyleRule();
   NS_ASSERTION(oldRule, "content must have rule");
 
--- a/layout/style/nsDOMCSSAttrDeclaration.h
+++ b/layout/style/nsDOMCSSAttrDeclaration.h
@@ -35,49 +35,50 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* DOM object for element.style */
 
 #ifndef nsDOMCSSAttributeDeclaration_h___
 #define nsDOMCSSAttributeDeclaration_h___
 
-#include "nsIDOMCSSStyleDeclaration.h"
 #include "nsDOMCSSDeclaration.h"
 
 #include "nsString.h"
+#include "nsWrapperCache.h"
+#include "nsIContent.h"
 
-class nsIContent;
 class nsICSSLoader;
 class nsICSSParser;
 
-class nsDOMCSSAttributeDeclaration : public nsDOMCSSDeclaration
+class nsDOMCSSAttributeDeclaration : public nsDOMCSSDeclaration,
+                                     public nsWrapperCache
 {
 public:
   nsDOMCSSAttributeDeclaration(nsIContent *aContent);
   ~nsDOMCSSAttributeDeclaration();
 
-  // impl AddRef/Release; QI is implemented by our parent class
-  NS_IMETHOD_(nsrefcnt) AddRef(void);
-  NS_IMETHOD_(nsrefcnt) Release(void);
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMCSSAttributeDeclaration)
 
-  virtual void DropReference();
   // If GetCSSDeclaration returns non-null, then the decl it returns
   // is owned by our current style rule.
   virtual nsresult GetCSSDeclaration(nsCSSDeclaration **aDecl,
                                      PRBool aAllocate);
   virtual nsresult GetCSSParsingEnvironment(nsIURI** aSheetURI,
                                             nsIURI** aBaseURI,
                                             nsIPrincipal** aSheetPrincipal,
                                             nsICSSLoader** aCSSLoader,
                                             nsICSSParser** aCSSParser);
   NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent);
 
+  virtual nsISupports *GetParentObject()
+  {
+    return mContent;
+  }
+
 protected:
   virtual nsresult DeclarationChanged();
   
-  nsAutoRefCnt mRefCnt;
-  NS_DECL_OWNINGTHREAD
-
-  nsIContent *mContent;
+  nsCOMPtr<nsIContent> mContent;
 };
 
 #endif /* nsDOMCSSAttributeDeclaration_h___ */
--- a/layout/style/nsDOMCSSDeclaration.cpp
+++ b/layout/style/nsDOMCSSDeclaration.cpp
@@ -57,24 +57,25 @@ nsDOMCSSDeclaration::nsDOMCSSDeclaration
   : mInner(this)
 {
 }
 
 nsDOMCSSDeclaration::~nsDOMCSSDeclaration()
 {
 }
 
-
-// QueryInterface implementation for nsDOMCSSDeclaration
-NS_INTERFACE_MAP_BEGIN(nsDOMCSSDeclaration)
-  NS_INTERFACE_MAP_ENTRY(nsICSSDeclaration)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration)
+NS_INTERFACE_TABLE_HEAD(nsDOMCSSDeclaration)
+  NS_OFFSET_AND_INTERFACE_TABLE_BEGIN(nsDOMCSSDeclaration)
+    NS_INTERFACE_TABLE_ENTRY(nsDOMCSSDeclaration, nsICSSDeclaration)
+    NS_INTERFACE_TABLE_ENTRY(nsDOMCSSDeclaration, nsIDOMCSSStyleDeclaration)
+    NS_INTERFACE_TABLE_ENTRY(nsDOMCSSDeclaration, nsISupports)
+  NS_OFFSET_AND_INTERFACE_TABLE_END
+  NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
   NS_INTERFACE_MAP_ENTRY_AGGREGATED(nsIDOMCSS2Properties, &mInner)
   NS_INTERFACE_MAP_ENTRY_AGGREGATED(nsIDOMNSCSS2Properties, &mInner)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMCSSStyleDeclaration)
   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSStyleDeclaration)
 NS_INTERFACE_MAP_END
 
 NS_IMETHODIMP
 nsDOMCSSDeclaration::GetPropertyValue(const nsCSSProperty aPropID,
                                       nsAString& aValue)
 {
   NS_PRECONDITION(aPropID != eCSSProperty_UNKNOWN,
--- a/layout/style/nsDOMCSSDeclaration.h
+++ b/layout/style/nsDOMCSSDeclaration.h
@@ -88,17 +88,16 @@ public:
   NS_IMETHOD GetPropertyPriority(const nsAString & propertyName,
                                  nsAString & _retval);
   NS_IMETHOD SetProperty(const nsAString & propertyName,
                          const nsAString & value, const nsAString & priority);
   NS_IMETHOD GetLength(PRUint32 *aLength);
   NS_IMETHOD Item(PRUint32 index, nsAString & _retval);
   NS_IMETHOD GetParentRule(nsIDOMCSSRule * *aParentRule) = 0; 
 
-  virtual void DropReference() = 0;
 protected:
   // Always fills in the out parameter, even on failure, and if the out
   // parameter is null the nsresult will be the correct thing to
   // propagate.
   virtual nsresult GetCSSDeclaration(nsCSSDeclaration **aDecl,
                                      PRBool aAllocate) = 0;
   virtual nsresult DeclarationChanged() = 0;
   
--- a/layout/style/nsICSSDeclaration.h
+++ b/layout/style/nsICSSDeclaration.h
@@ -79,16 +79,18 @@ public:
   
   /**
    * Method analogous to nsIDOMCSSStyleDeclaration::SetProperty.  This
    * method does NOT allow setting a priority (the priority will
    * always be set to default priority).
    */
   NS_IMETHOD SetPropertyValue(const nsCSSProperty aPropID,
                               const nsAString& aValue) = 0;
+
+  virtual nsISupports *GetParentObject() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsICSSDeclaration, NS_ICSSDECLARATION_IID)
 
 #define NS_DECL_NSICSSDECLARATION                               \
   NS_IMETHOD GetPropertyValue(const nsCSSProperty aPropID,    \
                               nsAString& aValue);               \
   NS_IMETHOD SetPropertyValue(const nsCSSProperty aPropID,    \
deleted file mode 100644
--- a/layout/style/nsIComputedDOMStyle.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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) 1999
- * 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 ***** */
-
-/* DOM object returned from element.getComputedStyle() */
-
-#ifndef nsIComputedDOMStyle_h___
-#define nsIComputedDOMStyle_h___
-
-#include "nsICSSDeclaration.h"
-
-class nsIDOMElement;
-class nsIPresShell;
-
-#define NS_ICOMPUTEDDOMSTYLE_IID \
- { 0x5f0197a1, 0xa873, 0x44e5, \
-    {0x96, 0x31, 0xac, 0xd6, 0xca, 0xb4, 0xf1, 0xe0 } }
-
-class nsIComputedDOMStyle : public nsICSSDeclaration
-{
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICOMPUTEDDOMSTYLE_IID)
-
-  NS_IMETHOD Init(nsIDOMElement *aElement, const nsAString& aPseudoElt,
-                  nsIPresShell *aPresShell) = 0;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsIComputedDOMStyle, NS_ICOMPUTEDDOMSTYLE_IID)
-
-nsresult 
-NS_NewComputedDOMStyle(nsIComputedDOMStyle** aComputedStyle);
-
-#endif /* nsIComputedDOMStyle_h___ */