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

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

Issue 29371763: Issue 4795 - Use modern JavaScript syntax (Closed)
Patch Set: Define and destructure backgroundPage more consistently, fix minor whitespace errors Created Jan. 18, 2017, 7:34 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
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
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 "use strict";
19
19 { 20 {
20 /* Pages */ 21 /* Pages */
21 22
22 var Page = ext.Page = function(tab) 23 let Page = ext.Page = function(tab)
23 { 24 {
24 this.id = tab.id; 25 this.id = tab.id;
25 this._url = tab.url && new URL(tab.url); 26 this._url = tab.url && new URL(tab.url);
26 27
27 this.browserAction = new BrowserAction(tab.id); 28 this.browserAction = new BrowserAction(tab.id);
28 this.contextMenus = new ContextMenus(this); 29 this.contextMenus = new ContextMenus(this);
29 }; 30 };
30 Page.prototype = { 31 Page.prototype = {
31 get url() 32 get url()
32 { 33 {
33 // usually our Page objects are created from Chrome's Tab objects, which 34 // usually our Page objects are created from Chrome's Tab objects, which
34 // provide the url. So we can return the url given in the constructor. 35 // provide the url. So we can return the url given in the constructor.
35 if (this._url) 36 if (this._url)
36 return this._url; 37 return this._url;
37 38
38 // but sometimes we only have the tab id when we create a Page object. 39 // but sometimes we only have the tab id when we create a Page object.
39 // In that case we get the url from top frame of the tab, recorded by 40 // In that case we get the url from top frame of the tab, recorded by
40 // the onBeforeRequest handler. 41 // the onBeforeRequest handler.
41 var frames = framesOfTabs[this.id]; 42 let frames = framesOfTabs[this.id];
42 if (frames) 43 if (frames)
43 { 44 {
44 var frame = frames[0]; 45 let frame = frames[0];
45 if (frame) 46 if (frame)
46 return frame.url; 47 return frame.url;
47 } 48 }
48 }, 49 },
49 sendMessage: function(message, responseCallback) 50 sendMessage(message, responseCallback)
50 { 51 {
51 chrome.tabs.sendMessage(this.id, message, responseCallback); 52 chrome.tabs.sendMessage(this.id, message, responseCallback);
52 } 53 }
53 }; 54 };
54 55
55 ext.getPage = function(id) 56 ext.getPage = id => new Page({id: parseInt(id, 10)});
56 {
57 return new Page({id: parseInt(id, 10)});
58 };
59 57
60 function afterTabLoaded(callback) 58 function afterTabLoaded(callback)
61 { 59 {
62 return function(openedTab) 60 return openedTab =>
63 { 61 {
64 var onUpdated = function(tabId, changeInfo, tab) 62 let onUpdated = (tabId, changeInfo, tab) =>
65 { 63 {
66 if (tabId == openedTab.id && changeInfo.status == "complete") 64 if (tabId == openedTab.id && changeInfo.status == "complete")
67 { 65 {
68 chrome.tabs.onUpdated.removeListener(onUpdated); 66 chrome.tabs.onUpdated.removeListener(onUpdated);
69 callback(new Page(openedTab)); 67 callback(new Page(openedTab));
70 } 68 }
71 }; 69 };
72 chrome.tabs.onUpdated.addListener(onUpdated); 70 chrome.tabs.onUpdated.addListener(onUpdated);
73 }; 71 };
74 } 72 }
75 73
76 ext.pages = { 74 ext.pages = {
77 open: function(url, callback) 75 open(url, callback)
78 { 76 {
79 chrome.tabs.create({url: url}, callback && afterTabLoaded(callback)); 77 chrome.tabs.create({url: url}, callback && afterTabLoaded(callback));
80 }, 78 },
81 query: function(info, callback) 79 query(info, callback)
82 { 80 {
83 var rawInfo = {}; 81 let rawInfo = {};
84 for (var property in info) 82 for (let property in info)
85 { 83 {
86 switch (property) 84 switch (property)
87 { 85 {
88 case "active": 86 case "active":
89 case "lastFocusedWindow": 87 case "lastFocusedWindow":
90 rawInfo[property] = info[property]; 88 rawInfo[property] = info[property];
91 } 89 }
92 } 90 }
93 91
94 chrome.tabs.query(rawInfo, function(tabs) 92 chrome.tabs.query(rawInfo, tabs =>
95 { 93 {
96 callback(tabs.map(function(tab) 94 callback(tabs.map(tab => new Page(tab)));
97 {
98 return new Page(tab);
99 }));
100 }); 95 });
101 }, 96 },
102 onLoading: new ext._EventTarget(), 97 onLoading: new ext._EventTarget(),
103 onActivated: new ext._EventTarget(), 98 onActivated: new ext._EventTarget(),
104 onRemoved: new ext._EventTarget() 99 onRemoved: new ext._EventTarget()
105 }; 100 };
106 101
107 chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) 102 chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) =>
108 { 103 {
109 if (changeInfo.status == "loading") 104 if (changeInfo.status == "loading")
110 ext.pages.onLoading._dispatch(new Page(tab)); 105 ext.pages.onLoading._dispatch(new Page(tab));
111 }); 106 });
112 107
113 function createFrame(tabId, frameId) 108 function createFrame(tabId, frameId)
114 { 109 {
115 var frames = framesOfTabs[tabId]; 110 let frames = framesOfTabs[tabId];
116 if (!frames) 111 if (!frames)
117 frames = framesOfTabs[tabId] = Object.create(null); 112 frames = framesOfTabs[tabId] = Object.create(null);
118 113
119 var frame = frames[frameId]; 114 let frame = frames[frameId];
120 if (!frame) 115 if (!frame)
121 frame = frames[frameId] = {}; 116 frame = frames[frameId] = {};
122 117
123 return frame; 118 return frame;
124 } 119 }
125 120
126 chrome.webNavigation.onBeforeNavigate.addListener(function(details) 121 chrome.webNavigation.onBeforeNavigate.addListener(details =>
127 { 122 {
128 // Capture parent frame here because onCommitted doesn't get this info. 123 // Capture parent frame here because onCommitted doesn't get this info.
129 var frame = createFrame(details.tabId, details.frameId); 124 let frame = createFrame(details.tabId, details.frameId);
130 frame.parent = framesOfTabs[details.tabId][details.parentFrameId] || null; 125 frame.parent = framesOfTabs[details.tabId][details.parentFrameId] || null;
131 }); 126 });
132 127
133 var eagerlyUpdatedPages = new ext.PageMap(); 128 let eagerlyUpdatedPages = new ext.PageMap();
134 129
135 ext._updatePageFrameStructure = function(frameId, tabId, url, eager) 130 ext._updatePageFrameStructure = (frameId, tabId, url, eager) =>
136 { 131 {
137 if (frameId == 0) 132 if (frameId == 0)
138 { 133 {
139 let page = new Page({id: tabId, url: url}); 134 let page = new Page({id: tabId, url: url});
140 135
141 if (eagerlyUpdatedPages.get(page) != url) 136 if (eagerlyUpdatedPages.get(page) != url)
142 { 137 {
143 ext._removeFromAllPageMaps(tabId); 138 ext._removeFromAllPageMaps(tabId);
144 139
145 // When a sitekey header is received we must immediately update the page 140 // When a sitekey header is received we must immediately update the page
146 // structure in order to record and use the key. We want to avoid 141 // structure in order to record and use the key. We want to avoid
147 // trashing the page structure if the onCommitted event is then fired 142 // trashing the page structure if the onCommitted event is then fired
148 // for the page. 143 // for the page.
149 if (eager) 144 if (eager)
150 eagerlyUpdatedPages.set(page, url); 145 eagerlyUpdatedPages.set(page, url);
151 146
152 chrome.tabs.get(tabId, function() 147 chrome.tabs.get(tabId, () =>
153 { 148 {
154 // If the tab is prerendered, chrome.tabs.get() sets 149 // If the tab is prerendered, chrome.tabs.get() sets
155 // chrome.runtime.lastError and we have to dispatch the onLoading even t, 150 // chrome.runtime.lastError and we have to dispatch the onLoading even t,
156 // since the onUpdated event isn't dispatched for prerendered tabs. 151 // since the onUpdated event isn't dispatched for prerendered tabs.
157 // However, we have to keep relying on the unUpdated event for tabs th at 152 // However, we have to keep relying on the unUpdated event for tabs th at
158 // are already visible. Otherwise browser action changes get overridde n 153 // are already visible. Otherwise browser action changes get overridde n
159 // when Chrome automatically resets them on navigation. 154 // when Chrome automatically resets them on navigation.
160 if (chrome.runtime.lastError) 155 if (chrome.runtime.lastError)
161 ext.pages.onLoading._dispatch(page); 156 ext.pages.onLoading._dispatch(page);
162 }); 157 });
163 } 158 }
164 } 159 }
165 160
166 // Update frame URL in frame structure 161 // Update frame URL in frame structure
167 var frame = createFrame(tabId, frameId); 162 let frame = createFrame(tabId, frameId);
168 frame.url = new URL(url); 163 frame.url = new URL(url);
169 }; 164 };
170 165
171 chrome.webNavigation.onCommitted.addListener(function(details) 166 chrome.webNavigation.onCommitted.addListener(details =>
172 { 167 {
173 ext._updatePageFrameStructure(details.frameId, details.tabId, details.url); 168 ext._updatePageFrameStructure(details.frameId, details.tabId, details.url);
174 }); 169 });
175 170
176 function forgetTab(tabId) 171 function forgetTab(tabId)
177 { 172 {
178 ext.pages.onRemoved._dispatch(tabId); 173 ext.pages.onRemoved._dispatch(tabId);
179 174
180 ext._removeFromAllPageMaps(tabId); 175 ext._removeFromAllPageMaps(tabId);
181 delete framesOfTabs[tabId]; 176 delete framesOfTabs[tabId];
182 } 177 }
183 178
184 chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId) 179 chrome.tabs.onReplaced.addListener((addedTabId, removedTabId) =>
185 { 180 {
186 forgetTab(removedTabId); 181 forgetTab(removedTabId);
187 }); 182 });
188 183
189 chrome.tabs.onRemoved.addListener(forgetTab); 184 chrome.tabs.onRemoved.addListener(forgetTab);
190 185
191 chrome.tabs.onActivated.addListener(function(details) 186 chrome.tabs.onActivated.addListener(details =>
192 { 187 {
193 ext.pages.onActivated._dispatch(new Page({id: details.tabId})); 188 ext.pages.onActivated._dispatch(new Page({id: details.tabId}));
194 }); 189 });
195 190
196 191
197 /* Browser actions */ 192 /* Browser actions */
198 193
199 var BrowserAction = function(tabId) 194 let BrowserAction = function(tabId)
200 { 195 {
201 this._tabId = tabId; 196 this._tabId = tabId;
202 this._changes = null; 197 this._changes = null;
203 }; 198 };
204 BrowserAction.prototype = { 199 BrowserAction.prototype = {
205 _applyChanges: function() 200 _applyChanges()
206 { 201 {
207 if ("iconPath" in this._changes) 202 if ("iconPath" in this._changes)
208 { 203 {
209 chrome.browserAction.setIcon({ 204 chrome.browserAction.setIcon({
210 tabId: this._tabId, 205 tabId: this._tabId,
211 path: { 206 path: {
212 16: this._changes.iconPath.replace("$size", "16"), 207 16: this._changes.iconPath.replace("$size", "16"),
213 19: this._changes.iconPath.replace("$size", "19"), 208 19: this._changes.iconPath.replace("$size", "19"),
214 20: this._changes.iconPath.replace("$size", "20"), 209 20: this._changes.iconPath.replace("$size", "20"),
215 32: this._changes.iconPath.replace("$size", "32"), 210 32: this._changes.iconPath.replace("$size", "32"),
(...skipping 14 matching lines...) Expand all
230 if ("badgeColor" in this._changes) 225 if ("badgeColor" in this._changes)
231 { 226 {
232 chrome.browserAction.setBadgeBackgroundColor({ 227 chrome.browserAction.setBadgeBackgroundColor({
233 tabId: this._tabId, 228 tabId: this._tabId,
234 color: this._changes.badgeColor 229 color: this._changes.badgeColor
235 }); 230 });
236 } 231 }
237 232
238 this._changes = null; 233 this._changes = null;
239 }, 234 },
240 _queueChanges: function() 235 _queueChanges()
241 { 236 {
242 chrome.tabs.get(this._tabId, function() 237 chrome.tabs.get(this._tabId, function()
243 { 238 {
244 // If the tab is prerendered, chrome.tabs.get() sets 239 // If the tab is prerendered, chrome.tabs.get() sets
245 // chrome.runtime.lastError and we have to delay our changes 240 // chrome.runtime.lastError and we have to delay our changes
246 // until the currently visible tab is replaced with the 241 // until the currently visible tab is replaced with the
247 // prerendered tab. Otherwise chrome.browserAction.set* fails. 242 // prerendered tab. Otherwise chrome.browserAction.set* fails.
248 if (chrome.runtime.lastError) 243 if (chrome.runtime.lastError)
249 { 244 {
250 var onReplaced = function(addedTabId, removedTabId) 245 let onReplaced = (addedTabId, removedTabId) =>
251 { 246 {
252 if (addedTabId == this._tabId) 247 if (addedTabId == this._tabId)
253 { 248 {
254 chrome.tabs.onReplaced.removeListener(onReplaced); 249 chrome.tabs.onReplaced.removeListener(onReplaced);
255 this._applyChanges(); 250 this._applyChanges();
256 } 251 }
257 }.bind(this); 252 };
258 chrome.tabs.onReplaced.addListener(onReplaced); 253 chrome.tabs.onReplaced.addListener(onReplaced);
259 } 254 }
260 else 255 else
261 { 256 {
262 this._applyChanges(); 257 this._applyChanges();
263 } 258 }
264 }.bind(this)); 259 }.bind(this));
265 }, 260 },
266 _addChange: function(name, value) 261 _addChange(name, value)
267 { 262 {
268 if (!this._changes) 263 if (!this._changes)
269 { 264 {
270 this._changes = {}; 265 this._changes = {};
271 this._queueChanges(); 266 this._queueChanges();
272 } 267 }
273 268
274 this._changes[name] = value; 269 this._changes[name] = value;
275 }, 270 },
276 setIcon: function(path) 271 setIcon(path)
277 { 272 {
278 this._addChange("iconPath", path); 273 this._addChange("iconPath", path);
279 }, 274 },
280 setBadge: function(badge) 275 setBadge(badge)
281 { 276 {
282 if (!badge) 277 if (!badge)
283 { 278 {
284 this._addChange("badgeText", ""); 279 this._addChange("badgeText", "");
285 } 280 }
286 else 281 else
287 { 282 {
288 if ("number" in badge) 283 if ("number" in badge)
289 this._addChange("badgeText", badge.number.toString()); 284 this._addChange("badgeText", badge.number.toString());
290 285
291 if ("color" in badge) 286 if ("color" in badge)
292 this._addChange("badgeColor", badge.color); 287 this._addChange("badgeColor", badge.color);
293 } 288 }
294 } 289 }
295 }; 290 };
296 291
297 292
298 /* Context menus */ 293 /* Context menus */
299 294
300 var contextMenuItems = new ext.PageMap(); 295 let contextMenuItems = new ext.PageMap();
301 var contextMenuUpdating = false; 296 let contextMenuUpdating = false;
302 297
303 var updateContextMenu = function() 298 let updateContextMenu = () =>
304 { 299 {
305 if (contextMenuUpdating) 300 if (contextMenuUpdating)
306 return; 301 return;
307 302
308 contextMenuUpdating = true; 303 contextMenuUpdating = true;
309 304
310 chrome.tabs.query({active: true, lastFocusedWindow: true}, function(tabs) 305 chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs =>
311 { 306 {
312 chrome.contextMenus.removeAll(function() 307 chrome.contextMenus.removeAll(() =>
313 { 308 {
314 contextMenuUpdating = false; 309 contextMenuUpdating = false;
315 310
316 if (tabs.length == 0) 311 if (tabs.length == 0)
317 return; 312 return;
318 313
319 var items = contextMenuItems.get({id: tabs[0].id}); 314 let items = contextMenuItems.get({id: tabs[0].id});
320 315
321 if (!items) 316 if (!items)
322 return; 317 return;
323 318
324 items.forEach(function(item) 319 items.forEach(item =>
325 { 320 {
326 chrome.contextMenus.create({ 321 chrome.contextMenus.create({
327 title: item.title, 322 title: item.title,
328 contexts: item.contexts, 323 contexts: item.contexts,
329 onclick: function(info, tab) 324 onclick(info, tab)
330 { 325 {
331 item.onclick(new Page(tab)); 326 item.onclick(new Page(tab));
332 } 327 }
333 }); 328 });
334 }); 329 });
335 }); 330 });
336 }); 331 });
337 }; 332 };
338 333
339 var ContextMenus = function(page) 334 let ContextMenus = function(page)
340 { 335 {
341 this._page = page; 336 this._page = page;
342 }; 337 };
343 ContextMenus.prototype = { 338 ContextMenus.prototype = {
344 create: function(item) 339 create(item)
345 { 340 {
346 var items = contextMenuItems.get(this._page); 341 let items = contextMenuItems.get(this._page);
347 if (!items) 342 if (!items)
348 contextMenuItems.set(this._page, items = []); 343 contextMenuItems.set(this._page, items = []);
349 344
350 items.push(item); 345 items.push(item);
351 updateContextMenu(); 346 updateContextMenu();
352 }, 347 },
353 remove: function(item) 348 remove(item)
354 { 349 {
355 let items = contextMenuItems.get(this._page); 350 let items = contextMenuItems.get(this._page);
356 if (items) 351 if (items)
357 { 352 {
358 let index = items.indexOf(item); 353 let index = items.indexOf(item);
359 if (index != -1) 354 if (index != -1)
360 { 355 {
361 items.splice(index, 1); 356 items.splice(index, 1);
362 updateContextMenu(); 357 updateContextMenu();
363 } 358 }
364 } 359 }
365 } 360 }
366 }; 361 };
367 362
368 chrome.tabs.onActivated.addListener(updateContextMenu); 363 chrome.tabs.onActivated.addListener(updateContextMenu);
369 364
370 chrome.windows.onFocusChanged.addListener(function(windowId) 365 chrome.windows.onFocusChanged.addListener(windowId =>
371 { 366 {
372 if (windowId != chrome.windows.WINDOW_ID_NONE) 367 if (windowId != chrome.windows.WINDOW_ID_NONE)
373 updateContextMenu(); 368 updateContextMenu();
374 }); 369 });
375 370
376 371
377 /* Web requests */ 372 /* Web requests */
378 373
379 var framesOfTabs = Object.create(null); 374 let framesOfTabs = Object.create(null);
380 375
381 ext.getFrame = function(tabId, frameId) 376 ext.getFrame = (tabId, frameId) =>
382 { 377 {
383 return (framesOfTabs[tabId] || {})[frameId]; 378 return (framesOfTabs[tabId] || {})[frameId];
384 }; 379 };
385 380
386 var handlerBehaviorChangedQuota = chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANG ED_CALLS_PER_10_MINUTES; 381 let handlerBehaviorChangedQuota = chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANG ED_CALLS_PER_10_MINUTES;
387 382
388 function propagateHandlerBehaviorChange() 383 function propagateHandlerBehaviorChange()
389 { 384 {
390 // Make sure to not call handlerBehaviorChanged() more often than allowed 385 // Make sure to not call handlerBehaviorChanged() more often than allowed
391 // by chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES. 386 // by chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES.
392 // Otherwise Chrome notifies the user that this extension is causing issues. 387 // Otherwise Chrome notifies the user that this extension is causing issues.
393 if (handlerBehaviorChangedQuota > 0) 388 if (handlerBehaviorChangedQuota > 0)
394 { 389 {
395 chrome.webNavigation.onBeforeNavigate.removeListener(propagateHandlerBehav iorChange); 390 chrome.webNavigation.onBeforeNavigate.removeListener(propagateHandlerBehav iorChange);
396 chrome.webRequest.handlerBehaviorChanged(); 391 chrome.webRequest.handlerBehaviorChanged();
397 392
398 handlerBehaviorChangedQuota--; 393 handlerBehaviorChangedQuota--;
399 setTimeout(function() { handlerBehaviorChangedQuota++; }, 600000); 394 setTimeout(() => { handlerBehaviorChangedQuota++; }, 600000);
400 } 395 }
401 } 396 }
402 397
403 ext.webRequest = { 398 ext.webRequest = {
404 onBeforeRequest: new ext._EventTarget(), 399 onBeforeRequest: new ext._EventTarget(),
405 handlerBehaviorChanged: function() 400 handlerBehaviorChanged()
406 { 401 {
407 // Defer handlerBehaviorChanged() until navigation occurs. 402 // Defer handlerBehaviorChanged() until navigation occurs.
408 // There wouldn't be any visible effect when calling it earlier, 403 // There wouldn't be any visible effect when calling it earlier,
409 // but it's an expensive operation and that way we avoid to call 404 // but it's an expensive operation and that way we avoid to call
410 // it multiple times, if multiple filters are added/removed. 405 // it multiple times, if multiple filters are added/removed.
411 var onBeforeNavigate = chrome.webNavigation.onBeforeNavigate; 406 let onBeforeNavigate = chrome.webNavigation.onBeforeNavigate;
412 if (!onBeforeNavigate.hasListener(propagateHandlerBehaviorChange)) 407 if (!onBeforeNavigate.hasListener(propagateHandlerBehaviorChange))
413 onBeforeNavigate.addListener(propagateHandlerBehaviorChange); 408 onBeforeNavigate.addListener(propagateHandlerBehaviorChange);
414 } 409 }
415 }; 410 };
416 411
417 chrome.tabs.query({}, function(tabs) 412 chrome.tabs.query({}, tabs =>
418 { 413 {
419 tabs.forEach(function(tab) 414 tabs.forEach(tab =>
420 { 415 {
421 chrome.webNavigation.getAllFrames({tabId: tab.id}, function(details) 416 chrome.webNavigation.getAllFrames({tabId: tab.id}, details =>
422 { 417 {
423 if (details && details.length > 0) 418 if (details && details.length > 0)
424 { 419 {
425 var frames = framesOfTabs[tab.id] = Object.create(null); 420 let frames = framesOfTabs[tab.id] = Object.create(null);
426 421
427 for (var i = 0; i < details.length; i++) 422 for (let i = 0; i < details.length; i++)
428 frames[details[i].frameId] = {url: new URL(details[i].url), parent: null}; 423 frames[details[i].frameId] = {url: new URL(details[i].url), parent: null};
429 424
430 for (var i = 0; i < details.length; i++) 425 for (let i = 0; i < details.length; i++)
431 { 426 {
432 var parentFrameId = details[i].parentFrameId; 427 let parentFrameId = details[i].parentFrameId;
433 428
434 if (parentFrameId != -1) 429 if (parentFrameId != -1)
435 frames[details[i].frameId].parent = frames[parentFrameId]; 430 frames[details[i].frameId].parent = frames[parentFrameId];
436 } 431 }
437 } 432 }
438 }); 433 });
439 }); 434 });
440 }); 435 });
441 436
442 chrome.webRequest.onBeforeRequest.addListener(function(details) 437 chrome.webRequest.onBeforeRequest.addListener(details =>
443 { 438 {
444 // The high-level code isn't interested in requests that aren't 439 // The high-level code isn't interested in requests that aren't
445 // related to a tab or requests loading a top-level document, 440 // related to a tab or requests loading a top-level document,
446 // those should never be blocked. 441 // those should never be blocked.
447 if (details.tabId == -1 || details.type == "main_frame") 442 if (details.tabId == -1 || details.type == "main_frame")
448 return; 443 return;
449 444
450 // We are looking for the frame that contains the element which 445 // We are looking for the frame that contains the element which
451 // has triggered this request. For most requests (e.g. images) we 446 // has triggered this request. For most requests (e.g. images) we
452 // can just use the request's frame ID, but for subdocument requests 447 // can just use the request's frame ID, but for subdocument requests
453 // (e.g. iframes) we must instead use the request's parent frame ID. 448 // (e.g. iframes) we must instead use the request's parent frame ID.
454 var frameId; 449 let frameId;
455 var requestType; 450 let requestType;
456 if (details.type == "sub_frame") 451 if (details.type == "sub_frame")
457 { 452 {
458 frameId = details.parentFrameId; 453 frameId = details.parentFrameId;
459 requestType = "SUBDOCUMENT"; 454 requestType = "SUBDOCUMENT";
460 } 455 }
461 else 456 else
462 { 457 {
463 frameId = details.frameId; 458 frameId = details.frameId;
464 requestType = details.type.toUpperCase(); 459 requestType = details.type.toUpperCase();
465 } 460 }
466 461
467 var frame = ext.getFrame(details.tabId, frameId); 462 let frame = ext.getFrame(details.tabId, frameId);
468 if (frame) 463 if (frame)
469 { 464 {
470 var results = ext.webRequest.onBeforeRequest._dispatch( 465 let results = ext.webRequest.onBeforeRequest._dispatch(
471 new URL(details.url), 466 new URL(details.url),
472 requestType, 467 requestType,
473 new Page({id: details.tabId}), 468 new Page({id: details.tabId}),
474 frame 469 frame
475 ); 470 );
476 471
477 if (results.indexOf(false) != -1) 472 if (results.indexOf(false) != -1)
478 return {cancel: true}; 473 return {cancel: true};
479 } 474 }
480 }, {urls: ["http://*/*", "https://*/*"]}, ["blocking"]); 475 }, {urls: ["http://*/*", "https://*/*"]}, ["blocking"]);
481 476
482 477
483 /* Message passing */ 478 /* Message passing */
484 479
485 chrome.runtime.onMessage.addListener(function(message, rawSender, sendResponse ) 480 chrome.runtime.onMessage.addListener((message, rawSender, sendResponse) =>
486 { 481 {
487 var sender = {}; 482 let sender = {};
488 483
489 // Add "page" and "frame" if the message was sent by a content script. 484 // Add "page" and "frame" if the message was sent by a content script.
490 // If sent by popup or the background page itself, there is no "tab". 485 // If sent by popup or the background page itself, there is no "tab".
491 if ("tab" in rawSender) 486 if ("tab" in rawSender)
492 { 487 {
493 sender.page = new Page(rawSender.tab); 488 sender.page = new Page(rawSender.tab);
494 sender.frame = { 489 sender.frame = {
495 url: new URL(rawSender.url), 490 url: new URL(rawSender.url),
496 get parent() 491 get parent()
497 { 492 {
498 var frames = framesOfTabs[rawSender.tab.id]; 493 let frames = framesOfTabs[rawSender.tab.id];
499 494
500 if (!frames) 495 if (!frames)
501 return null; 496 return null;
502 497
503 var frame = frames[rawSender.frameId]; 498 let frame = frames[rawSender.frameId];
504 if (frame) 499 if (frame)
505 return frame.parent; 500 return frame.parent;
506 501
507 return frames[0]; 502 return frames[0];
508 } 503 }
509 }; 504 };
510 } 505 }
511 506
512 return ext.onMessage._dispatch(message, sender, sendResponse).indexOf(true) != -1; 507 return ext.onMessage._dispatch(message, sender, sendResponse).indexOf(true) != -1;
513 }); 508 });
514 509
515 510
516 /* Storage */ 511 /* Storage */
517 512
518 ext.storage = { 513 ext.storage = {
519 get: function(keys, callback) 514 get(keys, callback)
520 { 515 {
521 chrome.storage.local.get(keys, callback); 516 chrome.storage.local.get(keys, callback);
522 }, 517 },
523 set: function(key, value, callback) 518 set(key, value, callback)
524 { 519 {
525 let items = {}; 520 let items = {};
526 items[key] = value; 521 items[key] = value;
527 chrome.storage.local.set(items, callback); 522 chrome.storage.local.set(items, callback);
528 }, 523 },
529 remove: function(key, callback) 524 remove(key, callback)
530 { 525 {
531 chrome.storage.local.remove(key, callback); 526 chrome.storage.local.remove(key, callback);
532 }, 527 },
533 onChanged: chrome.storage.onChanged 528 onChanged: chrome.storage.onChanged
534 }; 529 };
535 530
536 /* Options */ 531 /* Options */
537 532
538 if ("openOptionsPage" in chrome.runtime) 533 if ("openOptionsPage" in chrome.runtime)
539 { 534 {
540 ext.showOptions = function(callback) 535 ext.showOptions = callback =>
541 { 536 {
542 if (!callback) 537 if (!callback)
543 { 538 {
544 chrome.runtime.openOptionsPage(); 539 chrome.runtime.openOptionsPage();
545 } 540 }
546 else 541 else
547 { 542 {
548 chrome.runtime.openOptionsPage(() => 543 chrome.runtime.openOptionsPage(() =>
549 { 544 {
550 if (chrome.runtime.lastError) 545 if (chrome.runtime.lastError)
(...skipping 10 matching lines...) Expand all
561 } 556 }
562 }); 557 });
563 }); 558 });
564 } 559 }
565 }; 560 };
566 } 561 }
567 else 562 else
568 { 563 {
569 // Edge does not yet support runtime.openOptionsPage (tested version 38) 564 // Edge does not yet support runtime.openOptionsPage (tested version 38)
570 // and so this workaround needs to stay for now. 565 // and so this workaround needs to stay for now.
571 ext.showOptions = function(callback) 566 ext.showOptions = callback =>
572 { 567 {
573 chrome.windows.getLastFocused(function(win) 568 chrome.windows.getLastFocused(win =>
574 { 569 {
575 var optionsUrl = chrome.extension.getURL("options.html"); 570 let optionsUrl = chrome.extension.getURL("options.html");
576 var queryInfo = {url: optionsUrl}; 571 let queryInfo = {url: optionsUrl};
577 572
578 // extension pages can't be accessed in incognito windows. In order to 573 // extension pages can't be accessed in incognito windows. In order to
579 // correctly mimic the way in which Chrome opens extension options, 574 // correctly mimic the way in which Chrome opens extension options,
580 // we have to focus the options page in any other window. 575 // we have to focus the options page in any other window.
581 if (!win.incognito) 576 if (!win.incognito)
582 queryInfo.windowId = win.id; 577 queryInfo.windowId = win.id;
583 578
584 chrome.tabs.query(queryInfo, function(tabs) 579 chrome.tabs.query(queryInfo, tabs =>
585 { 580 {
586 if (tabs.length > 0) 581 if (tabs.length > 0)
587 { 582 {
588 var tab = tabs[0]; 583 let tab = tabs[0];
589 584
590 chrome.windows.update(tab.windowId, {focused: true}); 585 chrome.windows.update(tab.windowId, {focused: true});
591 chrome.tabs.update(tab.id, {active: true}); 586 chrome.tabs.update(tab.id, {active: true});
592 587
593 if (callback) 588 if (callback)
594 callback(new Page(tab)); 589 callback(new Page(tab));
595 } 590 }
596 else 591 else
597 { 592 {
598 ext.pages.open(optionsUrl, callback); 593 ext.pages.open(optionsUrl, callback);
599 } 594 }
600 }); 595 });
601 }); 596 });
602 }; 597 };
603 } 598 }
604 599
605 /* Windows */ 600 /* Windows */
606 ext.windows = { 601 ext.windows = {
607 create: function(createData, callback) 602 create(createData, callback)
608 { 603 {
609 chrome.windows.create(createData, function(createdWindow) 604 chrome.windows.create(createData, createdWindow =>
610 { 605 {
611 afterTabLoaded(callback)(createdWindow.tabs[0]); 606 afterTabLoaded(callback)(createdWindow.tabs[0]);
612 }); 607 });
613 } 608 }
614 }; 609 };
615 })(); 610 }
OLDNEW
« no previous file with comments | « background.js ('k') | chrome/ext/common.js » ('j') | chrome/ext/popup.js » ('J')

Powered by Google App Engine
This is Rietveld