From 991f41cbc8e56a61bd6c8c0aef3897416e6be012 Mon Sep 17 00:00:00 2001 From: "waterson%netscape.com" Date: Tue, 9 Feb 1999 03:15:41 +0000 Subject: [PATCH] Whacked to get RDF/XUL working right, with local content mderged in. git-svn-id: svn://10.0.0.236/trunk@20079 18797224-902f-48f8-a5cc-f745e15eee43 --- .../xul/document/src/nsXULDocument.cpp} | 884 +++---- mozilla/rdf/base/public/nsIRDFXMLDataSource.h | 16 - mozilla/rdf/base/src/Makefile.in | 1 - mozilla/rdf/base/src/makefile.win | 1 - mozilla/rdf/base/src/nsRDFContentSink.cpp | 15 - mozilla/rdf/base/src/nsRDFXMLDataSource.cpp | 23 - mozilla/rdf/build/makefile.win | 6 +- mozilla/rdf/build/nsRDFCID.h | 8 +- mozilla/rdf/build/nsRDFFactory.cpp | 49 +- .../public/nsIRDFContentModelBuilder.h | 32 +- mozilla/rdf/content/public/nsIRDFDocument.h | 48 +- mozilla/rdf/content/src/Makefile.in | 7 +- mozilla/rdf/content/src/makefile.win | 8 +- mozilla/rdf/content/src/nsRDFHTMLBuilder.cpp | 97 +- .../rdf/content/src/nsRDFResourceElement.cpp | 29 +- mozilla/rdf/content/src/nsRDFTreeBuilder.cpp | 775 +++--- mozilla/rdf/content/src/nsRDFXULBuilder.cpp | 429 +++- mozilla/rdf/content/src/nsXULDocument.cpp | 2198 +++++++++++++++++ mozilla/rdf/datasource/src/Makefile.in | 3 +- mozilla/rdf/datasource/src/makefile.win | 3 +- .../datasource/src/nsBookmarkDataSource.cpp | 20 +- .../src/nsXULContentSink.cpp | 25 +- .../rdf/datasource/src/nsXULDataSource.cpp | 23 - mozilla/rdf/macbuild/rdf.mcp | Bin 69686 -> 69686 bytes mozilla/rdf/macbuild/rdf.toc | 2 + 25 files changed, 3600 insertions(+), 1102 deletions(-) rename mozilla/{rdf/content/src/nsRDFDocument.cpp => content/xul/document/src/nsXULDocument.cpp} (77%) create mode 100644 mozilla/rdf/content/src/nsXULDocument.cpp rename mozilla/rdf/{base => datasource}/src/nsXULContentSink.cpp (98%) diff --git a/mozilla/rdf/content/src/nsRDFDocument.cpp b/mozilla/content/xul/document/src/nsXULDocument.cpp similarity index 77% rename from mozilla/rdf/content/src/nsRDFDocument.cpp rename to mozilla/content/xul/document/src/nsXULDocument.cpp index 9227c5e209f..fbacb2e2d7d 100644 --- a/mozilla/rdf/content/src/nsRDFDocument.cpp +++ b/mozilla/content/xul/document/src/nsXULDocument.cpp @@ -53,7 +53,6 @@ #include "nsIRDFDataSource.h" #include "nsIRDFDocument.h" #include "nsIRDFNode.h" -#include "nsIRDFObserver.h" #include "nsIRDFService.h" #include "nsIRDFXMLDataSource.h" #include "nsIScriptContextOwner.h" @@ -117,28 +116,182 @@ static NS_DEFINE_CID(kRDFXULBuilderCID, NS_RDFXULBUILDER_CID); //////////////////////////////////////////////////////////////////////// -static PLHashNumber -rdf_HashPointer(const void* key) -{ - return (PLHashNumber) key; -} - enum nsContentType { TEXT_RDF, TEXT_XUL, }; //////////////////////////////////////////////////////////////////////// +// nsElementMap -class RDFDocumentImpl : public nsIDocument, +class nsElementMap +{ +private: + PLHashTable* mResources; + + class ContentListItem { + public: + ContentListItem(nsIContent* aContent) + : mNext(nsnull), mContent(aContent) {} + + ContentListItem* mNext; + nsIContent* mContent; + }; + + static PLHashNumber + HashPointer(const void* key) + { + return (PLHashNumber) key; + } + + static PRIntn + ReleaseContentList(PLHashEntry* he, PRIntn index, void* closure) + { + ContentListItem* head = + (ContentListItem*) he->value; + + while (head) { + ContentListItem* doomed = head; + head = head->mNext; + delete doomed; + } + + return HT_ENUMERATE_NEXT; + } + +public: + nsElementMap(void) + { + // Create a table for mapping RDF resources to elements in the + // content tree. + static PRInt32 kInitialResourceTableSize = 1023; + if ((mResources = PL_NewHashTable(kInitialResourceTableSize, + HashPointer, + PL_CompareValues, + PL_CompareValues, + nsnull, + nsnull)) == nsnull) { + NS_ERROR("could not create hash table for resources"); + } + } + + virtual ~nsElementMap() + { + if (mResources) { + PL_HashTableEnumerateEntries(mResources, ReleaseContentList, nsnull); + PL_HashTableDestroy(mResources); + } + } + + nsresult + Add(nsIRDFResource* aResource, nsIContent* aContent) + { + NS_PRECONDITION(mResources != nsnull, "not initialized"); + if (! mResources) + return NS_ERROR_NOT_INITIALIZED; + + ContentListItem* head = + (ContentListItem*) PL_HashTableLookup(mResources, aResource); + + if (! head) { + head = new ContentListItem(aContent); + if (! head) + return NS_ERROR_OUT_OF_MEMORY; + + PL_HashTableAdd(mResources, aResource, head); + } + else { + while (1) { + if (head->mContent == aContent) { + NS_ERROR("attempt to add same element twice"); + return NS_ERROR_ILLEGAL_VALUE; + } + if (! head->mNext) + break; + + head = head->mNext; + } + + head->mNext = new ContentListItem(aContent); + if (! head->mNext) + return NS_ERROR_OUT_OF_MEMORY; + } + + return NS_OK; + } + + nsresult + Remove(nsIRDFResource* aResource, nsIContent* aContent) + { + NS_PRECONDITION(mResources != nsnull, "not initialized"); + if (! mResources) + return NS_ERROR_NOT_INITIALIZED; + + ContentListItem* head = + (ContentListItem*) PL_HashTableLookup(mResources, aResource); + + if (head) { + if (head->mContent == aContent) { + ContentListItem* newHead = head->mNext; + if (newHead) { + PL_HashTableAdd(mResources, aResource, newHead); + } + else { + PL_HashTableRemove(mResources, aResource); + } + delete head; + return NS_OK; + } + else { + ContentListItem* doomed = head->mNext; + while (doomed) { + if (doomed->mContent == aContent) { + head->mNext = doomed->mNext; + delete doomed; + return NS_OK; + } + head = doomed; + doomed = doomed->mNext; + } + } + } + + NS_ERROR("attempt to remove an element that was never added"); + return NS_ERROR_ILLEGAL_VALUE; + } + + nsresult + Find(nsIRDFResource* aResource, nsISupportsArray* aResults) + { + NS_PRECONDITION(mResources != nsnull, "not initialized"); + if (! mResources) + return NS_ERROR_NOT_INITIALIZED; + + aResults->Clear(); + ContentListItem* head = + (ContentListItem*) PL_HashTableLookup(mResources, aResource); + + while (head) { + aResults->AppendElement(head->mContent); + head = head->mNext; + } + return NS_OK; + } +}; + + + +//////////////////////////////////////////////////////////////////////// +// XULDocumentImpl + +class XULDocumentImpl : public nsIDocument, public nsIRDFDocument, - public nsIRDFObserver, public nsIRDFXMLDataSourceObserver, public nsIHTMLContentContainer { public: - RDFDocumentImpl(); - virtual ~RDFDocumentImpl(); + XULDocumentImpl(); + virtual ~XULDocumentImpl(); // nsISupports interface NS_DECL_ISUPPORTS @@ -300,25 +453,13 @@ public: // nsIRDFDocument interface NS_IMETHOD SetContentType(const char* aContentType); - NS_IMETHOD SetContentModelBuilder(nsIRDFContentModelBuilder* aBuilder); - NS_IMETHOD GetContentModelBuilder(nsIRDFContentModelBuilder** aBuilder); NS_IMETHOD SetRootResource(nsIRDFResource* resource); - NS_IMETHOD GetDataBase(nsIRDFCompositeDataSource*& result); - NS_IMETHOD AddTreeProperty(nsIRDFResource* resource); - NS_IMETHOD RemoveTreeProperty(nsIRDFResource* resource); - NS_IMETHOD IsTreeProperty(nsIRDFResource* aProperty, PRBool* aResult) const; - NS_IMETHOD MapResource(nsIRDFResource* aResource, nsIRDFContent* aContent); - NS_IMETHOD UnMapResource(nsIRDFResource* aResource, nsIRDFContent* aContent); NS_IMETHOD SplitProperty(nsIRDFResource* aResource, PRInt32* aNameSpaceID, nsIAtom** aTag); - - // nsIRDFObserver interface - NS_IMETHOD OnAssert(nsIRDFResource* subject, - nsIRDFResource* predicate, - nsIRDFNode* object); - - NS_IMETHOD OnUnassert(nsIRDFResource* subject, - nsIRDFResource* predicate, - nsIRDFNode* object); + NS_IMETHOD AddElementForResource(nsIRDFResource* aResource, nsIRDFContent* aElement); + NS_IMETHOD RemoveElementForResource(nsIRDFResource* aResource, nsIRDFContent* aElement); + NS_IMETHOD GetElementsForResource(nsIRDFResource* aResource, nsISupportsArray* aElements); + NS_IMETHOD CreateContents(nsIRDFContent* aElement); + NS_IMETHOD AddContentModelBuilder(nsIRDFContentModelBuilder* aBuilder); // nsIRDFXMLDataSourceObserver interface NS_IMETHOD OnBeginLoad(nsIRDFXMLDataSource* aDataSource); @@ -329,12 +470,10 @@ public: NS_IMETHOD OnRootResourceFound(nsIRDFXMLDataSource* aDataSource, nsIRDFResource* aResource); NS_IMETHOD OnCSSStyleSheetAdded(nsIRDFXMLDataSource* aDataSource, nsIURL* aStyleSheetURI); NS_IMETHOD OnNamedDataSourceAdded(nsIRDFXMLDataSource* aDataSource, const char* aNamedDataSourceURI); - NS_IMETHOD OnContentModelBuilderSpecified(nsIRDFXMLDataSource* aDataSource, nsID* aCID); // Implementation methods nsresult Init(void); nsresult StartLayout(void); - nsresult SetContentModelBuilderFromCID(nsID& aCID); protected: nsIContent* @@ -365,11 +504,10 @@ protected: nsINameSpaceManager* mNameSpaceManager; nsIHTMLStyleSheet* mAttrStyleSheet; nsIHTMLCSSStyleSheet* mInlineStyleSheet; - nsIRDFCompositeDataSource* mDB; nsIRDFService* mRDFService; - nsISupportsArray* mTreeProperties; - nsIRDFContentModelBuilder* mBuilder; - PLHashTable* mResources; + nsElementMap mResources; + nsISupportsArray* mBuilders; + nsIRDFContentModelBuilder* mXULBuilder; nsIRDFDataSource* mLocalDataSource; nsIRDFXMLDataSource* mDocumentDataSource; @@ -387,11 +525,11 @@ protected: class DummyListener : public nsIStreamListener { private: - RDFDocumentImpl* mRDFDocument; + XULDocumentImpl* mRDFDocument; PRBool mWasNotifiedOnce; // XXX why do we get _two_ OnStart/StopBinding() calls? public: - DummyListener(RDFDocumentImpl* aRDFDocument) + DummyListener(XULDocumentImpl* aRDFDocument) : mRDFDocument(aRDFDocument), mWasNotifiedOnce(PR_FALSE) { @@ -470,10 +608,11 @@ DummyListener::QueryInterface(REFNSIID aIID, void** aResult) } } + //////////////////////////////////////////////////////////////////////// // ctors & dtors -RDFDocumentImpl::RDFDocumentImpl(void) +XULDocumentImpl::XULDocumentImpl(void) : mArena(nsnull), mDocumentURL(nsnull), mDocumentURLGroup(nsnull), @@ -484,11 +623,9 @@ RDFDocumentImpl::RDFDocumentImpl(void) mDisplaySelection(PR_FALSE), mNameSpaceManager(nsnull), mAttrStyleSheet(nsnull), - mDB(nsnull), mRDFService(nsnull), - mTreeProperties(nsnull), - mBuilder(nsnull), - mResources(nsnull), + mBuilders(nsnull), + mXULBuilder(nsnull), mLocalDataSource(nsnull), mDocumentDataSource(nsnull), mContentType(TEXT_RDF) @@ -507,7 +644,7 @@ RDFDocumentImpl::RDFDocumentImpl(void) } -RDFDocumentImpl::~RDFDocumentImpl() +XULDocumentImpl::~XULDocumentImpl() { if (mDocumentDataSource) { mDocumentDataSource->RemoveXMLStreamObserver(this); @@ -515,25 +652,18 @@ RDFDocumentImpl::~RDFDocumentImpl() } NS_IF_RELEASE(mLocalDataSource); - if (mResources) - PL_HashTableDestroy(mResources); - if (mRDFService) { nsServiceManager::ReleaseService(kRDFServiceCID, mRDFService); mRDFService = nsnull; } // mParentDocument is never refcounted - NS_IF_RELEASE(mBuilder); + NS_IF_RELEASE(mBuilders); + NS_IF_RELEASE(mXULBuilder); NS_IF_RELEASE(mSelection); NS_IF_RELEASE(mScriptContextOwner); NS_IF_RELEASE(mAttrStyleSheet); - NS_IF_RELEASE(mTreeProperties); NS_IF_RELEASE(mRootContent); - if (mDB) { - mDB->RemoveObserver(this); - NS_RELEASE(mDB); - } NS_IF_RELEASE(mDocumentURLGroup); NS_IF_RELEASE(mDocumentURL); NS_IF_RELEASE(mArena); @@ -544,7 +674,7 @@ RDFDocumentImpl::~RDFDocumentImpl() // nsISupports interface NS_IMETHODIMP -RDFDocumentImpl::QueryInterface(REFNSIID iid, void** result) +XULDocumentImpl::QueryInterface(REFNSIID iid, void** result) { if (! result) return NS_ERROR_NULL_POINTER; @@ -570,21 +700,21 @@ RDFDocumentImpl::QueryInterface(REFNSIID iid, void** result) return NS_NOINTERFACE; } -NS_IMPL_ADDREF(RDFDocumentImpl); -NS_IMPL_RELEASE(RDFDocumentImpl); +NS_IMPL_ADDREF(XULDocumentImpl); +NS_IMPL_RELEASE(XULDocumentImpl); //////////////////////////////////////////////////////////////////////// // nsIDocument interface nsIArena* -RDFDocumentImpl::GetArena() +XULDocumentImpl::GetArena() { NS_IF_ADDREF(mArena); return mArena; } NS_IMETHODIMP -RDFDocumentImpl::StartDocumentLoad(nsIURL *aURL, +XULDocumentImpl::StartDocumentLoad(nsIURL *aURL, nsIContentViewerContainer* aContainer, nsIStreamListener **aDocListener, const char* aCommand) @@ -595,6 +725,15 @@ RDFDocumentImpl::StartDocumentLoad(nsIURL *aURL, nsresult rv; + mDocumentTitle.Truncate(); + + NS_IF_RELEASE(mDocumentURL); + mDocumentURL = aURL; + NS_ADDREF(aURL); + + NS_IF_RELEASE(mDocumentURLGroup); + (void)aURL->GetURLGroup(&mDocumentURLGroup); + // Delete references to style sheets - this should be done in superclass... PRInt32 index = mStyleSheets.Count(); while (--index >= 0) { @@ -604,15 +743,6 @@ RDFDocumentImpl::StartDocumentLoad(nsIURL *aURL, } mStyleSheets.Clear(); - NS_IF_RELEASE(mDocumentURL); - NS_IF_RELEASE(mDocumentURLGroup); - mDocumentTitle.Truncate(); - - mDocumentURL = aURL; - NS_ADDREF(aURL); - - (void)aURL->GetURLGroup(&mDocumentURLGroup); - // Create an HTML style sheet for the HTML content. nsIHTMLStyleSheet* sheet; if (NS_SUCCEEDED(rv = nsRepository::CreateInstance(kHTMLStyleSheetCID, @@ -631,6 +761,38 @@ RDFDocumentImpl::StartDocumentLoad(nsIURL *aURL, if (NS_FAILED(rv)) return rv; + // Create a composite data source that'll tie together local and + // remote stores. + nsIRDFCompositeDataSource* db; + if (NS_FAILED(rv = nsRepository::CreateInstance(kRDFCompositeDataSourceCID, + nsnull, + kIRDFCompositeDataSourceIID, + (void**) &db))) { + NS_ERROR("couldn't create composite datasource"); + return rv; + } + + // Create a XUL content model builder + NS_IF_RELEASE(mXULBuilder); + if (NS_FAILED(rv = nsRepository::CreateInstance(kRDFXULBuilderCID, + nsnull, + kIRDFContentModelBuilderIID, + (void**) &mXULBuilder))) { + NS_ERROR("couldn't create XUL builder"); + return rv; + } + + if (NS_FAILED(rv = mXULBuilder->SetDataBase(db))) { + NS_ERROR("couldn't set builder's db"); + return rv; + } + + NS_IF_RELEASE(mBuilders); + if (NS_FAILED(rv = AddContentModelBuilder(mXULBuilder))) { + NS_ERROR("could't add XUL builder"); + return rv; + } + // Create a "scratch" in-memory data store to associate with the // document to be a catch-all for any doc-specific info that we // need to store (e.g., current sort order, etc.) @@ -641,34 +803,42 @@ RDFDocumentImpl::StartDocumentLoad(nsIURL *aURL, if (NS_FAILED(rv = nsRepository::CreateInstance(kRDFInMemoryDataSourceCID, nsnull, kIRDFDataSourceIID, - (void**) &mLocalDataSource))) + (void**) &mLocalDataSource))) { + NS_ERROR("couldn't create local data source"); return rv; + } - if (NS_FAILED(rv = mDB->AddDataSource(mLocalDataSource))) - return rv; - - const char* uri; - if (NS_FAILED(rv = aURL->GetSpec(&uri))) + if (NS_FAILED(rv = db->AddDataSource(mLocalDataSource))) { + NS_ERROR("couldn't add local data source to db"); return rv; + } // Now load the actual RDF/XML document data source. First, we'll // see if the data source has been loaded and is registered with // the RDF service. If so, do some monkey business to "pretend" to // load it: really, we'll just walk its graph to generate the // content model. + const char* uri; + if (NS_FAILED(rv = aURL->GetSpec(&uri))) + return rv; + nsIRDFDataSource* ds; if (NS_SUCCEEDED(rv = mRDFService->GetDataSource(uri, &ds))) { // Add the RDF/XML data source to our composite data source + NS_IF_RELEASE(mDocumentDataSource); if (NS_FAILED(rv = ds->QueryInterface(kIRDFXMLDataSourceIID, (void**) &mDocumentDataSource))) { + NS_ERROR("unable to get RDF/XML interface to remote datasource"); NS_RELEASE(ds); return rv; } NS_RELEASE(ds); - if (NS_FAILED(rv = mDB->AddDataSource(mDocumentDataSource))) + if (NS_FAILED(rv = db->AddDataSource(mDocumentDataSource))) { + NS_ERROR("unable to add remote data source to db"); return rv; + } // we found the data source already loaded locally. Load it's // style sheets and attempt to include any named data sources @@ -694,17 +864,6 @@ RDFDocumentImpl::StartDocumentLoad(nsIURL *aURL, } } - nsID cid; - if (NS_SUCCEEDED(rv = mDocumentDataSource->GetContentModelBuilderCID(&cid))) { - SetContentModelBuilderFromCID(cid); - - nsIRDFResource* root; - if (NS_SUCCEEDED(rv = mDocumentDataSource->GetRootResource(&root))) { - SetRootResource(root); - StartLayout(); - } - } - // XXX Allright, this is an atrocious hack. Basically, we // construct a dummy listener object so that we can load the // URL, which allows us to receive StartLayout() and EndLoad() @@ -739,55 +898,25 @@ RDFDocumentImpl::StartDocumentLoad(nsIURL *aURL, } } else { - // We need to create either a serialized RDF/XML data source, - // or we need to make a XUL data source. Both of these data - // sources implement the nsIRDFXMLDataSource interface, which - // has to do with handling aspects of XML. - - if (mContentType == TEXT_RDF) { - rv = nsRepository::CreateInstance(kRDFXMLDataSourceCID, - nsnull, - kIRDFXMLDataSourceIID, - (void**) &mDocumentDataSource); - } - else if (mContentType == TEXT_XUL) { - rv = nsRepository::CreateInstance(kXULDataSourceCID, - nsnull, - kIRDFXMLDataSourceIID, - (void**) &mDocumentDataSource); - - NS_VERIFY(NS_SUCCEEDED(rv), "unable to create XUL datasource"); - - nsIRDFContentModelBuilder* builder; - rv = nsRepository::CreateInstance(kRDFXULBuilderCID, - nsnull, - kIRDFContentModelBuilderIID, - (void**) &builder); - - NS_VERIFY(NS_SUCCEEDED(rv), "unable to create XUL content model builder"); - - rv = SetContentModelBuilder(builder); - NS_VERIFY(NS_SUCCEEDED(rv), "unable to set document content model builder"); - } - else { - NS_ERROR("unknown content type"); - } - - if (rv != NS_OK) { - // an error occurred, and we have nothing. - NS_ERROR("problem constructing data source"); - return rv; - } - - if (NS_FAILED(rv = mDB->AddDataSource(mDocumentDataSource))) - return rv; - // We need to construct a new stream and load it. The stream // will automagically register itself as a named data source, // so if subsequent docs ask for it, they'll get the real // deal. In the meantime, add us as an // nsIRDFXMLDataSourceObserver so that we'll be notified when we // need to load style sheets, etc. + NS_IF_RELEASE(mDocumentDataSource); + if (NS_FAILED(rv = nsRepository::CreateInstance(kXULDataSourceCID, + nsnull, + kIRDFXMLDataSourceIID, + (void**) &mDocumentDataSource))) { + NS_ERROR("unable to create XUL datasource"); + return rv; + } + + if (NS_FAILED(rv = db->AddDataSource(mDocumentDataSource))) { + NS_ERROR("unable to add XUL datasource to db"); + return rv; + } nsIRDFXMLDataSource* doc; if (NS_SUCCEEDED(rv = mDocumentDataSource->QueryInterface(kIRDFXMLDataSourceIID, @@ -795,10 +924,16 @@ RDFDocumentImpl::StartDocumentLoad(nsIURL *aURL, doc->AddXMLStreamObserver(this); NS_RELEASE(doc); } + else { + NS_ERROR("unable to add self as stream observer on XUL datasource"); + } - if (NS_FAILED(rv = mDocumentDataSource->Init(uri))) + if (NS_FAILED(rv = mDocumentDataSource->Init(uri))) { + NS_ERROR("unable to initialize XUL data source"); return rv; + } + // XXX huh? if (aDocListener) { *aDocListener = nsnull; } @@ -808,27 +943,27 @@ RDFDocumentImpl::StartDocumentLoad(nsIURL *aURL, } const nsString* -RDFDocumentImpl::GetDocumentTitle() const +XULDocumentImpl::GetDocumentTitle() const { return &mDocumentTitle; } nsIURL* -RDFDocumentImpl::GetDocumentURL() const +XULDocumentImpl::GetDocumentURL() const { NS_IF_ADDREF(mDocumentURL); return mDocumentURL; } nsIURLGroup* -RDFDocumentImpl::GetDocumentURLGroup() const +XULDocumentImpl::GetDocumentURLGroup() const { NS_IF_ADDREF(mDocumentURLGroup); return mDocumentURLGroup; } NS_IMETHODIMP -RDFDocumentImpl::GetBaseURL(nsIURL*& aURL) const +XULDocumentImpl::GetBaseURL(nsIURL*& aURL) const { NS_IF_ADDREF(mDocumentURL); aURL = mDocumentURL; @@ -836,32 +971,32 @@ RDFDocumentImpl::GetBaseURL(nsIURL*& aURL) const } nsString* -RDFDocumentImpl::GetDocumentCharacterSet() const +XULDocumentImpl::GetDocumentCharacterSet() const { return mCharSetID; } void -RDFDocumentImpl::SetDocumentCharacterSet(nsString* aCharSetID) +XULDocumentImpl::SetDocumentCharacterSet(nsString* aCharSetID) { mCharSetID = aCharSetID; } NS_IMETHODIMP -RDFDocumentImpl::GetHeaderData(nsIAtom* aHeaderField, nsString& aData) const +XULDocumentImpl::GetHeaderData(nsIAtom* aHeaderField, nsString& aData) const { return NS_OK; } NS_IMETHODIMP -RDFDocumentImpl:: SetHeaderData(nsIAtom* aheaderField, const nsString& aData) +XULDocumentImpl:: SetHeaderData(nsIAtom* aheaderField, const nsString& aData) { return NS_OK; } nsresult -RDFDocumentImpl::CreateShell(nsIPresContext* aContext, +XULDocumentImpl::CreateShell(nsIPresContext* aContext, nsIViewManager* aViewManager, nsIStyleSet* aStyleSet, nsIPresShell** aInstancePtrResult) @@ -891,19 +1026,19 @@ RDFDocumentImpl::CreateShell(nsIPresContext* aContext, } PRBool -RDFDocumentImpl::DeleteShell(nsIPresShell* aShell) +XULDocumentImpl::DeleteShell(nsIPresShell* aShell) { return mPresShells.RemoveElement(aShell); } PRInt32 -RDFDocumentImpl::GetNumberOfShells() +XULDocumentImpl::GetNumberOfShells() { return mPresShells.Count(); } nsIPresShell* -RDFDocumentImpl::GetShellAt(PRInt32 aIndex) +XULDocumentImpl::GetShellAt(PRInt32 aIndex) { nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[aIndex]); NS_IF_ADDREF(shell); @@ -911,14 +1046,14 @@ RDFDocumentImpl::GetShellAt(PRInt32 aIndex) } nsIDocument* -RDFDocumentImpl::GetParentDocument() +XULDocumentImpl::GetParentDocument() { NS_IF_ADDREF(mParentDocument); return mParentDocument; } void -RDFDocumentImpl::SetParentDocument(nsIDocument* aParent) +XULDocumentImpl::SetParentDocument(nsIDocument* aParent) { // Note that we do *not* AddRef our parent because that would // create a circular reference. @@ -926,20 +1061,20 @@ RDFDocumentImpl::SetParentDocument(nsIDocument* aParent) } void -RDFDocumentImpl::AddSubDocument(nsIDocument* aSubDoc) +XULDocumentImpl::AddSubDocument(nsIDocument* aSubDoc) { // we don't do subdocs. PR_ASSERT(0); } PRInt32 -RDFDocumentImpl::GetNumberOfSubDocuments() +XULDocumentImpl::GetNumberOfSubDocuments() { return 0; } nsIDocument* -RDFDocumentImpl::GetSubDocumentAt(PRInt32 aIndex) +XULDocumentImpl::GetSubDocumentAt(PRInt32 aIndex) { // we don't do subdocs. PR_ASSERT(0); @@ -947,14 +1082,14 @@ RDFDocumentImpl::GetSubDocumentAt(PRInt32 aIndex) } nsIContent* -RDFDocumentImpl::GetRootContent() +XULDocumentImpl::GetRootContent() { NS_IF_ADDREF(mRootContent); return mRootContent; } void -RDFDocumentImpl::SetRootContent(nsIContent* aRoot) +XULDocumentImpl::SetRootContent(nsIContent* aRoot) { if (mRootContent) { mRootContent->SetDocument(nsnull, PR_TRUE); @@ -968,13 +1103,13 @@ RDFDocumentImpl::SetRootContent(nsIContent* aRoot) } PRInt32 -RDFDocumentImpl::GetNumberOfStyleSheets() +XULDocumentImpl::GetNumberOfStyleSheets() { return mStyleSheets.Count(); } nsIStyleSheet* -RDFDocumentImpl::GetStyleSheetAt(PRInt32 aIndex) +XULDocumentImpl::GetStyleSheetAt(PRInt32 aIndex) { nsIStyleSheet* sheet = NS_STATIC_CAST(nsIStyleSheet*, mStyleSheets[aIndex]); NS_IF_ADDREF(sheet); @@ -982,13 +1117,13 @@ RDFDocumentImpl::GetStyleSheetAt(PRInt32 aIndex) } PRInt32 -RDFDocumentImpl::GetIndexOfStyleSheet(nsIStyleSheet* aSheet) +XULDocumentImpl::GetIndexOfStyleSheet(nsIStyleSheet* aSheet) { return mStyleSheets.IndexOf(aSheet); } void -RDFDocumentImpl::AddStyleSheet(nsIStyleSheet* aSheet) +XULDocumentImpl::AddStyleSheet(nsIStyleSheet* aSheet) { NS_PRECONDITION(aSheet, "null arg"); if (!aSheet) @@ -1025,7 +1160,7 @@ RDFDocumentImpl::AddStyleSheet(nsIStyleSheet* aSheet) } void -RDFDocumentImpl::SetStyleSheetDisabledState(nsIStyleSheet* aSheet, +XULDocumentImpl::SetStyleSheetDisabledState(nsIStyleSheet* aSheet, PRBool aDisabled) { NS_PRECONDITION(nsnull != aSheet, "null arg"); @@ -1058,14 +1193,14 @@ RDFDocumentImpl::SetStyleSheetDisabledState(nsIStyleSheet* aSheet, } nsIScriptContextOwner * -RDFDocumentImpl::GetScriptContextOwner() +XULDocumentImpl::GetScriptContextOwner() { NS_IF_ADDREF(mScriptContextOwner); return mScriptContextOwner; } void -RDFDocumentImpl::SetScriptContextOwner(nsIScriptContextOwner *aScriptContextOwner) +XULDocumentImpl::SetScriptContextOwner(nsIScriptContextOwner *aScriptContextOwner) { // 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 @@ -1081,7 +1216,7 @@ RDFDocumentImpl::SetScriptContextOwner(nsIScriptContextOwner *aScriptContextOwne } NS_IMETHODIMP -RDFDocumentImpl::GetNameSpaceManager(nsINameSpaceManager*& aManager) +XULDocumentImpl::GetNameSpaceManager(nsINameSpaceManager*& aManager) { aManager = mNameSpaceManager; NS_IF_ADDREF(aManager); @@ -1092,7 +1227,7 @@ RDFDocumentImpl::GetNameSpaceManager(nsINameSpaceManager*& aManager) // Note: We don't hold a reference to the document observer; we assume // that it has a live reference to the document. void -RDFDocumentImpl::AddObserver(nsIDocumentObserver* aObserver) +XULDocumentImpl::AddObserver(nsIDocumentObserver* aObserver) { // XXX Make sure the observer isn't already in the list if (mObservers.IndexOf(aObserver) == -1) { @@ -1101,13 +1236,13 @@ RDFDocumentImpl::AddObserver(nsIDocumentObserver* aObserver) } PRBool -RDFDocumentImpl::RemoveObserver(nsIDocumentObserver* aObserver) +XULDocumentImpl::RemoveObserver(nsIDocumentObserver* aObserver) { return mObservers.RemoveElement(aObserver); } NS_IMETHODIMP -RDFDocumentImpl::BeginLoad() +XULDocumentImpl::BeginLoad() { PRInt32 i, count = mObservers.Count(); for (i = 0; i < count; i++) { @@ -1118,7 +1253,7 @@ RDFDocumentImpl::BeginLoad() } NS_IMETHODIMP -RDFDocumentImpl::EndLoad() +XULDocumentImpl::EndLoad() { PRInt32 i, count = mObservers.Count(); for (i = 0; i < count; i++) { @@ -1130,7 +1265,7 @@ RDFDocumentImpl::EndLoad() NS_IMETHODIMP -RDFDocumentImpl::ContentChanged(nsIContent* aContent, +XULDocumentImpl::ContentChanged(nsIContent* aContent, nsISupports* aSubContent) { PRInt32 count = mObservers.Count(); @@ -1142,7 +1277,7 @@ RDFDocumentImpl::ContentChanged(nsIContent* aContent, } NS_IMETHODIMP -RDFDocumentImpl::AttributeChanged(nsIContent* aChild, +XULDocumentImpl::AttributeChanged(nsIContent* aChild, nsIAtom* aAttribute, PRInt32 aHint) { @@ -1155,7 +1290,7 @@ RDFDocumentImpl::AttributeChanged(nsIContent* aChild, } NS_IMETHODIMP -RDFDocumentImpl::ContentAppended(nsIContent* aContainer, +XULDocumentImpl::ContentAppended(nsIContent* aContainer, PRInt32 aNewIndexInContainer) { PRInt32 count = mObservers.Count(); @@ -1167,7 +1302,7 @@ RDFDocumentImpl::ContentAppended(nsIContent* aContainer, } NS_IMETHODIMP -RDFDocumentImpl::ContentInserted(nsIContent* aContainer, +XULDocumentImpl::ContentInserted(nsIContent* aContainer, nsIContent* aChild, PRInt32 aIndexInContainer) { @@ -1181,7 +1316,7 @@ RDFDocumentImpl::ContentInserted(nsIContent* aContainer, } NS_IMETHODIMP -RDFDocumentImpl::ContentReplaced(nsIContent* aContainer, +XULDocumentImpl::ContentReplaced(nsIContent* aContainer, nsIContent* aOldChild, nsIContent* aNewChild, PRInt32 aIndexInContainer) @@ -1196,7 +1331,7 @@ RDFDocumentImpl::ContentReplaced(nsIContent* aContainer, } NS_IMETHODIMP -RDFDocumentImpl::ContentRemoved(nsIContent* aContainer, +XULDocumentImpl::ContentRemoved(nsIContent* aContainer, nsIContent* aChild, PRInt32 aIndexInContainer) { @@ -1210,7 +1345,7 @@ RDFDocumentImpl::ContentRemoved(nsIContent* aContainer, } NS_IMETHODIMP -RDFDocumentImpl::StyleRuleChanged(nsIStyleSheet* aStyleSheet, +XULDocumentImpl::StyleRuleChanged(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRule, PRInt32 aHint) { @@ -1223,7 +1358,7 @@ RDFDocumentImpl::StyleRuleChanged(nsIStyleSheet* aStyleSheet, } NS_IMETHODIMP -RDFDocumentImpl::StyleRuleAdded(nsIStyleSheet* aStyleSheet, +XULDocumentImpl::StyleRuleAdded(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRule) { PRInt32 count = mObservers.Count(); @@ -1235,7 +1370,7 @@ RDFDocumentImpl::StyleRuleAdded(nsIStyleSheet* aStyleSheet, } NS_IMETHODIMP -RDFDocumentImpl::StyleRuleRemoved(nsIStyleSheet* aStyleSheet, +XULDocumentImpl::StyleRuleRemoved(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRule) { PRInt32 count = mObservers.Count(); @@ -1247,7 +1382,7 @@ RDFDocumentImpl::StyleRuleRemoved(nsIStyleSheet* aStyleSheet, } NS_IMETHODIMP -RDFDocumentImpl::GetSelection(nsICollection** aSelection) +XULDocumentImpl::GetSelection(nsICollection** aSelection) { if (!mSelection) { PR_ASSERT(0); @@ -1260,7 +1395,7 @@ RDFDocumentImpl::GetSelection(nsICollection** aSelection) } NS_IMETHODIMP -RDFDocumentImpl::SelectAll() +XULDocumentImpl::SelectAll() { nsIContent * start = nsnull; @@ -1331,44 +1466,44 @@ RDFDocumentImpl::SelectAll() } NS_IMETHODIMP -RDFDocumentImpl::FindNext(const nsString &aSearchStr, PRBool aMatchCase, PRBool aSearchDown, PRBool &aIsFound) +XULDocumentImpl::FindNext(const nsString &aSearchStr, PRBool aMatchCase, PRBool aSearchDown, PRBool &aIsFound) { aIsFound = PR_FALSE; return NS_ERROR_FAILURE; } void -RDFDocumentImpl::CreateXIF(nsString & aBuffer, nsISelection* aSelection) +XULDocumentImpl::CreateXIF(nsString & aBuffer, nsISelection* aSelection) { PR_ASSERT(0); } void -RDFDocumentImpl::ToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode) +XULDocumentImpl::ToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode) { PR_ASSERT(0); } void -RDFDocumentImpl::BeginConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode) +XULDocumentImpl::BeginConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode) { PR_ASSERT(0); } void -RDFDocumentImpl::ConvertChildrenToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode) +XULDocumentImpl::ConvertChildrenToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode) { PR_ASSERT(0); } void -RDFDocumentImpl::FinishConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode) +XULDocumentImpl::FinishConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode) { PR_ASSERT(0); } PRBool -RDFDocumentImpl::IsInRange(const nsIContent *aStartContent, const nsIContent* aEndContent, const nsIContent* aContent) const +XULDocumentImpl::IsInRange(const nsIContent *aStartContent, const nsIContent* aEndContent, const nsIContent* aContent) const { PRBool result; @@ -1387,7 +1522,7 @@ RDFDocumentImpl::IsInRange(const nsIContent *aStartContent, const nsIContent* aE } PRBool -RDFDocumentImpl::IsBefore(const nsIContent *aNewContent, const nsIContent* aCurrentContent) const +XULDocumentImpl::IsBefore(const nsIContent *aNewContent, const nsIContent* aCurrentContent) const { PRBool result = PR_FALSE; @@ -1402,7 +1537,7 @@ RDFDocumentImpl::IsBefore(const nsIContent *aNewContent, const nsIContent* aCurr } PRBool -RDFDocumentImpl::IsInSelection(nsISelection* aSelection, const nsIContent *aContent) const +XULDocumentImpl::IsInSelection(nsISelection* aSelection, const nsIContent *aContent) const { PRBool result = PR_FALSE; @@ -1425,7 +1560,7 @@ RDFDocumentImpl::IsInSelection(nsISelection* aSelection, const nsIContent *aCont } nsIContent* -RDFDocumentImpl::GetPrevContent(const nsIContent *aContent) const +XULDocumentImpl::GetPrevContent(const nsIContent *aContent) const { nsIContent* result = nsnull; @@ -1449,7 +1584,7 @@ RDFDocumentImpl::GetPrevContent(const nsIContent *aContent) const } nsIContent* -RDFDocumentImpl::GetNextContent(const nsIContent *aContent) const +XULDocumentImpl::GetNextContent(const nsIContent *aContent) const { nsIContent* result = nsnull; @@ -1488,19 +1623,19 @@ RDFDocumentImpl::GetNextContent(const nsIContent *aContent) const } void -RDFDocumentImpl::SetDisplaySelection(PRBool aToggle) +XULDocumentImpl::SetDisplaySelection(PRBool aToggle) { mDisplaySelection = aToggle; } PRBool -RDFDocumentImpl::GetDisplaySelection() const +XULDocumentImpl::GetDisplaySelection() const { return mDisplaySelection; } NS_IMETHODIMP -RDFDocumentImpl::HandleDOMEvent(nsIPresContext& aPresContext, +XULDocumentImpl::HandleDOMEvent(nsIPresContext& aPresContext, nsEvent* aEvent, nsIDOMEvent** aDOMEvent, PRUint32 aFlags, @@ -1515,21 +1650,21 @@ RDFDocumentImpl::HandleDOMEvent(nsIPresContext& aPresContext, // nsIXMLDocument interface NS_IMETHODIMP -RDFDocumentImpl::PrologElementAt(PRUint32 aOffset, nsIContent** aContent) +XULDocumentImpl::PrologElementAt(PRUint32 aOffset, nsIContent** aContent) { PR_ASSERT(0); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP -RDFDocumentImpl::PrologCount(PRUint32* aCount) +XULDocumentImpl::PrologCount(PRUint32* aCount) { PR_ASSERT(0); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP -RDFDocumentImpl::AppendToProlog(nsIContent* aContent) +XULDocumentImpl::AppendToProlog(nsIContent* aContent) { PR_ASSERT(0); return NS_ERROR_NOT_IMPLEMENTED; @@ -1537,21 +1672,21 @@ RDFDocumentImpl::AppendToProlog(nsIContent* aContent) NS_IMETHODIMP -RDFDocumentImpl::EpilogElementAt(PRUint32 aOffset, nsIContent** aContent) +XULDocumentImpl::EpilogElementAt(PRUint32 aOffset, nsIContent** aContent) { PR_ASSERT(0); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP -RDFDocumentImpl::EpilogCount(PRUint32* aCount) +XULDocumentImpl::EpilogCount(PRUint32* aCount) { PR_ASSERT(0); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP -RDFDocumentImpl::AppendToEpilog(nsIContent* aContent) +XULDocumentImpl::AppendToEpilog(nsIContent* aContent) { PR_ASSERT(0); return NS_ERROR_NOT_IMPLEMENTED; @@ -1561,7 +1696,7 @@ RDFDocumentImpl::AppendToEpilog(nsIContent* aContent) // NS_IMETHODIMP -RDFDocumentImpl::GetAttributeStyleSheet(nsIHTMLStyleSheet** aResult) +XULDocumentImpl::GetAttributeStyleSheet(nsIHTMLStyleSheet** aResult) { NS_PRECONDITION(nsnull != aResult, "null ptr"); if (nsnull == aResult) { @@ -1578,7 +1713,7 @@ RDFDocumentImpl::GetAttributeStyleSheet(nsIHTMLStyleSheet** aResult) } NS_IMETHODIMP -RDFDocumentImpl::GetInlineStyleSheet(nsIHTMLCSSStyleSheet** aResult) +XULDocumentImpl::GetInlineStyleSheet(nsIHTMLCSSStyleSheet** aResult) { NS_NOTYETIMPLEMENTED("get the inline stylesheet!"); @@ -1600,7 +1735,7 @@ RDFDocumentImpl::GetInlineStyleSheet(nsIHTMLCSSStyleSheet** aResult) // nsIRDFDocument interface NS_IMETHODIMP -RDFDocumentImpl::SetContentType(const char* aContentType) +XULDocumentImpl::SetContentType(const char* aContentType) { mContentType = TEXT_RDF; if (0 == PL_strcmp("text/xul", aContentType)) @@ -1612,155 +1747,24 @@ RDFDocumentImpl::SetContentType(const char* aContentType) } NS_IMETHODIMP -RDFDocumentImpl::SetContentModelBuilder(nsIRDFContentModelBuilder* aBuilder) +XULDocumentImpl::SetRootResource(nsIRDFResource* aResource) { - NS_PRECONDITION(aBuilder != nsnull, "null ptr"); - if (! aBuilder) - return NS_ERROR_NULL_POINTER; - - NS_ADDREF(aBuilder); - mBuilder = aBuilder; - - nsresult rv; - - // The builder may try to ask us for our DB, so do this last... - if (NS_FAILED(rv = mBuilder->SetDocument(this))) - return rv; - - return NS_OK; -} - -NS_IMETHODIMP -RDFDocumentImpl::GetContentModelBuilder(nsIRDFContentModelBuilder** aBuilder) -{ - NS_PRECONDITION(aBuilder != nsnull, "null ptr"); - if (! aBuilder) - return NS_ERROR_NULL_POINTER; - - *aBuilder = mBuilder; - NS_IF_ADDREF(mBuilder); - return NS_OK; -} - -NS_IMETHODIMP -RDFDocumentImpl::SetRootResource(nsIRDFResource* aResource) -{ - NS_ASSERTION(mBuilder != nsnull, "not initialized"); - if (! mBuilder) + NS_PRECONDITION(mXULBuilder != nsnull, "not initialized"); + if (! mXULBuilder) return NS_ERROR_NOT_INITIALIZED; - nsresult rv = mBuilder->CreateRoot(aResource); + NS_PRECONDITION(mRootContent == nsnull, "already initialize"); + if (mRootContent) + return NS_ERROR_ALREADY_INITIALIZED; + + nsresult rv = mXULBuilder->CreateRootContent(aResource); + + NS_POSTCONDITION(mRootContent != nsnull, "root content wasn't set"); return rv; } NS_IMETHODIMP -RDFDocumentImpl::GetDataBase(nsIRDFCompositeDataSource*& result) -{ - NS_PRECONDITION(mDB != nsnull, "not initialized"); - if (! mDB) - return NS_ERROR_NOT_INITIALIZED; - - result = mDB; - NS_ADDREF(result); - - return NS_OK; -} - - -NS_IMETHODIMP -RDFDocumentImpl::AddTreeProperty(nsIRDFResource* resource) -{ - nsresult rv; - if (! mTreeProperties) { - if (NS_FAILED(rv = NS_NewISupportsArray(&mTreeProperties))) - return rv; - } - - // ensure uniqueness - if (mTreeProperties->IndexOf(resource) != -1) { - PR_ASSERT(0); - return NS_OK; - } - - mTreeProperties->AppendElement(resource); - return NS_OK; -} - - -NS_IMETHODIMP -RDFDocumentImpl::RemoveTreeProperty(nsIRDFResource* resource) -{ - if (! mTreeProperties) { - // XXX no properties have ever been inserted! - PR_ASSERT(0); - return NS_OK; - } - - if (! mTreeProperties->RemoveElement(resource)) { - // XXX that specific property has never been inserted! - PR_ASSERT(0); - return NS_OK; - } - - return NS_OK; -} - -NS_IMETHODIMP -RDFDocumentImpl::IsTreeProperty(nsIRDFResource* aProperty, PRBool* aResult) const -{ -#define TREE_PROPERTY_HACK -#if defined(TREE_PROPERTY_HACK) - const char* p; - aProperty->GetValue(&p); - nsAutoString s(p); - if (s.Equals(NC_NAMESPACE_URI "child") || - s.Equals(NC_NAMESPACE_URI "Folder") || - s.Equals(NC_NAMESPACE_URI "Columns") || - s.Equals(RDF_NAMESPACE_URI "child")) { - *aResult = PR_TRUE; - return NS_OK; - } -#endif // defined(TREE_PROPERTY_HACK) - if (rdf_IsOrdinalProperty(aProperty)) { - *aResult = PR_TRUE; - return NS_OK; - } - if (! mTreeProperties) { - *aResult = PR_FALSE; - return NS_OK; - } - if (mTreeProperties->IndexOf(aProperty) == -1) { - *aResult = PR_FALSE; - return NS_OK; - } - // XXX return "true" by default??? - *aResult = PR_TRUE; - return NS_OK; -} - - -NS_IMETHODIMP -RDFDocumentImpl::MapResource(nsIRDFResource* aResource, nsIRDFContent* aContent) -{ - // XXX busted: a resource might be located in multiple content - // elements in the tree. This needs to map to a set, not a single - // instance. - PL_HashTableAdd(mResources, aResource, aContent); - return NS_OK; -} - -NS_IMETHODIMP -RDFDocumentImpl::UnMapResource(nsIRDFResource* aResource, nsIRDFContent* aContent) -{ - // XXX busted: a resource might be located in multiple content - // elements in the tree. This needs to map to a set, not a single - // instance. - PL_HashTableRemove(mResources, aResource); - return NS_OK; -} - -NS_IMETHODIMP -RDFDocumentImpl::SplitProperty(nsIRDFResource* aProperty, +XULDocumentImpl::SplitProperty(nsIRDFResource* aProperty, PRInt32* aNameSpaceID, nsIAtom** aTag) { @@ -1843,65 +1847,113 @@ RDFDocumentImpl::SplitProperty(nsIRDFResource* aProperty, } -//////////////////////////////////////////////////////////////////////// -// nsIRDFObserver methods +NS_IMETHODIMP +XULDocumentImpl::AddElementForResource(nsIRDFResource* aResource, nsIRDFContent* aElement) +{ + NS_PRECONDITION(aResource != nsnull, "null ptr"); + if (! aResource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aElement != nsnull, "null ptr"); + if (! aElement) + return NS_ERROR_NULL_POINTER; + + mResources.Add(aResource, aElement); + return NS_OK; +} + NS_IMETHODIMP -RDFDocumentImpl::OnAssert(nsIRDFResource* subject, - nsIRDFResource* predicate, - nsIRDFNode* object) +XULDocumentImpl::RemoveElementForResource(nsIRDFResource* aResource, nsIRDFContent* aElement) { - NS_PRECONDITION(mResources != nsnull, "not initialized"); - if (! mResources) + NS_PRECONDITION(aResource != nsnull, "null ptr"); + if (! aResource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aElement != nsnull, "null ptr"); + if (! aElement) + return NS_ERROR_NULL_POINTER; + + mResources.Remove(aResource, aElement); + return NS_OK; +} + + +NS_IMETHODIMP +XULDocumentImpl::GetElementsForResource(nsIRDFResource* aResource, nsISupportsArray* aElements) +{ + NS_PRECONDITION(aElements != nsnull, "null ptr"); + if (! aElements) + return NS_ERROR_NULL_POINTER; + + mResources.Find(aResource, aElements); + return NS_OK; +} + + +NS_IMETHODIMP +XULDocumentImpl::CreateContents(nsIRDFContent* aElement) +{ + NS_PRECONDITION(aElement != nsnull, "null ptr"); + if (! aElement) + return NS_ERROR_NULL_POINTER; + + if (! mBuilders) return NS_ERROR_NOT_INITIALIZED; - nsIRDFContent* element = (nsIRDFContent*) PL_HashTableLookup(mResources, subject); + for (PRInt32 i = 0; i < mBuilders->Count(); ++i) { + // XXX we should QueryInterface() here + nsIRDFContentModelBuilder* builder + = (nsIRDFContentModelBuilder*) mBuilders->ElementAt(i); - if (! element) - // it's not in the tree: we're done! - return NS_OK; + NS_ASSERTION(builder != nsnull, "null ptr"); + if (! builder) + continue; - nsresult rv; - rv = mBuilder->OnAssert(element, predicate, object); - NS_ASSERTION(NS_SUCCEEDED(rv), "error notifying content model builder"); + nsresult rv = builder->CreateContents(aElement); + NS_ASSERTION(NS_SUCCEEDED(rv), "error creating content"); + // XXX ignore error code? + + NS_RELEASE(builder); + } return NS_OK; } -NS_IMETHODIMP -RDFDocumentImpl::OnUnassert(nsIRDFResource* subject, - nsIRDFResource* predicate, - nsIRDFNode* object) -{ - NS_PRECONDITION(mResources != nsnull, "not initialized"); - if (! mResources) - return NS_ERROR_NOT_INITIALIZED; - nsIRDFContent* element = (nsIRDFContent*) PL_HashTableLookup(mResources, subject); - if (! element) - // it's not in the tree: we're done! - return NS_OK; +NS_IMETHODIMP +XULDocumentImpl::AddContentModelBuilder(nsIRDFContentModelBuilder* aBuilder) +{ + NS_PRECONDITION(aBuilder != nsnull, "null ptr"); + if (! aBuilder) + return NS_ERROR_NULL_POINTER; nsresult rv; - rv = mBuilder->OnUnassert(element, predicate, object); - NS_ASSERTION(NS_SUCCEEDED(rv), "error notifying content model builder"); + if (! mBuilders) { + if (NS_FAILED(rv = NS_NewISupportsArray(&mBuilders))) + return rv; + } - return NS_OK; + if (NS_FAILED(rv = aBuilder->SetDocument(this))) { + NS_ERROR("unable to set builder's document"); + return rv; + } + + return mBuilders->AppendElement(aBuilder) ? NS_OK : NS_ERROR_FAILURE; } - //////////////////////////////////////////////////////////////////////// // nsIRDFXMLDataSourceObserver interface NS_IMETHODIMP -RDFDocumentImpl::OnBeginLoad(nsIRDFXMLDataSource* aDataSource) +XULDocumentImpl::OnBeginLoad(nsIRDFXMLDataSource* aDataSource) { return BeginLoad(); } NS_IMETHODIMP -RDFDocumentImpl::OnInterrupt(nsIRDFXMLDataSource* aDataSource) +XULDocumentImpl::OnInterrupt(nsIRDFXMLDataSource* aDataSource) { // flow any content that we have up until now. return NS_OK; @@ -1909,14 +1961,14 @@ RDFDocumentImpl::OnInterrupt(nsIRDFXMLDataSource* aDataSource) NS_IMETHODIMP -RDFDocumentImpl::OnResume(nsIRDFXMLDataSource* aDataSource) +XULDocumentImpl::OnResume(nsIRDFXMLDataSource* aDataSource) { return NS_OK; } NS_IMETHODIMP -RDFDocumentImpl::OnEndLoad(nsIRDFXMLDataSource* aDataSource) +XULDocumentImpl::OnEndLoad(nsIRDFXMLDataSource* aDataSource) { // XXX this is a temporary hack...please forgive... StartLayout(); @@ -1926,7 +1978,7 @@ RDFDocumentImpl::OnEndLoad(nsIRDFXMLDataSource* aDataSource) NS_IMETHODIMP -RDFDocumentImpl::OnRootResourceFound(nsIRDFXMLDataSource* aDataSource, nsIRDFResource* aResource) +XULDocumentImpl::OnRootResourceFound(nsIRDFXMLDataSource* aDataSource, nsIRDFResource* aResource) { nsresult rv; if (NS_SUCCEEDED(rv = SetRootResource(aResource))) { @@ -1938,30 +1990,23 @@ RDFDocumentImpl::OnRootResourceFound(nsIRDFXMLDataSource* aDataSource, nsIRDFRes NS_IMETHODIMP -RDFDocumentImpl::OnCSSStyleSheetAdded(nsIRDFXMLDataSource* aDataSource, nsIURL* aStyleSheetURL) +XULDocumentImpl::OnCSSStyleSheetAdded(nsIRDFXMLDataSource* aDataSource, nsIURL* aStyleSheetURL) { return LoadCSSStyleSheet(aStyleSheetURL); } NS_IMETHODIMP -RDFDocumentImpl::OnNamedDataSourceAdded(nsIRDFXMLDataSource* aDataSource, const char* aNamedDataSourceURI) +XULDocumentImpl::OnNamedDataSourceAdded(nsIRDFXMLDataSource* aDataSource, const char* aNamedDataSourceURI) { return AddNamedDataSource(aNamedDataSourceURI); } -NS_IMETHODIMP -RDFDocumentImpl::OnContentModelBuilderSpecified(nsIRDFXMLDataSource* aDataSource, - nsID* aCID) -{ - return SetContentModelBuilderFromCID(*aCID); -} - //////////////////////////////////////////////////////////////////////// // Implementation methods nsIContent* -RDFDocumentImpl::FindContent(const nsIContent* aStartNode, +XULDocumentImpl::FindContent(const nsIContent* aStartNode, const nsIContent* aTest1, const nsIContent* aTest2) const { @@ -1989,7 +2034,7 @@ RDFDocumentImpl::FindContent(const nsIContent* aStartNode, nsresult -RDFDocumentImpl::LoadCSSStyleSheet(nsIURL* url) +XULDocumentImpl::LoadCSSStyleSheet(nsIURL* url) { nsresult rv; nsIInputStream* iin; @@ -2036,25 +2081,37 @@ RDFDocumentImpl::LoadCSSStyleSheet(nsIURL* url) nsresult -RDFDocumentImpl::AddNamedDataSource(const char* uri) +XULDocumentImpl::AddNamedDataSource(const char* uri) { + NS_PRECONDITION(mXULBuilder != nsnull, "not initialized"); + if (! mXULBuilder) + return NS_ERROR_NOT_INITIALIZED; + nsresult rv; - nsIRDFDataSource* ds = nsnull; + nsCOMPtr ds; - if (NS_FAILED(rv = mRDFService->GetDataSource(uri, &ds))) - goto done; + if (NS_FAILED(rv = mRDFService->GetDataSource(uri, getter_AddRefs(ds)))) { + NS_ERROR("unable to get named datasource"); + return rv; + } - if (NS_FAILED(rv = mDB->AddDataSource(ds))) - goto done; + nsCOMPtr db; + if (NS_FAILED(rv = mXULBuilder->GetDataBase(getter_AddRefs(db)))) { + NS_ERROR("unable to get XUL db"); + return rv; + } -done: - NS_IF_RELEASE(ds); - return rv; + if (NS_FAILED(rv = db->AddDataSource(ds))) { + NS_ERROR("unable to add named data source to XUL db"); + return rv; + } + + return NS_OK; } nsresult -RDFDocumentImpl::Init(void) +XULDocumentImpl::Init(void) { nsresult rv; @@ -2068,29 +2125,6 @@ RDFDocumentImpl::Init(void) (void**) &mNameSpaceManager))) return rv; - // Create a table for mapping RDF resources to elements in the - // content tree. -static PRInt32 kInitialResourceTableSize = 1023; - if ((mResources = PL_NewHashTable(kInitialResourceTableSize, - rdf_HashPointer, - PL_CompareValues, - PL_CompareValues, - nsnull, - nsnull)) == nsnull) - return NS_ERROR_OUT_OF_MEMORY; - - // Create a composite data source that'll tie together local and - // remote stores. - if (NS_FAILED(rv = nsRepository::CreateInstance(kRDFCompositeDataSourceCID, - nsnull, - kIRDFCompositeDataSourceIID, - (void**) &mDB))) - return rv; - - // Make ourselves an observer - if (NS_FAILED(rv = mDB->AddObserver(this))) - return rv; - // Keep the RDF service cached in a member variable to make using // it a bit less painful if (NS_FAILED(rv = nsServiceManager::GetService(kRDFServiceCID, @@ -2102,27 +2136,9 @@ static PRInt32 kInitialResourceTableSize = 1023; } -nsresult -RDFDocumentImpl::SetContentModelBuilderFromCID(nsID& aCID) -{ - nsresult rv; - - nsCOMPtr builder; - if (NS_FAILED(rv = nsRepository::CreateInstance(aCID, nsnull, - kIRDFContentModelBuilderIID, - (void**) getter_AddRefs(builder)))) - return rv; - - if (NS_FAILED(rv = SetContentModelBuilder(builder))) - return rv; - - return NS_OK; -} - - nsresult -RDFDocumentImpl::StartLayout(void) +XULDocumentImpl::StartLayout(void) { PRInt32 count = GetNumberOfShells(); for (PRInt32 i = 0; i < count; i++) { @@ -2158,13 +2174,13 @@ RDFDocumentImpl::StartLayout(void) //////////////////////////////////////////////////////////////////////// nsresult -NS_NewRDFDocument(nsIRDFDocument** result) +NS_NewXULDocument(nsIRDFDocument** result) { NS_PRECONDITION(result != nsnull, "null ptr"); if (! result) return NS_ERROR_NULL_POINTER; - RDFDocumentImpl* doc = new RDFDocumentImpl(); + XULDocumentImpl* doc = new XULDocumentImpl(); if (! doc) return NS_ERROR_OUT_OF_MEMORY; diff --git a/mozilla/rdf/base/public/nsIRDFXMLDataSource.h b/mozilla/rdf/base/public/nsIRDFXMLDataSource.h index 73235c8a183..56c3772422b 100644 --- a/mozilla/rdf/base/public/nsIRDFXMLDataSource.h +++ b/mozilla/rdf/base/public/nsIRDFXMLDataSource.h @@ -84,12 +84,6 @@ public: */ NS_IMETHOD OnNamedDataSourceAdded(nsIRDFXMLDataSource* aStream, const char* aNamedDataSourceURI) = 0; - /** - * Called when a content model builder is specified (via XML processing - * instruction). - */ - NS_IMETHOD OnContentModelBuilderSpecified(nsIRDFXMLDataSource* aStream, - nsID* aCID) = 0; }; @@ -181,16 +175,6 @@ public: */ NS_IMETHOD AddNameSpace(nsIAtom* aPrefix, const nsString& aURI) = 0; - /** - * Set the RDF/XML document's content model builder class ID. - */ - NS_IMETHOD SetContentModelBuilderCID(nsID* aCID) = 0; - - /** - * Get the RDF/XML document's content model builder class ID. - */ - NS_IMETHOD GetContentModelBuilderCID(nsID* aCID) = 0; - /** * Add an observer to the document. The observer will be notified of * RDF/XML events via the nsIRDFXMLDataSourceObserver interface. Note that diff --git a/mozilla/rdf/base/src/Makefile.in b/mozilla/rdf/base/src/Makefile.in index 0ef7def48c2..ea82d1ef298 100644 --- a/mozilla/rdf/base/src/Makefile.in +++ b/mozilla/rdf/base/src/Makefile.in @@ -33,7 +33,6 @@ CPPSRCS = \ nsEmptyCursor.cpp \ nsInMemoryDataSource.cpp \ nsRDFContentSink.cpp \ - nsXULContentSink.cpp \ nsRDFService.cpp \ nsRDFXMLDataSource.cpp \ rdfutil.cpp \ diff --git a/mozilla/rdf/base/src/makefile.win b/mozilla/rdf/base/src/makefile.win index 44cba6f134c..41ebbd67566 100644 --- a/mozilla/rdf/base/src/makefile.win +++ b/mozilla/rdf/base/src/makefile.win @@ -26,7 +26,6 @@ CPP_OBJS=\ .\$(OBJDIR)\nsEmptyCursor.obj \ .\$(OBJDIR)\nsInMemoryDataSource.obj \ .\$(OBJDIR)\nsRDFContentSink.obj \ - .\$(OBJDIR)\nsXULContentSink.obj \ .\$(OBJDIR)\nsRDFService.obj \ .\$(OBJDIR)\nsRDFXMLDataSource.obj \ .\$(OBJDIR)\rdfutil.obj \ diff --git a/mozilla/rdf/base/src/nsRDFContentSink.cpp b/mozilla/rdf/base/src/nsRDFContentSink.cpp index 53934c3e5f1..f891f737c36 100644 --- a/mozilla/rdf/base/src/nsRDFContentSink.cpp +++ b/mozilla/rdf/base/src/nsRDFContentSink.cpp @@ -711,21 +711,6 @@ static const char kContentModelBuilderPI[] = "AddNamedDataSourceURI(uri); } - else if (0 == text.Find(kContentModelBuilderPI)) { - nsAutoString cidStr; - rv = rdf_GetQuotedAttributeValue(text, "cid", cidStr); - if (NS_FAILED(rv) || (0 == cidStr.Length())) - return rv; - - char buf[256]; - cidStr.ToCString(buf, sizeof(buf)); - - nsID cid; - if (! cid.Parse(buf)) - return NS_ERROR_FAILURE; - - rv = mDataSource->SetContentModelBuilderCID(&cid); - } return rv; } diff --git a/mozilla/rdf/base/src/nsRDFXMLDataSource.cpp b/mozilla/rdf/base/src/nsRDFXMLDataSource.cpp index c5567f9bf6f..5989a55cba6 100644 --- a/mozilla/rdf/base/src/nsRDFXMLDataSource.cpp +++ b/mozilla/rdf/base/src/nsRDFXMLDataSource.cpp @@ -229,7 +229,6 @@ protected: nsIRDFResource* mRootResource; PRBool mIsLoading; // true while the document is loading NameSpaceMap* mNameSpaces; - nsID mContentModelBuilderCID; public: RDFXMLDataSourceImpl(void); @@ -341,8 +340,6 @@ public: NS_IMETHOD AddNamedDataSourceURI(const char* aNamedDataSourceURI); NS_IMETHOD GetNamedDataSourceURIs(const char* const** aNamedDataSourceURIs, PRInt32* aCount); NS_IMETHOD AddNameSpace(nsIAtom* aPrefix, const nsString& aURI); - NS_IMETHOD SetContentModelBuilderCID(nsID* aCID); - NS_IMETHOD GetContentModelBuilderCID(nsID* aCID); NS_IMETHOD AddXMLStreamObserver(nsIRDFXMLDataSourceObserver* aObserver); NS_IMETHOD RemoveXMLStreamObserver(nsIRDFXMLDataSourceObserver* aObserver); @@ -919,26 +916,6 @@ RDFXMLDataSourceImpl::AddNameSpace(nsIAtom* aPrefix, const nsString& aURI) } -NS_IMETHODIMP -RDFXMLDataSourceImpl::SetContentModelBuilderCID(nsID* aCID) -{ - mContentModelBuilderCID = *aCID; - - for (PRInt32 i = mObservers.Count() - 1; i >= 0; --i) { - nsIRDFXMLDataSourceObserver* obs = (nsIRDFXMLDataSourceObserver*) mObservers[i]; - obs->OnContentModelBuilderSpecified(this, &mContentModelBuilderCID); - } - - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::GetContentModelBuilderCID(nsID* aCID) -{ - *aCID = mContentModelBuilderCID; - return NS_OK; -} - NS_IMETHODIMP RDFXMLDataSourceImpl::AddXMLStreamObserver(nsIRDFXMLDataSourceObserver* aObserver) { diff --git a/mozilla/rdf/build/makefile.win b/mozilla/rdf/build/makefile.win index 2ddbb3fca1e..c3e99280c06 100644 --- a/mozilla/rdf/build/makefile.win +++ b/mozilla/rdf/build/makefile.win @@ -30,6 +30,10 @@ CPP_OBJS=\ .\$(OBJDIR)\nsRDFFactory.obj \ $(NULL) +# XXX linking in raptor is a heinous crime that will go away once we +# have a more DOM-based mechanism for constructing elements and +# hooking in to their changes. + LLIBS=\ $(DIST)\lib\rdfbase_s.lib \ $(DIST)\lib\rdfcontent_s.lib \ @@ -39,9 +43,7 @@ LLIBS=\ $(DIST)\lib\raptorgfxwin.lib \ $(DIST)\lib\netlib.lib \ $(DIST)\lib\libplc21.lib \ -#if 0 # for HTML-in-XUL $(DIST)\lib\raptorhtml.lib \ -#endif $(LIBNSPR) MISCDEP=$(LLIBS) diff --git a/mozilla/rdf/build/nsRDFCID.h b/mozilla/rdf/build/nsRDFCID.h index f9f856ff226..884a027c0e4 100644 --- a/mozilla/rdf/build/nsRDFCID.h +++ b/mozilla/rdf/build/nsRDFCID.h @@ -46,10 +46,6 @@ #define NS_RDFCOMPOSITEDATASOURCE_CID \ { 0xe638d761, 0x8687, 0x11d2, { 0xb5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } } -// {541AFCB2-A9A3-11d2-8EC5-00805F29F370} -#define NS_RDFDOCUMENT_CID \ -{ 0x541afcb2, 0xa9a3, 0x11d2, { 0x8e, 0xc5, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } - // {954F0813-81DC-11d2-B52A-000000000000} #define NS_RDFHTMLBUILDER_CID \ { 0x954f0813, 0x81dc, 0x11d2, { 0xb5, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } } @@ -78,4 +74,8 @@ #define NS_XULCONTENTSINK_CID \ { 0xce058b21, 0xba9c, 0x11d2, { 0xbf, 0x86, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } } +// {541AFCB2-A9A3-11d2-8EC5-00805F29F370} +#define NS_XULDOCUMENT_CID \ +{ 0x541afcb2, 0xa9a3, 0x11d2, { 0x8e, 0xc5, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } + #endif // nsRDFCID_h__ diff --git a/mozilla/rdf/build/nsRDFFactory.cpp b/mozilla/rdf/build/nsRDFFactory.cpp index 0d739570d3e..c995766ac2a 100644 --- a/mozilla/rdf/build/nsRDFFactory.cpp +++ b/mozilla/rdf/build/nsRDFFactory.cpp @@ -33,6 +33,7 @@ #include "nsRDFBaseDataSources.h" #include "nsRDFBuiltInDataSources.h" #include "nsRDFCID.h" +#include "nsRepository.h" static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); @@ -40,15 +41,15 @@ static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); static NS_DEFINE_CID(kRDFBookmarkDataSourceCID, NS_RDFBOOKMARKDATASOURCE_CID); static NS_DEFINE_CID(kRDFCompositeDataSourceCID, NS_RDFCOMPOSITEDATASOURCE_CID); static NS_DEFINE_CID(kRDFContentSinkCID, NS_RDFCONTENTSINK_CID); -static NS_DEFINE_CID(kRDFDocumentCID, NS_RDFDOCUMENT_CID); static NS_DEFINE_CID(kRDFHTMLBuilderCID, NS_RDFHTMLBUILDER_CID); static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID); static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); static NS_DEFINE_CID(kRDFTreeBuilderCID, NS_RDFTREEBUILDER_CID); static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID); static NS_DEFINE_CID(kRDFXULBuilderCID, NS_RDFXULBUILDER_CID); -static NS_DEFINE_CID(kXULDataSourceCID, NS_XULDATASOURCE_CID); static NS_DEFINE_CID(kXULContentSinkCID, NS_XULCONTENTSINK_CID); +static NS_DEFINE_CID(kXULDataSourceCID, NS_XULDATASOURCE_CID); +static NS_DEFINE_CID(kXULDocumentCID, NS_XULDOCUMENT_CID); class RDFFactoryImpl : public nsIFactory { @@ -148,8 +149,8 @@ RDFFactoryImpl::CreateInstance(nsISupports *aOuter, if (NS_FAILED(rv = NS_NewRDFCompositeDataSource((nsIRDFCompositeDataSource**) &inst))) return rv; } - else if (mClassID.Equals(kRDFDocumentCID)) { - if (NS_FAILED(rv = NS_NewRDFDocument((nsIRDFDocument**) &inst))) + else if (mClassID.Equals(kXULDocumentCID)) { + if (NS_FAILED(rv = NS_NewXULDocument((nsIRDFDocument**) &inst))) return rv; } else if (mClassID.Equals(kRDFHTMLBuilderCID)) { @@ -219,3 +220,43 @@ NSGetFactory(const nsCID &aClass, nsISupports* aServiceManager, nsIFactory **aFa return NS_OK; } + + + +extern "C" PR_IMPLEMENT(nsresult) +NSRegisterSelf(const char* aPath) +{ + nsRepository::RegisterFactory(kRDFBookmarkDataSourceCID, aPath, PR_TRUE, PR_TRUE); + nsRepository::RegisterFactory(kRDFCompositeDataSourceCID, aPath, PR_TRUE, PR_TRUE); + nsRepository::RegisterFactory(kRDFContentSinkCID, aPath, PR_TRUE, PR_TRUE); + nsRepository::RegisterFactory(kRDFHTMLBuilderCID, aPath, PR_TRUE, PR_TRUE); + nsRepository::RegisterFactory(kRDFInMemoryDataSourceCID, aPath, PR_TRUE, PR_TRUE); + nsRepository::RegisterFactory(kRDFServiceCID, aPath, PR_TRUE, PR_TRUE); + nsRepository::RegisterFactory(kRDFTreeBuilderCID, aPath, PR_TRUE, PR_TRUE); + nsRepository::RegisterFactory(kRDFXMLDataSourceCID, aPath, PR_TRUE, PR_TRUE); + nsRepository::RegisterFactory(kRDFXULBuilderCID, aPath, PR_TRUE, PR_TRUE); + nsRepository::RegisterFactory(kXULContentSinkCID, aPath, PR_TRUE, PR_TRUE); + nsRepository::RegisterFactory(kXULDataSourceCID, aPath, PR_TRUE, PR_TRUE); + nsRepository::RegisterFactory(kXULDocumentCID, aPath, PR_TRUE, PR_TRUE); + return NS_OK; +} + + +extern "C" PR_IMPLEMENT(nsresult) +NSUnregisterSelf(const char* aPath) +{ + nsRepository::UnregisterFactory(kRDFBookmarkDataSourceCID, aPath); + nsRepository::UnregisterFactory(kRDFCompositeDataSourceCID, aPath); + nsRepository::UnregisterFactory(kRDFContentSinkCID, aPath); + nsRepository::UnregisterFactory(kRDFHTMLBuilderCID, aPath); + nsRepository::UnregisterFactory(kRDFInMemoryDataSourceCID, aPath); + nsRepository::UnregisterFactory(kRDFServiceCID, aPath); + nsRepository::UnregisterFactory(kRDFTreeBuilderCID, aPath); + nsRepository::UnregisterFactory(kRDFXMLDataSourceCID, aPath); + nsRepository::UnregisterFactory(kRDFXULBuilderCID, aPath); + nsRepository::UnregisterFactory(kXULContentSinkCID, aPath); + nsRepository::UnregisterFactory(kXULDataSourceCID, aPath); + nsRepository::UnregisterFactory(kXULDocumentCID, aPath); + return NS_OK; +} + diff --git a/mozilla/rdf/content/public/nsIRDFContentModelBuilder.h b/mozilla/rdf/content/public/nsIRDFContentModelBuilder.h index eb5a3de1fc3..5867ffa3a0a 100644 --- a/mozilla/rdf/content/public/nsIRDFContentModelBuilder.h +++ b/mozilla/rdf/content/public/nsIRDFContentModelBuilder.h @@ -30,7 +30,9 @@ #include "nsISupports.h" -class nsIRDFContent; +class nsIContent; +class nsIRDFCompositeDataSource; +class nsIRDFContent; // XXX get rid of these... class nsIRDFDocument; class nsIRDFNode; class nsIRDFResource; @@ -50,32 +52,20 @@ public: */ NS_IMETHOD SetDocument(nsIRDFDocument* aDocument) = 0; + NS_IMETHOD SetDataBase(nsIRDFCompositeDataSource* aDataBase) = 0; + NS_IMETHOD GetDataBase(nsIRDFCompositeDataSource** aDataBase) = 0; + /** - * Called to instruct the content model builder to construct the root - * document element. The content model builder should construct an - * nsIContent object and set the document's content root to that object - * via the nsIDocument::SetDocumentRoot() method. + * Set the root element from which this content model will + * operate. */ - NS_IMETHOD CreateRoot(nsIRDFResource* aResource) = 0; + NS_IMETHOD CreateRootContent(nsIRDFResource* aResource) = 0; + NS_IMETHOD SetRootContent(nsIContent* aElement) = 0; /** * Construct the contents for a container element. */ - NS_IMETHOD CreateContents(nsIRDFContent* aElement) = 0; - - /** - * Called when a new assertion is made to the RDF graph that affects an - * element in the content model. The content model builder should update - * the document's content model as appropriate. - */ - NS_IMETHOD OnAssert(nsIRDFContent* aElement, nsIRDFResource* aProperty, nsIRDFNode* aValue) = 0; - - /** - * Called when an assertion is removed from the RDF graph that affects - * an element in the content model. The content model builder should - * update the document's content model as appropriate. - */ - NS_IMETHOD OnUnassert(nsIRDFContent* aElement, nsIRDFResource* aProperty, nsIRDFNode* aValue) = 0; + NS_IMETHOD CreateContents(nsIContent* aElement) = 0; }; diff --git a/mozilla/rdf/content/public/nsIRDFDocument.h b/mozilla/rdf/content/public/nsIRDFDocument.h index b5572887a84..992c47962b1 100644 --- a/mozilla/rdf/content/public/nsIRDFDocument.h +++ b/mozilla/rdf/content/public/nsIRDFDocument.h @@ -56,57 +56,31 @@ public: */ NS_IMETHOD SetContentType(const char* aContentType) = 0; - /** - * Set the document's content model builder. - */ - NS_IMETHOD SetContentModelBuilder(nsIRDFContentModelBuilder* aBuilder) = 0; - - /** - * Get the document's content model builder. - */ - NS_IMETHOD GetContentModelBuilder(nsIRDFContentModelBuilder** aBuilder) = 0; - /** * Set the document's "root" resource. */ NS_IMETHOD SetRootResource(nsIRDFResource* aResource) = 0; - /** - * Retrieve the document's RDF data base. - */ - NS_IMETHOD GetDataBase(nsIRDFCompositeDataSource*& rDataBase) = 0; - // XXX the following two methods should probably accept strings as // parameters so you can mess with them via JS. Also, should they // take a "notify" parameter that would control whether any viewers // of the content model should be informed that the content model is // invalid? - /** - * Add a property to the set of "tree properties" that the document - * should use when constructing the content model from the RDF - * graph. - */ - NS_IMETHOD AddTreeProperty(nsIRDFResource* resource) = 0; - - /** - * Remove a property from the set of "tree properties" that the - * document should use when constructing the content model from the - * RDF graph. - */ - NS_IMETHOD RemoveTreeProperty(nsIRDFResource* resource) = 0; - - /** - * Determine whether the specified property is a "tree" property. - */ - NS_IMETHOD IsTreeProperty(nsIRDFResource* aProperty, PRBool* aResult) const = 0; - - NS_IMETHOD MapResource(nsIRDFResource* aResource, nsIRDFContent* aContent) = 0; - NS_IMETHOD UnMapResource(nsIRDFResource* aResource, nsIRDFContent* aContent) = 0; NS_IMETHOD SplitProperty(nsIRDFResource* aResource, PRInt32* aNameSpaceID, nsIAtom** aTag) = 0; + + NS_IMETHOD AddElementForResource(nsIRDFResource* aResource, nsIRDFContent* aElement) = 0; + + NS_IMETHOD RemoveElementForResource(nsIRDFResource* aResource, nsIRDFContent* aElement) = 0; + + NS_IMETHOD GetElementsForResource(nsIRDFResource* aResource, nsISupportsArray* aElements) = 0; + + NS_IMETHOD CreateContents(nsIRDFContent* aElement) = 0; + + NS_IMETHOD AddContentModelBuilder(nsIRDFContentModelBuilder* aBuilder) = 0; }; // factory functions -nsresult NS_NewRDFDocument(nsIRDFDocument** result); +nsresult NS_NewXULDocument(nsIRDFDocument** result); #endif // nsIRDFDocument_h___ diff --git a/mozilla/rdf/content/src/Makefile.in b/mozilla/rdf/content/src/Makefile.in index c07329a62bb..d221fe1bcdb 100644 --- a/mozilla/rdf/content/src/Makefile.in +++ b/mozilla/rdf/content/src/Makefile.in @@ -29,12 +29,12 @@ LIBRARY_NAME = rdfcontent_s CPPSRCS = \ nsRDFContentUtils.cpp \ nsRDFDOMNodeList.cpp \ - nsRDFDocument.cpp \ nsRDFGenericElement.cpp \ nsRDFHTMLBuilder.cpp \ nsRDFResourceElement.cpp \ nsRDFTreeBuilder.cpp \ nsRDFXULBuilder.cpp \ + nsXULDocument.cpp \ $(NULL) EXPORTS = \ @@ -50,6 +50,11 @@ REQUIRES = dom js netlib rdf raptor xpcom # a first-class XPCOM interface. INCLUDES += -I$(srcdir)/../../base/src +# XXX This is a dependency on Raptor for constructing HTML +# content. It'll go away once we move RDF content model construction +# outside the DOM APIs. +INCLUDES += -I$(srcdir)/../../../layout/html/base/src + MKSHLIB := # we don't want the shared lib diff --git a/mozilla/rdf/content/src/makefile.win b/mozilla/rdf/content/src/makefile.win index 48b437a9c96..03b0c386e95 100644 --- a/mozilla/rdf/content/src/makefile.win +++ b/mozilla/rdf/content/src/makefile.win @@ -22,14 +22,18 @@ LIBRARY_NAME=rdfcontent_s CPP_OBJS=\ .\$(OBJDIR)\nsRDFContentUtils.obj \ .\$(OBJDIR)\nsRDFDOMNodeList.obj \ - .\$(OBJDIR)\nsRDFDocument.obj \ .\$(OBJDIR)\nsRDFGenericElement.obj \ .\$(OBJDIR)\nsRDFHTMLBuilder.obj \ .\$(OBJDIR)\nsRDFResourceElement.obj \ .\$(OBJDIR)\nsRDFTreeBuilder.obj \ .\$(OBJDIR)\nsRDFXULBuilder.obj \ + .\$(OBJDIR)\nsXULDocument.obj \ $(NULL) +# XXX we are including layout\html\base\src to get HTML elements +# constructed directly from Raptor. The hope is that this'll +# eventually be replaced by a DOM-based mechanism. + LINCS= -I$(PUBLIC)\rdf \ -I$(PUBLIC)\xpcom \ -I$(PUBLIC)\netlib \ @@ -37,9 +41,7 @@ LINCS= -I$(PUBLIC)\rdf \ -I$(PUBLIC)\js \ -I$(PUBLIC)\dom \ -I$(DEPTH)\rdf\base\src \ -!if 0 # XXX need to link against layout.dll for this -I$(DEPTH)\layout\html\base\src \ -!endif $(NULL) include <$(DEPTH)\config\rules.mak> diff --git a/mozilla/rdf/content/src/nsRDFHTMLBuilder.cpp b/mozilla/rdf/content/src/nsRDFHTMLBuilder.cpp index 3280855d4ed..cdcc98ba2ce 100644 --- a/mozilla/rdf/content/src/nsRDFHTMLBuilder.cpp +++ b/mozilla/rdf/content/src/nsRDFHTMLBuilder.cpp @@ -49,12 +49,10 @@ static NS_DEFINE_IID(kIRDFContentModelBuilderIID, NS_IRDFCONTENTMODELBUILDER_IID //////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - class RDFHTMLBuilderImpl : public nsIRDFContentModelBuilder { private: - nsIRDFDocument* mDocument; + nsIRDFDocument* mDocument; nsIRDFCompositeDataSource* mDB; public: @@ -66,8 +64,11 @@ public: // nsIRDFContentModelBuilder interface NS_IMETHOD SetDocument(nsIRDFDocument* aDocument); - NS_IMETHOD CreateRoot(nsIRDFResource* aResource); - NS_IMETHOD CreateContents(nsIRDFContent* aElement); + NS_IMETHOD SetDataBase(nsIRDFCompositeDataSource* aDataBase); + NS_IMETHOD GetDataBase(nsIRDFCompositeDataSource** aDataBase); + NS_IMETHOD CreateRootContent(nsIRDFResource* aResource); + NS_IMETHOD SetRootContent(nsIContent* aElement); + NS_IMETHOD CreateContents(nsIContent* aElement); NS_IMETHOD OnAssert(nsIRDFContent* aElement, nsIRDFResource* aProperty, nsIRDFNode* aValue); NS_IMETHOD OnUnassert(nsIRDFContent* aElement, nsIRDFResource* aProperty, nsIRDFNode* aValue); @@ -79,6 +80,8 @@ public: nsresult AddLeafChild(nsIRDFContent* parent, nsIRDFResource* property, nsIRDFLiteral* value); + + PRBool IsTreeProperty(nsIRDFResource* aProperty); }; //////////////////////////////////////////////////////////////////////// @@ -105,7 +108,7 @@ RDFHTMLBuilderImpl::~RDFHTMLBuilderImpl(void) NS_RELEASE2(kIdAtom, refcnt); NS_IF_RELEASE(mDB); - // mDocument is _not_ refcounted + // NS_IF_RELEASE(mDocument) not refcounted } //////////////////////////////////////////////////////////////////////// @@ -201,18 +204,48 @@ RDFHTMLBuilderImpl::SetDocument(nsIRDFDocument* aDocument) if (! aDocument) return NS_ERROR_NULL_POINTER; + NS_PRECONDITION(mDocument == nsnull, "already initialized"); + if (mDocument) + return NS_ERROR_ALREADY_INITIALIZED; + mDocument = aDocument; // not refcounted - - nsresult rv; - if (NS_FAILED(rv = mDocument->GetDataBase(mDB))) - return rv; - return NS_OK; } NS_IMETHODIMP -RDFHTMLBuilderImpl::CreateRoot(nsIRDFResource* aResource) +RDFHTMLBuilderImpl::SetDataBase(nsIRDFCompositeDataSource* aDataBase) +{ + NS_PRECONDITION(aDataBase != nsnull, "null ptr"); + if (! aDataBase) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(mDB == nsnull, "already initialized"); + if (mDB) + return NS_ERROR_ALREADY_INITIALIZED; + + mDB = aDataBase; + NS_ADDREF(mDB); + return NS_OK; +} + + +NS_IMETHODIMP +RDFHTMLBuilderImpl::GetDataBase(nsIRDFCompositeDataSource** aDataBase) +{ + NS_PRECONDITION(aDataBase != nsnull, "null ptr"); + if (! aDataBase) + return NS_ERROR_NULL_POINTER; + + *aDataBase = mDB; + NS_ADDREF(mDB); + return NS_OK; +} + + + +NS_IMETHODIMP +RDFHTMLBuilderImpl::CreateRootContent(nsIRDFResource* aResource) { NS_PRECONDITION(mDocument != nsnull, "not initialized"); if (! mDocument) @@ -259,7 +292,14 @@ done: NS_IMETHODIMP -RDFHTMLBuilderImpl::CreateContents(nsIRDFContent* aElement) +RDFHTMLBuilderImpl::SetRootContent(nsIContent* aElement) +{ + NS_NOTYETIMPLEMENTED("write me"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +RDFHTMLBuilderImpl::CreateContents(nsIContent* aElement) { NS_NOTYETIMPLEMENTED("Adapt the implementation from RDFTreeBuilderImpl"); return NS_ERROR_NOT_IMPLEMENTED; @@ -281,9 +321,7 @@ RDFHTMLBuilderImpl::OnAssert(nsIRDFContent* parent, if (NS_SUCCEEDED(rv = value->QueryInterface(kIRDFResourceIID, (void**) &valueResource))) { // If it's a tree property or an RDF container, then add it as // a tree child and return. - PRBool isTreeProperty; - if ((NS_SUCCEEDED(rv = mDocument->IsTreeProperty(property, &isTreeProperty)) && isTreeProperty) || - (rdf_IsContainer(mDB, valueResource))) { + if (IsTreeProperty(property) || rdf_IsContainer(mDB, valueResource)) { rv = AddTreeChild(parent, property, valueResource); NS_RELEASE(valueResource); return rv; @@ -314,6 +352,33 @@ RDFHTMLBuilderImpl::OnUnassert(nsIRDFContent* parent, return NS_ERROR_NOT_IMPLEMENTED; } + +PRBool +RDFHTMLBuilderImpl::IsTreeProperty(nsIRDFResource* aProperty) +{ + // XXX This whole method is a mega-kludge. This should be read off + // of the element somehow... + +#define TREE_PROPERTY_HACK +#if defined(TREE_PROPERTY_HACK) + const char* p; + aProperty->GetValue(&p); + nsAutoString s(p); + if (s.Equals(NC_NAMESPACE_URI "child") || + s.Equals(NC_NAMESPACE_URI "Folder") || + s.Equals(NC_NAMESPACE_URI "Columns") || + s.Equals(RDF_NAMESPACE_URI "child")) { + return PR_TRUE; + } +#endif // defined(TREE_PROPERTY_HACK) + if (rdf_IsOrdinalProperty(aProperty)) { + return PR_TRUE; + } + return PR_FALSE; +} + + + //////////////////////////////////////////////////////////////////////// nsresult diff --git a/mozilla/rdf/content/src/nsRDFResourceElement.cpp b/mozilla/rdf/content/src/nsRDFResourceElement.cpp index 2858f1ae483..cd1e076d928 100644 --- a/mozilla/rdf/content/src/nsRDFResourceElement.cpp +++ b/mozilla/rdf/content/src/nsRDFResourceElement.cpp @@ -780,14 +780,22 @@ RDFResourceElementImpl::GetDocument(nsIDocument*& aResult) const NS_IMETHODIMP RDFResourceElementImpl::SetDocument(nsIDocument* aDocument, PRBool aDeep) { + nsresult rv; + nsCOMPtr rdfDoc; + if (mDocument) { - nsIRDFDocument* rdfDoc; - if (NS_SUCCEEDED(mDocument->QueryInterface(kIRDFDocumentIID, (void**) &rdfDoc))) { - rdfDoc->UnMapResource(mResource, NS_STATIC_CAST(nsIRDFContent*, this)); - NS_RELEASE(rdfDoc); + if (NS_SUCCEEDED(mDocument->QueryInterface(kIRDFDocumentIID, getter_AddRefs(rdfDoc)))) { + rv = rdfDoc->RemoveElementForResource(mResource, this); + NS_ASSERTION(NS_SUCCEEDED(rv), "error unmapping resource from element"); } } mDocument = aDocument; // not refcounted + if (mDocument) { + if (NS_SUCCEEDED(mDocument->QueryInterface(kIRDFDocumentIID, getter_AddRefs(rdfDoc)))) { + rv = rdfDoc->AddElementForResource(mResource, this); + NS_ASSERTION(NS_SUCCEEDED(rv), "error mapping resource to element"); + } + } if (aDeep && mChildren) { for (PRInt32 i = mChildren->Count() - 1; i >= 0; --i) { @@ -808,13 +816,6 @@ RDFResourceElementImpl::SetDocument(nsIDocument* aDocument, PRBool aDeep) NS_RELEASE(obj); } } - if (mDocument) { - nsIRDFDocument* rdfDoc; - if (NS_SUCCEEDED(mDocument->QueryInterface(kIRDFDocumentIID, (void**) &rdfDoc))) { - rdfDoc->MapResource(mResource, NS_STATIC_CAST(nsIRDFContent*, this)); - NS_RELEASE(rdfDoc); - } - } return NS_OK; } @@ -1532,11 +1533,7 @@ RDFResourceElementImpl::EnsureContentsGenerated(void) const (void**) getter_AddRefs(rdfDoc)))) return rv; - nsCOMPtr builder; - if (NS_FAILED(rv = rdfDoc->GetContentModelBuilder(getter_AddRefs(builder)))) - return rv; - - rv = builder->CreateContents(unconstThis); + rv = rdfDoc->CreateContents(unconstThis); NS_ASSERTION(NS_SUCCEEDED(rv), "problem creating kids"); return rv; } diff --git a/mozilla/rdf/content/src/nsRDFTreeBuilder.cpp b/mozilla/rdf/content/src/nsRDFTreeBuilder.cpp index 8db7f2ef6af..7c95297e37a 100644 --- a/mozilla/rdf/content/src/nsRDFTreeBuilder.cpp +++ b/mozilla/rdf/content/src/nsRDFTreeBuilder.cpp @@ -27,16 +27,13 @@ 1) Get a real namespace for XUL. This should go in a header file somewhere. - 2) Get the columns stuff _out_ of here and into XUL. The columns - code is what makes this thing as scary as it is right now. - - 3) We have a serious problem if all the columns aren't created by + 2) We have a serious problem if all the columns aren't created by the time that we start inserting rows into the table. Need to fix this so that columns can be dynamically added and removed (we need to do this anyway to handle column re-ordering or manipulation via DOM calls). - 4) There's lots of stuff screwed up with the ordering of walking the + 3) There's lots of stuff screwed up with the ordering of walking the tree, creating children, getting assertions, etc. A lot of this has to do with the "are children already generated" state variable that lives in the RDFResourceElementImpl. I need to sit @@ -53,6 +50,7 @@ #include "nsIRDFCompositeDataSource.h" #include "nsIRDFDocument.h" #include "nsIRDFNode.h" +#include "nsIRDFObserver.h" #include "nsIRDFService.h" #include "nsIServiceManager.h" #include "nsINameSpaceManager.h" @@ -67,10 +65,14 @@ //////////////////////////////////////////////////////////////////////// +DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, child); DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Columns); DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Column); +DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Folder); DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Title); +DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, child); + //////////////////////////////////////////////////////////////////////// static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID); @@ -79,23 +81,28 @@ static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID); static NS_DEFINE_IID(kIRDFLiteralIID, NS_IRDFLITERAL_IID); static NS_DEFINE_IID(kIRDFContentIID, NS_IRDFCONTENT_IID); static NS_DEFINE_IID(kIRDFContentModelBuilderIID, NS_IRDFCONTENTMODELBUILDER_IID); +static NS_DEFINE_IID(kIRDFObserverIID, NS_IRDFOBSERVER_IID); static NS_DEFINE_IID(kIRDFServiceIID, NS_IRDFSERVICE_IID); +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID); static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); //////////////////////////////////////////////////////////////////////// -class RDFTreeBuilderImpl : public nsIRDFContentModelBuilder +class RDFTreeBuilderImpl : public nsIRDFContentModelBuilder, + public nsIRDFObserver { private: - nsIRDFDocument* mDocument; + nsIRDFDocument* mDocument; nsIRDFCompositeDataSource* mDB; + nsIContent* mRoot; // pseudo-constants static nsrefcnt gRefCnt; static nsIRDFService* gRDFService; + static nsIAtom* kContentsGeneratedAtom; static nsIAtom* kIdAtom; static nsIAtom* kOpenAtom; static nsIAtom* kResourceAtom; @@ -104,14 +111,17 @@ private: static nsIAtom* kTreeCellAtom; static nsIAtom* kTreeChildrenAtom; static nsIAtom* kTreeHeadAtom; + static nsIAtom* kTreeIndentationAtom; static nsIAtom* kTreeItemAtom; - static nsIAtom* kTreeRowAtom; static PRInt32 kNameSpaceID_RDF; static PRInt32 kNameSpaceID_XUL; static nsIRDFResource* kNC_Title; + static nsIRDFResource* kNC_child; static nsIRDFResource* kNC_Column; + static nsIRDFResource* kNC_Folder; + static nsIRDFResource* kRDF_child; public: RDFTreeBuilderImpl(); @@ -122,11 +132,15 @@ public: // nsIRDFContentModelBuilder interface NS_IMETHOD SetDocument(nsIRDFDocument* aDocument); - NS_IMETHOD CreateRoot(nsIRDFResource* aResource); - NS_IMETHOD CreateContents(nsIRDFContent* aElement); - NS_IMETHOD OnAssert(nsIRDFContent* aElement, nsIRDFResource* aProperty, nsIRDFNode* aValue); - NS_IMETHOD OnUnassert(nsIRDFContent* aElement, nsIRDFResource* aProperty, nsIRDFNode* aValue); + NS_IMETHOD SetDataBase(nsIRDFCompositeDataSource* aDataBase); + NS_IMETHOD GetDataBase(nsIRDFCompositeDataSource** aDataBase); + NS_IMETHOD CreateRootContent(nsIRDFResource* aResource); + NS_IMETHOD SetRootContent(nsIContent* aElement); + NS_IMETHOD CreateContents(nsIContent* aElement); + // nsIRDFObserver interface + NS_IMETHOD OnAssert(nsIRDFResource* aSubject, nsIRDFResource* aPredicate, nsIRDFNode* aObject); + NS_IMETHOD OnUnassert(nsIRDFResource* aSubject, nsIRDFResource* aPredicate, nsIRDFNode* aObjetct); // Implementation methods nsresult @@ -158,8 +172,7 @@ public: nsIRDFResource* aValue); nsresult - CreateTreeItemRowAndCells(nsIContent* aTreeItemElement, - nsIContent** aTreeRowElement); + CreateTreeItemCells(nsIContent* aTreeItemElement); nsresult FindTreeCellForProperty(nsIContent* aTreeRowElement, @@ -171,31 +184,6 @@ public: nsIRDFResource* aProperty, nsIRDFNode* aValue); - // Most of this stuff is just noise that we need to implement - // column headers from RDF. Hopefully this'll go away once the XUL - // content sink gets written and we can specify it from there. - nsresult - EnsureTreeHasHeadAndRow(nsIContent* aParent, - nsIRDFNode* aColumnsContainer); - - nsresult - SetColumnTitle(nsIContent* aColumnElement, - nsIRDFNode* aTitle); - - nsresult - SetColumnResource(nsIContent* aColumnElement, - nsIRDFNode* aColumnIdentifier); - - nsresult - - AddTreeColumn(nsIContent* aElement, - nsIRDFNode* aColumn); - - - PRBool - IsRootColumnsProperty(nsIContent* aElement, - nsIRDFResource* aProperty); - PRBool IsTreeElement(nsIContent* aElement); @@ -210,12 +198,16 @@ public: PRBool IsColumnElement(nsIContent* node); + + PRBool + IsTreeProperty(nsIRDFResource* aProperty); }; //////////////////////////////////////////////////////////////////////// nsrefcnt RDFTreeBuilderImpl::gRefCnt = 0; +nsIAtom* RDFTreeBuilderImpl::kContentsGeneratedAtom; nsIAtom* RDFTreeBuilderImpl::kIdAtom; nsIAtom* RDFTreeBuilderImpl::kOpenAtom; nsIAtom* RDFTreeBuilderImpl::kResourceAtom; @@ -224,15 +216,20 @@ nsIAtom* RDFTreeBuilderImpl::kTreeBodyAtom; nsIAtom* RDFTreeBuilderImpl::kTreeCellAtom; nsIAtom* RDFTreeBuilderImpl::kTreeChildrenAtom; nsIAtom* RDFTreeBuilderImpl::kTreeHeadAtom; +nsIAtom* RDFTreeBuilderImpl::kTreeIndentationAtom; nsIAtom* RDFTreeBuilderImpl::kTreeItemAtom; -nsIAtom* RDFTreeBuilderImpl::kTreeRowAtom; PRInt32 RDFTreeBuilderImpl::kNameSpaceID_RDF; PRInt32 RDFTreeBuilderImpl::kNameSpaceID_XUL; nsIRDFService* RDFTreeBuilderImpl::gRDFService = nsnull; nsIRDFResource* RDFTreeBuilderImpl::kNC_Title; +nsIRDFResource* RDFTreeBuilderImpl::kNC_child; nsIRDFResource* RDFTreeBuilderImpl::kNC_Column; +nsIRDFResource* RDFTreeBuilderImpl::kNC_Folder; +nsIRDFResource* RDFTreeBuilderImpl::kRDF_child; + +//////////////////////////////////////////////////////////////////////// nsresult NS_NewRDFTreeBuilder(nsIRDFContentModelBuilder** result) @@ -253,21 +250,26 @@ NS_NewRDFTreeBuilder(nsIRDFContentModelBuilder** result) RDFTreeBuilderImpl::RDFTreeBuilderImpl(void) + : mDocument(nsnull), + mDB(nsnull), + mRoot(nsnull) { NS_INIT_REFCNT(); if (gRefCnt == 0) { - kIdAtom = NS_NewAtom("ID"); - kOpenAtom = NS_NewAtom("OPEN"); - kResourceAtom = NS_NewAtom("resource"); + kContentsGeneratedAtom = NS_NewAtom("contentsGenerated"); - kTreeAtom = NS_NewAtom("tree"); - kTreeBodyAtom = NS_NewAtom("treebody"); - kTreeCellAtom = NS_NewAtom("treecell"); - kTreeChildrenAtom = NS_NewAtom("treechildren"); - kTreeHeadAtom = NS_NewAtom("treehead"); - kTreeItemAtom = NS_NewAtom("treeitem"); - kTreeRowAtom = NS_NewAtom("treerow"); + kIdAtom = NS_NewAtom("ID"); + kOpenAtom = NS_NewAtom("OPEN"); + kResourceAtom = NS_NewAtom("resource"); + + kTreeAtom = NS_NewAtom("tree"); + kTreeBodyAtom = NS_NewAtom("treebody"); + kTreeCellAtom = NS_NewAtom("treecell"); + kTreeChildrenAtom = NS_NewAtom("treechildren"); + kTreeHeadAtom = NS_NewAtom("treehead"); + kTreeIndentationAtom = NS_NewAtom("treeindentation"); + kTreeItemAtom = NS_NewAtom("treeitem"); nsresult rv; @@ -312,8 +314,17 @@ static const char kRDFNameSpaceURI[] NS_VERIFY(NS_SUCCEEDED(gRDFService->GetResource(kURINC_Title, &kNC_Title)), "couldn't get resource"); + NS_VERIFY(NS_SUCCEEDED(gRDFService->GetResource(kURINC_child, &kNC_child)), + "couldn't get resource"); + NS_VERIFY(NS_SUCCEEDED(gRDFService->GetResource(kURINC_Column, &kNC_Column)), "couldn't get resource"); + + NS_VERIFY(NS_SUCCEEDED(gRDFService->GetResource(kURINC_Folder, &kNC_Folder)), + "couldn't get resource"); + + NS_VERIFY(NS_SUCCEEDED(gRDFService->GetResource(kURIRDF_child, &kRDF_child)), + "couldn't get resource"); } ++gRefCnt; @@ -321,11 +332,14 @@ static const char kRDFNameSpaceURI[] RDFTreeBuilderImpl::~RDFTreeBuilderImpl(void) { + NS_IF_RELEASE(mRoot); NS_IF_RELEASE(mDB); - NS_IF_RELEASE(mDocument); + // NS_IF_RELEASE(mDocument) not refcounted --gRefCnt; if (gRefCnt == 0) { + NS_RELEASE(kContentsGeneratedAtom); + NS_RELEASE(kIdAtom); NS_RELEASE(kOpenAtom); NS_RELEASE(kResourceAtom); @@ -335,8 +349,8 @@ RDFTreeBuilderImpl::~RDFTreeBuilderImpl(void) NS_RELEASE(kTreeCellAtom); NS_RELEASE(kTreeChildrenAtom); NS_RELEASE(kTreeHeadAtom); + NS_RELEASE(kTreeIndentationAtom); NS_RELEASE(kTreeItemAtom); - NS_RELEASE(kTreeRowAtom); NS_RELEASE(kNC_Title); NS_RELEASE(kNC_Column); @@ -347,7 +361,32 @@ RDFTreeBuilderImpl::~RDFTreeBuilderImpl(void) //////////////////////////////////////////////////////////////////////// -NS_IMPL_ISUPPORTS(RDFTreeBuilderImpl, kIRDFContentModelBuilderIID); +NS_IMPL_ADDREF(RDFTreeBuilderImpl); +NS_IMPL_RELEASE(RDFTreeBuilderImpl); + +NS_IMETHODIMP +RDFTreeBuilderImpl::QueryInterface(REFNSIID iid, void** aResult) +{ + NS_PRECONDITION(aResult != nsnull, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; + + if (iid.Equals(kIRDFContentModelBuilderIID) || + iid.Equals(kISupportsIID)) { + *aResult = NS_STATIC_CAST(nsIRDFContentModelBuilder*, this); + NS_ADDREF(this); + return NS_OK; + } + else if (iid.Equals(kIRDFObserverIID)) { + *aResult = NS_STATIC_CAST(nsIRDFObserver*, this); + NS_ADDREF(this); + return NS_OK; + } + else { + *aResult = nsnull; + return NS_NOINTERFACE; + } +} //////////////////////////////////////////////////////////////////////// // nsIRDFContentModelBuilder methods @@ -359,17 +398,47 @@ RDFTreeBuilderImpl::SetDocument(nsIRDFDocument* aDocument) if (! aDocument) return NS_ERROR_NULL_POINTER; + NS_PRECONDITION(mDocument == nsnull, "already initialized"); + if (mDocument) + return NS_ERROR_ALREADY_INITIALIZED; + mDocument = aDocument; // not refcounted - - nsresult rv; - if (NS_FAILED(rv = mDocument->GetDataBase(mDB))) - return rv; - return NS_OK; } + NS_IMETHODIMP -RDFTreeBuilderImpl::CreateRoot(nsIRDFResource* aResource) +RDFTreeBuilderImpl::SetDataBase(nsIRDFCompositeDataSource* aDataBase) +{ + NS_PRECONDITION(aDataBase != nsnull, "null ptr"); + if (! aDataBase) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(mDB == nsnull, "already initialized"); + if (mDB) + return NS_ERROR_ALREADY_INITIALIZED; + + mDB = aDataBase; + NS_ADDREF(mDB); + return NS_OK; +} + + +NS_IMETHODIMP +RDFTreeBuilderImpl::GetDataBase(nsIRDFCompositeDataSource** aDataBase) +{ + NS_PRECONDITION(aDataBase != nsnull, "null ptr"); + if (! aDataBase) + return NS_ERROR_NULL_POINTER; + + *aDataBase = mDB; + NS_ADDREF(mDB); + return NS_OK; +} + + +NS_IMETHODIMP +RDFTreeBuilderImpl::CreateRootContent(nsIRDFResource* aResource) { // Create a structure that looks like this: // @@ -437,15 +506,54 @@ RDFTreeBuilderImpl::CreateRoot(nsIRDFResource* aResource) return NS_OK; } +NS_IMETHODIMP +RDFTreeBuilderImpl::SetRootContent(nsIContent* aElement) +{ + NS_IF_RELEASE(mRoot); + mRoot = aElement; + NS_IF_ADDREF(mRoot); + return NS_OK; +} + NS_IMETHODIMP -RDFTreeBuilderImpl::CreateContents(nsIRDFContent* aElement) +RDFTreeBuilderImpl::CreateContents(nsIContent* aElement) { nsresult rv; - nsCOMPtr resource; - if (NS_FAILED(rv = aElement->GetResource(*getter_AddRefs(resource)))) + { + // Make sure that we're actually creating content for the tree + // content model that we've been assigned to deal with. + nsCOMPtr treeElement; + if (NS_FAILED(FindTreeElement(aElement, getter_AddRefs(treeElement)))) + return NS_OK; + + if (treeElement != mRoot) + return NS_OK; + } + + // Get the treeitem's resource so that we can generate cell + // values. We could QI for the nsIRDFResource here, but doing this + // via the nsIContent interface allows us to support generic nodes + // that might get added in by DOM calls. + nsAutoString uri; + if (NS_FAILED(rv = aElement->GetAttribute(kNameSpaceID_RDF, + kIdAtom, + uri))) { + NS_ERROR("severe error retrieving attribute"); return rv; + } + + if (rv != NS_CONTENT_ATTR_HAS_VALUE) { + NS_ERROR("tree element has no RDF:ID"); + return NS_ERROR_UNEXPECTED; + } + + nsCOMPtr resource; + if (NS_FAILED(rv = gRDFService->GetUnicodeResource(uri, getter_AddRefs(resource)))) { + NS_ERROR("unable to create resource"); + return rv; + } // XXX Eventually, we may want to factor this into one method that // handles RDF containers (RDF:Bag, et al.) and another that @@ -467,35 +575,38 @@ RDFTreeBuilderImpl::CreateContents(nsIRDFContent* aElement) // object that is member of the current container element; // rather, it specifies a "simple" property of the container // element. Skip it. - PRBool isTreeProperty; - if (NS_FAILED(rv = mDocument->IsTreeProperty(property, &isTreeProperty)) || !isTreeProperty) { + if (! IsTreeProperty(property)) continue; - } -#ifdef DEBUG - { - const char* s; - property->GetValue(&s); - } -#endif // Create a second cursor that'll enumerate all of the values // for all of the arcs. nsCOMPtr assertions; - if (NS_FAILED(rv = mDB->GetTargets(resource, property, PR_TRUE, getter_AddRefs(assertions)))) - break; + if (NS_FAILED(rv = mDB->GetTargets(resource, property, PR_TRUE, getter_AddRefs(assertions)))) { + NS_ERROR("unable to get targets for property"); + return rv; + } while (NS_SUCCEEDED(rv = assertions->Advance())) { nsCOMPtr value; - if (NS_FAILED(rv = assertions->GetValue(getter_AddRefs(value)))) - return rv; // XXX fatal + if (NS_FAILED(rv = assertions->GetValue(getter_AddRefs(value)))) { + NS_ERROR("unable to get cursor value"); + return rv; + } - // XXX Eventually, we should make this call the - // appropriate thing directly to avoid the overhead of - // figuring out what the heck is going on in OnAssert(): - // this'll be much easier once XUL specifies all the - // column info. - if (NS_FAILED(rv = OnAssert(aElement, property, value))) - return rv; // XXX fatal + nsCOMPtr valueResource; + if (NS_SUCCEEDED(value->QueryInterface(kIRDFResourceIID, (void**) getter_AddRefs(valueResource))) + && IsTreeProperty(property)) { + if (NS_FAILED(rv = AddTreeRow(aElement, property, valueResource))) { + NS_ERROR("unable to create tree row"); + return rv; + } + } + else { + if (NS_FAILED(rv = SetCellValue(aElement, property, value))) { + NS_ERROR("unable to set cell value"); + return rv; + } + } } } @@ -508,73 +619,91 @@ RDFTreeBuilderImpl::CreateContents(nsIRDFContent* aElement) NS_IMETHODIMP -RDFTreeBuilderImpl::OnAssert(nsIRDFContent* aElement, - nsIRDFResource* aProperty, - nsIRDFNode* aValue) +RDFTreeBuilderImpl::OnAssert(nsIRDFResource* aSubject, + nsIRDFResource* aPredicate, + nsIRDFNode* aObject) { - // So here's where a new assertion comes in. Figure out what that - // means to the content model. + NS_PRECONDITION(mDocument != nsnull, "not initialized"); + if (! mDocument) + return NS_ERROR_NOT_INITIALIZED; nsresult rv; - nsCOMPtr resource; - if (NS_SUCCEEDED(rv = aValue->QueryInterface(kIRDFResourceIID, - (void**) getter_AddRefs(resource)))) { - if (IsRootColumnsProperty(aElement, aProperty)) { - // XXX this should go away once XUL specifies columns... - return EnsureTreeHasHeadAndRow(aElement, aValue); - } - - if (IsColumnProperty(aElement, aProperty)) { - // XXX this should go away once XUL specifies columns... - return AddTreeColumn(aElement, aValue); - } - - PRBool isTreeProperty; - if (NS_SUCCEEDED(mDocument->IsTreeProperty(aProperty, &isTreeProperty)) && isTreeProperty) { - return AddTreeRow(aElement, aProperty, resource); - } - -#if 0 - if (rdf_IsContainer(mDB, resource)) { - return AddTreeRow(aElement, aProperty, resource); - } -#endif - - // fall through and add URI as a cell value + nsCOMPtr elements; + if (NS_FAILED(rv = NS_NewISupportsArray(getter_AddRefs(elements)))) { + NS_ERROR("unable to create new ISupportsArray"); + return rv; } - // XXX this should go away once XUL specifies columns... - if (IsColumnElement(aElement)) { - if (aProperty == kNC_Title) { - return SetColumnTitle(aElement, aValue); - } - else if (aProperty == kNC_Column) { - return SetColumnResource(aElement, aValue); + // Find all the elements in the content model that correspond to + // aSubject: for each, we'll try to build XUL children if + // appropriate. + if (NS_FAILED(rv = mDocument->GetElementsForResource(aSubject, elements))) { + NS_ERROR("unable to retrieve elements from resource"); + return rv; + } + + for (PRInt32 i = elements->Count() - 1; i >= 0; --i) { + nsCOMPtr element(elements->ElementAt(i)); + + // XXX somehow figure out if building XUL kids on this + // particular element makes any sense whatsoever. + + // We'll start by making sure that the element at least has + // the same parent has the content model builder's root + NS_NOTYETIMPLEMENTED("write me!"); + + nsCOMPtr resource; + if (NS_SUCCEEDED(aObject->QueryInterface(kIRDFResourceIID, + (void**) getter_AddRefs(resource))) + && IsTreeProperty(aPredicate)) { + // Okay, the object _is_ a resource, and the predicate is + // a tree property. So this'll be a new row in the tree + // control. + + // But if the contents of aElement _haven't_ yet been + // generated, then just ignore the assertion. We do this + // because we know that _eventually_ the contents will be + // generated (via CreateContents()) when somebody asks for + // them later. + nsAutoString contentsGenerated; + if (NS_FAILED(rv = element->GetAttribute(kNameSpaceID_XUL, + kContentsGeneratedAtom, + contentsGenerated))) { + NS_ERROR("severe problem trying to get attribute"); + return rv; + } + + if ((rv == NS_CONTENT_ATTR_HAS_VALUE) && + contentsGenerated.EqualsIgnoreCase("true")) { + // Okay, it's a "live" element, so go ahead and append the new + // child to this node. + if (NS_FAILED(rv = AddTreeRow(element, aPredicate, resource))) { + NS_ERROR("unable to create new tree row"); + return rv; + } + } } else { - // don't add any other crap to the column element - return NS_OK; + // Either the object of the assertion is not a resource, + // or the object is a resource and the predicate is not a + // tree property. So this won't be a new row in the + // table. See if we can use it to set a cell value on the + // current element. + if (NS_FAILED(rv = SetCellValue(element, aPredicate, aObject))) { + NS_ERROR("unable to set cell value"); + return rv; + } } } - - // XXX don't add random properties to the root or the column - // set. Properties that hang off of the root end up in the root's - // TREEHEAD tag, which makes them appear as dummy columns - // sometimes. - // XXX this should go away once XUL specifies columns... - if (IsTreeElement(aElement) || IsColumnSetElement(aElement)) { - return NS_OK; - } - - return SetCellValue(aElement, aProperty, aValue); + return NS_OK; } NS_IMETHODIMP -RDFTreeBuilderImpl::OnUnassert(nsIRDFContent* aElement, - nsIRDFResource* aProperty, - nsIRDFNode* aValue) +RDFTreeBuilderImpl::OnUnassert(nsIRDFResource* aSubject, + nsIRDFResource* aPredicate, + nsIRDFNode* aObject) { return NS_OK; } @@ -664,8 +793,13 @@ RDFTreeBuilderImpl::FindChildByTagAndResource(nsIContent* aElement, // might've added this stuff in... nsAutoString uri; - if (NS_FAILED(kid->GetAttribute(kNameSpaceID_RDF, kIdAtom, uri))) - continue; // not specified + if (NS_FAILED(rv = kid->GetAttribute(kNameSpaceID_RDF, kIdAtom, uri))) { + NS_ERROR("severe error retrieving attribute"); + return rv; // XXX fatal + } + + if (rv != NS_CONTENT_ATTR_HAS_VALUE) + continue; if (! uri.Equals(resourceURI)) continue; // not the resource we want @@ -779,9 +913,7 @@ RDFTreeBuilderImpl::AddTreeRow(nsIContent* aElement, treeChildren->AppendChildTo(treeItem, PR_TRUE); // Create the row and cell substructure - nsCOMPtr rowElement; - if (NS_FAILED(rv = CreateTreeItemRowAndCells(treeItem, - getter_AddRefs(rowElement)))) + if (NS_FAILED(rv = CreateTreeItemCells(treeItem))) return rv; if (NS_FAILED(rv = treeItem->SetContainer(PR_TRUE))) @@ -798,171 +930,6 @@ RDFTreeBuilderImpl::AddTreeRow(nsIContent* aElement, } -nsresult -RDFTreeBuilderImpl::EnsureTreeHasHeadAndRow(nsIContent* aTreeElement, - nsIRDFNode* aColumnsContainer) -{ - nsresult rv; - nsCOMPtr treeHead; - - // This constructs the tree header beneath the xul:tree tag: - // - // - // - // - // - // - // - // - // Where the RDF:ID corresponds to the URI of the RDF container - // that identifies all of the columns - - // See if the is already there... - if (NS_SUCCEEDED(rv = FindChildByTag(aTreeElement, - kNameSpaceID_XUL, - kTreeHeadAtom, - getter_AddRefs(treeHead)))) - return NS_OK; - - if (rv != NS_ERROR_RDF_NO_VALUE) - return rv; // something serious happened - - // ...nope. So create it. - if (NS_FAILED(rv = NS_NewRDFGenericElement(getter_AddRefs(treeHead), - kNameSpaceID_XUL, - kTreeHeadAtom))) - return rv; - - // ...and now create beneath - nsCOMPtr resource; - if (NS_FAILED(rv = aColumnsContainer->QueryInterface(kIRDFResourceIID, - (void**) getter_AddRefs(resource)))) - return rv; - - nsCOMPtr treeRow; - if (NS_FAILED(rv = NS_NewRDFResourceElement(getter_AddRefs(treeRow), - resource, - kNameSpaceID_XUL, - kTreeRowAtom))) - return rv; - - if (NS_FAILED(rv = treeRow->SetContainer(PR_TRUE))) - return rv; - - // Now put 'em both into the content model. - if (NS_FAILED(rv = aTreeElement->AppendChildTo(treeHead, PR_FALSE))) - return rv; - - if (NS_FAILED(rv = treeHead->AppendChildTo(treeRow, PR_FALSE))) - return rv; - - return NS_OK; -} - - -nsresult -RDFTreeBuilderImpl::SetColumnTitle(nsIContent* aColumnElement, - nsIRDFNode* aTitleNode) -{ - nsresult rv; - - nsCOMPtr title; - - if (NS_FAILED(aTitleNode->QueryInterface(kIRDFLiteralIID, - (void**) getter_AddRefs(title)))) - return rv; - - if (NS_FAILED(rv = rdf_AttachTextNode(aColumnElement, title))) - return rv; - - return NS_OK; -} - - -nsresult -RDFTreeBuilderImpl::SetColumnResource(nsIContent* aColumn, - nsIRDFNode* aNode) -{ - nsresult rv; - - // XXX if we were paranoid, we'd make sure that aTreeCellElement - // was really a in the tree's treehead. - - // This sets the RDF:resource property on the - // element to refer to the resource that this column is to - // represent. - - nsCOMPtr resource; - if (NS_FAILED(rv = aNode->QueryInterface(kIRDFResourceIID, - (void**) getter_AddRefs(resource)))) - return rv; - - const char* uri; - if (NS_FAILED(rv = resource->GetValue(&uri))) - return rv; - - if (NS_FAILED(rv = aColumn->SetAttribute(kNameSpaceID_RDF, - kResourceAtom, - uri, - PR_FALSE))) - return rv; - - // XXX At this point, if we've actually changed the column - // resource to something different, we need to grovel through all - // the rows in the table and fix up the cells corresponding to - // this column. - - return NS_OK; -} - - -nsresult -RDFTreeBuilderImpl::AddTreeColumn(nsIContent* aTreeRowElement, - nsIRDFNode* aColumnNode) -{ - nsresult rv; - - nsCOMPtr column; - if (NS_FAILED(rv = aColumnNode->QueryInterface(kIRDFResourceIID, - (void**) getter_AddRefs(column)))) - return rv; - - // Create a column element as a , with an RDF:ID of - // the column resource. - nsCOMPtr columnElement; - if (NS_FAILED(rv = NS_NewRDFResourceElement(getter_AddRefs(columnElement), - column, - kNameSpaceID_XUL, - kTreeCellAtom))) - return rv; - - if (NS_FAILED(rv = aTreeRowElement->AppendChildTo(columnElement, PR_FALSE))) - return rv; - - // Try to set the title now, if we can - nsCOMPtr titleNode; - if (NS_SUCCEEDED(rv = mDB->GetTarget(column, kNC_Title, PR_TRUE, getter_AddRefs(titleNode)))) - { - rv = SetColumnTitle(columnElement, titleNode); - NS_VERIFY(NS_SUCCEEDED(rv), "unable to set column title"); - } - - // Try to set the column resource, if we can - nsCOMPtr columnNode; - if (NS_SUCCEEDED(rv = mDB->GetTarget(column, kNC_Column, PR_TRUE, getter_AddRefs(columnNode)))) - { - rv = SetColumnResource(columnElement, columnNode); - NS_VERIFY(NS_SUCCEEDED(rv), "unable to set column resource"); - } - - // XXX At this point, we need to grovel through *all* the rows in - // the table, and add the cell corresponding to this column to - // each. - - return NS_OK; -} - - nsresult RDFTreeBuilderImpl::FindTreeElement(nsIContent* aElement, nsIContent** aTreeElement) @@ -995,18 +962,15 @@ RDFTreeBuilderImpl::FindTreeElement(nsIContent* aElement, element = parent; } - NS_ERROR("must not've started from within a xul:tree"); + //NS_ERROR("must not've started from within a xul:tree"); return NS_ERROR_FAILURE; } nsresult -RDFTreeBuilderImpl::CreateTreeItemRowAndCells(nsIContent* aTreeItemElement, - nsIContent** aTreeRowElement) +RDFTreeBuilderImpl::CreateTreeItemCells(nsIContent* aTreeItemElement) { // - // - // value - // + // value // ... // nsresult rv; @@ -1024,19 +988,16 @@ RDFTreeBuilderImpl::CreateTreeItemRowAndCells(nsIContent* aTreeItemElement, treeItemResourceURI))) return rv; + if (rv != NS_CONTENT_ATTR_HAS_VALUE) { + NS_ERROR("xul:treeitem has no RDF:ID"); + return NS_ERROR_UNEXPECTED; + } + nsCOMPtr treeItemResource; if (NS_FAILED(rv = gRDFService->GetUnicodeResource(treeItemResourceURI, getter_AddRefs(treeItemResource)))) return rv; - // Create the element - nsCOMPtr rowElement; - if (NS_FAILED(rv = EnsureElementHasGenericChild(aTreeItemElement, - kNameSpaceID_XUL, - kTreeRowAtom, - getter_AddRefs(rowElement)))) - return rv; - // Now walk up to the primordial tag, then down into // the so that we can iterate through all of the // tree's columns. @@ -1052,23 +1013,22 @@ RDFTreeBuilderImpl::CreateTreeItemRowAndCells(nsIContent* aTreeItemElement, getter_AddRefs(treeHead)))) return rv; - nsCOMPtr treeRow; + nsCOMPtr treeItem; if (NS_FAILED(rv = FindChildByTag(treeHead, kNameSpaceID_XUL, - kTreeRowAtom, - getter_AddRefs(treeRow)))) + kTreeItemAtom, + getter_AddRefs(treeItem)))) return rv; PRInt32 count; - if (NS_FAILED(rv = treeRow->ChildCount(count))) + if (NS_FAILED(rv = treeItem->ChildCount(count))) return rv; // Iterate through all the columns that have been specified, // constructing a cell in the content model for each one. for (PRInt32 i = 0; i < count; ++i) { - nsCOMPtr kid; - if (NS_FAILED(rv = treeRow->ChildAt(i, *getter_AddRefs(kid)))) + if (NS_FAILED(rv = treeItem->ChildAt(i, *getter_AddRefs(kid)))) return rv; // XXX fatal PRInt32 nameSpaceID; @@ -1089,48 +1049,91 @@ RDFTreeBuilderImpl::CreateTreeItemRowAndCells(nsIContent* aTreeItemElement, // of the tag. nsAutoString uri; if (NS_FAILED(rv = kid->GetAttribute(kNameSpaceID_RDF, kResourceAtom, uri))) { - NS_WARNING("column header with no RDF:resource"); - continue; + NS_ERROR("severe error occured retrieving attribute"); + return rv; } - // now construct the cell - nsCOMPtr property; - if (NS_FAILED(gRDFService->GetUnicodeResource(uri, getter_AddRefs(property)))) - return rv; // XXX fatal + if (rv == NS_CONTENT_ATTR_HAS_VALUE) { + // now construct the cell + nsCOMPtr property; + if (NS_FAILED(gRDFService->GetUnicodeResource(uri, getter_AddRefs(property)))) { + NS_ERROR("unable to construct resource for xul:treecell"); + return rv; // XXX fatal + } - nsCOMPtr cellElement; - if (NS_FAILED(rv = NS_NewRDFResourceElement(getter_AddRefs(cellElement), - property, - kNameSpaceID_XUL, - kTreeCellAtom))) - return rv; + nsCOMPtr cellElement; + if (NS_FAILED(rv = NS_NewRDFResourceElement(getter_AddRefs(cellElement), + property, + kNameSpaceID_XUL, + kTreeCellAtom))) { + NS_ERROR("unable to create new xul:treecell"); + return rv; + } - if (NS_FAILED(rv = rowElement->AppendChildTo(cellElement, PR_FALSE))) - return rv; + if (NS_FAILED(rv = aTreeItemElement->AppendChildTo(cellElement, PR_FALSE))) { + NS_ERROR("unable to appen xul:treecell to treeitem"); + return rv; + } - // Set its value, if we know it. - nsCOMPtr value; - if (NS_FAILED(rv = mDB->GetTarget(treeItemResource, - property, - PR_TRUE, - getter_AddRefs(value)))) { - if (rv != NS_ERROR_RDF_NO_VALUE) { + if (i == 0) { + // The first column gets a element. + + // XXX This is bogus: dogfood ready crap. We need to + // figure out a better way to specify this. + nsCOMPtr indentationElement; + if (NS_FAILED(rv = NS_NewRDFGenericElement(getter_AddRefs(indentationElement), + kNameSpaceID_XUL, + kTreeIndentationAtom))) { + NS_ERROR("unable to create indentation node"); + return rv; + } + + if (NS_FAILED(rv = cellElement->AppendChildTo(indentationElement, PR_FALSE))) { + NS_ERROR("unable to append indentation element"); + return rv; + } + } + + // Set its value, if we know it. + nsCOMPtr value; + if (NS_SUCCEEDED(rv = mDB->GetTarget(treeItemResource, + property, + PR_TRUE, + getter_AddRefs(value)))) { + if (NS_FAILED(rv = rdf_AttachTextNode(cellElement, value))) { + NS_ERROR("unable to attach text node to xul:treecell"); + return rv; // XXX fatal + } + } + else if (rv == NS_ERROR_RDF_NO_VALUE) { + // otherwise, there was no value for this. It'll have to + // get set later, when an OnAssert() comes in (if it even + // has a value at all...) + } + else { NS_ERROR("error getting cell's value"); return rv; // XXX something serious happened } - - // otherwise, there was no value for this. It'll have to - // get set later, when an OnAssert() comes in (if it even - // has a value at all...) - continue; } + else { + // attach an empty cell + NS_WARNING("column header with no RDF:resource"); - if (NS_FAILED(rv = rdf_AttachTextNode(cellElement, value))) - return rv; // XXX fatal + nsCOMPtr cellElement; + if (NS_FAILED(rv = NS_NewRDFGenericElement(getter_AddRefs(cellElement), + kNameSpaceID_XUL, + kTreeCellAtom))) { + NS_ERROR("unable to create new xul:treecell"); + return rv; + } + + if (NS_FAILED(rv = aTreeItemElement->AppendChildTo(cellElement, PR_FALSE))) { + NS_ERROR("unable to append xul:treecell to treeitem"); + return rv; + } + } } - *aTreeRowElement = rowElement; - NS_ADDREF(*aTreeRowElement); return NS_OK; } @@ -1145,20 +1148,10 @@ RDFTreeBuilderImpl::SetCellValue(nsIContent* aTreeItemElement, // XXX We assume that aTreeItemElement is actually a // , it'd be good to enforce this... - // Find the child of the - nsCOMPtr rowElement; - if (NS_FAILED(rv = FindChildByTag(aTreeItemElement, - kNameSpaceID_XUL, - kTreeRowAtom, - getter_AddRefs(rowElement)))) { - NS_ERROR("couldn't find xul:treerow in xul:treeitem"); - return rv; - } - - // Find the beneath that corresponds to - // aProperty + // Find the beneath that corresponds + // to aProperty nsCOMPtr cellElement; - if (NS_FAILED(rv = FindChildByTagAndResource(rowElement, + if (NS_FAILED(rv = FindChildByTagAndResource(aTreeItemElement, kNameSpaceID_XUL, kTreeCellAtom, aProperty, @@ -1183,24 +1176,6 @@ RDFTreeBuilderImpl::SetCellValue(nsIContent* aTreeItemElement, } -PRBool -RDFTreeBuilderImpl::IsRootColumnsProperty(nsIContent* aElement, - nsIRDFResource* aProperty) -{ - // Returns PR_TRUE if the element is the tree's root, and the - // property is "NC:Columns", which specifies the column set for - // the tree. - if (! IsTreeElement(aElement)) - return PR_FALSE; - - nsresult rv; - PRBool isColumnsProperty; - if (NS_FAILED(rv = aProperty->EqualsString(kURINC_Columns, &isColumnsProperty))) - return PR_FALSE; - - return isColumnsProperty; -} - PRBool RDFTreeBuilderImpl::IsTreeElement(nsIContent* element) @@ -1241,7 +1216,7 @@ PRBool RDFTreeBuilderImpl::IsColumnSetElement(nsIContent* aElement) { // Returns PR_TRUE if the specified element is the tree's column - // set; that is, it is the inside the + // set; that is, it is the inside the // that specifies the tree's columns. nsresult rv; @@ -1250,7 +1225,7 @@ RDFTreeBuilderImpl::IsColumnSetElement(nsIContent* aElement) if (NS_FAILED(rv = aElement->GetTag(*getter_AddRefs(elementTag)))) return PR_FALSE; - if (elementTag != kTreeRowAtom) + if (elementTag != kTreeItemAtom) return PR_FALSE; // "parent" must be xul:treehead @@ -1324,3 +1299,27 @@ RDFTreeBuilderImpl::IsColumnElement(nsIContent* aElement) return IsColumnSetElement(parent); } + + +PRBool +RDFTreeBuilderImpl::IsTreeProperty(nsIRDFResource* aProperty) +{ + // XXX This whole method is a mega-kludge. This should be read off + // of the element somehow... + +#define TREE_PROPERTY_HACK +#if defined(TREE_PROPERTY_HACK) + if ((aProperty == kNC_child) || + (aProperty == kNC_Folder) || + (aProperty == kRDF_child)) { + return PR_TRUE; + } + else +#endif // defined(TREE_PROPERTY_HACK) + if (rdf_IsOrdinalProperty(aProperty)) { + return PR_TRUE; + } + else { + return PR_FALSE; + } +} diff --git a/mozilla/rdf/content/src/nsRDFXULBuilder.cpp b/mozilla/rdf/content/src/nsRDFXULBuilder.cpp index e393f81b061..faa7b8063ea 100644 --- a/mozilla/rdf/content/src/nsRDFXULBuilder.cpp +++ b/mozilla/rdf/content/src/nsRDFXULBuilder.cpp @@ -21,6 +21,18 @@ An nsIRDFDocument implementation that builds a XUL content model. + TO DO + + 1) Make sure to hook up the code that keeps track of what content + nodes we're spying on. Ugh: one thing I just realized. By putting + this stuff in the content model builder, we've made it impossible + to cleanly release hidden nodes. We'll need a notification + mechanism for that... + + 2) Figure out how to drag in new builders to merge data from other + sources. I'm thinking something like just spying on the + and tags for some magical + attribute... */ @@ -35,6 +47,7 @@ #include "nsIRDFCompositeDataSource.h" #include "nsIRDFDocument.h" #include "nsIRDFNode.h" +#include "nsIRDFObserver.h" #include "nsIRDFService.h" #include "nsIServiceManager.h" #include "nsINameSpaceManager.h" @@ -47,24 +60,29 @@ #include "rdf.h" #include "rdfutil.h" -#if 0 // need to link against layout.dll for this... -#include "nsIHTMLContent.h" +// XXX These are needed as scaffolding until we get to a more +// DOM-based solution. #include "nsHTMLParts.h" -#endif +#include "nsIHTMLContent.h" //////////////////////////////////////////////////////////////////////// static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID); static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID); static NS_DEFINE_IID(kINameSpaceManagerIID, NS_INAMESPACEMANAGER_IID); -static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID); -static NS_DEFINE_IID(kIRDFLiteralIID, NS_IRDFLITERAL_IID); static NS_DEFINE_IID(kIRDFContentIID, NS_IRDFCONTENT_IID); static NS_DEFINE_IID(kIRDFContentModelBuilderIID, NS_IRDFCONTENTMODELBUILDER_IID); +static NS_DEFINE_IID(kIRDFCompositeDataSourceIID, NS_IRDFCOMPOSITEDATASOURCE_IID); +static NS_DEFINE_IID(kIRDFLiteralIID, NS_IRDFLITERAL_IID); +static NS_DEFINE_IID(kIRDFObserverIID, NS_IRDFOBSERVER_IID); +static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID); static NS_DEFINE_IID(kIRDFServiceIID, NS_IRDFSERVICE_IID); +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID); +static NS_DEFINE_CID(kRDFCompositeDataSourceCID, NS_RDFCOMPOSITEDATASOURCE_CID); static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); +static NS_DEFINE_CID(kRDFTreeBuilderCID, NS_RDFTREEBUILDER_CID); //////////////////////////////////////////////////////////////////////// // standard vocabulary items @@ -74,11 +92,13 @@ DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, child); // XXX bogus: needs to be NC:ch //////////////////////////////////////////////////////////////////////// -class RDFXULBuilderImpl : public nsIRDFContentModelBuilder +class RDFXULBuilderImpl : public nsIRDFContentModelBuilder, + public nsIRDFObserver { private: nsIRDFCompositeDataSource* mDB; nsIRDFDocument* mDocument; + nsIContent* mRoot; // pseudo-constants static PRInt32 gRefCnt; @@ -88,6 +108,9 @@ private: static PRInt32 kNameSpaceID_XUL; static nsIAtom* kContentsGeneratedAtom; + static nsIAtom* kDataSourcesAtom; + static nsIAtom* kIdAtom; + static nsIAtom* kTreeAtom; static nsIRDFResource* kRDF_type; static nsIRDFResource* kRDF_child; // XXX needs to become kNC_child @@ -101,10 +124,15 @@ public: // nsIRDFContentModelBuilder interface NS_IMETHOD SetDocument(nsIRDFDocument* aDocument); - NS_IMETHOD CreateRoot(nsIRDFResource* aResource); - NS_IMETHOD CreateContents(nsIRDFContent* aElement); - NS_IMETHOD OnAssert(nsIRDFContent* aElement, nsIRDFResource* aProperty, nsIRDFNode* aValue); - NS_IMETHOD OnUnassert(nsIRDFContent* aElement, nsIRDFResource* aProperty, nsIRDFNode* aValue); + NS_IMETHOD SetDataBase(nsIRDFCompositeDataSource* aDataBase); + NS_IMETHOD GetDataBase(nsIRDFCompositeDataSource** aDataBase); + NS_IMETHOD CreateRootContent(nsIRDFResource* aResource); + NS_IMETHOD SetRootContent(nsIContent* aResource); + NS_IMETHOD CreateContents(nsIContent* aElement); + + // nsIRDFObserver interface + NS_IMETHOD OnAssert(nsIRDFResource* aSubject, nsIRDFResource* aPredicate, nsIRDFNode* aObject); + NS_IMETHOD OnUnassert(nsIRDFResource* aSubject, nsIRDFResource* aPredicate, nsIRDFNode* aObjetct); // Implementation methods nsresult AppendChild(nsIContent* aElement, @@ -128,9 +156,13 @@ public: nsresult AddAttribute(nsIContent* aElement, nsIRDFResource* aProperty, nsIRDFNode* aValue); + + nsresult CreateTreeBuilder(nsIContent* aElement, + const nsString& aDataSources); }; //////////////////////////////////////////////////////////////////////// +// Pseudo-constants PRInt32 RDFXULBuilderImpl::gRefCnt = 0; nsIRDFService* RDFXULBuilderImpl::gRDFService = nsnull; @@ -139,6 +171,9 @@ PRInt32 RDFXULBuilderImpl::kNameSpaceID_RDF = kNameSpaceID_Unknown; PRInt32 RDFXULBuilderImpl::kNameSpaceID_XUL = kNameSpaceID_Unknown; nsIAtom* RDFXULBuilderImpl::kContentsGeneratedAtom = nsnull; +nsIAtom* RDFXULBuilderImpl::kIdAtom = nsnull; +nsIAtom* RDFXULBuilderImpl::kDataSourcesAtom = nsnull; +nsIAtom* RDFXULBuilderImpl::kTreeAtom = nsnull; nsIRDFResource* RDFXULBuilderImpl::kRDF_type = nsnull; nsIRDFResource* RDFXULBuilderImpl::kRDF_child = nsnull; @@ -162,9 +197,10 @@ NS_NewRDFXULBuilder(nsIRDFContentModelBuilder** result) } - RDFXULBuilderImpl::RDFXULBuilderImpl(void) - : mDB(nsnull) + : mDB(nsnull), + mDocument(nsnull), + mRoot(nsnull) { NS_INIT_REFCNT(); @@ -195,6 +231,11 @@ static const char kRDFNameSpaceURI[] NS_ERROR("couldn't create namepsace manager"); } + kContentsGeneratedAtom = NS_NewAtom("contentsGenerated"); + kIdAtom = NS_NewAtom("ID"); + kDataSourcesAtom = NS_NewAtom("datasources"); + kTreeAtom = NS_NewAtom("tree"); + if (NS_SUCCEEDED(rv = nsServiceManager::GetService(kRDFServiceCID, kIRDFServiceIID, @@ -207,16 +248,16 @@ static const char kRDFNameSpaceURI[] "unable to get resource"); } else { - NS_ERROR("couldnt' get RDF service"); + NS_ERROR("couldn't get RDF service"); } - - kContentsGeneratedAtom = NS_NewAtom("contentsGenerated"); } } RDFXULBuilderImpl::~RDFXULBuilderImpl(void) { + NS_IF_RELEASE(mRoot); NS_IF_RELEASE(mDB); + // NS_IF_RELEASE(mDocument) not refcounted if (--gRefCnt == 0) { if (gRDFService) @@ -224,13 +265,42 @@ RDFXULBuilderImpl::~RDFXULBuilderImpl(void) NS_IF_RELEASE(kRDF_type); NS_IF_RELEASE(kRDF_child); + NS_IF_RELEASE(kContentsGeneratedAtom); + NS_IF_RELEASE(kIdAtom); + NS_IF_RELEASE(kDataSourcesAtom); + NS_IF_RELEASE(kTreeAtom); } } //////////////////////////////////////////////////////////////////////// -NS_IMPL_ISUPPORTS(RDFXULBuilderImpl, kIRDFContentModelBuilderIID); +NS_IMPL_ADDREF(RDFXULBuilderImpl); +NS_IMPL_RELEASE(RDFXULBuilderImpl); + +NS_IMETHODIMP +RDFXULBuilderImpl::QueryInterface(REFNSIID iid, void** aResult) +{ + NS_PRECONDITION(aResult != nsnull, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; + + if (iid.Equals(kIRDFContentModelBuilderIID) || + iid.Equals(kISupportsIID)) { + *aResult = NS_STATIC_CAST(nsIRDFContentModelBuilder*, this); + NS_ADDREF(this); + return NS_OK; + } + else if (iid.Equals(kIRDFObserverIID)) { + *aResult = NS_STATIC_CAST(nsIRDFObserver*, this); + NS_ADDREF(this); + return NS_OK; + } + else { + *aResult = nsnull; + return NS_NOINTERFACE; + } +} //////////////////////////////////////////////////////////////////////// // nsIRDFContentModelBuilder methods @@ -242,17 +312,45 @@ RDFXULBuilderImpl::SetDocument(nsIRDFDocument* aDocument) if (! aDocument) return NS_ERROR_NULL_POINTER; + NS_PRECONDITION(mDocument == nsnull, "already initialized"); + if (mDocument) + return NS_ERROR_ALREADY_INITIALIZED; + mDocument = aDocument; // not refcounted - - nsresult rv; - if (NS_FAILED(rv = mDocument->GetDataBase(mDB))) - return rv; - return NS_OK; } NS_IMETHODIMP -RDFXULBuilderImpl::CreateRoot(nsIRDFResource* aResource) +RDFXULBuilderImpl::SetDataBase(nsIRDFCompositeDataSource* aDataBase) +{ + NS_PRECONDITION(aDataBase != nsnull, "null ptr"); + if (! aDataBase) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(mDB == nsnull, "already initialized"); + if (mDB) + return NS_ERROR_ALREADY_INITIALIZED; + + mDB = aDataBase; + NS_ADDREF(mDB); + return NS_OK; +} + +NS_IMETHODIMP +RDFXULBuilderImpl::GetDataBase(nsIRDFCompositeDataSource** aDataBase) +{ + NS_PRECONDITION(aDataBase != nsnull, "null ptr"); + if (! aDataBase) + return NS_ERROR_NULL_POINTER; + + *aDataBase = mDB; + NS_ADDREF(mDB); + return NS_OK; +} + + +NS_IMETHODIMP +RDFXULBuilderImpl::CreateRootContent(nsIRDFResource* aResource) { NS_PRECONDITION(mDocument != nsnull, "not initialized"); if (! mDocument) @@ -280,15 +378,30 @@ RDFXULBuilderImpl::CreateRoot(nsIRDFResource* aResource) doc->SetRootContent(root); + mRoot = root; + NS_ADDREF(mRoot); + return NS_OK; } NS_IMETHODIMP -RDFXULBuilderImpl::CreateContents(nsIRDFContent* aElement) +RDFXULBuilderImpl::SetRootContent(nsIContent* aElement) +{ + NS_IF_RELEASE(mRoot); + mRoot = aElement; + NS_IF_ADDREF(mRoot); + return NS_OK; +} + + +NS_IMETHODIMP +RDFXULBuilderImpl::CreateContents(nsIContent* aElement) { nsresult rv; + // First, mark the elements contents as being generated so that + // any re-entrant calls don't trigger an infinite recursion. if (NS_FAILED(rv = aElement->SetAttribute(kNameSpaceID_XUL, kContentsGeneratedAtom, "true", @@ -297,12 +410,33 @@ RDFXULBuilderImpl::CreateContents(nsIRDFContent* aElement) return rv; } - nsCOMPtr resource; - if (NS_FAILED(rv = aElement->GetResource(*getter_AddRefs(resource)))) { - NS_ERROR("unable to get resource from element"); + // Get the treeitem's resource so that we can generate cell + // values. We could QI for the nsIRDFResource here, but doing this + // via the nsIContent interface allows us to support generic nodes + // that might get added in by DOM calls. + nsAutoString uri; + if (NS_FAILED(rv = aElement->GetAttribute(kNameSpaceID_RDF, + kIdAtom, + uri))) { + NS_ERROR("severe error retrieving attribute"); return rv; } + if (rv != NS_CONTENT_ATTR_HAS_VALUE) { + NS_ERROR("tree element has no RDF:ID"); + return NS_ERROR_UNEXPECTED; + } + + nsCOMPtr resource; + if (NS_FAILED(rv = gRDFService->GetUnicodeResource(uri, getter_AddRefs(resource)))) { + NS_ERROR("unable to create resource"); + return rv; + } + + // Iterate through all of the XUL:child arcs, and construct + // appropriate children for each arc. + // + // XXX this is RDF:child for now; we should fix that... nsCOMPtr children; if (NS_FAILED(rv = mDB->GetTargets(resource, kRDF_child, PR_TRUE, getter_AddRefs(children)))) { NS_ERROR("unable to create cursor for children"); @@ -330,52 +464,75 @@ RDFXULBuilderImpl::CreateContents(nsIRDFContent* aElement) NS_IMETHODIMP -RDFXULBuilderImpl::OnAssert(nsIRDFContent* aElement, - nsIRDFResource* aProperty, - nsIRDFNode* aValue) +RDFXULBuilderImpl::OnAssert(nsIRDFResource* aSubject, + nsIRDFResource* aPredicate, + nsIRDFNode* aObject) { + NS_PRECONDITION(mDocument != nsnull, "not initialized"); + if (! mDocument) + return NS_ERROR_NOT_INITIALIZED; + nsresult rv; - if (aProperty == kRDF_child) { - // It's a child node. If the contents of aElement _haven't_ - // yet been generated, then just ignore the assertion. We do - // this because we know that _eventually_ the contents will be - // generated (via CreateContents()) when somebody asks for - // them later. - nsAutoString contentsGenerated; - if (NS_FAILED(rv = aElement->GetAttribute(kNameSpaceID_XUL, - kContentsGeneratedAtom, - contentsGenerated))) { - if (rv == NS_CONTENT_ATTR_NOT_THERE) { - return NS_OK; - } - else { + nsCOMPtr elements; + if (NS_FAILED(rv = NS_NewISupportsArray(getter_AddRefs(elements)))) { + NS_ERROR("unable to create new ISupportsArray"); + return rv; + } + + // Find all the elements in the content model that correspond to + // aSubject: for each, we'll try to build XUL children if + // appropriate. + if (NS_FAILED(rv = mDocument->GetElementsForResource(aSubject, elements))) { + NS_ERROR("unable to retrieve elements from resource"); + return rv; + } + + for (PRInt32 i = elements->Count() - 1; i >= 0; --i) { + nsCOMPtr element(elements->ElementAt(i)); + + // XXX somehow figure out if building XUL kids on this + // particular element makes any sense whatsoever. + + if (aPredicate == kRDF_child) { + // It's a child node. If the contents of aElement _haven't_ + // yet been generated, then just ignore the assertion. We do + // this because we know that _eventually_ the contents will be + // generated (via CreateContents()) when somebody asks for + // them later. + nsAutoString contentsGenerated; + if (NS_FAILED(rv = element->GetAttribute(kNameSpaceID_XUL, + kContentsGeneratedAtom, + contentsGenerated))) { NS_ERROR("severe problem trying to get attribute"); return rv; } - } - if (! contentsGenerated.EqualsIgnoreCase("true")) - return NS_OK; + if (rv == NS_CONTENT_ATTR_NOT_THERE || rv == NS_CONTENT_ATTR_NO_VALUE) + continue; - // Okay, it's a "live" element, so go ahead and append the new - // child to this node. - if (NS_FAILED(AppendChild(aElement, aValue))) { - NS_ERROR("problem appending child to content model"); - return rv; + if (! contentsGenerated.EqualsIgnoreCase("true")) + continue; + + // Okay, it's a "live" element, so go ahead and append the new + // child to this node. + if (NS_FAILED(AppendChild(element, aObject))) { + NS_ERROR("problem appending child to content model"); + return rv; + } } - } - else if (aProperty == kRDF_type) { - // We shouldn't ever see this: if we do, there ain't much we - // can do. - NS_ERROR("attempt to change tag type after-the-fact"); - return NS_ERROR_UNEXPECTED; - } - else { - // Add the thing as a vanilla attribute to the element. - if (NS_FAILED(rv = AddAttribute(aElement, aProperty, aValue))) { - NS_ERROR("unable to add attribute to the element"); - return rv; + else if (aPredicate == kRDF_type) { + // We shouldn't ever see this: if we do, there ain't much we + // can do. + NS_ERROR("attempt to change tag type after-the-fact"); + return NS_ERROR_UNEXPECTED; + } + else { + // Add the thing as a vanilla attribute to the element. + if (NS_FAILED(rv = AddAttribute(element, aPredicate, aObject))) { + NS_ERROR("unable to add attribute to the element"); + return rv; + } } } return NS_OK; @@ -383,9 +540,9 @@ RDFXULBuilderImpl::OnAssert(nsIRDFContent* aElement, NS_IMETHODIMP -RDFXULBuilderImpl::OnUnassert(nsIRDFContent* aElement, - nsIRDFResource* aProperty, - nsIRDFNode* aValue) +RDFXULBuilderImpl::OnUnassert(nsIRDFResource* aSubject, + nsIRDFResource* aPredicate, + nsIRDFNode* aObject) { NS_NOTYETIMPLEMENTED("write me!"); return NS_ERROR_NOT_IMPLEMENTED; @@ -467,10 +624,12 @@ RDFXULBuilderImpl::CreateElement(nsIRDFResource* aResource, return rv; } - if (nameSpaceID == kNameSpaceID_HTML) + if (nameSpaceID == kNameSpaceID_HTML) { return CreateHTMLElement(aResource, tag, aResult); - else + } + else { return CreateXULElement(aResource, nameSpaceID, tag, aResult); + } } nsresult @@ -478,17 +637,33 @@ RDFXULBuilderImpl::CreateHTMLElement(nsIRDFResource* aResource, nsIAtom* aTag, nsIContent** aResult) { - NS_NOTYETIMPLEMENTED("need to link against layout.dll for this to work"); - -#if 0 nsresult rv; + // XXX This is where we go out and create the HTML content. It's a + // bit of a hack: a bridge until we get to a more DOM-based + // solution. nsCOMPtr element; if (NS_FAILED(rv = NS_CreateHTMLElement(getter_AddRefs(element), aTag->GetUnicode()))) { NS_ERROR("unable to create HTML element"); return rv; } + { + // Force the document to be set _here_. Many of the + // AppendChildTo() implementations do not recursively ensure + // that the child's doc is the same as the parent's. + nsCOMPtr doc; + if (NS_FAILED(rv = mDocument->QueryInterface(kIDocumentIID, getter_AddRefs(doc)))) { + NS_ERROR("uh, this isn't a document!"); + return rv; + } + + if (NS_FAILED(rv = element->SetDocument(doc, PR_FALSE))) { + NS_ERROR("couldn't set document on the element"); + return rv; + } + } + // Now iterate through all the properties and add them as // attributes on the element. First, create a cursor that'll // iterate through all the properties that lead out of this @@ -548,7 +723,6 @@ RDFXULBuilderImpl::CreateHTMLElement(nsIRDFResource* aResource, NS_ERROR("unable to get nsIContent interface"); return rv; } -#endif return NS_OK; } @@ -658,6 +832,18 @@ RDFXULBuilderImpl::CreateXULElement(nsIRDFResource* aResource, return rv; } + // There are some tags that we need to pay extra-special attention to... + if (aTag == kTreeAtom) { + nsAutoString dataSources; + if (NS_CONTENT_ATTR_HAS_VALUE == + element->GetAttribute(kNameSpaceID_XUL, + kDataSourcesAtom, + dataSources)) { + rv = CreateTreeBuilder(element, dataSources); + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add datasources"); + } + } + // Finally, assign the newly constructed element to the result // pointer and addref it for the trip home. *aResult = element; @@ -709,3 +895,102 @@ RDFXULBuilderImpl::AddAttribute(nsIContent* aElement, return rv; } + + +nsresult +RDFXULBuilderImpl::CreateTreeBuilder(nsIContent* aElement, + const nsString& aDataSources) +{ + nsresult rv; + + // construct a new builder + nsCOMPtr builder; + if (NS_FAILED(rv = nsRepository::CreateInstance(kRDFTreeBuilderCID, + nsnull, + kIRDFContentModelBuilderIID, + (void**) getter_AddRefs(builder)))) { + NS_ERROR("unable to create tree content model builder"); + return rv; + } + + if (NS_FAILED(rv = builder->SetRootContent(aElement))) { + NS_ERROR("unable to set builder's root content element"); + return rv; + } + + // create a database for the builder + nsCOMPtr db; + if (NS_FAILED(rv = nsRepository::CreateInstance(kRDFCompositeDataSourceCID, + nsnull, + kIRDFCompositeDataSourceIID, + (void**) getter_AddRefs(db)))) { + NS_ERROR("unable to construct new composite data source"); + 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 < aDataSources.Length() && nsString::IsSpace(aDataSources[first])) + ++first; + + if (first >= aDataSources.Length()) + break; + + PRInt32 last = first; + while (last < aDataSources.Length() && !nsString::IsSpace(aDataSources[last])) + ++last; + + nsAutoString uri; + aDataSources.Mid(uri, first, last - first); + first = last + 1; + + nsCOMPtr ds; + + // Some monkey business to convert the nsAutoString to a + // C-string safely. Sure'd be nice to have this be automagic. + { + char buf[256], *p = buf; + if (uri.Length() >= sizeof(buf)) + p = new char[uri.Length() + 1]; + + uri.ToCString(p, uri.Length() + 1); + + rv = gRDFService->GetDataSource(p, getter_AddRefs(ds)); + + if (p != buf) + delete[] p; + } + + 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. + NS_WARNING("unable to load datasource"); + continue; + } + + if (NS_FAILED(rv = db->AddDataSource(ds))) { + NS_ERROR("unable to add datasource to composite data source"); + return rv; + } + } + + if (NS_FAILED(rv = builder->SetDataBase(db))) { + NS_ERROR("unable to set builder's database"); + return rv; + } + + // add it to the set of builders in use by the document + if (NS_FAILED(rv = mDocument->AddContentModelBuilder(builder))) { + NS_ERROR("unable to add builder to the document"); + return rv; + } + + return NS_OK; +} diff --git a/mozilla/rdf/content/src/nsXULDocument.cpp b/mozilla/rdf/content/src/nsXULDocument.cpp new file mode 100644 index 00000000000..fbacb2e2d7d --- /dev/null +++ b/mozilla/rdf/content/src/nsXULDocument.cpp @@ -0,0 +1,2198 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +/* + + An implementation for the nsIRDFDocument interface. This + implementation serves as the basis for generating an NGLayout + content model. + + TO DO + + 1) Figure out how to get rid of the DummyListener hack. + + */ + +#include "nsCOMPtr.h" +#include "nsIArena.h" +#include "nsICollection.h" +#include "nsIContent.h" +#include "nsICSSParser.h" +#include "nsICSSStyleSheet.h" +#include "nsIDTD.h" +#include "nsIDocument.h" +#include "nsIDocumentObserver.h" +#include "nsIEnumerator.h" +#include "nsIHTMLContentContainer.h" +#include "nsIHTMLCSSStyleSheet.h" +#include "nsIHTMLStyleSheet.h" +#include "nsINameSpaceManager.h" +#include "nsIParser.h" +#include "nsIPresContext.h" +#include "nsIPresShell.h" +#include "nsIRDFCompositeDataSource.h" +#include "nsIRDFContent.h" +#include "nsIRDFContentModelBuilder.h" +#include "nsIRDFCursor.h" +#include "nsIRDFDataSource.h" +#include "nsIRDFDocument.h" +#include "nsIRDFNode.h" +#include "nsIRDFService.h" +#include "nsIRDFXMLDataSource.h" +#include "nsIScriptContextOwner.h" +#include "nsIServiceManager.h" +#include "nsIStreamListener.h" +#include "nsIStyleSet.h" +#include "nsIStyleSheet.h" +#include "nsISupportsArray.h" +#include "nsIURL.h" +#include "nsIURLGroup.h" +#include "nsIWebShell.h" +#include "nsLayoutCID.h" +#include "nsParserCIID.h" +#include "nsRDFCID.h" +#include "nsRDFContentSink.h" +#include "nsVoidArray.h" +#include "plhash.h" +#include "plstr.h" +#include "rdfutil.h" + +//////////////////////////////////////////////////////////////////////// + +static NS_DEFINE_IID(kICSSParserIID, NS_ICSS_PARSER_IID); // XXX grr.. +static NS_DEFINE_IID(kICollectionIID, NS_ICOLLECTION_IID); +static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID); +static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID); +static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID); +static NS_DEFINE_IID(kIHTMLContentContainerIID, NS_IHTMLCONTENTCONTAINER_IID); +static NS_DEFINE_IID(kIHTMLStyleSheetIID, NS_IHTML_STYLE_SHEET_IID); +static NS_DEFINE_IID(kINameSpaceManagerIID, NS_INAMESPACEMANAGER_IID); +static NS_DEFINE_IID(kIParserIID, NS_IPARSER_IID); +static NS_DEFINE_IID(kIPresShellIID, NS_IPRESSHELL_IID); +static NS_DEFINE_IID(kIRDFCompositeDataSourceIID, NS_IRDFCOMPOSITEDATASOURCE_IID); +static NS_DEFINE_IID(kIRDFContentModelBuilderIID, NS_IRDFCONTENTMODELBUILDER_IID); +static NS_DEFINE_IID(kIRDFDataSourceIID, NS_IRDFDATASOURCE_IID); +static NS_DEFINE_IID(kIRDFDocumentIID, NS_IRDFDOCUMENT_IID); +static NS_DEFINE_IID(kIRDFLiteralIID, NS_IRDFLITERAL_IID); +static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID); +static NS_DEFINE_IID(kIRDFServiceIID, NS_IRDFSERVICE_IID); +static NS_DEFINE_IID(kIRDFXMLDataSourceIID, NS_IRDFXMLDATASOURCE_IID); +static NS_DEFINE_IID(kIStreamListenerIID, NS_ISTREAMLISTENER_IID); +static NS_DEFINE_IID(kIStreamObserverIID, NS_ISTREAMOBSERVER_IID); +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID); +static NS_DEFINE_IID(kIXMLDocumentIID, NS_IXMLDOCUMENT_IID); + +static NS_DEFINE_CID(kCSSParserCID, NS_CSSPARSER_CID); +static NS_DEFINE_CID(kHTMLStyleSheetCID, NS_HTMLSTYLESHEET_CID); +static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID); +static NS_DEFINE_CID(kParserCID, NS_PARSER_IID); // XXX +static NS_DEFINE_CID(kPresShellCID, NS_PRESSHELL_CID); +static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID); +static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); +static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID); +static NS_DEFINE_CID(kXULDataSourceCID, NS_XULDATASOURCE_CID); +static NS_DEFINE_CID(kRDFCompositeDataSourceCID, NS_RDFCOMPOSITEDATASOURCE_CID); +static NS_DEFINE_CID(kRangeListCID, NS_RANGELIST_CID); +static NS_DEFINE_CID(kWellFormedDTDCID, NS_WELLFORMEDDTD_CID); + +static NS_DEFINE_CID(kRDFXULBuilderCID, NS_RDFXULBUILDER_CID); + +//////////////////////////////////////////////////////////////////////// + +enum nsContentType { + TEXT_RDF, + TEXT_XUL, +}; + +//////////////////////////////////////////////////////////////////////// +// nsElementMap + +class nsElementMap +{ +private: + PLHashTable* mResources; + + class ContentListItem { + public: + ContentListItem(nsIContent* aContent) + : mNext(nsnull), mContent(aContent) {} + + ContentListItem* mNext; + nsIContent* mContent; + }; + + static PLHashNumber + HashPointer(const void* key) + { + return (PLHashNumber) key; + } + + static PRIntn + ReleaseContentList(PLHashEntry* he, PRIntn index, void* closure) + { + ContentListItem* head = + (ContentListItem*) he->value; + + while (head) { + ContentListItem* doomed = head; + head = head->mNext; + delete doomed; + } + + return HT_ENUMERATE_NEXT; + } + +public: + nsElementMap(void) + { + // Create a table for mapping RDF resources to elements in the + // content tree. + static PRInt32 kInitialResourceTableSize = 1023; + if ((mResources = PL_NewHashTable(kInitialResourceTableSize, + HashPointer, + PL_CompareValues, + PL_CompareValues, + nsnull, + nsnull)) == nsnull) { + NS_ERROR("could not create hash table for resources"); + } + } + + virtual ~nsElementMap() + { + if (mResources) { + PL_HashTableEnumerateEntries(mResources, ReleaseContentList, nsnull); + PL_HashTableDestroy(mResources); + } + } + + nsresult + Add(nsIRDFResource* aResource, nsIContent* aContent) + { + NS_PRECONDITION(mResources != nsnull, "not initialized"); + if (! mResources) + return NS_ERROR_NOT_INITIALIZED; + + ContentListItem* head = + (ContentListItem*) PL_HashTableLookup(mResources, aResource); + + if (! head) { + head = new ContentListItem(aContent); + if (! head) + return NS_ERROR_OUT_OF_MEMORY; + + PL_HashTableAdd(mResources, aResource, head); + } + else { + while (1) { + if (head->mContent == aContent) { + NS_ERROR("attempt to add same element twice"); + return NS_ERROR_ILLEGAL_VALUE; + } + if (! head->mNext) + break; + + head = head->mNext; + } + + head->mNext = new ContentListItem(aContent); + if (! head->mNext) + return NS_ERROR_OUT_OF_MEMORY; + } + + return NS_OK; + } + + nsresult + Remove(nsIRDFResource* aResource, nsIContent* aContent) + { + NS_PRECONDITION(mResources != nsnull, "not initialized"); + if (! mResources) + return NS_ERROR_NOT_INITIALIZED; + + ContentListItem* head = + (ContentListItem*) PL_HashTableLookup(mResources, aResource); + + if (head) { + if (head->mContent == aContent) { + ContentListItem* newHead = head->mNext; + if (newHead) { + PL_HashTableAdd(mResources, aResource, newHead); + } + else { + PL_HashTableRemove(mResources, aResource); + } + delete head; + return NS_OK; + } + else { + ContentListItem* doomed = head->mNext; + while (doomed) { + if (doomed->mContent == aContent) { + head->mNext = doomed->mNext; + delete doomed; + return NS_OK; + } + head = doomed; + doomed = doomed->mNext; + } + } + } + + NS_ERROR("attempt to remove an element that was never added"); + return NS_ERROR_ILLEGAL_VALUE; + } + + nsresult + Find(nsIRDFResource* aResource, nsISupportsArray* aResults) + { + NS_PRECONDITION(mResources != nsnull, "not initialized"); + if (! mResources) + return NS_ERROR_NOT_INITIALIZED; + + aResults->Clear(); + ContentListItem* head = + (ContentListItem*) PL_HashTableLookup(mResources, aResource); + + while (head) { + aResults->AppendElement(head->mContent); + head = head->mNext; + } + return NS_OK; + } +}; + + + +//////////////////////////////////////////////////////////////////////// +// XULDocumentImpl + +class XULDocumentImpl : public nsIDocument, + public nsIRDFDocument, + public nsIRDFXMLDataSourceObserver, + public nsIHTMLContentContainer +{ +public: + XULDocumentImpl(); + virtual ~XULDocumentImpl(); + + // nsISupports interface + NS_DECL_ISUPPORTS + + // nsIDocument interface + virtual nsIArena* GetArena(); + + NS_IMETHOD StartDocumentLoad(nsIURL *aUrl, + nsIContentViewerContainer* aContainer, + nsIStreamListener **aDocListener, + const char* aCommand); + + virtual const nsString* GetDocumentTitle() const; + + virtual nsIURL* GetDocumentURL() const; + + virtual nsIURLGroup* GetDocumentURLGroup() const; + + NS_IMETHOD GetBaseURL(nsIURL*& aURL) const; + + virtual nsString* GetDocumentCharacterSet() const; + + virtual void SetDocumentCharacterSet(nsString* aCharSetID); + + NS_IMETHOD GetHeaderData(nsIAtom* aHeaderField, nsString& aData) const; + NS_IMETHOD SetHeaderData(nsIAtom* aheaderField, const nsString& aData); + + virtual nsresult CreateShell(nsIPresContext* aContext, + nsIViewManager* aViewManager, + nsIStyleSet* aStyleSet, + nsIPresShell** aInstancePtrResult); + + virtual PRBool DeleteShell(nsIPresShell* aShell); + + virtual PRInt32 GetNumberOfShells(); + + virtual nsIPresShell* GetShellAt(PRInt32 aIndex); + + virtual nsIDocument* GetParentDocument(); + + virtual void SetParentDocument(nsIDocument* aParent); + + virtual void AddSubDocument(nsIDocument* aSubDoc); + + virtual PRInt32 GetNumberOfSubDocuments(); + + virtual nsIDocument* GetSubDocumentAt(PRInt32 aIndex); + + virtual nsIContent* GetRootContent(); + + virtual void SetRootContent(nsIContent* aRoot); + + virtual PRInt32 GetNumberOfStyleSheets(); + + virtual nsIStyleSheet* GetStyleSheetAt(PRInt32 aIndex); + + virtual PRInt32 GetIndexOfStyleSheet(nsIStyleSheet* aSheet); + + virtual void AddStyleSheet(nsIStyleSheet* aSheet); + + virtual void SetStyleSheetDisabledState(nsIStyleSheet* aSheet, + PRBool mDisabled); + + virtual nsIScriptContextOwner *GetScriptContextOwner(); + + virtual void SetScriptContextOwner(nsIScriptContextOwner *aScriptContextOwner); + + NS_IMETHOD GetNameSpaceManager(nsINameSpaceManager*& aManager); + + virtual void AddObserver(nsIDocumentObserver* aObserver); + + virtual PRBool RemoveObserver(nsIDocumentObserver* aObserver); + + NS_IMETHOD BeginLoad(); + + NS_IMETHOD EndLoad(); + + NS_IMETHOD ContentChanged(nsIContent* aContent, + nsISupports* aSubContent); + + NS_IMETHOD AttributeChanged(nsIContent* aChild, + nsIAtom* aAttribute, + PRInt32 aHint); // See nsStyleConsts fot hint values + + NS_IMETHOD ContentAppended(nsIContent* aContainer, + PRInt32 aNewIndexInContainer); + + NS_IMETHOD ContentInserted(nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer); + + NS_IMETHOD ContentReplaced(nsIContent* aContainer, + nsIContent* aOldChild, + nsIContent* aNewChild, + PRInt32 aIndexInContainer); + + NS_IMETHOD ContentRemoved(nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer); + + NS_IMETHOD StyleRuleChanged(nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint); // See nsStyleConsts fot hint values + + NS_IMETHOD StyleRuleAdded(nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + + NS_IMETHOD StyleRuleRemoved(nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule); + + NS_IMETHOD GetSelection(nsICollection** aSelection); + + NS_IMETHOD SelectAll(); + + NS_IMETHOD FindNext(const nsString &aSearchStr, PRBool aMatchCase, PRBool aSearchDown, PRBool &aIsFound); + + virtual void CreateXIF(nsString & aBuffer, nsISelection* aSelection); + + virtual void ToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode); + + virtual void BeginConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode); + + virtual void ConvertChildrenToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode); + + virtual void FinishConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode); + + virtual PRBool IsInRange(const nsIContent *aStartContent, const nsIContent* aEndContent, const nsIContent* aContent) const; + + virtual PRBool IsBefore(const nsIContent *aNewContent, const nsIContent* aCurrentContent) const; + + virtual PRBool IsInSelection(nsISelection* aSelection, const nsIContent *aContent) const; + + virtual nsIContent* GetPrevContent(const nsIContent *aContent) const; + + virtual nsIContent* GetNextContent(const nsIContent *aContent) const; + + virtual void SetDisplaySelection(PRBool aToggle); + + virtual PRBool GetDisplaySelection() const; + + NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus); + + + // nsIXMLDocument interface + NS_IMETHOD PrologElementAt(PRUint32 aOffset, nsIContent** aContent); + NS_IMETHOD PrologCount(PRUint32* aCount); + NS_IMETHOD AppendToProlog(nsIContent* aContent); + NS_IMETHOD EpilogElementAt(PRUint32 aOffset, nsIContent** aContent); + NS_IMETHOD EpilogCount(PRUint32* aCount); + NS_IMETHOD AppendToEpilog(nsIContent* aContent); + + // nsIHTMLContentContainer interface + NS_IMETHOD GetAttributeStyleSheet(nsIHTMLStyleSheet** aResult); + NS_IMETHOD GetInlineStyleSheet(nsIHTMLCSSStyleSheet** aResult); + + // nsIRDFDocument interface + NS_IMETHOD SetContentType(const char* aContentType); + NS_IMETHOD SetRootResource(nsIRDFResource* resource); + NS_IMETHOD SplitProperty(nsIRDFResource* aResource, PRInt32* aNameSpaceID, nsIAtom** aTag); + NS_IMETHOD AddElementForResource(nsIRDFResource* aResource, nsIRDFContent* aElement); + NS_IMETHOD RemoveElementForResource(nsIRDFResource* aResource, nsIRDFContent* aElement); + NS_IMETHOD GetElementsForResource(nsIRDFResource* aResource, nsISupportsArray* aElements); + NS_IMETHOD CreateContents(nsIRDFContent* aElement); + NS_IMETHOD AddContentModelBuilder(nsIRDFContentModelBuilder* aBuilder); + + // nsIRDFXMLDataSourceObserver interface + NS_IMETHOD OnBeginLoad(nsIRDFXMLDataSource* aDataSource); + NS_IMETHOD OnInterrupt(nsIRDFXMLDataSource* aDataSource); + NS_IMETHOD OnResume(nsIRDFXMLDataSource* aDataSource); + NS_IMETHOD OnEndLoad(nsIRDFXMLDataSource* aDataSource); + + NS_IMETHOD OnRootResourceFound(nsIRDFXMLDataSource* aDataSource, nsIRDFResource* aResource); + NS_IMETHOD OnCSSStyleSheetAdded(nsIRDFXMLDataSource* aDataSource, nsIURL* aStyleSheetURI); + NS_IMETHOD OnNamedDataSourceAdded(nsIRDFXMLDataSource* aDataSource, const char* aNamedDataSourceURI); + + // Implementation methods + nsresult Init(void); + nsresult StartLayout(void); + +protected: + nsIContent* + FindContent(const nsIContent* aStartNode, + const nsIContent* aTest1, + const nsIContent* aTest2) const; + + nsresult + LoadCSSStyleSheet(nsIURL* url); + + nsresult + AddNamedDataSource(const char* uri); + + + nsIArena* mArena; + nsVoidArray mObservers; + nsAutoString mDocumentTitle; + nsIURL* mDocumentURL; + nsIURLGroup* mDocumentURLGroup; + nsIContent* mRootContent; + nsIDocument* mParentDocument; + nsIScriptContextOwner* mScriptContextOwner; + nsString* mCharSetID; + nsVoidArray mStyleSheets; + nsICollection* mSelection; + PRBool mDisplaySelection; + nsVoidArray mPresShells; + nsINameSpaceManager* mNameSpaceManager; + nsIHTMLStyleSheet* mAttrStyleSheet; + nsIHTMLCSSStyleSheet* mInlineStyleSheet; + nsIRDFService* mRDFService; + nsElementMap mResources; + nsISupportsArray* mBuilders; + nsIRDFContentModelBuilder* mXULBuilder; + nsIRDFDataSource* mLocalDataSource; + nsIRDFXMLDataSource* mDocumentDataSource; + + nsContentType mContentType; // The document's type (RDF vs. XUL) +}; + + +//////////////////////////////////////////////////////////////////////// +// DummyListener +// +// This is a _total_ hack that is used to get stuff to draw right +// when a second copy is loaded. I need to talk to Guha about what +// the expected behavior should be... +// +class DummyListener : public nsIStreamListener +{ +private: + XULDocumentImpl* mRDFDocument; + PRBool mWasNotifiedOnce; // XXX why do we get _two_ OnStart/StopBinding() calls? + +public: + DummyListener(XULDocumentImpl* aRDFDocument) + : mRDFDocument(aRDFDocument), + mWasNotifiedOnce(PR_FALSE) + { + NS_INIT_REFCNT(); + NS_ADDREF(mRDFDocument); + } + + virtual ~DummyListener(void) { + NS_RELEASE(mRDFDocument); + } + + // nsISupports interface + NS_DECL_ISUPPORTS + + // nsIStreamObserver interface + NS_IMETHOD + OnStartBinding(nsIURL* aURL, const char *aContentType) { + if (! mWasNotifiedOnce) { + mRDFDocument->BeginLoad(); + mRDFDocument->StartLayout(); + } + return NS_OK; + } + + NS_IMETHOD + OnProgress(nsIURL* aURL, PRUint32 aProgress, PRUint32 aProgressMax) { + return NS_OK; + } + + NS_IMETHOD OnStatus(nsIURL* aURL, const PRUnichar* aMsg) { + return NS_OK; + } + + NS_IMETHOD OnStopBinding(nsIURL* aURL, nsresult aStatus, const PRUnichar* aMsg) { + if (! mWasNotifiedOnce) { + mRDFDocument->EndLoad(); + mWasNotifiedOnce = PR_TRUE; + } + return NS_OK; + } + + + // nsIStreamListener interface + NS_IMETHOD + GetBindInfo(nsIURL* aURL, nsStreamBindingInfo* aInfo) { + aInfo->seekable = PR_FALSE; + return NS_OK; + } + + NS_IMETHOD + OnDataAvailable(nsIURL* aURL, nsIInputStream *aIStream, PRUint32 aLength) { + return NS_OK; + } +}; + +NS_IMPL_ADDREF(DummyListener); +NS_IMPL_RELEASE(DummyListener); + +NS_IMETHODIMP +DummyListener::QueryInterface(REFNSIID aIID, void** aResult) +{ + NS_PRECONDITION(aResult != nsnull, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; + + if (aIID.Equals(kIStreamListenerIID) || + aIID.Equals(kIStreamObserverIID) || + aIID.Equals(kISupportsIID)) { + *aResult = NS_STATIC_CAST(nsIStreamListener*, this); + NS_ADDREF(this); + return NS_OK; + } + else { + *aResult = nsnull; + return NS_NOINTERFACE; + } +} + + +//////////////////////////////////////////////////////////////////////// +// ctors & dtors + +XULDocumentImpl::XULDocumentImpl(void) + : mArena(nsnull), + mDocumentURL(nsnull), + mDocumentURLGroup(nsnull), + mRootContent(nsnull), + mParentDocument(nsnull), + mScriptContextOwner(nsnull), + mSelection(nsnull), + mDisplaySelection(PR_FALSE), + mNameSpaceManager(nsnull), + mAttrStyleSheet(nsnull), + mRDFService(nsnull), + mBuilders(nsnull), + mXULBuilder(nsnull), + mLocalDataSource(nsnull), + mDocumentDataSource(nsnull), + mContentType(TEXT_RDF) +{ + NS_INIT_REFCNT(); + + nsresult rv; + + // construct a selection object + if (NS_FAILED(rv = nsRepository::CreateInstance(kRangeListCID, + nsnull, + kICollectionIID, + (void**) &mSelection))) + PR_ASSERT(0); + + +} + +XULDocumentImpl::~XULDocumentImpl() +{ + if (mDocumentDataSource) { + mDocumentDataSource->RemoveXMLStreamObserver(this); + NS_RELEASE(mDocumentDataSource); + } + NS_IF_RELEASE(mLocalDataSource); + + if (mRDFService) { + nsServiceManager::ReleaseService(kRDFServiceCID, mRDFService); + mRDFService = nsnull; + } + + // mParentDocument is never refcounted + NS_IF_RELEASE(mBuilders); + NS_IF_RELEASE(mXULBuilder); + NS_IF_RELEASE(mSelection); + NS_IF_RELEASE(mScriptContextOwner); + NS_IF_RELEASE(mAttrStyleSheet); + NS_IF_RELEASE(mRootContent); + NS_IF_RELEASE(mDocumentURLGroup); + NS_IF_RELEASE(mDocumentURL); + NS_IF_RELEASE(mArena); + NS_IF_RELEASE(mNameSpaceManager); +} + +//////////////////////////////////////////////////////////////////////// +// nsISupports interface + +NS_IMETHODIMP +XULDocumentImpl::QueryInterface(REFNSIID iid, void** result) +{ + if (! result) + return NS_ERROR_NULL_POINTER; + + *result = nsnull; + if (iid.Equals(kIDocumentIID) || + iid.Equals(kISupportsIID)) { + *result = NS_STATIC_CAST(nsIDocument*, this); + NS_ADDREF(this); + return NS_OK; + } + else if (iid.Equals(kIRDFDocumentIID) || + iid.Equals(kIXMLDocumentIID)) { + *result = NS_STATIC_CAST(nsIRDFDocument*, this); + NS_ADDREF(this); + return NS_OK; + } + else if (iid.Equals(kIHTMLContentContainerIID)) { + *result = NS_STATIC_CAST(nsIHTMLContentContainer*, this); + NS_ADDREF(this); + return NS_OK; + } + return NS_NOINTERFACE; +} + +NS_IMPL_ADDREF(XULDocumentImpl); +NS_IMPL_RELEASE(XULDocumentImpl); + +//////////////////////////////////////////////////////////////////////// +// nsIDocument interface + +nsIArena* +XULDocumentImpl::GetArena() +{ + NS_IF_ADDREF(mArena); + return mArena; +} + +NS_IMETHODIMP +XULDocumentImpl::StartDocumentLoad(nsIURL *aURL, + nsIContentViewerContainer* aContainer, + nsIStreamListener **aDocListener, + const char* aCommand) +{ + NS_ASSERTION(aURL != nsnull, "null ptr"); + if (! aURL) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + + mDocumentTitle.Truncate(); + + NS_IF_RELEASE(mDocumentURL); + mDocumentURL = aURL; + NS_ADDREF(aURL); + + NS_IF_RELEASE(mDocumentURLGroup); + (void)aURL->GetURLGroup(&mDocumentURLGroup); + + // Delete references to style sheets - this should be done in superclass... + PRInt32 index = mStyleSheets.Count(); + while (--index >= 0) { + nsIStyleSheet* sheet = (nsIStyleSheet*) mStyleSheets.ElementAt(index); + sheet->SetOwningDocument(nsnull); + NS_RELEASE(sheet); + } + mStyleSheets.Clear(); + + // Create an HTML style sheet for the HTML content. + nsIHTMLStyleSheet* sheet; + if (NS_SUCCEEDED(rv = nsRepository::CreateInstance(kHTMLStyleSheetCID, + nsnull, + kIHTMLStyleSheetIID, + (void**) &sheet))) { + if (NS_SUCCEEDED(rv = sheet->Init(aURL, this))) { + mAttrStyleSheet = sheet; + NS_ADDREF(mAttrStyleSheet); + + AddStyleSheet(mAttrStyleSheet); + } + NS_RELEASE(sheet); + } + + if (NS_FAILED(rv)) + return rv; + + // Create a composite data source that'll tie together local and + // remote stores. + nsIRDFCompositeDataSource* db; + if (NS_FAILED(rv = nsRepository::CreateInstance(kRDFCompositeDataSourceCID, + nsnull, + kIRDFCompositeDataSourceIID, + (void**) &db))) { + NS_ERROR("couldn't create composite datasource"); + return rv; + } + + // Create a XUL content model builder + NS_IF_RELEASE(mXULBuilder); + if (NS_FAILED(rv = nsRepository::CreateInstance(kRDFXULBuilderCID, + nsnull, + kIRDFContentModelBuilderIID, + (void**) &mXULBuilder))) { + NS_ERROR("couldn't create XUL builder"); + return rv; + } + + if (NS_FAILED(rv = mXULBuilder->SetDataBase(db))) { + NS_ERROR("couldn't set builder's db"); + return rv; + } + + NS_IF_RELEASE(mBuilders); + if (NS_FAILED(rv = AddContentModelBuilder(mXULBuilder))) { + NS_ERROR("could't add XUL builder"); + return rv; + } + + // Create a "scratch" in-memory data store to associate with the + // document to be a catch-all for any doc-specific info that we + // need to store (e.g., current sort order, etc.) + // + // XXX This needs to be cloned across windows, and the final + // instance needs to be flushed to disk. It may be that this is + // really an RDFXML data source... + if (NS_FAILED(rv = nsRepository::CreateInstance(kRDFInMemoryDataSourceCID, + nsnull, + kIRDFDataSourceIID, + (void**) &mLocalDataSource))) { + NS_ERROR("couldn't create local data source"); + return rv; + } + + if (NS_FAILED(rv = db->AddDataSource(mLocalDataSource))) { + NS_ERROR("couldn't add local data source to db"); + return rv; + } + + // Now load the actual RDF/XML document data source. First, we'll + // see if the data source has been loaded and is registered with + // the RDF service. If so, do some monkey business to "pretend" to + // load it: really, we'll just walk its graph to generate the + // content model. + const char* uri; + if (NS_FAILED(rv = aURL->GetSpec(&uri))) + return rv; + + nsIRDFDataSource* ds; + if (NS_SUCCEEDED(rv = mRDFService->GetDataSource(uri, &ds))) { + // Add the RDF/XML data source to our composite data source + NS_IF_RELEASE(mDocumentDataSource); + if (NS_FAILED(rv = ds->QueryInterface(kIRDFXMLDataSourceIID, + (void**) &mDocumentDataSource))) { + NS_ERROR("unable to get RDF/XML interface to remote datasource"); + NS_RELEASE(ds); + return rv; + } + + NS_RELEASE(ds); + + if (NS_FAILED(rv = db->AddDataSource(mDocumentDataSource))) { + NS_ERROR("unable to add remote data source to db"); + return rv; + } + + // we found the data source already loaded locally. Load it's + // style sheets and attempt to include any named data sources + // that it references into this document. + nsIURL** styleSheetURLs; + PRInt32 count; + if (NS_SUCCEEDED(rv = mDocumentDataSource->GetCSSStyleSheetURLs(&styleSheetURLs, &count))) { + for (PRInt32 i = 0; i < count; ++i) { + if (NS_FAILED(rv = LoadCSSStyleSheet(styleSheetURLs[i]))) { + NS_ASSERTION(PR_FALSE, "couldn't load style sheet"); + } + } + } + + const char* const* namedDataSourceURIs; + if (NS_SUCCEEDED(rv = mDocumentDataSource->GetNamedDataSourceURIs(&namedDataSourceURIs, &count))) { + for (PRInt32 i = 0; i < count; ++i) { + if (NS_FAILED(rv = AddNamedDataSource(namedDataSourceURIs[i]))) { +#ifdef DEBUG + printf("error adding named data source %s\n", namedDataSourceURIs[i]); +#endif + } + } + } + + // XXX Allright, this is an atrocious hack. Basically, we + // construct a dummy listener object so that we can load the + // URL, which allows us to receive StartLayout() and EndLoad() + // calls asynchronously. If we don't do this, then there is no + // way (that I could figure out) to force the content model to + // be traversed so that a document is laid out again. + // + // Looking at the "big picture" here, the real problem is that + // the "registered" data sources mechanism is really just a + // cache of stream data sources. It's not really clear what + // should happen when somebody opens a second document on the + // same source. You'd kinda like both to refer to the same + // thing, so changes to one are immediately reflected in the + // other. On the other hand, you'd also like to be able to + // _unload_ and reload a content model, say by doing + // "shift+reload". _So_, that kinda ties into the real cache, + // etc. etc. + // + // What I guess I'm saying is, maybe it doesn't make that much + // sense to register stream data sources when they're + // created...I dunno... + if (aDocListener) { + nsIStreamListener* lsnr = new DummyListener(this); + if (! lsnr) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(lsnr); + *aDocListener = lsnr; + + if (NS_FAILED(rv = NS_OpenURL(aURL, lsnr))) + return rv; + } + } + else { + // We need to construct a new stream and load it. The stream + // will automagically register itself as a named data source, + // so if subsequent docs ask for it, they'll get the real + // deal. In the meantime, add us as an + // nsIRDFXMLDataSourceObserver so that we'll be notified when we + // need to load style sheets, etc. + NS_IF_RELEASE(mDocumentDataSource); + if (NS_FAILED(rv = nsRepository::CreateInstance(kXULDataSourceCID, + nsnull, + kIRDFXMLDataSourceIID, + (void**) &mDocumentDataSource))) { + NS_ERROR("unable to create XUL datasource"); + return rv; + } + + if (NS_FAILED(rv = db->AddDataSource(mDocumentDataSource))) { + NS_ERROR("unable to add XUL datasource to db"); + return rv; + } + + nsIRDFXMLDataSource* doc; + if (NS_SUCCEEDED(rv = mDocumentDataSource->QueryInterface(kIRDFXMLDataSourceIID, + (void**) &doc))) { + doc->AddXMLStreamObserver(this); + NS_RELEASE(doc); + } + else { + NS_ERROR("unable to add self as stream observer on XUL datasource"); + } + + if (NS_FAILED(rv = mDocumentDataSource->Init(uri))) { + NS_ERROR("unable to initialize XUL data source"); + return rv; + } + + // XXX huh? + if (aDocListener) { + *aDocListener = nsnull; + } + } + + return NS_OK; +} + +const nsString* +XULDocumentImpl::GetDocumentTitle() const +{ + return &mDocumentTitle; +} + +nsIURL* +XULDocumentImpl::GetDocumentURL() const +{ + NS_IF_ADDREF(mDocumentURL); + return mDocumentURL; +} + +nsIURLGroup* +XULDocumentImpl::GetDocumentURLGroup() const +{ + NS_IF_ADDREF(mDocumentURLGroup); + return mDocumentURLGroup; +} + +NS_IMETHODIMP +XULDocumentImpl::GetBaseURL(nsIURL*& aURL) const +{ + NS_IF_ADDREF(mDocumentURL); + aURL = mDocumentURL; + return NS_OK; +} + +nsString* +XULDocumentImpl::GetDocumentCharacterSet() const +{ + return mCharSetID; +} + +void +XULDocumentImpl::SetDocumentCharacterSet(nsString* aCharSetID) +{ + mCharSetID = aCharSetID; +} + +NS_IMETHODIMP +XULDocumentImpl::GetHeaderData(nsIAtom* aHeaderField, nsString& aData) const +{ + return NS_OK; +} + +NS_IMETHODIMP +XULDocumentImpl:: SetHeaderData(nsIAtom* aheaderField, const nsString& aData) +{ + return NS_OK; +} + + +nsresult +XULDocumentImpl::CreateShell(nsIPresContext* aContext, + nsIViewManager* aViewManager, + nsIStyleSet* aStyleSet, + nsIPresShell** aInstancePtrResult) +{ + NS_PRECONDITION(aInstancePtrResult, "null ptr"); + if (! aInstancePtrResult) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + + nsIPresShell* shell; + if (NS_FAILED(rv = nsRepository::CreateInstance(kPresShellCID, + nsnull, + kIPresShellIID, + (void**) &shell))) + return rv; + + if (NS_FAILED(rv = shell->Init(this, aContext, aViewManager, aStyleSet))) { + NS_RELEASE(shell); + return rv; + } + + mPresShells.AppendElement(shell); + *aInstancePtrResult = shell; // addref implicit + + return NS_OK; +} + +PRBool +XULDocumentImpl::DeleteShell(nsIPresShell* aShell) +{ + return mPresShells.RemoveElement(aShell); +} + +PRInt32 +XULDocumentImpl::GetNumberOfShells() +{ + return mPresShells.Count(); +} + +nsIPresShell* +XULDocumentImpl::GetShellAt(PRInt32 aIndex) +{ + nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[aIndex]); + NS_IF_ADDREF(shell); + return shell; +} + +nsIDocument* +XULDocumentImpl::GetParentDocument() +{ + NS_IF_ADDREF(mParentDocument); + return mParentDocument; +} + +void +XULDocumentImpl::SetParentDocument(nsIDocument* aParent) +{ + // Note that we do *not* AddRef our parent because that would + // create a circular reference. + mParentDocument = aParent; +} + +void +XULDocumentImpl::AddSubDocument(nsIDocument* aSubDoc) +{ + // we don't do subdocs. + PR_ASSERT(0); +} + +PRInt32 +XULDocumentImpl::GetNumberOfSubDocuments() +{ + return 0; +} + +nsIDocument* +XULDocumentImpl::GetSubDocumentAt(PRInt32 aIndex) +{ + // we don't do subdocs. + PR_ASSERT(0); + return nsnull; +} + +nsIContent* +XULDocumentImpl::GetRootContent() +{ + NS_IF_ADDREF(mRootContent); + return mRootContent; +} + +void +XULDocumentImpl::SetRootContent(nsIContent* aRoot) +{ + if (mRootContent) { + mRootContent->SetDocument(nsnull, PR_TRUE); + NS_RELEASE(mRootContent); + } + mRootContent = aRoot; + if (mRootContent) { + mRootContent->SetDocument(this, PR_TRUE); + NS_ADDREF(mRootContent); + } +} + +PRInt32 +XULDocumentImpl::GetNumberOfStyleSheets() +{ + return mStyleSheets.Count(); +} + +nsIStyleSheet* +XULDocumentImpl::GetStyleSheetAt(PRInt32 aIndex) +{ + nsIStyleSheet* sheet = NS_STATIC_CAST(nsIStyleSheet*, mStyleSheets[aIndex]); + NS_IF_ADDREF(sheet); + return sheet; +} + +PRInt32 +XULDocumentImpl::GetIndexOfStyleSheet(nsIStyleSheet* aSheet) +{ + return mStyleSheets.IndexOf(aSheet); +} + +void +XULDocumentImpl::AddStyleSheet(nsIStyleSheet* aSheet) +{ + NS_PRECONDITION(aSheet, "null arg"); + if (!aSheet) + return; + + mStyleSheets.AppendElement(aSheet); + NS_ADDREF(aSheet); + + aSheet->SetOwningDocument(this); + + PRBool enabled; + aSheet->GetEnabled(enabled); + + if (enabled) { + PRInt32 count, index; + + count = mPresShells.Count(); + for (index = 0; index < count; index++) { + nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[index]); + nsIStyleSet* set = shell->GetStyleSet(); + if (nsnull != set) { + set->AddDocStyleSheet(aSheet, this); + NS_RELEASE(set); + } + } + + // XXX should observers be notified for disabled sheets??? I think not, but I could be wrong + count = mObservers.Count(); + for (index = 0; index < count; index++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index); + observer->StyleSheetAdded(this, aSheet); + } + } +} + +void +XULDocumentImpl::SetStyleSheetDisabledState(nsIStyleSheet* aSheet, + PRBool aDisabled) +{ + NS_PRECONDITION(nsnull != aSheet, "null arg"); + PRInt32 count; + PRInt32 index = mStyleSheets.IndexOf((void *)aSheet); + // If we're actually in the document style sheet list + if (-1 != index) { + count = mPresShells.Count(); + PRInt32 index; + for (index = 0; index < count; index++) { + nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(index); + nsIStyleSet* set = shell->GetStyleSet(); + if (nsnull != set) { + if (aDisabled) { + set->RemoveDocStyleSheet(aSheet); + } + else { + set->AddDocStyleSheet(aSheet, this); // put it first + } + NS_RELEASE(set); + } + } + } + + count = mObservers.Count(); + for (index = 0; index < count; index++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index); + observer->StyleSheetDisabledStateChanged(this, aSheet, aDisabled); + } +} + +nsIScriptContextOwner * +XULDocumentImpl::GetScriptContextOwner() +{ + NS_IF_ADDREF(mScriptContextOwner); + return mScriptContextOwner; +} + +void +XULDocumentImpl::SetScriptContextOwner(nsIScriptContextOwner *aScriptContextOwner) +{ + // 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 (!aScriptContextOwner && mRootContent) + mRootContent->SetDocument(nsnull, PR_TRUE); + + NS_IF_RELEASE(mScriptContextOwner); + mScriptContextOwner = aScriptContextOwner; + NS_IF_ADDREF(mScriptContextOwner); +} + +NS_IMETHODIMP +XULDocumentImpl::GetNameSpaceManager(nsINameSpaceManager*& aManager) +{ + 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. +void +XULDocumentImpl::AddObserver(nsIDocumentObserver* aObserver) +{ + // XXX Make sure the observer isn't already in the list + if (mObservers.IndexOf(aObserver) == -1) { + mObservers.AppendElement(aObserver); + } +} + +PRBool +XULDocumentImpl::RemoveObserver(nsIDocumentObserver* aObserver) +{ + return mObservers.RemoveElement(aObserver); +} + +NS_IMETHODIMP +XULDocumentImpl::BeginLoad() +{ + PRInt32 i, count = mObservers.Count(); + for (i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i]; + observer->BeginLoad(this); + } + return NS_OK; +} + +NS_IMETHODIMP +XULDocumentImpl::EndLoad() +{ + PRInt32 i, count = mObservers.Count(); + for (i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i]; + observer->EndLoad(this); + } + return NS_OK; +} + + +NS_IMETHODIMP +XULDocumentImpl::ContentChanged(nsIContent* aContent, + nsISupports* aSubContent) +{ + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->ContentChanged(this, aContent, aSubContent); + } + return NS_OK; +} + +NS_IMETHODIMP +XULDocumentImpl::AttributeChanged(nsIContent* aChild, + nsIAtom* aAttribute, + PRInt32 aHint) +{ + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->AttributeChanged(this, aChild, aAttribute, aHint); + } + return NS_OK; +} + +NS_IMETHODIMP +XULDocumentImpl::ContentAppended(nsIContent* aContainer, + PRInt32 aNewIndexInContainer) +{ + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->ContentAppended(this, aContainer, aNewIndexInContainer); + } + return NS_OK; +} + +NS_IMETHODIMP +XULDocumentImpl::ContentInserted(nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer) +{ + + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->ContentInserted(this, aContainer, aChild, aIndexInContainer); + } + return NS_OK; +} + +NS_IMETHODIMP +XULDocumentImpl::ContentReplaced(nsIContent* aContainer, + nsIContent* aOldChild, + nsIContent* aNewChild, + PRInt32 aIndexInContainer) +{ + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->ContentReplaced(this, aContainer, aOldChild, aNewChild, + aIndexInContainer); + } + return NS_OK; +} + +NS_IMETHODIMP +XULDocumentImpl::ContentRemoved(nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer) +{ + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->ContentRemoved(this, aContainer, + aChild, aIndexInContainer); + } + return NS_OK; +} + +NS_IMETHODIMP +XULDocumentImpl::StyleRuleChanged(nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule, + PRInt32 aHint) +{ + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->StyleRuleChanged(this, aStyleSheet, aStyleRule, aHint); + } + return NS_OK; +} + +NS_IMETHODIMP +XULDocumentImpl::StyleRuleAdded(nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->StyleRuleAdded(this, aStyleSheet, aStyleRule); + } + return NS_OK; +} + +NS_IMETHODIMP +XULDocumentImpl::StyleRuleRemoved(nsIStyleSheet* aStyleSheet, + nsIStyleRule* aStyleRule) +{ + PRInt32 count = mObservers.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->StyleRuleRemoved(this, aStyleSheet, aStyleRule); + } + return NS_OK; +} + +NS_IMETHODIMP +XULDocumentImpl::GetSelection(nsICollection** aSelection) +{ + if (!mSelection) { + PR_ASSERT(0); + *aSelection = nsnull; + return NS_ERROR_NOT_INITIALIZED; + } + NS_ADDREF(mSelection); + *aSelection = mSelection; + return NS_OK; +} + +NS_IMETHODIMP +XULDocumentImpl::SelectAll() +{ + + nsIContent * start = nsnull; + nsIContent * end = nsnull; + nsIContent * body = nsnull; + + nsString bodyStr("BODY"); + PRInt32 i, n; + mRootContent->ChildCount(n); + for (i=0;iChildAt(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; +} + +NS_IMETHODIMP +XULDocumentImpl::FindNext(const nsString &aSearchStr, PRBool aMatchCase, PRBool aSearchDown, PRBool &aIsFound) +{ + aIsFound = PR_FALSE; + return NS_ERROR_FAILURE; +} + +void +XULDocumentImpl::CreateXIF(nsString & aBuffer, nsISelection* aSelection) +{ + PR_ASSERT(0); +} + +void +XULDocumentImpl::ToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode) +{ + PR_ASSERT(0); +} + +void +XULDocumentImpl::BeginConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode) +{ + PR_ASSERT(0); +} + +void +XULDocumentImpl::ConvertChildrenToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode) +{ + PR_ASSERT(0); +} + +void +XULDocumentImpl::FinishConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode) +{ + PR_ASSERT(0); +} + +PRBool +XULDocumentImpl::IsInRange(const nsIContent *aStartContent, const nsIContent* aEndContent, const nsIContent* aContent) const +{ + 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; +} + +PRBool +XULDocumentImpl::IsBefore(const nsIContent *aNewContent, const nsIContent* aCurrentContent) const +{ + PRBool result = PR_FALSE; + + if (nsnull != aNewContent && nsnull != aCurrentContent && aNewContent != aCurrentContent) { + nsIContent* test = FindContent(mRootContent, aNewContent, aCurrentContent); + if (test == aNewContent) + result = PR_TRUE; + + NS_RELEASE(test); + } + return result; +} + +PRBool +XULDocumentImpl::IsInSelection(nsISelection* aSelection, const nsIContent *aContent) const +{ + 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; +} + +nsIContent* +XULDocumentImpl::GetPrevContent(const nsIContent *aContent) const +{ + nsIContent* result = nsnull; + + // Look at previous sibling + + if (nsnull != aContent) { + nsIContent* parent; + aContent->GetParent(parent); + + if (parent != nsnull && parent != mRootContent) { + PRInt32 index; + parent->IndexOf((nsIContent*)aContent, index); + if (index > 0) + parent->ChildAt(index-1, result); + else + result = GetPrevContent(parent); + } + NS_IF_RELEASE(parent); + } + return result; +} + +nsIContent* +XULDocumentImpl::GetNextContent(const nsIContent *aContent) const +{ + nsIContent* result = nsnull; + + if (nsnull != aContent) { + // Look at next sibling + nsIContent* parent; + aContent->GetParent(parent); + + if (parent != nsnull && parent != mRootContent) { + PRInt32 index; + parent->IndexOf((nsIContent*)aContent, index); + + PRInt32 count; + parent->ChildCount(count); + if (index+1 < count) { + parent->ChildAt(index+1, result); + // 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; +} + +void +XULDocumentImpl::SetDisplaySelection(PRBool aToggle) +{ + mDisplaySelection = aToggle; +} + +PRBool +XULDocumentImpl::GetDisplaySelection() const +{ + return mDisplaySelection; +} + +NS_IMETHODIMP +XULDocumentImpl::HandleDOMEvent(nsIPresContext& aPresContext, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus) +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + + +//////////////////////////////////////////////////////////////////////// +// nsIXMLDocument interface + +NS_IMETHODIMP +XULDocumentImpl::PrologElementAt(PRUint32 aOffset, nsIContent** aContent) +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +XULDocumentImpl::PrologCount(PRUint32* aCount) +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +XULDocumentImpl::AppendToProlog(nsIContent* aContent) +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP +XULDocumentImpl::EpilogElementAt(PRUint32 aOffset, nsIContent** aContent) +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +XULDocumentImpl::EpilogCount(PRUint32* aCount) +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +XULDocumentImpl::AppendToEpilog(nsIContent* aContent) +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + +//////////////////////////////////////////////////////////////////////// +// + +NS_IMETHODIMP +XULDocumentImpl::GetAttributeStyleSheet(nsIHTMLStyleSheet** aResult) +{ + NS_PRECONDITION(nsnull != aResult, "null ptr"); + if (nsnull == aResult) { + return NS_ERROR_NULL_POINTER; + } + *aResult = mAttrStyleSheet; + if (nsnull == mAttrStyleSheet) { + return NS_ERROR_NOT_AVAILABLE; // probably not the right error... + } + else { + NS_ADDREF(mAttrStyleSheet); + } + return NS_OK; +} + +NS_IMETHODIMP +XULDocumentImpl::GetInlineStyleSheet(nsIHTMLCSSStyleSheet** aResult) +{ + NS_NOTYETIMPLEMENTED("get the inline stylesheet!"); + + NS_PRECONDITION(nsnull != aResult, "null ptr"); + if (nsnull == aResult) { + return NS_ERROR_NULL_POINTER; + } + *aResult = mInlineStyleSheet; + if (nsnull == mInlineStyleSheet) { + return NS_ERROR_NOT_AVAILABLE; // probably not the right error... + } + else { + NS_ADDREF(mInlineStyleSheet); + } + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////// +// nsIRDFDocument interface + +NS_IMETHODIMP +XULDocumentImpl::SetContentType(const char* aContentType) +{ + mContentType = TEXT_RDF; + if (0 == PL_strcmp("text/xul", aContentType)) + { + mContentType = TEXT_XUL; + } + + return NS_OK; +} + +NS_IMETHODIMP +XULDocumentImpl::SetRootResource(nsIRDFResource* aResource) +{ + NS_PRECONDITION(mXULBuilder != nsnull, "not initialized"); + if (! mXULBuilder) + return NS_ERROR_NOT_INITIALIZED; + + NS_PRECONDITION(mRootContent == nsnull, "already initialize"); + if (mRootContent) + return NS_ERROR_ALREADY_INITIALIZED; + + nsresult rv = mXULBuilder->CreateRootContent(aResource); + + NS_POSTCONDITION(mRootContent != nsnull, "root content wasn't set"); + return rv; +} + +NS_IMETHODIMP +XULDocumentImpl::SplitProperty(nsIRDFResource* aProperty, + PRInt32* aNameSpaceID, + nsIAtom** aTag) +{ + NS_PRECONDITION(aProperty != nsnull, "null ptr"); + if (! aProperty) + return NS_ERROR_NULL_POINTER; + + // XXX okay, this is a total hack. for this to work right, we need + // to either: + // + // 1) Remember what the namespace and the tag were when the + // property was created, or + // + // 2) Iterate the entire set of namespace prefixes to see if the + // specified property's URI has any of them as a substring. + // + + const char* p; + aProperty->GetValue(&p); + nsAutoString uri(p); + + PRInt32 index; + + // First try to split the namespace using the rightmost '#' or '/' + // character. + if ((index = uri.RFind('#')) < 0) { + if ((index = uri.RFind('/')) < 0) { + NS_ERROR("make this smarter!"); + return NS_ERROR_FAILURE; + } + } + + // Using the above info, split the property's URI into a namespace + // prefix (that includes the trailing '#' or '/' character) and a + // tag. + nsAutoString tag; + PRInt32 count = uri.Length() - (index + 1); + uri.Right(tag, count); + uri.Cut(index + 1, count); + + // XXX XUL atoms seem to all be in lower case. HTML atoms are in + // upper case. This sucks. + //tag.ToUpperCase(); + + nsresult rv; + PRInt32 nameSpaceID; + rv = mNameSpaceManager->GetNameSpaceID(uri, nameSpaceID); + + // Did we find one? + if (NS_SUCCEEDED(rv) && nameSpaceID != kNameSpaceID_Unknown) { + *aNameSpaceID = nameSpaceID; + + if (nameSpaceID == kNameSpaceID_HTML) + tag.ToUpperCase(); + + *aTag = NS_NewAtom(tag); + return NS_OK; + } + + // Nope: so we'll need to be a bit more creative. Let's see + // what happens if we remove the rightmost '#' and then try... + if (uri.Last() == '#') { + uri.Truncate(uri.Length() - 1); + rv = mNameSpaceManager->GetNameSpaceID(uri, nameSpaceID); + + if (NS_SUCCEEDED(rv) && nameSpaceID != kNameSpaceID_Unknown) { + *aNameSpaceID = nameSpaceID; + + if (nameSpaceID == kNameSpaceID_HTML) + tag.ToUpperCase(); + + *aTag = NS_NewAtom(tag); + return NS_OK; + } + } + + // Okay, somebody make this code even more convoluted. + NS_ERROR("unable to convert URI to namespace/tag pair"); + return NS_ERROR_FAILURE; // XXX? +} + + +NS_IMETHODIMP +XULDocumentImpl::AddElementForResource(nsIRDFResource* aResource, nsIRDFContent* aElement) +{ + NS_PRECONDITION(aResource != nsnull, "null ptr"); + if (! aResource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aElement != nsnull, "null ptr"); + if (! aElement) + return NS_ERROR_NULL_POINTER; + + mResources.Add(aResource, aElement); + return NS_OK; +} + + +NS_IMETHODIMP +XULDocumentImpl::RemoveElementForResource(nsIRDFResource* aResource, nsIRDFContent* aElement) +{ + NS_PRECONDITION(aResource != nsnull, "null ptr"); + if (! aResource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aElement != nsnull, "null ptr"); + if (! aElement) + return NS_ERROR_NULL_POINTER; + + mResources.Remove(aResource, aElement); + return NS_OK; +} + + +NS_IMETHODIMP +XULDocumentImpl::GetElementsForResource(nsIRDFResource* aResource, nsISupportsArray* aElements) +{ + NS_PRECONDITION(aElements != nsnull, "null ptr"); + if (! aElements) + return NS_ERROR_NULL_POINTER; + + mResources.Find(aResource, aElements); + return NS_OK; +} + + +NS_IMETHODIMP +XULDocumentImpl::CreateContents(nsIRDFContent* aElement) +{ + NS_PRECONDITION(aElement != nsnull, "null ptr"); + if (! aElement) + return NS_ERROR_NULL_POINTER; + + if (! mBuilders) + return NS_ERROR_NOT_INITIALIZED; + + for (PRInt32 i = 0; i < mBuilders->Count(); ++i) { + // XXX we should QueryInterface() here + nsIRDFContentModelBuilder* builder + = (nsIRDFContentModelBuilder*) mBuilders->ElementAt(i); + + NS_ASSERTION(builder != nsnull, "null ptr"); + if (! builder) + continue; + + nsresult rv = builder->CreateContents(aElement); + NS_ASSERTION(NS_SUCCEEDED(rv), "error creating content"); + // XXX ignore error code? + + NS_RELEASE(builder); + } + + return NS_OK; +} + + +NS_IMETHODIMP +XULDocumentImpl::AddContentModelBuilder(nsIRDFContentModelBuilder* aBuilder) +{ + NS_PRECONDITION(aBuilder != nsnull, "null ptr"); + if (! aBuilder) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + if (! mBuilders) { + if (NS_FAILED(rv = NS_NewISupportsArray(&mBuilders))) + return rv; + } + + if (NS_FAILED(rv = aBuilder->SetDocument(this))) { + NS_ERROR("unable to set builder's document"); + return rv; + } + + return mBuilders->AppendElement(aBuilder) ? NS_OK : NS_ERROR_FAILURE; +} + +//////////////////////////////////////////////////////////////////////// +// nsIRDFXMLDataSourceObserver interface + +NS_IMETHODIMP +XULDocumentImpl::OnBeginLoad(nsIRDFXMLDataSource* aDataSource) +{ + return BeginLoad(); +} + + +NS_IMETHODIMP +XULDocumentImpl::OnInterrupt(nsIRDFXMLDataSource* aDataSource) +{ + // flow any content that we have up until now. + return NS_OK; +} + + +NS_IMETHODIMP +XULDocumentImpl::OnResume(nsIRDFXMLDataSource* aDataSource) +{ + return NS_OK; +} + + +NS_IMETHODIMP +XULDocumentImpl::OnEndLoad(nsIRDFXMLDataSource* aDataSource) +{ + // XXX this is a temporary hack...please forgive... + StartLayout(); + return EndLoad(); +} + + + +NS_IMETHODIMP +XULDocumentImpl::OnRootResourceFound(nsIRDFXMLDataSource* aDataSource, nsIRDFResource* aResource) +{ + nsresult rv; + if (NS_SUCCEEDED(rv = SetRootResource(aResource))) { + // XXX this is a temporary hack...please forgive... + //rv = StartLayout(); + } + return rv; +} + + +NS_IMETHODIMP +XULDocumentImpl::OnCSSStyleSheetAdded(nsIRDFXMLDataSource* aDataSource, nsIURL* aStyleSheetURL) +{ + return LoadCSSStyleSheet(aStyleSheetURL); +} + +NS_IMETHODIMP +XULDocumentImpl::OnNamedDataSourceAdded(nsIRDFXMLDataSource* aDataSource, const char* aNamedDataSourceURI) +{ + return AddNamedDataSource(aNamedDataSourceURI); +} + + +//////////////////////////////////////////////////////////////////////// +// Implementation methods + +nsIContent* +XULDocumentImpl::FindContent(const nsIContent* aStartNode, + const nsIContent* aTest1, + const nsIContent* aTest2) const +{ + PRInt32 count; + aStartNode->ChildCount(count); + + PRInt32 index; + for(index = 0; index < count;index++) { + nsIContent* child; + aStartNode->ChildAt(index, child); + 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; +} + + +nsresult +XULDocumentImpl::LoadCSSStyleSheet(nsIURL* url) +{ + nsresult rv; + nsIInputStream* iin; + rv = NS_OpenURL(url, &iin); + if (NS_OK != rv) { + NS_RELEASE(url); + return rv; + } + + nsIUnicharInputStream* uin = nsnull; + rv = NS_NewConverterStream(&uin, nsnull, iin); + NS_RELEASE(iin); + if (NS_OK != rv) { + NS_RELEASE(url); + return rv; + } + + nsICSSParser* parser; + rv = nsRepository::CreateInstance(kCSSParserCID, + nsnull, + kICSSParserIID, + (void**) &parser); + + if (NS_SUCCEEDED(rv)) { + nsICSSStyleSheet* sheet = nsnull; + // XXX note: we are ignoring rv until the error code stuff in the + // input routines is converted to use nsresult's + parser->SetCaseSensitive(PR_TRUE); + parser->Parse(uin, url, sheet); + if (nsnull != sheet) { + AddStyleSheet(sheet); + NS_RELEASE(sheet); + rv = NS_OK; + } else { + rv = NS_ERROR_OUT_OF_MEMORY;/* XXX */ + } + NS_RELEASE(parser); + } + + NS_RELEASE(uin); + NS_RELEASE(url); + return rv; +} + + +nsresult +XULDocumentImpl::AddNamedDataSource(const char* uri) +{ + NS_PRECONDITION(mXULBuilder != nsnull, "not initialized"); + if (! mXULBuilder) + return NS_ERROR_NOT_INITIALIZED; + + nsresult rv; + nsCOMPtr ds; + + if (NS_FAILED(rv = mRDFService->GetDataSource(uri, getter_AddRefs(ds)))) { + NS_ERROR("unable to get named datasource"); + return rv; + } + + nsCOMPtr db; + if (NS_FAILED(rv = mXULBuilder->GetDataBase(getter_AddRefs(db)))) { + NS_ERROR("unable to get XUL db"); + return rv; + } + + if (NS_FAILED(rv = db->AddDataSource(ds))) { + NS_ERROR("unable to add named data source to XUL db"); + return rv; + } + + return NS_OK; +} + + +nsresult +XULDocumentImpl::Init(void) +{ + nsresult rv; + + if (NS_FAILED(rv = NS_NewHeapArena(&mArena, nsnull))) + return rv; + + // Create a namespace manager so we can manage tags + if (NS_FAILED(rv = nsRepository::CreateInstance(kNameSpaceManagerCID, + nsnull, + kINameSpaceManagerIID, + (void**) &mNameSpaceManager))) + return rv; + + // Keep the RDF service cached in a member variable to make using + // it a bit less painful + if (NS_FAILED(rv = nsServiceManager::GetService(kRDFServiceCID, + kIRDFServiceIID, + (nsISupports**) &mRDFService))) + return rv; + + return NS_OK; +} + + + +nsresult +XULDocumentImpl::StartLayout(void) +{ + PRInt32 count = GetNumberOfShells(); + for (PRInt32 i = 0; i < count; i++) { + nsIPresShell* shell = GetShellAt(i); + if (nsnull == shell) + continue; + + // Resize-reflow this time + nsIPresContext* cx = shell->GetPresContext(); + nsRect r; + cx->GetVisibleArea(r); + shell->InitialReflow(r.width, r.height); + NS_RELEASE(cx); + + // Now trigger a refresh + nsIViewManager* vm = shell->GetViewManager(); + if (nsnull != vm) { + vm->EnableRefresh(); + NS_RELEASE(vm); + } + + // Start observing the document _after_ we do the initial + // reflow. Otherwise, we'll get into an trouble trying to + // creat kids before the root frame is established. + shell->BeginObservingDocument(); + + NS_RELEASE(shell); + } + return NS_OK; +} + + +//////////////////////////////////////////////////////////////////////// + +nsresult +NS_NewXULDocument(nsIRDFDocument** result) +{ + NS_PRECONDITION(result != nsnull, "null ptr"); + if (! result) + return NS_ERROR_NULL_POINTER; + + XULDocumentImpl* doc = new XULDocumentImpl(); + 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; +} + diff --git a/mozilla/rdf/datasource/src/Makefile.in b/mozilla/rdf/datasource/src/Makefile.in index 09e96ac6f76..dfd4e672b53 100644 --- a/mozilla/rdf/datasource/src/Makefile.in +++ b/mozilla/rdf/datasource/src/Makefile.in @@ -29,7 +29,8 @@ LIBRARY_NAME = rdfdatasource_s CPPSRCS = \ nsBookmarkDataSource.cpp \ nsMailDataSource.cpp \ - nsXULDataSource.cpp \ + nsXULContentSink.cpp \ + nsXULDataSource.cpp \ $(NULL) EXPORTS = \ diff --git a/mozilla/rdf/datasource/src/makefile.win b/mozilla/rdf/datasource/src/makefile.win index e276f0ad5e0..fb9fea2704b 100644 --- a/mozilla/rdf/datasource/src/makefile.win +++ b/mozilla/rdf/datasource/src/makefile.win @@ -22,7 +22,8 @@ LIBRARY_NAME=rdfdatasource_s CPP_OBJS=\ .\$(OBJDIR)\nsBookmarkDataSource.obj \ .\$(OBJDIR)\nsMailDataSource.obj \ - .\$(OBJDIR)\nsXULDataSource.obj \ + .\$(OBJDIR)\nsXULContentSink.obj \ + .\$(OBJDIR)\nsXULDataSource.obj \ $(NULL) # XXX Note the dependency on $(DEPTH)\rdf\base\src: we use rdfutil.h over diff --git a/mozilla/rdf/datasource/src/nsBookmarkDataSource.cpp b/mozilla/rdf/datasource/src/nsBookmarkDataSource.cpp index c041dbadcb3..f60c9f1a998 100644 --- a/mozilla/rdf/datasource/src/nsBookmarkDataSource.cpp +++ b/mozilla/rdf/datasource/src/nsBookmarkDataSource.cpp @@ -45,7 +45,8 @@ static NS_DEFINE_IID(kIRDFServiceIID, NS_IRDFSERVICE_IID); static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID); static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); -static const char kURINC_BookmarksRoot[] = "NC:BookmarksRoot"; // XXX? +static const char kURINC_BookmarksRoot[] = "NC:BookmarksRoot"; // XXX? +static const char kURINC_PersonalToolbarFolder[] = "NC:PersonalToolbarFolder"; // XXX? DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, child); DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, BookmarkAddDate); @@ -210,10 +211,16 @@ BookmarkParser::NextToken(void) if (mStack.Count() > 0) { // a regular old folder - - nsAutoString folderURI(kURINC_BookmarksRoot); - folderURI.Append('#'); - folderURI.Append(++mCounter, 10); + nsAutoString folderURI; + + if (mLine.Find(kPersonalToolbar) == 0) { + folderURI = kURINC_PersonalToolbarFolder; + } + else { + folderURI = kURINC_BookmarksRoot; + folderURI.Append('#'); + folderURI.Append(++mCounter, 10); + } if (NS_FAILED(mRDFService->GetUnicodeResource(folderURI, &folder))) return; @@ -240,9 +247,6 @@ BookmarkParser::NextToken(void) if (mState != eBookmarkParserState_InTitle) rdf_Assert(mDataSource, mLastItem, kURINC_Name, mLine); - - if (mLine.Find(kPersonalToolbar) == 0) - rdf_Assert(mDataSource, mLastItem, kURIRDF_instanceOf, kURINC_PersonalToolbarFolderCategory); } else if (mState == eBookmarkParserState_InItemTitle) { PR_ASSERT(mLastItem); diff --git a/mozilla/rdf/base/src/nsXULContentSink.cpp b/mozilla/rdf/datasource/src/nsXULContentSink.cpp similarity index 98% rename from mozilla/rdf/base/src/nsXULContentSink.cpp rename to mozilla/rdf/datasource/src/nsXULContentSink.cpp index a8684a7bf37..77326b2062a 100644 --- a/mozilla/rdf/base/src/nsXULContentSink.cpp +++ b/mozilla/rdf/datasource/src/nsXULContentSink.cpp @@ -342,14 +342,13 @@ public: protected: static nsrefcnt gRefCnt; - static nsINameSpaceManager* gNameSpaceManager; static nsIRDFService* gRDFService; // pseudo-constants static nsIRDFResource* kRDF_child; // XXX needs to be NC:child (or something else) static nsIRDFResource* kRDF_type; - static nsresult + nsresult MakeResourceFromQualifiedTag(PRInt32 aNameSpaceID, const nsString& aTag, nsIRDFResource** aResource); @@ -369,6 +368,7 @@ protected: PRInt32 GetNameSpaceID(nsIAtom* aPrefix); void PopNameSpaces(); + nsINameSpaceManager* mNameSpaceManager; nsVoidArray* mNameSpaceStack; void SplitQualifiedName(const nsString& aQualifiedName, @@ -398,7 +398,6 @@ protected: }; nsrefcnt XULContentSinkImpl::gRefCnt = 0; -nsINameSpaceManager* XULContentSinkImpl::gNameSpaceManager = nsnull; nsIRDFService* XULContentSinkImpl::gRDFService = nsnull; nsIRDFResource* XULContentSinkImpl::kRDF_child = nsnull; @@ -422,13 +421,6 @@ XULContentSinkImpl::XULContentSinkImpl() if (gRefCnt++ == 0) { nsresult rv; - rv = nsRepository::CreateInstance(kNameSpaceManagerCID, - nsnull, - kINameSpaceManagerIID, - (void**) &gNameSpaceManager); - - NS_VERIFY(NS_SUCCEEDED(rv), "unable to construct namespace manager"); - rv = nsServiceManager::GetService(kRDFServiceCID, kIRDFServiceIID, (nsISupports**) &gRDFService); @@ -446,6 +438,7 @@ XULContentSinkImpl::XULContentSinkImpl() XULContentSinkImpl::~XULContentSinkImpl() { + NS_IF_RELEASE(mNameSpaceManager); NS_IF_RELEASE(mDocumentURL); NS_IF_RELEASE(mDataSource); @@ -481,7 +474,6 @@ XULContentSinkImpl::~XULContentSinkImpl() if (--gRefCnt == 0) { nsServiceManager::ReleaseService(kRDFServiceCID, gRDFService); - NS_IF_RELEASE(gNameSpaceManager); NS_IF_RELEASE(kRDF_child); NS_IF_RELEASE(kRDF_type); } @@ -522,7 +514,7 @@ XULContentSinkImpl::MakeResourceFromQualifiedTag(PRInt32 aNameSpaceID, nsresult rv; nsAutoString uri; - rv = gNameSpaceManager->GetNameSpaceURI(aNameSpaceID, uri); + rv = mNameSpaceManager->GetNameSpaceURI(aNameSpaceID, uri); NS_VERIFY(NS_SUCCEEDED(rv), "unable to get namespace URI"); // some hacky logic to try to construct an appopriate URI for the @@ -832,13 +824,16 @@ XULContentSinkImpl::Init(nsIURL* aURL, nsINameSpaceManager* aNameSpaceManager) mDocumentURL = aURL; NS_ADDREF(aURL); + mNameSpaceManager = aNameSpaceManager; + NS_ADDREF(aNameSpaceManager); + nsresult rv; // XXX This is sure to change. Copied from mozilla/layout/xul/content/src/nsXULAtoms.cpp static const char kXULNameSpaceURI[] = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; - rv = gNameSpaceManager->RegisterNameSpace(kXULNameSpaceURI, kNameSpaceID_XUL); + rv = mNameSpaceManager->RegisterNameSpace(kXULNameSpaceURI, kNameSpaceID_XUL); NS_ASSERTION(NS_SUCCEEDED(rv), "unable to register XUL namespace"); if (NS_FAILED(rv = nsServiceManager::GetService(kRDFServiceCID, @@ -1027,7 +1022,7 @@ XULContentSinkImpl::AddAttributes(const nsIParserNode& aNode, // Get the URI for the namespace, so we can construct a // fully-qualified property name. - gNameSpaceManager->GetNameSpaceURI(nameSpaceID, k); + mNameSpaceManager->GetNameSpaceURI(nameSpaceID, k); // Insert a '#' if the namespace doesn't end with one, or the // attribute doesn't start with one. @@ -1201,7 +1196,7 @@ XULContentSinkImpl::PushNameSpacesFrom(const nsIParserNode& aNode) NS_ADDREF(nameSpace); } else { - gNameSpaceManager->CreateRootNameSpace(nameSpace); + mNameSpaceManager->CreateRootNameSpace(nameSpace); } if (nsnull != nameSpace) { diff --git a/mozilla/rdf/datasource/src/nsXULDataSource.cpp b/mozilla/rdf/datasource/src/nsXULDataSource.cpp index 95164f12cd8..9aa1f33db55 100644 --- a/mozilla/rdf/datasource/src/nsXULDataSource.cpp +++ b/mozilla/rdf/datasource/src/nsXULDataSource.cpp @@ -109,7 +109,6 @@ protected: nsIRDFResource* mRootResource; PRBool mIsLoading; // true while the document is loading NameSpaceMap* mNameSpaces; - nsID mContentModelBuilderCID; public: XULDataSourceImpl(void); @@ -225,8 +224,6 @@ public: NS_IMETHOD AddNamedDataSourceURI(const char* aNamedDataSourceURI); NS_IMETHOD GetNamedDataSourceURIs(const char* const** aNamedDataSourceURIs, PRInt32* aCount); NS_IMETHOD AddNameSpace(nsIAtom* aPrefix, const nsString& aURI); - NS_IMETHOD SetContentModelBuilderCID(nsID* aCID); - NS_IMETHOD GetContentModelBuilderCID(nsID* aCID); NS_IMETHOD AddXMLStreamObserver(nsIRDFXMLDataSourceObserver* aObserver); NS_IMETHOD RemoveXMLStreamObserver(nsIRDFXMLDataSourceObserver* aObserver); }; @@ -625,26 +622,6 @@ XULDataSourceImpl::AddNameSpace(nsIAtom* aPrefix, const nsString& aURI) } -NS_IMETHODIMP -XULDataSourceImpl::SetContentModelBuilderCID(nsID* aCID) -{ - mContentModelBuilderCID = *aCID; - - for (PRInt32 i = mObservers.Count() - 1; i >= 0; --i) { - nsIRDFXMLDataSourceObserver* obs = (nsIRDFXMLDataSourceObserver*) mObservers[i]; - obs->OnContentModelBuilderSpecified(this, &mContentModelBuilderCID); - } - - return NS_OK; -} - -NS_IMETHODIMP -XULDataSourceImpl::GetContentModelBuilderCID(nsID* aCID) -{ - *aCID = mContentModelBuilderCID; - return NS_OK; -} - NS_IMETHODIMP XULDataSourceImpl::AddXMLStreamObserver(nsIRDFXMLDataSourceObserver* aObserver) { diff --git a/mozilla/rdf/macbuild/rdf.mcp b/mozilla/rdf/macbuild/rdf.mcp index 5a6ddb8a9f195590eb376348db5c605e64a712fd..dfa2318ceccea471c21ed15cc3c18f169d52e671 100644 GIT binary patch delta 1884 zcma)6Yiv|S6rQ==yL-2LTcA8jx2>#{wn*c)ERV>7Wu>)Jy2v7+28z&bZ>6}~E$nU- zR9fl}6P2#pF>XSD@QVOaQXK;X2r(Lk)CxW#Bv8O$TZ|!quLPrr-`v?+^@s7?d^2ah znK^ULnLFpmUdxfamfm-?!YPCh7excCMQ4r`C_pniqs<&ch>oEHumiblw!MsIv3h%H z)nttG04GoYHG}Mr-uxRsQNo zFdjBqWA0#E8woXRiNs^oMq~V0cXUIjF-^ExpeLRTOq-YiQ<;G1wf6=GnhD7%+II9AqDc?79icERof2N!*+fmLsclfe`xV$F7FfZ}vl1jec zqtRr*se&L1+g?7O_s+Vca6Y#~VQc0UYdCWarZzF(+#+wR@lo#e~c{YKfX`IBsei84aUPl32Yxux<1<<}R&W@1sXCY(sybcunHHfs)$ z0uqy!AK+@071j=`?B-wzwX=ys3t9b;n{^LW(0X=as0jCUb!f6yQ|o_JILelG6|nKc zF}qDLW{g+5YUK#?YuWUKCs{R#y_v8$G-Aa`;*!Vn3T{!@?ZXxpsmbOavpfsm=l57k zk?}?GmQYjF8#Nljk=EyoE#7csYfC89;FUM)-4F|h_^u@bG`-!HV-H@2y)chM?7)_ah0{naWf-_&u9vX6!rmXoFdV$_qS z8>Fe97$MShk{An!v5Oc5#CSt7pU!9$h5wGCE_2*JJW0Fy(QK?c_nS_rXlSTCTisd z&*KQgCO2fi2yThwJHv2Dll+RQ;BcT2y&p}bJh*iqbiZK1??RI;`RjeqmkO4U3Xzva zX(#`5I|evVh<*^w1i7K{73d-gh~qYzOu1o>cme^z5|SnAkc>?IG6{XTUXME~|-UvVriG-ztdl$AyP_TqtyF41)>!P%ZdIkBs8I6ohy^;f6lrG4u2%2+eAq>mc9$V#ao~G>eYO_!HoKxE25a delta 1961 zcmah~du)?c6u)3>Ckd2jgfQ)u)ixLTL zvVaK$XT8QI7z}?Q>L9=k;DZ?AA3%`sFuoEVP9&g)#2Ji|K$ySV`wi4T^d#q=bAR`{ z=iKwVkMG!Cqa&s>joQZ+m{NC zV?zg37OXO|nU~DWmaVamZ3S$+HkVd1zvc-v>+9_$#QY>777?SHtV<*#(MUYd9&KL} ziTi> z5rx%16=9cWm9kt{CHI%O&8%aKJr&$v8OL}p7Ub3!6eqOIxo!8taJVVp_eNHCwzWAc z@QneQrCZC9EBCtysjgzH%Jca7s}E=@s1^xkjZi_4$p254XE`ScmW%&`v2oYSkQ&FFTEF0;)m2K5cBtK7)G zoj1;W<$id0_|F5p`}RG`eqEpg@4OG-F6G9mPpRtDV>$SV>OMsc>9HK_=|$5KtDdVK z6J?`)#TClVO*FoFD3NUMOxATpqK#e2Ws!JdT`ZbVw}$h|qlwz3UY|F!t!83EAd{Pr zF?<#`DmWNM_FiffA4=Z=S2odChaql0keXuTJNzyackDGPe6Z>589cb_2g>Qqqhem> zK=GNE?oqD2<}tCioMkk_Pg@A=tVS9khHOtPigT271Y+SxClHIT)?XvI)a`QJHtDuS zx6Qg;q1$%du4Gre_FP5p`E|RDO{gg}B5aV&t0~stxb%?<_CifHHL)W#wXC||^%!wm z?|e6uS=>nTUE%ALycJ=XO+f}+%!<0Ghd~wci=0wA>p_e(icb zWos@D@T0dV{TpS6bNL@XYLfgMZwbv}72ayv%wpczxRHCj73_+)aDqV;fHUjSZ9umz zDD{np1v#gA*ZawXR(Gy>e9 z^aOly?jhdgfCn?U`kRRPOa>-xxbh}Vey^Gs9=wqyT|JpVmdgNZ<$!BH$}r0b zqc#J3PU5ei4#gtzhAF@nOI#a-t&)kO`{4T}ZXE+VO5(T9!VgHiBn%spaqOpi&{-k} ztRKPV$qAu8_@WAk^&FZkIbpWAjX{Cpy%%RvR;GTLf?qFCyn)?l&dNBa#51;3poF}- z0EOjC{FmbZ8lWhOY!%LanZSPrej^l8atckUoUo@C{_{}C)_Y(=PyBTifMpq&*zUv1 ztx?aefR8N^(%&z(CjFU>wiJ92d&FX~1A{BY7s&N{+NDvSqMb;;tkKdQ+aN$a#}{t+ zAt+?vB{X_*hg;$6@5XufBgO3$e?!4C