From 34bcc1a5c2750b6f6fa9d9b971ac8aff796ddd1c Mon Sep 17 00:00:00 2001
From: Yuchen Pei <hi@ypei.me>
Date: Wed, 6 Apr 2022 17:35:05 +1000
Subject: linting

- eslint
- also adding eslintrc
---
 .eslintrc.js             |  17 ++
 bg/ExternalLicenses.js   |  29 ++--
 bg/ListManager.js        |  20 +--
 bg/ResponseMetaData.js   |  18 +-
 bg/ResponseProcessor.js  |  32 ++--
 common/Storage.js        |  24 +--
 common/Test.js           |   6 +-
 main_background.js       | 427 +++++++++++++++++++++--------------------------
 test/spec/LibreJSSpec.js | 140 ++++++++--------
 9 files changed, 344 insertions(+), 369 deletions(-)
 create mode 100644 .eslintrc.js

diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..d48f883
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,17 @@
+module.exports = {
+  "env": {
+    "browser": true,
+    "commonjs": true,
+    "es2021": true,
+    "node": true,
+    "webextensions": true
+  },
+  "extends": "eslint:recommended",
+  "parserOptions": {
+    "ecmaVersion": "latest"
+  },
+  "rules": {
+    "quotes": ["error", "single"],
+    "no-console": ["off"]
+  }
+}
diff --git a/bg/ExternalLicenses.js b/bg/ExternalLicenses.js
index 0e09b6d..1a8e58c 100644
--- a/bg/ExternalLicenses.js
+++ b/bg/ExternalLicenses.js
@@ -23,12 +23,12 @@
   Singleton to handle external licenses, e.g. WebLabels
 */
 
