diff --git a/mozilla/extensions/xforms/nsXFormsControl.cpp b/mozilla/extensions/xforms/nsXFormsControl.cpp index c11f78b84bb..32e03bfa9e2 100644 --- a/mozilla/extensions/xforms/nsXFormsControl.cpp +++ b/mozilla/extensions/xforms/nsXFormsControl.cpp @@ -49,7 +49,8 @@ #include "nsIDOMXPathEvaluator.h" #include "nsIDOMXPathResult.h" #include "nsIDOMXPathNSResolver.h" -#include "nsXFormsModelElement.h" + +NS_IMPL_ISUPPORTS1(nsXFormsControl, nsXFormsControl) nsXFormsModelElement* nsXFormsControl::GetModelAndBind(nsIDOMElement **aBindElement) diff --git a/mozilla/extensions/xforms/nsXFormsControl.h b/mozilla/extensions/xforms/nsXFormsControl.h index 4cbc5af6126..9911a037c46 100644 --- a/mozilla/extensions/xforms/nsXFormsControl.h +++ b/mozilla/extensions/xforms/nsXFormsControl.h @@ -48,16 +48,27 @@ class nsXFormsModelElement; class nsIDOMElement; +#define NS_XFORMSCONTROL_IID \ +{0x49bad098, 0xaa62, 0x49be, {0x98, 0x7b, 0xdb, 0x32, 0x66, 0x92, 0x1e, 0x0a}} + // Common implementation for XForms form controls -class nsXFormsControl : public nsXFormsElement +class nsXFormsControl : public nsXFormsElement, + public nsISupports { public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_XFORMSCONTROL_IID) + + NS_DECL_ISUPPORTS + + virtual NS_HIDDEN_(void) Refresh() = 0; + NS_HIDDEN_(nsXFormsModelElement*) GetModelAndBind(nsIDOMElement **aBindElement); NS_HIDDEN_(already_AddRefed) FindInstanceNode(); protected: nsCOMPtr mWrapper; + nsCOMPtr mInstanceNode; }; #endif diff --git a/mozilla/extensions/xforms/nsXFormsInputElement.cpp b/mozilla/extensions/xforms/nsXFormsInputElement.cpp index 4361b5859d7..14acde95ae7 100644 --- a/mozilla/extensions/xforms/nsXFormsInputElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsInputElement.cpp @@ -48,6 +48,8 @@ #include "nsXFormsControl.h" #include "nsISchema.h" #include "nsXFormsModelElement.h" +#include "nsIDOMHTMLInputElement.h" +#include "nsXFormsAtoms.h" static const nsIID sScriptingIIDs[] = { NS_IDOMELEMENT_IID, @@ -63,9 +65,11 @@ public: NS_DECL_NSIXTFXMLVISUAL NS_DECL_NSIXTFELEMENT + // nsXFormsControl + virtual NS_HIDDEN_(void) Refresh(); + private: - nsCOMPtr mInstanceNode; - nsCOMPtr mInput; + nsCOMPtr mInput; }; NS_IMPL_ISUPPORTS2(nsXFormsInputElement, nsIXTFXMLVisual, nsIXTFElement) @@ -76,6 +80,20 @@ NS_IMETHODIMP nsXFormsInputElement::OnCreated(nsIXTFXMLVisualWrapper *aWrapper) { mWrapper = aWrapper; + + nsCOMPtr node; + mWrapper->GetElementNode(getter_AddRefs(node)); + nsCOMPtr domDoc; + node->GetOwnerDocument(getter_AddRefs(domDoc)); + + nsCOMPtr inputElement; + domDoc->CreateElementNS(NS_LITERAL_STRING("http://www.w3.org/1999/xhtml"), + NS_LITERAL_STRING("input"), + getter_AddRefs(inputElement)); + + mInput = do_QueryInterface(inputElement); + NS_ENSURE_TRUE(mInput, NS_ERROR_FAILURE); + return NS_OK; } @@ -119,7 +137,7 @@ nsXFormsInputElement::GetScriptingInterfaces(PRUint32 *aCount, nsIID ***aArray) NS_IMETHODIMP nsXFormsInputElement::GetNotificationMask(PRUint32 *aMask) { - *aMask = nsIXTFElement::NOTIFY_DOCUMENT_CHANGED; + *aMask = nsIXTFElement::NOTIFY_ATTRIBUTE_SET; return NS_OK; } @@ -132,44 +150,6 @@ nsXFormsInputElement::WillChangeDocument(nsISupports *aNewDocument) NS_IMETHODIMP nsXFormsInputElement::DocumentChanged(nsISupports *aNewDocument) { - // For now, just create an HTML input element (type=text). - - // For correct behavior, this should: - // - locate the for this control - // - get the model's instance data - // - evaluate the 'ref' or 'bind' attribute on this control as an - // xpath expression on the instance data - // - check for a "type" model item property on the result node - // - construct appropriate UI for xsd:boolean, xsd:date, etc - - mInstanceNode = FindInstanceNode(); - - nsCOMPtr node; - mWrapper->GetElementNode(getter_AddRefs(node)); - nsCOMPtr domDoc; - node->GetOwnerDocument(getter_AddRefs(domDoc)); - - domDoc->CreateElementNS(NS_LITERAL_STRING("http://www.w3.org/1999/xhtml"), - NS_LITERAL_STRING("input"), - getter_AddRefs(mInput)); - - nsCOMPtr bindElement; - nsXFormsModelElement *model = GetModelAndBind(getter_AddRefs(bindElement)); - - if (model) { - nsCOMPtr type = model->GetTypeForControl(this); - nsCOMPtr biType = do_QueryInterface(type); - if (biType) { - PRUint16 typeValue = 0; - biType->GetBuiltinType(&typeValue); - - if (typeValue == nsISchemaBuiltinType::BUILTIN_TYPE_BOOLEAN) { - mInput->SetAttribute(NS_LITERAL_STRING("type"), - NS_LITERAL_STRING("checkbox")); - } - } - } - return NS_OK; } @@ -230,6 +210,11 @@ nsXFormsInputElement::WillSetAttribute(nsIAtom *aName, const nsAString &aValue) NS_IMETHODIMP nsXFormsInputElement::AttributeSet(nsIAtom *aName, const nsAString &aValue) { + if (aName == nsXFormsAtoms::bind || aName == nsXFormsAtoms::ref) { + mInstanceNode = FindInstanceNode(); + Refresh(); + } + return NS_OK; } @@ -251,6 +236,47 @@ nsXFormsInputElement::DoneAddingChildren() return NS_OK; } +void +nsXFormsInputElement::Refresh() +{ + if (!mInstanceNode) + mInstanceNode = FindInstanceNode(); + + if (!mInstanceNode || !mInput) + return; + + // Fetch our value from the instance data + nsCOMPtr node = do_QueryInterface(mInstanceNode); + NS_ASSERTION(node, "unexpected QI failure"); + + nsAutoString textContent; + node->GetTextContent(textContent); + + // Revalidate our type + nsCOMPtr bindElement; + nsXFormsModelElement *model = GetModelAndBind(getter_AddRefs(bindElement)); + + if (model) { + nsCOMPtr type = model->GetTypeForControl(this); + nsCOMPtr biType = do_QueryInterface(type); + PRUint16 typeValue = nsISchemaBuiltinType::BUILTIN_TYPE_STRING; + + if (biType) + biType->GetBuiltinType(&typeValue); + + if (typeValue == nsISchemaBuiltinType::BUILTIN_TYPE_BOOLEAN) { + mInput->SetAttribute(NS_LITERAL_STRING("type"), + NS_LITERAL_STRING("checkbox")); + + mInput->SetChecked(textContent.EqualsASCII("true") || + textContent.EqualsASCII("1")); + } else { + mInput->RemoveAttribute(NS_LITERAL_STRING("type")); + mInput->SetValue(textContent); + } + } +} + NS_HIDDEN_(nsresult) NS_NewXFormsInputElement(nsIXTFElement **aResult) {