From 0ae60a4b0461a4b40c4ca944f15eab72568c5729 Mon Sep 17 00:00:00 2001 From: Neil Deakin Date: Tue, 15 Dec 2009 11:07:50 -0500 Subject: [PATCH] Bug 321177, use recursive algorithm to find member variable, r=jonas --- .../templates/src/nsXULTemplateBuilder.cpp | 73 +++++++------------ .../xul/templates/src/nsXULTemplateBuilder.h | 3 +- 2 files changed, 26 insertions(+), 50 deletions(-) diff --git a/content/xul/templates/src/nsXULTemplateBuilder.cpp b/content/xul/templates/src/nsXULTemplateBuilder.cpp index a94aeffae09b..8f9ead6e0506 100644 --- a/content/xul/templates/src/nsXULTemplateBuilder.cpp +++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp @@ -1870,9 +1870,11 @@ nsXULTemplateBuilder::CompileTemplate(nsIContent* aTemplate, getter_AddRefs(action)); if (action){ - nsCOMPtr memberVariable; - DetermineMemberVariable(action, getter_AddRefs(memberVariable)); - if (! memberVariable) continue; + nsCOMPtr memberVariable = mMemberVariable; + if (!memberVariable) { + memberVariable = DetermineMemberVariable(action); + if (!memberVariable) continue; + } if (hasQuery) { nsCOMPtr tag; @@ -1994,9 +1996,11 @@ nsXULTemplateBuilder::CompileTemplate(nsIContent* aTemplate, if (tag) aQuerySet->SetTag(tag); - nsCOMPtr memberVariable; - DetermineMemberVariable(rulenode, getter_AddRefs(memberVariable)); - if (! memberVariable) continue; + nsCOMPtr memberVariable = mMemberVariable; + if (!memberVariable) { + memberVariable = DetermineMemberVariable(rulenode); + if (!memberVariable) continue; + } nsCOMPtr query(do_QueryInterface(aQuerySet->mQueryNode)); @@ -2077,53 +2081,26 @@ nsXULTemplateBuilder::CompileExtendedQuery(nsIContent* aRuleElement, return NS_OK; } -nsresult -nsXULTemplateBuilder::DetermineMemberVariable(nsIContent* aActionElement, - nsIAtom** aMemberVariable) +already_AddRefed +nsXULTemplateBuilder::DetermineMemberVariable(nsIContent* aElement) { - // If the member variable hasn't already been specified, then - // grovel over to find it. We'll use the first one - // that we find in a breadth-first search. + // recursively iterate over the children looking for an element + // with uri="?..." + for (nsINode::ChildIterator iter(aElement); !iter.IsDone(); iter.Next()) { + nsAutoString uri; + nsIContent *child = iter; + child->GetAttr(kNameSpaceID_None, nsGkAtoms::uri, uri); + if (!uri.IsEmpty() && uri[0] == PRUnichar('?')) { + return NS_NewAtom(uri); + } - if (mMemberVariable) { - *aMemberVariable = mMemberVariable; - NS_IF_ADDREF(*aMemberVariable); - } - else { - *aMemberVariable = nsnull; - - nsCOMArray unvisited; - - if (!unvisited.AppendObject(aActionElement)) - return NS_ERROR_OUT_OF_MEMORY; - - while (unvisited.Count()) { - nsIContent* next = unvisited[0]; - unvisited.RemoveObjectAt(0); - - nsAutoString uri; - next->GetAttr(kNameSpaceID_None, nsGkAtoms::uri, uri); - - if (!uri.IsEmpty() && uri[0] == PRUnichar('?')) { - // Found it. - *aMemberVariable = NS_NewAtom(uri); - break; - } - - // otherwise, append the children to the unvisited list: this - // results in a breadth-first search. - PRUint32 count = next->GetChildCount(); - - for (PRUint32 i = 0; i < count; ++i) { - nsIContent *child = next->GetChildAt(i); - - if (!unvisited.AppendObject(child)) - return NS_ERROR_OUT_OF_MEMORY; - } + nsCOMPtr result = DetermineMemberVariable(child); + if (result) { + return result.forget(); } } - return NS_OK; + return nsnull; } void diff --git a/content/xul/templates/src/nsXULTemplateBuilder.h b/content/xul/templates/src/nsXULTemplateBuilder.h index 6fd941ac241c..138b5e0f6f7b 100644 --- a/content/xul/templates/src/nsXULTemplateBuilder.h +++ b/content/xul/templates/src/nsXULTemplateBuilder.h @@ -212,8 +212,7 @@ public: * Determine the member variable from inside an action body. It will be * the value of the uri attribute on a node. */ - nsresult - DetermineMemberVariable(nsIContent* aActionElement, nsIAtom** aMemberVariable); + already_AddRefed DetermineMemberVariable(nsIContent* aElement); /** * Compile a simple query. A simple query is one that doesn't have a