1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/chrome/content/SelectHelper.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,138 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +"use strict"; 1.8 + 1.9 +var SelectHelper = { 1.10 + _uiBusy: false, 1.11 + 1.12 + handleEvent: function(aEvent) { 1.13 + this.handleClick(aEvent.target); 1.14 + }, 1.15 + 1.16 + handleClick: function(aTarget) { 1.17 + // if we're busy looking at a select we want to eat any clicks that 1.18 + // come to us, but not to process them 1.19 + if (this._uiBusy || !this._isMenu(aTarget) || aTarget.disabled) 1.20 + return; 1.21 + 1.22 + this._uiBusy = true; 1.23 + this.show(aTarget); 1.24 + this._uiBusy = false; 1.25 + }, 1.26 + 1.27 + show: function(aElement) { 1.28 + let list = this.getListForElement(aElement); 1.29 + 1.30 + let p = new Prompt({ 1.31 + window: aElement.contentDocument 1.32 + }); 1.33 + 1.34 + if (aElement.multiple) { 1.35 + p.addButton({ 1.36 + label: Strings.browser.GetStringFromName("selectHelper.closeMultipleSelectDialog") 1.37 + }).setMultiChoiceItems(list); 1.38 + } else { 1.39 + p.setSingleChoiceItems(list); 1.40 + } 1.41 + 1.42 + p.show((function(data) { 1.43 + let selected = data.list; 1.44 + 1.45 + if (aElement instanceof Ci.nsIDOMXULMenuListElement) { 1.46 + if (aElement.selectedIndex != selected[0]) { 1.47 + aElement.selectedIndex = selected[0]; 1.48 + this.fireOnCommand(aElement); 1.49 + } 1.50 + } else if (aElement instanceof HTMLSelectElement) { 1.51 + let changed = false; 1.52 + let i = 0; 1.53 + this.forOptions(aElement, function(aNode) { 1.54 + if (aNode.selected && selected.indexOf(i) == -1) { 1.55 + changed = true; 1.56 + aNode.selected = false; 1.57 + } else if (!aNode.selected && selected.indexOf(i) != -1) { 1.58 + changed = true; 1.59 + aNode.selected = true; 1.60 + } 1.61 + i++; 1.62 + }); 1.63 + 1.64 + if (changed) 1.65 + this.fireOnChange(aElement); 1.66 + } 1.67 + }).bind(this)); 1.68 + }, 1.69 + 1.70 + _isMenu: function(aElement) { 1.71 + return (aElement instanceof HTMLSelectElement || 1.72 + aElement instanceof Ci.nsIDOMXULMenuListElement); 1.73 + }, 1.74 + 1.75 + getListForElement: function(aElement) { 1.76 + let index = 0; 1.77 + let items = []; 1.78 + this.forOptions(aElement, function(aNode, aOptions, aParent) { 1.79 + let item = { 1.80 + label: aNode.text || aNode.label, 1.81 + header: aOptions.isGroup, 1.82 + disabled: aNode.disabled, 1.83 + id: index, 1.84 + selected: aNode.selected 1.85 + } 1.86 + 1.87 + if (aParent) { 1.88 + item.child = true; 1.89 + item.disabled = item.disabled || aParent.disabled; 1.90 + } 1.91 + items.push(item); 1.92 + 1.93 + index++; 1.94 + }); 1.95 + return items; 1.96 + }, 1.97 + 1.98 + forOptions: function(aElement, aFunction, aParent = null) { 1.99 + let element = aElement; 1.100 + if (aElement instanceof Ci.nsIDOMXULMenuListElement) 1.101 + element = aElement.menupopup; 1.102 + let children = element.children; 1.103 + let numChildren = children.length; 1.104 + 1.105 + // if there are no children in this select, we add a dummy row so that at least something appears 1.106 + if (numChildren == 0) 1.107 + aFunction.call(this, { label: "" }, { isGroup: false }, aParent); 1.108 + 1.109 + for (let i = 0; i < numChildren; i++) { 1.110 + let child = children[i]; 1.111 + if (child instanceof HTMLOptionElement || 1.112 + child instanceof Ci.nsIDOMXULSelectControlItemElement) { 1.113 + aFunction.call(this, child, { isGroup: false }, aParent); 1.114 + } else if (child instanceof HTMLOptGroupElement) { 1.115 + aFunction.call(this, child, { isGroup: true }); 1.116 + this.forOptions(child, aFunction, child); 1.117 + 1.118 + } 1.119 + } 1.120 + }, 1.121 + 1.122 + fireOnChange: function(aElement) { 1.123 + let evt = aElement.ownerDocument.createEvent("Events"); 1.124 + evt.initEvent("change", true, true, aElement.defaultView, 0, 1.125 + false, false, 1.126 + false, false, null); 1.127 + setTimeout(function() { 1.128 + aElement.dispatchEvent(evt); 1.129 + }, 0); 1.130 + }, 1.131 + 1.132 + fireOnCommand: function(aElement) { 1.133 + let evt = aElement.ownerDocument.createEvent("XULCommandEvent"); 1.134 + evt.initCommandEvent("command", true, true, aElement.defaultView, 0, 1.135 + false, false, 1.136 + false, false, null); 1.137 + setTimeout(function() { 1.138 + aElement.dispatchEvent(evt); 1.139 + }, 0); 1.140 + } 1.141 +};