browser/metro/base/content/helperui/SelectHelperUI.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 "use strict";
     7 /**
     8  * SelectHelperUI: Provides an interface for making a choice in a list.
     9  *   Supports simultaneous selection of choices and group headers.
    10  */
    11 var SelectHelperUI = {
    12   _list: null,
    14   get _container() {
    15     delete this._container;
    16     return this._container = document.getElementById("select-container");
    17   },
    19   get _listbox() {
    20     delete this._listbox;
    21     return this._listbox = document.getElementById("select-commands");
    22   },
    24   get _menuPopup() {
    25     let popup = document.getElementById("select-popup");
    26     delete this._menuPopup;
    27     return this._menuPopup = new MenuPopup(this._container, popup);
    28   },
    30   show: function selectHelperShow(aList, aTitle, aRect) {
    31     if (this._list) {
    32       this.reset();
    33     }
    35     this._list = aList;
    37     this._listbox.setAttribute("seltype", aList.multiple ? "multiple" : "single");
    39     let firstSelected = null;
    41     // Using a fragment prevent us to hang on huge list
    42     let fragment = document.createDocumentFragment();
    43     let choices = aList.choices;
    44     let selectedItems = [];
    45     for (let i = 0; i < choices.length; i++) {
    46       let choice = choices[i];
    47       let item = document.createElement("richlistitem");
    48       let label = document.createElement("label");
    50       item.setAttribute("class", "option-command listitem-iconic");
    51       item.setAttribute("flex", "1");
    52       item.setAttribute("crop", "center");
    53       label.setAttribute("value", choice.text);
    54       item.appendChild(label);
    55       item.setAttribute("oldstate", "false");
    56       choice.disabled ? item.setAttribute("disabled", "true")
    57                       : item.removeAttribute("disabled");
    59       fragment.appendChild(item);
    61       if (choice.group) {
    62         item.classList.add("optgroup");
    63         continue;
    64       }
    66       item.optionIndex = choice.optionIndex;
    67       item.choiceIndex = i;
    69       if (choice.inGroup) {
    70         item.classList.add("in-optgroup");
    71       }
    73       if (choice.selected) {
    74         firstSelected = firstSelected || item;
    75         selectedItems.push(item);
    76       }
    77     }
    78     this._listbox.appendChild(fragment);
    80     this._container.addEventListener("click", this, false);
    81     window.addEventListener("MozPrecisePointer", this, false);
    82     this._menuPopup.show(this._positionOptions(aRect));
    84     // Setup pre-selected items. Note, this has to happen after show.
    85     this._listbox.clearSelection();
    86     for (let item of selectedItems) {
    87       this._listbox.addItemToSelection(item);
    88       item.setAttribute("oldstate", "true");
    89     }
    90     this._listbox.ensureElementIsVisible(firstSelected);
    91   },
    93   reset: function selectHelperReset() {
    94     this._updateControl();
    95     while (this._listbox.hasChildNodes())
    96       this._listbox.removeChild(this._listbox.lastChild);
    97     this._list = null;
    98   },
   100   hide: function selectHelperHide() {
   101     if (!this._list)
   102       return;
   104     this._container.removeEventListener("click", this, false);
   105     window.removeEventListener("MozPrecisePointer", this, false);
   106     this._menuPopup.hide();
   107     this.reset();
   108   },
   110   _positionOptions: function _positionOptions(aRect) {
   111     let browser = Browser.selectedBrowser;
   112     let p0 = browser.ptBrowserToClient(aRect.left, aRect.top);
   113     let p1 = browser.ptBrowserToClient(aRect.right, aRect.bottom);
   115     return {
   116       xPos: p0.x,
   117       yPos: p1.y,
   118       bottomAligned: false,
   119       leftAligned: true
   120     };
   121   },
   123   _updateControl: function _selectHelperUpdateControl() {
   124     Browser.selectedBrowser.messageManager.sendAsyncMessage("FormAssist:ChoiceChange", { });
   125   },
   127   handleEvent: function selectHelperHandleEvent(aEvent) {
   128     switch (aEvent.type) {
   129       case "MozPrecisePointer":
   130         this.hide();
   131       break;
   132       case "click":
   133         let item = aEvent.target;
   134         if (item && item.hasOwnProperty("optionIndex")) {
   135           if (this._list.multiple) {
   136             // item.selected is always true here since that's how richlistbox handles
   137             // mouse click events. We track our own state so that we can toggle here
   138             // on click events. Iniial 'oldstate' values are setup in show above.
   139             if (item.getAttribute("oldstate") == "true") {
   140               item.setAttribute("oldstate", "false");
   141             } else {
   142               item.setAttribute("oldstate", "true");
   143             }
   144             // Fix up selected items - richlistbox will clear selection on click events
   145             // so we need to set selection on the items the user has previously chosen.
   146             this._listbox.clearSelection();
   147             for (let node of this._listbox.childNodes) {
   148               if (node.getAttribute("oldstate") == "true") {
   149                 this._listbox.addItemToSelection(node);
   150               }
   151             }
   152           }
   153           // Let the form element know we've added or removed a selected item.
   154           this.onSelect(item.optionIndex, item.selected);
   155         }
   156         break;
   157     }
   158   },
   160   onSelect: function selectHelperOnSelect(aIndex, aSelected) {
   161     Browser.selectedBrowser.messageManager.sendAsyncMessage("FormAssist:ChoiceSelect", {
   162       index: aIndex,
   163       selected: aSelected
   164     });
   165     if (!this._list.multiple) {
   166       this.hide();
   167     }
   168   }
   169 };

mercurial