Expose nsIXULDocument and nsIXULPrototypeDocument as public interfaces. Properly implement nsIXULDocument::CreateFromPrototype().

This commit is contained in:
waterson%netscape.com 1999-11-24 22:46:09 +00:00
Родитель 20db57f648
Коммит 062b2d5a6f
13 изменённых файлов: 917 добавлений и 135 удалений

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

@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
An XUL-specific extension to nsIXMLDocument. Includes methods for
setting the root resource of the document content model, a factory
method for constructing the children of a node, etc.
XXX This should really be called nsIXULDocument.
*/
#ifndef nsIXULDocument_h___
#define nsIXULDocument_h___
class nsIContent; // XXX nsIXMLDocument.h is bad and doesn't declare this class...
#include "nsIXMLDocument.h"
class nsForwardReference;
class nsIAtom;
class nsIDOMElement;
class nsIDOMHTMLFormElement;
class nsIPrincipal;
class nsIRDFContentModelBuilder;
class nsIRDFResource;
class nsISupportsArray;
class nsIXULPrototypeDocument;
// {954F0811-81DC-11d2-B52A-000000000000}
#define NS_IRDFDOCUMENT_IID \
{ 0x954f0811, 0x81dc, 0x11d2, { 0xb5, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }
/**
* RDF document extensions to nsIDocument
*/
class nsIRDFDataSource;
class nsIXULDocument : public nsIXMLDocument
{
public:
static const nsIID& GetIID() { static nsIID iid = NS_IRDFDOCUMENT_IID; return iid; }
// The resource-to-element map is a one-to-many mapping of RDF
// resources to content elements.
/**
* Add an entry to the ID-to-element map.
*/
NS_IMETHOD AddElementForID(const nsString& aID, nsIContent* aElement) = 0;
/**
* Remove an entry from the ID-to-element map.
*/
NS_IMETHOD RemoveElementForID(const nsString& aID, nsIContent* aElement) = 0;
/**
* Get the elements for a particular resource in the resource-to-element
* map. The nsISupportsArray will be truncated and filled in with
* nsIContent pointers.
*/
NS_IMETHOD GetElementsForID(const nsString& aID, nsISupportsArray* aElements) = 0;
NS_IMETHOD CreateContents(nsIContent* aElement) = 0;
/**
* Add a content model builder to the document.
*/
NS_IMETHOD AddContentModelBuilder(nsIRDFContentModelBuilder* aBuilder) = 0;
/**
* Manipulate the XUL document's form element
*/
NS_IMETHOD GetForm(nsIDOMHTMLFormElement** aForm) = 0;
NS_IMETHOD SetForm(nsIDOMHTMLFormElement* aForm) = 0;
/**
* Add a "forward declaration" of a XUL observer. Such declarations
* will be resolved when document loading completes.
*/
NS_IMETHOD AddForwardReference(nsForwardReference* aForwardReference) = 0;
NS_IMETHOD ResolveForwardReferences() = 0;
/**
* Create a XUL document from a prototype
*/
NS_IMETHOD CreateFromPrototype(const char* aCommand,
nsIXULPrototypeDocument* aPrototype) = 0;
};
// factory functions
nsresult NS_NewXULDocument(nsIXULDocument** result);
#endif // nsIXULDocument_h___

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

@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
*/
#ifndef nsIXULPrototypeDocument_h__
#define nsIXULPrototypeDocument_h__
#include "nsISupports.h"
class nsIAtom;
class nsIPrincipal;
class nsIURI;
class nsIStyleSheet;
class nsString;
class nsVoidArray;
class nsXULPrototypeElement;
// {187A63D0-8337-11d3-BE47-00104BDE6048}
#define NS_IXULPROTOTYPEDOCUMENT_IID \
{ 0x187a63d0, 0x8337, 0x11d3, { 0xbe, 0x47, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } }
class nsIXULPrototypeDocument : public nsISupports
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IXULPROTOTYPEDOCUMENT_IID);
/**
* Retrieve the URI of the document
*/
NS_IMETHOD SetURI(nsIURI* aURI) = 0;
NS_IMETHOD GetURI(nsIURI** aResult) = 0;
/**
* Retrieve the root XULPrototype element of the document.
*/
NS_IMETHOD GetRootElement(nsXULPrototypeElement** aResult) = 0;
NS_IMETHOD SetRootElement(nsXULPrototypeElement* aElement) = 0;
NS_IMETHOD AddStyleSheetReference(nsIURI* aStyleSheet) = 0;
NS_IMETHOD GetStyleSheetReferences(nsISupportsArray** aResult) = 0;
NS_IMETHOD AddOverlayReference(nsIURI* aURI) = 0;
NS_IMETHOD GetOverlayReferences(nsISupportsArray** aResult) = 0;
NS_IMETHOD GetHeaderData(nsIAtom* aField, nsString& aData) const = 0;
NS_IMETHOD SetHeaderData(nsIAtom* aField, const nsString& aData) = 0;
NS_IMETHOD GetDocumentPrincipal(nsIPrincipal** aResult) = 0;
NS_IMETHOD SetDocumentPrincipal(nsIPrincipal* aPrincipal) = 0;
};
extern NS_IMETHODIMP
NS_NewXULPrototypeDocument(nsISupports* aOuter, REFNSIID aIID, void** aResult);
#endif // nsIXULPrototypeDocument_h__

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

