Bug 1253486, [e10s only] hide select popups when the select element is removed, r=mconley
This commit is contained in:
@@ -26,13 +26,26 @@ const PAGECONTENT =
|
||||
" </optgroup></select><input />Text" +
|
||||
"</body></html>";
|
||||
|
||||
function openSelectPopup(selectPopup, withMouse)
|
||||
const PAGECONTENT_SMALL =
|
||||
"<html>" +
|
||||
"<body><select id='one'>" +
|
||||
" <option value='One'>One</option>" +
|
||||
" <option value='Two'>Two</option>" +
|
||||
"</select><select id='two'>" +
|
||||
" <option value='Three'>Three</option>" +
|
||||
" <option value='Four'>Four</option>" +
|
||||
"</select><select id='three'>" +
|
||||
" <option value='Five'>Five</option>" +
|
||||
" <option value='Six'>Six</option>" +
|
||||
"</select></body></html>";
|
||||
|
||||
function openSelectPopup(selectPopup, withMouse, selector = "select")
|
||||
{
|
||||
let popupShownPromise = BrowserTestUtils.waitForEvent(selectPopup, "popupshown");
|
||||
|
||||
if (withMouse) {
|
||||
return Promise.all([popupShownPromise,
|
||||
BrowserTestUtils.synthesizeMouseAtCenter("select", { }, gBrowser.selectedBrowser)]);
|
||||
BrowserTestUtils.synthesizeMouseAtCenter(selector, { }, gBrowser.selectedBrowser)]);
|
||||
}
|
||||
|
||||
setTimeout(() => EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true, code: "ArrowDown" }), 1500);
|
||||
@@ -41,7 +54,7 @@ function openSelectPopup(selectPopup, withMouse)
|
||||
|
||||
function hideSelectPopup(selectPopup, withEscape)
|
||||
{
|
||||
let popupShownPromise = BrowserTestUtils.waitForEvent(selectPopup, "popuphidden");
|
||||
let popupHiddenPromise = BrowserTestUtils.waitForEvent(selectPopup, "popuphidden");
|
||||
|
||||
if (withEscape) {
|
||||
EventUtils.synthesizeKey("KEY_Escape", { code: "Escape" });
|
||||
@@ -50,7 +63,7 @@ function hideSelectPopup(selectPopup, withEscape)
|
||||
EventUtils.synthesizeKey("KEY_Enter", { code: "Enter" });
|
||||
}
|
||||
|
||||
return popupShownPromise;
|
||||
return popupHiddenPromise;
|
||||
}
|
||||
|
||||
function getChangeEvents()
|
||||
@@ -62,11 +75,8 @@ function getChangeEvents()
|
||||
|
||||
function doSelectTests(contentType, dtd)
|
||||
{
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
yield promiseTabLoadEvent(tab, "data:" + contentType + "," + escape(dtd + "\n" + PAGECONTENT));
|
||||
|
||||
yield SimpleTest.promiseFocus(browser.contentWindow);
|
||||
const pageUrl = "data:" + contentType + "," + escape(dtd + "\n" + PAGECONTENT);
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
|
||||
|
||||
let menulist = document.getElementById("ContentSelectDropdown");
|
||||
let selectPopup = menulist.menupopup;
|
||||
@@ -138,7 +148,7 @@ function doSelectTests(contentType, dtd)
|
||||
is(selectPopup.lastChild.previousSibling.label, "Seven", "Spaces collapsed");
|
||||
is(selectPopup.lastChild.label, "\xA0\xA0Eight\xA0\xA0", "Non-breaking spaces not collapsed");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
|
||||
add_task(function*() {
|
||||
@@ -149,3 +159,46 @@ add_task(function*() {
|
||||
yield doSelectTests("application/xhtml+xml", XHTML_DTD);
|
||||
});
|
||||
|
||||
// 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(function*() {
|
||||
const pageUrl = "data:text/html," + escape(PAGECONTENT_SMALL);
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
|
||||
|
||||
let menulist = document.getElementById("ContentSelectDropdown");
|
||||
let selectPopup = menulist.menupopup;
|
||||
|
||||
// First, try it when a different <select> element than the one that is open is removed
|
||||
yield openSelectPopup(selectPopup, true, "#one");
|
||||
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function() {
|
||||
content.document.body.removeChild(content.document.getElementById("two"));
|
||||
});
|
||||
|
||||
// Wait a bit just to make sure the popup won't close.
|
||||
yield new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
is(selectPopup.state, "open", "Different popup did not affect open popup");
|
||||
|
||||
yield hideSelectPopup(selectPopup);
|
||||
|
||||
// Next, try it when the same <select> element than the one that is open is removed
|
||||
yield openSelectPopup(selectPopup, true, "#three");
|
||||
|
||||
let popupHiddenPromise = BrowserTestUtils.waitForEvent(selectPopup, "popuphidden");
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function() {
|
||||
content.document.body.removeChild(content.document.getElementById("three"));
|
||||
});
|
||||
yield popupHiddenPromise;
|
||||
|
||||
ok(true, "Popup hidden when select is removed");
|
||||
|
||||
// Finally, try it when the tab is closed while the select popup is open.
|
||||
yield openSelectPopup(selectPopup, true, "#one");
|
||||
|
||||
popupHiddenPromise = BrowserTestUtils.waitForEvent(selectPopup, "popuphidden");
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
yield popupHiddenPromise;
|
||||
|
||||
ok(true, "Popup hidden when tab is closed");
|
||||
});
|
||||
|
||||
@@ -141,6 +141,14 @@ nsListControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
mContent->RemoveSystemEventListener(NS_LITERAL_STRING("mousemove"),
|
||||
mEventListener, false);
|
||||
|
||||
if (XRE_IsContentProcess() &&
|
||||
Preferences::GetBool("browser.tabs.remote.desktopbehavior", false)) {
|
||||
nsContentUtils::AddScriptRunner(
|
||||
new AsyncEventDispatcher(mContent,
|
||||
NS_LITERAL_STRING("mozhidedropdown"), true,
|
||||
true));
|
||||
}
|
||||
|
||||
nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
|
||||
nsHTMLScrollFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
@@ -401,6 +401,12 @@
|
||||
Note: This overrides the destroy() method from browser.xml. -->
|
||||
<method name="destroy">
|
||||
<body><![CDATA[
|
||||
// Make sure that any open select is closed.
|
||||
if (this._selectParentHelper) {
|
||||
let menulist = document.getElementById(this.getAttribute("selectmenulist"));
|
||||
this._selectParentHelper.hide(menulist, this);
|
||||
}
|
||||
|
||||
if (this.mDestroyed)
|
||||
return;
|
||||
this.mDestroyed = true;
|
||||
@@ -483,7 +489,7 @@
|
||||
case "Forms:HideDropDown": {
|
||||
if (this._selectParentHelper) {
|
||||
let menulist = document.getElementById(this.getAttribute("selectmenulist"));
|
||||
this._selectParentHelper.hide(menulist);
|
||||
this._selectParentHelper.hide(menulist, this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ this.SelectContentHelper.prototype = {
|
||||
this.global.addMessageListener("Forms:MouseOver", this);
|
||||
this.global.addMessageListener("Forms:MouseOut", this);
|
||||
this.global.addEventListener("pagehide", this);
|
||||
this.global.addEventListener("mozhidedropdown", this);
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
@@ -44,6 +45,7 @@ this.SelectContentHelper.prototype = {
|
||||
this.global.removeMessageListener("Forms:MouseOver", this);
|
||||
this.global.removeMessageListener("Forms:MouseOut", this);
|
||||
this.global.removeEventListener("pagehide", this);
|
||||
this.global.removeEventListener("mozhidedropdown", this);
|
||||
this.element = null;
|
||||
this.global = null;
|
||||
},
|
||||
@@ -102,6 +104,12 @@ this.SelectContentHelper.prototype = {
|
||||
this.uninit();
|
||||
}
|
||||
break;
|
||||
case "mozhidedropdown":
|
||||
if (this.element === event.target) {
|
||||
this.global.sendAsyncMessage("Forms:HideDropDown", {});
|
||||
this.uninit();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,10 @@ this.SelectParentHelper = {
|
||||
menulist.selectedItem.scrollIntoView();
|
||||
},
|
||||
|
||||
hide: function(menulist) {
|
||||
menulist.menupopup.hidePopup();
|
||||
hide: function(menulist, browser) {
|
||||
if (currentBrowser == browser) {
|
||||
menulist.menupopup.hidePopup();
|
||||
}
|
||||
},
|
||||
|
||||
handleEvent: function(event) {
|
||||
|
||||
Reference in New Issue
Block a user