зеркало из https://github.com/mozilla/gecko-dev.git
XForms bug 281668 - select1 as a combobox. patch my smaug, r=beaufour,me a=mkaply
This commit is contained in:
Родитель
5df47986a3
Коммит
1bd0a8902f
|
@ -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 \
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 <Olli.Pettay@helsinki.fi> (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 \<label\> 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 \<label\> child element whenever it is refreshed.
|
||||
* This information will be propagated by the \<item\> to the nearest
|
||||
* \<select1\> element, which can then refresh its UI.
|
||||
*/
|
||||
void labelRefreshed();
|
||||
};
|
|
@ -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 <Olli.Pettay@helsinki.fi> (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 \<item\> elements.
|
||||
*/
|
||||
readonly attribute nsIDOMElement anonymousItemSetContent;
|
||||
};
|
|
@ -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 <Olli.Pettay@helsinki.fi> (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 \<label\> element.
|
||||
*/
|
||||
readonly attribute AString textValue;
|
||||
};
|
|
@ -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 \<select\>.
|
||||
*
|
||||
*/
|
||||
[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 \<select1\>. If the XFormsSelectChild is or
|
||||
* contains an \<item\>, which has the same value as the parameter |value|,
|
||||
* this method returns that \<item\>.
|
||||
*/
|
||||
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
|
||||
|
|
|
@ -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 \<choices\> 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<nsIDOMHTMLOptGroupElement> 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<nsIDOMElement> 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 <select> will look like this:
|
||||
//
|
||||
// <optgroup label="myLabel"/> (mOptGroup)
|
||||
//
|
||||
// <select1>'s anonymous content is created in XBL.
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
node->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
|
||||
//XXX Remove this when XBLizing <select>.
|
||||
nsCOMPtr<nsIDOMElement> 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<nsIDOMNode> 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<nsIDOMNodeList> children;
|
||||
nsresult rv = mElement->GetChildNodes(getter_AddRefs(children));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 childCount = 0;
|
||||
children->GetLength(&childCount);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> childNode;
|
||||
nsCOMPtr<nsIXFormsSelectChild> 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) {
|
||||
// <select1> 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<nsIDOMNode> firstChild, child2;
|
||||
|
|
|
@ -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<nsIDOMElement> 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<nsIDOMDocument> 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;
|
||||
|
|
|
@ -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<nsIXFormsUIWidget> 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<nsIDOMNode> 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
|
||||
|
|
|
@ -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) {}
|
||||
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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 \<input\>, \<secret\>, and \<textarea\> 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<nsIDOMNode> 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;
|
||||
|
||||
|
|
|
@ -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 \<item\> 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<nsIDOMHTMLOptionElement> mOption;
|
||||
|
||||
// context node (used by itemset)
|
||||
nsCOMPtr<nsIDOMElement> mContextNode;
|
||||
PRInt32 mContextPosition;
|
||||
PRInt32 mContextSize;
|
||||
// context node (used by itemset in select)
|
||||
nsCOMPtr<nsIDOMElement> 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<nsIDOMElement> 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 <select> will look like this:
|
||||
//
|
||||
// <option/> (mOption, also insertion point)
|
||||
//
|
||||
//XXX Remove when XBLizing <select>
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> 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<nsIDOMNode> 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<nsIDOMNode> firstChild, container;
|
||||
mElement->GetFirstChild(getter_AddRefs(firstChild));
|
||||
|
||||
// If this element is generated inside an <itemset>,
|
||||
// there is a <contextcontainer> 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<nsIDOMNodeList> 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) {
|
||||
// <select1> 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<nsIDOMNode> 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<nsIDOMNode> firstChild, container;
|
||||
mElement->GetFirstChild(getter_AddRefs(firstChild));
|
||||
|
||||
// If this element is generated inside an <itemset>,
|
||||
// there is a <contextcontainer> element between this element
|
||||
// and the actual childnodes.
|
||||
if (nsXFormsUtils::IsXFormsElement(firstChild,
|
||||
NS_LITERAL_STRING("contextcontainer"))) {
|
||||
container = firstChild;
|
||||
} else {
|
||||
container = mElement;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> children;
|
||||
container->GetChildNodes(getter_AddRefs(children));
|
||||
NS_ENSURE_STATE(children);
|
||||
|
||||
PRUint32 childCount;
|
||||
children->GetLength(&childCount);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
mElement->GetOwnerDocument(getter_AddRefs(doc));
|
||||
|
||||
nsCOMPtr<nsIDOMNode> child;
|
||||
for (PRUint32 i = 0; i < childCount; ++i) {
|
||||
children->Item(i, getter_AddRefs(child));
|
||||
if (nsXFormsUtils::IsXFormsElement(child, NS_LITERAL_STRING("label"))) {
|
||||
nsCOMPtr<nsIXFormsLabelElement> label(do_QueryInterface(child));
|
||||
if (label) {
|
||||
label->GetTextValue(aValue);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsItemElement::LabelRefreshed()
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mElement->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> 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<nsIDOMNode> parent, current;
|
||||
current = mElement;
|
||||
do {
|
||||
current->GetParentNode(getter_AddRefs(parent));
|
||||
if (nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select1"))) {
|
||||
nsCOMPtr<nsIXFormsControl> 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)
|
||||
{
|
||||
|
|
|
@ -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<nsIXFormsItemSetUIElement> uiItemSet(do_QueryInterface(mElement));
|
||||
NS_ENSURE_STATE(uiItemSet);
|
||||
|
||||
nsCOMPtr<nsIDOMElement> anonContent;
|
||||
uiItemSet->GetAnonymousItemSetContent(getter_AddRefs(anonContent));
|
||||
NS_ENSURE_STATE(anonContent);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> child, tmp;
|
||||
anonContent->GetFirstChild(getter_AddRefs(child));
|
||||
// Trying to select the first possible (generated) \<item\> element.
|
||||
while (child) {
|
||||
nsCOMPtr<nsIXFormsSelectChild> 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<nsIDOMNode> node, templateNode, cloneNode;
|
||||
nsCOMPtr<nsIDOMElement> itemNode, itemWrapperNode;
|
||||
nsCOMPtr<nsIDOMNode> node, templateNode, cloneNode, tmpNode;
|
||||
nsCOMPtr<nsIDOMElement> itemNode, itemWrapperNode, contextContainer;
|
||||
nsCOMPtr<nsIDOMNodeList> 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<nsIDOMElement> modelElement = do_QueryInterface(model);
|
||||
nsAutoString modelID;
|
||||
modelElement->GetAttribute(NS_LITERAL_STRING("id"), modelID);
|
||||
|
||||
itemNode->SetAttribute(NS_LITERAL_STRING("model"), modelID);
|
||||
|
||||
nsCOMPtr<nsIXFormsSelectChild> item = do_QueryInterface(itemNode);
|
||||
NS_ASSERTION(item, "item must be a SelectChild!");
|
||||
|
||||
item->SetContext(nsCOMPtr<nsIDOMElement>(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 <select>.
|
||||
nsCOMPtr<nsIDOMNode> parent, tmp;
|
||||
mElement->GetParentNode(getter_AddRefs(parent));
|
||||
PRBool parentIsSelect1 = PR_FALSE;
|
||||
while (parent &&
|
||||
!nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select"))) {
|
||||
if (nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select1"))) {
|
||||
parentIsSelect1 = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
tmp.swap(parent);
|
||||
tmp->GetParentNode(getter_AddRefs(parent));
|
||||
}
|
||||
|
||||
if (parentIsSelect1) {
|
||||
// For select1
|
||||
nsCOMPtr<nsIXFormsItemSetUIElement> uiItemSet(do_QueryInterface(mElement));
|
||||
nsCOMPtr<nsIDOMElement> anonContent;
|
||||
if (uiItemSet) {
|
||||
uiItemSet->GetAnonymousItemSetContent(getter_AddRefs(anonContent));
|
||||
}
|
||||
|
||||
mItems.AppendObject(item);
|
||||
NS_ENSURE_STATE(anonContent);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> childNode, nodeReturn;
|
||||
while (NS_SUCCEEDED(anonContent->GetFirstChild(getter_AddRefs(childNode))) &&
|
||||
childNode) {
|
||||
anonContent->RemoveChild(childNode, getter_AddRefs(nodeReturn));
|
||||
}
|
||||
|
||||
for (PRUint32 i = 0; i < nodeCount; ++i) {
|
||||
result->SnapshotItem(i, getter_AddRefs(node));
|
||||
NS_ASSERTION(node, "incorrect snapshot length");
|
||||
|
||||
nsresult rv = document->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS),
|
||||
NS_LITERAL_STRING("item"),
|
||||
getter_AddRefs(itemNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// XXX Could we get rid of the <contextcontainer>?
|
||||
rv = document->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS),
|
||||
NS_LITERAL_STRING("contextcontainer"),
|
||||
getter_AddRefs(contextContainer));
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMElement> modelElement = do_QueryInterface(model);
|
||||
nsAutoString modelID;
|
||||
modelElement->GetAttribute(NS_LITERAL_STRING("id"), modelID);
|
||||
|
||||
contextContainer->SetAttribute(NS_LITERAL_STRING("model"), modelID);
|
||||
|
||||
nsCOMPtr<nsIXFormsContextControl> ctx(do_QueryInterface(contextContainer));
|
||||
if (ctx) {
|
||||
ctx->SetContext(nsCOMPtr<nsIDOMElement>(do_QueryInterface(node)),
|
||||
i + 1, 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));
|
||||
contextContainer->AppendChild(cloneNode, getter_AddRefs(templateNode));
|
||||
}
|
||||
|
||||
itemNode->AppendChild(contextContainer, getter_AddRefs(tmpNode));
|
||||
anonContent->AppendChild(itemNode, getter_AddRefs(tmpNode));
|
||||
}
|
||||
} else {
|
||||
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<nsIDOMElement> modelElement = do_QueryInterface(model);
|
||||
nsAutoString modelID;
|
||||
modelElement->GetAttribute(NS_LITERAL_STRING("id"), modelID);
|
||||
|
||||
itemNode->SetAttribute(NS_LITERAL_STRING("model"), modelID);
|
||||
|
||||
nsCOMPtr<nsIXFormsSelectChild> item = do_QueryInterface(itemNode);
|
||||
NS_ASSERTION(item, "item must be a SelectChild!");
|
||||
|
||||
item->SetContext(nsCOMPtr<nsIDOMElement>(do_QueryInterface(node)),
|
||||
i + 1, 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));
|
||||
}
|
||||
|
||||
mItems.AppendObject(item);
|
||||
}
|
||||
}
|
||||
|
||||
// refresh parent control, since we are being defered
|
||||
|
|
|
@ -56,22 +56,27 @@
|
|||
#include "nsIXFormsUIWidget.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIXFormsLabelElement.h"
|
||||
#include "nsIXFormsItemElement.h"
|
||||
|
||||
class nsXFormsLabelElement : public nsXFormsDelegateStub,
|
||||
public nsIStreamListener,
|
||||
public nsIInterfaceRequestor
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIXFormsLabelElement
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSIXFORMSLABELELEMENT
|
||||
|
||||
// nsIXFormsDelegate
|
||||
NS_IMETHOD GetValue(nsAString& aValue);
|
||||
|
||||
// nsIXFormsControl
|
||||
NS_IMETHOD IsEventTarget(PRBool *aOK);
|
||||
NS_IMETHOD Refresh();
|
||||
|
||||
NS_IMETHOD OnCreated(nsIXTFBindableElementWrapper *aWrapper);
|
||||
|
||||
|
@ -92,11 +97,12 @@ private:
|
|||
nsCOMPtr<nsIChannel> mChannel;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED3(nsXFormsLabelElement,
|
||||
NS_IMPL_ISUPPORTS_INHERITED4(nsXFormsLabelElement,
|
||||
nsXFormsDelegateStub,
|
||||
nsIRequestObserver,
|
||||
nsIStreamListener,
|
||||
nsIInterfaceRequestor)
|
||||
nsIInterfaceRequestor,
|
||||
nsIXFormsLabelElement)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsLabelElement::OnCreated(nsIXTFBindableElementWrapper *aWrapper)
|
||||
|
@ -237,6 +243,30 @@ nsXFormsLabelElement::LoadExternalLabel(const nsAString& aSrc)
|
|||
|
||||
// nsIXFormsControl
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsLabelElement::Refresh()
|
||||
{
|
||||
nsXFormsDelegateStub::Refresh();
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
mElement->GetParentNode(getter_AddRefs(parent));
|
||||
|
||||
// If <label> is inside <select1> its parent is <item>
|
||||
// or <contextcontainer> (which parent is <item>).
|
||||
nsCOMPtr<nsIXFormsItemElement> item(do_QueryInterface(parent));
|
||||
if (item) {
|
||||
item->LabelRefreshed();
|
||||
} else if (parent) {
|
||||
nsCOMPtr<nsIDOMNode> grandparent;
|
||||
parent->GetParentNode(getter_AddRefs(grandparent));
|
||||
item = do_QueryInterface(grandparent);
|
||||
if (item) {
|
||||
item->LabelRefreshed();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsLabelElement::IsEventTarget(PRBool *aOK)
|
||||
{
|
||||
|
@ -332,6 +362,21 @@ nsXFormsLabelElement::OnStopRequest(nsIRequest *aRequest,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsLabelElement::GetTextValue(nsAString& aValue)
|
||||
{
|
||||
NS_ENSURE_STATE(mElement);
|
||||
GetValue(aValue);
|
||||
|
||||
if (aValue.IsVoid()) {
|
||||
nsCOMPtr<nsIDOM3Node> inner(do_QueryInterface(mElement));
|
||||
if (inner) {
|
||||
inner->GetTextContent(aValue);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_HIDDEN_(nsresult)
|
||||
NS_NewXFormsLabelElement(nsIXTFElement **aResult)
|
||||
|
|
|
@ -216,6 +216,12 @@ nsPostRefresh::~nsPostRefresh()
|
|||
}
|
||||
}
|
||||
|
||||
const nsVoidArray*
|
||||
nsPostRefresh::PostRefreshList()
|
||||
{
|
||||
return sPostRefreshList;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXFormsModelElement::NeedsPostRefresh(nsIXFormsControl* aControl)
|
||||
{
|
||||
|
|
|
@ -228,6 +228,7 @@ class nsPostRefresh {
|
|||
public:
|
||||
nsPostRefresh();
|
||||
~nsPostRefresh();
|
||||
static const nsVoidArray* PostRefreshList();
|
||||
};
|
||||
|
||||
NS_HIDDEN_(nsresult) NS_NewXFormsModelElement(nsIXTFElement **aResult);
|
||||
|
|
|
@ -75,10 +75,6 @@ public:
|
|||
NS_IMETHOD Bind();
|
||||
NS_IMETHOD Refresh();
|
||||
|
||||
#ifdef DEBUG_smaug
|
||||
virtual const char* Name() { return "output"; }
|
||||
#endif
|
||||
|
||||
// nsIXFormsDelegate
|
||||
NS_IMETHOD GetValue(nsAString& aValue);
|
||||
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
/* -*- 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 <Olli.Pettay@helsinki.fi> (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 ***** */
|
||||
|
||||
/**
|
||||
* Implementation of the XForms \<select1\> element.
|
||||
*/
|
||||
|
||||
#include "nsXFormsUtils.h"
|
||||
#include "nsXFormsControlStub.h"
|
||||
#include "nsXFormsDelegateStub.h"
|
||||
#include "nsXFormsAtoms.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMXPathResult.h"
|
||||
#include "nsIDOM3Node.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMText.h"
|
||||
#include "nsIXTFXMLVisualWrapper.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIXFormsUIWidget.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsXFormsModelElement.h"
|
||||
|
||||
class nsXFormsSelect1Element : public nsXFormsDelegateStub
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_IMETHOD OnCreated(nsIXTFBindableElementWrapper *aWrapper);
|
||||
|
||||
// nsIXTFElement overrides
|
||||
NS_IMETHOD ChildInserted(nsIDOMNode *aChild, PRUint32 aIndex);
|
||||
NS_IMETHOD ChildAppended(nsIDOMNode *aChild);
|
||||
NS_IMETHOD ChildRemoved(PRUint32 aIndex);
|
||||
NS_IMETHOD BeginAddingChildren();
|
||||
NS_IMETHOD DoneAddingChildren();
|
||||
|
||||
nsXFormsSelect1Element(const nsAString& aType)
|
||||
: nsXFormsDelegateStub(aType)
|
||||
{}
|
||||
protected:
|
||||
PRBool mAddingChildren;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsXFormsSelect1Element,
|
||||
nsXFormsDelegateStub)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsSelect1Element::OnCreated(nsIXTFBindableElementWrapper *aWrapper)
|
||||
{
|
||||
mAddingChildren = PR_FALSE;
|
||||
nsresult rv = nsXFormsDelegateStub::OnCreated(aWrapper);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aWrapper->SetNotificationMask(kStandardNotificationMask |
|
||||
nsIXTFElement::NOTIFY_CHILD_INSERTED |
|
||||
nsIXTFElement::NOTIFY_CHILD_APPENDED |
|
||||
nsIXTFElement::NOTIFY_CHILD_REMOVED |
|
||||
nsIXTFElement::NOTIFY_BEGIN_ADDING_CHILDREN |
|
||||
nsIXTFElement::NOTIFY_DONE_ADDING_CHILDREN);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsSelect1Element::BeginAddingChildren()
|
||||
{
|
||||
mAddingChildren = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsSelect1Element::DoneAddingChildren()
|
||||
{
|
||||
mAddingChildren = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsSelect1Element::ChildInserted(nsIDOMNode *aChild, PRUint32 aIndex)
|
||||
{
|
||||
if (!mAddingChildren) {
|
||||
Refresh();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsSelect1Element::ChildAppended(nsIDOMNode *aChild)
|
||||
{
|
||||
if (!mAddingChildren) {
|
||||
Refresh();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsSelect1Element::ChildRemoved(PRUint32 aIndex)
|
||||
{
|
||||
if (!mAddingChildren) {
|
||||
Refresh();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_HIDDEN_(nsresult)
|
||||
NS_NewXFormsSelect1Element(nsIXTFElement **aResult)
|
||||
{
|
||||
*aResult = new nsXFormsSelect1Element(NS_LITERAL_STRING("select1"));
|
||||
if (!*aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,687 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!-- ***** 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 <Olli.Pettay@helsinki.fi>
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either 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 ***** -->
|
||||
|
||||
<bindings id="select1Bindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xforms="http://www.w3.org/2002/xforms">
|
||||
|
||||
<!-- select1 -->
|
||||
<binding id="xformswidget-select1"
|
||||
extends="chrome://xforms/content/xforms.xml#xformswidget-base">
|
||||
|
||||
<!-- The strange indentation is because of the whitespace nodes.-->
|
||||
<content>
|
||||
<children includes="label"/>
|
||||
<html:div class="-moz-xforms-select1-popup" anonid="popup"
|
||||
onmouseover="this.parentNode.shouldHandleBlur = false;
|
||||
this.parentNode.mouseOver(event);"
|
||||
onmouseup="this.parentNode.mouseUp(event);"
|
||||
onmouseout="this.parentNode.shouldHandleBlur = true;">
|
||||
<children/>
|
||||
</html:div>
|
||||
<html:span class="-moz-select1-container"
|
||||
anonid="container"><html:input
|
||||
class="-moz-xforms-select1-input"
|
||||
anonid="control"
|
||||
onblur="this.parentNode.parentNode.handleBlur();"
|
||||
onclick="this.parentNode.parentNode.handleControlClick();"
|
||||
onkeypress="this.parentNode.parentNode.handleKeyPress(event);"
|
||||
onkeyup="this.parentNode.parentNode.handleKeyUp(event);"
|
||||
/><html:input class="-moz-xforms-select1-dropdown"
|
||||
type="button"
|
||||
anonid="dropmarker"
|
||||
tabindex="-1"
|
||||
onmousedown="this.parentNode.parentNode.shouldHandleBlur = false;"
|
||||
onmouseup="this.parentNode.parentNode.shouldHandleBlur = true;"
|
||||
onclick="this.parentNode.parentNode.togglePopup();
|
||||
this.previousSibling.focus();"
|
||||
/></html:span></content>
|
||||
|
||||
<implementation implements="nsIXFormsUIWidget">
|
||||
<field name="_inputField">null</field>
|
||||
<field name="_dropMarker">null</field>
|
||||
<field name="_popup">null</field>
|
||||
<field name="_container">null</field>
|
||||
<field name="_width">-1</field>
|
||||
|
||||
<!-- This is either an nsIXFormsItemElement or null. -->
|
||||
<field name="_selected">null</field>
|
||||
<field name="_tmpSelected">null</field>
|
||||
<field name="popupOpen">false</field>
|
||||
<field name="shouldHandleBlur">true</field>
|
||||
|
||||
<property name="selectionOpen" readonly="true">
|
||||
<getter>
|
||||
return this.getAttribute("selection") == "open";
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<property name="inputField" readonly="true">
|
||||
<getter>
|
||||
if (!this._inputField) {
|
||||
this._inputField =
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "control");
|
||||
}
|
||||
return this._inputField;
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<property name="dropMarker" readonly="true">
|
||||
<getter>
|
||||
if (!this._dropMarker) {
|
||||
this._dropMarker =
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "dropmarker");
|
||||
}
|
||||
return this._dropMarker;
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<property name="popup" readonly="true">
|
||||
<getter>
|
||||
if (!this._popup) {
|
||||
this._popup =
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "popup");
|
||||
}
|
||||
return this._popup;
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<property name="container" readonly="true">
|
||||
<getter>
|
||||
if (!this._container) {
|
||||
this._container =
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "container");
|
||||
}
|
||||
return this._container;
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<method name="updateInputField">
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (this._selected) {
|
||||
// Remove extra white space characters from the beginning of the label.
|
||||
this.inputField.value = this._selected.labelText.replace(/^[\s\n]+/, "");
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="handleControlClick">
|
||||
<parameter name="aEvent"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (this.selectionOpen && !this._selected) {
|
||||
if (this.getAttribute("incremental") != "false") {
|
||||
this.delegate.value = this.inputField.value;
|
||||
}
|
||||
} else {
|
||||
this.togglePopup();
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="handleKeyPress">
|
||||
<parameter name="aEvent"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var key = aEvent.keyCode;
|
||||
if (key == aEvent.DOM_VK_RETURN || key == aEvent.DOM_VK_ENTER) {
|
||||
var open = this.popupOpen;
|
||||
this.togglePopup();
|
||||
if (open && this._selected) {
|
||||
this.updateInputField();
|
||||
this.delegate.value = this._selected.value;
|
||||
}
|
||||
} else if (key == aEvent.DOM_VK_UP ||
|
||||
key == aEvent.DOM_VK_DOWN) {
|
||||
this.internalScroll(aEvent.keyCode == aEvent.DOM_VK_DOWN);
|
||||
if (this._selected && this.popupOpen) {
|
||||
var el = this._selected.QueryInterface(Components.interfaces.nsIDOMElement);
|
||||
if ("scrollIntoView" in el) {
|
||||
el.scrollIntoView(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.popupOpen && this.getAttribute("incremental") != "false") {
|
||||
if (this._selected) {
|
||||
this.updateInputField();
|
||||
this.delegate.value = this._selected.value;
|
||||
} else if (this.selectionOpen) {
|
||||
this.delegate.value = this.inputField.value;
|
||||
}
|
||||
}
|
||||
} else if (key == aEvent.DOM_VK_TAB) {
|
||||
// Hiding popup when user uses keyboard to focus out
|
||||
// from <select1>. No need to update the value of the control
|
||||
// in this case.
|
||||
if (this._selected && this.popupOpen) {
|
||||
this.hidePopup();
|
||||
this._selected.setActive(false);
|
||||
this._selected = this._tmpSelected;
|
||||
this._tmpSelected = null;
|
||||
if (this._selected) {
|
||||
this._selected.setActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="handleKeyUp">
|
||||
<parameter name="aEvent"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
// These events are handled in handleKeyPress...
|
||||
if (aEvent.keyCode == aEvent.DOM_VK_RETURN ||
|
||||
aEvent.keyCode == aEvent.DOM_VK_ENTER ||
|
||||
aEvent.keyCode == aEvent.DOM_VK_UP ||
|
||||
aEvent.keyCode == aEvent.DOM_VK_DOWN) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ..other key events are handled in keyUp, because otherwise
|
||||
// this.inputField.value doesn't show the just updated value.
|
||||
if (this.selectionOpen) {
|
||||
if (this._selected) {
|
||||
this._selected.setActive(false);
|
||||
this._selected = null;
|
||||
}
|
||||
if (this.getAttribute("incremental") != "false") {
|
||||
this.delegate.value = this.inputField.value;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<!-- This is used by internalScroll to find the next
|
||||
selectable <item>. Returns a DOMElement or null. -->
|
||||
<method name="findNextSelectable">
|
||||
<parameter name="aNode"/>
|
||||
<parameter name="aDown"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (!aNode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var node = aNode;
|
||||
var next = null;
|
||||
while (node) {
|
||||
if (aDown) {
|
||||
next = node.nextSibling;
|
||||
} else {
|
||||
next = node.previousSibling;
|
||||
}
|
||||
|
||||
if (next && next.namespaceURI == this.XFORMS_NS) {
|
||||
if (next.localName == "item") {
|
||||
return next;
|
||||
} else if (next.localName == "choices") {
|
||||
var child = null;
|
||||
if (aDown) {
|
||||
child = next.firstChild;
|
||||
} else {
|
||||
child = next.lastChild;
|
||||
}
|
||||
if (child.namespaceURI == this.XFORMS_NS &&
|
||||
child.localName == "item") {
|
||||
return child;
|
||||
}
|
||||
child = this.findNextSelectable(child, aDown);
|
||||
if (child) {
|
||||
return child;
|
||||
}
|
||||
} else if (next.localName == "itemset" &&
|
||||
next.anonymousItemSetContent.childNodes.length > 0) {
|
||||
return aDown ? next.anonymousItemSetContent.firstChild
|
||||
: next.anonymousItemSetContent.lastChild;
|
||||
}
|
||||
}
|
||||
node = next;
|
||||
}
|
||||
|
||||
// if we are in a choices or itemset element
|
||||
var parent = aNode.parentNode;
|
||||
if (parent.namespaceURI == this.XFORMS_NS &&
|
||||
parent.localName == "choices") {
|
||||
var sibling = aDown ? parent.nextSibling : parent.previousSibling;
|
||||
|
||||
if (sibling.namespaceURI == this.XFORMS_NS &&
|
||||
sibling.localName == "item") {
|
||||
return sibling;
|
||||
}
|
||||
return this.findNextSelectable(sibling, aDown);
|
||||
}
|
||||
|
||||
if (parent.parentNode.namespaceURI == this.XFORMS_NS &&
|
||||
parent.parentNode.localName == "itemset") {
|
||||
var sibling2 = aDown
|
||||
? parent.parentNode.nextSibling
|
||||
: parent.parentNode.previousSibling;
|
||||
|
||||
if (sibling2.namespaceURI == this.XFORMS_NS &&
|
||||
sibling2.localName == "item") {
|
||||
return sibling2;
|
||||
}
|
||||
return this.findNextSelectable(sibling2, aDown);
|
||||
}
|
||||
|
||||
return null;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="internalScroll">
|
||||
<parameter name="aDown"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var label = null;
|
||||
var next = null;
|
||||
var node = this.firstChild;
|
||||
while (node) {
|
||||
if (node.namespaceURI == this.XFORMS_NS &&
|
||||
node.localName == "label") {
|
||||
label = node;
|
||||
break;
|
||||
}
|
||||
node = node.nextSibling;
|
||||
}
|
||||
|
||||
if (this._selected) {
|
||||
node = this._selected.QueryInterface(Components.interfaces.nsIDOMNode);
|
||||
} else if (label) {
|
||||
node = label.nextSibling;
|
||||
} else {
|
||||
node = this.firstChild;
|
||||
}
|
||||
|
||||
next = this.findNextSelectable(node, aDown);
|
||||
if (next) {
|
||||
if (this._selected) {
|
||||
this._selected.setActive(false);
|
||||
this._selected = null;
|
||||
}
|
||||
|
||||
this._selected = next.QueryInterface(Components.interfaces.nsIXFormsItemElement);
|
||||
if (this._selected) {
|
||||
this._selected.setActive(true);
|
||||
this.updateInputField();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!aDown && this.selectionOpen) {
|
||||
if (this._selected) {
|
||||
this._selected.setActive(false);
|
||||
this._selected = null;
|
||||
}
|
||||
this.inputField.value = "";
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="mouseUp">
|
||||
<parameter name="aEvent"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
// Use original target, because <item> is possible (anonymously)
|
||||
// inside <itemset>
|
||||
var target = aEvent.originalTarget;
|
||||
while (target && target != this) {
|
||||
if (target.namespaceURI == this.XFORMS_NS &&
|
||||
(target.localName == "item" || target.localName == "choices")) {
|
||||
break;
|
||||
}
|
||||
target = target.parentNode;
|
||||
}
|
||||
|
||||
if (target == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.hidePopup();
|
||||
|
||||
if (this._selected) {
|
||||
this.updateInputField();
|
||||
this.delegate.value =
|
||||
this._selected.value;
|
||||
}
|
||||
this.inputField.focus();
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="mouseOver">
|
||||
<parameter name="aEvent"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
// Use original target, because <item> is possible (anonymously)
|
||||
// inside <itemset>
|
||||
var target = aEvent.originalTarget;
|
||||
while (target && target != this) {
|
||||
if (target.namespaceURI == this.XFORMS_NS && target.localName == "item") {
|
||||
if (this._selected) {
|
||||
this._selected.setActive(false);
|
||||
this._selected = null;
|
||||
}
|
||||
|
||||
var item =
|
||||
target.QueryInterface(Components.interfaces.nsIXFormsItemElement);
|
||||
if (item) {
|
||||
item.setActive(true);
|
||||
this._selected = item;
|
||||
}
|
||||
break;
|
||||
}
|
||||
target = target.parentNode;
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="hidePopup">
|
||||
<body>
|
||||
this.popup.style.visibility = "hidden";
|
||||
this.popupOpen = false;
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="refreshWidth">
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (!this.popupOpen) {
|
||||
this.inputField.removeAttribute("style");
|
||||
this.popup.style.width = "auto";
|
||||
this.popup.style.height = "auto";
|
||||
this.popup.style.maxHeight = "none";
|
||||
this._width = -1;
|
||||
var popupBox = document.getBoxObjectFor(this.popup);
|
||||
var w = popupBox.width;
|
||||
if (w > 0) {
|
||||
w = w + 12; // Adding some 'padding' for possible scrollbar
|
||||
this.inputField.setAttribute("style", "width:" + w + "px;");
|
||||
this._width = w + document.getBoxObjectFor(this.dropMarker).width;
|
||||
}
|
||||
this.popup.style.maxHeight = "10px";
|
||||
this.popup.style.left = "0px";
|
||||
this.popup.style.top = "0px";
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="togglePopup">
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (!this.popupOpen && !this.delegate.isReadonly) {
|
||||
// Calculating the size and position of the popup.
|
||||
var style = "";
|
||||
var containerBox = document.getBoxObjectFor(this.container);
|
||||
var x = containerBox.x;
|
||||
var y = containerBox.y;
|
||||
var h = containerBox.height;
|
||||
var w = containerBox.width;
|
||||
var targetY = y + h;
|
||||
this.popup.style.maxHeight = "none";
|
||||
var popupBox = document.getBoxObjectFor(this.popup);
|
||||
var popupHeight = popupBox.height;
|
||||
var pY = window.pageYOffset;
|
||||
var iH = window.innerHeight;
|
||||
var belowSelect = iH - (y + h - pY) - h;
|
||||
if (belowSelect < popupHeight) {
|
||||
if ((y - pY) > popupHeight) {
|
||||
targetY = y - popupHeight;
|
||||
} else if (belowSelect < (y - pY)) {
|
||||
style = style + "max-height:" + (y - pY) + "px;";
|
||||
targetY = pY;
|
||||
} else {
|
||||
style = style + "max-height:" + belowSelect + "px;";
|
||||
}
|
||||
}
|
||||
style = style + "left:" + x + "px;";
|
||||
style = style + "top:" + targetY + "px;";
|
||||
|
||||
style = style + "width:";
|
||||
if (this.selectionOpen) {
|
||||
style = style + w + "px;";
|
||||
} else if (this._width < 0) {
|
||||
style = style + "auto;"
|
||||
} else {
|
||||
style = style + this._width + "px;";
|
||||
}
|
||||
|
||||
style = style + "visibility:visible;";
|
||||
this.popup.setAttribute("style", style);
|
||||
this.popupOpen = true;
|
||||
this._tmpSelected = this._selected;
|
||||
|
||||
if (this._selected) {
|
||||
var el = this._selected.QueryInterface(Components.interfaces.nsIDOMElement);
|
||||
if ("scrollIntoView" in el) {
|
||||
el.scrollIntoView(false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.hidePopup();
|
||||
return;
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="refresh">
|
||||
<body>
|
||||
<![CDATA[
|
||||
try {
|
||||
var newValue = this.stringValue;
|
||||
|
||||
if (!this.selectionOpen || this.delegate.isReadonly) {
|
||||
this.inputField.setAttribute("readonly", "readonly");
|
||||
} else {
|
||||
this.inputField.removeAttribute("readonly");
|
||||
}
|
||||
|
||||
if (this._selected) {
|
||||
if (newValue ==
|
||||
this._selected.value) {
|
||||
return true;
|
||||
}
|
||||
this._selected.setActive(false);
|
||||
this._selected = null;
|
||||
}
|
||||
|
||||
this.selectItemByValue(newValue);
|
||||
|
||||
if (this._selected) {
|
||||
this.updateInputField();
|
||||
} else if (this.selectionOpen) {
|
||||
this.inputField.value = newValue;
|
||||
} else {
|
||||
// @todo out-of-range (XXX)
|
||||
this.inputField.value = "";
|
||||
}
|
||||
this.refreshWidth();
|
||||
} catch (ex) {}
|
||||
return true;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="focus">
|
||||
<body>
|
||||
this.inputField.focus();
|
||||
return true;
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="selectItemByValue">
|
||||
<parameter name="aValue"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var node = this.firstChild;
|
||||
var item;
|
||||
while (node) {
|
||||
item = null;
|
||||
try {
|
||||
if (node.nodeType == document.ELEMENT_NODE &&
|
||||
node.namespaceURI == this.XFORMS_NS && node.localName != "label") {
|
||||
|
||||
item = node.QueryInterface(Components.interfaces.nsIXFormsSelectChild);
|
||||
if (item) {
|
||||
item = item.selectItemByValue(aValue);
|
||||
if (item) {
|
||||
if (this._selected) {
|
||||
this._selected.setActive(false);
|
||||
this._selected = null;
|
||||
}
|
||||
this._selected = item.QueryInterface(Components.interfaces.nsIXFormsItemElement);
|
||||
if (this._selected) {
|
||||
this._selected.setActive(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ex) {}
|
||||
node = node.nextSibling;
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="handleBlur">
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (this.shouldHandleBlur) {
|
||||
var open = this.popupOpen;
|
||||
this.hidePopup();
|
||||
|
||||
if (open) {
|
||||
if (this._selected) {
|
||||
this._selected.setActive(false);
|
||||
this._selected = this._tmpSelected;
|
||||
this._tmpSelected = null;
|
||||
if (this._selected) {
|
||||
this._selected.setActive(true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.selectionOpen && !this._selected) {
|
||||
this.delegate.value = this.inputField.value;
|
||||
} else if (this._selected) {
|
||||
this.updateInputField();
|
||||
this.delegate.value = this._selected.value;
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
<binding id="xformswidget-select1-itemset">
|
||||
<content>
|
||||
<html:div style="display:none;">
|
||||
<children/>
|
||||
</html:div>
|
||||
<html:div anonid="insertion"/>
|
||||
</content>
|
||||
|
||||
<implementation implements="nsIXFormsItemSetUIElement">
|
||||
<field name="_anonymousItemSetContent">null</field>
|
||||
|
||||
<property name="anonymousItemSetContent" readonly="true">
|
||||
<getter>
|
||||
if (!this._anonymousItemSetContent) {
|
||||
this._anonymousItemSetContent =
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "insertion");
|
||||
}
|
||||
return this._anonymousItemSetContent;
|
||||
</getter>
|
||||
</property>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
|
||||
<!-- The binding for <item> is needed only because of the
|
||||
scrollIntoView method. -->
|
||||
<binding id="xformswidget-select1-item">
|
||||
<content>
|
||||
<html:div anonid="content">
|
||||
<children/>
|
||||
</html:div>
|
||||
</content>
|
||||
|
||||
<implementation>
|
||||
<field name="_content">null</field>
|
||||
<property name="content" readonly="true">
|
||||
<getter>
|
||||
if (!this._content) {
|
||||
this._content =
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "content");
|
||||
}
|
||||
return this._content;
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<!-- Only (X)HTML elements have method 'scrollIntoView',
|
||||
so we need to forward this method call to the anonymous content
|
||||
of this element. -->
|
||||
<method name="scrollIntoView">
|
||||
<parameter name="aTop"/>
|
||||
<body>
|
||||
this.content.scrollIntoView(aTop);
|
||||
</body>
|
||||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
</bindings>
|
|
@ -34,6 +34,7 @@
|
|||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
@namespace url(http://www.w3.org/2002/xforms);
|
||||
@namespace html url(http://www.w3.org/1999/xhtml);
|
||||
@namespace mozType url(http://www.mozilla.org/projects/xforms/2005/type);
|
||||
|
||||
repeat,
|
||||
|
@ -41,10 +42,23 @@ repeatitem,
|
|||
contextcontainer,
|
||||
group,
|
||||
switch,
|
||||
case {
|
||||
case,
|
||||
select1 item,
|
||||
select1 itemset,
|
||||
select1 choices {
|
||||
display: block;
|
||||
}
|
||||
|
||||
contextcontainer-inline {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
select item,
|
||||
select itemset,
|
||||
select choices {
|
||||
display: none;
|
||||
}
|
||||
|
||||
message[level="ephemeral"], hint {
|
||||
background-color: InfoBackground;
|
||||
color: InfoText;
|
||||
|
@ -94,3 +108,118 @@ trigger[appearance="minimal"]:hover, submit[appearance="minimal"]:hover {
|
|||
label {
|
||||
-moz-binding: url('chrome://xforms/content/xforms.xml#xformswidget-label');
|
||||
}
|
||||
|
||||
select1 {
|
||||
-moz-binding: url('chrome://xforms/content/select1.xml#xformswidget-select1');
|
||||
}
|
||||
|
||||
select1 itemset {
|
||||
-moz-binding: url('chrome://xforms/content/select1.xml#xformswidget-select1-itemset');
|
||||
}
|
||||
|
||||
/* Most of the select1 specific CSS is copied from forms.css */
|
||||
|
||||
select1 item {
|
||||
-moz-binding: url('chrome://xforms/content/select1.xml#xformswidget-select1-item');
|
||||
white-space : nowrap;
|
||||
}
|
||||
|
||||
html|input.-moz-xforms-select1-dropdown {
|
||||
width: 12px;
|
||||
height: 1.3em;
|
||||
white-space: nowrap;
|
||||
position: static !important;
|
||||
background-image: url("data:image/gif;base64,R0lGODlhBwAEAIAAAAAAAP%2F%2F%2FyH5BAEAAAEALAAAAAAHAAQAAAIIhA%2BBGWoNWSgAOw%3D%3D") !important;
|
||||
background-repeat: no-repeat !important;
|
||||
background-position: center !important;
|
||||
-moz-appearance: menulist-button;
|
||||
-moz-user-select: none !important;
|
||||
-moz-user-focus: ignore !important;
|
||||
-moz-binding: none;
|
||||
vertical-align: text-top;
|
||||
margin: 0px !important;
|
||||
margin-top: -1px !important;
|
||||
}
|
||||
|
||||
html|input.-moz-xforms-select1-dropdown::-moz-focus-inner {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
html|input.-moz-xforms-select1-dropdown:active:hover {
|
||||
border-style: outset;
|
||||
}
|
||||
|
||||
html|input.-moz-xforms-select1-input {
|
||||
border: 1px dotted transparent;
|
||||
margin-right: 0px;
|
||||
padding: 0px;
|
||||
font: -moz-list;
|
||||
-moz-box-sizing: border-box;
|
||||
height: 1.3em;
|
||||
line-height: normal !important;
|
||||
}
|
||||
|
||||
html|input.-moz-xforms-select1-input:focus {
|
||||
border: 1px dotted black;
|
||||
}
|
||||
|
||||
html|span.-moz-select1-container {
|
||||
margin: 0px;
|
||||
margin-bottom: 1px;
|
||||
border-color: ThreeDFace;
|
||||
background-color: -moz-Field;
|
||||
color: -moz-FieldText;
|
||||
font: -moz-list;
|
||||
line-height: normal !important;
|
||||
white-space: nowrap !important;
|
||||
text-align: start;
|
||||
cursor: default;
|
||||
-moz-box-sizing: border-box;
|
||||
-moz-appearance: menulist;
|
||||
border-style: inset;
|
||||
text-indent: 0;
|
||||
padding-right: 0px;
|
||||
overflow: hidden;
|
||||
border-width: 2px;
|
||||
padding-bottom: 0px;
|
||||
padding-top: 1px;
|
||||
}
|
||||
|
||||
html|div.-moz-xforms-select1-popup {
|
||||
border-width: 1px;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
border: 1px outset black !important;
|
||||
background-color: -moz-Field;
|
||||
font: -moz-list;
|
||||
text-align: start;
|
||||
visibility: hidden;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
position: absolute;
|
||||
-moz-user-select: none;
|
||||
z-index: 2147482647;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
item[_moz_active] {
|
||||
color: HighlightText;
|
||||
background: Highlight;
|
||||
}
|
||||
|
||||
choices > label {
|
||||
display: block;
|
||||
font: -moz-list;
|
||||
line-height: normal !important;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
font-size: inherit;
|
||||
-moz-user-select: none;
|
||||
text-indent: 0;
|
||||
}
|
||||
|
||||
choices > item, choices > itemset, choices > choices{
|
||||
padding-left: 20px;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,12 @@
|
|||
|
||||
<field name="_delegate">null</field>
|
||||
|
||||
<property name="XFORMS_NS" readonly="true">
|
||||
<getter>
|
||||
return "http://www.w3.org/2002/xforms";
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<property name="delegate" readonly="true">
|
||||
<getter>
|
||||
if (!this._delegate)
|
||||
|
|
Загрузка…
Ссылка в новой задаче