| 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 (function() |
| 19 { | 19 { |
| 20 /* Context menus */ | 20 /* Context menus */ |
| 21 | 21 |
| 22 var contextMenuItems = new ext.PageMap(); | 22 var contextMenuItems = new ext.PageMap(); |
| 23 var lastContextMenuTab; |
| 23 | 24 |
| 24 var ContextMenus = function(page) | 25 var ContextMenus = function(page) |
| 25 { | 26 { |
| 26 this._page = page; | 27 this._page = page; |
| 27 }; | 28 }; |
| 28 ContextMenus.prototype = { | 29 ContextMenus.prototype = { |
| 29 create: function(item) | 30 create: function(item) |
| 30 { | 31 { |
| 31 var items = contextMenuItems.get(this._page); | 32 var items = contextMenuItems.get(this._page); |
| 32 if (!items) | 33 if (!items) |
| 33 contextMenuItems.set(this._page, items = []); | 34 contextMenuItems.set(this._page, items = []); |
| 34 | 35 |
| 35 items.push(item); | 36 items.push(item); |
| 36 }, | 37 }, |
| 37 remove: function(item) | 38 remove: function(item) |
| 38 { | 39 { |
| 39 let items = contextMenuItems.get(this._page); | 40 let items = contextMenuItems.get(this._page); |
| 40 if (items) | 41 if (items) |
| 41 { | 42 { |
| 42 let index = items.indexOf(item); | 43 let index = items.indexOf(item); |
| 43 if (index != -1) | 44 if (index != -1) |
| 44 items.splice(index, 1); | 45 items.splice(index, 1); |
| 45 } | 46 } |
| 46 } | 47 } |
| 47 }; | 48 }; |
| 48 | 49 |
| 49 safari.application.addEventListener("contextmenu", function(event) | 50 safari.application.addEventListener("contextmenu", function(event) |
| 50 { | 51 { |
| 52 lastContextMenuTab = event.target; |
| 53 |
| 51 if (!event.userInfo) | 54 if (!event.userInfo) |
| 52 return; | 55 return; |
| 53 | 56 |
| 54 var pageId = event.userInfo.pageId; | 57 var documentId = event.userInfo.documentId; |
| 55 if (!pageId) | 58 if (!documentId) |
| 56 return; | 59 return; |
| 57 | 60 |
| 58 var page = pages[event.userInfo.pageId]; | 61 var page = pages[event.target._documentLookup[documentId].pageId]; |
| 59 var items = contextMenuItems.get(page); | 62 var items = contextMenuItems.get(page); |
| 60 if (!items) | 63 if (!items) |
| 61 return; | 64 return; |
| 62 | 65 |
| 63 var context = event.userInfo.tagName; | 66 var context = event.userInfo.tagName; |
| 64 if (context == "img") | 67 if (context == "img") |
| 65 context = "image"; | 68 context = "image"; |
| 66 | 69 |
| 67 for (var i = 0; i < items.length; i++) | 70 for (var i = 0; i < items.length; i++) |
| 68 { | 71 { |
| 69 // Supported contexts are: all, audio, image, video | 72 // Supported contexts are: all, audio, image, video |
| 70 var menuItem = items[i]; | 73 var menuItem = items[i]; |
| 71 if (menuItem.contexts.indexOf("all") == -1 && menuItem.contexts.indexOf(co
ntext) == -1) | 74 if (menuItem.contexts.indexOf("all") == -1 && menuItem.contexts.indexOf(co
ntext) == -1) |
| 72 continue; | 75 continue; |
| 73 | 76 |
| 74 event.contextMenu.appendContextMenuItem(i, menuItem.title); | 77 event.contextMenu.appendContextMenuItem(i, menuItem.title); |
| 75 } | 78 } |
| 76 }); | 79 }); |
| 77 | 80 |
| 78 safari.application.addEventListener("command", function(event) | 81 safari.application.addEventListener("command", function(event) |
| 79 { | 82 { |
| 80 var page = pages[event.userInfo.pageId]; | 83 var documentId = event.userInfo.documentId; |
| 84 var page = pages[lastContextMenuTab._documentLookup[documentId].pageId]; |
| 81 var items = contextMenuItems.get(page); | 85 var items = contextMenuItems.get(page); |
| 82 | 86 |
| 83 items[event.command].onclick(page); | 87 items[event.command].onclick(page); |
| 84 }); | 88 }); |
| 85 | 89 |
| 86 | 90 |
| 87 /* Browser actions */ | 91 /* Browser actions */ |
| 88 | 92 |
| 89 var toolbarItemProperties = {}; | 93 var toolbarItemProperties = {}; |
| 90 | 94 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 this.browserAction = new BrowserAction(this); | 201 this.browserAction = new BrowserAction(this); |
| 198 this.contextMenus = new ContextMenus(this); | 202 this.contextMenus = new ContextMenus(this); |
| 199 }; | 203 }; |
| 200 Page.prototype = { | 204 Page.prototype = { |
| 201 get url() | 205 get url() |
| 202 { | 206 { |
| 203 return this._frames[0].url; | 207 return this._frames[0].url; |
| 204 }, | 208 }, |
| 205 sendMessage: function(message, responseCallback) | 209 sendMessage: function(message, responseCallback) |
| 206 { | 210 { |
| 207 this._messageProxy.sendMessage(message, responseCallback, {pageId: this.id
}); | 211 var documentIds = []; |
| 212 for (var documentId in this._tab._documentLookup) |
| 213 if (this._tab._documentLookup[documentId].pageId == this.id) |
| 214 documentIds.push(documentId); |
| 215 |
| 216 this._messageProxy.sendMessage(message, responseCallback, |
| 217 {targetDocuments: documentIds}); |
| 208 } | 218 } |
| 209 }; | 219 }; |
| 210 | 220 |
| 211 ext.getPage = function(id) | 221 ext.getPage = function(id) |
| 212 { | 222 { |
| 213 return pages[id]; | 223 return pages[id]; |
| 214 }; | 224 }; |
| 215 | 225 |
| 216 var isPageActive = function(page) | 226 var isPageActive = function(page) |
| 217 { | 227 { |
| 218 var tab = page._tab; | 228 var tab = page._tab; |
| 219 var win = tab.browserWindow; | 229 var win = tab.browserWindow; |
| 220 return win && tab == win.activeTab && page == tab._visiblePage; | 230 return win && tab == win.activeTab && page == tab._visiblePage; |
| 221 }; | 231 }; |
| 222 | 232 |
| 223 var forgetPage = function(id) | 233 var forgetPage = function(id) |
| 224 { | 234 { |
| 225 ext.pages.onRemoved._dispatch(id); | 235 ext.pages.onRemoved._dispatch(id); |
| 226 | 236 |
| 227 ext._removeFromAllPageMaps(id); | 237 ext._removeFromAllPageMaps(id); |
| 228 | 238 |
| 229 delete pages[id]._tab._pages[id]; | 239 var tab = pages[id]._tab; |
| 240 |
| 241 for (var documentId in tab._documentLookup) |
| 242 { |
| 243 if (tab._documentLookup[documentId].pageId == id) |
| 244 delete tab._documentLookup[documentId]; |
| 245 } |
| 246 |
| 247 delete tab._pages[id]; |
| 230 delete pages[id]; | 248 delete pages[id]; |
| 231 }; | 249 }; |
| 232 | 250 |
| 233 var replacePage = function(page) | 251 var replacePage = function(page) |
| 234 { | 252 { |
| 235 var tab = page._tab; | 253 var tab = page._tab; |
| 236 tab._visiblePage = page; | 254 tab._visiblePage = page; |
| 237 | 255 |
| 238 for (var id in tab._pages) | 256 for (var id in tab._pages) |
| 239 { | 257 { |
| 240 if (id != page.id) | 258 if (id != page.id) |
| 241 forgetPage(id); | 259 forgetPage(id); |
| 242 } | 260 } |
| 243 | 261 |
| 244 if (isPageActive(page)) | 262 if (isPageActive(page)) |
| 245 updateToolbarItemForPage(page, tab.browserWindow); | 263 updateToolbarItemForPage(page, tab.browserWindow); |
| 246 }; | 264 }; |
| 247 | 265 |
| 248 var addPage = function(tab, url, prerendered) | 266 var addPage = function(tab, url, prerendered) |
| 249 { | 267 { |
| 250 var pageId = ++pageCounter; | 268 var pageId = ++pageCounter; |
| 251 | 269 |
| 252 if (!('_pages' in tab)) | 270 if (!('_pages' in tab)) |
| 253 tab._pages = Object.create(null); | 271 tab._pages = Object.create(null); |
| 254 | 272 |
| 273 if (!('_documentLookup' in tab)) |
| 274 tab._documentLookup = Object.create(null); |
| 275 |
| 255 var page = new Page(pageId, tab, url); | 276 var page = new Page(pageId, tab, url); |
| 256 pages[pageId] = tab._pages[pageId] = page; | 277 pages[pageId] = tab._pages[pageId] = page; |
| 257 | 278 |
| 258 // When a new page is shown, forget the previous page associated | 279 // When a new page is shown, forget the previous page associated |
| 259 // with its tab, and reset the toolbar item if necessary. | 280 // with its tab, and reset the toolbar item if necessary. |
| 260 // Note that it wouldn't be sufficient to do that when the old | 281 // Note that it wouldn't be sufficient to do that when the old |
| 261 // page is unloading, because Safari dispatches window.onunload | 282 // page is unloading, because Safari dispatches window.onunload |
| 262 // only when reloading the page or following links, but not when | 283 // only when reloading the page or following links, but not when |
| 263 // you enter a new URL in the address bar. | 284 // you enter a new URL in the address bar. |
| 264 if (!prerendered) | 285 if (!prerendered) |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 // use Safari's extension API to detect existing tabs. | 354 // use Safari's extension API to detect existing tabs. |
| 334 safari.application.browserWindows.forEach(function(win) | 355 safari.application.browserWindows.forEach(function(win) |
| 335 { | 356 { |
| 336 for (var i = 0; i < win.tabs.length; i++) | 357 for (var i = 0; i < win.tabs.length; i++) |
| 337 { | 358 { |
| 338 var tab = win.tabs[i]; | 359 var tab = win.tabs[i]; |
| 339 var url = tab.url; | 360 var url = tab.url; |
| 340 | 361 |
| 341 // For the new tab page the url property is undefined. | 362 // For the new tab page the url property is undefined. |
| 342 if (url) | 363 if (url) |
| 343 addPage(tab, url, false); | 364 { |
| 365 var pageId = addPage(tab, url, false); |
| 366 tab.page.dispatchMessage("requestDocumentId", {pageId: pageId}); |
| 367 } |
| 344 } | 368 } |
| 345 }); | 369 }); |
| 346 | 370 |
| 347 | 371 |
| 348 /* Web requests */ | 372 /* Web requests */ |
| 349 | 373 |
| 350 ext.webRequest = { | 374 ext.webRequest = { |
| 351 onBeforeRequest: new ext._EventTarget(), | 375 onBeforeRequest: new ext._EventTarget(), |
| 352 handlerBehaviorChanged: function() | 376 handlerBehaviorChanged: function() |
| 353 { | 377 { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 return function() | 442 return function() |
| 419 { | 443 { |
| 420 var page = pages[pageId]; | 444 var page = pages[pageId]; |
| 421 if (!page) | 445 if (!page) |
| 422 return; | 446 return; |
| 423 | 447 |
| 424 var objects = proxy.cache.get(page); | 448 var objects = proxy.cache.get(page); |
| 425 if (!objects) | 449 if (!objects) |
| 426 return; | 450 return; |
| 427 | 451 |
| 452 var targetDocument; |
| 453 for (var documentId in page._tab._documentLookup) |
| 454 { |
| 455 var result = page._tab._documentLookup[documentId]; |
| 456 if (result.pageId == pageId && result.frameId == frameId) |
| 457 { |
| 458 targetDocument = documentId; |
| 459 break; |
| 460 } |
| 461 } |
| 462 if (!targetDocument) |
| 463 return; |
| 464 |
| 428 page._tab.page.dispatchMessage("proxyCallback", | 465 page._tab.page.dispatchMessage("proxyCallback", |
| 429 { | 466 { |
| 430 pageId: pageId, | 467 targetDocuments: [targetDocument], |
| 431 frameId: frameId, | |
| 432 callbackId: callbackId, | 468 callbackId: callbackId, |
| 433 contextId: proxy.registerObject(this, objects), | 469 contextId: proxy.registerObject(this, objects), |
| 434 args: proxy.serializeSequence(arguments, objects) | 470 args: proxy.serializeSequence(arguments, objects) |
| 435 }); | 471 }); |
| 436 }; | 472 }; |
| 437 }, | 473 }, |
| 438 deserialize: function(spec, objects, pageId, memo) | 474 deserialize: function(spec, objects, pageId, frameId, memo) |
| 439 { | 475 { |
| 440 switch (spec.type) | 476 switch (spec.type) |
| 441 { | 477 { |
| 442 case "value": | 478 case "value": |
| 443 return spec.value; | 479 return spec.value; |
| 444 case "hosted": | 480 case "hosted": |
| 445 return objects[spec.objectId]; | 481 return objects[spec.objectId]; |
| 446 case "callback": | 482 case "callback": |
| 447 return this.createCallback(spec.callbackId, pageId, spec.frameId); | 483 return this.createCallback(spec.callbackId, pageId, frameId); |
| 448 case "object": | 484 case "object": |
| 449 case "array": | 485 case "array": |
| 450 if (!memo) | 486 if (!memo) |
| 451 memo = {specs: [], objects: []}; | 487 memo = {specs: [], objects: []}; |
| 452 | 488 |
| 453 var idx = memo.specs.indexOf(spec); | 489 var idx = memo.specs.indexOf(spec); |
| 454 if (idx != -1) | 490 if (idx != -1) |
| 455 return memo.objects[idx]; | 491 return memo.objects[idx]; |
| 456 | 492 |
| 457 var obj; | 493 var obj; |
| 458 if (spec.type == "array") | 494 if (spec.type == "array") |
| 459 obj = []; | 495 obj = []; |
| 460 else | 496 else |
| 461 obj = {}; | 497 obj = {}; |
| 462 | 498 |
| 463 memo.specs.push(spec); | 499 memo.specs.push(spec); |
| 464 memo.objects.push(obj); | 500 memo.objects.push(obj); |
| 465 | 501 |
| 466 if (spec.type == "array") | 502 if (spec.type == "array") |
| 467 for (var i = 0; i < spec.items.length; i++) | 503 for (var i = 0; i < spec.items.length; i++) |
| 468 obj.push(this.deserialize(spec.items[i], objects, pageId, memo)); | 504 obj.push(this.deserialize(spec.items[i], objects, |
| 505 pageId, frameId, memo)); |
| 469 else | 506 else |
| 470 for (var k in spec.properties) | 507 for (var k in spec.properties) |
| 471 obj[k] = this.deserialize(spec.properties[k], objects, pageId, mem
o); | 508 obj[k] = this.deserialize(spec.properties[k], objects, |
| 509 pageId, frameId, memo); |
| 472 | 510 |
| 473 return obj; | 511 return obj; |
| 474 } | 512 } |
| 475 }, | 513 }, |
| 476 getObjectCache: function(page) | 514 getObjectCache: function(page) |
| 477 { | 515 { |
| 478 var objects = this.cache.get(page); | 516 var objects = this.cache.get(page); |
| 479 if (!objects) | 517 if (!objects) |
| 480 { | 518 { |
| 481 objects = [window]; | 519 objects = [window]; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 503 var value = obj[message.property]; | 541 var value = obj[message.property]; |
| 504 } | 542 } |
| 505 catch (e) | 543 catch (e) |
| 506 { | 544 { |
| 507 return this.fail(e); | 545 return this.fail(e); |
| 508 } | 546 } |
| 509 | 547 |
| 510 return {succeed: true, result: this.serialize(value, objects)}; | 548 return {succeed: true, result: this.serialize(value, objects)}; |
| 511 case "setProperty": | 549 case "setProperty": |
| 512 var obj = objects[message.objectId]; | 550 var obj = objects[message.objectId]; |
| 513 var value = this.deserialize(message.value, objects, message.pageId); | 551 var value = this.deserialize(message.value, objects, |
| 552 message.pageId, message.frameId); |
| 514 | 553 |
| 515 try | 554 try |
| 516 { | 555 { |
| 517 obj[message.property] = value; | 556 obj[message.property] = value; |
| 518 } | 557 } |
| 519 catch (e) | 558 catch (e) |
| 520 { | 559 { |
| 521 return this.fail(e); | 560 return this.fail(e); |
| 522 } | 561 } |
| 523 | 562 |
| 524 return {succeed: true}; | 563 return {succeed: true}; |
| 525 case "callFunction": | 564 case "callFunction": |
| 526 var func = objects[message.functionId]; | 565 var func = objects[message.functionId]; |
| 527 var context = objects[message.contextId]; | 566 var context = objects[message.contextId]; |
| 528 | 567 |
| 529 var args = []; | 568 var args = []; |
| 530 for (var i = 0; i < message.args.length; i++) | 569 for (var i = 0; i < message.args.length; i++) |
| 531 args.push(this.deserialize(message.args[i], objects, message.pageId)
); | 570 args.push(this.deserialize(message.args[i], objects, |
| 571 message.pageId, message.frameId)); |
| 532 | 572 |
| 533 try | 573 try |
| 534 { | 574 { |
| 535 var result = func.apply(context, args); | 575 var result = func.apply(context, args); |
| 536 } | 576 } |
| 537 catch (e) | 577 catch (e) |
| 538 { | 578 { |
| 539 return this.fail(e); | 579 return this.fail(e); |
| 540 } | 580 } |
| 541 | 581 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 563 return objectInfo; | 603 return objectInfo; |
| 564 } | 604 } |
| 565 } | 605 } |
| 566 }; | 606 }; |
| 567 | 607 |
| 568 | 608 |
| 569 /* Message processing */ | 609 /* Message processing */ |
| 570 | 610 |
| 571 safari.application.addEventListener("message", function(event) | 611 safari.application.addEventListener("message", function(event) |
| 572 { | 612 { |
| 613 var tab = event.target; |
| 614 var message = event.message; |
| 615 var sender; |
| 616 if ("documentId" in message && "_documentLookup" in tab) |
| 617 { |
| 618 sender = tab._documentLookup[message.documentId]; |
| 619 if (sender) |
| 620 { |
| 621 sender.page = pages[sender.pageId]; |
| 622 sender.frame = sender.page._frames[sender.frameId]; |
| 623 } |
| 624 } |
| 625 |
| 573 switch (event.name) | 626 switch (event.name) |
| 574 { | 627 { |
| 575 case "canLoad": | 628 case "canLoad": |
| 576 switch (event.message.category) | 629 switch (message.category) |
| 577 { | 630 { |
| 578 case "loading": | |
| 579 var tab = event.target; | |
| 580 var message = event.message; | |
| 581 | |
| 582 var pageId; | |
| 583 var frameId; | |
| 584 | |
| 585 if (message.isTopLevel) | |
| 586 { | |
| 587 pageId = addPage(tab, message.url, message.isPrerendered); | |
| 588 frameId = 0; | |
| 589 | |
| 590 ext.pages.onLoading._dispatch(pages[pageId]); | |
| 591 } | |
| 592 else | |
| 593 { | |
| 594 var page; | |
| 595 var parentFrame; | |
| 596 | |
| 597 var lastPageId; | |
| 598 var lastPage; | |
| 599 var lastPageTopLevelFrame; | |
| 600 | |
| 601 // find the parent frame and its page for this sub frame, | |
| 602 // by matching its referrer with the URL of frames previously | |
| 603 // loaded in the same tab. If there is more than one match, | |
| 604 // the most recent loaded page and frame is preferred. | |
| 605 for (var curPageId in tab._pages) | |
| 606 { | |
| 607 var curPage = pages[curPageId]; | |
| 608 | |
| 609 for (var i = 0; i < curPage._frames.length; i++) | |
| 610 { | |
| 611 var curFrame = curPage._frames[i]; | |
| 612 | |
| 613 if (curFrame.url.href == message.referrer) | |
| 614 { | |
| 615 pageId = curPageId; | |
| 616 page = curPage; | |
| 617 parentFrame = curFrame; | |
| 618 } | |
| 619 | |
| 620 if (i == 0) | |
| 621 { | |
| 622 lastPageId = curPageId; | |
| 623 lastPage = curPage; | |
| 624 lastPageTopLevelFrame = curFrame; | |
| 625 } | |
| 626 } | |
| 627 } | |
| 628 | |
| 629 // if we can't find the parent frame and its page, fall back to | |
| 630 // the page most recently loaded in the tab and its top level fram
e | |
| 631 if (!page) | |
| 632 { | |
| 633 pageId = lastPageId; | |
| 634 page = lastPage; | |
| 635 parentFrame = lastPageTopLevelFrame; | |
| 636 } | |
| 637 | |
| 638 frameId = page._frames.length; | |
| 639 page._frames.push({url: new URL(message.url), parent: parentFrame}
); | |
| 640 } | |
| 641 event.message = {pageId: pageId, frameId: frameId}; | |
| 642 break; | |
| 643 case "webRequest": | 631 case "webRequest": |
| 644 var page = pages[event.message.pageId]; | |
| 645 var frame = page._frames[event.message.frameId]; | |
| 646 | |
| 647 var results = ext.webRequest.onBeforeRequest._dispatch( | 632 var results = ext.webRequest.onBeforeRequest._dispatch( |
| 648 new URL(event.message.url, frame.url), | 633 new URL(message.url, sender.frame.url), |
| 649 event.message.type, page, frame | 634 message.type, sender.page, sender.frame |
| 650 ); | 635 ); |
| 651 | 636 |
| 652 event.message = (results.indexOf(false) == -1); | 637 event.message = (results.indexOf(false) == -1); |
| 653 break; | 638 break; |
| 654 case "proxy": | 639 case "proxy": |
| 655 event.message = backgroundPageProxy.handleMessage(event.message); | 640 message.pageId = sender.pageId; |
| 641 message.frameId = sender.frameId; |
| 642 event.message = backgroundPageProxy.handleMessage(message); |
| 656 break; | 643 break; |
| 657 case "request": | 644 case "request": |
| 658 var page = pages[event.message.pageId]; | |
| 659 var sender = {page: page, frame: page._frames[event.message.frameId]
}; | |
| 660 | |
| 661 var response = null; | 645 var response = null; |
| 662 var sendResponse = function(message) { response = message; }; | 646 var sendResponse = function(message) { response = message; }; |
| 663 | 647 |
| 664 ext.onMessage._dispatch(event.message.payload, sender, sendResponse)
; | 648 ext.onMessage._dispatch(message.payload, sender, sendResponse); |
| 665 | 649 |
| 666 event.message = response; | 650 event.message = response; |
| 667 break; | 651 break; |
| 668 } | 652 } |
| 669 break; | 653 break; |
| 670 case "request": | 654 case "request": |
| 671 var page = pages[event.message.pageId]; | 655 sender.page._messageProxy.handleRequest(message, sender); |
| 672 var sender = {page: page, frame: page._frames[event.message.frameId]}; | |
| 673 page._messageProxy.handleRequest(event.message, sender); | |
| 674 break; | 656 break; |
| 675 case "response": | 657 case "response": |
| 676 pages[event.message.pageId]._messageProxy.handleResponse(event.message); | 658 // All documents within a page have the same pageId and that's all we |
| 659 // care about here. |
| 660 var pageId = tab._documentLookup[message.targetDocuments[0]].pageId; |
| 661 pages[pageId]._messageProxy.handleResponse(message); |
| 677 break; | 662 break; |
| 678 case "replaced": | 663 case "replaced": |
| 679 // when a prerendered page is shown, forget the previous page | 664 // when a prerendered page is shown, forget the previous page |
| 680 // associated with its tab, and reset the toolbar item if necessary. | 665 // associated with its tab, and reset the toolbar item if necessary. |
| 681 // Note that it wouldn't be sufficient to do that when the old | 666 // Note that it wouldn't be sufficient to do that when the old |
| 682 // page is unloading, because Safari dispatches window.onunload | 667 // page is unloading, because Safari dispatches window.onunload |
| 683 // only when reloading the page or following links, but not when | 668 // only when reloading the page or following links, but not when |
| 684 // the current page is replaced with a prerendered page. | 669 // the current page is replaced with a prerendered page. |
| 685 replacePage(pages[event.message.pageId]); | 670 replacePage(sender.page); |
| 671 break; |
| 672 case "loading": |
| 673 var pageId; |
| 674 var frameId; |
| 675 var documentId = message.documentId; |
| 676 |
| 677 if (message.isTopLevel) |
| 678 { |
| 679 pageId = addPage(tab, message.url, message.isPrerendered); |
| 680 frameId = 0; |
| 681 |
| 682 ext.pages.onLoading._dispatch(pages[pageId]); |
| 683 } |
| 684 else |
| 685 { |
| 686 var page; |
| 687 var parentFrame; |
| 688 |
| 689 var lastPageId; |
| 690 var lastPage; |
| 691 var lastPageTopLevelFrame; |
| 692 |
| 693 // find the parent frame and its page for this sub frame, |
| 694 // by matching its referrer with the URL of frames previously |
| 695 // loaded in the same tab. If there is more than one match, |
| 696 // the most recent loaded page and frame is preferred. |
| 697 for (var curPageId in tab._pages) |
| 698 { |
| 699 var curPage = pages[curPageId]; |
| 700 |
| 701 for (var i = 0; i < curPage._frames.length; i++) |
| 702 { |
| 703 var curFrame = curPage._frames[i]; |
| 704 |
| 705 if (curFrame.url.href == message.referrer) |
| 706 { |
| 707 pageId = curPageId; |
| 708 page = curPage; |
| 709 parentFrame = curFrame; |
| 710 } |
| 711 |
| 712 if (i == 0) |
| 713 { |
| 714 lastPageId = curPageId; |
| 715 lastPage = curPage; |
| 716 lastPageTopLevelFrame = curFrame; |
| 717 } |
| 718 } |
| 719 } |
| 720 |
| 721 // if we can't find the parent frame and its page, fall back to |
| 722 // the page most recently loaded in the tab and its top level frame |
| 723 if (!page) |
| 724 { |
| 725 pageId = lastPageId; |
| 726 page = lastPage; |
| 727 parentFrame = lastPageTopLevelFrame; |
| 728 } |
| 729 |
| 730 frameId = page._frames.length; |
| 731 page._frames.push({url: new URL(message.url), parent: parentFrame}); |
| 732 } |
| 733 |
| 734 tab._documentLookup[documentId] = {pageId: pageId, frameId: frameId}; |
| 735 break; |
| 736 case "documentId": |
| 737 tab._documentLookup[message.documentId] = { |
| 738 pageId: message.pageId, frameId: 0 |
| 739 }; |
| 686 break; | 740 break; |
| 687 } | 741 } |
| 688 }); | 742 }); |
| 689 | 743 |
| 690 | 744 |
| 691 /* Storage */ | 745 /* Storage */ |
| 692 | 746 |
| 693 ext.storage = { | 747 ext.storage = { |
| 694 get: function(keys, callback) | 748 get: function(keys, callback) |
| 695 { | 749 { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 /* Windows */ | 816 /* Windows */ |
| 763 ext.windows = { | 817 ext.windows = { |
| 764 // Safari doesn't provide as rich a windows API as Chrome does, so instead | 818 // Safari doesn't provide as rich a windows API as Chrome does, so instead |
| 765 // of chrome.windows.create we have to fall back to just opening a new tab. | 819 // of chrome.windows.create we have to fall back to just opening a new tab. |
| 766 create: function(createData, callback) | 820 create: function(createData, callback) |
| 767 { | 821 { |
| 768 ext.pages.open(createData.url, callback); | 822 ext.pages.open(createData.url, callback); |
| 769 } | 823 } |
| 770 }; | 824 }; |
| 771 })(); | 825 })(); |
| OLD | NEW |