зеркало из https://github.com/mozilla/gecko-dev.git
Bug 732063 - Move the SelectHelper code into a separate file [r=margaret]
This commit is contained in:
Родитель
c559960e11
Коммит
cb69901ad6
|
@ -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);
|
||||
}
|
||||
};
|
|
@ -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,123 +2892,8 @@ 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() {
|
||||
|
@ -3782,7 +3678,7 @@ var ClipboardHelper = {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var PluginHelper = {
|
||||
showDoorHanger: function(aTab) {
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче