| 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-present eyeo GmbH | 3 * Copyright (C) 2006-present 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 let frames = framesOfTabs.get(this.id); | 91 let frames = framesOfTabs.get(this.id); |
| 92 if (frames) | 92 if (frames) |
| 93 { | 93 { |
| 94 let frame = frames.get(0); | 94 let frame = frames.get(0); |
| 95 if (frame) | 95 if (frame) |
| 96 return frame.url; | 96 return frame.url; |
| 97 } | 97 } |
| 98 }, | 98 }, |
| 99 sendMessage(message, responseCallback) | 99 sendMessage(message, responseCallback) |
| 100 { | 100 { |
| 101 chrome.tabs.sendMessage(this.id, message, responseCallback); | 101 browser.tabs.sendMessage(this.id, message, responseCallback); |
| 102 } | 102 } |
| 103 }; | 103 }; |
| 104 | 104 |
| 105 ext.getPage = id => new Page({id: parseInt(id, 10)}); | 105 ext.getPage = id => new Page({id: parseInt(id, 10)}); |
| 106 | 106 |
| 107 function afterTabLoaded(callback) | 107 function afterTabLoaded(callback) |
| 108 { | 108 { |
| 109 return openedTab => | 109 return openedTab => |
| 110 { | 110 { |
| 111 let onUpdated = (tabId, changeInfo, tab) => | 111 let onUpdated = (tabId, changeInfo, tab) => |
| 112 { | 112 { |
| 113 if (tabId == openedTab.id && changeInfo.status == "complete") | 113 if (tabId == openedTab.id && changeInfo.status == "complete") |
| 114 { | 114 { |
| 115 chrome.tabs.onUpdated.removeListener(onUpdated); | 115 browser.tabs.onUpdated.removeListener(onUpdated); |
| 116 callback(new Page(openedTab)); | 116 callback(new Page(openedTab)); |
| 117 } | 117 } |
| 118 }; | 118 }; |
| 119 chrome.tabs.onUpdated.addListener(onUpdated); | 119 browser.tabs.onUpdated.addListener(onUpdated); |
| 120 }; | 120 }; |
| 121 } | 121 } |
| 122 | 122 |
| 123 ext.pages = { | 123 ext.pages = { |
| 124 onLoading: new ext._EventTarget(), | 124 onLoading: new ext._EventTarget(), |
| 125 onActivated: new ext._EventTarget(), | 125 onActivated: new ext._EventTarget(), |
| 126 onRemoved: new ext._EventTarget() | 126 onRemoved: new ext._EventTarget() |
| 127 }; | 127 }; |
| 128 | 128 |
| 129 chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => | 129 browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => |
| 130 { | 130 { |
| 131 if (changeInfo.status == "loading") | 131 if (changeInfo.status == "loading") |
| 132 ext.pages.onLoading._dispatch(new Page(tab)); | 132 ext.pages.onLoading._dispatch(new Page(tab)); |
| 133 }); | 133 }); |
| 134 | 134 |
| 135 function createFrame(tabId, frameId) | 135 function createFrame(tabId, frameId) |
| 136 { | 136 { |
| 137 let frames = framesOfTabs.get(tabId); | 137 let frames = framesOfTabs.get(tabId); |
| 138 if (!frames) | 138 if (!frames) |
| 139 { | 139 { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 152 } | 152 } |
| 153 | 153 |
| 154 function updatePageFrameStructure(frameId, tabId, url, parentFrameId) | 154 function updatePageFrameStructure(frameId, tabId, url, parentFrameId) |
| 155 { | 155 { |
| 156 if (frameId == 0) | 156 if (frameId == 0) |
| 157 { | 157 { |
| 158 let page = new Page({id: tabId, url}); | 158 let page = new Page({id: tabId, url}); |
| 159 | 159 |
| 160 ext._removeFromAllPageMaps(tabId); | 160 ext._removeFromAllPageMaps(tabId); |
| 161 | 161 |
| 162 chrome.tabs.get(tabId, () => | 162 browser.tabs.get(tabId, () => |
| 163 { | 163 { |
| 164 // If the tab is prerendered, chrome.tabs.get() sets | 164 // If the tab is prerendered, browser.tabs.get() sets |
| 165 // chrome.runtime.lastError and we have to dispatch the onLoading event, | 165 // browser.runtime.lastError and we have to dispatch the onLoading |
| 166 // since the onUpdated event isn't dispatched for prerendered tabs. | 166 // event, since the onUpdated event isn't dispatched for prerendered |
| 167 // However, we have to keep relying on the unUpdated event for tabs that | 167 // tabs. However, we have to keep relying on the onUpdated event for |
| 168 // are already visible. Otherwise browser action changes get overridden | 168 // tabs that are already visible. Otherwise browser action changes get |
| 169 // when Chrome automatically resets them on navigation. | 169 // overridden when Chrome automatically resets them on navigation. |
| 170 if (chrome.runtime.lastError) | 170 if (browser.runtime.lastError) |
| 171 ext.pages.onLoading._dispatch(page); | 171 ext.pages.onLoading._dispatch(page); |
| 172 }); | 172 }); |
| 173 } | 173 } |
| 174 | 174 |
| 175 // Update frame URL and parent in frame structure | 175 // Update frame URL and parent in frame structure |
| 176 let frame = createFrame(tabId, frameId); | 176 let frame = createFrame(tabId, frameId); |
| 177 frame.url = new URL(url); | 177 frame.url = new URL(url); |
| 178 | 178 |
| 179 let parentFrame = framesOfTabs.get(tabId).get(parentFrameId); | 179 let parentFrame = framesOfTabs.get(tabId).get(parentFrameId); |
| 180 if (parentFrame) | 180 if (parentFrame) |
| 181 frame.parent = parentFrame; | 181 frame.parent = parentFrame; |
| 182 } | 182 } |
| 183 | 183 |
| 184 chrome.webRequest.onHeadersReceived.addListener(details => | 184 browser.webRequest.onHeadersReceived.addListener(details => |
| 185 { | 185 { |
| 186 // We have to update the frame structure when switching to a new | 186 // We have to update the frame structure when switching to a new |
| 187 // document, so that we process any further requests made by that | 187 // document, so that we process any further requests made by that |
| 188 // document in the right context. Unfortunately, we cannot rely | 188 // document in the right context. Unfortunately, we cannot rely |
| 189 // on webNavigation.onCommitted since it isn't guaranteed to fire | 189 // on webNavigation.onCommitted since it isn't guaranteed to fire |
| 190 // before any subresources start downloading[1]. As an | 190 // before any subresources start downloading[1]. As an |
| 191 // alternative we use webRequest.onHeadersReceived for HTTP(S) | 191 // alternative we use webRequest.onHeadersReceived for HTTP(S) |
| 192 // URLs, being careful to ignore any responses that won't cause | 192 // URLs, being careful to ignore any responses that won't cause |
| 193 // the document to be replaced. | 193 // the document to be replaced. |
| 194 // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=665843 | 194 // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=665843 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 return; | 252 return; |
| 253 } | 253 } |
| 254 } | 254 } |
| 255 | 255 |
| 256 updatePageFrameStructure(details.frameId, details.tabId, details.url, | 256 updatePageFrameStructure(details.frameId, details.tabId, details.url, |
| 257 details.parentFrameId); | 257 details.parentFrameId); |
| 258 }, | 258 }, |
| 259 {types: ["main_frame", "sub_frame"], urls: ["http://*/*", "https://*/*"]}, | 259 {types: ["main_frame", "sub_frame"], urls: ["http://*/*", "https://*/*"]}, |
| 260 ["responseHeaders"]); | 260 ["responseHeaders"]); |
| 261 | 261 |
| 262 chrome.webNavigation.onBeforeNavigate.addListener(details => | 262 browser.webNavigation.onBeforeNavigate.addListener(details => |
| 263 { | 263 { |
| 264 // Since we can only listen for HTTP(S) responses using | 264 // Since we can only listen for HTTP(S) responses using |
| 265 // webRequest.onHeadersReceived we must update the page structure here for | 265 // webRequest.onHeadersReceived we must update the page structure here for |
| 266 // other navigations. | 266 // other navigations. |
| 267 let url = new URL(details.url); | 267 let url = new URL(details.url); |
| 268 if (url.protocol != "http:" && url.protocol != "https:") | 268 if (url.protocol != "http:" && url.protocol != "https:") |
| 269 { | 269 { |
| 270 updatePageFrameStructure(details.frameId, details.tabId, details.url, | 270 updatePageFrameStructure(details.frameId, details.tabId, details.url, |
| 271 details.parentFrameId); | 271 details.parentFrameId); |
| 272 } | 272 } |
| 273 }); | 273 }); |
| 274 | 274 |
| 275 function forgetTab(tabId) | 275 function forgetTab(tabId) |
| 276 { | 276 { |
| 277 ext.pages.onRemoved._dispatch(tabId); | 277 ext.pages.onRemoved._dispatch(tabId); |
| 278 | 278 |
| 279 ext._removeFromAllPageMaps(tabId); | 279 ext._removeFromAllPageMaps(tabId); |
| 280 framesOfTabs.delete(tabId); | 280 framesOfTabs.delete(tabId); |
| 281 } | 281 } |
| 282 | 282 |
| 283 chrome.tabs.onReplaced.addListener((addedTabId, removedTabId) => | 283 browser.tabs.onReplaced.addListener((addedTabId, removedTabId) => |
| 284 { | 284 { |
| 285 forgetTab(removedTabId); | 285 forgetTab(removedTabId); |
| 286 }); | 286 }); |
| 287 | 287 |
| 288 chrome.tabs.onRemoved.addListener(forgetTab); | 288 browser.tabs.onRemoved.addListener(forgetTab); |
| 289 | 289 |
| 290 chrome.tabs.onActivated.addListener(details => | 290 browser.tabs.onActivated.addListener(details => |
| 291 { | 291 { |
| 292 ext.pages.onActivated._dispatch(new Page({id: details.tabId})); | 292 ext.pages.onActivated._dispatch(new Page({id: details.tabId})); |
| 293 }); | 293 }); |
| 294 | 294 |
| 295 | 295 |
| 296 /* Browser actions */ | 296 /* Browser actions */ |
| 297 | 297 |
| 298 let BrowserAction = function(tabId) | 298 let BrowserAction = function(tabId) |
| 299 { | 299 { |
| 300 this._tabId = tabId; | 300 this._tabId = tabId; |
| 301 this._changes = null; | 301 this._changes = null; |
| 302 }; | 302 }; |
| 303 BrowserAction.prototype = { | 303 BrowserAction.prototype = { |
| 304 _applyChanges() | 304 _applyChanges() |
| 305 { | 305 { |
| 306 if ("iconPath" in this._changes) | 306 if ("iconPath" in this._changes) |
| 307 { | 307 { |
| 308 // Firefox for Android displays the browser action not as an icon but | 308 // Firefox for Android displays the browser action not as an icon but |
| 309 // as a menu item. There is no icon, but such an option may be added in | 309 // as a menu item. There is no icon, but such an option may be added in |
| 310 // the future. | 310 // the future. |
| 311 // https://bugzilla.mozilla.org/show_bug.cgi?id=1331746 | 311 // https://bugzilla.mozilla.org/show_bug.cgi?id=1331746 |
| 312 if ("setIcon" in chrome.browserAction) | 312 if ("setIcon" in browser.browserAction) |
| 313 { | 313 { |
| 314 let path = { | 314 let path = { |
| 315 16: this._changes.iconPath.replace("$size", "16"), | 315 16: this._changes.iconPath.replace("$size", "16"), |
| 316 19: this._changes.iconPath.replace("$size", "19"), | 316 19: this._changes.iconPath.replace("$size", "19"), |
| 317 20: this._changes.iconPath.replace("$size", "20"), | 317 20: this._changes.iconPath.replace("$size", "20"), |
| 318 32: this._changes.iconPath.replace("$size", "32"), | 318 32: this._changes.iconPath.replace("$size", "32"), |
| 319 38: this._changes.iconPath.replace("$size", "38"), | 319 38: this._changes.iconPath.replace("$size", "38"), |
| 320 40: this._changes.iconPath.replace("$size", "40") | 320 40: this._changes.iconPath.replace("$size", "40") |
| 321 }; | 321 }; |
| 322 try | 322 try |
| 323 { | 323 { |
| 324 chrome.browserAction.setIcon({tabId: this._tabId, path}); | 324 browser.browserAction.setIcon({tabId: this._tabId, path}); |
| 325 } | 325 } |
| 326 catch (e) | 326 catch (e) |
| 327 { | 327 { |
| 328 // Edge throws if passed icon sizes different than 19,20,38,40px. | 328 // Edge throws if passed icon sizes different than 19,20,38,40px. |
| 329 delete path[16]; | 329 delete path[16]; |
| 330 delete path[32]; | 330 delete path[32]; |
| 331 chrome.browserAction.setIcon({tabId: this._tabId, path}); | 331 browser.browserAction.setIcon({tabId: this._tabId, path}); |
| 332 } | 332 } |
| 333 } | 333 } |
| 334 } | 334 } |
| 335 | 335 |
| 336 if ("badgeText" in this._changes) | 336 if ("badgeText" in this._changes) |
| 337 { | 337 { |
| 338 // There is no badge on Firefox for Android; the browser action is | 338 // There is no badge on Firefox for Android; the browser action is |
| 339 // simply a menu item. | 339 // simply a menu item. |
| 340 if ("setBadgeText" in chrome.browserAction) | 340 if ("setBadgeText" in browser.browserAction) |
| 341 { | 341 { |
| 342 chrome.browserAction.setBadgeText({ | 342 browser.browserAction.setBadgeText({ |
| 343 tabId: this._tabId, | 343 tabId: this._tabId, |
| 344 text: this._changes.badgeText | 344 text: this._changes.badgeText |
| 345 }); | 345 }); |
| 346 } | 346 } |
| 347 } | 347 } |
| 348 | 348 |
| 349 if ("badgeColor" in this._changes) | 349 if ("badgeColor" in this._changes) |
| 350 { | 350 { |
| 351 // There is no badge on Firefox for Android; the browser action is | 351 // There is no badge on Firefox for Android; the browser action is |
| 352 // simply a menu item. | 352 // simply a menu item. |
| 353 if ("setBadgeBackgroundColor" in chrome.browserAction) | 353 if ("setBadgeBackgroundColor" in browser.browserAction) |
| 354 { | 354 { |
| 355 chrome.browserAction.setBadgeBackgroundColor({ | 355 browser.browserAction.setBadgeBackgroundColor({ |
| 356 tabId: this._tabId, | 356 tabId: this._tabId, |
| 357 color: this._changes.badgeColor | 357 color: this._changes.badgeColor |
| 358 }); | 358 }); |
| 359 } | 359 } |
| 360 } | 360 } |
| 361 | 361 |
| 362 this._changes = null; | 362 this._changes = null; |
| 363 }, | 363 }, |
| 364 _queueChanges() | 364 _queueChanges() |
| 365 { | 365 { |
| 366 chrome.tabs.get(this._tabId, () => | 366 browser.tabs.get(this._tabId, () => |
| 367 { | 367 { |
| 368 // If the tab is prerendered, chrome.tabs.get() sets | 368 // If the tab is prerendered, browser.tabs.get() sets |
| 369 // chrome.runtime.lastError and we have to delay our changes | 369 // browser.runtime.lastError and we have to delay our changes |
| 370 // until the currently visible tab is replaced with the | 370 // until the currently visible tab is replaced with the |
| 371 // prerendered tab. Otherwise chrome.browserAction.set* fails. | 371 // prerendered tab. Otherwise browser.browserAction.set* fails. |
| 372 if (chrome.runtime.lastError) | 372 if (browser.runtime.lastError) |
| 373 { | 373 { |
| 374 let onReplaced = (addedTabId, removedTabId) => | 374 let onReplaced = (addedTabId, removedTabId) => |
| 375 { | 375 { |
| 376 if (addedTabId == this._tabId) | 376 if (addedTabId == this._tabId) |
| 377 { | 377 { |
| 378 chrome.tabs.onReplaced.removeListener(onReplaced); | 378 browser.tabs.onReplaced.removeListener(onReplaced); |
| 379 this._applyChanges(); | 379 this._applyChanges(); |
| 380 } | 380 } |
| 381 }; | 381 }; |
| 382 chrome.tabs.onReplaced.addListener(onReplaced); | 382 browser.tabs.onReplaced.addListener(onReplaced); |
| 383 } | 383 } |
| 384 else | 384 else |
| 385 { | 385 { |
| 386 this._applyChanges(); | 386 this._applyChanges(); |
| 387 } | 387 } |
| 388 }); | 388 }); |
| 389 }, | 389 }, |
| 390 _addChange(name, value) | 390 _addChange(name, value) |
| 391 { | 391 { |
| 392 if (!this._changes) | 392 if (!this._changes) |
| (...skipping 28 matching lines...) Expand all Loading... |
| 421 | 421 |
| 422 /* Context menus */ | 422 /* Context menus */ |
| 423 | 423 |
| 424 let contextMenuItems = new ext.PageMap(); | 424 let contextMenuItems = new ext.PageMap(); |
| 425 let contextMenuUpdating = false; | 425 let contextMenuUpdating = false; |
| 426 | 426 |
| 427 let updateContextMenu = () => | 427 let updateContextMenu = () => |
| 428 { | 428 { |
| 429 // Firefox for Android does not support context menus. | 429 // Firefox for Android does not support context menus. |
| 430 // https://bugzilla.mozilla.org/show_bug.cgi?id=1269062 | 430 // https://bugzilla.mozilla.org/show_bug.cgi?id=1269062 |
| 431 if (!("contextMenus" in chrome) || contextMenuUpdating) | 431 if (!("contextMenus" in browser) || contextMenuUpdating) |
| 432 return; | 432 return; |
| 433 | 433 |
| 434 contextMenuUpdating = true; | 434 contextMenuUpdating = true; |
| 435 | 435 |
| 436 chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => | 436 browser.tabs.query({active: true, lastFocusedWindow: true}, tabs => |
| 437 { | 437 { |
| 438 chrome.contextMenus.removeAll(() => | 438 browser.contextMenus.removeAll(() => |
| 439 { | 439 { |
| 440 contextMenuUpdating = false; | 440 contextMenuUpdating = false; |
| 441 | 441 |
| 442 if (tabs.length == 0) | 442 if (tabs.length == 0) |
| 443 return; | 443 return; |
| 444 | 444 |
| 445 let items = contextMenuItems.get({id: tabs[0].id}); | 445 let items = contextMenuItems.get({id: tabs[0].id}); |
| 446 | 446 |
| 447 if (!items) | 447 if (!items) |
| 448 return; | 448 return; |
| 449 | 449 |
| 450 items.forEach(item => | 450 items.forEach(item => |
| 451 { | 451 { |
| 452 chrome.contextMenus.create({ | 452 browser.contextMenus.create({ |
| 453 title: item.title, | 453 title: item.title, |
| 454 contexts: item.contexts, | 454 contexts: item.contexts, |
| 455 onclick(info, tab) | 455 onclick(info, tab) |
| 456 { | 456 { |
| 457 item.onclick(new Page(tab)); | 457 item.onclick(new Page(tab)); |
| 458 } | 458 } |
| 459 }); | 459 }); |
| 460 }); | 460 }); |
| 461 }); | 461 }); |
| 462 }); | 462 }); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 484 let index = items.indexOf(item); | 484 let index = items.indexOf(item); |
| 485 if (index != -1) | 485 if (index != -1) |
| 486 { | 486 { |
| 487 items.splice(index, 1); | 487 items.splice(index, 1); |
| 488 updateContextMenu(); | 488 updateContextMenu(); |
| 489 } | 489 } |
| 490 } | 490 } |
| 491 } | 491 } |
| 492 }; | 492 }; |
| 493 | 493 |
| 494 chrome.tabs.onActivated.addListener(updateContextMenu); | 494 browser.tabs.onActivated.addListener(updateContextMenu); |
| 495 | 495 |
| 496 if ("windows" in chrome) | 496 if ("windows" in browser) |
| 497 { | 497 { |
| 498 chrome.windows.onFocusChanged.addListener(windowId => | 498 browser.windows.onFocusChanged.addListener(windowId => |
| 499 { | 499 { |
| 500 if (windowId != chrome.windows.WINDOW_ID_NONE) | 500 if (windowId != browser.windows.WINDOW_ID_NONE) |
| 501 updateContextMenu(); | 501 updateContextMenu(); |
| 502 }); | 502 }); |
| 503 } | 503 } |
| 504 | 504 |
| 505 | 505 |
| 506 /* Web requests */ | 506 /* Web requests */ |
| 507 | 507 |
| 508 let framesOfTabs = new Map(); | 508 let framesOfTabs = new Map(); |
| 509 | 509 |
| 510 ext.getFrame = (tabId, frameId) => | 510 ext.getFrame = (tabId, frameId) => |
| 511 { | 511 { |
| 512 let frames = framesOfTabs.get(tabId); | 512 let frames = framesOfTabs.get(tabId); |
| 513 return frames && frames.get(frameId); | 513 return frames && frames.get(frameId); |
| 514 }; | 514 }; |
| 515 | 515 |
| 516 let handlerBehaviorChangedQuota = | 516 let handlerBehaviorChangedQuota = |
| 517 chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES; | 517 browser.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES; |
| 518 | 518 |
| 519 function propagateHandlerBehaviorChange() | 519 function propagateHandlerBehaviorChange() |
| 520 { | 520 { |
| 521 // Make sure to not call handlerBehaviorChanged() more often than allowed | 521 // Make sure to not call handlerBehaviorChanged() more often than allowed |
| 522 // by chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES. | 522 // by browser.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES. |
| 523 // Otherwise Chrome notifies the user that this extension is causing issues. | 523 // Otherwise Chrome notifies the user that this extension is causing issues. |
| 524 if (handlerBehaviorChangedQuota > 0) | 524 if (handlerBehaviorChangedQuota > 0) |
| 525 { | 525 { |
| 526 chrome.webNavigation.onBeforeNavigate.removeListener( | 526 browser.webNavigation.onBeforeNavigate.removeListener( |
| 527 propagateHandlerBehaviorChange | 527 propagateHandlerBehaviorChange |
| 528 ); | 528 ); |
| 529 chrome.webRequest.handlerBehaviorChanged(); | 529 browser.webRequest.handlerBehaviorChanged(); |
| 530 | 530 |
| 531 handlerBehaviorChangedQuota--; | 531 handlerBehaviorChangedQuota--; |
| 532 setTimeout(() => { handlerBehaviorChangedQuota++; }, 600000); | 532 setTimeout(() => { handlerBehaviorChangedQuota++; }, 600000); |
| 533 } | 533 } |
| 534 } | 534 } |
| 535 | 535 |
| 536 ext.webRequest = { | 536 ext.webRequest = { |
| 537 onBeforeRequest: new ext._EventTarget(), | 537 onBeforeRequest: new ext._EventTarget(), |
| 538 handlerBehaviorChanged() | 538 handlerBehaviorChanged() |
| 539 { | 539 { |
| 540 // Defer handlerBehaviorChanged() until navigation occurs. | 540 // Defer handlerBehaviorChanged() until navigation occurs. |
| 541 // There wouldn't be any visible effect when calling it earlier, | 541 // There wouldn't be any visible effect when calling it earlier, |
| 542 // but it's an expensive operation and that way we avoid to call | 542 // but it's an expensive operation and that way we avoid to call |
| 543 // it multiple times, if multiple filters are added/removed. | 543 // it multiple times, if multiple filters are added/removed. |
| 544 let {onBeforeNavigate} = chrome.webNavigation; | 544 let {onBeforeNavigate} = browser.webNavigation; |
| 545 if (!onBeforeNavigate.hasListener(propagateHandlerBehaviorChange)) | 545 if (!onBeforeNavigate.hasListener(propagateHandlerBehaviorChange)) |
| 546 onBeforeNavigate.addListener(propagateHandlerBehaviorChange); | 546 onBeforeNavigate.addListener(propagateHandlerBehaviorChange); |
| 547 } | 547 } |
| 548 }; | 548 }; |
| 549 | 549 |
| 550 chrome.tabs.query({}, tabs => | 550 browser.tabs.query({}, tabs => |
| 551 { | 551 { |
| 552 tabs.forEach(tab => | 552 tabs.forEach(tab => |
| 553 { | 553 { |
| 554 chrome.webNavigation.getAllFrames({tabId: tab.id}, details => | 554 browser.webNavigation.getAllFrames({tabId: tab.id}, details => |
| 555 { | 555 { |
| 556 if (details && details.length > 0) | 556 if (details && details.length > 0) |
| 557 { | 557 { |
| 558 let frames = new Map(); | 558 let frames = new Map(); |
| 559 framesOfTabs.set(tab.id, frames); | 559 framesOfTabs.set(tab.id, frames); |
| 560 | 560 |
| 561 for (let detail of details) | 561 for (let detail of details) |
| 562 { | 562 { |
| 563 let frame = {url: new URL(detail.url)}; | 563 let frame = {url: new URL(detail.url)}; |
| 564 frames.set(detail.frameId, frame); | 564 frames.set(detail.frameId, frame); |
| 565 | 565 |
| 566 if (detail.parentFrameId != -1) | 566 if (detail.parentFrameId != -1) |
| 567 frame.parent = frames.get(detail.parentFrameId); | 567 frame.parent = frames.get(detail.parentFrameId); |
| 568 } | 568 } |
| 569 } | 569 } |
| 570 }); | 570 }); |
| 571 }); | 571 }); |
| 572 }); | 572 }); |
| 573 | 573 |
| 574 chrome.webRequest.onBeforeRequest.addListener(details => | 574 browser.webRequest.onBeforeRequest.addListener(details => |
| 575 { | 575 { |
| 576 // The high-level code isn't interested in requests that aren't | 576 // The high-level code isn't interested in requests that aren't |
| 577 // related to a tab or requests loading a top-level document, | 577 // related to a tab or requests loading a top-level document, |
| 578 // those should never be blocked. | 578 // those should never be blocked. |
| 579 if (details.type == "main_frame") | 579 if (details.type == "main_frame") |
| 580 return; | 580 return; |
| 581 | 581 |
| 582 // Filter out requests from non web protocols. Ideally, we'd explicitly | 582 // Filter out requests from non web protocols. Ideally, we'd explicitly |
| 583 // specify the protocols we are interested in (i.e. http://, https://, | 583 // specify the protocols we are interested in (i.e. http://, https://, |
| 584 // ws:// and wss://) with the url patterns, given below, when adding this | 584 // ws:// and wss://) with the url patterns, given below, when adding this |
| (...skipping 23 matching lines...) Expand all Loading... |
| 608 } | 608 } |
| 609 | 609 |
| 610 if (ext.webRequest.onBeforeRequest._dispatch( | 610 if (ext.webRequest.onBeforeRequest._dispatch( |
| 611 url, type, page, frame).includes(false)) | 611 url, type, page, frame).includes(false)) |
| 612 return {cancel: true}; | 612 return {cancel: true}; |
| 613 }, {urls: ["<all_urls>"]}, ["blocking"]); | 613 }, {urls: ["<all_urls>"]}, ["blocking"]); |
| 614 | 614 |
| 615 | 615 |
| 616 /* Message passing */ | 616 /* Message passing */ |
| 617 | 617 |
| 618 chrome.runtime.onMessage.addListener((message, rawSender, sendResponse) => | 618 browser.runtime.onMessage.addListener((message, rawSender, sendResponse) => |
| 619 { | 619 { |
| 620 let sender = {}; | 620 let sender = {}; |
| 621 | 621 |
| 622 // Add "page" and "frame" if the message was sent by a content script. | 622 // Add "page" and "frame" if the message was sent by a content script. |
| 623 // If sent by popup or the background page itself, there is no "tab". | 623 // If sent by popup or the background page itself, there is no "tab". |
| 624 if ("tab" in rawSender) | 624 if ("tab" in rawSender) |
| 625 { | 625 { |
| 626 sender.page = new Page(rawSender.tab); | 626 sender.page = new Page(rawSender.tab); |
| 627 sender.frame = { | 627 sender.frame = { |
| 628 id: rawSender.frameId, | 628 id: rawSender.frameId, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 649 message, sender, sendResponse | 649 message, sender, sendResponse |
| 650 ).includes(true); | 650 ).includes(true); |
| 651 }); | 651 }); |
| 652 | 652 |
| 653 | 653 |
| 654 /* Storage */ | 654 /* Storage */ |
| 655 | 655 |
| 656 ext.storage = { | 656 ext.storage = { |
| 657 get(keys, callback) | 657 get(keys, callback) |
| 658 { | 658 { |
| 659 chrome.storage.local.get(keys, callback); | 659 browser.storage.local.get(keys, callback); |
| 660 }, | 660 }, |
| 661 set(key, value, callback) | 661 set(key, value, callback) |
| 662 { | 662 { |
| 663 let items = {}; | 663 let items = {}; |
| 664 items[key] = value; | 664 items[key] = value; |
| 665 chrome.storage.local.set(items, callback); | 665 browser.storage.local.set(items, callback); |
| 666 }, | 666 }, |
| 667 remove(key, callback) | 667 remove(key, callback) |
| 668 { | 668 { |
| 669 chrome.storage.local.remove(key, callback); | 669 browser.storage.local.remove(key, callback); |
| 670 }, | 670 }, |
| 671 onChanged: chrome.storage.onChanged | 671 onChanged: browser.storage.onChanged |
| 672 }; | 672 }; |
| 673 | 673 |
| 674 /* Windows */ | 674 /* Windows */ |
| 675 ext.windows = { | 675 ext.windows = { |
| 676 create(createData, callback) | 676 create(createData, callback) |
| 677 { | 677 { |
| 678 chrome.windows.create(createData, createdWindow => | 678 browser.windows.create(createData, createdWindow => |
| 679 { | 679 { |
| 680 afterTabLoaded(callback)(createdWindow.tabs[0]); | 680 afterTabLoaded(callback)(createdWindow.tabs[0]); |
| 681 }); | 681 }); |
| 682 } | 682 } |
| 683 }; | 683 }; |
| 684 }()); | 684 }()); |
| OLD | NEW |