gecko-dev/toolkit/content/widgets/richlistbox.xml

398 lines
13 KiB
XML

<?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 Richlistbox code.
-
- The Initial Developer of the Original Code is
- IBM Corporation.
- Portions created by the Initial Developer are Copyright (C) 2005
- IBM Corporation. All Rights Reserved.
-
- Contributor(s):
- Doron Rosenberg <doronr@us.ibm.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 ***** -->
<bindings id="richlistboxBindings"
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="richlistbox">
<content>
<xul:scrollbox allowevents="true" orient="vertical" anonid="main-box"
flex="1" style="overflow: auto;"
xmlns:xhtml2="http://www.w3.org/TR/xhtml2"
xmlns:wairole="http://www.w3.org/2005/01/wai-rdf/GUIRoleTaxonomy#"
xhtml2:role="wairole:list">
<children />
</xul:scrollbox>
</content>
<resources>
<stylesheet src="chrome://global/skin/richlistbox.css"/>
</resources>
<implementation implements="nsIDOMXULSelectControlElement">
<field name="scrollBoxObject">null</field>
<constructor>
<![CDATA[
var x = document.getAnonymousElementByAttribute(this, "anonid", "main-box");
this.scrollBoxObject = x.boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
]]>
</constructor>
<property name="children">
<getter>
<![CDATA[
var childNodes = [];
for (var i = 0; i < this.childNodes.length; ++i) {
if (this.childNodes[i] instanceof Components.interfaces.nsIDOMXULSelectControlItemElement)
childNodes.push(this.childNodes[i]);
}
return childNodes;
]]>
</getter>
</property>
<method name="fireActiveItemEvent">
<body>
<![CDATA[
if (this.selectedItem) {
var event = document.createEvent("Events");
event.initEvent("DOMMenuItemActive", true, true);
this.selectedItem.dispatchEvent(event);
}
return false;
]]>
</body>
</method>
<property name="selectedIndex">
<getter>
<![CDATA[
var returnValue = -1;
// if there is a selected item, iterate the children looking for it.
if (this.selectedItem) {
var children = this.children;
var run = 0;
while (children[run] != this.selectedItem && run < children.length) {
run++;
}
if (children[run] == this.selectedItem)
returnValue = run;
}
return returnValue;
]]>
</getter>
<setter>
<![CDATA[
if (val == -1) {
// clear selection
this.clearSelection();
} else if (val >= 0) {
// only set if we get an item returned
var item = this.getItemAtIndex(val);
if (item)
this.selectedItem = item
}
]]>
</setter>
</property>
<field name="_selectedItem">null</field>
<property name="selectedItem">
<getter>
return this._selectedItem;
</getter>
<setter>
<![CDATA[
if (this._selectedItem)
this._selectedItem.selected = false;
this._selectedItem = val;
if (val) {
val.selected = true;
this.scrollBoxObject.ensureElementIsVisible(val);
this.fireActiveItemEvent();
this._fireOnSelect();
}
]]>
</setter>
</property>
<method name="clearSelection">
<body>
<![CDATA[
this.selectedItem = null;
]]>
</body>
</method>
<method name="getRowCount">
<body>
<![CDATA[
return this.children.length;
]]>
</body>
</method>
<method name="goUp">
<body>
<![CDATA[
// if nothing selected, we go from the bottom
for (var i = this.selectedItem ? this.selectedItem.previousSibling : this.lastChild; i; i = i.previousSibling) {
// could have a template element, which would be a sibling
if (i instanceof Components.interfaces.nsIDOMXULSelectControlItemElement) {
this.selectedItem = i;
return true;
}
}
return false;
]]>
</body>
</method>
<method name="goDown">
<body>
<![CDATA[
// if nothing selected, we go from the top
for (var i = this.selectedItem ? this.selectedItem.nextSibling : this.firstChild; i; i = i.nextSibling) {
// could have a template element, which would be a sibling
if (i instanceof Components.interfaces.nsIDOMXULSelectControlItemElement) {
this.selectedItem = i;
return true;
}
}
return false;
]]>
</body>
</method>
<method name="getItemAtIndex">
<parameter name="aIndex"/>
<body>
<![CDATA[
return this.children[aIndex];
]]>
</body>
</method>
<method name="init">
<body>
<![CDATA[
var lastSelected = this.getAttribute("last-selected");
if (lastSelected != "")
lastSelected = document.getElementById(lastSelected);
if (!lastSelected)
this.goDown();
else
this.selectedItem = lastSelected;
if (this.selectedItem)
this.scrollBoxObject.scrollToElement(this.selectedItem);
]]>
</body>
</method>
<method name="ensureElementIsVisible">
<parameter name="aElement"/>
<body>
<![CDATA[
this.scrollBoxObject.ensureElementIsVisible(aElement);
]]>
</body>
</method>
<method name="ensureSelectedElementIsVisible">
<body>
<![CDATA[
this.scrollBoxObject.ensureElementIsVisible(this.selectedItem);
]]>
</body>
</method>
<property name="suppressOnSelect">
<getter>
<![CDATA[
return this.getAttribute("suppressonselect") == "true";
]]>
</getter>
</property>
<method name="_fireOnSelect">
<body>
<![CDATA[
if (!this.suppressOnSelect) {
var event = document.createEvent("Events");
event.initEvent("select", false, true);
this.dispatchEvent(event);
// if we have controllers, notify the command dispatcher
if (this.controllers.getControllerCount() > 0)
document.commandDispatcher.updateCommands("richlistbox-select");
}
]]>
</body>
</method>
</implementation>
<handlers>
<handler event="keypress" keycode="VK_UP" action="goUp(); event.preventDefault();"/>
<handler event="keypress" keycode="VK_DOWN" action="goDown(); event.preventDefault();"/>
<handler event="keypress" keycode="VK_HOME" action="clearSelection(); goDown(); event.preventDefault();"/>
<handler event="keypress" keycode="VK_END" action="clearSelection(); goUp(); event.preventDefault();"/>
<handler event="click">
<![CDATA[
// clicking into nothing should unselect
if (event.originalTarget.getAttribute("anonid") == "main-box")
this.clearSelection();
]]>
</handler>
<handler event="contextmenu">
<![CDATA[
// if the context menu was opened via the keyboard, display it in the
// right location.
if (event.button != 2) {
var popup = document.getElementById(this.getAttribute("context"));
if (popup)
popup.showPopup(this.selectedItem, -1, -1, "context", "bottomleft", "topleft");
}
]]>
</handler>
<handler event="focus">
<![CDATA[
if (event.target == this)
this.fireActiveItemEvent();
]]>
</handler>
</handlers>
</binding>
<binding id="richlistitem"
extends="chrome://global/content/bindings/general.xml#basecontrol">
<content>
<children />
</content>
<resources>
<stylesheet src="chrome://global/skin/richlistbox.css"/>
</resources>
<implementation implements="nsIAccessibleProvider, nsIDOMXULSelectControlItemElement">
<!-- ///////////////// nsIAccessibleProvider ///////////////// -->
<property name="accessible">
<getter>
<![CDATA[
var accService = Components.classes["@mozilla.org/accessibilityService;1"].getService(Components.interfaces.nsIAccessibilityService);
return accService.createXULListitemAccessible(this);
]]>
</getter>
</property>
<!-- ///////////////// nsIDOMXULSelectControlItemElement ///////////////// -->
<property name="value" onget="return this.getAttribute('value');"
onset="this.setAttribute('value', val); return val;"/>
<property name="label">
<!-- Setter purposely not implemented; the getter returns a
concatentation of label text to expose via accessibility APIs-->
<getter>
<![CDATA[
var labelText = "";
var startEl = document.getAnonymousNodes(this)[0];
if (startEl) {
var labels =
startEl.getElementsByTagNameNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul',
'label');
var numLabels = labels.length;
for (count = 0; count < numLabels; count ++) {
if (labels[count].className != 'link') {
labelText += labels[count].value + ' ';
}
}
}
return labelText;
]]>
</getter>
</property>
<property name="selected"
onget="return this.getAttribute('selected');"
onset="return this.setAttribute('selected',val);"/>
<property name="control">
<getter>
<![CDATA[
var parent = this.parentNode;
while (parent) {
if (parent instanceof Components.interfaces.nsIDOMXULSelectControlElement)
return parent;
parent = parent.parentNode;
}
return null;
]]>
</getter>
</property>
</implementation>
<handlers>
<handler event="click">
<![CDATA[
var listbox = this.control;
if ((event.target == this) && event.ctrlKey && (listbox.selectedItem == this)) {
listbox.clearSelection();
} else {
listbox.selectedItem = this;
}
]]>
</handler>
<handler event="contextmenu" phase="capturing">
<![CDATA[
// This needed to be called before the contextmenu gets shown to handle
// someone rightclicking on an unselected item
if (event.target == this) {
var listbox = this.control;
if (listbox) {
listbox.selectedItem = this;
}
}
]]>
</handler>
</handlers>
</binding>
</bindings>