-"use strict";
+'use strict';
 
 let licensesByLabel = new Map();
 let licensesByUrl = new Map();
 {
-  let { licenses } = require("../license_definitions");
+  let { licenses } = require('../license_definitions');
   let mapByLabel = (label, license) => licensesByLabel.set(label.toUpperCase(), license);
   for (let [id, l] of Object.entries(licenses)) {
     let { identifier, canonicalUrl, licenseName } = l;
@@ -64,7 +64,7 @@ var ExternalLicenses = {
     let frameCache = tabCache && tabCache.get(frameId);
     let cache = frameCache && frameCache.get(documentUrl);
     let scriptInfo = await browser.tabs.sendMessage(tabId, {
-      action: "checkLicensedScript",
+      action: 'checkLicensedScript',
       url,
       cache,
     }, { frameId });
@@ -74,10 +74,10 @@ var ExternalLicenses = {
     }
     scriptInfo.licenses = new Set();
     scriptInfo.toString = function() {
-      let licenseIds = [...this.licenses].map(l => l.identifier).sort().join(", ");
+      let licenseIds = [...this.licenses].map(l => l.identifier).sort().join(', ');
       return licenseIds
-        ? `Free license${this.licenses.size > 1 ? "s" : ""} (${licenseIds})`
-        : "Unknown license(s)";
+        ? `Free license${this.licenses.size > 1 ? 's' : ''} (${licenseIds})`
+        : 'Unknown license(s)';
     }
     let match = (map, key) => {
       if (map.has(key)) {
@@ -112,22 +112,23 @@ var ExternalLicenses = {
     }
     frameCache.set(frameId, new Map([[documentUrl, cache]]));
 
-    let link = doc.querySelector(`link[rel="jslicense"], link[data-jslicense="1"], a[rel="jslicense"], a[data-jslicense="1"]`);
+    let link = doc.querySelector('link[rel="jslicense"], link[data-jslicense="1"], a[rel="jslicense"], a[data-jslicense="1"]');
     if (link) {
-      let href = link.getAttribute("href");
+      let href = link.getAttribute('href');
       cache.webLabels = { href };
       let move = () => !!doc.head.insertBefore(link, doc.head.firstChild);
       if (link.parentNode === doc.head) {
-        for (let node = link; node = node.previousElementSibling;) {
-          if (node.tagName.toUpperCase() === "SCRIPT") {
+        let node = link.previousElementSibling;
+        for (; node; node = node.previousElementSibling) {
+          if (node.tagName.toUpperCase() === 'SCRIPT') {
             return move();
           }
         }
       } else { // the reference is only in the body
-        if (link.tagName.toUpperCase() === "A") {
-          let newLink = doc.createElement("link");
-          newLink.rel = "jslicense";
-          newLink.setAttribute("href", href);
+        if (link.tagName.toUpperCase() === 'A') {
+          let newLink = doc.createElement('link');
+          newLink.rel = 'jslicense';
+          newLink.setAttribute('href', href);
           link = newLink;
         }
         return move();
diff --git a/bg/ListManager.js b/bg/ListManager.js
index f712356..3020197 100644
--- a/bg/ListManager.js
+++ b/bg/ListManager.js
@@ -23,7 +23,7 @@
   A class to manage whitelist/blacklist operations
 */
 
-let { ListStore } = require("../common/Storage");
+let { ListStore } = require('../common/Storage');
 
 class ListManager {
   constructor(whitelist, blacklist, builtInHashes) {
@@ -48,13 +48,13 @@ class ListManager {
     with a trailing (hash).
     Returns "blacklisted", "whitelisted" or defValue
   */
-  getStatus(key, defValue = "unknown") {
+  getStatus(key, defValue = 'unknown') {
     let { blacklist, whitelist } = this.lists;
     let inline = ListStore.inlineItem(key);
     if (inline) {
       return blacklist.contains(inline)
-        ? "blacklisted"
-        : whitelist.contains(inline) ? "whitelisted"
+        ? 'blacklisted'
+        : whitelist.contains(inline) ? 'whitelisted'
           : defValue;
     }
 
@@ -63,16 +63,16 @@ class ListManager {
       let url = ListStore.urlItem(key);
       let site = ListStore.siteItem(key);
       return (blacklist.contains(url) || ListManager.siteMatch(site, blacklist)
-        ? "blacklisted"
+        ? 'blacklisted'
         : whitelist.contains(url) || ListManager.siteMatch(site, whitelist)
-          ? "whitelisted" : defValue
+          ? 'whitelisted' : defValue
       );
     }
 
     let [hashItem, srcHash] = match; // (hash), hash
-    return blacklist.contains(hashItem) ? "blacklisted"
+    return blacklist.contains(hashItem) ? 'blacklisted'
       : this.builtInHashes.has(srcHash) || whitelist.contains(hashItem)
-        ? "whitelisted"
+        ? 'whitelisted'
         : defValue;
   }
 
@@ -85,13 +85,13 @@ class ListManager {
     if (list.contains(site)) {
       return site;
     }
-    site = site.replace(/^([\w-]+:\/\/)?(\w)/, "$1*.$2");
+    site = site.replace(/^([\w-]+:\/\/)?(\w)/, '$1*.$2');
     for (; ;) {
       if (list.contains(site)) {
         return site;
       }
       let oldKey = site;
-      site = site.replace(/(?:\*\.)*\w+(?=\.)/, "*");
+      site = site.replace(/(?:\*\.)*\w+(?=\.)/, '*');
       if (site === oldKey) {
         return null;
       }
diff --git a/bg/ResponseMetaData.js b/bg/ResponseMetaData.js
index 4570120..cb3fb2a 100644
--- a/bg/ResponseMetaData.js
+++ b/bg/ResponseMetaData.js
@@ -34,24 +34,24 @@ class ResponseMetaData {
     this.headers = {};
     for (let h of responseHeaders) {
       if (/^\s*Content-(Type|Disposition)\s*$/i.test(h.name)) {
-        let propertyName = h.name.split("-")[1].trim();
+        let propertyName = h.name.split('-')[1].trim();
         propertyName = `content${propertyName.charAt(0).toUpperCase()}${propertyName.substring(1).toLowerCase()}`;
         this[propertyName] = h.value;
         this.headers[propertyName] = h;
       }
     }
-    this.computedCharset = "";
+    this.computedCharset = '';
   }
 
   get charset() {
-    let charset = "";
+    let charset = '';
     if (this.contentType) {
       let m = this.contentType.match(/;\s*charset\s*=\s*(\S+)/);
       if (m) {
         charset = m[1];
       }
     }
-    Object.defineProperty(this, "charset", { value: charset, writable: false, configurable: true });
+    Object.defineProperty(this, 'charset', { value: charset, writable: false, configurable: true });
     return this.computedCharset = charset;
   }
 
@@ -69,12 +69,12 @@ class ResponseMetaData {
 
       // let's try figuring out the charset from <meta> tags
       let parser = new DOMParser();
-      let doc = parser.parseFromString(text, "text/html");
+      let doc = parser.parseFromString(text, 'text/html');
       let meta = doc.querySelectorAll('meta[charset], meta[http-equiv="content-type"], meta[content*="charset"]');
       for (let m of meta) {
-        charset = m.getAttribute("charset");
+        charset = m.getAttribute('charset');
         if (!charset) {
-          let match = m.getAttribute("content").match(/;\s*charset\s*=\s*([\w-]+)/i)
+          let match = m.getAttribute('content').match(/;\s*charset\s*=\s*([\w-]+)/i)
           if (match) charset = match[1];
         }
         if (charset) {
@@ -89,7 +89,7 @@ class ResponseMetaData {
     return text;
   }
 
-  createDecoder(charset = this.charset, def = "latin1") {
+  createDecoder(charset = this.charset, def = 'latin1') {
     if (charset) {
       try {
         return new TextDecoder(charset);
@@ -99,7 +99,7 @@ class ResponseMetaData {
     }
     return def ? new TextDecoder(def) : null;
   }
-};
+}
 ResponseMetaData.UTF8BOM = new Uint8Array(BOM);
 
 module.exports = { ResponseMetaData };
diff --git a/bg/ResponseProcessor.js b/bg/ResponseProcessor.js
index 078f38a..d964dab 100644
--- a/bg/ResponseProcessor.js
+++ b/bg/ResponseProcessor.js
@@ -24,22 +24,22 @@
   only the "interesting" HTML and script requests and leaving the other alone
 */
 
-let { ResponseMetaData } = require("./ResponseMetaData");
+let { ResponseMetaData } = require('./ResponseMetaData');
 
 let listeners = new WeakMap();
 let webRequestEvent = browser.webRequest.onHeadersReceived;
 
 class ResponseProcessor {
 
-  static install(handler, types = ["main_frame", "sub_frame", "script"]) {
+  static install(handler, types = ['main_frame', 'sub_frame', 'script']) {
     if (listeners.has(handler)) return false;
     let listener =
       async request => await new ResponseTextFilter(request).process(handler);
     listeners.set(handler, listener);
     webRequestEvent.addListener(
       listener,
-      { urls: ["<all_urls>"], types },
-      ["blocking", "responseHeaders"]
+      { urls: ['<all_urls>'], types },
+      ['blocking', 'responseHeaders']
     );
     return true;
   }
@@ -67,21 +67,21 @@ class ResponseTextFilter {
     this.canProcess = // we want to process html documents and scripts only
       (statusCode < 300 || statusCode >= 400) && // skip redirections
       !md.disposition && // skip forced downloads
-      (type === "script" || /\bhtml\b/i.test(md.contentType));
+      (type === 'script' || /\bhtml\b/i.test(md.contentType));
   }
 
   async process(handler) {
     if (!this.canProcess) return ResponseProcessor.ACCEPT;
     let { metaData, request } = this;
     let response = { request, metaData }; // we keep it around allowing callbacks to store state
-    if (typeof handler.pre === "function") {
+    if (typeof handler.pre === 'function') {
       let res = await handler.pre(response);
       if (res) return res;
       if (handler.post) handler = handler.post;
-      if (typeof handler !== "function") return ResponseProcessor.ACCEPT;
+      if (typeof handler !== 'function') return ResponseProcessor.ACCEPT;
     }
 
-    let { requestId, responseHeaders } = request;
+    let { requestId } = request;
     let filter = browser.webRequest.filterResponseData(requestId);
     let buffer = [];
 
@@ -89,9 +89,9 @@ class ResponseTextFilter {
       buffer.push(event.data);
     };
 
-    filter.onstop = async event => {
+    filter.onstop = async unused => {
       // concatenate chunks
-      let size = buffer.reduce((sum, chunk, n) => sum + chunk.byteLength, 0)
+      let size = buffer.reduce((sum, chunk) => sum + chunk.byteLength, 0)
       let allBytes = new Uint8Array(size);
       let pos = 0;
       for (let chunk of buffer) {
@@ -100,13 +100,13 @@ class ResponseTextFilter {
       }
       buffer = null; // allow garbage collection
       if (allBytes.indexOf(0) !== -1) {
-        console.debug("Warning: zeroes in bytestream, probable cached encoding mismatch.", request);
-        if (request.type === "script") {
-          console.debug("It's a script, trying to refetch it.");
-          response.text = await (await fetch(request.url, { cache: "reload", credentials: "include" })).text();
+        console.debug('Warning: zeroes in bytestream, probable cached encoding mismatch.', request);
+        if (request.type === 'script') {
+          console.debug('It\'s a script, trying to refetch it.');
+          response.text = await (await fetch(request.url, { cache: 'reload', credentials: 'include' })).text();
         } else {
-          console.debug("It's a %s, trying to decode it as UTF-16.", request.type);
-          response.text = new TextDecoder("utf-16be").decode(allBytes, { stream: true });
+          console.debug('It\'s a %s, trying to decode it as UTF-16.', request.type);
+          response.text = new TextDecoder('utf-16be').decode(allBytes, { stream: true });
         }
       } else {
         response.text = metaData.decode(allBytes);
diff --git a/common/Storage.js b/common/Storage.js
index 47261c5..6254d66 100644
--- a/common/Storage.js
+++ b/common/Storage.js
@@ -23,7 +23,7 @@
  A tiny wrapper around extensions storage API, supporting CSV serialization for
  retro-compatibility
 */
-"use strict";
+'use strict';
 
 var Storage = {
   ARRAY: {
@@ -45,7 +45,7 @@ var Storage = {
     },
 
     async save(key, list) {
-      return await browser.storage.local.set({ [key]: [...list].join(",") });
+      return await browser.storage.local.set({ [key]: [...list].join(',') });
     }
   }
 };
@@ -68,20 +68,20 @@ class ListStore {
 
   static inlineItem(url) {
     // here we simplify and hash inline script references
-    return url.startsWith("inline:") ? url
-      : url.startsWith("view-source:")
-      && url.replace(/^view-source:[\w-+]+:\/+([^/]+).*#line\d+/, "inline://$1#")
-        .replace(/\n[^]*/, s => s.replace(/\s+/g, ' ').substring(0, 16) + "…" + hash(s.trim()));
+    return url.startsWith('inline:') ? url
+      : url.startsWith('view-source:')
+      && url.replace(/^view-source:[\w-+]+:\/+([^/]+).*#line\d+/, 'inline://$1#')
+        .replace(/\n[^]*/, s => s.replace(/\s+/g, ' ').substring(0, 16) + '…' + hash(s.trim()));
   }
   static hashItem(hash) {
-    return hash.startsWith("(") ? hash : `(${hash})`;
+    return hash.startsWith('(') ? hash : `(${hash})`;
   }
   static urlItem(url) {
-    let queryPos = url.indexOf("?");
+    let queryPos = url.indexOf('?');
     return queryPos === -1 ? url : url.substring(0, queryPos);
   }
   static siteItem(url) {
-    if (url.endsWith("/*")) return url;
+    if (url.endsWith('/*')) return url;
     try {
       return `${new URL(url).origin}/*`;
     } catch (e) {
@@ -134,12 +134,12 @@ class ListStore {
 }
 
 function hash(source) {
-  var shaObj = new jssha("SHA-256", "TEXT")
+  var shaObj = new jssha('SHA-256', 'TEXT')
   shaObj.update(source);
-  return shaObj.getHash("HEX");
+  return shaObj.getHash('HEX');
 }
 
-if (typeof module === "object") {
+if (typeof module === 'object') {
   module.exports = { ListStore, Storage, hash };
   var jssha = require('jssha');
 }
diff --git a/common/Test.js b/common/Test.js
index 7acbfa0..88baff2 100644
--- a/common/Test.js
+++ b/common/Test.js
@@ -19,9 +19,9 @@
 * along with GNU LibreJS.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-"use strict";
+'use strict';
 var Test = (() => {
-  const RUNNER_URL = browser.extension.getURL("/test/SpecRunner.html");
+  const RUNNER_URL = browser.extension.getURL('/test/SpecRunner.html');
   return {
     /*
       returns RUNNER_URL if it's a test-enabled build or an about:debugging
@@ -50,6 +50,6 @@ var Test = (() => {
     }
   };
 })();
-if (typeof module === "object") {
+if (typeof module === 'object') {
   module.exports = Test;
 }
diff --git a/main_background.js b/main_background.js
index 0bfb33c..d3d7bb4 100644
--- a/main_background.js
+++ b/main_background.js
@@ -20,15 +20,15 @@
 * along with GNU LibreJS.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-var acorn = require('acorn');
-var acornLoose = require('acorn-loose');
-var legacy_license_lib = require("./legacy_license_check.js");
-var { ResponseProcessor } = require("./bg/ResponseProcessor");
-var { Storage, ListStore, hash } = require("./common/Storage");
-var { ListManager } = require("./bg/ListManager");
-var { ExternalLicenses } = require("./bg/ExternalLicenses");
-
-console.log("main_background.js");
+const acorn = require('acorn');
+const legacy_license_lib = require('./legacy_license_check.js');
+const { ResponseProcessor } = require('./bg/ResponseProcessor');
+const { Storage, ListStore, hash } = require('./common/Storage');
+const { ListManager } = require('./bg/ListManager');
+const { ExternalLicenses } = require('./bg/ExternalLicenses');
+const { licenses } = require('./license_definitions');
+
+console.log('main_background.js');
 /**
 *	If this is true, it evaluates entire scripts instead of returning as soon as it encounters a violation.
 *
@@ -41,7 +41,7 @@ var time = Date.now();
 
 function dbg_print(a, b) {
   if (PRINT_DEBUG == true) {
-    console.log("Time spent so far: " + (Date.now() - time) / 1000 + " seconds");
+    console.log('Time spent so far: ' + (Date.now() - time) / 1000 + ' seconds');
     if (b === undefined) {
       console.log(a);
     } else {
@@ -64,24 +64,18 @@ function dbg_print(a, b) {
   - "// @license [magnet link] [identifier]" then "// @license-end" (may also use /* comments)
   - Automatic whitelist: (http://bzr.savannah.gnu.org/lh/librejs/dev/annotate/head:/data/script_libraries/script-libraries.json_
 */
-const { licenses } = require("./license_definitions");
 
 // These are objects that it will search for in an initial regex pass over non-free scripts.
 var reserved_objects = [
   //"document",
   //"window",
-  "fetch",
-  "XMLHttpRequest",
-  "chrome", // only on chrome
-  "browser", // only on firefox
-  "eval"
+  'fetch',
+  'XMLHttpRequest',
+  'chrome', // only on chrome
+  'browser', // only on firefox
+  'eval'
 ];
 
-// Generates JSON key for local storage
-function get_storage_key(script_name, src_hash) {
-  return script_name;
-}
-
 /*
 *
 *	Called when something changes the persistent data of the add-on.
@@ -95,21 +89,13 @@ function get_storage_key(script_name, src_hash) {
 *
 */
 function options_listener(changes, area) {
-  // The cache must be flushed when settings are changed
-  // TODO: See if this can be minimized
-  function flushed() {
-    dbg_print("cache flushed");
-  }
-  //var flushingCache = browser.webRequest.handlerBehaviorChanged(flushed);
-
-
-  dbg_print("Items updated in area" + area + ": ");
+  dbg_print('Items updated in area' + area + ': ');
 
   var changedItems = Object.keys(changes);
-  var changed_items = "";
+  var changed_items = '';
   for (var i = 0; i < changedItems.length; i++) {
     var item = changedItems[i];
-    changed_items += item + ",";
+    changed_items += item + ',';
   }
   dbg_print(changed_items);
 
@@ -120,21 +106,21 @@ var activeMessagePorts = {};
 var activityReports = {};
 async function createReport(initializer) {
   if (!(initializer && (initializer.url || initializer.tabId))) {
-    throw new Error("createReport() needs an URL or a tabId at least");
+    throw new Error('createReport() needs an URL or a tabId at least');
   }
   let template = {
-    "accepted": [],
-    "blocked": [],
-    "blacklisted": [],
-    "whitelisted": [],
-    "unknown": [],
+    'accepted': [],
+    'blocked': [],
+    'blacklisted': [],
+    'whitelisted': [],
+    'unknown': [],
   };
   template = Object.assign(template, initializer);
-  let [url] = (template.url || (await browser.tabs.get(initializer.tabId)).url).split("#");
+  let [url] = (template.url || (await browser.tabs.get(initializer.tabId)).url).split('#');
   template.url = url;
   template.site = ListStore.siteItem(url);
   template.siteStatus = listManager.getStatus(template.site);
-  let list = { "whitelisted": whitelist, "blacklisted": blacklist }[template.siteStatus];
+  let list = { 'whitelisted': whitelist, 'blacklisted': blacklist }[template.siteStatus];
   if (list) {
     template.listedSite = ListManager.siteMatch(template.site, list);
   }
@@ -159,7 +145,7 @@ async function openReportInTab(data) {
 */
 function debug_delete_local() {
   browser.storage.local.clear();
-  dbg_print("Local storage cleared");
+  dbg_print('Local storage cleared');
 }
 
 /**
@@ -169,12 +155,12 @@ function debug_delete_local() {
 */
 function debug_print_local() {
   function storage_got(items) {
-    console.log("%c Local storage: ", 'color: red;');
+    console.log('%c Local storage: ', 'color: red;');
     for (var i in items) {
-      console.log("%c " + i + " = " + items[i], 'color: blue;');
+      console.log('%c ' + i + ' = ' + items[i], 'color: blue;');
     }
   }
-  console.log("%c Variable 'activityReports': ", 'color: red;');
+  console.log('%c Variable \'activityReports\': ', 'color: red;');
   console.log(activityReports);
   browser.storage.local.get(storage_got);
 }
@@ -200,7 +186,7 @@ async function updateReport(tabId, oldReport, updateUI = false) {
   for (let property of Object.keys(oldReport)) {
     let entries = oldReport[property];
     if (!Array.isArray(entries)) continue;
-    let defValue = property === "accepted" || property === "blocked" ? property : "unknown";
+    let defValue = property === 'accepted' || property === 'blocked' ? property : 'unknown';
     for (let script of entries) {
       let status = listManager.getStatus(script[0], defValue);
       if (Array.isArray(newReport[status])) newReport[status].push(script);
@@ -235,20 +221,20 @@ async function updateReport(tabId, oldReport, updateUI = false) {
 *	Make sure it will use the right URL when refering to a certain script.
 *
 */
-async function addReportEntry(tabId, scriptHashOrUrl, action) {
+async function addReportEntry(tabId, action) {
   let report = activityReports[tabId];
   if (!report) report = activityReports[tabId] =
     await createReport({ tabId });
   let type, actionValue;
-  for (type of ["accepted", "blocked", "whitelisted", "blacklisted"]) {
+  for (type of ['accepted', 'blocked', 'whitelisted', 'blacklisted']) {
     if (type in action) {
       actionValue = action[type];
       break;
     }
   }
   if (!actionValue) {
-    console.debug("Something wrong with action", action);
-    return "";
+    console.debug('Something wrong with action', action);
+    return '';
   }
 
   // Search unused data for the given entry
@@ -271,15 +257,12 @@ async function addReportEntry(tabId, scriptHashOrUrl, action) {
       entries.push(actionValue);
     }
   } catch (e) {
-    console.error("action %o, type %s, entryType %s", action, type, entryType, e);
-    entryType = "unknown";
+    console.error('action %o, type %s, entryType %s', action, type, entryType, e);
+    entryType = 'unknown';
   }
 
   if (activeMessagePorts[tabId]) {
-    try {
-      activeMessagePorts[tabId].postMessage({ show_info: report });
-    } catch (e) {
-    }
+    activeMessagePorts[tabId].postMessage({ show_info: report });
   }
 
   if (browser.sessions) browser.sessions.setTabValue(tabId, report.url, report);
@@ -290,14 +273,14 @@ async function addReportEntry(tabId, scriptHashOrUrl, action) {
 
 function get_domain(url) {
   var domain = url.replace('http://', '').replace('https://', '').split(/[/?#]/)[0];
-  if (url.indexOf("http://") == 0) {
-    domain = "http://" + domain;
+  if (url.indexOf('http://') == 0) {
+    domain = 'http://' + domain;
   }
-  else if (url.indexOf("https://") == 0) {
-    domain = "https://" + domain;
+  else if (url.indexOf('https://') == 0) {
+    domain = 'https://' + domain;
   }
-  domain = domain + "/";
-  domain = domain.replace(/ /g, "");
+  domain = domain + '/';
+  domain = domain.replace(/ /g, '');
   return domain;
 }
 
@@ -306,26 +289,25 @@ function get_domain(url) {
 *	This is the callback where the content scripts of the browser action will contact the background script.
 *
 */
-var portFromCS;
 async function connected(p) {
-  if (p.name === "contact_finder") {
+  if (p.name === 'contact_finder') {
     // style the contact finder panel
     await browser.tabs.insertCSS(p.sender.tab.id, {
-      file: "/content/dialog.css",
-      cssOrigin: "user",
+      file: '/content/dialog.css',
+      cssOrigin: 'user',
       matchAboutBlank: true,
       allFrames: true
     });
 
     // Send a message back with the relevant settings
-    p.postMessage(await browser.storage.local.get(["prefs_subject", "prefs_body"]));
+    p.postMessage(await browser.storage.local.get(['prefs_subject', 'prefs_body']));
     return;
   }
   p.onMessage.addListener(async function(m) {
     var update = false;
     var contact_finder = false;
 
-    for (let action of ["whitelist", "blacklist", "forget"]) {
+    for (let action of ['whitelist', 'blacklist', 'forget']) {
       if (m[action]) {
         let [key] = m[action];
         if (m.site) {
@@ -342,18 +324,18 @@ async function connected(p) {
       openReportInTab(m.report_tab);
     }
     // a debug feature
-    if (m["printlocalstorage"] !== undefined) {
-      console.log("Print local storage");
+    if (m['printlocalstorage'] !== undefined) {
+      console.log('Print local storage');
       debug_print_local();
     }
     // invoke_contact_finder
-    if (m["invoke_contact_finder"] !== undefined) {
+    if (m['invoke_contact_finder'] !== undefined) {
       contact_finder = true;
       await injectContactFinder();
     }
     // a debug feature (maybe give the user an option to do this?)
-    if (m["deletelocalstorage"] !== undefined) {
-      console.log("Delete local storage");
+    if (m['deletelocalstorage'] !== undefined) {
+      console.log('Delete local storage');
       debug_delete_local();
     }
 
@@ -365,8 +347,8 @@ async function connected(p) {
       //inject_contact_finder(tabs[0]["id"]);
     }
     if (update || m.update && activityReports[m.tabId]) {
-      let tabId = "tabId" in m ? m.tabId : tabs.pop().id;
-      dbg_print(`%c updating tab ${tabId}`, "color: red;");
+      let tabId = 'tabId' in m ? m.tabId : tabs.pop().id;
+      dbg_print(`%c updating tab ${tabId}`, 'color: red;');
       activeMessagePorts[tabId] = p;
       await updateReport(tabId, activityReports[tabId], true);
     } else {
@@ -374,10 +356,10 @@ async function connected(p) {
         if (activityReports[tab.id]) {
           // If we have some data stored here for this tabID, send it
           dbg_print(`[TABID: ${tab.id}] Sending stored data associated with browser action'`);
-          p.postMessage({ "show_info": activityReports[tab.id] });
+          p.postMessage({ 'show_info': activityReports[tab.id] });
         } else {
           // create a new entry
-          let report = activityReports[tab.id] = await createReport({ "url": tab.url, tabId: tab.id });
+          let report = activityReports[tab.id] = await createReport({ 'url': tab.url, tabId: tab.id });
           p.postMessage({ show_info: report });
           dbg_print(`[TABID: ${tab.id}] No data found, creating a new entry for this window.`);
         }
@@ -392,8 +374,8 @@ async function connected(p) {
 *	Delete the info we are storing about this tab if there is any.
 *
 */
-function delete_removed_tab_info(tab_id, remove_info) {
-  dbg_print("[TABID:" + tab_id + "]" + "Deleting stored info about closed tab");
+function delete_removed_tab_info(tab_id, _) {
+  dbg_print('[TABID:' + tab_id + ']' + 'Deleting stored info about closed tab');
   if (activityReports[tab_id] !== undefined) {
     delete activityReports[tab_id];
   }
@@ -411,8 +393,8 @@ function delete_removed_tab_info(tab_id, remove_info) {
 *
 */
 
-async function onTabUpdated(tabId, changedInfo, tab) {
-  let [url] = tab.url.split("#");
+async function onTabUpdated(tabId, _, tab) {
+  let [url] = tab.url.split('#');
   let report = activityReports[tabId];
   if (!(report && report.url === url)) {
     let cache = browser.sessions &&
@@ -429,52 +411,34 @@ async function onTabActivated({ tabId }) {
 
 /* *********************************************************************************************** */
 
-var fname_data = require("./fname_data.json").fname_data;
+var fname_data = require('./fname_data.json').fname_data;
 
 //************************this part can be tested in the HTML file index.html's script test.js****************************
 
 function full_evaluate(script) {
-  var res = true;
-  if (script === undefined || script == "") {
-    return [true, "Harmless null script"];
+  if (script === undefined || script == '') {
+    return [true, 'Harmless null script'];
   }
 
-  var ast = acornLoose.parse(script).body[0];
-
-  var flag = false;
   var amtloops = 0;
 
-  var loopkeys = { "for": true, "if": true, "while": true, "switch": true };
-  var operators = { "||": true, "&&": true, "=": true, "==": true, "++": true, "--": true, "+=": true, "-=": true, "*": true };
+  var loopkeys = { 'for': true, 'if': true, 'while': true, 'switch': true };
+  var operators = { '||': true, '&&': true, '=': true, '==': true, '++': true, '--': true, '+=': true, '-=': true, '*': true };
   try {
     var tokens = acorn.tokenizer(script);
   } catch (e) {
-    console.warn("Tokenizer could not be initiated (probably invalid code)");
-    return [false, "Tokenizer could not be initiated (probably invalid code)"];
+    console.warn('Tokenizer could not be initiated (probably invalid code)');
+    return [false, 'Tokenizer could not be initiated (probably invalid code)'];
   }
   try {
     var toke = tokens.getToken();
   } catch (e) {
     console.log(script);
     console.log(e);
-    console.warn("couldn't get first token (probably invalid code)");
-    console.warn("Continuing evaluation");
+    console.warn('couldn\'t get first token (probably invalid code)');
+    console.warn('Continuing evaluation');
   }
 
-  /**
-  * Given the end of an identifer token, it tests for bracket suffix notation
-  */
-  function being_called(end) {
-    var i = 0;
-    while (script.charAt(end + i).match(/\s/g) !== null) {
-      i++;
-      if (i >= script.length - 1) {
-        return false;
-      }
-    }
-
-    return script.charAt(end + i) == "(";
-  }
   /**
   * Given the end of an identifer token, it tests for parentheses
   */
@@ -486,9 +450,8 @@ function full_evaluate(script) {
         return false;
       }
     }
-    return script.charAt(end + i) == "[";
+    return script.charAt(end + i) == '[';
   }
-  var error_count = 0;
   var defines_functions = false;
   while (toke !== undefined && toke.type != acorn.tokTypes.eof) {
     if (toke.type.keyword !== undefined) {
@@ -497,17 +460,17 @@ function full_evaluate(script) {
 
       // This type of loop detection ignores functional loop alternatives and ternary operators
 
-      if (toke.type.keyword == "function") {
-        dbg_print("%c NOTICE: Function declaration.", "color:green");
+      if (toke.type.keyword == 'function') {
+        dbg_print('%c NOTICE: Function declaration.', 'color:green');
         defines_functions = true;
       }
 
       if (loopkeys[toke.type.keyword] !== undefined) {
         amtloops++;
         if (amtloops > 3) {
-          dbg_print("%c NONTRIVIAL: Too many loops/conditionals.", "color:red");
+          dbg_print('%c NONTRIVIAL: Too many loops/conditionals.', 'color:red');
           if (DEBUG == false) {
-            return [false, "NONTRIVIAL: Too many loops/conditionals."];
+            return [false, 'NONTRIVIAL: Too many loops/conditionals.'];
           }
         }
       }
@@ -517,44 +480,44 @@ function full_evaluate(script) {
     } else if (toke.value !== undefined) {
       var status = fname_data[toke.value];
       if (status === true) { // is the identifier banned?
-        dbg_print("%c NONTRIVIAL: nontrivial token: '" + toke.value + "'", "color:red");
+        dbg_print('%c NONTRIVIAL: nontrivial token: \'' + toke.value + '\'', 'color:red');
         if (DEBUG == false) {
-          return [false, "NONTRIVIAL: nontrivial token: '" + toke.value + "'"];
+          return [false, 'NONTRIVIAL: nontrivial token: \'' + toke.value + '\''];
         }
       } else if (status === false) {// is the identifier not banned?
         // Is there bracket suffix notation?
         if (is_bsn(toke.end)) {
-          dbg_print("%c NONTRIVIAL: Bracket suffix notation on variable '" + toke.value + "'", "color:red");
+          dbg_print('%c NONTRIVIAL: Bracket suffix notation on variable \'' + toke.value + '\'', 'color:red');
           if (DEBUG == false) {
-            return [false, "%c NONTRIVIAL: Bracket suffix notation on variable '" + toke.value + "'"];
+            return [false, '%c NONTRIVIAL: Bracket suffix notation on variable \'' + toke.value + '\''];
           }
         }
       } else if (status === undefined) {// is the identifier user defined?
         // Is there bracket suffix notation?
         if (is_bsn(toke.end)) {
-          dbg_print("%c NONTRIVIAL: Bracket suffix notation on variable '" + toke.value + "'", "color:red");
+          dbg_print('%c NONTRIVIAL: Bracket suffix notation on variable \'' + toke.value + '\'', 'color:red');
           if (DEBUG == false) {
-            return [false, "NONTRIVIAL: Bracket suffix notation on variable '" + toke.value + "'"];
+            return [false, 'NONTRIVIAL: Bracket suffix notation on variable \'' + toke.value + '\''];
           }
         }
       } else {
-        dbg_print("trivial token:" + toke.value);
+        dbg_print('trivial token:' + toke.value);
       }
     }
     // If not a keyword or an identifier it's some kind of operator, field parenthesis, brackets
     try {
       toke = tokens.getToken();
     } catch (e) {
-      dbg_print("Denied script because it cannot be parsed.");
-      return [false, "NONTRIVIAL: Cannot be parsed. This could mean it is a 404 error."];
+      dbg_print('Denied script because it cannot be parsed.');
+      return [false, 'NONTRIVIAL: Cannot be parsed. This could mean it is a 404 error.'];
     }
   }
 
-  dbg_print("%cAppears to be trivial.", "color:green;");
+  dbg_print('%cAppears to be trivial.', 'color:green;');
   if (defines_functions === true)
-    return [true, "Script appears to be trivial but defines functions."];
+    return [true, 'Script appears to be trivial but defines functions.'];
   else
-    return [true, "Script appears to be trivial."];
+    return [true, 'Script appears to be trivial.'];
 }
 
 
@@ -573,35 +536,31 @@ function full_evaluate(script) {
 */
 function evaluate(script, name) {
   function reserved_object_regex(object) {
-    var arith_operators = "\\+\\-\\*\\/\\%\\=";
-    var scope_chars = "\{\}\]\[\(\)\,";
-    var trailing_chars = "\s*" + "\(\.\[";
-    return new RegExp("(?:[^\\w\\d]|^|(?:" + arith_operators + "))" + object + '(?:\\s*?(?:[\\;\\,\\.\\(\\[])\\s*?)', "g");
+    var arith_operators = '\\+\\-\\*\\/\\%\\=';
+    return new RegExp('(?:[^\\w\\d]|^|(?:' + arith_operators + '))' + object + '(?:\\s*?(?:[\\;\\,\\.\\(\\[])\\s*?)', 'g');
   }
-  reserved_object_regex("window");
-  var all_strings = new RegExp('".*?"' + "|'.*?'", "gm");
+  reserved_object_regex('window');
   var ml_comment = /\/\*([\s\S]+?)\*\//g;
   var il_comment = /\/\/.+/gm;
-  var bracket_pairs = /\[.+?\]/g;
-  var temp = script.replace(/'.+?'+/gm, "'string'");
+  var temp = script.replace(/'.+?'+/gm, '\'string\'');
   temp = temp.replace(/".+?"+/gm, '"string"');
-  temp = temp.replace(ml_comment, "");
-  temp = temp.replace(il_comment, "");
-  dbg_print("%c ------evaluation results for " + name + "------", "color:white");
-  dbg_print("Script accesses reserved objects?");
+  temp = temp.replace(ml_comment, '');
+  temp = temp.replace(il_comment, '');
+  dbg_print('%c ------evaluation results for ' + name + '------', 'color:white');
+  dbg_print('Script accesses reserved objects?');
   var flag = true;
-  var reason = ""
+  var reason = ''
   // 	This is where individual "passes" are made over the code
   for (var i = 0; i < reserved_objects.length; i++) {
     var res = reserved_object_regex(reserved_objects[i]).exec(temp);
     if (res != null) {
-      dbg_print("%c fail", "color:red;");
+      dbg_print('%c fail', 'color:red;');
       flag = false;
-      reason = "Script uses a reserved object (" + reserved_objects[i] + ")";
+      reason = 'Script uses a reserved object (' + reserved_objects[i] + ')';
     }
   }
   if (flag) {
-    dbg_print("%c pass", "color:green;");
+    dbg_print('%c pass', 'color:green;');
   } else {
     return [flag, reason];
   }
@@ -612,15 +571,15 @@ function evaluate(script, name) {
 
 function validateLicense(matches) {
   if (!(Array.isArray(matches) && matches.length >= 4)) {
-    return [false, "Malformed or unrecognized license tag."];
+    return [false, 'Malformed or unrecognized license tag.'];
   }
 
-  const [all, first] = [matches[0], matches[2].replace("&amp;", "&")];
+  const [all, first] = [matches[0], matches[2].replace('&amp;', '&')];
 
   for (const key in licenses) {
     // Match by link on first parameter (legacy)
     for (const url of licenses[key].canonicalUrl) {
-      if (first === url || first === url.replace("^http://", "https://")) {
+      if (first === url || first === url.replace('^http://', 'https://')) {
         return [true, `Recognized license: "${licenses[key].licenseName}".`];
       }
     }
@@ -647,12 +606,12 @@ function license_read(scriptSrc, name, external = false) {
     return [true, scriptSrc, `Licensed under: ${license}`];
   }
   if (listManager.builtInHashes.has(hash(scriptSrc))) {
-    return [true, scriptSrc, "Common script known to be free software."];
+    return [true, scriptSrc, 'Common script known to be free software.'];
   }
 
-  let editedSrc = "";
+  let editedSrc = '';
   let uneditedSrc = scriptSrc.trim();
-  let reason = uneditedSrc ? "" : "Empty source.";
+  let reason = uneditedSrc ? '' : 'Empty source.';
   let partsDenied = false;
   let partsAccepted = false;
 
@@ -661,14 +620,14 @@ function license_read(scriptSrc, name, external = false) {
       return true; // empty, ignore it
     }
     const [trivial, message] = external ?
-      [false, "External script with no known license"]
+      [false, 'External script with no known license']
       : evaluate(s, name);
     if (trivial) {
       partsAccepted = true;
       editedSrc += s;
     } else {
       partsDenied = true;
-      if (s.startsWith("javascript:"))
+      if (s.startsWith('javascript:'))
         editedSrc += `# LIBREJS BLOCKED: ${message}`;
       else
         editedSrc += `/*\nLIBREJS BLOCKED: ${message}\n*/`;
@@ -678,7 +637,7 @@ function license_read(scriptSrc, name, external = false) {
   }
 
   while (uneditedSrc) {
-    const openingMatch = /\/[\/\*]\s*?(@license)\s+(\S+)\s+(\S+).*$/mi.exec(uneditedSrc);
+    const openingMatch = /\/[/*]\s*?(@license)\s+(\S+)\s+(\S+).*$/mi.exec(uneditedSrc);
     if (!openingMatch) { // no license found, check for triviality
       checkTriviality(uneditedSrc);
       break;
@@ -694,12 +653,12 @@ function license_read(scriptSrc, name, external = false) {
 
     const closureMatch = /\/([*/])\s*@license-end\b[^*/\n]*/i.exec(uneditedSrc);
     if (!closureMatch) {
-      const msg = "ERROR: @license with no @license-end";
+      const msg = 'ERROR: @license with no @license-end';
       return [false, `\n/*\n ${msg} \n*/\n`, msg];
     }
 
-    const closureEndIndex = closureMatch.index + closureMatch[0].length;
-    const commentEndOffset = uneditedSrc.substring(closureEndIndex).indexOf(closureMatch[1] === "*" ? "*/" : "\n");
+    let closureEndIndex = closureMatch.index + closureMatch[0].length;
+    const commentEndOffset = uneditedSrc.substring(closureEndIndex).indexOf(closureMatch[1] === '*' ? '*/' : '\n');
     if (commentEndOffset !== -1) {
       closureEndIndex += commentEndOffset;
     }
@@ -741,17 +700,17 @@ async function get_script(response, url, tabId = -1, whitelisted = false, index
   }
 
 
-  let scriptName = url.split("/").pop();
+  let scriptName = url.split('/').pop();
   if (whitelisted) {
     if (tabId !== -1) {
       let site = ListManager.siteMatch(url, whitelist);
       // Accept without reading script, it was explicitly whitelisted
       let reason = site
         ? `All ${site} whitelisted by user`
-        : "Address whitelisted by user";
-      addReportEntry(tabId, url, { "whitelisted": [site || url, reason], url });
+        : 'Address whitelisted by user';
+      addReportEntry(tabId, { 'whitelisted': [site || url, reason], url });
     }
-    if (response.startsWith("javascript:"))
+    if (response.startsWith('javascript:'))
       return result(response);
     else
       return result(`/* LibreJS: script whitelisted by user preference. */\n${response}`);
@@ -763,25 +722,27 @@ async function get_script(response, url, tabId = -1, whitelisted = false, index
     return result(verdict ? response : editedSource);
   }
 
-  let sourceHash = hash(response);
   let domain = get_domain(url);
   let report = activityReports[tabId] || (activityReports[tabId] = await createReport({ tabId }));
   updateBadge(tabId, report, !verdict);
-  let category = await addReportEntry(tabId, sourceHash, { "url": domain, [verdict ? "accepted" : "blocked"]: [url, reason] });
+  let category = await addReportEntry(tabId, { 'url': domain, [verdict ? 'accepted' : 'blocked']: [url, reason] });
   switch (category) {
-    case "blacklisted":
+    case 'blacklisted': {
       editedSource = `/* LibreJS: script ${category} by user. */`;
-      return result(response.startsWith("javascript:")
+      return result(response.startsWith('javascript:')
         ? `javascript:void(${encodeURIComponent(editedSource)})` : editedSource);
-    case "whitelisted":
-      return result(response.startsWith("javascript:")
+    }
+    case 'whitelisted': {
+      return result(response.startsWith('javascript:')
         ? response : `/* LibreJS: script ${category} by user. */\n${response}`);
-    default:
+    }
+    default: {
       let scriptSource = verdict ? response : editedSource;
-      return result(response.startsWith("javascript:")
+      return result(response.startsWith('javascript:')
         ? (verdict ? scriptSource : `javascript:void(/* ${scriptSource} */)`)
         : `/* LibreJS: script ${category}. */\n${scriptSource}`
       );
+    }
   }
 }
 
@@ -789,9 +750,9 @@ async function get_script(response, url, tabId = -1, whitelisted = false, index
 function updateBadge(tabId, report = null, forceRed = false) {
   let blockedCount = report ? report.blocked.length + report.blacklisted.length : 0;
   let [text, color] = blockedCount > 0 || forceRed
-    ? [blockedCount && blockedCount.toString() || "!", "red"] : ["✓", "green"]
+    ? [blockedCount && blockedCount.toString() || '!', 'red'] : ['✓', 'green']
   let { browserAction } = browser;
-  if ("setBadgeText" in browserAction) {
+  if ('setBadgeText' in browserAction) {
     browserAction.setBadgeText({ text, tabId });
     browserAction.setBadgeBackgroundColor({ color, tabId });
   } else {
@@ -815,11 +776,11 @@ async function blockBlacklistedScripts(request) {
   let { url, tabId, documentUrl } = request;
   url = ListStore.urlItem(url);
   let status = listManager.getStatus(url);
-  if (status !== "blacklisted") return {};
+  if (status !== 'blacklisted') return {};
   let blacklistedSite = ListManager.siteMatch(url, blacklist);
-  await addReportEntry(tabId, url, {
+  await addReportEntry(tabId, {
     url: documentUrl,
-    "blacklisted": [url, /\*/.test(blacklistedSite) ? `User blacklisted ${blacklistedSite}` : "Blacklisted by user"]
+    'blacklisted': [url, /\*/.test(blacklistedSite) ? `User blacklisted ${blacklistedSite}` : 'Blacklisted by user']
   });
   return { cancel: true };
 }
@@ -844,36 +805,36 @@ var ResponseHandler = {
 
     let blacklistedSite = ListManager.siteMatch(site, blacklist);
     let blacklisted = blacklistedSite || blacklist.contains(url);
-    let topUrl = type === "sub_frame" && request.frameAncestors && request.frameAncestors.pop() || documentUrl;
+    let topUrl = type === 'sub_frame' && request.frameAncestors && request.frameAncestors.pop() || documentUrl;
 
     if (blacklisted) {
-      if (type === "script") {
+      if (type === 'script') {
         // this shouldn't happen, because we intercept earlier in blockBlacklistedScripts()
         return ResponseProcessor.REJECT;
       }
-      if (type === "main_frame") { // we handle the page change here too, since we won't call edit_html()
+      if (type === 'main_frame') { // we handle the page change here too, since we won't call edit_html()
         activityReports[tabId] = await createReport({ url: fullUrl, tabId });
         // Go on without parsing the page: it was explicitly blacklisted
         let reason = blacklistedSite
           ? `All ${blacklistedSite} blacklisted by user`
-          : "Address blacklisted by user";
-        await addReportEntry(tabId, url, { "blacklisted": [blacklistedSite || url, reason], url: fullUrl });
+          : 'Address blacklisted by user';
+        await addReportEntry(tabId, { 'blacklisted': [blacklistedSite || url, reason], url: fullUrl });
       }
       // use CSP to restrict JavaScript execution in the page
       request.responseHeaders.unshift({
-        name: `Content-security-policy`,
-        value: `script-src 'none';`
+        name: 'Content-security-policy',
+        value: 'script-src \'none\';'
       });
       return { responseHeaders: request.responseHeaders }; // let's skip the inline script parsing, since we block by CSP
     } else {
       let whitelistedSite = ListManager.siteMatch(site, whitelist);
       let whitelisted = response.whitelisted = whitelistedSite || whitelist.contains(url);
-      if (type === "script") {
+      if (type === 'script') {
         if (whitelisted) {
           // accept the script and stop processing
-          addReportEntry(tabId, url, {
+          addReportEntry(tabId, {
             url: topUrl,
-            "whitelisted": [url, whitelistedSite ? `User whitelisted ${whitelistedSite}` : "Whitelisted by user"]
+            'whitelisted': [url, whitelistedSite ? `User whitelisted ${whitelistedSite}` : 'Whitelisted by user']
           });
           return ResponseProcessor.ACCEPT;
         } else {
@@ -882,13 +843,13 @@ var ResponseHandler = {
             let verdict, ret;
             let msg = scriptInfo.toString();
             if (scriptInfo.free) {
-              verdict = "accepted";
+              verdict = 'accepted';
               ret = ResponseProcessor.ACCEPT;
             } else {
-              verdict = "blocked";
+              verdict = 'blocked';
               ret = ResponseProcessor.REJECT;
             }
-            addReportEntry(tabId, url, { url, [verdict]: [url, msg] });
+            addReportEntry(tabId, { url, [verdict]: [url, msg] });
             return ret;
           }
         }
@@ -904,7 +865,7 @@ var ResponseHandler = {
   */
   async post(response) {
     let { type } = response.request;
-    let handle_it = type === "script" ? handle_script : handle_html;
+    let handle_it = type === 'script' ? handle_script : handle_html;
     return await handle_it(response, response.whitelisted);
   }
 }
@@ -914,7 +875,7 @@ var ResponseHandler = {
 */
 async function handle_script(response, whitelisted) {
   let { text, request } = response;
-  let { url, tabId, frameId } = request;
+  let { url, tabId } = request;
   url = ListStore.urlItem(url);
   let edited = await get_script(text, url, tabId, whitelisted, -2);
   return Array.isArray(edited) ? edited[0] : edited;
@@ -928,7 +889,7 @@ function doc2HTML(doc) {
   let s = doc.documentElement.outerHTML;
   if (doc.doctype) {
     let dt = doc.doctype;
-    let sDoctype = `<!DOCTYPE ${dt.name || "html"}`;
+    let sDoctype = `<!DOCTYPE ${dt.name || 'html'}`;
     if (dt.publicId) sDoctype += ` PUBLIC "${dt.publicId}"`;
     if (dt.systemId) sDoctype += ` "${dt.systemId}"`;
     s = `${sDoctype}>\n${s}`;
@@ -940,7 +901,7 @@ function doc2HTML(doc) {
 * Shortcut to create a correctly namespaced DOM HTML elements
 */
 function createHTMLElement(doc, name) {
-  return doc.createElementNS("http://www.w3.org/1999/xhtml", name);
+  return doc.createElementNS('http://www.w3.org/1999/xhtml', name);
 }
 
 /**
@@ -948,7 +909,7 @@ function createHTMLElement(doc, name) {
 * NOSCRIPT elements to visible the same way as NoScript and uBlock do)
 */
 function forceElement(doc, element) {
-  let replacement = createHTMLElement(doc, "span");
+  let replacement = createHTMLElement(doc, 'span');
   replacement.innerHTML = element.innerHTML;
   element.replaceWith(replacement);
   return replacement;
@@ -962,12 +923,11 @@ function forceElement(doc, element) {
 function forceNoscriptElements(doc) {
   let shown = 0;
   // inspired by NoScript's onScriptDisabled.js
-  for (let noscript of doc.querySelectorAll("noscript:not([data-librejs-nodisplay])")) {
+  for (let noscript of doc.querySelectorAll('noscript:not([data-librejs-nodisplay])')) {
     let replacement = forceElement(doc, noscript);
     // emulate meta-refresh
     let meta = replacement.querySelector('meta[http-equiv="refresh"]');
     if (meta) {
-      refresh = true;
       doc.head.appendChild(meta);
     }
     shown++;
@@ -981,7 +941,7 @@ function forceNoscriptElements(doc) {
 */
 function showConditionalElements(doc) {
   let shown = 0;
-  for (let element of document.querySelectorAll("[data-librejs-display]")) {
+  for (let element of document.querySelectorAll('[data-librejs-display]')) {
     forceElement(doc, element);
     shown++;
   }
@@ -998,27 +958,27 @@ function read_metadata(meta_element) {
     return;
   }
 
-  console.log("metadata found");
+  console.log('metadata found');
 
   var metadata = {};
 
   try {
     metadata = JSON.parse(meta_element.innerHTML);
   } catch (error) {
-    console.log("Could not parse metadata on page.")
+    console.log('Could not parse metadata on page.')
     return false;
   }
 
-  var license_str = metadata["intrinsic-events"];
+  var license_str = metadata['intrinsic-events'];
   if (license_str === undefined) {
-    console.log("No intrinsic events license");
+    console.log('No intrinsic events license');
     return false;
   }
   console.log(license_str);
 
-  var parts = license_str.split(" ");
+  var parts = license_str.split(' ');
   if (parts.length != 2) {
-    console.log("invalid (>2 tokens)");
+    console.log('invalid (>2 tokens)');
     return false;
   }
 
@@ -1026,15 +986,15 @@ function read_metadata(meta_element) {
   parts[0] = parts[0].replace(/&amp;/g, '&');
 
   try {
-    for (const url of licenses[part[1]].canonicalUrl) {
-      if (url.startsWith("magnet:") && url == parts[0]) {
+    for (const url of licenses[parts[1]].canonicalUrl) {
+      if (url.startsWith('magnet:') && url == parts[0]) {
         return true;
       }
     }
-    console.log("invalid (doesn't match licenses)");
+    console.log('invalid (doesn\'t match licenses)');
     return false;
   } catch (error) {
-    console.log("invalid (threw error, key didn't exist)");
+    console.log('invalid (threw error, key didn\'t exist)');
     return false;
   }
 }
@@ -1045,7 +1005,7 @@ function read_metadata(meta_element) {
 async function editHtml(html, documentUrl, tabId, frameId, whitelisted) {
 
   var parser = new DOMParser();
-  var html_doc = parser.parseFromString(html, "text/html");
+  var html_doc = parser.parseFromString(html, 'text/html');
 
   // moves external licenses reference, if any, before any <SCRIPT> element
   ExternalLicenses.optimizeDocument(html_doc, { tabId, frameId, documentUrl });
@@ -1059,8 +1019,8 @@ async function editHtml(html, documentUrl, tabId, frameId, whitelisted) {
 
   var scripts = html_doc.scripts;
 
-  var meta_element = html_doc.getElementById("LibreJS-info");
-  var first_script_src = "";
+  var meta_element = html_doc.getElementById('LibreJS-info');
+  var first_script_src = '';
 
   // get the potential inline source that can contain a license
   for (let script of scripts) {
@@ -1072,38 +1032,36 @@ async function editHtml(html, documentUrl, tabId, frameId, whitelisted) {
   }
 
   let license = false;
-  if (first_script_src != "") {
+  if (first_script_src != '') {
     license = legacy_license_lib.check(first_script_src);
   }
 
   let findLine = finder => finder.test(html) && html.substring(0, finder.lastIndex).split(/\n/).length || 0;
   if (read_metadata(meta_element) || license) {
-    console.log("Valid license for intrinsic events found");
+    console.log('Valid license for intrinsic events found');
     let line, extras;
     if (meta_element) {
       line = findLine(/id\s*=\s*['"]?LibreJS-info\b/gi);
-      extras = "(0)";
+      extras = '(0)';
     } else if (license) {
       line = html.substring(0, html.indexOf(first_script_src)).split(/\n/).length;
-      extras = "\n" + first_script_src;
+      extras = '\n' + first_script_src;
     }
-    let viewUrl = line ? `view-source:${documentUrl}#line${line}(<${meta_element ? meta_element.tagName : "SCRIPT"}>)${extras}` : url;
-    addReportEntry(tabId, url, { url, "accepted": [viewUrl, `Global license for the page: ${license}`] });
+    let viewUrl = line ? `view-source:${documentUrl}#line${line}(<${meta_element ? meta_element.tagName : 'SCRIPT'}>)${extras}` : url;
+    addReportEntry(tabId, { url, 'accepted': [viewUrl, `Global license for the page: ${license}`] });
     // Do not process inline scripts
     scripts = [];
   } else {
     let dejaVu = new Map(); // deduplication map & edited script cache
     let modified = false;
     // Deal with intrinsic events
-    let intrinsecindex = 0;
     let intrinsicFinder = /<[a-z][^>]*\b(on\w+|href\s*=\s*['"]?javascript:)/gi;
-    for (let element of html_doc.all) {
+    for (let element of html_doc.querySelectorAll('*')) {
       let line = -1;
       for (let attr of element.attributes) {
         let { name, value } = attr;
         value = value.trim();
-        if (name.startsWith("on") || (name === "href" && value.toLowerCase().startsWith("javascript:"))) {
-          intrinsecindex++;
+        if (name.startsWith('on') || (name === 'href' && value.toLowerCase().startsWith('javascript:'))) {
           if (line === -1) {
             line = findLine(intrinsicFinder);
           }
@@ -1114,7 +1072,7 @@ async function editHtml(html, documentUrl, tabId, frameId, whitelisted) {
               edited = dejaVu.get(key);
             } else {
               let url = `view-source:${documentUrl}#line${line}(<${element.tagName} ${name}>)\n${value.trim()}`;
-              if (name === "href") value = decodeURIComponent(value);
+              if (name === 'href') value = decodeURIComponent(value);
               edited = await get_script(value, url, tabId, whitelist.contains(url)); dejaVu.set(key, edited);
             }
             if (edited && edited !== value) {
@@ -1133,7 +1091,7 @@ async function editHtml(html, documentUrl, tabId, frameId, whitelisted) {
     for (let i = 0, len = scripts.length; i < len; i++) {
       let script = scripts[i];
       let line = findLine(scriptFinder);
-      if (!script.src && !(script.type && script.type !== "text/javascript")) {
+      if (!script.src && !(script.type && script.type !== 'text/javascript')) {
         let source = script.textContent.trim();
         let editedSource;
         if (dejaVu.has(source)) {
@@ -1170,18 +1128,18 @@ async function editHtml(html, documentUrl, tabId, frameId, whitelisted) {
 async function handle_html(response, whitelisted) {
   let { text, request } = response;
   let { url, tabId, frameId, type } = request;
-  if (type === "main_frame") {
+  if (type === 'main_frame') {
     activityReports[tabId] = await createReport({ url, tabId });
     updateBadge(tabId);
   }
   return await editHtml(text, url, tabId, frameId, whitelisted);
 }
 
-var whitelist = new ListStore("pref_whitelist", Storage.CSV);
-var blacklist = new ListStore("pref_blacklist", Storage.CSV);
+var whitelist = new ListStore('pref_whitelist', Storage.CSV);
+var blacklist = new ListStore('pref_blacklist', Storage.CSV);
 var listManager = new ListManager(whitelist, blacklist,
   // built-in whitelist of script hashes, e.g. jQuery
-  Object.values(require("./hash_script/whitelist").whitelist)
+  Object.values(require('./hash_script/whitelist').whitelist)
     .reduce((a, b) => a.concat(b)) // as a flat array
     .map(script => script.hash)
 );
@@ -1189,7 +1147,7 @@ var listManager = new ListManager(whitelist, blacklist,
 
 async function initDefaults() {
   let defaults = {
-    pref_subject: "Issues with Javascript on your website",
+    pref_subject: 'Issues with Javascript on your website',
     pref_body: `Please consider using a free license for the Javascript on your website.
 
 [Message generated by LibreJS. See https://www.gnu.org/software/librejs/ for more information]
@@ -1223,18 +1181,18 @@ async function init_addon() {
   browser.tabs.onActivated.addListener(onTabActivated);
   // Prevents Google Analytics from being loaded from Google servers
   let all_types = [
-    "beacon", "csp_report", "font", "image", "imageset", "main_frame", "media",
-    "object", "object_subrequest", "ping", "script", "stylesheet", "sub_frame",
-    "web_manifest", "websocket", "xbl", "xml_dtd", "xmlhttprequest", "xslt",
-    "other"
+    'beacon', 'csp_report', 'font', 'image', 'imageset', 'main_frame', 'media',
+    'object', 'object_subrequest', 'ping', 'script', 'stylesheet', 'sub_frame',
+    'web_manifest', 'websocket', 'xbl', 'xml_dtd', 'xmlhttprequest', 'xslt',
+    'other'
   ];
   browser.webRequest.onBeforeRequest.addListener(blockGoogleAnalytics,
-    { urls: ["<all_urls>"], types: all_types },
-    ["blocking"]
+    { urls: ['<all_urls>'], types: all_types },
+    ['blocking']
   );
   browser.webRequest.onBeforeRequest.addListener(blockBlacklistedScripts,
-    { urls: ["<all_urls>"], types: ["script"] },
-    ["blocking"]
+    { urls: ['<all_urls>'], types: ['script'] },
+    ['blocking']
   );
   browser.webRequest.onResponseStarted.addListener(request => {
     let { tabId } = request;
@@ -1242,15 +1200,14 @@ async function init_addon() {
     if (report) {
       updateBadge(tabId, activityReports[tabId]);
     }
-  }, { urls: ["<all_urls>"], types: ["main_frame"] });
+  }, { urls: ['<all_urls>'], types: ['main_frame'] });
 
   // Analyzes all the html documents and external scripts as they're loaded
   ResponseProcessor.install(ResponseHandler);
 
   legacy_license_lib.init();
 
-
-  let Test = require("./common/Test");
+  const Test = require('./common/Test');
   if (Test.getURL()) {
     // export testable functions to the global scope
     this.LibreJS = {
@@ -1260,7 +1217,7 @@ async function init_addon() {
       ListManager, ListStore, Storage,
     };
     // create or focus the autotest tab if it's a debugging session
-    if ((await browser.management.getSelf()).installType === "development") {
+    if ((await browser.management.getSelf()).installType === 'development') {
       Test.getTab(true);
     }
   }
@@ -1272,8 +1229,8 @@ async function init_addon() {
 */
 async function injectContactFinder(tabId) {
   await Promise.all([
-    browser.tabs.insertCSS(tabId, { file: "/content/overlay.css", cssOrigin: "user" }),
-    browser.tabs.executeScript(tabId, { file: "/content/contactFinder.js" }),
+    browser.tabs.insertCSS(tabId, { file: '/content/overlay.css', cssOrigin: 'user' }),
+    browser.tabs.executeScript(tabId, { file: '/content/contactFinder.js' }),
   ]);
 }
 
diff --git a/test/spec/LibreJSSpec.js b/test/spec/LibreJSSpec.js
index 1320a2a..9e96af5 100644
--- a/test/spec/LibreJSSpec.js
+++ b/test/spec/LibreJSSpec.js
@@ -18,9 +18,9 @@
 * You should have received a copy of the GNU General Public License
 * along with GNU LibreJS.  If not, see <http://www.gnu.org/licenses/>.
 */
-"use strict";
+'use strict';
 
-describe("LibreJS' components", () => {
+describe('LibreJS\' components', () => {
   let LibreJS = browser.extension.getBackgroundPage().LibreJS;
   let license = {
     id: 'GPL-3.0',
@@ -33,60 +33,60 @@ describe("LibreJS' components", () => {
     magnet: 'magnet:?xt=urn:btih:2f739d935676111cfff4b4693e3816e664797050&dn=acme-1.5.txt'
   };
 
-  let trivial = "1+1";
-  let nontrivial = `function nt() { document.documentElement.innerHTML=""; nt(); }`;
+  let trivial = '1+1';
+  let nontrivial = 'function nt() { document.documentElement.innerHTML=""; nt(); }';
   let licensed = `// @license ${license.magnet} ${license.id}\n${nontrivial}\n// @license-end`;
   let unknownLicensed = `// @license ${unknownLicense.magnet} ${unknownLicense.id}\n${nontrivial}\n// @license-end`;
   let malformedLicensed = `// @license\n${nontrivial}`;
   let tab, documentUrl;
 
   beforeAll(async () => {
-    let url = browser.extension.getURL("/test/resources/index.html");
+    let url = browser.extension.getURL('/test/resources/index.html');
     tab = (await browser.tabs.query({ url }))[0] || (await browser.tabs.create({ url }));
     documentUrl = url;
 
   });
 
-  describe("The whitelist/blacklist manager", () => {
+  describe('The whitelist/blacklist manager', () => {
     let { ListManager, ListStore, Storage } = LibreJS;
-    let lm = new ListManager(new ListStore("_test.whitelist", Storage.CSV), new ListStore("_test.blacklist", Storage.CSV), new Set());
-    let forgot = ["http://formerly.whitelist.ed/", "http://formerly.blacklist.ed/"];
+    let lm = new ListManager(new ListStore('_test.whitelist', Storage.CSV), new ListStore('_test.blacklist', Storage.CSV), new Set());
+    let forgot = ['http://formerly.whitelist.ed/', 'http://formerly.blacklist.ed/'];
 
     beforeAll(async () => {
-      await lm.whitelist("https://fsf.org/*", "https://*.gnu.org/*", forgot[0]);
-      await lm.blacklist("https://*.evil.gnu.org/*", "https://verybad.com/*", forgot[1]);
+      await lm.whitelist('https://fsf.org/*', 'https://*.gnu.org/*', forgot[0]);
+      await lm.blacklist('https://*.evil.gnu.org/*', 'https://verybad.com/*', forgot[1]);
     });
 
-    it("Should handle basic CRUD operations", async () => {
-      expect(lm.getStatus(forgot[0])).toBe("whitelisted");
-      expect(lm.getStatus(forgot[1])).toBe("blacklisted");
+    it('Should handle basic CRUD operations', async () => {
+      expect(lm.getStatus(forgot[0])).toBe('whitelisted');
+      expect(lm.getStatus(forgot[1])).toBe('blacklisted');
 
       await lm.forget(...forgot);
 
       for (let url of forgot) {
-        expect(lm.getStatus(url)).toBe("unknown");
+        expect(lm.getStatus(url)).toBe('unknown');
       }
     });
 
-    it("Should support full path wildcards", () => {
-      expect(lm.getStatus("https://unknown.org")).toBe("unknown");
-      expect(lm.getStatus("https://fsf.org/some/path")).toBe("whitelisted");
-      expect(lm.getStatus("https://fsf.org/")).toBe("whitelisted");
-      expect(lm.getStatus("https://fsf.org")).toBe("whitelisted");
-      expect(lm.getStatus("https://subdomain.fsf.org")).toBe("unknown");
-      expect(lm.getStatus("https://verybad.com/some/other/path?with=querystring")).toBe("blacklisted");
+    it('Should support full path wildcards', () => {
+      expect(lm.getStatus('https://unknown.org')).toBe('unknown');
+      expect(lm.getStatus('https://fsf.org/some/path')).toBe('whitelisted');
+      expect(lm.getStatus('https://fsf.org/')).toBe('whitelisted');
+      expect(lm.getStatus('https://fsf.org')).toBe('whitelisted');
+      expect(lm.getStatus('https://subdomain.fsf.org')).toBe('unknown');
+      expect(lm.getStatus('https://verybad.com/some/other/path?with=querystring')).toBe('blacklisted');
     });
-    it("Should support subdomain wildcards", () => {
-      expect(lm.getStatus("https://gnu.org")).toBe("whitelisted");
-      expect(lm.getStatus("https://www.gnu.org")).toBe("whitelisted");
-      expect(lm.getStatus("https://evil.gnu.org")).toBe("blacklisted");
-      expect(lm.getStatus("https://more.evil.gnu.org")).toBe("blacklisted");
-      expect(lm.getStatus("https://more.evil.gnu.org/some/evil/path?too")).toBe("blacklisted");
+    it('Should support subdomain wildcards', () => {
+      expect(lm.getStatus('https://gnu.org')).toBe('whitelisted');
+      expect(lm.getStatus('https://www.gnu.org')).toBe('whitelisted');
+      expect(lm.getStatus('https://evil.gnu.org')).toBe('blacklisted');
+      expect(lm.getStatus('https://more.evil.gnu.org')).toBe('blacklisted');
+      expect(lm.getStatus('https://more.evil.gnu.org/some/evil/path?too')).toBe('blacklisted');
     });
   })
 
-  describe("The external script source processor", () => {
-    let url = "https://www.gnu.org/mock-script.js";
+  describe('The external script source processor', () => {
+    let url = 'https://www.gnu.org/mock-script.js';
 
     let processScript = async (source, whitelisted = false) =>
       await LibreJS.handle_script({
@@ -94,125 +94,125 @@ describe("LibreJS' components", () => {
         request: { url, tabId: tab.id, documentUrl, frameId: 0 },
       }, whitelisted);
 
-    it("should accept whitelisted scripts", async () => {
+    it('should accept whitelisted scripts', async () => {
       expect(await processScript(nontrivial, true) || nontrivial).toContain(nontrivial);
     });
 
-    it("should block trivial scripts too", async () => {
+    it('should block trivial scripts too', async () => {
       let processed = await processScript(trivial);
       expect(processed || trivial).not.toContain(trivial);
     });
 
-    it("should block non-trivial scripts", async () => {
+    it('should block non-trivial scripts', async () => {
       let processed = await processScript(nontrivial);
       expect(processed || nontrivial).not.toContain(nontrivial);
     });
 
-    it("should accept scripts with known free license tags", async () => {
+    it('should accept scripts with known free license tags', async () => {
       let processed = await processScript(licensed);
       expect(processed || licensed).toContain(nontrivial);
     });
 
-    it("should block scripts with unknown license tags", async () => {
+    it('should block scripts with unknown license tags', async () => {
       let processed = await processScript(unknownLicensed);
       expect(processed).not.toContain(nontrivial);
     });
 
-    it("should block scripts with malformed license tags", async () => {
+    it('should block scripts with malformed license tags', async () => {
       let processed = await processScript(malformedLicensed);
       expect(processed).not.toContain(nontrivial);
     });
   });
 
-  describe("The HTML processor", () => {
+  describe('The HTML processor', () => {
     let processHtml =
       async (html, whitelisted = false) =>
         LibreJS.editHtml(html, tab.url, tab.id, 0, whitelisted);
 
-    let addScript = (html, script, before = "</head>") =>
+    let addScript = (html, script, before = '</head>') =>
       html.replace(before, `<script>${script}</script>${before}`);
 
-    let addToBody = (html, fragment) => html.replace("</body>", `${fragment}</body>`);
+    let addToBody = (html, fragment) => html.replace('</body>', `${fragment}</body>`);
 
     let jsUrl = js => `javascript:${encodeURIComponent(js)}`;
 
-    function extractScripts(html, def = "") {
+    function extractScripts(html, def = '') {
       let matches = html && html.match(/<script>[^]*?<\/script>/g);
-      return matches && matches.join("") || def;
+      return matches && matches.join('') || def;
     }
 
     let html, nontrivialInHtml;
     beforeAll(async () => {
       html = (await browser.tabs.executeScript(tab.id, {
-        runAt: "document_start",
-        code: "document.documentElement.outerHTML"
+        runAt: 'document_start',
+        code: 'document.documentElement.outerHTML'
       }))[0];
       nontrivialInHtml = addScript(html, nontrivial);
     });
 
-    it("should not modify scriptless documents", async () => {
+    it('should not modify scriptless documents', async () => {
       expect(await processHtml(html)).toBeNull();
     });
 
-    it("should not modify whitelisted documents", async () => {
+    it('should not modify whitelisted documents', async () => {
       expect(await processHtml(nontrivialInHtml, true)).toBeNull();
     });
 
-    it("should accept trivial scripts", async () => {
+    it('should accept trivial scripts', async () => {
       let trivialInHtml = addScript(html, trivial);
       let processed = await processHtml(trivialInHtml);
       expect(extractScripts(processed, trivial)).toContain(trivial);
     });
 
-    it("should block non-trivial scripts", async () => {
+    it('should block non-trivial scripts', async () => {
       let processed = await processHtml(nontrivialInHtml);
       expect(extractScripts(processed, nontrivial)).not.toContain(nontrivial);
     });
 
-    it("should accept scripts with known free license tags", async () => {
+    it('should accept scripts with known free license tags', async () => {
       let licensedInHtml = addScript(html, licensed);
       let processed = await processHtml(licensedInHtml);
       expect(extractScripts(processed, licensed)).toContain(nontrivial);
     });
 
-    it("should block scripts with unknown license tags", async () => {
+    it('should block scripts with unknown license tags', async () => {
       let unknownInHtml = addScript(html, unknownLicensed);
       let processed = await processHtml(unknownInHtml);
       expect(extractScripts(processed, nontrivial)).not.toContain(nontrivial);
     });
 
-    it("should block scripts with malformed license tags", async () => {
+    it('should block scripts with malformed license tags', async () => {
       let malformedInHtml = addScript(html, malformedLicensed);
       let processed = await processHtml(malformedInHtml);
       expect(extractScripts(processed, nontrivial)).not.toContain(nontrivial);
     });
 
-    it("should accept scripts on globally licensed pages", async () => {
+    it('should accept scripts on globally licensed pages', async () => {
       let globalLicense = `/* @licstart The following is the entire license notice
         for the JavaScript code in this page.
         -- Some free license --
         @licend The above is the entire license notice for the JavaScript code in this page. */`;
 
-      let licensed = addScript(nontrivialInHtml, globalLicense, "<script>");
+      let licensed = addScript(nontrivialInHtml, globalLicense, '<script>');
       let processed = await processHtml(html);
       expect(extractScripts(processed, licensed)).toContain(nontrivial);
     });
 
-    it("should discriminate trivial, non-trivial and licensed mixed on the same page", async () => {
+    it('should discriminate trivial, non-trivial and licensed mixed on the same page', async () => {
       let mixedPage = addScript(addScript(nontrivialInHtml, trivial), licensed);
       let processed = await processHtml(mixedPage);
       expect(processed).not.toBeNull();
       let scripts = extractScripts(processed, nontrivial);
       expect(scripts).toContain(trivial);
       expect(scripts).toContain(licensed);
-      expect(scripts.replace(licensed, "")).not.toContain(nontrivial);
+      expect(scripts.replace(licensed, '')).not.toContain(nontrivial);
     });
 
-    it("should correctly process (de)duplicated inline scripts", async () => {
+    it('should correctly process (de)duplicated inline scripts', async () => {
       let trivialAsUrl = jsUrl(trivial);
       let nontrivialAsUrl = jsUrl(nontrivial);
       let a = (url, label) => `<a href="${url}">${label}</a>`;
-      let mixedPage = `<body></body>`;
+      let mixedPage = '<body></body>';
       for (let dup = 0; dup < 3; dup++) {
         mixedPage = addToBody(mixedPage, a(trivialAsUrl, `Trivial #${dup}`));
         mixedPage = addToBody(mixedPage, a(nontrivialAsUrl, `Nontrivial #${dup}`));
@@ -223,8 +223,8 @@ describe("LibreJS' components", () => {
       expect(processed).not.toContain(nontrivialAsUrl);
     });
 
-    it("should force displaying NOSCRIPT elements (except those with @data-librejs-nodisplay) where scripts have been blocked", async () => {
-      let noscriptContent = "I'm NOSCRIPT content";
+    it('should force displaying NOSCRIPT elements (except those with @data-librejs-nodisplay) where scripts have been blocked', async () => {
+      let noscriptContent = 'I\'m NOSCRIPT content';
       let asNoscript = `<noscript>${noscriptContent}</noscript>`;
       let asNodisplay = `<noscript data-librejs-nodisplay>${noscriptContent}</noscript>`;
       let asSpan = `<span>${noscriptContent}</span>`;
@@ -235,11 +235,11 @@ describe("LibreJS' components", () => {
       expect(processed).not.toContain(asNodisplay);
     });
 
-    it("should always force displaying @data-librejs-display elements", async () => {
-      let content = "I'm FORCED content";
+    it('should always force displaying @data-librejs-display elements', async () => {
+      let content = 'I\'m FORCED content';
       let asDisplay = `<span data-librejs-display>${content}</span>`;
       let asSpan = `<span>${content}</span>`;
-      for (let page of [nontrivialInHtml, "<body></body>"]) {
+      for (let page of [nontrivialInHtml, '<body></body>']) {
         page = addToBody(page, asDisplay);
         let processed = await processHtml(page);
         expect(processed).not.toContain(asDisplay);
@@ -248,7 +248,7 @@ describe("LibreJS' components", () => {
     });
   });
 
-  describe("The external (Web Labels) license checker", () => {
+  describe('The external (Web Labels) license checker', () => {
     let { ExternalLicenses } = LibreJS;
     let check;
 
@@ -257,27 +257,27 @@ describe("LibreJS' components", () => {
       let resolve = url => new URL(url, documentUrl).href;
       check = async url => await ExternalLicenses.check(Object.assign({ url: resolve(url) }, args));
       await browser.tabs.executeScript(tab.id, {
-        file: "/content/externalLicenseChecker.js"
+        file: '/content/externalLicenseChecker.js'
       });
     });
 
-    it("should recognize free licenses", async () => {
-      let scriptInfo = await check("jquery.js");
+    it('should recognize free licenses', async () => {
+      let scriptInfo = await check('jquery.js');
       console.debug(scriptInfo);
       expect(scriptInfo.free).toBeTruthy();
     });
-    it("should accept scripts if any of multiple licenses is free", async () => {
-      let scriptInfo = await check("app-trilicensed.js");
+    it('should accept scripts if any of multiple licenses is free', async () => {
+      let scriptInfo = await check('app-trilicensed.js');
       console.debug(scriptInfo);
       expect(scriptInfo.free).toBeTruthy();
     });
-    it("should block scripts declaring only proprietary license(s)", async () => {
-      let scriptInfo = await check("proprietary.js");
+    it('should block scripts declaring only proprietary license(s)', async () => {
+      let scriptInfo = await check('proprietary.js');
       console.debug(scriptInfo);
       expect(scriptInfo.free).toBeFalsy();
     });
-    it("should block scripts not declaring any license", async () => {
-      let scriptInfo = await check("tracker.js");
+    it('should block scripts not declaring any license', async () => {
+      let scriptInfo = await check('tracker.js');
       console.debug(scriptInfo);
       expect(scriptInfo).toBeNull();
     });
-- 
cgit v1.2.3