XForms bug 281668 - select1 as a combobox. patch my smaug, r=beaufour,me a=mkaply

This commit is contained in:
doronr%us.ibm.com 2005-08-03 18:43:45 +00:00
Родитель 5df47986a3
Коммит 1bd0a8902f
22 изменённых файлов: 1647 добавлений и 255 удалений

Просмотреть файл

@ -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)