зеркало из https://github.com/mozilla/pjs.git
Bug 415772, use XMLHttpRequest to load xml datasources, r=smaug,sr=peterv
This commit is contained in:
Родитель
47a4005ee7
Коммит
844f82285b
|
@ -158,7 +158,7 @@ interface nsIXULTemplateQueryProcessor;
|
|||
*
|
||||
* See http://wiki.mozilla.org/XUL:Templates_Plan for details about templates.
|
||||
*/
|
||||
[scriptable, uuid(fd8fe8a1-5dc3-4830-84b7-f75baccb4a9b)]
|
||||
[scriptable, uuid(1762801E-1147-4197-BF0D-D749C903AF74)]
|
||||
interface nsIXULTemplateBuilder : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -166,10 +166,24 @@ interface nsIXULTemplateBuilder : nsISupports
|
|||
*/
|
||||
readonly attribute nsIDOMElement root;
|
||||
|
||||
/**
|
||||
* The opaque datasource object that is used for the template. This object
|
||||
* is created by the getDataSource method of the query processor. May be
|
||||
* null if the datasource has not been loaded yet. Set this attribute to
|
||||
* use a different datasource and rebuild the template.
|
||||
*
|
||||
* For an RDF datasource, this will be the same as the database. For XML
|
||||
* this will be the nsIDOMNode for the datasource document or node for
|
||||
* an inline reference (such as #name). Other query processors may use
|
||||
* other types for the datasource.
|
||||
*/
|
||||
attribute nsISupports datasource;
|
||||
|
||||
/**
|
||||
* The composite datasource that the template builder observes
|
||||
* and uses to create content. This is used only for RDF queries and
|
||||
* is maintained for backwards compatibility.
|
||||
* and uses to create content. This is used only for RDF queries and is
|
||||
* maintained for backwards compatibility. It will be the same object as
|
||||
* the datasource property. For non-RDF queries, it will always be null.
|
||||
*/
|
||||
readonly attribute nsIRDFCompositeDataSource database;
|
||||
|
||||
|
|
|
@ -320,6 +320,25 @@ nsXULTemplateBuilder::GetRoot(nsIDOMElement** aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTemplateBuilder::GetDatasource(nsISupports** aResult)
|
||||
{
|
||||
if (mCompDB)
|
||||
NS_ADDREF(*aResult = mCompDB);
|
||||
else
|
||||
NS_IF_ADDREF(*aResult = mDataSource);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTemplateBuilder::SetDatasource(nsISupports* aResult)
|
||||
{
|
||||
mDataSource = aResult;
|
||||
mCompDB = do_QueryInterface(mDataSource);
|
||||
|
||||
return Rebuild();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTemplateBuilder::GetDatabase(nsIRDFCompositeDataSource** aResult)
|
||||
{
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "nsIArray.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
#include "nsXULTemplateBuilder.h"
|
||||
#include "nsXULTemplateQueryProcessorXML.h"
|
||||
|
@ -109,9 +110,11 @@ nsXULTemplateResultSetXML::GetNext(nsISupports **aResult)
|
|||
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_NSCOMPTR(mRequest)
|
||||
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_NSCOMPTR(mRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsXULTemplateQueryProcessorXML,
|
||||
nsIXULTemplateQueryProcessor)
|
||||
|
@ -123,6 +126,14 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULTemplateQueryProcessorXML)
|
|||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULTemplateQueryProcessor)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
/*
|
||||
* Only the first datasource in aDataSource is used, which should be either an
|
||||
* nsIURI of an XML document, or a DOM node. If the former, GetDatasource will
|
||||
* load the document asynchronously and return null in aResult. Once the
|
||||
* document has loaded, the builder's datasource will be set to the XML
|
||||
* document. If the datasource is a DOM node, the node will be returned in
|
||||
* aResult.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsXULTemplateQueryProcessorXML::GetDatasource(nsIArray* aDataSources,
|
||||
nsIDOMNode* aRootNode,
|
||||
|
@ -141,6 +152,22 @@ nsXULTemplateQueryProcessorXML::GetDatasource(nsIArray* aDataSources,
|
|||
if (length == 0)
|
||||
return NS_OK;
|
||||
|
||||
// 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;
|
||||
|
||||
nsCAutoString uriStr;
|
||||
rv = uri->GetSpec(uriStr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIContent> root = do_QueryInterface(aRootNode);
|
||||
if (!root)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
@ -149,52 +176,43 @@ nsXULTemplateQueryProcessorXML::GetDatasource(nsIArray* aDataSources,
|
|||
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;
|
||||
nsCOMPtr<nsIURI> uri2;
|
||||
docPrincipal->GetURI(getter_AddRefs(uri2));
|
||||
|
||||
PRBool hasHadScriptObject = PR_TRUE;
|
||||
nsIScriptGlobalObject* scriptObject =
|
||||
doc->GetScriptHandlingObject(hasHadScriptObject);
|
||||
NS_ENSURE_STATE(scriptObject || !hasHadScriptObject);
|
||||
nsAutoString emptyStr;
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
rv = nsContentUtils::CreateDocument(emptyStr, emptyStr, nsnull,
|
||||
docurl, doc->GetBaseURI(),
|
||||
docPrincipal,
|
||||
scriptObject,
|
||||
getter_AddRefs(domDocument));
|
||||
|
||||
nsIScriptContext *context = scriptObject->GetContext();
|
||||
NS_ENSURE_TRUE(context, NS_OK);
|
||||
|
||||
nsCOMPtr<nsIXMLHttpRequest> req =
|
||||
do_CreateInstance(NS_XMLHTTPREQUEST_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> owner = do_QueryInterface(scriptObject);
|
||||
req->Init(docPrincipal, context, owner);
|
||||
|
||||
rv = req->OpenRequest(NS_LITERAL_CSTRING("GET"), uriStr, PR_TRUE,
|
||||
EmptyString(), EmptyString());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(req));
|
||||
rv = target->AddEventListener(NS_LITERAL_STRING("load"), this, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = target->AddEventListener(NS_LITERAL_STRING("error"), this, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = req->Send(nsnull);
|
||||
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);
|
||||
}
|
||||
mRequest = req;
|
||||
|
||||
*aShouldDelayBuilding = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -455,20 +473,19 @@ nsXULTemplateQueryProcessorXML::HandleEvent(nsIDOMEvent* aEvent)
|
|||
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();
|
||||
NS_ASSERTION(mRequest, "request was not set");
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
if (NS_SUCCEEDED(mRequest->GetResponseXML(getter_AddRefs(doc))))
|
||||
mTemplateBuilder->SetDatasource(doc);
|
||||
|
||||
// to avoid leak. we don't need it after...
|
||||
mTemplateBuilder = nsnull;
|
||||
|
||||
return rv;
|
||||
mRequest = nsnull;
|
||||
}
|
||||
else if (eventType.EqualsLiteral("error")) {
|
||||
mTemplateBuilder = nsnull;
|
||||
mRequest = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nsIDOMXPathResult.h"
|
||||
#include "nsXMLBinding.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIXMLHttpRequest.h"
|
||||
|
||||
class nsXULTemplateQueryProcessorXML;
|
||||
|
||||
|
@ -185,6 +186,8 @@ private:
|
|||
nsCOMPtr<nsIDOMXPathEvaluator> mEvaluator;
|
||||
|
||||
nsCOMPtr<nsIXULTemplateBuilder> mTemplateBuilder;
|
||||
|
||||
nsCOMPtr<nsIXMLHttpRequest> mRequest;
|
||||
};
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче