Bug 1029104 - Convert XPathExpression to WebIDL bindings, various small fixes. r=bz.

--HG--
extra : rebase_source : 9f0422a1077e8722daaa5242d1c925ff35611b96
This commit is contained in:
Peter Van der Beken 2013-07-04 17:40:10 +02:00
parent 9f2f121898
commit dfa58aaf91
6 changed files with 74 additions and 102 deletions

View File

@ -15,24 +15,7 @@ using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(nsXMLBindingSet)
NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(nsXMLBindingSet)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLBindingSet)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXMLBindingSet)
nsXMLBinding* binding = tmp->mFirst;
while (binding) {
binding->mExpr = nullptr;
binding = binding->mNext;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXMLBindingSet)
nsXMLBinding* binding = tmp->mFirst;
while (binding) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "nsXMLBinding::mExpr");
cb.NoteXPCOMChild(binding->mExpr);
binding = binding->mNext;
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION(nsXMLBindingSet, mFirst)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsXMLBindingSet, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXMLBindingSet, Release)
@ -40,11 +23,10 @@ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXMLBindingSet, Release)
nsXMLBindingSet::~nsXMLBindingSet()
{}
nsresult
void
nsXMLBindingSet::AddBinding(nsIAtom* aVar, nsIDOMXPathExpression* aExpr)
{
nsAutoPtr<nsXMLBinding> newbinding(new nsXMLBinding(aVar, aExpr));
NS_ENSURE_TRUE(newbinding, NS_ERROR_OUT_OF_MEMORY);
if (mFirst) {
nsXMLBinding* binding = mFirst;
@ -53,12 +35,12 @@ nsXMLBindingSet::AddBinding(nsIAtom* aVar, nsIDOMXPathExpression* aExpr)
// if the target variable is already used in a binding, ignore it
// since it won't be useful for anything
if (binding->mVar == aVar)
return NS_OK;
return;
// add the binding at the end of the list
if (!binding->mNext) {
binding->mNext = newbinding;
break;
return;
}
binding = binding->mNext;
@ -67,8 +49,6 @@ nsXMLBindingSet::AddBinding(nsIAtom* aVar, nsIDOMXPathExpression* aExpr)
else {
mFirst = newbinding;
}
return NS_OK;
}
int32_t
@ -102,8 +82,7 @@ nsXMLBindingValues::GetAssignmentFor(nsXULTemplateResultXML* aResult,
return value;
}
nsCOMPtr<nsIDOMNode> contextNode;
aResult->GetNode(getter_AddRefs(contextNode));
nsCOMPtr<nsIDOMNode> contextNode = do_QueryInterface(aResult->Node());
if (!contextNode) {
return nullptr;
}
@ -119,22 +98,16 @@ nsXMLBindingValues::GetAssignmentFor(nsXULTemplateResultXML* aResult,
return mValues[aIndex];
}
void
nsINode*
nsXMLBindingValues::GetNodeAssignmentFor(nsXULTemplateResultXML* aResult,
nsXMLBinding* aBinding,
int32_t aIndex,
nsIDOMNode** aNode)
int32_t aIndex)
{
XPathResult* result = GetAssignmentFor(aResult, aBinding, aIndex,
XPathResult::FIRST_ORDERED_NODE_TYPE);
nsINode* node;
ErrorResult rv;
if (result && (node = result->GetSingleNodeValue(rv))) {
CallQueryInterface(node, aNode);
} else {
*aNode = nullptr;
}
return result ? result->GetSingleNodeValue(rv) : nullptr;
}
void

View File

