diff --git a/mozilla/content/xul/content/src/Makefile.in b/mozilla/content/xul/content/src/Makefile.in index 7529a983f6c..fd87bb3fde8 100644 --- a/mozilla/content/xul/content/src/Makefile.in +++ b/mozilla/content/xul/content/src/Makefile.in @@ -69,6 +69,7 @@ REQUIRES = xpcom \ webshell \ view \ htmlparser \ + docshell \ $(NULL) ifdef MOZ_XUL diff --git a/mozilla/content/xul/content/src/nsXULElement.cpp b/mozilla/content/xul/content/src/nsXULElement.cpp index 4b3ddb7ba48..b6e728295d8 100644 --- a/mozilla/content/xul/content/src/nsXULElement.cpp +++ b/mozilla/content/xul/content/src/nsXULElement.cpp @@ -135,7 +135,7 @@ #include "nsGkAtoms.h" #include "nsXULContentUtils.h" #include "nsNodeUtils.h" - +#include "nsFrameLoader.h" #include "prlog.h" #include "rdf.h" @@ -215,26 +215,32 @@ PRUint32 nsXULPrototypeAttribute::gNumCacheSets; PRUint32 nsXULPrototypeAttribute::gNumCacheFills; #endif -class nsXULElementTearoff : public nsIDOMElementCSSInlineStyle +class nsXULElementTearoff : public nsIDOMElementCSSInlineStyle, + public nsIFrameLoaderOwner { public: - NS_DECL_ISUPPORTS + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULElementTearoff, + nsIDOMElementCSSInlineStyle) nsXULElementTearoff(nsXULElement *aElement) : mElement(aElement) { } - NS_FORWARD_NSIDOMELEMENTCSSINLINESTYLE(mElement->) - + NS_FORWARD_NSIDOMELEMENTCSSINLINESTYLE(static_cast(mElement.get())->) + NS_FORWARD_NSIFRAMELOADEROWNER(static_cast(mElement.get())->); private: - nsRefPtr mElement; + nsCOMPtr mElement; }; -NS_IMPL_ADDREF(nsXULElementTearoff) -NS_IMPL_RELEASE(nsXULElementTearoff) +NS_IMPL_CYCLE_COLLECTION_1(nsXULElementTearoff, mElement) -NS_INTERFACE_MAP_BEGIN(nsXULElementTearoff) +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULElementTearoff) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULElementTearoff) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULElementTearoff) + NS_INTERFACE_MAP_ENTRY(nsIFrameLoaderOwner) NS_INTERFACE_MAP_ENTRY(nsIDOMElementCSSInlineStyle) NS_INTERFACE_MAP_END_AGGREGATED(mElement) @@ -257,6 +263,9 @@ nsXULElement::nsXULSlots::nsXULSlots(PtrBits aFlags) nsXULElement::nsXULSlots::~nsXULSlots() { NS_IF_RELEASE(mControllers); // Forces release + if (mFrameLoader) { + mFrameLoader->Destroy(); + } } nsINode::nsSlots* @@ -405,6 +414,9 @@ nsXULElement::QueryInterface(REFNSIID aIID, void** aInstancePtr) } else if (aIID.Equals(NS_GET_IID(nsIClassInfo))) { inst = NS_GetDOMClassInfoInstance(eDOMClassInfo_XULElement_id); NS_ENSURE_TRUE(inst, NS_ERROR_OUT_OF_MEMORY); + } else if (aIID.Equals(NS_GET_IID(nsIFrameLoaderOwner))) { + inst = static_cast(new nsXULElementTearoff(this)); + NS_ENSURE_TRUE(inst, NS_ERROR_OUT_OF_MEMORY); } else { return PostQueryInterface(aIID, aInstancePtr); } @@ -812,6 +824,29 @@ nsXULElement::MaybeAddPopupListener(nsIAtom* aLocalName) // nsIContent interface // +nsresult +nsXULElement::BindToTree(nsIDocument* aDocument, + nsIContent* aParent, + nsIContent* aBindingParent, + PRBool aCompileEventHandlers) +{ + nsresult rv = nsGenericElement::BindToTree(aDocument, aParent, + aBindingParent, + aCompileEventHandlers); + NS_ENSURE_SUCCESS(rv, rv); + + if (aDocument) { + // We're in a document now. Kick off the frame load. + nsCOMPtr fl; + GetFrameLoader(getter_AddRefs(fl)); + if (fl) { + fl->LoadFrame(); + } + } + + return rv; +} + void nsXULElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent) { @@ -826,9 +861,18 @@ nsXULElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent) // mDocument in nsGlobalWindow::SetDocShell, but I'm not // sure whether that would fix all possible cycles through // mControllers.) - nsDOMSlots* slots = GetExistingDOMSlots(); + nsXULSlots* slots = static_cast(GetExistingDOMSlots()); if (slots) { NS_IF_RELEASE(slots->mControllers); + if (slots->mFrameLoader) { + // This element is being taken out of the document, destroy the + // possible frame loader. + // XXXbz we really want to only partially destroy the frame + // loader... we don't want to tear down the docshell. Food for + // later bug. + slots->mFrameLoader->Destroy(); + slots->mFrameLoader = nsnull; + } } nsGenericElement::UnbindFromTree(aDeep, aNullParent); @@ -1066,6 +1110,14 @@ nsXULElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName, SetTitlebarColor(color); } + if (aName == nsGkAtoms::src && document) { + nsCOMPtr fl; + GetFrameLoader(getter_AddRefs(fl)); + if (fl) { + fl->LoadFrame(); + } + } + // XXX need to check if they're changing an event handler: if // so, then we need to unhook the old one. Or something. } @@ -1473,9 +1525,13 @@ nsXULElement::GetAttrCount() const void nsXULElement::DestroyContent() { - nsDOMSlots* slots = GetExistingDOMSlots(); + nsXULSlots* slots = static_cast(GetExistingDOMSlots()); if (slots) { - NS_IF_RELEASE(slots->mControllers); + NS_IF_RELEASE(slots->mControllers); + if (slots->mFrameLoader) { + slots->mFrameLoader->Destroy(); + slots->mFrameLoader = nsnull; + } } nsGenericElement::DestroyContent(); @@ -1948,6 +2004,28 @@ nsXULElement::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) return NS_OK; } +nsresult +nsXULElement::GetFrameLoader(nsIFrameLoader** aFrameLoader) +{ + *aFrameLoader = nsnull; + // Allow frame loader only on objects for which a container box object + // can be obtained. + nsIAtom* tag = Tag(); + if (tag != nsGkAtoms::browser && + tag != nsGkAtoms::editor && + tag != nsGkAtoms::iframe) { + return NS_OK; + } + nsXULSlots* slots = static_cast(GetSlots()); + NS_ENSURE_TRUE(slots, NS_ERROR_OUT_OF_MEMORY); + if (!slots->mFrameLoader && IsInDoc()) { + slots->mFrameLoader = new nsFrameLoader(this); + NS_ENSURE_TRUE(slots->mFrameLoader, NS_ERROR_OUT_OF_MEMORY); + } + NS_IF_ADDREF(*aFrameLoader = slots->mFrameLoader); + return NS_OK; +} + NS_IMETHODIMP nsXULElement::GetParentTree(nsIDOMXULMultiSelectControlElement** aTreeElement) { diff --git a/mozilla/content/xul/content/src/nsXULElement.h b/mozilla/content/xul/content/src/nsXULElement.h index dd084f0b0f5..94c902cd1ee 100644 --- a/mozilla/content/xul/content/src/nsXULElement.h +++ b/mozilla/content/xul/content/src/nsXULElement.h @@ -77,6 +77,7 @@ #include "nsAutoPtr.h" #include "nsGenericElement.h" #include "nsDOMScriptObjectHolder.h" +#include "nsIFrameLoader.h" class nsIDocument; class nsString; @@ -548,6 +549,9 @@ public: PRBool aNotify); // nsIContent + virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, + nsIContent* aBindingParent, + PRBool aCompileEventHandlers); virtual void UnbindFromTree(PRBool aDeep, PRBool aNullParent); virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify); virtual nsIAtom *GetIDAttributeName() const; @@ -620,6 +624,8 @@ public: nsresult GetStyle(nsIDOMCSSStyleDeclaration** aStyle); + nsresult GetFrameLoader(nsIFrameLoader** aFrameLoader); + virtual void RecompileScriptEventListeners(); // This function should ONLY be used by BindToTree implementations. @@ -655,6 +661,8 @@ protected: public: nsXULSlots(PtrBits aFlags); virtual ~nsXULSlots(); + + nsCOMPtr mFrameLoader; }; virtual nsINode::nsSlots* CreateSlots(); diff --git a/mozilla/layout/generic/nsFrameFrame.cpp b/mozilla/layout/generic/nsFrameFrame.cpp index 6e12375db27..d87c7d9042f 100644 --- a/mozilla/layout/generic/nsFrameFrame.cpp +++ b/mozilla/layout/generic/nsFrameFrame.cpp @@ -211,13 +211,12 @@ protected: nsCOMPtr mFrameLoader; nsIView* mInnerView; PRPackedBool mDidCreateDoc; - PRPackedBool mOwnsFrameLoader; PRPackedBool mIsInline; PRPackedBool mPostedReflowCallback; }; nsSubDocumentFrame::nsSubDocumentFrame(nsStyleContext* aContext) - : nsLeafFrame(aContext), mDidCreateDoc(PR_FALSE), mOwnsFrameLoader(PR_FALSE), + : nsLeafFrame(aContext), mDidCreateDoc(PR_FALSE), mIsInline(PR_FALSE), mPostedReflowCallback(PR_FALSE) { } @@ -635,13 +634,8 @@ nsSubDocumentFrame::AttributeChanged(PRInt32 aNameSpaceID, return NS_OK; } - if (aAttribute == nsGkAtoms::src) { - if (mOwnsFrameLoader && mFrameLoader) { - mFrameLoader->LoadFrame(); - } - } // If the noResize attribute changes, dis/allow frame to be resized - else if (aAttribute == nsGkAtoms::noresize) { + if (aAttribute == nsGkAtoms::noresize) { // Note that we're not doing content type checks, but that's ok -- if // they'd fail we will just end up with a null framesetFrame. if (mContent->GetParent()->Tag() == nsGkAtoms::frameset) { @@ -774,13 +768,6 @@ nsSubDocumentFrame::Destroy() } } - if (mFrameLoader && mOwnsFrameLoader) { - // We own this frame loader, and we're going away, so destroy our - // frame loader. - - mFrameLoader->Destroy(); - } - nsLeafFrame::Destroy(); } @@ -820,21 +807,7 @@ nsSubDocumentFrame::GetDocShell(nsIDocShell **aDocShell) loaderOwner->GetFrameLoader(getter_AddRefs(mFrameLoader)); } - if (!mFrameLoader) { - // No frame loader available from the content, create our own... - mFrameLoader = new nsFrameLoader(content); - if (!mFrameLoader) - return NS_ERROR_OUT_OF_MEMORY; - - // ... remember that we own this frame loader... - mOwnsFrameLoader = PR_TRUE; - - // ... and tell it to start loading. - // the failure to load a URL does not constitute failure to - // create/initialize the docshell and therefore the LoadFrame() - // call's return value should not be propagated. - mFrameLoader->LoadFrame(); - } + NS_ENSURE_STATE(mFrameLoader); } return mFrameLoader->GetDocShell(aDocShell);