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 |