@ -91,6 +91,7 @@
#include "nsIStyleSet.h"
#include "nsIStyleSheet.h"
#include "nsITextContent.h"
#include "nsITimer.h"
#include "nsIURL.h"
#include "nsIWebShell.h"
#include "nsIXMLContent.h"
@ -121,33 +122,34 @@
// CIDs
//
static NS_DEFINE_CID(kEventListenerManagerCID, NS_EVENTLISTENERMANAGER_CID);
static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID);
static NS_DEFINE_CID(kCSSParserCID, NS_CSSPARSER_CID);
static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID);
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
static NS_DEFINE_CID(kEventListenerManagerCID, NS_EVENTLISTENERMANAGER_CID);
static NS_DEFINE_CID(kHTMLCSSStyleSheetCID, NS_HTML_CSS_STYLESHEET_CID);
static NS_DEFINE_CID(kHTMLElementFactoryCID, NS_HTML_ELEMENT_FACTORY_CID);
static NS_DEFINE_CID(kHTMLStyleSheetCID, NS_HTMLSTYLESHEET_CID);
static NS_DEFINE_CID(kHTMLCSSStyleSheetCID, NS_HTML_CSS_STYLESHEET_CID);
static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID);
static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID);
static NS_DEFINE_CID(kLWBrkCID, NS_LWBRK_CID);
static NS_DEFINE_CID(kLoadGroupCID, NS_LOADGROUP_CID);
static NS_DEFINE_CID(kLocalStoreCID, NS_LOCALSTORE_CID);
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
static NS_DEFINE_CID(kParserCID, NS_PARSER_IID); // XXX
static NS_DEFINE_CID(kPresShellCID, NS_PRESSHELL_CID);
static NS_DEFINE_CID(kRDFCompositeDataSourceCID, NS_RDFCOMPOSITEDATASOURCE_CID);
static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
static NS_DEFINE_CID(kLocalStoreCID, NS_LOCALSTORE_CID);
static NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID);
static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID);
static NS_DEFINE_CID(kTextNodeCID, NS_TEXTNODE_CID);
static NS_DEFINE_CID(kWellFormedDTDCID, NS_WELLFORMEDDTD_CID);
static NS_DEFINE_CID(kXMLElementFactoryCID, NS_XML_ELEMENT_FACTORY_CID);
static NS_DEFINE_CID(kXULCommandDispatcherCID, NS_XULCOMMANDDISPATCHER_CID);
static NS_DEFINE_CID(kXULContentSinkCID, NS_XULCONTENTSINK_CID);
static NS_DEFINE_CID(kXULContentUtilsCID, NS_XULCONTENTUTILS_CID);
static NS_DEFINE_CID(kXULCommandDispatcherCID, NS_XULCOMMANDDISPATCHER_CID);
static NS_DEFINE_CID(kXULKeyListenerCID, NS_XULKEYLISTENER_CID);
static NS_DEFINE_CID(kXULPrototypeCacheCID, NS_XULPROTOTYPECACHE_CID);
static NS_DEFINE_CID(kXULTemplateBuilderCID, NS_XULTEMPLATEBUILDER_CID);
static NS_DEFINE_CID(kLWBrkCID, NS_LWBRK_CID);
static NS_DEFINE_IID(kIParserIID, NS_IPARSER_IID);
@ -217,17 +219,19 @@ PRLogModuleInfo* nsXULDocument::gXULLog;
class PlaceholderChannel : public nsIChannel
{
protected:
PlaceholderChannel();
virtual ~PlaceholderChannel();
static PRInt32 gRefCnt;
static nsIURI* gURI;
PlaceholderChannel();
virtual ~PlaceholderChannel();
static PRInt32 gRefCnt;
static nsIURI* gURI;
nsCOMPtr<nsILoadGroup> mLoadGroup;
public:
static nsresult
Create(nsIChannel** aResult);
static nsresult
Create(nsIChannel** aResult);
NS_DECL_ISUPPORTS
NS_DECL_ISUPPORTS
// nsIRequest
NS_IMETHOD IsPending(PRBool *_retval) { *_retval = PR_TRUE; return NS_OK; }
@ -249,8 +253,8 @@ public:
NS_IMETHOD GetContentLength(PRInt32 *aContentLength) { *aContentLength = 0; return NS_OK; }
NS_IMETHOD GetOwner(nsISupports * *aOwner) { *aOwner = nsnull; return NS_OK; }
NS_IMETHOD SetOwner(nsISupports * aOwner) { return NS_OK; }
NS_IMETHOD GetLoadGroup(nsILoadGroup * *aLoadGroup) { *aLoadGroup = nsnull; return NS_OK; }
NS_IMETHOD SetLoadGroup(nsILoadGroup * aLoadGroup) { return NS_OK; }
NS_IMETHOD GetLoadGroup(nsILoadGroup * *aLoadGroup) { *aLoadGroup = mLoadGroup; NS_IF_ADDREF(*aLoadGroup); return NS_OK; }
NS_IMETHOD SetLoadGroup(nsILoadGroup * aLoadGroup) { mLoadGroup = aLoadGroup; return NS_OK; }
NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor * *aNotificationCallbacks) { *aNotificationCallbacks = nsnull; return NS_OK; }
NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor * aNotificationCallbacks) { return NS_OK; }
};
@ -265,35 +269,36 @@ NS_IMPL_QUERY_INTERFACE2(PlaceholderChannel, nsIRequest, nsIChannel);
nsresult
PlaceholderChannel::Create(nsIChannel** aResult)
{
PlaceholderChannel* channel = new PlaceholderChannel();
if (! channel)
return NS_ERROR_OUT_OF_MEMORY;
PlaceholderChannel* channel = new PlaceholderChannel();
if (! channel)
return NS_ERROR_OUT_OF_MEMORY;
*aResult = channel;
NS_ADDREF(*aResult);
return NS_OK;
*aResult = channel;
NS_ADDREF(*aResult);
return NS_OK;
}
PlaceholderChannel::PlaceholderChannel()
{
NS_INIT_REFCNT();
if (gRefCnt++ == 0) {
nsresult rv;
rv = NS_NewURI(&gURI, "about:xul-master-placeholder", nsnull);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create about:xul-master-placeholder");
}
NS_INIT_REFCNT();
if (gRefCnt++ == 0) {
nsresult rv;
rv = NS_NewURI(&gURI, "about:xul-master-placeholder", nsnull);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create about:xul-master-placeholder");
}
}
PlaceholderChannel::~PlaceholderChannel()
{
if (--gRefCnt == 0) {
NS_IF_RELEASE(gURI);
}
if (--gRefCnt == 0) {
NS_IF_RELEASE(gURI);
}
}
//----------------------------------------------------------------------
//
// ctors & dtors
@ -1966,12 +1971,11 @@ nsXULDocument::ResolveForwardReferences()
NS_IMETHODIMP
nsXULDocument::CreateFromPrototype(const char* aCommand,
nsIXULPrototypeDocument* aPrototype,
nsISupports* aContainer)
nsIXULPrototypeDocument* aPrototype)
{
nsresult rv;
mCurrentPrototype = aPrototype;
mMasterPrototype = mCurrentPrototype = aPrototype;
rv = mCurrentPrototype->GetURI(getter_AddRefs(mDocumentURL));
if (NS_FAILED(rv)) return rv;
@ -1984,9 +1988,34 @@ nsXULDocument::CreateFromPrototype(const char* aCommand,
rv = AddPrototypeSheets();
if (NS_FAILED(rv)) return rv;
// Now create the delegates from the prototype
rv = PrepareToWalk();
if (NS_FAILED(rv)) return rv;
{
nsCOMPtr<nsILoadGroup> loadgroup;
rv = nsComponentManager::CreateInstance(kLoadGroupCID,
nsnull,
NS_GET_IID(nsILoadGroup),
getter_AddRefs(loadgroup));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIStreamObserver> loader;
rv = CachedChromeLoader::Create(this, getter_AddRefs(loader));
if (NS_FAILED(rv)) return rv;
rv = loadgroup->Init(loader);
if (NS_FAILED(rv)) return rv;
// Even though we are only holding a weak reference to the
// load group, any channels that get added to the load group
// will acquire strong refs, keeping the load group alive
// until the last channel is complete.
mDocumentLoadGroup = getter_AddRefs(NS_GetWeakReference(loadgroup));
// Now create the delegates from the prototype
rv = PrepareToWalk();
if (NS_FAILED(rv)) return rv;
// Closing this scope will result in the placeholder channel
// being the only reference to the load group.
}
rv = ResumeWalk();
return rv;
@ -3922,7 +3951,7 @@ nsXULDocument::PrepareToLoadPrototype(nsIURI* aURI, const char* aCommand,
if (NS_FAILED(rv)) return rv;
// Bootstrap the master document prototype
if (!mMasterPrototype.get()) {
if (! mMasterPrototype) {
mMasterPrototype = mCurrentPrototype;
mMasterPrototype->SetDocumentPrincipal(aDocumentPrincipal);
}
@ -4321,18 +4350,21 @@ nsXULDocument::PrepareToWalk()
// Add the root element to the XUL document's ID-to-element map.
rv = AddElementToMap(root);
if (NS_FAILED(rv)) return rv;
// Add a dummy channel to the load group as a placeholder for the document
// load
rv = PlaceholderChannel::Create(getter_AddRefs(mPlaceholderChannel));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
NS_ASSERTION(group != nsnull, "no load group");
if (group) {
rv = group->AddChannel(mPlaceholderChannel, nsnull);
if (NS_FAILED(rv)) return rv;
rv = mPlaceholderChannel->SetLoadGroup(group);
if (NS_FAILED(rv)) return rv;
rv = group->AddChannel(mPlaceholderChannel, nsnull);
if (NS_FAILED(rv)) return rv;
}
}
@ -4669,17 +4701,17 @@ nsXULDocument::ResumeWalk()
}
#endif
// Remove the placeholder channel; if we're the last channel in the
// load group, this will fire the OnEndDocumentLoad() method in the
// webshell, and run the onload handlers, etc.
nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
if (group) {
rv = group->RemoveChannel(mPlaceholderChannel, nsnull, NS_OK, nsnull);
if (NS_FAILED(rv)) return rv;
mPlaceholderChannel = nsnull;
}
// Remove the placeholder channel; if we're the last channel in the
// load group, this will fire the OnEndDocumentLoad() method in the
// webshell, and run the onload handlers, etc.
nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
if (group) {
rv = group->RemoveChannel(mPlaceholderChannel, nsnull, NS_OK, nsnull);
if (NS_FAILED(rv)) return rv;
mPlaceholderChannel = nsnull;
}
return rv;
}
@ -5507,3 +5539,141 @@ nsXULDocument::IsChromeURI(nsIURI* aURI)
return PR_FALSE;
}
//----------------------------------------------------------------------
//
// CachedChromeLoader
//
nsXULDocument::CachedChromeLoader::CachedChromeLoader(nsXULDocument* aDocument)
: mDocument(aDocument),
mLoading(PR_TRUE)
{
NS_INIT_REFCNT();
NS_ADDREF(aDocument);
}
nsXULDocument::CachedChromeLoader::~CachedChromeLoader()
{
NS_RELEASE(mDocument);
}
nsresult
nsXULDocument::CachedChromeLoader::Create(nsXULDocument* aDocument, nsIStreamObserver** aResult)
{
CachedChromeLoader* loader = new CachedChromeLoader(aDocument);
if (! loader)
return NS_ERROR_OUT_OF_MEMORY;
*aResult = loader;
NS_ADDREF(*aResult);
return NS_OK;
}
NS_IMPL_ADDREF(nsXULDocument::CachedChromeLoader);
NS_IMPL_RELEASE(nsXULDocument::CachedChromeLoader);
NS_IMETHODIMP
nsXULDocument::CachedChromeLoader::QueryInterface(REFNSIID aIID, void** aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(NS_GET_IID(nsIStreamObserver)) ||
aIID.Equals(NS_GET_IID(nsISupports))) {
*aResult = this;
NS_ADDREF(this);
return NS_OK;
}
else {
*aResult = nsnull;
return NS_NOINTERFACE;
}
}
NS_IMETHODIMP
nsXULDocument::CachedChromeLoader::OnStartRequest(nsIChannel* aChannel, nsISupports* aContext)
{
return NS_OK;
}
NS_IMETHODIMP
nsXULDocument::CachedChromeLoader::OnStopRequest(nsIChannel* aChannel,
nsISupports* aContext,
nsresult aStatus,
const PRUnichar* aErrorMsg)
{
// Not loading. Bail!
if (! mLoading)
return NS_OK;
nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocument->mDocumentLoadGroup);
// No more load group. Bail!
if (! group)
return NS_OK;
nsresult rv;
PRUint32 count;
rv = group->GetActiveCount(&count);
if (NS_FAILED(rv)) return rv;
// Still loading. Bail!
if (count != 0)
return NS_OK;
mLoading = PR_FALSE;
for (PRInt32 i = mDocument->GetNumberOfShells() - 1; i >= 0; --i) {
// Walk from the pres shell down to the script context
// owner. We'll consider any failure along the way
// non-terminal, and will continue on to the other pres
// shells.
nsIPresShell* shell = mDocument->GetShellAt(i);
NS_ASSERTION(shell != nsnull, "null shell");
if (! shell)
continue;
// the pres shell has a pres context...
nsCOMPtr<nsIPresContext> presContext;
shell->GetPresContext(getter_AddRefs(presContext));
NS_ASSERTION(presContext != nsnull, "shell has no pres context");
if (! presContext)
continue;
// the pres context should have a content container (really the webshell)...
nsCOMPtr<nsISupports> container;
presContext->GetContainer(getter_AddRefs(container));
NS_ASSERTION(container != nsnull, "pres context has no container");
if (! container)
continue;
// the container should be a script context owner...
nsCOMPtr<nsIScriptContextOwner> owner = do_QueryInterface(container);
NS_ASSERTION(owner != nsnull, "container is not a script context owner");
if (! owner)
continue;
// and the script context owner has a script global object...
nsCOMPtr<nsIScriptGlobalObject> global;
rv = owner->GetScriptGlobalObject(getter_AddRefs(global));
if (NS_FAILED(rv))
continue;
// dispatch the 'load' event to the script global object
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event;
event.eventStructType = NS_EVENT;
event.message = NS_PAGE_LOAD;
rv = global->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
if (NS_FAILED(rv))
continue;
}
return NS_OK;
}

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

