mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-08-18 07:29:28 +00:00
150 lines
4.2 KiB
JavaScript
150 lines
4.2 KiB
JavaScript
/* 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/. */
|
|
"use strict";
|
|
|
|
var SelectHelper = {
|
|
_uiBusy: false,
|
|
|
|
handleEvent: function(aEvent) {
|
|
this.handleClick(aEvent.target);
|
|
},
|
|
|
|
handleClick: function(aTarget) {
|
|
// if we're busy looking at a select we want to eat any clicks that
|
|
// come to us, but not to process them
|
|
if (this._uiBusy || !this._isMenu(aTarget) || this._isDisabledElement(aTarget))
|
|
return;
|
|
|
|
this._uiBusy = true;
|
|
this.show(aTarget);
|
|
this._uiBusy = false;
|
|
},
|
|
|
|
show: function(aElement) {
|
|
let list = this.getListForElement(aElement);
|
|
|
|
let p = new Prompt({
|
|
window: aElement.contentDocument
|
|
});
|
|
|
|
if (aElement.multiple) {
|
|
p.addButton({
|
|
label: Strings.browser.GetStringFromName("selectHelper.closeMultipleSelectDialog")
|
|
}).setMultiChoiceItems(list);
|
|
} else {
|
|
p.setSingleChoiceItems(list);
|
|
}
|
|
|
|
p.show((function(data) {
|
|
let selected = data.list;
|
|
|
|
if (aElement instanceof Ci.nsIDOMXULMenuListElement) {
|
|
if (aElement.selectedIndex != selected[0]) {
|
|
aElement.selectedIndex = selected[0];
|
|
this.fireOnCommand(aElement);
|
|
}
|
|
} else if (aElement instanceof HTMLSelectElement) {
|
|
let changed = false;
|
|
let i = 0;
|
|
this.forOptions(aElement, function(aNode) {
|
|
if (aNode.selected && selected.indexOf(i) == -1) {
|
|
changed = true;
|
|
aNode.selected = false;
|
|
} else if (!aNode.selected && selected.indexOf(i) != -1) {
|
|
changed = true;
|
|
aNode.selected = true;
|
|
}
|
|
i++;
|
|
});
|
|
|
|
if (changed)
|
|
this.fireOnChange(aElement);
|
|
}
|
|
}).bind(this));
|
|
},
|
|
|
|
_isMenu: function(aElement) {
|
|
return (aElement instanceof HTMLSelectElement ||
|
|
aElement instanceof Ci.nsIDOMXULMenuListElement);
|
|
},
|
|
|
|
getListForElement: function(aElement) {
|
|
let index = 0;
|
|
let items = [];
|
|
this.forOptions(aElement, function(aNode, aOptions, aParent) {
|
|
let item = {
|
|
label: aNode.text || aNode.label,
|
|
header: aOptions.isGroup,
|
|
disabled: aNode.disabled,
|
|
id: index,
|
|
selected: aNode.selected
|
|
}
|
|
|
|
if (aParent) {
|
|
item.child = true;
|
|
item.disabled = item.disabled || aParent.disabled;
|
|
}
|
|
items.push(item);
|
|
|
|
index++;
|
|
});
|
|
return items;
|
|
},
|
|
|
|
forOptions: function(aElement, aFunction, aParent = null) {
|
|
let element = aElement;
|
|
if (aElement instanceof Ci.nsIDOMXULMenuListElement)
|
|
element = aElement.menupopup;
|
|
let children = element.children;
|
|
let numChildren = children.length;
|
|
|
|
// if there are no children in this select, we add a dummy row so that at least something appears
|
|
if (numChildren == 0)
|
|
aFunction.call(this, { label: "" }, { isGroup: false }, aParent);
|
|
|
|
for (let i = 0; i < numChildren; i++) {
|
|
let child = children[i];
|
|
if (child instanceof HTMLOptionElement ||
|
|
child instanceof Ci.nsIDOMXULSelectControlItemElement) {
|
|
aFunction.call(this, child, { isGroup: false }, aParent);
|
|
} else if (child instanceof HTMLOptGroupElement) {
|
|
aFunction.call(this, child, { isGroup: true });
|
|
this.forOptions(child, aFunction, child);
|
|
|
|
}
|
|
}
|
|
},
|
|
|
|
fireOnChange: function(aElement) {
|
|
let evt = aElement.ownerDocument.createEvent("Events");
|
|
evt.initEvent("change", true, true, aElement.defaultView, 0,
|
|
false, false,
|
|
false, false, null);
|
|
setTimeout(function() {
|
|
aElement.dispatchEvent(evt);
|
|
}, 0);
|
|
},
|
|
|
|
fireOnCommand: function(aElement) {
|
|
let evt = aElement.ownerDocument.createEvent("XULCommandEvent");
|
|
evt.initCommandEvent("command", true, true, aElement.defaultView, 0,
|
|
false, false,
|
|
false, false, null);
|
|
setTimeout(function() {
|
|
aElement.dispatchEvent(evt);
|
|
}, 0);
|
|
},
|
|
|
|
_isDisabledElement : function(aElement) {
|
|
let currentElement = aElement;
|
|
while (currentElement) {
|
|
if (currentElement.disabled)
|
|
return true;
|
|
|
|
currentElement = currentElement.parentElement;
|
|
}
|
|
return false;
|
|
}
|
|
};
|