@ -11,6 +11,7 @@
#include "nsCycleCollectionParticipant.h"
#include "mozilla/Attributes.h"
class nsINode;
class nsXULTemplateResultXML;
class nsXMLBindingValues;
namespace mozilla {
@ -44,6 +45,28 @@ struct nsXMLBinding {
}
};
inline void
ImplCycleCollectionUnlink(nsXMLBinding* aBinding)
{
while (aBinding) {
aBinding->mExpr = nullptr;
aBinding = aBinding->mNext;
}
}
inline void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
nsXMLBinding* aBinding,
const char* aName,
uint32_t aFlags = 0)
{
while (aBinding) {
CycleCollectionNoteChild(aCallback, aBinding->mExpr.get(),
"nsXMLBinding::mExpr", aFlags);
aBinding = aBinding->mNext;
}
}
/**
* a collection of <binding> descriptors. This object is refcounted by
* nsXMLBindingValues objects and the query processor.
@ -71,7 +94,7 @@ public:
/**
* Add a binding to the set
*/
nsresult
void
AddBinding(nsIAtom* aVar, nsIDOMXPathExpression* aExpr);
/**
@ -131,11 +154,10 @@ public:
int32_t idx,
uint16_t type);
void
nsINode*
GetNodeAssignmentFor(nsXULTemplateResultXML* aResult,
nsXMLBinding* aBinding,
int32_t idx,
nsIDOMNode** aValue);
int32_t idx);
void
GetStringAssignmentFor(nsXULTemplateResultXML* aResult,

View File

@ -21,10 +21,11 @@
#include "nsPIDOMWindow.h"
#include "nsXULContentUtils.h"
#include "nsXMLHttpRequest.h"
#include "mozilla/dom/XPathEvaluator.h"
#include "nsXULTemplateQueryProcessorXML.h"
#include "nsXULTemplateResultXML.h"
#include "nsXULSortService.h"
#include "mozilla/dom/Element.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -53,15 +54,13 @@ NS_IMETHODIMP
nsXULTemplateResultSetXML::GetNext(nsISupports **aResult)
{
ErrorResult rv;
nsCOMPtr<nsIDOMNode> node =
do_QueryInterface(mResults->SnapshotItem(mPosition, rv));
nsINode* node = mResults->SnapshotItem(mPosition, rv);
if (rv.Failed()) {
return rv.ErrorCode();
}
nsXULTemplateResultXML* result =
new nsXULTemplateResultXML(mQuery, node, mBindingSet);
NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
new nsXULTemplateResultXML(mQuery, node->AsContent(), mBindingSet);
++mPosition;
*aResult = result;
@ -217,8 +216,7 @@ nsXULTemplateQueryProcessorXML::InitializeForBuilding(nsISupports* aDatasource,
mRoot = do_QueryInterface(aDatasource);
NS_ENSURE_STATE(mRoot);
mEvaluator = do_CreateInstance("@mozilla.org/dom/xpath-evaluator;1");
NS_ENSURE_TRUE(mEvaluator, NS_ERROR_OUT_OF_MEMORY);
mEvaluator = new XPathEvaluator();
return NS_OK;
}
@ -255,7 +253,7 @@ nsXULTemplateQueryProcessorXML::CompileQuery(nsIXULTemplateBuilder* aBuilder,
expr.Assign('*');
nsCOMPtr<nsIDOMXPathExpression> compiledexpr;
rv = CreateExpression(expr, aQueryNode, getter_AddRefs(compiledexpr));
rv = CreateExpression(expr, content, getter_AddRefs(compiledexpr));
if (NS_FAILED(rv)) {
nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_XPATH);
return rv;
@ -263,7 +261,6 @@ nsXULTemplateQueryProcessorXML::CompileQuery(nsIXULTemplateBuilder* aBuilder,
nsRefPtr<nsXMLQuery> query =
new nsXMLQuery(this, aMemberVariable, compiledexpr);
NS_ENSURE_TRUE(query, NS_ERROR_OUT_OF_MEMORY);
for (nsIContent* condition = content->GetFirstChild();
condition;
@ -279,9 +276,7 @@ nsXULTemplateQueryProcessorXML::CompileQuery(nsIXULTemplateBuilder* aBuilder,
// ignore assignments without a variable or an expression
if (!var.IsEmpty() && !expr.IsEmpty()) {
nsCOMPtr<nsIDOMNode> conditionNode =
do_QueryInterface(condition);
rv = CreateExpression(expr, conditionNode,
rv = CreateExpression(expr, condition,
getter_AddRefs(compiledexpr));
if (NS_FAILED(rv)) {
nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_ASSIGN_XPATH);
@ -290,8 +285,7 @@ nsXULTemplateQueryProcessorXML::CompileQuery(nsIXULTemplateBuilder* aBuilder,
nsCOMPtr<nsIAtom> varatom = do_GetAtom(var);
rv = query->AddBinding(varatom, compiledexpr);
NS_ENSURE_SUCCESS(rv, rv);
query->AddBinding(varatom, compiledexpr);
}
}
}
@ -299,7 +293,7 @@ nsXULTemplateQueryProcessorXML::CompileQuery(nsIXULTemplateBuilder* aBuilder,
*_retval = query;
NS_ADDREF(*_retval);
return rv;
return NS_OK;
}
NS_IMETHODIMP
@ -340,7 +334,6 @@ nsXULTemplateQueryProcessorXML::GenerateResults(nsISupports* aDatasource,
nsXULTemplateResultSetXML* results =
new nsXULTemplateResultSetXML(xmlquery, exprresults,
xmlquery->GetBindingSet());
NS_ENSURE_TRUE(results, NS_ERROR_OUT_OF_MEMORY);
*aResults = results;
NS_ADDREF(*aResults);
@ -363,16 +356,18 @@ nsXULTemplateQueryProcessorXML::AddBinding(nsIDOMNode* aRuleNode,
mRuleToBindingsMap.Put(aRuleNode, bindings);
}
nsCOMPtr<nsINode> ruleNode = do_QueryInterface(aRuleNode);
nsCOMPtr<nsIDOMXPathExpression> compiledexpr;
nsresult rv =
CreateExpression(aExpr, aRuleNode, getter_AddRefs(compiledexpr));
CreateExpression(aExpr, ruleNode, getter_AddRefs(compiledexpr));
if (NS_FAILED(rv)) {
nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_BINDING_XPATH);
return NS_OK;
}
// aRef isn't currently used for XML query processors
return bindings->AddBinding(aVar, compiledexpr);
bindings->AddBinding(aVar, compiledexpr);
return NS_OK;
}
NS_IMETHODIMP
@ -383,10 +378,10 @@ nsXULTemplateQueryProcessorXML::TranslateRef(nsISupports* aDatasource,
*aRef = nullptr;
// the datasource is either a document or a DOM element
nsCOMPtr<nsIDOMElement> rootElement;
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDatasource);
nsCOMPtr<Element> rootElement;
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDatasource);
if (doc)
doc->GetDocumentElement(getter_AddRefs(rootElement));
rootElement = doc->GetRootElement();
else
rootElement = do_QueryInterface(aDatasource);
@ -396,7 +391,6 @@ nsXULTemplateQueryProcessorXML::TranslateRef(nsISupports* aDatasource,
nsXULTemplateResultXML* result =
new nsXULTemplateResultXML(nullptr, rootElement, nullptr);
NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
*aRef = result;
NS_ADDREF(*aRef);
@ -436,19 +430,14 @@ nsXULTemplateQueryProcessorXML::GetOptionalBindingsForRule(nsIDOMNode* aRuleNode
nsresult
nsXULTemplateQueryProcessorXML::CreateExpression(const nsAString& aExpr,
nsIDOMNode* aNode,
nsINode* aNode,
nsIDOMXPathExpression** aCompiledExpr)
{
nsCOMPtr<nsIDOMXPathNSResolver> nsResolver;
nsCOMPtr<nsIDOMDocument> doc;
aNode->GetOwnerDocument(getter_AddRefs(doc));
nsCOMPtr<nsIDOMXPathEvaluator> eval = do_QueryInterface(doc);
if (eval) {
nsresult rv =
eval->CreateNSResolver(aNode, getter_AddRefs(nsResolver));
NS_ENSURE_SUCCESS(rv, rv);
ErrorResult rv;
nsCOMPtr<nsIDOMXPathNSResolver> nsResolver =
aNode->OwnerDoc()->CreateNSResolver(aNode, rv);
if (rv.Failed()) {
return rv.ErrorCode();
}
return mEvaluator->CreateExpression(aExpr, nsResolver, aCompiledExpr);

View File

@ -49,15 +49,14 @@ class nsXMLQuery MOZ_FINAL : public nsISupports
nsXMLBindingSet* GetBindingSet() { return mRequiredBindings; }
// add a required binding for the query
nsresult
void
AddBinding(nsIAtom* aVar, nsIDOMXPathExpression* aExpr)
{
if (!mRequiredBindings) {
mRequiredBindings = new nsXMLBindingSet();
NS_ENSURE_TRUE(mRequiredBindings, NS_ERROR_OUT_OF_MEMORY);
}
return mRequiredBindings->AddBinding(aVar, aExpr);
mRequiredBindings->AddBinding(aVar, aExpr);
}
nsXMLQuery(nsXULTemplateQueryProcessorXML* aProcessor,
@ -145,7 +144,7 @@ public:
// resolving namespaces
nsresult
CreateExpression(const nsAString& aExpr,
nsIDOMNode* aNode,
nsINode* aNode,
nsIDOMXPathExpression** aCompiledExpr);
private:

View File

@ -18,17 +18,15 @@ static uint32_t sTemplateId = 0;
NS_IMPL_ISUPPORTS(nsXULTemplateResultXML, nsIXULTemplateResult)
nsXULTemplateResultXML::nsXULTemplateResultXML(nsXMLQuery* aQuery,
nsIDOMNode* aNode,
nsIContent* aNode,
nsXMLBindingSet* aBindings)
: mQuery(aQuery), mNode(aNode)
{
nsCOMPtr<nsIContent> content = do_QueryInterface(mNode);
// If the node has an id, create the uri from it. Otherwise, there isn't
// anything to identify the node with so just use a somewhat random number.
nsCOMPtr<nsIAtom> id = content->GetID();
nsCOMPtr<nsIAtom> id = mNode->GetID();
if (id) {
nsCOMPtr<nsIURI> uri = content->GetBaseURI();
nsCOMPtr<nsIURI> uri = mNode->GetBaseURI();
nsAutoCString spec;
uri->GetSpec(spec);
@ -52,10 +50,7 @@ NS_IMETHODIMP
nsXULTemplateResultXML::GetIsContainer(bool* aIsContainer)
{
// a node is considered a container if it has children
if (mNode)
mNode->HasChildNodes(aIsContainer);
else
*aIsContainer = false;
*aIsContainer = mNode && mNode->HasChildNodes();
return NS_OK;
}
@ -148,7 +143,7 @@ nsXULTemplateResultXML::GetBindingObjectFor(nsIAtom* aVar, nsISupports** aValue)
NS_ENSURE_ARG_POINTER(aVar);
nsXMLBinding* binding;
nsCOMPtr<nsIDOMNode> node;
nsCOMPtr<nsISupports> node;
if (mQuery && aVar == mQuery->GetMemberVariable()) {
node = mNode;
@ -156,20 +151,17 @@ nsXULTemplateResultXML::GetBindingObjectFor(nsIAtom* aVar, nsISupports** aValue)
else {
int32_t idx = mRequiredValues.LookupTargetIndex(aVar, &binding);
if (idx > 0) {
mRequiredValues.GetNodeAssignmentFor(this, binding, idx,
getter_AddRefs(node));
node = mRequiredValues.GetNodeAssignmentFor(this, binding, idx);
}
else {
idx = mOptionalValues.LookupTargetIndex(aVar, &binding);
if (idx > 0) {
mOptionalValues.GetNodeAssignmentFor(this, binding, idx,
getter_AddRefs(node));
node = mOptionalValues.GetNodeAssignmentFor(this, binding, idx);
}
}
}
*aValue = node;
NS_IF_ADDREF(*aValue);
node.forget(aValue);
return NS_OK;
}
@ -195,10 +187,3 @@ nsXULTemplateResultXML::HasBeenRemoved()
{
return NS_OK;
}
void
nsXULTemplateResultXML::GetNode(nsIDOMNode** aNode)
{
*aNode = mNode;
NS_IF_ADDREF(*aNode);
}

View File

@ -7,6 +7,7 @@
#define nsXULTemplateResultXML_h__
#include "nsCOMPtr.h"
#include "nsIContent.h"
#include "nsIURI.h"
#include "nsIRDFResource.h"
#include "nsXULTemplateQueryProcessorXML.h"
@ -24,10 +25,13 @@ public:
NS_DECL_NSIXULTEMPLATERESULT
nsXULTemplateResultXML(nsXMLQuery* aQuery,
nsIDOMNode* aNode,
nsIContent* aNode,
nsXMLBindingSet* aBindings);
void GetNode(nsIDOMNode** aNode);
nsIContent* Node()
{
return mNode;
}
protected:
@ -43,7 +47,7 @@ protected:
nsCOMPtr<nsXMLQuery> mQuery;
// context node in datasource
nsCOMPtr<nsIDOMNode> mNode;
nsCOMPtr<nsIContent> mNode;
// assignments in query
nsXMLBindingValues mRequiredValues;