mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
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:
parent
d60e939f6a
commit
5ccef39c52
@ -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"),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
||||
|
99
toolkit/modules/FindBarChild.jsm
Normal file
99
toolkit/modules/FindBarChild.jsm
Normal 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");
|
||||
}
|
||||
}
|
@ -200,6 +200,7 @@ EXTRA_JS_MODULES += [
|
||||
'E10SUtils.jsm',
|
||||
'EventEmitter.jsm',
|
||||
'FileUtils.jsm',
|
||||
'FindBarChild.jsm',
|
||||
'Finder.jsm',
|
||||
'FinderHighlighter.jsm',
|
||||
'FinderIterator.jsm',
|
||||
|
Loading…
Reference in New Issue
Block a user