added SetDocument implementation
added Get/SetDocLoaderObserver added base implementation for nsIDocShellContainer methods started filling in GetVisibility started nsIContentViewerContainer methods, very rough added FireStartDocumentLoad, FireEndDocumentLoad added DestroyChildren git-svn-id: svn://10.0.0.236/trunk@53145 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -20,14 +20,32 @@
|
||||
* Travis Bogard <travis@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsDocShellBase.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDocumentViewer.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsCURILoader.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsNeckoUtil.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
#ifdef XXX_NS_DEBUG // XXX: we'll need a logging facility for debugging
|
||||
#define WEB_TRACE(_bit,_args) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (WEB_LOG_TEST(gLogModule,_bit)) { \
|
||||
PR_LogPrint _args; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
#else
|
||||
#define WEB_TRACE(_bit,_args)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include "nsDocShellBase.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//*** nsDocShellBase: Object Management
|
||||
@@ -119,13 +137,115 @@ NS_IMETHODIMP nsDocShellBase::GetCurrentURI(nsIURI** aURI)
|
||||
}
|
||||
|
||||
// SetDocument is only meaningful for doc shells that support DOM documents. Not all do.
|
||||
NS_IMETHODIMP nsDocShellBase::SetDocument(nsIDOMDocument* aDocument,
|
||||
nsIPresContext* presContext)
|
||||
NS_IMETHODIMP
|
||||
nsDocShellBase::SetDocument(nsIDOMDocument *aDOMDoc, nsIDOMElement *aRootNode)
|
||||
{
|
||||
NS_WARN_IF_FALSE(PR_FALSE, "Subclasses should override this method!!!!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
// The tricky part is bypassing the normal load process and just putting a document into
|
||||
// the webshell. This is particularly nasty, since webshells don't normally even know
|
||||
// about their documents
|
||||
|
||||
// (1) Create a document viewer
|
||||
nsCOMPtr<nsIContentViewer> documentViewer;
|
||||
nsCOMPtr<nsIDocumentLoaderFactory> docFactory;
|
||||
static NS_DEFINE_CID(kLayoutDocumentLoaderFactoryCID, NS_LAYOUT_DOCUMENT_LOADER_FACTORY_CID);
|
||||
NS_ENSURE_SUCCESS(nsComponentManager::CreateInstance(kLayoutDocumentLoaderFactoryCID, nsnull,
|
||||
nsIDocumentLoaderFactory::GetIID(),
|
||||
(void**)getter_AddRefs(docFactory)),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDOMDoc);
|
||||
if (!doc) { return NS_ERROR_NULL_POINTER; }
|
||||
NS_ENSURE_SUCCESS(docFactory->CreateInstanceForDocument(this,
|
||||
doc,
|
||||
"view",
|
||||
getter_AddRefs(documentViewer)),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
// (2) Feed the docshell to the content viewer
|
||||
NS_ENSURE_SUCCESS(documentViewer->SetContainer(this), NS_ERROR_FAILURE);
|
||||
|
||||
// (3) Tell the content viewer container to embed the content viewer.
|
||||
// (This step causes everything to be set up for an initial flow.)
|
||||
NS_ENSURE_SUCCESS(Embed(documentViewer, "view", nsnull), NS_ERROR_FAILURE);
|
||||
|
||||
// XXX: It would be great to get rid of this dummy channel!
|
||||
const nsAutoString uriString = "about:blank";
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_ENSURE_SUCCESS(NS_NewURI(getter_AddRefs(uri), uriString), NS_ERROR_FAILURE);
|
||||
if (!uri) { return NS_ERROR_OUT_OF_MEMORY; }
|
||||
|
||||
nsCOMPtr<nsIChannel> dummyChannel;
|
||||
NS_ENSURE_SUCCESS(NS_OpenURI(getter_AddRefs(dummyChannel), uri, nsnull), NS_ERROR_FAILURE);
|
||||
|
||||
// (4) fire start document load notification
|
||||
NS_ENSURE_SUCCESS(doc->StartDocumentLoad("view", dummyChannel, nsnull, this, nsnull), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(FireStartDocumentLoad(mDocLoader, uri, "load"), NS_ERROR_FAILURE);
|
||||
|
||||
// (5) hook up the document and its content
|
||||
nsCOMPtr<nsIContent> rootContent = do_QueryInterface(aRootNode);
|
||||
if (!doc) { return NS_ERROR_OUT_OF_MEMORY; }
|
||||
NS_ENSURE_SUCCESS(rootContent->SetDocument(doc, PR_FALSE), NS_ERROR_FAILURE);
|
||||
doc->SetRootContent(rootContent);
|
||||
|
||||
// (6) reflow the document
|
||||
//XXX: SetScrolling doesn't make any sense
|
||||
//SetScrolling(-1, PR_FALSE);
|
||||
PRInt32 i;
|
||||
PRInt32 ns = doc->GetNumberOfShells();
|
||||
for (i = 0; i < ns; i++)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> shell(dont_AddRef(doc->GetShellAt(i)));
|
||||
if (shell)
|
||||
{
|
||||
// Make shell an observer for next time
|
||||
NS_ENSURE_SUCCESS(shell->BeginObservingDocument(), NS_ERROR_FAILURE);
|
||||
|
||||
// Resize-reflow this time
|
||||
nsCOMPtr<nsIDocumentViewer> docViewer = do_QueryInterface(documentViewer);
|
||||
if (!docViewer) { return NS_ERROR_OUT_OF_MEMORY; }
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
NS_ENSURE_SUCCESS(docViewer->GetPresContext(*(getter_AddRefs(presContext))), NS_ERROR_FAILURE);
|
||||
if (!presContext) { return NS_ERROR_OUT_OF_MEMORY; }
|
||||
float p2t;
|
||||
presContext->GetScaledPixelsToTwips(&p2t);
|
||||
|
||||
nsRect r;
|
||||
NS_ENSURE_SUCCESS(GetPosition(&r.x, &r.y), NS_ERROR_FAILURE);;
|
||||
NS_ENSURE_SUCCESS(GetSize(&r.width, &r.height), NS_ERROR_FAILURE);;
|
||||
NS_ENSURE_SUCCESS(shell->InitialReflow(NSToCoordRound(r.width * p2t), NSToCoordRound(r.height * p2t)), NS_ERROR_FAILURE);
|
||||
|
||||
// Now trigger a refresh
|
||||
nsCOMPtr<nsIViewManager> vm;
|
||||
NS_ENSURE_SUCCESS(shell->GetViewManager(getter_AddRefs(vm)), NS_ERROR_FAILURE);
|
||||
if (vm)
|
||||
{
|
||||
PRBool enabled;
|
||||
documentViewer->GetEnableRendering(&enabled);
|
||||
if (enabled) {
|
||||
vm->EnableRefresh();
|
||||
}
|
||||
NS_ENSURE_SUCCESS(vm->SetWindowDimensions(NSToCoordRound(r.width * p2t),
|
||||
NSToCoordRound(r.height * p2t)),
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// (7) fire end document load notification
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIDocumentLoaderObserver> dlObserver;
|
||||
// XXX: this was just "this", and webshell container relied on getting a webshell
|
||||
// through this interface. No one else uses it anywhere afaict
|
||||
//if (!dlObserver) { return NS_ERROR_NO_INTERFACE; }
|
||||
NS_ENSURE_SUCCESS(FireEndDocumentLoad(mDocLoader, dummyChannel, rv, dlObserver), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); // test the resulting out-param separately
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// caller is responsible for calling nsString::Recycle(*aName);
|
||||
NS_IMETHODIMP nsDocShellBase::GetName(PRUnichar** aName)
|
||||
{
|
||||
@@ -285,6 +405,24 @@ NS_IMETHODIMP nsDocShellBase::SetZoom(float zoom)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShellBase::GetDocLoaderObserver(nsIDocumentLoaderObserver * *aDocLoaderObserver)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDocLoaderObserver);
|
||||
|
||||
*aDocLoaderObserver = mDocLoaderObserver;
|
||||
NS_IF_ADDREF(*aDocLoaderObserver);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShellBase::SetDocLoaderObserver(nsIDocumentLoaderObserver * aDocLoaderObserver)
|
||||
{
|
||||
// it's legal for aDocLoaderObserver to be null.
|
||||
mDocLoaderObserver = aDocLoaderObserver;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsDocShellBase::nsIDocShellEdit
|
||||
//*****************************************************************************
|
||||
@@ -465,6 +603,87 @@ NS_IMETHODIMP nsDocShellBase::GetPrintable(PRBool* printable)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// nsDocShellBase::nsIDocShellContainer
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP nsDocShellBase::GetChildCount(PRInt32 *aChildCount)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aChildCount);
|
||||
*aChildCount = mChildren.Count();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocShellBase::AddChild(nsIDocShell *aChild)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aChild);
|
||||
|
||||
NS_ENSURE_SUCCESS(aChild->SetParent(this), NS_ERROR_FAILURE);
|
||||
mChildren.AppendElement(aChild);
|
||||
NS_ADDREF(aChild);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX: tiny semantic change from webshell. aChild is only effected if it was actually a child of this docshell
|
||||
NS_IMETHODIMP nsDocShellBase::RemoveChild(nsIDocShell *aChild)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aChild);
|
||||
|
||||
PRBool childRemoved = mChildren.RemoveElement(aChild);
|
||||
if (PR_TRUE==childRemoved)
|
||||
{
|
||||
aChild->SetParent(nsnull);
|
||||
NS_RELEASE(aChild);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIEnumerator childEnumerator; */
|
||||
NS_IMETHODIMP nsDocShellBase::GetChildEnumerator(nsIEnumerator * *aChildEnumerator)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aChildEnumerator);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* depth-first search for a child shell with aName */
|
||||
NS_IMETHODIMP nsDocShellBase::FindChildWithName(const PRUnichar *aName, nsIDocShell **_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aName);
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
*_retval = nsnull; // if we don't find one, we return NS_OK and a null result
|
||||
nsAutoString name(aName);
|
||||
PRUnichar *childName;
|
||||
PRInt32 i, n = mChildren.Count();
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
nsIDocShell* child = (nsIDocShell*) mChildren.ElementAt(i); // doesn't addref the result
|
||||
if (nsnull != child) {
|
||||
child->GetName(&childName);
|
||||
if (name.Equals(childName)) {
|
||||
*_retval = child;
|
||||
NS_ADDREF(child);
|
||||
break;
|
||||
}
|
||||
|
||||
// See if child contains the shell with the given name
|
||||
nsCOMPtr<nsIDocShellContainer> childAsContainer = do_QueryInterface(child);
|
||||
if (child)
|
||||
{
|
||||
NS_ENSURE_SUCCESS(childAsContainer->FindChildWithName(name.GetUnicode(), _retval), NS_ERROR_FAILURE);
|
||||
}
|
||||
if (_retval) { // found it
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// nsDocShellBase::nsIGenericWindow
|
||||
//*****************************************************************************
|
||||
@@ -763,18 +982,42 @@ NS_IMETHODIMP nsDocShellBase::SetParentNativeWindow(nativeWindow parentNativeWin
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocShellBase::GetVisibility(PRBool* visibility)
|
||||
NS_IMETHODIMP nsDocShellBase::GetVisibility(PRBool* aVisibility)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(visibility);
|
||||
NS_ENSURE_ARG_POINTER(aVisibility);
|
||||
|
||||
if(!mCreated)
|
||||
*visibility = mBaseInitInfo->visible;
|
||||
else
|
||||
{
|
||||
//XXX Query underlying control
|
||||
}
|
||||
if(!mCreated) {
|
||||
*aVisibility = mBaseInitInfo->visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the pres shell
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
NS_ENSURE_SUCCESS(GetPresShell(getter_AddRefs(presShell)), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
// get the view manager
|
||||
nsCOMPtr<nsIViewManager> vm;
|
||||
NS_ENSURE_SUCCESS(presShell->GetViewManager(getter_AddRefs(vm)), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(vm, NS_ERROR_FAILURE);
|
||||
|
||||
// get the root view
|
||||
nsIView *rootView=nsnull; // views are not ref counted
|
||||
NS_ENSURE_SUCCESS(vm->GetRootView(rootView), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(rootView, NS_ERROR_FAILURE);
|
||||
|
||||
// convert the view's visibility attribute to a bool
|
||||
nsViewVisibility vis;
|
||||
NS_ENSURE_TRUE(rootView->GetVisibility(vis), NS_ERROR_FAILURE);
|
||||
if (nsViewVisibility_kHide==vis) {
|
||||
*aVisibility = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
*aVisibility = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocShellBase::SetVisibility(PRBool visibility)
|
||||
@@ -1060,6 +1303,106 @@ NS_IMETHODIMP nsDocShellBase::ScrollByPages(PRInt32 numPages)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsDocShellBase::nsIContentViewerContainer
|
||||
//*****************************************************************************
|
||||
NS_IMETHODIMP nsDocShellBase::QueryCapability(const nsIID &aIID, void** aResult)
|
||||
{
|
||||
NS_ENSURE_SUCCESS(PR_FALSE, NS_ERROR_NOT_IMPLEMENTED);
|
||||
return NS_OK;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP nsDocShellBase::Embed(nsIContentViewer* aContentViewer,
|
||||
const char * aCommand,
|
||||
nsISupports * aExtraInfo)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aContentViewer);
|
||||
// null aCommand is ok
|
||||
// null aExtraInfo is ok
|
||||
|
||||
WEB_TRACE(WEB_TRACE_CALLS,
|
||||
("nsWebShell::Embed: this=%p aDocViewer=%p aCommand=%s aExtraInfo=%p",
|
||||
this, aContentViewer, aCommand ? aCommand : "", aExtraInfo));
|
||||
|
||||
nsRect bounds;
|
||||
// (1) reset state, clean up any left-over data from previous embedding
|
||||
mContentViewer = nsnull;
|
||||
if (nsnull != mScriptContext) {
|
||||
mScriptContext->GC();
|
||||
}
|
||||
|
||||
// (2) set the new content viewer
|
||||
mContentViewer = aContentViewer;
|
||||
|
||||
// XXX: comment from webshell code --
|
||||
// check to see if we have a window to embed into --dwc0001
|
||||
/* Note we also need to check for the presence of a native widget. If the
|
||||
webshell is hidden before it's embedded, which can happen in an onload
|
||||
handler, the native widget is destroyed before this code is run. This
|
||||
appears to be mostly harmless except on Windows, where the subsequent
|
||||
attempt to create a child window without a parent is met with disdain
|
||||
by the OS. It's handy, then, that GetNativeData on Windows returns
|
||||
null in this case. */
|
||||
/* XXX native window
|
||||
if(mWindow && mWindow->GetNativeData(NS_NATIVE_WIDGET))
|
||||
{
|
||||
mWindow->GetClientBounds(bounds);
|
||||
bounds.x = bounds.y = 0;
|
||||
rv = mContentViewer->Init(mWindow->GetNativeData(NS_NATIVE_WIDGET),
|
||||
mDeviceContext,
|
||||
mPrefs,
|
||||
bounds,
|
||||
mScrollPref);
|
||||
|
||||
// If the history state has been set by session history,
|
||||
// set it on the pres shell now that we have a content
|
||||
// viewer.
|
||||
|
||||
//XXX: history, should be removed
|
||||
if (mContentViewer && mHistoryState) {
|
||||
nsCOMPtr<nsIDocumentViewer> docv = do_QueryInterface(mContentViewer);
|
||||
if (nsnull != docv) {
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
rv = docv->GetPresShell(*getter_AddRefs(shell));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = shell->SetHistoryState((nsILayoutHistoryState*) mHistoryState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mContentViewer->Show();
|
||||
}
|
||||
} else {
|
||||
mContentViewer = nsnull;
|
||||
}
|
||||
*/
|
||||
|
||||
// Now that we have switched documents, forget all of our children
|
||||
DestroyChildren();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocShellBase::GetContentViewer(nsIContentViewer** aResult)
|
||||
{
|
||||
NS_ENSURE_SUCCESS(PR_FALSE, NS_ERROR_NOT_IMPLEMENTED);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocShellBase::HandleUnknownContentType(nsIDocumentLoader* aLoader,
|
||||
nsIChannel* channel,
|
||||
const char *aContentType,
|
||||
const char *aCommand)
|
||||
{
|
||||
NS_ENSURE_SUCCESS(PR_FALSE, NS_ERROR_NOT_IMPLEMENTED);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// nsDocShellBase: Helper Routines
|
||||
//*****************************************************************************
|
||||
@@ -1139,3 +1482,190 @@ void nsDocShellBase::SetCurrentURI(nsIURI* aUri)
|
||||
mCurrentURI = aUri; //This assignment addrefs
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShellBase::FireStartDocumentLoad(nsIDocumentLoader* aLoader,
|
||||
nsIURI * aURL, //XXX: should be the channel?
|
||||
const char * aCommand)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLoader);
|
||||
NS_ENSURE_ARG_POINTER(aURL);
|
||||
NS_ENSURE_ARG_POINTER(aCommand);
|
||||
|
||||
nsCOMPtr<nsIDocumentViewer> docViewer;
|
||||
if (mScriptGlobal && (aLoader == mDocLoader))
|
||||
{
|
||||
docViewer = do_QueryInterface(mContentViewer);
|
||||
if (docViewer)
|
||||
{
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
NS_ENSURE_SUCCESS(docViewer->GetPresContext(*(getter_AddRefs(presContext))), NS_ERROR_FAILURE);
|
||||
if (presContext)
|
||||
{
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsMouseEvent event;
|
||||
event.eventStructType = NS_EVENT;
|
||||
event.message = NS_PAGE_UNLOAD;
|
||||
NS_ENSURE_SUCCESS(mScriptGlobal->HandleDOMEvent(*presContext,
|
||||
&event,
|
||||
nsnull,
|
||||
NS_EVENT_FLAG_INIT,
|
||||
status),
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aLoader == mDocLoader)
|
||||
{
|
||||
nsCOMPtr<nsIDocumentLoaderObserver> dlObserver;
|
||||
|
||||
if (!mDocLoaderObserver && mParent)
|
||||
{
|
||||
/* If this is a frame (in which case it would have a parent && doesn't
|
||||
* have a documentloaderObserver, get it from the rootWebShell
|
||||
*/
|
||||
nsCOMPtr<nsIDocShell> root;
|
||||
NS_ENSURE_SUCCESS(GetRootDocShell(getter_AddRefs(root)), NS_ERROR_FAILURE);
|
||||
|
||||
if (root)
|
||||
NS_ENSURE_SUCCESS(root->GetDocLoaderObserver(getter_AddRefs(dlObserver)), NS_ERROR_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
dlObserver = do_QueryInterface(mDocLoaderObserver); // we need this to addref
|
||||
}
|
||||
/*
|
||||
* Fire the OnStartDocumentLoad of the webshell observer
|
||||
*/
|
||||
/* XXX This code means "notify dlObserver only if we're the top level webshell.
|
||||
I don't know why that would be, can't subdocument have doc loader observers?
|
||||
*/
|
||||
if (/*(nsnull != mContainer) && */(nsnull != dlObserver))
|
||||
{
|
||||
NS_ENSURE_SUCCESS(dlObserver->OnStartDocumentLoad(mDocLoader, aURL, aCommand),
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShellBase::FireEndDocumentLoad(nsIDocumentLoader* aLoader,
|
||||
nsIChannel * aChannel,
|
||||
nsresult aStatus,
|
||||
nsIDocumentLoaderObserver * aDocLoadObserver)
|
||||
{
|
||||
#ifdef MOZ_PERF_METRICS
|
||||
RAPTOR_STOPWATCH_DEBUGTRACE(("Stop: nsWebShell::OnEndDocumentLoad(), this=%p\n", this));
|
||||
NS_STOP_STOPWATCH(mTotalTime)
|
||||
RAPTOR_STOPWATCH_TRACE(("Total (Layout + Page Load) Time (webshell=%p): ", this));
|
||||
mTotalTime.Print();
|
||||
RAPTOR_STOPWATCH_TRACE(("\n"));
|
||||
#endif
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aLoader);
|
||||
NS_ENSURE_ARG_POINTER(aChannel);
|
||||
// null aDocLoadObserver is legal
|
||||
|
||||
nsCOMPtr<nsIURI> aURL;
|
||||
NS_ENSURE_SUCCESS(aChannel->GetURI(getter_AddRefs(aURL)), NS_ERROR_FAILURE);
|
||||
|
||||
if (aLoader == mDocLoader)
|
||||
{
|
||||
if (mScriptGlobal && mContentViewer)
|
||||
{
|
||||
nsCOMPtr<nsIDocumentViewer> docViewer;
|
||||
docViewer = do_QueryInterface(mContentViewer);
|
||||
if (docViewer)
|
||||
{
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
NS_ENSURE_SUCCESS(docViewer->GetPresContext(*(getter_AddRefs(presContext))), NS_ERROR_FAILURE);
|
||||
if (presContext)
|
||||
{
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsMouseEvent event;
|
||||
event.eventStructType = NS_EVENT;
|
||||
event.message = NS_PAGE_LOAD;
|
||||
NS_ENSURE_SUCCESS(mScriptGlobal->HandleDOMEvent(*presContext,
|
||||
&event,
|
||||
nsnull,
|
||||
NS_EVENT_FLAG_INIT,
|
||||
status),
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fire the EndLoadURL of the web shell container
|
||||
/* XXX: what replaces mContainer?
|
||||
if (nsnull != aURL)
|
||||
{
|
||||
nsAutoString urlString;
|
||||
char* spec;
|
||||
rv = aURL->GetSpec(&spec);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
urlString = spec;
|
||||
if (nsnull != mContainer) {
|
||||
rv = mContainer->EndLoadURL(this, urlString.GetUnicode(), 0);
|
||||
}
|
||||
nsCRT::free(spec);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
nsCOMPtr<nsIDocumentLoaderObserver> dlObserver;
|
||||
if (!mDocLoaderObserver && mParent)
|
||||
{
|
||||
// If this is a frame (in which case it would have a parent && doesn't
|
||||
// have a documentloaderObserver, get it from the rootWebShell
|
||||
nsCOMPtr<nsIDocShell> root;
|
||||
NS_ENSURE_SUCCESS(GetRootDocShell(getter_AddRefs(root)), NS_ERROR_FAILURE);
|
||||
|
||||
if (root)
|
||||
NS_ENSURE_SUCCESS(root->GetDocLoaderObserver(getter_AddRefs(dlObserver)), NS_ERROR_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Take care of the Trailing slash situation */
|
||||
/* XXX: session history stuff, should be taken care of external to the docshell
|
||||
if (mSHist)
|
||||
CheckForTrailingSlash(aURL);
|
||||
*/
|
||||
dlObserver = do_QueryInterface(mDocLoaderObserver); // we need this to addref
|
||||
}
|
||||
|
||||
/*
|
||||
* Fire the OnEndDocumentLoad of the DocLoaderobserver
|
||||
*/
|
||||
if (dlObserver && aURL) {
|
||||
NS_ENSURE_SUCCESS(dlObserver->OnEndDocumentLoad(mDocLoader, aChannel, aStatus, aDocLoadObserver),
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocShellBase::DestroyChildren()
|
||||
{
|
||||
PRInt32 i, n = mChildren.Count();
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
nsIDocShell* shell = (nsIDocShell*) mChildren.ElementAt(i);
|
||||
NS_WARN_IF_FALSE(shell, "docshell has null child");
|
||||
if (shell)
|
||||
{
|
||||
shell->SetParent(nsnull);
|
||||
// XXX: will shells have a separate Destroy? See webshell::Destroy for what it does
|
||||
//shell->Destroy();
|
||||
NS_RELEASE(shell);
|
||||
}
|
||||
}
|
||||
mChildren.Clear();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user