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

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

Issue 29372398: Issue 4804 - Avoid trashing pagemaps prematurely (Closed)
Patch Set: Rebased Created Jan. 23, 2017, 10:19 a.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 | lib/whitelisting.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 <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
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 if (!frames) 111 if (!frames)
112 frames = framesOfTabs[tabId] = Object.create(null); 112 frames = framesOfTabs[tabId] = Object.create(null);
113 113
114 let frame = frames[frameId]; 114 let frame = frames[frameId];
115 if (!frame) 115 if (!frame)
116 frame = frames[frameId] = {}; 116 frame = frames[frameId] = {};
117 117
118 return frame; 118 return frame;
119 } 119 }
120 120
121 chrome.webNavigation.onBeforeNavigate.addListener(details => 121 function updatePageFrameStructure(frameId, tabId, url)
122 {
123 // Capture parent frame here because onCommitted doesn't get this info.
124 let frame = createFrame(details.tabId, details.frameId);
125 frame.parent = framesOfTabs[details.tabId][details.parentFrameId] || null;
126 });
127
128 let eagerlyUpdatedPages = new ext.PageMap();
129
130 ext._updatePageFrameStructure = (frameId, tabId, url, eager) =>
131 { 122 {
132 if (frameId == 0) 123 if (frameId == 0)
133 { 124 {
134 let page = new Page({id: tabId, url: url}); 125 let page = new Page({id: tabId, url: url});
135 126
136 if (eagerlyUpdatedPages.get(page) != url) 127 chrome.tabs.get(tabId, () =>
137 { 128 {
138 ext._removeFromAllPageMaps(tabId); 129 // If the tab is prerendered, chrome.tabs.get() sets
139 130 // chrome.runtime.lastError and we have to dispatch the onLoading event,
140 // When a sitekey header is received we must immediately update the page 131 // since the onUpdated event isn't dispatched for prerendered tabs.
141 // structure in order to record and use the key. We want to avoid 132 // However, we have to keep relying on the unUpdated event for tabs that
142 // trashing the page structure if the onCommitted event is then fired 133 // are already visible. Otherwise browser action changes get overridden
143 // for the page. 134 // when Chrome automatically resets them on navigation.
144 if (eager) 135 if (chrome.runtime.lastError)
145 eagerlyUpdatedPages.set(page, url); 136 ext.pages.onLoading._dispatch(page);
146 137 });
147 chrome.tabs.get(tabId, () =>
148 {
149 // If the tab is prerendered, chrome.tabs.get() sets
150 // chrome.runtime.lastError and we have to dispatch the onLoading even t,
151 // since the onUpdated event isn't dispatched for prerendered tabs.
152 // However, we have to keep relying on the unUpdated event for tabs th at
153 // are already visible. Otherwise browser action changes get overridde n
154 // when Chrome automatically resets them on navigation.
155 if (chrome.runtime.lastError)
156 ext.pages.onLoading._dispatch(page);
157 });
158 }
159 } 138 }
160 139
161 // Update frame URL in frame structure 140 // Update frame URL in frame structure
162 let frame = createFrame(tabId, frameId); 141 let frame = createFrame(tabId, frameId);
163 frame.url = new URL(url); 142 frame.url = new URL(url);
164 }; 143 };
165 144
166 chrome.webNavigation.onCommitted.addListener(details => 145 chrome.webNavigation.onCommitted.addListener(details =>
167 { 146 {
168 ext._updatePageFrameStructure(details.frameId, details.tabId, details.url); 147 updatePageFrameStructure(details.frameId, details.tabId, details.url);
148 });
149
150 chrome.webRequest.onHeadersReceived.addListener(details =>
151 {
152 // Ideally we would only need the above chrome.webNavigation.onCommitted
153 // listener to update the page state but unfortunately pages can make web
154 // requests before their onCommitted event fires[1].
155 // So for HTTP/S requests we can also use onHeadersReceived, being careful
156 // to ignore responses which won't directly result in a navigation, for
157 // example redirections.
158 // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=665843
159 /**** FIXME - Check Chromium code to ensure we got these right! ****/
160 if (!(details.statusCode > 299 && details.statusCode < 400 &&
161 details.statusCode != 304) || details.statusCode == 204)
162 updatePageFrameStructure(details.frameId, details.tabId, details.url);
163 }, {types: ["main_frame", "sub_frame"], urls: ["http://*/*", "https://*/*"]});
164
165 chrome.webNavigation.onBeforeNavigate.addListener(details =>
166 {
167 // Capture parent frame here because onCommitted doesn't get this info.
168 let frame = createFrame(details.tabId, details.frameId);
169 frame.parent = framesOfTabs[details.tabId][details.parentFrameId] || null;
170
171 // Since we can only listen for HTTP/S requests with onHeadersReceived we
172 // must update the page structure here for other navigations which might
173 // result in further requests.
174 let url = new URL(details.url);
175 if (url.protocol == "about:" || url.protocol == "data:")
176 updatePageFrameStructure(details.frameId, details.tabId, details.url);
169 }); 177 });
170 178
171 function forgetTab(tabId) 179 function forgetTab(tabId)
172 { 180 {
173 ext.pages.onRemoved._dispatch(tabId); 181 ext.pages.onRemoved._dispatch(tabId);
174 182
175 ext._removeFromAllPageMaps(tabId); 183 ext._removeFromAllPageMaps(tabId);
176 delete framesOfTabs[tabId]; 184 delete framesOfTabs[tabId];
177 } 185 }
178 186
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 chrome.browserAction.setBadgeBackgroundColor({ 235 chrome.browserAction.setBadgeBackgroundColor({
228 tabId: this._tabId, 236 tabId: this._tabId,
229 color: this._changes.badgeColor 237 color: this._changes.badgeColor
230 }); 238 });
231 } 239 }
232 240
233 this._changes = null; 241 this._changes = null;
234 }, 242 },
235 _queueChanges() 243 _queueChanges()
236 { 244 {
237 chrome.tabs.get(this._tabId, function() 245 chrome.tabs.get(this._tabId, () =>
238 { 246 {
239 // If the tab is prerendered, chrome.tabs.get() sets 247 // If the tab is prerendered, chrome.tabs.get() sets
240 // chrome.runtime.lastError and we have to delay our changes 248 // chrome.runtime.lastError and we have to delay our changes
241 // until the currently visible tab is replaced with the 249 // until the currently visible tab is replaced with the
242 // prerendered tab. Otherwise chrome.browserAction.set* fails. 250 // prerendered tab. Otherwise chrome.browserAction.set* fails.
243 if (chrome.runtime.lastError) 251 if (chrome.runtime.lastError)
244 { 252 {
245 let onReplaced = (addedTabId, removedTabId) => 253 let onReplaced = (addedTabId, removedTabId) =>
246 { 254 {
247 if (addedTabId == this._tabId) 255 if (addedTabId == this._tabId)
248 { 256 {
249 chrome.tabs.onReplaced.removeListener(onReplaced); 257 chrome.tabs.onReplaced.removeListener(onReplaced);
250 this._applyChanges(); 258 this._applyChanges();
251 } 259 }
252 }; 260 };
253 chrome.tabs.onReplaced.addListener(onReplaced); 261 chrome.tabs.onReplaced.addListener(onReplaced);
254 } 262 }
255 else 263 else
256 { 264 {
257 this._applyChanges(); 265 this._applyChanges();
258 } 266 }
259 }.bind(this)); 267 });
260 }, 268 },
261 _addChange(name, value) 269 _addChange(name, value)
262 { 270 {
263 if (!this._changes) 271 if (!this._changes)
264 { 272 {
265 this._changes = {}; 273 this._changes = {};
266 this._queueChanges(); 274 this._queueChanges();
267 } 275 }
268 276
269 this._changes[name] = value; 277 this._changes[name] = value;
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 ext.windows = { 609 ext.windows = {
602 create(createData, callback) 610 create(createData, callback)
603 { 611 {
604 chrome.windows.create(createData, createdWindow => 612 chrome.windows.create(createData, createdWindow =>
605 { 613 {
606 afterTabLoaded(callback)(createdWindow.tabs[0]); 614 afterTabLoaded(callback)(createdWindow.tabs[0]);
607 }); 615 });
608 } 616 }
609 }; 617 };
610 } 618 }
OLDNEW
« no previous file with comments | « no previous file | lib/whitelisting.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld