Bug 332083, expose interface xforms:select to control selection, p=surkov, r=me+aaronr

This commit is contained in:
Olli.Pettay%helsinki.fi 2006-10-27 10:49:09 +00:00
parent 513ea03353
commit dea869cf01
8 changed files with 424 additions and 76 deletions

View File

@ -128,6 +128,8 @@ XPIDLSRCS = \
nsIXFormsSwitchElement.idl \
nsIXFormsCaseElement.idl \
nsIXFormsCaseUIElement.idl \
nsIXFormsNSSelect1Element.idl \
nsIXFormsNSSelectElement.idl \
nsIXFormsSelectChild.idl \
nsIXFormsValueElement.idl \
nsIXFormsRepeatElement.idl \

View File

@ -0,0 +1,55 @@
/* -*- Mode: IDL; 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
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
*
* 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 ***** */
#include "nsISupports.idl"
interface nsIDOMNode;
/**
* Defines additional post-spec. methods for the xforms select1 element.
*/
[scriptable, uuid(5ead20bd-1462-4834-a5ad-46a80570de3e)]
interface nsIXFormsNSSelect1Element : nsISupports
{
/**
* Get/set selected xforms item element.
*/
attribute nsIDOMNode selectedItem;
};

View File

@ -0,0 +1,91 @@
/* -*- Mode: IDL; 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
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
*
* 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 ***** */
#include "nsISupports.idl"
interface nsIDOMNode;
interface nsIDOMNodeList;
/**
* Defines additional post-spec. methods for the xforms:select element.
*/
[scriptable, uuid(2740b6ce-a5cc-432d-882e-56290cf6389f)]
interface nsIXFormsNSSelectElement : nsISupports
{
/**
* Get array of selected xforms:item elements.
*/
readonly attribute nsIDOMNodeList selectedItems;
/**
* Select xforms:item element. If xforms:select element has selected items
* then selection for them will be saved.
*
* @param item - xforms:item element.
*/
void addItemToSelection(in nsIDOMNode item);
/**
* Unselect xforms item element. If xforms:select element has other selected
* items then selection for them will be saved.
*
* @param item - xforms:item element.
*/
void removeItemFromSelection(in nsIDOMNode item);
/**
* Unselect all selected xforms:item elements.
*/
void clearSelection();
/**
* Select all xforms:item elements.
*/
void selectAll();
/**
* Check whether given xforms:item element is selected or not.
*
* @param item - xforms item element.
*
* @return - true if given xforms:item element is selected.
*/
boolean isItemSelected(in nsIDOMNode item);
};

View File

