Use size and position in XPath expressions. Bug 265460, r=smaug+doronr, a=mkaply

This commit is contained in:
allan%beaufour.dk 2005-06-02 07:00:11 +00:00
parent f4dd6c43ce
commit 9e16b8b19a
11 changed files with 153 additions and 104 deletions

View File

@ -58,10 +58,16 @@ interface nsIXFormsContextControl : nsISupports
* @note The actual model ID must be returned. An empty |aModelID| should
* only be returned if the default model has an id="".
*/
void getContext(out AString aModelID, out nsIDOMNode aContextNode, out long aContextPosition, out long aContextSize);
void getContext(out AString aModelID, out nsIDOMNode aContextNode,
out long aContextPosition, out long aContextSize);
/**
* Used by parents to set the context node for children.
* Used by parents to set the context for children.
*
* @param aContextNode The context node
* @param aContextPosition The context position
* @param aContextSize The context size
*/
void setContextNode(in nsIDOMNode aContextNode);
void setContext(in nsIDOMNode aContextNode, in long aContextPosition,
in long aContextSize);
};

View File

@ -78,7 +78,16 @@ protected:
/** The HTML representation for the node */
nsCOMPtr<nsIDOMElement> mHTMLElement;
/** The context position for the element */
PRInt32 mContextPosition;
/** The context size for the element */
PRInt32 mContextSize;
public:
nsXFormsContextContainer()
: mContextPosition(1), mContextSize(1) {}
NS_DECL_ISUPPORTS_INHERITED
// nsIXTFXMLVisual overrides
@ -96,7 +105,13 @@ public:
// nsIXFormsControl
NS_IMETHOD Bind();
NS_IMETHOD Refresh();
NS_IMETHOD SetContextNode(nsIDOMNode *aContextNode);
NS_IMETHOD SetContext(nsIDOMNode *aContextNode,
PRInt32 aContextPosition,
PRInt32 aContextSize);
NS_IMETHOD GetContext(nsAString &aModelID,
nsIDOMNode **aContextNode,
PRInt32 *aContextPosition,
PRInt32 *aContextSize);
NS_IMETHOD IsEventTarget(PRBool *aOK);
// nsIXFormsRepeatItemElement
@ -242,9 +257,13 @@ nsXFormsContextContainer::CloneState(nsIDOMElement *aElement)
// nsIXFormsContextControl
NS_IMETHODIMP
nsXFormsContextContainer::SetContextNode(nsIDOMNode *aContextNode)
nsXFormsContextContainer::SetContext(nsIDOMNode *aContextNode,
PRInt32 aContextPosition,
PRInt32 aContextSize)
{
mBoundNode = aContextNode;
mContextPosition = aContextPosition;
mContextSize = aContextSize;
// Remove from old model (if any)
if (mModel) {
@ -261,6 +280,24 @@ nsXFormsContextContainer::SetContextNode(nsIDOMNode *aContextNode)
return NS_OK;
}
NS_IMETHODIMP
nsXFormsContextContainer::GetContext(nsAString &aModelID,
nsIDOMNode **aContextNode,
PRInt32 *aContextPosition,
PRInt32 *aContextSize)
{
nsresult rv = nsXFormsControlStub::GetContext(aModelID,
aContextNode,
aContextPosition,
aContextSize);
NS_ENSURE_SUCCESS(rv, rv);
*aContextPosition = mContextPosition;
*aContextSize = mContextSize;
return NS_OK;
}
// nsIXFormsControl
NS_IMETHODIMP

View File

@ -412,7 +412,9 @@ nsXFormsControlStubBase::AttributeRemoved(nsIAtom *aName)
// nsIXFormsContextControl
NS_IMETHODIMP
nsXFormsControlStubBase::SetContextNode(nsIDOMNode *aContextNode)
nsXFormsControlStubBase::SetContext(nsIDOMNode *aContextNode,
PRInt32 aContextPosition,
PRInt32 aContextSize)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -361,7 +361,7 @@ nsXFormsItemElement::Refresh()
container->SetAttribute(modelStr, modelID);
nsCOMPtr<nsIXFormsContextControl> context = do_QueryInterface(container);
context->SetContextNode(mContextNode);
context->SetContext(mContextNode, 1, 1);
for (PRUint32 i = 0; i < childCount; ++i) {
children->Item(i, getter_AddRefs(child));

View File

@ -42,7 +42,7 @@
#include "nsIDOMDocument.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMText.h"
#include "nsIDOMXPathExpression.h"
#include "nsIDOMNSXPathExpression.h"
#include "nsIDOMXPathResult.h"
#include "nsDeque.h"
#include "nsIModelElementPrivate.h"
@ -80,10 +80,10 @@ nsXFormsMDGNode::~nsXFormsMDGNode()
}
void
nsXFormsMDGNode::SetExpression(nsIDOMXPathExpression *aExpression,
PRBool aDynFunc,
PRInt32 aContextPosition,
PRInt32 aContextSize)
nsXFormsMDGNode::SetExpression(nsIDOMNSXPathExpression *aExpression,
PRBool aDynFunc,
PRInt32 aContextPosition,
PRInt32 aContextSize)
{
mHasExpr = PR_TRUE;
mDynFunc = aDynFunc;
@ -150,13 +150,13 @@ nsXFormsMDGEngine::Init(nsIModelElementPrivate *aModel)
}
nsresult
nsXFormsMDGEngine::AddMIP(ModelItemPropName aType,
nsIDOMXPathExpression *aExpression,
nsCOMArray<nsIDOMNode> *aDependencies,
PRBool aDynFunc,
nsIDOMNode *aContextNode,
PRInt32 aContextPos,
PRInt32 aContextSize)
nsXFormsMDGEngine::AddMIP(ModelItemPropName aType,
nsIDOMNSXPathExpression *aExpression,
nsCOMArray<nsIDOMNode> *aDependencies,
PRBool aDynFunc,
nsIDOMNode *aContextNode,
PRInt32 aContextPos,
PRInt32 aContextSize)
{
NS_ENSURE_ARG(aContextNode);
@ -353,15 +353,15 @@ nsXFormsMDGEngine::Recalculate(nsCOMArray<nsIDOMNode> *aChangedNodes)
switch (g->mType) {
case eModel_calculate:
if (g->HasExpr()) {
nsISupports* retval;
rv = g->mExpression->Evaluate(g->mContextNode,
nsIDOMXPathResult::STRING_TYPE,
nsnull,
&retval);
nsCOMPtr<nsIDOMXPathResult> xpath_res;
rv = g->mExpression->EvaluateWithContext(g->mContextNode,
g->mContextPosition,
g->mContextSize,
nsIDOMXPathResult::STRING_TYPE,
nsnull,
getter_AddRefs(xpath_res));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMXPathResult> xpath_res = do_QueryInterface(retval);
NS_ENSURE_TRUE(xpath_res, NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_STATE(xpath_res);
nsAutoString nodeval;
rv = xpath_res->GetStringValue(nodeval);
@ -920,15 +920,15 @@ nsXFormsMDGEngine::BooleanExpression(nsXFormsMDGNode* aNode, PRBool& state)
NS_ENSURE_ARG_POINTER(aNode);
NS_ENSURE_TRUE(aNode->mExpression, NS_ERROR_FAILURE);
/// @todo Use aNode->contextPosition and aNode->contextSize (XXX)
/// @see https://bugzilla.mozilla.org/show_bug.cgi?id=265460
nsISupports* retval;
nsresult rv;
rv = aNode->mExpression->Evaluate(aNode->mContextNode,
nsIDOMXPathResult::BOOLEAN_TYPE,
nsnull,
&retval);
rv = aNode->mExpression->EvaluateWithContext(aNode->mContextNode,
aNode->mContextPosition,
aNode->mContextSize,
nsIDOMXPathResult::BOOLEAN_TYPE,
nsnull,
&retval);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMXPathResult> xpath_res = do_QueryInterface(retval);

View File

@ -52,7 +52,7 @@
#include "nsXFormsNodeState.h"
#include "nsIModelElementPrivate.h"
class nsIDOMXPathExpression;
class nsIDOMNSXPathExpression;
/**
* Data structure for nodes in the graph.
@ -73,7 +73,7 @@ public:
nsCOMPtr<nsIDOMNode> mContextNode;
/** The XPath expression for this node */
nsCOMPtr<nsIDOMXPathExpression> mExpression;
nsCOMPtr<nsIDOMNSXPathExpression> mExpression;
/** List of nodes that depend on this node */
nsVoidArray mSuc;
@ -119,10 +119,10 @@ public:
* @param aContextPosition The context position for the expression
* @param aContextSize The context size for the expression
*/
void SetExpression(nsIDOMXPathExpression *aExpression,
PRBool aDynFunc,
PRInt32 aContextPosition,
PRInt32 aContextSize);
void SetExpression(nsIDOMNSXPathExpression *aExpression,
PRBool aDynFunc,
PRInt32 aContextPosition,
PRInt32 aContextSize);
/** Does node have an expression? */
PRBool HasExpr() const;
@ -355,13 +355,13 @@ public:
* @param aContextPos The context positions of aExpression
* @param aContextSize The context size for aExpression
*/
nsresult AddMIP(ModelItemPropName aType,
nsIDOMXPathExpression *aExpression,
nsCOMArray<nsIDOMNode> *aDependencies,
PRBool aDynFunc,
nsIDOMNode *aContextNode,
PRInt32 aContextPos,
PRInt32 aContextSize);
nsresult AddMIP(ModelItemPropName aType,
nsIDOMNSXPathExpression *aExpression,
nsCOMArray<nsIDOMNode> *aDependencies,
PRBool aDynFunc,
nsIDOMNode *aContextNode,
PRInt32 aContextPos,
PRInt32 aContextSize);
/**
* Recalculate the MDG.

View File

@ -57,7 +57,7 @@
#include "nsIDOMXPathResult.h"
#include "nsIXFormsXPathEvaluator.h"
#include "nsIDOMXPathNSResolver.h"
#include "nsIDOMXPathExpression.h"
#include "nsIDOMNSXPathExpression.h"
#include "nsIScriptGlobalObject.h"
#include "nsIContent.h"
#include "nsIURL.h"
@ -1285,12 +1285,12 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
nsIDOMElement *aBindElement)
{
// Get the model item properties specified by this \<bind\>.
nsCOMPtr<nsIDOMXPathExpression> props[eModel__count];
nsCOMPtr<nsIDOMNSXPathExpression> props[eModel__count];
nsAutoString propStrings[eModel__count];
nsresult rv;
nsAutoString attrStr;
for (int i = 0; i < eModel__count; ++i) {
for (PRUint32 i = 0; i < eModel__count; ++i) {
sModelPropsList[i]->ToString(attrStr);
aBindElement->GetAttribute(attrStr, propStrings[i]);
@ -1317,9 +1317,8 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
if (expr.IsEmpty()) {
expr = NS_LITERAL_STRING(".");
}
///
/// @todo use aContextSize and aContextPosition in evaluation (XXX)
rv = aEvaluator->Evaluate(expr, aContextNode, aBindElement,
rv = aEvaluator->Evaluate(expr, aContextNode, aContextSize, aContextPosition,
aBindElement,
nsIDOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
nsnull, getter_AddRefs(result));
if (NS_FAILED(rv)) {
@ -1358,7 +1357,7 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
nsXFormsXPathParser parser;
nsXFormsXPathAnalyzer analyzer(aEvaluator, aBindElement);
PRBool multiMIP = PR_FALSE;
for (int j = 0; j < eModel__count; ++j) {
for (PRUint32 j = 0; j < eModel__count; ++j) {
if (propStrings[j].IsEmpty())
continue;
@ -1406,12 +1405,13 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
NS_ENSURE_SUCCESS(rv, rv);
} else {
// the rest of the MIPs are given to the MDG
nsCOMPtr<nsIDOMXPathExpression> expr = props[j];
nsCOMPtr<nsIDOMNSXPathExpression> expr = props[j];
// Get node dependencies
nsAutoPtr<nsXFormsXPathNode> xNode(parser.Parse(propStrings[j]));
deps.Clear();
rv = analyzer.Analyze(node, xNode, expr, &propStrings[j], &deps);
rv = analyzer.Analyze(node, xNode, expr, &propStrings[j], &deps,
snapItem + 1, snapLen);
NS_ENSURE_SUCCESS(rv, rv);
// Insert into MDG

View File

@ -694,9 +694,6 @@ nsXFormsRepeatElement::Refresh()
rv = mHTMLElement->GetOwnerDocument(getter_AddRefs(domDoc));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString strSize;
strSize.AppendInt(contextSize);
mMaxIndex = contextSize;
for (PRUint32 i = 1; i < mMaxIndex + 1; ++i) {
// Create <contextcontainer>
@ -706,15 +703,12 @@ nsXFormsRepeatElement::Refresh()
getter_AddRefs(riElement));
NS_ENSURE_SUCCESS(rv, rv);
// Set context size, context position, and model as attributes
// Set model as attribute
if (!modelID.IsEmpty()) {
riElement->SetAttribute(NS_LITERAL_STRING("model"), modelID);
}
nsAutoString strPos; strPos.AppendInt(i);
riElement->SetAttribute(NS_LITERAL_STRING("contextposition"), strPos);
riElement->SetAttribute(NS_LITERAL_STRING("contextsize"), strSize);
// Get and set context node
// Get context node
nsCOMPtr<nsIXFormsContextControl> riContext = do_QueryInterface(riElement);
NS_ENSURE_TRUE(riContext, NS_ERROR_FAILURE);
@ -724,8 +718,9 @@ nsXFormsRepeatElement::Refresh()
nsCOMPtr<nsIDOMElement> contextElement = do_QueryInterface(contextNode);
NS_ENSURE_TRUE(contextElement, NS_ERROR_FAILURE);
rv = riContext->SetContextNode(contextElement);
// Set context node, position, and size
rv = riContext->SetContext(contextElement, i, contextSize);
NS_ENSURE_SUCCESS(rv, rv);
// Iterate over template children, clone them, and append them to <contextcontainer>

View File

@ -69,7 +69,7 @@
#include "nsXFormsXPathAnalyzer.h"
#include "nsXFormsXPathParser.h"
#include "nsXFormsXPathNode.h"
#include "nsIDOMXPathExpression.h"
#include "nsIDOMNSXPathExpression.h"
#include "nsArray.h"
#include "nsIScriptSecurityManager.h"
@ -263,7 +263,7 @@ nsXFormsUtils::GetNodeContext(nsIDOMElement *aElement,
PRBool *aOuterBind,
nsIDOMNode **aContextNode,
PRInt32 *aContextPosition,
PRInt32 *aContextSize)
PRInt32 *aContextSize)
{
NS_ENSURE_ARG(aElement);
NS_ENSURE_ARG(aOuterBind);
@ -271,6 +271,12 @@ nsXFormsUtils::GetNodeContext(nsIDOMElement *aElement,
NS_ENSURE_ARG_POINTER(aBindElement);
*aBindElement = nsnull;
// Set default context size and position
if (aContextSize)
*aContextSize = 1;
if (aContextPosition)
*aContextPosition = 1;
// Find correct model element
nsCOMPtr<nsIDOMDocument> domDoc;
aElement->GetOwnerDocument(getter_AddRefs(domDoc));
@ -290,12 +296,6 @@ nsXFormsUtils::GetNodeContext(nsIDOMElement *aElement,
return NS_ERROR_ABORT;
}
// Context size and position are always 1
if (aContextSize)
*aContextSize = 1;
if (aContextPosition)
*aContextPosition = 1;
*aOuterBind = GetParentModel(*aBindElement, aModel);
NS_ENSURE_STATE(*aModel);
} else {
@ -400,7 +400,7 @@ nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
do_CreateInstance("@mozilla.org/dom/xforms-xpath-evaluator;1");
NS_ENSURE_TRUE(eval, nsnull);
nsCOMPtr<nsIDOMXPathExpression> expression;
nsCOMPtr<nsIDOMNSXPathExpression> expression;
eval->CreateExpression(aExpression,
aResolverNode,
getter_AddRefs(expression));
@ -412,13 +412,13 @@ nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
return nsnull;
}
///
/// @todo Evaluate() should use aContextPosition and aContextSize
nsCOMPtr<nsISupports> supResult;
nsresult rv = expression->Evaluate(aContextNode,
aResultType,
nsnull,
getter_AddRefs(supResult));
nsresult rv = expression->EvaluateWithContext(aContextNode,
aContextPosition,
aContextSize,
aResultType,
nsnull,
getter_AddRefs(supResult));
nsIDOMXPathResult *result = nsnull;
if (NS_SUCCEEDED(rv) && supResult) {
@ -433,7 +433,9 @@ nsXFormsUtils::EvaluateXPath(const nsAString &aExpression,
xNode,
expression,
&aExpression,
aSet);
aSet,
aContextSize,
aContextPosition);
NS_ENSURE_SUCCESS(rv, nsnull);
if (aIndexesUsed)
@ -524,8 +526,8 @@ nsXFormsUtils::EvaluateNodeBinding(nsIDOMElement *aElement,
contextNode,
aElement,
aResultType,
contextSize,
contextPosition,
contextSize,
aDeps,
aIndexesUsed);

View File

@ -60,11 +60,13 @@ nsXFormsXPathAnalyzer::~nsXFormsXPathAnalyzer()
}
nsresult
nsXFormsXPathAnalyzer::Analyze(nsIDOMNode *aContextNode,
const nsXFormsXPathNode *aNode,
nsIDOMXPathExpression *aExpression,
const nsAString *aExprString,
nsCOMArray<nsIDOMNode> *aSet)
nsXFormsXPathAnalyzer::Analyze(nsIDOMNode *aContextNode,
const nsXFormsXPathNode *aNode,
nsIDOMNSXPathExpression *aExpression,
const nsAString *aExprString,
nsCOMArray<nsIDOMNode> *aSet,
PRUint32 aSize,
PRUint32 aPosition)
{
NS_ENSURE_ARG(aContextNode);
NS_ENSURE_ARG(aNode);
@ -75,6 +77,8 @@ nsXFormsXPathAnalyzer::Analyze(nsIDOMNode *aContextNode,
mCurExpression = aExpression;
mCurExprString = aExprString;
mCurSet = aSet;
mCurSize = aSize;
mCurPosition = aPosition;
#ifdef DEBUG_XF_ANALYZER
printf("=====================================\n");
@ -165,9 +169,8 @@ nsXFormsXPathAnalyzer::AnalyzeRecursively(nsIDOMNode *aContextNode,
} else {
xp = Substring(*mCurExprString, aNode->mStartIndex, aNode->mEndIndex - aNode->mStartIndex);
}
rv = mEvaluator->Evaluate(xp, aContextNode, mResolver,
nsIDOMXPathResult::ANY_TYPE,
rv = mEvaluator->Evaluate(xp, aContextNode, mCurPosition, mCurSize,
mResolver, nsIDOMXPathResult::ANY_TYPE,
nsnull, getter_AddRefs(result));
NS_ENSURE_SUCCESS(rv, rv);
@ -182,8 +185,8 @@ nsXFormsXPathAnalyzer::AnalyzeRecursively(nsIDOMNode *aContextNode,
indexSize,
xp.Length() - indexSize - 1); // remove final ')' too
nsCOMPtr<nsIDOMXPathResult> stringRes;
rv = mEvaluator->Evaluate(indexExpr, aContextNode, mResolver,
nsIDOMXPathResult::STRING_TYPE,
rv = mEvaluator->Evaluate(indexExpr, aContextNode, mCurPosition, mCurSize,
mResolver, nsIDOMXPathResult::STRING_TYPE,
nsnull, getter_AddRefs(stringRes));
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -41,7 +41,7 @@
#include "nsCOMPtr.h"
#include "nsCOMArray.h"
#include "nsXFormsXPathNode.h"
#include "nsIDOMXPathExpression.h"
#include "nsIDOMNSXPathExpression.h"
#include "nsIXFormsXPathEvaluator.h"
#include "nsIDOMXPathNSResolver.h"
#include "nsIDOMNode.h"
@ -58,13 +58,15 @@
*/
class nsXFormsXPathAnalyzer {
private:
nsCOMPtr<nsIXFormsXPathEvaluator> mEvaluator;
nsCOMPtr<nsIDOMNode> mResolver;
nsCOMPtr<nsIXFormsXPathEvaluator> mEvaluator;
nsCOMPtr<nsIDOMNode> mResolver;
nsCOMArray<nsIDOMNode> *mCurSet;
nsCOMPtr<nsIDOMXPathExpression> mCurExpression;
const nsAString *mCurExprString;
nsStringArray mIndexesUsed;
nsCOMArray<nsIDOMNode> *mCurSet;
nsCOMPtr<nsIDOMNSXPathExpression> mCurExpression;
const nsAString *mCurExprString;
PRUint32 mCurSize;
PRUint32 mCurPosition;
nsStringArray mIndexesUsed;
nsresult AnalyzeRecursively(nsIDOMNode *aContextNode,
const nsXFormsXPathNode *aNode,
@ -75,11 +77,13 @@ public:
nsIDOMNode *aResolver);
~nsXFormsXPathAnalyzer();
nsresult Analyze(nsIDOMNode *aContextNode,
const nsXFormsXPathNode *aNode,
nsIDOMXPathExpression *aExpression,
const nsAString *aExprString,
nsCOMArray<nsIDOMNode> *aSet);
nsresult Analyze(nsIDOMNode *aContextNode,
const nsXFormsXPathNode *aNode,
nsIDOMNSXPathExpression *aExpression,
const nsAString *aExprString,
nsCOMArray<nsIDOMNode> *aSet,
PRUint32 aSize,
PRUint32 aPosition);
const nsStringArray& IndexesUsed() const;
};