home *** CD-ROM | disk | FTP | other *** search
- <?xml version="1.0"?>
-
- <bindings id="radioBindings"
- xmlns="http://www.mozilla.org/xbl"
- xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:xbl="http://www.mozilla.org/xbl">
-
- <binding id="radiogroup">
- <resources>
- <stylesheet src="chrome://global/skin/radio.css"/>
- </resources>
-
- <implementation implements="nsIDOMXULSelectControlElement, nsIAccessibleProvider">
- <property name="accessible">
- <getter>
- <![CDATA[
- var accService = Components.classes["@mozilla.org/accessibilityService;1"].getService(Components.interfaces.nsIAccessibilityService);
- return accService.createXULRadioGroupAccessible(this);
- ]]>
- </getter>
- </property>
-
- <property name="value" onset="this.setAttribute('value',val); return val;"
- onget="return this.getAttribute('value');"/>
- <property name="disabled">
- <getter>
- <![CDATA[
- if (this.getAttribute('disabled') == 'true')
- return true;
- var children = this._getRadioChildren();
- for (var i = 0; i < children.length; ++i) {
- if (!children[i].hidden && !children[i].collapsed && !children[i].disabled)
- return false;
- }
- return true;
- ]]>
- </getter>
- <setter>
- <![CDATA[
- if (val)
- this.setAttribute('disabled', 'true');
- else
- this.removeAttribute('disabled');
- var children = this._getRadioChildren();
- for (var i = 0; i < children.length; ++i) {
- children[i].disabled = val;
- }
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="selectedIndex">
- <getter>
- <![CDATA[
- var children = this._getRadioChildren();
- for (var i = 0; i < children.length; ++i) {
- if (children[i].selected)
- return i;
- }
- return -1;
- ]]>
- </getter>
- <setter>
- <![CDATA[
- this.selectedItem = this._getRadioChildren()[val];
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="selectedItem">
- <getter>
- <![CDATA[
- var children = this._getRadioChildren();
- for (var i = 0; i < children.length; ++i) {
- if (children[i].selected)
- return children[i];
- }
- return null;
- ]]>
- </getter>
- <setter>
- <![CDATA[
- var focused = this.getAttribute("focused") == "true";
- var alreadySelected = false;
-
- if (val) {
- alreadySelected = val.getAttribute("selected") == "true";
- val.setAttribute("focused", focused);
- val.setAttribute("selected", "true");
- this.value = val.value;
- }
-
- // uncheck all other group nodes
- var children = this._getRadioChildren();
- for (var i = 0; i < children.length; ++i) {
- if (children[i] != val) {
- children[i].removeAttribute("selected");
- children[i].removeAttribute("focused");
- }
- }
-
- var event = document.createEvent("Events");
- event.initEvent("select", false, true);
- this.dispatchEvent(event);
-
- if (!alreadySelected && focused) {
- // Only report if actual change
- var myEvent = document.createEvent("Events");
- myEvent.initEvent("RadioStateChange", true, true);
- val.dispatchEvent(myEvent);
- }
-
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="focusedItem">
- <getter>
- <![CDATA[
- var children = this._getRadioChildren();
- for (var i = 0; i < children.length; ++i) {
- if (children[i].getAttribute("focused") == "true")
- return children[i];
- }
- return null;
- ]]>
- </getter>
- <setter>
- <![CDATA[
- if (val) val.setAttribute("focused", "true");
-
- // unfocus all other group nodes
- var children = this._getRadioChildren();
- for (var i = 0; i < children.length; ++i) {
- if (children[i] != val)
- children[i].removeAttribute("focused");
- }
- return val;
- ]]>
- </setter>
- </property>
-
- <method name="checkAdjacentElement">
- <parameter name="aNextFlag"/>
- <body>
- <![CDATA[
- var currentElement = this.focusedItem;
- var i;
- var children = this._getRadioChildren();
- for (i = 0; i < children.length; ++i ) {
- if (children[i] == currentElement)
- break;
- }
- var index = i;
-
- if (aNextFlag) {
- do {
- if (++i == children.length)
- i = 0;
- if (i == index)
- break;
- }
- while (children[i].hidden || children[i].collapsed || children[i].disabled);
- // XXX check for display/visibility props too
-
- this.selectedItem = children[i];
- children[i].doCommand();
- }
- else {
- do {
- if (i == 0)
- i = children.length;
- if (--i == index)
- break;
- }
- while (children[i].hidden || children[i].collapsed || children[i].disabled);
- // XXX check for display/visibility props too
-
- this.selectedItem = children[i];
- children[i].doCommand();
- }
- ]]>
- </body>
- </method>
- <field name="mRadioChildren">null</field>
- <method name="_getRadioChildren">
- <body>
- <![CDATA[
- if (this.mRadioChildren)
- return this.mRadioChildren;
-
- // Don't store the collected child nodes immediately,
- // collecting the child nodes could trigger constructors
- // which would blow away our list.
- var radioChildren = [];
- function _filterRadioGroup(aNode) {
- switch (aNode.localName) {
- case "radio": return NodeFilter.FILTER_ACCEPT;
- case "template":
- case "radiogroup": return NodeFilter.FILTER_REJECT;
- default: return NodeFilter.FILTER_SKIP;
- }
- }
- var iterator = this.ownerDocument.createTreeWalker(this, NodeFilter.SHOW_ELEMENT, _filterRadioGroup, true);
- while (iterator.nextNode())
- radioChildren.push(iterator.currentNode);
-
- return this.mRadioChildren = radioChildren;
- ]]>
- </body>
- </method>
-
- <method name="appendItem">
- <parameter name="label"/>
- <parameter name="value"/>
- <body>
- <![CDATA[
- var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- var radio = document.createElementNS(XULNS, "radio");
- radio.setAttribute("label", label);
- radio.setAttribute("value", value);
- this.appendChild(radio);
- return radio;
- ]]>
- </body>
- </method>
-
- <method name="insertItemAt">
- <parameter name="index"/>
- <parameter name="label"/>
- <parameter name="value"/>
- <body>
- <![CDATA[
- var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- var radio = document.createElementNS(XULNS, "radio");
- radio.setAttribute("label", label);
- radio.setAttribute("value", value);
- var before = this.childNodes[index];
- if (before)
- this.insertBefore(radio, before);
- else
- this.appendChild(radio);
- return radio;
- ]]>
- </body>
- </method>
-
- <method name="removeItemAt">
- <parameter name="index"/>
- <body>
- <![CDATA[
- var remove = this.childNodes[index];
- if (remove)
- this.removeChild(remove);
- return remove;
- ]]>
- </body>
- </method>
- </implementation>
-
- <handlers>
- <handler event="select">
- <![CDATA[
- //XXXblake this should not be necessary
- // initEvent was supposed to prevent this from bubbling
- event.preventBubble();
- ]]>
- </handler>
- <handler event="mousedown">
- if (this.disabled)
- event.preventDefault();
- </handler>
-
- <!-- keyboard navigation -->
- <!-- Here's how keyboard navigation works in radio groups on Windows:
- The group takes 'focus'
- The user is then free to navigate around inside the group
- using the arrow keys. Accessing previous or following radio buttons
- is done solely through the arrow keys and not the tab button. Tab
- takes you to the next widget in the tab order -->
- <handler event="keypress" key=" " phase="target">
- this.selectedItem = this.focusedItem;
- this.selectedItem.doCommand();
- </handler>
- <handler event="keypress" keycode="VK_UP" phase="target">
- this.checkAdjacentElement(false);
- event.preventBubble();
- </handler>
- <handler event="keypress" keycode="VK_LEFT" phase="target">
- this.checkAdjacentElement(false);
- event.preventBubble();
- </handler>
- <handler event="keypress" keycode="VK_DOWN" phase="target">
- this.checkAdjacentElement(true);
- event.preventBubble();
- </handler>
- <handler event="keypress" keycode="VK_RIGHT" phase="target">
- this.checkAdjacentElement(true);
- event.preventBubble();
- </handler>
-
- <!-- set a focused attribute on the selected item when the group
- receives focus so that we can style it as if it were focused even though
- it is not (Windows platform behaviour is for the group to receive focus,
- not the item -->
- <handler event="focus" phase="target">
- <![CDATA[
- this.setAttribute("focused", "true");
- if (this.focusedItem)
- return;
-
- var val = this.selectedItem;
- if (!val || val.disabled || val.hidden || val.collapsed) {
- var children = this._getRadioChildren();
- for (var i = 0; i < children.length; ++i) {
- if (!children[i].hidden && !children[i].collapsed && !children[i].disabled) {
- val = children[i];
- break;
- }
- }
- }
- this.focusedItem = val;
- ]]>
- </handler>
- <handler event="blur" phase="target">
- this.removeAttribute("focused");
- this.focusedItem = null;
- </handler>
- </handlers>
- </binding>
-
- <binding id="radio" extends="chrome://global/content/bindings/general.xml#control-item">
- <resources>
- <stylesheet src="chrome://global/skin/radio.css"/>
- </resources>
-
- <content>
- <xul:image class="radio-check" xbl:inherits="disabled,selected"/>
- <xul:hbox class="radio-label-box" flex="1">
- <xul:image class="radio-icon" xbl:inherits="src"/>
- <xul:label class="radio-label" xbl:inherits="xbl:text=label,accesskey,crop" flex="1"/>
- </xul:hbox>
- </content>
-
- <implementation implements="nsIDOMXULSelectControlItemElement, nsIAccessibleProvider">
- <constructor>
- <![CDATA[
- // Just clear out the parent's cached list of radio children
- this.radioGroup.mRadioChildren = null;
- ]]>
- </constructor>
- <destructor>
- <![CDATA[
- var radioList = this.radioGroup.mRadioChildren;
- if (!radioList)
- return;
- for (var i = 0; i < radioList.length; ++i) {
- if (radioList[i] == this) {
- radioList.splice(i, 1);
- return;
- }
- }
- ]]>
- </destructor>
- <property name="accessible">
- <getter>
- <![CDATA[
- var accService = Components.classes["@mozilla.org/accessibilityService;1"].getService(Components.interfaces.nsIAccessibilityService);
- return accService.createXULRadioButtonAccessible(this);
- ]]>
- </getter>
- </property>
- <property name="selected" readonly="true">
- <getter>
- <![CDATA[
- return this.hasAttribute('selected');
- ]]>
- </getter>
- </property>
- <property name="radioGroup">
- <getter>
- <![CDATA[
- var parent = this.parentNode;
- while (parent) {
- if (parent.localName == "radiogroup")
- return parent;
- parent = parent.parentNode;
- }
- return null;
- ]]>
- </getter>
- </property>
- </implementation>
- <handlers>
- <handler event="click" button="0">
- <![CDATA[
- if (!this.disabled)
- this.radioGroup.selectedItem = this;
- ]]>
- </handler>
-
- <handler event="mousedown" button="0">
- <![CDATA[
- if (!this.disabled)
- this.radioGroup.focusedItem = this;
- ]]>
- </handler>
- </handlers>
- </binding>
-
- </bindings>
-