From 4483ce92f1f8ee968ed250e00fa4eb05ae2ea171 Mon Sep 17 00:00:00 2001 From: "doronr%us.ibm.com" Date: Tue, 1 Feb 2005 16:02:54 +0000 Subject: [PATCH] XForms bug 279516 - controls not initialized with MIP's. Patch by beaufour, r=smaug/sr=bryner git-svn-id: svn://10.0.0.236/trunk@168633 18797224-902f-48f8-a5cc-f745e15eee43 --- .../extensions/xforms/nsXFormsControlStub.cpp | 10 ++ .../xforms/nsXFormsInputElement.cpp | 2 +- .../xforms/nsXFormsModelElement.cpp | 93 ++++++++++++++----- .../extensions/xforms/nsXFormsModelElement.h | 14 ++- mozilla/extensions/xforms/nsXFormsNodeState.h | 2 +- 5 files changed, 93 insertions(+), 28 deletions(-) diff --git a/mozilla/extensions/xforms/nsXFormsControlStub.cpp b/mozilla/extensions/xforms/nsXFormsControlStub.cpp index 4c0502a0533..33bea2ebf3e 100644 --- a/mozilla/extensions/xforms/nsXFormsControlStub.cpp +++ b/mozilla/extensions/xforms/nsXFormsControlStub.cpp @@ -244,6 +244,16 @@ nsXFormsControlStub::HandleDefault(nsIDOMEvent *aEvent, NS_ENSURE_ARG(aHandled); if (aEvent) { + // Check that we are the target of the event + nsCOMPtr target; + aEvent->GetTarget(getter_AddRefs(target)); + nsCOMPtr targetE(do_QueryInterface(target)); + if (targetE && targetE != mElement) { + *aHandled = PR_FALSE; + return NS_OK; + } + + // Handle event nsAutoString type; aEvent->GetType(type); diff --git a/mozilla/extensions/xforms/nsXFormsInputElement.cpp b/mozilla/extensions/xforms/nsXFormsInputElement.cpp index 917f94140e1..2f33ce0225d 100644 --- a/mozilla/extensions/xforms/nsXFormsInputElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsInputElement.cpp @@ -272,7 +272,7 @@ nsXFormsInputElement::Refresh() { if (!mControl || !mModel) return NS_OK; - + nsAutoString text; PRBool readonly = GetReadOnlyState(); if (mBoundNode) { diff --git a/mozilla/extensions/xforms/nsXFormsModelElement.cpp b/mozilla/extensions/xforms/nsXFormsModelElement.cpp index ac519dc28b6..58b08fb10ff 100644 --- a/mozilla/extensions/xforms/nsXFormsModelElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsModelElement.cpp @@ -359,15 +359,18 @@ nsXFormsModelElement::HandleDefault(nsIDOMEvent *aEvent, PRBool *aHandled) nsAutoString type; aEvent->GetType(type); + nsresult rv = NS_OK; if (type.EqualsASCII(sXFormsEventsEntries[eEvent_Refresh].name)) { - Refresh(); + rv = Refresh(); } else if (type.EqualsASCII(sXFormsEventsEntries[eEvent_Revalidate].name)) { - Revalidate(); + rv = Revalidate(); } else if (type.EqualsASCII(sXFormsEventsEntries[eEvent_Recalculate].name)) { - Recalculate(); + rv = Recalculate(); } else if (type.EqualsASCII(sXFormsEventsEntries[eEvent_Rebuild].name)) { - Rebuild(); + rv = Rebuild(); + } else if (type.EqualsASCII(sXFormsEventsEntries[eEvent_ModelConstructDone].name)) { + rv = ConstructDone(); } else if (type.EqualsASCII(sXFormsEventsEntries[eEvent_Ready].name)) { Ready(); } else if (type.EqualsASCII(sXFormsEventsEntries[eEvent_Reset].name)) { @@ -376,6 +379,23 @@ nsXFormsModelElement::HandleDefault(nsIDOMEvent *aEvent, PRBool *aHandled) *aHandled = PR_FALSE; } +#ifdef DEBUG + if (NS_FAILED(rv)) + printf("nsXFormsModelElement::HandleDefault() failed!\n"); +#endif + + return rv; +} + +NS_IMETHODIMP +nsXFormsModelElement::ConstructDone() +{ + InitializeControls(); + + /// @bug This is not entirely correct. xforms-ready should be sent when + /// _all_ models have initialized their controls. + nsXFormsUtils::DispatchEvent(mElement, eEvent_Ready); + return NS_OK; } @@ -427,7 +447,9 @@ nsXFormsModelElement::Rebuild() // TODO: Clear graph and re-attach elements // 1 . Clear graph - mMDG.Clear(); + nsresult rv; + rv = mMDG.Clear(); + NS_ENSURE_SUCCESS(rv, rv); // 2. Re-attach all elements @@ -458,7 +480,8 @@ nsXFormsModelElement::Rebuild() } // 3. Rebuild graph - ProcessBindElements(); + rv = ProcessBindElements(); + NS_ENSURE_SUCCESS(rv, rv); return mMDG.Rebuild(); } @@ -475,37 +498,37 @@ nsXFormsModelElement::Recalculate() void nsXFormsModelElement::DispatchEvents(nsIXFormsControl *aControl, - nsIDOMNode *aNode) + nsIDOMNode *aNode, + PRBool aInitialize) { + if (!aControl || !aNode) + return; + nsCOMPtr element; aControl->GetElement(getter_AddRefs(element)); - - const nsXFormsNodeState* ns = mMDG.GetNodeState(aNode); - if (!element || !ns) { -#ifdef DEBUG_beaufour - printf("nsXFormsModelElement::DispatchEvents(): Could not get element or node state for node!\n"); -#endif + const nsXFormsNodeState *ns = mMDG.GetNodeState(aNode); + + if (!element || !ns) return; - } - if (ns->ShouldDispatchValid()) { + if (aInitialize || ns->ShouldDispatchValid()) { nsXFormsUtils::DispatchEvent(element, ns->IsValid() ? eEvent_Valid : eEvent_Invalid); } - if (ns->ShouldDispatchReadonly()) { + if (aInitialize || ns->ShouldDispatchReadonly()) { nsXFormsUtils::DispatchEvent(element, ns->IsReadonly() ? eEvent_Readonly : eEvent_Readwrite); } - if (ns->ShouldDispatchRequired()) { + if (aInitialize || ns->ShouldDispatchRequired()) { nsXFormsUtils::DispatchEvent(element, ns->IsRequired() ? eEvent_Required : eEvent_Optional); } - if (ns->ShouldDispatchRelevant()) { + if (aInitialize || ns->ShouldDispatchRelevant()) { nsXFormsUtils::DispatchEvent(element, ns->IsRelevant() ? eEvent_Enabled : eEvent_Disabled); } - if (ns->ShouldDispatchValueChanged()) { + if (aInitialize || ns->ShouldDispatchValueChanged()) { nsXFormsUtils::DispatchEvent(element, eEvent_ValueChanged); } } @@ -1099,8 +1122,6 @@ nsXFormsModelElement::FinishConstruction() // we get the instance data from our instance child nodes - ProcessBindElements(); - // 5. dispatch xforms-rebuild, xforms-recalculate, xforms-revalidate nsXFormsUtils::DispatchEvent(mElement, eEvent_Rebuild); @@ -1112,6 +1133,29 @@ nsXFormsModelElement::FinishConstruction() return NS_OK; } +void +nsXFormsModelElement::InitializeControls() +{ + PRInt32 controlCount = mFormControls.Count(); + for (PRInt32 i = 0; i < controlCount; ++i) { + // Get control + nsIXFormsControl *control = NS_STATIC_CAST(nsIXFormsControl*, + mFormControls[i]); + if (!control) + continue; + + // Get bound node + nsCOMPtr boundNode; + control->GetBoundNode(getter_AddRefs(boundNode)); + + // Dispatch events + DispatchEvents(control, boundNode, PR_TRUE); + // Refresh controls + control->Refresh(); + } +} + + void nsXFormsModelElement::MaybeNotifyCompletion() { @@ -1140,7 +1184,6 @@ nsXFormsModelElement::MaybeNotifyCompletion() nsXFormsModelElement *model = NS_STATIC_CAST(nsXFormsModelElement *, models->ElementAt(i)); nsXFormsUtils::DispatchEvent(model->mElement, eEvent_ModelConstructDone); - nsXFormsUtils::DispatchEvent(model->mElement, eEvent_Ready); } } @@ -1187,6 +1230,9 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator, nsIDOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, nsnull, getter_AddRefs(result)); if (NS_FAILED(rv)) { +#ifdef DEBUG + printf("xforms-binding-exception: XPath Evaluation failed\n"); +#endif nsXFormsUtils::DispatchEvent(mElement, eEvent_BindingException); return rv; } @@ -1296,6 +1342,9 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator, // @see http://www.w3.org/TR/xforms/slice4.html#evt-modelConstruct // (item 4, c) if (multiMIP) { +#ifdef DEBUG + printf("xforms-binding-exception: Multiple MIPs on same node!"); +#endif nsXFormsUtils::DispatchEvent(aBindElement, eEvent_BindingException); return NS_ERROR_FAILURE; diff --git a/mozilla/extensions/xforms/nsXFormsModelElement.h b/mozilla/extensions/xforms/nsXFormsModelElement.h index e115d3c9938..b59b7ab7bcb 100644 --- a/mozilla/extensions/xforms/nsXFormsModelElement.h +++ b/mozilla/extensions/xforms/nsXFormsModelElement.h @@ -65,9 +65,6 @@ class nsXFormsControl; * initializing the model and its controls. * * @see http://www.w3.org/TR/xforms/slice3.html#structure-model - * - * @todo We need to dispatch the initial (default) events to controls (XXX) - * */ class nsXFormsModelElement : public nsXFormsStubElement, public nsIModelElementPrivate, @@ -104,8 +101,12 @@ private: NS_HIDDEN_(void) Ready(); NS_HIDDEN_(void) BackupOrRestoreInstanceData(PRBool restore); + /** Initializes the MIPs on all form controls */ + NS_HIDDEN_(void) InitializeControls(); + NS_HIDDEN_(nsresult) ProcessBindElements(); NS_HIDDEN_(nsresult) FinishConstruction(); + NS_HIDDEN_(nsresult) ConstructDone(); NS_HIDDEN_(void) MaybeNotifyCompletion(); NS_HIDDEN_(nsresult) ProcessBind(nsIXFormsXPathEvaluator *aEvaluator, @@ -119,9 +120,14 @@ private: /** * Dispatch the necessary events to a control, aControl, when the instance * node, aNode, it is bound to changes state. + * + * @param aControl The event target + * @param aNode The instance node + * @param aInitialize Send events for all flags */ NS_HIDDEN_(void) DispatchEvents(nsIXFormsControl *aControl, - nsIDOMNode *aNode); + nsIDOMNode *aNode, + PRBool aInitialize = PR_FALSE); // Returns true when all external documents have been loaded PRBool IsComplete() const { return (mSchemaTotal == mSchemaCount diff --git a/mozilla/extensions/xforms/nsXFormsNodeState.h b/mozilla/extensions/xforms/nsXFormsNodeState.h index 3300afd224f..ac3ee47351f 100644 --- a/mozilla/extensions/xforms/nsXFormsNodeState.h +++ b/mozilla/extensions/xforms/nsXFormsNodeState.h @@ -43,7 +43,7 @@ #include "nscore.h" #ifdef DEBUG -#//define DEBUG_XF_NODESTATE +//#define DEBUG_XF_NODESTATE #endif /** Flags used in nsXFormsNodeState */