Bug 395609, r=roc+sicking, sr=sicking, a=beltzner

This commit is contained in:
Olli.Pettay@helsinki.fi 2008-03-21 04:18:10 -07:00
Родитель 42f36fb417
Коммит e0bc1058eb
5 изменённых файлов: 118 добавлений и 44 удалений

Просмотреть файл

@ -508,10 +508,13 @@
</vbox>
</hbox>
#ifdef TOOLBAR_CUSTOMIZATION_SHEET
<panel id="customizeToolbarSheetPopup" noautohide="true">
<panel id="customizeToolbarSheetPopup" noautohide="true"
onpopupshowing="document.getElementById('customizeToolbarSheetIFrame')
.setAttribute('src', 'chrome://global/content/customizeToolbar.xul');"
onpopuphidden="document.getElementById('customizeToolbarSheetIFrame')
.setAttribute('src', 'about:blank');">
<iframe id="customizeToolbarSheetIFrame"
style="&dialog.style;"
src="chrome://global/content/customizeToolbar.xul"
hidden="true"/>
</panel>
#endif

Просмотреть файл

@ -69,6 +69,7 @@ REQUIRES = xpcom \
webshell \
view \
htmlparser \
docshell \
$(NULL)
ifdef MOZ_XUL

Просмотреть файл

@ -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<nsXULElement*>(mElement.get())->)
NS_FORWARD_NSIFRAMELOADEROWNER(static_cast<nsXULElement*>(mElement.get())->);
private:
nsRefPtr<nsXULElement> mElement;
nsCOMPtr<nsIDOMXULElement> 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<nsIFrameLoaderOwner*>(new nsXULElementTearoff(this));
NS_ENSURE_TRUE(inst, NS_ERROR_OUT_OF_MEMORY);
} else {
return PostQueryInterface(aIID, aInstancePtr);
}
@ -854,6 +866,25 @@ 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.
LoadSrc();
}
return rv;
}
void
nsXULElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
{
@ -868,9 +899,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<nsXULSlots*>(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);
@ -1108,6 +1148,10 @@ nsXULElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
SetTitlebarColor(color);
}
if (aName == nsGkAtoms::src && document) {
LoadSrc();
}
// XXX need to check if they're changing an event handler: if
// so, then we need to unhook the old one. Or something.
}
@ -1517,9 +1561,13 @@ nsXULElement::GetAttrCount() const
void
nsXULElement::DestroyContent()
{
nsDOMSlots* slots = GetExistingDOMSlots();
nsXULSlots* slots = static_cast<nsXULSlots*>(GetExistingDOMSlots());
if (slots) {
NS_IF_RELEASE(slots->mControllers);
NS_IF_RELEASE(slots->mControllers);
if (slots->mFrameLoader) {
slots->mFrameLoader->Destroy();
slots->mFrameLoader = nsnull;
}
}
nsGenericElement::DestroyContent();
@ -1992,6 +2040,44 @@ nsXULElement::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
return NS_OK;
}
nsresult
nsXULElement::LoadSrc()
{
// 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;
}
if (!IsInDoc() ||
!GetOwnerDoc()->GetRootContent() ||
GetOwnerDoc()->GetRootContent()->
NodeInfo()->Equals(nsGkAtoms::overlay, kNameSpaceID_XUL)) {
return NS_OK;
}
nsXULSlots* slots = static_cast<nsXULSlots*>(GetSlots());
NS_ENSURE_TRUE(slots, NS_ERROR_OUT_OF_MEMORY);
if (!slots->mFrameLoader) {
slots->mFrameLoader = new nsFrameLoader(this);
NS_ENSURE_TRUE(slots->mFrameLoader, NS_ERROR_OUT_OF_MEMORY);
}
return slots->mFrameLoader->LoadFrame();
}
nsresult
nsXULElement::GetFrameLoader(nsIFrameLoader **aFrameLoader)
{
*aFrameLoader = nsnull;
nsXULSlots* slots = static_cast<nsXULSlots*>(GetExistingSlots());
if (slots) {
NS_IF_ADDREF(*aFrameLoader = slots->mFrameLoader);
}
return NS_OK;
}
NS_IMETHODIMP
nsXULElement::GetParentTree(nsIDOMXULMultiSelectControlElement** aTreeElement)
{

Просмотреть файл

@ -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,9 @@ public:
nsresult GetStyle(nsIDOMCSSStyleDeclaration** aStyle);
nsresult GetFrameLoader(nsIFrameLoader** aFrameLoader);
virtual void RecompileScriptEventListeners();
// This function should ONLY be used by BindToTree implementations.
@ -655,10 +662,14 @@ protected:
public:
nsXULSlots(PtrBits aFlags);
virtual ~nsXULSlots();
nsCOMPtr<nsIFrameLoader> mFrameLoader;
};
virtual nsINode::nsSlots* CreateSlots();
nsresult LoadSrc();
// Required fields
nsRefPtr<nsXULPrototypeElement> mPrototype;

Просмотреть файл

@ -212,13 +212,12 @@ protected:
nsCOMPtr<nsIFrameLoader> 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)
{
}
@ -646,13 +645,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) {
@ -785,13 +779,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();
}
@ -831,21 +818,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);