@ -66,6 +66,7 @@ class nsILoadGroup;
class nsIRDFResource;
class nsIRDFService;
class nsIScriptContextOwner;
class nsITimer;
class nsIUnicharStreamLoader;
class nsIXMLElementFactory;
class nsIXULContentUtils;
@ -285,8 +286,7 @@ public:
NS_IMETHOD ResolveForwardReferences();
NS_IMETHOD CreateFromPrototype(const char* aCommand,
nsIXULPrototypeDocument* aPrototype,
nsISupports* aContainer);
nsIXULPrototypeDocument* aPrototype);
// nsIStreamLoadableDocument interface
NS_IMETHOD LoadFromStream(nsIInputStream& xulStream,
@ -748,6 +748,27 @@ protected:
// timing
nsTime mLoadStart;
#endif
class CachedChromeLoader : public nsIStreamObserver
{
protected:
CachedChromeLoader(nsXULDocument* aDocument);
virtual ~CachedChromeLoader();
nsXULDocument* mDocument;
PRBool mLoading;
public:
static nsresult Create(nsXULDocument* aDocument, nsIStreamObserver** aResult);
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIStreamObserver interface
NS_DECL_NSISTREAMOBSERVER
};
friend class CachedChromeLoader;
};

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

@ -1,12 +1,14 @@
nsIDOMXULCommandDispatcher.h
nsIDOMXULDocument.h
nsIDOMXULEditorElement.h
nsIDOMXULElement.h
nsIDOMXULTreeElement.h
nsIDOMXULEditorElement.h
nsIStreamLoadableDocument.h
nsIXULCommandDispatcher.h
nsIXULContentSink.h
nsIXULContentUtils.h
nsIXULDocument.h
nsIXULKeyListener.h
nsIXULPopupListener.h
nsIXULPrototypeCache.h
nsIXULCommandDispatcher.h
nsIXULKeyListener.h
nsIStreamLoadableDocument.h
nsIXULPrototypeDocument.h

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

