| LEFT | RIGHT | 
|---|
| 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 | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 40       // 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 | 
| 41       // the onBeforeRequest handler. | 41       // the onBeforeRequest handler. | 
| 42       let frames = framesOfTabs[this.id]; | 42       let frames = framesOfTabs[this.id]; | 
| 43       if (frames) | 43       if (frames) | 
| 44       { | 44       { | 
| 45         let frame = frames[0]; | 45         let frame = frames[0]; | 
| 46         if (frame) | 46         if (frame) | 
| 47           return frame.url; | 47           return frame.url; | 
| 48       } | 48       } | 
| 49     }, | 49     }, | 
| 50     sendMessage: function(message, responseCallback) | 50     sendMessage(message, responseCallback) | 
| 51     { | 51     { | 
| 52       chrome.tabs.sendMessage(this.id, message, responseCallback); | 52       chrome.tabs.sendMessage(this.id, message, responseCallback); | 
| 53     } | 53     } | 
| 54   }; | 54   }; | 
| 55 | 55 | 
| 56   ext.getPage = id => new Page({id: parseInt(id, 10)}); | 56   ext.getPage = id => new Page({id: parseInt(id, 10)}); | 
| 57 | 57 | 
| 58   function afterTabLoaded(callback) | 58   function afterTabLoaded(callback) | 
| 59   { | 59   { | 
| 60      return openedTab => | 60      return openedTab => | 
| 61      { | 61      { | 
| 62        let onUpdated = (tabId, changeInfo, tab) => | 62        let onUpdated = (tabId, changeInfo, tab) => | 
| 63        { | 63        { | 
| 64          if (tabId == openedTab.id && changeInfo.status == "complete") | 64          if (tabId == openedTab.id && changeInfo.status == "complete") | 
| 65          { | 65          { | 
| 66            chrome.tabs.onUpdated.removeListener(onUpdated); | 66            chrome.tabs.onUpdated.removeListener(onUpdated); | 
| 67            callback(new Page(openedTab)); | 67            callback(new Page(openedTab)); | 
| 68          } | 68          } | 
| 69        }; | 69        }; | 
| 70        chrome.tabs.onUpdated.addListener(onUpdated); | 70        chrome.tabs.onUpdated.addListener(onUpdated); | 
| 71      }; | 71      }; | 
| 72   } | 72   } | 
| 73 | 73 | 
| 74   ext.pages = { | 74   ext.pages = { | 
| 75     open: (url, callback) => | 75     open(url, callback) | 
| 76     { | 76     { | 
| 77       chrome.tabs.create({url: url}, callback && afterTabLoaded(callback)); | 77       chrome.tabs.create({url: url}, callback && afterTabLoaded(callback)); | 
| 78     }, | 78     }, | 
| 79     query: (info, callback) => | 79     query(info, callback) | 
| 80     { | 80     { | 
| 81       let rawInfo = {}; | 81       let rawInfo = {}; | 
| 82       for (let property in info) | 82       for (let property in info) | 
| 83       { | 83       { | 
| 84         switch (property) | 84         switch (property) | 
| 85         { | 85         { | 
| 86           case "active": | 86           case "active": | 
| 87           case "lastFocusedWindow": | 87           case "lastFocusedWindow": | 
| 88             rawInfo[property] = info[property]; | 88             rawInfo[property] = info[property]; | 
| 89         } | 89         } | 
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 190 | 190 | 
| 191 | 191 | 
| 192   /* Browser actions */ | 192   /* Browser actions */ | 
| 193 | 193 | 
| 194   let BrowserAction = function(tabId) | 194   let BrowserAction = function(tabId) | 
| 195   { | 195   { | 
| 196     this._tabId = tabId; | 196     this._tabId = tabId; | 
| 197     this._changes = null; | 197     this._changes = null; | 
| 198   }; | 198   }; | 
| 199   BrowserAction.prototype = { | 199   BrowserAction.prototype = { | 
| 200     _applyChanges: function() | 200     _applyChanges() | 
| 201     { | 201     { | 
| 202       if ("iconPath" in this._changes) | 202       if ("iconPath" in this._changes) | 
| 203       { | 203       { | 
| 204         chrome.browserAction.setIcon({ | 204         chrome.browserAction.setIcon({ | 
| 205           tabId: this._tabId, | 205           tabId: this._tabId, | 
| 206           path: { | 206           path: { | 
| 207             16: this._changes.iconPath.replace("$size", "16"), | 207             16: this._changes.iconPath.replace("$size", "16"), | 
| 208             19: this._changes.iconPath.replace("$size", "19"), | 208             19: this._changes.iconPath.replace("$size", "19"), | 
| 209             20: this._changes.iconPath.replace("$size", "20"), | 209             20: this._changes.iconPath.replace("$size", "20"), | 
| 210             32: this._changes.iconPath.replace("$size", "32"), | 210             32: this._changes.iconPath.replace("$size", "32"), | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 225       if ("badgeColor" in this._changes) | 225       if ("badgeColor" in this._changes) | 
| 226       { | 226       { | 
| 227         chrome.browserAction.setBadgeBackgroundColor({ | 227         chrome.browserAction.setBadgeBackgroundColor({ | 
| 228           tabId: this._tabId, | 228           tabId: this._tabId, | 
| 229           color: this._changes.badgeColor | 229           color: this._changes.badgeColor | 
| 230         }); | 230         }); | 
| 231       } | 231       } | 
| 232 | 232 | 
| 233       this._changes = null; | 233       this._changes = null; | 
| 234     }, | 234     }, | 
| 235     _queueChanges: function() | 235     _queueChanges() | 
| 236     { | 236     { | 
| 237       chrome.tabs.get(this._tabId, function() | 237       chrome.tabs.get(this._tabId, function() | 
| 238       { | 238       { | 
| 239         // If the tab is prerendered, chrome.tabs.get() sets | 239         // If the tab is prerendered, chrome.tabs.get() sets | 
| 240         // chrome.runtime.lastError and we have to delay our changes | 240         // chrome.runtime.lastError and we have to delay our changes | 
| 241         // until the currently visible tab is replaced with the | 241         // until the currently visible tab is replaced with the | 
| 242         // prerendered tab. Otherwise chrome.browserAction.set* fails. | 242         // prerendered tab. Otherwise chrome.browserAction.set* fails. | 
| 243         if (chrome.runtime.lastError) | 243         if (chrome.runtime.lastError) | 
| 244         { | 244         { | 
| 245           let onReplaced = (addedTabId, removedTabId) => | 245           let onReplaced = (addedTabId, removedTabId) => | 
| 246           { | 246           { | 
| 247             if (addedTabId == this._tabId) | 247             if (addedTabId == this._tabId) | 
| 248             { | 248             { | 
| 249               chrome.tabs.onReplaced.removeListener(onReplaced); | 249               chrome.tabs.onReplaced.removeListener(onReplaced); | 
| 250               this._applyChanges(); | 250               this._applyChanges(); | 
| 251             } | 251             } | 
| 252           }; | 252           }; | 
| 253           chrome.tabs.onReplaced.addListener(onReplaced); | 253           chrome.tabs.onReplaced.addListener(onReplaced); | 
| 254         } | 254         } | 
| 255         else | 255         else | 
| 256         { | 256         { | 
| 257           this._applyChanges(); | 257           this._applyChanges(); | 
| 258         } | 258         } | 
| 259       }.bind(this)); | 259       }.bind(this)); | 
| 260     }, | 260     }, | 
| 261     _addChange: function(name, value) | 261     _addChange(name, value) | 
| 262     { | 262     { | 
| 263       if (!this._changes) | 263       if (!this._changes) | 
| 264       { | 264       { | 
| 265         this._changes = {}; | 265         this._changes = {}; | 
| 266         this._queueChanges(); | 266         this._queueChanges(); | 
| 267       } | 267       } | 
| 268 | 268 | 
| 269       this._changes[name] = value; | 269       this._changes[name] = value; | 
| 270     }, | 270     }, | 
| 271     setIcon: function(path) | 271     setIcon(path) | 
| 272     { | 272     { | 
| 273       this._addChange("iconPath", path); | 273       this._addChange("iconPath", path); | 
| 274     }, | 274     }, | 
| 275     setBadge: function(badge) | 275     setBadge(badge) | 
| 276     { | 276     { | 
| 277       if (!badge) | 277       if (!badge) | 
| 278       { | 278       { | 
| 279         this._addChange("badgeText", ""); | 279         this._addChange("badgeText", ""); | 
| 280       } | 280       } | 
| 281       else | 281       else | 
| 282       { | 282       { | 
| 283         if ("number" in badge) | 283         if ("number" in badge) | 
| 284           this._addChange("badgeText", badge.number.toString()); | 284           this._addChange("badgeText", badge.number.toString()); | 
| 285 | 285 | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 314         let items = contextMenuItems.get({id: tabs[0].id}); | 314         let items = contextMenuItems.get({id: tabs[0].id}); | 
| 315 | 315 | 
| 316         if (!items) | 316         if (!items) | 
| 317           return; | 317           return; | 
| 318 | 318 | 
| 319         items.forEach(item => | 319         items.forEach(item => | 
| 320         { | 320         { | 
| 321           chrome.contextMenus.create({ | 321           chrome.contextMenus.create({ | 
| 322             title: item.title, | 322             title: item.title, | 
| 323             contexts: item.contexts, | 323             contexts: item.contexts, | 
| 324             onclick: (info, tab) => | 324             onclick(info, tab) | 
| 325             { | 325             { | 
| 326               item.onclick(new Page(tab)); | 326               item.onclick(new Page(tab)); | 
| 327             } | 327             } | 
| 328           }); | 328           }); | 
| 329         }); | 329         }); | 
| 330       }); | 330       }); | 
| 331     }); | 331     }); | 
| 332   }; | 332   }; | 
| 333 | 333 | 
| 334   let ContextMenus = function(page) | 334   let ContextMenus = function(page) | 
| 335   { | 335   { | 
| 336     this._page = page; | 336     this._page = page; | 
| 337   }; | 337   }; | 
| 338   ContextMenus.prototype = { | 338   ContextMenus.prototype = { | 
| 339     create: function(item) | 339     create(item) | 
| 340     { | 340     { | 
| 341       let items = contextMenuItems.get(this._page); | 341       let items = contextMenuItems.get(this._page); | 
| 342       if (!items) | 342       if (!items) | 
| 343         contextMenuItems.set(this._page, items = []); | 343         contextMenuItems.set(this._page, items = []); | 
| 344 | 344 | 
| 345       items.push(item); | 345       items.push(item); | 
| 346       updateContextMenu(); | 346       updateContextMenu(); | 
| 347     }, | 347     }, | 
| 348     remove: function(item) | 348     remove(item) | 
| 349     { | 349     { | 
| 350       let items = contextMenuItems.get(this._page); | 350       let items = contextMenuItems.get(this._page); | 
| 351       if (items) | 351       if (items) | 
| 352       { | 352       { | 
| 353         let index = items.indexOf(item); | 353         let index = items.indexOf(item); | 
| 354         if (index != -1) | 354         if (index != -1) | 
| 355         { | 355         { | 
| 356           items.splice(index, 1); | 356           items.splice(index, 1); | 
| 357           updateContextMenu(); | 357           updateContextMenu(); | 
| 358         } | 358         } | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 390       chrome.webNavigation.onBeforeNavigate.removeListener(propagateHandlerBehav
     iorChange); | 390       chrome.webNavigation.onBeforeNavigate.removeListener(propagateHandlerBehav
     iorChange); | 
| 391       chrome.webRequest.handlerBehaviorChanged(); | 391       chrome.webRequest.handlerBehaviorChanged(); | 
| 392 | 392 | 
| 393       handlerBehaviorChangedQuota--; | 393       handlerBehaviorChangedQuota--; | 
| 394       setTimeout(() => { handlerBehaviorChangedQuota++; }, 600000); | 394       setTimeout(() => { handlerBehaviorChangedQuota++; }, 600000); | 
| 395     } | 395     } | 
| 396   } | 396   } | 
| 397 | 397 | 
| 398   ext.webRequest = { | 398   ext.webRequest = { | 
| 399     onBeforeRequest: new ext._EventTarget(), | 399     onBeforeRequest: new ext._EventTarget(), | 
| 400     handlerBehaviorChanged: () => | 400     handlerBehaviorChanged() | 
| 401     { | 401     { | 
| 402       // Defer handlerBehaviorChanged() until navigation occurs. | 402       // Defer handlerBehaviorChanged() until navigation occurs. | 
| 403       // There wouldn't be any visible effect when calling it earlier, | 403       // There wouldn't be any visible effect when calling it earlier, | 
| 404       // 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 | 
| 405       // it multiple times, if multiple filters are added/removed. | 405       // it multiple times, if multiple filters are added/removed. | 
| 406       let onBeforeNavigate = chrome.webNavigation.onBeforeNavigate; | 406       let onBeforeNavigate = chrome.webNavigation.onBeforeNavigate; | 
| 407       if (!onBeforeNavigate.hasListener(propagateHandlerBehaviorChange)) | 407       if (!onBeforeNavigate.hasListener(propagateHandlerBehaviorChange)) | 
| 408         onBeforeNavigate.addListener(propagateHandlerBehaviorChange); | 408         onBeforeNavigate.addListener(propagateHandlerBehaviorChange); | 
| 409     } | 409     } | 
| 410   }; | 410   }; | 
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 504       }; | 504       }; | 
| 505     } | 505     } | 
| 506 | 506 | 
| 507     return ext.onMessage._dispatch(message, sender, sendResponse).indexOf(true) 
     != -1; | 507     return ext.onMessage._dispatch(message, sender, sendResponse).indexOf(true) 
     != -1; | 
| 508   }); | 508   }); | 
| 509 | 509 | 
| 510 | 510 | 
| 511   /* Storage */ | 511   /* Storage */ | 
| 512 | 512 | 
| 513   ext.storage = { | 513   ext.storage = { | 
| 514     get: (keys, callback) => | 514     get(keys, callback) | 
| 515     { | 515     { | 
| 516       chrome.storage.local.get(keys, callback); | 516       chrome.storage.local.get(keys, callback); | 
| 517     }, | 517     }, | 
| 518     set: (key, value, callback) => | 518     set(key, value, callback) | 
| 519     { | 519     { | 
| 520       let items = {}; | 520       let items = {}; | 
| 521       items[key] = value; | 521       items[key] = value; | 
| 522       chrome.storage.local.set(items, callback); | 522       chrome.storage.local.set(items, callback); | 
| 523     }, | 523     }, | 
| 524     remove: (key, callback) => | 524     remove(key, callback) | 
| 525     { | 525     { | 
| 526       chrome.storage.local.remove(key, callback); | 526       chrome.storage.local.remove(key, callback); | 
| 527     }, | 527     }, | 
| 528     onChanged: chrome.storage.onChanged | 528     onChanged: chrome.storage.onChanged | 
| 529   }; | 529   }; | 
| 530 | 530 | 
| 531   /* Options */ | 531   /* Options */ | 
| 532 | 532 | 
| 533   if ("openOptionsPage" in chrome.runtime) | 533   if ("openOptionsPage" in chrome.runtime) | 
| 534   { | 534   { | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 592           { | 592           { | 
| 593             ext.pages.open(optionsUrl, callback); | 593             ext.pages.open(optionsUrl, callback); | 
| 594           } | 594           } | 
| 595         }); | 595         }); | 
| 596       }); | 596       }); | 
| 597     }; | 597     }; | 
| 598   } | 598   } | 
| 599 | 599 | 
| 600   /* Windows */ | 600   /* Windows */ | 
| 601   ext.windows = { | 601   ext.windows = { | 
| 602     create: (createData, callback) => | 602     create(createData, callback) | 
| 603     { | 603     { | 
| 604       chrome.windows.create(createData, createdWindow => | 604       chrome.windows.create(createData, createdWindow => | 
| 605       { | 605       { | 
| 606         afterTabLoaded(callback)(createdWindow.tabs[0]); | 606         afterTabLoaded(callback)(createdWindow.tabs[0]); | 
| 607       }); | 607       }); | 
| 608     } | 608     } | 
| 609   }; | 609   }; | 
| 610 } | 610 } | 
| LEFT | RIGHT | 
|---|