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, 2:03 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 isPreloadedPage = function(message, tab)
21 {
22 // the message was sent by a preloaded page if document.hidden was set, desp ite the tab is visible
23 return message.isDocumentHidden && tab.browserWindow.visible && tab.browserW indow.activeTab == tab
24 };
25
26
20 /* Events */ 27 /* Events */
21 28
22 var TabEventTarget = function() 29 var TabEventTarget = function()
23 { 30 {
24 WrappedEventTarget.apply(this, arguments); 31 WrappedEventTarget.apply(this, arguments);
25 }; 32 };
26 TabEventTarget.prototype = { 33 TabEventTarget.prototype = {
27 __proto__: WrappedEventTarget.prototype, 34 __proto__: WrappedEventTarget.prototype,
28 _wrapListener: function(listener) 35 _wrapListener: function(listener)
29 { 36 {
30 return function(event) 37 return function(event)
31 { 38 {
32 if (event.target instanceof SafariBrowserTab) 39 if (event.target instanceof SafariBrowserTab)
33 listener(new Tab(event.target)); 40 listener(new Tab(event.target));
34 }; 41 };
35 } 42 }
36 }; 43 };
37 44
38 var LoadingTabEventTarget = function(target) 45 var LoadingTabEventTarget = function(target)
39 { 46 {
40 WrappedEventTarget.call(this, target, "message", false); 47 WrappedEventTarget.call(this, target, "message", false);
48 this._preloadedTabs = new TabMap();
41 }; 49 };
42 LoadingTabEventTarget.prototype = { 50 LoadingTabEventTarget.prototype = {
43 __proto__: WrappedEventTarget.prototype, 51 __proto__: WrappedEventTarget.prototype,
44 _wrapListener: function(listener) 52 _wrapListener: function(listener)
45 { 53 {
46 return function (event) 54 return function (event)
47 { 55 {
48 if (event.name == "loading") 56 switch (event.name)
49 listener(new Tab(event.target)); 57 {
50 }; 58 case "loading":
59 var tab = new Tab(event.target);
60
61 // when the "loading" message was sent form a preloaded
Wladimir Palant 2014/01/24 14:11:34 form => from
62 // page in Safari 7.0, we have to wait until the page is
63 // shown, before calling the listener. The high-level code
64 // doesn't know anything about preloaded pages and expects
65 // all events to be related to the current visible page.
66 if (isPreloadedPage(event.message, event.target))
67 this._preloadedTabs.set(tab, null);
68 else
69 {
70 this._preloadedTabs.delete(tab);
71 listener(tab);
72 }
73
74 break;
75 case "show":
76 var tab = new Tab(event.target);
77
78 if (this._preloadedTabs.has(tab))
79 {
80 this._preloadedTabs.delete(tab);
Wladimir Palant 2014/01/24 14:11:34 What if a preloaded page is simply discarded? Won'
Sebastian Noack 2014/01/24 14:17:49 Just temporarily until another page is loaded in t
81 listener(tab);
82 }
83 }
84 }.bind(this);
51 } 85 }
52 }; 86 };
53 87
54 var BackgroundMessageEventTarget = function() 88 var BackgroundMessageEventTarget = function()
55 { 89 {
56 MessageEventTarget.call(this, safari.application); 90 MessageEventTarget.call(this, safari.application);
57 }; 91 };
58 BackgroundMessageEventTarget.prototype = { 92 BackgroundMessageEventTarget.prototype = {
59 __proto__: MessageEventTarget.prototype, 93 __proto__: MessageEventTarget.prototype,
60 _getResponseDispatcher: function(event) 94 _getResponseDispatcher: function(event)
61 { 95 {
62 return event.target.page; 96 return event.target.page;
63 }, 97 },
64 _getSenderDetails: function(event) 98 _getSenderDetails: function(event)
65 { 99 {
66 return { 100 return {
67 tab: new Tab(event.target), 101 tab: new Tab(event.target),
68 frame: new Frame( 102 frame: new Frame(
69 event.message.documentUrl, 103 event.message.documentUrl,
70 event.message.isTopLevel, 104 event.message.isTopLevel,
71 event.target 105 event.target
72 ) 106 )
73 }; 107 };
108 },
109 _ignoreIf: function(event)
110 {
111 // when receiving a message from a preloaded page in Safari 7.0, we
112 // have to defer procesing of that message, until the page is shown.
113 // The high-level code doesn't know anything about preloaded pages
114 // and expects all message to be sent from the current visible page.
115 if (isPreloadedPage(event.message, event.target))
116 {
117 event.target.page.dispatchMessage("response", {
118 requestId: event.message.requestId,
119 deferred: true
120 });
121 return true;
122 }
123
124 return false;
74 } 125 }
75 }; 126 };
76 127
77 128
78 /* Tabs */ 129 /* Tabs */
79 130
80 Tab = function(tab) 131 Tab = function(tab)
81 { 132 {
82 this._tab = tab; 133 this._tab = tab;
83 134
(...skipping 13 matching lines...) Expand all
97 { 148 {
98 this._tab.close(); 149 this._tab.close();
99 }, 150 },
100 activate: function() 151 activate: function()
101 { 152 {
102 this._tab.activate(); 153 this._tab.activate();
103 }, 154 },
104 sendMessage: function(message, responseCallback) 155 sendMessage: function(message, responseCallback)
105 { 156 {
106 _sendMessage( 157 _sendMessage(
107 message, responseCallback, 158 // message payload
108 this._tab.page, this._tab 159 message,
160 // response callback
161 responseCallback && function(response) { responseCallback(response.paylo ad); },
162 // message dispatcher
163 this._tab.page,
164 // response event target
165 this._tab,
166 // extra data
167 {
168 isTabVisible: this._tab.browserWindow.visible &&
169 this._tab.browserWindow.activeTab == this._tab
170 }
109 ); 171 );
110 } 172 }
111 }; 173 };
112 174
113 TabMap = function(deleteOnPageUnload) 175 TabMap = function(deleteOnPageUnload)
114 { 176 {
115 this._data = []; 177 this._data = [];
116 this._deleteOnPageUnload = deleteOnPageUnload; 178 this._deleteOnPageUnload = deleteOnPageUnload;
117 179
118 this.delete = this.delete.bind(this); 180 this.delete = this.delete.bind(this);
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 629
568 630
569 /* Web request blocking */ 631 /* Web request blocking */
570 632
571 ext.webRequest = { 633 ext.webRequest = {
572 onBeforeRequest: { 634 onBeforeRequest: {
573 _listeners: [], 635 _listeners: [],
574 636
575 _handleMessage: function(message, rawTab) 637 _handleMessage: function(message, rawTab)
576 { 638 {
639 // we have to defer loading of resources on preloaded pages
640 // in Safari 7.0, until the page is shown. The high-level code
641 // doesn't know anything about preloaded pages and expects all
642 // web requests to be related to the current visible page.
643 if (isPreloadedPage(message, rawTab))
644 return "deferred";
645
577 var tab = new Tab(rawTab); 646 var tab = new Tab(rawTab);
578 var frame = new Frame(message.documentUrl, message.isTopLevel, rawTab); 647 var frame = new Frame(message.documentUrl, message.isTopLevel, rawTab);
579 648
580 for (var i = 0; i < this._listeners.length; i++) 649 for (var i = 0; i < this._listeners.length; i++)
581 { 650 {
582 if (this._listeners[i](message.url, message.type, tab, frame) === fals e) 651 if (this._listeners[i](message.url, message.type, tab, frame) === fals e)
583 return false; 652 return "blocked";
584 } 653 }
585 654
586 return true; 655 return "ok";
587 }, 656 },
588 addListener: function(listener) 657 addListener: function(listener)
589 { 658 {
590 this._listeners.push(listener); 659 this._listeners.push(listener);
591 }, 660 },
592 removeListener: function(listener) 661 removeListener: function(listener)
593 { 662 {
594 var idx = this._listeners.indexOf(listener); 663 var idx = this._listeners.indexOf(listener);
595 if (idx != -1) 664 if (idx != -1)
596 this._listeners.splice(idx, 1); 665 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++) 775 for (var i = 0; i < contextMenuItems.length; i++)
707 { 776 {
708 if (contextMenuItems[i].id == event.command) 777 if (contextMenuItems[i].id == event.command)
709 { 778 {
710 contextMenuItems[i].onclick(event.userInfo.srcUrl, new Tab(safari.applic ation.activeBrowserWindow.activeTab)); 779 contextMenuItems[i].onclick(event.userInfo.srcUrl, new Tab(safari.applic ation.activeBrowserWindow.activeTab));
711 break; 780 break;
712 } 781 }
713 } 782 }
714 }, false); 783 }, false);
715 })(); 784 })();
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