Backed out changeset 434a86b48ee0 (bug 1129567) because it wasn't meant to land on trunk.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 05 Feb 2015 10:39:12 -0500
changeset 227661 7a3357ffc0e5aa966f34e4b715697975322caa9f
parent 227660 434a86b48ee0068f71702af7d513b4424ffb361e
child 227662 d0d66a5cad388d510a0803534eaf4334c258b6da
push id11177
push userryanvm@gmail.com
push dateThu, 05 Feb 2015 15:39:16 +0000
treeherderfx-team@7a3357ffc0e5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1129567
milestone38.0a1
backs out434a86b48ee0068f71702af7d513b4424ffb361e
Backed out changeset 434a86b48ee0 (bug 1129567) because it wasn't meant to land on trunk.
addon-sdk/source/lib/sdk/page-mod.js
--- a/addon-sdk/source/lib/sdk/page-mod.js
+++ b/addon-sdk/source/lib/sdk/page-mod.js
@@ -9,21 +9,20 @@ module.metadata = {
 
 const observers = require('./system/events');
 const { contract: loaderContract } = require('./content/loader');
 const { contract } = require('./util/contract');
 const { getAttachEventType, WorkerHost } = require('./content/utils');
 const { Class } = require('./core/heritage');
 const { Disposable } = require('./core/disposable');
 const { WeakReference } = require('./core/reference');
-const { Worker } = require('./deprecated/sync-worker');
+const { Worker } = require('./content/worker');
 const { EventTarget } = require('./event/target');
 const { on, emit, once, setListeners } = require('./event/core');
 const { on: domOn, removeListener: domOff } = require('./dom/events');
-const { pipe } = require('./event/utils');
 const { isRegExp, isUndefined } = require('./lang/type');
 const { merge } = require('./util/object');
 const { windowIterator } = require('./deprecated/window-utils');
 const { isBrowser, getFrames } = require('./window/utils');
 const { getTabs, getTabContentWindow, getTabForContentWindow,
         getURI: getTabURI } = require('./tabs/utils');
 const { ignoreWindow } = require('./private-browsing/utils');
 const { Style } = require("./stylesheet/style");
@@ -109,17 +108,16 @@ const modContract = contract(merge({}, l
  * PageMod constructor (exported below).
  * @constructor
  */
 const PageMod = Class({
   implements: [
     modContract.properties(modelFor),
     EventTarget,
     Disposable,
-    WeakReference
   ],
   extends: WorkerHost(workerFor),
   setup: function PageMod(options) {
     let mod = this;
     let model = modContract(options);
     models.set(this, model);
 
     // Set listeners on {PageMod} itself, not the underlying worker,
@@ -186,16 +184,20 @@ function onContentWindow({ subject: docu
       onContent(pagemod, window);
   }
 }
 
 function applyOnExistingDocuments (mod) {
   getTabs().forEach(tab => {
     // Fake a newly created document
     let window = getTabContentWindow(tab);
+    // on startup with e10s, contentWindow might not exist yet,
+    // in which case we will get notified by "document-element-inserted".
+    if (!window || !window.frames)
+      return;
     let uri = getTabURI(tab);
     if (has(mod.attachTo, "top") && modMatchesURI(mod, uri))
       onContent(mod, window);
     if (has(mod.attachTo, "frame"))
       getFrames(window).
         filter(iframe => modMatchesURI(mod, iframe.location.href)).
         forEach(frame => onContent(mod, frame));
   });
@@ -208,21 +210,25 @@ function createWorker (mod, window) {
     contentScriptFile: mod.contentScriptFile,
     contentScriptOptions: mod.contentScriptOptions,
     // Bug 980468: Syntax errors from scripts can happen before the worker
     // can set up an error handler. They are per-mod rather than per-worker
     // so are best handled at the mod level.
     onError: (e) => emit(mod, 'error', e)
   });
   workers.set(mod, worker);
-  pipe(worker, mod);
-  emit(mod, 'attach', worker);
-  once(worker, 'detach', function detach() {
-    worker.destroy();
-  });
+  worker.on('*', (event, ...args) => {
+    // worker's "attach" event passes a window as the argument
+    // page-mod's "attach" event needs a worker
+    if (event === 'attach')
+      emit(mod, event, worker)
+    else
+      emit(mod, event, ...args);
+  })
+  once(worker, 'detach', () => worker.destroy());
 }
 
 function onContent (mod, window) {
   // not registered yet
   if (!pagemods.has(mod))
     return;
 
   let isTopDocument = window.top === window;
@@ -251,16 +257,30 @@ function onContent (mod, window) {
   }
 
   let eventName = getAttachEventType(mod) || 'load';
   domOn(window, eventName, function onReady (e) {
     if (e.target.defaultView !== window)
       return;
     domOff(window, eventName, onReady, true);
     createWorker(mod, window);
+
+    // Attaching is asynchronous so if the document is already loaded we will
+    // miss the pageshow event so send a synthetic one.
+    if (window.document.readyState == "complete") {
+      mod.on('attach', worker => {
+        try {
+          worker.send('pageshow');
+          emit(worker, 'pageshow');
+        }
+        catch (e) {
+          // This can fail if an earlier attach listener destroyed the worker
+        }
+      });
+    }
   }, true);
 }
 
 function isMatchingAttachState (mod, window) {
   let state = window.document.readyState;
   return 'start' === mod.contentScriptWhen ||
       // Is `load` event already dispatched?
       'complete' === state ||