Bug 1365562 - Ensure that SessionStore is initialized before any interaction via WebExtension APIs, r?mixedpuppy draft
authorBob Silverberg <bsilverberg@mozilla.com>
Wed, 24 May 2017 09:26:16 -0400
changeset 584538 6bd1b43173246105a35641488d6bbde33f53ba2a
parent 584413 e8da7192201e5786614ec49d557e64dffd114ff2
child 630416 55d2713ddd844a7a6e64cb6b56e89538c18b0ffe
push id60778
push userbmo:bob.silverberg@gmail.com
push dateThu, 25 May 2017 16:58:37 +0000
reviewersmixedpuppy
bugs1365562
milestone55.0a1
Bug 1365562 - Ensure that SessionStore is initialized before any interaction via WebExtension APIs, r?mixedpuppy Awaiting the resolution of SessionStore.promiseInitialized as the first step in each API method that needs to interact with SessionStore. As I needed to await a promise, took the opportunity to migrate the entire file to async/await. MozReview-Commit-ID: 3ovavDHimhj
browser/components/extensions/ext-sessions.js
--- a/browser/components/extensions/ext-sessions.js
+++ b/browser/components/extensions/ext-sessions.js
@@ -1,13 +1,14 @@
 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set sts=2 sw=2 et tw=80: */
 "use strict";
 
 var {
+  ExtensionError,
   promiseObserved,
 } = ExtensionUtils;
 
 XPCOMUtils.defineLazyModuleGetter(this, "SessionStore",
                                   "resource:///modules/sessionstore/SessionStore.jsm");
 
 const SS_ON_CLOSED_OBJECTS_CHANGED = "sessionstore-closed-objects-changed";
 
@@ -32,73 +33,74 @@ function getRecentlyClosed(maxResults, e
     }
   }
 
   // Sort windows and tabs
   recentlyClosed.sort((a, b) => b.lastModified - a.lastModified);
   return recentlyClosed.slice(0, maxResults);
 }
 
-function createSession(restored, extension, sessionId) {
+async function createSession(restored, extension, sessionId) {
   if (!restored) {
-    return Promise.reject({message: `Could not restore object using sessionId ${sessionId}.`});
+    throw new ExtensionError(`Could not restore object using sessionId ${sessionId}.`);
   }
   let sessionObj = {lastModified: Date.now()};
   if (restored instanceof Ci.nsIDOMChromeWindow) {
-    return promiseObserved("sessionstore-single-window-restored", subject => subject == restored).then(() => {
-      sessionObj.window = extension.windowManager.convert(restored, {populate: true});
-      return Promise.resolve(sessionObj);
-    });
+    await promiseObserved("sessionstore-single-window-restored", subject => subject == restored);
+    sessionObj.window = extension.windowManager.convert(restored, {populate: true});
+    return sessionObj;
   }
   sessionObj.tab = extension.tabManager.convert(restored);
-  return Promise.resolve(sessionObj);
+  return sessionObj;
 }
 
 this.sessions = class extends ExtensionAPI {
   getAPI(context) {
     let {extension} = context;
     return {
       sessions: {
-        getRecentlyClosed: function(filter) {
+        async getRecentlyClosed(filter) {
+          await SessionStore.promiseInitialized;
           let maxResults = filter.maxResults == undefined ? this.MAX_SESSION_RESULTS : filter.maxResults;
-          return Promise.resolve(getRecentlyClosed(maxResults, extension));
+          return getRecentlyClosed(maxResults, extension);
         },
 
-        forgetClosedTab: function(windowId, sessionId) {
+        async forgetClosedTab(windowId, sessionId) {
+          await SessionStore.promiseInitialized;
           let window = context.extension.windowManager.get(windowId).window;
           let closedTabData = SessionStore.getClosedTabData(window, false);
 
           let closedTabIndex = closedTabData.findIndex((closedTab) => {
             return closedTab.closedId === parseInt(sessionId, 10);
           });
 
           if (closedTabIndex < 0) {
-            return Promise.reject({message: `Could not find closed tab using sessionId ${sessionId}.`});
+            throw new ExtensionError(`Could not find closed tab using sessionId ${sessionId}.`);
           }
 
           SessionStore.forgetClosedTab(window, closedTabIndex);
-          return Promise.resolve();
         },
 
-        forgetClosedWindow: function(sessionId) {
+        async forgetClosedWindow(sessionId) {
+          await SessionStore.promiseInitialized;
           let closedWindowData = SessionStore.getClosedWindowData(false);
 
           let closedWindowIndex = closedWindowData.findIndex((closedWindow) => {
             return closedWindow.closedId === parseInt(sessionId, 10);
           });
 
           if (closedWindowIndex < 0) {
-            return Promise.reject({message: `Could not find closed window using sessionId ${sessionId}.`});
+            throw new ExtensionError(`Could not find closed window using sessionId ${sessionId}.`);
           }
 
           SessionStore.forgetClosedWindow(closedWindowIndex);
-          return Promise.resolve();
         },
 
-        restore: function(sessionId) {
+        async restore(sessionId) {
+          await SessionStore.promiseInitialized;
           let session, closedId;
           if (sessionId) {
             closedId = sessionId;
             session = SessionStore.undoCloseById(closedId);
           } else if (SessionStore.lastClosedObjectType == "window") {
             // If the most recently closed object is a window, just undo closing the most recent window.
             session = SessionStore.undoCloseWindow(0);
           } else {