Index: background.js
diff --git a/background.js b/background.js
index cfc9536c00e1c2d3a57673cbaecff059253279fc..3df38b6b5797b9ecaae1b53b9f558db14b814242 100644
--- a/background.js
+++ b/background.js
@@ -15,23 +15,25 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-var RegExpFilter = require("filterClasses").RegExpFilter;
-var ElemHide = require("elemHide").ElemHide;
-var checkWhitelisted = require("whitelisting").checkWhitelisted;
-var extractHostFromFrame = require("url").extractHostFromFrame;
-var port = require("messaging").port;
-var devtools = require("devtools");
+"use strict";
 
-port.on("get-selectors", function(msg, sender)
+const {RegExpFilter} = require("filterClasses");
+const {ElemHide} = require("elemHide");
+const {checkWhitelisted} = require("whitelisting");
+const {extractHostFromFrame} = require("url");
+const {port} = require("messaging");
+const devtools = require("devtools");
+
+port.on("get-selectors", (msg, sender) =>
 {
-  var selectors;
-  var trace = devtools && devtools.hasPanel(sender.page);
+  let selectors;
+  let trace = devtools && devtools.hasPanel(sender.page);
 
   if (!checkWhitelisted(sender.page, sender.frame,
                         RegExpFilter.typeMap.DOCUMENT |
                         RegExpFilter.typeMap.ELEMHIDE))
   {
-    var specificOnly = checkWhitelisted(sender.page, sender.frame,
+    let specificOnly = checkWhitelisted(sender.page, sender.frame,
                                         RegExpFilter.typeMap.GENERICHIDE);
     selectors = ElemHide.getSelectorsForDomain(
       extractHostFromFrame(sender.frame),
@@ -46,9 +48,9 @@ port.on("get-selectors", function(msg, sender)
   return {selectors: selectors, trace: trace};
 });
 
-port.on("forward", function(msg, sender)
+port.on("forward", (msg, sender) =>
 {
-  var targetPage;
+  let targetPage;
   if (msg.targetPageId)
     targetPage = ext.getPage(msg.targetPageId);
   else
Index: chrome/ext/background.js
diff --git a/chrome/ext/background.js b/chrome/ext/background.js
index 87a044d3a62c4502066eb47e03fa08109ab21c4f..8cec8296408b0cafb5452c7eb0afb6e67d59035b 100644
--- a/chrome/ext/background.js
+++ b/chrome/ext/background.js
@@ -15,11 +15,12 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-(function()
+"use strict";
+
 {
   /* Pages */
 
-  var Page = ext.Page = function(tab)
+  let Page = ext.Page = function(tab)
   {
     this.id = tab.id;
     this._url = tab.url && new URL(tab.url);
@@ -38,30 +39,27 @@
       // but sometimes we only have the tab id when we create a Page object.
       // In that case we get the url from top frame of the tab, recorded by
       // the onBeforeRequest handler.
-      var frames = framesOfTabs[this.id];
+      let frames = framesOfTabs[this.id];
       if (frames)
       {
-        var frame = frames[0];
+        let frame = frames[0];
         if (frame)
           return frame.url;
       }
     },
-    sendMessage: function(message, responseCallback)
+    sendMessage(message, responseCallback)
     {
       chrome.tabs.sendMessage(this.id, message, responseCallback);
     }
   };
 
-  ext.getPage = function(id)
-  {
-    return new Page({id: parseInt(id, 10)});
-  };
+  ext.getPage = id => new Page({id: parseInt(id, 10)});
 
   function afterTabLoaded(callback)
   {
-     return function(openedTab)
+     return openedTab =>
      {
-       var onUpdated = function(tabId, changeInfo, tab)
+       let onUpdated = (tabId, changeInfo, tab) =>
        {
          if (tabId == openedTab.id && changeInfo.status == "complete")
          {
@@ -74,14 +72,14 @@
   }
 
   ext.pages = {
-    open: function(url, callback)
+    open(url, callback)
     {
       chrome.tabs.create({url: url}, callback && afterTabLoaded(callback));
     },
-    query: function(info, callback)
+    query(info, callback)
     {
-      var rawInfo = {};
-      for (var property in info)
+      let rawInfo = {};
+      for (let property in info)
       {
         switch (property)
         {
@@ -91,12 +89,9 @@
         }
       }
 
-      chrome.tabs.query(rawInfo, function(tabs)
+      chrome.tabs.query(rawInfo, tabs =>
       {
-        callback(tabs.map(function(tab)
-        {
-          return new Page(tab);
-        }));
+        callback(tabs.map(tab => new Page(tab)));
       });
     },
     onLoading: new ext._EventTarget(),
@@ -104,7 +99,7 @@
     onRemoved: new ext._EventTarget()
   };
 
-  chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab)
+  chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) =>
   {
     if (changeInfo.status == "loading")
       ext.pages.onLoading._dispatch(new Page(tab));
@@ -112,27 +107,27 @@
 
   function createFrame(tabId, frameId)
   {
-    var frames = framesOfTabs[tabId];
+    let frames = framesOfTabs[tabId];
     if (!frames)
       frames = framesOfTabs[tabId] = Object.create(null);
 
-    var frame = frames[frameId];
+    let frame = frames[frameId];
     if (!frame)
       frame = frames[frameId] = {};
 
     return frame;
   }
 
-  chrome.webNavigation.onBeforeNavigate.addListener(function(details)
+  chrome.webNavigation.onBeforeNavigate.addListener(details =>
   {
     // Capture parent frame here because onCommitted doesn't get this info.
-    var frame = createFrame(details.tabId, details.frameId);
+    let frame = createFrame(details.tabId, details.frameId);
     frame.parent = framesOfTabs[details.tabId][details.parentFrameId] || null;
   });
 
-  var eagerlyUpdatedPages = new ext.PageMap();
+  let eagerlyUpdatedPages = new ext.PageMap();
 
-  ext._updatePageFrameStructure = function(frameId, tabId, url, eager)
+  ext._updatePageFrameStructure = (frameId, tabId, url, eager) =>
   {
     if (frameId == 0)
     {
@@ -149,7 +144,7 @@
         if (eager)
           eagerlyUpdatedPages.set(page, url);
 
-        chrome.tabs.get(tabId, function()
+        chrome.tabs.get(tabId, () =>
         {
           // If the tab is prerendered, chrome.tabs.get() sets
           // chrome.runtime.lastError and we have to dispatch the onLoading event,
@@ -164,11 +159,11 @@
     }
 
     // Update frame URL in frame structure
-    var frame = createFrame(tabId, frameId);
+    let frame = createFrame(tabId, frameId);
     frame.url = new URL(url);
   };
 
-  chrome.webNavigation.onCommitted.addListener(function(details)
+  chrome.webNavigation.onCommitted.addListener(details =>
   {
     ext._updatePageFrameStructure(details.frameId, details.tabId, details.url);
   });
@@ -181,14 +176,14 @@
     delete framesOfTabs[tabId];
   }
 
-  chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId)
+  chrome.tabs.onReplaced.addListener((addedTabId, removedTabId) =>
   {
     forgetTab(removedTabId);
   });
 
   chrome.tabs.onRemoved.addListener(forgetTab);
 
-  chrome.tabs.onActivated.addListener(function(details)
+  chrome.tabs.onActivated.addListener(details =>
   {
     ext.pages.onActivated._dispatch(new Page({id: details.tabId}));
   });
@@ -196,13 +191,13 @@
 
   /* Browser actions */
 
-  var BrowserAction = function(tabId)
+  let BrowserAction = function(tabId)
   {
     this._tabId = tabId;
     this._changes = null;
   };
   BrowserAction.prototype = {
-    _applyChanges: function()
+    _applyChanges()
     {
       if ("iconPath" in this._changes)
       {
@@ -237,7 +232,7 @@
 
       this._changes = null;
     },
-    _queueChanges: function()
+    _queueChanges()
     {
       chrome.tabs.get(this._tabId, function()
       {
@@ -247,14 +242,14 @@
         // prerendered tab. Otherwise chrome.browserAction.set* fails.
         if (chrome.runtime.lastError)
         {
-          var onReplaced = function(addedTabId, removedTabId)
+          let onReplaced = (addedTabId, removedTabId) =>
           {
             if (addedTabId == this._tabId)
             {
               chrome.tabs.onReplaced.removeListener(onReplaced);
               this._applyChanges();
             }
-          }.bind(this);
+          };
           chrome.tabs.onReplaced.addListener(onReplaced);
         }
         else
@@ -263,7 +258,7 @@
         }
       }.bind(this));
     },
-    _addChange: function(name, value)
+    _addChange(name, value)
     {
       if (!this._changes)
       {
@@ -273,11 +268,11 @@
 
       this._changes[name] = value;
     },
-    setIcon: function(path)
+    setIcon(path)
     {
       this._addChange("iconPath", path);
     },
-    setBadge: function(badge)
+    setBadge(badge)
     {
       if (!badge)
       {
@@ -297,36 +292,36 @@
 
   /* Context menus */
 
-  var contextMenuItems = new ext.PageMap();
-  var contextMenuUpdating = false;
+  let contextMenuItems = new ext.PageMap();
+  let contextMenuUpdating = false;
 
-  var updateContextMenu = function()
+  let updateContextMenu = () =>
   {
     if (contextMenuUpdating)
       return;
 
     contextMenuUpdating = true;
 
-    chrome.tabs.query({active: true, lastFocusedWindow: true}, function(tabs)
+    chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs =>
     {
-      chrome.contextMenus.removeAll(function()
+      chrome.contextMenus.removeAll(() =>
       {
         contextMenuUpdating = false;
 
         if (tabs.length == 0)
           return;
 
-        var items = contextMenuItems.get({id: tabs[0].id});
+        let items = contextMenuItems.get({id: tabs[0].id});
 
         if (!items)
           return;
 
-        items.forEach(function(item)
+        items.forEach(item =>
         {
           chrome.contextMenus.create({
             title: item.title,
             contexts: item.contexts,
-            onclick: function(info, tab)
+            onclick(info, tab)
             {
               item.onclick(new Page(tab));
             }
@@ -336,21 +331,21 @@
     });
   };
 
-  var ContextMenus = function(page)
+  let ContextMenus = function(page)
   {
     this._page = page;
   };
   ContextMenus.prototype = {
-    create: function(item)
+    create(item)
     {
-      var items = contextMenuItems.get(this._page);
+      let items = contextMenuItems.get(this._page);
       if (!items)
         contextMenuItems.set(this._page, items = []);
 
       items.push(item);
       updateContextMenu();
     },
-    remove: function(item)
+    remove(item)
     {
       let items = contextMenuItems.get(this._page);
       if (items)
@@ -367,7 +362,7 @@
 
   chrome.tabs.onActivated.addListener(updateContextMenu);
 
-  chrome.windows.onFocusChanged.addListener(function(windowId)
+  chrome.windows.onFocusChanged.addListener(windowId =>
   {
     if (windowId != chrome.windows.WINDOW_ID_NONE)
       updateContextMenu();
@@ -376,14 +371,14 @@
 
   /* Web requests */
 
-  var framesOfTabs = Object.create(null);
+  let framesOfTabs = Object.create(null);
 
-  ext.getFrame = function(tabId, frameId)
+  ext.getFrame = (tabId, frameId) =>
   {
     return (framesOfTabs[tabId] || {})[frameId];
   };
 
-  var handlerBehaviorChangedQuota = chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES;
+  let handlerBehaviorChangedQuota = chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES;
 
   function propagateHandlerBehaviorChange()
   {
@@ -396,40 +391,40 @@
       chrome.webRequest.handlerBehaviorChanged();
 
       handlerBehaviorChangedQuota--;
-      setTimeout(function() { handlerBehaviorChangedQuota++; }, 600000);
+      setTimeout(() => { handlerBehaviorChangedQuota++; }, 600000);
     }
   }
 
   ext.webRequest = {
     onBeforeRequest: new ext._EventTarget(),
-    handlerBehaviorChanged: function()
+    handlerBehaviorChanged()
     {
       // Defer handlerBehaviorChanged() until navigation occurs.
       // There wouldn't be any visible effect when calling it earlier,
       // but it's an expensive operation and that way we avoid to call
       // it multiple times, if multiple filters are added/removed.
-      var onBeforeNavigate = chrome.webNavigation.onBeforeNavigate;
+      let onBeforeNavigate = chrome.webNavigation.onBeforeNavigate;
       if (!onBeforeNavigate.hasListener(propagateHandlerBehaviorChange))
         onBeforeNavigate.addListener(propagateHandlerBehaviorChange);
     }
   };
 
-  chrome.tabs.query({}, function(tabs)
+  chrome.tabs.query({}, tabs =>
   {
-    tabs.forEach(function(tab)
+    tabs.forEach(tab =>
     {
-      chrome.webNavigation.getAllFrames({tabId: tab.id}, function(details)
+      chrome.webNavigation.getAllFrames({tabId: tab.id}, details =>
       {
         if (details && details.length > 0)
         {
-          var frames = framesOfTabs[tab.id] = Object.create(null);
+          let frames = framesOfTabs[tab.id] = Object.create(null);
 
-          for (var i = 0; i < details.length; i++)
+          for (let i = 0; i < details.length; i++)
             frames[details[i].frameId] = {url: new URL(details[i].url), parent: null};
 
-          for (var i = 0; i < details.length; i++)
+          for (let i = 0; i < details.length; i++)
           {
-            var parentFrameId = details[i].parentFrameId;
+            let parentFrameId = details[i].parentFrameId;
 
             if (parentFrameId != -1)
               frames[details[i].frameId].parent = frames[parentFrameId];
@@ -439,7 +434,7 @@
     });
   });
 
-  chrome.webRequest.onBeforeRequest.addListener(function(details)
+  chrome.webRequest.onBeforeRequest.addListener(details =>
   {
     // The high-level code isn't interested in requests that aren't
     // related to a tab or requests loading a top-level document,
@@ -451,8 +446,8 @@
     // has triggered this request. For most requests (e.g. images) we
     // can just use the request's frame ID, but for subdocument requests
     // (e.g. iframes) we must instead use the request's parent frame ID.
-    var frameId;
-    var requestType;
+    let frameId;
+    let requestType;
     if (details.type == "sub_frame")
     {
       frameId = details.parentFrameId;
@@ -464,10 +459,10 @@
       requestType = details.type.toUpperCase();
     }
 
-    var frame = ext.getFrame(details.tabId, frameId);
+    let frame = ext.getFrame(details.tabId, frameId);
     if (frame)
     {
-      var results = ext.webRequest.onBeforeRequest._dispatch(
+      let results = ext.webRequest.onBeforeRequest._dispatch(
         new URL(details.url),
         requestType,
         new Page({id: details.tabId}),
@@ -482,9 +477,9 @@
 
   /* Message passing */
 
-  chrome.runtime.onMessage.addListener(function(message, rawSender, sendResponse)
+  chrome.runtime.onMessage.addListener((message, rawSender, sendResponse) =>
   {
-    var sender = {};
+    let sender = {};
 
     // Add "page" and "frame" if the message was sent by a content script.
     // If sent by popup or the background page itself, there is no "tab".
@@ -495,12 +490,12 @@
         url: new URL(rawSender.url),
         get parent()
         {
-          var frames = framesOfTabs[rawSender.tab.id];
+          let frames = framesOfTabs[rawSender.tab.id];
 
           if (!frames)
             return null;
 
-          var frame = frames[rawSender.frameId];
+          let frame = frames[rawSender.frameId];
           if (frame)
             return frame.parent;
 
@@ -516,17 +511,17 @@
   /* Storage */
 
   ext.storage = {
-    get: function(keys, callback)
+    get(keys, callback)
     {
       chrome.storage.local.get(keys, callback);
     },
-    set: function(key, value, callback)
+    set(key, value, callback)
     {
       let items = {};
       items[key] = value;
       chrome.storage.local.set(items, callback);
     },
-    remove: function(key, callback)
+    remove(key, callback)
     {
       chrome.storage.local.remove(key, callback);
     },
@@ -537,7 +532,7 @@
 
   if ("openOptionsPage" in chrome.runtime)
   {
-    ext.showOptions = function(callback)
+    ext.showOptions = callback =>
     {
       if (!callback)
       {
@@ -568,12 +563,12 @@
   {
     // Edge does not yet support runtime.openOptionsPage (tested version 38)
     // and so this workaround needs to stay for now.
-    ext.showOptions = function(callback)
+    ext.showOptions = callback =>
     {
-      chrome.windows.getLastFocused(function(win)
+      chrome.windows.getLastFocused(win =>
       {
-        var optionsUrl = chrome.extension.getURL("options.html");
-        var queryInfo = {url: optionsUrl};
+        let optionsUrl = chrome.extension.getURL("options.html");
+        let queryInfo = {url: optionsUrl};
 
         // extension pages can't be accessed in incognito windows. In order to
         // correctly mimic the way in which Chrome opens extension options,
@@ -581,11 +576,11 @@
         if (!win.incognito)
           queryInfo.windowId = win.id;
 
-        chrome.tabs.query(queryInfo, function(tabs)
+        chrome.tabs.query(queryInfo, tabs =>
         {
           if (tabs.length > 0)
           {
-            var tab = tabs[0];
+            let tab = tabs[0];
 
             chrome.windows.update(tab.windowId, {focused: true});
             chrome.tabs.update(tab.id, {active: true});
@@ -604,12 +599,12 @@
 
   /* Windows */
   ext.windows = {
-    create: function(createData, callback)
+    create(createData, callback)
     {
-      chrome.windows.create(createData, function(createdWindow)
+      chrome.windows.create(createData, createdWindow =>
       {
         afterTabLoaded(callback)(createdWindow.tabs[0]);
       });
     }
   };
-})();
+}
Index: chrome/ext/common.js
diff --git a/chrome/ext/common.js b/chrome/ext/common.js
index 2e5c776dccb493894383117b12bebafc411587b5..5401aaa2885a234c537d2dcbdd4b1267e04f0660 100644
--- a/chrome/ext/common.js
+++ b/chrome/ext/common.js
@@ -15,8 +15,17 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-(function()
+"use strict";
+
 {
+  // Workaround since HTMLCollection and NodeList didn't have iterator support
+  // before Chrome 51.
+  // https://bugs.chromium.org/p/chromium/issues/detail?id=401699
+  if (!(Symbol.iterator in HTMLCollection.prototype))
+    HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
+  if (!(Symbol.iterator in NodeList.prototype))
+    NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
+
   /* Message passing */
 
   ext.onMessage = new ext._EventTarget();
@@ -26,7 +35,7 @@
 
   ext.backgroundPage = {
     sendMessage: chrome.runtime.sendMessage,
-    getWindow: function()
+    getWindow()
     {
       return chrome.extension.getBackgroundPage();
     }
@@ -37,4 +46,4 @@
 
   ext.getURL = chrome.extension.getURL;
   ext.i18n = chrome.i18n;
-})();
+}
Index: chrome/ext/content.js
diff --git a/chrome/ext/content.js b/chrome/ext/content.js
index b54fdcfb0c9f568738704a7587554dfce14949d8..bde266392fe4e40114177ee485c5f5b7696c4a62 100644
--- a/chrome/ext/content.js
+++ b/chrome/ext/content.js
@@ -1,14 +1,15 @@
-chrome.runtime.onMessage.addListener(function(message, sender, sendResponse)
+"use strict";
+
+chrome.runtime.onMessage.addListener((message, sender, sendResponse) =>
 {
   return ext.onMessage._dispatch(message, {}, sendResponse).indexOf(true) != -1;
 });
 
-ext.onExtensionUnloaded = (function()
 {
-  var port = null;
+  let port = null;
 
-  return {
-    addListener: function(listener)
+  ext.onExtensionUnloaded = {
+    addListener(listener)
     {
       if (!port)
         port = chrome.runtime.connect();
@@ -17,7 +18,7 @@ ext.onExtensionUnloaded = (function()
       // background page dies and automatically disconnects all ports
       port.onDisconnect.addListener(listener);
     },
-    removeListener: function(listener)
+    removeListener(listener)
     {
       if (port)
       {
@@ -31,4 +32,4 @@ ext.onExtensionUnloaded = (function()
       }
     }
   };
-})();
+}
Index: chrome/ext/devtools.js
diff --git a/chrome/ext/devtools.js b/chrome/ext/devtools.js
index e7093d54e876297e2236eca488773314782b14c8..dbc9738c7254d3afa3fc0d26247d9cd1a41b0909 100644
--- a/chrome/ext/devtools.js
+++ b/chrome/ext/devtools.js
@@ -17,11 +17,10 @@
 
 "use strict";
 
-(function()
 {
-  var inspectedTabId = chrome.devtools.inspectedWindow.tabId;
-  var port = chrome.runtime.connect({name: "devtools-" + inspectedTabId});
+  let inspectedTabId = chrome.devtools.inspectedWindow.tabId;
+  let port = chrome.runtime.connect({name: "devtools-" + inspectedTabId});
 
   ext.onMessage = port.onMessage;
   ext.devtools = chrome.devtools;
-})();
+}
Index: chrome/ext/popup.js
diff --git a/chrome/ext/popup.js b/chrome/ext/popup.js
index 40932374211505989553c15352d2e7215e7d07da..f5132aa457a4366129078917064aefc9092ebc42 100644
--- a/chrome/ext/popup.js
+++ b/chrome/ext/popup.js
@@ -1,9 +1,10 @@
-(function()
+"use strict";
+
 {
-  var backgroundPage = chrome.extension.getBackgroundPage();
-  window.ext = Object.create(backgroundPage.ext);
+  const backgroundPage = chrome.extension.getBackgroundPage();
+  var ext = Object.create(backgroundPage.ext);
 
-  ext.closePopup = function()
+  ext.closePopup = () =>
   {
     window.close();
   };
@@ -13,9 +14,9 @@
   ext.backgroundPage = {
     sendMessage: chrome.runtime.sendMessage,
 
-    getWindow: function()
+    getWindow()
     {
       return backgroundPage;
     }
   };
-})();
+}
Index: composer.js
diff --git a/composer.js b/composer.js
index fc8e9ccaf6e0e13baeb2b5f166bf7b4f45625405..6c54eff99dd0775af4f9262f61defc7be4dd1ad7 100644
--- a/composer.js
+++ b/composer.js
@@ -15,7 +15,9 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-var targetPageId = null;
+"use strict";
+
+let targetPageId = null;
 
 function onKeyDown(event)
 {
@@ -38,7 +40,7 @@ function addFilters()
     type: "filters.importRaw",
     text: document.getElementById("filters").value
   },
-  function(errors)
+  errors =>
   {
     if (errors.length > 0)
       alert(errors.join("\n"));
@@ -77,7 +79,7 @@ function init()
 
   document.getElementById("filters").focus();
 
-  ext.onMessage.addListener(function(msg, sender, sendResponse)
+  ext.onMessage.addListener((msg, sender, sendResponse) =>
   {
     switch (msg.type)
     {
Index: composer.postload.js
diff --git a/composer.postload.js b/composer.postload.js
index 98fef095aa636d2c8753329fc41d64234e6f839e..6b87f0ba5e2a4cc61e1c9eb0e1c4a98099966a3b 100644
--- a/composer.postload.js
+++ b/composer.postload.js
@@ -80,14 +80,14 @@ function getBlockableElementOrAncestor(element, callback)
       let images = document.querySelectorAll("img[usemap]");
       let image = null;
 
-      for (let i = 0; i < images.length; i++)
+      for (let currentImage of images)
       {
-        let usemap = images[i].getAttribute("usemap");
+        let usemap = currentImage.getAttribute("usemap");
         let index = usemap.indexOf("#");
 
         if (index != -1 && usemap.substr(index + 1) == element.name)
         {
-          image = images[i];
+          image = currentImage;
           break;
         }
       }
@@ -165,7 +165,7 @@ function highlightElement(element, shadowColor, backgroundColor)
 {
   unhighlightElement(element);
 
-  let highlightWithOverlay = function()
+  let highlightWithOverlay = () =>
   {
     let overlay = addElementOverlay(element);
 
@@ -183,7 +183,7 @@ function highlightElement(element, shadowColor, backgroundColor)
     };
   };
 
-  let highlightWithStyleAttribute = function()
+  let highlightWithStyleAttribute = () =>
   {
     let originalBoxShadow = element.style.getPropertyValue("box-shadow");
     let originalBoxShadowPriority =
Index: ext/background.js
diff --git a/ext/background.js b/ext/background.js
index f6ce8ce075bae22f0569a1cdd741ee29646ba580..d8f67beff947da4193fdddaa5dd1a655ae5a4446 100644
--- a/ext/background.js
+++ b/ext/background.js
@@ -15,55 +15,56 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-(function()
+"use strict";
+
 {
-  var nonEmptyPageMaps = Object.create(null);
-  var pageMapCounter = 0;
+  let nonEmptyPageMaps = Object.create(null);
+  let pageMapCounter = 0;
 
-  var PageMap = ext.PageMap = function()
+  let PageMap = ext.PageMap = function()
   {
     this._map = Object.create(null);
     this._id = ++pageMapCounter;
   };
   PageMap.prototype = {
-    _delete: function(id)
+    _delete(id)
     {
       delete this._map[id];
 
       if (Object.keys(this._map).length == 0)
         delete nonEmptyPageMaps[this._id];
     },
-    keys: function()
+    keys()
     {
       return Object.keys(this._map).map(ext.getPage);
     },
-    get: function(page)
+    get(page)
     {
       return this._map[page.id];
     },
-    set: function(page, value)
+    set(page, value)
     {
       this._map[page.id] = value;
       nonEmptyPageMaps[this._id] = this;
     },
-    has: function(page)
+    has(page)
     {
       return page.id in this._map;
     },
-    clear: function()
+    clear()
     {
-      for (var id in this._map)
+      for (let id in this._map)
         this._delete(id);
     },
-    delete: function(page)
+    delete(page)
     {
       this._delete(page.id);
     }
   };
 
-  ext._removeFromAllPageMaps = function(pageId)
+  ext._removeFromAllPageMaps = pageId =>
   {
-    for (var pageMapId in nonEmptyPageMaps)
+    for (let pageMapId in nonEmptyPageMaps)
       nonEmptyPageMaps[pageMapId]._delete(pageId);
   };
-})();
+}
Index: ext/common.js
diff --git a/ext/common.js b/ext/common.js
index c75ced186d633fc3bf4183be4fb5d9dd6c5db666..445dc73ad58621eae3adf7a5170a687e093707bd 100644
--- a/ext/common.js
+++ b/ext/common.js
@@ -15,36 +15,36 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+"use strict";
 
-(function()
 {
-  window.ext = {};
+  var ext = {};
 
-  var EventTarget = ext._EventTarget = function()
+  let EventTarget = ext._EventTarget = function()
   {
     this._listeners = [];
   };
   EventTarget.prototype = {
-    addListener: function(listener)
+    addListener(listener)
     {
       if (this._listeners.indexOf(listener) == -1)
         this._listeners.push(listener);
     },
-    removeListener: function(listener)
+    removeListener(listener)
     {
-      var idx = this._listeners.indexOf(listener);
+      let idx = this._listeners.indexOf(listener);
       if (idx != -1)
         this._listeners.splice(idx, 1);
     },
-    _dispatch: function()
+    _dispatch()
     {
-      var results = [];
-      var listeners = this._listeners.slice();
+      let results = [];
+      let listeners = this._listeners.slice();
 
-      for (var i = 0; i < listeners.length; i++)
-        results.push(listeners[i].apply(null, arguments));
+      for (let listener of listeners)
+        results.push(listener.apply(null, arguments));
 
       return results;
     }
   };
-})();
+}
Index: include.preload.js
diff --git a/include.preload.js b/include.preload.js
index 86e52c32afceb894f6591a84b0eca3b1842383ce..1c28cb6bc9ac88a2703015ab49d5978a0ee3c6e9 100644
--- a/include.preload.js
+++ b/include.preload.js
@@ -15,7 +15,9 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-var typeMap = {
+"use strict";
+
+const typeMap = {
   "img": "IMAGE",
   "input": "IMAGE",
   "picture": "IMAGE",
@@ -29,24 +31,23 @@ var typeMap = {
 
 function getURLsFromObjectElement(element)
 {
-  var url = element.getAttribute("data");
+  let url = element.getAttribute("data");
   if (url)
     return [url];
 
-  for (var i = 0; i < element.children.length; i++)
+  for (let child of element.children)
   {
-    var child = element.children[i];
     if (child.localName != "param")
       continue;
 
-    var name = child.getAttribute("name");
+    let name = child.getAttribute("name");
     if (name != "movie"  && // Adobe Flash
         name != "source" && // Silverlight
         name != "src"    && // Real Media + Quicktime
         name != "FileName") // Windows Media
       continue;
 
-    var value = child.getAttribute("value");
+    let value = child.getAttribute("value");
     if (!value)
       continue;
 
@@ -58,17 +59,16 @@ function getURLsFromObjectElement(element)
 
 function getURLsFromAttributes(element)
 {
-  var urls = [];
+  let urls = [];
 
   if (element.src)
     urls.push(element.src);
 
   if (element.srcset)
   {
-    var candidates = element.srcset.split(",");
-    for (var i = 0; i < candidates.length; i++)
+    for (let candidate of element.srcset.split(","))
     {
-      var url = candidates[i].trim().replace(/\s+\S+$/, "");
+      let url = candidate.trim().replace(/\s+\S+$/, "");
       if (url)
         urls.push(url);
     }
@@ -79,11 +79,10 @@ function getURLsFromAttributes(element)
 
 function getURLsFromMediaElement(element)
 {
-  var urls = getURLsFromAttributes(element);
+  let urls = getURLsFromAttributes(element);
 
-  for (var i = 0; i < element.children.length; i++)
+  for (let child of element.children)
   {
-    var child = element.children[i];
     if (child.localName == "source" || child.localName == "track")
       urls.push.apply(urls, getURLsFromAttributes(child));
   }
@@ -96,7 +95,7 @@ function getURLsFromMediaElement(element)
 
 function getURLsFromElement(element)
 {
-  var urls;
+  let urls;
   switch (element.localName)
   {
     case "object":
@@ -114,7 +113,7 @@ function getURLsFromElement(element)
       break;
   }
 
-  for (var i = 0; i < urls.length; i++)
+  for (let i = 0; i < urls.length; i++)
   {
     if (/^(?!https?:)[\w-]+:/i.test(urls[i]))
       urls.splice(i--, 1);
@@ -125,11 +124,11 @@ function getURLsFromElement(element)
 
 function checkCollapse(element)
 {
-  var mediatype = typeMap[element.localName];
+  let mediatype = typeMap[element.localName];
   if (!mediatype)
     return;
 
-  var urls = getURLsFromElement(element);
+  let urls = getURLsFromElement(element);
   if (urls.length == 0)
     return;
 
@@ -141,12 +140,12 @@ function checkCollapse(element)
       baseURL: document.location.href
     },
 
-    function(collapse)
+    collapse =>
     {
       function collapseElement()
       {
-        var propertyName = "display";
-        var propertyValue = "none";
+        let propertyName = "display";
+        let propertyValue = "none";
         if (element.localName == "frame")
         {
           propertyName = "visibility";
@@ -175,7 +174,7 @@ function checkCollapse(element)
 
 function checkSitekey()
 {
-  var attr = document.documentElement.getAttribute("data-adblockkey");
+  let attr = document.documentElement.getAttribute("data-adblockkey");
   if (attr)
     ext.backgroundPage.sendMessage({type: "filters.addKey", token: attr});
 }
@@ -208,26 +207,24 @@ function ElementHidingTracer(selectors)
     this.trace();
 }
 ElementHidingTracer.prototype = {
-  checkNodes: function(nodes)
+  checkNodes(nodes)
   {
-    var matchedSelectors = [];
+    let matchedSelectors = [];
 
     // Find all selectors that match any hidden element inside the given nodes.
-    for (var i = 0; i < this.selectors.length; i++)
+    for (let selector of this.selectors)
     {
-      var selector = this.selectors[i];
-
-      for (var j = 0; j < nodes.length; j++)
+      for (let node of nodes)
       {
-        var elements = nodes[j].querySelectorAll(selector);
-        var matched = false;
+        let elements = node.querySelectorAll(selector);
+        let matched = false;
 
-        for (var k = 0; k < elements.length; k++)
+        for (let element of elements)
         {
           // Only consider selectors that actually have an effect on the
           // computed styles, and aren't overridden by rules with higher
           // priority, or haven't been circumvented in a different way.
-          if (getComputedStyle(elements[k]).display == "none")
+          if (getComputedStyle(element).display == "none")
           {
             matchedSelectors.push(selector);
             matched = true;
@@ -247,26 +244,25 @@ ElementHidingTracer.prototype = {
       });
   },
 
-  onTimeout: function()
+  onTimeout()
   {
     this.checkNodes(this.changedNodes);
     this.changedNodes = [];
     this.timeout = null;
   },
 
-  observe: function(mutations)
+  observe(mutations)
   {
     // Forget previously changed nodes that are no longer in the DOM.
-    for (var i = 0; i < this.changedNodes.length; i++)
+    for (let i = 0; i < this.changedNodes.length; i++)
     {
       if (!document.contains(this.changedNodes[i]))
         this.changedNodes.splice(i--, 1);
     }
 
-    for (var j = 0; j < mutations.length; j++)
+    for (let mutation of mutations)
     {
-      var mutation = mutations[j];
-      var node = mutation.target;
+      let node = mutation.target;
 
       // Ignore mutations of nodes that aren't in the DOM anymore.
       if (!document.contains(node))
@@ -278,10 +274,10 @@ ElementHidingTracer.prototype = {
       if (mutation.type == "attributes")
         node = node.parentNode;
 
-      var addNode = true;
-      for (var k = 0; k < this.changedNodes.length; k++)
+      let addNode = true;
+      for (let i = 0; i < this.changedNodes.length; i++)
       {
-        var previouslyChangedNode = this.changedNodes[k];
+        let previouslyChangedNode = this.changedNodes[i];
 
         // If we are already going to check an ancestor of this node,
         // we can ignore this node, since it will be considered anyway
@@ -296,7 +292,7 @@ ElementHidingTracer.prototype = {
         // we can ignore that node, since it will be considered anyway
         // when checking one of its ancestors.
         if (node.contains(previouslyChangedNode))
-          this.changedNodes.splice(k--, 1);
+          this.changedNodes.splice(i--, 1);
       }
 
       if (addNode)
@@ -310,7 +306,7 @@ ElementHidingTracer.prototype = {
       this.timeout = setTimeout(this.onTimeout.bind(this), 1000);
   },
 
-  trace: function()
+  trace()
   {
     this.checkNodes([document]);
 
@@ -324,7 +320,7 @@ ElementHidingTracer.prototype = {
     );
   },
 
-  disconnect: function()
+  disconnect()
   {
     document.removeEventListener("DOMContentLoaded", this.trace);
     this.observer.disconnect();
@@ -334,7 +330,7 @@ ElementHidingTracer.prototype = {
 
 function runInPageContext(fn, arg)
 {
-  var script = document.createElement("script");
+  let script = document.createElement("script");
   script.type = "application/javascript";
   script.async = false;
   script.textContent = "(" + fn + ")(" + JSON.stringify(arg) + ");";
@@ -349,14 +345,14 @@ function runInPageContext(fn, arg)
 // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=129353
 function wrapWebSocket()
 {
-  var eventName = "abpws-" + Math.random().toString(36).substr(2);
+  let eventName = "abpws-" + Math.random().toString(36).substr(2);
 
-  document.addEventListener(eventName, function(event)
+  document.addEventListener(eventName, event =>
   {
     ext.backgroundPage.sendMessage({
       type: "request.websocket",
       url: event.detail.url
-    }, function (block)
+    }, block =>
     {
       document.dispatchEvent(
         new CustomEvent(eventName + "-" + event.detail.url, {detail: block})
@@ -364,20 +360,20 @@ function wrapWebSocket()
     });
   });
 
-  runInPageContext(function(eventName)
+  runInPageContext(eventName =>
   {
     // As far as possible we must track everything we use that could be
     // sabotaged by the website later in order to circumvent us.
-    var RealWebSocket = WebSocket;
-    var closeWebSocket = Function.prototype.call.bind(RealWebSocket.prototype.close);
-    var addEventListener = document.addEventListener.bind(document);
-    var removeEventListener = document.removeEventListener.bind(document);
-    var dispatchEvent = document.dispatchEvent.bind(document);
-    var CustomEvent = window.CustomEvent;
+    let RealWebSocket = WebSocket;
+    let closeWebSocket = Function.prototype.call.bind(RealWebSocket.prototype.close);
+    let addEventListener = document.addEventListener.bind(document);
+    let removeEventListener = document.removeEventListener.bind(document);
+    let dispatchEvent = document.dispatchEvent.bind(document);
+    let CustomEvent = window.CustomEvent;
 
     function checkRequest(url, callback)
     {
-      var incomingEventName = eventName + "-" + url;
+      let incomingEventName = eventName + "-" + url;
       function listener(event)
       {
         callback(event.detail);
@@ -396,13 +392,13 @@ function wrapWebSocket()
       if (!(this instanceof WrappedWebSocket)) return RealWebSocket();
       if (arguments.length < 1) return new RealWebSocket();
 
-      var websocket;
+      let websocket;
       if (arguments.length == 1)
         websocket = new RealWebSocket(url);
       else
         websocket = new RealWebSocket(url, arguments[1]);
 
-      checkRequest(websocket.url, function(blocked)
+      checkRequest(websocket.url, blocked =>
       {
         if (blocked)
           closeWebSocket(websocket);
@@ -432,7 +428,7 @@ function ElemHide()
 
   this.elemHideEmulation = new ElemHideEmulation(
     window,
-    function(callback)
+    callback =>
     {
       ext.backgroundPage.sendMessage({
         type: "filters.get",
@@ -445,7 +441,7 @@ function ElemHide()
 ElemHide.prototype = {
   selectorGroupSize: 200,
 
-  createShadowTree: function()
+  createShadowTree()
   {
     // Use Shadow DOM if available as to not mess with with web pages that
     // rely on the order of their own <style> tags (#309). However, creating
@@ -462,25 +458,25 @@ ElemHide.prototype = {
     // Finally since some users have both AdBlock and Adblock Plus installed we
     // have to consider how the two extensions interact. For example we want to
     // avoid creating the shadowRoot twice.
-    var shadow = document.documentElement.shadowRoot ||
+    let shadow = document.documentElement.shadowRoot ||
                  document.documentElement.createShadowRoot();
     shadow.appendChild(document.createElement("shadow"));
 
     // Stop the website from messing with our shadow root (#4191, #4298).
     if ("shadowRoot" in Element.prototype)
     {
-      runInPageContext(function()
+      runInPageContext(() =>
       {
-        var ourShadowRoot = document.documentElement.shadowRoot;
+        let ourShadowRoot = document.documentElement.shadowRoot;
         if (!ourShadowRoot)
           return;
-        var desc = Object.getOwnPropertyDescriptor(Element.prototype, "shadowRoot");
-        var shadowRoot = Function.prototype.call.bind(desc.get);
+        let desc = Object.getOwnPropertyDescriptor(Element.prototype, "shadowRoot");
+        let shadowRoot = Function.prototype.call.bind(desc.get);
 
         Object.defineProperty(Element.prototype, "shadowRoot", {
-          configurable: true, enumerable: true, get: function()
+          configurable: true, enumerable: true, get()
           {
-            var shadow = shadowRoot(this);
+            let shadow = shadowRoot(this);
             return shadow == ourShadowRoot ? null : shadow;
           }
         });
@@ -490,7 +486,7 @@ ElemHide.prototype = {
     return shadow;
   },
 
-  addSelectors: function(selectors)
+  addSelectors(selectors)
   {
     if (selectors.length == 0)
       return;
@@ -518,12 +514,12 @@ ElemHide.prototype = {
     // insertion point.
     if (this.shadow)
     {
-      var preparedSelectors = [];
-      for (var i = 0; i < selectors.length; i++)
+      let preparedSelectors = [];
+      for (let selector of selectors)
       {
-        var subSelectors = splitSelector(selectors[i]);
-        for (var j = 0; j < subSelectors.length; j++)
-          preparedSelectors.push("::content " + subSelectors[j]);
+        let subSelectors = splitSelector(selector);
+        for (let subSelector of subSelectors)
+          preparedSelectors.push("::content " + subSelector);
       }
       selectors = preparedSelectors;
     }
@@ -533,20 +529,20 @@ ElemHide.prototype = {
     // (Chrome also has a limit, larger... but we're not certain exactly what it
     //  is! Edge apparently has no such limit.)
     // [1] - https://github.com/WebKit/webkit/blob/1cb2227f6b2a1035f7bdc46e5ab69debb75fc1de/Source/WebCore/css/RuleSet.h#L68
-    for (var i = 0; i < selectors.length; i += this.selectorGroupSize)
+    for (let i = 0; i < selectors.length; i += this.selectorGroupSize)
     {
-      var selector = selectors.slice(i, i + this.selectorGroupSize).join(", ");
+      let selector = selectors.slice(i, i + this.selectorGroupSize).join(", ");
       this.style.sheet.insertRule(selector + "{display: none !important;}",
                                   this.style.sheet.cssRules.length);
     }
   },
 
-  apply: function()
+  apply()
   {
-    var selectors = null;
-    var elemHideEmulationLoaded = false;
+    let selectors = null;
+    let elemHideEmulationLoaded = false;
 
-    var checkLoaded = function()
+    let checkLoaded = function()
     {
       if (!selectors || !elemHideEmulationLoaded)
         return;
@@ -566,13 +562,13 @@ ElemHide.prototype = {
         this.tracer = new ElementHidingTracer(selectors.selectors);
     }.bind(this);
 
-    ext.backgroundPage.sendMessage({type: "get-selectors"}, function(response)
+    ext.backgroundPage.sendMessage({type: "get-selectors"}, response =>
     {
       selectors = response;
       checkLoaded();
     });
 
-    this.elemHideEmulation.load(function()
+    this.elemHideEmulation.load(() =>
     {
       elemHideEmulationLoaded = true;
       checkLoaded();
@@ -585,17 +581,19 @@ if (document instanceof HTMLDocument)
   checkSitekey();
   wrapWebSocket();
 
+  // This variable is also used by our other content scripts, outside of the
+  // current scope.
   var elemhide = new ElemHide();
   elemhide.apply();
 
-  document.addEventListener("error", function(event)
+  document.addEventListener("error", event =>
   {
     checkCollapse(event.target);
   }, true);
 
-  document.addEventListener("load", function(event)
+  document.addEventListener("load", event =>
   {
-    var element = event.target;
+    let element = event.target;
     if (/^i?frame$/.test(element.localName))
       checkCollapse(element);
   }, true);
Index: lib/compat.js
diff --git a/lib/compat.js b/lib/compat.js
index d544edca8faa300d5ff3833b0470131b43d7b4a6..21439f3d353d904341f2b54ac7fe7f14190ac3bd 100644
--- a/lib/compat.js
+++ b/lib/compat.js
@@ -15,6 +15,8 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+"use strict";
+
 //
 // Module framework stuff
 //
@@ -33,28 +35,28 @@ require.scopes = Object.create(null);
 
 function importAll(module, globalObj)
 {
-  var exports = require(module);
-  for (var key in exports)
+  let exports = require(module);
+  for (let key in exports)
     globalObj[key] = exports[key];
 }
 
-onShutdown = {
+let onShutdown = {
   done: false,
-  add: function() {},
-  remove: function() {}
+  add() {},
+  remove() {}
 };
 
 //
 // XPCOM emulation
 //
 
-var Components =
+let Components =
 {
   interfaces:
   {
     nsIFile: {DIRECTORY_TYPE: 0},
-    nsIFileURL: function() {},
-    nsIHttpChannel: function() {},
+    nsIFileURL() {},
+    nsIHttpChannel() {},
     nsITimer: {TYPE_REPEATING_SLACK: 0},
     nsIInterfaceRequestor: null,
     nsIChannelEventSink: null
@@ -63,44 +65,35 @@ var Components =
   {
     "@mozilla.org/timer;1":
     {
-      createInstance: function()
-      {
-        return new FakeTimer();
-      }
+      createInstance() { return new FakeTimer(); }
     },
     "@mozilla.org/xmlextras/xmlhttprequest;1":
     {
-      createInstance: function()
-      {
-        return new XMLHttpRequest();
-      }
+      createInstance() { return new XMLHttpRequest(); }
     }
   },
   results: {},
   utils: {
-    import: function()
+    import()
     {
     },
-    reportError: function(e)
+    reportError(e)
     {
       console.error(e);
       console.trace();
     }
   },
   manager: null,
-  ID: function()
-  {
-    return null;
-  }
+  ID() { return null; }
 };
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 const Cu = Components.utils;
 
-var XPCOMUtils =
+let XPCOMUtils =
 {
-  generateQI: function() {}
+  generateQI() {}
 };
 
 //
@@ -121,40 +114,40 @@ FakeFile.prototype =
   {
     this.path = value;
   },
-  append: function(path)
+  append(path)
   {
     this.path += path;
   },
-  clone: function()
+  clone()
   {
     return new FakeFile(this.path);
   },
   get parent()
   {
-    return {create: function() {}};
+    return {create() {}};
   },
-  normalize: function() {}
+  normalize() {}
 };
 
 //
 // Services.jsm module emulation
 //
 
-var Services =
+let Services =
 {
   obs: {
-    addObserver: function() {},
-    removeObserver: function() {}
+    addObserver() {},
+    removeObserver() {}
   },
   vc: {
-    compare: function(v1, v2)
+    compare(v1, v2)
     {
       function parsePart(s)
       {
         if (!s)
           return parsePart("0");
 
-        var part = {
+        let part = {
           numA: 0,
           strB: "",
           numC: 0,
@@ -167,7 +160,7 @@ var Services =
           return part;
         }
 
-        var matches = s.match(/(\d*)(\D*)(\d*)(.*)/);
+        let matches = s.match(/(\d*)(\D*)(\d*)(.*)/);
         part.numA = parseInt(matches[1], 10) || part.numA;
         part.strB = matches[2] || part.strB;
         part.numC = parseInt(matches[3], 10) || part.numC;
@@ -193,9 +186,9 @@ var Services =
 
       function compareParts(p1, p2)
       {
-        var result = 0;
-        var elements = ["numA", "strB", "numC", "extraD"];
-        elements.some(function(element)
+        let result = 0;
+        let elements = ["numA", "strB", "numC", "extraD"];
+        elements.some(element =>
         {
           result = comparePartElement(p1[element], p2[element]);
           return result;
@@ -203,11 +196,11 @@ var Services =
         return result;
       }
 
-      var parts1 = v1.split(".");
-      var parts2 = v2.split(".");
-      for (var i = 0; i < Math.max(parts1.length, parts2.length); i++)
+      let parts1 = v1.split(".");
+      let parts2 = v2.split(".");
+      for (let i = 0; i < Math.max(parts1.length, parts2.length); i++)
       {
-        var result = compareParts(parsePart(parts1[i]), parsePart(parts2[i]));
+        let result = compareParts(parsePart(parts1[i]), parsePart(parts2[i]));
         if (result)
           return result;
       }
@@ -220,7 +213,7 @@ var Services =
 // FileUtils.jsm module emulation
 //
 
-var FileUtils =
+let FileUtils =
 {
   PERMS_DIRECTORY: 0
 };
@@ -232,26 +225,25 @@ FakeTimer.prototype =
 {
   delay: 0,
   callback: null,
-  initWithCallback: function(callback, delay)
+  initWithCallback(callback, delay)
   {
     this.callback = callback;
     this.delay = delay;
     this.scheduleTimeout();
   },
-  scheduleTimeout: function()
+  scheduleTimeout()
   {
-    var me = this;
-    window.setTimeout(function()
+    window.setTimeout(() =>
     {
       try
       {
-        me.callback();
+        this.callback();
       }
       catch(e)
       {
         Cu.reportError(e);
       }
-      me.scheduleTimeout();
+      this.scheduleTimeout();
     }, this.delay);
   }
 };
@@ -267,7 +259,7 @@ XMLHttpRequest.prototype.channel =
   loadFlags: 0,
   INHIBIT_CACHING: 0,
   VALIDATE_ALWAYS: 0,
-  QueryInterface: function()
+  QueryInterface()
   {
     return this;
   }
Index: lib/csp.js
diff --git a/lib/csp.js b/lib/csp.js
index 5309863ab1bb65b9f8a5318d44ef723d0a6d49e9..6f43c352d9681613ef881fe3a187c2a17969a6ec 100644
--- a/lib/csp.js
+++ b/lib/csp.js
@@ -17,11 +17,11 @@
 
 "use strict";
 
-let {defaultMatcher} = require("matcher");
-let {BlockingFilter, RegExpFilter} = require("filterClasses");
-let {getDecodedHostname} = require("url");
+const {defaultMatcher} = require("matcher");
+const {BlockingFilter, RegExpFilter} = require("filterClasses");
+const {getDecodedHostname} = require("url");
 
-chrome.webRequest.onHeadersReceived.addListener(function(details)
+chrome.webRequest.onHeadersReceived.addListener(details =>
 {
   let hostname = getDecodedHostname(new URL(details.url));
   let match = defaultMatcher.matchesAny("", RegExpFilter.typeMap.WEBSOCKET,
Index: lib/devtools.js
diff --git a/lib/devtools.js b/lib/devtools.js
index 2fdf5ec8ccde7a433a87bbac8e844519b33fb528..89c50d4342816f4072cae2225c20d63fb6e44bd7 100644
--- a/lib/devtools.js
+++ b/lib/devtools.js
@@ -17,13 +17,13 @@
 
 "use strict";
 
-let {RegExpFilter, WhitelistFilter, ElemHideFilter} = require("filterClasses");
-let {SpecialSubscription} = require("subscriptionClasses");
-let {FilterStorage} = require("filterStorage");
-let {defaultMatcher} = require("matcher");
-let {FilterNotifier} = require("filterNotifier");
-let {extractHostFromFrame} = require("url");
-let {port} = require("messaging");
+const {RegExpFilter, WhitelistFilter, ElemHideFilter} = require("filterClasses");
+const {SpecialSubscription} = require("subscriptionClasses");
+const {FilterStorage} = require("filterStorage");
+const {defaultMatcher} = require("matcher");
+const {FilterNotifier} = require("filterNotifier");
+const {extractHostFromFrame} = require("url");
+const {port} = require("messaging");
 
 const nonRequestTypes = ["DOCUMENT", "ELEMHIDE", "GENERICBLOCK", "GENERICHIDE"];
 
Index: lib/filterComposer.js
diff --git a/lib/filterComposer.js b/lib/filterComposer.js
index 10390f9f3be7462ec52da3639872fa1df757b2a8..454204a2989159ed3d3e8c58e726a7795594bc5c 100644
--- a/lib/filterComposer.js
+++ b/lib/filterComposer.js
@@ -19,13 +19,13 @@
 
 "use strict";
 
-let {defaultMatcher} = require("matcher");
-let {RegExpFilter} = require("filterClasses");
-let {FilterNotifier} = require("filterNotifier");
-let {Prefs} = require("prefs");
-let {extractHostFromFrame, stringifyURL, isThirdParty} = require("url");
-let {getKey, checkWhitelisted} = require("whitelisting");
-let {port} = require("messaging");
+const {defaultMatcher} = require("matcher");
+const {RegExpFilter} = require("filterClasses");
+const {FilterNotifier} = require("filterNotifier");
+const {Prefs} = require("prefs");
+const {extractHostFromFrame, stringifyURL, isThirdParty} = require("url");
+const {getKey, checkWhitelisted} = require("whitelisting");
+const {port} = require("messaging");
 
 let readyPages = new ext.PageMap();
 
@@ -35,7 +35,7 @@ let readyPages = new ext.PageMap();
  * @param {Page} page
  * @return {boolean}
  */
-exports.isPageReady = function(page)
+exports.isPageReady = page =>
 {
   return readyPages.has(page);
 };
@@ -66,7 +66,7 @@ let escapeCSS =
  * @return {string}
  * @static
  */
-exports.escapeCSS = function(s)
+exports.escapeCSS = s =>
 {
   return s.replace(/^[\d\-]|[^\w\-\u0080-\uFFFF]/g, escapeChar);
 };
@@ -79,7 +79,7 @@ let quoteCSS =
  * @return {string}
  * @static
  */
-exports.quoteCSS = function(value)
+exports.quoteCSS = value =>
 {
   return '"' + value.replace(/["\\\{\}\x00-\x1F\x7F]/g, escapeChar) + '"';
 };
@@ -156,7 +156,7 @@ function composeFilters(details)
 let contextMenuItem = {
   title: ext.i18n.getMessage("block_element"),
   contexts: ["image", "video", "audio"],
-  onclick: page =>
+  onclick(page)
   {
     page.sendMessage({type: "composer.content.contextMenuClicked"});
   }
Index: lib/filterValidation.js
diff --git a/lib/filterValidation.js b/lib/filterValidation.js
index f5de14b7a75c670802a37fa676a10cb51c51dcd5..c280fcceba42d50b1b00ba55a1b5f0b091ba8a40 100644
--- a/lib/filterValidation.js
+++ b/lib/filterValidation.js
@@ -17,8 +17,10 @@
 
 /** @module filterValidation */
 
-let {Filter, InvalidFilter, ElemHideBase} = require("filterClasses");
-let {Utils} = require("utils");
+"use strict";
+
+const {Filter, InvalidFilter, ElemHideBase} = require("filterClasses");
+const {Utils} = require("utils");
 
 /**
  * An error returned by
@@ -63,7 +65,7 @@ FilterParsingError.prototype = {
    *
    * @return {string}
    */
-  toString: function()
+  toString()
   {
     let message;
     if (this.reason)
@@ -115,7 +117,7 @@ let parseFilter =
  * @param {string}  text
  * @return {ParsedFilter}
  */
-exports.parseFilter = function(text)
+exports.parseFilter = text =>
 {
   let filter = null;
   text = Filter.normalize(text);
@@ -149,7 +151,7 @@ exports.parseFilter = function(text)
  * @param {string}  text
  * @return {ParsedFilters}
  */
-exports.parseFilters = function(text)
+exports.parseFilters = text =>
 {
   let lines = text.split("\n");
   let filters = [];
Index: lib/icon.js
diff --git a/lib/icon.js b/lib/icon.js
index a2e56a174a24d4c36fec0a658c108990bc92e8bb..c7590fce9c8f4bef26cbb7ab428a58b7ee97afed 100644
--- a/lib/icon.js
+++ b/lib/icon.js
@@ -19,7 +19,7 @@
 
 "use strict";
 
-let {FilterNotifier} = require("filterNotifier");
+const {FilterNotifier} = require("filterNotifier");
 
 const frameOpacities =  [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
                          1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
@@ -185,7 +185,7 @@ let stopIconAnimation =
  * @return {Promise} A promise that is fullfilled when
  *                   the icon animation has been stopped.
  */
-exports.stopIconAnimation = function()
+exports.stopIconAnimation = () =>
 {
   stopRequested = true;
   return notRunning.then(() =>
@@ -201,7 +201,7 @@ exports.stopIconAnimation = function()
  *
  * @param {string} type  The notification type (i.e: "information" or "critical")
  */
-exports.startIconAnimation = function(type)
+exports.startIconAnimation = type =>
 {
   notRunning = new Promise(resolve =>
   {
Index: lib/io.js
diff --git a/lib/io.js b/lib/io.js
index 6a07389c6f2eafec04176b87cf46de1cacbd17c6..4b352d0036d40e65157666ba728ddd84e2420101 100644
--- a/lib/io.js
+++ b/lib/io.js
@@ -15,6 +15,8 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+"use strict";
+
 const keyPrefix = "file:";
 
 function fileToKey(file)
@@ -26,7 +28,7 @@ function loadFile(file, successCallback, errorCallback)
 {
   let key = fileToKey(file);
 
-  ext.storage.get([key], function(items)
+  ext.storage.get([key], items =>
   {
     let entry = items[key];
 
@@ -51,12 +53,9 @@ function saveFile(file, data, callback)
 
 exports.IO =
 {
-  resolveFilePath: function(path)
-  {
-    return new FakeFile(path);
-  },
+  resolveFilePath(path) { return new FakeFile(path); },
 
-  readFromFile: function(file, listener, callback)
+  readFromFile(file, listener, callback)
   {
     function onLoaded(entry)
     {
@@ -70,12 +69,12 @@ exports.IO =
     loadFile(file, onLoaded, callback);
   },
 
-  writeToFile: function(file, data, callback)
+  writeToFile(file, data, callback)
   {
     saveFile(file, data, callback);
   },
 
-  copyFile: function(fromFile, toFile, callback)
+  copyFile(fromFile, toFile, callback)
   {
     function onLoaded(entry)
     {
@@ -85,11 +84,11 @@ exports.IO =
     loadFile(fromFile, onLoaded, callback);
   },
 
-  renameFile: function(fromFile, newName, callback)
+  renameFile(fromFile, newName, callback)
   {
     function onLoaded(entry)
     {
-      ext.storage.remove(fileToKey(fromFile), function()
+      ext.storage.remove(fileToKey(fromFile), () =>
       {
         ext.storage.set(keyPrefix + newName, entry, callback);
       });
@@ -98,12 +97,12 @@ exports.IO =
     loadFile(fromFile, onLoaded, callback);
   },
 
-  removeFile: function(file, callback)
+  removeFile(file, callback)
   {
     ext.storage.remove(fileToKey(file), callback);
   },
 
-  statFile: function(file, callback)
+  statFile(file, callback)
   {
     function onLoaded(entry)
     {
Index: lib/messaging.js
diff --git a/lib/messaging.js b/lib/messaging.js
index 8cb24de383f32a0a7995339e5863a533687b1e68..4e8f3237b546fb5bbb9de02b5f8c9ef9438b3d8d 100644
--- a/lib/messaging.js
+++ b/lib/messaging.js
@@ -19,7 +19,7 @@
 
 "use strict";
 
-let {EventEmitter} = require("events");
+const {EventEmitter} = require("events");
 
 /**
  * Communication port wrapping ext.onMessage to receive messages.
@@ -34,7 +34,7 @@ function Port()
 };
 
 Port.prototype = {
-  _onMessage: function(message, sender, sendResponse)
+  _onMessage(message, sender, sendResponse)
   {
     let async = false;
     let callbacks = this._eventEmitter.listeners(message.type);
@@ -81,7 +81,7 @@ Port.prototype = {
    * @param {string}   name
    * @param {Port~messageCallback} callback
    */
-  on: function(name, callback)
+  on(name, callback)
   {
     this._eventEmitter.on(name, callback);
   },
@@ -92,7 +92,7 @@ Port.prototype = {
    * @param {string}   name
    * @param {Port~messageCallback} callback
    */
-  off: function(name, callback)
+  off(name, callback)
   {
     this._eventEmitter.off(name, callback);
   },
@@ -100,7 +100,7 @@ Port.prototype = {
   /**
    * Disables the port and makes it stop listening to incoming messages.
    */
-  disconnect: function()
+  disconnect()
   {
     ext.onMessage.removeListener(this._onMessage);
   }
Index: lib/notificationHelper.js
diff --git a/lib/notificationHelper.js b/lib/notificationHelper.js
index 9a8875a3ecb3c8357397763406546df3c9371be6..2dc0ce900dcac3aadff84bbe881c3931a9bd341a 100644
--- a/lib/notificationHelper.js
+++ b/lib/notificationHelper.js
@@ -17,12 +17,14 @@
 
 /** @module notificationHelper */
 
-let {startIconAnimation, stopIconAnimation} = require("icon");
-let {Utils} = require("utils");
-let {Notification: NotificationStorage} = require("notification");
-let {stringifyURL} = require("url");
-let {initAntiAdblockNotification} = require("antiadblockInit");
-let {Prefs} = require("prefs");
+"use strict";
+
+const {startIconAnimation, stopIconAnimation} = require("icon");
+const {Utils} = require("utils");
+const {Notification: NotificationStorage} = require("notification");
+const {stringifyURL} = require("url");
+const {initAntiAdblockNotification} = require("antiadblockInit");
+const {Prefs} = require("prefs");
 
 let activeNotification = null;
 let activeButtons = null;
@@ -36,7 +38,7 @@ displayMethods.information = ["icon", "popup"];
 function prepareNotificationIconAndPopup()
 {
   let animateIcon = shouldDisplay("icon", activeNotification.type);
-  activeNotification.onClicked = function()
+  activeNotification.onClicked = () =>
   {
     if (animateIcon)
       stopIconAnimation();
@@ -120,7 +122,7 @@ function notificationButtonClick(buttonIndex)
       break;
     case "configure":
       Prefs.notifications_showui = true;
-      ext.showOptions(function(page)
+      ext.showOptions(page =>
       {
         page.sendMessage({
           type: "app.respond",
@@ -150,14 +152,14 @@ function initChromeNotifications()
     if (activeNotification && activeNotification.type != "question" && !("links" in activeNotification))
       return;
 
-    chrome.notifications.clear(notificationId, function(wasCleared)
+    chrome.notifications.clear(notificationId, wasCleared =>
     {
       if (wasCleared)
         notificationClosed();
     });
   }
 
-  chrome.notifications.onButtonClicked.addListener(function(notificationId, buttonIndex)
+  chrome.notifications.onButtonClicked.addListener((notificationId, buttonIndex) =>
   {
     notificationButtonClick(buttonIndex);
     clearActiveNotification(notificationId);
@@ -229,7 +231,7 @@ function showNotification(notification)
 /**
  * Initializes the notification system.
  */
-exports.initNotifications = function()
+exports.initNotifications = () =>
 {
   if ("notifications" in chrome)
     initChromeNotifications();
@@ -241,10 +243,7 @@ exports.initNotifications = function()
  *
  * @return {?object}
  */
-exports.getActiveNotification = function()
-{
-  return activeNotification;
-};
+exports.getActiveNotification = () => activeNotification;
 
 let shouldDisplay =
 /**
@@ -255,7 +254,7 @@ let shouldDisplay =
  * @param {string} notificationType
  * @return {boolean}
  */
-exports.shouldDisplay = function(method, notificationType)
+exports.shouldDisplay = (method, notificationType) =>
 {
   let methods = displayMethods[notificationType] || defaultDisplayMethods;
   return methods.indexOf(method) > -1;
Index: lib/popupBlocker.js
diff --git a/lib/popupBlocker.js b/lib/popupBlocker.js
index 464ba9e77d81ebb031d34cdafa2d4f6a0aefb11a..3c171f0aff419a2cdf35c1632e49805d6c2c902a 100644
--- a/lib/popupBlocker.js
+++ b/lib/popupBlocker.js
@@ -19,11 +19,11 @@
 
 "use strict";
 
-let {defaultMatcher} = require("matcher");
-let {BlockingFilter} = require("filterClasses");
-let {stringifyURL, isThirdParty, extractHostFromFrame} = require("url");
-let {checkWhitelisted} = require("whitelisting");
-let {logRequest} = require("devtools");
+const {defaultMatcher} = require("matcher");
+const {BlockingFilter} = require("filterClasses");
+const {stringifyURL, isThirdParty, extractHostFromFrame} = require("url");
+const {checkWhitelisted} = require("whitelisting");
+const {logRequest} = require("devtools");
 
 let loadingPopups = Object.create(null);
 
Index: lib/prefs.js
diff --git a/lib/prefs.js b/lib/prefs.js
index e1aa3f751c5feb430e5dfb83ada7917bd777bd9f..632e3aa03936d8d10a02cfbc8ecd92b58f9721af 100644
--- a/lib/prefs.js
+++ b/lib/prefs.js
@@ -17,7 +17,9 @@
 
 /** @module prefs */
 
-let {EventEmitter} = require("events");
+"use strict";
+
+const {EventEmitter} = require("events");
 
 const keyPrefix = "pref:";
 
@@ -188,7 +190,7 @@ let Prefs = exports.Prefs = {
    * @param {string}   preference
    * @param {function} callback
    */
-  on: function(preference, callback)
+  on(preference, callback)
   {
     eventEmitter.on(preference, callback);
   },
@@ -199,7 +201,7 @@ let Prefs = exports.Prefs = {
    * @param {string}   preference
    * @param {function} callback
    */
-  off: function(preference, callback)
+  off(preference, callback)
   {
     eventEmitter.off(preference, callback);
   },
@@ -230,11 +232,8 @@ function prefToKey(pref)
 function addPreference(pref)
 {
   Object.defineProperty(Prefs, pref, {
-    get: function()
-    {
-      return (pref in overrides ? overrides : defaults)[pref];
-    },
-    set: function(value)
+    get() { return (pref in overrides ? overrides : defaults)[pref]; },
+    set(value)
     {
       let defaultValue = defaults[pref];
 
@@ -262,7 +261,7 @@ function init()
   prefs.forEach(addPreference);
 
   let localLoaded = new Promise(resolve => {
-    ext.storage.get(prefs.map(prefToKey), function(items)
+    ext.storage.get(prefs.map(prefToKey), items =>
     {
       for (let key in items)
         overrides[keyToPref(key)] = items[key];
@@ -274,7 +273,7 @@ function init()
   let managedLoaded = new Promise(resolve => {
     if (require("info").platform == "chromium" && "managed" in chrome.storage)
     {
-      chrome.storage.managed.get(null, function(items)
+      chrome.storage.managed.get(null, items =>
       {
         // Opera doesn't support chrome.storage.managed, but instead simply
         // removing the API, Opera sets chrome.runtime.lastError when using it.
@@ -296,7 +295,7 @@ function init()
 
   function onLoaded()
   {
-    ext.storage.onChanged.addListener(function(changes)
+    ext.storage.onChanged.addListener(changes =>
     {
       for (let key in changes)
       {
Index: lib/requestBlocker.js
diff --git a/lib/requestBlocker.js b/lib/requestBlocker.js
index 91df223d5a1b82d6684d5d20f8a8c44ee7c4ed87..a36c8bdcdb5982ddc44a0d53d2bb86ac689ccebc 100644
--- a/lib/requestBlocker.js
+++ b/lib/requestBlocker.js
@@ -19,15 +19,15 @@
 
 "use strict";
 
-let {Filter, RegExpFilter, BlockingFilter} = require("filterClasses");
-let {Subscription} = require("subscriptionClasses");
-let {defaultMatcher} = require("matcher");
-let {FilterNotifier} = require("filterNotifier");
-let {Prefs} = require("prefs");
-let {checkWhitelisted, getKey} = require("whitelisting");
-let {stringifyURL, extractHostFromFrame, isThirdParty} = require("url");
-let {port} = require("messaging");
-let devtools = require("devtools");
+const {Filter, RegExpFilter, BlockingFilter} = require("filterClasses");
+const {Subscription} = require("subscriptionClasses");
+const {defaultMatcher} = require("matcher");
+const {FilterNotifier} = require("filterNotifier");
+const {Prefs} = require("prefs");
+const {checkWhitelisted, getKey} = require("whitelisting");
+const {stringifyURL, extractHostFromFrame, isThirdParty} = require("url");
+const {port} = require("messaging");
+const devtools = require("devtools");
 
 // Chrome can't distinguish between OBJECT_SUBREQUEST and OBJECT requests.
 RegExpFilter.typeMap.OBJECT_SUBREQUEST = RegExpFilter.typeMap.OBJECT;
@@ -152,7 +152,7 @@ FilterNotifier.on("filter.removed", onFilterChange);
 FilterNotifier.on("filter.disabled", arg => onFilterChange(arg, true));
 FilterNotifier.on("load", onFilterChange);
 
-port.on("request.websocket", function(msg, sender)
+port.on("request.websocket", (msg, sender) =>
 {
   return ext.webRequest.onBeforeRequest._dispatch(
     new URL(msg.url),
Index: lib/stats.js
diff --git a/lib/stats.js b/lib/stats.js
index 81dfff3af0728c3ef5941002c01f055752cdccc3..8f6cd32fd1131e4afe7faa6f8bead3156489bdc7 100644
--- a/lib/stats.js
+++ b/lib/stats.js
@@ -17,11 +17,13 @@
 
 /** @module stats */
 
-let {Prefs} = require("prefs");
-let {BlockingFilter} = require("filterClasses");
-let {FilterNotifier} = require("filterNotifier");
+"use strict";
 
-let badgeColor = "#646464";
+const {Prefs} = require("prefs");
+const {BlockingFilter} = require("filterClasses");
+const {FilterNotifier} = require("filterNotifier");
+
+const badgeColor = "#646464";
 let blockedPerPage = new ext.PageMap();
 
 /**
@@ -30,10 +32,7 @@ let blockedPerPage = new ext.PageMap();
  * @param  {Page} page
  * @return {Number}
  */
-exports.getBlockedPerPage = function(page)
-{
-  return blockedPerPage.get(page) || 0;
-};
+exports.getBlockedPerPage = page => blockedPerPage.get(page) || 0;
 
 FilterNotifier.on("filter.hitCount", (filter, newValue, oldValue, page) =>
 {
@@ -57,11 +56,10 @@ FilterNotifier.on("filter.hitCount", (filter, newValue, oldValue, page) =>
 
 Prefs.on("show_statsinicon", () =>
 {
-  ext.pages.query({}, function(pages)
+  ext.pages.query({}, pages =>
   {
-    for (var i = 0; i < pages.length; i++)
+    for (let page of pages)
     {
-      let page = pages[i];
       let badge = null;
 
       if (Prefs.show_statsinicon)
Index: lib/subscriptionInit.js
diff --git a/lib/subscriptionInit.js b/lib/subscriptionInit.js
index 211fcb343adc88a79220ca2616899bc400c40357..1c530da32d57cd9e7bbfaf0e1269ea7ee29a9a53 100644
--- a/lib/subscriptionInit.js
+++ b/lib/subscriptionInit.js
@@ -19,14 +19,14 @@
 
 "use strict";
 
-let {Subscription, DownloadableSubscription,
-     SpecialSubscription} = require("subscriptionClasses");
-let {FilterStorage} = require("filterStorage");
-let {FilterNotifier} = require("filterNotifier");
-let {Prefs} = require("prefs");
-let {Synchronizer} = require("synchronizer");
-let {Utils} = require("utils");
-let {initNotifications} = require("notificationHelper");
+const {Subscription, DownloadableSubscription,
+       SpecialSubscription} = require("subscriptionClasses");
+const {FilterStorage} = require("filterStorage");
+const {FilterNotifier} = require("filterNotifier");
+const {Prefs} = require("prefs");
+const {Synchronizer} = require("synchronizer");
+const {Utils} = require("utils");
+const {initNotifications} = require("notificationHelper");
 
 let firstRun;
 let subscriptionsCallback = null;
@@ -180,7 +180,7 @@ exports.reinitialized = false;
  *
  * @param {function}
  */
-exports.setSubscriptionsCallback = function(callback)
+exports.setSubscriptionsCallback = callback =>
 {
   subscriptionsCallback = callback;
 };
Index: lib/tldjs.js
diff --git a/lib/tldjs.js b/lib/tldjs.js
index c354375b2fb223fc83c4472f642d4802a2b3d1b5..9106aa2161267a8d5889f7f1ab3f876148eb273f 100644
--- a/lib/tldjs.js
+++ b/lib/tldjs.js
@@ -17,6 +17,8 @@
 
 /** @module tldjs */
 
+"use strict";
+
 let getDomain =
 /**
  * Get the base domain for given hostname.
@@ -24,7 +26,7 @@ let getDomain =
  * @param {string} hostname
  * @return {string}
  */
-exports.getDomain = function(hostname)
+exports.getDomain = hostname =>
 {
   let bits = hostname.split(".");
   let cutoff = bits.length - 2;
Index: lib/uninstall.js
diff --git a/lib/uninstall.js b/lib/uninstall.js
index 0c2ad71c82b728239558c2bdae7ccc9a143d9923..cc83bac7589fc70bc0542d82da9b9ab6a05b4124 100644
--- a/lib/uninstall.js
+++ b/lib/uninstall.js
@@ -17,16 +17,17 @@
 
 /** @module uninstall */
 
-let info = require("info");
-let {Prefs} = require("prefs");
-let {Utils} = require("utils");
+"use strict";
+
+const info = require("info");
+const {Prefs} = require("prefs");
+const {Utils} = require("utils");
 
 function setUninstallURL()
 {
   let search = [];
-  let keys = ["addonName", "addonVersion", "application", "applicationVersion",
-              "platform", "platformVersion"];
-  for (let key of keys)
+  for (let key of ["addonName", "addonVersion", "application",
+                   "applicationVersion", "platform", "platformVersion"])
     search.push(key + "=" + encodeURIComponent(info[key]));
 
   let downlCount = Prefs.notificationdata.downloadCount || 0;
Index: lib/url.js
diff --git a/lib/url.js b/lib/url.js
index 4ea741dbbfee3134f421426713b877edf6f39364..7614799423094d75f900f13e7f0cd35919c8b950 100644
--- a/lib/url.js
+++ b/lib/url.js
@@ -17,8 +17,10 @@
 
 /** @module url */
 
-let getDomain = require("tldjs").getDomain;
-let punycode = require("punycode");
+"use strict";
+
+const {getDomain} = require("tldjs");
+const punycode = require("punycode");
 
 let getDecodedHostname =
 /**
@@ -28,7 +30,7 @@ let getDecodedHostname =
  * @return {string}
  * @static
  */
-exports.getDecodedHostname = function(url)
+exports.getDecodedHostname = url =>
 {
   let hostname = url.hostname;
 
@@ -46,7 +48,7 @@ exports.getDecodedHostname = function(url)
  * @param {Frame} frame
  * @return {string}
  */
-exports.extractHostFromFrame = function(frame)
+exports.extractHostFromFrame = frame =>
 {
   for (; frame; frame = frame.parent)
   {
@@ -65,7 +67,7 @@ exports.extractHostFromFrame = function(frame)
  * @param {URL} url
  * @return {string}
  */
-exports.stringifyURL = function(url)
+exports.stringifyURL = url =>
 {
   let protocol = url.protocol;
   let href = url.href;
@@ -102,7 +104,7 @@ function isDomain(hostname)
  * @param {string} documentHost  The IDN-decoded hostname of the document
  * @return {Boolean}
  */
-exports.isThirdParty = function(url, documentHost)
+exports.isThirdParty = (url, documentHost) =>
 {
   let requestHost = getDecodedHostname(url).replace(/\.+$/, "");
   documentHost = documentHost.replace(/\.+$/, "");
Index: lib/utils.js
diff --git a/lib/utils.js b/lib/utils.js
index e965cad717e4cb7f2c19a8181a4edbebf322f14c..9361039f8137f85bb5fe4f7fbf43590531c9a657 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -15,19 +15,21 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-var Utils = exports.Utils = {
+"use strict";
+
+let Utils = exports.Utils = {
   systemPrincipal: null,
-  getString: function(id)
+  getString(id)
   {
     return ext.i18n.getMessage("global_" + id);
   },
-  runAsync: function(callback)
+  runAsync(callback)
   {
     if (document.readyState == "loading")
     {
       // Make sure to not run asynchronous actions before all
       // scripts loaded. This caused issues on Opera in the past.
-      let onDOMContentLoaded = function()
+      let onDOMContentLoaded = () =>
       {
         document.removeEventListener("DOMContentLoaded", onDOMContentLoaded);
         callback();
@@ -41,40 +43,38 @@ var Utils = exports.Utils = {
   },
   get appLocale()
   {
-    var locale = ext.i18n.getMessage("@@ui_locale").replace(/_/g, "-");
+    let locale = ext.i18n.getMessage("@@ui_locale").replace(/_/g, "-");
     Object.defineProperty(this, "appLocale", {value: locale, enumerable: true});
     return this.appLocale;
   },
-  generateChecksum: function(lines)
+  generateChecksum(lines)
   {
     // We cannot calculate MD5 checksums yet :-(
     return null;
   },
-  checkLocalePrefixMatch: function(prefixes)
+  checkLocalePrefixMatch(prefixes)
   {
     if (!prefixes)
       return null;
 
-    var list = prefixes.split(",");
-    for (var i = 0; i < list.length; i++)
-      if (new RegExp("^" + list[i] + "\\b").test(this.appLocale))
-        return list[i];
+    for (let prefix of prefixes.split(","))
+      if (new RegExp("^" + prefix + "\\b").test(this.appLocale))
+        return prefix;
 
     return null;
   },
 
-  chooseFilterSubscription: function(subscriptions)
+  chooseFilterSubscription(subscriptions)
   {
-    var selectedItem = null;
-    var selectedPrefix = null;
-    var matchCount = 0;
-    for (var i = 0; i < subscriptions.length; i++)
+    let selectedItem = null;
+    let selectedPrefix = null;
+    let matchCount = 0;
+    for (let subscription of subscriptions)
     {
-      var subscription = subscriptions[i];
       if (!selectedItem)
         selectedItem = subscription;
 
-      var prefix = require("utils").Utils.checkLocalePrefixMatch(subscription.getAttribute("prefixes"));
+      let prefix = Utils.checkLocalePrefixMatch(subscription.getAttribute("prefixes"));
       if (prefix)
       {
         if (!selectedPrefix || selectedPrefix.length < prefix.length)
@@ -102,14 +102,13 @@ var Utils = exports.Utils = {
     return selectedItem;
   },
 
-  getDocLink: function(linkID)
+  getDocLink(linkID)
   {
-    var Prefs = require("prefs").Prefs;
-    var docLink = Prefs.documentation_link;
+    let docLink = require("prefs").Prefs.documentation_link;
     return docLink.replace(/%LINK%/g, linkID).replace(/%LANG%/g, Utils.appLocale);
   },
 
-  yield: function()
+  yield()
   {
   }
 };
Index: lib/whitelisting.js
diff --git a/lib/whitelisting.js b/lib/whitelisting.js
index 3283952bf860f7db1d853941ef76643db4a8862c..da2f187d797906149caf29831a0187942a74525e 100644
--- a/lib/whitelisting.js
+++ b/lib/whitelisting.js
@@ -19,14 +19,15 @@
 
 "use strict";
 
-let {defaultMatcher} = require("matcher");
-let {RegExpFilter} = require("filterClasses");
-let {DownloadableSubscription} = require("subscriptionClasses");
-let {FilterNotifier} = require("filterNotifier");
-let {stringifyURL, getDecodedHostname, extractHostFromFrame, isThirdParty} = require("url");
-let {port} = require("messaging");
-let devtools = require("devtools");
-let {verifySignature} = require("rsa");
+const {defaultMatcher} = require("matcher");
+const {RegExpFilter} = require("filterClasses");
+const {DownloadableSubscription} = require("subscriptionClasses");
+const {FilterNotifier} = require("filterNotifier");
+const {stringifyURL, getDecodedHostname,
+       extractHostFromFrame, isThirdParty} = require("url");
+const {port} = require("messaging");
+const devtools = require("devtools");
+const {verifySignature} = require("rsa");
 
 let sitekeys = new ext.PageMap();
 
@@ -60,7 +61,7 @@ let checkWhitelisted =
  * @param {number} [typeMask=RegExpFilter.typeMap.DOCUMENT]
  * @return {?WhitelistFilter}
  */
-exports.checkWhitelisted = function(page, frame, typeMask)
+exports.checkWhitelisted = (page, frame, typeMask) =>
 {
   if (typeof typeMask == "undefined")
     typeMask = RegExpFilter.typeMap.DOCUMENT;
@@ -118,7 +119,7 @@ let getKey =
  * @param {Frame} frame
  * @return {string}
  */
-exports.getKey = function(page, frame)
+exports.getKey = (page, frame) =>
 {
   let keys = sitekeys.get(page);
   if (!keys)
Index: notification.js
diff --git a/notification.js b/notification.js
index 2c553d2ca291941a4f3f1f699ef77b684f29ccd3..bcc5d8554573ed06eb53b139529884653efecc02 100644
--- a/notification.js
+++ b/notification.js
@@ -15,22 +15,21 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-var backgroundPage = ext.backgroundPage.getWindow();
-var require = backgroundPage.require;
+"use strict";
 
-var Utils = require("utils").Utils;
-var Notification = require("notification").Notification;
-var notificationHelper = require("notificationHelper");
-var getActiveNotification = notificationHelper.getActiveNotification;
-var shouldDisplayNotification = notificationHelper.shouldDisplay;
+const {require} = ext.backgroundPage.getWindow();
+
+const {Utils} = require("utils");
+const {Notification} = require("notification");
+const {getActiveNotification, shouldDisplay} = require("notificationHelper");
 
 function getDocLinks(notification)
 {
   if (!notification.links)
     return [];
 
-  var docLinks = [];
-  notification.links.forEach(function(link)
+  let docLinks = [];
+  notification.links.forEach(link =>
   {
     docLinks.push(Utils.getDocLink(link));
   });
@@ -39,21 +38,21 @@ function getDocLinks(notification)
 
 function insertMessage(element, text, links)
 {
-  var match = /^(.*?)<(a|strong)>(.*?)<\/\2>(.*)$/.exec(text);
+  let match = /^(.*?)<(a|strong)>(.*?)<\/\2>(.*)$/.exec(text);
   if (!match)
   {
     element.appendChild(document.createTextNode(text));
     return;
   }
 
-  var before = match[1];
-  var tagName = match[2];
-  var value = match[3];
-  var after = match[4];
+  let before = match[1];
+  let tagName = match[2];
+  let value = match[3];
+  let after = match[4];
 
   insertMessage(element, before, links);
 
-  var newElement = document.createElement(tagName);
+  let newElement = document.createElement(tagName);
   if (tagName === "a" && links && links.length)
     newElement.href = links.shift();
   insertMessage(newElement, value, links);
@@ -62,23 +61,23 @@ function insertMessage(element, text, links)
   insertMessage(element, after, links);
 }
 
-window.addEventListener("load", function()
+window.addEventListener("load", () =>
 {
-  var notification = getActiveNotification();
-  if (!notification || !shouldDisplayNotification("popup", notification.type))
+  let notification = getActiveNotification();
+  if (!notification || !shouldDisplay("popup", notification.type))
     return;
 
-  var texts = Notification.getLocalizedTexts(notification);
-  var titleElement = document.getElementById("notification-title");
+  let texts = Notification.getLocalizedTexts(notification);
+  let titleElement = document.getElementById("notification-title");
   titleElement.textContent = texts.title;
 
-  var docLinks = getDocLinks(notification);
-  var messageElement = document.getElementById("notification-message");
+  let docLinks = getDocLinks(notification);
+  let messageElement = document.getElementById("notification-message");
   insertMessage(messageElement, texts.message, docLinks);
 
-  messageElement.addEventListener("click", function(event)
+  messageElement.addEventListener("click", event =>
   {
-    var link = event.target;
+    let link = event.target;
     while (link && link !== messageElement && link.localName !== "a")
       link = link.parentNode;
     if (!link)
@@ -88,10 +87,10 @@ window.addEventListener("load", function()
     ext.pages.open(link.href);
   });
 
-  var notificationElement = document.getElementById("notification");
+  let notificationElement = document.getElementById("notification");
   notificationElement.className = notification.type;
   notificationElement.hidden = false;
-  notificationElement.addEventListener("click", function(event)
+  notificationElement.addEventListener("click", event =>
   {
     switch (event.target.id)
     {
Index: options.js
diff --git a/options.js b/options.js
index 51c3752a2e9374f28981c9b68337c9326a953588..9ecfcabb4ce52007dfbed3b3e8e755b4e7adb259 100644
--- a/options.js
+++ b/options.js
@@ -32,27 +32,27 @@
  */
 function wrapper(baseMessage /* , [paramKeys] */)
 {
-  var paramKeys = [];
-  for (var i = 1; i < arguments.length; i++)
+  let paramKeys = [];
+  for (let i = 1; i < arguments.length; i++)
     paramKeys.push(arguments[i]);
 
   return function(/* [paramValues], callback */)
   {
-    var message = Object.create(null);
-    for (var key in baseMessage)
+    let message = Object.create(null);
+    for (let key in baseMessage)
       if (baseMessage.hasOwnProperty(key))
         message[key] = baseMessage[key];
 
-    var paramValues = [];
-    var callback;
+    let paramValues = [];
+    let callback;
 
     if (arguments.length > 0)
     {
-      var lastArg = arguments[arguments.length - 1];
+      let lastArg = arguments[arguments.length - 1];
       if (typeof lastArg == "function")
         callback = lastArg;
 
-      for (var i = 0; i < arguments.length - (callback ? 1 : 0); i++)
+      for (let i = 0; i < arguments.length - (callback ? 1 : 0); i++)
         message[paramKeys[i]] = arguments[i];
     }
 
@@ -60,29 +60,28 @@ function wrapper(baseMessage /* , [paramKeys] */)
   };
 }
 
-var getDocLink = wrapper({type: "app.get", what: "doclink"}, "link");
-var getInfo = wrapper({type: "app.get"}, "what");
-var getPref = wrapper({type: "prefs.get"}, "key");
-var togglePref = wrapper({type: "prefs.toggle"}, "key");
-var getSubscriptions = wrapper({type: "subscriptions.get"},
-                               "downloadable", "special");
-var removeSubscription = wrapper({type: "subscriptions.remove"}, "url");
-var addSubscription = wrapper({type: "subscriptions.add"},
+const getDocLink = wrapper({type: "app.get", what: "doclink"}, "link");
+const getInfo = wrapper({type: "app.get"}, "what");
+const getPref = wrapper({type: "prefs.get"}, "key");
+const togglePref = wrapper({type: "prefs.toggle"}, "key");
+const getSubscriptions = wrapper({type: "subscriptions.get"},
+                                 "downloadable", "special");
+const removeSubscription = wrapper({type: "subscriptions.remove"}, "url");
+const addSubscription = wrapper({type: "subscriptions.add"},
                                 "url", "title", "homepage");
-var toggleSubscription = wrapper({type: "subscriptions.toggle"},
-                                 "url", "keepInstalled");
-var updateSubscription = wrapper({type: "subscriptions.update"}, "url");
-var importRawFilters = wrapper({type: "filters.importRaw"},
-                               "text", "removeExisting");
-var addFilter = wrapper({type: "filters.add"}, "text");
-var getFilters = wrapper({type: "filters.get"}, "subscriptionUrl");
-var removeFilter = wrapper({type: "filters.remove"}, "text");
+const toggleSubscription = wrapper({type: "subscriptions.toggle"},
+                                   "url", "keepInstalled");
+const updateSubscription = wrapper({type: "subscriptions.update"}, "url");
+const importRawFilters = wrapper({type: "filters.importRaw"},
+                                 "text", "removeExisting");
+const addFilter = wrapper({type: "filters.add"}, "text");
+const getFilters = wrapper({type: "filters.get"}, "subscriptionUrl");
+const removeFilter = wrapper({type: "filters.remove"}, "text");
 
-var i18n = ext.i18n;
-var whitelistedDomainRegexp = /^@@\|\|([^\/:]+)\^\$document$/;
-var delayedSubscriptionSelection = null;
+const whitelistedDomainRegexp = /^@@\|\|([^\/:]+)\^\$document$/;
+let delayedSubscriptionSelection = null;
 
-var acceptableAdsUrl;
+let acceptableAdsUrl;
 
 // Loads options from localStorage and sets UI elements accordingly
 function loadOptions()
@@ -91,27 +90,27 @@ function loadOptions()
   document.title = i18n.getMessage("options");
 
   // Set links
-  getPref("subscriptions_exceptionsurl", function(url)
+  getPref("subscriptions_exceptionsurl", url =>
   {
     acceptableAdsUrl = url;
     $("#acceptableAdsLink").attr("href", acceptableAdsUrl);
   });
-  getDocLink("acceptable_ads", function(url)
+  getDocLink("acceptable_ads", url =>
   {
     $("#acceptableAdsDocs").attr("href", url);
   });
-  getDocLink("filterdoc", function(url)
+  getDocLink("filterdoc", url =>
   {
     setLinks("filter-must-follow-syntax", url);
   });
-  getInfo("application", function(application)
+  getInfo("application", application =>
   {
-    getInfo("platform", function(platform)
+    getInfo("platform", platform =>
     {
       if (platform == "chromium" && application != "opera")
         application = "chrome";
 
-      getDocLink(application + "_support", function(url)
+      getDocLink(application + "_support", url =>
       {
         setLinks("found-a-bug", url);
       });
@@ -143,12 +142,12 @@ function loadOptions()
   initCheckbox("show_devtools_panel");
   initCheckbox("shouldShowNotifications", "notifications_ignoredcategories");
 
-  getInfo("features", function(features)
+  getInfo("features", features =>
   {
     if (!features.devToolsPanel)
       document.getElementById("showDevtoolsPanelContainer").hidden = true;
   });
-  getPref("notifications_showui", function(notifications_showui)
+  getPref("notifications_showui", notifications_showui =>
   {
     if (!notifications_showui)
       document.getElementById("shouldShowNotificationsContainer").hidden = true;
@@ -187,15 +186,14 @@ $(loadOptions);
 
 function convertSpecialSubscription(subscription)
 {
-  getFilters(subscription.url, function(filters)
+  getFilters(subscription.url, filters =>
   {
-    for (var j = 0; j < filters.length; j++)
+    for (let filter of filters)
     {
-      var filter = filters[j].text;
-      if (whitelistedDomainRegexp.test(filter))
+      if (whitelistedDomainRegexp.test(filter.text))
         appendToListBox("excludedDomainsBox", RegExp.$1);
       else
-        appendToListBox("userFiltersBox", filter);
+        appendToListBox("userFiltersBox", filter.text);
     }
   });
 }
@@ -204,15 +202,14 @@ function convertSpecialSubscription(subscription)
 function reloadFilters()
 {
   // Load user filter URLs
-  var container = document.getElementById("filterLists");
+  let container = document.getElementById("filterLists");
   while (container.lastChild)
     container.removeChild(container.lastChild);
 
-  getSubscriptions(true, false, function(subscriptions)
+  getSubscriptions(true, false, subscriptions =>
   {
-    for (var i = 0; i < subscriptions.length; i++)
+    for (let subscription of subscriptions)
     {
-      var subscription = subscriptions[i];
       if (subscription.url == acceptableAdsUrl)
         $("#acceptableAds").prop("checked", !subscription.disabled);
       else
@@ -221,27 +218,27 @@ function reloadFilters()
   });
 
   // User-entered filters
-  getSubscriptions(false, true, function(subscriptions)
+  getSubscriptions(false, true, subscriptions =>
   {
     document.getElementById("userFiltersBox").innerHTML = "";
     document.getElementById("excludedDomainsBox").innerHTML = "";
 
-    for (var i = 0; i < subscriptions.length; i++)
-      convertSpecialSubscription(subscriptions[i]);
+    for (let subscription of subscriptions)
+      convertSpecialSubscription(subscription);
   });
 }
 
 function initCheckbox(id, key)
 {
   key = key || id;
-  var checkbox = document.getElementById(id);
+  let checkbox = document.getElementById(id);
 
-  getPref(key, function(value)
+  getPref(key, value =>
   {
     onPrefMessage(key, value);
   });
 
-  checkbox.addEventListener("click", function()
+  checkbox.addEventListener("click", () =>
   {
     togglePref(key);
   }, false);
@@ -250,24 +247,24 @@ function initCheckbox(id, key)
 function loadRecommendations()
 {
   fetch("subscriptions.xml")
-    .then(function(response)
+    .then(response =>
     {
       return response.text();
     })
-    .then(function(text)
+    .then(text =>
     {
-      var selectedIndex = 0;
-      var selectedPrefix = null;
-      var matchCount = 0;
+      let selectedIndex = 0;
+      let selectedPrefix = null;
+      let matchCount = 0;
 
-      var list = document.getElementById("subscriptionSelector");
-      var doc = new DOMParser().parseFromString(text, "application/xml");
-      var elements = doc.documentElement.getElementsByTagName("subscription");
+      let list = document.getElementById("subscriptionSelector");
+      let doc = new DOMParser().parseFromString(text, "application/xml");
+      let elements = doc.documentElement.getElementsByTagName("subscription");
 
-      for (var i = 0; i < elements.length; i++)
+      for (let i = 0; i < elements.length; i++)
       {
-        var element = elements[i];
-        var option = new Option();
+        let element = elements[i];
+        let option = new Option();
         option.text = element.getAttribute("title") + " (" +
                       element.getAttribute("specialization") + ")";
         option._data = {
@@ -276,7 +273,7 @@ function loadRecommendations()
           homepage: element.getAttribute("homepage")
         };
 
-        var prefix = element.getAttribute("prefixes");
+        let prefix = element.getAttribute("prefixes");
         if (prefix)
         {
           prefix = prefix.replace(/\W/g, "_");
@@ -307,8 +304,8 @@ function loadRecommendations()
         list.appendChild(option);
       }
 
-      var option = new Option();
-      var label = i18n.getMessage("filters_addSubscriptionOther_label");
+      let option = new Option();
+      let label = i18n.getMessage("filters_addSubscriptionOther_label");
       option.text = label + "\u2026";
       option._data = null;
       list.appendChild(option);
@@ -322,7 +319,7 @@ function loadRecommendations()
 
 function startSubscriptionSelection(title, url)
 {
-  var list = document.getElementById("subscriptionSelector");
+  let list = document.getElementById("subscriptionSelector");
   if (list.length == 0)
   {
     delayedSubscriptionSelection = [title, url];
@@ -345,8 +342,8 @@ function startSubscriptionSelection(title, url)
 
 function updateSubscriptionSelection()
 {
-  var list = document.getElementById("subscriptionSelector");
-  var data = list.options[list.selectedIndex]._data;
+  let list = document.getElementById("subscriptionSelector");
+  let data = list.options[list.selectedIndex]._data;
   if (data)
     $("#customSubscriptionContainer").hide();
   else
@@ -358,13 +355,13 @@ function updateSubscriptionSelection()
 
 function addSubscriptionClicked()
 {
-  var list = document.getElementById("subscriptionSelector");
-  var data = list.options[list.selectedIndex]._data;
+  let list = document.getElementById("subscriptionSelector");
+  let data = list.options[list.selectedIndex]._data;
   if (data)
     addSubscription(data.url, data.title, data.homepage);
   else
   {
-    var url = document.getElementById("customSubscriptionLocation").value.trim();
+    let url = document.getElementById("customSubscriptionLocation").value.trim();
     if (!/^https?:/i.test(url))
     {
       alert(i18n.getMessage("global_subscription_invalid_location"));
@@ -372,7 +369,7 @@ function addSubscriptionClicked()
       return;
     }
 
-    var title = document.getElementById("customSubscriptionTitle").value.trim();
+    let title = document.getElementById("customSubscriptionTitle").value.trim();
     if (!title)
       title = url;
 
@@ -391,10 +388,9 @@ function toggleAcceptableAds()
 
 function findSubscriptionElement(subscription)
 {
-  var children = document.getElementById("filterLists").childNodes;
-  for (var i = 0; i < children.length; i++)
-    if (children[i]._subscription.url == subscription.url)
-      return children[i];
+  for (let child of document.getElementById("filterLists").childNodes)
+    if (child._subscription.url == subscription.url)
+      return child;
   return null;
 }
 
@@ -405,7 +401,7 @@ function updateSubscriptionInfo(element, subscription)
   else
     subscription = element._subscription;
 
-  var title = element.getElementsByClassName("subscriptionTitle")[0];
+  let title = element.getElementsByClassName("subscriptionTitle")[0];
   title.textContent = subscription.title;
   title.setAttribute("title", subscription.url);
   if (subscription.homepage)
@@ -413,20 +409,20 @@ function updateSubscriptionInfo(element, subscription)
   else
     title.href = subscription.url;
 
-  var enabled = element.getElementsByClassName("subscriptionEnabled")[0];
+  let enabled = element.getElementsByClassName("subscriptionEnabled")[0];
   enabled.checked = !subscription.disabled;
 
-  var lastUpdate = element.getElementsByClassName("subscriptionUpdate")[0];
+  let lastUpdate = element.getElementsByClassName("subscriptionUpdate")[0];
   lastUpdate.classList.remove("error");
 
-  var downloadStatus = subscription.downloadStatus;
+  let downloadStatus = subscription.downloadStatus;
   if (subscription.isDownloading)
   {
     lastUpdate.textContent = i18n.getMessage("filters_subscription_lastDownload_inProgress");
   }
   else if (downloadStatus && downloadStatus != "synchronize_ok")
   {
-     var map =
+     let map =
      {
        "synchronize_invalid_url": "filters_subscription_lastDownload_invalidURL",
        "synchronize_connection_error": "filters_subscription_lastDownload_connectionError",
@@ -441,15 +437,15 @@ function updateSubscriptionInfo(element, subscription)
   }
   else if (subscription.lastDownload > 0)
   {
-    var timeDate = i18n_timeDateStrings(subscription.lastDownload * 1000);
-    var messageID = (timeDate[1] ? "last_updated_at" : "last_updated_at_today");
+    let timeDate = i18n_timeDateStrings(subscription.lastDownload * 1000);
+    let messageID = (timeDate[1] ? "last_updated_at" : "last_updated_at_today");
     lastUpdate.textContent = i18n.getMessage(messageID, timeDate);
   }
 }
 
 function onSubscriptionMessage(action, subscription)
 {
-  var element = findSubscriptionElement(subscription);
+  let element = findSubscriptionElement(subscription);
 
   switch (action)
   {
@@ -491,7 +487,7 @@ function onPrefMessage(key, value)
       value = value.indexOf("*") == -1;
       break;
   }
-  var checkbox = document.getElementById(key);
+  let checkbox = document.getElementById(key);
   if (checkbox)
     checkbox.checked = value;
 }
@@ -522,7 +518,7 @@ function onFilterMessage(action, filter)
 function appendToListBox(boxId, text)
 {
   // Note: document.createElement("option") is unreliable in Opera
-  var elt = new Option();
+  let elt = new Option();
   elt.text = text;
   elt.value = text;
   document.getElementById(boxId).appendChild(elt);
@@ -541,12 +537,12 @@ function addWhitelistDomain(event)
 {
   event.preventDefault();
 
-  var domain = document.getElementById("newWhitelistDomain").value.replace(/\s/g, "");
+  let domain = document.getElementById("newWhitelistDomain").value.replace(/\s/g, "");
   document.getElementById("newWhitelistDomain").value = "";
   if (!domain)
     return;
 
-  var filterText = "@@||" + domain + "^$document";
+  let filterText = "@@||" + domain + "^$document";
   addFilter(filterText);
 }
 
@@ -555,8 +551,8 @@ function addTypedFilter(event)
 {
   event.preventDefault();
 
-  var element = document.getElementById("newFilter");
-  addFilter(element.value, function(errors)
+  let element = document.getElementById("newFilter");
+  addFilter(element.value, errors =>
   {
     if (errors.length > 0)
       alert(errors.join("\n"));
@@ -569,16 +565,15 @@ function addTypedFilter(event)
 function removeSelectedExcludedDomain(event)
 {
   event.preventDefault();
-  var excludedDomainsBox = document.getElementById("excludedDomainsBox");
-  var remove = [];
-  for (var i = 0; i < excludedDomainsBox.length; i++)
-    if (excludedDomainsBox.options[i].selected)
-      remove.push(excludedDomainsBox.options[i].value);
+  let remove = [];
+  for (let option of document.getElementById("excludedDomainsBox").options)
+    if (option.selected)
+      remove.push(option.value);
   if (!remove.length)
     return;
 
-  for (var i = 0; i < remove.length; i++)
-    removeFilter("@@||" + remove[i] + "^$document");
+  for (let domain of remove)
+    removeFilter("@@||" + domain + "^$document");
 }
 
 // Removes all currently selected filters
@@ -614,9 +609,9 @@ function toggleFiltersInRawFormat(event)
 // Imports filters in the raw text box
 function importRawFiltersText()
 {
-  var text = document.getElementById("rawFiltersText").value;
+  let text = document.getElementById("rawFiltersText").value;
 
-  importRawFilters(text, true, function(errors)
+  importRawFilters(text, true, errors =>
   {
     if (errors.length > 0)
       alert(errors.join("\n"));
@@ -635,15 +630,15 @@ function updateFilterLists()
 // Adds a subscription entry to the UI.
 function addSubscriptionEntry(subscription)
 {
-  var template = document.getElementById("subscriptionTemplate");
-  var element = template.cloneNode(true);
+  let template = document.getElementById("subscriptionTemplate");
+  let element = template.cloneNode(true);
   element.removeAttribute("id");
   element._subscription = subscription;
 
-  var removeButton = element.getElementsByClassName("subscriptionRemoveButton")[0];
+  let removeButton = element.getElementsByClassName("subscriptionRemoveButton")[0];
   removeButton.setAttribute("title", removeButton.textContent);
   removeButton.textContent = "\xD7";
-  removeButton.addEventListener("click", function()
+  removeButton.addEventListener("click", () =>
   {
     if (!confirm(i18n.getMessage("global_remove_subscription_warning")))
       return;
@@ -651,14 +646,14 @@ function addSubscriptionEntry(subscription)
     removeSubscription(subscription.url);
   }, false);
 
-  getPref("additional_subscriptions", function(additionalSubscriptions)
+  getPref("additional_subscriptions", additionalSubscriptions =>
   {
     if (additionalSubscriptions.indexOf(subscription.url) != -1)
       removeButton.style.visibility = "hidden";
   });
 
-  var enabled = element.getElementsByClassName("subscriptionEnabled")[0];
-  enabled.addEventListener("click", function()
+  let enabled = element.getElementsByClassName("subscriptionEnabled")[0];
+  enabled.addEventListener("click", () =>
   {
     subscription.disabled = !subscription.disabled;
     toggleSubscription(subscription.url, true);
@@ -671,12 +666,12 @@ function addSubscriptionEntry(subscription)
 
 function setLinks(id)
 {
-  var element = document.getElementById(id);
+  let element = document.getElementById(id);
   if (!element)
     return;
 
-  var links = element.getElementsByTagName("a");
-  for (var i = 0; i < links.length; i++)
+  let links = element.getElementsByTagName("a");
+  for (let i = 0; i < links.length; i++)
   {
     if (typeof arguments[i + 1] == "string")
     {
@@ -691,7 +686,7 @@ function setLinks(id)
   }
 }
 
-ext.onMessage.addListener(function(message)
+ext.onMessage.addListener(message =>
 {
   switch (message.type)
   {
@@ -699,25 +694,24 @@ ext.onMessage.addListener(function(message)
       switch (message.action)
       {
         case "addSubscription":
-          var subscription = message.args[0];
+          let subscription = message.args[0];
           startSubscriptionSelection(subscription.title, subscription.url);
           break;
         case "focusSection":
-          var tabs = document.getElementsByClassName("ui-tabs-panel");
-          for (var i = 0; i < tabs.length; i++)
+          for (let tab of document.getElementsByClassName("ui-tabs-panel"))
           {
-            var found = tabs[i].querySelector(
+            let found = tab.querySelector(
               "[data-section='" + message.args[0] + "']"
             );
             if (!found)
               continue;
 
-            var previous = document.getElementsByClassName("focused");
+            let previous = document.getElementsByClassName("focused");
             if (previous.length > 0)
               previous[0].classList.remove("focused");
 
-            var tab = $("[href='#" + tabs[i].id + "']");
-            $("#tabs").tabs("select", tab.parent().index());
+            let index = $("[href='#" + tab.id + "']").parent().index();
+            $("#tabs").tabs("select", index);
             found.classList.add("focused");
           }
           break;
Index: popup.js
diff --git a/popup.js b/popup.js
index d611a7b44aa3bfd718e15635d0ec99297413008e..cce3937f49c4c09551b26a582d0437c86dfa258f 100644
--- a/popup.js
+++ b/popup.js
@@ -15,20 +15,21 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-var backgroundPage = ext.backgroundPage.getWindow();
-var require = backgroundPage.require;
+"use strict";
 
-var Filter = require("filterClasses").Filter;
-var FilterStorage = require("filterStorage").FilterStorage;
-var Prefs = require("prefs").Prefs;
-var checkWhitelisted = require("whitelisting").checkWhitelisted;
-var getDecodedHostname = require("url").getDecodedHostname;
+const {require} = ext.backgroundPage.getWindow();
 
-var page = null;
+const {Filter} = require("filterClasses");
+const {FilterStorage} = require("filterStorage");
+const {Prefs} = require("prefs");
+const {checkWhitelisted} = require("whitelisting");
+const {getDecodedHostname} = require("url");
+
+let page = null;
 
 function onLoad()
 {
-  ext.pages.query({active: true, lastFocusedWindow: true}, function(pages)
+  ext.pages.query({active: true, lastFocusedWindow: true}, pages =>
   {
     page = pages[0];
 
@@ -40,7 +41,7 @@ function onLoad()
     {
       document.body.classList.add("nohtml");
       require("messaging").getPort(window).on(
-        "composer.ready", function(message, sender)
+        "composer.ready", (message, sender) =>
         {
           if (sender.page.id == page.id)
             document.body.classList.remove("nohtml");
@@ -57,7 +58,7 @@ function onLoad()
       if (checkWhitelisted(page))
         document.body.classList.add("disabled");
 
-      page.sendMessage({type: "composer.content.getState"}, function(response)
+      page.sendMessage({type: "composer.content.getState"}, response =>
       {
         if (response && response.active)
           document.body.classList.add("clickhide-active");
@@ -68,16 +69,14 @@ function onLoad()
   document.getElementById("enabled").addEventListener("click", toggleEnabled, false);
   document.getElementById("clickhide").addEventListener("click", activateClickHide, false);
   document.getElementById("clickhide-cancel").addEventListener("click", cancelClickHide, false);
-  document.getElementById("options").addEventListener("click", function()
+  document.getElementById("options").addEventListener("click", () =>
   {
     ext.showOptions();
   }, false);
 
   // Set up collapsing of menu items
-  var collapsers = document.getElementsByClassName("collapse");
-  for (var i = 0; i < collapsers.length; i++)
+  for (let collapser of document.getElementsByClassName("collapse"))
   {
-    var collapser = collapsers[i];
     collapser.addEventListener("click", toggleCollapse, false);
     if (!Prefs[collapser.dataset.option])
       document.getElementById(collapser.dataset.collapsable).classList.add("collapsed");
@@ -86,11 +85,11 @@ function onLoad()
 
 function toggleEnabled()
 {
-  var disabled = document.body.classList.toggle("disabled");
+  let disabled = document.body.classList.toggle("disabled");
   if (disabled)
   {
-    var host = getDecodedHostname(page.url).replace(/^www\./, "");
-    var filter = Filter.fromText("@@||" + host + "^$document");
+    let host = getDecodedHostname(page.url).replace(/^www\./, "");
+    let filter = Filter.fromText("@@||" + host + "^$document");
     if (filter.subscriptions.length && filter.disabled)
       filter.disabled = false;
     else
@@ -102,7 +101,7 @@ function toggleEnabled()
   else
   {
     // Remove any exception rules applying to this URL
-    var filter = checkWhitelisted(page);
+    let filter = checkWhitelisted(page);
     while (filter)
     {
       FilterStorage.removeFilter(filter);
@@ -135,7 +134,7 @@ function cancelClickHide()
 
 function toggleCollapse(event)
 {
-  var collapser = event.currentTarget;
+  let collapser = event.currentTarget;
   Prefs[collapser.dataset.option] = !Prefs[collapser.dataset.option];
   collapser.parentNode.classList.toggle("collapsed");
 }
Index: qunit/common.js
diff --git a/qunit/common.js b/qunit/common.js
index 8142b621d4e71d019239b964b1d52bb4fb6943d8..906348ce243b91729a5067c9dcfe1c47627fc0b4 100644
--- a/qunit/common.js
+++ b/qunit/common.js
@@ -15,6 +15,7 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+"use strict";
 
 importAll("filterClasses", this);
 importAll("subscriptionClasses", this);
@@ -43,9 +44,9 @@ function restoreFilterComponents()
 function preparePrefs()
 {
   this._pbackup = Object.create(null);
-  for (var pref in Prefs)
+  for (let pref in Prefs)
   {
-    var value = Prefs[pref];
+    let value = Prefs[pref];
     this._pbackup[pref] = value;
   }
   Prefs.enabled = true;
@@ -53,7 +54,7 @@ function preparePrefs()
 
 function restorePrefs()
 {
-  for (var pref in this._pbackup)
+  for (let pref in this._pbackup)
     Prefs[pref] = this._pbackup[pref];
 }
 
Index: qunit/tests/cssEscaping.js
diff --git a/qunit/tests/cssEscaping.js b/qunit/tests/cssEscaping.js
index 5986646293ff46de59655ed24bf0bd9d214306fa..1ba05486dca37b0f970f9522b44b01d19317935e 100644
--- a/qunit/tests/cssEscaping.js
+++ b/qunit/tests/cssEscaping.js
@@ -1,27 +1,23 @@
-(function()
-{
-  var filterClasses = require("filterClasses");
-  var Filter = filterClasses.Filter;
-  var ElemHideFilter = filterClasses.ElemHideFilter;
+"use strict";
 
-  var filterComposer = require("filterComposer");
-  var escapeCSS = filterComposer.escapeCSS;
-  var quoteCSS = filterComposer.quoteCSS;
+{
+  const {Filter, ElemHideFilter} = require("filterClasses");
+  const {escapeCSS, quoteCSS} = require("filterComposer");
 
   module("CSS escaping");
 
-  test("CSS escaping", function()
+  test("CSS escaping", () =>
   {
     function testSelector(opts)
     {
-      var mustMatch = opts.mustMatch !== false;
-      var doc = document.implementation.createHTMLDocument();
+      let mustMatch = opts.mustMatch !== false;
+      let doc = document.implementation.createHTMLDocument();
 
-      var style = doc.createElement("style");
+      let style = doc.createElement("style");
       doc.documentElement.appendChild(style);
       style.sheet.insertRule(opts.selector + " {}", 0);
 
-      var element;
+      let element;
       try
       {
         element = doc.createElement(opts.tagName || "div");
@@ -37,14 +33,14 @@
 
       if (element)
       {
-        for (var attr in opts.attributes)
+        for (let attr in opts.attributes)
           element.setAttribute(attr, opts.attributes[attr]);
 
         doc.documentElement.appendChild(element);
       }
 
-      var foundElement = doc.querySelector(opts.selector);
-      var filter = Filter.fromText("##" + opts.selector);
+      let foundElement = doc.querySelector(opts.selector);
+      let filter = Filter.fromText("##" + opts.selector);
 
       if (!(filter instanceof ElemHideFilter))
       {
@@ -87,9 +83,9 @@
       });
     }
 
-    for (var i = 1; i < 0x80; i++)
+    for (let i = 1; i < 0x80; i++)
     {
-      var chr = String.fromCharCode(i);
+      let chr = String.fromCharCode(i);
 
       // Make sure that all ASCII characters are correctly escaped.
       testEscape(chr);
@@ -106,4 +102,4 @@
     // Test some non-ASCII characters. However, those shouldn't require escaping.
     testEscape("\uD83D\uDE3B\u2665\u00E4");
   });
-})();
+}
Index: qunit/tests/filterValidation.js
diff --git a/qunit/tests/filterValidation.js b/qunit/tests/filterValidation.js
index 38b96ea8267638248e842696e26b7345f669d258..9f8cd721a15bdfd1827f31f3b2d15d7285b910b3 100644
--- a/qunit/tests/filterValidation.js
+++ b/qunit/tests/filterValidation.js
@@ -1,17 +1,14 @@
-(function()
-{
-  var filterValidation = require("filterValidation");
-  var parseFilter = filterValidation.parseFilter;
-  var parseFilters = filterValidation.parseFilters;
+"use strict";
 
-  var filterClasses = require("filterClasses");
-  var BlockingFilter = filterClasses.BlockingFilter;
-  var ElemHideFilter = filterClasses.ElemHideFilter;
-  var CommentFilter = filterClasses.CommentFilter;
+{
+  const {parseFilter, parseFilters} = require("filterValidation");
+  const {BlockingFilter,
+         ElemHideFilter,
+         CommentFilter} = require("filterClasses");
 
   module("Filter validation");
 
-  test("Detecting invalid filters", function()
+  test("Detecting invalid filters", () =>
   {
     equal(parseFilter("||example.com^$unknown").error.type, "invalid-filter", "unknown option");
     equal(parseFilter("[foobar]").error.type, "unexpected-filter-list-header", "filter list header");
@@ -19,9 +16,9 @@
     ok(/\b4\b/.test(parseFilters("!comment\r\n||example.com^\n\n##/").errors[0]), "error contains corresponding line number");
   });
 
-  test("Allowing valid filters", function()
+  test("Allowing valid filters", () =>
   {
-    var text, filter;
+    let text, filter;
 
     text = "||example.com^";
     filter = parseFilter(text).filter;
@@ -41,17 +38,17 @@
     equal(parseFilter("").filter, null, "empty filter parsed as 'null'");
   });
 
-  test("Normalizing filters", function()
+  test("Normalizing filters", () =>
   {
-    var ws = " \t\r\n";
+    let ws = " \t\r\n";
 
     equal(parseFilter(ws + "@@" + ws + "||" + ws + "example.com" + ws + "^" + ws).filter.text, "@@||example.com^", "unnecessary spaces");
     equal(parseFilter(ws).filter, null, "only spaces");
   });
 
-  test("Parsing multiple filters", function()
+  test("Parsing multiple filters", () =>
   {
-    var result = parseFilters("||example.com^\n \n###foobar\r\n! foo bar\n");
+    let result = parseFilters("||example.com^\n \n###foobar\r\n! foo bar\n");
 
     equal(result.errors.length, 0, "no error occurred");
     equal(result.filters.length, 3, "all filters parsed");
@@ -65,4 +62,4 @@
     ok(result.filters[2] instanceof CommentFilter,  "3rd filter is comment");
     equal(result.filters[2].text, "! foo bar",      "3rd filter text matches");
   });
-})();
+}
Index: qunit/tests/prefs.js
diff --git a/qunit/tests/prefs.js b/qunit/tests/prefs.js
index f620ca9a555056d0a53856fb805a0cc64120011a..5430c8b2eb7ab123a1d9b84e41224c1bc8ac5629 100644
--- a/qunit/tests/prefs.js
+++ b/qunit/tests/prefs.js
@@ -1,13 +1,14 @@
-(function()
+"use strict";
+
 {
   module("Preferences",
   {
-    setup: function()
+    setup()
     {
       preparePrefs.call(this);
     },
 
-    teardown: function()
+    teardown()
     {
       restorePrefs.call(this);
     }
@@ -17,7 +18,7 @@
   {
     let done = assert.async();
     let key = "pref:" + name;
-    chrome.storage.local.get(key, function(items)
+    chrome.storage.local.get(key, items =>
     {
       equal(key in items, expectedValue, description);
       done();
@@ -28,14 +29,14 @@
   {
     let done = assert.async();
     let key = "pref:" + name;
-    chrome.storage.local.get(key, function(items)
+    chrome.storage.local.get(key, items =>
     {
       deepEqual(items[key], expectedValue, description);
       done();
     });
   }
 
-  test("Numerical pref", function(assert)
+  test("Numerical pref", assert =>
   {
     Prefs.patternsbackups = 5;
     equal(Prefs.patternsbackups, 5, "Prefs object returns the correct value after setting pref to default value");
@@ -46,7 +47,7 @@
     checkPref("patternsbackups", 12, "Value has been written", assert);
   });
 
-  test("Boolean pref", function(assert)
+  test("Boolean pref", assert =>
   {
     Prefs.enabled = true;
     equal(Prefs.enabled, true, "Prefs object returns the correct value after setting pref to default value");
@@ -57,7 +58,7 @@
     checkPref("enabled", false, "Value has been written", assert);
   });
 
-  test("String pref", function(assert)
+  test("String pref", assert =>
   {
     let defaultValue = "https://notification.adblockplus.org/notification.json";
     Prefs.notificationurl = defaultValue;
@@ -71,7 +72,7 @@
     checkPref("notificationurl", newValue, "Value has been written", assert);
   });
 
-  test("Object pref (complete replacement)", function(assert)
+  test("Object pref (complete replacement)", assert =>
   {
     Prefs.notificationdata = {};
     deepEqual(Prefs.notificationdata, {}, "Prefs object returns the correct value after setting pref to default value");
@@ -83,7 +84,7 @@
     checkPref("notificationdata", newValue, "Value has been written", assert);
   });
 
-  test("Property-wise modification", function(assert)
+  test("Property-wise modification", assert =>
   {
     Prefs.notificationdata = {};
 
@@ -99,4 +100,4 @@
     Prefs.notificationdata = JSON.parse(JSON.stringify(Prefs.notificationdata));
     deepEqual(Prefs.notificationdata, {}, "Prefs object returns the correct value after setting pref to default value");
   });
-})();
+}
Index: qunit/tests/url.js
diff --git a/qunit/tests/url.js b/qunit/tests/url.js
index 1b504cb70d7442a8f5cbfa086266fec9bc19dfaf..58376f442b59f914a94122455777213d45cc2588 100644
--- a/qunit/tests/url.js
+++ b/qunit/tests/url.js
@@ -15,18 +15,17 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+"use strict";
 
-(function()
 {
-  var url = require("url");
-  var getDecodedHostname = url.getDecodedHostname;
-  var extractHostFromFrame = url.extractHostFromFrame;
-  var stringifyURL = url.stringifyURL;
-  var isThirdParty = url.isThirdParty;
+  let {getDecodedHostname,
+       extractHostFromFrame,
+       stringifyURL,
+       isThirdParty} = require("url");
 
   module("URL/host tools");
 
-  test("Extracting hostname from URL", function()
+  test("Extracting hostname from URL", () =>
   {
     function testURLHostname(url, expectedHostname, message)
     {
@@ -46,14 +45,14 @@
     testURLHostname("http://[2001:db8:85a3::8a2e:370:7334]/", "[2001:db8:85a3::8a2e:370:7334]", "IPv6 address");
   });
 
-  test("Extracting hostname from frame", function()
+  test("Extracting hostname from frame", () =>
   {
     function testFrameHostname(hierarchy, expectedHostname, message)
     {
-      var frame = null;
+      let frame = null;
 
-      for (var i = 0; i < hierarchy.length; i++)
-        frame = {parent: frame, url: new URL(hierarchy[i])};
+      for (let url of hierarchy)
+        frame = {parent: frame, url: new URL(url)};
 
       equal(extractHostFromFrame(frame), expectedHostname, message);
     }
@@ -66,7 +65,7 @@
     testFrameHostname(["http://xn--f-1gaa.com/"], "f\u00f6\u00f6.com", "with punycode");
   });
 
-  test("Stringifying URLs", function()
+  test("Stringifying URLs", () =>
   {
     function testNormalizedURL(url, expectedURL, message)
     {
@@ -89,7 +88,7 @@
     testPreservedURL("data:text/plain,foo", "data: URL");
   });
 
-  test("Third-party checks", function()
+  test("Third-party checks", () =>
   {
     function hostnameToURL(hostname)
     {
@@ -134,4 +133,4 @@
     testThirdParty("xn--f-1gaa.com", "f\u00f6\u00f6.com", false, "same IDN isn't third-party");
     testThirdParty("example.com..", "example.com....", false, "traling dots are ignored");
   });
-})();
+}
Index: qunit/tests/versionComparator.js
diff --git a/qunit/tests/versionComparator.js b/qunit/tests/versionComparator.js
index 891b32aa29f1af01d468b599e8d58b67d8068782..8b799175d77ecc2fbd0aa851f746cc4ebfe47e15 100644
--- a/qunit/tests/versionComparator.js
+++ b/qunit/tests/versionComparator.js
@@ -15,26 +15,26 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+"use strict";
 
-(function()
 {
-  var compare = Services.vc.compare;
+  let compare = Services.vc.compare;
 
   function allPairs(array)
   {
-    var pairs = [];
-    for (var i = 0; i < array.length - 1; i++)
-      for (var j = i + 1; j < array.length; j++)
+    let pairs = [];
+    for (let i = 0; i < array.length - 1; i++)
+      for (let j = i + 1; j < array.length; j++)
         pairs.push([array[i], array[j]]);
     return pairs;
   }
 
   function versionsEqual(versions)
   {
-    allPairs(versions).forEach(function(pair)
+    allPairs(versions).forEach(pair =>
     {
-      var v1 = pair[0];
-      var v2 = pair[1];
+      let v1 = pair[0];
+      let v2 = pair[1];
       equal(compare(v1, v2), 0, "'" + v1 + "' should be equal to '" + v2 + "'");
     });
   }
@@ -48,35 +48,35 @@
   }
 
   module("Test utilities");
-  test("allPairs", 1, function()
+  test("allPairs", 1, () =>
   {
     deepEqual(allPairs([1, 2, 3]), [[1, 2], [1, 3], [2, 3]]);
   });
 
   module("versionComparator");
 
-  test("Optional zero", 12, function()
+  test("Optional zero", 12, () =>
   {
     versionsEqual(["1", "1.0", "1.0.0", "1.0.0.0"]);
     versionsEqual(["1.a", "1.0a", "1.a0", "1.0a0"]);
   });
 
-  test("+", 2, function()
+  test("+", 2, () =>
   {
     versionsEqual(["2pre", "1+"]);
     versionsEqual(["1.1pre", "1.0+"]);
   });
 
-  test("*", 6, function()
+  test("*", 6, () =>
   {
     versionSmaller("1", "*");
     versionSmaller("1.1", "1.*");
     versionSmaller("1.*", "2");
   });
 
-  test("Examples", 296, function()
+  test("Examples", 296, () =>
   {
-    var examples = [
+    let examples = [
       "1.0+a",
       "1.0a",
       "1.0pre1",
@@ -90,19 +90,19 @@
       ["1.10", "1.010", "1.00010"],
     ];
 
-    examples.forEach(function(example)
+    examples.forEach(example =>
     {
       if (example instanceof Array)
         versionsEqual(example);
     });
 
-    allPairs(examples).forEach(function(pair)
+    allPairs(examples).forEach(pair =>
     {
-      var v1 = [].concat(pair[0]);
-      var v2 = [].concat(pair[1]);
-      for (var i = 0; i < v1.length; i++)
-        for (var j = 0; j < v2.length; j++)
+      let v1 = [].concat(pair[0]);
+      let v2 = [].concat(pair[1]);
+      for (let i = 0; i < v1.length; i++)
+        for (let j = 0; j < v2.length; j++)
           versionSmaller(v1[i], v2[j]);
     });
   });
-})();
+}
Index: stats.js
diff --git a/stats.js b/stats.js
index 416f0bbafd0edaf86b6fdf4f71aefd7208c55d5a..39197c8a9a5796d3b5d25643c3801f1423fb1ddd 100644
--- a/stats.js
+++ b/stats.js
@@ -15,19 +15,20 @@
  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-(function()
+"use strict";
+
 {
-  var backgroundPage = ext.backgroundPage.getWindow();
-  var require = backgroundPage.require;
-  var getBlockedPerPage = require("stats").getBlockedPerPage;
-  var FilterNotifier = require("filterNotifier").FilterNotifier;
-  var Prefs = require("prefs").Prefs;
+  const {require} = ext.backgroundPage.getWindow();
+
+  const {getBlockedPerPage} = require("stats");
+  const {FilterNotifier} = require("filterNotifier");
+  const {Prefs} = require("prefs");
 
-  var currentPage;
-  var shareURL = "https://adblockplus.org/";
+  let currentPage;
+  const shareURL = "https://adblockplus.org/";
 
-  var messageMark = {};
-  var shareLinks = {
+  let messageMark = {};
+  let shareLinks = {
     facebook: ["https://www.facebook.com/dialog/feed", {
       app_id: "475542399197328",
       link: shareURL,
@@ -53,13 +54,13 @@
 
   function createShareLink(network, blockedCount)
   {
-    var url = shareLinks[network][0];
-    var params = shareLinks[network][1];
+    let url = shareLinks[network][0];
+    let params = shareLinks[network][1];
 
-    var querystring = [];
-    for (var key in params)
+    let querystring = [];
+    for (let key in params)
     {
-      var value = params[key];
+      let value = params[key];
       if (value == messageMark)
         value = i18n.getMessage("stats_share_message", blockedCount);
       querystring.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
@@ -70,13 +71,13 @@
   function onLoad()
   {
     document.getElementById("share-box").addEventListener("click", share, false);
-    var showIconNumber = document.getElementById("show-iconnumber");
+    let showIconNumber = document.getElementById("show-iconnumber");
     showIconNumber.setAttribute("aria-checked", Prefs.show_statsinicon);
     showIconNumber.addEventListener("click", toggleIconNumber, false);
     document.querySelector("label[for='show-iconnumber']").addEventListener("click", toggleIconNumber, false);
 
     // Update stats
-    ext.pages.query({active: true, lastFocusedWindow: true}, function(pages)
+    ext.pages.query({active: true, lastFocusedWindow: true}, pages =>
     {
       currentPage = pages[0];
       updateStats();
@@ -94,19 +95,19 @@
 
   function updateStats()
   {
-    var statsPage = document.getElementById("stats-page");
-    var blockedPage = getBlockedPerPage(currentPage).toLocaleString();
+    let statsPage = document.getElementById("stats-page");
+    let blockedPage = getBlockedPerPage(currentPage).toLocaleString();
     i18n.setElementText(statsPage, "stats_label_page", [blockedPage]);
 
-    var statsTotal = document.getElementById("stats-total");
-    var blockedTotal = Prefs.blocked_total.toLocaleString();
+    let statsTotal = document.getElementById("stats-total");
+    let blockedTotal = Prefs.blocked_total.toLocaleString();
     i18n.setElementText(statsTotal, "stats_label_total", [blockedTotal]);
   }
 
   function share(ev)
   {
     // Easter Egg
-    var blocked = Prefs.blocked_total;
+    let blocked = Prefs.blocked_total;
     if (blocked <= 9000 || blocked >= 10000)
       blocked = blocked.toLocaleString();
     else
@@ -123,4 +124,4 @@
 
   document.addEventListener("DOMContentLoaded", onLoad, false);
   window.addEventListener("unload", onUnload, false);
-})();
+}
Index: subscriptionLink.postload.js
diff --git a/subscriptionLink.postload.js b/subscriptionLink.postload.js
index 09316efca0fc116de00a51c10456e8149316747e..0aaf68c78dd12e4f82afa3f37b3138529207893f 100644
--- a/subscriptionLink.postload.js
+++ b/subscriptionLink.postload.js
@@ -19,7 +19,7 @@
 
 if (document instanceof HTMLDocument)
 {
-  document.addEventListener("click", function(event)
+  document.addEventListener("click", event =>
   {
     // Ignore right-clicks
     if (event.button == 2)
@@ -30,7 +30,7 @@ if (document instanceof HTMLDocument)
       return;
 
     // Search the link associated with the click
-    var link = event.target;
+    let link = event.target;
     while (!(link instanceof HTMLAnchorElement))
     {
       link = link.parentNode;
@@ -52,12 +52,11 @@ if (document instanceof HTMLDocument)
     event.stopPropagation();
 
     // Decode URL parameters
-    var params = link.search.substr(1).split("&");
-    var title = null;
-    var url = null;
-    for (var i = 0; i < params.length; i++)
+    let title = null;
+    let url = null;
+    for (let param of link.search.substr(1).split("&"))
     {
-      var parts = params[i].split("=", 2);
+      let parts = param.split("=", 2);
       if (parts.length != 2 || !/\S/.test(parts[1]))
         continue;
       switch (parts[0])
Index: utils.js
diff --git a/utils.js b/utils.js
index 64b7274494c869713ebf1b051036859f5677823f..f9895072b5f83756812608eb2cd7f6de66c909e7 100644
--- a/utils.js
+++ b/utils.js
@@ -1,20 +1,16 @@
-var backgroundPage = ext.backgroundPage.getWindow();
-var require = backgroundPage.require;
+"use strict";
 
-var Services = backgroundPage.Services;
-var Synchronizer = require("synchronizer").Synchronizer;
-var Utils = require("utils").Utils;
-var Prefs = require("prefs").Prefs;
-var FilterStorage = require("filterStorage").FilterStorage;
-var FilterNotifier = require("filterNotifier").FilterNotifier;
+const {require, Services} = ext.backgroundPage.getWindow();
 
-var subscriptionClasses = require("subscriptionClasses");
-var Subscription = subscriptionClasses.Subscription;
-var DownloadableSubscription = subscriptionClasses.DownloadableSubscription;
-var filterClasses = require("filterClasses");
-var Filter = filterClasses.Filter;
-var BlockingFilter = filterClasses.BlockingFilter;
-var defaultMatcher = require("matcher").defaultMatcher;
+const {Synchronizer} = require("synchronizer");
+const {Utils} = require("utils");
+const {Prefs} = require("prefs");
+const {FilterStorage} = require("filterStorage");
+const {FilterNotifier} = require("filterNotifier");
+
+const {Subscription, DownloadableSubscription} = require("subscriptionClasses");
+const {Filter, BlockingFilter} = require("filterClasses");
+const {defaultMatcher} = require("matcher");
 
 /**
  * Shortcut for document.getElementById(id)
