зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1333990: Part 3b - Preload matching content scripts when opening document channels. r=aswan,billm
This uses the http-on-opening-request observer that's dispatched in the child process to begin preloading matching content scripts as early in the load cycle as possible. Ideally we would use the network predictor for this, but most of its prediction work happens in the parent process, and there are no simple ways for us to hook into it. This currently does not do any pre-loading in the parent process, mainly because there isn't a good way to distinguish top-level document loads that are happening directly in the parent versus those that are being proxied from the child. MozReview-Commit-ID: dIQW68HtxZ --HG-- extra : rebase_source : b36f6c8516d0550a0d5bb0df895ce6db76ab3538
This commit is contained in:
Родитель
53e241ffbc
Коммит
6a80b8df35
|
@ -159,6 +159,40 @@ Script.prototype = {
|
|||
return urls;
|
||||
},
|
||||
|
||||
matchesLoadInfo(uri, loadInfo) {
|
||||
if (!this.matchesURI(uri)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.options.all_frames && !loadInfo.isTopLevelLoad) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
matchesURI(uri) {
|
||||
if (!(this.matches_.matches(uri) || this.matches_host_.matchesIgnoringPath(uri))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.exclude_matches_.matches(uri)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.options.include_globs != null) {
|
||||
if (!this.include_globs_.matches(uri.spec)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.exclude_globs_.matches(uri.spec)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
matches(window) {
|
||||
let uri = window.document.documentURIObject;
|
||||
let principal = window.document.nodePrincipal;
|
||||
|
@ -191,21 +225,7 @@ Script.prototype = {
|
|||
uri = principal.URI;
|
||||
}
|
||||
|
||||
if (!(this.matches_.matches(uri) || this.matches_host_.matchesIgnoringPath(uri))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.exclude_matches_.matches(uri)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.options.include_globs != null) {
|
||||
if (!this.include_globs_.matches(uri.spec)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.exclude_globs_.matches(uri.spec)) {
|
||||
if (!this.matchesURI(uri)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -511,12 +531,18 @@ DocumentManager = {
|
|||
extensionPageWindows: new Map(),
|
||||
|
||||
init() {
|
||||
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
|
||||
Services.obs.addObserver(this, "http-on-opening-request", false);
|
||||
}
|
||||
Services.obs.addObserver(this, "content-document-global-created", false);
|
||||
Services.obs.addObserver(this, "document-element-inserted", false);
|
||||
Services.obs.addObserver(this, "inner-window-destroyed", false);
|
||||
},
|
||||
|
||||
uninit() {
|
||||
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
|
||||
Services.obs.removeObserver(this, "http-on-opening-request");
|
||||
}
|
||||
Services.obs.removeObserver(this, "content-document-global-created");
|
||||
Services.obs.removeObserver(this, "document-element-inserted");
|
||||
Services.obs.removeObserver(this, "inner-window-destroyed");
|
||||
|
@ -556,7 +582,7 @@ DocumentManager = {
|
|||
}
|
||||
},
|
||||
|
||||
observe: function(subject, topic, data) {
|
||||
observe(subject, topic, data) {
|
||||
// For some types of documents (about:blank), we only see the first
|
||||
// notification, for others (data: URIs) we only observe the second.
|
||||
if (topic == "content-document-global-created" || topic == "document-element-inserted") {
|
||||
|
@ -613,10 +639,19 @@ DocumentManager = {
|
|||
}
|
||||
|
||||
ExtensionChild.destroyExtensionContext(windowId);
|
||||
} else if (topic === "http-on-opening-request") {
|
||||
let {loadInfo} = subject.QueryInterface(Ci.nsIChannel);
|
||||
if (loadInfo) {
|
||||
let {externalContentPolicyType: type} = loadInfo;
|
||||
if (type === Ci.nsIContentPolicy.TYPE_DOCUMENT ||
|
||||
type === Ci.nsIContentPolicy.TYPE_SUBDOCUMENT) {
|
||||
this.preloadScripts(subject.URI, loadInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
handleEvent: function(event) {
|
||||
handleEvent(event) {
|
||||
let window = event.currentTarget;
|
||||
if (event.target != window.document) {
|
||||
// We use capturing listeners so we have precedence over content script
|
||||
|
@ -775,6 +810,16 @@ DocumentManager = {
|
|||
}
|
||||
},
|
||||
|
||||
preloadScripts(uri, loadInfo) {
|
||||
for (let extension of ExtensionManager.extensions.values()) {
|
||||
for (let script of extension.scripts) {
|
||||
if (script.matchesLoadInfo(uri, loadInfo)) {
|
||||
script.compileScripts();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
trigger(when, window) {
|
||||
if (when === "document_start") {
|
||||
for (let extension of ExtensionManager.extensions.values()) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче