Bug 1472491: Part 5l - Add OfflineAppsChild actor. r=felipe draft
authorKris Maglione <maglione.k@gmail.com>
Sun, 29 Jul 2018 21:17:41 -0700
changeset 828447 5b1873a25ff537ef660f61f43e8888a2645a1214
parent 828446 a99faebb7fad33fc6820a50575e49aced22b7320
child 828448 3ceb1eaaa69c249da3f2e82befe96db77156a7c1
push id118680
push usermaglione.k@gmail.com
push dateFri, 10 Aug 2018 23:04:22 +0000
reviewersfelipe
bugs1472491
milestone63.0a1
Bug 1472491: Part 5l - Add OfflineAppsChild actor. r=felipe MozReview-Commit-ID: Jo8Uqifw7sm
browser/actors/OfflineAppsChild.jsm
browser/actors/moz.build
browser/base/content/content.js
browser/components/nsBrowserGlue.js
toolkit/content/browser-content.js
copy from browser/base/content/content.js
copy to browser/actors/OfflineAppsChild.jsm
--- a/browser/base/content/content.js
+++ b/browser/actors/OfflineAppsChild.jsm
@@ -1,154 +1,70 @@
+/* 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/. */
 
-/* This content script should work in any browser or iframe and should not
- * depend on the frame being contained in tabbrowser. */
-
-/* eslint-env mozilla/frame-script */
-/* eslint no-unused-vars: ["error", {args: "none"}] */
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-// TabChildGlobal
-var global = this;
+var EXPORTED_SYMBOLS = ["OfflineAppsChild"];
 
-XPCOMUtils.defineLazyModuleGetters(this, {
-  ContentLinkHandler: "resource:///modules/ContentLinkHandler.jsm",
-  ContentMetaHandler: "resource:///modules/ContentMetaHandler.jsm",
-  ContentWebRTC: "resource:///modules/ContentWebRTC.jsm",
-  LoginFormFactory: "resource://gre/modules/LoginManagerContent.jsm",
-  InsecurePasswordUtils: "resource://gre/modules/InsecurePasswordUtils.jsm",
-  FormSubmitObserver: "resource:///modules/FormSubmitObserver.jsm",
-  PageMetadata: "resource://gre/modules/PageMetadata.jsm",
-  ContextMenuChild: "resource:///modules/ContextMenuChild.jsm",
-});
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "LoginManagerContent", () => {
-  let tmp = {};
-  ChromeUtils.import("resource://gre/modules/LoginManagerContent.jsm", tmp);
-  tmp.LoginManagerContent.setupEventListeners(global);
-  return tmp.LoginManagerContent;
-});
-
-XPCOMUtils.defineLazyProxy(this, "formSubmitObserver", () => {
-  return new FormSubmitObserver(content, this);
-}, {
-  // stub QI
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIFormSubmitObserver, Ci.nsISupportsWeakReference])
-});
-
-Services.obs.addObserver(formSubmitObserver, "invalidformsubmit", true);
+class OfflineAppsChild extends ActorChild {
+  constructor(mm) {
+    super(mm);
 
-// NOTE: Much of this logic is duplicated in BrowserCLH.js for Android.
-addMessageListener("RemoteLogins:fillForm", function(message) {
-  // intercept if ContextMenu.jsm had sent a plain object for remote targets
-  message.objects.inputElement = ContextMenuChild.getTarget(global, message, "inputElement");
-  LoginManagerContent.receiveMessage(message, content);
-});
-addEventListener("DOMFormHasPassword", function(event) {
-  LoginManagerContent.onDOMFormHasPassword(event, content);
-  let formLike = LoginFormFactory.createFromForm(event.originalTarget);
-  InsecurePasswordUtils.reportInsecurePasswords(formLike);
-});
-addEventListener("DOMInputPasswordAdded", function(event) {
-  LoginManagerContent.onDOMInputPasswordAdded(event, content);
-  let formLike = LoginFormFactory.createFromField(event.originalTarget);
-  InsecurePasswordUtils.reportInsecurePasswords(formLike);
-});
-addEventListener("DOMAutoComplete", function(event) {
-  LoginManagerContent.onUsernameInput(event);
-});
-
-new ContentLinkHandler(this);
-ContentMetaHandler.init(this);
-
-// This is a temporary hack to prevent regressions (bug 1471327).
-void content;
-
-addEventListener("DOMWindowFocus", function(event) {
-  sendAsyncMessage("DOMWindowFocus", {});
-}, false);
-
-// We use this shim so that ContentWebRTC.jsm will not be loaded until
-// it is actually needed.
-var ContentWebRTCShim = message => ContentWebRTC.receiveMessage(message);
+    this._docId = 0;
+    this._docIdMap = new Map();
 
-addMessageListener("rtcpeer:Allow", ContentWebRTCShim);
-addMessageListener("rtcpeer:Deny", ContentWebRTCShim);
-addMessageListener("webrtc:Allow", ContentWebRTCShim);
-addMessageListener("webrtc:Deny", ContentWebRTCShim);
-addMessageListener("webrtc:StopSharing", ContentWebRTCShim);
+    this._docManifestSet = new Set();
 
-var PageMetadataMessenger = {
-  init() {
-    addMessageListener("PageMetadata:GetPageData", this);
-    addMessageListener("PageMetadata:GetMicroformats", this);
-    this.init = null;
-  },
-  receiveMessage(message) {
-    switch (message.name) {
-      case "PageMetadata:GetPageData": {
-        let target = ContextMenuChild.getTarget(global, message);
-        let result = PageMetadata.getData(content.document, target);
-        sendAsyncMessage("PageMetadata:PageDataResult", result);
-        break;
-      }
-      case "PageMetadata:GetMicroformats": {
-        let target = ContextMenuChild.getTarget(global, message);
-        let result = PageMetadata.getMicroformats(content.document, target);
-        sendAsyncMessage("PageMetadata:MicroformatsResult", result);
-        break;
-      }
-    }
+    this._observerAdded = false;
   }
-};
-PageMetadataMessenger.init();
 
-let OfflineApps = {
-  _docId: 0,
-  _docIdMap: new Map(),
-
-  _docManifestSet: new Set(),
-
-  _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") {
+      let doc = event.target;
+      let info = {
+        uri: doc.documentURI,
+        characterSet: doc.characterSet,
+        manifest: doc.documentElement.getAttribute("manifest"),
+        principal: doc.nodePrincipal,
+      };
+      this.mm.sendAsyncMessage("MozApplicationManifest", info);
+
       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;
@@ -161,54 +77,53 @@ let OfflineApps = {
         // 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));
-    sendAsyncMessage("OfflineApps:RequestPermission", {
+    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)) {
-        sendAsyncMessage("OfflineApps:CheckUsage", {uri: uri.spec});
+        this.mm.sendAsyncMessage("OfflineApps:CheckUsage", {uri: uri.spec});
       }
     }
-  },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver,
-                                          Ci.nsISupportsWeakReference]),
-};
+  }
+}
 
