зеркало из https://github.com/mozilla/pjs.git
[XForms] XPath expression errors when expr spans mult instances. Bug 348993, r=doronr+olli
This commit is contained in:
Родитель
fc5f3cdea2
Коммит
6e115f0df7
|
@ -2310,20 +2310,6 @@ nsXFormsModelElement::ProcessBind(nsIDOMXPathEvaluator *aEvaluator,
|
|||
sModelPropsList[i]->ToString(attrStr);
|
||||
|
||||
aBindElement->GetAttribute(attrStr, propStrings[i]);
|
||||
if (!propStrings[i].IsEmpty() &&
|
||||
i != eModel_type &&
|
||||
i != eModel_p3ptype) {
|
||||
rv = nsXFormsUtils::CreateExpression(eval, propStrings[i], resolver,
|
||||
aBindElement,
|
||||
getter_AddRefs(props[i]));
|
||||
if (NS_FAILED(rv)) {
|
||||
const PRUnichar *strings[] = { propStrings[i].get() };
|
||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("mipParseError"),
|
||||
strings, 1, aBindElement, aBindElement);
|
||||
nsXFormsUtils::DispatchEvent(mElement, eEvent_ComputeException);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the nodeset that this bind applies to.
|
||||
|
@ -2382,16 +2368,47 @@ nsXFormsModelElement::ProcessBind(nsIDOMXPathEvaluator *aEvaluator,
|
|||
// Iterate over resultset
|
||||
nsCOMArray<nsIDOMNode> deps;
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
PRUint32 snapItem;
|
||||
for (snapItem = 0; snapItem < snapLen; ++snapItem) {
|
||||
|
||||
if (!snapLen) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We rightly assume that all the nodes in the nodeset came from the same
|
||||
// document. So now we'll get the xpath evaluator from that document. We
|
||||
// need to ensure that the context node for the evaluation of each MIP
|
||||
// expression and the evaluator for those expressions came from the same
|
||||
// document. It is a rule for xpath.
|
||||
PRUint32 snapItem = 0;
|
||||
|
||||
for (; snapItem < snapLen; ++snapItem) {
|
||||
rv = result->SnapshotItem(snapItem, getter_AddRefs(node));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!node) {
|
||||
|
||||
if (node){
|
||||
break;
|
||||
} else {
|
||||
NS_WARNING("nsXFormsModelElement::ProcessBind(): Empty node in result set.");
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!node) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> nodesetDoc;
|
||||
node->GetOwnerDocument(getter_AddRefs(nodesetDoc));
|
||||
|
||||
nsCOMPtr<nsIDOMXPathEvaluator> nodesetEval = do_QueryInterface(nodesetDoc);
|
||||
nsCOMPtr<nsIXPathEvaluatorInternal> nodesetEvalInternal =
|
||||
do_QueryInterface(nodesetEval);
|
||||
NS_ENSURE_STATE(nodesetEval && nodesetEvalInternal);
|
||||
|
||||
// Since we've already gotten the first node in the nodeset and verified it is
|
||||
// good to go, we'll contine on. For this node and each subsequent node in
|
||||
// the nodeset, we'll evaluate the MIP expressions attached to the bind
|
||||
// element and add them to the MDG. And also process any binds that this
|
||||
// bind contains (aka nested binds).
|
||||
while (node && snapItem < snapLen) {
|
||||
|
||||
// Apply MIPs
|
||||
nsXFormsXPathParser parser;
|
||||
|
@ -2429,6 +2446,19 @@ nsXFormsModelElement::ProcessBind(nsIDOMXPathEvaluator *aEvaluator,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
} else {
|
||||
|
||||
rv = nsXFormsUtils::CreateExpression(nodesetEvalInternal,
|
||||
propStrings[j], resolver,
|
||||
aBindElement,
|
||||
getter_AddRefs(props[j]));
|
||||
if (NS_FAILED(rv)) {
|
||||
const PRUnichar *strings[] = { propStrings[j].get() };
|
||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("mipParseError"),
|
||||
strings, 1, aBindElement, aBindElement);
|
||||
nsXFormsUtils::DispatchEvent(mElement, eEvent_ComputeException);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// the rest of the MIPs are given to the MDG
|
||||
nsCOMPtr<nsIDOMNSXPathExpression> expr = do_QueryInterface(props[j]);
|
||||
|
||||
|
@ -2501,6 +2531,19 @@ nsXFormsModelElement::ProcessBind(nsIDOMXPathEvaluator *aEvaluator,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
++snapItem;
|
||||
while (snapItem < snapLen) {
|
||||
rv = result->SnapshotItem(snapItem, getter_AddRefs(node));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (node) {
|
||||
break;
|
||||
}
|
||||
|
||||
NS_WARNING("nsXFormsModelElement::ProcessBind(): Empty node in result set.");
|
||||
snapItem++;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -439,6 +439,8 @@ nsXFormsUtils::CreateExpression(nsIXPathEvaluatorInternal *aEvaluator,
|
|||
contractid.AppendCString(NS_LITERAL_CSTRING("@mozilla.org/xforms-xpath-functions;1"));
|
||||
state.AppendObject(aState);
|
||||
|
||||
// if somehow the contextNode and the evaluator weren't spawned from the same
|
||||
// document, this could fail with NS_ERROR_DOM_WRONG_DOCUMENT_ERR
|
||||
nsCOMPtr<nsIDOMXPathExpression> expression;
|
||||
return aEvaluator->CreateExpression(aExpression, aResolver, &ns, &contractid,
|
||||
&state, aResult);
|
||||
|
@ -561,6 +563,8 @@ nsXFormsUtils::EvaluateXPath(nsIXPathEvaluatorInternal *aEvaluator,
|
|||
do_QueryInterface(expression, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// if somehow the contextNode and the evaluator weren't spawned from the same
|
||||
// document, this could fail with NS_ERROR_DOM_WRONG_DOCUMENT_ERR
|
||||
nsCOMPtr<nsISupports> supResult;
|
||||
rv = nsExpression->EvaluateWithContext(aContextNode, aContextPosition,
|
||||
aContextSize, aResultType,
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
#include "nsXFormsXPathAnalyzer.h"
|
||||
#include "nsIDOMXPathResult.h"
|
||||
#include "nsXFormsUtils.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMXPathEvaluator.h"
|
||||
#include "nsIXPathEvaluatorInternal.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
//#define DEBUG_XF_ANALYZER
|
||||
|
@ -177,7 +180,20 @@ nsXFormsXPathAnalyzer::AnalyzeRecursively(nsIDOMNode *aContextNode,
|
|||
xp = Substring(*mCurExprString, aNode->mStartIndex,
|
||||
aNode->mEndIndex - aNode->mStartIndex);
|
||||
}
|
||||
rv = nsXFormsUtils::EvaluateXPath(mEvaluator, xp, aContextNode, mResolver,
|
||||
|
||||
// It is an error to use an evaluator from a different document than the
|
||||
// context node. The context node can change as we recurse and be
|
||||
// from an different instance document than the context node we used to
|
||||
// kick off the evaluation. More efficient to just get the evaluator every
|
||||
// time we recurse rather than caching it and testing.
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
aContextNode->GetOwnerDocument(getter_AddRefs(doc));
|
||||
nsCOMPtr<nsIDOMXPathEvaluator> eval = do_QueryInterface(doc);
|
||||
nsCOMPtr<nsIXPathEvaluatorInternal> evalInternal = do_QueryInterface(eval);
|
||||
NS_ENSURE_STATE(evalInternal);
|
||||
|
||||
rv = nsXFormsUtils::EvaluateXPath(evalInternal, xp, aContextNode, mResolver,
|
||||
mState, nsIDOMXPathResult::ANY_TYPE,
|
||||
mCurPosition, mCurSize, nsnull,
|
||||
getter_AddRefs(result));
|
||||
|
@ -200,7 +216,7 @@ nsXFormsXPathAnalyzer::AnalyzeRecursively(nsIDOMNode *aContextNode,
|
|||
xp.Length() - indexSize - 1); // remove final ')' too
|
||||
|
||||
nsCOMPtr<nsIDOMXPathResult> stringRes;
|
||||
rv = nsXFormsUtils::EvaluateXPath(mEvaluator, indexExpr, aContextNode,
|
||||
rv = nsXFormsUtils::EvaluateXPath(evalInternal, indexExpr, aContextNode,
|
||||
mResolver, mState,
|
||||
nsIDOMXPathResult::STRING_TYPE,
|
||||
mCurPosition, mCurSize, nsnull,
|
||||
|
|
Загрузка…
Ссылка в новой задаче