home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2005 October / Gamestar_77_2005-10_dvd.iso / Programy / nsb-install-8-0.exe / chrome / toolkit.jar / content / global / bindings / tree.xml < prev    next >
Extensible Markup Language  |  2005-07-29  |  38KB  |  1,066 lines

  1. <?xml version="1.0"?>
  2.  
  3. <bindings id="treeBindings"
  4.    xmlns="http://www.mozilla.org/xbl"
  5.    xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  6.    xmlns:xbl="http://www.mozilla.org/xbl">
  7.  
  8.   <binding id="tree-base">
  9.     <resources>
  10.       <stylesheet src="chrome://global/skin/tree.css"/>
  11.     </resources>
  12.   </binding>
  13.  
  14.   <binding id="tree" extends="chrome://global/content/bindings/tree.xml#tree-base">
  15.     <content>
  16.       <children includes="treecols"/>
  17.       <xul:treerows class="tree-rows" flex="1">
  18.         <children/>
  19.       </xul:treerows>
  20.     </content>
  21.  
  22.     <implementation implements="nsIAccessibleProvider">
  23.  
  24.       <!-- ///////////////// nsIAccessibleProvider ///////////////// -->
  25.  
  26.       <property name="accessible">
  27.         <getter>
  28.           <![CDATA[
  29.             var accService = Components.classes["@mozilla.org/accessibilityService;1"].getService(Components.interfaces.nsIAccessibilityService);
  30.             return accService.createXULTreeAccessible(this);
  31.           ]]>
  32.         </getter>
  33.       </property>
  34.  
  35.       <property name="treeBoxObject"
  36.                 onget="return this.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);"
  37.                 readonly="true"/>
  38.       <property name="view"
  39.                 onget="return this.treeBoxObject.view;"
  40.                 onset="return this.treeBoxObject.view=val;"/>
  41.       <property name="contentView"
  42.                 onget="return this.treeBoxObject.view; /*.QueryInterface(Components.interfaces.nsITreeContentView)*/"
  43.                 readonly="true"/>
  44.       <property name="builderView"
  45.                 onget="return this.treeBoxObject.view; /*.QueryInterface(Components.interfaces.nsIXULTreeBuilder)*/"
  46.                 readonly="true"/>
  47.       <property name="currentIndex"
  48.                 onget="return this.treeBoxObject.selection.currentIndex;"
  49.                 onset="return this.treeBoxObject.selection.currentIndex=val;"/>
  50.       <field name="pageUpOrDownMovesSelection">
  51.         true
  52.       </field>
  53.       <field name="selectionHead">
  54.         -1
  55.       </field>
  56.       <field name="selectionTail">
  57.         -1
  58.       </field>
  59.       <property name="enableColumnDrag"
  60.                 onget="return this.hasAttribute('enableColumnDrag');"
  61.                 onset="if (val) this.setAttribute('enableColumnDrag', 'true');
  62.                        else this.removeAttribute('enableColumnDrag'); return val;"/>
  63.  
  64.       <property name="firstOrdinalColumn">
  65.         <getter><![CDATA[
  66.           var cols = this.firstChild;
  67.           while (cols && cols.localName != "treecols")
  68.             cols = cols.nextSibling;
  69.  
  70.           if (cols)
  71.             return cols.boxObject.firstChild;
  72.           else
  73.             return null;
  74.         ]]></getter>
  75.       </property>
  76.  
  77.       <property name="disableKeyNavigation"
  78.                 onget="return this.hasAttribute('disableKeyNavigation');"
  79.                 onset="if (val) this.setAttribute('disableKeyNavigation', 'true');
  80.                        else this.removeAttribute('disableKeyNavigation'); return val;"/>
  81.  
  82.       <property name="_selectDelay"
  83.                 onset="this.setAttribute('_selectDelay', val);"
  84.                 onget="return this.getAttribute('_selectDelay') || 50;"/>
  85.       <field name="_columnsDirty">true</field>
  86.       <field name="_lastKeyTime">0</field>
  87.       <field name="_incrementalString">""</field>
  88.  
  89.       <method name="_ensureColumnOrder">
  90.         <body><![CDATA[
  91.           if (this._columnsDirty) {
  92.             // update the ordinal position of each column to assure that it is
  93.             // an odd number and 2 positions above it's next sibling
  94.             var col = this.firstOrdinalColumn;
  95.             var cols = [];
  96.             while (col) {
  97.               if (col.localName == "treecol" && col.parentNode.parentNode == this)
  98.                 cols[cols.length] = col;
  99.               col = col.boxObject.nextSibling;
  100.             }
  101.             var i;
  102.             for (i = 0; i < cols.length; ++i)
  103.               cols[i].setAttribute("ordinal", (i*2)+1);
  104.  
  105.             // update the ordinal positions of splitters to even numbers, so that
  106.             // they are in between columns
  107.             var splitters = this.getElementsByTagName("splitter");
  108.             for (i = 0; i < splitters.length; ++i)
  109.               splitters[i].setAttribute("ordinal", (i+1)*2);
  110.  
  111.             this._columnsDirty = false;
  112.           }
  113.         ]]></body>
  114.       </method>
  115.  
  116.       <method name="_reorderColumn">
  117.         <parameter name="aColMove"/>
  118.         <parameter name="aColBefore"/>
  119.         <parameter name="aBefore"/>
  120.         <body><![CDATA[
  121.           this._ensureColumnOrder();
  122.  
  123.           var cols = [];
  124.           var col;
  125.           if (aColBefore.ordinal < aColMove.ordinal) {
  126.             col = aColBefore;
  127.             while (col) {
  128.               if (col.localName == "treecol")
  129.                 cols.push(col);
  130.               col = col.boxObject.nextSibling;
  131.               if (col == aColMove)
  132.                 break;
  133.             }
  134.  
  135.             aColMove.ordinal = aColBefore.ordinal;
  136.             var i;
  137.             for (i = 0; i < cols.length; ++i)
  138.               cols[i].ordinal += 2;
  139.           } else {
  140.             col = aColMove.boxObject.nextSibling;
  141.             while (col) {
  142.               if (col.localName == "treecol")
  143.                 cols.push(col);
  144.               col = col.boxObject.nextSibling;
  145.               if (col == aColBefore && aBefore)
  146.                 break;
  147.             }
  148.  
  149.             aColMove.ordinal = aBefore ? aColBefore.ordinal-2 : aColBefore.ordinal;
  150.  
  151.             for (i = 0; i < cols.length; ++i)
  152.               cols[i].ordinal -= 2;
  153.           }
  154.         ]]></body>
  155.       </method>
  156.  
  157.       <method name="_getColumnAtX">
  158.         <parameter name="aX"/>
  159.         <parameter name="aThresh"/>
  160.         <parameter name="aPos"/>
  161.         <body><![CDATA[
  162.           if (aPos) aPos.value = "before";
  163.  
  164.           var col = this.firstOrdinalColumn;
  165.           var lastCol = null;
  166.           var currentX = this.boxObject.x;
  167.           while (col) {
  168.             if (col.localName == "treecol" && col.parentNode.parentNode == this) {
  169.               var cw = col.boxObject.width;
  170.               if (cw > 0) {
  171.                 currentX += cw;
  172.                 if (currentX - (cw*aThresh) > aX)
  173.                   return col;
  174.               }
  175.               lastCol = col;
  176.             }
  177.             col = col.boxObject.nextSibling;
  178.           }
  179.  
  180.           if (aPos) aPos.value = "after";
  181.           return lastCol;
  182.         ]]></body>
  183.       </method>
  184.  
  185.     </implementation>
  186.  
  187.     <handlers>
  188.       <handler event="DOMMouseScroll" phase="capturing">
  189.         <![CDATA[
  190.           var rows = event.detail;
  191.           if (rows == NSUIEvent.SCROLL_PAGE_UP)
  192.             this.treeBoxObject.scrollByPages(-1);
  193.           else if (rows == NSUIEvent.SCROLL_PAGE_DOWN)
  194.             this.treeBoxObject.scrollByPages(1);
  195.           else
  196.             this.treeBoxObject.scrollByLines(rows);
  197.         ]]>
  198.       </handler>
  199.       <handler event="focus" action="this.treeBoxObject.focused = true;"/>
  200.       <handler event="blur" action="this.treeBoxObject.focused = false;"/>
  201.  
  202.       <handler event="dragenter" action="this.treeBoxObject.onDragEnter(event);"/>
  203.       <handler event="dragexit" action="this.treeBoxObject.onDragExit(event);"/>
  204.       <handler event="dragover" action="this.treeBoxObject.onDragOver(event);"/>
  205.       <handler event="dragdrop" action="this.treeBoxObject.onDragDrop(event);"/>
  206.  
  207.       <handler event="keypress" keycode="vk_enter">
  208.         <![CDATA[
  209.          if (this.currentIndex == -1)
  210.            return;
  211.          if (this.treeBoxObject.view.isContainer(this.currentIndex))
  212.            this.treeBoxObject.view.toggleOpenState(this.currentIndex);
  213.         ]]>
  214.       </handler>
  215.       <handler event="keypress" keycode="vk_return">
  216.         <![CDATA[
  217.          if (this.currentIndex == -1)
  218.            return;
  219.          if (this.treeBoxObject.view.isContainer(this.currentIndex))
  220.            this.treeBoxObject.view.toggleOpenState(this.currentIndex);
  221.         ]]>
  222.       </handler>
  223.       <handler event="keypress" keycode="vk_left">
  224.         <![CDATA[
  225.          if (this.currentIndex == -1)
  226.            return;
  227.          if (this.treeBoxObject.view.isContainer(this.currentIndex) &&
  228.              this.treeBoxObject.view.isContainerOpen(this.currentIndex)) {
  229.            this.treeBoxObject.view.toggleOpenState(this.currentIndex);
  230.          }
  231.          else {
  232.            var parentIndex = this.treeBoxObject.view.getParentIndex(this.currentIndex);
  233.            if (parentIndex >= 0) {
  234.              this.treeBoxObject.selection.select(parentIndex);
  235.              this.treeBoxObject.ensureRowIsVisible(parentIndex);
  236.            }
  237.          }
  238.         ]]>
  239.       </handler>
  240.       <handler event="keypress" keycode="vk_right">
  241.         <![CDATA[
  242.          if (this.currentIndex == -1)
  243.            return;
  244.          if (this.treeBoxObject.view.isContainer(this.currentIndex)) {
  245.            if (!this.treeBoxObject.view.isContainerOpen(this.currentIndex))
  246.              this.treeBoxObject.view.toggleOpenState(this.currentIndex);
  247.          }
  248.         ]]>
  249.       </handler>
  250.       <handler event="keypress" keycode="vk_up">
  251.         <![CDATA[
  252.          var c = this.currentIndex;
  253.          if (c == -1 || c == 0)
  254.            return;
  255.          this.selectionHead = -1;
  256.          this.selectionTail = -1;
  257.          this.treeBoxObject.selection.timedSelect(c-1, this._selectDelay);
  258.          this.treeBoxObject.ensureRowIsVisible(c-1);
  259.         ]]>
  260.       </handler>
  261.       <handler event="keypress" keycode="vk_down">
  262.         <![CDATA[
  263.          var c = this.currentIndex;
  264.          try { if (c+1 == this.treeBoxObject.view.rowCount)
  265.            return;
  266.          } catch (e) {}
  267.          this.selectionHead = -1;
  268.          this.selectionTail = -1;
  269.          this.treeBoxObject.selection.timedSelect(c+1, this._selectDelay);
  270.          this.treeBoxObject.ensureRowIsVisible(c+1);
  271.         ]]>
  272.       </handler>
  273.       <handler event="keypress" keycode="vk_up" modifiers="shift">
  274.         <![CDATA[
  275.          if (this.treeBoxObject.selection.single)
  276.            return;
  277.          var c = this.currentIndex;
  278.          if (c == -1 || c == 0)
  279.            return;
  280.          if (c == this.selectionTail) {
  281.            if (this.selectionHead < this.selectionTail) {
  282.              this.treeBoxObject.selection.toggleSelect(c);
  283.              this.currentIndex = c - 1;
  284.            }
  285.            else {
  286.              this.treeBoxObject.selection.toggleSelect(c - 1);
  287.            }
  288.          }
  289.          else {
  290.            this.treeBoxObject.selection.clearSelection();
  291.            this.selectionHead = c;
  292.            this.treeBoxObject.selection.rangedSelect(c, c - 1, true);
  293.          }
  294.          this.selectionTail = c - 1;
  295.          this.treeBoxObject.ensureRowIsVisible(c - 1);
  296.         ]]>
  297.       </handler>
  298.       <handler event="keypress" keycode="vk_down" modifiers="shift">
  299.         <![CDATA[
  300.          if (this.treeBoxObject.selection.single)
  301.            return;
  302.          var c = this.currentIndex;
  303.          try { if (c+1 == this.treeBoxObject.view.rowCount)
  304.            return;
  305.          } catch (e) {}
  306.          if (c == this.selectionTail) {
  307.            if (this.selectionHead > this.selectionTail) {
  308.              this.treeBoxObject.selection.toggleSelect(c);
  309.              this.currentIndex = c + 1;
  310.            }
  311.            else
  312.              this.treeBoxObject.selection.toggleSelect(c + 1);
  313.          }
  314.          else {
  315.            this.treeBoxObject.selection.clearSelection();
  316.            this.selectionHead = c;
  317.            this.treeBoxObject.selection.rangedSelect(c, c + 1, true);
  318.          }
  319.          this.selectionTail = c + 1;
  320.          this.treeBoxObject.ensureRowIsVisible(c + 1);
  321.         ]]>
  322.       </handler>
  323.       <handler event="keypress" keycode="vk_up" modifiers="control">
  324.         <![CDATA[
  325.          var c = this.currentIndex;
  326.          if (c == -1 || c == 0)
  327.            return;
  328.          this.currentIndex = c-1;
  329.          this.treeBoxObject.ensureRowIsVisible(c-1);
  330.         ]]>
  331.       </handler>
  332.       <handler event="keypress" keycode="vk_down" modifiers="control">
  333.         <![CDATA[
  334.          var c = this.currentIndex;
  335.          try { if (c+1 == this.treeBoxObject.view.rowCount)
  336.            return;
  337.          } catch (e) {}
  338.          this.currentIndex = c+1;
  339.          this.treeBoxObject.ensureRowIsVisible(c+1);
  340.         ]]>
  341.       </handler>
  342.       <handler event="keypress" keycode="vk_page_up">
  343.         <![CDATA[
  344.          if (! this.pageUpOrDownMovesSelection) {
  345.            this.treeBoxObject.scrollByPages(-1);
  346.            return;
  347.          }
  348.          var c = this.currentIndex;
  349.          if (c == 0)
  350.            return;
  351.          this.selectionHead = -1;
  352.          this.selectionTail = -1;
  353.          var f = this.treeBoxObject.getFirstVisibleRow();
  354.          var i = 0;
  355.          if (f > 0) {
  356.            var p = this.treeBoxObject.getPageCount();
  357.            if (f - p >= 0)
  358.              i = c - p;
  359.            else
  360.              i = c - f;
  361.            this.treeBoxObject.scrollByPages(-1);
  362.          }
  363.          this.treeBoxObject.selection.timedSelect(i, this._selectDelay);
  364.         ]]>
  365.       </handler>
  366.       <handler event="keypress" keycode="vk_page_down">
  367.         <![CDATA[
  368.          if (! this.pageUpOrDownMovesSelection) {
  369.            this.treeBoxObject.scrollByPages(1);
  370.            return;
  371.          }
  372.          var c = this.currentIndex;
  373.          var l = this.treeBoxObject.view.rowCount - 1;
  374.          if (c == l)
  375.            return;
  376.          this.selectionHead = -1;
  377.          this.selectionTail = -1;
  378.          var f = this.treeBoxObject.getFirstVisibleRow();
  379.          var p = this.treeBoxObject.getPageCount();
  380.          var i = l;
  381.          var lastTopRowIndex = l - p;
  382.          if (f <= lastTopRowIndex) {
  383.            if (f + p <= lastTopRowIndex)
  384.              i = c + p;
  385.            else
  386.              i = lastTopRowIndex + c - f + 1;
  387.            this.treeBoxObject.scrollByPages(1);
  388.          }
  389.          this.treeBoxObject.selection.timedSelect(i, this._selectDelay);
  390.         ]]>
  391.       </handler>
  392.       <handler event="keypress" keycode="vk_page_up" modifiers="shift">
  393.         <![CDATA[
  394.          if (this.treeBoxObject.selection.single)
  395.            return;
  396.          var c = this.currentIndex;
  397.          if (c == 0)
  398.            return;
  399.          var f = this.treeBoxObject.getFirstVisibleRow();
  400.          var i = 0;
  401.          if (f > 0) {
  402.            var p = this.treeBoxObject.getPageCount();
  403.            if (f - p >= 0)
  404.              i = c - p;
  405.            else
  406.              i = c - f;
  407.            this.treeBoxObject.scrollByPages(-1);
  408.          }
  409.          if (c == this.selectionTail) {
  410.            if (this.selectionHead < this.selectionTail) {
  411.              if (i < this.selectionHead) {
  412.                this.treeBoxObject.selection.clearRange(c, this.selectionHead + 1);
  413.                this.treeBoxObject.selection.rangedSelect(this.selectionHead - 1, i, true);
  414.              }
  415.              else {
  416.                this.treeBoxObject.selection.clearRange(c, i + 1);
  417.                this.currentIndex = i;
  418.              }
  419.            }
  420.            else
  421.              this.treeBoxObject.selection.rangedSelect(c - 1, i, true);
  422.          }
  423.          else {
  424.            this.treeBoxObject.selection.clearSelection();
  425.            this.selectionHead = c;
  426.            this.treeBoxObject.selection.rangedSelect(c, i, true);
  427.          }
  428.          this.selectionTail = i;
  429.         ]]>
  430.       </handler>
  431.       <handler event="keypress" keycode="vk_page_down" modifiers="shift">
  432.         <![CDATA[
  433.          if (this.treeBoxObject.selection.single)
  434.            return;
  435.          var c = this.currentIndex;
  436.          var l = this.treeBoxObject.view.rowCount - 1;
  437.          if (c == l)
  438.            return;
  439.          var f = this.treeBoxObject.getFirstVisibleRow();
  440.          var p = this.treeBoxObject.getPageCount();
  441.          var i = l;
  442.          var lastTopRowIndex = l - p;
  443.          if (f <= lastTopRowIndex) {
  444.            if (f + p <= lastTopRowIndex)
  445.              i = c + p;
  446.            else
  447.              i = lastTopRowIndex + c - f + 1;
  448.            this.treeBoxObject.scrollByPages(1);
  449.          }
  450.          if (c == this.selectionTail) {
  451.            if (this.selectionHead > this.selectionTail) {
  452.              if (i > this.selectionHead) {
  453.                this.treeBoxObject.selection.clearRange(c, this.selectionHead - 1);
  454.                this.treeBoxObject.selection.rangedSelect(this.selectionHead + 1, i, true);
  455.              }
  456.              else {
  457.                this.treeBoxObject.selection.clearRange(c, i - 1);
  458.                this.currentIndex = i;
  459.              }
  460.            }
  461.            else
  462.              this.treeBoxObject.selection.rangedSelect(c + 1, i, true);
  463.          }
  464.          else {
  465.            this.treeBoxObject.selection.clearSelection();
  466.            this.selectionHead = c;
  467.            this.treeBoxObject.selection.rangedSelect(c, i, true);
  468.          }
  469.          this.selectionTail = i;
  470.         ]]>
  471.       </handler>
  472.       <handler event="keypress" keycode="vk_page_up" modifiers="control">
  473.         <![CDATA[
  474.          var c = this.currentIndex;
  475.          if (c == 0)
  476.            return;
  477.          var f = this.treeBoxObject.getFirstVisibleRow();
  478.          var i = 0;
  479.          if (f > 0) {
  480.            var p = this.treeBoxObject.getPageCount();
  481.            if (f - p >= 0)
  482.              i = c - p;
  483.            else
  484.              i = c - f;
  485.            this.treeBoxObject.scrollByPages(-1);
  486.          }
  487.          this.currentIndex = i;
  488.         ]]>
  489.       </handler>
  490.       <handler event="keypress" keycode="vk_page_down" modifiers="control">
  491.         <![CDATA[
  492.          var c = this.currentIndex;
  493.          var l = this.treeBoxObject.view.rowCount - 1;
  494.          if (c == l)
  495.            return;
  496.          var f = this.treeBoxObject.getFirstVisibleRow();
  497.          var p = this.treeBoxObject.getPageCount();
  498.          var i = l;
  499.          var lastTopRowIndex = l - p;
  500.          if (f <= lastTopRowIndex) {
  501.            if (f + p <= lastTopRowIndex)
  502.              i = c + p;
  503.            else
  504.              i = lastTopRowIndex + c - f + 1;
  505.            this.treeBoxObject.scrollByPages(1);
  506.          }
  507.          this.currentIndex = i;
  508.         ]]>
  509.       </handler>
  510.       <handler event="keypress" keycode="vk_home">
  511.         <![CDATA[
  512.          if (this.currentIndex == 0)
  513.            return;
  514.          this.selectionHead = -1;
  515.          this.selectionTail = -1;
  516.          this.treeBoxObject.selection.select(0);
  517.          this.treeBoxObject.ensureRowIsVisible(0);
  518.         ]]>
  519.       </handler>
  520.       <handler event="keypress" keycode="vk_end">
  521.         <![CDATA[
  522.          var l = this.treeBoxObject.view.rowCount - 1;
  523.          if (this.currentIndex == l)
  524.            return;
  525.          this.selectionHead = -1;
  526.          this.selectionTail = -1;
  527.          this.treeBoxObject.selection.select(l);
  528.          this.treeBoxObject.ensureRowIsVisible(l);
  529.         ]]>
  530.       </handler>
  531.       <handler event="keypress" keycode="vk_home" modifiers="shift">
  532.         <![CDATA[
  533.          if (this.treeBoxObject.selection.single)
  534.            return;
  535.          var c = this.currentIndex;
  536.          if (c == 0)
  537.            return;
  538.          if (c != this.selectionTail) {
  539.            this.treeBoxObject.selection.clearSelection();
  540.            this.selectionHead = c;
  541.          }
  542.          this.treeBoxObject.selection.rangedSelect(c, 0, true);
  543.          this.selectionTail = 0;
  544.          this.treeBoxObject.ensureRowIsVisible(0);
  545.         ]]>
  546.       </handler>
  547.       <handler event="keypress" keycode="vk_end" modifiers="shift">
  548.         <![CDATA[
  549.          if (this.treeBoxObject.selection.single)
  550.            return;
  551.          var c = this.currentIndex;
  552.          var l = this.treeBoxObject.view.rowCount - 1;
  553.          if (c == l)
  554.            return;
  555.          if (c != this.selectionTail) {
  556.            this.treeBoxObject.selection.clearSelection();
  557.            this.selectionHead = c;
  558.          }
  559.          this.treeBoxObject.selection.rangedSelect(c, l, true);
  560.          this.selectionTail = l;
  561.          this.treeBoxObject.ensureRowIsVisible(l);
  562.         ]]>
  563.       </handler>
  564.       <handler event="keypress" keycode="vk_home" modifiers="control">
  565.         <![CDATA[
  566.          if (this.currentIndex == 0)
  567.            return;
  568.          this.currentIndex = 0;
  569.          this.treeBoxObject.ensureRowIsVisible(0);
  570.         ]]>
  571.       </handler>
  572.       <handler event="keypress" keycode="vk_end" modifiers="control">
  573.         <![CDATA[
  574.          var l = this.treeBoxObject.view.rowCount - 1;
  575.          if (this.currentIndex == l)
  576.            return;
  577.          this.currentIndex = l;
  578.          this.treeBoxObject.ensureRowIsVisible(l);
  579.         ]]>
  580.       </handler>
  581.       <handler event="keypress">
  582.         <![CDATA[
  583.          var c = this.currentIndex;
  584.          if (event.keyCode == ' '.charCodeAt(0)) {
  585.            if (!this.treeBoxObject.selection.isSelected(c))
  586.              this.treeBoxObject.selection.toggleSelect(c);
  587.          }
  588.          else if (!this.disableKeyNavigation && event.charCode > 0 &&
  589.                   !event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey) {
  590.            var key = String.fromCharCode(event.charCode);
  591.            key = key.toLowerCase();
  592.            if (event.timeStamp - this._lastKeyTime > 1000)
  593.              this._incrementalString = key;
  594.            else
  595.              this._incrementalString += key;
  596.            this._lastKeyTime = event.timeStamp;
  597.  
  598.            var length = this._incrementalString.length;
  599.            var incrementalString = this._incrementalString;
  600.            var charIndex = 1;
  601.            while (charIndex < length && incrementalString[charIndex] == incrementalString[charIndex - 1])
  602.              charIndex++;
  603.            // If all letters in incremental string are same, just try to match the first one
  604.            if (charIndex == length) {
  605.              length = 1;
  606.              incrementalString = incrementalString.substring(0, length);
  607.            }
  608.  
  609.            var primarycol = this.treeBoxObject.getKeyColumnIndex();
  610.            var colID = this.treeBoxObject.getColumnID(primarycol);
  611.            var rowCount = this.treeBoxObject.view.rowCount;
  612.            var start = 1;
  613.  
  614.            if (length > 1) {
  615.              start = 0;
  616.              if (c < 0)
  617.                c = 0;
  618.            }
  619.  
  620.            for (var i = 0; i < rowCount; i++) {
  621.              var l = (i + start + c) % rowCount;
  622.              var cellText = this.treeBoxObject.view.getCellText(l, colID);
  623.              cellText = cellText.substring(0, length).toLowerCase();
  624.              if (cellText == incrementalString) {
  625.                this.selectionHead = -1;
  626.                this.selectionTail = -1;
  627.                this.treeBoxObject.selection.timedSelect(l, this._selectDelay);
  628.                this.treeBoxObject.ensureRowIsVisible(l);
  629.                break;
  630.              }
  631.            }
  632.           }
  633.          ]]>
  634.       </handler>
  635.     </handlers>
  636.   </binding>
  637.  
  638.   <binding id="treecols" extends="chrome://global/content/bindings/tree.xml#tree-base">
  639.     <content>
  640.       <children includes="treecol|splitter"/>
  641.       <xul:treecolpicker class="treecol-image" fixed="true" ordinal="2147483647" xbl:inherits="tooltiptext=pickertooltiptext"/>
  642.     </content>
  643.     <implementation implements="nsIAccessibleProvider">
  644.       <property name="accessible">
  645.         <getter>
  646.           <![CDATA[
  647.             var accService = Components.classes["@mozilla.org/accessibilityService;1"].getService(Components.interfaces.nsIAccessibilityService);
  648.             return accService.createXULTreeColumnsAccessible(this);
  649.           ]]>
  650.         </getter>
  651.       </property>
  652.     </implementation>
  653.   </binding>
  654.  
  655.   <binding id="treerows" extends="chrome://global/content/bindings/tree.xml#tree-base">
  656.     <content>
  657.       <xul:hbox flex="1" class="tree-bodybox">
  658.         <children/>
  659.       </xul:hbox>
  660.       <xul:scrollbar height="0" minwidth="0" minheight="0" orient="vertical" class="tree-scrollbar" collapsed="true"/>
  661.     </content>
  662.     <handlers>
  663.       <handler event="underflow">
  664.         <![CDATA[
  665.           document.getAnonymousNodes(this)[1].collapsed = true;
  666.           event.preventBubble();
  667.         ]]>
  668.       </handler>
  669.       <handler event="overflow">
  670.         <![CDATA[
  671.           document.getAnonymousNodes(this)[1].collapsed = false;
  672.           event.preventBubble();
  673.         ]]>
  674.       </handler>
  675.     </handlers>
  676.   </binding>
  677.  
  678.   <binding id="treebody" extends="chrome://global/content/bindings/tree.xml#tree-base">
  679.     <implementation>
  680.       <constructor>
  681.         if ("_ensureColumnOrder" in this.parentNode)
  682.           this.parentNode._ensureColumnOrder();
  683.       </constructor>
  684.  
  685.       <field name="_lastSelectedRow">
  686.         -1
  687.       </field>
  688.     </implementation>
  689.     <handlers>
  690.       <!-- If there is no modifier key, we select on mousedown, not
  691.            click, so that drags work correctly. -->
  692.       <handler event="mousedown">
  693.       <![CDATA[
  694.          if (((!event.ctrlKey || !this.parentNode.pageUpOrDownMovesSelection) &&
  695.              !event.shiftKey && !event.metaKey) ||
  696.              this.parentNode.treeBoxObject.selection.single) {
  697.            var row = {};
  698.            var col = {};
  699.            var obj = {};
  700.            var b = this.parentNode.treeBoxObject;
  701.            b.getCellAt(event.clientX, event.clientY, row, col, obj);
  702.  
  703.            // save off the last selected row
  704.            this._lastSelectedRow = row.value;
  705.  
  706.            if (row.value == -1)
  707.              return;
  708.  
  709.            if (col.value && obj.value != "twisty") {
  710.              var column = document.getElementById(col.value);
  711.              var cycler = column.hasAttribute('cycler');
  712.  
  713.              if (cycler)
  714.                b.view.cycleCell(row.value, col.value);
  715.              else
  716.                  if (!b.selection.isSelected(row.value)) {
  717.                  b.selection.select(row.value);
  718.                  b.ensureRowIsVisible(row.value);
  719.                }
  720.            }
  721.          }
  722.       ]]>
  723.       </handler>
  724.  
  725.       <!-- On a click (up+down on the same item), deselect everything
  726.            except this item. -->
  727.       <handler event="click">
  728.       <![CDATA[
  729.         if (event.button != 0) return;
  730.         var row = {};
  731.         var col = {};
  732.         var obj = {};
  733.         var b = this.parentNode.treeBoxObject;
  734.         b.getCellAt(event.clientX, event.clientY, row, col, obj);
  735.  
  736.         if (row.value == -1)
  737.           return;
  738.  
  739.         if (obj.value == "twisty") {
  740.           if (b.selection.currentIndex >= 0 &&
  741.               b.view.isContainerOpen(row.value)) {
  742.             var parentIndex = b.view.getParentIndex(b.selection.currentIndex);
  743.             while (parentIndex >= 0 && parentIndex != row.value)
  744.               parentIndex = b.view.getParentIndex(parentIndex);
  745.             if (parentIndex == row.value)
  746.               b.selection.select(parentIndex);
  747.           }
  748.           b.view.toggleOpenState(row.value);
  749.           return;
  750.         }
  751.  
  752.         if (! this.parentNode.treeBoxObject.selection.single) {
  753.           var augment = event.ctrlKey || event.metaKey;
  754.           if (event.shiftKey) {
  755.             b.selection.rangedSelect(-1, row.value, augment);
  756.             b.ensureRowIsVisible(row.value);
  757.             return;
  758.           }
  759.           if (augment) {
  760.             b.selection.toggleSelect(row.value);
  761.             b.ensureRowIsVisible(row.value);
  762.             b.selection.currentIndex = row.value;
  763.             return;
  764.           }
  765.         }
  766.  
  767.         /* We want to deselect all the selected items except what was
  768.           clicked, UNLESS it was a right-click.  We have to do this
  769.           in click rather than mousedown so that you can drag a
  770.           selected group of items */
  771.  
  772.         if (!col.value) return;
  773.         var column = document.getElementById(col.value);
  774.         var cycler = column.hasAttribute('cycler');
  775.  
  776.         // if the last row has changed in between the time we
  777.         // mousedown and the time we click, don't fire the select handler.
  778.         // see bug #92366
  779.         if (!cycler && this._lastSelectedRow == row.value) {
  780.           b.selection.select(row.value);
  781.           b.ensureRowIsVisible(row.value);
  782.         }
  783.       ]]>
  784.       </handler>
  785.  
  786.       <!-- double-click -->
  787.       <handler event="click" clickcount="2">
  788.       <![CDATA[
  789.            var row = {};
  790.            var col = {};
  791.            var obj = {};
  792.            var b = this.parentNode.treeBoxObject;
  793.            b.getCellAt(event.clientX, event.clientY, row, col, obj);
  794.  
  795.            if (row.value == -1)
  796.              return;
  797.  
  798.            var column = document.getElementById(col.value);
  799.            var cycler = column.hasAttribute('cycler');
  800.  
  801.            if (!cycler && obj.value != "twisty" && b.view.isContainer(row.value))
  802.              b.view.toggleOpenState(row.value);
  803.       ]]>
  804.       </handler>
  805.  
  806.     </handlers>
  807.   </binding>
  808.  
  809.   <binding id="treecol-base" extends="chrome://global/content/bindings/tree.xml#tree-base">
  810.     <implementation>
  811.       <constructor>
  812.         this.parentNode.parentNode._columnsDirty = true;
  813.       </constructor>
  814.  
  815.       <property name="ordinal">
  816.         <getter><![CDATA[
  817.           var val = this.getAttribute("ordinal");
  818.           return val == "" ? 1 : (val == "0" ? 0 : parseInt(val));
  819.         ]]></getter>
  820.         <setter><![CDATA[
  821.           this.setAttribute("ordinal", val);
  822.         ]]></setter>
  823.       </property>
  824.  
  825.       <property name="_previousVisibleColumn">
  826.         <getter><![CDATA[
  827.           var sib = this.boxObject.previousSibling;
  828.           while (sib) {
  829.             if (sib.localName == "treecol" && sib.boxObject.width > 0 && sib.parentNode == this.parentNode)
  830.               return sib;
  831.             sib = sib.boxObject.previousSibling;
  832.           }
  833.           return null;
  834.         ]]></getter>
  835.       </property>
  836.  
  837.       <method name="onDragMouseMove">
  838.         <parameter name="aEvent"/>
  839.         <body><![CDATA[
  840.           var col = document.treecolDragging;
  841.           if (!col) return;
  842.  
  843.           // determine if we have moved the mouse far enough
  844.           // to initiate a drag
  845.           if (col.mDragGesturing) {
  846.             if (Math.abs(aEvent.clientX - col.mStartDragX) < 5 &&
  847.                 Math.abs(aEvent.clientY - col.mStartDragY) < 5) {
  848.               return;
  849.             } else {
  850.               col.mDragGesturing = false;
  851.               col.setAttribute("dragging", "true");
  852.               window.addEventListener("click", col.onDragMouseClick, true);
  853.             }
  854.           }
  855.  
  856.           var pos = {};
  857.           var targetCol = col.parentNode.parentNode._getColumnAtX(aEvent.clientX, 0.5, pos);
  858.  
  859.           // bail if we haven't mousemoved to a different column
  860.           if (col.mTargetCol == targetCol && col.mTargetDir == pos.value)
  861.             return;
  862.  
  863.           var tree = col.parentNode.parentNode;
  864.           var sib;
  865.           if (col.mTargetCol) {
  866.             // remove previous insertbefore/after attributes
  867.             col.mTargetCol.removeAttribute("insertbefore");
  868.             col.mTargetCol.removeAttribute("insertafter");
  869.             tree.treeBoxObject.invalidateColumn(col.mTargetCol.id);
  870.             sib = col.mTargetCol._previousVisibleColumn;
  871.             if (sib) {
  872.               sib.removeAttribute("insertafter");
  873.               tree.treeBoxObject.invalidateColumn(sib.id);
  874.             }
  875.             col.mTargetCol = null;
  876.             col.mTargetDir = null;
  877.           }
  878.  
  879.           if (targetCol) {
  880.             // set insertbefore/after attributes
  881.             if (pos.value == "after") {
  882.               targetCol.setAttribute("insertafter", "true");
  883.             } else {
  884.               targetCol.setAttribute("insertbefore", "true");
  885.               sib = targetCol._previousVisibleColumn;
  886.               if (sib) {
  887.                 sib.setAttribute("insertafter", "true");
  888.                 tree.treeBoxObject.invalidateColumn(sib.id);
  889.               }
  890.             }
  891.             tree.treeBoxObject.invalidateColumn(targetCol.id);
  892.             col.mTargetCol = targetCol;
  893.             col.mTargetDir = pos.value;
  894.           }
  895.         ]]></body>
  896.       </method>
  897.  
  898.       <method name="onDragMouseUp">
  899.         <parameter name="aEvent"/>
  900.         <body><![CDATA[
  901.           var col = document.treecolDragging;
  902.           if (!col) return;
  903.  
  904.           if (!col.mDragGesturing) {
  905.             if (col.mTargetCol) {
  906.               // remove insertbefore/after attributes
  907.               var before = col.mTargetCol.hasAttribute("insertbefore");
  908.               col.mTargetCol.removeAttribute(before ? "insertbefore" : "insertafter");
  909.               if (before) {
  910.                 var sib = col.mTargetCol._previousVisibleColumn;
  911.                 if (sib)
  912.                   sib.removeAttribute("insertafter");
  913.               }
  914.  
  915.               // move the column
  916.               if (col != col.mTargetCol)
  917.                 col.parentNode.parentNode._reorderColumn(col, col.mTargetCol, before);
  918.  
  919.               // repaint to remove lines
  920.               col.parentNode.parentNode.treeBoxObject.invalidate();
  921.  
  922.               col.mTargetCol = null;
  923.             }
  924.           } else
  925.             col.mDragGesturing = false;
  926.  
  927.           document.treecolDragging = null;
  928.           col.removeAttribute("dragging");
  929.  
  930.           window.removeEventListener("mousemove", col.onDragMouseMove, true);
  931.           window.removeEventListener("mouseup", col.onDragMouseUp, true);
  932.           // we have to wait for the click event to fire before removing
  933.           // cancelling handler
  934.           var clickHandler = function(handler) {
  935.             window.removeEventListener("click", handler, true);
  936.           };
  937.           window.setTimeout(clickHandler, 0, col.onDragMouseClick);
  938.         ]]></body>
  939.       </method>
  940.  
  941.       <method name="onDragMouseClick">
  942.         <parameter name="aEvent"/>
  943.         <body><![CDATA[
  944.           // prevent click event from firing after column drag and drop
  945.           aEvent.preventBubble();
  946.           aEvent.preventDefault();
  947.         ]]></body>
  948.       </method>
  949.     </implementation>
  950.  
  951.     <handlers>
  952.       <handler event="mousedown" button="0"><![CDATA[
  953.         if (this.parentNode.parentNode.enableColumnDrag) {
  954.           var xulns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
  955.           var cols = this.parentNode.getElementsByTagNameNS(xulns, "treecol");
  956.  
  957.           // only start column drag operation if there are at least 2 visible columns
  958.           var visible = 0;
  959.           for (var i = 0; i < cols.length; ++i)
  960.             if (cols[i].boxObject.width > 0) ++visible;
  961.  
  962.           if (visible > 1) {
  963.             window.addEventListener("mousemove", this.onDragMouseMove, false);
  964.             window.addEventListener("mouseup", this.onDragMouseUp, false);
  965.             document.treecolDragging = this;
  966.             this.mDragGesturing = true;
  967.             this.mStartDragX = event.clientX;
  968.             this.mStartDragY = event.clientY;
  969.           }
  970.         }
  971.       ]]></handler>
  972.     </handlers>
  973.   </binding>
  974.  
  975.   <binding id="treecol" extends="chrome://global/content/bindings/tree.xml#treecol-base">
  976.     <content>
  977.       <xul:label class="treecol-text" xbl:inherits="crop,value=label" flex="1" crop="right"/>
  978.       <xul:image class="treecol-sortdirection" xbl:inherits="sortDirection"/>
  979.     </content>
  980.     <implementation implements="nsIAccessibleProvider">
  981.       <property name="accessible">
  982.         <getter>
  983.           <![CDATA[
  984.             var accService = Components.classes["@mozilla.org/accessibilityService;1"].getService(Components.interfaces.nsIAccessibilityService);
  985.             return accService.createXULTreeColumnitemAccessible(this);
  986.           ]]>
  987.         </getter>
  988.       </property>
  989.     </implementation>
  990.  
  991.     <handlers>
  992.       <handler event="click" button="0" phase="target" action="this.parentNode.parentNode.treeBoxObject.view.cycleHeader(this.id, this);"/>
  993.     </handlers>
  994.   </binding>
  995.  
  996.   <binding id="treecol-image" extends="chrome://global/content/bindings/tree.xml#treecol-base">
  997.     <content>
  998.       <xul:image class="treecol-icon" xbl:inherits="src"/>
  999.     </content>
  1000.     <handlers>
  1001.       <handler event="click" button="0" action="this.parentNode.parentNode.treeBoxObject.view.cycleHeader(this.id, this)"/>
  1002.     </handlers>
  1003.   </binding>
  1004.  
  1005.   <binding id="columnpicker" display="xul:button"
  1006.            extends="chrome://global/content/bindings/tree.xml#tree-base">
  1007.     <content>
  1008.       <xul:image class="tree-columnpicker-icon"/>
  1009.       <xul:menupopup anonid="popup"/>
  1010.     </content>
  1011.  
  1012.     <implementation>
  1013.       <method name="buildPopup">
  1014.         <parameter name="aPopup"/>
  1015.         <body>
  1016.           <![CDATA[
  1017.             // we no longer cache the picker content.
  1018.             // remove the old content
  1019.             while (aPopup.hasChildNodes())
  1020.               aPopup.removeChild(aPopup.lastChild);
  1021.  
  1022.             for (var currCol = this.parentNode.firstChild; currCol; currCol = currCol.nextSibling) {
  1023.               // Construct an entry for each column in the row, unless
  1024.               // it is not being shown
  1025.               if (currCol.localName == "treecol" && !currCol.hasAttribute("ignoreincolumnpicker")) {
  1026.                 var popupChild = document.createElement("menuitem");
  1027.                 popupChild.setAttribute("type", "checkbox");
  1028.                 var columnName = currCol.getAttribute("display") || currCol.getAttribute("label");
  1029.                 popupChild.setAttribute("label", columnName);
  1030.                 popupChild.setAttribute("colid", currCol.id);
  1031.                 if (currCol.getAttribute("hidden") != "true")
  1032.                   popupChild.setAttribute("checked", "true");
  1033.                 if (currCol.getAttribute("primary") == "true")
  1034.                   popupChild.setAttribute("disabled", "true");
  1035.                 aPopup.appendChild(popupChild);
  1036.               }
  1037.             }
  1038.           ]]>
  1039.         </body>
  1040.       </method>
  1041.     </implementation>
  1042.  
  1043.     <handlers>
  1044.       <handler event="command">
  1045.         <![CDATA[
  1046.           if (event.originalTarget == this) {
  1047.             var popup = document.getAnonymousElementByAttribute(this, "anonid", "popup");
  1048.             this.buildPopup(popup);
  1049.             popup.showPopup(this, -1, -1, "popup", "bottomright", "topright");
  1050.           } else {
  1051.             var colid = event.originalTarget.getAttribute("colid");
  1052.             var colNode = document.getElementById(colid);
  1053.             if (colNode) {
  1054.               if (colNode.getAttribute("hidden") == "true")
  1055.                 colNode.setAttribute("hidden", "false");
  1056.               else
  1057.                 colNode.setAttribute("hidden", "true");
  1058.             }
  1059.           }
  1060.         ]]>
  1061.       </handler>
  1062.     </handlers>
  1063.   </binding>
  1064. </bindings>
  1065.  
  1066.