| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
| 3  * Copyright (C) 2006-2016 Eyeo GmbH | 3  * Copyright (C) 2006-2016 Eyeo GmbH | 
| 4  * | 4  * | 
| 5  * Adblock Plus is free software: you can redistribute it and/or modify | 5  * Adblock Plus is free software: you can redistribute it and/or modify | 
| 6  * it under the terms of the GNU General Public License version 3 as | 6  * it under the terms of the GNU General Public License version 3 as | 
| 7  * published by the Free Software Foundation. | 7  * published by the Free Software Foundation. | 
| 8  * | 8  * | 
| 9  * Adblock Plus is distributed in the hope that it will be useful, | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
| 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| 12  * GNU General Public License for more details. | 12  * GNU General Public License for more details. | 
| 13  * | 13  * | 
| 14  * You should have received a copy of the GNU General Public License | 14  * You should have received a copy of the GNU General Public License | 
| 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
| 16  */ | 16  */ | 
| 17 | 17 | 
| 18 (function() | 18 "use strict"; | 
|  | 19 | 
| 19 { | 20 { | 
| 20   /* Pages */ | 21   /* Pages */ | 
| 21 | 22 | 
| 22   var Page = ext.Page = function(tab) | 23   let Page = ext.Page = function(tab) | 
| 23   { | 24   { | 
| 24     this.id = tab.id; | 25     this.id = tab.id; | 
| 25     this._url = tab.url && new URL(tab.url); | 26     this._url = tab.url && new URL(tab.url); | 
| 26 | 27 | 
| 27     this.browserAction = new BrowserAction(tab.id); | 28     this.browserAction = new BrowserAction(tab.id); | 
| 28     this.contextMenus = new ContextMenus(this); | 29     this.contextMenus = new ContextMenus(this); | 
| 29   }; | 30   }; | 
| 30   Page.prototype = { | 31   Page.prototype = { | 
| 31     get url() | 32     get url() | 
| 32     { | 33     { | 
| 33       // usually our Page objects are created from Chrome's Tab objects, which | 34       // usually our Page objects are created from Chrome's Tab objects, which | 
| 34       // provide the url. So we can return the url given in the constructor. | 35       // provide the url. So we can return the url given in the constructor. | 
| 35       if (this._url) | 36       if (this._url) | 
| 36         return this._url; | 37         return this._url; | 
| 37 | 38 | 
| 38       // but sometimes we only have the tab id when we create a Page object. | 39       // but sometimes we only have the tab id when we create a Page object. | 
| 39       // In that case we get the url from top frame of the tab, recorded by | 40       // In that case we get the url from top frame of the tab, recorded by | 
| 40       // the onBeforeRequest handler. | 41       // the onBeforeRequest handler. | 
| 41       var frames = framesOfTabs[this.id]; | 42       let frames = framesOfTabs[this.id]; | 
| 42       if (frames) | 43       if (frames) | 
| 43       { | 44       { | 
| 44         var frame = frames[0]; | 45         let frame = frames[0]; | 
| 45         if (frame) | 46         if (frame) | 
| 46           return frame.url; | 47           return frame.url; | 
| 47       } | 48       } | 
| 48     }, | 49     }, | 
| 49     sendMessage: function(message, responseCallback) | 50     sendMessage: function(message, responseCallback) | 
| 50     { | 51     { | 
| 51       chrome.tabs.sendMessage(this.id, message, responseCallback); | 52       chrome.tabs.sendMessage(this.id, message, responseCallback); | 
| 52     } | 53     } | 
| 53   }; | 54   }; | 
| 54 | 55 | 
| 55   ext.getPage = function(id) | 56   ext.getPage = id => new Page({id: parseInt(id, 10)}); | 
| 56   { |  | 
| 57     return new Page({id: parseInt(id, 10)}); |  | 
| 58   }; |  | 
| 59 | 57 | 
| 60   function afterTabLoaded(callback) | 58   function afterTabLoaded(callback) | 
| 61   { | 59   { | 
| 62      return function(openedTab) | 60      return openedTab => | 
| 63      { | 61      { | 
| 64        var onUpdated = function(tabId, changeInfo, tab) | 62        let onUpdated = (tabId, changeInfo, tab) => | 
| 65        { | 63        { | 
| 66          if (tabId == openedTab.id && changeInfo.status == "complete") | 64          if (tabId == openedTab.id && changeInfo.status == "complete") | 
| 67          { | 65          { | 
| 68            chrome.tabs.onUpdated.removeListener(onUpdated); | 66            chrome.tabs.onUpdated.removeListener(onUpdated); | 
| 69            callback(new Page(openedTab)); | 67            callback(new Page(openedTab)); | 
| 70          } | 68          } | 
| 71        }; | 69        }; | 
| 72        chrome.tabs.onUpdated.addListener(onUpdated); | 70        chrome.tabs.onUpdated.addListener(onUpdated); | 
| 73      }; | 71      }; | 
| 74   } | 72   } | 
| 75 | 73 | 
| 76   ext.pages = { | 74   ext.pages = { | 
| 77     open: function(url, callback) | 75     open: (url, callback) => | 
| 78     { | 76     { | 
| 79       chrome.tabs.create({url: url}, callback && afterTabLoaded(callback)); | 77       chrome.tabs.create({url: url}, callback && afterTabLoaded(callback)); | 
| 80     }, | 78     }, | 
| 81     query: function(info, callback) | 79     query: (info, callback) => | 
| 82     { | 80     { | 
| 83       var rawInfo = {}; | 81       let rawInfo = {}; | 
| 84       for (var property in info) | 82       for (let property in info) | 
| 85       { | 83       { | 
| 86         switch (property) | 84         switch (property) | 
| 87         { | 85         { | 
| 88           case "active": | 86           case "active": | 
| 89           case "lastFocusedWindow": | 87           case "lastFocusedWindow": | 
| 90             rawInfo[property] = info[property]; | 88             rawInfo[property] = info[property]; | 
| 91         } | 89         } | 
| 92       } | 90       } | 
| 93 | 91 | 
| 94       chrome.tabs.query(rawInfo, function(tabs) | 92       chrome.tabs.query(rawInfo, tabs => | 
| 95       { | 93       { | 
| 96         callback(tabs.map(function(tab) | 94         callback(tabs.map(tab => new Page(tab))); | 
| 97         { |  | 
| 98           return new Page(tab); |  | 
| 99         })); |  | 
| 100       }); | 95       }); | 
| 101     }, | 96     }, | 
| 102     onLoading: new ext._EventTarget(), | 97     onLoading: new ext._EventTarget(), | 
| 103     onActivated: new ext._EventTarget(), | 98     onActivated: new ext._EventTarget(), | 
| 104     onRemoved: new ext._EventTarget() | 99     onRemoved: new ext._EventTarget() | 
| 105   }; | 100   }; | 
| 106 | 101 | 
| 107   chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) | 102   chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => | 
| 108   { | 103   { | 
| 109     if (changeInfo.status == "loading") | 104     if (changeInfo.status == "loading") | 
| 110       ext.pages.onLoading._dispatch(new Page(tab)); | 105       ext.pages.onLoading._dispatch(new Page(tab)); | 
| 111   }); | 106   }); | 
| 112 | 107 | 
| 113   function createFrame(tabId, frameId) | 108   function createFrame(tabId, frameId) | 
| 114   { | 109   { | 
| 115     var frames = framesOfTabs[tabId]; | 110     let frames = framesOfTabs[tabId]; | 
| 116     if (!frames) | 111     if (!frames) | 
| 117       frames = framesOfTabs[tabId] = Object.create(null); | 112       frames = framesOfTabs[tabId] = Object.create(null); | 
| 118 | 113 | 
| 119     var frame = frames[frameId]; | 114     let frame = frames[frameId]; | 
| 120     if (!frame) | 115     if (!frame) | 
| 121       frame = frames[frameId] = {}; | 116       frame = frames[frameId] = {}; | 
| 122 | 117 | 
| 123     return frame; | 118     return frame; | 
| 124   } | 119   } | 
| 125 | 120 | 
| 126   chrome.webNavigation.onBeforeNavigate.addListener(function(details) | 121   chrome.webNavigation.onBeforeNavigate.addListener(details => | 
| 127   { | 122   { | 
| 128     // Capture parent frame here because onCommitted doesn't get this info. | 123     // Capture parent frame here because onCommitted doesn't get this info. | 
| 129     var frame = createFrame(details.tabId, details.frameId); | 124     let frame = createFrame(details.tabId, details.frameId); | 
| 130     frame.parent = framesOfTabs[details.tabId][details.parentFrameId] || null; | 125     frame.parent = framesOfTabs[details.tabId][details.parentFrameId] || null; | 
| 131   }); | 126   }); | 
| 132 | 127 | 
| 133   var eagerlyUpdatedPages = new ext.PageMap(); | 128   let eagerlyUpdatedPages = new ext.PageMap(); | 
| 134 | 129 | 
| 135   ext._updatePageFrameStructure = function(frameId, tabId, url, eager) | 130   ext._updatePageFrameStructure = (frameId, tabId, url, eager) => | 
| 136   { | 131   { | 
| 137     if (frameId == 0) | 132     if (frameId == 0) | 
| 138     { | 133     { | 
| 139       let page = new Page({id: tabId, url: url}); | 134       let page = new Page({id: tabId, url: url}); | 
| 140 | 135 | 
| 141       if (eagerlyUpdatedPages.get(page) != url) | 136       if (eagerlyUpdatedPages.get(page) != url) | 
| 142       { | 137       { | 
| 143         ext._removeFromAllPageMaps(tabId); | 138         ext._removeFromAllPageMaps(tabId); | 
| 144 | 139 | 
| 145         // When a sitekey header is received we must immediately update the page | 140         // When a sitekey header is received we must immediately update the page | 
| 146         // structure in order to record and use the key. We want to avoid | 141         // structure in order to record and use the key. We want to avoid | 
| 147         // trashing the page structure if the onCommitted event is then fired | 142         // trashing the page structure if the onCommitted event is then fired | 
| 148         // for the page. | 143         // for the page. | 
| 149         if (eager) | 144         if (eager) | 
| 150           eagerlyUpdatedPages.set(page, url); | 145           eagerlyUpdatedPages.set(page, url); | 
| 151 | 146 | 
| 152         chrome.tabs.get(tabId, function() | 147         chrome.tabs.get(tabId, () => | 
| 153         { | 148         { | 
| 154           // If the tab is prerendered, chrome.tabs.get() sets | 149           // If the tab is prerendered, chrome.tabs.get() sets | 
| 155           // chrome.runtime.lastError and we have to dispatch the onLoading even
     t, | 150           // chrome.runtime.lastError and we have to dispatch the onLoading even
     t, | 
| 156           // since the onUpdated event isn't dispatched for prerendered tabs. | 151           // since the onUpdated event isn't dispatched for prerendered tabs. | 
| 157           // However, we have to keep relying on the unUpdated event for tabs th
     at | 152           // However, we have to keep relying on the unUpdated event for tabs th
     at | 
| 158           // are already visible. Otherwise browser action changes get overridde
     n | 153           // are already visible. Otherwise browser action changes get overridde
     n | 
| 159           // when Chrome automatically resets them on navigation. | 154           // when Chrome automatically resets them on navigation. | 
| 160           if (chrome.runtime.lastError) | 155           if (chrome.runtime.lastError) | 
| 161             ext.pages.onLoading._dispatch(page); | 156             ext.pages.onLoading._dispatch(page); | 
| 162         }); | 157         }); | 
| 163       } | 158       } | 
| 164     } | 159     } | 
| 165 | 160 | 
| 166     // Update frame URL in frame structure | 161     // Update frame URL in frame structure | 
| 167     var frame = createFrame(tabId, frameId); | 162     let frame = createFrame(tabId, frameId); | 
| 168     frame.url = new URL(url); | 163     frame.url = new URL(url); | 
| 169   }; | 164   }; | 
| 170 | 165 | 
| 171   chrome.webNavigation.onCommitted.addListener(function(details) | 166   chrome.webNavigation.onCommitted.addListener(details => | 
| 172   { | 167   { | 
| 173     ext._updatePageFrameStructure(details.frameId, details.tabId, details.url); | 168     ext._updatePageFrameStructure(details.frameId, details.tabId, details.url); | 
| 174   }); | 169   }); | 
| 175 | 170 | 
| 176   function forgetTab(tabId) | 171   function forgetTab(tabId) | 
| 177   { | 172   { | 
| 178     ext.pages.onRemoved._dispatch(tabId); | 173     ext.pages.onRemoved._dispatch(tabId); | 
| 179 | 174 | 
| 180     ext._removeFromAllPageMaps(tabId); | 175     ext._removeFromAllPageMaps(tabId); | 
| 181     delete framesOfTabs[tabId]; | 176     delete framesOfTabs[tabId]; | 
| 182   } | 177   } | 
| 183 | 178 | 
| 184   chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId) | 179   chrome.tabs.onReplaced.addListener((addedTabId, removedTabId) => | 
| 185   { | 180   { | 
| 186     forgetTab(removedTabId); | 181     forgetTab(removedTabId); | 
| 187   }); | 182   }); | 
| 188 | 183 | 
| 189   chrome.tabs.onRemoved.addListener(forgetTab); | 184   chrome.tabs.onRemoved.addListener(forgetTab); | 
| 190 | 185 | 
| 191   chrome.tabs.onActivated.addListener(function(details) | 186   chrome.tabs.onActivated.addListener(details => | 
| 192   { | 187   { | 
| 193     ext.pages.onActivated._dispatch(new Page({id: details.tabId})); | 188     ext.pages.onActivated._dispatch(new Page({id: details.tabId})); | 
| 194   }); | 189   }); | 
| 195 | 190 | 
| 196 | 191 | 
| 197   /* Browser actions */ | 192   /* Browser actions */ | 
| 198 | 193 | 
| 199   var BrowserAction = function(tabId) | 194   let BrowserAction = function(tabId) | 
| 200   { | 195   { | 
| 201     this._tabId = tabId; | 196     this._tabId = tabId; | 
| 202     this._changes = null; | 197     this._changes = null; | 
| 203   }; | 198   }; | 
| 204   BrowserAction.prototype = { | 199   BrowserAction.prototype = { | 
| 205     _applyChanges: function() | 200     _applyChanges: function() | 
| 206     { | 201     { | 
| 207       if ("iconPath" in this._changes) | 202       if ("iconPath" in this._changes) | 
| 208       { | 203       { | 
| 209         chrome.browserAction.setIcon({ | 204         chrome.browserAction.setIcon({ | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 240     _queueChanges: function() | 235     _queueChanges: function() | 
| 241     { | 236     { | 
| 242       chrome.tabs.get(this._tabId, function() | 237       chrome.tabs.get(this._tabId, function() | 
| 243       { | 238       { | 
| 244         // If the tab is prerendered, chrome.tabs.get() sets | 239         // If the tab is prerendered, chrome.tabs.get() sets | 
| 245         // chrome.runtime.lastError and we have to delay our changes | 240         // chrome.runtime.lastError and we have to delay our changes | 
| 246         // until the currently visible tab is replaced with the | 241         // until the currently visible tab is replaced with the | 
| 247         // prerendered tab. Otherwise chrome.browserAction.set* fails. | 242         // prerendered tab. Otherwise chrome.browserAction.set* fails. | 
| 248         if (chrome.runtime.lastError) | 243         if (chrome.runtime.lastError) | 
| 249         { | 244         { | 
| 250           var onReplaced = function(addedTabId, removedTabId) | 245           let onReplaced = (addedTabId, removedTabId) => | 
| 251           { | 246           { | 
| 252             if (addedTabId == this._tabId) | 247             if (addedTabId == this._tabId) | 
| 253             { | 248             { | 
| 254               chrome.tabs.onReplaced.removeListener(onReplaced); | 249               chrome.tabs.onReplaced.removeListener(onReplaced); | 
| 255               this._applyChanges(); | 250               this._applyChanges(); | 
| 256             } | 251             } | 
| 257           }.bind(this); | 252           }; | 
| 258           chrome.tabs.onReplaced.addListener(onReplaced); | 253           chrome.tabs.onReplaced.addListener(onReplaced); | 
| 259         } | 254         } | 
| 260         else | 255         else | 
| 261         { | 256         { | 
| 262           this._applyChanges(); | 257           this._applyChanges(); | 
| 263         } | 258         } | 
| 264       }.bind(this)); | 259       }.bind(this)); | 
| 265     }, | 260     }, | 
| 266     _addChange: function(name, value) | 261     _addChange: function(name, value) | 
| 267     { | 262     { | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 290 | 285 | 
| 291         if ("color" in badge) | 286         if ("color" in badge) | 
| 292           this._addChange("badgeColor", badge.color); | 287           this._addChange("badgeColor", badge.color); | 
| 293       } | 288       } | 
| 294     } | 289     } | 
| 295   }; | 290   }; | 
| 296 | 291 | 
| 297 | 292 | 
| 298   /* Context menus */ | 293   /* Context menus */ | 
| 299 | 294 | 
| 300   var contextMenuItems = new ext.PageMap(); | 295   let contextMenuItems = new ext.PageMap(); | 
| 301   var contextMenuUpdating = false; | 296   let contextMenuUpdating = false; | 
| 302 | 297 | 
| 303   var updateContextMenu = function() | 298   let updateContextMenu = () => | 
| 304   { | 299   { | 
| 305     if (contextMenuUpdating) | 300     if (contextMenuUpdating) | 
| 306       return; | 301       return; | 
| 307 | 302 | 
| 308     contextMenuUpdating = true; | 303     contextMenuUpdating = true; | 
| 309 | 304 | 
| 310     chrome.tabs.query({active: true, lastFocusedWindow: true}, function(tabs) | 305     chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => | 
| 311     { | 306     { | 
| 312       chrome.contextMenus.removeAll(function() | 307       chrome.contextMenus.removeAll(() => | 
| 313       { | 308       { | 
| 314         contextMenuUpdating = false; | 309         contextMenuUpdating = false; | 
| 315 | 310 | 
| 316         if (tabs.length == 0) | 311         if (tabs.length == 0) | 
| 317           return; | 312           return; | 
| 318 | 313 | 
| 319         var items = contextMenuItems.get({id: tabs[0].id}); | 314         let items = contextMenuItems.get({id: tabs[0].id}); | 
| 320 | 315 | 
| 321         if (!items) | 316         if (!items) | 
| 322           return; | 317           return; | 
| 323 | 318 | 
| 324         items.forEach(function(item) | 319         items.forEach(item => | 
| 325         { | 320         { | 
| 326           chrome.contextMenus.create({ | 321           chrome.contextMenus.create({ | 
| 327             title: item.title, | 322             title: item.title, | 
| 328             contexts: item.contexts, | 323             contexts: item.contexts, | 
| 329             onclick: function(info, tab) | 324             onclick: (info, tab) => | 
| 330             { | 325             { | 
| 331               item.onclick(new Page(tab)); | 326               item.onclick(new Page(tab)); | 
| 332             } | 327             } | 
| 333           }); | 328           }); | 
| 334         }); | 329         }); | 
| 335       }); | 330       }); | 
| 336     }); | 331     }); | 
| 337   }; | 332   }; | 
| 338 | 333 | 
| 339   var ContextMenus = function(page) | 334   let ContextMenus = function(page) | 
| 340   { | 335   { | 
| 341     this._page = page; | 336     this._page = page; | 
| 342   }; | 337   }; | 
| 343   ContextMenus.prototype = { | 338   ContextMenus.prototype = { | 
| 344     create: function(item) | 339     create: function(item) | 
| 345     { | 340     { | 
| 346       var items = contextMenuItems.get(this._page); | 341       let items = contextMenuItems.get(this._page); | 
| 347       if (!items) | 342       if (!items) | 
| 348         contextMenuItems.set(this._page, items = []); | 343         contextMenuItems.set(this._page, items = []); | 
| 349 | 344 | 
| 350       items.push(item); | 345       items.push(item); | 
| 351       updateContextMenu(); | 346       updateContextMenu(); | 
| 352     }, | 347     }, | 
| 353     remove: function(item) | 348     remove: function(item) | 
| 354     { | 349     { | 
| 355       let items = contextMenuItems.get(this._page); | 350       let items = contextMenuItems.get(this._page); | 
| 356       if (items) | 351       if (items) | 
| 357       { | 352       { | 
| 358         let index = items.indexOf(item); | 353         let index = items.indexOf(item); | 
| 359         if (index != -1) | 354         if (index != -1) | 
| 360         { | 355         { | 
| 361           items.splice(index, 1); | 356           items.splice(index, 1); | 
| 362           updateContextMenu(); | 357           updateContextMenu(); | 
| 363         } | 358         } | 
| 364       } | 359       } | 
| 365     } | 360     } | 
| 366   }; | 361   }; | 
| 367 | 362 | 
| 368   chrome.tabs.onActivated.addListener(updateContextMenu); | 363   chrome.tabs.onActivated.addListener(updateContextMenu); | 
| 369 | 364 | 
| 370   chrome.windows.onFocusChanged.addListener(function(windowId) | 365   chrome.windows.onFocusChanged.addListener(windowId => | 
| 371   { | 366   { | 
| 372     if (windowId != chrome.windows.WINDOW_ID_NONE) | 367     if (windowId != chrome.windows.WINDOW_ID_NONE) | 
| 373       updateContextMenu(); | 368       updateContextMenu(); | 
| 374   }); | 369   }); | 
| 375 | 370 | 
| 376 | 371 | 
| 377   /* Web requests */ | 372   /* Web requests */ | 
| 378 | 373 | 
| 379   var framesOfTabs = Object.create(null); | 374   let framesOfTabs = Object.create(null); | 
| 380 | 375 | 
| 381   ext.getFrame = function(tabId, frameId) | 376   ext.getFrame = (tabId, frameId) => | 
| 382   { | 377   { | 
| 383     return (framesOfTabs[tabId] || {})[frameId]; | 378     return (framesOfTabs[tabId] || {})[frameId]; | 
| 384   }; | 379   }; | 
| 385 | 380 | 
| 386   var handlerBehaviorChangedQuota = chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANG
     ED_CALLS_PER_10_MINUTES; | 381   let handlerBehaviorChangedQuota = chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANG
     ED_CALLS_PER_10_MINUTES; | 
| 387 | 382 | 
| 388   function propagateHandlerBehaviorChange() | 383   function propagateHandlerBehaviorChange() | 
| 389   { | 384   { | 
| 390     // Make sure to not call handlerBehaviorChanged() more often than allowed | 385     // Make sure to not call handlerBehaviorChanged() more often than allowed | 
| 391     // by chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES. | 386     // by chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES. | 
| 392     // Otherwise Chrome notifies the user that this extension is causing issues. | 387     // Otherwise Chrome notifies the user that this extension is causing issues. | 
| 393     if (handlerBehaviorChangedQuota > 0) | 388     if (handlerBehaviorChangedQuota > 0) | 
| 394     { | 389     { | 
| 395       chrome.webNavigation.onBeforeNavigate.removeListener(propagateHandlerBehav
     iorChange); | 390       chrome.webNavigation.onBeforeNavigate.removeListener(propagateHandlerBehav
     iorChange); | 
| 396       chrome.webRequest.handlerBehaviorChanged(); | 391       chrome.webRequest.handlerBehaviorChanged(); | 
| 397 | 392 | 
| 398       handlerBehaviorChangedQuota--; | 393       handlerBehaviorChangedQuota--; | 
| 399       setTimeout(function() { handlerBehaviorChangedQuota++; }, 600000); | 394       setTimeout(() => { handlerBehaviorChangedQuota++; }, 600000); | 
| 400     } | 395     } | 
| 401   } | 396   } | 
| 402 | 397 | 
| 403   ext.webRequest = { | 398   ext.webRequest = { | 
| 404     onBeforeRequest: new ext._EventTarget(), | 399     onBeforeRequest: new ext._EventTarget(), | 
| 405     handlerBehaviorChanged: function() | 400     handlerBehaviorChanged: () => | 
| 406     { | 401     { | 
| 407       // Defer handlerBehaviorChanged() until navigation occurs. | 402       // Defer handlerBehaviorChanged() until navigation occurs. | 
| 408       // There wouldn't be any visible effect when calling it earlier, | 403       // There wouldn't be any visible effect when calling it earlier, | 
| 409       // but it's an expensive operation and that way we avoid to call | 404       // but it's an expensive operation and that way we avoid to call | 
| 410       // it multiple times, if multiple filters are added/removed. | 405       // it multiple times, if multiple filters are added/removed. | 
| 411       var onBeforeNavigate = chrome.webNavigation.onBeforeNavigate; | 406       let onBeforeNavigate = chrome.webNavigation.onBeforeNavigate; | 
| 412       if (!onBeforeNavigate.hasListener(propagateHandlerBehaviorChange)) | 407       if (!onBeforeNavigate.hasListener(propagateHandlerBehaviorChange)) | 
| 413         onBeforeNavigate.addListener(propagateHandlerBehaviorChange); | 408         onBeforeNavigate.addListener(propagateHandlerBehaviorChange); | 
| 414     } | 409     } | 
| 415   }; | 410   }; | 
| 416 | 411 | 
| 417   chrome.tabs.query({}, function(tabs) | 412   chrome.tabs.query({}, tabs => | 
| 418   { | 413   { | 
| 419     tabs.forEach(function(tab) | 414     tabs.forEach(tab => | 
| 420     { | 415     { | 
| 421       chrome.webNavigation.getAllFrames({tabId: tab.id}, function(details) | 416       chrome.webNavigation.getAllFrames({tabId: tab.id}, details => | 
| 422       { | 417       { | 
| 423         if (details && details.length > 0) | 418         if (details && details.length > 0) | 
| 424         { | 419         { | 
| 425           var frames = framesOfTabs[tab.id] = Object.create(null); | 420           let frames = framesOfTabs[tab.id] = Object.create(null); | 
| 426 | 421 | 
| 427           for (var i = 0; i < details.length; i++) | 422           for (let i = 0; i < details.length; i++) | 
| 428             frames[details[i].frameId] = {url: new URL(details[i].url), parent: 
     null}; | 423             frames[details[i].frameId] = {url: new URL(details[i].url), parent: 
     null}; | 
| 429 | 424 | 
| 430           for (var i = 0; i < details.length; i++) | 425           for (let i = 0; i < details.length; i++) | 
| 431           { | 426           { | 
| 432             var parentFrameId = details[i].parentFrameId; | 427             let parentFrameId = details[i].parentFrameId; | 
| 433 | 428 | 
| 434             if (parentFrameId != -1) | 429             if (parentFrameId != -1) | 
| 435               frames[details[i].frameId].parent = frames[parentFrameId]; | 430               frames[details[i].frameId].parent = frames[parentFrameId]; | 
| 436           } | 431           } | 
| 437         } | 432         } | 
| 438       }); | 433       }); | 
| 439     }); | 434     }); | 
| 440   }); | 435   }); | 
| 441 | 436 | 
| 442   chrome.webRequest.onBeforeRequest.addListener(function(details) | 437   chrome.webRequest.onBeforeRequest.addListener(details => | 
| 443   { | 438   { | 
| 444     // The high-level code isn't interested in requests that aren't | 439     // The high-level code isn't interested in requests that aren't | 
| 445     // related to a tab or requests loading a top-level document, | 440     // related to a tab or requests loading a top-level document, | 
| 446     // those should never be blocked. | 441     // those should never be blocked. | 
| 447     if (details.tabId == -1 || details.type == "main_frame") | 442     if (details.tabId == -1 || details.type == "main_frame") | 
| 448       return; | 443       return; | 
| 449 | 444 | 
| 450     // We are looking for the frame that contains the element which | 445     // We are looking for the frame that contains the element which | 
| 451     // has triggered this request. For most requests (e.g. images) we | 446     // has triggered this request. For most requests (e.g. images) we | 
| 452     // can just use the request's frame ID, but for subdocument requests | 447     // can just use the request's frame ID, but for subdocument requests | 
| 453     // (e.g. iframes) we must instead use the request's parent frame ID. | 448     // (e.g. iframes) we must instead use the request's parent frame ID. | 
| 454     var frameId; | 449     let frameId; | 
| 455     var requestType; | 450     let requestType; | 
| 456     if (details.type == "sub_frame") | 451     if (details.type == "sub_frame") | 
| 457     { | 452     { | 
| 458       frameId = details.parentFrameId; | 453       frameId = details.parentFrameId; | 
| 459       requestType = "SUBDOCUMENT"; | 454       requestType = "SUBDOCUMENT"; | 
| 460     } | 455     } | 
| 461     else | 456     else | 
| 462     { | 457     { | 
| 463       frameId = details.frameId; | 458       frameId = details.frameId; | 
| 464       requestType = details.type.toUpperCase(); | 459       requestType = details.type.toUpperCase(); | 
| 465     } | 460     } | 
| 466 | 461 | 
| 467     var frame = ext.getFrame(details.tabId, frameId); | 462     let frame = ext.getFrame(details.tabId, frameId); | 
| 468     if (frame) | 463     if (frame) | 
| 469     { | 464     { | 
| 470       var results = ext.webRequest.onBeforeRequest._dispatch( | 465       let results = ext.webRequest.onBeforeRequest._dispatch( | 
| 471         new URL(details.url), | 466         new URL(details.url), | 
| 472         requestType, | 467         requestType, | 
| 473         new Page({id: details.tabId}), | 468         new Page({id: details.tabId}), | 
| 474         frame | 469         frame | 
| 475       ); | 470       ); | 
| 476 | 471 | 
| 477       if (results.indexOf(false) != -1) | 472       if (results.indexOf(false) != -1) | 
| 478         return {cancel: true}; | 473         return {cancel: true}; | 
| 479     } | 474     } | 
| 480   }, {urls: ["http://*/*", "https://*/*"]}, ["blocking"]); | 475   }, {urls: ["http://*/*", "https://*/*"]}, ["blocking"]); | 
| 481 | 476 | 
| 482 | 477 | 
| 483   /* Message passing */ | 478   /* Message passing */ | 
| 484 | 479 | 
| 485   chrome.runtime.onMessage.addListener(function(message, rawSender, sendResponse
     ) | 480   chrome.runtime.onMessage.addListener((message, rawSender, sendResponse) => | 
| 486   { | 481   { | 
| 487     var sender = {}; | 482     let sender = {}; | 
| 488 | 483 | 
| 489     // Add "page" and "frame" if the message was sent by a content script. | 484     // Add "page" and "frame" if the message was sent by a content script. | 
| 490     // If sent by popup or the background page itself, there is no "tab". | 485     // If sent by popup or the background page itself, there is no "tab". | 
| 491     if ("tab" in rawSender) | 486     if ("tab" in rawSender) | 
| 492     { | 487     { | 
| 493       sender.page = new Page(rawSender.tab); | 488       sender.page = new Page(rawSender.tab); | 
| 494       sender.frame = { | 489       sender.frame = { | 
| 495         url: new URL(rawSender.url), | 490         url: new URL(rawSender.url), | 
| 496         get parent() | 491         get parent() | 
| 497         { | 492         { | 
| 498           var frames = framesOfTabs[rawSender.tab.id]; | 493           let frames = framesOfTabs[rawSender.tab.id]; | 
| 499 | 494 | 
| 500           if (!frames) | 495           if (!frames) | 
| 501             return null; | 496             return null; | 
| 502 | 497 | 
| 503           var frame = frames[rawSender.frameId]; | 498           let frame = frames[rawSender.frameId]; | 
| 504           if (frame) | 499           if (frame) | 
| 505             return frame.parent; | 500             return frame.parent; | 
| 506 | 501 | 
| 507           return frames[0]; | 502           return frames[0]; | 
| 508         } | 503         } | 
| 509       }; | 504       }; | 
| 510     } | 505     } | 
| 511 | 506 | 
| 512     return ext.onMessage._dispatch(message, sender, sendResponse).indexOf(true) 
     != -1; | 507     return ext.onMessage._dispatch(message, sender, sendResponse).indexOf(true) 
     != -1; | 
| 513   }); | 508   }); | 
| 514 | 509 | 
| 515 | 510 | 
| 516   /* Storage */ | 511   /* Storage */ | 
| 517 | 512 | 
| 518   ext.storage = { | 513   ext.storage = { | 
| 519     get: function(keys, callback) | 514     get: (keys, callback) => | 
| 520     { | 515     { | 
| 521       chrome.storage.local.get(keys, callback); | 516       chrome.storage.local.get(keys, callback); | 
| 522     }, | 517     }, | 
| 523     set: function(key, value, callback) | 518     set: (key, value, callback) => | 
| 524     { | 519     { | 
| 525       let items = {}; | 520       let items = {}; | 
| 526       items[key] = value; | 521       items[key] = value; | 
| 527       chrome.storage.local.set(items, callback); | 522       chrome.storage.local.set(items, callback); | 
| 528     }, | 523     }, | 
| 529     remove: function(key, callback) | 524     remove: (key, callback) => | 
| 530     { | 525     { | 
| 531       chrome.storage.local.remove(key, callback); | 526       chrome.storage.local.remove(key, callback); | 
| 532     }, | 527     }, | 
| 533     onChanged: chrome.storage.onChanged | 528     onChanged: chrome.storage.onChanged | 
| 534   }; | 529   }; | 
| 535 | 530 | 
| 536   /* Options */ | 531   /* Options */ | 
| 537 | 532 | 
| 538   if ("openOptionsPage" in chrome.runtime) | 533   if ("openOptionsPage" in chrome.runtime) | 
| 539   { | 534   { | 
| 540     ext.showOptions = function(callback) | 535     ext.showOptions = callback => | 
| 541     { | 536     { | 
| 542       if (!callback) | 537       if (!callback) | 
| 543       { | 538       { | 
| 544         chrome.runtime.openOptionsPage(); | 539         chrome.runtime.openOptionsPage(); | 
| 545       } | 540       } | 
| 546       else | 541       else | 
| 547       { | 542       { | 
| 548         chrome.runtime.openOptionsPage(() => | 543         chrome.runtime.openOptionsPage(() => | 
| 549         { | 544         { | 
| 550           if (chrome.runtime.lastError) | 545           if (chrome.runtime.lastError) | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 561             } | 556             } | 
| 562           }); | 557           }); | 
| 563         }); | 558         }); | 
| 564       } | 559       } | 
| 565     }; | 560     }; | 
| 566   } | 561   } | 
| 567   else | 562   else | 
| 568   { | 563   { | 
| 569     // Edge does not yet support runtime.openOptionsPage (tested version 38) | 564     // Edge does not yet support runtime.openOptionsPage (tested version 38) | 
| 570     // and so this workaround needs to stay for now. | 565     // and so this workaround needs to stay for now. | 
| 571     ext.showOptions = function(callback) | 566     ext.showOptions = callback => | 
| 572     { | 567     { | 
| 573       chrome.windows.getLastFocused(function(win) | 568       chrome.windows.getLastFocused(win => | 
| 574       { | 569       { | 
| 575         var optionsUrl = chrome.extension.getURL("options.html"); | 570         let optionsUrl = chrome.extension.getURL("options.html"); | 
| 576         var queryInfo = {url: optionsUrl}; | 571         let queryInfo = {url: optionsUrl}; | 
| 577 | 572 | 
| 578         // extension pages can't be accessed in incognito windows. In order to | 573         // extension pages can't be accessed in incognito windows. In order to | 
| 579         // correctly mimic the way in which Chrome opens extension options, | 574         // correctly mimic the way in which Chrome opens extension options, | 
| 580         // we have to focus the options page in any other window. | 575         // we have to focus the options page in any other window. | 
| 581         if (!win.incognito) | 576         if (!win.incognito) | 
| 582           queryInfo.windowId = win.id; | 577           queryInfo.windowId = win.id; | 
| 583 | 578 | 
| 584         chrome.tabs.query(queryInfo, function(tabs) | 579         chrome.tabs.query(queryInfo, tabs => | 
| 585         { | 580         { | 
| 586           if (tabs.length > 0) | 581           if (tabs.length > 0) | 
| 587           { | 582           { | 
| 588             var tab = tabs[0]; | 583             let tab = tabs[0]; | 
| 589 | 584 | 
| 590             chrome.windows.update(tab.windowId, {focused: true}); | 585             chrome.windows.update(tab.windowId, {focused: true}); | 
| 591             chrome.tabs.update(tab.id, {active: true}); | 586             chrome.tabs.update(tab.id, {active: true}); | 
| 592 | 587 | 
| 593             if (callback) | 588             if (callback) | 
| 594               callback(new Page(tab)); | 589               callback(new Page(tab)); | 
| 595           } | 590           } | 
| 596           else | 591           else | 
| 597           { | 592           { | 
| 598             ext.pages.open(optionsUrl, callback); | 593             ext.pages.open(optionsUrl, callback); | 
| 599           } | 594           } | 
| 600         }); | 595         }); | 
| 601       }); | 596       }); | 
| 602     }; | 597     }; | 
| 603   } | 598   } | 
| 604 | 599 | 
| 605   /* Windows */ | 600   /* Windows */ | 
| 606   ext.windows = { | 601   ext.windows = { | 
| 607     create: function(createData, callback) | 602     create: (createData, callback) => | 
| 608     { | 603     { | 
| 609       chrome.windows.create(createData, function(createdWindow) | 604       chrome.windows.create(createData, createdWindow => | 
| 610       { | 605       { | 
| 611         afterTabLoaded(callback)(createdWindow.tabs[0]); | 606         afterTabLoaded(callback)(createdWindow.tabs[0]); | 
| 612       }); | 607       }); | 
| 613     } | 608     } | 
| 614   }; | 609   }; | 
| 615 })(); | 610 } | 
| OLD | NEW | 
|---|