Bug 321170, Templates needs to be able to load datasources other than RDF, p=laurent@xulfr.org, r=enndeakin, sr=peterv

This commit is contained in:
Olli.Pettay%helsinki.fi 2007-07-19 13:49:29 +00:00
Родитель c4b3e1d303
Коммит e4979d068b
6 изменённых файлов: 344 добавлений и 153 удалений

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

@ -19,6 +19,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Laurent Jouanneau <laurent.jouanneau@disruptive-innovations.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -38,6 +39,7 @@
#include "nsISupports.idl"
interface nsIAtom;
interface nsIArray;
interface nsISimpleEnumerator;
interface nsIXULTemplateResult;
interface nsIXULTemplateRuleFilter;
@ -105,9 +107,38 @@ interface nsIXULTemplateBuilder;
* nsIRDFDataSource or a DOM node, and will always be the same one in between
* calls to initializeForBuilding and done.
*/
[scriptable, uuid(11c63d9e-0c0c-444f-b252-f06c546c2ec7)]
[scriptable, uuid(970f1c36-5d2e-4cbc-a1cf-e3327b50df71)]
interface nsIXULTemplateQueryProcessor : nsISupports
{
/**
* Retrieve the datasource to use for the query processor. The list of
* datasources in a template is specified using the datasources attribute as
* a space separated list of URIs. This list is processed by the builder and
* supplied to the query processor in the aDataSources array as a list of
* nsIURI objects or nsIDOMNode objects. This method may return an object
* corresponding to these URIs and the builder will supply this object to
* other query processor methods. For example, for an XML source, the
* datasource might be an nsIDOMNode.
* All of these URIs are checked by the builder so it is safe to use them.
* If the query processor needs to load the datasource asynchronously, it
* may set the aShouldDelayBuilding returned parameter to true to delay
* building the template content, and call the builder's Rebuild method when
* the data is available.
*
* @param aDataSources the list of nsIURI objects and/or nsIDOMNode objects
* @param aRootNode the root node the builder is attached to
* @param aIsTrusted true if the template is in a trusted document
* @param aBuilder the template builder
* @param aShouldDelayBuilding [out] whether the builder should wait to
* build the content or not
* @returns a datasource object
*/
nsISupports getDatasource(in nsIArray aDataSources,
in nsIDOMNode aRootNode,
in boolean aIsTrusted,
in nsIXULTemplateBuilder aBuilder,
out boolean aShouldDelayBuilding);
/**
* Initialize for query generation. This will be called before the rules are
* processed and whenever the template is rebuilt. This method must be

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

@ -26,6 +26,7 @@
* Pierre Phaneuf <pp@ludusdesign.com>
* Joe Hewitt <hewitt@netscape.com>
* Neil Deakin <enndeakin@sympatico.ca>
* Laurent Jouanneau <laurent.jouanneau@disruptive-innovations.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -81,6 +82,7 @@
#include "nsIServiceManager.h"
#include "nsISimpleEnumerator.h"
#include "nsISupportsArray.h"
#include "nsIMutableArray.h"
#include "nsIURL.h"
#include "nsIXPConnect.h"
#include "nsContentCID.h"
@ -1090,6 +1092,7 @@ nsXULTemplateBuilder::ContentRemoved(nsIDocument* aDocument,
mDB = nsnull;
mCompDB = nsnull;
mRoot = nsnull;
mDataSource = nsnull;
}
}
@ -1134,7 +1137,7 @@ nsXULTemplateBuilder::LoadDataSources(nsIDocument* aDocument,
mCompDB = nsnull;
mDataSource = nsnull;
*aShouldDelayBuilding = PR_TRUE;
*aShouldDelayBuilding = PR_FALSE;
nsAutoString datasources;
mRoot->GetAttr(kNameSpaceID_None, nsGkAtoms::datasources, datasources);
@ -1142,27 +1145,6 @@ nsXULTemplateBuilder::LoadDataSources(nsIDocument* aDocument,
nsAutoString querytype;
mRoot->GetAttr(kNameSpaceID_None, nsGkAtoms::querytype, querytype);
// if the datasources begins with '#', it is a reference to a node
// within the same document.
PRBool shouldLoadUrls = PR_TRUE;
if (datasources.CharAt(0) == '#') {
shouldLoadUrls = PR_FALSE;
if (querytype.IsEmpty()) {
querytype.AssignLiteral("xml");
}
nsCOMPtr<nsIDOMDocument> domdoc = do_QueryInterface(aDocument);
nsCOMPtr<nsIDOMElement> dsnode;
domdoc->GetElementById(Substring(datasources, 1),
getter_AddRefs(dsnode));
if (dsnode) {
mDataSource = dsnode;
*aShouldDelayBuilding = PR_FALSE;
}
}
// create the query processor. The querytype attribute on the root element
// may be used to create one of a specific type.
@ -1180,8 +1162,6 @@ nsXULTemplateBuilder::LoadDataSources(nsIDocument* aDocument,
NS_ENSURE_TRUE(mQueryProcessor, NS_ERROR_OUT_OF_MEMORY);
}
else {
shouldLoadUrls = PR_FALSE;
nsCAutoString cid(NS_QUERY_PROCESSOR_CONTRACTID_PREFIX);
AppendUTF16toUTF8(querytype, cid);
mQueryProcessor = do_CreateInstance(cid.get(), &rv);
@ -1189,11 +1169,9 @@ nsXULTemplateBuilder::LoadDataSources(nsIDocument* aDocument,
NS_ENSURE_TRUE(mQueryProcessor, rv);
}
if (shouldLoadUrls) {
rv = LoadDataSourceUrls(aDocument, datasources,
isRDFQuery, aShouldDelayBuilding);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = LoadDataSourceUrls(aDocument, datasources,
isRDFQuery, aShouldDelayBuilding);
NS_ENSURE_SUCCESS(rv, rv);
// Now set the database on the element, so that script writers can
// access it.
@ -1226,49 +1204,17 @@ nsXULTemplateBuilder::LoadDataSourceUrls(nsIDocument* aDocument,
nsresult rv = IsSystemPrincipal(docPrincipal, &isTrusted);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIRDFDataSource> localstore;
if (isTrusted) {
rv = gRDFService->GetDataSource("rdf:local-store", getter_AddRefs(localstore));
NS_ENSURE_SUCCESS(rv, rv);
}
if (aIsRDFQuery) {
// create a database for the builder
mCompDB = do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX "composite-datasource");
if (! mCompDB) {
NS_ERROR("unable to construct new composite data source");
return NS_ERROR_UNEXPECTED;
}
// check for magical attributes. XXX move to ``flags''?
if (mRoot->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::coalesceduplicatearcs,
nsGkAtoms::_false, eCaseMatters))
mCompDB->SetCoalesceDuplicateArcs(PR_FALSE);
if (mRoot->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::allownegativeassertions,
nsGkAtoms::_false, eCaseMatters))
mCompDB->SetAllowNegativeAssertions(PR_FALSE);
if (localstore) {
// If we're a privileged (e.g., chrome) document, then add the
// local store as the first data source in the db. Note that
// we _might_ not be able to get a local store if we haven't
// got a profile to read from yet.
rv = mCompDB->AddDataSource(localstore);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add local store to db");
NS_ENSURE_SUCCESS(rv, 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
//
nsIURI *docurl = aDocument->GetDocumentURI();
nsCOMPtr<nsIMutableArray> uriList = do_CreateInstance(NS_ARRAY_CONTRACTID);
if (!uriList)
return NS_ERROR_FAILURE;
nsAutoString datasources(aDataSources);
PRUint32 first = 0;
while (1) {
@ -1290,18 +1236,32 @@ nsXULTemplateBuilder::LoadDataSourceUrls(nsIDocument* aDocument,
if (uriStr.EqualsLiteral("rdf:null"))
continue;
if (uriStr.CharAt(0) == '#') {
// ok, the datasource is certainly a node of the current document
nsCOMPtr<nsIDOMDocument> domdoc = do_QueryInterface(aDocument);
nsCOMPtr<nsIDOMElement> dsnode;
domdoc->GetElementById(Substring(uriStr, 1),
getter_AddRefs(dsnode));
if (dsnode)
uriList->AppendElement(dsnode, PR_FALSE);
continue;
}
// N.B. that `failure' (e.g., because it's an unknown
// protocol) leaves uriStr unaltered.
NS_MakeAbsoluteURI(uriStr, uriStr, docurl);
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), uriStr);
if (NS_FAILED(rv) || !uri)
continue; // Necko will barf if our URI is weird
nsCOMPtr<nsIPrincipal> principal;
if (!isTrusted) {
// Our document is untrusted, so check to see if we can
// load the datasource that they've asked for.
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), uriStr);
if (NS_FAILED(rv) || !uri)
continue; // Necko will barf if our URI is weird
rv = gScriptSecurityManager->GetCodebasePrincipal(uri, getter_AddRefs(principal));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get codebase principal");
@ -1320,90 +1280,42 @@ nsXULTemplateBuilder::LoadDataSourceUrls(nsIDocument* aDocument,
// document. Let it load!
}
if (aIsRDFQuery) {
nsCOMPtr<nsIRDFDataSource> ds;
nsCAutoString uristrC;
uristrC.AssignWithConversion(uriStr);
rv = gRDFService->GetDataSource(uristrC.get(), getter_AddRefs(ds));
if (NS_FAILED(rv)) {
// This is only a warning because the data source may not
// be accessible for any number of reasons, including
// security, a bad URL, etc.
#ifdef DEBUG
nsCAutoString msg;
msg.Append("unable to load datasource '");
msg.AppendWithConversion(uriStr);
msg.Append('\'');
NS_WARNING(msg.get());
#endif
continue;
}
mCompDB->AddDataSource(ds);
}
else {
nsAutoString emptyStr;
nsCOMPtr<nsIDOMDocument> domDocument;
rv = nsContentUtils::CreateDocument(emptyStr, emptyStr, nsnull,
docurl, aDocument->GetBaseURI(),
docPrincipal,
getter_AddRefs(domDocument));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(domDocument);
target->AddEventListener(NS_LITERAL_STRING("load"), this, PR_FALSE);
nsCOMPtr<nsIDOMXMLDocument> xmldoc = do_QueryInterface(domDocument);
PRBool ok;
xmldoc->Load(uriStr, &ok);
if (ok) {
mDataSource = domDocument;
*aShouldDelayBuilding = PR_TRUE;
}
// only one XML datasource is supported currently
break;
}
uriList->AppendElement(uri, PR_FALSE);
}
if (aIsRDFQuery) {
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(mRoot);
rv = mQueryProcessor->GetDatasource(uriList,
rootNode,
isTrusted,
this,
aShouldDelayBuilding,
getter_AddRefs(mDataSource));
NS_ENSURE_SUCCESS(rv, rv);
if (aIsRDFQuery && mDataSource) {
// check if we were given an inference engine type
nsAutoString infer;
mRoot->GetAttr(kNameSpaceID_None, nsGkAtoms::infer, infer);
if (!infer.IsEmpty()) {
nsCString inferCID(NS_RDF_INFER_DATASOURCE_CONTRACTID_PREFIX);
AppendUTF16toUTF8(infer, inferCID);
nsCOMPtr<nsIRDFInferDataSource> inferDB =
do_CreateInstance(inferCID.get());
if (inferDB) {
inferDB->SetBaseDataSource(mCompDB);
mDB = do_QueryInterface(inferDB);
} else {
NS_WARNING("failed to construct inference engine specified on template");
}
nsCOMPtr<nsIRDFInferDataSource> inferDB = do_QueryInterface(mDataSource);
if (inferDB) {
nsCOMPtr<nsIRDFDataSource> ds;
inferDB->GetBaseDataSource(getter_AddRefs(ds));
if (ds)
mCompDB = do_QueryInterface(ds);
}
if (!mDB)
mDB = mCompDB;
mDataSource = mDB;
if (!mCompDB)
mCompDB = do_QueryInterface(mDataSource);
mDB = do_QueryInterface(mDataSource);
}
else {
mDB = localstore;
if (!mDB && isTrusted) {
gRDFService->GetDataSource("rdf:local-store", getter_AddRefs(mDB));
}
return NS_OK;
}
NS_IMETHODIMP
nsXULTemplateBuilder::HandleEvent(nsIDOMEvent* aEvent)
{
return Rebuild();
}
nsresult
nsXULTemplateBuilder::InitHTMLTemplateRoot()
{

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

@ -53,7 +53,6 @@
#include "nsIRDFObserver.h"
#include "nsIRDFService.h"
#include "nsIXULTemplateBuilder.h"
#include "nsIDOMEventListener.h"
#include "nsFixedSizeAllocator.h"
#include "nsVoidArray.h"
@ -78,7 +77,6 @@ class nsIRDFCompositeDataSource;
* set of rules.
*/
class nsXULTemplateBuilder : public nsIXULTemplateBuilder,
public nsIDOMEventListener,
public nsStubDocumentObserver
{
public:
@ -101,8 +99,6 @@ public:
// nsIXULTemplateBuilder interface
NS_DECL_NSIXULTEMPLATEBUILDER
NS_DECL_NSIDOMEVENTLISTENER
// nsIMutationObserver
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED

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

@ -26,6 +26,7 @@
* Pierre Phaneuf <pp@ludusdesign.com>
* Joe Hewitt <hewitt@netscape.com>
* Neil Deakin <enndeakin@sympatico.ca>
* Laurent Jouanneau <laurent.jouanneau@disruptive-innovations.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -46,6 +47,7 @@
#include "nsIRDFNode.h"
#include "nsIRDFObserver.h"
#include "nsIRDFRemoteDataSource.h"
#include "nsIRDFInferDataSource.h"
#include "nsIRDFService.h"
#include "nsRDFCID.h"
#include "nsIServiceManager.h"
@ -56,6 +58,7 @@
#include "nsUnicharUtils.h"
#include "nsAttrName.h"
#include "rdf.h"
#include "nsArrayUtils.h"
#include "nsContentTestNode.h"
#include "nsRDFConInstanceTestNode.h"
@ -215,6 +218,119 @@ nsXULTemplateQueryProcessorRDF::InitGlobals()
// nsIXULTemplateQueryProcessor interface
//
NS_IMETHODIMP
nsXULTemplateQueryProcessorRDF::GetDatasource(nsIArray* aDataSources,
nsIDOMNode* aRootNode,
PRBool aIsTrusted,
nsIXULTemplateBuilder* aBuilder,
PRBool* aShouldDelayBuilding,
nsISupports** aResult)
{
nsCOMPtr<nsIRDFCompositeDataSource> compDB;
nsCOMPtr<nsIContent> root = do_QueryInterface(aRootNode);
nsresult rv;
*aResult = nsnull;
*aShouldDelayBuilding = PR_FALSE;
NS_ENSURE_TRUE(root, NS_ERROR_UNEXPECTED);
// make sure the RDF service is set up
rv = InitGlobals();
NS_ENSURE_SUCCESS(rv, rv);
// create a database for the builder
compDB = do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX
"composite-datasource");
if (!compDB) {
NS_ERROR("unable to construct new composite data source");
return NS_ERROR_UNEXPECTED;
}
// check for magical attributes. XXX move to ``flags''?
if (root->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::coalesceduplicatearcs,
nsGkAtoms::_false, eCaseMatters))
compDB->SetCoalesceDuplicateArcs(PR_FALSE);
if (root->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::allownegativeassertions,
nsGkAtoms::_false, eCaseMatters))
compDB->SetAllowNegativeAssertions(PR_FALSE);
if (aIsTrusted) {
// If we're a privileged (e.g., chrome) document, then add the
// local store as the first data source in the db. Note that
// we _might_ not be able to get a local store if we haven't
// got a profile to read from yet.
nsCOMPtr<nsIRDFDataSource> localstore;
rv = gRDFService->GetDataSource("rdf:local-store",
getter_AddRefs(localstore));
NS_ENSURE_SUCCESS(rv, rv);
rv = compDB->AddDataSource(localstore);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add local store to db");
NS_ENSURE_SUCCESS(rv, rv);
}
PRUint32 length, index;
rv = aDataSources->GetLength(&length);
NS_ENSURE_SUCCESS(rv,rv);
for (index = 0; index < length; index++) {
nsCOMPtr<nsIURI> uri = do_QueryElementAt(aDataSources, index);
if (!uri) // we ignore other datasources than uri
continue;
nsCOMPtr<nsIRDFDataSource> ds;
nsCAutoString uristrC;
uri->GetSpec(uristrC);
rv = gRDFService->GetDataSource(uristrC.get(), getter_AddRefs(ds));
if (NS_FAILED(rv)) {
// This is only a warning because the data source may not
// be accessible for any number of reasons, including
// security, a bad URL, etc.
#ifdef DEBUG
nsCAutoString msg;
msg.Append("unable to load datasource '");
msg.Append(uristrC);
msg.Append('\'');
NS_WARNING(msg.get());
#endif
continue;
}
compDB->AddDataSource(ds);
}
// check if we were given an inference engine type
nsAutoString infer;
nsCOMPtr<nsIRDFDataSource> db;
root->GetAttr(kNameSpaceID_None, nsGkAtoms::infer, infer);
if (!infer.IsEmpty()) {
nsCString inferCID(NS_RDF_INFER_DATASOURCE_CONTRACTID_PREFIX);
AppendUTF16toUTF8(infer, inferCID);
nsCOMPtr<nsIRDFInferDataSource> inferDB =
do_CreateInstance(inferCID.get());
if (inferDB) {
inferDB->SetBaseDataSource(compDB);
db = do_QueryInterface(inferDB);
}
else {
NS_WARNING("failed to construct inference engine specified on template");
}
}
if (!db)
db = compDB;
return CallQueryInterface(db, aResult);
}
NS_IMETHODIMP
nsXULTemplateQueryProcessorRDF::InitializeForBuilding(nsISupports* aDatasource,

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

@ -19,6 +19,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Laurent Jouanneau <laurent.jouanneau@disruptive-innovations.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -37,14 +38,23 @@
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsIDOMDocument.h"
#include "nsIDOMXMLDocument.h"
#include "nsIDOMNode.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMElement.h"
#include "nsIDOMEvent.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMXPathNSResolver.h"
#include "nsIDocument.h"
#include "nsIContent.h"
#include "nsINameSpaceManager.h"
#include "nsGkAtoms.h"
#include "nsIServiceManager.h"
#include "nsUnicharUtils.h"
#include "nsIURI.h"
#include "nsIArray.h"
#include "nsContentUtils.h"
#include "nsArrayUtils.h"
#include "nsXULTemplateBuilder.h"
#include "nsXULTemplateQueryProcessorXML.h"
@ -96,13 +106,101 @@ nsXULTemplateResultSetXML::GetNext(nsISupports **aResult)
// nsXULTemplateQueryProcessorXML
//
NS_IMPL_ISUPPORTS1(nsXULTemplateQueryProcessorXML, nsIXULTemplateQueryProcessor)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTemplateQueryProcessorXML)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULTemplateQueryProcessorXML)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTemplateBuilder)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULTemplateQueryProcessorXML)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTemplateBuilder)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsXULTemplateQueryProcessorXML,
nsIXULTemplateQueryProcessor)
NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsXULTemplateQueryProcessorXML,
nsIXULTemplateQueryProcessor)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULTemplateQueryProcessorXML)
NS_INTERFACE_MAP_ENTRY(nsIXULTemplateQueryProcessor)
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULTemplateQueryProcessor)
NS_INTERFACE_MAP_END
NS_IMETHODIMP
nsXULTemplateQueryProcessorXML::GetDatasource(nsIArray* aDataSources,
nsIDOMNode* aRootNode,
PRBool aIsTrusted,
nsIXULTemplateBuilder* aBuilder,
PRBool* aShouldDelayBuilding,
nsISupports** aResult)
{
*aResult = nsnull;
*aShouldDelayBuilding = PR_FALSE;
nsresult rv;
PRUint32 length;
aDataSources->GetLength(&length);
if (length == 0)
return NS_OK;
nsCOMPtr<nsIContent> root = do_QueryInterface(aRootNode);
if (!root)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIDocument> doc = root->GetCurrentDoc();
if (!doc)
return NS_ERROR_UNEXPECTED;
nsIURI *docurl = doc->GetDocumentURI();
nsIPrincipal *docPrincipal = doc->NodePrincipal();
// we get only the first item, because the query processor supports only
// one document as a datasource
nsCOMPtr<nsIDOMNode> node = do_QueryElementAt(aDataSources, 0);
if (node) {
return CallQueryInterface(node, aResult);
}
nsCOMPtr<nsIURI> uri = do_QueryElementAt(aDataSources,0);
if (!uri)
return NS_ERROR_UNEXPECTED;
nsAutoString emptyStr;
nsCOMPtr<nsIDOMDocument> domDocument;
rv = nsContentUtils::CreateDocument(emptyStr, emptyStr, nsnull,
docurl, doc->GetBaseURI(),
docPrincipal,
getter_AddRefs(domDocument));
NS_ENSURE_SUCCESS(rv, rv);
mTemplateBuilder = aBuilder;
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(domDocument);
target->AddEventListener(NS_LITERAL_STRING("load"), this, PR_FALSE);
nsCOMPtr<nsIDOMXMLDocument> xmldoc = do_QueryInterface(domDocument);
PRBool ok;
nsCAutoString uristrC;
uri->GetSpec(uristrC);
xmldoc->Load(NS_ConvertUTF8toUTF16(uristrC), &ok);
if (ok) {
*aShouldDelayBuilding = PR_TRUE;
return CallQueryInterface(domDocument, aResult);
}
return NS_OK;
}
NS_IMETHODIMP
nsXULTemplateQueryProcessorXML::InitializeForBuilding(nsISupports* aDatasource,
nsIXULTemplateBuilder* aBuilder,
nsIDOMNode* aRootNode)
{
if (mGenerationStarted)
return NS_ERROR_UNEXPECTED;
// the datasource is either a document or a DOM element
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDatasource);
if (doc)
@ -343,3 +441,29 @@ nsXULTemplateQueryProcessorXML::CreateExpression(const nsAString& aExpr,
return mEvaluator->CreateExpression(aExpr, nsResolver, aCompiledExpr);
}
NS_IMETHODIMP
nsXULTemplateQueryProcessorXML::HandleEvent(nsIDOMEvent* aEvent)
{
NS_PRECONDITION(aEvent, "aEvent null");
nsAutoString eventType;
aEvent->GetType(eventType);
if (eventType.EqualsLiteral("load") && mTemplateBuilder) {
// remove the listener
nsCOMPtr<nsIDOMEventTarget> target;
aEvent->GetTarget(getter_AddRefs(target));
if (target) {
target->RemoveEventListener(NS_LITERAL_STRING("load"), this, PR_FALSE);
}
// rebuild the template
nsresult rv = mTemplateBuilder->Rebuild();
// to avoid leak. we don't need it after...
mTemplateBuilder = nsnull;
return rv;
}
return NS_OK;
}

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

