diff --git a/mozilla/content/base/public/nsIDocument.h b/mozilla/content/base/public/nsIDocument.h index 318116d1e52..fd7b562a846 100644 --- a/mozilla/content/base/public/nsIDocument.h +++ b/mozilla/content/base/public/nsIDocument.h @@ -35,6 +35,7 @@ class nsIStyleSheet; class nsIURL; class nsIViewManager; class nsString; +class nsIWebWidget; class nsIDOMEvent; // IID for the nsIDocument interface @@ -61,6 +62,7 @@ public: NS_IMETHOD LoadURL(nsIURL* aURL, nsIStreamListener* aListener, + nsIWebWidget* aWebWidget, nsIPostData* aPostData = 0) = 0; /** diff --git a/mozilla/content/html/document/src/nsHTMLContentSink.cpp b/mozilla/content/html/document/src/nsHTMLContentSink.cpp index 82e24e80518..8860e70e246 100644 --- a/mozilla/content/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/content/html/document/src/nsHTMLContentSink.cpp @@ -40,9 +40,10 @@ #include "nsIImageMap.h" #include "nsRepository.h" +#include "nsIWebWidget.h" extern nsresult NS_NewHTMLIFrame(nsIHTMLContent** aInstancePtrResult, - nsIAtom* aTag); // XXX move + nsIAtom* aTag, nsIWebWidget* aWebWidget); // XXX move // XXX attribute values have entities in them - use the parsers expander! // XXX Go through a factory for this one @@ -96,7 +97,7 @@ public: return (void*) rv; } - nsresult Init(nsIDocument* aDoc, nsIURL* aURL); + nsresult Init(nsIDocument* aDoc, nsIURL* aURL, nsIWebWidget* aWebWidget); nsIHTMLContent* GetCurrentContainer(eHTMLTags* aType); virtual PRBool SetTitle(const nsString& aValue); @@ -217,6 +218,7 @@ protected: PRTime mUpdateDelta; PRBool mLayoutStarted; PRInt32 mInMonolithicContainer; + nsIWebWidget* mWebWidget; }; // Note: operator new zeros our memory @@ -244,13 +246,14 @@ HTMLContentSink::~HTMLContentSink() NS_IF_RELEASE(mCurrentMap); NS_IF_RELEASE(mCurrentSelect); NS_IF_RELEASE(mCurrentOption); + NS_IF_RELEASE(mWebWidget); if (nsnull != mTitle) { delete mTitle; } } -nsresult HTMLContentSink::Init(nsIDocument* aDoc, nsIURL* aDocURL) +nsresult HTMLContentSink::Init(nsIDocument* aDoc, nsIURL* aDocURL, nsIWebWidget* aWebWidget) { NS_IF_RELEASE(mDocument); mDocument = aDoc; @@ -260,6 +263,10 @@ nsresult HTMLContentSink::Init(nsIDocument* aDoc, nsIURL* aDocURL) mDocumentURL = aDocURL; NS_IF_ADDREF(mDocumentURL); + NS_IF_RELEASE(mWebWidget); + mWebWidget = aWebWidget; + NS_IF_ADDREF(mWebWidget); + // Make root part NS_IF_RELEASE(mRoot); nsresult rv = NS_NewRootPart(&mRoot, aDoc); @@ -1323,7 +1330,7 @@ HTMLContentSink::ProcessIFRAMETag(nsIHTMLContent** aInstancePtrResult, tmp.ToUpperCase(); nsIAtom* atom = NS_NewAtom(tmp); - nsresult rv = NS_NewHTMLIFrame(aInstancePtrResult, atom); + nsresult rv = NS_NewHTMLIFrame(aInstancePtrResult, atom, mWebWidget); NS_RELEASE(atom); return rv; @@ -1425,7 +1432,8 @@ HTMLContentSink::WillResume(void) nsresult NS_NewHTMLContentSink(nsIHTMLContentSink** aInstancePtrResult, nsIDocument* aDoc, - nsIURL* aURL) + nsIURL* aURL, + nsIWebWidget* aWebWidget) { NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); if (nsnull == aInstancePtrResult) { @@ -1435,7 +1443,7 @@ nsresult NS_NewHTMLContentSink(nsIHTMLContentSink** aInstancePtrResult, if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } - nsresult rv = it->Init(aDoc, aURL); + nsresult rv = it->Init(aDoc, aURL, aWebWidget); if (NS_OK != rv) { delete it; return rv; diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp index b4a2abc8ed0..2dce5e5d613 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp @@ -32,6 +32,7 @@ #include "nsIDOMText.h" #include "nsIPostToServer.h" #include "nsIURL.h" +#include "nsIWebWidget.h" static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID); static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); @@ -75,7 +76,7 @@ NS_IMETHODIMP nsHTMLDocument::QueryInterface(REFNSIID aIID, NS_IMETHODIMP nsHTMLDocument::LoadURL(nsIURL* aURL, nsIStreamListener* aListener, - nsIPostData* aPostData) + nsIWebWidget* aWebWidget, nsIPostData* aPostData) { // Delete references to style sheets - this should be done in superclass... PRInt32 index = mStyleSheets.Count(); @@ -114,7 +115,7 @@ nsHTMLDocument::LoadURL(nsIURL* aURL, nsIStreamListener* aListener, nsresult rv = NS_NewParser(&parser); if (NS_OK == rv) { nsIHTMLContentSink* sink; - rv = NS_NewHTMLContentSink(&sink, this, aURL); + rv = NS_NewHTMLContentSink(&sink, this, aURL, aWebWidget); if (NS_OK == rv) { nsIHTMLCSSStyleSheet* styleAttrSheet; if (NS_OK == NS_NewHTMLCSSStyleSheet(&styleAttrSheet, aURL)) { diff --git a/mozilla/content/html/document/src/nsHTMLDocument.h b/mozilla/content/html/document/src/nsHTMLDocument.h index 2655709b96a..b44140d8a73 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.h +++ b/mozilla/content/html/document/src/nsHTMLDocument.h @@ -22,6 +22,7 @@ #include "nsIHTMLDocument.h" class nsIHTMLStyleSheet; +class nsIWebWidget; class nsHTMLDocument : public nsDocument { public: @@ -32,6 +33,7 @@ public: NS_IMETHOD LoadURL(nsIURL* aURL, nsIStreamListener* aListener, + nsIWebWidget* aWebWidget, nsIPostData* aPostData = 0); NS_IMETHOD SetTitle(const nsString& aTitle); diff --git a/mozilla/layout/base/public/nsIDocument.h b/mozilla/layout/base/public/nsIDocument.h index 318116d1e52..fd7b562a846 100644 --- a/mozilla/layout/base/public/nsIDocument.h +++ b/mozilla/layout/base/public/nsIDocument.h @@ -35,6 +35,7 @@ class nsIStyleSheet; class nsIURL; class nsIViewManager; class nsString; +class nsIWebWidget; class nsIDOMEvent; // IID for the nsIDocument interface @@ -61,6 +62,7 @@ public: NS_IMETHOD LoadURL(nsIURL* aURL, nsIStreamListener* aListener, + nsIWebWidget* aWebWidget, nsIPostData* aPostData = 0) = 0; /** diff --git a/mozilla/layout/generic/nsHTMLParts.h b/mozilla/layout/generic/nsHTMLParts.h index d6adf958af3..934a10752a2 100644 --- a/mozilla/layout/generic/nsHTMLParts.h +++ b/mozilla/layout/generic/nsHTMLParts.h @@ -30,12 +30,14 @@ class nsIHTMLContentSink; class nsITextContent; class nsIURL; class nsString; +class nsIWebWidget; // XXX naming consistency puhleeze! extern nsresult NS_NewHTMLContentSink(nsIHTMLContentSink** aInstancePtrResult, nsIDocument* aDoc, - nsIURL* aURL); + nsIURL* aURL, + nsIWebWidget* aWebWidget); // Create an html root part extern nsresult diff --git a/mozilla/layout/html/base/src/nsHTMLParts.h b/mozilla/layout/html/base/src/nsHTMLParts.h index d6adf958af3..934a10752a2 100644 --- a/mozilla/layout/html/base/src/nsHTMLParts.h +++ b/mozilla/layout/html/base/src/nsHTMLParts.h @@ -30,12 +30,14 @@ class nsIHTMLContentSink; class nsITextContent; class nsIURL; class nsString; +class nsIWebWidget; // XXX naming consistency puhleeze! extern nsresult NS_NewHTMLContentSink(nsIHTMLContentSink** aInstancePtrResult, nsIDocument* aDoc, - nsIURL* aURL); + nsIURL* aURL, + nsIWebWidget* aWebWidget); // Create an html root part extern nsresult diff --git a/mozilla/layout/html/document/src/nsHTMLContentSink.cpp b/mozilla/layout/html/document/src/nsHTMLContentSink.cpp index 82e24e80518..8860e70e246 100644 --- a/mozilla/layout/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/layout/html/document/src/nsHTMLContentSink.cpp @@ -40,9 +40,10 @@ #include "nsIImageMap.h" #include "nsRepository.h" +#include "nsIWebWidget.h" extern nsresult NS_NewHTMLIFrame(nsIHTMLContent** aInstancePtrResult, - nsIAtom* aTag); // XXX move + nsIAtom* aTag, nsIWebWidget* aWebWidget); // XXX move // XXX attribute values have entities in them - use the parsers expander! // XXX Go through a factory for this one @@ -96,7 +97,7 @@ public: return (void*) rv; } - nsresult Init(nsIDocument* aDoc, nsIURL* aURL); + nsresult Init(nsIDocument* aDoc, nsIURL* aURL, nsIWebWidget* aWebWidget); nsIHTMLContent* GetCurrentContainer(eHTMLTags* aType); virtual PRBool SetTitle(const nsString& aValue); @@ -217,6 +218,7 @@ protected: PRTime mUpdateDelta; PRBool mLayoutStarted; PRInt32 mInMonolithicContainer; + nsIWebWidget* mWebWidget; }; // Note: operator new zeros our memory @@ -244,13 +246,14 @@ HTMLContentSink::~HTMLContentSink() NS_IF_RELEASE(mCurrentMap); NS_IF_RELEASE(mCurrentSelect); NS_IF_RELEASE(mCurrentOption); + NS_IF_RELEASE(mWebWidget); if (nsnull != mTitle) { delete mTitle; } } -nsresult HTMLContentSink::Init(nsIDocument* aDoc, nsIURL* aDocURL) +nsresult HTMLContentSink::Init(nsIDocument* aDoc, nsIURL* aDocURL, nsIWebWidget* aWebWidget) { NS_IF_RELEASE(mDocument); mDocument = aDoc; @@ -260,6 +263,10 @@ nsresult HTMLContentSink::Init(nsIDocument* aDoc, nsIURL* aDocURL) mDocumentURL = aDocURL; NS_IF_ADDREF(mDocumentURL); + NS_IF_RELEASE(mWebWidget); + mWebWidget = aWebWidget; + NS_IF_ADDREF(mWebWidget); + // Make root part NS_IF_RELEASE(mRoot); nsresult rv = NS_NewRootPart(&mRoot, aDoc); @@ -1323,7 +1330,7 @@ HTMLContentSink::ProcessIFRAMETag(nsIHTMLContent** aInstancePtrResult, tmp.ToUpperCase(); nsIAtom* atom = NS_NewAtom(tmp); - nsresult rv = NS_NewHTMLIFrame(aInstancePtrResult, atom); + nsresult rv = NS_NewHTMLIFrame(aInstancePtrResult, atom, mWebWidget); NS_RELEASE(atom); return rv; @@ -1425,7 +1432,8 @@ HTMLContentSink::WillResume(void) nsresult NS_NewHTMLContentSink(nsIHTMLContentSink** aInstancePtrResult, nsIDocument* aDoc, - nsIURL* aURL) + nsIURL* aURL, + nsIWebWidget* aWebWidget) { NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); if (nsnull == aInstancePtrResult) { @@ -1435,7 +1443,7 @@ nsresult NS_NewHTMLContentSink(nsIHTMLContentSink** aInstancePtrResult, if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } - nsresult rv = it->Init(aDoc, aURL); + nsresult rv = it->Init(aDoc, aURL, aWebWidget); if (NS_OK != rv) { delete it; return rv; diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.cpp b/mozilla/layout/html/document/src/nsHTMLDocument.cpp index b4a2abc8ed0..2dce5e5d613 100644 --- a/mozilla/layout/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/layout/html/document/src/nsHTMLDocument.cpp @@ -32,6 +32,7 @@ #include "nsIDOMText.h" #include "nsIPostToServer.h" #include "nsIURL.h" +#include "nsIWebWidget.h" static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID); static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); @@ -75,7 +76,7 @@ NS_IMETHODIMP nsHTMLDocument::QueryInterface(REFNSIID aIID, NS_IMETHODIMP nsHTMLDocument::LoadURL(nsIURL* aURL, nsIStreamListener* aListener, - nsIPostData* aPostData) + nsIWebWidget* aWebWidget, nsIPostData* aPostData) { // Delete references to style sheets - this should be done in superclass... PRInt32 index = mStyleSheets.Count(); @@ -114,7 +115,7 @@ nsHTMLDocument::LoadURL(nsIURL* aURL, nsIStreamListener* aListener, nsresult rv = NS_NewParser(&parser); if (NS_OK == rv) { nsIHTMLContentSink* sink; - rv = NS_NewHTMLContentSink(&sink, this, aURL); + rv = NS_NewHTMLContentSink(&sink, this, aURL, aWebWidget); if (NS_OK == rv) { nsIHTMLCSSStyleSheet* styleAttrSheet; if (NS_OK == NS_NewHTMLCSSStyleSheet(&styleAttrSheet, aURL)) { diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.h b/mozilla/layout/html/document/src/nsHTMLDocument.h index 2655709b96a..b44140d8a73 100644 --- a/mozilla/layout/html/document/src/nsHTMLDocument.h +++ b/mozilla/layout/html/document/src/nsHTMLDocument.h @@ -22,6 +22,7 @@ #include "nsIHTMLDocument.h" class nsIHTMLStyleSheet; +class nsIWebWidget; class nsHTMLDocument : public nsDocument { public: @@ -32,6 +33,7 @@ public: NS_IMETHOD LoadURL(nsIURL* aURL, nsIStreamListener* aListener, + nsIWebWidget* aWebWidget, nsIPostData* aPostData = 0); NS_IMETHOD SetTitle(const nsString& aTitle); diff --git a/mozilla/layout/html/document/src/nsHTMLIFrame.cpp b/mozilla/layout/html/document/src/nsHTMLIFrame.cpp index 33b7b6f4552..05158d5962c 100644 --- a/mozilla/layout/html/document/src/nsHTMLIFrame.cpp +++ b/mozilla/layout/html/document/src/nsHTMLIFrame.cpp @@ -32,6 +32,7 @@ #include "nsWidgetsCID.h" #include "nsViewsCID.h" #include "nsHTMLAtoms.h" +#include "nsIScrollableView.h" static NS_DEFINE_IID(kIStreamListenerIID, NS_ISTREAMNOTIFICATION_IID); static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); @@ -123,6 +124,8 @@ public: void GetSize(float aPixelsToTwips, nsSize& aSize); PRBool GetURL(nsString& aURLSpec); + PRBool GetName(nsString& aName); + nsScrollPreference GetScrolling(); #if 0 virtual nsContentAttr GetAttribute(nsIAtom* aAttribute, @@ -132,11 +135,15 @@ public: #endif protected: - nsHTMLIFrame(nsIAtom* aTag); + nsHTMLIFrame(nsIAtom* aTag, nsIWebWidget* aParentWebWidget); virtual ~nsHTMLIFrame(); + // this is held for a short time until the frame uses it, so it is not ref counted + nsIWebWidget* mParentWebWidget; + friend nsresult NS_NewHTMLIFrame(nsIHTMLContent** aInstancePtrResult, - nsIAtom* aTag); + nsIAtom* aTag, nsIWebWidget* aWebWidget); + friend class nsHTMLIFrameFrame; }; @@ -193,7 +200,6 @@ float nsHTMLIFrameFrame::GetTwipsToPixels() if (parentSup) { nsIWebWidget* parentWidget; nsresult res = parentSup->QueryInterface(kIWebWidgetIID, (void**)&parentWidget); - NS_RELEASE(parentSup); if (NS_OK == res) { nsIPresContext* presContext = parentWidget->GetPresContext(); NS_RELEASE(parentWidget); @@ -252,33 +258,27 @@ void TempMakeAbsURL(nsIContent* aContent, nsString& aRelURL, nsString& aAbsURL) void nsHTMLIFrameFrame::CreateWebWidget(nsSize aSize, nsString& aURL) { - // create the web widget - NSRepository::CreateInstance(kCWebWidgetCID, nsnull, kIWebWidgetIID, (void**)&mWebWidget); + nsHTMLIFrame* content = (nsHTMLIFrame*)mContent; - if (nsnull == mWebWidget) { + // create the web widget, set its name + NSRepository::CreateInstance(kCWebWidgetCID, nsnull, kIWebWidgetIID, (void**)&mWebWidget); + if (nsnull != mWebWidget) { + nsString frameName; + if (content->GetName(frameName)) { + mWebWidget->SetName(frameName); + } + } + else { NS_ASSERTION(0, "could not create web widget"); return; } + nsresult result; - // Get the parent web widget, set the parentage - nsIFrame* parent; - GetGeometricParent(parent); // don't need to release - nsIWebWidget* parentWebWidget = nsnull; - while (nsnull != parent) { - nsIWebFrame* webFrame; - result = parent->QueryInterface(kIWebFrameIID, (void**)&webFrame); - if (NS_OK == result) { - parentWebWidget = webFrame->GetWebWidget(); - NS_RELEASE(webFrame); - break; - } - parent->GetGeometricParent(parent); - } - if (!parentWebWidget) { - parentWebWidget = mWebWidget->GetRootWebWidget(); - } - mWebWidget->SetContainer(parentWebWidget); + // set the web widget parentage + nsIWebWidget* parentWebWidget = content->mParentWebWidget; + parentWebWidget->AddChild(mWebWidget); + // Get the view manager, conversion float t2p = 0.0f; @@ -290,7 +290,7 @@ void nsHTMLIFrameFrame::CreateWebWidget(nsSize aSize, nsString& aURL) viewMan = presShell->GetViewManager(); NS_RELEASE(presShell); NS_RELEASE(presContext); - NS_RELEASE(parentWebWidget); + //NS_RELEASE(parentWebWidget); // create, init, set the parent of the view @@ -317,7 +317,8 @@ void nsHTMLIFrameFrame::CreateWebWidget(nsSize aSize, nsString& aURL) NS_RELEASE(view); nsRect webBounds(0, 0, NS_TO_INT_ROUND(aSize.width * t2p), NS_TO_INT_ROUND(aSize.height * t2p)); - mWebWidget->Init(widget->GetNativeData(NS_NATIVE_WINDOW), webBounds); + mWebWidget->Init(widget->GetNativeData(NS_NATIVE_WINDOW), webBounds, + content->GetScrolling()); NS_RELEASE(widget); // load the document @@ -361,12 +362,14 @@ nsHTMLIFrameFrame::GetDesiredSize(nsIPresContext* aPresContext, // nsHTMLIFrame -nsHTMLIFrame::nsHTMLIFrame(nsIAtom* aTag) : nsHTMLContainer(aTag) +nsHTMLIFrame::nsHTMLIFrame(nsIAtom* aTag, nsIWebWidget* aParentWebWidget) + : nsHTMLContainer(aTag), mParentWebWidget(aParentWebWidget) { } nsHTMLIFrame::~nsHTMLIFrame() { + mParentWebWidget = nsnull; } nsresult @@ -429,16 +432,47 @@ PRBool nsHTMLIFrame::GetURL(nsString& aURLSpec) return PR_FALSE; } +PRBool nsHTMLIFrame::GetName(nsString& aName) +{ + nsHTMLValue value; + if (eContentAttr_HasValue == (GetAttribute(nsHTMLAtoms::name, value))) { + if (eHTMLUnit_String == value.GetUnit()) { + value.GetStringValue(aName); + return PR_TRUE; + } + } + aName.SetLength(0); + return PR_FALSE; +} + +nsScrollPreference nsHTMLIFrame::GetScrolling() +{ + nsHTMLValue value; + if (eContentAttr_HasValue == (GetAttribute(nsHTMLAtoms::scrolling, value))) { + if (eHTMLUnit_String == value.GetUnit()) { + nsAutoString scrolling; + value.GetStringValue(scrolling); + if (scrolling.EqualsIgnoreCase("yes")) { + return nsScrollPreference_kAlwaysScroll; + } + else if (scrolling.EqualsIgnoreCase("no")) { + return nsScrollPreference_kNeverScroll; + } + } + } + return nsScrollPreference_kAuto; +} + nsresult NS_NewHTMLIFrame(nsIHTMLContent** aInstancePtrResult, - nsIAtom* aTag) + nsIAtom* aTag, nsIWebWidget* aWebWidget) { NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); if (nsnull == aInstancePtrResult) { return NS_ERROR_NULL_POINTER; } - nsIHTMLContent* it = new nsHTMLIFrame(aTag); + nsIHTMLContent* it = new nsHTMLIFrame(aTag, aWebWidget); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; diff --git a/mozilla/layout/html/tests/TestAttributes.cpp b/mozilla/layout/html/tests/TestAttributes.cpp index 304aedb7ded..43188b04b76 100644 --- a/mozilla/layout/html/tests/TestAttributes.cpp +++ b/mozilla/layout/html/tests/TestAttributes.cpp @@ -29,6 +29,7 @@ #include "nsISupportsArray.h" #include "nsDocument.h" #include "nsIURL.h" +#include "nsIWebWidget.h" void testAttributes(nsIHTMLContent* content) { nsIAtom* sBORDER = NS_NewAtom("BORDER"); @@ -168,7 +169,7 @@ class MyDocument : public nsDocument { public: MyDocument(); NS_IMETHOD LoadURL(nsIURL* aURL, nsIStreamListener* aListener, - nsIPostData* aPostData) + nsIWebWidget* aWebWidget, nsIPostData* aPostData) { return NS_OK; } diff --git a/mozilla/webshell/public/nsIDocumentWidget.h b/mozilla/webshell/public/nsIDocumentWidget.h index 3f4788d72ae..e0f813f0824 100644 --- a/mozilla/webshell/public/nsIDocumentWidget.h +++ b/mozilla/webshell/public/nsIDocumentWidget.h @@ -20,6 +20,7 @@ #include "nsIWidget.h" #include "nsRect.h" +#include "nsIScrollableView.h" class nsIDocument; class nsIPostData; class nsIScriptContext; @@ -32,7 +33,8 @@ class nsIDocumentWidget : public nsISupports { public: // Create a native window for this web widget; may be called once virtual nsresult Init(nsNativeWindow aNativeParent, - const nsRect& aBounds) = 0; + const nsRect& aBounds, + nsScrollPreference aScrolling = nsScrollPreference_kAuto) = 0; virtual nsRect GetBounds() = 0; diff --git a/mozilla/webshell/public/nsIWebWidget.h b/mozilla/webshell/public/nsIWebWidget.h index a8c4079fd05..29194f38e4c 100644 --- a/mozilla/webshell/public/nsIWebWidget.h +++ b/mozilla/webshell/public/nsIWebWidget.h @@ -20,6 +20,7 @@ #include "nsweb.h" #include "nsIDocumentWidget.h" +#include "nsIScrollableView.h" class nsIDOMDocument; class nsILinkHandler; class nsIPresContext; @@ -44,7 +45,8 @@ public: // Create a native window for this web widget; may be called once virtual nsresult Init(nsNativeWindow aNativeParent, - const nsRect& aBounds) = 0; + const nsRect& aBounds, + nsScrollPreference aScrolling = nsScrollPreference_kAuto) = 0; // Create a native window for this web widget; may be called once. // Use the given presentation context and document for the widget @@ -53,14 +55,25 @@ public: virtual nsresult Init(nsNativeWindow aNativeParent, const nsRect& aBounds, nsIDocument* aDocument, - nsIPresContext* aPresContext) = 0; + nsIPresContext* aPresContext, + nsScrollPreference aScrolling = nsScrollPreference_kAuto) = 0; - NS_IMETHOD SetContainer(nsISupports* aContainer) = 0; + // XXX instead of nsISupports for aContainer, something like nsIContainer would be better + NS_IMETHOD SetContainer(nsISupports* aContainer, PRBool aRelationship = PR_TRUE) = 0; NS_IMETHOD GetContainer(nsISupports** aResult) = 0; - // XXX temp hack - virtual void SetRootWebWidget(nsIWebWidget* aWebWidget) = 0; + virtual PRInt32 GetNumChildren() = 0; + + NS_IMETHOD AddChild(nsIWebWidget* aChild, PRBool aRelationship = PR_TRUE) = 0; + + NS_IMETHOD GetChildAt(PRInt32 aIndex, nsIWebWidget** aChild) = 0; + + virtual PRBool GetName(nsString& aName) = 0; + virtual void SetName(const nsString& aName) = 0; + virtual nsIWebWidget* GetWebWidgetWithName(const nsString& aName) = 0; + virtual nsIWebWidget* GetTarget(const nsString& aName) = 0; + virtual nsIWebWidget* GetRootWebWidget() = 0; NS_IMETHOD SetLinkHandler(nsILinkHandler* aHandler) = 0; diff --git a/mozilla/webshell/src/nsLinkHandler.cpp b/mozilla/webshell/src/nsLinkHandler.cpp index 5c21b18a8bc..af03aeada58 100644 --- a/mozilla/webshell/src/nsLinkHandler.cpp +++ b/mozilla/webshell/src/nsLinkHandler.cpp @@ -196,7 +196,9 @@ LinkHandlerImpl::HandleLinkClickEvent(const nsString& aURLSpec, nsIPostData* aPostData) { if (nsnull != mWidget) { - mWidget->LoadURL(aURLSpec, nsnull, aPostData); + nsIWebWidget* targetWidget = mWidget->GetTarget(aTargetSpec); + targetWidget->LoadURL(aURLSpec, nsnull, aPostData); + NS_RELEASE(targetWidget); } } diff --git a/mozilla/webshell/src/nsWebWidget.cpp b/mozilla/webshell/src/nsWebWidget.cpp index 9c338fa82f0..055d464eb83 100644 --- a/mozilla/webshell/src/nsWebWidget.cpp +++ b/mozilla/webshell/src/nsWebWidget.cpp @@ -24,7 +24,6 @@ #include "nsIContent.h" #include "nsIDocument.h" #include "nsIFrame.h" -#include "nsIWebFrame.h" #include "nsIWidget.h" #include "nsIScrollbar.h" #include "nsUnitConversion.h" @@ -43,7 +42,7 @@ #include "nsIDOMDocument.h" #include "prprf.h" #include "prtime.h" - +#include "nsVoidArray.h" #include "nscore.h" #include "nsIFactory.h" #include "nsISupports.h" @@ -68,11 +67,13 @@ public: NS_DECL_ISUPPORTS virtual nsresult Init(nsNativeWindow aParent, - const nsRect& aBounds); + const nsRect& aBounds, + nsScrollPreference aScrolling = nsScrollPreference_kAuto); virtual nsresult Init(nsNativeWindow aParent, const nsRect& aBounds, nsIDocument* aDocument, - nsIPresContext* aPresContext); + nsIPresContext* aPresContext, + nsScrollPreference aScrolling = nsScrollPreference_kAuto); virtual nsRect GetBounds(); virtual void SetBounds(const nsRect& aBounds); @@ -80,14 +81,20 @@ public: virtual void Show(); virtual void Hide(); - NS_IMETHOD SetContainer(nsISupports* aContainer); + NS_IMETHOD SetContainer(nsISupports* aContainer, PRBool aRelationship = PR_TRUE); NS_IMETHOD GetContainer(nsISupports** aResult); - // XXX temp hack - virtual void SetRootWebWidget(nsIWebWidget* aWebWidget); + virtual PRInt32 GetNumChildren(); + NS_IMETHOD AddChild(nsIWebWidget* aChild, PRBool aRelationship = PR_TRUE); + NS_IMETHOD GetChildAt(PRInt32 aIndex, nsIWebWidget** aChild); + virtual nsIWebWidget* GetRootWebWidget(); - nsIPresContext* GetPresContext(); + virtual nsIPresContext* GetPresContext(); + virtual PRBool GetName(nsString& aName); + virtual void SetName(const nsString& aName); + virtual nsIWebWidget* GetWebWidgetWithName(const nsString& aName); + virtual nsIWebWidget* GetTarget(const nsString& aName); NS_IMETHOD SetLinkHandler(nsILinkHandler* aHandler); @@ -112,9 +119,11 @@ public: private: nsresult ProvideDefaultHandlers(); void ForceRefresh(); - nsresult MakeWindow(nsNativeWindow aParent, const nsRect& aBounds); + nsresult MakeWindow(nsNativeWindow aParent, const nsRect& aBounds, + nsScrollPreference aScrolling); nsresult InitUAStyleSheet(void); nsresult CreateStyleSet(nsIDocument* aDocument, nsIStyleSet** aStyleSet); + void ReleaseChildren(); nsIWidget* mWindow; nsIView *mView; @@ -127,14 +136,19 @@ private: nsIScriptGlobalObject *mScriptGlobal; nsIScriptContext* mScriptContext; - static nsIWebWidget* gRootWebWidget; + nsVoidArray mChildren; + //static nsIWebWidget* gRootWebWidget; + nsString* mName; + + friend class WebWidgetImpl; }; //---------------------------------------------------------------------- static NS_DEFINE_IID(kIWebWidgetIID, NS_IWEBWIDGET_IID); +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); -nsIWebWidget* WebWidgetImpl::gRootWebWidget = nsnull; +//nsIWebWidget* WebWidgetImpl::gRootWebWidget = nsnull; // Note: operator new zeros our memory WebWidgetImpl::WebWidgetImpl() @@ -146,7 +160,6 @@ nsresult WebWidgetImpl::QueryInterface(REFNSIID aIID, void** aInstancePtr) if (NULL == aInstancePtr) { return NS_ERROR_NULL_POINTER; } - static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); if (aIID.Equals(kIWebWidgetIID)) { *aInstancePtr = (void*)(nsIWebWidget*)this; @@ -166,6 +179,10 @@ NS_IMPL_RELEASE(WebWidgetImpl) WebWidgetImpl::~WebWidgetImpl() { +printf("del %d ", this); + ReleaseChildren(); + mContainer = nsnull; + // Release windows and views if (nsnull != mViewManager) { @@ -177,7 +194,6 @@ WebWidgetImpl::~WebWidgetImpl() NS_IF_RELEASE(mWindow); NS_IF_RELEASE(mView); - NS_IF_RELEASE(mContainer); NS_IF_RELEASE(mLinkHandler); // Note: release context then shell @@ -189,8 +205,131 @@ WebWidgetImpl::~WebWidgetImpl() NS_IF_RELEASE(mScriptGlobal); } +void Check(WebWidgetImpl* ww) +{ + PRInt32 foo = ww->GetNumChildren(); + for (int i = 0; i < foo; i++) { + nsIWebWidget* child; + ww->GetChildAt(i, &child); + if (child == 0) { + printf("hello"); + } + } +} + + + +void WebWidgetImpl::ReleaseChildren() +{ + PRInt32 numChildren = GetNumChildren(); + for (PRInt32 i = 0; i < numChildren; i++) { + nsIWebWidget* child; + GetChildAt(i, &child); + child->SetContainer(nsnull, PR_FALSE); + PRInt32 refCnt = child->Release(); // XXX can't use macro, need ref count + // XXX add this back and find out why the ref count is 1 + // NS_ASSERTION(0 == refCnt, "reference to a web widget that will have no parent"); + } + mChildren.Clear(); +} + +PRBool WebWidgetImpl::GetName(nsString& aName) +{ + if (mName) { + aName = *mName; + return PR_TRUE; + } else { + return PR_FALSE; + } +} + +void WebWidgetImpl::SetName(const nsString& aName) +{ + if (!mName) { + mName = new nsString(aName); + } +} + +nsIWebWidget* WebWidgetImpl::GetWebWidgetWithName(const nsString& aName) +{ + nsIWebWidget* ww = this; + if (mName && (mName->EqualsIgnoreCase(aName))) { + NS_ADDREF(this); + return this; + } + + PRInt32 numChildren = GetNumChildren(); + for (PRInt32 i = 0; i < numChildren; i++) { + nsIWebWidget* child; + GetChildAt(i, &child); +if ((numChildren == 3) && (i == 0)) { + printf("hello "); +} + nsIWebWidget* result = child->GetWebWidgetWithName(aName); + if (result) { + return result; + } + NS_RELEASE(child); + } + + return nsnull; +} + +nsIWebWidget* WebWidgetImpl::GetTarget(const nsString& aName) +{ + nsIWebWidget* target = nsnull; + + if (aName.EqualsIgnoreCase("_blank")) { + NS_ASSERTION(0, "not implemented yet"); + target = this; + } + else if (aName.EqualsIgnoreCase("_self")) { + target = this; + } + else if (aName.EqualsIgnoreCase("_parent")) { + nsIWebWidget* top = GetRootWebWidget(); + if (top == this) { + target = this; + NS_RELEASE(top); + } + else { + nsISupports* container; + nsresult result = GetContainer(&container); + if (NS_OK == result) { + result = container->QueryInterface(kIWebWidgetIID, (void**)&target); + if (NS_OK != result) { + NS_ASSERTION(0, "invalid container"); + target = this; + } + } + else { + NS_ASSERTION(0, "invalid container for sub document - not a web widget"); + } + } + } + else if (aName.EqualsIgnoreCase("_top")) { + target = GetRootWebWidget(); + } + else { + nsIWebWidget* top = GetRootWebWidget(); + target = top->GetWebWidgetWithName(aName); + NS_RELEASE(top); + if (!target) { + target = this; + } + } + + if (target == this) { + NS_ADDREF(this); + } + + return target; +} + + nsresult WebWidgetImpl::MakeWindow(nsNativeWindow aNativeParent, - const nsRect& aBounds) + const nsRect& aBounds, + nsScrollPreference aScrolling) { nsresult rv; static NS_DEFINE_IID(kViewManagerCID, NS_VIEW_MANAGER_CID); @@ -227,13 +366,23 @@ nsresult WebWidgetImpl::MakeWindow(nsNativeWindow aNativeParent, return rv; } + static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID); + nsIScrollableView* scrollView; + rv = mView->QueryInterface(kScrollViewIID, (void**)&scrollView); + if (NS_OK == rv) { + scrollView->SetScrollPreference(aScrolling); + } + else { + NS_ASSERTION(0, "invalid scrolling view"); + return rv; + } + // Setup hierarchical relationship in view manager mViewManager->SetRootView(mView); mWindow = mView->GetWidget(); if (mWindow) { mViewManager->SetRootWindow(mWindow); } -printf("webwidget.mView=%d widget=%d parent=%d \n", mView, mWindow, aNativeParent); //set frame rate to 25 fps mViewManager->SetFrameRate(25); @@ -242,14 +391,15 @@ printf("webwidget.mView=%d widget=%d parent=%d \n", mView, mWindow, aNativeParen } nsresult WebWidgetImpl::Init(nsNativeWindow aNativeParent, - const nsRect& aBounds) + const nsRect& aBounds, + nsScrollPreference aScrolling) { // Create presentation context nsresult rv = NS_NewGalleyContext(&mPresContext); if (NS_OK != rv) { return rv; } - return MakeWindow(aNativeParent, aBounds); + return MakeWindow(aNativeParent, aBounds, aScrolling); } nsresult WebWidgetImpl::InitUAStyleSheet(void) @@ -296,7 +446,8 @@ nsresult WebWidgetImpl::InitUAStyleSheet(void) nsresult WebWidgetImpl::Init(nsNativeWindow aNativeParent, const nsRect& aBounds, nsIDocument* aDocument, - nsIPresContext* aPresContext) + nsIPresContext* aPresContext, + nsScrollPreference aScrolling) { NS_PRECONDITION(nsnull != aPresContext, "null ptr"); NS_PRECONDITION(nsnull != aDocument, "null ptr"); @@ -307,7 +458,7 @@ nsresult WebWidgetImpl::Init(nsNativeWindow aNativeParent, mPresContext = aPresContext; NS_ADDREF(aPresContext); - nsresult rv = MakeWindow(aNativeParent, aBounds); + nsresult rv = MakeWindow(aNativeParent, aBounds, aScrolling); if (NS_OK != rv) { return rv; } @@ -412,8 +563,6 @@ nsresult WebWidgetImpl::ProvideDefaultHandlers() // XXX need to save old document in case of failure? Does caller do that? -static NS_DEFINE_IID(kIWebFrameIID, NS_IWEBFRAME_IID); - NS_IMETHODIMP WebWidgetImpl::LoadURL(const nsString& aURLSpec, nsIStreamListener* aListener, @@ -456,15 +605,19 @@ WebWidgetImpl::LoadURL(const nsString& aURLSpec, // set the root web widget to this if its container is not // an embedded web webwidget - nsISupports* parent; - rv = GetContainer(&parent); - if ((rv == NS_OK) && (nsnull != parent)) { - nsISupports* webFrame; - rv = parent->QueryInterface(kIWebFrameIID, (void**)&webFrame); - if (rv != NS_OK) { - SetRootWebWidget(this); - } - } + //nsISupports* parent; + //rv = GetContainer(&parent); + //if ((rv == NS_OK) && (nsnull != parent)) { + // nsISupports* webFrame; + // rv = parent->QueryInterface(kIWebWidgetIID, (void**)&webFrame); + // if (rv == NS_OK) { + // NS_RELEASE(webFrame); + // } else { + // SetRootWebWidget(this); + // } + //} + + ReleaseChildren(); // Create style set nsIStyleSet* styleSet = nsnull; @@ -507,7 +660,7 @@ WebWidgetImpl::LoadURL(const nsString& aURLSpec, // Now load the document mPresShell->EnterReflowLock(); - doc->LoadURL(url, aListener, aPostData); + doc->LoadURL(url, aListener, this, aPostData); mPresShell->ExitReflowLock(); PRTime end = PR_Now(); @@ -558,11 +711,32 @@ NS_IMETHODIMP WebWidgetImpl::GetLinkHandler(nsILinkHandler** aResult) return NS_OK; } -NS_IMETHODIMP WebWidgetImpl::SetContainer(nsISupports* aContainer) -{ // XXX this should most likely be a WEAK reference - NS_IF_RELEASE(mContainer); +NS_IMETHODIMP WebWidgetImpl::SetContainer(nsISupports* aContainer, PRBool aRelationship) +{ mContainer = aContainer; - NS_IF_ADDREF(aContainer); + + if (nsnull == aContainer) { + return NS_OK; + } + + if (aRelationship) { + // if aContainer is a web widget add this as a child + nsIWebWidget* ww; + nsresult result = aContainer->QueryInterface(kIWebWidgetIID, (void**)&ww); + if (NS_OK == result) { + nsIWebWidget* thisWW; + result = QueryInterface(kIWebWidgetIID, (void**)&thisWW); + if (NS_OK == result) { + ww->AddChild(thisWW, PR_FALSE); + NS_RELEASE(thisWW); + } else { + NS_ASSERTION(0, "invalid nsISupports"); + return result; + } + NS_RELEASE(ww); + } + } + if (nsnull != mPresContext) { mPresContext->SetContainer(aContainer); } @@ -576,21 +750,70 @@ NS_IMETHODIMP WebWidgetImpl::GetContainer(nsISupports** aResult) return NS_ERROR_NULL_POINTER; } *aResult = mContainer; - NS_IF_ADDREF(mContainer); return NS_OK; } -void WebWidgetImpl::SetRootWebWidget(nsIWebWidget* aWebWidget) +PRInt32 WebWidgetImpl::GetNumChildren() { - NS_IF_RELEASE(gRootWebWidget); - gRootWebWidget = aWebWidget; - NS_IF_ADDREF(gRootWebWidget); + return mChildren.Count(); } +NS_IMETHODIMP WebWidgetImpl::AddChild(nsIWebWidget* aChild, PRBool aRelationship) +{ + NS_ASSERTION(nsnull != aChild, "null child"); + + mChildren.AppendElement(aChild); + + if (aRelationship) { + nsISupports* thisSupports; + nsresult result = QueryInterface(kISupportsIID, (void**)&thisSupports); + if (NS_OK == result) { + aChild->SetContainer(thisSupports, PR_FALSE); + NS_RELEASE(thisSupports); + } else { + NS_ASSERTION(0, "invalid nsISupports"); + return result; + } + } + + NS_ADDREF(aChild); + return NS_OK; +} + +NS_IMETHODIMP WebWidgetImpl::GetChildAt(PRInt32 aIndex, nsIWebWidget** aChild) +{ + NS_ASSERTION(nsnull != aChild, "null child address"); + *aChild = (nsIWebWidget*)mChildren.ElementAt(aIndex); + NS_ADDREF(*aChild); + return NS_OK; +} + +//void WebWidgetImpl::SetRootWebWidget(nsIWebWidget* aWebWidget) +//{ +// if (aWebWidget != gRootWebWidget) { +// NS_IF_RELEASE(gRootWebWidget); +// gRootWebWidget = aWebWidget; +// NS_IF_ADDREF(gRootWebWidget); +// } +//} + nsIWebWidget* WebWidgetImpl::GetRootWebWidget() { - NS_IF_ADDREF(gRootWebWidget); - return gRootWebWidget; + nsIWebWidget* childWW = this; + nsISupports* parSup; + childWW->GetContainer(&parSup); + if (parSup) { + nsIWebWidget* parWW; + nsresult result = parSup->QueryInterface(kIWebWidgetIID, (void**)&parWW); + if (NS_OK == result) { + nsIWebWidget* root = parWW->GetRootWebWidget(); + NS_RELEASE(parWW); + return root; + } + } + + NS_ADDREF(this); + return this; } //---------------------------------------------------------------------- @@ -809,7 +1032,7 @@ nsresult WebWidgetImpl::ReleaseScriptContext() /* nsWebWidgetFactory /*******************************************/ -static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +//static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); static NS_DEFINE_IID(kCWebWidget, NS_WEBWIDGET_CID); diff --git a/mozilla/webshell/tests/viewer/nsViewer.cpp b/mozilla/webshell/tests/viewer/nsViewer.cpp index 7cc7f6dfbe6..8c39cc9fddc 100644 --- a/mozilla/webshell/tests/viewer/nsViewer.cpp +++ b/mozilla/webshell/tests/viewer/nsViewer.cpp @@ -458,7 +458,9 @@ DocObserver::HandleLinkClickEvent(const nsString& aURLSpec, nsIPostData* aPostData) { if (nsnull != mWebWidget) { - mWebWidget->LoadURL(aURLSpec, (nsIStreamListener*)this, aPostData); + nsIWebWidget* targetWidget = mWebWidget->GetTarget(aTargetSpec); + targetWidget->LoadURL(aURLSpec, (nsIStreamListener*)this, aPostData); + NS_RELEASE(targetWidget); } } @@ -513,9 +515,6 @@ static DocObserver* NewObserver(nsIWebWidget* ww) ww->SetContainer((nsIDocumentObserver*) it); return it; } - else { - NS_RELEASE(oldContainer); - } } return nsnull; } diff --git a/mozilla/webshell/tests/viewer/nsViewer.h b/mozilla/webshell/tests/viewer/nsViewer.h index ca6e88c64aa..f66d031a74f 100644 --- a/mozilla/webshell/tests/viewer/nsViewer.h +++ b/mozilla/webshell/tests/viewer/nsViewer.h @@ -40,6 +40,7 @@ #define MAXPATHLEN 1024 +// XXX this is redundant with nsLinkHandler class DocObserver : public nsIDocumentObserver, public nsIStreamListener, public nsILinkHandler diff --git a/mozilla/webshell/tests/viewer/samples/test9.html b/mozilla/webshell/tests/viewer/samples/test9.html index 12f9f6bdf39..96d2a18b79b 100644 --- a/mozilla/webshell/tests/viewer/samples/test9.html +++ b/mozilla/webshell/tests/viewer/samples/test9.html @@ -5,10 +5,35 @@

Example 9: Frames

-hello -  - +Put test6.html in frame1, + frame2, + frame3, + frame3.1, + self, + parent, + top
- +Put test9a.html in frame1, + frame2, + frame3, + frame3.1, + self, + parent, + top +
+
+frame1              +                +                +         +frame2 +
+ +  + +
+frame3 +
+ diff --git a/mozilla/webshell/tests/viewer/samples/test9a.html b/mozilla/webshell/tests/viewer/samples/test9a.html index 377f2ae83e2..8735ae70027 100644 --- a/mozilla/webshell/tests/viewer/samples/test9a.html +++ b/mozilla/webshell/tests/viewer/samples/test9a.html @@ -1,7 +1,16 @@ -a frame within a frame +Put test5.html in frame1, + frame2, + frame3, + frame3.1, + self, + parent, + top
- +
+frame3.1 +
+