-addEventListener("MozApplicationManifest", OfflineApps, false);
-addMessageListener("OfflineApps:StartFetching", OfflineApps);
+OfflineAppsChild.prototype.QueryInterface =
+  ChromeUtils.generateQI([Ci.nsIObserver,
+                          Ci.nsISupportsWeakReference]);
--- a/browser/actors/moz.build
+++ b/browser/actors/moz.build
@@ -20,12 +20,13 @@ FINAL_TARGET_FILES.actors += [
     'AboutReaderChild.jsm',
     'BlockedSiteChild.jsm',
     'BrowserTabChild.jsm',
     'ClickHandlerChild.jsm',
     'ContentSearchChild.jsm',
     'ContextMenuChild.jsm',
     'LightWeightThemeInstallChild.jsm',
     'NetErrorChild.jsm',
+    'OfflineAppsChild.jsm',
     'PageInfoChild.jsm',
     'PageStyleChild.jsm',
     'PluginChild.jsm',
 ]
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -101,114 +101,8 @@ var PageMetadataMessenger = {
         let result = PageMetadata.getMicroformats(content.document, target);
         sendAsyncMessage("PageMetadata:MicroformatsResult", result);
         break;
       }
     }
   }
 };
 PageMetadataMessenger.init();
-
-let OfflineApps = {
-  _docId: 0,
-  _docIdMap: new Map(),
-
-  _docManifestSet: new Set(),
-
-  _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));
-    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)) {
-        sendAsyncMessage("OfflineApps:CheckUsage", {uri: uri.spec});
-      }
-    }
-  },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver,
-                                          Ci.nsISupportsWeakReference]),
-};
-
-addEventListener("MozApplicationManifest", OfflineApps, false);
-addMessageListener("OfflineApps:StartFetching", OfflineApps);
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -127,16 +127,28 @@ let ACTORS = {
       allFrames: true,
       messages: [
         "Browser:CaptivePortalFreed",
         "CertErrorDetails",
       ],
     },
   },
 
+  OfflineApps: {
+    child: {
+      module: "resource:///actors/OfflineAppsChild.jsm",
+      events: {
+        "MozApplicationManifest": {},
+      },
+      messages: [
+        "OfflineApps:StartFetching",
+      ],
+    },
+  },
+
   PageInfo: {
     child: {
       module: "resource:///actors/PageInfoChild.jsm",
       messages: ["PageInfo:getData"],
     },
   },
 
   PageStyle: {
--- a/toolkit/content/browser-content.js
+++ b/toolkit/content/browser-content.js
@@ -323,27 +323,16 @@ addMessageListener("Browser:PurgeSession
 
   if (purge > 0) {
     sessionHistory.legacySHistory.PurgeHistory(purge);
   }
 });
 
 addMessageListener("ViewSource:GetSelection", SelectionSourceContent);
 
-addEventListener("MozApplicationManifest", function(e) {
-  let doc = e.target;
-  let info = {
-    uri: doc.documentURI,
-    characterSet: doc.characterSet,
-    manifest: doc.documentElement.getAttribute("manifest"),
-    principal: doc.nodePrincipal,
-  };
-  sendAsyncMessage("MozApplicationManifest", info);
-}, false);
-
 let AutoComplete = {
   _connected: false,
 
   init() {
     addEventListener("unload", this, {once: true});
     addEventListener("DOMContentLoaded", this, {once: true});
     // WebExtension browserAction is preloaded and does not receive DCL, wait
     // on pageshow so we can hookup the formfill controller.