@ -29,18 +29,20 @@ include $(DEPTH)/config/autoconf.mk
MODULE = rdf
EXPORTS = \
nsIDOMXULCommandDispatcher.h \
nsIDOMXULDocument.h \
nsIDOMXULEditorElement.h \
nsIDOMXULElement.h \
nsIDOMXULTreeElement.h \
nsIDOMXULEditorElement.h \
nsIStreamLoadableDocument.h \
nsIXULCommandDispatcher.h \
nsIXULContentSink.h \
nsIXULContentUtils.h \
nsIXULDocument.h \
nsIXULKeyListener.h \
nsIXULPopupListener.h \
nsIXULPrototypeCache.h \
nsIDOMXULCommandDispatcher.h \
nsIXULContentUtils.h \
nsIXULCommandDispatcher.h \
nsIStreamLoadableDocument.h \
nsIXULKeyListener.h \
nsIXULPrototypeDocument.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))

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

@ -25,18 +25,20 @@ MODULE=rdf
DEPTH=..\..\..
EXPORTS = \
nsIDOMXULCommandDispatcher.h \
nsIStreamLoadableDocument.h \
nsIXULCommandDispatcher.h \
nsIXULKeyListener.h \
nsIXULPopupListener.h \
nsIDOMXULDocument.h \
nsIDOMXULEditorElement.h \
nsIDOMXULElement.h \
nsIDOMXULTreeElement.h \
nsIDOMXULEditorElement.h \
nsIXULContentSink.h \
nsIXULPopupListener.h \
nsIXULPrototypeCache.h \
nsIDOMXULCommandDispatcher.h \
nsIXULCommandDispatcher.h \
nsIXULContentUtils.h \
nsIStreamLoadableDocument.h \
nsIXULKeyListener.h \
nsIXULDocument.h \
nsIXULPrototypeCache.h \
nsIXULPrototypeDocument.h \
$(NULL)
include <$(DEPTH)/config/rules.mak>

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

