Bug 1479318: Minimize the amount of content Findbar code loaded by default. r=felipe

MozReview-Commit-ID: Gu4RyWKmaAz

--HG--
rename : toolkit/content/browser-content.js => toolkit/modules/FindBarChild.jsm
extra : source : 177e4adb94d1b63002577995deed230ba15624f8
extra : intermediate-source : 915862a355e959c92c9ea7fb1cd7adbcf03bfb98
This commit is contained in:
Kris Maglione 2018-07-29 14:38:44 -07:00
parent d60e939f6a
commit 5ccef39c52
6 changed files with 154 additions and 161 deletions

View File

@ -464,22 +464,18 @@ window._gBrowser = {
_setFindbarData() {
// Ensure we know what the find bar key is in the content process:
let initialProcessData = Services.ppmm.initialProcessData;
if (!initialProcessData.findBarShortcutData) {
let {sharedData} = Services.ppmm;
if (!sharedData.has("Findbar:Shortcut")) {
let keyEl = document.getElementById("key_find");
let mods = keyEl.getAttribute("modifiers")
.replace(/accel/i, AppConstants.platform == "macosx" ? "meta" : "control");
initialProcessData.findBarShortcutData = {
sharedData.set("Findbar:Shortcut", {
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);
shiftKey: mods.includes("shift"),
ctrlKey: mods.includes("control"),
altKey: mods.includes("alt"),
metaKey: mods.includes("meta"),
});
}
},

View File

@ -49,6 +49,12 @@ XPCOMUtils.defineLazyProxy(this, "DateTimePickerContent", () => {
return new tmp.DateTimePickerContent(this);
});
XPCOMUtils.defineLazyProxy(this, "FindBarChild", () => {
let tmp = {};
ChromeUtils.import("resource://gre/modules/FindBarChild.jsm", tmp);
return new tmp.FindBarChild(this);
}, {inQuickFind: false, inPassThrough: false});
// Lazily load the finder code
addMessageListener("Finder:Initialize", function() {
@ -117,13 +123,6 @@ addMessageListener("SwitchDocumentDirection", () => {
});
var FindBar = {
/* Please keep in sync with toolkit/content/widgets/findbar.xml */
FIND_NORMAL: 0,
FIND_TYPEAHEAD: 1,
FIND_LINKS: 2,
_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
@ -131,159 +130,59 @@ var FindBar = {
* 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();
Services.els.addSystemEventListener(global, "keypress",
this.onKeypress.bind(this), false);
this.init = null;
},
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;
}
},
handleEvent(event) {
switch (event.type) {
case "keypress":
this._onKeypress(event);
break;
case "mouseup":
this._onMouseup(event);
break;
}
},
/**
* 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.
*/
_canAndShouldFastFind() {
let should = false;
let can = BrowserUtils.canFastFind(content);
if (can) {
// XXXgijs: why all these shenanigans? Why not use the event's target?
let focusedWindow = {};
let elt = Services.focus.getFocusedElementForWindow(content, true, focusedWindow);
let win = focusedWindow.value;
should = BrowserUtils.shouldFastFind(elt, win);
}
return { can, should };
},
_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;
}
// Check the focused element etc.
let fastFind = this._canAndShouldFastFind();
// Can we even use find in this page at all?
if (!fastFind.can) {
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) && RemoteFinder._manualFAYT;
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);
eventMatchesFindShortcut(aEvent) {
if (!this._findKey) {
this._findKey = Services.cpmm.sharedData.get("Findbar:Shortcut");
if (!this._findKey) {
return false;
}
}
},
_passKeyToParent(event) {
event.preventDefault();
// These are the properties required to dispatch another 'real' event
// to the findbar in the parent in _dispatchKeypressEvent in findbar.xml .
// If you make changes here, verify that that method can still do its job.
const kRequiredProps = [
"type", "bubbles", "cancelable", "ctrlKey", "altKey", "shiftKey",
"metaKey", "keyCode", "charCode",
];
let fakeEvent = {};
for (let prop of kRequiredProps) {
fakeEvent[prop] = event[prop];
for (let k in this._findKey) {
if (this._findKey[k] != aEvent[k]) {
return false;
}
}
sendAsyncMessage("Findbar:Keypress", fakeEvent);
return true;
},
_onMouseup(event) {
if (this._findMode != this.FIND_NORMAL)
sendAsyncMessage("Findbar:Mouseup");
onKeypress(event) {
if (!FindBarChild.inPassThrough &&
this.eventMatchesFindShortcut(event)) {
return FindBarChild.start(event);
}
if (event.ctrlKey || event.altKey || event.metaKey || event.defaultPrevented ||
!BrowserUtils.canFastFind(content)) {
return null;
}
if (FindBarChild.inPassThrough || FindBarChild.inQuickFind) {
return FindBarChild.onKeypress(event);
}
if (event.charCode && BrowserUtils.shouldFastFind(event.target)) {
let key = String.fromCharCode(event.charCode);
if ((key == "/" || key == "'") && RemoteFinder._manualFAYT) {
return FindBarChild.startQuickFind(event);
}
if (key != " " && RemoteFinder._findAsYouType) {
return FindBarChild.startQuickFind(event, true);
}
}
return null;
},
};
FindBar.init();

View File

@ -220,7 +220,7 @@
</content>
<implementation>
<!-- Please keep in sync with toolkit/content/browser-content.js -->
<!-- Please keep in sync with toolkit/modules/FindBarChild.jsm -->
<field name="FIND_NORMAL">0</field>
<field name="FIND_TYPEAHEAD">1</field>
<field name="FIND_LINKS">2</field>

View File

@ -290,12 +290,10 @@ var BrowserUtils = {
*
* @param elt
* The element that is focused
* @param win
* The window that is focused
*
*/
shouldFastFind(elt, win) {
shouldFastFind(elt) {
if (elt) {
let win = elt.ownerGlobal;
if (elt instanceof win.HTMLInputElement && elt.mozIsTextField(false))
return false;

View File

@ -0,0 +1,99 @@
// vim: set ts=2 sw=2 sts=2 tw=80:
// 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";
var EXPORTED_SYMBOLS = ["FindBarChild"];
ChromeUtils.defineModuleGetter(this, "RemoteFinder",
"resource://gre/modules/RemoteFinder.jsm");
ChromeUtils.defineModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
/* Please keep in sync with toolkit/this.mm.content/widgets/findbar.xml */
const FIND_NORMAL = 0;
const FIND_TYPEAHEAD = 1;
const FIND_LINKS = 2;
class FindBarChild {
constructor(mm) {
this.mm = mm;
this.findMode = 0;
this.inQuickFind = false;
this.mm.addMessageListener("Findbar:UpdateState", this);
Services.els.addSystemEventListener(this.mm, "mouseup", this, false);
}
start(event) {
this.inPassThrough = true;
}
startQuickFind(event, autostart = false) {
let mode = FIND_TYPEAHEAD;
if (event.charCode == "'".charAt(0) ||
autostart && RemoteFinder._typeAheadLinksOnly) {
mode = FIND_LINKS;
}
// Set findMode immediately (without waiting for child->parent->child roundtrip)
// to ensure we pass any further keypresses, too.
this.findMode = mode;
this.passKeyToParent(event);
}
receiveMessage(msg) {
switch (msg.name) {
case "Findbar:UpdateState":
this.findMode = msg.data.findMode;
this.inQuickFind = msg.data.hasQuickFindTimeout;
if (msg.data.isOpenAndFocused) {
this.inPassThrough = false;
}
break;
}
}
handleEvent(event) {
switch (event.type) {
case "keypress":
this.onKeypress(event);
break;
case "mouseup":
this.onMouseup(event);
break;
}
}
onKeypress(event) {
if (this.inPassThrough) {
this.passKeyToParent(event);
} else if (this.findMode != FIND_NORMAL && this.inQuickFind && event.charCode) {
this.passKeyToParent(event);
}
}
passKeyToParent(event) {
event.preventDefault();
// These are the properties required to dispatch another 'real' event
// to the findbar in the parent in _dispatchKeypressEvent in findbar.xml .
// If you make changes here, verify that that method can still do its job.
const kRequiredProps = [
"type", "bubbles", "cancelable", "ctrlKey", "altKey", "shiftKey",
"metaKey", "keyCode", "charCode",
];
let fakeEvent = {};
for (let prop of kRequiredProps) {
fakeEvent[prop] = event[prop];
}
this.mm.sendAsyncMessage("Findbar:Keypress", fakeEvent);
}
onMouseup(event) {
if (this.findMode != FIND_NORMAL)
this.mm.sendAsyncMessage("Findbar:Mouseup");
}
}

View File

@ -200,6 +200,7 @@ EXTRA_JS_MODULES += [
'E10SUtils.jsm',
'EventEmitter.jsm',
'FileUtils.jsm',
'FindBarChild.jsm',
'Finder.jsm',
'FinderHighlighter.jsm',
'FinderIterator.jsm',