diff --git a/mozilla/extensions/xforms/Makefile.in b/mozilla/extensions/xforms/Makefile.in index cb180e662c9..d1df8d0d25c 100644 --- a/mozilla/extensions/xforms/Makefile.in +++ b/mozilla/extensions/xforms/Makefile.in @@ -93,6 +93,9 @@ XPIDLSRCS = \ nsIXFormsControlBase.idl \ nsIXFormsDelegate.idl \ nsIXFormsUIWidget.idl \ + nsIXFormsItemElement.idl \ + nsIXFormsLabelElement.idl \ + nsIXFormsItemSetUIElement.idl \ $(NULL) CPPSRCS = \ @@ -137,6 +140,7 @@ CPPSRCS = \ nsXFormsSwitchElement.cpp \ nsXFormsUploadElement.cpp \ nsXFormsSelectElement.cpp \ + nsXFormsSelect1Element.cpp \ nsXFormsItemElement.cpp \ nsXFormsValueElement.cpp \ nsXFormsChoicesElement.cpp \ diff --git a/mozilla/extensions/xforms/jar.mn b/mozilla/extensions/xforms/jar.mn index a7725880bf8..98d6f2c646a 100755 --- a/mozilla/extensions/xforms/jar.mn +++ b/mozilla/extensions/xforms/jar.mn @@ -7,7 +7,8 @@ xforms.jar: * content/xforms/xforms-prefs.xul (resources/content/xforms-prefs.xul) * content/xforms/xforms-prefs-ui.xul (resources/content/xforms-prefs-ui.xul) * content/xforms/xforms-prefs.js (resources/content/xforms-prefs.js) - content/xforms/xforms.xml (resources/content/xforms.xml) + content/xforms/xforms.xml (resources/content/xforms.xml) + content/xforms/select1.xml (resources/content/select1.xml) * locale/en-US/xforms/contents.rdf (resources/locale/en-US/contents.rdf) locale/en-US/xforms/xforms.properties (resources/locale/en-US/xforms.properties) locale/en-US/xforms/xforms.dtd (resources/locale/en-US/xforms.dtd) diff --git a/mozilla/extensions/xforms/nsIXFormsItemElement.idl b/mozilla/extensions/xforms/nsIXFormsItemElement.idl new file mode 100644 index 00000000000..66da4694dee --- /dev/null +++ b/mozilla/extensions/xforms/nsIXFormsItemElement.idl @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla XForms support. + * + * The Initial Developer of the Original Code is + * Olli Pettay. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Olli Pettay (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +/** + * Interface implemented by the item element. + */ +[scriptable, uuid(796a2e26-a40b-4ebf-be2c-42faf5fea6c4)] +interface nsIXFormsItemElement : nsISupports +{ + /** + * The text value of the \ child element of the item. + */ + readonly attribute AString labelText; + + /** + * The value of the item element. + */ + readonly attribute AString value; + + /** + * Marks item active. In current implementation '_moz_active' attribute is + * set to the element if aActive is true. The attribute can be used when + * styling the element. + */ + void setActive(in boolean aActive); + + /** + * This is called by the \ child element whenever it is refreshed. + * This information will be propagated by the \ to the nearest + * \ element, which can then refresh its UI. + */ + void labelRefreshed(); +}; diff --git a/mozilla/extensions/xforms/nsIXFormsItemSetUIElement.idl b/mozilla/extensions/xforms/nsIXFormsItemSetUIElement.idl new file mode 100644 index 00000000000..3dfc7cbe40e --- /dev/null +++ b/mozilla/extensions/xforms/nsIXFormsItemSetUIElement.idl @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla XForms support. + * + * The Initial Developer of the Original Code is + * Olli Pettay. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Olli Pettay (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +interface nsIDOMElement; + +/** + * Interface implemented by the XBL part of the itemset element. + */ +[scriptable, uuid(19862a10-42ac-4d20-8204-9c44a122797d)] +interface nsIXFormsItemSetUIElement : nsISupports +{ + /** + * anonymousItemSetContent will be used as a parent element for + * the generated \ elements. + */ + readonly attribute nsIDOMElement anonymousItemSetContent; +}; diff --git a/mozilla/extensions/xforms/nsIXFormsLabelElement.idl b/mozilla/extensions/xforms/nsIXFormsLabelElement.idl new file mode 100644 index 00000000000..9d6b8f645c0 --- /dev/null +++ b/mozilla/extensions/xforms/nsIXFormsLabelElement.idl @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla XForms support. + * + * The Initial Developer of the Original Code is + * Olli Pettay. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Olli Pettay (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + + +/** + * Interface implemented by the label element. + */ +[uuid(f357747b-a1a2-4044-bd25-cb5d5b4fde3a)] +interface nsIXFormsLabelElement : nsISupports +{ + /** + * The text value of the \ element. + */ + readonly attribute AString textValue; +}; diff --git a/mozilla/extensions/xforms/nsIXFormsSelectChild.idl b/mozilla/extensions/xforms/nsIXFormsSelectChild.idl index 72a9772d8dd..51e900cd317 100644 --- a/mozilla/extensions/xforms/nsIXFormsSelectChild.idl +++ b/mozilla/extensions/xforms/nsIXFormsSelectChild.idl @@ -52,7 +52,7 @@ class nsStringArray; * of an XForms select element (choices, item, itemset). */ -[uuid(21e37ef5-ce3e-4ff1-b7b2-fb34c4e2c8be)] +[scriptable, uuid(a29ac2bd-f36a-451e-99e1-0f3bd94ffbef)] interface nsIXFormsSelectChild : nsISupports { /** @@ -62,20 +62,27 @@ interface nsIXFormsSelectChild : nsISupports readonly attribute nsIArray anonymousNodes; /** - * These two methods allow the select to synchronize selection with the - * instance data. - * * selectItemsByValue() handles children that have a value element child. * If the value element text for this child is contained in the |values| - * array, then the item should select itself. + * array, then the item should select itself. Used in \. * + */ + [noscript] void selectItemsByValue(in constStringArray values); + + /** * selectItemsByContent() handles children that have a copy element child. * If |node| points to the same instance data node as the item, then the * item should select itself. */ - void selectItemsByValue(in constStringArray values); void selectItemsByContent(in nsIDOMNode node); + /* + * selectItemByValue is used in \. If the XFormsSelectChild is or + * contains an \, which has the same value as the parameter |value|, + * this method returns that \. + */ + nsIDOMNode selectItemByValue(in AString value); + /** * Instructs the item to serialize its selected elements. * For children that have a value child, they should append the value of diff --git a/mozilla/extensions/xforms/nsXFormsChoicesElement.cpp b/mozilla/extensions/xforms/nsXFormsChoicesElement.cpp index 6ec3ce63de6..821861665be 100644 --- a/mozilla/extensions/xforms/nsXFormsChoicesElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsChoicesElement.cpp @@ -41,11 +41,12 @@ #include "nsIDOMHTMLOptGroupElement.h" #include "nsString.h" #include "nsCOMPtr.h" -#include "nsIXTFGenericElementWrapper.h" +#include "nsIXTFBindableElementWrapper.h" #include "nsIDOMDocument.h" #include "nsIDOMNodeList.h" #include "nsXFormsUtils.h" #include "nsArray.h" +#include "nsIXTFXMLVisualWrapper.h" /** * Implementation of XForms \ element. This creates an HTML @@ -53,7 +54,7 @@ * of the optgroup. */ -class nsXFormsChoicesElement : public nsXFormsStubElement, +class nsXFormsChoicesElement : public nsXFormsBindableStub, public nsIXFormsSelectChild { public: @@ -61,8 +62,7 @@ public: NS_DECL_ISUPPORTS_INHERITED - // nsIXTFGenericElement overrides - NS_IMETHOD OnCreated(nsIXTFGenericElementWrapper *aWrapper); + NS_IMETHOD OnCreated(nsIXTFBindableElementWrapper *aWrapper); // nsIXTFElement overrides NS_IMETHOD ParentChanged(nsIDOMElement *aNewParent); @@ -79,16 +79,17 @@ public: NS_DECL_NSIXFORMSSELECTCHILD private: - nsIDOMElement *mElement; + nsIDOMElement* mElement; nsCOMPtr mOptGroup; + PRBool mInsideSelect1; }; NS_IMPL_ISUPPORTS_INHERITED1(nsXFormsChoicesElement, - nsXFormsStubElement, + nsXFormsBindableStub, nsIXFormsSelectChild) NS_IMETHODIMP -nsXFormsChoicesElement::OnCreated(nsIXTFGenericElementWrapper *aWrapper) +nsXFormsChoicesElement::OnCreated(nsIXTFBindableElementWrapper *aWrapper) { aWrapper->SetNotificationMask(nsIXTFElement::NOTIFY_PARENT_CHANGED | nsIXTFElement::NOTIFY_CHILD_INSERTED | @@ -96,6 +97,8 @@ nsXFormsChoicesElement::OnCreated(nsIXTFGenericElementWrapper *aWrapper) nsIXTFElement::NOTIFY_CHILD_REMOVED | nsIXTFElement::NOTIFY_BEGIN_ADDING_CHILDREN); + mInsideSelect1 = PR_FALSE; + nsCOMPtr node; aWrapper->GetElementNode(getter_AddRefs(node)); @@ -106,14 +109,16 @@ nsXFormsChoicesElement::OnCreated(nsIXTFGenericElementWrapper *aWrapper) mElement = node; NS_ASSERTION(mElement, "Wrapper is not an nsIDOMElement, we'll crash soon"); - // Our anonymous content structure will look like this: + // Our anonymous content structure in . nsCOMPtr element; domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML), NS_LITERAL_STRING("optgroup"), @@ -128,9 +133,20 @@ nsXFormsChoicesElement::OnCreated(nsIXTFGenericElementWrapper *aWrapper) NS_IMETHODIMP nsXFormsChoicesElement::ParentChanged(nsIDOMElement *aNewParent) { - if (aNewParent) + mInsideSelect1 = PR_FALSE; + if (aNewParent) { + nsCOMPtr parent, tmp; + mElement->GetParentNode(getter_AddRefs(parent)); + while (parent) { + if (nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select1"))) { + mInsideSelect1 = PR_TRUE; + break; + } + tmp.swap(parent); + tmp->GetParentNode(getter_AddRefs(parent)); + } Refresh(); - + } return NS_OK; } @@ -251,6 +267,35 @@ nsXFormsChoicesElement::GetAnonymousNodes(nsIArray **aNodes) return NS_OK; } +NS_IMETHODIMP +nsXFormsChoicesElement::SelectItemByValue(const nsAString &aValue, nsIDOMNode **aSelected) +{ + NS_ENSURE_ARG_POINTER(aSelected); + NS_ENSURE_STATE(mElement); + *aSelected = nsnull; + nsCOMPtr children; + nsresult rv = mElement->GetChildNodes(getter_AddRefs(children)); + NS_ENSURE_SUCCESS(rv, rv); + + PRUint32 childCount = 0; + children->GetLength(&childCount); + + nsCOMPtr childNode; + nsCOMPtr childItem; + + for (PRUint32 i = 0; i < childCount; ++i) { + children->Item(i, getter_AddRefs(childNode)); + childItem = do_QueryInterface(childNode); + if (childItem) { + childItem->SelectItemByValue(aValue, aSelected); + if (*aSelected) + return NS_OK; + } + } + + return NS_OK; +} + NS_IMETHODIMP nsXFormsChoicesElement::SelectItemsByValue(const nsStringArray &aValueList) { @@ -322,6 +367,12 @@ nsXFormsChoicesElement::SetContext(nsIDOMElement *aContextNode, NS_IMETHODIMP nsXFormsChoicesElement::Refresh() { + if (mInsideSelect1) { + // is XBLized, so there is no need to recreate UI - + // XBL will do it for us. + return NS_OK; + } + // Remove any existing first child that is not an option, to clear out // any existing label. nsCOMPtr firstChild, child2; diff --git a/mozilla/extensions/xforms/nsXFormsContextContainer.cpp b/mozilla/extensions/xforms/nsXFormsContextContainer.cpp index 2e7e269fcaf..0a11c07ba2e 100644 --- a/mozilla/extensions/xforms/nsXFormsContextContainer.cpp +++ b/mozilla/extensions/xforms/nsXFormsContextContainer.cpp @@ -36,7 +36,7 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsIXTFXMLVisualWrapper.h" +#include "nsIXTFBindableElementWrapper.h" #include "nsCOMPtr.h" #include "nsString.h" @@ -71,12 +71,10 @@ * @see http://www.w3.org/TR/xforms/sliceF.html#id2645142 * @see http://bugzilla.mozilla.org/show_bug.cgi?id=271724 */ -class nsXFormsContextContainer : public nsXFormsControlStub, +class nsXFormsContextContainer : public nsXFormsBindableControlStub, public nsIXFormsRepeatItemElement { protected: - /** The HTML representation for the node */ - nsCOMPtr mHTMLElement; /** The context position for the element */ PRInt32 mContextPosition; @@ -90,17 +88,9 @@ public: NS_DECL_ISUPPORTS_INHERITED - // nsIXTFXMLVisual overrides - NS_IMETHOD OnCreated(nsIXTFXMLVisualWrapper *aWrapper); - - // nsIXTFVisual overrides - NS_IMETHOD HandleDefault(nsIDOMEvent *aEvent, PRBool *aHandled); - NS_IMETHOD GetVisualContent(nsIDOMElement **aElement); - NS_IMETHOD GetInsertionPoint(nsIDOMElement **aElement); - // nsIXTFElement overrides - NS_IMETHOD OnDestroyed(); NS_IMETHOD CloneState(nsIDOMElement *aElement); + NS_IMETHOD HandleDefault(nsIDOMEvent *aEvent, PRBool *aHandled); // nsIXFormsControl NS_IMETHOD Bind(); @@ -119,75 +109,20 @@ public: #ifdef DEBUG_smaug virtual const char* Name() { - return mIsBlock ? "contextcontainer" : "contextcontainer-inline"; + if (mElement) { + nsAutoString localName; + mElement->GetLocalName(localName); + return NS_ConvertUTF16toUTF8(localName).get(); + } + return "contextcontainer(inline?)"; } - - PRBool mIsBlock; #endif }; NS_IMPL_ISUPPORTS_INHERITED1(nsXFormsContextContainer, - nsXFormsControlStub, + nsXFormsBindableControlStub, nsIXFormsRepeatItemElement) -// nsIXTFXMLVisual -NS_IMETHODIMP -nsXFormsContextContainer::OnCreated(nsIXTFXMLVisualWrapper *aWrapper) -{ -#ifdef DEBUG_XF_CONTEXTCONTAINER - printf("nsXFormsContextContainer::OnCreated(aWrapper=%p)\n", (void*) aWrapper); -#endif - - nsresult rv = nsXFormsControlStub::OnCreated(aWrapper); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr domDoc; - rv = mElement->GetOwnerDocument(getter_AddRefs(domDoc)); - NS_ENSURE_SUCCESS(rv, rv); - - PRBool isBlock; - - // If we're a "contextcontainer" element, then we create a div child. - // If not, we're a "contextcontainer-inline" element and create a span child. - nsAutoString localName; - mElement->GetLocalName(localName); - isBlock = localName.EqualsLiteral("contextcontainer"); - -#ifdef DEBUG_smaug - mIsBlock = isBlock; -#endif - - // Create UI element - rv = domDoc->CreateElementNS(NS_LITERAL_STRING("http://www.w3.org/1999/xhtml"), - isBlock ? NS_LITERAL_STRING("div") : - NS_LITERAL_STRING("span"), - getter_AddRefs(mHTMLElement)); - NS_ENSURE_SUCCESS(rv, rv); - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsContextContainer::GetVisualContent(nsIDOMElement **aElement) -{ -#ifdef DEBUG_XF_CONTEXTCONTAINER - printf("nsXFormsContextContainer::GetVisualContent()\n"); -#endif - - NS_IF_ADDREF(*aElement = mHTMLElement); - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsContextContainer::GetInsertionPoint(nsIDOMElement **aElement) -{ -#ifdef DEBUG_XF_CONTEXTCONTAINER - printf("nsXFormsContextContainer::GetInsertionPoint()\n"); -#endif - - NS_IF_ADDREF(*aElement = mHTMLElement); - - return NS_OK; -} // nsIXTFElement NS_IMETHODIMP @@ -200,7 +135,7 @@ nsXFormsContextContainer::HandleDefault(nsIDOMEvent *aEvent, nsAutoString type; aEvent->GetType(type); if (!type.EqualsLiteral("focus")) - return nsXFormsControlStub::HandleDefault(aEvent, aHandled); + return nsXFormsBindableControlStub::HandleDefault(aEvent, aHandled); if (!nsXFormsUtils::EventHandlingAllowed(aEvent, mElement)) return NS_OK; @@ -235,14 +170,6 @@ nsXFormsContextContainer::HandleDefault(nsIDOMEvent *aEvent, return repeat->SetIndex(&tmp, PR_FALSE); } -NS_IMETHODIMP -nsXFormsContextContainer::OnDestroyed() -{ - mHTMLElement = nsnull; - - return nsXFormsControlStub::OnDestroyed(); -} - NS_IMETHODIMP nsXFormsContextContainer::CloneState(nsIDOMElement *aElement) { @@ -291,10 +218,10 @@ nsXFormsContextContainer::GetContext(nsAString &aModelID, PRInt32 *aContextPosition, PRInt32 *aContextSize) { - nsresult rv = nsXFormsControlStub::GetContext(aModelID, - aContextNode, - aContextPosition, - aContextSize); + nsresult rv = nsXFormsBindableControlStub::GetContext(aModelID, + aContextNode, + aContextPosition, + aContextSize); NS_ENSURE_SUCCESS(rv, rv); *aContextPosition = mContextPosition; diff --git a/mozilla/extensions/xforms/nsXFormsDelegateStub.cpp b/mozilla/extensions/xforms/nsXFormsDelegateStub.cpp index 4ae206ff3b7..125130e8c4f 100644 --- a/mozilla/extensions/xforms/nsXFormsDelegateStub.cpp +++ b/mozilla/extensions/xforms/nsXFormsDelegateStub.cpp @@ -100,6 +100,12 @@ nsXFormsDelegateStub::Refresh() if (mRepeatState == eType_Template) return NS_OK; + const nsVoidArray* list = nsPostRefresh::PostRefreshList(); + if (list && list->IndexOf(this) >= 0) { + // This control will be refreshed later. + return NS_OK; + } + SetMozTypeAttribute(); nsCOMPtr widget = do_QueryInterface(mElement); @@ -139,7 +145,26 @@ nsXFormsDelegateStub::GetValue(nsAString& aValue) NS_IMETHODIMP nsXFormsDelegateStub::SetValue(const nsAString& aValue) { - return NS_ERROR_NOT_IMPLEMENTED; + if (!mBoundNode || !mModel) + return NS_OK; + + PRBool changed; + nsresult rv = mModel->SetNodeValue(mBoundNode, aValue, &changed); + NS_ENSURE_SUCCESS(rv, rv); + if (changed) { + nsCOMPtr model = do_QueryInterface(mModel); + + if (model) { + rv = nsXFormsUtils::DispatchEvent(model, eEvent_Recalculate); + NS_ENSURE_SUCCESS(rv, rv); + rv = nsXFormsUtils::DispatchEvent(model, eEvent_Revalidate); + NS_ENSURE_SUCCESS(rv, rv); + rv = nsXFormsUtils::DispatchEvent(model, eEvent_Refresh); + NS_ENSURE_SUCCESS(rv, rv); + } + } + + return NS_OK; } nsresult diff --git a/mozilla/extensions/xforms/nsXFormsDelegateStub.h b/mozilla/extensions/xforms/nsXFormsDelegateStub.h index dbb181154d0..3fb11134d21 100644 --- a/mozilla/extensions/xforms/nsXFormsDelegateStub.h +++ b/mozilla/extensions/xforms/nsXFormsDelegateStub.h @@ -80,6 +80,18 @@ public: NS_IMETHOD TryFocus(PRBool* aOK); NS_IMETHOD Refresh(); +#ifdef DEBUG_smaug + virtual const char* Name() + { + if (mControlType.IsEmpty()) { + return "[undefined delegate]"; + } + + return NS_ConvertUTF16toUTF8(mControlType).get(); + } +#endif + + nsXFormsDelegateStub(const nsAString& aType = EmptyString()) : mControlType(aType), mRepeatState(eType_Unknown) {} diff --git a/mozilla/extensions/xforms/nsXFormsElementFactory.cpp b/mozilla/extensions/xforms/nsXFormsElementFactory.cpp index 8f0e4f36bc8..d94fe36f131 100644 --- a/mozilla/extensions/xforms/nsXFormsElementFactory.cpp +++ b/mozilla/extensions/xforms/nsXFormsElementFactory.cpp @@ -63,6 +63,7 @@ NS_HIDDEN_(nsresult) NS_NewXFormsTriggerElement(nsIXTFElement **aElement); NS_HIDDEN_(nsresult) NS_NewXFormsSubmitElement(nsIXTFElement **aElement); NS_HIDDEN_(nsresult) NS_NewXFormsLabelElement(nsIXTFElement **aElement); NS_HIDDEN_(nsresult) NS_NewXFormsSelectElement(nsIXTFElement **aElement); +NS_HIDDEN_(nsresult) NS_NewXFormsSelect1Element(nsIXTFElement **aElement); NS_HIDDEN_(nsresult) NS_NewXFormsItemElement(nsIXTFElement **aElement); NS_HIDDEN_(nsresult) NS_NewXFormsValueElement(nsIXTFElement **aElement); NS_HIDDEN_(nsresult) NS_NewXFormsChoicesElement(nsIXTFElement **aElement); @@ -125,8 +126,10 @@ nsXFormsElementFactory::CreateElement(const nsAString& aTagName, return NS_NewXFormsContextContainer(aElement); if (aTagName.EqualsLiteral("label")) return NS_NewXFormsLabelElement(aElement); - if (aTagName.EqualsLiteral("select") || aTagName.EqualsLiteral("select1")) + if (aTagName.EqualsLiteral("select")) return NS_NewXFormsSelectElement(aElement); + if (aTagName.EqualsLiteral("select1")) + return NS_NewXFormsSelect1Element(aElement); if (aTagName.EqualsLiteral("item")) return NS_NewXFormsItemElement(aElement); if (aTagName.EqualsLiteral("itemset")) diff --git a/mozilla/extensions/xforms/nsXFormsInputElement.cpp b/mozilla/extensions/xforms/nsXFormsInputElement.cpp index 139eb044557..74796833258 100644 --- a/mozilla/extensions/xforms/nsXFormsInputElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsInputElement.cpp @@ -37,89 +37,14 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsIDOMEventTarget.h" -#include "nsIDOM3Node.h" -#include "nsIDOMElement.h" -#include "nsMemory.h" -#include "nsCOMPtr.h" -#include "nsString.h" -#include "nsIXTFXMLVisualWrapper.h" -#include "nsIDOMDocument.h" -#include "nsIXFormsControl.h" -#include "nsXFormsControlStub.h" -#include "nsISchema.h" -#include "nsIDOMHTMLInputElement.h" -#include "nsIDOMHTMLTextAreaElement.h" -#include "nsAutoPtr.h" -#include "nsIDOMXPathResult.h" -#include "nsIDOMFocusListener.h" -#include "nsXFormsUtils.h" -#include "nsIModelElementPrivate.h" -#include "nsIContent.h" -#include "nsIDOMXPathExpression.h" -#include "nsXFormsAtoms.h" #include "nsXFormsDelegateStub.h" -/** - * Implementation of the \, \, and \ elements. - */ -class nsXFormsInputElement : public nsXFormsDelegateStub -{ -public: - - // nsIXFormsDelegate - NS_IMETHOD SetValue(const nsAString& aValue); - - enum ControlType { - eType_Input, - eType_Secret, - eType_TextArea - }; - -#ifdef DEBUG_smaug - virtual const char* Name() { return "input"; } -#endif - - // nsXFormsInputElement - nsXFormsInputElement(const nsAString& aType) - : nsXFormsDelegateStub(aType) - {} -}; - - -// nsIXFormsDelegate - -NS_IMETHODIMP -nsXFormsInputElement::SetValue(const nsAString& aValue) -{ - if (!mBoundNode || !mModel) - return NS_OK; - - PRBool changed; - nsresult rv = mModel->SetNodeValue(mBoundNode, aValue, &changed); - NS_ENSURE_SUCCESS(rv, rv); - if (changed) { - nsCOMPtr model = do_QueryInterface(mModel); - - if (model) { - rv = nsXFormsUtils::DispatchEvent(model, eEvent_Recalculate); - NS_ENSURE_SUCCESS(rv, rv); - rv = nsXFormsUtils::DispatchEvent(model, eEvent_Revalidate); - NS_ENSURE_SUCCESS(rv, rv); - rv = nsXFormsUtils::DispatchEvent(model, eEvent_Refresh); - NS_ENSURE_SUCCESS(rv, rv); - } - } - - return NS_OK; -} - // Creators NS_HIDDEN_(nsresult) NS_NewXFormsInputElement(nsIXTFElement **aResult) { - *aResult = new nsXFormsInputElement(NS_LITERAL_STRING("input")); + *aResult = new nsXFormsDelegateStub(NS_LITERAL_STRING("input")); if (!*aResult) return NS_ERROR_OUT_OF_MEMORY; @@ -130,7 +55,7 @@ NS_NewXFormsInputElement(nsIXTFElement **aResult) NS_HIDDEN_(nsresult) NS_NewXFormsSecretElement(nsIXTFElement **aResult) { - *aResult = new nsXFormsInputElement(NS_LITERAL_STRING("secret")); + *aResult = new nsXFormsDelegateStub(NS_LITERAL_STRING("secret")); if (!*aResult) return NS_ERROR_OUT_OF_MEMORY; @@ -141,7 +66,7 @@ NS_NewXFormsSecretElement(nsIXTFElement **aResult) NS_HIDDEN_(nsresult) NS_NewXFormsTextAreaElement(nsIXTFElement **aResult) { - *aResult = new nsXFormsInputElement(NS_LITERAL_STRING("textarea")); + *aResult = new nsXFormsDelegateStub(NS_LITERAL_STRING("textarea")); if (!*aResult) return NS_ERROR_OUT_OF_MEMORY; diff --git a/mozilla/extensions/xforms/nsXFormsItemElement.cpp b/mozilla/extensions/xforms/nsXFormsItemElement.cpp index 76663b481a9..27dd6b0b04b 100644 --- a/mozilla/extensions/xforms/nsXFormsItemElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsItemElement.cpp @@ -41,7 +41,6 @@ #include "nsIDOMHTMLOptionElement.h" #include "nsXFormsAtoms.h" #include "nsIDOMNodeList.h" -#include "nsIXTFGenericElementWrapper.h" #include "nsIDOMDocument.h" #include "nsString.h" #include "nsXFormsUtils.h" @@ -49,9 +48,14 @@ #include "nsArray.h" #include "nsVoidArray.h" #include "nsIDOMText.h" -#include "nsIXTFXMLVisualWrapper.h" +#include "nsIXTFBindableElementWrapper.h" #include "nsIXFormsContextControl.h" #include "nsIModelElementPrivate.h" +#include "nsIXFormsItemElement.h" +#include "nsIXFormsControl.h" +#include "nsIXFormsLabelElement.h" +#include "nsIDocument.h" +#include "nsXFormsModelElement.h" /** * nsXFormsItemElement implements the XForms \ element. @@ -60,20 +64,22 @@ * select element. */ -class nsXFormsItemElement : public nsXFormsStubElement, - public nsIXFormsSelectChild +class nsXFormsItemElement : public nsXFormsBindableStub, + public nsIXFormsSelectChild, + public nsIXFormsItemElement { public: nsXFormsItemElement() : mElement(nsnull), mContextPosition(0), - mContextSize(0) + mContextSize(0), + mInsideSelect1(PR_FALSE) { } NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIXFORMSITEMELEMENT - // nsIXTFGenericElement overrides - NS_IMETHOD OnCreated(nsIXTFGenericElementWrapper *aWrapper); + NS_IMETHOD OnCreated(nsIXTFBindableElementWrapper *aWrapper); // nsIXTFElement overrides NS_IMETHOD ParentChanged(nsIDOMElement *aNewParent); @@ -90,29 +96,31 @@ public: NS_DECL_NSIXFORMSSELECTCHILD private: - NS_HIDDEN_(nsresult) GetValue(nsString &aValue); - nsIDOMElement *mElement; + nsIDOMElement* mElement; nsCOMPtr mOption; - // context node (used by itemset) - nsCOMPtr mContextNode; - PRInt32 mContextPosition; - PRInt32 mContextSize; + // context node (used by itemset in select) + nsCOMPtr mContextNode; + PRInt32 mContextPosition; + PRInt32 mContextSize; + PRBool mInsideSelect1; }; -NS_IMPL_ISUPPORTS_INHERITED1(nsXFormsItemElement, - nsXFormsStubElement, - nsIXFormsSelectChild) +NS_IMPL_ISUPPORTS_INHERITED2(nsXFormsItemElement, + nsXFormsBindableStub, + nsIXFormsSelectChild, + nsIXFormsItemElement) NS_IMETHODIMP -nsXFormsItemElement::OnCreated(nsIXTFGenericElementWrapper *aWrapper) +nsXFormsItemElement::OnCreated(nsIXTFBindableElementWrapper *aWrapper) { aWrapper->SetNotificationMask(nsIXTFElement::NOTIFY_PARENT_CHANGED | nsIXTFElement::NOTIFY_CHILD_INSERTED | nsIXTFElement::NOTIFY_CHILD_APPENDED | nsIXTFElement::NOTIFY_WILL_REMOVE_CHILD | - nsIXTFElement::NOTIFY_BEGIN_ADDING_CHILDREN); + nsIXTFElement::NOTIFY_BEGIN_ADDING_CHILDREN | + nsIXTFElement::NOTIFY_DONE_ADDING_CHILDREN); nsCOMPtr node; aWrapper->GetElementNode(getter_AddRefs(node)); @@ -124,10 +132,11 @@ nsXFormsItemElement::OnCreated(nsIXTFGenericElementWrapper *aWrapper) mElement = node; NS_ASSERTION(mElement, "Wrapper is not an nsIDOMElement, we'll crash soon"); - // Our anonymous content structure will look like this: + // Our anonymous content structure in nsCOMPtr domDoc; node->GetOwnerDocument(getter_AddRefs(domDoc)); @@ -146,8 +155,21 @@ nsXFormsItemElement::OnCreated(nsIXTFGenericElementWrapper *aWrapper) NS_IMETHODIMP nsXFormsItemElement::ParentChanged(nsIDOMElement *aNewParent) { - if (aNewParent) + mInsideSelect1 = PR_FALSE; + if (aNewParent) { + nsCOMPtr parent, tmp; + mElement->GetParentNode(getter_AddRefs(parent)); + while (parent) { + if (nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select1"))) { + mInsideSelect1 = PR_TRUE; + break; + } + tmp.swap(parent); + tmp->GetParentNode(getter_AddRefs(parent)); + } + Refresh(); + } return NS_OK; } @@ -240,6 +262,22 @@ nsXFormsItemElement::GetAnonymousNodes(nsIArray **aNodes) return NS_OK; } +NS_IMETHODIMP +nsXFormsItemElement::SelectItemByValue(const nsAString &aValue, nsIDOMNode **aSelected) +{ + NS_ENSURE_ARG_POINTER(aSelected); + NS_ENSURE_STATE(mElement); + nsAutoString value; + GetValue(value); + if (aValue.Equals(value)) { + NS_ADDREF(*aSelected = mElement); + } else { + *aSelected = nsnull; + } + + return NS_OK; +} + NS_IMETHODIMP nsXFormsItemElement::SelectItemsByValue(const nsStringArray &aValueList) { @@ -298,14 +336,26 @@ nsXFormsItemElement::SetContext(nsIDOMElement *aContextNode, return NS_OK; } -// internal methods - -nsresult -nsXFormsItemElement::GetValue(nsString &aValue) +NS_IMETHODIMP +nsXFormsItemElement::GetValue(nsAString &aValue) { + + nsCOMPtr firstChild, container; + mElement->GetFirstChild(getter_AddRefs(firstChild)); + + // If this element is generated inside an , + // there is a element between this element + // and the actual childnodes. + if (nsXFormsUtils::IsXFormsElement(firstChild, + NS_LITERAL_STRING("contextcontainer"))) { + container = firstChild; + } else { + container = mElement; + } + // Find our value child and get its text content. nsCOMPtr children; - nsresult rv = mElement->GetChildNodes(getter_AddRefs(children)); + nsresult rv = container->GetChildNodes(getter_AddRefs(children)); NS_ENSURE_SUCCESS(rv, rv); PRUint32 childCount; @@ -330,6 +380,12 @@ nsXFormsItemElement::GetValue(nsString &aValue) NS_IMETHODIMP nsXFormsItemElement::Refresh() { + if (mInsideSelect1) { + // is XBLized, so there is no need to recreate UI - + // XBL will do it for us. + return NS_OK; + } + // Clear out all of the existing option text nsCOMPtr child, child2; while (NS_SUCCEEDED(mOption->GetFirstChild(getter_AddRefs(child))) && child) @@ -382,6 +438,91 @@ nsXFormsItemElement::Refresh() return NS_OK; } +NS_IMETHODIMP +nsXFormsItemElement::SetActive(PRBool aActive) +{ + /// @see comment in nsIXFormsItemElement.idl + + NS_NAMED_LITERAL_STRING(active, "_moz_active"); + + return aActive ? + mElement->SetAttribute(active, NS_LITERAL_STRING("1")) : + mElement->RemoveAttribute(active); +} + +NS_IMETHODIMP +nsXFormsItemElement::GetLabelText(nsAString& aValue) +{ + NS_ENSURE_STATE(mElement); + aValue.Truncate(0); + + nsCOMPtr firstChild, container; + mElement->GetFirstChild(getter_AddRefs(firstChild)); + + // If this element is generated inside an , + // there is a element between this element + // and the actual childnodes. + if (nsXFormsUtils::IsXFormsElement(firstChild, + NS_LITERAL_STRING("contextcontainer"))) { + container = firstChild; + } else { + container = mElement; + } + + nsCOMPtr children; + container->GetChildNodes(getter_AddRefs(children)); + NS_ENSURE_STATE(children); + + PRUint32 childCount; + children->GetLength(&childCount); + + nsCOMPtr doc; + mElement->GetOwnerDocument(getter_AddRefs(doc)); + + nsCOMPtr child; + for (PRUint32 i = 0; i < childCount; ++i) { + children->Item(i, getter_AddRefs(child)); + if (nsXFormsUtils::IsXFormsElement(child, NS_LITERAL_STRING("label"))) { + nsCOMPtr label(do_QueryInterface(child)); + if (label) { + label->GetTextValue(aValue); + return NS_OK; + } + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXFormsItemElement::LabelRefreshed() +{ + nsCOMPtr domDoc; + mElement->GetOwnerDocument(getter_AddRefs(domDoc)); + nsCOMPtr doc = do_QueryInterface(domDoc); + // This is an optimization. It prevents us doing some of the unnecessary + // refreshes. + if (doc && doc->GetProperty(nsXFormsAtoms::deferredBindListProperty)) { + return NS_OK; + } + + NS_ENSURE_STATE(mElement); + nsCOMPtr parent, current; + current = mElement; + do { + current->GetParentNode(getter_AddRefs(parent)); + if (nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select1"))) { + nsCOMPtr select1(do_QueryInterface(parent)); + if (select1) { + select1->Refresh(); + } + return NS_OK; + } + current = parent; + } while(current); + return NS_OK; +} + NS_HIDDEN_(nsresult) NS_NewXFormsItemElement(nsIXTFElement **aResult) { diff --git a/mozilla/extensions/xforms/nsXFormsItemSetElement.cpp b/mozilla/extensions/xforms/nsXFormsItemSetElement.cpp index 4074e74e8ef..77399ce8c61 100644 --- a/mozilla/extensions/xforms/nsXFormsItemSetElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsItemSetElement.cpp @@ -41,7 +41,7 @@ #include "nsIDOMHTMLOptGroupElement.h" #include "nsString.h" #include "nsCOMPtr.h" -#include "nsIXTFGenericElementWrapper.h" +#include "nsIXTFBindableElementWrapper.h" #include "nsIDOMDocument.h" #include "nsIDOMNodeList.h" #include "nsIDocument.h" @@ -50,8 +50,9 @@ #include "nsArray.h" #include "nsIXFormsControlBase.h" #include "nsIXFormsControl.h" +#include "nsIXFormsItemSetUIElement.h" -class nsXFormsItemSetElement : public nsXFormsStubElement, +class nsXFormsItemSetElement : public nsXFormsBindableStub, public nsIXFormsSelectChild, public nsIXFormsControlBase { @@ -60,8 +61,7 @@ public: NS_DECL_ISUPPORTS_INHERITED - // nsIXTFGenericElement overrides - NS_IMETHOD OnCreated(nsIXTFGenericElementWrapper *aWrapper); + NS_IMETHOD OnCreated(nsIXTFBindableElementWrapper *aWrapper); // nsIXTFElement overrides NS_IMETHOD ParentChanged(nsIDOMElement *aNewParent); @@ -84,12 +84,12 @@ private: }; NS_IMPL_ISUPPORTS_INHERITED2(nsXFormsItemSetElement, - nsXFormsStubElement, + nsXFormsBindableStub, nsIXFormsSelectChild, nsIXFormsControlBase) NS_IMETHODIMP -nsXFormsItemSetElement::OnCreated(nsIXTFGenericElementWrapper *aWrapper) +nsXFormsItemSetElement::OnCreated(nsIXTFBindableElementWrapper *aWrapper) { aWrapper->SetNotificationMask(nsIXTFElement::NOTIFY_PARENT_CHANGED | nsIXTFElement::NOTIFY_CHILD_INSERTED | @@ -203,6 +203,37 @@ nsXFormsItemSetElement::GetAnonymousNodes(nsIArray **aNodes) return NS_OK; } +NS_IMETHODIMP +nsXFormsItemSetElement::SelectItemByValue(const nsAString &aValue, nsIDOMNode **aSelected) +{ + NS_ENSURE_ARG_POINTER(aSelected); + NS_ENSURE_STATE(mElement); + *aSelected = nsnull; + // nsIXFormsItemSetUIElement is implemented by the XBL binding. + nsCOMPtr uiItemSet(do_QueryInterface(mElement)); + NS_ENSURE_STATE(uiItemSet); + + nsCOMPtr anonContent; + uiItemSet->GetAnonymousItemSetContent(getter_AddRefs(anonContent)); + NS_ENSURE_STATE(anonContent); + + nsCOMPtr child, tmp; + anonContent->GetFirstChild(getter_AddRefs(child)); + // Trying to select the first possible (generated) \ element. + while (child) { + nsCOMPtr selectChild(do_QueryInterface(tmp)); + if (selectChild) { + selectChild->SelectItemByValue(aValue, aSelected); + if (*aSelected) { + return NS_OK; + } + } + tmp.swap(child); + tmp->GetNextSibling(getter_AddRefs(child)); + } + return NS_OK; +} + NS_IMETHODIMP nsXFormsItemSetElement::SelectItemsByValue(const nsStringArray &aValueList) { @@ -271,8 +302,8 @@ nsXFormsItemSetElement::Refresh() if (!result) return NS_OK; - nsCOMPtr node, templateNode, cloneNode; - nsCOMPtr itemNode, itemWrapperNode; + nsCOMPtr node, templateNode, cloneNode, tmpNode; + nsCOMPtr itemNode, itemWrapperNode, contextContainer; nsCOMPtr templateNodes; mElement->GetChildNodes(getter_AddRefs(templateNodes)); PRUint32 templateNodeCount = 0; @@ -287,37 +318,106 @@ nsXFormsItemSetElement::Refresh() PRUint32 nodeCount; result->GetSnapshotLength(&nodeCount); - for (PRUint32 i = 0; i < nodeCount; ++i) { - result->SnapshotItem(i, getter_AddRefs(node)); - NS_ASSERTION(node, "incorrect snapshot length"); - - document->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS), - NS_LITERAL_STRING("item"), - getter_AddRefs(itemNode)); - - if (!itemNode) - return NS_OK; - - nsCOMPtr modelElement = do_QueryInterface(model); - nsAutoString modelID; - modelElement->GetAttribute(NS_LITERAL_STRING("id"), modelID); - - itemNode->SetAttribute(NS_LITERAL_STRING("model"), modelID); - - nsCOMPtr item = do_QueryInterface(itemNode); - NS_ASSERTION(item, "item must be a SelectChild!"); - - item->SetContext(nsCOMPtr(do_QueryInterface(node)), - i, nodeCount); - - // Clone the template content under the item - for (PRUint32 j = 0; j < templateNodeCount; ++j) { - templateNodes->Item(j, getter_AddRefs(templateNode)); - templateNode->CloneNode(PR_TRUE, getter_AddRefs(cloneNode)); - itemNode->AppendChild(cloneNode, getter_AddRefs(templateNode)); + // XXX Possibly cleanup this when XBLizing