OLD | NEW |
1 /* | 1 /* |
2 * This file is part of Adblock Plus <http://adblockplus.org/>, | 2 * This file is part of Adblock Plus <http://adblockplus.org/>, |
3 * Copyright (C) 2006-2014 Eyeo GmbH | 3 * Copyright (C) 2006-2014 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 }; | 45 }; |
46 Page.prototype = { | 46 Page.prototype = { |
47 get url() | 47 get url() |
48 { | 48 { |
49 return this._frames[0].url; | 49 return this._frames[0].url; |
50 }, | 50 }, |
51 activate: function() | 51 activate: function() |
52 { | 52 { |
53 this._tab.activate(); | 53 this._tab.activate(); |
54 }, | 54 }, |
| 55 close: function() |
| 56 { |
| 57 this._tab.close(); |
| 58 }, |
55 sendMessage: function(message, responseCallback) | 59 sendMessage: function(message, responseCallback) |
56 { | 60 { |
57 this._messageProxy.sendMessage(message, responseCallback, {pageId: this._i
d}); | 61 this._messageProxy.sendMessage(message, responseCallback, {pageId: this._i
d}); |
58 } | 62 } |
59 }; | 63 }; |
60 | 64 |
61 var isPageActive = function(page) | 65 var isPageActive = function(page) |
62 { | 66 { |
63 return page._tab == page._tab.browserWindow.activeTab && !page._prerendered; | 67 return page._tab == page._tab.browserWindow.activeTab && !page._prerendered; |
64 }; | 68 }; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 if ("active" in info && info.active != isPageActive(page)) | 116 if ("active" in info && info.active != isPageActive(page)) |
113 continue; | 117 continue; |
114 if ("lastFocusedWindow" in info && info.lastFocusedWindow != (win == saf
ari.application.activeBrowserWindow)) | 118 if ("lastFocusedWindow" in info && info.lastFocusedWindow != (win == saf
ari.application.activeBrowserWindow)) |
115 continue; | 119 continue; |
116 | 120 |
117 matchedPages.push(page); | 121 matchedPages.push(page); |
118 }; | 122 }; |
119 | 123 |
120 callback(matchedPages); | 124 callback(matchedPages); |
121 }, | 125 }, |
122 onLoading: new ext._EventTarget() | 126 onLoading: new ext._EventTarget(), |
| 127 onPopup: new ext._EventTarget() |
123 }; | 128 }; |
124 | 129 |
125 safari.application.addEventListener("close", function(event) | 130 safari.application.addEventListener("close", function(event) |
126 { | 131 { |
127 // this event is dispatched on closing windows and tabs. However when a | 132 // this event is dispatched on closing windows and tabs. However when a |
128 // window is closed, it is first dispatched on each tab in the window and | 133 // window is closed, it is first dispatched on each tab in the window and |
129 // then on the window itself. But we are only interested in closed tabs. | 134 // then on the window itself. But we are only interested in closed tabs. |
130 if (!(event.target instanceof SafariBrowserTab)) | 135 if (!(event.target instanceof SafariBrowserTab)) |
131 return; | 136 return; |
132 | 137 |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 objectInfo.prototypeOf = "Function"; | 521 objectInfo.prototypeOf = "Function"; |
517 | 522 |
518 return objectInfo; | 523 return objectInfo; |
519 } | 524 } |
520 } | 525 } |
521 }; | 526 }; |
522 | 527 |
523 | 528 |
524 /* Message processing */ | 529 /* Message processing */ |
525 | 530 |
| 531 var findPageAndFrame = function(tab, url) |
| 532 { |
| 533 var page = null; |
| 534 var frame = null; |
| 535 |
| 536 var lastPage; |
| 537 var lastPageTopLevelFrame; |
| 538 |
| 539 // find the parent frame and its page for this sub frame, |
| 540 // by matching its referrer with the URL of frames previously |
| 541 // loaded in the same tab. If there is more than one match, |
| 542 // the most recent loaded page and frame is preferred. |
| 543 for (var curPageId in pages) |
| 544 { |
| 545 var curPage = pages[curPageId]; |
| 546 if (tab && curPage._tab != tab) |
| 547 continue; |
| 548 |
| 549 for (var i = 0; i < curPage._frames.length; i++) |
| 550 { |
| 551 var curFrame = curPage._frames[i]; |
| 552 |
| 553 if (curFrame.url == url) |
| 554 { |
| 555 page = curPage; |
| 556 frame = curFrame; |
| 557 } |
| 558 |
| 559 if (i == 0) |
| 560 { |
| 561 lastPage = curPage; |
| 562 lastPageTopLevelFrame = curFrame; |
| 563 } |
| 564 } |
| 565 } |
| 566 |
| 567 // if we can't find the parent frame and its page, fall back to |
| 568 // the page most recently loaded in the tab and its top level frame |
| 569 return { |
| 570 page: page || lastPage, |
| 571 frame: frame || lastPageTopLevelFrame |
| 572 }; |
| 573 }; |
| 574 |
526 safari.application.addEventListener("message", function(event) | 575 safari.application.addEventListener("message", function(event) |
527 { | 576 { |
528 switch (event.name) | 577 switch (event.name) |
529 { | 578 { |
530 case "canLoad": | 579 case "canLoad": |
531 switch (event.message.category) | 580 switch (event.message.category) |
532 { | 581 { |
533 case "loading": | 582 case "loading": |
534 var pageId; | 583 var pageId; |
535 var frameId; | 584 var frameId; |
536 | 585 |
537 if (event.message.isTopLevel) | 586 if (event.message.isTopLevel) |
538 { | 587 { |
539 pageId = ++pageCounter; | 588 pageId = ++pageCounter; |
540 frameId = 0; | 589 frameId = 0; |
541 | 590 |
542 var isPrerendered = event.message.isPrerendered; | 591 var isPrerendered = event.message.isPrerendered; |
543 var page = pages[pageId] = new Page( | 592 var page = new Page( |
544 pageId, | 593 pageId, |
545 event.target, | 594 event.target, |
546 event.message.url, | 595 event.message.url, |
547 isPrerendered | 596 isPrerendered |
548 ); | 597 ); |
549 | 598 |
550 // when a new page is shown, forget the previous page associated | 599 if (event.message.isPopup && !event.target._popupLoaded) |
551 // with its tab, and reset the toolbar item if necessary. | 600 { |
552 // Note that it wouldn't be sufficient to do that when the old | 601 if (!("_opener" in event.target)) |
553 // page is unloading, because Safari dispatches window.onunload | 602 event.target._opener = findPageAndFrame(null, event.message.re
ferrer); |
554 // only when reloading the page or following links, but not when | |
555 // you enter a new URL in the address bar. | |
556 if (!isPrerendered) | |
557 replacePage(page); | |
558 | 603 |
559 ext.pages.onLoading._dispatch(page); | 604 if (page.url != "about:blank") |
| 605 event.target._popupLoaded = true; |
| 606 |
| 607 ext.pages.onPopup._dispatch(page, event.target._opener); |
| 608 } |
| 609 |
| 610 if (event.target.browserWindow) |
| 611 { |
| 612 pages[pageId] = page; |
| 613 |
| 614 // when a new page is shown, forget the previous page associated |
| 615 // with its tab, and reset the toolbar item if necessary. |
| 616 // Note that it wouldn't be sufficient to do that when the old |
| 617 // page is unloading, because Safari dispatches window.onunload |
| 618 // only when reloading the page or following links, but not when |
| 619 // you enter a new URL in the address bar. |
| 620 if (!isPrerendered) |
| 621 replacePage(page); |
| 622 |
| 623 ext.pages.onLoading._dispatch(page); |
| 624 } |
560 } | 625 } |
561 else | 626 else |
562 { | 627 { |
563 var page; | 628 var parent = findPageAndFrame(event.target, event.message.referrer
); |
564 var parentFrame; | |
565 | 629 |
566 var lastPageId; | 630 pageId = parent.page._id; |
567 var lastPage; | 631 frameId = parent.page._frames.length; |
568 var lastPageTopLevelFrame; | |
569 | 632 |
570 // find the parent frame and its page for this sub frame, | 633 parent.page._frames.push({ |
571 // by matching its referrer with the URL of frames previously | |
572 // loaded in the same tab. If there is more than one match, | |
573 // the most recent loaded page and frame is preferred. | |
574 for (var curPageId in pages) | |
575 { | |
576 var curPage = pages[curPageId]; | |
577 if (curPage._tab != event.target) | |
578 continue; | |
579 | |
580 for (var i = 0; i < curPage._frames.length; i++) | |
581 { | |
582 var curFrame = curPage._frames[i]; | |
583 | |
584 if (curFrame.url == event.message.referrer) | |
585 { | |
586 pageId = curPageId; | |
587 page = curPage; | |
588 parentFrame = curFrame; | |
589 } | |
590 | |
591 if (i == 0) | |
592 { | |
593 lastPageId = curPageId; | |
594 lastPage = curPage; | |
595 lastPageTopLevelFrame = curFrame; | |
596 } | |
597 } | |
598 } | |
599 | |
600 // if we can't find the parent frame and its page, fall back to | |
601 // the page most recently loaded in the tab and its top level fram
e | |
602 if (!page) | |
603 { | |
604 pageId = lastPageId; | |
605 page = lastPage; | |
606 parentFrame = lastPageTopLevelFrame; | |
607 } | |
608 | |
609 frameId = page._frames.length; | |
610 page._frames.push({ | |
611 url: event.message.url, | 634 url: event.message.url, |
612 parent: parentFrame | 635 parent: parent.frame |
613 }); | 636 }); |
614 } | 637 } |
615 | 638 |
616 event.message = {pageId: pageId, frameId: frameId}; | 639 event.message = {pageId: pageId, frameId: frameId}; |
617 break; | 640 break; |
618 case "webRequest": | 641 case "webRequest": |
619 var page = pages[event.message.pageId]; | 642 var page = pages[event.message.pageId]; |
620 | 643 |
621 event.message = ext.webRequest.onBeforeRequest._dispatch( | 644 event.message = ext.webRequest.onBeforeRequest._dispatch( |
622 event.message.url, | 645 event.message.url, |
(...skipping 28 matching lines...) Expand all Loading... |
651 replacePage(page); | 674 replacePage(page); |
652 break; | 675 break; |
653 } | 676 } |
654 }); | 677 }); |
655 | 678 |
656 | 679 |
657 /* Storage */ | 680 /* Storage */ |
658 | 681 |
659 ext.storage = safari.extension.settings; | 682 ext.storage = safari.extension.settings; |
660 })(); | 683 })(); |
OLD | NEW |