From f7eb900faeb278b83951cc954cef8fa90aa4dfd8 Mon Sep 17 00:00:00 2001 From: "hyatt%netscape.com" Date: Wed, 10 Mar 1999 20:05:12 +0000 Subject: [PATCH] Working on XUL fragments. git-svn-id: svn://10.0.0.236/trunk@23551 18797224-902f-48f8-a5cc-f745e15eee43 --- .../content/xul/content/src/nsXULElement.cpp | 2 + .../xul/document/src/nsXULDocument.cpp | 37 +++++--- .../rdf/content/public/nsIXULChildDocument.h | 5 +- mozilla/rdf/content/src/nsRDFElement.cpp | 2 + mozilla/rdf/content/src/nsRDFXULBuilder.cpp | 17 +++- mozilla/rdf/content/src/nsXULDocument.cpp | 37 +++++--- mozilla/rdf/content/src/nsXULElement.cpp | 2 + .../rdf/datasource/src/nsXULContentSink.cpp | 89 ++++++++++++++----- 8 files changed, 144 insertions(+), 47 deletions(-) diff --git a/mozilla/content/xul/content/src/nsXULElement.cpp b/mozilla/content/xul/content/src/nsXULElement.cpp index 56e54f2168e..ee60a394b75 100644 --- a/mozilla/content/xul/content/src/nsXULElement.cpp +++ b/mozilla/content/xul/content/src/nsXULElement.cpp @@ -83,6 +83,7 @@ #include "nsIDOMFormListener.h" #include "nsIScriptContextOwner.h" #include "nsIStyledContent.h" +#include "nsIRDFContent.h" #include "nsIStyleRule.h" #include "nsIURL.h" #include "nsXULTreeElement.h" @@ -255,6 +256,7 @@ public: // Implementation methods nsresult GetResource(nsIRDFResource** aResource); + nsresult EnsureContentsGenerated(void) const; nsresult AddScriptEventListener(nsIAtom* aName, const nsString& aValue, REFNSIID aIID); diff --git a/mozilla/content/xul/document/src/nsXULDocument.cpp b/mozilla/content/xul/document/src/nsXULDocument.cpp index 01c3f4ec8c4..b76338574c3 100644 --- a/mozilla/content/xul/document/src/nsXULDocument.cpp +++ b/mozilla/content/xul/document/src/nsXULDocument.cpp @@ -509,8 +509,8 @@ public: NS_IMETHOD GetCommand(nsString& aCommand); // nsIXULChildDocument Interface - NS_IMETHOD SetFragmentRoot(nsIContent* aFragmentRoot); - NS_IMETHOD GetFragmentRoot(nsIContent** aFragmentRoot); + NS_IMETHOD SetFragmentRoot(nsIRDFResource* aFragmentRoot); + NS_IMETHOD GetFragmentRoot(nsIRDFResource** aFragmentRoot); // nsIDOMNode interface NS_IMETHOD GetNodeName(nsString& aNodeName); @@ -618,7 +618,8 @@ protected: nsILineBreaker* mLineBreaker; nsIContentViewerContainer* mContentViewerContainer; nsString mCommand; - nsIContent* mFragmentRoot; + nsIRDFResource* mFragmentRoot; + nsVoidArray mSubDocuments; }; PRInt32 XULDocumentImpl::gRefCnt; @@ -680,6 +681,13 @@ XULDocumentImpl::~XULDocumentImpl() } // mParentDocument is never refcounted + // Delete references to sub-documents + PRInt32 index = mSubDocuments.Count(); + while (--index >= 0) { + nsIDocument* subdoc = (nsIDocument*) mSubDocuments.ElementAt(index); + NS_RELEASE(subdoc); + } + NS_IF_RELEASE(mBuilders); NS_IF_RELEASE(mXULBuilder); NS_IF_RELEASE(mSelection); @@ -694,7 +702,7 @@ XULDocumentImpl::~XULDocumentImpl() NS_IF_RELEASE(mLineBreaker); NS_IF_RELEASE(mContentViewerContainer); NS_IF_RELEASE(mFragmentRoot); - + if (--gRefCnt == 0) { NS_IF_RELEASE(kIdAtom); NS_IF_RELEASE(kObservesAtom); @@ -1165,22 +1173,24 @@ XULDocumentImpl::SetParentDocument(nsIDocument* aParent) void XULDocumentImpl::AddSubDocument(nsIDocument* aSubDoc) { - // we don't do subdocs. - PR_ASSERT(0); + NS_ADDREF(aSubDoc); + mSubDocuments.AppendElement(aSubDoc); } PRInt32 XULDocumentImpl::GetNumberOfSubDocuments() { - return 0; + return mSubDocuments.Count(); } nsIDocument* XULDocumentImpl::GetSubDocumentAt(PRInt32 aIndex) { - // we don't do subdocs. - PR_ASSERT(0); - return nsnull; + nsIDocument* doc = (nsIDocument*) mSubDocuments.ElementAt(aIndex); + if (nsnull != doc) { + NS_ADDREF(doc); + } + return doc; } nsIContent* @@ -2355,7 +2365,7 @@ XULDocumentImpl::GetCommand(nsString& aCommand) //////////////////////////////////////////////////////////////////////// // nsIXULChildDocument interface NS_IMETHODIMP -XULDocumentImpl::SetFragmentRoot(nsIContent* aFragmentRoot) +XULDocumentImpl::SetFragmentRoot(nsIRDFResource* aFragmentRoot) { if (aFragmentRoot != mFragmentRoot) { @@ -2367,7 +2377,7 @@ XULDocumentImpl::SetFragmentRoot(nsIContent* aFragmentRoot) } NS_IMETHODIMP -XULDocumentImpl::GetFragmentRoot(nsIContent** aFragmentRoot) +XULDocumentImpl::GetFragmentRoot(nsIRDFResource** aFragmentRoot) { if (mFragmentRoot) { NS_ADDREF(mFragmentRoot); @@ -2991,6 +3001,9 @@ XULDocumentImpl::Init(void) nsresult XULDocumentImpl::StartLayout(void) { + if (mFragmentRoot) + return NS_OK; // Subdocuments rely on the parent document for layout + PRInt32 count = GetNumberOfShells(); for (PRInt32 i = 0; i < count; i++) { nsIPresShell* shell = GetShellAt(i); diff --git a/mozilla/rdf/content/public/nsIXULChildDocument.h b/mozilla/rdf/content/public/nsIXULChildDocument.h index b7ea2d88bf5..bd2d1dd49b2 100644 --- a/mozilla/rdf/content/public/nsIXULChildDocument.h +++ b/mozilla/rdf/content/public/nsIXULChildDocument.h @@ -26,13 +26,14 @@ { 0x7b75c621, 0xd641, 0x11d2, { 0xbf, 0x86, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } } class nsIContentViewerContainer; +class nsIRDFResource; class nsIXULChildDocument: public nsISupports { public: static const nsIID& GetIID() { static nsIID iid = NS_IXULCHILDDOCUMENT_IID; return iid; } - NS_IMETHOD SetFragmentRoot(nsIContent* aContent) = 0; - NS_IMETHOD GetFragmentRoot(nsIContent** aContent) = 0; + NS_IMETHOD SetFragmentRoot(nsIRDFResource* aContent) = 0; + NS_IMETHOD GetFragmentRoot(nsIRDFResource** aContent) = 0; }; #endif // nsIXULChildDocument_h__ diff --git a/mozilla/rdf/content/src/nsRDFElement.cpp b/mozilla/rdf/content/src/nsRDFElement.cpp index 56e54f2168e..ee60a394b75 100644 --- a/mozilla/rdf/content/src/nsRDFElement.cpp +++ b/mozilla/rdf/content/src/nsRDFElement.cpp @@ -83,6 +83,7 @@ #include "nsIDOMFormListener.h" #include "nsIScriptContextOwner.h" #include "nsIStyledContent.h" +#include "nsIRDFContent.h" #include "nsIStyleRule.h" #include "nsIURL.h" #include "nsXULTreeElement.h" @@ -255,6 +256,7 @@ public: // Implementation methods nsresult GetResource(nsIRDFResource** aResource); + nsresult EnsureContentsGenerated(void) const; nsresult AddScriptEventListener(nsIAtom* aName, const nsString& aValue, REFNSIID aIID); diff --git a/mozilla/rdf/content/src/nsRDFXULBuilder.cpp b/mozilla/rdf/content/src/nsRDFXULBuilder.cpp index ec3ef46a7be..973705b6cf9 100644 --- a/mozilla/rdf/content/src/nsRDFXULBuilder.cpp +++ b/mozilla/rdf/content/src/nsRDFXULBuilder.cpp @@ -602,6 +602,8 @@ RDFXULBuilderImpl::CreateContents(nsIContent* aElement) } subDocument->SetParentDocument(parentDoc); + parentDoc->AddSubDocument(subDocument); + nsCOMPtr streamListener; nsCOMPtr container; nsCOMPtr xulParentDocument; @@ -631,7 +633,20 @@ RDFXULBuilderImpl::CreateContents(nsIContent* aElement) return rv; } - xulChildDocument->SetFragmentRoot(aElement); + nsCOMPtr xulElement; + xulElement = do_QueryInterface(aElement); + if (!xulElement) { + NS_ERROR("The fragment root is not a XUL element."); + return rv; + } + + nsCOMPtr rdfResource; + //xulElement->GetResource(rdfResource); + if (!rdfResource) { + NS_ERROR("The fragment root doesn't have an RDF resource behind it."); + return rv; + } + xulChildDocument->SetFragmentRoot(rdfResource); if (NS_FAILED(rv = subDocument->StartDocumentLoad(includeURL, container, getter_AddRefs(streamListener), commandChars))) { diff --git a/mozilla/rdf/content/src/nsXULDocument.cpp b/mozilla/rdf/content/src/nsXULDocument.cpp index 01c3f4ec8c4..b76338574c3 100644 --- a/mozilla/rdf/content/src/nsXULDocument.cpp +++ b/mozilla/rdf/content/src/nsXULDocument.cpp @@ -509,8 +509,8 @@ public: NS_IMETHOD GetCommand(nsString& aCommand); // nsIXULChildDocument Interface - NS_IMETHOD SetFragmentRoot(nsIContent* aFragmentRoot); - NS_IMETHOD GetFragmentRoot(nsIContent** aFragmentRoot); + NS_IMETHOD SetFragmentRoot(nsIRDFResource* aFragmentRoot); + NS_IMETHOD GetFragmentRoot(nsIRDFResource** aFragmentRoot); // nsIDOMNode interface NS_IMETHOD GetNodeName(nsString& aNodeName); @@ -618,7 +618,8 @@ protected: nsILineBreaker* mLineBreaker; nsIContentViewerContainer* mContentViewerContainer; nsString mCommand; - nsIContent* mFragmentRoot; + nsIRDFResource* mFragmentRoot; + nsVoidArray mSubDocuments; }; PRInt32 XULDocumentImpl::gRefCnt; @@ -680,6 +681,13 @@ XULDocumentImpl::~XULDocumentImpl() } // mParentDocument is never refcounted + // Delete references to sub-documents + PRInt32 index = mSubDocuments.Count(); + while (--index >= 0) { + nsIDocument* subdoc = (nsIDocument*) mSubDocuments.ElementAt(index); + NS_RELEASE(subdoc); + } + NS_IF_RELEASE(mBuilders); NS_IF_RELEASE(mXULBuilder); NS_IF_RELEASE(mSelection); @@ -694,7 +702,7 @@ XULDocumentImpl::~XULDocumentImpl() NS_IF_RELEASE(mLineBreaker); NS_IF_RELEASE(mContentViewerContainer); NS_IF_RELEASE(mFragmentRoot); - + if (--gRefCnt == 0) { NS_IF_RELEASE(kIdAtom); NS_IF_RELEASE(kObservesAtom); @@ -1165,22 +1173,24 @@ XULDocumentImpl::SetParentDocument(nsIDocument* aParent) void XULDocumentImpl::AddSubDocument(nsIDocument* aSubDoc) { - // we don't do subdocs. - PR_ASSERT(0); + NS_ADDREF(aSubDoc); + mSubDocuments.AppendElement(aSubDoc); } PRInt32 XULDocumentImpl::GetNumberOfSubDocuments() { - return 0; + return mSubDocuments.Count(); } nsIDocument* XULDocumentImpl::GetSubDocumentAt(PRInt32 aIndex) { - // we don't do subdocs. - PR_ASSERT(0); - return nsnull; + nsIDocument* doc = (nsIDocument*) mSubDocuments.ElementAt(aIndex); + if (nsnull != doc) { + NS_ADDREF(doc); + } + return doc; } nsIContent* @@ -2355,7 +2365,7 @@ XULDocumentImpl::GetCommand(nsString& aCommand) //////////////////////////////////////////////////////////////////////// // nsIXULChildDocument interface NS_IMETHODIMP -XULDocumentImpl::SetFragmentRoot(nsIContent* aFragmentRoot) +XULDocumentImpl::SetFragmentRoot(nsIRDFResource* aFragmentRoot) { if (aFragmentRoot != mFragmentRoot) { @@ -2367,7 +2377,7 @@ XULDocumentImpl::SetFragmentRoot(nsIContent* aFragmentRoot) } NS_IMETHODIMP -XULDocumentImpl::GetFragmentRoot(nsIContent** aFragmentRoot) +XULDocumentImpl::GetFragmentRoot(nsIRDFResource** aFragmentRoot) { if (mFragmentRoot) { NS_ADDREF(mFragmentRoot); @@ -2991,6 +3001,9 @@ XULDocumentImpl::Init(void) nsresult XULDocumentImpl::StartLayout(void) { + if (mFragmentRoot) + return NS_OK; // Subdocuments rely on the parent document for layout + PRInt32 count = GetNumberOfShells(); for (PRInt32 i = 0; i < count; i++) { nsIPresShell* shell = GetShellAt(i); diff --git a/mozilla/rdf/content/src/nsXULElement.cpp b/mozilla/rdf/content/src/nsXULElement.cpp index 56e54f2168e..ee60a394b75 100644 --- a/mozilla/rdf/content/src/nsXULElement.cpp +++ b/mozilla/rdf/content/src/nsXULElement.cpp @@ -83,6 +83,7 @@ #include "nsIDOMFormListener.h" #include "nsIScriptContextOwner.h" #include "nsIStyledContent.h" +#include "nsIRDFContent.h" #include "nsIStyleRule.h" #include "nsIURL.h" #include "nsXULTreeElement.h" @@ -255,6 +256,7 @@ public: // Implementation methods nsresult GetResource(nsIRDFResource** aResource); + nsresult EnsureContentsGenerated(void) const; nsresult AddScriptEventListener(nsIAtom* aName, const nsString& aValue, REFNSIID aIID); diff --git a/mozilla/rdf/datasource/src/nsXULContentSink.cpp b/mozilla/rdf/datasource/src/nsXULContentSink.cpp index 83d673461b7..2e61a5f95c5 100644 --- a/mozilla/rdf/datasource/src/nsXULContentSink.cpp +++ b/mozilla/rdf/datasource/src/nsXULContentSink.cpp @@ -40,6 +40,7 @@ #include "nsINameSpaceManager.h" #include "nsIParser.h" #include "nsIPresShell.h" +#include "nsIRDFContent.h" #include "nsIRDFDocument.h" #include "nsIRDFNode.h" #include "nsIRDFService.h" @@ -239,7 +240,7 @@ protected: nsIDocument* mDocument; nsIParser* mParser; - nsIContent* mFragmentRoot; + nsIRDFResource* mFragmentRoot; }; @@ -842,24 +843,66 @@ XULContentSinkImpl::AddEntityReference(const nsIParserNode& aNode) NS_IMETHODIMP XULContentSinkImpl::Init(nsIDocument* aDocument, nsIWebShell* aWebShell, nsIRDFDataSource* aDataSource) { + nsresult rv; + NS_PRECONDITION(aDocument != nsnull, "null ptr"); if (! aDocument) return NS_ERROR_NULL_POINTER; - + nsCOMPtr childDocument; childDocument = do_QueryInterface(mDocument); if (childDocument != nsnull) { childDocument->GetFragmentRoot(&mFragmentRoot); + NS_PRECONDITION(mFragmentRoot, "must have a fragment root to place the fragment properly"); if (mFragmentRoot) { // We're totally a subdocument. Find the root document's // data source and make assertions there. + + // First of all, find the root document. + nsIDocument* rootDocument; + nsIDocument* currDocument; + currDocument = aDocument; + NS_ADDREF(currDocument); + while (currDocument != nsnull) { + NS_IF_RELEASE(rootDocument); + rootDocument = currDocument; + currDocument = rootDocument->GetParentDocument(); + } + + // Retrieve the root data source. + nsCOMPtr rdfRootDoc; + rdfRootDoc = do_QueryInterface(rootDocument); + if (rdfRootDoc == nsnull) { + NS_ERROR("Root document of a XUL fragment is not an RDF doc."); + NS_RELEASE(rootDocument); + return rv; + } + + nsCOMPtr docDataSource; + if (NS_FAILED(rv = rdfRootDoc->GetDocumentDataSource(getter_AddRefs(docDataSource)))) { + NS_ERROR("Unable to retrieve an RDF document's data source."); + NS_RELEASE(rootDocument); + return rv; + } + + NS_IF_RELEASE(mDataSource); + mDataSource = docDataSource.get(); + NS_ADDREF(mDataSource); } + else return NS_ERROR_NULL_POINTER; } + else { - NS_PRECONDITION(aDataSource != nsnull, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; + NS_PRECONDITION(aDataSource != nsnull, "null ptr"); + if (! aDataSource) + return NS_ERROR_NULL_POINTER; + NS_IF_RELEASE(mDataSource); + mDataSource = aDataSource; + NS_ADDREF(aDataSource); + } + + NS_IF_RELEASE(mDocument); mDocument = aDocument; NS_ADDREF(mDocument); @@ -867,20 +910,17 @@ XULContentSinkImpl::Init(nsIDocument* aDocument, nsIWebShell* aWebShell, nsIRDFD NS_IF_RELEASE(mDocumentURL); mDocumentURL = mDocument->GetDocumentURL(); - NS_IF_RELEASE(mDataSource); - mDataSource = aDataSource; - NS_ADDREF(aDataSource); - - nsresult rv; - if (NS_FAILED(rv = mDocument->GetNameSpaceManager(mNameSpaceManager))) { NS_ERROR("unable to get document namespace manager"); return rv; } - rv = mNameSpaceManager->RegisterNameSpace(kXULNameSpaceURI, kNameSpaceID_XUL); - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to register XUL namespace"); - + if (mFragmentRoot) { + // XUL Namespace isn't registered if we're a root document. + rv = mNameSpaceManager->RegisterNameSpace(kXULNameSpaceURI, kNameSpaceID_XUL); + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to register XUL namespace"); + } + mState = eXULContentSinkState_InProlog; return NS_OK; @@ -1146,12 +1186,21 @@ XULContentSinkImpl::OpenTag(const nsIParserNode& aNode) // container). mHaveSetRootResource = PR_TRUE; - nsCOMPtr rdfDoc; - if (NS_SUCCEEDED(mDocument->QueryInterface(nsIRDFDocument::GetIID(), - (void**) getter_AddRefs(rdfDoc)))) { - if (NS_FAILED(rv = rdfDoc->SetRootResource(rdfResource))) { - NS_ERROR("couldn't set root resource"); - return rv; + if (mFragmentRoot) { + // We're a subdocument. We need to take this fragment + // node (which is the root of the fragment) and completely + // discard it. The fragment root's resource is actually what + // should become the root of this subtree. + rdfResource = dont_QueryInterface(mFragmentRoot); + } + else { + nsCOMPtr rdfDoc; + if (NS_SUCCEEDED(mDocument->QueryInterface(nsIRDFDocument::GetIID(), + (void**) getter_AddRefs(rdfDoc)))) { + if (NS_FAILED(rv = rdfDoc->SetRootResource(rdfResource))) { + NS_ERROR("couldn't set root resource"); + return rv; + } } } }