@ -19,6 +19,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Laurent Jouanneau <laurent.jouanneau@disruptive-innovations.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -37,6 +38,7 @@
#ifndef nsXULTemplateQueryProcessorXML_h__
#define nsXULTemplateQueryProcessorXML_h__
#include "nsIXULTemplateBuilder.h"
#include "nsIXULTemplateQueryProcessor.h"
#include "nsISimpleEnumerator.h"
@ -44,10 +46,12 @@
#include "nsCOMArray.h"
#include "nsRefPtrHashtable.h"
#include "nsIDOMElement.h"
#include "nsIDOMEventListener.h"
#include "nsIDOMXPathExpression.h"
#include "nsIDOMXPathEvaluator.h"
#include "nsIDOMXPathResult.h"
#include "nsXMLBinding.h"
#include "nsCycleCollectionParticipant.h"
class nsXULTemplateQueryProcessorXML;
@ -140,7 +144,8 @@ public:
{}
};
class nsXULTemplateQueryProcessorXML : public nsIXULTemplateQueryProcessor
class nsXULTemplateQueryProcessorXML : public nsIXULTemplateQueryProcessor,
public nsIDOMEventListener
{
public:
@ -149,11 +154,16 @@ public:
{}
// nsISupports interface
NS_DECL_ISUPPORTS
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULTemplateQueryProcessorXML,
nsIXULTemplateQueryProcessor)
// nsIXULTemplateQueryProcessor interface
NS_DECL_NSIXULTEMPLATEQUERYPROCESSOR
// nsIDOMEventListener interface
NS_DECL_NSIDOMEVENTLISTENER
nsXMLBindingSet*
GetOptionalBindingsForRule(nsIDOMNode* aRuleNode);
@ -173,6 +183,8 @@ private:
nsCOMPtr<nsIDOMElement> mRoot;
nsCOMPtr<nsIDOMXPathEvaluator> mEvaluator;
nsCOMPtr<nsIXULTemplateBuilder> mTemplateBuilder;
};