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