Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: safari/ext/background.js

Issue 5092502491103232: Deal with preloadded pages in Safari 7.0 (Closed)
Patch Set: Created Jan. 23, 2014, 3:21 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | safari/ext/common.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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-2013 Eyeo GmbH 3 * Copyright (C) 2006-2013 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 var isTabVisible = function(tab)
21 {
22 return tab.browserWindow.visible && tab.browserWindow.activeTab == tab;
23 };
24
25 var sentByPreloadedPage = function(message, tab)
26 {
27 // the message was sent by a preloaded page if document.hidden was set,
28 // despite the tab is visible
29 return message.isDocumentHidden && isTabVisible(tab);
30 };
31
32
20 /* Events */ 33 /* Events */
21 34
22 var TabEventTarget = function() 35 var TabEventTarget = function()
23 { 36 {
24 WrappedEventTarget.apply(this, arguments); 37 WrappedEventTarget.apply(this, arguments);
25 }; 38 };
26 TabEventTarget.prototype = { 39 TabEventTarget.prototype = {
27 __proto__: WrappedEventTarget.prototype, 40 __proto__: WrappedEventTarget.prototype,
28 _wrapListener: function(listener) 41 _wrapListener: function(listener)
29 { 42 {
30 return function(event) 43 return function(event)
31 { 44 {
32 if (event.target instanceof SafariBrowserTab) 45 if (event.target instanceof SafariBrowserTab)
33 listener(new Tab(event.target)); 46 listener(new Tab(event.target));
34 }; 47 };
35 } 48 }
36 }; 49 };
37 50
38 var LoadingTabEventTarget = function(target) 51 var LoadingTabEventTarget = function(target)
39 { 52 {
40 WrappedEventTarget.call(this, target, "message", false); 53 WrappedEventTarget.call(this, target, "message", false);
54 this._preloadedTabs = new TabMap();
41 }; 55 };
42 LoadingTabEventTarget.prototype = { 56 LoadingTabEventTarget.prototype = {
43 __proto__: WrappedEventTarget.prototype, 57 __proto__: WrappedEventTarget.prototype,
44 _wrapListener: function(listener) 58 _wrapListener: function(listener)
45 { 59 {
46 return function (event) 60 return function (event)
47 { 61 {
48 if (event.name == "loading") 62 switch (event.name)
49 listener(new Tab(event.target)); 63 {
50 }; 64 case "loading":
65 var tab = new Tab(event.target);
66
67 // when the "loading" message was sent form a preloaded
68 // page in Safari 7.0, we have to wait until the page is
69 // shown, before calling the listener. The high-level code
70 // doesn't know anything about preloaded pages and expects
71 // all events to be related to the current visible page.
72 if (sentByPreloadedPage(event.message, event.target))
73 this._preloadedTabs.set(tab, null);
74 else
75 {
76 this._preloadedTabs.delete(tab);
77 listener(tab);
78 }
79
80 break;
81 case "show":
82 var tab = new Tab(event.target);
83
84 if (this._preloadedTabs.has(tab))
85 {
86 this._preloadedTabs.delete(tab);
87 listener(tab);
88 }
89 }
90 }.bind(this);
51 } 91 }
52 }; 92 };
53 93
54 var BackgroundMessageEventTarget = function() 94 var BackgroundMessageEventTarget = function()
55 { 95 {
56 MessageEventTarget.call(this, safari.application); 96 MessageEventTarget.call(this, safari.application);
57 }; 97 };
58 BackgroundMessageEventTarget.prototype = { 98 BackgroundMessageEventTarget.prototype = {
59 __proto__: MessageEventTarget.prototype, 99 __proto__: MessageEventTarget.prototype,
60 _getResponseDispatcher: function(event) 100 _getResponseDispatcher: function(event)
61 { 101 {
62 return event.target.page; 102 return event.target.page;
63 }, 103 },
64 _getSenderDetails: function(event) 104 _getSenderDetails: function(event)
65 { 105 {
66 return { 106 return {
67 tab: new Tab(event.target), 107 tab: new Tab(event.target),
68 frame: new Frame( 108 frame: new Frame(
69 event.message.documentUrl, 109 event.message.documentUrl,
70 event.message.isTopLevel, 110 event.message.isTopLevel,
71 event.target 111 event.target
72 ) 112 )
73 }; 113 };
114 },
115 _ignoreIf: function(event)
116 {
117 // when receiving a message from a preloaded page in Safari 7.0, we
118 // have to defer procesing of that message, until the page is shown.
119 // The high-level code doesn't know anything about preloaded pages
120 // and expects all message to be sent from the current visible page.
121 if (sentByPreloadedPage(event.message, event.target))
122 {
123 event.target.page.dispatchMessage("response", {
124 requestId: event.message.requestId,
125 deferred: true
126 });
127 return true;
128 }
129
130 return false;
74 } 131 }
75 }; 132 };
76 133
77 134
78 /* Tabs */ 135 /* Tabs */
79 136
80 Tab = function(tab) 137 Tab = function(tab)
81 { 138 {
82 this._tab = tab; 139 this._tab = tab;
83 140
(...skipping 13 matching lines...) Expand all
97 { 154 {
98 this._tab.close(); 155 this._tab.close();
99 }, 156 },
100 activate: function() 157 activate: function()
101 { 158 {
102 this._tab.activate(); 159 this._tab.activate();
103 }, 160 },
104 sendMessage: function(message, responseCallback) 161 sendMessage: function(message, responseCallback)
105 { 162 {
106 _sendMessage( 163 _sendMessage(
107 message, responseCallback, 164 // message payload
108 this._tab.page, this._tab 165 message,
166 // response callback
167 responseCallback && function(response) { responseCallback(response.paylo ad); },
168 // message dispatcher
169 this._tab.page,
170 // response event target
171 this._tab,
172 // extra data
173 {
174 isTabVisible: isTabVisible(this._tab)
175 }
109 ); 176 );
110 } 177 }
111 }; 178 };
112 179
113 TabMap = function(deleteOnPageUnload) 180 TabMap = function(deleteOnPageUnload)
114 { 181 {
115 this._data = []; 182 this._data = [];
116 this._deleteOnPageUnload = deleteOnPageUnload; 183 this._deleteOnPageUnload = deleteOnPageUnload;
117 184
118 this.delete = this.delete.bind(this); 185 this.delete = this.delete.bind(this);
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 634
568 635
569 /* Web request blocking */ 636 /* Web request blocking */
570 637
571 ext.webRequest = { 638 ext.webRequest = {
572 onBeforeRequest: { 639 onBeforeRequest: {
573 _listeners: [], 640 _listeners: [],
574 641
575 _handleMessage: function(message, rawTab) 642 _handleMessage: function(message, rawTab)
576 { 643 {
644 // we have to defer loading of resources on preloaded pages
645 // in Safari 7.0, until the page is shown. The high-level code
646 // doesn't know anything about preloaded pages and expects all
647 // web requests to be related to the current visible page.
648 if (sentByPreloadedPage(message, rawTab))
649 return "deferred";
650
577 var tab = new Tab(rawTab); 651 var tab = new Tab(rawTab);
578 var frame = new Frame(message.documentUrl, message.isTopLevel, rawTab); 652 var frame = new Frame(message.documentUrl, message.isTopLevel, rawTab);
579 653
580 for (var i = 0; i < this._listeners.length; i++) 654 for (var i = 0; i < this._listeners.length; i++)
581 { 655 {
582 if (this._listeners[i](message.url, message.type, tab, frame) === fals e) 656 if (this._listeners[i](message.url, message.type, tab, frame) === fals e)
583 return false; 657 return "blocked";
584 } 658 }
585 659
586 return true; 660 return "ok";
587 }, 661 },
588 addListener: function(listener) 662 addListener: function(listener)
589 { 663 {
590 this._listeners.push(listener); 664 this._listeners.push(listener);
591 }, 665 },
592 removeListener: function(listener) 666 removeListener: function(listener)
593 { 667 {
594 var idx = this._listeners.indexOf(listener); 668 var idx = this._listeners.indexOf(listener);
595 if (idx != -1) 669 if (idx != -1)
596 this._listeners.splice(idx, 1); 670 this._listeners.splice(idx, 1);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 for (var i = 0; i < contextMenuItems.length; i++) 780 for (var i = 0; i < contextMenuItems.length; i++)
707 { 781 {
708 if (contextMenuItems[i].id == event.command) 782 if (contextMenuItems[i].id == event.command)
709 { 783 {
710 contextMenuItems[i].onclick(event.userInfo.srcUrl, new Tab(safari.applic ation.activeBrowserWindow.activeTab)); 784 contextMenuItems[i].onclick(event.userInfo.srcUrl, new Tab(safari.applic ation.activeBrowserWindow.activeTab));
711 break; 785 break;
712 } 786 }
713 } 787 }
714 }, false); 788 }, false);
715 })(); 789 })();
OLDNEW
« no previous file with comments | « no previous file | safari/ext/common.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld