is(await getInputEvents(), 0, "Before closed - number of input events");
is(await getChangeEvents(), 0, "Before closed - number of change events");
is(await getClickEvents(), 0, "Before closed - number of click events");
EventUtils.synthesizeKey("a", { accelKey: true });
await SpecialPowers.spawn(
gBrowser.selectedBrowser,
[{ isWindows }], function (args) { Assert.equal(
String(content.getSelection()),
args.isWindows ? "Text" : "", "Select all while popup is open"
);
}
);
// Backspace should not go back
let handleKeyPress = function () {
ok(false, "Should not get keypress event");
};
window.addEventListener("keypress", handleKeyPress);
EventUtils.synthesizeKey("KEY_Backspace");
window.removeEventListener("keypress", handleKeyPress);
await hideSelectPopup();
is(menulist.selectedIndex, 3, "Item 3 still selected");
is(await getInputEvents(), 1, "After closed - number of input events");
is(await getChangeEvents(), 1, "After closed - number of change events");
is(await getClickEvents(), 0, "After closed - number of click events");
// Opening and closing the popup without changing the value should not fire a change event.
await openSelectPopup("click");
await hideSelectPopup("escape");
is(
await getInputEvents(),
1, "Open and close with no change - number of input events"
);
is(
await getChangeEvents(),
1, "Open and close with no change - number of change events"
);
is(
await getClickEvents(),
1, "Open and close with no change - number of click events"
);
EventUtils.synthesizeKey("KEY_Tab");
EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
is(
await getInputEvents(),
1, "Tab away from select with no change - number of input events"
);
is(
await getChangeEvents(),
1, "Tab away from select with no change - number of change events"
);
is(
await getClickEvents(),
1, "Tab away from select with no change - number of click events"
);
await openSelectPopup("click");
EventUtils.synthesizeKey("KEY_ArrowDown");
await hideSelectPopup("escape");
is(
await getInputEvents(),
isWindows ? 2 : 1, "Open and close with change - number of input events"
);
is(
await getChangeEvents(),
isWindows ? 2 : 1, "Open and close with change - number of change events"
);
is(
await getClickEvents(),
2, "Open and close with change - number of click events"
);
EventUtils.synthesizeKey("KEY_Tab");
EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
is(
await getInputEvents(),
isWindows ? 2 : 1, "Tab away from select with change - number of input events"
);
is(
await getChangeEvents(),
isWindows ? 2 : 1, "Tab away from select with change - number of change events"
);
is(
await getClickEvents(),
2, "Tab away from select with change - number of click events"
);
// This test opens a select popup and removes the content node of a popup while // The popup should close if its node is removed.
add_task(async function () { const pageUrl = "data:text/html," + escape(PAGECONTENT_SMALL);
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
// First, try it when a different <select> element than the one that is open is removed const selectPopup = await openSelectPopup("click", "#one");
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () {
content.document.body.removeChild(content.document.getElementById("two"));
});
// Wait a bit just to make sure the popup won't close.
await new Promise(resolve => setTimeout(resolve, 1000));
is(selectPopup.state, "open", "Different popup did not affect open popup");
await hideSelectPopup();
// Next, try it when the same <select> element than the one that is open is removed
await openSelectPopup("click", "#three");
let popupHiddenPromise = BrowserTestUtils.waitForEvent(
selectPopup, "popuphidden"
);
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () {
content.document.body.removeChild(content.document.getElementById("three"));
});
await popupHiddenPromise;
ok(true, "Popup hidden when select is removed");
// Finally, try it when the tab is closed while the select popup is open.
await openSelectPopup("click", "#one");
// This test opens a select popup that is isn't a frame and has some translations applied.
add_task(async function () { const pageUrl = "data:text/html," + escape(PAGECONTENT_TRANSLATED);
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
// We need to explicitly call Element.focus() since dataURL is treated as // cross-origin, thus autofocus doesn't work there. const iframe = await SpecialPowers.spawn(tab.linkedBrowser, [], () => { return content.document.querySelector("iframe").browsingContext;
});
await SpecialPowers.spawn(iframe, [], async () => { const input = content.document.getElementById("select"); const focusPromise = new Promise(resolve => {
input.addEventListener("focus", resolve, { once: true });
});
input.focus();
await focusPromise;
});
// First, get the position of the select popup when no translations have been applied. const selectPopup = await openSelectPopup();
let rect = selectPopup.getBoundingClientRect();
let expectedX = rect.left;
let expectedY = rect.top;
await hideSelectPopup();
// Iterate through a set of steps which each add more translation to the select's expected position.
let steps = [
["div", "transform: translateX(7px) translateY(13px);", 7, 13],
[ "frame", "border-top: 5px solid green; border-left: 10px solid red; border-right: 35px solid blue;",
10,
5,
],
[ "frame", "border: none; padding-left: 6px; padding-right: 12px; padding-top: 2px;",
-4,
-3,
],
["select", "margin: 9px; transform: translateY(-3px);", 9, 6],
];
for (let stepIndex = 0; stepIndex < steps.length; stepIndex++) {
let step = steps[stepIndex];
await SpecialPowers.spawn(
gBrowser.selectedBrowser,
[step],
async function (contentStep) { returnnew Promise(resolve => {
let changedWin = content;
let elem; if (contentStep[0] == "select") {
changedWin = content.document.getElementById("frame").contentWindow;
elem = changedWin.document.getElementById("select");
} else {
elem = content.document.getElementById(contentStep[0]);
}
// Test that we get the right events when a select popup is changed.
add_task(async function test_event_order() { const URL = "data:text/html," + escape(PAGECONTENT_SMALL);
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: URL,
},
async function (browser) { // According to https://html.spec.whatwg.org/#the-select-element, // we want to fire input, change, and then click events on the // <select> (in that order) when it has changed.
let expectedEnter = [
{
type: "input",
cancelable: false,
targetIsOption: false,
composed: true,
},
{
type: "change",
cancelable: false,
targetIsOption: false,
composed: false,
},
];
async function performSelectSearchTests(win) {
let browser = win.gBrowser.selectedBrowser;
await SpecialPowers.spawn(browser, [], async function () {
let doc = content.document;
let select = doc.getElementById("one");
for (var i = 0; i < 40; i++) {
select.add(new content.Option("Test" + i));
}
let selectPopup = await openSelectPopup(false, "select", win);
let searchElement = selectPopup.querySelector( ".contentSelectDropdown-searchbox"
);
searchElement.focus();
EventUtils.synthesizeKey("O", {}, win);
is(selectPopup.children[2].hidden, false, "First option should be visible");
is(selectPopup.children[3].hidden, false, "Second option should be visible");
EventUtils.synthesizeKey("3", {}, win);
is(selectPopup.children[2].hidden, true, "First option should be hidden");
is(selectPopup.children[3].hidden, true, "Second option should be hidden");
is(selectPopup.children[4].hidden, false, "Third option should be visible");
EventUtils.synthesizeKey("Z", {}, win);
is(selectPopup.children[4].hidden, true, "Third option should be hidden");
is(
selectPopup.children[1].hidden, true, "First group header should be hidden"
);
EventUtils.synthesizeKey("KEY_Backspace", {}, win);
is(selectPopup.children[4].hidden, false, "Third option should be visible");
EventUtils.synthesizeKey("KEY_Backspace", {}, win);
is(
selectPopup.children[5].hidden, false, "Second group header should be visible"
);
EventUtils.synthesizeKey("KEY_Backspace", {}, win);
EventUtils.synthesizeKey("O", {}, win);
EventUtils.synthesizeKey("5", {}, win);
is(
selectPopup.children[5].hidden, false, "Second group header should be visible"
);
is(
selectPopup.children[1].hidden, true, "First group header should be hidden"
);
EventUtils.synthesizeKey("KEY_Backspace", {}, win);
is(
selectPopup.children[1].hidden, false, "First group header should be shown"
);
EventUtils.synthesizeKey("KEY_Backspace", {}, win);
is(
selectPopup.children[8].hidden, true, "Option hidden by content should remain hidden"
);
await hideSelectPopup("escape", win);
}
// This test checks the functionality of search in select elements with groups // and a large number of options.
add_task(async function test_select_search() {
await SpecialPowers.pushPrefEnv({
set: [["dom.forms.selectSearch", true]],
}); const pageUrl = "data:text/html," + escape(PAGECONTENT_GROUPS);
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
await performSelectSearchTests(window);
BrowserTestUtils.removeTab(tab);
await SpecialPowers.popPrefEnv();
});
// This test checks that a mousemove event is fired correctly at the menu and // not at the browser, ensuring that any mouse capture has been cleared.
add_task(async function test_mousemove_correcttarget() { const pageUrl = "data:text/html," + escape(PAGECONTENT_SMALL);
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
// The popup should be closed when fullscreen mode is entered or exited. for (let steps = 0; steps < 2; steps++) {
await openSelectPopup("click");
let popupHiddenPromise = BrowserTestUtils.waitForEvent(
selectPopup, "popuphidden"
);
let sizeModeChanged = BrowserTestUtils.waitForEvent(
window, "sizemodechange"
);
BrowserCommands.fullScreen();
await sizeModeChanged;
await popupHiddenPromise;
}
BrowserTestUtils.removeTab(tab);
});
// This test checks when a <select> element has some options with altered display values.
add_task(async function test_somehidden() { const pageUrl = "data:text/html," + escape(PAGECONTENT_SOMEHIDDEN);
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
let selectPopup = await openSelectPopup("click");
// The exact number is not needed; just ensure the height is larger than 4 items to accommodate any popup borders. Assert.greaterOrEqual(
selectPopup.getBoundingClientRect().height,
selectPopup.lastElementChild.getBoundingClientRect().height * 4, "Height contains at least 4 items"
); Assert.less(
selectPopup.getBoundingClientRect().height,
selectPopup.lastElementChild.getBoundingClientRect().height * 5, "Height doesn't contain 5 items"
);
// The label contains the substring 'Visible' for items that are visible. // Otherwise, it is expected to be display: none.
is(selectPopup.parentNode.itemCount, 9, "Correct number of items");
let child = selectPopup.firstElementChild;
let idx = 1; while (child) {
is(
getComputedStyle(child).display,
child.label.indexOf("Visible") > 0 ? "flex" : "none", "Item " + idx++ + " is visible"
);
child = child.nextElementSibling;
}
// This test checks that the popup is closed when the select element is blurred.
add_task(async function test_blur_hides_popup() { const pageUrl = "data:text/html," + escape(PAGECONTENT_SMALL);
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
content.addEventListener( "blur", function (event) {
event.preventDefault();
event.stopPropagation();
}, true
);
let popupHiddenPromise = BrowserTestUtils.waitForEvent(
selectPopup, "popuphidden"
);
await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
content.document.getElementById("one").blur();
});
await popupHiddenPromise;
ok(true, "Blur closed popup");
BrowserTestUtils.removeTab(tab);
});
// Test zoom handling.
add_task(async function test_zoom() { const pageUrl = "data:text/html," + escape(PAGECONTENT_SMALL);
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
info("Opening the popup"); const selectPopup = await openSelectPopup("click");
info("Opened the popup");
let nonZoomedFontSize = parseFloat(
getComputedStyle(selectPopup.querySelector("menuitem")).fontSize,
10
);
info("font-size is " + nonZoomedFontSize);
await hideSelectPopup();
info("Hide the popup");
for (let i = 0; i < 2; ++i) {
info("Testing with full zoom: " + ZoomManager.useFullZoom);
// This is confusing, but does the right thing.
FullZoom.setZoom(2.0, tab.linkedBrowser);
// Test change and input events get handled consistently
await openSelectPopup("click");
EventUtils.synthesizeKey("KEY_ArrowDown");
await hideSelectPopup();
is(
await getChangeEvents(),
1, "Should get change and input events consistently"
);
is(
await getInputEvents(),
1, "Should get change and input events consistently (input)"
);
BrowserTestUtils.removeTab(tab);
});
add_task(async function test_label_not_text() { const PAGE_CONTENT = `
<!doctype html>
<select>
<option label="Some nifty Label">Some Element Text Instead</option>
<option label="">Element Text</option>
</select>
`;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.