Bug 732063 - Move the SelectHelper code into a separate file [r=margaret]

This commit is contained in:
Matt Brubeck 2012-03-01 10:58:19 -08:00
parent bd2fa87f12
commit c71e9867af
3 changed files with 139 additions and 119 deletions

View File

@ -0,0 +1,123 @@
/* 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,
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)
return true;
let target = aTarget;
while (target) {
if (this._isSelectElement(target) && !target.disabled) {
this._uiBusy = true;
target.focus();
let list = this.getListForElement(target);
this.show(list, target);
target = null;
this._uiBusy = false;
return true;
}
if (target)
target = target.parentNode;
}
return false;
},
show: function(aList, aElement) {
let data = JSON.parse(sendMessageToJava({ gecko: aList }));
let selected = data.button;
if (selected == -1)
return;
if (!(selected instanceof Array)) {
let temp = [];
for (let i = 0; i < aList.listitems.length; i++) {
temp[i] = (i == selected);
}
selected = temp;
}
this.forOptions(aElement, function(aNode, aIndex) {
aNode.selected = selected[aIndex];
});
this.fireOnChange(aElement);
},
_isSelectElement: function(aElement) {
return (aElement instanceof HTMLSelectElement);
},
getListForElement: function(aElement) {
let result = {
type: "Prompt:Show",
multiple: aElement.multiple,
selected: [],
listitems: []
};
if (aElement.multiple) {
result.buttons = [
{ label: Strings.browser.GetStringFromName("selectHelper.closeMultipleSelectDialog") },
];
}
this.forOptions(aElement, function(aNode, aIndex, aIsGroup, aInGroup) {
let item = {
label: aNode.text || aNode.label,
isGroup: aIsGroup,
inGroup: aInGroup,
disabled: aNode.disabled,
id: aIndex
}
if (aInGroup)
item.disabled = item.disabled || aNode.parentNode.disabled;
result.listitems[aIndex] = item;
result.selected[aIndex] = aNode.selected;
});
return result;
},
forOptions: function(aElement, aFunction) {
let optionIndex = 0;
let children = aElement.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:""}, optionIndex);
for (let i = 0; i < numChildren; i++) {
let child = children[i];
if (child instanceof HTMLOptionElement) {
// This is a regular choice under no group.
aFunction.call(this, child, optionIndex, false, false);
optionIndex++;
} else if (child instanceof HTMLOptGroupElement) {
aFunction.call(this, child, optionIndex, true, false);
optionIndex++;
let subchildren = child.children;
let numSubchildren = subchildren.length;
for (let j = 0; j < numSubchildren; j++) {
let subchild = subchildren[j];
aFunction.call(this, subchild, optionIndex, false, true);
optionIndex++;
}
}
}
},
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);
}
};

View File

@ -51,6 +51,18 @@ XPCOMUtils.defineLazyGetter(this, "PluralForm", function() {
return PluralForm;
});
// Lazily-loaded browser scripts:
[
["SelectHelper", "chrome://browser/content/SelectHelper.js"],
].forEach(function (aScript) {
let [name, script] = aScript;
XPCOMUtils.defineLazyGetter(window, name, function() {
let sandbox = {};
Services.scriptloader.loadSubScript(script, sandbox);
return sandbox[name];
});
});
XPCOMUtils.defineLazyServiceGetter(this, "Haptic",
"@mozilla.org/widget/hapticfeedback;1", "nsIHapticFeedback");
@ -2266,7 +2278,7 @@ var BrowserEventHandler = {
}
} else if (aTopic == "Gesture:SingleTap") {
let element = this._highlightElement;
if (element && !FormAssistant.handleClick(element)) {
if (element && !SelectHelper.handleClick(element)) {
try {
let data = JSON.parse(aData);
[data.x, data.y] = ElementTouchHelper.toScreenCoords(element.ownerDocument.defaultView, data.x, data.y);
@ -2795,7 +2807,6 @@ var FormAssistant = {
// Used to keep track of the element that corresponds to the current
// autocomplete suggestions
_currentInputElement: null,
_uiBusy: false,
init: function() {
Services.obs.addObserver(this, "FormAssist:AutoComplete", false);
@ -2881,124 +2892,9 @@ var FormAssistant = {
}
return suggestions;
},
show: function(aList, aElement) {
let data = JSON.parse(sendMessageToJava({ gecko: aList }));
let selected = data.button;
if (selected == -1)
return;
if (!(selected instanceof Array)) {
let temp = [];
for (let i = 0; i < aList.listitems.length; i++) {
temp[i] = (i == selected);
}
selected = temp;
}
this.forOptions(aElement, function(aNode, aIndex) {
aNode.selected = selected[aIndex];
});
this.fireOnChange(aElement);
},
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)
return true;
let target = aTarget;
while (target) {
if (this._isSelectElement(target) && !target.disabled) {
this._uiBusy = true;
target.focus();
let list = this.getListForElement(target);
this.show(list, target);
target = null;
this._uiBusy = false;
return true;
}
if (target)
target = target.parentNode;
}
return false;
},
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);
},
_isSelectElement: function(aElement) {
return (aElement instanceof HTMLSelectElement);
},
getListForElement: function(aElement) {
let result = {
type: "Prompt:Show",
multiple: aElement.multiple,
selected: [],
listitems: []
};
if (aElement.multiple) {
result.buttons = [
{ label: Strings.browser.GetStringFromName("selectHelper.closeMultipleSelectDialog") },
];
}
this.forOptions(aElement, function(aNode, aIndex, aIsGroup, aInGroup) {
let item = {
label: aNode.text || aNode.label,
isGroup: aIsGroup,
inGroup: aInGroup,
disabled: aNode.disabled,
id: aIndex
}
if (aInGroup)
item.disabled = item.disabled || aNode.parentNode.disabled;
result.listitems[aIndex] = item;
result.selected[aIndex] = aNode.selected;
});
return result;
},
forOptions: function(aElement, aFunction) {
let optionIndex = 0;
let children = aElement.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:""}, optionIndex);
for (let i = 0; i < numChildren; i++) {
let child = children[i];
if (child instanceof HTMLOptionElement) {
// This is a regular choice under no group.
aFunction.call(this, child, optionIndex, false, false);
optionIndex++;
} else if (child instanceof HTMLOptGroupElement) {
aFunction.call(this, child, optionIndex, true, false);
optionIndex++;
let subchildren = child.children;
let numSubchildren = subchildren.length;
for (let j = 0; j < numSubchildren; j++) {
let subchild = subchildren[j];
aFunction.call(this, subchild, optionIndex, false, true);
optionIndex++;
}
}
}
}
}
var XPInstallObserver = {
init: function xpi_init() {
Services.obs.addObserver(XPInstallObserver, "addon-install-blocked", false);
@ -3782,7 +3678,7 @@ var ClipboardHelper = {
return false;
}
}
}
};
var PluginHelper = {
showDoorHanger: function(aTab) {

View File

@ -24,6 +24,7 @@ chrome.jar:
content/exceptions.js (content/exceptions.js)
* content/downloads.js (content/downloads.js)
content/netError.xhtml (content/netError.xhtml)
content/SelectHelper.js (content/SelectHelper.js)
% override chrome://global/content/config.xul chrome://browser/content/config.xhtml
% override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml