mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 960354 - Various fixes for multi-select dropdowns plus tests. r=mbrubeck
This commit is contained in:
parent
08cbae02b2
commit
220404e591
@ -28,19 +28,20 @@ var SelectHelperUI = {
|
||||
},
|
||||
|
||||
show: function selectHelperShow(aList, aTitle, aRect) {
|
||||
if (this._list)
|
||||
if (this._list) {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
this._list = aList;
|
||||
|
||||
// The element label is used as a title to give more context
|
||||
this._container.setAttribute("multiple", aList.multiple ? "true" : "false");
|
||||
this._listbox.setAttribute("seltype", aList.multiple ? "multiple" : "single");
|
||||
|
||||
let firstSelected = null;
|
||||
|
||||
// Using a fragment prevent us to hang on huge list
|
||||
let fragment = document.createDocumentFragment();
|
||||
let choices = aList.choices;
|
||||
let selectedItems = [];
|
||||
for (let i = 0; i < choices.length; i++) {
|
||||
let choice = choices[i];
|
||||
let item = document.createElement("richlistitem");
|
||||
@ -51,12 +52,10 @@ var SelectHelperUI = {
|
||||
item.setAttribute("crop", "center");
|
||||
label.setAttribute("value", choice.text);
|
||||
item.appendChild(label);
|
||||
|
||||
choice.selected ? item.setAttribute("selected", "true")
|
||||
: item.removeAttribute("selected");
|
||||
|
||||
item.setAttribute("oldstate", "false");
|
||||
choice.disabled ? item.setAttribute("disabled", "true")
|
||||
: item.removeAttribute("disabled");
|
||||
|
||||
fragment.appendChild(item);
|
||||
|
||||
if (choice.group) {
|
||||
@ -67,18 +66,27 @@ var SelectHelperUI = {
|
||||
item.optionIndex = choice.optionIndex;
|
||||
item.choiceIndex = i;
|
||||
|
||||
if (choice.inGroup)
|
||||
if (choice.inGroup) {
|
||||
item.classList.add("in-optgroup");
|
||||
}
|
||||
|
||||
if (choice.selected) {
|
||||
item.classList.add("selected");
|
||||
firstSelected = firstSelected || item;
|
||||
selectedItems.push(item);
|
||||
}
|
||||
}
|
||||
this._listbox.appendChild(fragment);
|
||||
|
||||
this._container.addEventListener("click", this, false);
|
||||
window.addEventListener("MozPrecisePointer", this, false);
|
||||
this._menuPopup.show(this._positionOptions(aRect));
|
||||
|
||||
// Setup pre-selected items. Note, this has to happen after show.
|
||||
this._listbox.clearSelection();
|
||||
for (let item of selectedItems) {
|
||||
this._listbox.addItemToSelection(item);
|
||||
item.setAttribute("oldstate", "true");
|
||||
}
|
||||
this._listbox.ensureElementIsVisible(firstSelected);
|
||||
},
|
||||
|
||||
@ -94,6 +102,7 @@ var SelectHelperUI = {
|
||||
return;
|
||||
|
||||
this._container.removeEventListener("click", this, false);
|
||||
window.removeEventListener("MozPrecisePointer", this, false);
|
||||
this._menuPopup.hide();
|
||||
this.reset();
|
||||
},
|
||||
@ -111,31 +120,38 @@ var SelectHelperUI = {
|
||||
};
|
||||
},
|
||||
|
||||
_forEachOption: function _selectHelperForEachOption(aCallback) {
|
||||
let children = this._listbox.childNodes;
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
let item = children[i];
|
||||
if (!item.hasOwnProperty("optionIndex"))
|
||||
continue;
|
||||
aCallback(item, i);
|
||||
}
|
||||
},
|
||||
|
||||
_updateControl: function _selectHelperUpdateControl() {
|
||||
Browser.selectedBrowser.messageManager.sendAsyncMessage("FormAssist:ChoiceChange", { });
|
||||
},
|
||||
|
||||
handleEvent: function selectHelperHandleEvent(aEvent) {
|
||||
switch (aEvent.type) {
|
||||
case "MozPrecisePointer":
|
||||
this.hide();
|
||||
break;
|
||||
case "click":
|
||||
let item = aEvent.target;
|
||||
if (item && item.hasOwnProperty("optionIndex")) {
|
||||
if (this._list.multiple) {
|
||||
item.classList.toggle("selected");
|
||||
} else {
|
||||
item.classList.add("selected");
|
||||
// item.selected is always true here since that's how richlistbox handles
|
||||
// mouse click events. We track our own state so that we can toggle here
|
||||
// on click events. Iniial 'oldstate' values are setup in show above.
|
||||
if (item.getAttribute("oldstate") == "true") {
|
||||
item.setAttribute("oldstate", "false");
|
||||
} else {
|
||||
item.setAttribute("oldstate", "true");
|
||||
}
|
||||
// Fix up selected items - richlistbox will clear selection on click events
|
||||
// so we need to set selection on the items the user has previously chosen.
|
||||
this._listbox.clearSelection();
|
||||
for (let node of this._listbox.childNodes) {
|
||||
if (node.getAttribute("oldstate") == "true") {
|
||||
this._listbox.addItemToSelection(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.onSelect(item.optionIndex, item.classList.contains("selected"));
|
||||
// Let the form element know we've added or removed a selected item.
|
||||
this.onSelect(item.optionIndex, item.selected);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
21
browser/metro/base/tests/mochitest/browser_form_selects.html
Normal file
21
browser/metro/base/tests/mochitest/browser_form_selects.html
Normal file
@ -0,0 +1,21 @@
|
||||
<html>
|
||||
<body bgcolor=white>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<center>
|
||||
<select id="selectelement" style="height:200px; width:150px;" multiple>
|
||||
<option id="opt1">option 1</option>
|
||||
<option id="opt2">option 2</option>
|
||||
<option id="opt3">option 3</option>
|
||||
<option id="opt4">option 4</option>
|
||||
<option id="opt5">option 5</option>
|
||||
<option id="opt6">option 6</option>
|
||||
<option id="opt7">option 7</option>
|
||||
<option id="opt8">option 8</option>
|
||||
<option id="opt9">option 9</option>
|
||||
</select>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
71
browser/metro/base/tests/mochitest/browser_form_selects.js
Normal file
71
browser/metro/base/tests/mochitest/browser_form_selects.js
Normal file
@ -0,0 +1,71 @@
|
||||
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
|
||||
/* 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";
|
||||
|
||||
function test() {
|
||||
runTests();
|
||||
}
|
||||
|
||||
gTests.push({
|
||||
desc: "form multi-select test 1",
|
||||
setUp: function () {
|
||||
},
|
||||
tearDown: function () {
|
||||
},
|
||||
run: function () {
|
||||
yield addTab(chromeRoot + "browser_form_selects.html");
|
||||
yield waitForCondition(function () {
|
||||
return !Browser.selectedTab.isLoading();
|
||||
});
|
||||
|
||||
let win = Browser.selectedTab.browser.contentWindow;
|
||||
let tabdoc = Browser.selectedTab.browser.contentWindow.document;
|
||||
let select = tabdoc.getElementById("selectelement");
|
||||
|
||||
// display the touch menu
|
||||
let promise = waitForEvent(tabdoc, "popupshown");
|
||||
sendNativeTap(select);
|
||||
yield promise;
|
||||
|
||||
// tap every option
|
||||
for (let node of SelectHelperUI._listbox.childNodes) {
|
||||
sendNativeTap(node);
|
||||
}
|
||||
|
||||
yield waitForMs(100);
|
||||
|
||||
// check the menu state
|
||||
for (let node of SelectHelperUI._listbox.childNodes) {
|
||||
ok(node.selected, "option is selected");
|
||||
}
|
||||
|
||||
// check the underlying form state
|
||||
for (let index = 1; index < 10; index++) {
|
||||
let option = tabdoc.getElementById("opt" + index);
|
||||
ok(option.selected, "opt" + index + " form option selected");
|
||||
}
|
||||
|
||||
// tap every option again
|
||||
for (let node of SelectHelperUI._listbox.childNodes) {
|
||||
sendNativeTap(node);
|
||||
}
|
||||
|
||||
yield waitForMs(100);
|
||||
|
||||
// check the menu state
|
||||
for (let node of SelectHelperUI._listbox.childNodes) {
|
||||
ok(!node.selected, "option is not selected");
|
||||
}
|
||||
|
||||
// check the underlying form state
|
||||
for (let index = 1; index < 10; index++) {
|
||||
let option = tabdoc.getElementById("opt" + index);
|
||||
ok(!option.selected, "opt" + index + " form option not selected");
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
@ -6,6 +6,7 @@ support-files =
|
||||
browser_context_menu_tests_04.html
|
||||
browser_findbar.html
|
||||
browser_form_auto_complete.html
|
||||
browser_form_selects.html
|
||||
browser_link_click.html
|
||||
browser_onscreen_keyboard.html
|
||||
browser_progress_indicator.xul
|
||||
@ -43,6 +44,7 @@ support-files =
|
||||
[browser_downloads.js]
|
||||
[browser_findbar.js]
|
||||
[browser_form_auto_complete.js]
|
||||
[browser_form_selects.js]
|
||||
[browser_history.js]
|
||||
[browser_inputsource.js]
|
||||
[browser_link_click.js]
|
||||
|
@ -240,11 +240,6 @@ menulist {
|
||||
border: 0 none;
|
||||
}
|
||||
|
||||
.option-command.selected {
|
||||
background-color: #ff8000;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.option-command.optgroup {
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
|
Loading…
Reference in New Issue
Block a user