@ -56,7 +56,7 @@
All controls are inherited from interface bindings realized in select.xml.
-->
<!-- SELECT/SELECT1 APPEARANCE='COMPACT' : <DEFAULT> -->
<!-- SELECT APPEARANCE='COMPACT' : <DEFAULT> -->
<binding id="xformswidget-select-compact"
extends="chrome://xforms/content/select.xml#xformswidget-select-base">
<content>
@ -70,7 +70,7 @@
</content>
</binding>
<!-- SELECT/SELECT1 APPEARANCE='FULL' -->
<!-- SELECT APPEARANCE='FULL' -->
<binding id="xformswidget-select-full"
extends="chrome://xforms/content/select.xml#xformswidget-select-base">
<content>
@ -86,6 +86,36 @@
</content>
</binding>
<!-- SELECT1 APPEARANCE='COMPACT' : <DEFAULT> -->
<binding id="xformswidget-select1-compact"
extends="chrome://xforms/content/select.xml#xformswidget-select1-base">
<content>
<html:label>
<html:span class="label-container">
<children includes="label"/>
</html:span>
<html:span anonid="control" xbl:inherits="style, accesskey"/>
<children/>
</html:label>
</content>
</binding>
<!-- SELECT1 APPEARANCE='FULL' -->
<binding id="xformswidget-select1-full"
extends="chrome://xforms/content/select.xml#xformswidget-select1-base">
<content>
<html:table xbl:inherits="style">
<html:tr>
<html:td valign="top"><children includes="label"/></html:td>
<html:td>
<html:span anonid="control" xbl:inherits="style, accesskey"/>
</html:td>
</html:tr>
</html:table>
<children/>
</content>
</binding>
<!-- CONTROL WIDGETS FOR SELECT/SELECT1 CONTROLS
All control widgets are underlying controls for select/select1 and serve to
@ -111,10 +141,6 @@
</content>
<implementation>
<property name="selectedIndex"
onget="return this.control.selectedIndex;"
onset="this.control.selectedIndex = val;"/>
<method name="removeAllItems">
<body>
for (var i = this.control.childNodes.length; i > 0; i--) {
@ -212,17 +238,6 @@
extends="chrome://xforms/content/select.xml#controlwidget-nonativewidget-base">
<implementation>
<!-- XXX: not implemented -->
<property name="selectedIndex"
onget="throw new Error(this.selectedIndexErrorMsg);"
onset="throw new Error(this.selectedIndexErrorMsg);"/>
<field name="selectedIndexErrorMsg">
<![CDATA[
"<xforms:select appearance='full'/>: 'selectedIndex' property isn't implemented."
]]>
</field>
<method name="removeAllItems">
<body>
for (var i = this.control.childNodes.length; i > 0; i--) {

View File

@ -66,7 +66,18 @@
</xul:hbox>
<children/>
</content>
</binding>
<binding id="xformswidget-select1"
extends="chrome://xforms/content/select.xml#xformswidget-select1-base">
<content>
<xul:hbox flex="1">
<children includes="label"/>
<xul:box anonid="control" xbl:inherits="style, accesskey"
class="xf-value" flex="1"/>
</xul:hbox>
<children/>
</content>
</binding>
@ -75,8 +86,6 @@
separate binding for each appearance attribute value then it will be happen
automatically.
-->
<binding id="xformswidget-select-minimal"
extends="#xformswidget-select"/>
<binding id="xformswidget-select-compact"
extends="#xformswidget-select"/>
@ -84,6 +93,14 @@
<binding id="xformswidget-select-full"
extends="#xformswidget-select"/>
<binding id="xformswidget-select1-minimal"
extends="#xformswidget-select1"/>
<binding id="xformswidget-select1-compact"
extends="#xformswidget-select1"/>
<binding id="xformswidget-select1-full"
extends="#xformswidget-select1"/>
<!-- CONTROL WIDGETS FOR SELECT CONTROLS
The section contains underlying widgets implementations needed for xforms
@ -110,10 +127,6 @@
</content>
<implementation>
<property name="selectedIndex"
onget="return this.control.selectedIndex;"
onset="this.control.selectedIndex = val;"/>
<method name="removeAllItems">
<body>
// removeItemAt fires 'select' event event if 'suppressonselect'
@ -237,17 +250,6 @@
</content>
<implementation>
<!-- XXX: Property 'selectedIndex' is not implemented -->
<property name="selectedIndex"
onget="throw new Error(this.selectedIndexErrorMsg);"
onset="throw new Error(this.selectedIndexErrorMsg);"/>
<field name="selectedIndexErrorMsg">
<![CDATA[
"<xforms:select appearance='full'/>: 'selectedIndex' property isn't implemented."
]]>
</field>
<method name="removeAllItems">
<body>
for (var i = this.control.childNodes.length; i > 0; i--) {
@ -402,10 +404,6 @@
</content>
<implementation>
<property name="selectedIndex"
onget="return this.control.selectedIndex;"
onset="this.control.selectedIndex = val;"/>
<method name="removeAllItems">
<body>
var popup = this.control.menupopup;
@ -544,17 +542,6 @@
</content>
<implementation>
<!-- XXX: Property 'selectedIndex' is not implemented -->
<property name="selectedIndex"
onget="throw new Error(this.selectedIndexErrorMsg);"
onset="throw new Error(this.selectedIndexErrorMsg);"/>
<field name="selectedIndexErrorMsg">
<![CDATA[
"<xforms:select1 appearance='full'/>: 'selectedIndex' property isn't implemented."
]]>
</field>
<method name="removeAllItems">
<body>
for (var i = this.control.childNodes.length; i > 0; i--) {

View File

@ -23,6 +23,7 @@
- Contributor(s):
- Doron Rosenberg <doronr@us.ibm.com>
- Olli Pettay <Olli.Pettay@helsinki.fi>
- Alexander Surkov <surkov.alexander@gmail.com>
-
- 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
@ -52,8 +53,6 @@
readonly - set/get readonly state
selectedIndex - selects item by index / returns index of first selected item
appendItem(label, value, group) - appends item, returns item control
@param label - label control
@param value - item's value
@ -88,16 +87,12 @@
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:xbl="http://www.mozilla.org/xbl">
<!-- SELECT BASE -->
<binding id="xformswidget-select-base"
<!-- BASE for select/select1 elements. -->
<binding id="xformswidget-selectcontrols-base"
extends="chrome://xforms/content/xforms.xml#xformswidget-base">
<implementation implements="nsIXFormsUIWidget">
<property name="selectedIndex"
onget="return this.control.selectedIndex"
onset="this.control.selectedIndex = val;"/>
<!-- Make sure we don't refresh while we are refreshing (race condition).
This happens when we are inside a repeat for example. We use the
_refreshing field to store if we are refreshing or not. -->
@ -629,6 +624,33 @@
</body>
</method>
<!-- Updates the instance data bound to this control.
@param aIncremental - if true then it means the update is additional and
instance data will be updated only if @incremental attribute value of
this control is not false.
-->
<method name="updateInstanceData">
<parameter name="aIncremental"/>
<body>
<![CDATA[
// Fire 'xfroms-select'/'xforms-deselect' events and unselect illegaly
// selected items.
var copySelectedOrDeselected = new Boolean();
copySelectedOrDeselected.value = false;
var contentEnvelope =
this._processSelectedValues(copySelectedOrDeselected);
if (!aIncremental || this.incremental) {
if (contentEnvelope) {
this._setBoundValue(contentEnvelope,
copySelectedOrDeselected.value);
}
}
]]>
</body>
</method>
<method name="_setBoundValue">
<parameter name="aContentEnvelope"/>
<parameter name="aCopySelectedOrDeselected"/>
@ -855,7 +877,15 @@
</body>
</method>
<!-- Array of objects that contains objects for all items of this control,
serves to keep xforms items and native items together.
Object has next properties:
control - xforms:item element
option - native widget for xforms:item
wasSelected - flag specifies whether native item was selected or not.
-->
<field name="_controlArray">new Array()</field>
<field name="_selectedElementArray">new Array()</field>
<field name="_defaultHash">null</field>
<field name="_accessorValueCache">null</field>
@ -872,6 +902,162 @@
</binding>
<!-- SELECT BASE
Implements nsIXFormsNSSelectElement interface.
-->
<binding id="xformswidget-select-base"
extends="#xformswidget-selectcontrols-base">
<implementation implements="nsIXFormsNSSelectElement">
<!-- nsIXFormsNSSelectElement -->
<property name="selectedItems" readonly="true">
<getter>
<![CDATA[
var items = [];
for (var i = 0; i < this._controlArray.length; i++) {
var nativeitem = this._controlArray[i].option;
if (this.control.isItemSelected(nativeitem)) {
var item = this._controlArray[i].control;
items.push(item);
}
}
return items;
]]>
</getter>
</property>
<method name="addItemToSelection">
<parameter name="aItem"/>
<body>
var nativeitem = this.getNativeItem(aItem);
if (!this.control.isItemSelected(nativeitem)) {
this.control.addItemToSelection(nativeitem);
this.updateInstanceData();
}
</body>
</method>
<method name="removeItemFromSelection">
<parameter name="aItem"/>
<body>
var nativeitem = this.getNativeItem(aItem);
if (this.control.isItemSelected(nativeitem)) {
this.control.removeItemFromSelection(nativeitem);
this.updateInstanceData();
}
</body>
</method>
<method name="clearSelection">
<body>
<![CDATA[
changed = false;
for (var i = 0; i < this._controlArray.length; i++) {
var nativeitem = this._controlArray[i].option;
if (this.control.isItemSelected(nativeitem)) {
this.control.removeItemFromSelection(nativeitem);
changed = true;
}
}
if (changed)
this.updateInstanceData();
]]>
</body>
</method>
<method name="selectAll">
<body>
<![CDATA[
var changed = false;
for (var i = 0; i < this._controlArray.length; i++) {
var nativeitem = this._controlArray[i].option;
if (!this.control.isItemSelected(nativeitem)) {
this.control.addItemToSelection(nativeitem);
changed = true;
}
}
if (changed)
this.updateInstanceData();
]]>
</body>
</method>
<method name="isItemSelected">
<parameter name="aItem"/>
<body>
return this.control.isItemSelected(this.getNativeItem(aItem));
</body>
</method>
<!-- private -->
<method name="getNativeItem">
<parameter name="aItem"/>
<body>
<![CDATA[
for (var i = 0; i < this._controlArray.length; i++) {
if (this._controlArray[i].control == aItem)
return this._controlArray[i].option;
}
return null;
]]>
</body>
</method>
</implementation>
</binding>
<!-- SELECT1 BASE
Implements nsIXFormsNSSelect1Element interface.
-->
<binding id="xformswidget-select1-base"
extends="#xformswidget-selectcontrols-base">
<implementation implements="nsIXFormsNSSelect1Element">
<property name="selectedItem">
<getter>
<![CDATA[
for (var i = 0; i < this._controlArray.length; i++) {
var nativeitem = this._controlArray[i].option;
var item = this._controlArray[i].control;
if (this.control.isItemSelected(nativeitem)) {
return item;
}
}
return null;
]]>
</getter>
<setter>
<![CDATA[
var changed = false;
for (var i = 0; i < this._controlArray.length; i++) {
var nativeitem = this._controlArray[i].option;
var item = this._controlArray[i].control;
if (!this.control.isItemSelected(nativeitem)) {
if (item == val) {
this.control.addItemToSelection(nativeitem);
if (changed)
break;
changed = true;
}
} else {
if (item != val) {
this.control.removeItemFromSelection(nativeitem);
if (changed)
break;
changed = true;
}
}
}
if (changed)
this.updateInstanceData();
]]>
</setter>
</property>
</implementation>
</binding>
<!-- BASE CONTROL WIDGET FOR XFORMS SELECTS
The 'controlwidget-base' is the base binding of underlying controls. Thease
underlying controls implement functionality asked for by object returned by
@ -958,18 +1144,7 @@
if (this.parentControl.incremental && !aIncremental)
return;
// Fire 'xfroms-select'/'xforms-deselect' events and unselect illegaly
// selected items.
var copySelectedOrDeselected = new Boolean();
copySelectedOrDeselected.value = false;
var contentEnvelope =
this.parentControl._processSelectedValues(copySelectedOrDeselected);
if (!aIncremental || this.parentControl.incremental) {
if (contentEnvelope) {
this.parentControl._setBoundValue(contentEnvelope, copySelectedOrDeselected.value);
}
}
this.parentControl.updateInstanceData(aIncremental);
]]>
</body>
</method>
@ -978,7 +1153,8 @@
<method name="dispatchDOMUIEvent">
<parameter name="aType"/>
<body>
this.parentControl.dispatchDOMUIEvent(aType);
if (this.parentControl)
this.parentControl.dispatchDOMUIEvent(aType);
</body>
</method>

View File

@ -78,7 +78,29 @@
this.previousSibling.focus();"
/></html:span></content>
<implementation implements="nsIXFormsUIWidget">
<implementation implements="nsIXFormsUIWidget, nsIXFormsNSSelect1Element">
<!-- nsIXFormsNSSelect1Element -->
<property name="selectedItem">
<getter>
return this._selected;
</getter>
<setter>
if (this._selected == val)
return;
if (this._selected)
this._selected.setActive(false);
this._selected =
val.QueryInterface(Components.interfaces.nsIXFormsItemElement);
if (this._selected) {
this._selected.setActive(true);
this.updateInputField();
this._handleSelection(true);
}
</setter>
</property>
<field name="_inputField">null</field>
<field name="_dropMarker">null</field>
<field name="_popup">null</field>

View File

@ -500,7 +500,7 @@ html|*:root select1[appearance='minimal'] item {
}
xul|*:root select1 {
-moz-binding: url('chrome://xforms/content/select-xul.xml#xformswidget-select-minimal');
-moz-binding: url('chrome://xforms/content/select-xul.xml#xformswidget-select1-minimal');
}
xul|*:root select1 xul|box[anonid="control"] {
-moz-binding: url('chrome://xforms/content/select-xul.xml#controlwidget-select1-minimal');
@ -508,14 +508,14 @@ xul|*:root select1 xul|box[anonid="control"] {
/* select1 appearance='compact' */
html|*:root select1[appearance="compact"] {
-moz-binding: url('chrome://xforms/content/select-xhtml.xml#xformswidget-select-compact');
-moz-binding: url('chrome://xforms/content/select-xhtml.xml#xformswidget-select1-compact');
}
html|*:root select1[appearance="compact"] html|span[anonid="control"] {
-moz-binding: url('chrome://xforms/content/select-xhtml.xml#controlwidget-select1-compact');
}
xul|*:root select1[appearance="compact"] {
-moz-binding: url('chrome://xforms/content/select-xul.xml#xformswidget-select-compact');
-moz-binding: url('chrome://xforms/content/select-xul.xml#xformswidget-select1-compact');
}
xul|*:root select1[appearance="compact"] xul|box[anonid="control"] {
-moz-binding: url('chrome://xforms/content/select-xul.xml#controlwidget-select1-compact');
@ -523,14 +523,14 @@ xul|*:root select1[appearance="compact"] xul|box[anonid="control"] {
/* select1 appearance='full' */
html|*:root select1[appearance="full"] {
-moz-binding: url('chrome://xforms/content/select-xhtml.xml#xformswidget-select-full');
-moz-binding: url('chrome://xforms/content/select-xhtml.xml#xformswidget-select1-full');
}
html|*:root select1[appearance="full"] html|span[anonid="control"] {
-moz-binding: url('chrome://xforms/content/select-xhtml.xml#controlwidget-select1-full');
}
xul|*:root select1[appearance="full"] {
-moz-binding: url('chrome://xforms/content/select-xul.xml#xformswidget-select-full');
-moz-binding: url('chrome://xforms/content/select-xul.xml#xformswidget-select1-full');
}
xul|*:root select1[appearance="full"] xul|box[anonid="control"] {
-moz-binding: url('chrome://xforms/content/select-xul.xml#controlwidget-select1-full');