mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1140512 - Ensure FindBar communicates properly with content after remoteness change. r=mikedeboer
This commit is contained in:
parent
f252d4ca30
commit
79d7095e90
@ -451,5 +451,31 @@ this.BrowserTestUtils = {
|
||||
tab.ownerDocument.defaultView.gBrowser.removeTab(tab);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Version of EventUtils' `sendChar` function; it will synthesize a keypress
|
||||
* event in a child process and returns a Promise that will result when the
|
||||
* event was fired. Instead of a Window, a Browser object is required to be
|
||||
* passed to this function.
|
||||
*
|
||||
* @param {String} char
|
||||
* A character for the keypress event that is sent to the browser.
|
||||
* @param {Browser} browser
|
||||
* Browser element, must not be null.
|
||||
*
|
||||
* @returns {Promise}
|
||||
* @resolves True if the keypress event was synthesized.
|
||||
*/
|
||||
sendChar(char, browser) {
|
||||
return new Promise(resolve => {
|
||||
let mm = browser.messageManager;
|
||||
mm.addMessageListener("Test:SendCharDone", function charMsg(message) {
|
||||
mm.removeMessageListener("Test:SendCharDone", charMsg);
|
||||
resolve(message.data.sendCharResult);
|
||||
});
|
||||
|
||||
mm.sendAsyncMessage("Test:SendChar", { char: char });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -11,6 +11,10 @@ EventUtils.window = {};
|
||||
EventUtils.parent = EventUtils.window;
|
||||
EventUtils._EU_Ci = Components.interfaces;
|
||||
EventUtils._EU_Cc = Components.classes;
|
||||
// EventUtils' `sendChar` function relies on the navigator to synthetize events.
|
||||
EventUtils.navigator = content.document.defaultView.navigator;
|
||||
EventUtils.KeyboardEvent = content.document.defaultView.KeyboardEvent;
|
||||
|
||||
Services.scriptloader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
|
||||
|
||||
addMessageListener("Test:SynthesizeMouse", (message) => {
|
||||
@ -39,3 +43,8 @@ addMessageListener("Test:SynthesizeMouse", (message) => {
|
||||
let result = EventUtils.synthesizeMouseAtPoint(left, top, data.event, content);
|
||||
sendAsyncMessage("Test:SynthesizeMouseDone", { defaultPrevented: result });
|
||||
});
|
||||
|
||||
addMessageListener("Test:SendChar", message => {
|
||||
let result = EventUtils.sendChar(message.data.char, content);
|
||||
sendAsyncMessage("Test:SendCharDone", { sendCharResult: result });
|
||||
});
|
||||
|
@ -18,7 +18,6 @@ skip-if = e10s # Bug 1064580
|
||||
[browser_f7_caret_browsing.js]
|
||||
skip-if = e10s
|
||||
[browser_findbar.js]
|
||||
skip-if = e10s # Disabled for e10s: Bug ?????? - seems to be a timing issue with RemoteFinder.jsm messages coming later than the tests expect.
|
||||
[browser_input_file_tooltips.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content (TypeError: doc.createElement is not a function)
|
||||
[browser_isSynthetic.js]
|
||||
|
@ -2,6 +2,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
Components.utils.import("resource://gre/modules/Timer.jsm", this);
|
||||
|
||||
const TEST_PAGE_URI = "data:text/html;charset=utf-8,The letter s.";
|
||||
|
||||
/**
|
||||
* Makes sure that the findbar hotkeys (' and /) event listeners
|
||||
* are added to the system event group and do not get blocked
|
||||
@ -11,7 +13,7 @@ add_task(function* test_hotkey_event_propagation() {
|
||||
info("Ensure hotkeys are not affected by stopPropagation.");
|
||||
|
||||
// Opening new tab
|
||||
let tab = yield promiseTestPageLoad();
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI);
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
let findbar = gBrowser.getFindBar();
|
||||
|
||||
@ -23,24 +25,29 @@ add_task(function* test_hotkey_event_propagation() {
|
||||
is(findbar.hidden, true, "Findbar is hidden now.");
|
||||
gBrowser.selectedTab = tab;
|
||||
yield promiseFocus();
|
||||
EventUtils.sendChar(key, browser.contentWindow);
|
||||
yield BrowserTestUtils.sendChar(key, browser);
|
||||
is(findbar.hidden, false, "Findbar should not be hidden.");
|
||||
yield closeFindbarAndWait(findbar);
|
||||
}
|
||||
|
||||
// Stop propagation for all keyboard events.
|
||||
let window = browser.contentWindow;
|
||||
let stopPropagation = function(e) { e.stopImmediatePropagation(); };
|
||||
window.addEventListener("keydown", stopPropagation, true);
|
||||
window.addEventListener("keypress", stopPropagation, true);
|
||||
window.addEventListener("keyup", stopPropagation, true);
|
||||
let frameScript = () => {
|
||||
const stopPropagation = e => e.stopImmediatePropagation();
|
||||
let window = content.document.defaultView;
|
||||
window.removeEventListener("keydown", stopPropagation);
|
||||
window.removeEventListener("keypress", stopPropagation);
|
||||
window.removeEventListener("keyup", stopPropagation);
|
||||
};
|
||||
|
||||
let mm = browser.messageManager;
|
||||
mm.loadFrameScript("data:,(" + frameScript.toString() + ")();", false);
|
||||
|
||||
// Checking if findbar still appears when any hotkey is pressed.
|
||||
for (let key of HOTKEYS) {
|
||||
is(findbar.hidden, true, "Findbar is hidden now.");
|
||||
gBrowser.selectedTab = tab;
|
||||
yield promiseFocus();
|
||||
EventUtils.sendChar(key, browser.contentWindow);
|
||||
yield BrowserTestUtils.sendChar(key, browser);
|
||||
is(findbar.hidden, false, "Findbar should not be hidden.");
|
||||
yield closeFindbarAndWait(findbar);
|
||||
}
|
||||
@ -51,7 +58,7 @@ add_task(function* test_hotkey_event_propagation() {
|
||||
add_task(function* test_not_found() {
|
||||
info("Check correct 'Phrase not found' on new tab");
|
||||
|
||||
let tab = yield promiseTestPageLoad();
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI);
|
||||
|
||||
// Search for the first word.
|
||||
yield promiseFindFinished("--- THIS SHOULD NEVER MATCH ---", false);
|
||||
@ -63,7 +70,7 @@ add_task(function* test_not_found() {
|
||||
});
|
||||
|
||||
add_task(function* test_found() {
|
||||
let tab = yield promiseTestPageLoad();
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI);
|
||||
|
||||
// Search for a string that WILL be found, with 'Highlight All' on
|
||||
yield promiseFindFinished("S", true);
|
||||
@ -76,10 +83,10 @@ add_task(function* test_found() {
|
||||
// Setting first findbar to case-sensitive mode should not affect
|
||||
// new tab find bar.
|
||||
add_task(function* test_tabwise_case_sensitive() {
|
||||
let tab1 = yield promiseTestPageLoad();
|
||||
let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI);
|
||||
let findbar1 = gBrowser.getFindBar();
|
||||
|
||||
let tab2 = yield promiseTestPageLoad();
|
||||
let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI);
|
||||
let findbar2 = gBrowser.getFindBar();
|
||||
|
||||
// Toggle case sensitivity for first findbar
|
||||
@ -102,22 +109,33 @@ add_task(function* test_tabwise_case_sensitive() {
|
||||
gBrowser.removeTab(tab2);
|
||||
});
|
||||
|
||||
function promiseTestPageLoad() {
|
||||
let deferred = Promise.defer();
|
||||
/**
|
||||
* Navigating from a web page (for example mozilla.org) to an internal page
|
||||
* (like about:addons) might trigger a change of browser's remoteness.
|
||||
* 'Remoteness change' means that rendering page content moves from child
|
||||
* process into the parent process or the other way around.
|
||||
* This test ensures that findbar properly handles such a change.
|
||||
*/
|
||||
add_task(function * test_reinitialization_at_remoteness_change() {
|
||||
info("Ensure findbar re-initialization at remoteness change.");
|
||||
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab("data:text/html;charset=utf-8,The letter s.");
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
browser.addEventListener("load", function listener() {
|
||||
if (browser.currentURI.spec == "about:blank")
|
||||
return;
|
||||
info("Page loaded: " + browser.currentURI.spec);
|
||||
browser.removeEventListener("load", listener, true);
|
||||
// Load a remote page and trigger findbar construction.
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI);
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
let findbar = gBrowser.getFindBar();
|
||||
|
||||
deferred.resolve(tab);
|
||||
}, true);
|
||||
// Findbar should operate normally.
|
||||
yield promiseFindFinished("s", false);
|
||||
ok(!findbar._findStatusDesc.textContent, "Findbar status should be empty");
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
gBrowser.updateBrowserRemoteness(browser, false);
|
||||
|
||||
// Findbar should keep operating normally.
|
||||
yield promiseFindFinished("s", false);
|
||||
ok(!findbar._findStatusDesc.textContent, "Findbar status should be empty");
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
function promiseFindFinished(searchText, highlightOn) {
|
||||
let deferred = Promise.defer();
|
||||
@ -131,8 +149,17 @@ function promiseFindFinished(searchText, highlightOn) {
|
||||
findbar._findField.value = searchText;
|
||||
|
||||
let resultListener;
|
||||
// When highlighting is on the finder sends a second "FOUND" message after
|
||||
// the search wraps. This causes timing problems with e10s. waitMore
|
||||
// forces foundOrTimeout wait for the second "FOUND" message before
|
||||
// resolving the promise.
|
||||
let waitMore = highlightOn;
|
||||
let findTimeout = setTimeout(() => foundOrTimedout(null), 2000);
|
||||
let foundOrTimedout = function(aData) {
|
||||
if (aData !== null && waitMore) {
|
||||
waitMore = false;
|
||||
return;
|
||||
}
|
||||
if (aData === null)
|
||||
info("Result listener not called, timeout reached.");
|
||||
clearTimeout(findTimeout);
|
||||
|
@ -373,12 +373,28 @@
|
||||
// browser property
|
||||
if (this.getAttribute("browserid"))
|
||||
setTimeout(function(aSelf) { aSelf.browser = aSelf.browser; }, 0, this);
|
||||
|
||||
if (typeof gBrowser !== 'undefined')
|
||||
gBrowser.tabContainer.addEventListener("TabRemotenessChange", this);
|
||||
]]></constructor>
|
||||
|
||||
<destructor><![CDATA[
|
||||
this.destroy();
|
||||
]]></destructor>
|
||||
|
||||
<method name="handleEvent">
|
||||
<parameter name="aEvent"/>
|
||||
<body><![CDATA[
|
||||
switch(aEvent.type) {
|
||||
case "onRemotenessChange":
|
||||
// Reinitializing browser to re-attach listeners.
|
||||
this.browser._lastSearchString = this._findField.value;
|
||||
this.browser = this.browser;
|
||||
break;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<!-- This is necessary because the destructor isn't called when
|
||||
we are removed from a document that is not destroyed. This
|
||||
needs to be explicitly called in this case -->
|
||||
@ -402,6 +418,9 @@
|
||||
|
||||
// Clear all timers that might still be running.
|
||||
this._cancelTimers();
|
||||
|
||||
if (typeof gBrowser !== 'undefined')
|
||||
gBrowser.tabContainer.removeEventListener("TabRemotenessChange", this);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user