зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1371523 - remove find bar sync ipc message, r=mikedeboer
MozReview-Commit-ID: C0VO0U3UJ76 --HG-- extra : rebase_source : 01e33223409023b03bd2ac83652953cc586be1ae
This commit is contained in:
Родитель
1a9b300cbb
Коммит
1037d799f9
|
@ -54,9 +54,8 @@ window._gBrowser = {
|
|||
|
||||
// To correctly handle keypresses for potential FindAsYouType, while
|
||||
// the tab's find bar is not yet initialized.
|
||||
this._findAsYouType = Services.prefs.getBoolPref("accessibility.typeaheadfind");
|
||||
Services.prefs.addObserver("accessibility.typeaheadfind", this);
|
||||
messageManager.addMessageListener("Findbar:Keypress", this);
|
||||
this._setFindbarData();
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "animationsEnabled",
|
||||
"toolkit.cosmeticAnimations.enabled");
|
||||
|
@ -438,6 +437,27 @@ window._gBrowser = {
|
|||
return this.selectedBrowser.userTypedValue;
|
||||
},
|
||||
|
||||
_setFindbarData() {
|
||||
// Ensure we know what the find bar key is in the content process:
|
||||
let initialProcessData = Services.ppmm.initialProcessData;
|
||||
if (!initialProcessData.findBarShortcutData) {
|
||||
let keyEl = document.getElementById("key_find");
|
||||
let mods = keyEl.getAttribute("modifiers")
|
||||
.replace(/accel/i, AppConstants.platform == "macosx" ? "meta" : "control");
|
||||
initialProcessData.findBarShortcutData = {
|
||||
key: keyEl.getAttribute("key"),
|
||||
modifiers: {
|
||||
shiftKey: mods.includes("shift"),
|
||||
ctrlKey: mods.includes("control"),
|
||||
altKey: mods.includes("alt"),
|
||||
metaKey: mods.includes("meta"),
|
||||
},
|
||||
};
|
||||
Services.ppmm.broadcastAsyncMessage("Findbar:ShortcutData",
|
||||
initialProcessData.findBarShortcutData);
|
||||
}
|
||||
},
|
||||
|
||||
isFindBarInitialized(aTab) {
|
||||
return (aTab || this.selectedTab)._findBar != undefined;
|
||||
},
|
||||
|
@ -469,27 +489,20 @@ window._gBrowser = {
|
|||
/**
|
||||
* Create a findbar instance.
|
||||
* @param aTab the tab to create the find bar for.
|
||||
* @param aForce Whether to force a sync flush to trigger XBL construction immediately.
|
||||
* @return the created findbar, or null if the window or tab is closed/closing.
|
||||
*/
|
||||
async _createFindBar(aTab, aForce = false) {
|
||||
async _createFindBar(aTab) {
|
||||
let findBar = document.createElementNS(this._XUL_NS, "findbar");
|
||||
let browser = this.getBrowserForTab(aTab);
|
||||
let browserContainer = this.getBrowserContainer(browser);
|
||||
browserContainer.appendChild(findBar);
|
||||
|
||||
if (aForce) {
|
||||
// Force a style flush to ensure that our binding is attached.
|
||||
// Remove after bug 1371523 makes more of this async.
|
||||
findBar.clientTop;
|
||||
} else {
|
||||
await new Promise(r => requestAnimationFrame(r));
|
||||
if (window.closed || aTab.closing) {
|
||||
delete aTab._pendingFindBar;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
await new Promise(r => requestAnimationFrame(r));
|
||||
delete aTab._pendingFindBar;
|
||||
if (window.closed || aTab.closing) {
|
||||
delete aTab._pendingFindBar;
|
||||
return null;
|
||||
}
|
||||
|
||||
findBar.browser = browser;
|
||||
findBar._findField.value = this._lastFindValue;
|
||||
|
@ -3784,30 +3797,11 @@ window._gBrowser = {
|
|||
case "Findbar:Keypress":
|
||||
{
|
||||
let tab = this.getTabForBrowser(browser);
|
||||
// If the find bar for this tab is not yet alive, only initialize
|
||||
// it if there's a possibility FindAsYouType will be used.
|
||||
// There's no point in doing it for most random keypresses.
|
||||
if (!this.isFindBarInitialized(tab) &&
|
||||
data.shouldFastFind) {
|
||||
let shouldFastFind = this._findAsYouType;
|
||||
if (!shouldFastFind) {
|
||||
// Please keep in sync with toolkit/content/widgets/findbar.xml
|
||||
const FAYT_LINKS_KEY = "'";
|
||||
const FAYT_TEXT_KEY = "/";
|
||||
let charCode = data.fakeEvent.charCode;
|
||||
let key = charCode ? String.fromCharCode(charCode) : null;
|
||||
shouldFastFind = key == FAYT_LINKS_KEY || key == FAYT_TEXT_KEY;
|
||||
}
|
||||
if (shouldFastFind) {
|
||||
// Make sure we return the result.
|
||||
// This needs sync initialization of the find bar, unfortunately.
|
||||
// bug 1371523 tracks removing all of this.
|
||||
|
||||
// This returns a promise, so don't use the result...
|
||||
this._createFindBar(tab, true);
|
||||
// ... just grab the 'cached' version now we know it exists.
|
||||
this.getCachedFindBar().receiveMessage(aMessage);
|
||||
}
|
||||
if (!this.isFindBarInitialized(tab)) {
|
||||
let fakeEvent = data;
|
||||
this.getFindBar(tab).then(findbar => {
|
||||
findbar._onBrowserKeypress(fakeEvent);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3876,12 +3870,6 @@ window._gBrowser = {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case "nsPref:changed":
|
||||
{
|
||||
// This is the only pref observed.
|
||||
this._findAsYouType = Services.prefs.getBoolPref("accessibility.typeaheadfind");
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -3942,8 +3930,6 @@ window._gBrowser = {
|
|||
this._switcher.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
Services.prefs.removeObserver("accessibility.typeaheadfind", this);
|
||||
},
|
||||
|
||||
_setupEventListeners() {
|
||||
|
|
|
@ -172,8 +172,11 @@ var testData = [
|
|||
},
|
||||
];
|
||||
|
||||
function sendKeys(aKeys) {
|
||||
function sendKeys(aKeys, aElem) {
|
||||
for (let i = 0; i < aKeys.length; i++) {
|
||||
// Force layout flush between keys to ensure focus is correct.
|
||||
// This shouldn't be necessary; bug 1450219 tracks this.
|
||||
aElem.clientTop;
|
||||
let key = aKeys[i];
|
||||
if (key.startsWith("KEY_")) {
|
||||
synthesizeKey(key);
|
||||
|
@ -189,7 +192,7 @@ function test() {
|
|||
for (let { keys, initialVal, expectedVal } of testData) {
|
||||
elem.focus();
|
||||
elem.value = initialVal;
|
||||
sendKeys(keys);
|
||||
sendKeys(keys, elem);
|
||||
is(elem.value, expectedVal,
|
||||
"Test with " + keys + ", result should be " + expectedVal);
|
||||
elem.value = "";
|
||||
|
|
|
@ -17,6 +17,8 @@ ChromeUtils.defineModuleGetter(this, "SelectContentHelper",
|
|||
"resource://gre/modules/SelectContentHelper.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "FindContent",
|
||||
"resource://gre/modules/FindContent.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "RemoteFinder",
|
||||
"resource://gre/modules/RemoteFinder.jsm");
|
||||
|
||||
var global = this;
|
||||
|
||||
|
@ -927,16 +929,37 @@ var FindBar = {
|
|||
|
||||
_findMode: 0,
|
||||
|
||||
/**
|
||||
* _findKey and _findModifiers are used to determine whether a keypress
|
||||
* is a user attempting to use the find shortcut, after which we'll
|
||||
* route keypresses to the parent until we know the findbar has focus
|
||||
* there. To do this, we need shortcut data from the parent.
|
||||
*/
|
||||
_findKey: null,
|
||||
_findModifiers: null,
|
||||
|
||||
init() {
|
||||
addMessageListener("Findbar:UpdateState", this);
|
||||
Services.els.addSystemEventListener(global, "keypress", this, false);
|
||||
Services.els.addSystemEventListener(global, "mouseup", this, false);
|
||||
this._initShortcutData();
|
||||
},
|
||||
|
||||
receiveMessage(msg) {
|
||||
switch (msg.name) {
|
||||
case "Findbar:UpdateState":
|
||||
this._findMode = msg.data.findMode;
|
||||
this._quickFindTimeout = msg.data.hasQuickFindTimeout;
|
||||
if (msg.data.isOpenAndFocused) {
|
||||
this._keepPassingUntilToldOtherwise = false;
|
||||
}
|
||||
break;
|
||||
case "Findbar:ShortcutData":
|
||||
// Set us up to never need this again for the lifetime of this process,
|
||||
// and remove the listener.
|
||||
Services.cpmm.initialProcessData.findBarShortcutData = msg.data;
|
||||
Services.cpmm.removeMessageListener("Findbar:ShortcutData", this);
|
||||
this._initShortcutData(msg.data);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
@ -952,6 +975,36 @@ var FindBar = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Use initial process data for find key/modifier data if we have it.
|
||||
* Otherwise, add a listener so we get the data when the parent process has
|
||||
* it.
|
||||
*/
|
||||
_initShortcutData(data = Services.cpmm.initialProcessData.findBarShortcutData) {
|
||||
if (data) {
|
||||
this._findKey = data.key;
|
||||
this._findModifiers = data.modifiers;
|
||||
} else {
|
||||
Services.cpmm.addMessageListener("Findbar:ShortcutData", this);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether this key event will start the findbar in the parent,
|
||||
* in which case we should pass any further key events to the parent to avoid
|
||||
* them being lost.
|
||||
* @param aEvent the key event to check.
|
||||
*/
|
||||
_eventMatchesFindShortcut(aEvent) {
|
||||
let modifiers = this._findModifiers;
|
||||
if (!modifiers) {
|
||||
return false;
|
||||
}
|
||||
return aEvent.ctrlKey == modifiers.ctrlKey && aEvent.altKey == modifiers.altKey &&
|
||||
aEvent.shiftKey == modifiers.shiftKey && aEvent.metaKey == modifiers.metaKey &&
|
||||
aEvent.key == this._findKey;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns whether FAYT can be used for the given event in
|
||||
* the current content state.
|
||||
|
@ -970,9 +1023,14 @@ var FindBar = {
|
|||
},
|
||||
|
||||
_onKeypress(event) {
|
||||
const FAYT_LINKS_KEY = "'";
|
||||
const FAYT_TEXT_KEY = "/";
|
||||
if (this._eventMatchesFindShortcut(event)) {
|
||||
this._keepPassingUntilToldOtherwise = true;
|
||||
}
|
||||
// Useless keys:
|
||||
if (event.ctrlKey || event.altKey || event.metaKey || event.defaultPrevented) {
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the focused element etc.
|
||||
|
@ -980,9 +1038,39 @@ var FindBar = {
|
|||
|
||||
// Can we even use find in this page at all?
|
||||
if (!fastFind.can) {
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
if (this._keepPassingUntilToldOtherwise) {
|
||||
this._passKeyToParent(event);
|
||||
return;
|
||||
}
|
||||
if (!fastFind.should) {
|
||||
return;
|
||||
}
|
||||
|
||||
let charCode = event.charCode;
|
||||
// If the find bar is open and quick find is on, send the key to the parent.
|
||||
if (this._findMode != this.FIND_NORMAL && this._quickFindTimeout) {
|
||||
if (!charCode)
|
||||
return;
|
||||
this._passKeyToParent(event);
|
||||
} else {
|
||||
let key = charCode ? String.fromCharCode(charCode) : null;
|
||||
let manualstartFAYT = (key == FAYT_LINKS_KEY || key == FAYT_TEXT_KEY);
|
||||
let autostartFAYT = !manualstartFAYT && RemoteFinder._findAsYouType && key && key != " ";
|
||||
if (manualstartFAYT || autostartFAYT) {
|
||||
let mode = (key == FAYT_LINKS_KEY || (autostartFAYT && RemoteFinder._typeAheadLinksOnly)) ?
|
||||
this.FIND_LINKS : this.FIND_TYPEAHEAD;
|
||||
// Set _findMode immediately (without waiting for child->parent->child roundtrip)
|
||||
// to ensure we pass any further keypresses, too.
|
||||
this._findMode = mode;
|
||||
this._passKeyToParent(event);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_passKeyToParent(event) {
|
||||
event.preventDefault();
|
||||
let fakeEvent = {};
|
||||
for (let k in event) {
|
||||
if (typeof event[k] != "object" && typeof event[k] != "function" &&
|
||||
|
@ -990,16 +1078,7 @@ var FindBar = {
|
|||
fakeEvent[k] = event[k];
|
||||
}
|
||||
}
|
||||
// sendSyncMessage returns an array of the responses from all listeners
|
||||
let rv = sendSyncMessage("Findbar:Keypress", {
|
||||
fakeEvent,
|
||||
shouldFastFind: fastFind.should
|
||||
});
|
||||
if (rv.includes(false)) {
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
return undefined;
|
||||
sendAsyncMessage("Findbar:Keypress", fakeEvent);
|
||||
},
|
||||
|
||||
_onMouseup(event) {
|
||||
|
|
|
@ -161,7 +161,7 @@ add_task(async function test_reinitialization_at_remoteness_change() {
|
|||
* Ensure that the initial typed characters aren't lost immediately after
|
||||
* opening the find bar.
|
||||
*/
|
||||
add_task(async function() {
|
||||
add_task(async function e10sLostKeys() {
|
||||
// This test only makes sence in e10s evironment.
|
||||
if (!gMultiProcessBrowser) {
|
||||
info("Skipping this test because of non-e10s environment.");
|
||||
|
@ -169,7 +169,6 @@ add_task(async function() {
|
|||
}
|
||||
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE_URI);
|
||||
let browser = tab.linkedBrowser;
|
||||
|
||||
ok(!gFindBarInitialized, "findbar isn't initialized yet");
|
||||
|
||||
|
@ -177,21 +176,19 @@ add_task(async function() {
|
|||
let findBar = gFindBar;
|
||||
let initialValue = findBar._findField.value;
|
||||
|
||||
await EventUtils.synthesizeAndWaitKey("f", { accelKey: true }, window, null,
|
||||
() => {
|
||||
await EventUtils.synthesizeAndWaitKey("f", { accelKey: true }, window, null, () => {
|
||||
// We can't afford to wait for the promise to resolve, by then the
|
||||
// find bar is visible and focused, so sending characters to the
|
||||
// content browser wouldn't work.
|
||||
isnot(document.activeElement, findBar._findField.inputField,
|
||||
"findbar is not yet focused");
|
||||
EventUtils.synthesizeKey("a");
|
||||
EventUtils.synthesizeKey("b");
|
||||
EventUtils.synthesizeKey("c");
|
||||
is(findBar._findField.value, initialValue, "still has initial find query");
|
||||
});
|
||||
|
||||
let promises = [
|
||||
BrowserTestUtils.sendChar("a", browser),
|
||||
BrowserTestUtils.sendChar("b", browser),
|
||||
BrowserTestUtils.sendChar("c", browser)
|
||||
];
|
||||
|
||||
is(findBar._findField.value, initialValue, "still has initial find query");
|
||||
|
||||
await Promise.all(promises);
|
||||
await BrowserTestUtils.waitForCondition(() => findBar._findField.value.length == 3);
|
||||
is(document.activeElement, findBar._findField.inputField,
|
||||
"findbar is now focused");
|
||||
is(findBar._findField.value, "abc", "abc fully entered as find query");
|
||||
|
|
|
@ -115,10 +115,11 @@
|
|||
]]></handler>
|
||||
|
||||
<handler event="focus"><![CDATA[
|
||||
let findbar = this.findbar;
|
||||
if (/Mac/.test(navigator.platform)) {
|
||||
let findbar = this.findbar;
|
||||
findbar._onFindFieldFocus();
|
||||
}
|
||||
findbar._updateBrowserWithState();
|
||||
]]></handler>
|
||||
|
||||
<handler event="compositionstart"><![CDATA[
|
||||
|
@ -128,6 +129,7 @@
|
|||
if (findbar._quickFindTimeout) {
|
||||
clearTimeout(findbar._quickFindTimeout);
|
||||
findbar._quickFindTimeout = null;
|
||||
findbar._updateBrowserWithState();
|
||||
}
|
||||
]]></handler>
|
||||
|
||||
|
@ -467,6 +469,7 @@
|
|||
// findbar is already hidden.
|
||||
if (this._isIMEComposing || this.hidden) {
|
||||
this._quickFindTimeout = null;
|
||||
this._updateBrowserWithState();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -475,6 +478,7 @@
|
|||
this.close();
|
||||
this._quickFindTimeout = null;
|
||||
}, this._quickFindTimeoutLength);
|
||||
this._updateBrowserWithState();
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -746,6 +750,7 @@
|
|||
this.browser.finder.onFindbarClose();
|
||||
|
||||
this._cancelTimers();
|
||||
this._updateBrowserWithState();
|
||||
|
||||
this._findFailedString = null;
|
||||
]]></body>
|
||||
|
@ -830,41 +835,26 @@
|
|||
]]></body>
|
||||
</method>
|
||||
|
||||
<!-- We get a fake event object through an IPC message which contains the
|
||||
data we need to make a decision. We then return |true| if and only if
|
||||
the page gets to deal with the event itself. Everywhere we return
|
||||
false, the message sender will take care of calling event.preventDefault
|
||||
on the real event. -->
|
||||
<!-- We get a fake event object through an IPC message when FAYT is being used
|
||||
from within the browser. We then stuff that input in the find bar here. -->
|
||||
<method name="_onBrowserKeypress">
|
||||
<parameter name="aFakeEvent"/>
|
||||
<parameter name="aShouldFastFind"/>
|
||||
<body><![CDATA[
|
||||
const FAYT_LINKS_KEY = "'";
|
||||
const FAYT_TEXT_KEY = "/";
|
||||
|
||||
// Fast keypresses can stack up when the content process is slow or
|
||||
// hangs when in e10s mode. We make sure the findbar isn't 'opened'
|
||||
// several times in a row, because then the find query is selected
|
||||
// each time, losing characters typed initially.
|
||||
let inputField = this._findField.inputField;
|
||||
if (!this.hidden && document.activeElement == inputField) {
|
||||
this._dispatchKeypressEvent(inputField, aFakeEvent);
|
||||
return false;
|
||||
if (!this.hidden && this._findField.inputField == document.activeElement) {
|
||||
this._dispatchKeypressEvent(this._findField.inputField, aFakeEvent);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._findMode != this.FIND_NORMAL && this._quickFindTimeout) {
|
||||
if (!aFakeEvent.charCode)
|
||||
return true;
|
||||
|
||||
this._findField.select();
|
||||
this._findField.focus();
|
||||
this._dispatchKeypressEvent(this._findField.inputField, aFakeEvent);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aShouldFastFind)
|
||||
return true;
|
||||
|
||||
let key = aFakeEvent.charCode ? String.fromCharCode(aFakeEvent.charCode) : null;
|
||||
let manualstartFAYT = (key == FAYT_LINKS_KEY || key == FAYT_TEXT_KEY);
|
||||
let autostartFAYT = !manualstartFAYT && this._findAsYouType &&
|
||||
|
@ -887,10 +877,7 @@
|
|||
this._dispatchKeypressEvent(this._findField.inputField, aFakeEvent);
|
||||
else
|
||||
this._updateStatusUI(this.nsITypeAheadFind.FIND_FOUND);
|
||||
|
||||
return false;
|
||||
}
|
||||
return undefined;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -906,10 +893,9 @@
|
|||
if (!this.hidden && this._findMode != this.FIND_NORMAL)
|
||||
this.close();
|
||||
break;
|
||||
|
||||
case "Findbar:Keypress":
|
||||
return this._onBrowserKeypress(aMessage.data.fakeEvent,
|
||||
aMessage.data.shouldFastFind);
|
||||
this._onBrowserKeypress(aMessage.data);
|
||||
break;
|
||||
}
|
||||
return undefined;
|
||||
]]></body>
|
||||
|
@ -919,7 +905,9 @@
|
|||
<body><![CDATA[
|
||||
if (this._browser && this._browser.messageManager) {
|
||||
this._browser.messageManager.sendAsyncMessage("Findbar:UpdateState", {
|
||||
findMode: this._findMode
|
||||
findMode: this._findMode,
|
||||
isOpenAndFocused: !this.hidden && document.activeElement == this._findField.inputField,
|
||||
hasQuickFindTimeout: !!this._quickFindTimeout,
|
||||
});
|
||||
}
|
||||
]]></body>
|
||||
|
|
|
@ -328,3 +328,9 @@ RemoteFinderListener.prototype = {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(RemoteFinder, "_typeAheadLinksOnly",
|
||||
"accessibility.typeaheadfind.linksonly");
|
||||
XPCOMUtils.defineLazyPreferenceGetter(RemoteFinder, "_findAsYouType",
|
||||
"accessibility.typeaheadfind");
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче