Source code

Revision control

Other Tools

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
<?xml version="1.0"?>

<!-- This Source Code Form is subject to the terms of the Mozilla Public
   - License, v. 2.0. If a copy of the MPL was not distributed with this
   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->

<!-- This file relies on these specific Chrome/XBL globals -->
<!-- globals ChromeNodeList -->

<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="richlistitem"
           extends="chrome://global/content/bindings/general.xml#basetext">
    <implementation implements="nsIDOMXULSelectControlItemElement">
      <field name="selectedByMouseOver">false</field>

      <destructor>
        <![CDATA[
          var control = this.control;
          if (!control)
            return;
          // When we are destructed and we are current or selected, unselect ourselves
          // so that richlistbox's selection doesn't point to something not in the DOM.
          // We don't want to reset last-selected, so we set _suppressOnSelect.
          if (this.selected) {
            var suppressSelect = control._suppressOnSelect;
            control._suppressOnSelect = true;
            control.removeItemFromSelection(this);
            control._suppressOnSelect = suppressSelect;
          }
          if (this.current)
            control.currentItem = null;
        ]]>
      </destructor>

      <!-- nsIDOMXULSelectControlItemElement -->
      <property name="label" readonly="true">
        <!-- Setter purposely not implemented; the getter returns a
             concatentation of label text to expose via accessibility APIs -->
        <getter>
          <![CDATA[
            const XULNS =
              "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
            return Array.from(this.getElementsByTagNameNS(XULNS, "label"),
                             label => label.value)
                        .join(" ");
          ]]>
        </getter>
      </property>

      <property name="searchLabel">
        <getter>
          <![CDATA[
            return this.hasAttribute("searchlabel") ?
                   this.getAttribute("searchlabel") : this.label;
          ]]>
        </getter>
        <setter>
          <![CDATA[
            if (val !== null)
              this.setAttribute("searchlabel", val);
            else
              // fall back to the label property (default value)
              this.removeAttribute("searchlabel");
            return val;
          ]]>
        </setter>
      </property>

      <!-- nsIDOMXULSelectControlItemElement -->
      <property name="value" onget="return this.getAttribute('value');"
                             onset="this.setAttribute('value', val); return val;"/>

      <!-- nsIDOMXULSelectControlItemElement -->
      <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>

      <!-- nsIDOMXULSelectControlItemElement -->
      <property name="control">
        <getter><![CDATA[
          var parent = this.parentNode;
          while (parent) {
            if (parent.localName == "richlistbox")
              return parent;
            parent = parent.parentNode;
          }
          return null;
        ]]></getter>
      </property>

      <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>
    </implementation>

    <handlers>
      <!-- If there is no modifier key, we select on mousedown, not
           click, so that drags work correctly. -->
      <handler event="mousedown">
        <![CDATA[
          var control = this.control;
          if (!control || control.disabled)
            return;
          if ((!event.ctrlKey || (/Mac/.test(navigator.platform) && event.button == 2)) &&
              !event.shiftKey && !event.metaKey) {
            if (!this.selected) {
              control.selectItem(this);
            }
            control.currentItem = this;
          }
        ]]>
      </handler>

      <!-- On a click (up+down on the same item), deselect everything
           except this item. -->
      <handler event="click" button="0">
        <![CDATA[
          var control = this.control;
          if (!control || control.disabled)
            return;
          control._userSelecting = true;
          if (control.selType != "multiple") {
            control.selectItem(this);
          } else if (event.ctrlKey || event.metaKey) {
            control.toggleItemSelection(this);
            control.currentItem = this;
          } else if (event.shiftKey) {
            control.selectItemRange(null, this);
            control.currentItem = this;
          } 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 */

            // use selectItemRange instead of selectItem, because this
            // doesn't de- and reselect this item if it is selected
            control.selectItemRange(this, this);
          }
          control._userSelecting = false;
        ]]>
      </handler>
    </handlers>
  </binding>
</bindings>