/* globals browser, console, XMLHttpRequest, Image, document, setTimeout, navigator */
/* globals loadSelector, analytics, communication, catcher, makeUuid */
window.main = (function () {
  let exports = {};

  const pasteSymbol = (window.navigator.platform.match(/Mac/i)) ? "\u2318" : "Ctrl";
  const { sendEvent } = analytics;

  let manifest = browser.runtime.getManifest();
  let backend;

  exports.setBackend = function (newBackend) {
    backend = newBackend;
    backend = backend.replace(/\/*$/, "");
  };

  exports.getBackend = function () {
    return backend;
  };

  for (let permission of manifest.permissions) {
    if (permission.search(/^https?:\/\//i) != -1) {
      exports.setBackend(permission);
      break;
    }
  }

  browser.browserAction.onClicked.addListener(function(tab) {
    if(tab.url.match(/about:(newtab|blank)/i)) {
      sendEvent("goto-myshots", "about-newtab");
      browser.tabs.update({url: backend + "/shots"});
    } else {
      sendEvent("start-shot", "toolbar-pageshot-button");
      catcher.watchPromise(loadSelector());
    }
  });

  browser.contextMenus.create({
    id: "create-pageshot",
    title: "Create Page Shot",
    contexts: ["page"]
  }, () => {
    // Note: unlike most browser.* functions this one does not return a promise
    if (browser.runtime.lastError) {
      catcher.unhandled(new Error(browser.runtime.lastError.message));
    }
  });

  browser.contextMenus.onClicked.addListener(catcher.watchFunction((info, tab) => {
    if (! tab) {
      // Not in a page/tab context, ignore
      return;
    }
    sendEvent("start-shot", "context-menu");
    catcher.watchPromise(loadSelector());
  }));


  communication.register("sendEvent", (...args) => {
    catcher.watchPromise(sendEvent(...args));
    // We don't wait for it to complete:
    return null;
  });

  communication.register("openMyShots", () => {
    browser.tabs.create({url: backend + "/shots"});
  });

  communication.register("openShot", ({url, copied}) => {
    if (copied) {
      const id = makeUuid();
      browser.notifications.create(id, {
        type: "basic",
        iconUrl: "../icons/clipboard-32.png",
        title: "Link Copied",
        message: "The link to your shot has been copied to the clipboard. Press "
        + pasteSymbol + "-V to paste."
      });
    }
  });

  return exports;
})();

@@ -785,17 +785,30 @@
 ner(
-f
+catcher.watchF
 unction(
 tab)
@@ -803,20 +803,24 @@
 unction(
+(
 tab)
+ =%3E
  %7B%0A    i
@@ -820,16 +820,17 @@
 %7B%0A    if
+ 
 (tab.url
@@ -911,32 +911,53 @@
 newtab%22);%0A      
+catcher.watchPromise(
 browser.tabs.upd
@@ -982,24 +982,25 @@
 + %22/shots%22%7D)
+)
 ;%0A    %7D else
@@ -1106,32 +1106,33 @@
 r());%0A    %7D%0A  %7D)
+)
 ;%0A%0A  browser.con
@@ -1917,24 +1917,31 @@
 () =%3E %7B%0A    
+return 
 browser.tabs
@@ -2094,16 +2094,23 @@
 ;%0A      
+return 
 browser.

Add watchFunction to the onClicked event handler Return or catch some browser.* promise-returning functions that were not being watched before