diff --git a/extensions/xforms/nsIXFormsRepeatItemElement.idl b/extensions/xforms/nsIXFormsRepeatItemElement.idl index 0d933952e4c..960274a8d6b 100644 --- a/extensions/xforms/nsIXFormsRepeatItemElement.idl +++ b/extensions/xforms/nsIXFormsRepeatItemElement.idl @@ -43,7 +43,7 @@ #include "nsISupports.idl" -[uuid(2bd6a7c7-ca59-408b-9a2a-c1bdef919fd5)] +[uuid(a60f5ef2-6c3d-4c57-af19-033734354115)] interface nsIXFormsRepeatItemElement : nsISupports { /** @@ -51,4 +51,9 @@ interface nsIXFormsRepeatItemElement : nsISupports * can set the :repeat-index accordingly. */ attribute boolean indexState; + + /** + * This returns the context position of the repeat item. + */ + readonly attribute long contextPosition; }; diff --git a/extensions/xforms/nsXFormsContextContainer.cpp b/extensions/xforms/nsXFormsContextContainer.cpp index 0e2006ba98b..e8f8840d332 100644 --- a/extensions/xforms/nsXFormsContextContainer.cpp +++ b/extensions/xforms/nsXFormsContextContainer.cpp @@ -45,6 +45,7 @@ #include "nsIDOMDocument.h" #include "nsIDOMElement.h" #include "nsIDOMEvent.h" +#include "nsIDOMNSEvent.h" #include "nsIDOMEventTarget.h" #include "nsIDOMSerializer.h" #include "nsIDOMXPathResult.h" @@ -137,40 +138,70 @@ nsXFormsContextContainer::HandleDefault(nsIDOMEvent *aEvent, nsAutoString type; aEvent->GetType(type); - if (!type.EqualsLiteral("focus")) + // Need to use "DOMFocusIn" here, "focus" doesn't bubble + if (!type.EqualsLiteral("DOMFocusIn")) return nsXFormsBindableControlStub::HandleDefault(aEvent, aHandled); if (!nsXFormsUtils::EventHandlingAllowed(aEvent, mElement)) return NS_OK; - /* - * Either we, or an element we contain, has gotten focus, so we need to set - * the repeat index. This is done through the \ the - * nsXFormsContextContainer belongs to. - * - * Start by finding the \ (our grandparent): - *
-   *  <-- gParent
-   *   
- * <-- this - *
- *
- *
- */ - nsCOMPtr parent; - mElement->GetParentNode(getter_AddRefs(parent)); - NS_ASSERTION(parent, "how can we get focus without a parent?"); - - nsCOMPtr gParent; - parent->GetParentNode(getter_AddRefs(gParent)); - nsCOMPtr repeat = do_QueryInterface(gParent); - if (!repeat) - // Not a child to a \ - return NS_OK; + // Need to explicitly create the parent chain. This ensures that this code + // works both in 1.8, which has the old event dispatching code, and also in + // the later versions of Gecko with the new event dispatching. + // See also Bug 331081. + nsCOMPtr event = do_QueryInterface(aEvent); + NS_ENSURE_STATE(event); + nsCOMPtr target; + event->GetOriginalTarget(getter_AddRefs(target)); + nsCOMPtr currentNode = do_QueryInterface(target); - // Tell \ about the new index position - PRUint32 tmp = mContextPosition; - return repeat->SetIndex(&tmp, PR_FALSE); + nsCOMArray containerStack(4); + while (currentNode) { + nsCOMPtr repeatItem = + do_QueryInterface(currentNode); + if (repeatItem) { + containerStack.AppendObject(currentNode); + } + nsCOMPtr parent; + currentNode->GetParentNode(getter_AddRefs(parent)); + currentNode.swap(parent); + } + + for (PRInt32 i = containerStack.Count() - 1; i >= 0; --i) { + nsCOMPtr node = containerStack[i]; + if (node) { + // Either we, or an element we contain, has gotten focus, so we need to + // set the repeat index. This is done through the the + // nsXFormsContextContainer belongs to. + // + // Start by finding the (our grandparent): + // <-- gParent + //
+ // <-- this + //
+ //
+ nsCOMPtr parent; + node->GetParentNode(getter_AddRefs(parent)); + if (parent) { + nsCOMPtr grandParent; + parent->GetParentNode(getter_AddRefs(grandParent)); + nsCOMPtr repeat = + do_QueryInterface(grandParent); + nsCOMPtr repeatItem = + do_QueryInterface(node); + if (repeat && repeatItem) { + PRInt32 position = 1; + repeatItem->GetContextPosition(&position); + // Tell about the new index position + PRUint32 tmp = position; + repeat->SetIndex(&tmp, PR_FALSE); + } + } + } + } + + *aHandled = PR_TRUE; + return NS_OK; } NS_IMETHODIMP @@ -279,6 +310,13 @@ nsXFormsContextContainer::GetIndexState(PRBool *aHasIndex) return NS_OK; } +NS_IMETHODIMP +nsXFormsContextContainer::GetContextPosition(PRInt32 *aContextPosition) +{ + *aContextPosition = mContextPosition; + return NS_OK; +} + // Factory NS_HIDDEN_(nsresult) NS_NewXFormsContextContainer(nsIXTFElement **aResult)