Bug 1498410 - Part 4 - Export comma-dangle refactoring as a separate commit to ease reviews; r=ianbicking
authorJared Hirsch <ohai@6a68.net>
Mon, 15 Oct 2018 20:10:29 +0000
changeset 489698 9ea94e903beb6a372923f1238d9828968774db67
parent 489697 3fab2169b6a001d1f8e03342c2866c88a7d1beb0
child 489699 62bc409457f364b9f6a29ce4968850fbeff5702b
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersianbicking
bugs1498410
milestone64.0a1
Bug 1498410 - Part 4 - Export comma-dangle refactoring as a separate commit to ease reviews; r=ianbicking MozReview-Commit-ID: 455LZbfCGfy Differential Revision: https://phabricator.services.mozilla.com/D8506
browser/extensions/screenshots/background/analytics.js
browser/extensions/screenshots/background/auth.js
browser/extensions/screenshots/background/deviceInfo.js
browser/extensions/screenshots/background/main.js
browser/extensions/screenshots/background/selectorLoader.js
browser/extensions/screenshots/background/senderror.js
browser/extensions/screenshots/background/startBackground.js
browser/extensions/screenshots/background/takeshot.js
browser/extensions/screenshots/build/selection.js
browser/extensions/screenshots/build/thumbnailGenerator.js
browser/extensions/screenshots/catcher.js
browser/extensions/screenshots/onboarding/slides.js
browser/extensions/screenshots/selector/shooter.js
browser/extensions/screenshots/selector/ui.js
browser/extensions/screenshots/selector/uicontrol.js
browser/extensions/screenshots/selector/util.js
--- a/browser/extensions/screenshots/background/analytics.js
+++ b/browser/extensions/screenshots/background/analytics.js
@@ -11,17 +11,17 @@ this.analytics = (function() {
   const EVENT_BATCH_DURATION = 1000; // ms for setTimeout
   let pendingEvents = [];
   let pendingTimings = [];
   let eventsTimeoutHandle, timingsTimeoutHandle;
   const fetchOptions = {
     method: "POST",
     mode: "cors",
     headers: { "content-type": "application/json" },
-    credentials: "include"
+    credentials: "include",
   };
 
   function flushEvents() {
     if (pendingEvents.length === 0) {
       return;
     }
 
     const eventsUrl = `${main.getBackend()}/event`;
@@ -58,17 +58,17 @@ this.analytics = (function() {
   function sendTiming(timingLabel, timingVar, timingValue) {
     // sendTiming is only called in response to sendEvent, so no need to check
     // the telemetry pref again here.
     const timingCategory = "addon";
     pendingTimings.push({
       timingCategory,
       timingLabel,
       timingVar,
-      timingValue
+      timingValue,
     });
     if (!timingsTimeoutHandle) {
       timingsTimeoutHandle = setTimeout(() => {
         timingsTimeoutHandle = null;
         flushTimings();
       }, EVENT_BATCH_DURATION);
     }
   }
@@ -110,17 +110,17 @@ this.analytics = (function() {
     for (const [gaField, value] of Object.entries(abTests)) {
       options[gaField] = value;
     }
     pendingEvents.push({
       eventTime: Date.now(),
       event: eventCategory,
       action,
       label,
-      options
+      options,
     });
     if (!eventsTimeoutHandle) {
       eventsTimeoutHandle = setTimeout(() => {
         eventsTimeoutHandle = null;
         flushEvents();
       }, EVENT_BATCH_DURATION);
     }
     // This function used to return a Promise that was not used at any of the
@@ -168,121 +168,121 @@ this.analytics = (function() {
   // is deleted.
   const rules = [{
     name: "page-action",
     start: { action: "start-shot", label: "toolbar-button" },
     end: { action: "internal", label: "unhide-preselection-frame" },
     cancel: [
       { action: "cancel-shot" },
       { action: "internal", label: "document-hidden" },
-      { action: "internal", label: "unhide-onboarding-frame" }
-    ]
+      { action: "internal", label: "unhide-onboarding-frame" },
+    ],
   }, {
     name: "context-menu",
     start: { action: "start-shot", label: "context-menu" },
     end: { action: "internal", label: "unhide-preselection-frame" },
     cancel: [
       { action: "cancel-shot" },
       { action: "internal", label: "document-hidden" },
-      { action: "internal", label: "unhide-onboarding-frame" }
-    ]
+      { action: "internal", label: "unhide-onboarding-frame" },
+    ],
   }, {
     name: "page-action-onboarding",
     start: { action: "start-shot", label: "toolbar-button" },
     end: { action: "internal", label: "unhide-onboarding-frame" },
     cancel: [
       { action: "cancel-shot" },
       { action: "internal", label: "document-hidden" },
-      { action: "internal", label: "unhide-preselection-frame" }
-    ]
+      { action: "internal", label: "unhide-preselection-frame" },
+    ],
   }, {
     name: "context-menu-onboarding",
     start: { action: "start-shot", label: "context-menu" },
     end: { action: "internal", label: "unhide-onboarding-frame" },
     cancel: [
       { action: "cancel-shot" },
       { action: "internal", label: "document-hidden" },
-      { action: "internal", label: "unhide-preselection-frame" }
-    ]
+      { action: "internal", label: "unhide-preselection-frame" },
+    ],
   }, {
     name: "capture-full-page",
     start: { action: "capture-full-page" },
     end: { action: "internal", label: "unhide-preview-frame" },
     cancel: [
       { action: "cancel-shot" },
-      { action: "internal", label: "document-hidden" }
-    ]
+      { action: "internal", label: "document-hidden" },
+    ],
   }, {
     name: "capture-visible",
     start: { action: "capture-visible" },
     end: { action: "internal", label: "unhide-preview-frame" },
     cancel: [
       { action: "cancel-shot" },
-      { action: "internal", label: "document-hidden" }
-    ]
+      { action: "internal", label: "document-hidden" },
+    ],
   }, {
     name: "make-selection",
     start: { action: "make-selection" },
     end: { action: "internal", label: "unhide-selection-frame" },
     cancel: [
       { action: "cancel-shot" },
-      { action: "internal", label: "document-hidden" }
-    ]
+      { action: "internal", label: "document-hidden" },
+    ],
   }, {
     name: "save-shot",
     start: { action: "save-shot" },
     end: { action: "internal", label: "open-shot-tab" },
-    cancel: [{ action: "cancel-shot" }, { action: "upload-failed" }]
+    cancel: [{ action: "cancel-shot" }, { action: "upload-failed" }],
   }, {
     name: "save-visible",
     start: { action: "save-visible" },
     end: { action: "internal", label: "open-shot-tab" },
-    cancel: [{ action: "cancel-shot" }, { action: "upload-failed" }]
+    cancel: [{ action: "cancel-shot" }, { action: "upload-failed" }],
   }, {
     name: "save-full-page",
     start: { action: "save-full-page" },
     end: { action: "internal", label: "open-shot-tab" },
-    cancel: [{ action: "cancel-shot" }, { action: "upload-failed" }]
+    cancel: [{ action: "cancel-shot" }, { action: "upload-failed" }],
   }, {
     name: "save-full-page-truncated",
     start: { action: "save-full-page-truncated" },
     end: { action: "internal", label: "open-shot-tab" },
-    cancel: [{ action: "cancel-shot" }, { action: "upload-failed" }]
+    cancel: [{ action: "cancel-shot" }, { action: "upload-failed" }],
   }, {
     name: "download-shot",
     start: { action: "download-shot" },
     end: { action: "internal", label: "deactivate" },
     cancel: [
       { action: "cancel-shot" },
-      { action: "internal", label: "document-hidden" }
-    ]
+      { action: "internal", label: "document-hidden" },
+    ],
   }, {
     name: "download-full-page",
     start: { action: "download-full-page" },
     end: { action: "internal", label: "deactivate" },
     cancel: [
       { action: "cancel-shot" },
-      { action: "internal", label: "document-hidden" }
-    ]
+      { action: "internal", label: "document-hidden" },
+    ],
   }, {
     name: "download-full-page-truncated",
     start: { action: "download-full-page-truncated" },
     end: { action: "internal", label: "deactivate" },
     cancel: [
       { action: "cancel-shot" },
-      { action: "internal", label: "document-hidden" }
-    ]
+      { action: "internal", label: "document-hidden" },
+    ],
   }, {
     name: "download-visible",
     start: { action: "download-visible" },
     end: { action: "internal", label: "deactivate" },
     cancel: [
       { action: "cancel-shot" },
-      { action: "internal", label: "document-hidden" }
-    ]
+      { action: "internal", label: "document-hidden" },
+    ],
   }];
 
   // Match a filter (action and optional label) against an action and label.
   function match(filter, action, label) {
     return filter.label ?
       filter.action === action && filter.label === label :
       filter.action === action;
   }
--- a/browser/extensions/screenshots/background/auth.js
+++ b/browser/extensions/screenshots/background/auth.js
@@ -35,17 +35,17 @@ this.auth = (function() {
   exports.getDeviceId = function() {
     return registrationInfo && registrationInfo.deviceId;
   };
 
   function generateRegistrationInfo() {
     const info = {
       deviceId: `anon${makeUuid()}`,
       secret: makeUuid(),
-      registered: false
+      registered: false,
     };
     return info;
   }
 
   function register() {
     return new Promise((resolve, reject) => {
       const registerUrl = main.getBackend() + "/api/register";
       // TODO: replace xhr with Fetch #2261
@@ -71,17 +71,17 @@ this.auth = (function() {
         analytics.sendEvent("register-failed", "connection-error");
         const exc = new Error("Error contacting server");
         exc.popupMessage = "LOGIN_CONNECTION_ERROR";
         reject(exc);
       });
       req.send(JSON.stringify({
         deviceId: registrationInfo.deviceId,
         secret: registrationInfo.secret,
-        deviceInfo: JSON.stringify(deviceInfo())
+        deviceInfo: JSON.stringify(deviceInfo()),
       }));
     });
   }
 
   function login(options) {
     const { ownershipCheck, noRegister } = options || {};
     return new Promise((resolve, reject) => {
       return fetchStoredInfo.then(() => {
--- a/browser/extensions/screenshots/background/deviceInfo.js
+++ b/browser/extensions/screenshots/background/deviceInfo.js
@@ -22,13 +22,13 @@ this.deviceInfo = (function() {
       platform: platformInfo.os,
       architecture: platformInfo.arch,
       version: firefoxVersion || chromeVersion,
       // These don't seem to apply to Chrome:
       // build: system.build,
       // platformVersion: system.platformVersion,
       userAgent: navigator.userAgent,
       appVendor: appName,
-      appName
+      appName,
     };
   };
 
 })();
--- a/browser/extensions/screenshots/background/main.js
+++ b/browser/extensions/screenshots/background/main.js
@@ -127,17 +127,17 @@ this.main = (function() {
       }
       if (!urlEnabled(tab.url)) {
         if (!onboarded) {
           sendEvent("goto-onboarding", "selection-button", {incognito: tab.incognito});
           forceOnboarding();
           return;
         }
         senderror.showError({
-          popupMessage: "UNSHOOTABLE_PAGE"
+          popupMessage: "UNSHOOTABLE_PAGE",
         });
         return;
       }
       // No need to catch() here because of watchPromise().
       // eslint-disable-next-line promise/catch-or-return
       toggleSelector(tab)
         .then(() => sendEvent("start-shot", "context-menu", {incognito: tab.incognito}));
     }));
@@ -195,17 +195,17 @@ this.main = (function() {
 
   communication.register("openShot", (sender, {url, copied}) => {
     if (copied) {
       const id = makeUuid();
       return browser.notifications.create(id, {
         type: "basic",
         iconUrl: "../icons/copied-notification.svg",
         title: browser.i18n.getMessage("notificationLinkCopiedTitle"),
-        message: browser.i18n.getMessage("notificationLinkCopiedDetails", pasteSymbol)
+        message: browser.i18n.getMessage("notificationLinkCopiedDetails", pasteSymbol),
       });
     }
     return null;
   });
 
   // This is used for truncated full page downloads and copy to clipboards.
   // Those longer operations need to display an animated spinner/loader, so
   // it's preferable to perform toDataURL() in the background.
@@ -229,17 +229,17 @@ this.main = (function() {
     return blobConverters.blobToArray(blob).then(buffer => {
       return browser.clipboard.setImageData(
         buffer, blob.type.split("/", 2)[1]).then(() => {
           catcher.watchPromise(incrementCount("copy"));
           return browser.notifications.create({
             type: "basic",
             iconUrl: "../icons/copied-notification.svg",
             title: browser.i18n.getMessage("notificationImageCopiedTitle"),
-            message: browser.i18n.getMessage("notificationImageCopiedDetails", pasteSymbol)
+            message: browser.i18n.getMessage("notificationImageCopiedDetails", pasteSymbol),
           });
         });
     });
   });
 
   communication.register("downloadShot", (sender, info) => {
     // 'data:' urls don't work directly, let's use a Blob
     // see http://stackoverflow.com/questions/40269862/save-data-uri-as-file-using-downloads-download-api
@@ -256,17 +256,17 @@ this.main = (function() {
       }
     });
     browser.downloads.onChanged.addListener(onChangedCallback);
     catcher.watchPromise(incrementCount("download"));
     return browser.windows.getLastFocused().then(windowInfo => {
       return browser.downloads.download({
         url,
         incognito: windowInfo.incognito,
-        filename: info.filename
+        filename: info.filename,
       }).catch((error) => {
         // We are not logging error message when user cancels download
         if (error && error.message && !error.message.includes("canceled")) {
           log.error(error.message);
         }
       }).then((id) => {
         downloadId = id;
       });
@@ -281,17 +281,17 @@ this.main = (function() {
     hasSeenOnboarding = Promise.resolve(true);
     catcher.watchPromise(browser.storage.local.set({hasSeenOnboarding: true}));
   });
 
   communication.register("abortStartShot", () => {
     // Note, we only show the error but don't report it, as we know that we can't
     // take shots of these pages:
     senderror.showError({
-      popupMessage: "UNSHOOTABLE_PAGE"
+      popupMessage: "UNSHOOTABLE_PAGE",
     });
   });
 
   // A Screenshots page wants us to start/force onboarding
   communication.register("requestOnboarding", (sender) => {
     return startSelectionWithOnboarding(sender.tab);
   });
 
--- a/browser/extensions/screenshots/background/selectorLoader.js
+++ b/browser/extensions/screenshots/background/selectorLoader.js
@@ -14,56 +14,56 @@ this.selectorLoader = (function() {
     "build/buildSettings.js",
     "log.js",
     "catcher.js",
     "assertIsTrusted.js",
     "assertIsBlankDocument.js",
     "blobConverters.js",
     "background/selectorLoader.js",
     "selector/callBackground.js",
-    "selector/util.js"
+    "selector/util.js",
   ];
 
   const selectorScripts = [
     "clipboard.js",
     "makeUuid.js",
     "build/selection.js",
     "build/shot.js",
     "randomString.js",
     "domainFromUrl.js",
     "build/inlineSelectionCss.js",
     "selector/documentMetadata.js",
     "selector/ui.js",
     "selector/shooter.js",
-    "selector/uicontrol.js"
+    "selector/uicontrol.js",
   ];
 
   // These are loaded on request (by the selector worker) to activate the onboarding:
   const onboardingScripts = [
     "build/onboardingCss.js",
     "build/onboardingHtml.js",
-    "onboarding/slides.js"
+    "onboarding/slides.js",
   ];
 
   exports.unloadIfLoaded = function(tabId) {
     return browser.tabs.executeScript(tabId, {
       code: "this.selectorLoader && this.selectorLoader.unloadModules()",
-      runAt: "document_start"
+      runAt: "document_start",
     }).then(result => {
       return result && result[0];
     });
   };
 
   exports.testIfLoaded = function(tabId) {
     if (loadingTabs.has(tabId)) {
       return true;
     }
     return browser.tabs.executeScript(tabId, {
       code: "!!this.selectorLoader",
-      runAt: "document_start"
+      runAt: "document_start",
     }).then(result => {
       return result && result[0];
     });
   };
 
   const loadingTabs = new Set();
 
   exports.loadModules = function(tabId, hasSeenOnboarding) {
@@ -95,31 +95,31 @@ this.selectorLoader = (function() {
         return browser.experiments.screenshots.getUpdateChannel().then((channel) => {
           return browser.tabs.get(tabId).then(tab => {
             const downloadOnly = !historyEnabled || uploadDisabled || channel === "esr" || tab.incognito;
             return browser.tabs.executeScript(tabId, {
               // Note: `window` here refers to a global accessible to content
               // scripts, but not the scripts in the underlying page. For more
               // details, see https://mdn.io/WebExtensions/Content_scripts#Content_script_environment
               code: `window.downloadOnly = ${downloadOnly}`,
-              runAt: "document_start"
+              runAt: "document_start",
             });
           });
         });
       });
     });
   }
 
   function executeModules(tabId, scripts) {
     let lastPromise = Promise.resolve(null);
     scripts.forEach((file) => {
       lastPromise = lastPromise.then(() => {
         return browser.tabs.executeScript(tabId, {
           file,
-          runAt: "document_start"
+          runAt: "document_start",
         }).catch((error) => {
           log.error("error in script:", file, error);
           error.scriptName = file;
           throw error;
         });
       });
     });
     return lastPromise.then(() => {
--- a/browser/extensions/screenshots/background/senderror.js
+++ b/browser/extensions/screenshots/background/senderror.js
@@ -8,52 +8,52 @@ this.senderror = (function() {
   const manifest = browser.runtime.getManifest();
 
   // Do not show an error more than every ERROR_TIME_LIMIT milliseconds:
   const ERROR_TIME_LIMIT = 3000;
 
   const messages = {
     REQUEST_ERROR: {
       title: browser.i18n.getMessage("requestErrorTitle"),
-      info: browser.i18n.getMessage("requestErrorDetails")
+      info: browser.i18n.getMessage("requestErrorDetails"),
     },
     CONNECTION_ERROR: {
       title: browser.i18n.getMessage("connectionErrorTitle"),
-      info: browser.i18n.getMessage("connectionErrorDetails")
+      info: browser.i18n.getMessage("connectionErrorDetails"),
     },
     LOGIN_ERROR: {
       title: browser.i18n.getMessage("requestErrorTitle"),
-      info: browser.i18n.getMessage("loginErrorDetails")
+      info: browser.i18n.getMessage("loginErrorDetails"),
     },
     LOGIN_CONNECTION_ERROR: {
       title: browser.i18n.getMessage("connectionErrorTitle"),
-      info: browser.i18n.getMessage("connectionErrorDetails")
+      info: browser.i18n.getMessage("connectionErrorDetails"),
     },
     UNSHOOTABLE_PAGE: {
       title: browser.i18n.getMessage("unshootablePageErrorTitle"),
-      info: browser.i18n.getMessage("unshootablePageErrorDetails")
+      info: browser.i18n.getMessage("unshootablePageErrorDetails"),
     },
     SHOT_PAGE: {
-      title: browser.i18n.getMessage("selfScreenshotErrorTitle")
+      title: browser.i18n.getMessage("selfScreenshotErrorTitle"),
     },
     MY_SHOTS: {
-      title: browser.i18n.getMessage("selfScreenshotErrorTitle")
+      title: browser.i18n.getMessage("selfScreenshotErrorTitle"),
     },
     EMPTY_SELECTION: {
-      title: browser.i18n.getMessage("emptySelectionErrorTitle")
+      title: browser.i18n.getMessage("emptySelectionErrorTitle"),
     },
     PRIVATE_WINDOW: {
       title: browser.i18n.getMessage("privateWindowErrorTitle"),
-      info: browser.i18n.getMessage("privateWindowErrorDetails")
+      info: browser.i18n.getMessage("privateWindowErrorDetails"),
     },
     generic: {
       title: browser.i18n.getMessage("genericErrorTitle"),
       info: browser.i18n.getMessage("genericErrorDetails"),
-      showMessage: true
-    }
+      showMessage: true,
+    },
   };
 
   communication.register("reportError", (sender, error) => {
     catcher.unhandled(error);
   });
 
   let lastErrorTime;
 
@@ -77,17 +77,17 @@ this.senderror = (function() {
         message = error.message;
       }
     }
     if (Date.now() - startBackground.startTime > 5 * 1000) {
       browser.notifications.create(id, {
         type: "basic",
         // FIXME: need iconUrl for an image, see #2239
         title,
-        message
+        message,
       });
     }
   };
 
   exports.reportError = function(e) {
     if (!analytics.isTelemetryEnabled()) {
       log.error("Telemetry disabled. Not sending critical error:", e);
       return;
@@ -118,17 +118,17 @@ this.senderror = (function() {
       }
     }
     rest.stack = exception.stack;
     Raven.captureException(exception, {
       logger: "addon",
       tags: {category: e.popupMessage},
       release: manifest.version,
       message: exception.message,
-      extra: rest
+      extra: rest,
     });
   };
 
   catcher.registerHandler((errorObj) => {
     if (!errorObj.noPopup) {
       exports.showError(errorObj);
     }
     if (!errorObj.noReport) {
--- a/browser/extensions/screenshots/background/startBackground.js
+++ b/browser/extensions/screenshots/background/startBackground.js
@@ -21,32 +21,32 @@ this.startBackground = (function() {
     "background/auth.js",
     "background/senderror.js",
     "build/raven.js",
     "build/shot.js",
     "build/thumbnailGenerator.js",
     "background/analytics.js",
     "background/deviceInfo.js",
     "background/takeshot.js",
-    "background/main.js"
+    "background/main.js",
   ];
 
   browser.pageAction.onClicked.addListener(tab => {
     loadIfNecessary().then(() => {
       main.onClicked(tab);
     }).catch(error => {
       console.error("Error loading Screenshots:", error);
     });
   });
 
   browser.contextMenus.create({
     id: "create-screenshot",
     title: browser.i18n.getMessage("contextMenuLabel"),
     contexts: ["page"],
-    documentUrlPatterns: ["<all_urls>"]
+    documentUrlPatterns: ["<all_urls>"],
   });
 
   browser.contextMenus.onClicked.addListener((info, tab) => {
     loadIfNecessary().then(() => {
       main.onClickedContextMenu(info, tab);
     }).catch((error) => {
       console.error("Error loading Screenshots:", error);
     });
--- a/browser/extensions/screenshots/background/takeshot.js
+++ b/browser/extensions/screenshots/background/takeshot.js
@@ -22,19 +22,19 @@ this.takeshot = (function() {
           createdDate: Date.now(),
           image: {
             url: buildSettings.uploadBinary ? "" : dataUrl,
             captureType,
             text: captureText,
             location: selectedPos,
             dimensions: {
               x: selectedPos.right - selectedPos.left,
-              y: selectedPos.bottom - selectedPos.top
-            }
-          }
+              y: selectedPos.bottom - selectedPos.top,
+            },
+          },
         });
       });
     }
     const shotAbTests = {};
     const abTests = auth.getAbTests();
     for (const testName of Object.keys(abTests)) {
       if (abTests[testName].shotField) {
         shotAbTests[testName] = abTests[testName].value;
@@ -89,17 +89,17 @@ this.takeshot = (function() {
     return screenshotPage(selectedPos, scroll);
   });
 
   function screenshotPage(pos, scroll) {
     pos = {
       top: pos.top - scroll.scrollY,
       left: pos.left - scroll.scrollX,
       bottom: pos.bottom - scroll.scrollY,
-      right: pos.right - scroll.scrollX
+      right: pos.right - scroll.scrollX,
     };
     pos.width = pos.right - pos.left;
     pos.height = pos.bottom - pos.top;
     return catcher.watchPromise(browser.tabs.captureVisibleTab(
       null,
       {format: "png"}
     ).then((dataUrl) => {
       const image = new Image();
@@ -172,17 +172,17 @@ this.takeshot = (function() {
         body = concatBuffers(body, enc.encode("\r\n").buffer);
       }
 
       let tail = `\r\n--${boundary}--`;
       tail = enc.encode(tail);
       body = concatBuffers(body, tail.buffer);
       return {
         "content-type": `multipart/form-data; boundary=${boundary}`,
-        body
+        body,
       };
     });
   }
 
   function uploadShot(shot, blob, thumbnail) {
     let headers;
     return auth.authHeaders().then((_headers) => {
       headers = _headers;
@@ -194,27 +194,27 @@ this.takeshot = (function() {
         return createMultipart(
           {shot: JSON.stringify(shot)},
 
           files
         );
       }
       return {
         "content-type": "application/json",
-        body: JSON.stringify(shot)
+        body: JSON.stringify(shot),
       };
 
     }).then((submission) => {
       headers["content-type"] = submission["content-type"];
       sendEvent("upload", "started", {eventValue: Math.floor(submission.body.length / 1000)});
       return fetch(shot.jsonUrl, {
         method: "PUT",
         mode: "cors",
         headers,
-        body: submission.body
+        body: submission.body,
       });
     }).then((resp) => {
       if (!resp.ok) {
         sendEvent("upload-failed", `status-${resp.status}`);
         const exc = new Error(`Response failed with status ${resp.status}`);
         exc.popupMessage = "REQUEST_ERROR";
         throw exc;
       } else {
--- a/browser/extensions/screenshots/build/selection.js
+++ b/browser/extensions/screenshots/build/selection.js
@@ -57,17 +57,17 @@ this.selection = (function () {let expor
     return Math.abs(this.y2 - this.y1);
   }
 
   rect() {
     return {
       top: Math.floor(this.top),
       left: Math.floor(this.left),
       bottom: Math.floor(this.bottom),
-      right: Math.floor(this.right)
+      right: Math.floor(this.right),
     };
   }
 
   union(other) {
     return new Selection(
       Math.min(this.left, other.left),
       Math.min(this.top, other.top),
       Math.max(this.right, other.right),
@@ -89,17 +89,17 @@ this.selection = (function () {let expor
     return new Selection(this.x1, this.y1, this.x2, this.y2);
   }
 
   toJSON() {
     return {
       left: this.left,
       right: this.right,
       top: this.top,
-      bottom: this.bottom
+      bottom: this.bottom,
     };
   }
 
   static getBoundingClientRect(el) {
     if (!el.getBoundingClientRect) {
       // Typically the <html> element or somesuch
       return null;
     }
--- a/browser/extensions/screenshots/build/thumbnailGenerator.js
+++ b/browser/extensions/screenshots/build/thumbnailGenerator.js
@@ -43,17 +43,17 @@ function getThumbnailDimensions(imageWid
     thumbnailImageHeight = Math.min(scaledY, maxThumbnailHeight,
                                     maxThumbnailHeight / (maxThumbnailWidth / imageWidth));
   }
 
   return {
     width: thumbnailImageWidth,
     height: thumbnailImageHeight,
     scaledX,
-    scaledY
+    scaledY,
   };
 }
 
 /**
  * @param {dataUrl} String Data URL of the original image.
  * @param {int} imageHeight Height in pixels of the original image.
  * @param {int} imageWidth Width in pixels of the original image.
  * @param {String} urlOrBlob 'blob' for a blob, otherwise data url.
--- a/browser/extensions/screenshots/catcher.js
+++ b/browser/extensions/screenshots/catcher.js
@@ -29,17 +29,17 @@ this.catcher = (function() {
     let result;
     if (exc.fromMakeError) {
       result = exc;
     } else {
       result = {
         fromMakeError: true,
         name: exc.name || "ERROR",
         message: String(exc),
-        stack: exc.stack
+        stack: exc.stack,
       };
       for (const attr in exc) {
         result[attr] = exc[attr];
       }
     }
     if (info) {
       for (const attr of Object.keys(info)) {
         result[attr] = info[attr];
--- a/browser/extensions/screenshots/onboarding/slides.js
+++ b/browser/extensions/screenshots/onboarding/slides.js
@@ -89,21 +89,21 @@ this.slides = (function() {
     // termsAndPrivacyNoticeCloudServices is a more complicated substitution:
     const termsContainer = doc.querySelector(".onboarding-legal-notice");
     termsContainer.innerHTML = "";
     const termsSentinel = "__TERMS__";
     const privacySentinel = "__PRIVACY__";
     const sentinelSplitter = "!!!";
     const linkTexts = {
       [termsSentinel]: browser.i18n.getMessage("termsAndPrivacyNoticeTermsLink"),
-      [privacySentinel]: browser.i18n.getMessage("termsAndPrivacyNoticyPrivacyLink")
+      [privacySentinel]: browser.i18n.getMessage("termsAndPrivacyNoticyPrivacyLink"),
     };
     const linkUrls = {
       [termsSentinel]: "https://www.mozilla.org/about/legal/terms/services/",
-      [privacySentinel]: "https://www.mozilla.org/privacy/firefox/"
+      [privacySentinel]: "https://www.mozilla.org/privacy/firefox/",
     };
     const text = browser.i18n.getMessage(
       "termsAndPrivacyNotice2",
       [sentinelSplitter + termsSentinel + sentinelSplitter,
        sentinelSplitter + privacySentinel + sentinelSplitter]);
     const parts = text.split(sentinelSplitter);
     for (const part of parts) {
       let el;
--- a/browser/extensions/screenshots/selector/shooter.js
+++ b/browser/extensions/screenshots/selector/shooter.js
@@ -147,34 +147,34 @@ this.shooter = (function() { // eslint-d
         image: {
           url: buildSettings.uploadBinary ? "" : dataUrl,
           type,
           captureType,
           text: captureText,
           location: selectedPos,
           dimensions: {
             x: selectedPos.right - selectedPos.left,
-            y: selectedPos.bottom - selectedPos.top
-          }
-        }
+            y: selectedPos.bottom - selectedPos.top,
+          },
+        },
       });
     }
     catcher.watchPromise(callBackground("takeShot", {
       captureType,
       captureText,
       scroll: {
         scrollX: window.scrollX,
         scrollY: window.scrollY,
         innerHeight: window.innerHeight,
-        innerWidth: window.innerWidth
+        innerWidth: window.innerWidth,
       },
       selectedPos,
       shotId: shotObject.id,
       shot: shotObject.toJSON(),
-      imageBlob
+      imageBlob,
     }).then((url) => {
       return clipboard.copy(url).then((copied) => {
         return callBackground("openShot", { url, copied });
       });
     }, (error) => {
       if ("popupMessage" in error && (error.popupMessage === "REQUEST_ERROR" || error.popupMessage === "CONNECTION_ERROR")) {
         // The error has been signaled to the user, but unlike other errors (or
         // success) we should not abort the selection
@@ -201,30 +201,30 @@ this.shooter = (function() { // eslint-d
       if (!dataUrl) {
         promise = callBackground(
           "screenshotPage",
           selectedPos.toJSON(),
           {
             scrollX: window.scrollX,
             scrollY: window.scrollY,
             innerHeight: window.innerHeight,
-            innerWidth: window.innerWidth
+            innerWidth: window.innerWidth,
           });
       }
       catcher.watchPromise(promise.then((dataUrl) => {
         let type = blobConverters.getTypeFromDataUrl(dataUrl);
         type = type ? type.split("/", 2)[1] : null;
         shotObject.delAllClips();
         shotObject.addClip({
           createdDate: Date.now(),
           image: {
             url: dataUrl,
             type,
-            location: selectedPos
-          }
+            location: selectedPos,
+          },
         });
         ui.triggerDownload(dataUrl, shotObject.filename);
         uicontrol.deactivate();
       }));
     }));
   };
 
   let copyInProgress = null;
@@ -267,17 +267,17 @@ this.shooter = (function() { // eslint-d
     callBackground("sendEvent", ...args);
   };
 
   catcher.watchFunction(() => {
     shotObject = new AbstractShot(
       backend,
       randomString(RANDOM_STRING_LENGTH) + "/" + domainFromUrl(location),
       {
-        origin: shot.originFromUrl(location.href)
+        origin: shot.originFromUrl(location.href),
       }
     );
     shotObject.update(documentMetadata());
   })();
 
   return exports;
 })();
 null;
--- a/browser/extensions/screenshots/selector/ui.js
+++ b/browser/extensions/screenshots/selector/ui.js
@@ -125,17 +125,17 @@ this.ui = (function() { // eslint-disabl
 
   const iframeSelection = exports.iframeSelection = {
     element: null,
     addClassName: "",
     sizeTracking: {
       timer: null,
       windowDelayer: null,
       lastHeight: null,
-      lastWidth: null
+      lastWidth: null,
     },
     document: null,
     display(installHandlerOnDocument) {
       return new Promise((resolve, reject) => {
         if (!this.element) {
           this.element = initializeIframe();
           this.element.id = "firefox-screenshots-selection-iframe";
           this.element.style.display = "none";
@@ -257,17 +257,17 @@ this.ui = (function() { // eslint-disabl
       }
       return el;
     },
 
     remove() {
       this.stopSizeWatch();
       util.removeNode(this.element);
       this.element = this.document = null;
-    }
+    },
   };
 
   iframeSelection.onResize = watchFunction(assertIsTrusted(onResize.bind(iframeSelection)), true);
 
   const iframePreSelection = exports.iframePreSelection = {
     element: null,
     document: null,
     display(installHandlerOnDocument, standardOverlayCallbacks) {
@@ -371,17 +371,17 @@ this.ui = (function() { // eslint-disabl
       return el;
     },
 
     remove() {
       this.hide();
       util.removeNode(this.element);
       this.element = null;
       this.document = null;
-    }
+    },
   };
 
   const iframePreview = exports.iframePreview = {
     element: null,
     document: null,
     display(installHandlerOnDocument, standardOverlayCallbacks) {
       return new Promise((resolve, reject) => {
         if (!this.element) {
@@ -475,17 +475,17 @@ this.ui = (function() { // eslint-disabl
       this.document.body.querySelector(".loader").style.display = "";
     },
 
     remove() {
       this.hide();
       util.removeNode(this.element);
       this.element = null;
       this.document = null;
-    }
+    },
   };
 
   iframePreSelection.onResize = watchFunction(onResize.bind(iframePreSelection), true);
 
   const iframe = exports.iframe = {
     currentIframe: iframePreSelection,
     display(installHandlerOnDocument, standardOverlayCallbacks) {
       return iframeSelection.display(installHandlerOnDocument)
@@ -539,17 +539,17 @@ this.ui = (function() { // eslint-disabl
     },
 
     usePreview() {
       if (this.currentIframe === iframeSelection || this.currentIframe === iframePreSelection) {
         this.hide();
       }
       this.currentIframe = iframePreview;
       this.unhide();
-    }
+    },
   };
 
   const movements = ["topLeft", "top", "topRight", "left", "right", "bottomLeft", "bottom", "bottomRight"];
 
   /** Creates the selection box */
   exports.Box = {
 
     display(pos, callbacks) {
@@ -810,17 +810,17 @@ this.ui = (function() { // eslint-disabl
       }
       this.save.removeAttribute("disabled");
     },
 
     el: null,
     boxTopEl: null,
     boxLeftEl: null,
     boxRightEl: null,
-    boxBottomEl: null
+    boxBottomEl: null,
   };
 
   exports.HoverBox = {
 
     el: null,
 
     display(rect) {
       if (!this.el) {
@@ -841,17 +841,17 @@ this.ui = (function() { // eslint-disabl
       if (this.downloadNotice) {
         this.downloadNotice.display = "none";
       }
     },
 
     remove() {
       util.removeNode(this.el);
       this.el = null;
-    }
+    },
   };
 
   exports.PixelDimensions = {
     el: null,
     xEl: null,
     yEl: null,
     display(xPos, yPos, x, y) {
       if (!this.el) {
@@ -865,17 +865,17 @@ this.ui = (function() { // eslint-disabl
       this.xEl.textContent = Math.round(x);
       this.yEl.textContent = Math.round(y);
       this.el.style.top = (yPos + 12) + "px";
       this.el.style.left = (xPos + 12) + "px";
     },
     remove() {
       util.removeNode(this.el);
       this.el = this.xEl = this.yEl = null;
-    }
+    },
   };
 
   exports.Preview = {
     display(dataUrl, showCropWarning) {
       const img = makeEl("IMG");
       const imgBlob = blobConverters.dataUrlToBlob(dataUrl);
       img.src = URL.createObjectURL(imgBlob);
       iframe.document().querySelector(".preview-image").appendChild(img);
@@ -885,17 +885,17 @@ this.ui = (function() { // eslint-disabl
           <tr class="notice-wrapper">
             <td class="notice-content"></td>
           </tr>
         </tbody>`;
         const contentCell = imageCroppedEl.getElementsByTagName("td");
         contentCell[0].textContent = browser.i18n.getMessage("imageCropPopupWarning", buildSettings.maxImageHeight);
         iframe.document().querySelector(".preview-buttons").appendChild(imageCroppedEl);
       }
-    }
+    },
   };
 
   /** Removes every UI this module creates */
   exports.remove = function() {
     for (const name in exports) {
       if (name.startsWith("iframe")) {
         continue;
       }
--- a/browser/extensions/screenshots/selector/uicontrol.js
+++ b/browser/extensions/screenshots/selector/uicontrol.js
@@ -69,35 +69,35 @@ this.uicontrol = (function() {
 
   function round10(n) {
     return Math.floor(n / 10) * 10;
   }
 
   function eventOptionsForBox(box) {
     return {
       cd1: round10(Math.abs(box.bottom - box.top)),
-      cd2: round10(Math.abs(box.right - box.left))
+      cd2: round10(Math.abs(box.right - box.left)),
     };
   }
 
   function eventOptionsForResize(boxStart, boxEnd) {
     return {
       cd1: round10(
         (boxEnd.bottom - boxEnd.top)
         - (boxStart.bottom - boxStart.top)),
       cd2: round10(
         (boxEnd.right - boxEnd.left)
-        - (boxStart.right - boxStart.left))
+        - (boxStart.right - boxStart.left)),
     };
   }
 
   function eventOptionsForMove(posStart, posEnd) {
     return {
       cd1: round10(posEnd.y - posStart.y),
-      cd2: round10(posEnd.x - posStart.x)
+      cd2: round10(posEnd.x - posStart.x),
     };
   }
 
   function downloadShot() {
     const previewDataUrl = (captureType === "fullPageTruncated") ? null : dataUrl;
     // Downloaded shots don't have dimension limits
     removeDimensionLimitsOnFullPageShot();
     shooter.downloadShot(selectedPos, previewDataUrl, captureType);
@@ -120,26 +120,26 @@ this.uicontrol = (function() {
     topLeft: ["x1", "y1"],
     top: [null, "y1"],
     topRight: ["x2", "y1"],
     left: ["x1", null],
     right: ["x2", null],
     bottomLeft: ["x1", "y2"],
     bottom: [null, "y2"],
     bottomRight: ["x2", "y2"],
-    move: ["*", "*"]
+    move: ["*", "*"],
   };
 
   const doNotAutoselectTags = {
     H1: true,
     H2: true,
     H3: true,
     H4: true,
     H5: true,
-    H6: true
+    H6: true,
   };
 
   let captureType;
 
   function removeDimensionLimitsOnFullPageShot() {
     if (captureType === "fullPageTruncated") {
       captureType = "fullPage";
       selectedPos = new Selection(
@@ -156,17 +156,17 @@ this.uicontrol = (function() {
       sendEvent("save-shot", "overlay-save-button");
       shooter.takeShot("selection", selectedPos);
     }, download: () => {
       sendEvent("download-shot", "overlay-download-button");
       downloadShot();
     }, copy: () => {
       sendEvent("copy-shot", "overlay-copy-button");
       copyShot();
-    }
+    },
   };
 
   const standardOverlayCallbacks = {
     cancel: () => {
       sendEvent("cancel-shot", "cancel-preview-button");
       exports.deactivate();
     },
     onClickCancel: e => {
@@ -220,17 +220,17 @@ this.uicontrol = (function() {
     },
     onDownloadPreview: () => {
       sendEvent(`download-${captureType.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase()}`, "download-preview-button");
       downloadShot();
     },
     onCopyPreview: () => {
       sendEvent(`copy-${captureType.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase()}`, "copy-preview-button");
       copyShot();
-    }
+    },
   };
 
   /** Holds all the objects that handle events for each state: */
   const stateHandlers = {};
 
   function getState() {
     return getState.state;
   }
@@ -286,38 +286,38 @@ this.uicontrol = (function() {
 
   let dataUrl;
 
   stateHandlers.previewing = {
     start() {
       dataUrl = shooter.screenshotPage(selectedPos, captureType);
       ui.iframe.usePreview();
       ui.Preview.display(dataUrl, captureType === "fullPageTruncated");
-    }
+    },
   };
 
   stateHandlers.onboarding = {
     start() {
       if (typeof slides === "undefined") {
         throw new Error("Attempted to set state to onboarding without loading slides");
       }
       sendEvent("internal", "unhide-onboarding-frame");
       catcher.watchPromise(slides.display({
-        onEnd: this.slidesOnEnd.bind(this)
+        onEnd: this.slidesOnEnd.bind(this),
       }));
     },
 
     slidesOnEnd() {
       callBackground("hasSeenOnboarding");
       setState("crosshairs");
     },
 
     end() {
       slides.remove();
-    }
+    },
   };
 
   stateHandlers.crosshairs = {
 
     cachedEl: null,
 
     start() {
       selectedPos = mousedownPos = null;
@@ -494,17 +494,17 @@ this.uicontrol = (function() {
       event.stopPropagation();
       event.preventDefault();
       return false;
     },
 
     end() {
       ui.HoverBox.remove();
       ui.PixelDimensions.remove();
-    }
+    },
   };
 
   stateHandlers.draggingReady = {
     minMove: 40, // px
     minAutoImageWidth: 40,
     minAutoImageHeight: 40,
     maxAutoElementWidth: 800,
     maxAutoElementHeight: 600,
@@ -585,17 +585,17 @@ this.uicontrol = (function() {
         }
         el = el.parentNode;
       }
       return null;
     },
 
     end() {
       mouseupNoAutoselect = false;
-    }
+    },
 
   };
 
   stateHandlers.dragging = {
 
     start() {
       ui.iframe.useSelection();
       ui.Box.display(selectedPos);
@@ -614,24 +614,24 @@ this.uicontrol = (function() {
       selectedPos.y2 = util.truncateY(event.pageY);
       ui.Box.display(selectedPos, standardDisplayCallbacks);
       sendEvent(
         "make-selection", "selection-drag",
         eventOptionsForBox({
           top: selectedPos.y1,
           bottom: selectedPos.y2,
           left: selectedPos.x1,
-          right: selectedPos.x2
+          right: selectedPos.x2,
         }));
       setState("selected");
     },
 
     end() {
       ui.PixelDimensions.remove();
-    }
+    },
   };
 
   stateHandlers.selected = {
     start() {
       ui.iframe.useSelection();
     },
 
     mousedown(event) {
@@ -648,17 +648,17 @@ this.uicontrol = (function() {
         sendEvent("start-move-selection", "selection");
         stateHandlers.resizing.startResize(event, "move");
       } else if (!ui.Box.isControl(target)) {
         mousedownPos = new Pos(event.pageX, event.pageY);
         setState("crosshairs");
       }
       event.preventDefault();
       return false;
-    }
+    },
   };
 
   stateHandlers.resizing = {
     start() {
       ui.iframe.useSelection();
       selectedPos.sortCoords();
     },
 
@@ -727,24 +727,24 @@ this.uicontrol = (function() {
       scrollIfByEdge(event.pageX, event.pageY);
       ui.Box.display(selectedPos);
     },
 
     end() {
       resizeDirection = resizeStartPos = resizeStartSelected = null;
       selectedPos.sortCoords();
       ui.PixelDimensions.remove();
-    }
+    },
   };
 
   stateHandlers.cancel = {
     start() {
       ui.iframe.hide();
       ui.Box.remove();
-    }
+    },
   };
 
   function getDocumentWidth() {
     return Math.max(
       document.body && document.body.clientWidth,
       document.documentElement.clientWidth,
       document.body && document.body.scrollWidth,
       document.documentElement.scrollWidth);
--- a/browser/extensions/screenshots/selector/util.js
+++ b/browser/extensions/screenshots/selector/util.js
@@ -41,17 +41,17 @@ this.util = (function() { // eslint-disa
     const scrollY = window.scrollY;
     const text = [];
     function traverse(el) {
       let elBox = el.getBoundingClientRect();
       elBox = {
         top: elBox.top + scrollY,
         bottom: elBox.bottom + scrollY,
         left: elBox.left + scrollX,
-        right: elBox.right + scrollX
+        right: elBox.right + scrollX,
       };
       if (elBox.bottom < box.top ||
           elBox.top > box.bottom ||
           elBox.right < box.left ||
           elBox.left > box.right) {
         // Totally outside of the box
         return;
       }