1999-08-30 02:45:54 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
1998-12-24 05:07:14 +00:00
|
|
|
*
|
1999-11-06 03:43:54 +00:00
|
|
|
* 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/
|
1998-12-24 05:07:14 +00:00
|
|
|
*
|
1999-11-06 03:43:54 +00:00
|
|
|
* 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.
|
1998-12-24 05:07:14 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Mozilla Communicator client code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
1999-11-06 03:43:54 +00:00
|
|
|
* Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
2000-01-11 20:49:15 +00:00
|
|
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
1998-12-24 05:07:14 +00:00
|
|
|
*/
|
|
|
|
|
1999-01-05 21:57:59 +00:00
|
|
|
/*
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
An implementation for the XUL document. This implementation serves
|
|
|
|
as the basis for generating an NGLayout content model.
|
1999-01-05 21:57:59 +00:00
|
|
|
|
1999-08-30 02:45:54 +00:00
|
|
|
To Do
|
|
|
|
-----
|
1999-01-14 10:55:08 +00:00
|
|
|
|
1999-08-30 02:45:54 +00:00
|
|
|
1. Implement DOM range constructors.
|
|
|
|
|
|
|
|
2. Implement XIF conversion (this is really low priority).
|
|
|
|
|
|
|
|
Notes
|
|
|
|
-----
|
|
|
|
|
|
|
|
1. We do some monkey business in the document observer methods to
|
|
|
|
keep the element map in sync for HTML elements. Why don't we just
|
|
|
|
do it for _all_ elements? Well, in the case of XUL elements,
|
|
|
|
which may be lazily created during frame construction, the
|
|
|
|
document observer methods will never be called because we'll be
|
|
|
|
adding the XUL nodes into the content model "quietly".
|
|
|
|
|
|
|
|
2. The "element map" maps an RDF resource to the elements whose 'id'
|
|
|
|
or 'ref' attributes refer to that resource. We re-use the element
|
|
|
|
map to support the HTML-like 'getElementById()' method.
|
|
|
|
|
|
|
|
*/
|
1999-01-05 21:57:59 +00:00
|
|
|
|
1999-04-16 08:38:17 +00:00
|
|
|
// Note the ALPHABETICAL ORDERING
|
1999-10-29 01:21:15 +00:00
|
|
|
#include "nsXULDocument.h"
|
|
|
|
|
1999-04-16 08:38:17 +00:00
|
|
|
#include "nsDOMCID.h"
|
1999-10-29 01:21:15 +00:00
|
|
|
#include "nsIBrowserWindow.h"
|
|
|
|
#include "nsIChromeRegistry.h"
|
|
|
|
#include "nsIComponentManager.h"
|
1999-12-06 23:05:31 +00:00
|
|
|
#include "nsIContentSink.h" // for NS_CONTENT_ID_COUNTER_BASE
|
1999-10-29 01:21:15 +00:00
|
|
|
#include "nsIContentViewer.h"
|
1999-11-02 01:14:07 +00:00
|
|
|
#include "nsICSSStyleSheet.h"
|
1999-05-16 07:05:51 +00:00
|
|
|
#include "nsIDOMEvent.h"
|
1999-10-29 01:21:15 +00:00
|
|
|
#include "nsIDOMEventListener.h"
|
|
|
|
#include "nsIDOMEventReceiver.h"
|
1999-02-16 19:30:04 +00:00
|
|
|
#include "nsIDOMScriptObjectFactory.h"
|
|
|
|
#include "nsIDOMStyleSheetCollection.h"
|
1999-04-16 08:38:17 +00:00
|
|
|
#include "nsIDOMText.h"
|
|
|
|
#include "nsIDOMXULElement.h"
|
1998-12-24 05:07:14 +00:00
|
|
|
#include "nsIDTD.h"
|
|
|
|
#include "nsIDocumentObserver.h"
|
1999-10-29 01:21:15 +00:00
|
|
|
#include "nsIFormControl.h"
|
1999-05-28 11:30:59 +00:00
|
|
|
#include "nsIHTMLContent.h"
|
2000-01-19 03:11:39 +00:00
|
|
|
#include "nsIElementFactory.h"
|
1999-10-29 01:21:15 +00:00
|
|
|
#include "nsIInputStream.h"
|
|
|
|
#include "nsILoadGroup.h"
|
1999-04-16 08:38:17 +00:00
|
|
|
#include "nsINameSpace.h"
|
1998-12-24 05:07:14 +00:00
|
|
|
#include "nsIParser.h"
|
1999-01-12 19:41:06 +00:00
|
|
|
#include "nsIPresContext.h"
|
|
|
|
#include "nsIPresShell.h"
|
1999-11-18 02:25:33 +00:00
|
|
|
#include "nsIPrincipal.h"
|
1999-10-29 01:21:15 +00:00
|
|
|
#include "nsIPrivateDOMEvent.h"
|
1999-01-20 01:42:13 +00:00
|
|
|
#include "nsIRDFCompositeDataSource.h"
|
1999-05-05 03:09:50 +00:00
|
|
|
#include "nsIRDFContainerUtils.h"
|
1999-01-12 19:41:06 +00:00
|
|
|
#include "nsIRDFContentModelBuilder.h"
|
1998-12-24 05:07:14 +00:00
|
|
|
#include "nsIRDFNode.h"
|
1999-09-03 08:57:42 +00:00
|
|
|
#include "nsIRDFRemoteDataSource.h"
|
1999-01-05 03:53:15 +00:00
|
|
|
#include "nsIRDFService.h"
|
1998-12-24 05:07:14 +00:00
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsIStreamListener.h"
|
1999-04-16 08:38:17 +00:00
|
|
|
#include "nsIStyleContext.h"
|
1998-12-24 05:07:14 +00:00
|
|
|
#include "nsIStyleSet.h"
|
|
|
|
#include "nsIStyleSheet.h"
|
1999-04-16 08:38:17 +00:00
|
|
|
#include "nsITextContent.h"
|
1999-11-24 22:46:09 +00:00
|
|
|
#include "nsITimer.h"
|
1998-12-24 05:07:14 +00:00
|
|
|
#include "nsIURL.h"
|
|
|
|
#include "nsIWebShell.h"
|
1999-11-29 06:04:15 +00:00
|
|
|
#include "nsIBaseWindow.h"
|
1999-04-16 08:38:17 +00:00
|
|
|
#include "nsIXMLContent.h"
|
1999-10-29 01:21:15 +00:00
|
|
|
#include "nsIXULContent.h"
|
1999-02-16 19:30:04 +00:00
|
|
|
#include "nsIXULContentSink.h"
|
1999-10-29 01:21:15 +00:00
|
|
|
#include "nsIXULContentUtils.h"
|
|
|
|
#include "nsIXULKeyListener.h"
|
|
|
|
#include "nsIXULPrototypeCache.h"
|
|
|
|
#include "nsLWBrkCIID.h"
|
1998-12-24 05:07:14 +00:00
|
|
|
#include "nsLayoutCID.h"
|
1999-11-30 04:50:42 +00:00
|
|
|
#include "nsNetUtil.h"
|
1998-12-24 05:07:14 +00:00
|
|
|
#include "nsParserCIID.h"
|
1998-12-24 06:22:21 +00:00
|
|
|
#include "nsRDFCID.h"
|
1999-02-16 19:30:04 +00:00
|
|
|
#include "nsRDFDOMNodeList.h"
|
1999-10-29 01:21:15 +00:00
|
|
|
#include "nsXPIDLString.h"
|
1999-12-08 06:04:10 +00:00
|
|
|
#include "nsIDOMWindow.h"
|
1999-12-05 23:04:22 +00:00
|
|
|
#include "nsXULCommandDispatcher.h"
|
1999-10-29 01:21:15 +00:00
|
|
|
#include "nsXULDocument.h"
|
1999-10-20 18:55:32 +00:00
|
|
|
#include "nsXULElement.h"
|
1999-02-03 02:48:55 +00:00
|
|
|
#include "plstr.h"
|
1999-03-09 09:44:27 +00:00
|
|
|
#include "prlog.h"
|
1999-04-16 08:38:17 +00:00
|
|
|
#include "rdf.h"
|
1999-10-29 01:21:15 +00:00
|
|
|
#include "rdfutil.h"
|
1999-10-30 02:52:11 +00:00
|
|
|
#include "nsIFrame.h"
|
1999-02-23 03:31:26 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// CIDs
|
|
|
|
//
|
1998-12-24 05:07:14 +00:00
|
|
|
|
1999-11-24 22:46:09 +00:00
|
|
|
static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID);
|
1999-04-16 08:38:17 +00:00
|
|
|
static NS_DEFINE_CID(kCSSParserCID, NS_CSSPARSER_CID);
|
1999-11-24 22:46:09 +00:00
|
|
|
static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID);
|
1999-02-16 19:30:04 +00:00
|
|
|
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
1999-11-24 22:46:09 +00:00
|
|
|
static NS_DEFINE_CID(kEventListenerManagerCID, NS_EVENTLISTENERMANAGER_CID);
|
|
|
|
static NS_DEFINE_CID(kHTMLCSSStyleSheetCID, NS_HTML_CSS_STYLESHEET_CID);
|
1999-10-05 21:13:55 +00:00
|
|
|
static NS_DEFINE_CID(kHTMLElementFactoryCID, NS_HTML_ELEMENT_FACTORY_CID);
|
1999-04-16 08:38:17 +00:00
|
|
|
static NS_DEFINE_CID(kHTMLStyleSheetCID, NS_HTMLSTYLESHEET_CID);
|
1999-11-24 22:46:09 +00:00
|
|
|
static NS_DEFINE_CID(kLWBrkCID, NS_LWBRK_CID);
|
|
|
|
static NS_DEFINE_CID(kLoadGroupCID, NS_LOADGROUP_CID);
|
|
|
|
static NS_DEFINE_CID(kLocalStoreCID, NS_LOCALSTORE_CID);
|
1999-04-16 08:38:17 +00:00
|
|
|
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);
|
1999-02-16 19:30:04 +00:00
|
|
|
static NS_DEFINE_CID(kRDFCompositeDataSourceCID, NS_RDFCOMPOSITEDATASOURCE_CID);
|
1999-04-27 05:53:53 +00:00
|
|
|
static NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID);
|
1999-11-24 22:46:09 +00:00
|
|
|
static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
|
1999-04-16 08:38:17 +00:00
|
|
|
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);
|
1999-10-29 01:21:15 +00:00
|
|
|
static NS_DEFINE_CID(kXMLElementFactoryCID, NS_XML_ELEMENT_FACTORY_CID);
|
1999-04-16 08:38:17 +00:00
|
|
|
static NS_DEFINE_CID(kXULContentSinkCID, NS_XULCONTENTSINK_CID);
|
1999-09-07 02:51:13 +00:00
|
|
|
static NS_DEFINE_CID(kXULContentUtilsCID, NS_XULCONTENTUTILS_CID);
|
1999-10-29 01:21:15 +00:00
|
|
|
static NS_DEFINE_CID(kXULKeyListenerCID, NS_XULKEYLISTENER_CID);
|
|
|
|
static NS_DEFINE_CID(kXULPrototypeCacheCID, NS_XULPROTOTYPECACHE_CID);
|
|
|
|
static NS_DEFINE_CID(kXULTemplateBuilderCID, NS_XULTEMPLATEBUILDER_CID);
|
1999-02-03 02:48:55 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
static NS_DEFINE_IID(kIParserIID, NS_IPARSER_IID);
|
1999-02-23 03:31:26 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Miscellaneous Constants
|
|
|
|
//
|
1999-04-16 08:38:17 +00:00
|
|
|
|
|
|
|
#define XUL_NAMESPACE_URI "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
1999-04-02 19:51:35 +00:00
|
|
|
|
1999-11-17 03:20:03 +00:00
|
|
|
const nsForwardReference::Phase nsForwardReference::kPasses[] = {
|
|
|
|
nsForwardReference::eConstruction,
|
|
|
|
nsForwardReference::eHookup,
|
|
|
|
nsForwardReference::eDone
|
1999-10-29 01:21:15 +00:00
|
|
|
};
|
1999-09-07 02:51:13 +00:00
|
|
|
|
1999-01-12 19:41:06 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Statics
|
|
|
|
//
|
1999-09-03 07:02:25 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
PRInt32 nsXULDocument::gRefCnt = 0;
|
1999-09-30 02:32:34 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
nsIAtom* nsXULDocument::kAttributeAtom;
|
|
|
|
nsIAtom* nsXULDocument::kCommandUpdaterAtom;
|
|
|
|
nsIAtom* nsXULDocument::kDataSourcesAtom;
|
|
|
|
nsIAtom* nsXULDocument::kElementAtom;
|
|
|
|
nsIAtom* nsXULDocument::kIdAtom;
|
|
|
|
nsIAtom* nsXULDocument::kKeysetAtom;
|
|
|
|
nsIAtom* nsXULDocument::kObservesAtom;
|
|
|
|
nsIAtom* nsXULDocument::kOpenAtom;
|
|
|
|
nsIAtom* nsXULDocument::kOverlayAtom;
|
|
|
|
nsIAtom* nsXULDocument::kPersistAtom;
|
|
|
|
nsIAtom* nsXULDocument::kPositionAtom;
|
|
|
|
nsIAtom* nsXULDocument::kRefAtom;
|
|
|
|
nsIAtom* nsXULDocument::kRuleAtom;
|
|
|
|
nsIAtom* nsXULDocument::kTemplateAtom;
|
1999-01-14 10:55:08 +00:00
|
|
|
|
2000-01-12 01:47:23 +00:00
|
|
|
nsIAtom* nsXULDocument::kCoalesceAtom;
|
|
|
|
nsIAtom* nsXULDocument::kAllowNegativesAtom;
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
nsIRDFService* nsXULDocument::gRDFService;
|
|
|
|
nsIRDFResource* nsXULDocument::kNC_persist;
|
|
|
|
nsIRDFResource* nsXULDocument::kNC_attribute;
|
|
|
|
nsIRDFResource* nsXULDocument::kNC_value;
|
1999-09-17 04:29:53 +00:00
|
|
|
|
2000-01-19 03:11:39 +00:00
|
|
|
nsIElementFactory* nsXULDocument::gHTMLElementFactory;
|
|
|
|
nsIElementFactory* nsXULDocument::gXMLElementFactory;
|
1999-02-09 03:15:41 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
nsINameSpaceManager* nsXULDocument::gNameSpaceManager;
|
|
|
|
PRInt32 nsXULDocument::kNameSpaceID_XUL;
|
1999-10-05 21:13:55 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
nsIXULContentUtils* nsXULDocument::gXULUtils;
|
1999-11-02 01:14:07 +00:00
|
|
|
nsIXULPrototypeCache* nsXULDocument::gXULCache;
|
1999-04-16 08:38:17 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
PRLogModuleInfo* nsXULDocument::gXULLog;
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-12-16 03:19:34 +00:00
|
|
|
class nsProxyLoadStream : public nsIInputStream
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
const char* mBuffer;
|
|
|
|
PRUint32 mSize;
|
|
|
|
PRUint32 mIndex;
|
|
|
|
|
|
|
|
public:
|
|
|
|
nsProxyLoadStream(void) : mBuffer(nsnull)
|
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~nsProxyLoadStream(void) {
|
|
|
|
}
|
|
|
|
|
|
|
|
// nsISupports
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// nsIBaseStream
|
|
|
|
NS_IMETHOD Close(void) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// nsIInputStream
|
|
|
|
NS_IMETHOD Available(PRUint32 *aLength) {
|
|
|
|
*aLength = mSize - mIndex;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHOD Read(char* aBuf, PRUint32 aCount, PRUint32 *aReadCount) {
|
|
|
|
PRUint32 readCount = 0;
|
|
|
|
while (mIndex < mSize && aCount > 0) {
|
|
|
|
*aBuf = mBuffer[mIndex];
|
|
|
|
aBuf++;
|
|
|
|
mIndex++;
|
|
|
|
readCount++;
|
|
|
|
aCount--;
|
|
|
|
}
|
|
|
|
*aReadCount = readCount;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Implementation
|
|
|
|
void SetBuffer(const char* aBuffer, PRUint32 aSize) {
|
|
|
|
mBuffer = aBuffer;
|
|
|
|
mSize = aSize;
|
|
|
|
mIndex = 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-01-11 20:49:15 +00:00
|
|
|
NS_IMPL_ISUPPORTS(nsProxyLoadStream, NS_GET_IID(nsIInputStream));
|
1999-12-16 03:19:34 +00:00
|
|
|
|
1999-11-23 01:44:51 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// PlaceholderChannel
|
|
|
|
//
|
|
|
|
// This is a dummy channel implementation that we add to the load
|
|
|
|
// group. It ensures that EndDocumentLoad() in the webshell doesn't
|
|
|
|
// fire before we've finished building the complete document content
|
|
|
|
// model.
|
|
|
|
//
|
|
|
|
|
|
|
|
class PlaceholderChannel : public nsIChannel
|
|
|
|
{
|
|
|
|
protected:
|
1999-11-24 22:46:09 +00:00
|
|
|
PlaceholderChannel();
|
|
|
|
virtual ~PlaceholderChannel();
|
|
|
|
|
|
|
|
static PRInt32 gRefCnt;
|
|
|
|
static nsIURI* gURI;
|
|
|
|
|
|
|
|
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
1999-11-23 01:44:51 +00:00
|
|
|
|
|
|
|
public:
|
1999-11-24 22:46:09 +00:00
|
|
|
static nsresult
|
|
|
|
Create(nsIChannel** aResult);
|
1999-11-23 01:44:51 +00:00
|
|
|
|
1999-11-24 22:46:09 +00:00
|
|
|
NS_DECL_ISUPPORTS
|
1999-11-23 01:44:51 +00:00
|
|
|
|
|
|
|
// nsIRequest
|
|
|
|
NS_IMETHOD IsPending(PRBool *_retval) { *_retval = PR_TRUE; return NS_OK; }
|
|
|
|
NS_IMETHOD Cancel(void) { return NS_OK; }
|
|
|
|
NS_IMETHOD Suspend(void) { return NS_OK; }
|
|
|
|
NS_IMETHOD Resume(void) { return NS_OK; }
|
|
|
|
|
|
|
|
// nsIChannel
|
|
|
|
NS_IMETHOD GetOriginalURI(nsIURI * *aOriginalURI) { *aOriginalURI = gURI; NS_ADDREF(*aOriginalURI); return NS_OK; }
|
|
|
|
NS_IMETHOD GetURI(nsIURI * *aURI) { *aURI = gURI; NS_ADDREF(*aURI); return NS_OK; }
|
|
|
|
NS_IMETHOD OpenInputStream(PRUint32 startPosition, PRInt32 readCount, nsIInputStream **_retval) { *_retval = nsnull; return NS_OK; }
|
|
|
|
NS_IMETHOD OpenOutputStream(PRUint32 startPosition, nsIOutputStream **_retval) { *_retval = nsnull; return NS_OK; }
|
|
|
|
NS_IMETHOD AsyncOpen(nsIStreamObserver *observer, nsISupports *ctxt) { return NS_OK; }
|
|
|
|
NS_IMETHOD AsyncRead(PRUint32 startPosition, PRInt32 readCount, nsISupports *ctxt, nsIStreamListener *listener) { return NS_OK; }
|
|
|
|
NS_IMETHOD AsyncWrite(nsIInputStream *fromStream, PRUint32 startPosition, PRInt32 writeCount, nsISupports *ctxt, nsIStreamObserver *observer) { return NS_OK; }
|
|
|
|
NS_IMETHOD GetLoadAttributes(nsLoadFlags *aLoadAttributes) { *aLoadAttributes = nsIChannel::LOAD_NORMAL; return NS_OK; }
|
|
|
|
NS_IMETHOD SetLoadAttributes(nsLoadFlags aLoadAttributes) { return NS_OK; }
|
|
|
|
NS_IMETHOD GetContentType(char * *aContentType) { *aContentType = nsnull; return NS_OK; }
|
2000-01-08 06:26:04 +00:00
|
|
|
NS_IMETHOD SetContentType(const char *aContentType) { return NS_OK; }
|
1999-11-23 01:44:51 +00:00
|
|
|
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; }
|
1999-11-24 22:46:09 +00:00
|
|
|
NS_IMETHOD GetLoadGroup(nsILoadGroup * *aLoadGroup) { *aLoadGroup = mLoadGroup; NS_IF_ADDREF(*aLoadGroup); return NS_OK; }
|
|
|
|
NS_IMETHOD SetLoadGroup(nsILoadGroup * aLoadGroup) { mLoadGroup = aLoadGroup; return NS_OK; }
|
1999-11-23 01:44:51 +00:00
|
|
|
NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor * *aNotificationCallbacks) { *aNotificationCallbacks = nsnull; return NS_OK; }
|
|
|
|
NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor * aNotificationCallbacks) { return NS_OK; }
|
|
|
|
};
|
|
|
|
|
|
|
|
PRInt32 PlaceholderChannel::gRefCnt;
|
|
|
|
nsIURI* PlaceholderChannel::gURI;
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF(PlaceholderChannel);
|
|
|
|
NS_IMPL_RELEASE(PlaceholderChannel);
|
|
|
|
NS_IMPL_QUERY_INTERFACE2(PlaceholderChannel, nsIRequest, nsIChannel);
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
PlaceholderChannel::Create(nsIChannel** aResult)
|
|
|
|
{
|
1999-11-24 22:46:09 +00:00
|
|
|
PlaceholderChannel* channel = new PlaceholderChannel();
|
|
|
|
if (! channel)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
1999-11-23 01:44:51 +00:00
|
|
|
|
1999-11-24 22:46:09 +00:00
|
|
|
*aResult = channel;
|
|
|
|
NS_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
1999-11-23 01:44:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PlaceholderChannel::PlaceholderChannel()
|
|
|
|
{
|
1999-11-24 22:46:09 +00:00
|
|
|
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");
|
|
|
|
}
|
1999-11-23 01:44:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PlaceholderChannel::~PlaceholderChannel()
|
|
|
|
{
|
1999-11-24 22:46:09 +00:00
|
|
|
if (--gRefCnt == 0) {
|
|
|
|
NS_IF_RELEASE(gURI);
|
|
|
|
}
|
1999-11-23 01:44:51 +00:00
|
|
|
}
|
|
|
|
|
1999-11-24 22:46:09 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-01-12 19:41:06 +00:00
|
|
|
// ctors & dtors
|
1999-10-29 01:21:15 +00:00
|
|
|
//
|
1999-01-12 19:41:06 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::nsXULDocument(void)
|
1999-05-28 11:30:59 +00:00
|
|
|
: mParentDocument(nsnull),
|
1999-12-17 00:06:28 +00:00
|
|
|
mScriptGlobalObject(nsnull),
|
1999-02-16 19:30:04 +00:00
|
|
|
mScriptObject(nsnull),
|
1999-11-18 02:25:33 +00:00
|
|
|
mNextSrcLoadWaiter(nsnull),
|
1999-04-27 21:49:25 +00:00
|
|
|
mCharSetID("UTF-8"),
|
1999-05-28 11:30:59 +00:00
|
|
|
mDisplaySelection(PR_FALSE),
|
1999-12-15 23:18:34 +00:00
|
|
|
mIsKeyBindingDoc(PR_FALSE),
|
1999-09-30 02:32:34 +00:00
|
|
|
mIsPopup(PR_FALSE),
|
1999-11-17 03:20:03 +00:00
|
|
|
mResolutionPhase(nsForwardReference::eStart),
|
1999-12-06 23:05:31 +00:00
|
|
|
mNextContentID(NS_CONTENT_ID_COUNTER_BASE),
|
1999-11-23 01:44:51 +00:00
|
|
|
mState(eState_Master),
|
|
|
|
mCurrentScriptProto(nsnull)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::~nsXULDocument()
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_ASSERTION(mNextSrcLoadWaiter == nsnull,
|
|
|
|
"unreferenced document still waiting for script source to load?");
|
|
|
|
|
1999-09-30 02:32:34 +00:00
|
|
|
// In case we failed somewhere early on and the forward observer
|
|
|
|
// decls never got resolved.
|
1999-10-05 21:13:55 +00:00
|
|
|
DestroyForwardReferences();
|
1999-09-30 02:32:34 +00:00
|
|
|
|
1998-12-24 05:07:14 +00:00
|
|
|
// mParentDocument is never refcounted
|
1999-03-10 20:05:12 +00:00
|
|
|
// Delete references to sub-documents
|
1999-05-28 11:30:59 +00:00
|
|
|
{
|
|
|
|
PRInt32 i = mSubDocuments.Count();
|
|
|
|
while (--i >= 0) {
|
|
|
|
nsIDocument* subdoc = (nsIDocument*) mSubDocuments.ElementAt(i);
|
|
|
|
NS_RELEASE(subdoc);
|
|
|
|
}
|
1999-05-16 09:09:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Delete references to style sheets but only if we aren't a popup document.
|
|
|
|
if (!mIsPopup) {
|
1999-05-28 11:30:59 +00:00
|
|
|
PRInt32 i = mStyleSheets.Count();
|
|
|
|
while (--i >= 0) {
|
|
|
|
nsIStyleSheet* sheet = (nsIStyleSheet*) mStyleSheets.ElementAt(i);
|
1999-05-16 09:09:00 +00:00
|
|
|
sheet->SetOwningDocument(nsnull);
|
|
|
|
NS_RELEASE(sheet);
|
|
|
|
}
|
1999-03-10 20:05:12 +00:00
|
|
|
}
|
|
|
|
|
1999-04-30 09:04:36 +00:00
|
|
|
// set all builder references to document to nsnull -- out of band notification
|
|
|
|
// to break ownership cycle
|
1999-04-07 00:27:40 +00:00
|
|
|
if (mBuilders)
|
|
|
|
{
|
1999-05-13 04:56:04 +00:00
|
|
|
PRUint32 cnt = 0;
|
|
|
|
nsresult rv = mBuilders->Count(&cnt);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
|
1999-04-07 00:27:40 +00:00
|
|
|
|
1999-08-06 17:59:05 +00:00
|
|
|
for (PRUint32 i = 0; i < cnt; ++i) {
|
|
|
|
nsIRDFContentModelBuilder* builder
|
|
|
|
= (nsIRDFContentModelBuilder*) mBuilders->ElementAt(i);
|
|
|
|
|
|
|
|
NS_ASSERTION(builder != nsnull, "null ptr");
|
|
|
|
if (! builder) continue;
|
|
|
|
|
|
|
|
rv = builder->SetDocument(nsnull);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "error unlinking builder from document");
|
|
|
|
// XXX ignore error code?
|
|
|
|
|
|
|
|
rv = builder->SetDataBase(nsnull);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "error unlinking builder from database");
|
|
|
|
|
|
|
|
NS_RELEASE(builder);
|
|
|
|
}
|
1999-04-07 00:27:40 +00:00
|
|
|
}
|
|
|
|
|
1999-09-03 08:57:42 +00:00
|
|
|
if (mLocalStore) {
|
|
|
|
nsCOMPtr<nsIRDFRemoteDataSource> remote = do_QueryInterface(mLocalStore);
|
|
|
|
if (remote)
|
|
|
|
remote->Flush();
|
|
|
|
}
|
|
|
|
|
1999-05-26 23:42:29 +00:00
|
|
|
if (mCSSLoader) {
|
|
|
|
mCSSLoader->DropDocumentReference();
|
1999-05-28 11:30:59 +00:00
|
|
|
}
|
1999-09-25 16:29:22 +00:00
|
|
|
|
|
|
|
#if 0
|
1999-09-24 19:49:15 +00:00
|
|
|
PRInt32 i;
|
|
|
|
for (i = 0; i < mObservers.Count(); i++) {
|
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(i);
|
|
|
|
observer->DocumentWillBeDestroyed(this);
|
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
}
|
1999-09-25 16:29:22 +00:00
|
|
|
#endif
|
1999-09-24 19:49:15 +00:00
|
|
|
|
1999-02-24 04:46:47 +00:00
|
|
|
if (--gRefCnt == 0) {
|
1999-10-29 01:21:15 +00:00
|
|
|
NS_IF_RELEASE(kAttributeAtom);
|
1999-09-17 04:29:53 +00:00
|
|
|
NS_IF_RELEASE(kCommandUpdaterAtom);
|
1999-10-29 01:21:15 +00:00
|
|
|
NS_IF_RELEASE(kDataSourcesAtom);
|
|
|
|
NS_IF_RELEASE(kElementAtom);
|
1999-02-24 04:46:47 +00:00
|
|
|
NS_IF_RELEASE(kIdAtom);
|
1999-10-29 01:21:15 +00:00
|
|
|
NS_IF_RELEASE(kKeysetAtom);
|
1999-02-24 04:46:47 +00:00
|
|
|
NS_IF_RELEASE(kObservesAtom);
|
1999-08-30 02:45:54 +00:00
|
|
|
NS_IF_RELEASE(kOpenAtom);
|
1999-10-29 01:21:15 +00:00
|
|
|
NS_IF_RELEASE(kOverlayAtom);
|
1999-09-03 07:02:25 +00:00
|
|
|
NS_IF_RELEASE(kPersistAtom);
|
1999-10-29 01:21:15 +00:00
|
|
|
NS_IF_RELEASE(kPositionAtom);
|
1999-08-30 02:45:54 +00:00
|
|
|
NS_IF_RELEASE(kRefAtom);
|
|
|
|
NS_IF_RELEASE(kRuleAtom);
|
|
|
|
NS_IF_RELEASE(kTemplateAtom);
|
1999-04-16 08:38:17 +00:00
|
|
|
|
2000-01-12 01:47:23 +00:00
|
|
|
NS_IF_RELEASE(kCoalesceAtom);
|
|
|
|
NS_IF_RELEASE(kAllowNegativesAtom);
|
|
|
|
|
1999-04-16 08:38:17 +00:00
|
|
|
if (gRDFService) {
|
|
|
|
nsServiceManager::ReleaseService(kRDFServiceCID, gRDFService);
|
|
|
|
gRDFService = nsnull;
|
|
|
|
}
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
NS_IF_RELEASE(kNC_persist);
|
|
|
|
NS_IF_RELEASE(kNC_attribute);
|
|
|
|
NS_IF_RELEASE(kNC_value);
|
|
|
|
|
|
|
|
NS_IF_RELEASE(gHTMLElementFactory);
|
1999-10-29 01:21:15 +00:00
|
|
|
NS_IF_RELEASE(gXMLElementFactory);
|
1999-10-05 21:13:55 +00:00
|
|
|
|
1999-09-07 02:51:13 +00:00
|
|
|
if (gXULUtils) {
|
|
|
|
nsServiceManager::ReleaseService(kXULContentUtilsCID, gXULUtils);
|
|
|
|
gXULUtils = nsnull;
|
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
|
1999-11-02 01:14:07 +00:00
|
|
|
if (gXULCache) {
|
|
|
|
nsServiceManager::ReleaseService(kXULPrototypeCacheCID, gXULCache);
|
|
|
|
gXULCache = nsnull;
|
1999-10-29 01:21:15 +00:00
|
|
|
}
|
1999-02-24 04:46:47 +00:00
|
|
|
}
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-10-05 21:13:55 +00:00
|
|
|
NS_NewXULDocument(nsIXULDocument** result)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(result != nsnull, "null ptr");
|
|
|
|
if (! result)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument* doc = new nsXULDocument();
|
1999-02-16 19:30:04 +00:00
|
|
|
if (! doc)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
NS_ADDREF(doc);
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
if (NS_FAILED(rv = doc->Init())) {
|
|
|
|
NS_RELEASE(doc);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
*result = doc;
|
|
|
|
return NS_OK;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-01-12 19:41:06 +00:00
|
|
|
// nsISupports interface
|
1999-10-29 01:21:15 +00:00
|
|
|
//
|
1999-01-12 19:41:06 +00:00
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::QueryInterface(REFNSIID iid, void** result)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
if (! result)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
*result = nsnull;
|
1999-10-05 21:13:55 +00:00
|
|
|
if (iid.Equals(NS_GET_IID(nsIDocument)) ||
|
|
|
|
iid.Equals(NS_GET_IID(nsISupports))) {
|
1998-12-24 05:07:14 +00:00
|
|
|
*result = NS_STATIC_CAST(nsIDocument*, this);
|
|
|
|
}
|
1999-10-05 21:13:55 +00:00
|
|
|
else if (iid.Equals(NS_GET_IID(nsIXULDocument)) ||
|
|
|
|
iid.Equals(NS_GET_IID(nsIXMLDocument))) {
|
|
|
|
*result = NS_STATIC_CAST(nsIXULDocument*, this);
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
2000-01-11 20:49:15 +00:00
|
|
|
else if (iid.Equals(NS_GET_IID(nsIDOMXULDocument)) ||
|
|
|
|
iid.Equals(NS_GET_IID(nsIDOMDocument)) ||
|
|
|
|
iid.Equals(NS_GET_IID(nsIDOMNode))) {
|
1999-02-17 11:09:57 +00:00
|
|
|
*result = NS_STATIC_CAST(nsIDOMXULDocument*, this);
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
2000-01-11 20:49:15 +00:00
|
|
|
else if (iid.Equals(NS_GET_IID(nsIDOMNSDocument))) {
|
1999-05-19 04:28:40 +00:00
|
|
|
*result = NS_STATIC_CAST(nsIDOMNSDocument*, this);
|
|
|
|
}
|
1999-10-05 21:13:55 +00:00
|
|
|
else if (iid.Equals(NS_GET_IID(nsIJSScriptObject))) {
|
1999-02-16 19:30:04 +00:00
|
|
|
*result = NS_STATIC_CAST(nsIJSScriptObject*, this);
|
|
|
|
}
|
1999-10-05 21:13:55 +00:00
|
|
|
else if (iid.Equals(NS_GET_IID(nsIScriptObjectOwner))) {
|
1999-02-16 19:30:04 +00:00
|
|
|
*result = NS_STATIC_CAST(nsIScriptObjectOwner*, this);
|
|
|
|
}
|
1999-10-05 21:13:55 +00:00
|
|
|
else if (iid.Equals(NS_GET_IID(nsIHTMLContentContainer))) {
|
1999-02-04 10:50:50 +00:00
|
|
|
*result = NS_STATIC_CAST(nsIHTMLContentContainer*, this);
|
|
|
|
}
|
1999-10-05 21:13:55 +00:00
|
|
|
else if (iid.Equals(NS_GET_IID(nsIDOMEventReceiver))) {
|
1999-05-04 23:32:25 +00:00
|
|
|
*result = NS_STATIC_CAST(nsIDOMEventReceiver*, this);
|
|
|
|
}
|
1999-10-05 21:13:55 +00:00
|
|
|
else if (iid.Equals(NS_GET_IID(nsIDOMEventTarget))) {
|
1999-05-04 23:32:25 +00:00
|
|
|
*result = NS_STATIC_CAST(nsIDOMEventTarget*, this);
|
|
|
|
}
|
1999-10-05 21:13:55 +00:00
|
|
|
else if (iid.Equals(NS_GET_IID(nsIDOMEventCapturer))) {
|
1999-05-04 23:32:25 +00:00
|
|
|
*result = NS_STATIC_CAST(nsIDOMEventCapturer*, this);
|
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
else if (iid.Equals(NS_GET_IID(nsIStreamLoadableDocument))) {
|
|
|
|
*result = NS_STATIC_CAST(nsIStreamLoadableDocument*, this);
|
|
|
|
}
|
|
|
|
else if (iid.Equals(NS_GET_IID(nsISupportsWeakReference))) {
|
|
|
|
*result = NS_STATIC_CAST(nsISupportsWeakReference*, this);
|
1999-04-23 16:48:33 +00:00
|
|
|
}
|
1999-11-02 06:49:44 +00:00
|
|
|
else if (iid.Equals(NS_GET_IID(nsIUnicharStreamLoaderObserver))) {
|
|
|
|
*result = NS_STATIC_CAST(nsIUnicharStreamLoaderObserver*, this);
|
|
|
|
}
|
1999-02-17 11:56:15 +00:00
|
|
|
else {
|
|
|
|
*result = nsnull;
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
}
|
|
|
|
NS_ADDREF(this);
|
|
|
|
return NS_OK;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
NS_IMPL_ADDREF(nsXULDocument);
|
|
|
|
NS_IMPL_RELEASE(nsXULDocument);
|
1998-12-24 05:07:14 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1998-12-24 05:07:14 +00:00
|
|
|
// nsIDocument interface
|
1999-10-29 01:21:15 +00:00
|
|
|
//
|
1998-12-24 05:07:14 +00:00
|
|
|
|
|
|
|
nsIArena*
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetArena()
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-04-30 09:04:36 +00:00
|
|
|
nsIArena* result = mArena;
|
|
|
|
NS_IF_ADDREF(result);
|
|
|
|
return result;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetContentType(nsString& aContentType) const
|
1999-05-11 20:22:52 +00:00
|
|
|
{
|
|
|
|
aContentType.SetString("text/xul");
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::PrepareStyleSheets(nsIURI* anURL)
|
1999-05-16 08:50:27 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-05-16 08:50:27 +00:00
|
|
|
// Delete references to style sheets - this should be done in superclass...
|
1999-05-28 11:30:59 +00:00
|
|
|
PRInt32 i = mStyleSheets.Count();
|
|
|
|
while (--i >= 0) {
|
|
|
|
nsIStyleSheet* sheet = (nsIStyleSheet*) mStyleSheets.ElementAt(i);
|
1999-05-16 08:50:27 +00:00
|
|
|
sheet->SetOwningDocument(nsnull);
|
|
|
|
NS_RELEASE(sheet);
|
|
|
|
}
|
|
|
|
mStyleSheets.Clear();
|
|
|
|
|
|
|
|
// Create an HTML style sheet for the HTML content.
|
1999-05-28 11:30:59 +00:00
|
|
|
nsCOMPtr<nsIHTMLStyleSheet> sheet;
|
1999-05-16 08:50:27 +00:00
|
|
|
if (NS_SUCCEEDED(rv = nsComponentManager::CreateInstance(kHTMLStyleSheetCID,
|
|
|
|
nsnull,
|
1999-10-05 21:13:55 +00:00
|
|
|
NS_GET_IID(nsIHTMLStyleSheet),
|
1999-05-28 11:30:59 +00:00
|
|
|
getter_AddRefs(sheet)))) {
|
1999-05-16 08:50:27 +00:00
|
|
|
if (NS_SUCCEEDED(rv = sheet->Init(anURL, this))) {
|
|
|
|
mAttrStyleSheet = sheet;
|
|
|
|
AddStyleSheet(mAttrStyleSheet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
NS_ERROR("unable to add HTML style sheet");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
// Create an inline style sheet for inline content that contains a style
|
1999-05-16 08:50:27 +00:00
|
|
|
// attribute.
|
|
|
|
nsIHTMLCSSStyleSheet* inlineSheet;
|
|
|
|
if (NS_SUCCEEDED(rv = nsComponentManager::CreateInstance(kHTMLCSSStyleSheetCID,
|
|
|
|
nsnull,
|
1999-10-05 21:13:55 +00:00
|
|
|
NS_GET_IID(nsIHTMLCSSStyleSheet),
|
1999-05-16 08:50:27 +00:00
|
|
|
(void**)&inlineSheet))) {
|
|
|
|
if (NS_SUCCEEDED(rv = inlineSheet->Init(anURL, this))) {
|
|
|
|
mInlineStyleSheet = dont_QueryInterface(inlineSheet);
|
|
|
|
AddStyleSheet(mInlineStyleSheet);
|
|
|
|
}
|
|
|
|
NS_RELEASE(inlineSheet);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
NS_ERROR("unable to add inline style sheet");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-12-15 23:18:34 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::SetIsKeybindingDocument(PRBool aIsKeyBindingDoc)
|
|
|
|
{
|
|
|
|
mIsKeyBindingDoc = aIsKeyBindingDoc;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-12-08 04:56:56 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::SetDocumentURL(nsIURI* anURL)
|
1999-05-16 08:50:27 +00:00
|
|
|
{
|
1999-05-28 11:30:59 +00:00
|
|
|
mDocumentURL = dont_QueryInterface(anURL);
|
1999-12-08 04:56:56 +00:00
|
|
|
return NS_OK;
|
1999-05-16 08:50:27 +00:00
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::StartDocumentLoad(const char* aCommand,
|
|
|
|
nsIChannel* aChannel,
|
|
|
|
nsILoadGroup* aLoadGroup,
|
1999-11-15 22:14:37 +00:00
|
|
|
nsISupports* aContainer,
|
1999-10-29 01:21:15 +00:00
|
|
|
nsIStreamListener **aDocListener)
|
1999-04-23 16:48:33 +00:00
|
|
|
{
|
1999-12-04 07:45:57 +00:00
|
|
|
nsresult rv;
|
|
|
|
mCommand = aCommand;
|
|
|
|
|
|
|
|
mDocumentLoadGroup = getter_AddRefs(NS_GetWeakReference(aLoadGroup));
|
|
|
|
|
|
|
|
mDocumentTitle.Truncate();
|
|
|
|
|
|
|
|
rv = aChannel->GetOriginalURI(getter_AddRefs(mDocumentURL));
|
1999-10-29 01:21:15 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-12-24 05:07:14 +00:00
|
|
|
|
1999-12-04 07:45:57 +00:00
|
|
|
rv = PrepareStyleSheets(mDocumentURL);
|
1999-10-29 01:21:15 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-01-17 19:34:23 +00:00
|
|
|
// Get the content type, if possible, to see if it's a cached XUL
|
|
|
|
// load. We explicitly ignore failure at this point, because
|
|
|
|
// certain hacks (cough, the directory viewer) need to be able to
|
|
|
|
// StartDocumentLoad() before the channel's content type has been
|
|
|
|
// detected.
|
2000-01-11 21:18:19 +00:00
|
|
|
nsXPIDLCString contentType;
|
2000-01-17 19:34:23 +00:00
|
|
|
(void) aChannel->GetContentType(getter_Copies(contentType));
|
1999-04-23 16:48:33 +00:00
|
|
|
|
2000-01-17 19:34:23 +00:00
|
|
|
if (contentType && PL_strcmp(contentType, "text/cached-xul") == 0) {
|
2000-01-11 21:18:19 +00:00
|
|
|
// Look in the chrome cache: we've got this puppy loaded
|
|
|
|
// already.
|
|
|
|
nsCOMPtr<nsIXULPrototypeDocument> proto;
|
|
|
|
rv = gXULCache->GetPrototype(mDocumentURL, getter_AddRefs(proto));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
NS_ASSERTION(proto != nsnull, "no prototype on cached load");
|
|
|
|
if (! proto)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
1999-12-04 07:45:57 +00:00
|
|
|
mMasterPrototype = mCurrentPrototype = proto;
|
|
|
|
|
|
|
|
rv = AddPrototypeSheets();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
1999-12-04 07:45:57 +00:00
|
|
|
*aDocListener = new CachedChromeStreamListener(this);
|
|
|
|
if (! *aDocListener)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
else {
|
2000-01-11 21:18:19 +00:00
|
|
|
// It's just a vanilla document load. Create a parser to deal
|
|
|
|
// with the stream n' stuff.
|
1999-12-04 07:45:57 +00:00
|
|
|
nsCOMPtr<nsIParser> parser;
|
|
|
|
rv = PrepareToLoad(aContainer, aCommand, aChannel, aLoadGroup, getter_AddRefs(parser));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStreamListener> listener = do_QueryInterface(parser, &rv);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "parser doesn't support nsIStreamListener");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
*aDocListener = listener;
|
|
|
|
|
|
|
|
parser->Parse(mDocumentURL);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IF_ADDREF(*aDocListener);
|
1999-10-29 01:21:15 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-04-23 16:48:33 +00:00
|
|
|
|
1998-12-24 05:07:14 +00:00
|
|
|
const nsString*
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetDocumentTitle() const
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
return &mDocumentTitle;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
nsIURI*
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetDocumentURL() const
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-06-23 03:29:44 +00:00
|
|
|
nsIURI* result = mDocumentURL;
|
1999-05-28 11:30:59 +00:00
|
|
|
NS_IF_ADDREF(result);
|
|
|
|
return result;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
2000-01-26 15:33:57 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::GetPrincipal(nsIPrincipal **aPrincipal)
|
1999-08-29 21:58:42 +00:00
|
|
|
{
|
2000-01-26 15:33:57 +00:00
|
|
|
return mMasterPrototype->GetDocumentPrincipal(aPrincipal);
|
1999-08-29 21:58:42 +00:00
|
|
|
}
|
|
|
|
|
1999-10-05 04:08:14 +00:00
|
|
|
|
1999-09-18 06:34:24 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetDocumentLoadGroup(nsILoadGroup **aGroup) const
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-09-21 06:44:56 +00:00
|
|
|
nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
|
|
|
|
|
|
|
|
*aGroup = group;
|
1999-09-18 06:34:24 +00:00
|
|
|
NS_IF_ADDREF(*aGroup);
|
|
|
|
return NS_OK;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetBaseURL(nsIURI*& aURL) const
|
1999-01-15 01:53:50 +00:00
|
|
|
{
|
|
|
|
aURL = mDocumentURL;
|
1999-05-28 11:30:59 +00:00
|
|
|
NS_IF_ADDREF(aURL);
|
1999-01-15 01:53:50 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-04-27 21:49:25 +00:00
|
|
|
NS_IMETHODIMP
|
1999-11-18 02:25:33 +00:00
|
|
|
nsXULDocument::GetDocumentCharacterSet(nsString& oCharSetID)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-04-27 21:49:25 +00:00
|
|
|
oCharSetID = mCharSetID;
|
|
|
|
return NS_OK;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-04-27 21:49:25 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::SetDocumentCharacterSet(const nsString& aCharSetID)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
mCharSetID = aCharSetID;
|
1999-04-27 21:49:25 +00:00
|
|
|
return NS_OK;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-02-23 03:31:26 +00:00
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::GetLineBreaker(nsILineBreaker** aResult)
|
1999-02-23 03:31:26 +00:00
|
|
|
{
|
1999-05-28 11:30:59 +00:00
|
|
|
if(! mLineBreaker) {
|
1999-02-23 03:31:26 +00:00
|
|
|
// no line breaker, find a default one
|
|
|
|
nsILineBreakerFactory *lf;
|
|
|
|
nsresult result;
|
|
|
|
result = nsServiceManager::GetService(kLWBrkCID,
|
1999-10-05 21:13:55 +00:00
|
|
|
NS_GET_IID(nsILineBreakerFactory),
|
1999-02-23 03:31:26 +00:00
|
|
|
(nsISupports **)&lf);
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
nsILineBreaker *lb = nsnull ;
|
|
|
|
nsAutoString lbarg("");
|
|
|
|
result = lf->GetBreaker(lbarg, &lb);
|
|
|
|
if(NS_SUCCEEDED(result)) {
|
1999-11-30 22:24:16 +00:00
|
|
|
mLineBreaker = dont_AddRef(lb);
|
1999-02-23 03:31:26 +00:00
|
|
|
}
|
|
|
|
result = nsServiceManager::ReleaseService(kLWBrkCID, lf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*aResult = mLineBreaker;
|
1999-05-28 11:30:59 +00:00
|
|
|
NS_IF_ADDREF(*aResult);
|
1999-02-23 03:31:26 +00:00
|
|
|
return NS_OK; // XXX we should do error handling here
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::SetLineBreaker(nsILineBreaker* aLineBreaker)
|
1999-02-23 03:31:26 +00:00
|
|
|
{
|
1999-05-28 11:30:59 +00:00
|
|
|
mLineBreaker = dont_QueryInterface(aLineBreaker);
|
1999-02-23 03:31:26 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::GetWordBreaker(nsIWordBreaker** aResult)
|
1999-03-27 00:58:42 +00:00
|
|
|
{
|
1999-05-28 11:30:59 +00:00
|
|
|
if (! mWordBreaker) {
|
1999-03-27 00:58:42 +00:00
|
|
|
// no line breaker, find a default one
|
|
|
|
nsIWordBreakerFactory *lf;
|
|
|
|
nsresult result;
|
|
|
|
result = nsServiceManager::GetService(kLWBrkCID,
|
1999-10-05 21:13:55 +00:00
|
|
|
NS_GET_IID(nsIWordBreakerFactory),
|
1999-03-27 00:58:42 +00:00
|
|
|
(nsISupports **)&lf);
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
nsIWordBreaker *lb = nsnull ;
|
|
|
|
nsAutoString lbarg("");
|
|
|
|
result = lf->GetBreaker(lbarg, &lb);
|
|
|
|
if(NS_SUCCEEDED(result)) {
|
1999-11-30 22:24:16 +00:00
|
|
|
mWordBreaker = dont_AddRef(lb);
|
1999-03-27 00:58:42 +00:00
|
|
|
}
|
|
|
|
result = nsServiceManager::ReleaseService(kLWBrkCID, lf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*aResult = mWordBreaker;
|
1999-05-28 11:30:59 +00:00
|
|
|
NS_IF_ADDREF(*aResult);
|
1999-03-27 00:58:42 +00:00
|
|
|
return NS_OK; // XXX we should do error handling here
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::SetWordBreaker(nsIWordBreaker* aWordBreaker)
|
1999-03-27 00:58:42 +00:00
|
|
|
{
|
1999-05-28 11:30:59 +00:00
|
|
|
mWordBreaker = dont_QueryInterface(aWordBreaker);
|
1999-03-27 00:58:42 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-02-23 03:31:26 +00:00
|
|
|
|
|
|
|
|
1999-01-23 06:59:35 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetHeaderData(nsIAtom* aHeaderField, nsString& aData) const
|
1999-01-23 06:59:35 +00:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument:: SetHeaderData(nsIAtom* aHeaderField, const nsString& aData)
|
1999-01-23 06:59:35 +00:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-07-07 01:17:21 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CreateShell(nsIPresContext* aContext,
|
1999-01-14 10:55:08 +00:00
|
|
|
nsIViewManager* aViewManager,
|
|
|
|
nsIStyleSet* aStyleSet,
|
|
|
|
nsIPresShell** aInstancePtrResult)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(aInstancePtrResult, "null ptr");
|
|
|
|
if (! aInstancePtrResult)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsIPresShell* shell;
|
1999-03-09 09:44:27 +00:00
|
|
|
if (NS_FAILED(rv = nsComponentManager::CreateInstance(kPresShellCID,
|
1998-12-24 05:07:14 +00:00
|
|
|
nsnull,
|
1999-10-05 21:13:55 +00:00
|
|
|
NS_GET_IID(nsIPresShell),
|
1998-12-24 05:07:14 +00:00
|
|
|
(void**) &shell)))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
if (NS_FAILED(rv = shell->Init(this, aContext, aViewManager, aStyleSet))) {
|
|
|
|
NS_RELEASE(shell);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
mPresShells.AppendElement(shell);
|
1999-04-30 09:04:36 +00:00
|
|
|
*aInstancePtrResult = shell; // addref implicit in CreateInstance()
|
1998-12-24 05:07:14 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
PRBool
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::DeleteShell(nsIPresShell* aShell)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
return mPresShells.RemoveElement(aShell);
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
PRInt32
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetNumberOfShells()
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
return mPresShells.Count();
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
nsIPresShell*
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetShellAt(PRInt32 aIndex)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[aIndex]);
|
|
|
|
NS_IF_ADDREF(shell);
|
|
|
|
return shell;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
nsIDocument*
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetParentDocument()
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
NS_IF_ADDREF(mParentDocument);
|
|
|
|
return mParentDocument;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
void
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::SetParentDocument(nsIDocument* aParent)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
// Note that we do *not* AddRef our parent because that would
|
|
|
|
// create a circular reference.
|
|
|
|
mParentDocument = aParent;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
void
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::AddSubDocument(nsIDocument* aSubDoc)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-03-10 20:05:12 +00:00
|
|
|
NS_ADDREF(aSubDoc);
|
|
|
|
mSubDocuments.AppendElement(aSubDoc);
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
PRInt32
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetNumberOfSubDocuments()
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-03-10 20:05:12 +00:00
|
|
|
return mSubDocuments.Count();
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
nsIDocument*
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetSubDocumentAt(PRInt32 aIndex)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-03-10 20:05:12 +00:00
|
|
|
nsIDocument* doc = (nsIDocument*) mSubDocuments.ElementAt(aIndex);
|
|
|
|
if (nsnull != doc) {
|
|
|
|
NS_ADDREF(doc);
|
|
|
|
}
|
|
|
|
return doc;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
nsIContent*
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetRootContent()
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-05-28 11:30:59 +00:00
|
|
|
nsIContent* result = mRootContent;
|
|
|
|
NS_IF_ADDREF(result);
|
|
|
|
return result;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
void
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::SetRootContent(nsIContent* aRoot)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-01-12 19:41:06 +00:00
|
|
|
if (mRootContent) {
|
|
|
|
mRootContent->SetDocument(nsnull, PR_TRUE);
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
mRootContent = aRoot;
|
1999-01-12 19:41:06 +00:00
|
|
|
if (mRootContent) {
|
|
|
|
mRootContent->SetDocument(this, PR_TRUE);
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::AppendToProlog(nsIContent* aContent)
|
1999-03-31 20:49:42 +00:00
|
|
|
{
|
2000-01-26 20:39:28 +00:00
|
|
|
NS_ASSERTION(0, "not implemented");
|
1999-03-31 20:49:42 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::AppendToEpilog(nsIContent* aContent)
|
1999-03-31 20:49:42 +00:00
|
|
|
{
|
2000-01-26 20:39:28 +00:00
|
|
|
NS_ASSERTION(0, "not implemented");
|
1999-03-31 20:49:42 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ChildAt(PRInt32 aIndex, nsIContent*& aResult) const
|
1999-03-31 20:49:42 +00:00
|
|
|
{
|
2000-01-26 20:39:28 +00:00
|
|
|
NS_ASSERTION(0, "not implemented");
|
1999-03-31 20:49:42 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::IndexOf(nsIContent* aPossibleChild, PRInt32& aIndex) const
|
1999-03-31 20:49:42 +00:00
|
|
|
{
|
2000-01-26 20:39:28 +00:00
|
|
|
NS_ASSERTION(0, "not implemented");
|
1999-03-31 20:49:42 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetChildCount(PRInt32& aCount)
|
1999-03-31 20:49:42 +00:00
|
|
|
{
|
2000-01-26 20:39:28 +00:00
|
|
|
NS_ASSERTION(0, "not implemented");
|
1999-03-31 20:49:42 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
PRInt32
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetNumberOfStyleSheets()
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
return mStyleSheets.Count();
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
nsIStyleSheet*
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetStyleSheetAt(PRInt32 aIndex)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
nsIStyleSheet* sheet = NS_STATIC_CAST(nsIStyleSheet*, mStyleSheets[aIndex]);
|
|
|
|
NS_IF_ADDREF(sheet);
|
|
|
|
return sheet;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
PRInt32
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetIndexOfStyleSheet(nsIStyleSheet* aSheet)
|
1999-01-23 06:59:35 +00:00
|
|
|
{
|
|
|
|
return mStyleSheets.IndexOf(aSheet);
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
void
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::AddStyleSheet(nsIStyleSheet* aSheet)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(aSheet, "null arg");
|
|
|
|
if (!aSheet)
|
|
|
|
return;
|
|
|
|
|
1999-05-28 11:30:59 +00:00
|
|
|
if (aSheet == mAttrStyleSheet.get()) { // always first
|
1999-05-18 23:02:00 +00:00
|
|
|
mStyleSheets.InsertElementAt(aSheet, 0);
|
|
|
|
}
|
1999-05-19 00:05:40 +00:00
|
|
|
else if (aSheet == (nsIHTMLCSSStyleSheet*)mInlineStyleSheet) { // always last
|
1999-05-18 23:02:00 +00:00
|
|
|
mStyleSheets.AppendElement(aSheet);
|
|
|
|
}
|
|
|
|
else {
|
1999-05-19 00:05:40 +00:00
|
|
|
if ((nsIHTMLCSSStyleSheet*)mInlineStyleSheet == mStyleSheets.ElementAt(mStyleSheets.Count() - 1)) {
|
1999-05-18 23:02:00 +00:00
|
|
|
// keep attr sheet last
|
|
|
|
mStyleSheets.InsertElementAt(aSheet, mStyleSheets.Count() - 1);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mStyleSheets.AppendElement(aSheet);
|
|
|
|
}
|
1999-11-02 01:14:07 +00:00
|
|
|
|
|
|
|
// Put the style sheet into the XUL cache if the XUL cache is
|
|
|
|
// actually enabled and the document is chrome.
|
|
|
|
if (gXULUtils->UseXULCache() && IsChromeURI(mDocumentURL)) {
|
|
|
|
nsCOMPtr<nsICSSStyleSheet> css = do_QueryInterface(aSheet);
|
|
|
|
if (css) {
|
|
|
|
gXULCache->PutStyleSheet(css);
|
|
|
|
}
|
|
|
|
}
|
1999-05-18 23:02:00 +00:00
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
NS_ADDREF(aSheet);
|
|
|
|
|
|
|
|
aSheet->SetOwningDocument(this);
|
|
|
|
|
|
|
|
PRBool enabled;
|
|
|
|
aSheet->GetEnabled(enabled);
|
|
|
|
|
|
|
|
if (enabled) {
|
1999-05-28 11:30:59 +00:00
|
|
|
PRInt32 count, i;
|
1998-12-24 05:07:14 +00:00
|
|
|
|
|
|
|
count = mPresShells.Count();
|
1999-05-28 11:30:59 +00:00
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[i]);
|
1999-02-12 17:45:58 +00:00
|
|
|
nsCOMPtr<nsIStyleSet> set;
|
|
|
|
shell->GetStyleSet(getter_AddRefs(set));
|
1999-02-12 18:41:26 +00:00
|
|
|
if (set) {
|
1999-01-23 06:59:35 +00:00
|
|
|
set->AddDocStyleSheet(aSheet, this);
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX should observers be notified for disabled sheets??? I think not, but I could be wrong
|
1999-05-28 11:30:59 +00:00
|
|
|
for (i = 0; i < mObservers.Count(); i++) {
|
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(i);
|
1998-12-24 05:07:14 +00:00
|
|
|
observer->StyleSheetAdded(this, aSheet);
|
1999-05-28 11:30:59 +00:00
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
1999-05-18 23:02:00 +00:00
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-11-29 22:15:07 +00:00
|
|
|
void
|
|
|
|
nsXULDocument::RemoveStyleSheet(nsIStyleSheet* aSheet)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aSheet, "null arg");
|
|
|
|
mStyleSheets.RemoveElement(aSheet);
|
|
|
|
|
|
|
|
PRBool enabled = PR_TRUE;
|
|
|
|
aSheet->GetEnabled(enabled);
|
|
|
|
|
|
|
|
if (enabled) {
|
|
|
|
PRInt32 count = mPresShells.Count();
|
|
|
|
PRInt32 index;
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(index);
|
|
|
|
nsCOMPtr<nsIStyleSet> set;
|
|
|
|
if (NS_SUCCEEDED(shell->GetStyleSet(getter_AddRefs(set)))) {
|
|
|
|
if (set) {
|
|
|
|
set->RemoveDocStyleSheet(aSheet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX should observers be notified for disabled sheets??? I think not, but I could be wrong
|
|
|
|
for (index = 0; index < mObservers.Count(); index++) {
|
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index);
|
|
|
|
observer->StyleSheetRemoved(this, aSheet);
|
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(index)) {
|
|
|
|
index--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-11-30 04:33:28 +00:00
|
|
|
|
|
|
|
aSheet->SetOwningDocument(nsnull);
|
|
|
|
NS_RELEASE(aSheet);
|
1999-11-29 22:15:07 +00:00
|
|
|
}
|
|
|
|
|
1999-05-18 23:02:00 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex, PRBool aNotify)
|
1999-05-18 23:02:00 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aSheet, "null ptr");
|
1999-11-02 01:14:07 +00:00
|
|
|
|
|
|
|
// Put the style sheet into the XUL cache if the XUL cache is
|
|
|
|
// actually enabled and the document is chrome.
|
|
|
|
if (gXULUtils->UseXULCache() && IsChromeURI(mDocumentURL)) {
|
|
|
|
nsCOMPtr<nsICSSStyleSheet> css = do_QueryInterface(aSheet);
|
|
|
|
if (css) {
|
|
|
|
gXULCache->PutStyleSheet(css);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-05-18 23:02:00 +00:00
|
|
|
mStyleSheets.InsertElementAt(aSheet, aIndex + 1); // offset by one for attribute sheet
|
|
|
|
|
|
|
|
NS_ADDREF(aSheet);
|
|
|
|
aSheet->SetOwningDocument(this);
|
|
|
|
|
|
|
|
PRBool enabled = PR_TRUE;
|
|
|
|
aSheet->GetEnabled(enabled);
|
|
|
|
|
|
|
|
PRInt32 count;
|
1999-05-28 11:30:59 +00:00
|
|
|
PRInt32 i;
|
1999-05-18 23:02:00 +00:00
|
|
|
if (enabled) {
|
|
|
|
count = mPresShells.Count();
|
1999-05-28 11:30:59 +00:00
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(i);
|
1999-05-18 23:02:00 +00:00
|
|
|
nsCOMPtr<nsIStyleSet> set;
|
|
|
|
shell->GetStyleSet(getter_AddRefs(set));
|
|
|
|
if (set) {
|
|
|
|
set->AddDocStyleSheet(aSheet, this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (aNotify) { // notify here even if disabled, there may have been others that weren't notified
|
1999-05-28 11:30:59 +00:00
|
|
|
for (i = 0; i < mObservers.Count(); i++) {
|
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(i);
|
1999-05-18 23:02:00 +00:00
|
|
|
observer->StyleSheetAdded(this, aSheet);
|
1999-05-28 11:30:59 +00:00
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
1999-05-18 23:02:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-11-02 01:14:07 +00:00
|
|
|
|
1999-05-18 23:02:00 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
void
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::SetStyleSheetDisabledState(nsIStyleSheet* aSheet,
|
1998-12-24 05:07:14 +00:00
|
|
|
PRBool aDisabled)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aSheet, "null arg");
|
|
|
|
PRInt32 count;
|
1999-05-28 11:30:59 +00:00
|
|
|
PRInt32 i;
|
|
|
|
|
1998-12-24 05:07:14 +00:00
|
|
|
// If we're actually in the document style sheet list
|
1999-05-28 11:30:59 +00:00
|
|
|
if (-1 != mStyleSheets.IndexOf((void *)aSheet)) {
|
1998-12-24 05:07:14 +00:00
|
|
|
count = mPresShells.Count();
|
1999-05-28 11:30:59 +00:00
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(i);
|
1999-02-12 17:45:58 +00:00
|
|
|
nsCOMPtr<nsIStyleSet> set;
|
|
|
|
shell->GetStyleSet(getter_AddRefs(set));
|
1999-02-12 18:41:26 +00:00
|
|
|
if (set) {
|
1998-12-24 05:07:14 +00:00
|
|
|
if (aDisabled) {
|
|
|
|
set->RemoveDocStyleSheet(aSheet);
|
|
|
|
}
|
|
|
|
else {
|
1999-01-23 06:59:35 +00:00
|
|
|
set->AddDocStyleSheet(aSheet, this); // put it first
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-11-18 02:25:33 +00:00
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
|
1999-05-28 11:30:59 +00:00
|
|
|
for (i = 0; i < mObservers.Count(); i++) {
|
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(i);
|
1998-12-24 05:07:14 +00:00
|
|
|
observer->StyleSheetDisabledStateChanged(this, aSheet, aDisabled);
|
1999-05-28 11:30:59 +00:00
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
1999-05-18 23:02:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetCSSLoader(nsICSSLoader*& aLoader)
|
1999-05-18 23:02:00 +00:00
|
|
|
{
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
if (! mCSSLoader) {
|
|
|
|
result = nsComponentManager::CreateInstance(kCSSLoaderCID,
|
|
|
|
nsnull,
|
1999-10-05 21:13:55 +00:00
|
|
|
NS_GET_IID(nsICSSLoader),
|
1999-10-29 01:21:15 +00:00
|
|
|
getter_AddRefs(mCSSLoader));
|
1999-05-18 23:02:00 +00:00
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
result = mCSSLoader->Init(this);
|
1999-05-26 23:42:29 +00:00
|
|
|
mCSSLoader->SetCaseSensitive(PR_TRUE);
|
1999-07-07 01:17:21 +00:00
|
|
|
mCSSLoader->SetQuirkMode(PR_FALSE); // no quirks in XUL
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
1999-05-18 23:02:00 +00:00
|
|
|
}
|
|
|
|
aLoader = mCSSLoader;
|
|
|
|
NS_IF_ADDREF(aLoader);
|
|
|
|
return result;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-12-03 09:24:22 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::GetScriptGlobalObject(nsIScriptGlobalObject** aScriptGlobalObject)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-12-17 00:06:28 +00:00
|
|
|
*aScriptGlobalObject = mScriptGlobalObject;
|
1999-12-03 09:24:22 +00:00
|
|
|
NS_IF_ADDREF(*aScriptGlobalObject);
|
|
|
|
return NS_OK;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-12-03 09:24:22 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-12-17 00:06:28 +00:00
|
|
|
if (!aScriptGlobalObject) {
|
|
|
|
// XXX HACK ALERT! If the script context owner is null, the
|
|
|
|
// document will soon be going away. So tell our content that
|
|
|
|
// to lose its reference to the document. This has to be done
|
|
|
|
// before we actually set the script context owner to null so
|
|
|
|
// that the content elements can remove references to their
|
|
|
|
// script objects.
|
|
|
|
if (mRootContent)
|
|
|
|
mRootContent->SetDocument(nsnull, PR_TRUE);
|
|
|
|
|
|
|
|
// Break circular reference for the case where the currently
|
|
|
|
// focused window is ourself.
|
|
|
|
if (mCommandDispatcher)
|
|
|
|
mCommandDispatcher->SetFocusedWindow(nsnull);
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
|
1999-12-03 09:24:22 +00:00
|
|
|
mScriptGlobalObject = aScriptGlobalObject;
|
|
|
|
return NS_OK;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetNameSpaceManager(nsINameSpaceManager*& aManager)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
aManager = mNameSpaceManager;
|
|
|
|
NS_IF_ADDREF(aManager);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Note: We don't hold a reference to the document observer; we assume
|
|
|
|
// that it has a live reference to the document.
|
1999-11-18 02:25:33 +00:00
|
|
|
void
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::AddObserver(nsIDocumentObserver* aObserver)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
// XXX Make sure the observer isn't already in the list
|
|
|
|
if (mObservers.IndexOf(aObserver) == -1) {
|
|
|
|
mObservers.AppendElement(aObserver);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
PRBool
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::RemoveObserver(nsIDocumentObserver* aObserver)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
return mObservers.RemoveElement(aObserver);
|
|
|
|
}
|
|
|
|
|
2000-01-28 23:43:12 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::BeginUpdate()
|
|
|
|
{
|
|
|
|
// XXX Never called. Does this matter?
|
|
|
|
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i];
|
|
|
|
observer->BeginUpdate(this);
|
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::EndUpdate()
|
|
|
|
{
|
|
|
|
// XXX Never called. Does this matter?
|
|
|
|
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i];
|
|
|
|
observer->EndUpdate(this);
|
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::BeginLoad()
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-10-29 01:21:15 +00:00
|
|
|
// XXX Never called. Does this matter?
|
1999-08-30 02:45:54 +00:00
|
|
|
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
1998-12-24 05:07:14 +00:00
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i];
|
|
|
|
observer->BeginLoad(this);
|
1999-05-18 23:02:00 +00:00
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::EndLoad()
|
|
|
|
{
|
1999-10-05 21:13:55 +00:00
|
|
|
nsresult rv;
|
1999-11-02 01:14:07 +00:00
|
|
|
|
|
|
|
// Whack the prototype document into the cache so that the next
|
|
|
|
// time somebody asks for it, they don't need to load it by hand.
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
rv = mCurrentPrototype->GetURI(getter_AddRefs(uri));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (gXULUtils->UseXULCache() && IsChromeURI(mDocumentURL)) {
|
|
|
|
// If it's a 'chrome:' prototype document, then put it into
|
|
|
|
// the prototype cache; other XUL documents will be reloaded
|
|
|
|
// each time.
|
|
|
|
rv = gXULCache->PutPrototype(mCurrentPrototype);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now walk the prototype to build content.
|
1999-10-29 01:21:15 +00:00
|
|
|
rv = PrepareToWalk();
|
1999-10-05 21:13:55 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-07-16 04:03:52 +00:00
|
|
|
|
1999-12-16 03:19:34 +00:00
|
|
|
if (mIsKeyBindingDoc && (mCurrentPrototype != mMasterPrototype))
|
|
|
|
return NS_OK; // If we're a keybinding doc and we're loading an overlay
|
1999-12-04 07:45:57 +00:00
|
|
|
return ResumeWalk();
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ContentChanged(nsIContent* aContent,
|
1998-12-24 05:07:14 +00:00
|
|
|
nsISupports* aSubContent)
|
|
|
|
{
|
1999-08-30 02:45:54 +00:00
|
|
|
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
1998-12-24 05:07:14 +00:00
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
|
|
|
observer->ContentChanged(this, aContent, aSubContent);
|
1999-05-18 23:02:00 +00:00
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ContentStatesChanged(nsIContent* aContent1, nsIContent* aContent2)
|
1999-02-27 07:15:09 +00:00
|
|
|
{
|
1999-08-30 02:45:54 +00:00
|
|
|
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
1999-02-27 07:15:09 +00:00
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
1999-04-20 00:00:02 +00:00
|
|
|
observer->ContentStatesChanged(this, aContent1, aContent2);
|
1999-05-18 23:02:00 +00:00
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
|
|
|
}
|
1999-02-27 07:15:09 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::AttributeChanged(nsIContent* aElement,
|
1999-10-15 23:17:53 +00:00
|
|
|
PRInt32 aNameSpaceID,
|
1999-08-30 02:45:54 +00:00
|
|
|
nsIAtom* aAttribute,
|
|
|
|
PRInt32 aHint)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-08-30 02:45:54 +00:00
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
PRInt32 nameSpaceID;
|
1999-08-31 06:40:41 +00:00
|
|
|
rv = aElement->GetNameSpaceID(nameSpaceID);
|
1999-08-30 02:45:54 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// First see if we need to update our element map.
|
1999-10-07 10:09:17 +00:00
|
|
|
if ((aAttribute == kIdAtom) || (aAttribute == kRefAtom)) {
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-10-07 10:09:17 +00:00
|
|
|
rv = mElementMap.Enumerate(RemoveElementsFromMapByContent, aElement);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-10-07 10:09:17 +00:00
|
|
|
// That'll have removed _both_ the 'ref' and 'id' entries from
|
|
|
|
// the map. So add 'em back now.
|
|
|
|
rv = AddElementToMap(aElement);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-08-30 02:45:54 +00:00
|
|
|
}
|
|
|
|
|
1999-08-31 06:40:41 +00:00
|
|
|
// Now notify external observers
|
|
|
|
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
1999-10-15 23:17:53 +00:00
|
|
|
observer->AttributeChanged(this, aElement, aNameSpaceID, aAttribute, aHint);
|
1999-08-31 06:40:41 +00:00
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
1999-10-07 10:09:17 +00:00
|
|
|
i--;
|
1999-08-31 06:40:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle "special" cases. We do this handling _after_ we've
|
|
|
|
// notified the observer to ensure that any frames that are
|
|
|
|
// caching information (e.g., the tree widget and the 'open'
|
|
|
|
// attribute) will notice things properly.
|
1999-09-24 19:49:15 +00:00
|
|
|
if ((nameSpaceID == kNameSpaceID_XUL) && (aAttribute == kOpenAtom)) {
|
|
|
|
nsAutoString open;
|
|
|
|
rv = aElement->GetAttribute(kNameSpaceID_None, kOpenAtom, open);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-09-24 19:49:15 +00:00
|
|
|
if ((rv == NS_CONTENT_ATTR_HAS_VALUE) && (open.Equals("true"))) {
|
|
|
|
OpenWidgetItem(aElement);
|
1999-08-30 02:45:54 +00:00
|
|
|
}
|
1999-09-24 19:49:15 +00:00
|
|
|
else {
|
|
|
|
CloseWidgetItem(aElement);
|
1999-08-30 02:45:54 +00:00
|
|
|
}
|
|
|
|
}
|
1999-09-24 19:49:15 +00:00
|
|
|
else if (aAttribute == kRefAtom) {
|
|
|
|
RebuildWidgetItem(aElement);
|
|
|
|
}
|
|
|
|
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-09-03 07:02:25 +00:00
|
|
|
// Finally, see if there is anything we need to persist in the
|
|
|
|
// localstore.
|
|
|
|
//
|
|
|
|
// XXX Namespace handling broken :-(
|
|
|
|
nsAutoString persist;
|
|
|
|
rv = aElement->GetAttribute(kNameSpaceID_None, kPersistAtom, persist);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
|
|
|
|
nsAutoString attr;
|
|
|
|
rv = aAttribute->ToString(attr);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (persist.Find(attr) >= 0) {
|
|
|
|
rv = Persist(aElement, kNameSpaceID_None, aAttribute);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-12-24 05:07:14 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ContentAppended(nsIContent* aContainer,
|
1999-08-30 02:45:54 +00:00
|
|
|
PRInt32 aNewIndexInContainer)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-08-30 02:45:54 +00:00
|
|
|
// First update our element map
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
PRInt32 count;
|
|
|
|
rv = aContainer->ChildCount(count);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
for (PRInt32 i = aNewIndexInContainer; i < count; ++i) {
|
|
|
|
nsCOMPtr<nsIContent> child;
|
|
|
|
rv = aContainer->ChildAt(i, *getter_AddRefs(child));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-09-17 04:29:53 +00:00
|
|
|
rv = AddSubtreeToDocument(child);
|
1999-08-30 02:45:54 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now notify external observers
|
|
|
|
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
1998-12-24 05:07:14 +00:00
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
|
|
|
observer->ContentAppended(this, aContainer, aNewIndexInContainer);
|
1999-05-18 23:02:00 +00:00
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ContentInserted(nsIContent* aContainer,
|
1999-08-30 02:45:54 +00:00
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-08-30 02:45:54 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-09-17 04:29:53 +00:00
|
|
|
rv = AddSubtreeToDocument(aChild);
|
1999-08-30 02:45:54 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now notify external observers
|
|
|
|
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
1998-12-24 05:07:14 +00:00
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
|
|
|
observer->ContentInserted(this, aContainer, aChild, aIndexInContainer);
|
1999-05-18 23:02:00 +00:00
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ContentReplaced(nsIContent* aContainer,
|
1999-08-30 02:45:54 +00:00
|
|
|
nsIContent* aOldChild,
|
|
|
|
nsIContent* aNewChild,
|
|
|
|
PRInt32 aIndexInContainer)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-08-30 02:45:54 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-09-17 04:29:53 +00:00
|
|
|
rv = RemoveSubtreeFromDocument(aOldChild);
|
1999-08-30 02:45:54 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-09-17 04:29:53 +00:00
|
|
|
rv = AddSubtreeToDocument(aNewChild);
|
1999-08-30 02:45:54 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now notify external observers
|
|
|
|
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
1998-12-24 05:07:14 +00:00
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
|
|
|
observer->ContentReplaced(this, aContainer, aOldChild, aNewChild,
|
|
|
|
aIndexInContainer);
|
1999-05-18 23:02:00 +00:00
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ContentRemoved(nsIContent* aContainer,
|
1999-08-30 02:45:54 +00:00
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-08-30 02:45:54 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-09-17 04:29:53 +00:00
|
|
|
rv = RemoveSubtreeFromDocument(aChild);
|
1999-08-30 02:45:54 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now notify external observers
|
|
|
|
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
1998-12-24 05:07:14 +00:00
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
1999-11-18 02:25:33 +00:00
|
|
|
observer->ContentRemoved(this, aContainer,
|
1998-12-24 05:07:14 +00:00
|
|
|
aChild, aIndexInContainer);
|
1999-05-18 23:02:00 +00:00
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::StyleRuleChanged(nsIStyleSheet* aStyleSheet,
|
1999-08-30 02:45:54 +00:00
|
|
|
nsIStyleRule* aStyleRule,
|
|
|
|
PRInt32 aHint)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-08-30 02:45:54 +00:00
|
|
|
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
1998-12-24 05:07:14 +00:00
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
|
|
|
observer->StyleRuleChanged(this, aStyleSheet, aStyleRule, aHint);
|
1999-05-18 23:02:00 +00:00
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::StyleRuleAdded(nsIStyleSheet* aStyleSheet,
|
1999-08-30 02:45:54 +00:00
|
|
|
nsIStyleRule* aStyleRule)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-08-30 02:45:54 +00:00
|
|
|
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
1998-12-24 05:07:14 +00:00
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
|
|
|
observer->StyleRuleAdded(this, aStyleSheet, aStyleRule);
|
1999-05-18 23:02:00 +00:00
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::StyleRuleRemoved(nsIStyleSheet* aStyleSheet,
|
1999-08-30 02:45:54 +00:00
|
|
|
nsIStyleRule* aStyleRule)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-08-30 02:45:54 +00:00
|
|
|
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
1998-12-24 05:07:14 +00:00
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
|
|
|
observer->StyleRuleRemoved(this, aStyleSheet, aStyleRule);
|
1999-05-18 23:02:00 +00:00
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetSelection(nsIDOMSelection** aSelection)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
if (!mSelection) {
|
2000-01-26 20:39:28 +00:00
|
|
|
NS_ASSERTION(0,"not initialized");
|
1998-12-24 05:07:14 +00:00
|
|
|
*aSelection = nsnull;
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
|
|
}
|
|
|
|
*aSelection = mSelection;
|
1999-05-28 11:30:59 +00:00
|
|
|
NS_ADDREF(*aSelection);
|
1998-12-24 05:07:14 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::SelectAll()
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
nsIContent * start = nsnull;
|
|
|
|
nsIContent * end = nsnull;
|
|
|
|
nsIContent * body = nsnull;
|
|
|
|
|
1999-06-24 21:19:02 +00:00
|
|
|
nsAutoString bodyStr("BODY");
|
1998-12-24 05:07:14 +00:00
|
|
|
PRInt32 i, n;
|
|
|
|
mRootContent->ChildCount(n);
|
|
|
|
for (i=0;i<n;i++) {
|
|
|
|
nsIContent * child;
|
|
|
|
mRootContent->ChildAt(i, child);
|
|
|
|
PRBool isSynthetic;
|
|
|
|
child->IsSynthetic(isSynthetic);
|
|
|
|
if (!isSynthetic) {
|
|
|
|
nsIAtom * atom;
|
|
|
|
child->GetTag(atom);
|
|
|
|
if (bodyStr.EqualsIgnoreCase(atom)) {
|
|
|
|
body = child;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
NS_RELEASE(child);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (body == nsnull) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
start = body;
|
|
|
|
// Find Very first Piece of Content
|
|
|
|
for (;;) {
|
|
|
|
start->ChildCount(n);
|
|
|
|
if (n <= 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nsIContent * child = start;
|
|
|
|
child->ChildAt(0, start);
|
|
|
|
NS_RELEASE(child);
|
|
|
|
}
|
|
|
|
|
|
|
|
end = body;
|
|
|
|
// Last piece of Content
|
|
|
|
for (;;) {
|
|
|
|
end->ChildCount(n);
|
|
|
|
if (n <= 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nsIContent * child = end;
|
|
|
|
child->ChildAt(n-1, end);
|
|
|
|
NS_RELEASE(child);
|
|
|
|
}
|
|
|
|
|
|
|
|
//NS_RELEASE(start);
|
|
|
|
//NS_RELEASE(end);
|
|
|
|
|
|
|
|
#if 0 // XXX nsSelectionRange is in another DLL
|
|
|
|
nsSelectionRange * range = mSelection->GetRange();
|
|
|
|
nsSelectionPoint * startPnt = range->GetStartPoint();
|
|
|
|
nsSelectionPoint * endPnt = range->GetEndPoint();
|
|
|
|
startPnt->SetPoint(start, -1, PR_TRUE);
|
|
|
|
endPnt->SetPoint(end, -1, PR_FALSE);
|
|
|
|
#endif
|
|
|
|
SetDisplaySelection(PR_TRUE);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::FindNext(const nsString &aSearchStr, PRBool aMatchCase, PRBool aSearchDown, PRBool &aIsFound)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
aIsFound = PR_FALSE;
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CreateXIF(nsString & aBuffer, nsIDOMSelection* aSelection)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
2000-01-26 20:39:28 +00:00
|
|
|
NS_ASSERTION(0,"CreateXIF");
|
1999-09-15 17:57:55 +00:00
|
|
|
return NS_OK;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
2000-01-26 20:39:28 +00:00
|
|
|
NS_ASSERTION(0,"ToXIF");
|
1999-09-15 17:57:55 +00:00
|
|
|
return NS_OK;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
2000-01-24 06:43:15 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::FlushPendingNotifications()
|
|
|
|
{
|
|
|
|
PRInt32 i, count = mPresShells.Count();
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[i]);
|
|
|
|
if (shell) {
|
|
|
|
shell->FlushPendingNotifications();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
void
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::BeginConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
2000-01-26 20:39:28 +00:00
|
|
|
NS_ASSERTION(0,"BeginConvertToXIF");
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
void
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ConvertChildrenToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
2000-01-26 20:39:28 +00:00
|
|
|
NS_ASSERTION(0,"ConvertChildrenToXIF");
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
void
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::FinishConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
2000-01-26 20:39:28 +00:00
|
|
|
NS_ASSERTION(0,"FinishConvertToXIF");
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
PRBool
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::IsInRange(const nsIContent *aStartContent, const nsIContent* aEndContent, const nsIContent* aContent) const
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
PRBool result;
|
|
|
|
|
|
|
|
if (aStartContent == aEndContent) {
|
|
|
|
return PRBool(aContent == aStartContent);
|
|
|
|
}
|
|
|
|
else if (aStartContent == aContent || aEndContent == aContent) {
|
|
|
|
result = PR_TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
result = IsBefore(aStartContent,aContent);
|
|
|
|
if (result)
|
|
|
|
result = IsBefore(aContent, aEndContent);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
PRBool
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::IsBefore(const nsIContent *aNewContent, const nsIContent* aCurrentContent) const
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
PRBool result = PR_FALSE;
|
|
|
|
|
|
|
|
if (nsnull != aNewContent && nsnull != aCurrentContent && aNewContent != aCurrentContent) {
|
1999-01-14 10:55:08 +00:00
|
|
|
nsIContent* test = FindContent(mRootContent, aNewContent, aCurrentContent);
|
1998-12-24 05:07:14 +00:00
|
|
|
if (test == aNewContent)
|
|
|
|
result = PR_TRUE;
|
|
|
|
|
|
|
|
NS_RELEASE(test);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
PRBool
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::IsInSelection(nsIDOMSelection* aSelection, const nsIContent *aContent) const
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
PRBool result = PR_FALSE;
|
|
|
|
|
|
|
|
if (mSelection != nsnull) {
|
|
|
|
#if 0 // XXX can't include this because nsSelectionPoint is in another DLL.
|
|
|
|
nsSelectionRange* range = mSelection->GetRange();
|
|
|
|
if (range != nsnull) {
|
|
|
|
nsSelectionPoint* startPoint = range->GetStartPoint();
|
|
|
|
nsSelectionPoint* endPoint = range->GetEndPoint();
|
|
|
|
|
|
|
|
nsIContent* startContent = startPoint->GetContent();
|
|
|
|
nsIContent* endContent = endPoint->GetContent();
|
|
|
|
result = IsInRange(startContent, endContent, aContent);
|
|
|
|
NS_IF_RELEASE(startContent);
|
|
|
|
NS_IF_RELEASE(endContent);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
nsIContent*
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetPrevContent(const nsIContent *aContent) const
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
nsIContent* result = nsnull;
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1998-12-24 05:07:14 +00:00
|
|
|
// Look at previous sibling
|
|
|
|
|
|
|
|
if (nsnull != aContent) {
|
1999-11-18 02:25:33 +00:00
|
|
|
nsIContent* parent;
|
1998-12-24 05:07:14 +00:00
|
|
|
aContent->GetParent(parent);
|
|
|
|
|
1999-05-28 11:30:59 +00:00
|
|
|
if (parent && parent != mRootContent.get()) {
|
|
|
|
PRInt32 i;
|
|
|
|
parent->IndexOf((nsIContent*)aContent, i);
|
|
|
|
if (i > 0)
|
|
|
|
parent->ChildAt(i - 1, result);
|
1998-12-24 05:07:14 +00:00
|
|
|
else
|
|
|
|
result = GetPrevContent(parent);
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(parent);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
nsIContent*
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetNextContent(const nsIContent *aContent) const
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
nsIContent* result = nsnull;
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1998-12-24 05:07:14 +00:00
|
|
|
if (nsnull != aContent) {
|
|
|
|
// Look at next sibling
|
|
|
|
nsIContent* parent;
|
|
|
|
aContent->GetParent(parent);
|
|
|
|
|
1999-05-28 11:30:59 +00:00
|
|
|
if (parent != nsnull && parent != mRootContent.get()) {
|
|
|
|
PRInt32 i;
|
|
|
|
parent->IndexOf((nsIContent*)aContent, i);
|
1998-12-24 05:07:14 +00:00
|
|
|
|
|
|
|
PRInt32 count;
|
|
|
|
parent->ChildCount(count);
|
1999-05-28 11:30:59 +00:00
|
|
|
if (i + 1 < count) {
|
|
|
|
parent->ChildAt(i + 1, result);
|
1998-12-24 05:07:14 +00:00
|
|
|
// Get first child down the tree
|
|
|
|
for (;;) {
|
|
|
|
PRInt32 n;
|
|
|
|
result->ChildCount(n);
|
|
|
|
if (n <= 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
nsIContent * old = result;
|
|
|
|
old->ChildAt(0, result);
|
|
|
|
NS_RELEASE(old);
|
|
|
|
result->ChildCount(n);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
result = GetNextContent(parent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(parent);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
void
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::SetDisplaySelection(PRBool aToggle)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
mDisplaySelection = aToggle;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
PRBool
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetDisplaySelection() const
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
|
|
|
return mDisplaySelection;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-11-24 06:03:41 +00:00
|
|
|
nsXULDocument::HandleDOMEvent(nsIPresContext* aPresContext,
|
1999-11-18 02:25:33 +00:00
|
|
|
nsEvent* aEvent,
|
1998-12-24 05:07:14 +00:00
|
|
|
nsIDOMEvent** aDOMEvent,
|
|
|
|
PRUint32 aFlags,
|
1999-11-24 06:03:41 +00:00
|
|
|
nsEventStatus* aEventStatus)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-05-16 07:05:51 +00:00
|
|
|
nsresult ret = NS_OK;
|
|
|
|
nsIDOMEvent* domEvent = nsnull;
|
|
|
|
|
|
|
|
if (NS_EVENT_FLAG_INIT == aFlags) {
|
|
|
|
aDOMEvent = &domEvent;
|
1999-07-19 19:54:34 +00:00
|
|
|
aEvent->flags = NS_EVENT_FLAG_NONE;
|
1999-05-16 07:05:51 +00:00
|
|
|
}
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-05-16 07:05:51 +00:00
|
|
|
//Capturing stage
|
1999-12-03 12:09:10 +00:00
|
|
|
if (NS_EVENT_FLAG_BUBBLE != aFlags && mScriptGlobalObject) {
|
1999-12-03 09:24:22 +00:00
|
|
|
mScriptGlobalObject->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
|
1999-05-16 07:05:51 +00:00
|
|
|
}
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-05-16 07:05:51 +00:00
|
|
|
//Local handling stage
|
1999-07-19 19:54:34 +00:00
|
|
|
if (mListenerManager && !(aEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH)) {
|
|
|
|
aEvent->flags = aFlags;
|
1999-05-16 07:05:51 +00:00
|
|
|
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Bubbling stage
|
1999-12-03 12:09:10 +00:00
|
|
|
if (NS_EVENT_FLAG_CAPTURE != aFlags && mScriptGlobalObject) {
|
1999-12-03 09:24:22 +00:00
|
|
|
mScriptGlobalObject->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_BUBBLE, aEventStatus);
|
1999-05-16 07:05:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_EVENT_FLAG_INIT == aFlags) {
|
|
|
|
// We're leaving the DOM event loop so if we created a DOM event, release here.
|
|
|
|
if (nsnull != *aDOMEvent) {
|
|
|
|
nsrefcnt rc;
|
|
|
|
NS_RELEASE2(*aDOMEvent, rc);
|
|
|
|
if (0 != rc) {
|
|
|
|
//Okay, so someone in the DOM loop (a listener, JS object) still has a ref to the DOM Event but
|
|
|
|
//the internal data hasn't been malloc'd. Force a copy of the data here so the DOM Event is still valid.
|
|
|
|
nsIPrivateDOMEvent *privateEvent;
|
1999-10-05 21:13:55 +00:00
|
|
|
if (NS_OK == (*aDOMEvent)->QueryInterface(NS_GET_IID(nsIPrivateDOMEvent), (void**)&privateEvent)) {
|
1999-05-16 07:05:51 +00:00
|
|
|
privateEvent->DuplicatePrivateData();
|
|
|
|
NS_RELEASE(privateEvent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
aDOMEvent = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1998-12-24 05:07:14 +00:00
|
|
|
// nsIXMLDocument interface
|
1999-10-29 01:21:15 +00:00
|
|
|
//
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetContentById(const nsString& aName, nsIContent** aContent)
|
1999-03-20 01:51:00 +00:00
|
|
|
{
|
2000-01-26 20:39:28 +00:00
|
|
|
NS_ASSERTION(0,"not implemented");
|
1999-03-20 01:51:00 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-06-28 14:12:07 +00:00
|
|
|
#ifdef XSL
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::SetTransformMediator(nsITransformMediator* aMediator)
|
1999-06-28 14:12:07 +00:00
|
|
|
{
|
2000-01-26 20:39:28 +00:00
|
|
|
NS_ASSERTION(0,"not implemented");
|
1999-06-28 14:12:07 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
#endif
|
1999-02-04 10:50:50 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-10-05 21:13:55 +00:00
|
|
|
// nsIXULDocument interface
|
1999-10-29 01:21:15 +00:00
|
|
|
//
|
1998-12-24 05:07:14 +00:00
|
|
|
|
1999-02-09 03:15:41 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::AddElementForID(const nsString& aID, nsIContent* aElement)
|
1999-02-09 03:15:41 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(aElement != nsnull, "null ptr");
|
|
|
|
if (! aElement)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
mElementMap.Add(aID, aElement);
|
1999-02-09 03:15:41 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-01-12 19:41:06 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::RemoveElementForID(const nsString& aID, nsIContent* aElement)
|
1998-12-24 05:07:14 +00:00
|
|
|
{
|
1999-02-09 03:15:41 +00:00
|
|
|
NS_PRECONDITION(aElement != nsnull, "null ptr");
|
|
|
|
if (! aElement)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1999-01-12 19:41:06 +00:00
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
mElementMap.Remove(aID, aElement);
|
1999-02-09 03:15:41 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
|
1999-02-01 22:34:51 +00:00
|
|
|
|
1999-02-09 03:15:41 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetElementsForID(const nsString& aID, nsISupportsArray* aElements)
|
1999-02-09 03:15:41 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(aElements != nsnull, "null ptr");
|
|
|
|
if (! aElements)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
mElementMap.Find(aID, aElements);
|
1999-01-12 19:41:06 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-09 03:15:41 +00:00
|
|
|
|
1999-01-12 19:41:06 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CreateContents(nsIContent* aElement)
|
1999-01-12 19:41:06 +00:00
|
|
|
{
|
1999-02-09 03:15:41 +00:00
|
|
|
NS_PRECONDITION(aElement != nsnull, "null ptr");
|
|
|
|
if (! aElement)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
if (! mBuilders)
|
1999-01-12 19:41:06 +00:00
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
|
|
|
1999-05-13 04:56:04 +00:00
|
|
|
PRUint32 cnt = 0;
|
|
|
|
nsresult rv = mBuilders->Count(&cnt);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
|
|
|
|
for (PRUint32 i = 0; i < cnt; ++i) {
|
1999-02-09 03:15:41 +00:00
|
|
|
// XXX we should QueryInterface() here
|
|
|
|
nsIRDFContentModelBuilder* builder
|
|
|
|
= (nsIRDFContentModelBuilder*) mBuilders->ElementAt(i);
|
1999-01-12 19:41:06 +00:00
|
|
|
|
1999-02-09 03:15:41 +00:00
|
|
|
NS_ASSERTION(builder != nsnull, "null ptr");
|
|
|
|
if (! builder)
|
|
|
|
continue;
|
|
|
|
|
1999-05-28 11:30:59 +00:00
|
|
|
rv = builder->CreateContents(aElement);
|
1999-02-09 03:15:41 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "error creating content");
|
|
|
|
// XXX ignore error code?
|
|
|
|
|
|
|
|
NS_RELEASE(builder);
|
|
|
|
}
|
1999-02-01 22:34:51 +00:00
|
|
|
|
1999-01-12 19:41:06 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
|
|
|
|
|
1999-02-09 03:15:41 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::AddContentModelBuilder(nsIRDFContentModelBuilder* aBuilder)
|
1999-02-09 03:15:41 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(aBuilder != nsnull, "null ptr");
|
|
|
|
if (! aBuilder)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
if (! mBuilders) {
|
1999-05-28 11:30:59 +00:00
|
|
|
rv = NS_NewISupportsArray(getter_AddRefs(mBuilders));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-02-09 03:15:41 +00:00
|
|
|
}
|
|
|
|
|
1999-05-28 11:30:59 +00:00
|
|
|
rv = aBuilder->SetDocument(this);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-02-09 03:15:41 +00:00
|
|
|
|
1999-04-14 23:06:22 +00:00
|
|
|
return mBuilders->AppendElement(aBuilder) ? NS_OK : NS_ERROR_FAILURE;
|
1999-02-09 03:15:41 +00:00
|
|
|
}
|
|
|
|
|
1999-05-28 11:30:59 +00:00
|
|
|
|
1999-05-20 06:39:37 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetForm(nsIDOMHTMLFormElement** aForm)
|
1999-05-20 06:39:37 +00:00
|
|
|
{
|
|
|
|
*aForm = mHiddenForm;
|
1999-05-28 11:30:59 +00:00
|
|
|
NS_IF_ADDREF(*aForm);
|
1999-05-20 06:39:37 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::SetForm(nsIDOMHTMLFormElement* aForm)
|
1999-05-20 06:39:37 +00:00
|
|
|
{
|
1999-05-28 11:30:59 +00:00
|
|
|
mHiddenForm = dont_QueryInterface(aForm);
|
1999-07-25 04:38:57 +00:00
|
|
|
|
|
|
|
// Set the document.
|
|
|
|
nsCOMPtr<nsIContent> formContent = do_QueryInterface(aForm);
|
|
|
|
formContent->SetDocument(this, PR_TRUE);
|
|
|
|
|
|
|
|
// Forms are containers, and as such take up a bit of space.
|
|
|
|
// Set a style attribute to keep the hidden form from showing up.
|
|
|
|
mHiddenForm->SetAttribute("style", "margin:0em");
|
1999-05-28 11:30:59 +00:00
|
|
|
return NS_OK;
|
1999-05-20 06:39:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-09-30 02:32:34 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::AddForwardReference(nsForwardReference* aRef)
|
1999-09-30 02:32:34 +00:00
|
|
|
{
|
1999-11-17 03:20:03 +00:00
|
|
|
if (mResolutionPhase < aRef->GetPhase()) {
|
1999-10-05 21:13:55 +00:00
|
|
|
mForwardReferences.AppendElement(aRef);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
NS_ERROR("forward references have already been resolved");
|
|
|
|
delete aRef;
|
|
|
|
}
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-09-30 02:32:34 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ResolveForwardReferences()
|
1999-10-05 21:13:55 +00:00
|
|
|
{
|
1999-11-17 03:20:03 +00:00
|
|
|
if (mResolutionPhase == nsForwardReference::eDone)
|
1999-10-05 21:13:55 +00:00
|
|
|
return NS_OK;
|
1999-09-30 02:32:34 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
// Resolve each outstanding 'forward' reference. We iterate
|
|
|
|
// through the list of forward references until no more forward
|
|
|
|
// references can be resolved. This annealing process is
|
|
|
|
// guaranteed to converge because we've "closed the gate" to new
|
|
|
|
// forward references.
|
1999-09-30 02:32:34 +00:00
|
|
|
|
1999-11-17 03:20:03 +00:00
|
|
|
const nsForwardReference::Phase* pass = nsForwardReference::kPasses;
|
1999-11-17 02:45:46 +00:00
|
|
|
while ((mResolutionPhase = *pass) != nsForwardReference::eDone) {
|
1999-10-29 01:21:15 +00:00
|
|
|
PRInt32 previous = 0;
|
|
|
|
while (mForwardReferences.Count() && mForwardReferences.Count() != previous) {
|
|
|
|
previous = mForwardReferences.Count();
|
1999-09-30 02:32:34 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
for (PRInt32 i = 0; i < mForwardReferences.Count(); ++i) {
|
|
|
|
nsForwardReference* fwdref = NS_REINTERPRET_CAST(nsForwardReference*, mForwardReferences[i]);
|
1999-09-30 02:32:34 +00:00
|
|
|
|
1999-11-17 03:20:03 +00:00
|
|
|
if (fwdref->GetPhase() == *pass) {
|
1999-11-17 02:45:46 +00:00
|
|
|
nsForwardReference::Result result = fwdref->Resolve();
|
1999-10-05 21:13:55 +00:00
|
|
|
|
1999-11-17 02:45:46 +00:00
|
|
|
switch (result) {
|
|
|
|
case nsForwardReference::eResolve_Succeeded:
|
|
|
|
case nsForwardReference::eResolve_Error:
|
|
|
|
mForwardReferences.RemoveElementAt(i);
|
|
|
|
delete fwdref;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
1999-11-17 02:45:46 +00:00
|
|
|
// fixup because we removed from list
|
|
|
|
--i;
|
|
|
|
break;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
1999-11-17 02:45:46 +00:00
|
|
|
case nsForwardReference::eResolve_Later:
|
|
|
|
// do nothing. we'll try again later
|
|
|
|
;
|
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
}
|
1999-09-30 02:32:34 +00:00
|
|
|
}
|
|
|
|
}
|
1999-11-17 02:45:46 +00:00
|
|
|
|
|
|
|
++pass;
|
1999-09-30 02:32:34 +00:00
|
|
|
}
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
DestroyForwardReferences();
|
1999-09-30 02:32:34 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-12-08 04:56:56 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::SetMasterPrototype(nsIXULPrototypeDocument* aDocument)
|
|
|
|
{
|
|
|
|
mMasterPrototype = aDocument;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-01-22 22:00:35 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::GetMasterPrototype(nsIXULPrototypeDocument** aDocument)
|
|
|
|
{
|
|
|
|
*aDocument = mMasterPrototype;
|
|
|
|
NS_IF_ADDREF(*aDocument);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-12-08 04:56:56 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::SetCurrentPrototype(nsIXULPrototypeDocument* aDocument)
|
|
|
|
{
|
|
|
|
mCurrentPrototype = aDocument;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-05-20 06:39:37 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// nsIStreamLoadableDocument interface
|
|
|
|
//
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::LoadFromStream(nsIInputStream& xulStream,
|
1999-11-15 22:14:37 +00:00
|
|
|
nsISupports* aContainer,
|
1999-10-29 01:21:15 +00:00
|
|
|
const char* aCommand)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
// XXXbe this is dead code, eliminate
|
1999-10-29 01:21:15 +00:00
|
|
|
nsCOMPtr<nsIParser> parser;
|
|
|
|
rv = PrepareToLoad(aContainer, aCommand, nsnull, nsnull, getter_AddRefs(parser));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
parser->Parse(xulStream);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// nsIDOMDocument interface
|
|
|
|
//
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::GetDoctype(nsIDOMDocumentType** aDoctype)
|
1999-01-14 10:55:08 +00:00
|
|
|
{
|
1999-02-16 19:30:04 +00:00
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-01-14 10:55:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetImplementation(nsIDOMDOMImplementation** aImplementation)
|
1999-01-14 10:55:08 +00:00
|
|
|
{
|
1999-02-16 19:30:04 +00:00
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-01-14 10:55:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetDocumentElement(nsIDOMElement** aDocumentElement)
|
1999-01-14 10:55:08 +00:00
|
|
|
{
|
1999-05-28 11:30:59 +00:00
|
|
|
NS_PRECONDITION(aDocumentElement != nsnull, "null ptr");
|
|
|
|
if (! aDocumentElement)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1999-02-17 22:32:40 +00:00
|
|
|
|
1999-05-28 11:30:59 +00:00
|
|
|
if (mRootContent) {
|
2000-01-11 20:49:15 +00:00
|
|
|
return mRootContent->QueryInterface(NS_GET_IID(nsIDOMElement), (void**)aDocumentElement);
|
1999-05-28 11:30:59 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aDocumentElement = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-01-14 10:55:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
|
1999-01-14 10:55:08 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CreateElement(const nsString& aTagName, nsIDOMElement** aReturn)
|
1999-01-14 10:55:08 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
NS_PRECONDITION(aReturn != nsnull, "null ptr");
|
|
|
|
if (! aReturn)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-07-27 17:20:28 +00:00
|
|
|
#ifdef PR_LOGGING
|
|
|
|
if (PR_LOG_TEST(gXULLog, PR_LOG_DEBUG)) {
|
|
|
|
char* tagCStr = aTagName.ToNewCString();
|
|
|
|
|
|
|
|
PR_LOG(gXULLog, PR_LOG_DEBUG,
|
|
|
|
("xul[CreateElement] %s", tagCStr));
|
|
|
|
|
1999-09-04 13:59:52 +00:00
|
|
|
nsCRT::free(tagCStr);
|
1999-07-27 17:20:28 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1999-04-16 08:38:17 +00:00
|
|
|
nsCOMPtr<nsIAtom> name;
|
|
|
|
PRInt32 nameSpaceID;
|
|
|
|
|
1999-07-07 06:52:21 +00:00
|
|
|
*aReturn = nsnull;
|
|
|
|
|
1999-04-16 08:38:17 +00:00
|
|
|
// parse the user-provided string into a tag name and a namespace ID
|
|
|
|
rv = ParseTagString(aTagName, *getter_AddRefs(name), nameSpaceID);
|
1999-07-07 06:52:21 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
char* tagNameStr = aTagName.ToNewCString();
|
|
|
|
PR_LOG(gXULLog, PR_LOG_ERROR,
|
|
|
|
("xul[CreateElement] unable to parse tag '%s'; no such namespace.", tagNameStr));
|
1999-09-04 13:59:52 +00:00
|
|
|
nsCRT::free(tagNameStr);
|
1999-07-07 06:52:21 +00:00
|
|
|
#endif
|
|
|
|
return rv;
|
|
|
|
}
|
1999-04-16 08:38:17 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> result;
|
1999-10-05 21:13:55 +00:00
|
|
|
rv = CreateElement(nameSpaceID, name, getter_AddRefs(result));
|
1999-04-16 08:38:17 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// get the DOM interface
|
2000-01-11 20:49:15 +00:00
|
|
|
rv = result->QueryInterface(NS_GET_IID(nsIDOMElement), (void**) aReturn);
|
1999-04-16 08:38:17 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "not a DOM element");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
return NS_OK;
|
1999-01-14 10:55:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CreateDocumentFragment(nsIDOMDocumentFragment** aReturn)
|
1999-01-14 10:55:08 +00:00
|
|
|
{
|
1999-02-16 19:30:04 +00:00
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-01-14 10:55:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CreateTextNode(const nsString& aData, nsIDOMText** aReturn)
|
1999-01-14 10:55:08 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
NS_PRECONDITION(aReturn != nsnull, "null ptr");
|
|
|
|
if (! aReturn)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsITextContent> text;
|
2000-01-11 20:49:15 +00:00
|
|
|
rv = nsComponentManager::CreateInstance(kTextNodeCID, nsnull, NS_GET_IID(nsITextContent), getter_AddRefs(text));
|
1999-04-16 08:38:17 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = text->SetText(aData.GetUnicode(), aData.Length(), PR_FALSE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-01-11 20:49:15 +00:00
|
|
|
rv = text->QueryInterface(NS_GET_IID(nsIDOMText), (void**) aReturn);
|
1999-04-16 08:38:17 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "not a DOMText");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
return NS_OK;
|
1999-01-14 10:55:08 +00:00
|
|
|
}
|
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
|
1999-01-14 10:55:08 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CreateComment(const nsString& aData, nsIDOMComment** aReturn)
|
1999-01-14 10:55:08 +00:00
|
|
|
{
|
1999-02-16 19:30:04 +00:00
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-01-14 10:55:08 +00:00
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
|
1999-02-01 22:34:51 +00:00
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CreateCDATASection(const nsString& aData, nsIDOMCDATASection** aReturn)
|
1999-01-12 19:41:06 +00:00
|
|
|
{
|
1999-02-16 19:30:04 +00:00
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
1999-01-12 19:41:06 +00:00
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CreateProcessingInstruction(const nsString& aTarget, const nsString& aData, nsIDOMProcessingInstruction** aReturn)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-01-12 19:41:06 +00:00
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
|
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn)
|
1999-01-14 10:55:08 +00:00
|
|
|
{
|
1999-02-16 19:30:04 +00:00
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CreateEntityReference(const nsString& aName, nsIDOMEntityReference** aReturn)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetElementsByTagName(const nsString& aTagName, nsIDOMNodeList** aReturn)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsRDFDOMNodeList* elements;
|
|
|
|
if (NS_FAILED(rv = nsRDFDOMNodeList::Create(&elements))) {
|
|
|
|
NS_ERROR("unable to create node list");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIContent* root = GetRootContent();
|
|
|
|
NS_ASSERTION(root != nsnull, "no doc root");
|
|
|
|
|
|
|
|
if (root != nsnull) {
|
|
|
|
nsIDOMNode* domRoot;
|
2000-01-11 20:49:15 +00:00
|
|
|
if (NS_SUCCEEDED(rv = root->QueryInterface(NS_GET_IID(nsIDOMNode), (void**) &domRoot))) {
|
1999-02-16 19:30:04 +00:00
|
|
|
rv = GetElementsByTagName(domRoot, aTagName, elements);
|
|
|
|
NS_RELEASE(domRoot);
|
|
|
|
}
|
|
|
|
NS_RELEASE(root);
|
|
|
|
}
|
|
|
|
|
|
|
|
*aReturn = elements;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-23 02:40:51 +00:00
|
|
|
NS_IMETHODIMP
|
1999-11-18 02:25:33 +00:00
|
|
|
nsXULDocument::GetElementsByAttribute(const nsString& aAttribute, const nsString& aValue,
|
1999-02-23 02:40:51 +00:00
|
|
|
nsIDOMNodeList** aReturn)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsRDFDOMNodeList* elements;
|
|
|
|
if (NS_FAILED(rv = nsRDFDOMNodeList::Create(&elements))) {
|
|
|
|
NS_ERROR("unable to create node list");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIContent* root = GetRootContent();
|
|
|
|
NS_ASSERTION(root != nsnull, "no doc root");
|
|
|
|
|
|
|
|
if (root != nsnull) {
|
|
|
|
nsIDOMNode* domRoot;
|
2000-01-11 20:49:15 +00:00
|
|
|
if (NS_SUCCEEDED(rv = root->QueryInterface(NS_GET_IID(nsIDOMNode), (void**) &domRoot))) {
|
1999-02-23 02:40:51 +00:00
|
|
|
rv = GetElementsByAttribute(domRoot, aAttribute, aValue, elements);
|
|
|
|
NS_RELEASE(domRoot);
|
|
|
|
}
|
|
|
|
NS_RELEASE(root);
|
|
|
|
}
|
|
|
|
|
|
|
|
*aReturn = elements;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
|
1999-09-03 07:02:25 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::Persist(const nsString& aID, const nsString& aAttr)
|
1999-09-03 07:02:25 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMElement> domelement;
|
|
|
|
rv = GetElementById(aID, getter_AddRefs(domelement));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (! domelement)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> element = do_QueryInterface(domelement);
|
|
|
|
NS_ASSERTION(element != nsnull, "null ptr");
|
|
|
|
if (! element)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
PRInt32 nameSpaceID;
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
rv = element->ParseAttributeString(aAttr, *getter_AddRefs(tag), nameSpaceID);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = Persist(element, nameSpaceID, tag);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::Persist(nsIContent* aElement, PRInt32 aNameSpaceID, nsIAtom* aAttribute)
|
1999-09-03 07:02:25 +00:00
|
|
|
{
|
1999-09-14 22:36:55 +00:00
|
|
|
// First make sure we _have_ a local store to stuff the persited
|
|
|
|
// information into. (We might not have one if profile information
|
|
|
|
// hasn't been loaded yet...)
|
|
|
|
if (! mLocalStore)
|
|
|
|
return NS_OK;
|
|
|
|
|
1999-09-03 07:02:25 +00:00
|
|
|
nsresult rv;
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
nsCOMPtr<nsIRDFResource> element;
|
|
|
|
rv = gXULUtils->GetElementResource(aElement, getter_AddRefs(element));
|
1999-09-03 07:02:25 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// No ID, so nothing to persist.
|
1999-10-05 21:13:55 +00:00
|
|
|
if (! element)
|
1999-09-03 07:02:25 +00:00
|
|
|
return NS_OK;
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
// Ick. Construct a property from the attribute. Punt on
|
|
|
|
// namespaces for now.
|
|
|
|
const PRUnichar* attrstr;
|
|
|
|
rv = aAttribute->GetUnicode(&attrstr);
|
1999-09-03 07:02:25 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
nsCOMPtr<nsIRDFResource> attr;
|
|
|
|
rv = gRDFService->GetResource(nsCAutoString(attrstr), getter_AddRefs(attr));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// Turn the value into a literal
|
|
|
|
nsAutoString valuestr;
|
|
|
|
rv = aElement->GetAttribute(kNameSpaceID_None, aAttribute, valuestr);
|
1999-09-03 07:02:25 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
PRBool novalue = (rv != NS_CONTENT_ATTR_HAS_VALUE);
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
// See if there was an old value...
|
|
|
|
nsCOMPtr<nsIRDFNode> oldvalue;
|
|
|
|
rv = mLocalStore->GetTarget(element, attr, PR_TRUE, getter_AddRefs(oldvalue));
|
1999-09-03 07:02:25 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
if (oldvalue && novalue) {
|
|
|
|
// ...there was an oldvalue, and they've removed it. XXXThis
|
|
|
|
// handling isn't quite right...
|
|
|
|
rv = mLocalStore->Unassert(element, attr, oldvalue);
|
1999-09-03 07:02:25 +00:00
|
|
|
}
|
|
|
|
else {
|
1999-10-05 21:13:55 +00:00
|
|
|
// Now either 'change' or 'assert' based on whether there was
|
|
|
|
// an old value.
|
|
|
|
nsCOMPtr<nsIRDFLiteral> newvalue;
|
|
|
|
rv = gRDFService->GetLiteral(valuestr.GetUnicode(), getter_AddRefs(newvalue));
|
1999-09-03 07:02:25 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
if (oldvalue) {
|
|
|
|
rv = mLocalStore->Change(element, attr, oldvalue, newvalue);
|
1999-09-03 07:02:25 +00:00
|
|
|
}
|
|
|
|
else {
|
1999-10-05 21:13:55 +00:00
|
|
|
rv = mLocalStore->Assert(element, attr, newvalue, PR_TRUE);
|
1999-09-03 07:02:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-05 21:13:55 +00:00
|
|
|
|
|
|
|
// Add it to the persisted set for this document (if it's not
|
|
|
|
// there already).
|
|
|
|
{
|
|
|
|
nsXPIDLCString docurl;
|
|
|
|
rv = mDocumentURL->GetSpec(getter_Copies(docurl));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFResource> doc;
|
|
|
|
rv = gRDFService->GetResource(docurl, getter_AddRefs(doc));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
PRBool hasAssertion;
|
|
|
|
rv = mLocalStore->HasAssertion(doc, kNC_persist, element, PR_TRUE, &hasAssertion);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (! hasAssertion) {
|
|
|
|
rv = mLocalStore->Assert(doc, kNC_persist, element, PR_TRUE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-09-03 07:02:25 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-09-30 02:32:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::DestroyForwardReferences()
|
1999-09-30 02:32:34 +00:00
|
|
|
{
|
1999-10-05 21:13:55 +00:00
|
|
|
for (PRInt32 i = mForwardReferences.Count() - 1; i >= 0; --i) {
|
|
|
|
nsForwardReference* fwdref = NS_REINTERPRET_CAST(nsForwardReference*, mForwardReferences[i]);
|
|
|
|
delete fwdref;
|
1999-09-30 02:32:34 +00:00
|
|
|
}
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
mForwardReferences.Clear();
|
1999-09-30 02:32:34 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-05-19 04:28:40 +00:00
|
|
|
// nsIDOMNSDocument interface
|
1999-10-29 01:21:15 +00:00
|
|
|
//
|
1999-05-19 04:28:40 +00:00
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetStyleSheets(nsIDOMStyleSheetCollection** aStyleSheets)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2000-01-15 02:01:05 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::GetCharacterSet(nsString& aCharacterSet)
|
|
|
|
{
|
|
|
|
return GetDocumentCharacterSet(aCharacterSet);
|
|
|
|
}
|
1999-02-16 19:30:04 +00:00
|
|
|
|
1999-05-19 04:28:40 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CreateElementWithNameSpace(const nsString& aTagName,
|
1999-05-19 04:28:40 +00:00
|
|
|
const nsString& aNameSpace,
|
|
|
|
nsIDOMElement** aResult)
|
|
|
|
{
|
|
|
|
// Create a DOM element given a namespace URI and a tag name.
|
|
|
|
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
|
|
|
if (! aResult)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-07-27 17:20:28 +00:00
|
|
|
#ifdef PR_LOGGING
|
|
|
|
if (PR_LOG_TEST(gXULLog, PR_LOG_DEBUG)) {
|
|
|
|
char* namespaceCStr = aNameSpace.ToNewCString();
|
|
|
|
char* tagCStr = aTagName.ToNewCString();
|
|
|
|
|
|
|
|
PR_LOG(gXULLog, PR_LOG_DEBUG,
|
|
|
|
("xul[CreateElementWithNameSpace] [%s]:%s", namespaceCStr, tagCStr));
|
|
|
|
|
1999-09-04 13:59:52 +00:00
|
|
|
nsCRT::free(tagCStr);
|
|
|
|
nsCRT::free(namespaceCStr);
|
1999-07-27 17:20:28 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1999-06-12 19:33:37 +00:00
|
|
|
nsCOMPtr<nsIAtom> name = dont_AddRef(NS_NewAtom(aTagName.GetUnicode()));
|
1999-05-19 04:28:40 +00:00
|
|
|
if (! name)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
PRInt32 nameSpaceID;
|
|
|
|
rv = mNameSpaceManager->GetNameSpaceID(aNameSpace, nameSpaceID);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> result;
|
1999-10-05 21:13:55 +00:00
|
|
|
rv = CreateElement(nameSpaceID, name, getter_AddRefs(result));
|
1999-05-19 04:28:40 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// get the DOM interface
|
2000-01-11 20:49:15 +00:00
|
|
|
rv = result->QueryInterface(NS_GET_IID(nsIDOMElement), (void**) aResult);
|
1999-05-19 04:28:40 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "not a DOM element");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CreateRange(nsIDOMRange** aRange)
|
1999-05-19 04:28:40 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetWidth(PRInt32* aWidth)
|
1999-10-06 20:33:58 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
1999-11-18 02:25:33 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetHeight(PRInt32* aHeight)
|
1999-10-06 20:33:58 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
1999-02-16 19:30:04 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-02-17 11:09:57 +00:00
|
|
|
// nsIDOMXULDocument interface
|
1999-10-29 01:21:15 +00:00
|
|
|
//
|
1999-02-17 11:09:57 +00:00
|
|
|
|
1999-05-15 08:46:14 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetPopupNode(nsIDOMNode** aNode)
|
1999-07-01 00:07:41 +00:00
|
|
|
{
|
1999-11-18 02:25:33 +00:00
|
|
|
*aNode = mPopupNode;
|
|
|
|
NS_IF_ADDREF(*aNode);
|
|
|
|
return NS_OK;
|
1999-07-01 00:07:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::SetPopupNode(nsIDOMNode* aNode)
|
1999-05-15 08:46:14 +00:00
|
|
|
{
|
1999-11-18 02:25:33 +00:00
|
|
|
mPopupNode = dont_QueryInterface(aNode);
|
|
|
|
return NS_OK;
|
1999-07-01 00:07:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetTooltipNode(nsIDOMNode** aNode)
|
1999-07-01 00:07:41 +00:00
|
|
|
{
|
1999-11-18 02:25:33 +00:00
|
|
|
*aNode = mTooltipNode;
|
|
|
|
NS_IF_ADDREF(*aNode);
|
|
|
|
return NS_OK;
|
1999-05-15 08:46:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::SetTooltipNode(nsIDOMNode* aNode)
|
1999-05-15 08:46:14 +00:00
|
|
|
{
|
1999-11-18 02:25:33 +00:00
|
|
|
mTooltipNode = dont_QueryInterface(aNode);
|
|
|
|
return NS_OK;
|
1999-05-15 08:46:14 +00:00
|
|
|
}
|
|
|
|
|
1999-07-01 00:07:41 +00:00
|
|
|
|
1999-05-28 20:24:58 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetCommandDispatcher(nsIDOMXULCommandDispatcher** aTracker)
|
1999-05-28 20:24:58 +00:00
|
|
|
{
|
1999-08-25 01:49:24 +00:00
|
|
|
*aTracker = mCommandDispatcher;
|
1999-05-28 20:24:58 +00:00
|
|
|
NS_IF_ADDREF(*aTracker);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-01-13 02:59:08 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::GetControls(nsIDOMHTMLCollection ** aResult) {
|
|
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
|
|
|
|
// for now, just return the elements in the HTML form...
|
|
|
|
// eventually we could return other XUL elements
|
|
|
|
if (mHiddenForm)
|
|
|
|
return mHiddenForm->GetElements(aResult);
|
|
|
|
else
|
|
|
|
*aResult = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-17 11:09:57 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetElementById(const nsString& aId, nsIDOMElement** aReturn)
|
1999-02-17 11:09:57 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
nsCOMPtr<nsIContent> element;
|
|
|
|
rv = mElementMap.FindFirst(aId, getter_AddRefs(element));
|
1999-08-30 02:45:54 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-02-17 11:09:57 +00:00
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
if (element) {
|
|
|
|
rv = element->QueryInterface(NS_GET_IID(nsIDOMElement), (void**) aReturn);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aReturn = nsnull;
|
|
|
|
rv = NS_OK;
|
1999-02-17 11:09:57 +00:00
|
|
|
}
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
return rv;
|
1999-02-17 18:46:23 +00:00
|
|
|
}
|
|
|
|
|
1999-09-17 04:29:53 +00:00
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::AddSubtreeToDocument(nsIContent* aElement)
|
1999-09-17 04:29:53 +00:00
|
|
|
{
|
|
|
|
// Do a bunch of work that's necessary when an element gets added
|
|
|
|
// to the XUL Document.
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// 1. Add the element to the resource-to-element map
|
|
|
|
rv = AddElementToMap(aElement);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// 2. If the element is a 'command updater' (i.e., has a
|
|
|
|
// "commandupdater='true'" attribute), then add the element to the
|
|
|
|
// document's command dispatcher
|
|
|
|
nsAutoString value;
|
|
|
|
rv = aElement->GetAttribute(kNameSpaceID_None, kCommandUpdaterAtom, value);
|
|
|
|
if ((rv == NS_CONTENT_ATTR_HAS_VALUE) && value.Equals("true")) {
|
1999-10-13 00:43:46 +00:00
|
|
|
rv = gXULUtils->SetCommandUpdater(this, aElement);
|
1999-09-17 04:29:53 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
1999-11-08 19:07:13 +00:00
|
|
|
// 3. Check for a broadcaster hookup attribute, in which case
|
|
|
|
// we'll hook the node up as a listener on a broadcaster.
|
1999-11-17 02:45:46 +00:00
|
|
|
PRBool listener, resolved;
|
|
|
|
rv = CheckBroadcasterHookup(this, aElement, &listener, &resolved);
|
1999-11-08 19:07:13 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// If it's not there yet, we may be able to defer hookup until
|
|
|
|
// later.
|
1999-11-17 03:20:03 +00:00
|
|
|
if (listener && !resolved && (mResolutionPhase != nsForwardReference::eDone)) {
|
1999-11-08 19:07:13 +00:00
|
|
|
BroadcasterHookup* hookup = new BroadcasterHookup(this, aElement);
|
|
|
|
if (! hookup)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
rv = AddForwardReference(hookup);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
2000-01-22 22:00:35 +00:00
|
|
|
// 4. Recurse to children.
|
1999-09-17 04:29:53 +00:00
|
|
|
PRInt32 count;
|
|
|
|
nsCOMPtr<nsIXULContent> xulcontent = do_QueryInterface(aElement);
|
|
|
|
rv = xulcontent ? xulcontent->PeekChildCount(count) : aElement->ChildCount(count);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
while (--count >= 0) {
|
|
|
|
nsCOMPtr<nsIContent> child;
|
|
|
|
rv = aElement->ChildAt(count, *getter_AddRefs(child));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = AddSubtreeToDocument(child);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::RemoveSubtreeFromDocument(nsIContent* aElement)
|
1999-09-17 04:29:53 +00:00
|
|
|
{
|
|
|
|
// Do a bunch of cleanup to remove an element from the XUL
|
|
|
|
// document.
|
|
|
|
nsresult rv;
|
|
|
|
|
2000-01-22 22:00:35 +00:00
|
|
|
// 1. Remove any children from the document.
|
1999-09-17 04:29:53 +00:00
|
|
|
PRInt32 count;
|
|
|
|
nsCOMPtr<nsIXULContent> xulcontent = do_QueryInterface(aElement);
|
|
|
|
rv = xulcontent ? xulcontent->PeekChildCount(count) : aElement->ChildCount(count);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
while (--count >= 0) {
|
|
|
|
nsCOMPtr<nsIContent> child;
|
|
|
|
rv = aElement->ChildAt(count, *getter_AddRefs(child));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = RemoveSubtreeFromDocument(child);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
2000-01-22 22:00:35 +00:00
|
|
|
// 2. Remove the element from the resource-to-element map
|
1999-09-17 04:29:53 +00:00
|
|
|
rv = RemoveElementFromMap(aElement);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-01-22 22:00:35 +00:00
|
|
|
// 3. If the element is a 'command updater', then remove the
|
1999-09-17 04:29:53 +00:00
|
|
|
// element from the document's command dispatcher.
|
|
|
|
nsAutoString value;
|
|
|
|
rv = aElement->GetAttribute(kNameSpaceID_None, kCommandUpdaterAtom, value);
|
|
|
|
if ((rv == NS_CONTENT_ATTR_HAS_VALUE) && value.Equals("true")) {
|
|
|
|
nsCOMPtr<nsIDOMElement> domelement = do_QueryInterface(aElement);
|
|
|
|
NS_ASSERTION(domelement != nsnull, "not a DOM element");
|
|
|
|
if (! domelement)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
rv = mCommandDispatcher->RemoveCommandUpdater(domelement);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Attributes that are used with getElementById() and the
|
|
|
|
// resource-to-element map.
|
1999-10-29 01:21:15 +00:00
|
|
|
nsIAtom** nsXULDocument::kIdentityAttrs[] = { &kIdAtom, &kRefAtom, nsnull };
|
1999-08-30 02:45:54 +00:00
|
|
|
|
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::AddElementToMap(nsIContent* aElement)
|
1999-08-30 02:45:54 +00:00
|
|
|
{
|
1999-09-17 04:29:53 +00:00
|
|
|
// Look at the element's 'id' and 'ref' attributes, and if set,
|
|
|
|
// add pointers in the resource-to-element map to the element.
|
1999-08-30 02:45:54 +00:00
|
|
|
nsresult rv;
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
for (PRInt32 i = 0; kIdentityAttrs[i] != nsnull; ++i) {
|
|
|
|
nsAutoString value;
|
|
|
|
rv = aElement->GetAttribute(kNameSpaceID_None, *kIdentityAttrs[i], value);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get attribute");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
|
|
|
|
rv = mElementMap.Add(value, aElement);
|
1999-08-30 02:45:54 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::RemoveElementFromMap(nsIContent* aElement)
|
1999-08-30 02:45:54 +00:00
|
|
|
{
|
1999-09-17 04:29:53 +00:00
|
|
|
// Remove the element from the resource-to-element map.
|
1999-08-30 02:45:54 +00:00
|
|
|
nsresult rv;
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
for (PRInt32 i = 0; kIdentityAttrs[i] != nsnull; ++i) {
|
|
|
|
nsAutoString value;
|
|
|
|
rv = aElement->GetAttribute(kNameSpaceID_None, *kIdentityAttrs[i], value);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get attribute");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
|
|
|
|
rv = mElementMap.Remove(value, aElement);
|
1999-08-30 02:45:54 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PRIntn
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::RemoveElementsFromMapByContent(const nsString& aID,
|
1999-08-30 02:45:54 +00:00
|
|
|
nsIContent* aElement,
|
|
|
|
void* aClosure)
|
|
|
|
{
|
|
|
|
nsIContent* content = NS_REINTERPRET_CAST(nsIContent*, aClosure);
|
|
|
|
return (aElement == content) ? HT_ENUMERATE_REMOVE : HT_ENUMERATE_NEXT;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-02-16 19:30:04 +00:00
|
|
|
// nsIDOMNode interface
|
1999-10-29 01:21:15 +00:00
|
|
|
//
|
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetNodeName(nsString& aNodeName)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
aNodeName.SetString("#document");
|
|
|
|
return NS_OK;
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetNodeValue(nsString& aNodeValue)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
aNodeValue.Truncate();
|
|
|
|
return NS_OK;
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::SetNodeValue(const nsString& aNodeValue)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
return NS_OK;
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetNodeType(PRUint16* aNodeType)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
*aNodeType = nsIDOMNode::DOCUMENT_NODE;
|
|
|
|
return NS_OK;
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetParentNode(nsIDOMNode** aParentNode)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-02-17 11:09:57 +00:00
|
|
|
*aParentNode = nsnull;
|
|
|
|
return NS_OK;
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetChildNodes(nsIDOMNodeList** aChildNodes)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
NS_PRECONDITION(aChildNodes != nsnull, "null ptr");
|
|
|
|
if (! aChildNodes)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
if (mRootContent) {
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
*aChildNodes = nsnull;
|
|
|
|
|
|
|
|
nsRDFDOMNodeList* children;
|
|
|
|
rv = nsRDFDOMNodeList::Create(&children);
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-05-04 23:32:25 +00:00
|
|
|
nsIDOMNode* domNode = nsnull;
|
2000-01-11 20:49:15 +00:00
|
|
|
rv = mRootContent->QueryInterface(NS_GET_IID(nsIDOMNode), (void**)&domNode);
|
1999-04-16 08:38:17 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "root content is not a DOM node");
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
rv = children->AppendNode(domNode);
|
|
|
|
NS_RELEASE(domNode);
|
|
|
|
|
|
|
|
*aChildNodes = children;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we get here, something bad happened.
|
|
|
|
NS_RELEASE(children);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aChildNodes = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::HasChildNodes(PRBool* aHasChildNodes)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
NS_PRECONDITION(aHasChildNodes != nsnull, "null ptr");
|
|
|
|
if (! aHasChildNodes)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
if (mRootContent) {
|
|
|
|
*aHasChildNodes = PR_TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aHasChildNodes = PR_FALSE;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetFirstChild(nsIDOMNode** aFirstChild)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
NS_PRECONDITION(aFirstChild != nsnull, "null ptr");
|
|
|
|
if (! aFirstChild)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
if (mRootContent) {
|
2000-01-11 20:49:15 +00:00
|
|
|
return mRootContent->QueryInterface(NS_GET_IID(nsIDOMNode), (void**) aFirstChild);
|
1999-04-16 08:38:17 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aFirstChild = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetLastChild(nsIDOMNode** aLastChild)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
NS_PRECONDITION(aLastChild != nsnull, "null ptr");
|
|
|
|
if (! aLastChild)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
if (mRootContent) {
|
2000-01-11 20:49:15 +00:00
|
|
|
return mRootContent->QueryInterface(NS_GET_IID(nsIDOMNode), (void**) aLastChild);
|
1999-04-16 08:38:17 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aLastChild = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetPreviousSibling(nsIDOMNode** aPreviousSibling)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
NS_PRECONDITION(aPreviousSibling != nsnull, "null ptr");
|
|
|
|
if (! aPreviousSibling)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
*aPreviousSibling = nsnull;
|
|
|
|
return NS_OK;
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetNextSibling(nsIDOMNode** aNextSibling)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
NS_PRECONDITION(aNextSibling != nsnull, "null ptr");
|
|
|
|
if (! aNextSibling)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
*aNextSibling = nsnull;
|
|
|
|
return NS_OK;
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
NS_PRECONDITION(aAttributes != nsnull, "null ptr");
|
|
|
|
if (! aAttributes)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
*aAttributes = nsnull;
|
|
|
|
return NS_OK;
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
NS_PRECONDITION(aOwnerDocument != nsnull, "null ptr");
|
|
|
|
if (! aOwnerDocument)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
*aOwnerDocument = nsnull;
|
|
|
|
return NS_OK;
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me!");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-04-16 08:38:17 +00:00
|
|
|
// We don't allow cloning of a document
|
|
|
|
*aReturn = nsnull;
|
|
|
|
return NS_OK;
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-02-16 19:30:04 +00:00
|
|
|
// nsIJSScriptObject interface
|
1999-10-29 01:21:15 +00:00
|
|
|
//
|
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
PRBool
|
1999-12-18 20:29:29 +00:00
|
|
|
nsXULDocument::AddProperty(JSContext *aContext, JSObject *aObj, jsval aID, jsval *aVp)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me");
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PRBool
|
1999-12-18 20:29:29 +00:00
|
|
|
nsXULDocument::DeleteProperty(JSContext *aContext, JSObject *aObj, jsval aID, jsval *aVp)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me");
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PRBool
|
1999-12-18 20:29:29 +00:00
|
|
|
nsXULDocument::GetProperty(JSContext *aContext, JSObject *aObj, jsval aID, jsval *aVp)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-11-18 02:25:33 +00:00
|
|
|
if (JSVAL_IS_STRING(aID)) {
|
|
|
|
JSString *jsString = JS_ValueToString(aContext, aID);
|
|
|
|
if (!jsString)
|
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
if (PL_strcmp("location", JS_GetStringBytes(jsString)) == 0) {
|
1999-12-03 09:24:22 +00:00
|
|
|
nsCOMPtr<nsIJSScriptObject> window = do_QueryInterface(mScriptGlobalObject);
|
|
|
|
if (nsnull != window) {
|
1999-12-18 20:29:29 +00:00
|
|
|
return window->GetProperty(aContext, aObj, aID, aVp);
|
1999-12-03 09:24:22 +00:00
|
|
|
}
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
return PR_TRUE;
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PRBool
|
1999-12-18 20:29:29 +00:00
|
|
|
nsXULDocument::SetProperty(JSContext *aContext, JSObject *aObj, jsval aID, jsval *aVp)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-07-15 01:22:59 +00:00
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (JSVAL_IS_STRING(aID)) {
|
|
|
|
char* s = JS_GetStringBytes(JS_ValueToString(aContext, aID));
|
|
|
|
if (PL_strcmp("title", s) == 0) {
|
1999-11-18 02:25:33 +00:00
|
|
|
JSString* jsString = JS_ValueToString(aContext, *aVp);
|
|
|
|
if (!jsString)
|
|
|
|
return PR_FALSE;
|
|
|
|
nsAutoString title(JS_GetStringChars(jsString));
|
1999-07-15 01:22:59 +00:00
|
|
|
for (PRInt32 i = mPresShells.Count() - 1; i >= 0; --i) {
|
|
|
|
nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[i]);
|
|
|
|
nsCOMPtr<nsIPresContext> context;
|
|
|
|
rv = shell->GetPresContext(getter_AddRefs(context));
|
|
|
|
if (NS_FAILED(rv)) return PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> container;
|
|
|
|
rv = context->GetContainer(getter_AddRefs(container));
|
|
|
|
if (NS_FAILED(rv)) return PR_FALSE;
|
|
|
|
|
|
|
|
if (! container) continue;
|
|
|
|
|
1999-11-29 06:04:15 +00:00
|
|
|
nsCOMPtr<nsIBaseWindow> webShellWin = do_QueryInterface(container);
|
|
|
|
if(!webShellWin) continue;
|
1999-07-15 01:22:59 +00:00
|
|
|
|
1999-12-04 07:45:57 +00:00
|
|
|
rv = webShellWin->SetTitle(title.GetUnicode());
|
|
|
|
if (NS_FAILED(rv)) return PR_FALSE;
|
1999-07-15 01:22:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (PL_strcmp("location", s) == 0) {
|
|
|
|
NS_NOTYETIMPLEMENTED("write me");
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
1999-02-16 19:30:04 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PRBool
|
1999-12-18 20:29:29 +00:00
|
|
|
nsXULDocument::EnumerateProperty(JSContext *aContext, JSObject *aObj)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me");
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PRBool
|
1999-12-18 20:29:29 +00:00
|
|
|
nsXULDocument::Resolve(JSContext *aContext, JSObject *aObj, jsval aID)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PRBool
|
1999-12-18 20:29:29 +00:00
|
|
|
nsXULDocument::Convert(JSContext *aContext, JSObject *aObj, jsval aID)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me");
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
1999-12-18 20:29:29 +00:00
|
|
|
nsXULDocument::Finalize(JSContext *aContext, JSObject *aObj)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_NOTYETIMPLEMENTED("write me");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-02-16 19:30:04 +00:00
|
|
|
// nsIScriptObjectOwner interface
|
1999-10-29 01:21:15 +00:00
|
|
|
//
|
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
1999-11-29 20:53:40 +00:00
|
|
|
if (! mScriptObject) {
|
|
|
|
// ...we need to instantiate our script object for the first
|
|
|
|
// time.
|
1999-02-16 19:30:04 +00:00
|
|
|
|
1999-11-29 20:53:40 +00:00
|
|
|
// Make sure that we've got our script context owner; this
|
|
|
|
// assertion will fire if we've tried to get the script object
|
|
|
|
// before our scope has been set up.
|
1999-12-04 07:45:57 +00:00
|
|
|
NS_ASSERTION(mScriptGlobalObject != nsnull, "no script object");
|
|
|
|
if (! mScriptGlobalObject)
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
1999-11-29 20:53:40 +00:00
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// Use the global object from our script context owner (the
|
|
|
|
// window) as the parent of our own script object. (Using the
|
|
|
|
// global object from aContext would make our script object
|
|
|
|
// dynamically scoped in the first context that ever tried to
|
|
|
|
// use us!)
|
|
|
|
|
|
|
|
rv = NS_NewScriptXULDocument(aContext,
|
|
|
|
NS_STATIC_CAST(nsISupports*, NS_STATIC_CAST(nsIDOMXULDocument*, this)),
|
1999-12-03 09:24:22 +00:00
|
|
|
mScriptGlobalObject, &mScriptObject);
|
1999-11-29 20:53:40 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
1999-11-29 20:53:40 +00:00
|
|
|
*aScriptObject = mScriptObject;
|
|
|
|
return NS_OK;
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::SetScriptObject(void *aScriptObject)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
mScriptObject = aScriptObject;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-02-16 19:30:04 +00:00
|
|
|
// nsIHTMLContentContainer interface
|
1999-10-29 01:21:15 +00:00
|
|
|
//
|
1999-02-16 19:30:04 +00:00
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetAttributeStyleSheet(nsIHTMLStyleSheet** aResult)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
*aResult = mAttrStyleSheet;
|
1999-05-28 11:30:59 +00:00
|
|
|
if (! mAttrStyleSheet) {
|
1999-02-16 19:30:04 +00:00
|
|
|
return NS_ERROR_NOT_AVAILABLE; // probably not the right error...
|
|
|
|
}
|
|
|
|
else {
|
1999-05-28 11:30:59 +00:00
|
|
|
NS_ADDREF(*aResult);
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetInlineStyleSheet(nsIHTMLCSSStyleSheet** aResult)
|
1999-02-16 19:30:04 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
*aResult = mInlineStyleSheet;
|
1999-04-30 09:04:36 +00:00
|
|
|
if (!mInlineStyleSheet) {
|
1999-02-16 19:30:04 +00:00
|
|
|
return NS_ERROR_NOT_AVAILABLE; // probably not the right error...
|
|
|
|
}
|
|
|
|
else {
|
1999-04-30 09:04:36 +00:00
|
|
|
NS_ADDREF(*aResult);
|
1999-02-16 19:30:04 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-02-16 19:30:04 +00:00
|
|
|
// Implementation methods
|
1999-10-29 01:21:15 +00:00
|
|
|
//
|
1999-02-16 19:30:04 +00:00
|
|
|
|
|
|
|
nsIContent*
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::FindContent(const nsIContent* aStartNode,
|
1999-11-18 02:25:33 +00:00
|
|
|
const nsIContent* aTest1,
|
1999-02-16 19:30:04 +00:00
|
|
|
const nsIContent* aTest2) const
|
|
|
|
{
|
|
|
|
PRInt32 count;
|
|
|
|
aStartNode->ChildCount(count);
|
|
|
|
|
1999-05-28 11:30:59 +00:00
|
|
|
PRInt32 i;
|
|
|
|
for(i = 0; i < count; i++) {
|
1999-02-16 19:30:04 +00:00
|
|
|
nsIContent* child;
|
1999-05-28 11:30:59 +00:00
|
|
|
aStartNode->ChildAt(i, child);
|
1999-02-16 19:30:04 +00:00
|
|
|
nsIContent* content = FindContent(child,aTest1,aTest2);
|
|
|
|
if (content != nsnull) {
|
|
|
|
NS_IF_RELEASE(child);
|
|
|
|
return content;
|
|
|
|
}
|
|
|
|
if (child == aTest1 || child == aTest2) {
|
|
|
|
NS_IF_RELEASE(content);
|
|
|
|
return child;
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(child);
|
|
|
|
NS_IF_RELEASE(content);
|
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-02-01 22:34:51 +00:00
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::Init()
|
1999-02-01 22:34:51 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
rv = NS_NewHeapArena(getter_AddRefs(mArena), nsnull);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-02-01 22:34:51 +00:00
|
|
|
|
1999-02-04 10:50:50 +00:00
|
|
|
// Create a namespace manager so we can manage tags
|
1999-10-05 21:13:55 +00:00
|
|
|
rv = nsComponentManager::CreateInstance(kNameSpaceManagerCID,
|
|
|
|
nsnull,
|
|
|
|
NS_GET_IID(nsINameSpaceManager),
|
|
|
|
getter_AddRefs(mNameSpaceManager));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-02-01 22:34:51 +00:00
|
|
|
|
1999-12-15 23:18:34 +00:00
|
|
|
if (!mIsKeyBindingDoc) {
|
|
|
|
// Create our focus tracker and hook it up.
|
|
|
|
rv = nsXULCommandDispatcher::Create(getter_AddRefs(mCommandDispatcher));
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a focus tracker");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-05-28 22:55:10 +00:00
|
|
|
|
1999-12-15 23:18:34 +00:00
|
|
|
nsCOMPtr<nsIDOMEventListener> CommandDispatcher =
|
|
|
|
do_QueryInterface(mCommandDispatcher);
|
1999-10-05 21:13:55 +00:00
|
|
|
|
1999-12-15 23:18:34 +00:00
|
|
|
if (CommandDispatcher) {
|
|
|
|
// Take the focus tracker and add it as an event listener for focus and blur events.
|
|
|
|
AddEventListener("focus", CommandDispatcher, PR_TRUE);
|
|
|
|
AddEventListener("blur", CommandDispatcher, PR_TRUE);
|
|
|
|
}
|
1999-05-28 22:55:10 +00:00
|
|
|
}
|
1999-10-05 21:13:55 +00:00
|
|
|
// Get the local store. Yeah, I know. I wish GetService() used a
|
|
|
|
// 'void**', too.
|
|
|
|
nsIRDFDataSource* localstore;
|
|
|
|
rv = nsServiceManager::GetService(kLocalStoreCID,
|
|
|
|
NS_GET_IID(nsIRDFDataSource),
|
|
|
|
(nsISupports**) &localstore);
|
|
|
|
|
|
|
|
// this _could_ fail; e.g., if we've tried to grab the local store
|
|
|
|
// before profiles have initialized. If so, no big deal; nothing
|
|
|
|
// will persist.
|
|
|
|
|
1999-10-05 22:22:40 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
mLocalStore = localstore;
|
|
|
|
NS_IF_RELEASE(localstore);
|
|
|
|
}
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
// Create a new nsISupportsArray for dealing with overlay references
|
|
|
|
rv = NS_NewISupportsArray(getter_AddRefs(mUnloadedOverlays));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// Create a new nsISupportsArray that will hold owning references
|
|
|
|
// to each of the prototype documents used to construct this
|
|
|
|
// document. That will ensure that prototype elements will remain
|
|
|
|
// alive.
|
|
|
|
rv = NS_NewISupportsArray(getter_AddRefs(mPrototypes));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
#if 0
|
|
|
|
// construct a selection object
|
|
|
|
if (NS_FAILED(rv = nsComponentManager::CreateInstance(kRangeListCID,
|
|
|
|
nsnull,
|
|
|
|
kIDOMSelectionIID,
|
|
|
|
(void**) &mSelection))) {
|
|
|
|
NS_ERROR("unable to create DOM selection");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (gRefCnt++ == 0) {
|
1999-10-29 01:21:15 +00:00
|
|
|
kAttributeAtom = NS_NewAtom("attribute");
|
|
|
|
kCommandUpdaterAtom = NS_NewAtom("commandupdater");
|
|
|
|
kDataSourcesAtom = NS_NewAtom("datasources");
|
|
|
|
kElementAtom = NS_NewAtom("element");
|
|
|
|
kIdAtom = NS_NewAtom("id");
|
|
|
|
kKeysetAtom = NS_NewAtom("keyset");
|
|
|
|
kObservesAtom = NS_NewAtom("observes");
|
|
|
|
kOpenAtom = NS_NewAtom("open");
|
|
|
|
kOverlayAtom = NS_NewAtom("overlay");
|
|
|
|
kPersistAtom = NS_NewAtom("persist");
|
|
|
|
kPositionAtom = NS_NewAtom("position");
|
|
|
|
kRefAtom = NS_NewAtom("ref");
|
|
|
|
kRuleAtom = NS_NewAtom("rule");
|
|
|
|
kTemplateAtom = NS_NewAtom("template");
|
1999-10-05 21:13:55 +00:00
|
|
|
|
2000-01-12 01:47:23 +00:00
|
|
|
kCoalesceAtom = NS_NewAtom("coalesceduplicatearcs");
|
|
|
|
kAllowNegativesAtom = NS_NewAtom("allownegativeassertions");
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
// Keep the RDF service cached in a member variable to make using
|
|
|
|
// it a bit less painful
|
|
|
|
rv = nsServiceManager::GetService(kRDFServiceCID,
|
|
|
|
NS_GET_IID(nsIRDFService),
|
|
|
|
(nsISupports**) &gRDFService);
|
|
|
|
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF Service");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
gRDFService->GetResource(NC_NAMESPACE_URI "persist", &kNC_persist);
|
|
|
|
gRDFService->GetResource(NC_NAMESPACE_URI "attribute", &kNC_attribute);
|
|
|
|
gRDFService->GetResource(NC_NAMESPACE_URI "value", &kNC_value);
|
|
|
|
|
|
|
|
rv = nsComponentManager::CreateInstance(kHTMLElementFactoryCID,
|
|
|
|
nsnull,
|
2000-01-19 03:11:39 +00:00
|
|
|
NS_GET_IID(nsIElementFactory),
|
1999-10-05 21:13:55 +00:00
|
|
|
(void**) &gHTMLElementFactory);
|
|
|
|
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get HTML element factory");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
rv = nsComponentManager::CreateInstance(kXMLElementFactoryCID,
|
|
|
|
nsnull,
|
2000-01-19 03:11:39 +00:00
|
|
|
NS_GET_IID(nsIElementFactory),
|
1999-10-29 01:21:15 +00:00
|
|
|
(void**) &gXMLElementFactory);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get XML element factory");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
rv = nsServiceManager::GetService(kNameSpaceManagerCID,
|
|
|
|
NS_GET_IID(nsINameSpaceManager),
|
|
|
|
(nsISupports**) &gNameSpaceManager);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get namespace manager");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
#define XUL_NAMESPACE_URI "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
|
|
static const char kXULNameSpaceURI[] = XUL_NAMESPACE_URI;
|
|
|
|
gNameSpaceManager->RegisterNameSpace(kXULNameSpaceURI, kNameSpaceID_XUL);
|
|
|
|
|
|
|
|
|
|
|
|
rv = nsServiceManager::GetService(kXULContentUtilsCID,
|
|
|
|
NS_GET_IID(nsIXULContentUtils),
|
|
|
|
(nsISupports**) &gXULUtils);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
rv = nsServiceManager::GetService(kXULPrototypeCacheCID,
|
|
|
|
NS_GET_IID(nsIXULPrototypeCache),
|
1999-11-02 01:14:07 +00:00
|
|
|
(nsISupports**) &gXULCache);
|
1999-10-29 01:21:15 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-05 21:13:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
if (! gXULLog)
|
|
|
|
gXULLog = PR_NewLogModule("nsXULDocument");
|
|
|
|
#endif
|
|
|
|
|
1999-02-01 22:34:51 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-01-14 10:55:08 +00:00
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::StartLayout(void)
|
1999-01-14 10:55:08 +00:00
|
|
|
{
|
1999-10-29 01:21:15 +00:00
|
|
|
if (! mRootContent) {
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
nsXPIDLCString urlspec;
|
|
|
|
mDocumentURL->GetSpec(getter_Copies(urlspec));
|
|
|
|
|
|
|
|
PR_LOG(gXULLog, PR_LOG_ALWAYS,
|
|
|
|
("xul: unable to layout '%s'; no root content", (const char*) urlspec));
|
|
|
|
#endif
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-01-14 10:55:08 +00:00
|
|
|
PRInt32 count = GetNumberOfShells();
|
|
|
|
for (PRInt32 i = 0; i < count; i++) {
|
1999-07-04 04:09:54 +00:00
|
|
|
nsIPresShell* shell = GetShellAt(i);
|
|
|
|
if (nsnull == shell)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Resize-reflow this time
|
|
|
|
nsCOMPtr<nsIPresContext> cx;
|
|
|
|
shell->GetPresContext(getter_AddRefs(cx));
|
1999-12-06 23:03:53 +00:00
|
|
|
NS_ASSERTION(cx != nsnull, "no pres context");
|
|
|
|
if (! cx)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> container;
|
|
|
|
cx->GetContainer(getter_AddRefs(container));
|
|
|
|
NS_ASSERTION(container != nsnull, "pres context has no container");
|
|
|
|
if (! container)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
1999-07-04 04:09:54 +00:00
|
|
|
|
1999-07-07 22:34:10 +00:00
|
|
|
nsCOMPtr<nsIWebShell> webShell;
|
1999-12-06 23:03:53 +00:00
|
|
|
webShell = do_QueryInterface(container);
|
|
|
|
NS_ASSERTION(webShell != nsnull, "container is not a webshell");
|
|
|
|
if (! webShell)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
1999-07-07 22:34:10 +00:00
|
|
|
|
1999-12-06 23:03:53 +00:00
|
|
|
webShell->SetScrolling(NS_STYLE_OVERFLOW_HIDDEN);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIWebShellContainer> webShellContainer;
|
|
|
|
webShell->GetContainer(*getter_AddRefs(webShellContainer));
|
|
|
|
NS_ASSERTION(webShellContainer != nsnull, "webshell has no container");
|
|
|
|
if (! webShellContainer)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIBrowserWindow> browser;
|
|
|
|
browser = do_QueryInterface(webShellContainer);
|
1999-11-18 02:25:33 +00:00
|
|
|
|
|
|
|
nsRect r;
|
1999-07-04 04:09:54 +00:00
|
|
|
cx->GetVisibleArea(r);
|
2000-01-15 02:01:05 +00:00
|
|
|
|
2000-01-15 05:53:41 +00:00
|
|
|
// Trigger a refresh before the call to InitialReflow(), because
|
1999-07-21 04:47:15 +00:00
|
|
|
// the view manager's UpdateView() function is dropping dirty rects if
|
|
|
|
// refresh is disabled rather than accumulating them until refresh is
|
|
|
|
// enabled and then triggering a repaint...
|
1999-07-04 04:09:54 +00:00
|
|
|
nsCOMPtr<nsIViewManager> vm;
|
|
|
|
shell->GetViewManager(getter_AddRefs(vm));
|
|
|
|
if (vm) {
|
1999-07-07 22:34:10 +00:00
|
|
|
nsCOMPtr<nsIContentViewer> contentViewer;
|
|
|
|
nsresult rv = webShell->GetContentViewer(getter_AddRefs(contentViewer));
|
|
|
|
if (NS_SUCCEEDED(rv) && (contentViewer != nsnull)) {
|
|
|
|
PRBool enabled;
|
|
|
|
contentViewer->GetEnableRendering(&enabled);
|
|
|
|
if (enabled) {
|
|
|
|
vm->EnableRefresh();
|
|
|
|
}
|
|
|
|
}
|
1999-07-04 04:09:54 +00:00
|
|
|
}
|
2000-01-15 05:53:41 +00:00
|
|
|
|
|
|
|
shell->InitialReflow(r.width, r.height);
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-07-04 04:09:54 +00:00
|
|
|
// Start observing the document _after_ we do the initial
|
|
|
|
// reflow. Otherwise, we'll get into an trouble trying to
|
|
|
|
// create kids before the root frame is established.
|
|
|
|
shell->BeginObservingDocument();
|
|
|
|
|
|
|
|
NS_RELEASE(shell);
|
1999-01-14 10:55:08 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-01-12 19:41:06 +00:00
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetElementsByTagName(nsIDOMNode* aNode,
|
1999-02-16 19:30:04 +00:00
|
|
|
const nsString& aTagName,
|
|
|
|
nsRDFDOMNodeList* aElements)
|
1999-01-12 19:41:06 +00:00
|
|
|
{
|
1999-02-16 19:30:04 +00:00
|
|
|
nsresult rv;
|
1998-12-24 05:07:14 +00:00
|
|
|
|
1999-02-25 02:58:11 +00:00
|
|
|
nsCOMPtr<nsIDOMElement> element;
|
|
|
|
element = do_QueryInterface(aNode);
|
|
|
|
if (!element)
|
|
|
|
return NS_OK;
|
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
if (aTagName.Equals("*")) {
|
|
|
|
if (NS_FAILED(rv = aElements->AppendNode(aNode))) {
|
|
|
|
NS_ERROR("unable to append element to node list");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nsAutoString name;
|
|
|
|
if (NS_FAILED(rv = aNode->GetNodeName(name))) {
|
|
|
|
NS_ERROR("unable to get node name");
|
|
|
|
return rv;
|
|
|
|
}
|
1998-12-24 05:07:14 +00:00
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
if (aTagName.Equals(name)) {
|
|
|
|
if (NS_FAILED(rv = aElements->AppendNode(aNode))) {
|
|
|
|
NS_ERROR("unable to append element to node list");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-02-01 22:34:51 +00:00
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
nsCOMPtr<nsIDOMNodeList> children;
|
|
|
|
if (NS_FAILED(rv = aNode->GetChildNodes( getter_AddRefs(children) ))) {
|
|
|
|
NS_ERROR("unable to get node's children");
|
1999-02-01 22:34:51 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
// no kids: terminate the recursion
|
|
|
|
if (! children)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
PRUint32 length;
|
|
|
|
if (NS_FAILED(children->GetLength(&length))) {
|
|
|
|
NS_ERROR("unable to get node list's length");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (PRUint32 i = 0; i < length; ++i) {
|
|
|
|
nsCOMPtr<nsIDOMNode> child;
|
|
|
|
if (NS_FAILED(rv = children->Item(i, getter_AddRefs(child) ))) {
|
|
|
|
NS_ERROR("unable to get child from list");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_FAILED(rv = GetElementsByTagName(child, aTagName, aElements))) {
|
|
|
|
NS_ERROR("unable to recursively get elements by tag name");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-01-12 19:41:06 +00:00
|
|
|
return NS_OK;
|
1998-12-24 05:07:14 +00:00
|
|
|
}
|
|
|
|
|
1999-02-23 02:40:51 +00:00
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetElementsByAttribute(nsIDOMNode* aNode,
|
1999-03-09 08:10:50 +00:00
|
|
|
const nsString& aAttribute,
|
|
|
|
const nsString& aValue,
|
|
|
|
nsRDFDOMNodeList* aElements)
|
1999-02-23 02:40:51 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-02-25 02:58:11 +00:00
|
|
|
nsCOMPtr<nsIDOMElement> element;
|
|
|
|
element = do_QueryInterface(aNode);
|
|
|
|
if (!element)
|
1999-03-09 08:10:50 +00:00
|
|
|
return NS_OK;
|
1999-02-23 02:40:51 +00:00
|
|
|
|
1999-03-09 08:10:50 +00:00
|
|
|
nsAutoString attrValue;
|
|
|
|
if (NS_FAILED(rv = element->GetAttribute(aAttribute, attrValue))) {
|
|
|
|
NS_ERROR("unable to get attribute value");
|
|
|
|
return rv;
|
|
|
|
}
|
1999-02-23 02:40:51 +00:00
|
|
|
|
1999-03-09 08:10:50 +00:00
|
|
|
if ((attrValue == aValue) || (attrValue.Length() > 0 && aValue == "*")) {
|
1999-02-23 02:40:51 +00:00
|
|
|
if (NS_FAILED(rv = aElements->AppendNode(aNode))) {
|
|
|
|
NS_ERROR("unable to append element to node list");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-02-23 02:40:51 +00:00
|
|
|
nsCOMPtr<nsIDOMNodeList> children;
|
|
|
|
if (NS_FAILED(rv = aNode->GetChildNodes( getter_AddRefs(children) ))) {
|
|
|
|
NS_ERROR("unable to get node's children");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// no kids: terminate the recursion
|
|
|
|
if (! children)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
PRUint32 length;
|
|
|
|
if (NS_FAILED(children->GetLength(&length))) {
|
|
|
|
NS_ERROR("unable to get node list's length");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (PRUint32 i = 0; i < length; ++i) {
|
|
|
|
nsCOMPtr<nsIDOMNode> child;
|
|
|
|
if (NS_FAILED(rv = children->Item(i, getter_AddRefs(child) ))) {
|
|
|
|
NS_ERROR("unable to get child from list");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_FAILED(rv = GetElementsByAttribute(child, aAttribute, aValue, aElements))) {
|
|
|
|
NS_ERROR("unable to recursively get elements by attribute");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-16 19:30:04 +00:00
|
|
|
|
|
|
|
|
1999-04-16 08:38:17 +00:00
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ParseTagString(const nsString& aTagName, nsIAtom*& aName, PRInt32& aNameSpaceID)
|
1999-04-16 08:38:17 +00:00
|
|
|
{
|
|
|
|
// Parse the tag into a name and a namespace ID. This is slightly
|
|
|
|
// different than nsIContent::ParseAttributeString() because we
|
|
|
|
// take the default namespace into account (rather than just
|
|
|
|
// assigning "no namespace") in the case that there is no
|
|
|
|
// namespace prefix present.
|
|
|
|
|
1999-07-18 00:01:21 +00:00
|
|
|
static char kNameSpaceSeparator = ':';
|
1999-04-16 08:38:17 +00:00
|
|
|
|
|
|
|
// XXX this is a gross hack, but it'll carry us for now. We parse
|
|
|
|
// the tag name using the root content, which presumably has all
|
|
|
|
// the namespace info we need.
|
|
|
|
NS_PRECONDITION(mRootContent != nsnull, "not initialized");
|
|
|
|
if (! mRootContent)
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIXMLContent> xml( do_QueryInterface(mRootContent) );
|
|
|
|
if (! xml) return NS_ERROR_UNEXPECTED;
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-04-16 08:38:17 +00:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsINameSpace> ns;
|
|
|
|
rv = xml->GetContainingNameSpace(*getter_AddRefs(ns));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
NS_ASSERTION(ns != nsnull, "expected xml namespace info to be available");
|
|
|
|
if (! ns)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
nsAutoString prefix;
|
|
|
|
nsAutoString name(aTagName);
|
1999-07-18 00:01:21 +00:00
|
|
|
PRInt32 nsoffset = name.FindChar(kNameSpaceSeparator);
|
1999-04-16 08:38:17 +00:00
|
|
|
if (-1 != nsoffset) {
|
|
|
|
name.Left(prefix, nsoffset);
|
|
|
|
name.Cut(0, nsoffset+1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Figure out the namespace ID
|
|
|
|
nsCOMPtr<nsIAtom> nameSpaceAtom;
|
|
|
|
if (0 < prefix.Length())
|
|
|
|
nameSpaceAtom = getter_AddRefs(NS_NewAtom(prefix));
|
|
|
|
|
|
|
|
rv = ns->FindNameSpaceID(nameSpaceAtom, aNameSpaceID);
|
1999-07-07 06:52:21 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-04-16 08:38:17 +00:00
|
|
|
|
|
|
|
aName = NS_NewAtom(name);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-05-04 23:32:25 +00:00
|
|
|
// nsIDOMEventCapturer and nsIDOMEventReceiver Interface Implementations
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID)
|
1999-05-04 23:32:25 +00:00
|
|
|
{
|
|
|
|
nsIEventListenerManager *manager;
|
|
|
|
|
|
|
|
if (NS_OK == GetListenerManager(&manager)) {
|
|
|
|
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
|
|
|
NS_RELEASE(manager);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID)
|
1999-05-04 23:32:25 +00:00
|
|
|
{
|
1999-05-28 11:30:59 +00:00
|
|
|
if (mListenerManager) {
|
1999-05-04 23:32:25 +00:00
|
|
|
mListenerManager->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-11-18 02:25:33 +00:00
|
|
|
nsXULDocument::AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
|
1999-07-19 19:54:34 +00:00
|
|
|
PRBool aUseCapture)
|
1999-05-04 23:32:25 +00:00
|
|
|
{
|
|
|
|
nsIEventListenerManager *manager;
|
|
|
|
|
|
|
|
if (NS_OK == GetListenerManager(&manager)) {
|
1999-07-19 19:54:34 +00:00
|
|
|
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
1999-05-04 23:32:25 +00:00
|
|
|
|
|
|
|
manager->AddEventListenerByType(aListener, aType, flags);
|
|
|
|
NS_RELEASE(manager);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-11-18 02:25:33 +00:00
|
|
|
nsXULDocument::RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
|
1999-07-19 19:54:34 +00:00
|
|
|
PRBool aUseCapture)
|
1999-05-04 23:32:25 +00:00
|
|
|
{
|
1999-05-28 11:30:59 +00:00
|
|
|
if (mListenerManager) {
|
1999-07-19 19:54:34 +00:00
|
|
|
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
1999-05-04 23:32:25 +00:00
|
|
|
|
|
|
|
mListenerManager->RemoveEventListenerByType(aListener, aType, flags);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetListenerManager(nsIEventListenerManager** aResult)
|
1999-05-04 23:32:25 +00:00
|
|
|
{
|
1999-05-28 11:30:59 +00:00
|
|
|
if (! mListenerManager) {
|
|
|
|
nsresult rv;
|
|
|
|
rv = nsComponentManager::CreateInstance(kEventListenerManagerCID,
|
|
|
|
nsnull,
|
1999-10-05 21:13:55 +00:00
|
|
|
NS_GET_IID(nsIEventListenerManager),
|
1999-05-28 11:30:59 +00:00
|
|
|
getter_AddRefs(mListenerManager));
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-05-04 23:32:25 +00:00
|
|
|
}
|
1999-05-28 11:30:59 +00:00
|
|
|
*aResult = mListenerManager;
|
|
|
|
NS_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
1999-05-04 23:32:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::GetNewListenerManager(nsIEventListenerManager **aResult)
|
1999-05-04 23:32:25 +00:00
|
|
|
{
|
|
|
|
return nsComponentManager::CreateInstance(kEventListenerManagerCID,
|
|
|
|
nsnull,
|
1999-10-05 21:13:55 +00:00
|
|
|
NS_GET_IID(nsIEventListenerManager),
|
1999-05-04 23:32:25 +00:00
|
|
|
(void**) aResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CaptureEvent(const nsString& aType)
|
1999-05-04 23:32:25 +00:00
|
|
|
{
|
|
|
|
nsIEventListenerManager *mManager;
|
|
|
|
|
|
|
|
if (NS_OK == GetListenerManager(&mManager)) {
|
|
|
|
//mManager->CaptureEvent(aListener);
|
|
|
|
NS_RELEASE(mManager);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ReleaseEvent(const nsString& aType)
|
1999-05-04 23:32:25 +00:00
|
|
|
{
|
1999-05-28 11:30:59 +00:00
|
|
|
if (mListenerManager) {
|
1999-05-04 23:32:25 +00:00
|
|
|
//mListenerManager->ReleaseEvent(aListener);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
1999-05-19 04:28:40 +00:00
|
|
|
|
1999-08-30 02:45:54 +00:00
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::OpenWidgetItem(nsIContent* aElement)
|
1999-08-30 02:45:54 +00:00
|
|
|
{
|
1999-08-31 06:40:41 +00:00
|
|
|
NS_PRECONDITION(aElement != nsnull, "null ptr");
|
|
|
|
if (! aElement)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
if (! mBuilders)
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-08-30 02:45:54 +00:00
|
|
|
#ifdef PR_LOGGING
|
|
|
|
if (PR_LOG_TEST(gXULLog, PR_LOG_DEBUG)) {
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
rv = aElement->GetTag(*getter_AddRefs(tag));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsAutoString tagStr;
|
|
|
|
tag->ToString(tagStr);
|
|
|
|
|
|
|
|
PR_LOG(gXULLog, PR_LOG_DEBUG,
|
|
|
|
("xuldoc open-widget-item %s",
|
|
|
|
(const char*) nsCAutoString(tagStr)));
|
|
|
|
}
|
|
|
|
#endif
|
1999-08-31 06:40:41 +00:00
|
|
|
|
|
|
|
PRUint32 cnt = 0;
|
|
|
|
rv = mBuilders->Count(&cnt);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
|
|
|
|
for (PRUint32 i = 0; i < cnt; ++i) {
|
|
|
|
// XXX we should QueryInterface() here
|
|
|
|
nsIRDFContentModelBuilder* builder
|
|
|
|
= (nsIRDFContentModelBuilder*) mBuilders->ElementAt(i);
|
|
|
|
|
|
|
|
NS_ASSERTION(builder != nsnull, "null ptr");
|
|
|
|
if (! builder)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
rv = builder->OpenContainer(aElement);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "error opening container");
|
|
|
|
// XXX ignore error code?
|
|
|
|
|
|
|
|
NS_RELEASE(builder);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
1999-08-30 02:45:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CloseWidgetItem(nsIContent* aElement)
|
1999-08-30 02:45:54 +00:00
|
|
|
{
|
1999-08-31 06:40:41 +00:00
|
|
|
NS_PRECONDITION(aElement != nsnull, "null ptr");
|
|
|
|
if (! aElement)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
if (! mBuilders)
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
|
|
|
1999-08-30 02:45:54 +00:00
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
if (PR_LOG_TEST(gXULLog, PR_LOG_DEBUG)) {
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
rv = aElement->GetTag(*getter_AddRefs(tag));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsAutoString tagStr;
|
|
|
|
tag->ToString(tagStr);
|
|
|
|
|
|
|
|
PR_LOG(gXULLog, PR_LOG_DEBUG,
|
|
|
|
("xuldoc close-widget-item %s",
|
|
|
|
(const char*) nsCAutoString(tagStr)));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1999-08-31 06:40:41 +00:00
|
|
|
PRUint32 cnt = 0;
|
|
|
|
rv = mBuilders->Count(&cnt);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
|
|
|
|
for (PRUint32 i = 0; i < cnt; ++i) {
|
|
|
|
// XXX we should QueryInterface() here
|
|
|
|
nsIRDFContentModelBuilder* builder
|
|
|
|
= (nsIRDFContentModelBuilder*) mBuilders->ElementAt(i);
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-08-31 06:40:41 +00:00
|
|
|
NS_ASSERTION(builder != nsnull, "null ptr");
|
|
|
|
if (! builder)
|
|
|
|
continue;
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-08-31 06:40:41 +00:00
|
|
|
rv = builder->CloseContainer(aElement);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "error closing container");
|
|
|
|
// XXX ignore error code?
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-08-31 06:40:41 +00:00
|
|
|
NS_RELEASE(builder);
|
1999-08-30 02:45:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::RebuildWidgetItem(nsIContent* aElement)
|
1999-08-30 02:45:54 +00:00
|
|
|
{
|
1999-08-31 06:40:41 +00:00
|
|
|
NS_PRECONDITION(aElement != nsnull, "null ptr");
|
|
|
|
if (! aElement)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-08-31 06:40:41 +00:00
|
|
|
if (! mBuilders)
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-08-31 06:40:41 +00:00
|
|
|
nsresult rv;
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-08-31 06:40:41 +00:00
|
|
|
#ifdef PR_LOGGING
|
|
|
|
if (PR_LOG_TEST(gXULLog, PR_LOG_DEBUG)) {
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
rv = aElement->GetTag(*getter_AddRefs(tag));
|
1999-08-30 02:45:54 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-08-31 06:40:41 +00:00
|
|
|
nsAutoString tagStr;
|
|
|
|
tag->ToString(tagStr);
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-08-31 06:40:41 +00:00
|
|
|
PR_LOG(gXULLog, PR_LOG_DEBUG,
|
|
|
|
("xuldoc close-widget-item %s",
|
|
|
|
(const char*) nsCAutoString(tagStr)));
|
1999-08-30 02:45:54 +00:00
|
|
|
}
|
1999-08-31 06:40:41 +00:00
|
|
|
#endif
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-08-31 06:40:41 +00:00
|
|
|
PRUint32 cnt = 0;
|
|
|
|
rv = mBuilders->Count(&cnt);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
|
|
|
|
for (PRUint32 i = 0; i < cnt; ++i) {
|
|
|
|
// XXX we should QueryInterface() here
|
|
|
|
nsIRDFContentModelBuilder* builder
|
|
|
|
= (nsIRDFContentModelBuilder*) mBuilders->ElementAt(i);
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-08-31 06:40:41 +00:00
|
|
|
NS_ASSERTION(builder != nsnull, "null ptr");
|
|
|
|
if (! builder)
|
|
|
|
continue;
|
1999-08-30 02:45:54 +00:00
|
|
|
|
1999-08-31 06:40:41 +00:00
|
|
|
rv = builder->RebuildContainer(aElement);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "error rebuilding container");
|
|
|
|
// XXX ignore error code?
|
|
|
|
|
|
|
|
NS_RELEASE(builder);
|
|
|
|
}
|
1999-08-30 02:45:54 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::CreateElement(PRInt32 aNameSpaceID,
|
1999-12-06 23:05:31 +00:00
|
|
|
nsIAtom* aTag,
|
|
|
|
nsIContent** aResult)
|
1999-10-05 21:13:55 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIContent> result;
|
|
|
|
|
2000-01-19 03:11:39 +00:00
|
|
|
if (aNameSpaceID == kNameSpaceID_XUL) {
|
|
|
|
rv = nsXULElement::Create(aNameSpaceID, aTag, getter_AddRefs(result));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
else if (aNameSpaceID == kNameSpaceID_HTML) {
|
1999-10-05 21:13:55 +00:00
|
|
|
const PRUnichar *tagName;
|
|
|
|
aTag->GetUnicode(&tagName);
|
|
|
|
|
2000-01-19 03:11:39 +00:00
|
|
|
rv = gHTMLElementFactory->CreateInstanceByTag(tagName, getter_AddRefs(result));
|
1999-10-05 21:13:55 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (! result)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
else {
|
2000-01-19 03:11:39 +00:00
|
|
|
const PRUnichar *tagName;
|
|
|
|
aTag->GetUnicode(&tagName);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIElementFactory> elementFactory;
|
|
|
|
GetElementFactory(aNameSpaceID, getter_AddRefs(elementFactory));
|
|
|
|
|
|
|
|
rv = elementFactory->CreateInstanceByTag(tagName, getter_AddRefs(result));
|
1999-10-05 21:13:55 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-01-19 03:11:39 +00:00
|
|
|
|
|
|
|
if (! result)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
1999-10-05 21:13:55 +00:00
|
|
|
}
|
|
|
|
|
2000-02-02 19:46:03 +00:00
|
|
|
#if 1 // XXXwaterson remove this eventually
|
|
|
|
result->SetDocument(this, PR_FALSE);
|
|
|
|
#endif
|
1999-12-06 23:05:31 +00:00
|
|
|
result->SetContentID(mNextContentID++);
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
*aResult = result;
|
|
|
|
NS_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-11-15 22:14:37 +00:00
|
|
|
nsXULDocument::PrepareToLoad(nsISupports* aContainer,
|
1999-10-29 01:21:15 +00:00
|
|
|
const char* aCommand,
|
|
|
|
nsIChannel* aChannel,
|
|
|
|
nsILoadGroup* aLoadGroup,
|
|
|
|
nsIParser** aResult)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// Get the document's principal
|
|
|
|
nsCOMPtr<nsISupports> owner;
|
|
|
|
rv = aChannel->GetOwner(getter_AddRefs(owner));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(owner);
|
1999-10-29 01:21:15 +00:00
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
return PrepareToLoadPrototype(mDocumentURL, aCommand, principal, aResult);
|
1999-10-29 01:21:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-11-18 02:25:33 +00:00
|
|
|
nsXULDocument::PrepareToLoadPrototype(nsIURI* aURI, const char* aCommand,
|
|
|
|
nsIPrincipal* aDocumentPrincipal,
|
|
|
|
nsIParser** aResult)
|
1999-10-29 01:21:15 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// Create a new prototype document
|
|
|
|
rv = NS_NewXULPrototypeDocument(nsnull, NS_GET_IID(nsIXULPrototypeDocument), getter_AddRefs(mCurrentPrototype));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
// Bootstrap the master document prototype
|
1999-11-24 22:46:09 +00:00
|
|
|
if (! mMasterPrototype) {
|
1999-11-18 02:25:33 +00:00
|
|
|
mMasterPrototype = mCurrentPrototype;
|
|
|
|
mMasterPrototype->SetDocumentPrincipal(aDocumentPrincipal);
|
|
|
|
}
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
rv = mCurrentPrototype->SetURI(aURI);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// Create a XUL content sink, a parser, and kick off a load for
|
|
|
|
// the overlay.
|
|
|
|
nsCOMPtr<nsIXULContentSink> sink;
|
|
|
|
rv = nsComponentManager::CreateInstance(kXULContentSinkCID,
|
|
|
|
nsnull,
|
|
|
|
NS_GET_IID(nsIXULContentSink),
|
|
|
|
getter_AddRefs(sink));
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create XUL content sink");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = sink->Init(this, mCurrentPrototype);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to initialize datasource sink");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIParser> parser;
|
|
|
|
rv = nsComponentManager::CreateInstance(kParserCID,
|
|
|
|
nsnull,
|
|
|
|
kIParserIID,
|
|
|
|
getter_AddRefs(parser));
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create parser");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
parser->SetCommand(aCommand);
|
|
|
|
|
|
|
|
nsAutoString utf8("UTF-8");
|
|
|
|
parser->SetDocumentCharset(utf8, kCharsetFromDocTypeDefault);
|
|
|
|
parser->SetContentSink(sink); // grabs a reference to the parser
|
|
|
|
|
|
|
|
*aResult = parser;
|
|
|
|
NS_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::ApplyPersistentAttributes()
|
1999-10-05 21:13:55 +00:00
|
|
|
{
|
|
|
|
// Add all of the 'persisted' attributes into the content
|
|
|
|
// model.
|
|
|
|
if (! mLocalStore)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsISupportsArray> array;
|
|
|
|
|
|
|
|
nsXPIDLCString docurl;
|
|
|
|
rv = mDocumentURL->GetSpec(getter_Copies(docurl));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFResource> doc;
|
|
|
|
rv = gRDFService->GetResource(docurl, getter_AddRefs(doc));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> elements;
|
|
|
|
rv = mLocalStore->GetTargets(doc, kNC_persist, PR_TRUE, getter_AddRefs(elements));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
PRBool hasmore;
|
|
|
|
rv = elements->HasMoreElements(&hasmore);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (! hasmore)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (! array) {
|
|
|
|
rv = NS_NewISupportsArray(getter_AddRefs(array));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> isupports;
|
|
|
|
rv = elements->GetNext(getter_AddRefs(isupports));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFResource> resource = do_QueryInterface(isupports);
|
|
|
|
if (! resource) {
|
|
|
|
NS_WARNING("expected element to be a resource");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* uri;
|
|
|
|
rv = resource->GetValueConst(&uri);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsAutoString id;
|
|
|
|
rv = gXULUtils->MakeElementID(this, nsAutoString(uri), id);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to compute element ID");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = GetElementsForID(id, array);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
PRUint32 cnt;
|
|
|
|
rv = array->Count(&cnt);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (! cnt)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
rv = ApplyPersistentAttributesToElements(resource, array);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ApplyPersistentAttributesToElements(nsIRDFResource* aResource, nsISupportsArray* aElements)
|
1999-10-05 21:13:55 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> attrs;
|
|
|
|
rv = mLocalStore->ArcLabelsOut(aResource, getter_AddRefs(attrs));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
PRBool hasmore;
|
|
|
|
rv = attrs->HasMoreElements(&hasmore);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (! hasmore)
|
|
|
|
break;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> isupports;
|
|
|
|
rv = attrs->GetNext(getter_AddRefs(isupports));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFResource> property = do_QueryInterface(isupports);
|
|
|
|
if (! property) {
|
|
|
|
NS_WARNING("expected a resource");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* attrname;
|
|
|
|
rv = property->GetValueConst(&attrname);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIAtom> attr = dont_AddRef(NS_NewAtom(attrname));
|
|
|
|
if (! attr)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
// XXX could hang namespace off here, as well...
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFNode> node;
|
|
|
|
rv = mLocalStore->GetTarget(aResource, property, PR_TRUE, getter_AddRefs(node));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFLiteral> literal = do_QueryInterface(node);
|
|
|
|
if (! literal) {
|
|
|
|
NS_WARNING("expected a literal");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const PRUnichar* value;
|
|
|
|
rv = literal->GetValueConst(&value);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-10-06 06:42:27 +00:00
|
|
|
PRInt32 len = nsCRT::strlen(value);
|
|
|
|
CBufDescriptor wrapper(value, PR_TRUE, len + 1, len);
|
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
PRUint32 cnt;
|
|
|
|
rv = aElements->Count(&cnt);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-10-05 21:13:55 +00:00
|
|
|
for (PRInt32 i = PRInt32(cnt) - 1; i >= 0; --i) {
|
|
|
|
nsISupports* isupports2 = aElements->ElementAt(i);
|
|
|
|
if (! isupports2)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> element = do_QueryInterface(isupports2);
|
|
|
|
NS_RELEASE(isupports2);
|
|
|
|
|
|
|
|
rv = element->SetAttribute(/* XXX */ kNameSpaceID_None,
|
|
|
|
attr,
|
|
|
|
nsAutoString(wrapper),
|
|
|
|
PR_FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// nsXULDocument::ContextStack
|
|
|
|
//
|
1999-10-05 21:13:55 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
nsXULDocument::ContextStack::ContextStack()
|
|
|
|
: mTop(nsnull), mDepth(0)
|
1999-10-27 02:21:05 +00:00
|
|
|
{
|
1999-10-29 01:21:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsXULDocument::ContextStack::~ContextStack()
|
|
|
|
{
|
|
|
|
while (mTop) {
|
|
|
|
Entry* doomed = mTop;
|
|
|
|
mTop = mTop->mNext;
|
|
|
|
NS_IF_RELEASE(doomed->mElement);
|
|
|
|
delete doomed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::ContextStack::Push(nsXULPrototypeElement* aPrototype, nsIContent* aElement)
|
|
|
|
{
|
|
|
|
Entry* entry = new Entry;
|
|
|
|
if (! entry)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
entry->mPrototype = aPrototype;
|
|
|
|
entry->mElement = aElement;
|
|
|
|
NS_IF_ADDREF(entry->mElement);
|
|
|
|
entry->mIndex = 0;
|
|
|
|
|
|
|
|
entry->mNext = mTop;
|
|
|
|
mTop = entry;
|
|
|
|
|
|
|
|
++mDepth;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::ContextStack::Pop()
|
|
|
|
{
|
|
|
|
if (mDepth == 0)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
Entry* doomed = mTop;
|
|
|
|
mTop = mTop->mNext;
|
|
|
|
--mDepth;
|
|
|
|
|
|
|
|
NS_IF_RELEASE(doomed->mElement);
|
|
|
|
delete doomed;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::ContextStack::Peek(nsXULPrototypeElement** aPrototype,
|
|
|
|
nsIContent** aElement,
|
|
|
|
PRInt32* aIndex)
|
|
|
|
{
|
|
|
|
if (mDepth == 0)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
*aPrototype = mTop->mPrototype;
|
|
|
|
*aElement = mTop->mElement;
|
|
|
|
NS_IF_ADDREF(*aElement);
|
|
|
|
*aIndex = mTop->mIndex;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::ContextStack::SetTopIndex(PRInt32 aIndex)
|
|
|
|
{
|
|
|
|
if (mDepth == 0)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
mTop->mIndex = aIndex;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsXULDocument::ContextStack::IsInsideXULTemplate()
|
|
|
|
{
|
|
|
|
if (mDepth) {
|
|
|
|
nsCOMPtr<nsIContent> element = dont_QueryInterface(mTop->mElement);
|
|
|
|
while (element) {
|
|
|
|
PRInt32 nameSpaceID;
|
|
|
|
element->GetNameSpaceID(nameSpaceID);
|
|
|
|
if (nameSpaceID == kNameSpaceID_XUL) {
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
element->GetTag(*getter_AddRefs(tag));
|
|
|
|
if (tag.get() == kTemplateAtom) {
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> parent;
|
|
|
|
element->GetParent(*getter_AddRefs(parent));
|
|
|
|
element = parent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Content model walking routines
|
|
|
|
//
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::PrepareToWalk()
|
|
|
|
{
|
|
|
|
// Prepare to walk the mCurrentPrototype
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// Keep an owning reference to the prototype document so that its
|
|
|
|
// elements aren't yanked from beneath us.
|
|
|
|
mPrototypes->AppendElement(mCurrentPrototype);
|
|
|
|
|
|
|
|
// Push the overlay references onto our overlay processing
|
|
|
|
// stack. GetOverlayReferences() will return an ordered array of
|
|
|
|
// overlay references...
|
1999-11-02 01:14:07 +00:00
|
|
|
nsCOMPtr<nsISupportsArray> overlays;
|
|
|
|
rv = mCurrentPrototype->GetOverlayReferences(getter_AddRefs(overlays));
|
1999-10-29 01:21:15 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// ...and we preserve this ordering by appending to our
|
|
|
|
// mUnloadedOverlays array in reverse order
|
1999-11-02 01:14:07 +00:00
|
|
|
PRUint32 count;
|
|
|
|
overlays->Count(&count);
|
|
|
|
for (PRInt32 i = count - 1; i >= 0; --i) {
|
1999-11-02 02:02:27 +00:00
|
|
|
nsISupports* isupports = overlays->ElementAt(i);
|
1999-11-02 01:14:07 +00:00
|
|
|
mUnloadedOverlays->AppendElement(isupports);
|
1999-11-02 02:02:27 +00:00
|
|
|
NS_IF_RELEASE(isupports);
|
1999-10-29 01:21:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now check the chrome registry for any additional overlays.
|
|
|
|
rv = AddChromeOverlays();
|
|
|
|
|
|
|
|
// Get the prototype's root element and initialize the context
|
|
|
|
// stack for the prototype walk.
|
|
|
|
nsXULPrototypeElement* proto;
|
|
|
|
rv = mCurrentPrototype->GetRootElement(&proto);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
if (! proto) {
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
nsCOMPtr<nsIURI> url;
|
|
|
|
rv = mCurrentPrototype->GetURI(getter_AddRefs(url));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsXPIDLCString urlspec;
|
|
|
|
rv = url->GetSpec(getter_Copies(urlspec));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
PR_LOG(gXULLog, PR_LOG_ALWAYS,
|
|
|
|
("xul: error parsing '%s'", (const char*) urlspec));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do one-time initialization if we're preparing to walk the
|
|
|
|
// master document's prototype.
|
|
|
|
nsCOMPtr<nsIContent> root;
|
|
|
|
|
|
|
|
if (mState == eState_Master) {
|
|
|
|
rv = CreateElement(proto, getter_AddRefs(root));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
SetRootContent(root);
|
|
|
|
|
|
|
|
// Create the document's "hidden form" element which will wrap all
|
|
|
|
// HTML form elements that turn up.
|
2000-01-19 03:11:39 +00:00
|
|
|
nsCOMPtr<nsIContent> form;
|
1999-10-29 01:21:15 +00:00
|
|
|
rv = gHTMLElementFactory->CreateInstanceByTag(nsAutoString("form"),
|
|
|
|
getter_AddRefs(form));
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create form element");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMHTMLFormElement> htmlFormElement = do_QueryInterface(form);
|
|
|
|
NS_ASSERTION(htmlFormElement != nsnull, "not an nSIDOMHTMLFormElement");
|
|
|
|
if (! htmlFormElement)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
rv = SetForm(htmlFormElement);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to set form element");
|
|
|
|
if (NS_FAILED(rv)) return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> content = do_QueryInterface(form);
|
|
|
|
NS_ASSERTION(content != nsnull, "not an nsIContent");
|
|
|
|
if (! content)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
// XXX Would like to make this anonymous, but still need the
|
|
|
|
// form's frame to get built. For now make it explicit.
|
1999-11-18 02:25:33 +00:00
|
|
|
rv = root->InsertChildAt(content, 0, PR_FALSE);
|
1999-10-29 01:21:15 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add anonymous form element");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// Add the root element to the XUL document's ID-to-element map.
|
|
|
|
rv = AddElementToMap(root);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-11-24 22:46:09 +00:00
|
|
|
|
1999-11-23 01:44:51 +00:00
|
|
|
// 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;
|
1999-11-24 22:46:09 +00:00
|
|
|
|
1999-11-23 01:44:51 +00:00
|
|
|
nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
|
1999-12-08 04:56:56 +00:00
|
|
|
|
1999-11-23 01:44:51 +00:00
|
|
|
if (group) {
|
1999-11-24 22:46:09 +00:00
|
|
|
rv = mPlaceholderChannel->SetLoadGroup(group);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = group->AddChannel(mPlaceholderChannel, nsnull);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-11-23 01:44:51 +00:00
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
}
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
rv = mContextStack.Push(proto, root);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::AddChromeOverlays()
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
NS_WITH_SERVICE(nsIChromeRegistry, reg, kChromeRegistryCID, &rv);
|
|
|
|
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> oe;
|
1999-11-05 05:31:15 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
rv = mCurrentPrototype->GetURI(getter_AddRefs(uri));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
reg->GetOverlays(uri, getter_AddRefs(oe));
|
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
if (!oe)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
PRBool moreElements;
|
|
|
|
oe->HasMoreElements(&moreElements);
|
|
|
|
|
|
|
|
while (moreElements) {
|
|
|
|
nsCOMPtr<nsISupports> next;
|
|
|
|
oe->GetNext(getter_AddRefs(next));
|
|
|
|
if (!next)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> uri = do_QueryInterface(next);
|
|
|
|
if (!uri)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
mUnloadedOverlays->AppendElement(uri);
|
|
|
|
|
|
|
|
oe->HasMoreElements(&moreElements);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::ResumeWalk()
|
|
|
|
{
|
|
|
|
// Walk the prototype and build the delegate content model. The
|
|
|
|
// walk is performed in a top-down, left-to-right fashion. That
|
|
|
|
// is, a parent is built before any of its children; a node is
|
|
|
|
// only built after all of its siblings to the left are fully
|
|
|
|
// constructed.
|
|
|
|
//
|
|
|
|
// It is interruptable so that transcluded documents (e.g.,
|
|
|
|
// <html:script src="..." />) can be properly re-loaded if the
|
|
|
|
// cached copy of the document becomes stale.
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
// Begin (or resume) walking the current prototype.
|
|
|
|
|
|
|
|
while (mContextStack.Depth() > 0) {
|
|
|
|
// Look at the top of the stack to determine what we're
|
|
|
|
// currently working on.
|
|
|
|
nsXULPrototypeElement* proto;
|
|
|
|
nsCOMPtr<nsIContent> element;
|
|
|
|
PRInt32 indx;
|
|
|
|
rv = mContextStack.Peek(&proto, getter_AddRefs(element), &indx);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (indx >= proto->mNumChildren) {
|
1999-12-08 07:59:12 +00:00
|
|
|
if (element && ((mState == eState_Master) || (mContextStack.Depth() > 2))) {
|
1999-10-29 01:21:15 +00:00
|
|
|
// We've processed all of the prototype's children.
|
|
|
|
// Check the element for a 'datasources' attribute, in
|
|
|
|
// which case we'll need to create a template builder
|
|
|
|
// and construct the first 'ply' of elements beneath
|
|
|
|
// it.
|
|
|
|
//
|
|
|
|
// N.B. that we do this -after- all other XUL children
|
|
|
|
// have been created: this ensures that there'll be a
|
|
|
|
// <template> tag available when we try to build that
|
|
|
|
// first ply of generated elements.
|
|
|
|
//
|
|
|
|
// N.B. that we do -not- do this if we are dealing
|
|
|
|
// with an 'overlay element'; that is, an element
|
|
|
|
// in the first ply of an overlay
|
|
|
|
// document. OverlayForwardReference::Merge() will
|
|
|
|
// handle that case.
|
|
|
|
rv = CheckTemplateBuilder(element);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now pop the context stack back up to the parent
|
|
|
|
// element and continue the prototype walk.
|
|
|
|
mContextStack.Pop();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Grab the next child, and advance the current context stack
|
|
|
|
// to the next sibling to our right.
|
|
|
|
nsXULPrototypeNode* childproto = proto->mChildren[indx];
|
|
|
|
mContextStack.SetTopIndex(++indx);
|
|
|
|
|
|
|
|
switch (childproto->mType) {
|
|
|
|
case nsXULPrototypeNode::eType_Element: {
|
|
|
|
// An 'element', which may contain more content.
|
|
|
|
nsXULPrototypeElement* protoele =
|
|
|
|
NS_REINTERPRET_CAST(nsXULPrototypeElement*, childproto);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> child;
|
|
|
|
|
|
|
|
if ((mState == eState_Master) || (mContextStack.Depth() > 1)) {
|
1999-11-08 19:07:13 +00:00
|
|
|
// We're in the master document -or -we're in an
|
|
|
|
// overlay, and far enough down into the overlay's
|
|
|
|
// content that we can simply build the delegates
|
|
|
|
// and attach them to the parent node.
|
1999-10-29 01:21:15 +00:00
|
|
|
rv = CreateElement(protoele, getter_AddRefs(child));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// ...and append it to the content model.
|
|
|
|
rv = element->AppendChildTo(child, PR_FALSE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-11-08 19:07:13 +00:00
|
|
|
// ...but only do document-level hookup if we're
|
|
|
|
// in the master document. For an overlay, this
|
|
|
|
// will happend when the overlay is successfully
|
|
|
|
// resolved.
|
|
|
|
if (mState == eState_Master) {
|
|
|
|
rv = AddSubtreeToDocument(child);
|
1999-11-04 18:37:58 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// We're in the "first ply" of an overlay: the
|
|
|
|
// "hookup" nodes. Create an 'overlay' element so
|
|
|
|
// that we can continue to build content, and
|
|
|
|
// enter a forward reference so we can hook it up
|
|
|
|
// later.
|
|
|
|
rv = CreateOverlayElement(protoele, getter_AddRefs(child));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If it has children, push the element onto the context
|
|
|
|
// stack and begin to process them.
|
|
|
|
if (protoele->mNumChildren > 0) {
|
|
|
|
rv = mContextStack.Push(protoele, child);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case nsXULPrototypeNode::eType_Script: {
|
1999-11-18 02:25:33 +00:00
|
|
|
// A script reference. Execute the script immediately;
|
1999-10-29 01:21:15 +00:00
|
|
|
// this may have side effects in the content model.
|
|
|
|
nsXULPrototypeScript* scriptproto =
|
|
|
|
NS_REINTERPRET_CAST(nsXULPrototypeScript*, childproto);
|
|
|
|
|
|
|
|
if (scriptproto->mSrcURI) {
|
|
|
|
// A transcluded script reference; this may
|
|
|
|
// "block" our prototype walk if the script isn't
|
|
|
|
// cached, or the cached copy of the script is
|
|
|
|
// stale and must be reloaded.
|
|
|
|
PRBool blocked;
|
1999-11-18 02:25:33 +00:00
|
|
|
rv = LoadScript(scriptproto, &blocked);
|
1999-10-29 01:21:15 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (blocked)
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-11-18 02:25:33 +00:00
|
|
|
else if (scriptproto->mScriptObject) {
|
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 00:43:30 +00:00
|
|
|
// An inline script
|
1999-11-18 02:25:33 +00:00
|
|
|
rv = ExecuteScript(scriptproto->mScriptObject);
|
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 00:43:30 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
}
|
|
|
|
break;
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
case nsXULPrototypeNode::eType_Text: {
|
|
|
|
// A simple text node.
|
|
|
|
nsCOMPtr<nsITextContent> text;
|
|
|
|
rv = nsComponentManager::CreateInstance(kTextNodeCID,
|
|
|
|
nsnull,
|
|
|
|
NS_GET_IID(nsITextContent),
|
|
|
|
getter_AddRefs(text));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsXULPrototypeText* textproto =
|
|
|
|
NS_REINTERPRET_CAST(nsXULPrototypeText*, childproto);
|
|
|
|
|
|
|
|
rv = text->SetText(textproto->mValue.GetUnicode(),
|
|
|
|
textproto->mValue.Length(),
|
|
|
|
PR_FALSE);
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> child = do_QueryInterface(text);
|
|
|
|
if (! child)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
rv = element->AppendChildTo(child, PR_FALSE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Once we get here, the context stack will have been
|
|
|
|
// depleted. That means that the entire prototype has been
|
|
|
|
// walked and content has been constructed.
|
|
|
|
|
|
|
|
// If we're not already, mark us as now processing overlays.
|
|
|
|
mState = eState_Overlay;
|
|
|
|
|
|
|
|
PRUint32 count;
|
|
|
|
mUnloadedOverlays->Count(&count);
|
|
|
|
|
|
|
|
// If there are no overlay URIs, then we're done.
|
|
|
|
if (! count)
|
|
|
|
break;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> uri =
|
|
|
|
dont_AddRef(NS_REINTERPRET_CAST(nsIURI*, mUnloadedOverlays->ElementAt(count - 1)));
|
|
|
|
|
|
|
|
mUnloadedOverlays->RemoveElementAt(count - 1);
|
|
|
|
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
if (PR_LOG_TEST(gXULLog, PR_LOG_DEBUG)) {
|
|
|
|
nsXPIDLCString urlspec;
|
|
|
|
uri->GetSpec(getter_Copies(urlspec));
|
|
|
|
|
|
|
|
PR_LOG(gXULLog, PR_LOG_DEBUG,
|
|
|
|
("xul: loading overlay %s", (const char*) urlspec));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Look in the prototype cache for the prototype document with
|
|
|
|
// the specified URI.
|
1999-11-02 01:14:07 +00:00
|
|
|
rv = gXULCache->GetPrototype(uri, getter_AddRefs(mCurrentPrototype));
|
1999-10-29 01:21:15 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-11-02 01:14:07 +00:00
|
|
|
if (gXULUtils->UseXULCache() && mCurrentPrototype) {
|
|
|
|
// Found the overlay's prototype in the cache.
|
|
|
|
rv = AddPrototypeSheets();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// Now prepare to walk the prototype to create its content
|
1999-10-29 01:21:15 +00:00
|
|
|
rv = PrepareToWalk();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
PR_LOG(gXULLog, PR_LOG_DEBUG, ("xul: overlay was cached"));
|
|
|
|
}
|
|
|
|
else {
|
1999-12-16 03:19:34 +00:00
|
|
|
// Not there. Initiate a load.
|
1999-10-29 01:21:15 +00:00
|
|
|
PR_LOG(gXULLog, PR_LOG_DEBUG, ("xul: overlay was not cached"));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIParser> parser;
|
1999-11-18 02:25:33 +00:00
|
|
|
rv = PrepareToLoadPrototype(uri, "view", nsnull, getter_AddRefs(parser));
|
1999-10-29 01:21:15 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStreamListener> listener = do_QueryInterface(parser);
|
|
|
|
if (! listener)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
parser->Parse(uri);
|
|
|
|
|
1999-12-16 03:19:34 +00:00
|
|
|
// If we're a keybinding document, the overlay load must
|
|
|
|
// occur synchronously.
|
|
|
|
if (mIsKeyBindingDoc) {
|
|
|
|
nsCOMPtr<nsIChannel> channel;
|
|
|
|
rv = NS_OpenURI(getter_AddRefs(channel), uri, nsnull);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
nsCOMPtr<nsIInputStream> in;
|
|
|
|
PRUint32 sourceOffset = 0;
|
|
|
|
rv = channel->OpenInputStream(0, -1, getter_AddRefs(in));
|
|
|
|
|
|
|
|
// If we couldn't open the channel, then just return.
|
|
|
|
if (NS_FAILED(rv)) return NS_OK;
|
|
|
|
|
|
|
|
NS_ASSERTION(in != nsnull, "no input stream");
|
|
|
|
if (! in) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
nsProxyLoadStream* proxy = new nsProxyLoadStream();
|
|
|
|
if (! proxy)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
listener->OnStartRequest(channel, nsnull);
|
|
|
|
while (PR_TRUE) {
|
|
|
|
char buf[1024];
|
|
|
|
PRUint32 readCount;
|
|
|
|
|
|
|
|
if (NS_FAILED(rv = in->Read(buf, sizeof(buf), &readCount)))
|
|
|
|
break; // error
|
|
|
|
|
|
|
|
if (readCount == 0)
|
|
|
|
break; // eof
|
|
|
|
|
|
|
|
proxy->SetBuffer(buf, readCount);
|
|
|
|
|
|
|
|
rv = listener->OnDataAvailable(channel, nsnull, proxy, sourceOffset, readCount);
|
|
|
|
sourceOffset += readCount;
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
listener->OnStopRequest(channel, nsnull, NS_OK, nsnull);
|
|
|
|
|
|
|
|
// don't leak proxy!
|
|
|
|
proxy->Close();
|
|
|
|
delete proxy;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
|
|
|
|
rv = NS_OpenURI(listener, nsnull, uri, group);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
// Return to the main event loop and eagerly await the
|
|
|
|
// overlay load's completion. When the content sink
|
|
|
|
// completes, it will trigger an EndLoad(), which'll wind
|
|
|
|
// us back up here, in ResumeWalk().
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we get here, there is nothing left for us to walk. The content
|
|
|
|
// model is built and ready for layout.
|
1999-11-23 01:44:51 +00:00
|
|
|
rv = ResolveForwardReferences();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = ApplyPersistentAttributes();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-12-04 07:45:57 +00:00
|
|
|
// Everything after this point we only want to do once we're
|
|
|
|
// certain that we've been embedded in a presentation shell.
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
StartLayout();
|
|
|
|
|
|
|
|
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
|
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i];
|
|
|
|
observer->EndLoad(this);
|
|
|
|
if (observer != (nsIDocumentObserver*)mObservers.ElementAt(i)) {
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-11-24 22:46:09 +00:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-11-18 02:25:33 +00:00
|
|
|
nsXULDocument::LoadScript(nsXULPrototypeScript* aScriptProto, PRBool* aBlock)
|
1999-10-29 01:21:15 +00:00
|
|
|
{
|
|
|
|
// Load a transcluded script
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
if (aScriptProto->mScriptObject) {
|
|
|
|
rv = ExecuteScript(aScriptProto->mScriptObject);
|
1999-10-29 01:21:15 +00:00
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
// Ignore return value from execution, and don't block
|
1999-11-02 01:14:07 +00:00
|
|
|
*aBlock = PR_FALSE;
|
1999-10-29 01:21:15 +00:00
|
|
|
}
|
|
|
|
else {
|
1999-11-18 02:25:33 +00:00
|
|
|
// Set the current script prototype so that OnUnicharStreamComplete
|
|
|
|
// can get report the right file if there are errors in the script.
|
1999-11-23 01:44:51 +00:00
|
|
|
NS_ASSERTION(!mCurrentScriptProto,
|
|
|
|
"still loading a script when starting another load?");
|
1999-11-18 02:25:33 +00:00
|
|
|
mCurrentScriptProto = aScriptProto;
|
|
|
|
|
1999-11-23 01:44:51 +00:00
|
|
|
if (aScriptProto->mSrcLoading) {
|
1999-11-18 02:25:33 +00:00
|
|
|
// Another XULDocument load has started, which is still in progress.
|
|
|
|
// Remember to ResumeWalk this document when the load completes.
|
|
|
|
mNextSrcLoadWaiter = aScriptProto->mSrcLoadWaiters;
|
|
|
|
aScriptProto->mSrcLoadWaiters = this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
|
1999-10-29 01:21:15 +00:00
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
// N.B., the loader will be released in OnUnicharStreamComplete
|
|
|
|
nsIUnicharStreamLoader* loader;
|
|
|
|
rv = NS_NewUnicharStreamLoader(&loader, aScriptProto->mSrcURI, this, group);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
aScriptProto->mSrcLoading = PR_TRUE;
|
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
// Block until OnUnicharStreamComplete resumes us.
|
1999-10-29 01:21:15 +00:00
|
|
|
*aBlock = PR_TRUE;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-30 04:50:42 +00:00
|
|
|
NS_IMETHODIMP
|
1999-11-02 06:49:44 +00:00
|
|
|
nsXULDocument::OnUnicharStreamComplete(nsIUnicharStreamLoader* aLoader,
|
|
|
|
nsresult aStatus,
|
1999-11-30 04:50:42 +00:00
|
|
|
PRUint32 stringLen,
|
1999-11-02 06:49:44 +00:00
|
|
|
const PRUnichar* string)
|
1999-10-29 01:21:15 +00:00
|
|
|
{
|
|
|
|
// This is the completion routine that will be called when a
|
1999-11-18 02:25:33 +00:00
|
|
|
// transcluded script completes. Compile and execute the script
|
|
|
|
// if the load was successful, then continue building content
|
|
|
|
// from the prototype.
|
1999-10-29 01:21:15 +00:00
|
|
|
nsresult rv;
|
|
|
|
|
1999-11-23 01:44:51 +00:00
|
|
|
NS_ASSERTION(mCurrentScriptProto && mCurrentScriptProto->mSrcLoading,
|
1999-11-18 02:25:33 +00:00
|
|
|
"script source not loading on unichar stream complete?");
|
1999-11-02 01:14:07 +00:00
|
|
|
|
1999-11-23 01:44:51 +00:00
|
|
|
// Clear mCurrentScriptProto now, but save it first for use below in
|
|
|
|
// the compile/execute code, and in the while loop that resumes walks
|
|
|
|
// of other documents that raced to load this script
|
|
|
|
nsXULPrototypeScript* scriptProto = mCurrentScriptProto;
|
|
|
|
mCurrentScriptProto = nsnull;
|
|
|
|
|
|
|
|
// Clear the prototype's loading flag before executing the script or
|
|
|
|
// resuming document walks, in case any of those control flows starts a
|
|
|
|
// new script load.
|
|
|
|
scriptProto->mSrcLoading = PR_FALSE;
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
if (NS_SUCCEEDED(aStatus)) {
|
1999-11-30 04:50:42 +00:00
|
|
|
rv = scriptProto->Compile(string, stringLen,
|
1999-11-23 01:44:51 +00:00
|
|
|
scriptProto->mSrcURI, 1,
|
1999-12-17 00:06:28 +00:00
|
|
|
this, mMasterPrototype);
|
1999-11-23 01:44:51 +00:00
|
|
|
aStatus = rv;
|
1999-11-18 02:25:33 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-23 01:44:51 +00:00
|
|
|
rv = ExecuteScript(scriptProto->mScriptObject);
|
1999-11-02 01:14:07 +00:00
|
|
|
}
|
1999-11-18 02:25:33 +00:00
|
|
|
// ignore any evaluation errors
|
1999-10-29 01:21:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// balance the addref we added in LoadScript()
|
|
|
|
NS_RELEASE(aLoader);
|
|
|
|
|
1999-11-02 06:49:44 +00:00
|
|
|
rv = ResumeWalk();
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-11-23 01:44:51 +00:00
|
|
|
// Load a pointer to the prototype-script's list of nsXULDocuments who
|
|
|
|
// raced to load the same script
|
|
|
|
nsXULDocument** docp = &scriptProto->mSrcLoadWaiters;
|
|
|
|
|
|
|
|
// Resume walking other documents that waited for this one's load, first
|
|
|
|
// executing the script we just compiled, in each doc's script context
|
1999-11-18 02:25:33 +00:00
|
|
|
nsXULDocument* doc;
|
|
|
|
while ((doc = *docp) != nsnull) {
|
1999-11-23 01:44:51 +00:00
|
|
|
NS_ASSERTION(doc->mCurrentScriptProto == scriptProto,
|
|
|
|
"waiting for wrong script to load?");
|
|
|
|
doc->mCurrentScriptProto = nsnull;
|
|
|
|
|
|
|
|
// Unlink doc from scriptProto's list before executing and resuming
|
1999-11-18 02:25:33 +00:00
|
|
|
*docp = doc->mNextSrcLoadWaiter;
|
|
|
|
doc->mNextSrcLoadWaiter = nsnull;
|
1999-11-23 01:44:51 +00:00
|
|
|
|
|
|
|
// Execute only if we loaded and compiled successfully, then resume
|
|
|
|
if (NS_SUCCEEDED(aStatus)) {
|
|
|
|
doc->ExecuteScript(scriptProto->mScriptObject);
|
|
|
|
}
|
1999-11-20 03:10:42 +00:00
|
|
|
doc->ResumeWalk();
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_RELEASE(doc);
|
|
|
|
}
|
1999-11-23 01:44:51 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-11-18 02:25:33 +00:00
|
|
|
nsXULDocument::ExecuteScript(JSObject* aScriptObject)
|
1999-10-29 01:21:15 +00:00
|
|
|
{
|
1999-11-18 02:25:33 +00:00
|
|
|
// Execute the precompiled script with the given version
|
1999-10-29 01:21:15 +00:00
|
|
|
nsresult rv;
|
|
|
|
|
1999-12-04 07:45:57 +00:00
|
|
|
NS_ASSERTION(mScriptGlobalObject != nsnull, "no script global object");
|
|
|
|
if (! mScriptGlobalObject)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIScriptContext> context;
|
1999-12-03 09:24:22 +00:00
|
|
|
rv = mScriptGlobalObject->GetContext(getter_AddRefs(context));
|
1999-10-29 01:21:15 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-11-18 02:25:33 +00:00
|
|
|
rv = context->ExecuteScript(aScriptObject, nsnull, nsnull, nsnull);
|
1999-10-29 01:21:15 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::CreateElement(nsXULPrototypeElement* aPrototype, nsIContent** aResult)
|
|
|
|
{
|
|
|
|
// Create a content model element from a prototype element.
|
|
|
|
NS_PRECONDITION(aPrototype != nsnull, "null ptr");
|
|
|
|
if (! aPrototype)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
if (PR_LOG_TEST(gXULLog, PR_LOG_ALWAYS)) {
|
|
|
|
nsAutoString tagstr;
|
|
|
|
aPrototype->mTag->ToString(tagstr);
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
PR_LOG(gXULLog, PR_LOG_ALWAYS,
|
|
|
|
("xul: creating <%s> from prototype",
|
|
|
|
(const char*) nsCAutoString(tagstr)));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> result;
|
|
|
|
|
|
|
|
if (aPrototype->mNameSpaceID == kNameSpaceID_HTML) {
|
|
|
|
// If it's an HTML element, it's gonna be heavyweight no matter
|
|
|
|
// what. So we need to copy everything out of the prototype
|
|
|
|
// into the element.
|
|
|
|
nsAutoString tagStr;
|
|
|
|
rv = aPrototype->mTag->ToString(tagStr);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-11-18 02:25:33 +00:00
|
|
|
|
2000-01-19 03:11:39 +00:00
|
|
|
gHTMLElementFactory->CreateInstanceByTag(tagStr.GetUnicode(), getter_AddRefs(result));
|
1999-10-29 01:21:15 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (! result)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
rv = result->SetDocument(this, PR_FALSE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = AddAttributes(aPrototype, result);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-01-19 03:11:39 +00:00
|
|
|
nsCOMPtr<nsIFormControl> htmlformctrl = do_QueryInterface(result);
|
1999-10-29 01:21:15 +00:00
|
|
|
if (htmlformctrl) {
|
|
|
|
nsCOMPtr<nsIDOMHTMLFormElement> docform;
|
|
|
|
rv = GetForm(getter_AddRefs(docform));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
NS_ASSERTION(docform != nsnull, "no document form");
|
|
|
|
if (! docform)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
htmlformctrl->SetForm(docform);
|
|
|
|
}
|
|
|
|
}
|
2000-01-19 03:11:39 +00:00
|
|
|
else if (aPrototype->mNameSpaceID != kNameSpaceID_XUL) {
|
|
|
|
// If it's not a XUL element, it's gonna be heavyweight no matter
|
|
|
|
// what. So we need to copy everything out of the prototype
|
|
|
|
// into the element.
|
|
|
|
nsAutoString tagStr;
|
|
|
|
rv = aPrototype->mTag->ToString(tagStr);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIElementFactory> elementFactory;
|
|
|
|
GetElementFactory(aPrototype->mNameSpaceID, getter_AddRefs(elementFactory));
|
|
|
|
elementFactory->CreateInstanceByTag(tagStr.GetUnicode(), getter_AddRefs(result));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (! result)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
rv = result->SetDocument(this, PR_FALSE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = AddAttributes(aPrototype, result);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
else {
|
|
|
|
// If it's a XUL element, it'll be lightweight until somebody
|
|
|
|
// monkeys with it.
|
1999-11-04 19:43:43 +00:00
|
|
|
rv = nsXULElement::Create(aPrototype, this, PR_TRUE, getter_AddRefs(result));
|
1999-10-29 01:21:15 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// We also need to pay special attention to the keyset tag to set up a listener
|
|
|
|
if ((aPrototype->mNameSpaceID == kNameSpaceID_XUL) &&
|
1999-12-15 23:18:34 +00:00
|
|
|
(aPrototype->mTag.get() == kKeysetAtom) &&
|
|
|
|
! mIsKeyBindingDoc) {
|
1999-10-29 01:21:15 +00:00
|
|
|
// Create our nsXULKeyListener and hook it up.
|
|
|
|
nsCOMPtr<nsIXULKeyListener> keyListener;
|
|
|
|
rv = nsComponentManager::CreateInstance(kXULKeyListenerCID,
|
|
|
|
nsnull,
|
|
|
|
NS_GET_IID(nsIXULKeyListener),
|
|
|
|
getter_AddRefs(keyListener));
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a key listener");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
nsCOMPtr<nsIDOMEventListener> domEventListener = do_QueryInterface(keyListener);
|
|
|
|
if (domEventListener) {
|
|
|
|
// Init the listener with the keyset node
|
|
|
|
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(result);
|
|
|
|
keyListener->Init(domElement, this);
|
1999-11-18 02:25:33 +00:00
|
|
|
|
2000-01-27 09:43:19 +00:00
|
|
|
AddEventListener("keypress", domEventListener, PR_FALSE);
|
|
|
|
AddEventListener("keydown", domEventListener, PR_FALSE);
|
|
|
|
AddEventListener("keyup", domEventListener, PR_FALSE);
|
1999-10-29 01:21:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-12-06 23:05:31 +00:00
|
|
|
result->SetContentID(mNextContentID++);
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
*aResult = result;
|
|
|
|
NS_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::CreateOverlayElement(nsXULPrototypeElement* aPrototype, nsIContent** aResult)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// This doesn't really do anything except create a placeholder
|
|
|
|
// element. I'd use an XML element, but it gets its knickers in a
|
|
|
|
// knot with DOM ranges when you try to remove its children.
|
|
|
|
nsCOMPtr<nsIContent> element;
|
1999-11-04 19:43:43 +00:00
|
|
|
rv = nsXULElement::Create(aPrototype, this, PR_FALSE, getter_AddRefs(element));
|
1999-10-29 01:21:15 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-11-08 19:07:13 +00:00
|
|
|
OverlayForwardReference* fwdref = new OverlayForwardReference(this, element);
|
1999-10-29 01:21:15 +00:00
|
|
|
if (! fwdref)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
// transferring ownership to ya...
|
|
|
|
rv = AddForwardReference(fwdref);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
*aResult = element;
|
|
|
|
NS_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::AddAttributes(nsXULPrototypeElement* aPrototype, nsIContent* aElement)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
for (PRInt32 i = 0; i < aPrototype->mNumAttributes; ++i) {
|
|
|
|
nsXULPrototypeAttribute* protoattr = &(aPrototype->mAttributes[i]);
|
|
|
|
|
|
|
|
rv = aElement->SetAttribute(protoattr->mNameSpaceID,
|
|
|
|
protoattr->mName,
|
|
|
|
protoattr->mValue,
|
|
|
|
PR_FALSE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::CheckTemplateBuilder(nsIContent* aElement)
|
|
|
|
{
|
|
|
|
// Check aElement for a 'datasources' attribute, and if it has
|
|
|
|
// one, create and initialize a template builder.
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsAutoString datasources;
|
|
|
|
rv = aElement->GetAttribute(kNameSpaceID_None, kDataSourcesAtom, datasources);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (rv != NS_CONTENT_ATTR_HAS_VALUE)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// Get the document and its URL
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
rv = aElement->GetDocument(*getter_AddRefs(doc));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
NS_ASSERTION(doc != nsnull, "no document");
|
|
|
|
if (! doc)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> docurl = dont_AddRef(doc->GetDocumentURL());
|
|
|
|
|
|
|
|
// construct a new builder
|
|
|
|
nsCOMPtr<nsIRDFContentModelBuilder> builder;
|
|
|
|
rv = nsComponentManager::CreateInstance(kXULTemplateBuilderCID,
|
|
|
|
nsnull,
|
|
|
|
NS_GET_IID(nsIRDFContentModelBuilder),
|
|
|
|
getter_AddRefs(builder));
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create tree content model builder");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = builder->SetRootContent(aElement);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to set builder's root content element");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// create a database for the builder
|
|
|
|
nsCOMPtr<nsIRDFCompositeDataSource> db;
|
|
|
|
rv = nsComponentManager::CreateInstance(kRDFCompositeDataSourceCID,
|
|
|
|
nsnull,
|
|
|
|
NS_GET_IID(nsIRDFCompositeDataSource),
|
|
|
|
getter_AddRefs(db));
|
|
|
|
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to construct new composite data source");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-01-12 01:47:23 +00:00
|
|
|
// check for magical attributes
|
|
|
|
nsAutoString attrib;
|
|
|
|
if (NS_SUCCEEDED(rv = aElement->GetAttribute(kNameSpaceID_None, kCoalesceAtom, attrib))
|
|
|
|
&& (rv == NS_CONTENT_ATTR_HAS_VALUE) && (attrib.Equals("false")))
|
|
|
|
{
|
|
|
|
db->SetCoalesceDuplicateArcs(PR_FALSE);
|
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(rv = aElement->GetAttribute(kNameSpaceID_None, kAllowNegativesAtom, attrib))
|
|
|
|
&& (rv == NS_CONTENT_ATTR_HAS_VALUE) && (attrib.Equals("false")))
|
|
|
|
{
|
|
|
|
db->SetAllowNegativeAssertions(PR_FALSE);
|
|
|
|
}
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
// Add the local store as the first data source in the db. Note
|
|
|
|
// that we _might_ not be able to get a local store if we haven't
|
|
|
|
// got a profile to read from yet.
|
|
|
|
nsCOMPtr<nsIRDFDataSource> localstore;
|
|
|
|
rv = gRDFService->GetDataSource("rdf:local-store", getter_AddRefs(localstore));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
rv = db->AddDataSource(localstore);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add local store to db");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse datasources: they are assumed to be a whitespace
|
|
|
|
// separated list of URIs; e.g.,
|
|
|
|
//
|
|
|
|
// rdf:bookmarks rdf:history http://foo.bar.com/blah.cgi?baz=9
|
|
|
|
//
|
|
|
|
PRInt32 first = 0;
|
|
|
|
|
|
|
|
while(1) {
|
|
|
|
while (first < datasources.Length() && nsString::IsSpace(datasources.CharAt(first)))
|
|
|
|
++first;
|
|
|
|
|
|
|
|
if (first >= datasources.Length())
|
|
|
|
break;
|
|
|
|
|
|
|
|
PRInt32 last = first;
|
|
|
|
while (last < datasources.Length() && !nsString::IsSpace(datasources.CharAt(last)))
|
|
|
|
++last;
|
|
|
|
|
|
|
|
nsAutoString uri;
|
|
|
|
datasources.Mid(uri, first, last - first);
|
|
|
|
first = last + 1;
|
|
|
|
|
|
|
|
// A special 'dummy' datasource
|
|
|
|
if (uri.Equals("rdf:null"))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
rv = rdf_MakeAbsoluteURI(docurl, uri);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFDataSource> ds;
|
|
|
|
rv = gRDFService->GetDataSource(nsCAutoString(uri), getter_AddRefs(ds));
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
// This is only a warning because the data source may not
|
|
|
|
// be accessable for any number of reasons, including
|
|
|
|
// security, a bad URL, etc.
|
|
|
|
#ifdef DEBUG
|
|
|
|
nsCAutoString msg;
|
|
|
|
msg += "unable to load datasource '";
|
|
|
|
msg += nsCAutoString(uri);
|
|
|
|
msg += '\'';
|
|
|
|
NS_WARNING((const char*) msg);
|
|
|
|
#endif
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = db->AddDataSource(ds);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add datasource to composite data source");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// add it to the set of builders in use by the document
|
|
|
|
nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(doc);
|
|
|
|
if (! xuldoc)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
rv = xuldoc->AddContentModelBuilder(builder);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add builder to the document");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = builder->SetDataBase(db);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to set builder's database");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-11-02 01:14:07 +00:00
|
|
|
nsCOMPtr<nsIXULContent> xulcontent = do_QueryInterface(aElement);
|
|
|
|
if (xulcontent) {
|
|
|
|
// Mark the XUL element as being lazy, so the template builder
|
|
|
|
// will run when layout first asks for these nodes.
|
|
|
|
//
|
|
|
|
//rv = xulcontent->ClearLazyState(eTemplateContentsBuilt | eContainerContentsBuilt);
|
|
|
|
//if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
xulcontent->SetLazyState(nsIXULContent::eChildrenMustBeRebuilt);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Force construction of immediate template sub-content _now_.
|
|
|
|
rv = builder->CreateContents(aElement);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create template contents");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-02 01:14:07 +00:00
|
|
|
nsresult
|
|
|
|
nsXULDocument::AddPrototypeSheets()
|
|
|
|
{
|
|
|
|
// Add mCurrentPrototype's style sheets to the document.
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupportsArray> sheets;
|
|
|
|
rv = mCurrentPrototype->GetStyleSheetReferences(getter_AddRefs(sheets));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
PRUint32 count;
|
|
|
|
sheets->Count(&count);
|
|
|
|
for (PRUint32 i = 0; i < count; ++i) {
|
1999-11-02 02:02:27 +00:00
|
|
|
nsISupports* isupports = sheets->ElementAt(i);
|
1999-11-02 01:14:07 +00:00
|
|
|
nsCOMPtr<nsIURI> uri = do_QueryInterface(isupports);
|
1999-11-18 02:25:33 +00:00
|
|
|
NS_IF_RELEASE(isupports);
|
1999-11-02 02:02:27 +00:00
|
|
|
|
1999-11-02 01:14:07 +00:00
|
|
|
NS_ASSERTION(uri != nsnull, "not a URI!!!");
|
|
|
|
if (! uri)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
nsCOMPtr<nsICSSStyleSheet> sheet;
|
|
|
|
rv = gXULCache->GetStyleSheet(uri, getter_AddRefs(sheet));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
NS_ASSERTION(sheet != nsnull, "uh oh, sheet wasn't in the cache. go reload it");
|
|
|
|
if (! sheet)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
nsCOMPtr<nsICSSStyleSheet> newsheet;
|
|
|
|
rv = sheet->Clone(*getter_AddRefs(newsheet));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
AddStyleSheet(newsheet);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// nsXULDocument::OverlayForwardReference
|
|
|
|
//
|
|
|
|
|
|
|
|
nsForwardReference::Result
|
|
|
|
nsXULDocument::OverlayForwardReference::Resolve()
|
|
|
|
{
|
|
|
|
// Resolve a forward reference from an overlay element; attempt to
|
|
|
|
// hook it up into the main document.
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsAutoString id;
|
|
|
|
rv = mOverlay->GetAttribute(kNameSpaceID_None, kIdAtom, id);
|
|
|
|
if (NS_FAILED(rv)) return eResolve_Error;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMElement> domtarget;
|
1999-11-08 19:07:13 +00:00
|
|
|
rv = mDocument->GetElementById(id, getter_AddRefs(domtarget));
|
1999-10-29 01:21:15 +00:00
|
|
|
if (NS_FAILED(rv)) return eResolve_Error;
|
|
|
|
|
|
|
|
// If we can't find the element in the document, defer the hookup
|
|
|
|
// until later.
|
|
|
|
if (! domtarget)
|
|
|
|
return eResolve_Later;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> target = do_QueryInterface(domtarget);
|
|
|
|
NS_ASSERTION(target != nsnull, "not an nsIContent");
|
|
|
|
if (! target)
|
|
|
|
return eResolve_Error;
|
|
|
|
|
|
|
|
rv = Merge(target, mOverlay);
|
|
|
|
if (NS_FAILED(rv)) return eResolve_Error;
|
|
|
|
|
|
|
|
PR_LOG(gXULLog, PR_LOG_ALWAYS,
|
|
|
|
("xul: overlay resolved '%s'",
|
|
|
|
(const char*) nsCAutoString(id)));
|
|
|
|
|
|
|
|
mResolved = PR_TRUE;
|
|
|
|
return eResolve_Succeeded;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::OverlayForwardReference::Merge(nsIContent* aTargetNode,
|
|
|
|
nsIContent* aOverlayNode)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
{
|
|
|
|
// Whack the attributes from aOverlayNode onto aTargetNode
|
|
|
|
PRInt32 count;
|
|
|
|
rv = aOverlayNode->GetAttributeCount(count);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
for (PRInt32 i = 0; i < count; ++i) {
|
|
|
|
PRInt32 nameSpaceID;
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
rv = aOverlayNode->GetAttributeNameAt(i, nameSpaceID, *getter_AddRefs(tag));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (nameSpaceID == kNameSpaceID_None && tag.get() == kIdAtom)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
nsAutoString value;
|
|
|
|
rv = aOverlayNode->GetAttribute(nameSpaceID, tag, value);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = aTargetNode->SetAttribute(nameSpaceID, tag, value, PR_FALSE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
// Now move any kids
|
|
|
|
PRInt32 count;
|
|
|
|
rv = aOverlayNode->ChildCount(count);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
for (PRInt32 i = 0; i < count; ++i) {
|
1999-11-08 19:07:13 +00:00
|
|
|
// Remove the child from the temporary "overlay
|
|
|
|
// placeholder" node, and insert into the content model.
|
1999-10-29 01:21:15 +00:00
|
|
|
nsCOMPtr<nsIContent> child;
|
|
|
|
rv = aOverlayNode->ChildAt(0, *getter_AddRefs(child));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = aOverlayNode->RemoveChildAt(0, PR_FALSE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = InsertElement(aTargetNode, child);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
1999-11-08 19:07:13 +00:00
|
|
|
// Add child and any descendants to the element map
|
|
|
|
rv = mDocument->AddSubtreeToDocument(aTargetNode);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
// Now check for a 'datasources' attribute, and build a
|
|
|
|
// template builder if necessary.
|
|
|
|
rv = CheckTemplateBuilder(aTargetNode);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsXULDocument::OverlayForwardReference::~OverlayForwardReference()
|
|
|
|
{
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
if (PR_LOG_TEST(gXULLog, PR_LOG_ALWAYS) && !mResolved) {
|
|
|
|
nsAutoString id;
|
|
|
|
mOverlay->GetAttribute(kNameSpaceID_None, kIdAtom, id);
|
1999-11-18 02:25:33 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
PR_LOG(gXULLog, PR_LOG_ALWAYS,
|
|
|
|
("xul: overlay failed to resolve '%s'",
|
|
|
|
(const char*) nsCAutoString(id)));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// nsXULDocument::BroadcasterHookup
|
|
|
|
//
|
|
|
|
|
|
|
|
nsForwardReference::Result
|
|
|
|
nsXULDocument::BroadcasterHookup::Resolve()
|
1999-11-08 19:07:13 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-11-17 02:45:46 +00:00
|
|
|
|
|
|
|
PRBool listener;
|
|
|
|
rv = CheckBroadcasterHookup(mDocument, mObservesElement, &listener, &mResolved);
|
1999-11-08 19:07:13 +00:00
|
|
|
if (NS_FAILED(rv)) return eResolve_Error;
|
|
|
|
|
|
|
|
return mResolved ? eResolve_Succeeded : eResolve_Later;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsXULDocument::BroadcasterHookup::~BroadcasterHookup()
|
|
|
|
{
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
if (PR_LOG_TEST(gXULLog, PR_LOG_ALWAYS) && !mResolved) {
|
|
|
|
// Tell the world we failed
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
rv = mObservesElement->GetTag(*getter_AddRefs(tag));
|
|
|
|
if (NS_FAILED(rv)) return;
|
|
|
|
|
|
|
|
nsAutoString broadcasterID;
|
|
|
|
nsAutoString attribute;
|
|
|
|
|
|
|
|
if (tag.get() == kObservesAtom) {
|
|
|
|
rv = mObservesElement->GetAttribute(kNameSpaceID_None, kElementAtom, broadcasterID);
|
|
|
|
if (NS_FAILED(rv)) return;
|
|
|
|
|
|
|
|
rv = mObservesElement->GetAttribute(kNameSpaceID_None, kAttributeAtom, attribute);
|
|
|
|
if (NS_FAILED(rv)) return;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = mObservesElement->GetAttribute(kNameSpaceID_None, kObservesAtom, broadcasterID);
|
|
|
|
if (NS_FAILED(rv)) return;
|
|
|
|
|
|
|
|
attribute = "*";
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoString tagStr;
|
|
|
|
rv = tag->ToString(tagStr);
|
|
|
|
if (NS_FAILED(rv)) return;
|
|
|
|
|
|
|
|
PR_LOG(gXULLog, PR_LOG_ALWAYS,
|
|
|
|
("xul: broadcaster hookup failed <%s attribute='%s'> to %s",
|
|
|
|
(const char*) nsCAutoString(tagStr),
|
|
|
|
(const char*) nsCAutoString(attribute),
|
|
|
|
(const char*) nsCAutoString(broadcasterID)));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
|
|
|
|
nsIContent* aElement,
|
1999-11-17 02:45:46 +00:00
|
|
|
PRBool* aNeedsHookup,
|
1999-11-08 19:07:13 +00:00
|
|
|
PRBool* aDidResolve)
|
1999-10-29 01:21:15 +00:00
|
|
|
{
|
|
|
|
// Resolve a broadcaster hookup. Look at the element that we're
|
|
|
|
// trying to resolve: it could be an '<observes>' element, or just
|
|
|
|
// a vanilla element with an 'observes' attribute on it.
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-11-08 19:07:13 +00:00
|
|
|
*aDidResolve = PR_FALSE;
|
|
|
|
|
|
|
|
PRInt32 nameSpaceID;
|
|
|
|
rv = aElement->GetNameSpaceID(nameSpaceID);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
nsCOMPtr<nsIAtom> tag;
|
1999-11-08 19:07:13 +00:00
|
|
|
rv = aElement->GetTag(*getter_AddRefs(tag));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMElement> listener;
|
|
|
|
nsAutoString broadcasterID;
|
|
|
|
nsAutoString attribute;
|
|
|
|
|
1999-11-08 19:07:13 +00:00
|
|
|
if ((nameSpaceID == kNameSpaceID_XUL) && (tag.get() == kObservesAtom)) {
|
1999-10-29 01:21:15 +00:00
|
|
|
// It's an <observes> element, which means that the actual
|
|
|
|
// listener is the _parent_ node. This element should have an
|
|
|
|
// 'element' attribute that specifies the ID of the
|
|
|
|
// broadcaster element, and an 'attribute' element, which
|
|
|
|
// specifies the name of the attribute to observe.
|
|
|
|
nsCOMPtr<nsIContent> parent;
|
1999-11-08 19:07:13 +00:00
|
|
|
rv = aElement->GetParent(*getter_AddRefs(parent));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIAtom> parentTag;
|
|
|
|
rv = parent->GetTag(*getter_AddRefs(parentTag));
|
1999-11-08 19:07:13 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
// If we're still parented by an 'overlay' tag, then we haven't
|
|
|
|
// made it into the real document yet. Defer hookup.
|
1999-11-17 02:45:46 +00:00
|
|
|
if (parentTag.get() == kOverlayAtom) {
|
|
|
|
*aNeedsHookup = PR_TRUE;
|
1999-11-08 19:07:13 +00:00
|
|
|
return NS_OK;
|
1999-11-17 02:45:46 +00:00
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
listener = do_QueryInterface(parent);
|
|
|
|
|
1999-11-08 19:07:13 +00:00
|
|
|
rv = aElement->GetAttribute(kNameSpaceID_None, kElementAtom, broadcasterID);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
1999-11-08 19:07:13 +00:00
|
|
|
rv = aElement->GetAttribute(kNameSpaceID_None, kAttributeAtom, attribute);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 01:21:15 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// It's a generic element, which means that we'll use the
|
|
|
|
// value of the 'observes' attribute to determine the ID of
|
|
|
|
// the broadcaster element, and we'll watch _all_ of its
|
|
|
|
// values.
|
1999-11-08 19:07:13 +00:00
|
|
|
rv = aElement->GetAttribute(kNameSpaceID_None, kObservesAtom, broadcasterID);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// Bail if there's no broadcasterID
|
1999-11-17 02:45:46 +00:00
|
|
|
if ((rv != NS_CONTENT_ATTR_HAS_VALUE) || (broadcasterID.Length() == 0)) {
|
|
|
|
*aNeedsHookup = PR_FALSE;
|
1999-11-08 19:07:13 +00:00
|
|
|
return NS_OK;
|
1999-11-17 02:45:46 +00:00
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
|
1999-11-08 19:07:13 +00:00
|
|
|
listener = do_QueryInterface(aElement);
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
attribute = "*";
|
|
|
|
}
|
|
|
|
|
1999-11-04 18:37:58 +00:00
|
|
|
// Make sure we got a valid listener.
|
|
|
|
NS_ASSERTION(listener != nsnull, "no listener");
|
|
|
|
if (! listener)
|
1999-11-08 19:07:13 +00:00
|
|
|
return NS_ERROR_UNEXPECTED;
|
1999-11-04 18:37:58 +00:00
|
|
|
|
1999-10-29 01:21:15 +00:00
|
|
|
// Try to find the broadcaster element in the document.
|
|
|
|
nsCOMPtr<nsIDOMElement> target;
|
1999-11-08 19:07:13 +00:00
|
|
|
rv = aDocument->GetElementById(broadcasterID, getter_AddRefs(target));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
// If we can't find the broadcaster, then we'll need to defer the
|
|
|
|
// hookup. We may need to resolve some of the other overlays
|
|
|
|
// first.
|
1999-11-17 02:45:46 +00:00
|
|
|
if (! target) {
|
|
|
|
*aNeedsHookup = PR_TRUE;
|
1999-11-08 19:07:13 +00:00
|
|
|
return NS_OK;
|
1999-11-17 02:45:46 +00:00
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMXULElement> broadcaster = do_QueryInterface(target);
|
1999-11-17 02:45:46 +00:00
|
|
|
if (! broadcaster) {
|
|
|
|
*aNeedsHookup = PR_FALSE;
|
1999-11-08 19:07:13 +00:00
|
|
|
return NS_OK; // not a XUL element, so we can't subscribe
|
1999-11-17 02:45:46 +00:00
|
|
|
}
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
rv = broadcaster->AddBroadcastListener(attribute, listener);
|
1999-11-08 19:07:13 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
// Tell the world we succeeded
|
|
|
|
if (PR_LOG_TEST(gXULLog, PR_LOG_ALWAYS)) {
|
|
|
|
nsCOMPtr<nsIContent> content =
|
|
|
|
do_QueryInterface(listener);
|
|
|
|
|
|
|
|
NS_ASSERTION(content != nsnull, "not an nsIContent");
|
|
|
|
if (! content)
|
1999-11-08 19:07:13 +00:00
|
|
|
return rv;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIAtom> tag2;
|
|
|
|
rv = content->GetTag(*getter_AddRefs(tag2));
|
1999-11-08 19:07:13 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
nsAutoString tagStr;
|
|
|
|
rv = tag2->ToString(tagStr);
|
1999-11-08 19:07:13 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 01:21:15 +00:00
|
|
|
|
|
|
|
PR_LOG(gXULLog, PR_LOG_ALWAYS,
|
|
|
|
("xul: broadcaster hookup <%s attribute='%s'> to %s",
|
|
|
|
(const char*) nsCAutoString(tagStr),
|
|
|
|
(const char*) nsCAutoString(attribute),
|
|
|
|
(const char*) nsCAutoString(broadcasterID)));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1999-11-17 02:45:46 +00:00
|
|
|
*aNeedsHookup = PR_FALSE;
|
1999-11-08 19:07:13 +00:00
|
|
|
*aDidResolve = PR_TRUE;
|
|
|
|
return NS_OK;
|
1999-10-29 01:21:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsXULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild)
|
|
|
|
{
|
|
|
|
// Insert aChild appropriately into aParent, accountinf for a
|
|
|
|
// 'pos' attribute set on aChild.
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsAutoString posStr;
|
|
|
|
rv = aChild->GetAttribute(kNameSpaceID_None, kPositionAtom, posStr);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
PRBool wasInserted = PR_FALSE;
|
|
|
|
|
|
|
|
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
|
|
|
|
// Positions are one-indexed.
|
|
|
|
PRInt32 pos = posStr.ToInteger(NS_REINTERPRET_CAST(PRInt32*, &rv));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
rv = aParent->InsertChildAt(aChild, pos - 1, PR_FALSE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
wasInserted = PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! wasInserted) {
|
|
|
|
rv = aParent->AppendChildTo(aChild, PR_FALSE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-02 01:14:07 +00:00
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsXULDocument::IsChromeURI(nsIURI* aURI)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsXPIDLCString protocol;
|
|
|
|
rv = aURI->GetScheme(getter_Copies(protocol));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
if (PL_strcmp(protocol, "chrome") == 0) {
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
1999-11-24 22:46:09 +00:00
|
|
|
|
2000-01-19 03:11:39 +00:00
|
|
|
void
|
|
|
|
nsXULDocument::GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsAutoString nameSpace;
|
|
|
|
gNameSpaceManager->GetNameSpaceURI(aNameSpaceID, nameSpace);
|
|
|
|
|
|
|
|
nsCAutoString progID = NS_ELEMENT_FACTORY_PROGID_PREFIX;
|
|
|
|
progID += nameSpace;
|
|
|
|
|
|
|
|
// Retrieve the appropriate factory.
|
|
|
|
NS_WITH_SERVICE(nsIElementFactory, elementFactory, progID, &rv);
|
|
|
|
|
|
|
|
if (!elementFactory)
|
|
|
|
elementFactory = gXMLElementFactory; // Nothing found. Use generic XML element.
|
|
|
|
|
|
|
|
*aResult = elementFactory;
|
|
|
|
NS_IF_ADDREF(*aResult);
|
|
|
|
}
|
|
|
|
|
1999-11-24 22:46:09 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-12-04 07:45:57 +00:00
|
|
|
// CachedChromeStreamListener
|
1999-11-24 22:46:09 +00:00
|
|
|
//
|
|
|
|
|
1999-12-04 07:45:57 +00:00
|
|
|
nsXULDocument::CachedChromeStreamListener::CachedChromeStreamListener(nsXULDocument* aDocument)
|
|
|
|
: mDocument(aDocument)
|
1999-11-24 22:46:09 +00:00
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
1999-12-04 07:45:57 +00:00
|
|
|
NS_ADDREF(mDocument);
|
1999-11-24 22:46:09 +00:00
|
|
|
}
|
|
|
|
|
1999-12-04 07:45:57 +00:00
|
|
|
|
|
|
|
nsXULDocument::CachedChromeStreamListener::~CachedChromeStreamListener()
|
1999-11-24 22:46:09 +00:00
|
|
|
{
|
|
|
|
NS_RELEASE(mDocument);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-12-04 07:45:57 +00:00
|
|
|
NS_IMPL_ISUPPORTS2(nsXULDocument::CachedChromeStreamListener, nsIStreamObserver, nsIStreamListener);
|
1999-11-24 22:46:09 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-12-04 07:45:57 +00:00
|
|
|
nsXULDocument::CachedChromeStreamListener::OnStartRequest(nsIChannel* aChannel, nsISupports* acontext)
|
1999-11-24 22:46:09 +00:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-12-04 07:45:57 +00:00
|
|
|
nsXULDocument::CachedChromeStreamListener::OnStopRequest(nsIChannel* aChannel,
|
|
|
|
nsISupports* aContext,
|
|
|
|
nsresult aStatus,
|
|
|
|
const PRUnichar* aErrorMsg)
|
1999-11-24 22:46:09 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-12-04 07:45:57 +00:00
|
|
|
rv = mDocument->PrepareToWalk();
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to prepare for walk");
|
1999-11-24 22:46:09 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-12-04 07:45:57 +00:00
|
|
|
return mDocument->ResumeWalk();
|
|
|
|
}
|
1999-11-24 22:46:09 +00:00
|
|
|
|
|
|
|
|
1999-12-04 07:45:57 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsXULDocument::CachedChromeStreamListener::OnDataAvailable(nsIChannel* aChannel,
|
|
|
|
nsISupports* aContext,
|
|
|
|
nsIInputStream* aInStr,
|
|
|
|
PRUint32 aSourceOffset,
|
|
|
|
PRUint32 aCount)
|
|
|
|
{
|
|
|
|
NS_NOTREACHED("CachedChromeStream doesn't receive data");
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
1999-11-24 22:46:09 +00:00
|
|
|
}
|
2000-01-19 03:28:06 +00:00
|
|
|
|
|
|
|
// The XUL element factory
|
|
|
|
|
|
|
|
class XULElementFactoryImpl : public nsIElementFactory
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
XULElementFactoryImpl();
|
|
|
|
virtual ~XULElementFactoryImpl();
|
|
|
|
|
|
|
|
public:
|
|
|
|
friend
|
|
|
|
nsresult
|
|
|
|
NS_NewXULElementFactory(nsIElementFactory** aResult);
|
|
|
|
|
|
|
|
// nsISupports interface
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// nsIElementFactory interface
|
|
|
|
NS_IMETHOD CreateInstanceByTag(const nsString& aTag, nsIContent** aResult);
|
|
|
|
|
|
|
|
static PRUint32 gRefCnt;
|
|
|
|
static PRInt32 kNameSpaceID_XUL;
|
|
|
|
static nsINameSpaceManager* gNameSpaceManager;
|
|
|
|
};
|
|
|
|
|
|
|
|
PRUint32 XULElementFactoryImpl::gRefCnt = 0;
|
|
|
|
PRInt32 XULElementFactoryImpl::kNameSpaceID_XUL;
|
|
|
|
nsINameSpaceManager* XULElementFactoryImpl::gNameSpaceManager = nsnull;
|
|
|
|
|
|
|
|
XULElementFactoryImpl::XULElementFactoryImpl()
|
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
gRefCnt++;
|
|
|
|
if (gRefCnt == 1) {
|
|
|
|
nsresult rv = nsServiceManager::GetService(kNameSpaceManagerCID,
|
|
|
|
NS_GET_IID(nsINameSpaceManager),
|
|
|
|
(nsISupports**) &gNameSpaceManager);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get namespace manager");
|
|
|
|
if (NS_FAILED(rv)) return;
|
|
|
|
|
|
|
|
#define XUL_NAMESPACE_URI "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
|
|
static const char kXULNameSpaceURI[] = XUL_NAMESPACE_URI;
|
|
|
|
gNameSpaceManager->RegisterNameSpace(kXULNameSpaceURI, kNameSpaceID_XUL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
XULElementFactoryImpl::~XULElementFactoryImpl()
|
|
|
|
{
|
|
|
|
gRefCnt--;
|
|
|
|
if (gRefCnt == 0) {
|
|
|
|
NS_IF_RELEASE(gNameSpaceManager);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS(XULElementFactoryImpl, NS_GET_IID(nsIElementFactory));
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
NS_NewXULElementFactory(nsIElementFactory** aResult)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
|
|
|
if (! aResult)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
XULElementFactoryImpl* result = new XULElementFactoryImpl();
|
|
|
|
if (! result)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
NS_ADDREF(result);
|
|
|
|
*aResult = result;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
XULElementFactoryImpl::CreateInstanceByTag(const nsString& aTag, nsIContent** aResult)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIAtom> tag = dont_AddRef(NS_NewAtom(aTag));
|
|
|
|
if (! tag)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
return nsXULElement::Create(kNameSpaceID_XUL, tag, aResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|