@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
An XUL-specific extension to nsIXMLDocument. Includes methods for
setting the root resource of the document content model, a factory
method for constructing the children of a node, etc.
XXX This should really be called nsIXULDocument.
*/
#ifndef nsIXULDocument_h___
#define nsIXULDocument_h___
class nsIContent; // XXX nsIXMLDocument.h is bad and doesn't declare this class...
#include "nsIXMLDocument.h"
class nsForwardReference;
class nsIAtom;
class nsIDOMElement;
class nsIDOMHTMLFormElement;
class nsIPrincipal;
class nsIRDFContentModelBuilder;
class nsIRDFResource;
class nsISupportsArray;
class nsIXULPrototypeDocument;
// {954F0811-81DC-11d2-B52A-000000000000}
#define NS_IRDFDOCUMENT_IID \
{ 0x954f0811, 0x81dc, 0x11d2, { 0xb5, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }
/**
* RDF document extensions to nsIDocument
*/
class nsIRDFDataSource;
class nsIXULDocument : public nsIXMLDocument
{
public:
static const nsIID& GetIID() { static nsIID iid = NS_IRDFDOCUMENT_IID; return iid; }
// The resource-to-element map is a one-to-many mapping of RDF
// resources to content elements.
/**
* Add an entry to the ID-to-element map.
*/
NS_IMETHOD AddElementForID(const nsString& aID, nsIContent* aElement) = 0;
/**
* Remove an entry from the ID-to-element map.
*/
NS_IMETHOD RemoveElementForID(const nsString& aID, nsIContent* aElement) = 0;
/**
* Get the elements for a particular resource in the resource-to-element
* map. The nsISupportsArray will be truncated and filled in with
* nsIContent pointers.
*/
NS_IMETHOD GetElementsForID(const nsString& aID, nsISupportsArray* aElements) = 0;
NS_IMETHOD CreateContents(nsIContent* aElement) = 0;
/**
* Add a content model builder to the document.
*/
NS_IMETHOD AddContentModelBuilder(nsIRDFContentModelBuilder* aBuilder) = 0;
/**
* Manipulate the XUL document's form element
*/
NS_IMETHOD GetForm(nsIDOMHTMLFormElement** aForm) = 0;
NS_IMETHOD SetForm(nsIDOMHTMLFormElement* aForm) = 0;
/**
* Add a "forward declaration" of a XUL observer. Such declarations
* will be resolved when document loading completes.
*/
NS_IMETHOD AddForwardReference(nsForwardReference* aForwardReference) = 0;
NS_IMETHOD ResolveForwardReferences() = 0;
/**
* Create a XUL document from a prototype
*/
NS_IMETHOD CreateFromPrototype(const char* aCommand,
nsIXULPrototypeDocument* aPrototype) = 0;
};
// factory functions
nsresult NS_NewXULDocument(nsIXULDocument** result);
#endif // nsIXULDocument_h___

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

@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
*/
#ifndef nsIXULPrototypeDocument_h__
#define nsIXULPrototypeDocument_h__
#include "nsISupports.h"
class nsIAtom;
class nsIPrincipal;
class nsIURI;
class nsIStyleSheet;
class nsString;
class nsVoidArray;
class nsXULPrototypeElement;
// {187A63D0-8337-11d3-BE47-00104BDE6048}
#define NS_IXULPROTOTYPEDOCUMENT_IID \
{ 0x187a63d0, 0x8337, 0x11d3, { 0xbe, 0x47, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } }
class nsIXULPrototypeDocument : public nsISupports
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IXULPROTOTYPEDOCUMENT_IID);
/**
* Retrieve the URI of the document
*/
NS_IMETHOD SetURI(nsIURI* aURI) = 0;
NS_IMETHOD GetURI(nsIURI** aResult) = 0;
/**
* Retrieve the root XULPrototype element of the document.
*/
NS_IMETHOD GetRootElement(nsXULPrototypeElement** aResult) = 0;
NS_IMETHOD SetRootElement(nsXULPrototypeElement* aElement) = 0;
NS_IMETHOD AddStyleSheetReference(nsIURI* aStyleSheet) = 0;
NS_IMETHOD GetStyleSheetReferences(nsISupportsArray** aResult) = 0;
NS_IMETHOD AddOverlayReference(nsIURI* aURI) = 0;
NS_IMETHOD GetOverlayReferences(nsISupportsArray** aResult) = 0;
NS_IMETHOD GetHeaderData(nsIAtom* aField, nsString& aData) const = 0;
NS_IMETHOD SetHeaderData(nsIAtom* aField, const nsString& aData) = 0;
NS_IMETHOD GetDocumentPrincipal(nsIPrincipal** aResult) = 0;
NS_IMETHOD SetDocumentPrincipal(nsIPrincipal* aPrincipal) = 0;
};
extern NS_IMETHODIMP
NS_NewXULPrototypeDocument(nsISupports* aOuter, REFNSIID aIID, void** aResult);
#endif // nsIXULPrototypeDocument_h__

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

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

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

@ -91,6 +91,7 @@
#include "nsIStyleSet.h"
#include "nsIStyleSheet.h"
#include "nsITextContent.h"
#include "nsITimer.h"
#include "nsIURL.h"
#include "nsIWebShell.h"
#include "nsIXMLContent.h"
@ -121,33 +122,34 @@
// CIDs
//
static NS_DEFINE_CID(kEventListenerManagerCID, NS_EVENTLISTENERMANAGER_CID);
static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID);
static NS_DEFINE_CID(kCSSParserCID, NS_CSSPARSER_CID);
static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID);
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
static NS_DEFINE_CID(kEventListenerManagerCID, NS_EVENTLISTENERMANAGER_CID);
static NS_DEFINE_CID(kHTMLCSSStyleSheetCID, NS_HTML_CSS_STYLESHEET_CID);
static NS_DEFINE_CID(kHTMLElementFactoryCID, NS_HTML_ELEMENT_FACTORY_CID);
static NS_DEFINE_CID(kHTMLStyleSheetCID, NS_HTMLSTYLESHEET_CID);
static NS_DEFINE_CID(kHTMLCSSStyleSheetCID, NS_HTML_CSS_STYLESHEET_CID);
static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID);
static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID);
static NS_DEFINE_CID(kLWBrkCID, NS_LWBRK_CID);
static NS_DEFINE_CID(kLoadGroupCID, NS_LOADGROUP_CID);
static NS_DEFINE_CID(kLocalStoreCID, NS_LOCALSTORE_CID);
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
static NS_DEFINE_CID(kParserCID, NS_PARSER_IID); // XXX
static NS_DEFINE_CID(kPresShellCID, NS_PRESSHELL_CID);
static NS_DEFINE_CID(kRDFCompositeDataSourceCID, NS_RDFCOMPOSITEDATASOURCE_CID);
static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
static NS_DEFINE_CID(kLocalStoreCID, NS_LOCALSTORE_CID);
static NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID);
static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID);
static NS_DEFINE_CID(kTextNodeCID, NS_TEXTNODE_CID);
static NS_DEFINE_CID(kWellFormedDTDCID, NS_WELLFORMEDDTD_CID);
static NS_DEFINE_CID(kXMLElementFactoryCID, NS_XML_ELEMENT_FACTORY_CID);
static NS_DEFINE_CID(kXULCommandDispatcherCID, NS_XULCOMMANDDISPATCHER_CID);
static NS_DEFINE_CID(kXULContentSinkCID, NS_XULCONTENTSINK_CID);
static NS_DEFINE_CID(kXULContentUtilsCID, NS_XULCONTENTUTILS_CID);
static NS_DEFINE_CID(kXULCommandDispatcherCID, NS_XULCOMMANDDISPATCHER_CID);
static NS_DEFINE_CID(kXULKeyListenerCID, NS_XULKEYLISTENER_CID);
static NS_DEFINE_CID(kXULPrototypeCacheCID, NS_XULPROTOTYPECACHE_CID);
static NS_DEFINE_CID(kXULTemplateBuilderCID, NS_XULTEMPLATEBUILDER_CID);
static NS_DEFINE_CID(kLWBrkCID, NS_LWBRK_CID);
static NS_DEFINE_IID(kIParserIID, NS_IPARSER_IID);
@ -217,17 +219,19 @@ PRLogModuleInfo* nsXULDocument::gXULLog;
class PlaceholderChannel : public nsIChannel
{
protected:
PlaceholderChannel();
virtual ~PlaceholderChannel();
static PRInt32 gRefCnt;
static nsIURI* gURI;
PlaceholderChannel();
virtual ~PlaceholderChannel();
static PRInt32 gRefCnt;
static nsIURI* gURI;
nsCOMPtr<nsILoadGroup> mLoadGroup;
public:
static nsresult
Create(nsIChannel** aResult);
static nsresult
Create(nsIChannel** aResult);
NS_DECL_ISUPPORTS
NS_DECL_ISUPPORTS
// nsIRequest
NS_IMETHOD IsPending(PRBool *_retval) { *_retval = PR_TRUE; return NS_OK; }
@ -249,8 +253,8 @@ public:
NS_IMETHOD GetContentLength(PRInt32 *aContentLength) { *aContentLength = 0; return NS_OK; }
NS_IMETHOD GetOwner(nsISupports * *aOwner) { *aOwner = nsnull; return NS_OK; }
NS_IMETHOD SetOwner(nsISupports * aOwner) { return NS_OK; }
NS_IMETHOD GetLoadGroup(nsILoadGroup * *aLoadGroup) { *aLoadGroup = nsnull; return NS_OK; }
NS_IMETHOD SetLoadGroup(nsILoadGroup * aLoadGroup) { return NS_OK; }
NS_IMETHOD GetLoadGroup(nsILoadGroup * *aLoadGroup) { *aLoadGroup = mLoadGroup; NS_IF_ADDREF(*aLoadGroup); return NS_OK; }
NS_IMETHOD SetLoadGroup(nsILoadGroup * aLoadGroup) { mLoadGroup = aLoadGroup; return NS_OK; }
NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor * *aNotificationCallbacks) { *aNotificationCallbacks = nsnull; return NS_OK; }
NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor * aNotificationCallbacks) { return NS_OK; }
};
@ -265,35 +269,36 @@ NS_IMPL_QUERY_INTERFACE2(PlaceholderChannel, nsIRequest, nsIChannel);
nsresult
PlaceholderChannel::Create(nsIChannel** aResult)
{
PlaceholderChannel* channel = new PlaceholderChannel();
if (! channel)
return NS_ERROR_OUT_OF_MEMORY;
PlaceholderChannel* channel = new PlaceholderChannel();
if (! channel)
return NS_ERROR_OUT_OF_MEMORY;
*aResult = channel;
NS_ADDREF(*aResult);
return NS_OK;
*aResult = channel;
NS_ADDREF(*aResult);
return NS_OK;
}
PlaceholderChannel::PlaceholderChannel()
{
NS_INIT_REFCNT();
if (gRefCnt++ == 0) {
nsresult rv;
rv = NS_NewURI(&gURI, "about:xul-master-placeholder", nsnull);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create about:xul-master-placeholder");
}
NS_INIT_REFCNT();
if (gRefCnt++ == 0) {
nsresult rv;
rv = NS_NewURI(&gURI, "about:xul-master-placeholder", nsnull);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create about:xul-master-placeholder");
}
}
PlaceholderChannel::~PlaceholderChannel()
{
if (--gRefCnt == 0) {
NS_IF_RELEASE(gURI);
}
if (--gRefCnt == 0) {
NS_IF_RELEASE(gURI);
}
}
//----------------------------------------------------------------------
//
// ctors & dtors
@ -1966,12 +1971,11 @@ nsXULDocument::ResolveForwardReferences()
NS_IMETHODIMP
nsXULDocument::CreateFromPrototype(const char* aCommand,
nsIXULPrototypeDocument* aPrototype,
nsISupports* aContainer)
nsIXULPrototypeDocument* aPrototype)
{
nsresult rv;
mCurrentPrototype = aPrototype;
mMasterPrototype = mCurrentPrototype = aPrototype;
rv = mCurrentPrototype->GetURI(getter_AddRefs(mDocumentURL));
if (NS_FAILED(rv)) return rv;
@ -1984,9 +1988,34 @@ nsXULDocument::CreateFromPrototype(const char* aCommand,
rv = AddPrototypeSheets();
if (NS_FAILED(rv)) return rv;
// Now create the delegates from the prototype
rv = PrepareToWalk();
if (NS_FAILED(rv)) return rv;
{
nsCOMPtr<nsILoadGroup> loadgroup;
rv = nsComponentManager::CreateInstance(kLoadGroupCID,
nsnull,
NS_GET_IID(nsILoadGroup),
getter_AddRefs(loadgroup));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIStreamObserver> loader;
rv = CachedChromeLoader::Create(this, getter_AddRefs(loader));
if (NS_FAILED(rv)) return rv;
rv = loadgroup->Init(loader);
if (NS_FAILED(rv)) return rv;
// Even though we are only holding a weak reference to the
// load group, any channels that get added to the load group
// will acquire strong refs, keeping the load group alive
// until the last channel is complete.
mDocumentLoadGroup = getter_AddRefs(NS_GetWeakReference(loadgroup));
// Now create the delegates from the prototype
rv = PrepareToWalk();
if (NS_FAILED(rv)) return rv;
// Closing this scope will result in the placeholder channel
// being the only reference to the load group.
}
rv = ResumeWalk();
return rv;
@ -3922,7 +3951,7 @@ nsXULDocument::PrepareToLoadPrototype(nsIURI* aURI, const char* aCommand,
if (NS_FAILED(rv)) return rv;
// Bootstrap the master document prototype
if (!mMasterPrototype.get()) {
if (! mMasterPrototype) {
mMasterPrototype = mCurrentPrototype;
mMasterPrototype->SetDocumentPrincipal(aDocumentPrincipal);
}
@ -4321,18 +4350,21 @@ nsXULDocument::PrepareToWalk()
// Add the root element to the XUL document's ID-to-element map.
rv = AddElementToMap(root);
if (NS_FAILED(rv)) return rv;
// Add a dummy channel to the load group as a placeholder for the document
// load
rv = PlaceholderChannel::Create(getter_AddRefs(mPlaceholderChannel));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
NS_ASSERTION(group != nsnull, "no load group");
if (group) {
rv = group->AddChannel(mPlaceholderChannel, nsnull);
if (NS_FAILED(rv)) return rv;
rv = mPlaceholderChannel->SetLoadGroup(group);
if (NS_FAILED(rv)) return rv;
rv = group->AddChannel(mPlaceholderChannel, nsnull);
if (NS_FAILED(rv)) return rv;
}
}
@ -4669,17 +4701,17 @@ nsXULDocument::ResumeWalk()
}
#endif
// Remove the placeholder channel; if we're the last channel in the
// load group, this will fire the OnEndDocumentLoad() method in the
// webshell, and run the onload handlers, etc.
nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
if (group) {
rv = group->RemoveChannel(mPlaceholderChannel, nsnull, NS_OK, nsnull);
if (NS_FAILED(rv)) return rv;
mPlaceholderChannel = nsnull;
}
// Remove the placeholder channel; if we're the last channel in the
// load group, this will fire the OnEndDocumentLoad() method in the
// webshell, and run the onload handlers, etc.
nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
if (group) {
rv = group->RemoveChannel(mPlaceholderChannel, nsnull, NS_OK, nsnull);
if (NS_FAILED(rv)) return rv;
mPlaceholderChannel = nsnull;
}
return rv;
}
@ -5507,3 +5539,141 @@ nsXULDocument::IsChromeURI(nsIURI* aURI)
return PR_FALSE;
}
//----------------------------------------------------------------------
//
// CachedChromeLoader
//
nsXULDocument::CachedChromeLoader::CachedChromeLoader(nsXULDocument* aDocument)
: mDocument(aDocument),
mLoading(PR_TRUE)
{
NS_INIT_REFCNT();
NS_ADDREF(aDocument);
}
nsXULDocument::CachedChromeLoader::~CachedChromeLoader()
{
NS_RELEASE(mDocument);
}
nsresult
nsXULDocument::CachedChromeLoader::Create(nsXULDocument* aDocument, nsIStreamObserver** aResult)
{
CachedChromeLoader* loader = new CachedChromeLoader(aDocument);
if (! loader)
return NS_ERROR_OUT_OF_MEMORY;
*aResult = loader;
NS_ADDREF(*aResult);
return NS_OK;
}
NS_IMPL_ADDREF(nsXULDocument::CachedChromeLoader);
NS_IMPL_RELEASE(nsXULDocument::CachedChromeLoader);
NS_IMETHODIMP
nsXULDocument::CachedChromeLoader::QueryInterface(REFNSIID aIID, void** aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(NS_GET_IID(nsIStreamObserver)) ||
aIID.Equals(NS_GET_IID(nsISupports))) {
*aResult = this;
NS_ADDREF(this);
return NS_OK;
}
else {
*aResult = nsnull;
return NS_NOINTERFACE;
}
}
NS_IMETHODIMP
nsXULDocument::CachedChromeLoader::OnStartRequest(nsIChannel* aChannel, nsISupports* aContext)
{
return NS_OK;
}
NS_IMETHODIMP
nsXULDocument::CachedChromeLoader::OnStopRequest(nsIChannel* aChannel,
nsISupports* aContext,
nsresult aStatus,
const PRUnichar* aErrorMsg)
{
// Not loading. Bail!
if (! mLoading)
return NS_OK;
nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocument->mDocumentLoadGroup);
// No more load group. Bail!
if (! group)
return NS_OK;
nsresult rv;
PRUint32 count;
rv = group->GetActiveCount(&count);
if (NS_FAILED(rv)) return rv;
// Still loading. Bail!
if (count != 0)
return NS_OK;
mLoading = PR_FALSE;
for (PRInt32 i = mDocument->GetNumberOfShells() - 1; i >= 0; --i) {
// Walk from the pres shell down to the script context
// owner. We'll consider any failure along the way
// non-terminal, and will continue on to the other pres
// shells.
nsIPresShell* shell = mDocument->GetShellAt(i);
NS_ASSERTION(shell != nsnull, "null shell");
if (! shell)
continue;
// the pres shell has a pres context...
nsCOMPtr<nsIPresContext> presContext;
shell->GetPresContext(getter_AddRefs(presContext));
NS_ASSERTION(presContext != nsnull, "shell has no pres context");
if (! presContext)
continue;
// the pres context should have a content container (really the webshell)...
nsCOMPtr<nsISupports> container;
presContext->GetContainer(getter_AddRefs(container));
NS_ASSERTION(container != nsnull, "pres context has no container");
if (! container)
continue;
// the container should be a script context owner...
nsCOMPtr<nsIScriptContextOwner> owner = do_QueryInterface(container);
NS_ASSERTION(owner != nsnull, "container is not a script context owner");
if (! owner)
continue;
// and the script context owner has a script global object...
nsCOMPtr<nsIScriptGlobalObject> global;
rv = owner->GetScriptGlobalObject(getter_AddRefs(global));
if (NS_FAILED(rv))
continue;
// dispatch the 'load' event to the script global object
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event;
event.eventStructType = NS_EVENT;
event.message = NS_PAGE_LOAD;
rv = global->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
if (NS_FAILED(rv))
continue;
}
return NS_OK;
}

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

@ -66,6 +66,7 @@ class nsILoadGroup;
class nsIRDFResource;
class nsIRDFService;
class nsIScriptContextOwner;
class nsITimer;
class nsIUnicharStreamLoader;
class nsIXMLElementFactory;
class nsIXULContentUtils;
@ -285,8 +286,7 @@ public:
NS_IMETHOD ResolveForwardReferences();
NS_IMETHOD CreateFromPrototype(const char* aCommand,
nsIXULPrototypeDocument* aPrototype,
nsISupports* aContainer);
nsIXULPrototypeDocument* aPrototype);
// nsIStreamLoadableDocument interface
NS_IMETHOD LoadFromStream(nsIInputStream& xulStream,
@ -748,6 +748,27 @@ protected:
// timing
nsTime mLoadStart;
#endif
class CachedChromeLoader : public nsIStreamObserver
{
protected:
CachedChromeLoader(nsXULDocument* aDocument);
virtual ~CachedChromeLoader();
nsXULDocument* mDocument;
PRBool mLoading;
public:
static nsresult Create(nsXULDocument* aDocument, nsIStreamObserver** aResult);
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIStreamObserver interface
NS_DECL_NSISTREAMOBSERVER
};
friend class CachedChromeLoader;
};