979 lines
31 KiB
XML
979 lines
31 KiB
XML
<?xml version="1.0"?>
|
|
|
|
<bindings id="treeBindings"
|
|
xmlns="http://www.mozilla.org/xbl"
|
|
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
|
|
|
<binding id="tree-base">
|
|
<resources>
|
|
<stylesheet src="chrome://global/content/bindings/tree.css"/>
|
|
<stylesheet src="chrome://global/skin/tree.css"/>
|
|
</resources>
|
|
</binding>
|
|
|
|
<binding id="tree"
|
|
extends="chrome://global/content/bindings/tree.xml#tree-base">
|
|
<content>
|
|
<children>
|
|
<xul:treecolgroup>
|
|
<xul:treecol flex="1"/>
|
|
</xul:treecolgroup>
|
|
</children>
|
|
<xul:treerows class="tree-container-treerows" inherits="dragover,dragdroptree">
|
|
<children includes="treehead|treechildren"/>
|
|
</xul:treerows>
|
|
</content>
|
|
|
|
<implementation implements="nsIDOMXULMultiSelectControlElement">
|
|
<field name="_isUpSelection">0</field>
|
|
<field name="_isDownSelection">0</field>
|
|
<field name="_suppressOnSelect">false</field>
|
|
<field name="_selectionStart">null</field>
|
|
<field name="_currentItem">null</field>
|
|
<field name="_selectTimeout">null</field>
|
|
|
|
<constructor>
|
|
<![CDATA[
|
|
var els = this.getElementsByAttribute("selected", "true");
|
|
this.selectedItems = [];
|
|
for (var i = 0; i < els.length; ++i)
|
|
this.selectedItems.push(els[i]);
|
|
]]>
|
|
</constructor>
|
|
|
|
<!-- ///////////////// public tree members ///////////////// -->
|
|
|
|
<property name="treeBoxObject"
|
|
onget="return this.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);"
|
|
readonly="true"/>
|
|
|
|
<method name="timedSelect">
|
|
<parameter name="item"/>
|
|
<parameter name="timeout"/>
|
|
<body>
|
|
<![CDATA[
|
|
var suppress = this._suppressOnSelect;
|
|
if (timeout != -1)
|
|
this._suppressOnSelect = true;
|
|
|
|
this.selectItem(item);
|
|
|
|
this._suppressOnSelect = suppress;
|
|
|
|
if (timeout != -1) {
|
|
if (this._selectTimeout)
|
|
window.clearTimeout(this._selectTimeout);
|
|
|
|
this._selectTimeout = window.setTimeout(this._selectTimeoutHandler, timeout, this);
|
|
}
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- ///////////////// private tree members ///////////////// -->
|
|
|
|
<method name="_fireOnSelect">
|
|
<body>
|
|
<![CDATA[
|
|
if (!this._suppressOnSelect && this.getAttribute("suppressonselect") != "true") {
|
|
var event = document.createEvent("Events");
|
|
event.initEvent("select", false, true);
|
|
this.dispatchEvent(event);
|
|
}
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<method name="_selectTimeoutHandler">
|
|
<parameter name="me"/>
|
|
<body>
|
|
<![CDATA[
|
|
me._fireOnSelect();
|
|
this._selectTimeout = null;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- ///////////////// nsIDOMXULSelectControlElement ///////////////// -->
|
|
|
|
<property name="selType"
|
|
onget="return this.getAttribute('seltype')"
|
|
onset="this.setAttribute('seltype', val); return val;"/>
|
|
|
|
<property name="selectedIndex">
|
|
<getter><![CDATA[
|
|
return this.selectedItems.length > 0 ? this.getIndexOfItem(this.selectedItems[0]) : -1;
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
if (val >= 0)
|
|
this.selectItem(this.getItemAtIndex(val));
|
|
else
|
|
this.clearSelection();
|
|
]]></setter>
|
|
</property>
|
|
|
|
<property name="selectedItem">
|
|
<getter><![CDATA[
|
|
return this.selectedItems.length > 0 ? this.selectedItems[0] : null;
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
this.selectItem(item);
|
|
]]></setter>
|
|
</property>
|
|
|
|
<property name="value">
|
|
<getter>
|
|
<![CDATA[
|
|
if (this.selectedItems.length > 0)
|
|
return this.selectedItem.value;
|
|
else
|
|
return null;
|
|
]]>
|
|
</getter>
|
|
<setter>
|
|
<![CDATA[
|
|
var kids = this.getElementsByAttribute("value", val);
|
|
if (kids && kids.length)
|
|
this.selectItem(kids[0]);
|
|
return val;
|
|
]]>
|
|
</setter>
|
|
</property>
|
|
|
|
<method name="appendItem">
|
|
<parameter name="label"/>
|
|
<parameter name="value"/>
|
|
<body>
|
|
<![CDATA[
|
|
var kiddies = this.getElementsByTagName("treechildren")[0];
|
|
var item = null;
|
|
if (kiddies) {
|
|
var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
|
item = document.createElementNS(XULNS, "treeitem");
|
|
var row = document.createElementNS(XULNS, "treerow");
|
|
var cell = document.createElementNS(XULNS, "treecell");
|
|
item.setAttribute("label", label);
|
|
item.setAttribute("value", value);
|
|
kiddies.appendChild(item);
|
|
}
|
|
return item;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<method name="insertItemAt">
|
|
<parameter name="index"/>
|
|
<parameter name="label"/>
|
|
<parameter name="value"/>
|
|
<body>
|
|
<![CDATA[
|
|
var kiddies = this.getElementsByTagName("treechildren")[0];
|
|
var item = null;
|
|
if (kiddies) {
|
|
var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
|
item = document.createElementNS(XULNS, "treeitem");
|
|
item.setAttribute("label", label);
|
|
item.setAttribute("value", value);
|
|
var before = kiddies.childNodes[index];
|
|
if (before)
|
|
kiddies.insertBefore(item, before);
|
|
else
|
|
kiddies.appendChild(item);
|
|
}
|
|
return item;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<method name="removeItemAt">
|
|
<parameter name="index"/>
|
|
<body>
|
|
<![CDATA[
|
|
var kiddies = this.getElementsByTagName("treechildren")[0];
|
|
var remove = null;
|
|
if (kiddies) {
|
|
remove = kiddies.childNodes[index];
|
|
if (remove)
|
|
kiddies.removeChild(remove);
|
|
}
|
|
return remove;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
<!-- ///////////////// nsIDOMXULSelectMultipleControlElement ///////////////// -->
|
|
|
|
<property name="currentItem" onget="return this._currentItem;">
|
|
<setter>
|
|
<![CDATA[
|
|
if (this._currentItem)
|
|
this._currentItem.current = false;
|
|
this._currentItem = val;
|
|
if (val)
|
|
val.current = true;
|
|
return val;
|
|
]]>
|
|
</setter>
|
|
</property>
|
|
|
|
<property name="selectedCount" onget="return this.selectedItems.length;"/>
|
|
|
|
<method name="getSelectedItem">
|
|
<parameter name="index"/>
|
|
<body>
|
|
<![CDATA[
|
|
return index < this.selectedItems.length ? this.selectedItems[index] : null;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<method name="addItemToSelection">
|
|
<parameter name="item"/>
|
|
<body>
|
|
<![CDATA[
|
|
if (item.selected)
|
|
return;
|
|
|
|
this.selectedItems.push(item);
|
|
item.selected = true;
|
|
|
|
this._fireOnSelect();
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<method name="removeItemFromSelection">
|
|
<parameter name="item"/>
|
|
<body>
|
|
<![CDATA[
|
|
if (!item.selected)
|
|
return;
|
|
|
|
for (var i = 0; i < this.selectedItems.length; ++i) {
|
|
if (this.selectedItems[i] == item) {
|
|
this.selectedItems.splice(i, 1);
|
|
item.selected = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
this._fireOnSelect();
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<method name="toggleItemSelection">
|
|
<parameter name="item"/>
|
|
<body>
|
|
<![CDATA[
|
|
if (item.selected)
|
|
this.removeItemFromSelection(item);
|
|
else
|
|
this.addItemToSelection(item);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<method name="selectItem">
|
|
<parameter name="item"/>
|
|
<body>
|
|
<![CDATA[
|
|
if (!item)
|
|
return;
|
|
if (this.selectedItems.length == 1 && this.selectedItems[0] == item)
|
|
return;
|
|
|
|
this._selectionStart = null;
|
|
|
|
var suppress = this._suppressOnSelect;
|
|
this._suppressOnSelect = true;
|
|
|
|
this.clearSelection();
|
|
this.addItemToSelection(item);
|
|
this.currentItem = item;
|
|
|
|
this._suppressOnSelect = suppress;
|
|
this._fireOnSelect();
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<method name="selectItemRange">
|
|
<parameter name="startItem"/>
|
|
<parameter name="endItem"/>
|
|
<body>
|
|
<![CDATA[
|
|
if (this.selType != "multiple")
|
|
return;
|
|
|
|
if (!startItem)
|
|
startItem = this._selectionStart ? this._selectionStart : this.currentItem;
|
|
if (!startItem)
|
|
startItem = endItem;
|
|
|
|
var suppressSelect = this._suppressOnSelect;
|
|
this._suppressOnSelect = true;
|
|
this.clearSelection();
|
|
|
|
this._selectionStart = startItem;
|
|
|
|
var currentItem;
|
|
var startIndex = this.getIndexOfItem(startItem);
|
|
var endIndex = this.getIndexOfItem(endItem);
|
|
if (endIndex < startIndex) {
|
|
currentItem = endItem;
|
|
endItem = startItem;
|
|
startItem = currentItem;
|
|
} else {
|
|
currentItem = startItem;
|
|
}
|
|
|
|
while (currentItem) {
|
|
if (currentItem.localName == "treeitem")
|
|
this.addItemToSelection(currentItem);
|
|
if (currentItem == endItem)
|
|
break;
|
|
currentItem = this.getNextItem(currentItem, 1);
|
|
}
|
|
|
|
this._suppressOnSelect = suppressSelect;
|
|
|
|
this._fireOnSelect();
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<method name="selectAll">
|
|
<body>
|
|
<![CDATA[
|
|
var suppress = this._suppressOnSelect;
|
|
this._suppressOnSelect = true;
|
|
|
|
var item = this.getItemAtIndex(0);
|
|
while (item) {
|
|
this.addItemToSelection(item);
|
|
item = this.getNextItem(item, 1);
|
|
}
|
|
|
|
this._suppressOnSelect = suppress;
|
|
this._fireOnSelect();
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<method name="invertSelection">
|
|
<body>
|
|
<![CDATA[
|
|
var suppress = this._suppressOnSelect;
|
|
this._suppressOnSelect = true;
|
|
|
|
var item = this.getItemAtIndex(0);
|
|
while (item) {
|
|
if (item.selected)
|
|
this.removeItemFromSelection(item);
|
|
else
|
|
this.addItemToSelection(item);
|
|
item = this.getNextItem(item, 1);
|
|
}
|
|
|
|
this._suppressOnSelect = suppress;
|
|
this._fireOnSelect();
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<method name="clearSelection">
|
|
<body>
|
|
<![CDATA[
|
|
for (var i = this.selectedItems.length-1; i >= 0; --i)
|
|
this.selectedItems[i].selected = false;
|
|
|
|
this.selectedItems.splice(0, this.selectedItems.length);
|
|
this._selectionStart = null;
|
|
this._fireOnSelect();
|
|
]]>
|
|
</body>
|
|
</method>
|
|
|
|
<!-- ///////////////// nsITreeBoxObject ///////////////// -->
|
|
|
|
<method name="getNextItem">
|
|
<parameter name="startItem"/>
|
|
<parameter name="delta"/>
|
|
<body>
|
|
return this.treeBoxObject.getNextItem(startItem, delta);
|
|
</body>
|
|
</method>
|
|
<method name="getPreviousItem">
|
|
<parameter name="startItem"/>
|
|
<parameter name="delta"/>
|
|
<body>
|
|
return this.treeBoxObject.getPreviousItem(startItem, delta);
|
|
</body>
|
|
</method>
|
|
<method name="getIndexOfItem">
|
|
<parameter name="item"/>
|
|
<body>
|
|
return this.treeBoxObject.getIndexOfItem(item);
|
|
</body>
|
|
</method>
|
|
<method name="getItemAtIndex">
|
|
<parameter name="index"/>
|
|
<body>
|
|
return this.treeBoxObject.getItemAtIndex(index);
|
|
</body>
|
|
</method>
|
|
<method name="ensureIndexIsVisible">
|
|
<parameter name="index"/>
|
|
<body>
|
|
return this.treeBoxObject.ensureIndexIsVisible(index);
|
|
</body>
|
|
</method>
|
|
<method name="ensureElementIsVisible">
|
|
<parameter name="element"/>
|
|
<body>
|
|
return this.ensureIndexIsVisible(this.treeBoxObject.getIndexOfItem(element));
|
|
</body>
|
|
</method>
|
|
<method name="scrollToIndex">
|
|
<parameter name="index"/>
|
|
<body>
|
|
return this.treeBoxObject.scrollToIndex(index);
|
|
</body>
|
|
</method>
|
|
<method name="getNumberOfVisibleRows">
|
|
<body>
|
|
return this.treeBoxObject.getNumberOfVisibleRows();
|
|
</body>
|
|
</method>
|
|
<method name="getIndexOfFirstVisibleRow">
|
|
<body>
|
|
return this.treeBoxObject.getIndexOfFirstVisibleRow();
|
|
</body>
|
|
</method>
|
|
<method name="getRowCount">
|
|
<body>
|
|
return this.treeBoxObject.getRowCount();
|
|
</body>
|
|
</method>
|
|
</implementation>
|
|
|
|
<handlers>
|
|
<handler event="keypress" keycode="vk_enter">
|
|
<![CDATA[
|
|
if (event.target != this || this.selectedItems.length != 1)
|
|
return;
|
|
this.selectedItems[0].toggleOpenState();
|
|
]]>
|
|
</handler>
|
|
<handler event="keypress" keycode="vk_return">
|
|
<![CDATA[
|
|
if (event.target != this || this.selectedItems.length != 1)
|
|
return;
|
|
this.selectedItems[0].toggleOpenState();
|
|
]]>
|
|
</handler>
|
|
<handler event="keypress" keycode="vk_left">
|
|
<![CDATA[
|
|
if (event.target != this || this.selectedItems.length != 1)
|
|
return;
|
|
if (this.selectedItems[0].getAttribute("open") != "true") {
|
|
var el = this.selectedItems[0].parentNode.parentNode
|
|
if ( el && (el.tagName != "tree") ) this.selectItem(el);
|
|
}
|
|
else {
|
|
el = this.selectedItems[0];
|
|
el.close();
|
|
}
|
|
]]>
|
|
</handler>
|
|
<handler event="keypress" keycode="vk_right">
|
|
<![CDATA[
|
|
if (event.target != this || this.selectedItems.length != 1)
|
|
return;
|
|
this.selectedItems[0].open();
|
|
]]>
|
|
</handler>
|
|
<handler event="keypress" keycode="vk_up">
|
|
<![CDATA[
|
|
if (event.target != this || this.selectedItems.length < 1)
|
|
return;
|
|
this._isUpSelection=0;
|
|
this._isDownSelection=0;
|
|
var n = this.getPreviousItem(this.selectedItems[this.selectedItems.length-1], 1);
|
|
if (n) {
|
|
this.ensureIndexIsVisible(this.getIndexOfItem(n));
|
|
this.timedSelect(n, 500);
|
|
}
|
|
]]>
|
|
</handler>
|
|
<handler event="keypress" keycode="vk_down">
|
|
<![CDATA[
|
|
if (event.target != this)
|
|
return;
|
|
|
|
var n;
|
|
if (this.selectedItems.length == 0) {
|
|
n = this.getItemAtIndex(0);
|
|
}
|
|
else {
|
|
this._isUpSelection=0;
|
|
this._isDownSelection=0;
|
|
n = this.getNextItem(this.selectedItems[this.selectedItems.length-1], 1);
|
|
}
|
|
|
|
if (n) {
|
|
this.ensureIndexIsVisible(this.getIndexOfItem(n));
|
|
this.timedSelect(n, 500);
|
|
}
|
|
]]>
|
|
</handler>
|
|
<handler event="keypress" modifiers="shift" keycode="vk_up">
|
|
<![CDATA[
|
|
var l=this.selectedItems.length;
|
|
if (event.target != this || l < 1 || this.selType != "multiple")
|
|
return;
|
|
var n = this.getPreviousItem(this.selectedItems[l-1], 1);
|
|
if (n) {
|
|
this.ensureElementIsVisible(n);
|
|
if ( this._isDownSelection) {
|
|
if ( l > 1 )
|
|
this.removeItemFromSelection(this.selectedItems[l-1]);
|
|
if ( l <= 2 )
|
|
this._isDownSelection=0;
|
|
}
|
|
else {
|
|
this.addItemToSelection(n);
|
|
this._isUpSelection=1;
|
|
}
|
|
}
|
|
]]>
|
|
</handler>
|
|
<handler event="keypress" modifiers="shift" keycode="vk_down">
|
|
<![CDATA[
|
|
var l=this.selectedItems.length;
|
|
if (event.target != this || l < 1 || this.selType != "multiple")
|
|
return;
|
|
var n = this.getNextItem(this.selectedItems[l-1], 1);
|
|
if (n) {
|
|
this.ensureElementIsVisible(n);
|
|
if ( this._isUpSelection) {
|
|
if ( l > 1 )
|
|
this.removeItemFromSelection(this.selectedItems[l-1]);
|
|
if ( l <= 2 )
|
|
this._isUpSelection=0;
|
|
}
|
|
else {
|
|
this.addItemToSelection(n);
|
|
this._isDownSelection=1;
|
|
}
|
|
}
|
|
]]>
|
|
</handler>
|
|
<handler event="keypress" keycode="vk_page_up">
|
|
<![CDATA[
|
|
var l = this.selectedItems.length;
|
|
if (event.target != this || l < 1)
|
|
return;
|
|
this._isUpSelection=0;
|
|
this._isDownSelection=0;
|
|
var i = this.getIndexOfFirstVisibleRow();
|
|
if ( i == 0 )
|
|
var n=this.getItemAtIndex(0);
|
|
else {
|
|
var v = this.getNumberOfVisibleRows();
|
|
n = this.getPreviousItem(this.selectedItems[l-1], v);
|
|
var newIndex = i - v;
|
|
if ( ! n || newIndex < 0 ) {
|
|
newIndex=0;
|
|
n=this.getItemAtIndex(this.getIndexOfItem(this.selectedItems[l-1]) - i);
|
|
}
|
|
this.scrollToIndex(newIndex);
|
|
}
|
|
this.timedSelect(n, 500);
|
|
]]>
|
|
</handler>
|
|
<handler event="keypress" keycode="vk_page_down">
|
|
<![CDATA[
|
|
var l = this.selectedItems.length;
|
|
if (event.target != this || l < 1)
|
|
return;
|
|
this._isUpSelection=0;
|
|
this._isDownSelection=0;
|
|
var i = this.getIndexOfFirstVisibleRow();
|
|
var v = this.getNumberOfVisibleRows();
|
|
var count = this.getRowCount();
|
|
var n;
|
|
if ( i >= count - v )
|
|
n=this.getItemAtIndex(count - 1);
|
|
else {
|
|
n = this.getNextItem(this.selectedItems[l-1], v);
|
|
var newIndex = i + v;
|
|
if ( ! n || newIndex > count - v ) {
|
|
newIndex = count - v;
|
|
n = this.getItemAtIndex(newIndex + this.getIndexOfItem(this.selectedItems[l-1]) - i);
|
|
}
|
|
this.scrollToIndex(newIndex);
|
|
}
|
|
this.timedSelect(n, 500);
|
|
]]>
|
|
</handler>
|
|
<handler event="keypress" keycode="vk_home">
|
|
<![CDATA[
|
|
if (event.target != this || this.selectedItems.length < 1)
|
|
return;
|
|
this._isUpSelection=0;
|
|
this._isDownSelection=0;
|
|
this.scrollToIndex(0);
|
|
this.selectItem(this.getItemAtIndex(0));
|
|
]]>
|
|
</handler>
|
|
<handler event="keypress" keycode="vk_end">
|
|
<![CDATA[
|
|
if (event.target != this || this.selectedItems.length < 1)
|
|
return;
|
|
this._isUpSelection=0;
|
|
this._isDownSelection=0;
|
|
var count = this.getRowCount();
|
|
this.ensureIndexIsVisible(count-1);
|
|
this.selectItem(this.getItemAtIndex(count-1));
|
|
]]>
|
|
</handler>
|
|
</handlers>
|
|
</binding>
|
|
|
|
<binding id="treerows"
|
|
extends="chrome://global/content/bindings/tree.xml#tree-base">
|
|
<content outer="true"/>
|
|
|
|
<implementation>
|
|
<constructor>
|
|
this.addEventListener("DOMMouseScroll", this._handleMouseScroll, true);
|
|
</constructor>
|
|
|
|
<field name="_handleMouseScroll">
|
|
<![CDATA[
|
|
({
|
|
subject: this,
|
|
handleEvent: function(aEvent)
|
|
{
|
|
var treeBox = this.subject.parentNode.treeBoxObject;
|
|
var rows = aEvent.detail;
|
|
if (rows == NSUIEvent.SCROLL_PAGE_UP)
|
|
rows = -1 * treeBox.getNumberOfVisibleRows();
|
|
else if (rows == NSUIEvent.SCROLL_PAGE_DOWN)
|
|
rows = treeBox.getNumberOfVisibleRows();
|
|
|
|
treeBox.scrollByLines(rows);
|
|
}
|
|
})
|
|
]]>
|
|
</field>
|
|
|
|
<method name="_getMouseTargetItem">
|
|
<parameter name="event"/>
|
|
<body>
|
|
<![CDATA[
|
|
var p = event.originalTarget;
|
|
while (p) {
|
|
if (p.localName == "treeitem")
|
|
return p;
|
|
p = p.parentNode;
|
|
}
|
|
return null;
|
|
]]>
|
|
</body>
|
|
</method>
|
|
</implementation>
|
|
|
|
<handlers>
|
|
<!-- If there is no modifier key, we select on mousedown, not
|
|
click, so that drags work correctly. -->
|
|
<handler event="mousedown">
|
|
<![CDATA[
|
|
var targetItem = this._getMouseTargetItem(event);
|
|
if (targetItem && !event.ctrlKey && !event.shiftKey && !event.metaKey) {
|
|
if (!targetItem.selected)
|
|
parentNode.selectItem(targetItem);
|
|
|
|
parentNode.currentItem = targetItem;
|
|
}
|
|
]]>
|
|
</handler>
|
|
|
|
<!-- On a click (up+down on the same item), deselect everything
|
|
except this item. -->
|
|
<handler event="click">
|
|
<![CDATA[
|
|
if (event.button != 0) return;
|
|
var targetItem = this._getMouseTargetItem(event);
|
|
if (targetItem) {
|
|
if (event.ctrlKey || event.metaKey) {
|
|
parentNode.toggleItemSelection(targetItem);
|
|
parentNode.currentItem = targetItem;
|
|
}
|
|
else if (event.shiftKey) {
|
|
parentNode.selectItemRange(null, targetItem);
|
|
parentNode.currentItem = targetItem;
|
|
}
|
|
else {
|
|
/* We want to deselect all the selected items except what was
|
|
clicked, UNLESS it was a right-click. We have to do this
|
|
in click rather than mousedown so that you can drag a
|
|
selected group of items */
|
|
|
|
var selectedItems = parentNode.selectedItems;
|
|
var didSuppressSelect = false;
|
|
var i = 0;
|
|
while (i < selectedItems.length) {
|
|
if (selectedItems[i] != targetItem) {
|
|
if (!didSuppressSelect) {
|
|
parentNode._suppressOnSelect = true;
|
|
didSuppressSelect = true;
|
|
}
|
|
parentNode.removeItemFromSelection(selectedItems[i]);
|
|
}
|
|
else
|
|
i++;
|
|
}
|
|
if (didSuppressSelect)
|
|
parentNode._suppressOnSelect = false;
|
|
}
|
|
}
|
|
]]>
|
|
</handler>
|
|
|
|
<!-- double-click -->
|
|
<handler event="click" clickcount="2">
|
|
<![CDATA[
|
|
if (event.originalTarget.localName == 'treecell') {
|
|
var n = event.originalTarget.parentNode.parentNode;
|
|
n.toggleOpenState();
|
|
}
|
|
]]>
|
|
</handler>
|
|
|
|
<!-- normal, single click -->
|
|
<handler event="click">
|
|
<![CDATA[
|
|
try {
|
|
if (event.originalTarget.getAttribute('twisty') == 'true') {
|
|
var n = event.originalTarget.parentNode.parentNode.parentNode;
|
|
n.toggleOpenState();
|
|
}
|
|
} catch (e) {}
|
|
]]>
|
|
</handler>
|
|
|
|
</handlers>
|
|
</binding>
|
|
|
|
<binding id="treeitem"
|
|
extends="chrome://global/content/bindings/general.xml#basetext">
|
|
<resources>
|
|
<stylesheet src="chrome://global/content/bindings/tree.css"/>
|
|
<stylesheet src="chrome://global/skin/tree.css"/>
|
|
</resources>
|
|
|
|
<implementation implements="nsIDOMXULSelectControlItemElement">
|
|
<property name="current" onget="return this.getAttribute('current') == 'true';">
|
|
<setter><![CDATA[
|
|
if (val)
|
|
this.setAttribute("current", "true");
|
|
else
|
|
this.removeAttribute("current");
|
|
return val;
|
|
]]></setter>
|
|
</property>
|
|
|
|
<!-- ///////////////// nsIDOMXULSelectControlItemElement ///////////////// -->
|
|
|
|
<property name="value" onget="return this.getAttribute('value');"
|
|
onset="this.setAttribute('value', val); return val;"/>
|
|
|
|
<property name="selected" onget="return this.getAttribute('selected') == 'true';">
|
|
<setter><![CDATA[
|
|
if (val)
|
|
this.setAttribute("selected", "true");
|
|
else
|
|
this.removeAttribute("selected");
|
|
return val;
|
|
]]></setter>
|
|
</property>
|
|
|
|
<property name="control">
|
|
<getter><![CDATA[
|
|
var parent = this.parentNode;
|
|
while (parent) {
|
|
if (parent.localName == "tree")
|
|
return parent;
|
|
parent = parent.parentNode;
|
|
}
|
|
return null;
|
|
]]></getter>
|
|
</property>
|
|
|
|
<!-- ///////////////// public treeitem members ///////////////// -->
|
|
|
|
<method name="toggleOpenState">
|
|
<body>
|
|
<![CDATA[
|
|
if ((this.getAttribute('container') == 'true') &&
|
|
(this.getAttribute('empty') != 'true')) {
|
|
if (this.getAttribute('open') == 'true')
|
|
this.removeAttribute('open');
|
|
else this.setAttribute('open', 'true');
|
|
}
|
|
]]>
|
|
</body>
|
|
</method>
|
|
<method name="open">
|
|
<body>
|
|
<![CDATA[
|
|
if ((this.getAttribute('container') == 'true') &&
|
|
(this.getAttribute('empty') != 'true')) {
|
|
if (this.getAttribute('open') != 'true')
|
|
this.setAttribute('open', 'true');
|
|
}
|
|
]]>
|
|
</body>
|
|
</method>
|
|
<method name="close">
|
|
<body>
|
|
<![CDATA[
|
|
if ((this.getAttribute('container') == 'true') &&
|
|
(this.getAttribute('empty') != 'true')) {
|
|
if (this.getAttribute('open') == 'true')
|
|
this.removeAttribute('open');
|
|
}
|
|
]]>
|
|
</body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<binding id="treecell"
|
|
extends="chrome://global/content/bindings/tree.xml#tree-base">
|
|
<content>
|
|
<xul:label class="tree-cell-text" inherits="crop,value=label,align" flex="1" crop="right"/>
|
|
</content>
|
|
</binding>
|
|
|
|
<binding id="treecell-align-right"
|
|
extends="chrome://global/content/bindings/tree.xml#tree-base">
|
|
<content>
|
|
<xul:spacer flex="5"/>
|
|
<xul:label class="tree-cell-text" inherits="crop,value=label,align" flex="1" crop="right"/>
|
|
</content>
|
|
</binding>
|
|
|
|
<binding id="treecell-iconic"
|
|
extends="chrome://global/content/bindings/tree.xml#tree-base">
|
|
<content>
|
|
<xul:image class="tree-cell-icon" inherits="validate,src"/>
|
|
<xul:label class="tree-cell-text" inherits="crop,value=label,align" flex="1" crop="right"/>
|
|
</content>
|
|
</binding>
|
|
|
|
<binding id="treecell-image"
|
|
extends="chrome://global/content/bindings/tree.xml#tree-base">
|
|
<content>
|
|
<xul:image class="tree-cell-image" inherits="validate,src"/>
|
|
</content>
|
|
</binding>
|
|
|
|
<binding id="treecell-indented-folder"
|
|
extends="chrome://global/content/bindings/tree.xml#tree-base">
|
|
<content>
|
|
<xul:treeindentation/>
|
|
<xul:image class="tree-cell-twisty" twisty="true" inherits="hidden=notwisty" allowevents="true"/>
|
|
<xul:image class="tree-cell-primary-icon" inherits="validate,src"/>
|
|
<xul:label class="tree-cell-text" inherits="crop,value=label,align" flex="1" crop="right"/>
|
|
</content>
|
|
</binding>
|
|
|
|
<binding id="treecell-indented-folder-inline-edit"
|
|
extends="chrome://global/content/bindings/general.xml#inline-edit-base">
|
|
<resources>
|
|
<stylesheet src="chrome://global/content/bindings/tree.css"/>
|
|
<stylesheet src="chrome://global/skin/tree.css"/>
|
|
</resources>
|
|
|
|
<content>
|
|
<xul:treeindentation/>
|
|
<xul:image class="tree-cell-twisty" twisty="true" inherits="hidden=notwisty" allowevents="true"/>
|
|
<xul:image class="tree-cell-primary-icon-inline-edit-folder" inherits="validate,src"/>
|
|
<xul:hbox class="inline-edit-cell-box" flex="1" ileattr="text-container">
|
|
<xul:label class="inline-edit-cell-text" ileattr="text" rootcontent="treecell"
|
|
inherits="crop,value=label,align,mode" flex="1" crop="right"/>
|
|
</xul:hbox>
|
|
</content>
|
|
</binding>
|
|
|
|
<binding id="treecell-indented-leaf-inline-edit"
|
|
extends="chrome://global/content/bindings/general.xml#inline-edit-base">
|
|
<resources>
|
|
<stylesheet src="chrome://global/content/bindings/tree.css"/>
|
|
<stylesheet src="chrome://global/skin/tree.css"/>
|
|
</resources>
|
|
|
|
<content>
|
|
<xul:treeindentation/>
|
|
<xul:image class="tree-cell-primary-icon" inherits="validate,src"/>
|
|
<xul:hbox class="inline-edit-cell-box" flex="1" ileattr="text-container">
|
|
<xul:label class="tree-cell-text" ileattr="text" rootcontent="treecell"
|
|
inherits="crop,value=label,align,mode" flex="1" crop="right"/>
|
|
</xul:hbox>
|
|
</content>
|
|
</binding>
|
|
|
|
<binding id="treecell-inline-edit"
|
|
extends="chrome://global/content/bindings/general.xml#inline-edit-base">
|
|
<resources>
|
|
<stylesheet src="chrome://global/content/bindings/tree.css"/>
|
|
<stylesheet src="chrome://global/skin/tree.css"/>
|
|
</resources>
|
|
|
|
<content>
|
|
<xul:hbox class="inline-edit-cell-box" flex="1" ileattr="text-container">
|
|
<xul:label class="tree-cell-text" ileattr="text" rootcontent="treecell"
|
|
inherits="crop,value=label,align,mode" flex="1" crop="right"/>
|
|
</xul:hbox>
|
|
</content>
|
|
</binding>
|
|
|
|
<binding id="treecell-indented-leaf"
|
|
extends="chrome://global/content/bindings/tree.xml#tree-base">
|
|
<content>
|
|
<xul:treeindentation/>
|
|
<xul:image class="tree-cell-primary-icon" inherits="validate,src"/>
|
|
<xul:label class="tree-cell-text" inherits="crop,value=label,align" flex="1" crop="right"/>
|
|
</content>
|
|
</binding>
|
|
|
|
<binding id="treecell-text" extends="xul:text">
|
|
<content crop="right"/>
|
|
</binding>
|
|
|
|
<binding id="treecell-header"
|
|
extends="chrome://global/content/bindings/tree.xml#tree-base">
|
|
<content>
|
|
<xul:hbox class="treecell-header-box" flex="1" align="center">
|
|
<xul:image class="tree-header-image" inherits="validate,src"/>
|
|
<xul:label class="tree-header-text" inherits="crop,value=label,disabled" flex="1" crop="right"/>
|
|
<xul:image class="tree-header-sortdirection"/>
|
|
</xul:hbox>
|
|
</content>
|
|
</binding>
|
|
|
|
<binding id="treecell-header-image"
|
|
extends="chrome://global/content/bindings/tree.xml#tree-base">
|
|
<content>
|
|
<xul:hbox class="treecell-header-image-box" flex="1" align="center">
|
|
<xul:image class="tree-header-image" inherits="validate,src"/>
|
|
</xul:hbox>
|
|
</content>
|
|
</binding>
|
|
|
|
</bindings>
|
|
|