mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-23 18:26:15 +00:00
93a0f8e0fd
If the pref browser.fission.simulate is true, the event dispatcher in ActorManagerChild will not dispatch events to actors that aren't associated with the same window as the event's target. In addition, when that pref is on, the actors associated with sub-frames will have their content property bound to the correct content window, that might differ from the message manager's window (which is always related to the top level). Then, in order to write Fission-compatible code, that specific actor will need to be declared with allFrames = true, meaning that it wants to be instantiated for every frame, and not just top-level ones Differential Revision: https://phabricator.services.mozilla.com/D6358 --HG-- extra : moz-landing-system : lando
121 lines
3.6 KiB
JavaScript
121 lines
3.6 KiB
JavaScript
/* vim: set ts=2 sw=2 sts=2 et tw=80: */
|
|
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
|
/* 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/. */
|
|
|
|
var EXPORTED_SYMBOLS = ["OfflineAppsChild"];
|
|
|
|
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
|
|
|
|
class OfflineAppsChild extends ActorChild {
|
|
constructor(dispatcher) {
|
|
super(dispatcher);
|
|
|
|
this._docId = 0;
|
|
this._docIdMap = new Map();
|
|
|
|
this._docManifestSet = new Set();
|
|
|
|
this._observerAdded = false;
|
|
}
|
|
|
|
registerWindow(aWindow) {
|
|
if (!this._observerAdded) {
|
|
this._observerAdded = true;
|
|
Services.obs.addObserver(this, "offline-cache-update-completed", true);
|
|
}
|
|
let manifestURI = this._getManifestURI(aWindow);
|
|
this._docManifestSet.add(manifestURI.spec);
|
|
}
|
|
|
|
handleEvent(event) {
|
|
if (event.type == "MozApplicationManifest") {
|
|
this.offlineAppRequested(event.originalTarget.defaultView);
|
|
}
|
|
}
|
|
|
|
_getManifestURI(aWindow) {
|
|
if (!aWindow.document.documentElement)
|
|
return null;
|
|
|
|
var attr = aWindow.document.documentElement.getAttribute("manifest");
|
|
if (!attr)
|
|
return null;
|
|
|
|
try {
|
|
return Services.io.newURI(attr, aWindow.document.characterSet,
|
|
Services.io.newURI(aWindow.location.href));
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
offlineAppRequested(aContentWindow) {
|
|
this.registerWindow(aContentWindow);
|
|
if (!Services.prefs.getBoolPref("browser.offline-apps.notify")) {
|
|
return;
|
|
}
|
|
|
|
let currentURI = aContentWindow.document.documentURIObject;
|
|
// don't bother showing UI if the user has already made a decision
|
|
if (Services.perms.testExactPermission(currentURI, "offline-app") != Services.perms.UNKNOWN_ACTION)
|
|
return;
|
|
|
|
try {
|
|
if (Services.prefs.getBoolPref("offline-apps.allow_by_default")) {
|
|
// all pages can use offline capabilities, no need to ask the user
|
|
return;
|
|
}
|
|
} catch (e) {
|
|
// this pref isn't set by default, ignore failures
|
|
}
|
|
let docId = ++this._docId;
|
|
this._docIdMap.set(docId, Cu.getWeakReference(aContentWindow.document));
|
|
this.mm.sendAsyncMessage("OfflineApps:RequestPermission", {
|
|
uri: currentURI.spec,
|
|
docId,
|
|
});
|
|
}
|
|
|
|
_startFetching(aDocument) {
|
|
if (!aDocument.documentElement)
|
|
return;
|
|
|
|
let manifestURI = this._getManifestURI(aDocument.defaultView);
|
|
if (!manifestURI)
|
|
return;
|
|
|
|
var updateService = Cc["@mozilla.org/offlinecacheupdate-service;1"].
|
|
getService(Ci.nsIOfflineCacheUpdateService);
|
|
updateService.scheduleUpdate(manifestURI, aDocument.documentURIObject,
|
|
aDocument.nodePrincipal, aDocument.defaultView);
|
|
}
|
|
|
|
receiveMessage(aMessage) {
|
|
if (aMessage.name == "OfflineApps:StartFetching") {
|
|
let doc = this._docIdMap.get(aMessage.data.docId);
|
|
doc = doc && doc.get();
|
|
if (doc) {
|
|
this._startFetching(doc);
|
|
}
|
|
this._docIdMap.delete(aMessage.data.docId);
|
|
}
|
|
}
|
|
|
|
observe(aSubject, aTopic, aState) {
|
|
if (aTopic == "offline-cache-update-completed") {
|
|
let cacheUpdate = aSubject.QueryInterface(Ci.nsIOfflineCacheUpdate);
|
|
let uri = cacheUpdate.manifestURI;
|
|
if (uri && this._docManifestSet.has(uri.spec)) {
|
|
this.mm.sendAsyncMessage("OfflineApps:CheckUsage", {uri: uri.spec});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
OfflineAppsChild.prototype.QueryInterface =
|
|
ChromeUtils.generateQI([Ci.nsIObserver,
|
|
Ci.nsISupportsWeakReference]);
|