annotate background.js @ 0:d13d59494613

Initial revision
author Guido Berhoerster <guido+set-aside@berhoerster.name>
date Sat, 17 Nov 2018 10:44:16 +0100
parents
children b0827360b8e4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
1 /*
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
2 * Copyright (C) 2018 Guido Berhoerster <guido+set-aside@berhoerster.name>
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
3 *
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
4 * This Source Code Form is subject to the terms of the Mozilla Public
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
7 */
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
8
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
9 'use strict';
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
10
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
11 const SUPPORTED_PROTOCOLS = ['https:', 'http:', 'ftp:'];
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
12 const GROUP_KEY_RE = /^collection:[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
13 const FIREFOX_VERSION_RE = /^(\d+(?:\.\d+)*)(?:([ab]|pre)(\d+))?$/;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
14 const FIREFOX_RELEASE_TYPES = {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
15 'a': 'alpha',
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
16 'b': 'beta',
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
17 'pre': 'prerelease',
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
18 '': ''
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
19 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
20 const THUMBNAIL_WIDTH = 224;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
21 const THUMBNAIL_HEIGHT = 128;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
22
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
23 var tabCollectionsProxy;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
24
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
25 function generateUuidV4String() {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
26 let uuid = new Uint8Array(16);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
27 window.crypto.getRandomValues(uuid);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
28 uuid[6] = (uuid[6] & 0x0f) | 0x40;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
29 uuid[8] = (uuid[8] & 0x3f) | 0x80;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
30
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
31 let result = [];
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
32 for (let i = 0; i < uuid.length; i++) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
33 if (i == 4 || i == 6 || i == 8 || i == 10) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
34 result.push('-');
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
35 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
36 result.push(uuid[i].toString(16).padStart(2, '0'));
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
37 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
38
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
39 return result.join('');
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
40 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
41
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
42 function parseFirefoxVersion(firefoxVersionString) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
43 let [, versionString, releaseTypeAbbrev = '', releaseNumberString = '0'] =
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
44 FIREFOX_VERSION_RE.exec(firefoxVersionString);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
45
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
46 let releaseType = FIREFOX_RELEASE_TYPES[releaseTypeAbbrev];
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
47
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
48 let releaseNumber = parseInt(releaseNumberString);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
49 let [major = 0, minor = 0, patch = 0] = versionString.split('.')
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
50 .map(x => parseInt(x));
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
51
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
52 return {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
53 major,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
54 minor,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
55 patch,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
56 releaseType,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
57 releaseNumber,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
58 };
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
59 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
60
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
61 class Tab {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
62 static deserialize(object) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
63 return new Tab(object);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
64 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
65
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
66 constructor({url, title, uuid = generateUuidV4String(), favIconUrl = null,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
67 thumbnailUrl = null}) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
68 this.uuid = uuid;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
69 this.url = url;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
70 this.title = title;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
71 this.favIconUrl = favIconUrl;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
72 this.thumbnailUrl = thumbnailUrl;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
73 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
74
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
75 serialize() {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
76 return Object.assign({}, this);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
77 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
78 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
79
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
80 class TabCollection {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
81 static deserialize(object) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
82 object.tabs = Array.from(object.tabs,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
83 ([, tab]) => [tab.uuid, Tab.deserialize(tab)]);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
84 return new TabCollection(object);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
85 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
86
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
87 constructor({tabs, uuid = generateUuidV4String(), date = new Date()}) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
88 this.uuid = uuid;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
89 this.date = new Date(date);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
90 this.tabs = new Map();
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
91 // allow any type which allows iteration
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
92 for (let [, tab] of tabs) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
93 this.tabs.set(tab.uuid, tab);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
94 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
95 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
96
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
97 serialize() {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
98 let serializedTabs = [];
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
99 for (let [tabUuid, tab] of this.tabs) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
100 serializedTabs.push([tab.uuid, tab.serialize()]);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
101 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
102 return {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
103 uuid: this.uuid,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
104 date: this.date.toJSON(),
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
105 tabs: serializedTabs
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
106 };
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
107 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
108 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
109
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
110 class TabCollectionsStorageProxy {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
111 constructor() {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
112 this.tabCollections = new Map();
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
113 this.ports = new Set();
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
114 this.browserVersion = undefined;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
115 this.messageQueue = [];
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
116 this.isInitialized = false;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
117
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
118 browser.runtime.onConnect.addListener(this.onConnect.bind(this));
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
119 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
120
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
121 async init() {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
122 let browserInfo = await browser.runtime.getBrowserInfo();
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
123 this.browserVersion = parseFirefoxVersion(browserInfo.version);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
124
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
125 // get all tab collections and deserialize them in a Map
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
126 let storageEntries = Object.entries(await browser.storage.sync.get())
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
127 .filter(([key, value]) => GROUP_KEY_RE.test(key))
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
128 .map(([key, tabCollection]) =>
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
129 [tabCollection.uuid, TabCollection.deserialize(tabCollection)]);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
130 this.tabCollections = new Map(storageEntries);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
131 console.log('tab collections from storage');
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
132 console.table(this.tabCollections);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
133 console.groupEnd();
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
134 browser.storage.onChanged.addListener(this.onStorageChanged.bind(this));
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
135
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
136 this.isInitialized = true;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
137
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
138 while (this.messageQueue.length > 0) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
139 let [message, port] = this.messageQueue.pop();
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
140 if (this.ports.has(port)) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
141 this.onMessage(message, port);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
142 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
143 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
144 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
145
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
146 async createTabThumbnail(tabId) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
147 let captureUrl = await browser.tabs.captureTab(tabId);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
148 let thumbnailUrl = await new Promise((resolve, reject) => {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
149 let image = new Image();
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
150 image.addEventListener('load', ev => {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
151 let canvas = document.createElement('canvas');
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
152 canvas.width = THUMBNAIL_WIDTH;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
153 canvas.height = THUMBNAIL_HEIGHT;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
154 let dWidth = canvas.width;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
155 let dHeight = dWidth * (image.height / image.width);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
156
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
157 let ctx = canvas.getContext('2d');
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
158 ctx.fillStyle = '#fff';
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
159 ctx.fillRect(0, 0, canvas.width, canvas.height);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
160 ctx.drawImage(image, 0, 0, dWidth, dHeight);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
161
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
162 resolve(canvas.toDataURL('image/jpeg', 0.75));
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
163 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
164 image.addEventListener('error', e => {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
165 reject(e);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
166 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
167 image.src = captureUrl;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
168 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
169 return thumbnailUrl;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
170 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
171
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
172 async createTabCollection(windowId) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
173 let browserTabs = await browser.tabs.query({
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
174 windowId,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
175 hidden: false,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
176 pinned:false
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
177 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
178
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
179 // sanity check to prevent saving tabs from incognito windows
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
180 if (browserTabs.length === 0 || browserTabs[0].incognito) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
181 return;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
182 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
183
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
184 // filter out tabs which cannot be restored
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
185 browserTabs = browserTabs.filter(browserTab =>
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
186 SUPPORTED_PROTOCOLS.includes(new URL(browserTab.url).protocol));
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
187 if (browserTabs.length === 0) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
188 return;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
189 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
190
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
191 let tabs = browserTabs.map(browserTab => {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
192 let tab = new Tab({
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
193 url: browserTab.url,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
194 title: browserTab.title,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
195 favIconUrl: browserTab.favIconUrl
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
196 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
197 return [tab.uuid, tab];
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
198 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
199
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
200 // create empty tab which becomes the new active tab
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
201 await browser.tabs.create({active: true});
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
202
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
203 // capture tabs, return null for discarded tabs since they can only be
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
204 // captured after they have been restored, e.g. through user
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
205 // interaction, and thus might hang the capture process indefinetly
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
206 let thumbnails = await Promise.all(browserTabs.map(browserTab =>
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
207 !browserTab.discarded ?
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
208 this.createTabThumbnail(browserTab.id) : null));
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
209 for (let [, tab] of tabs) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
210 tab.thumbnailUrl = thumbnails.shift();
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
211 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
212
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
213 let tabCollection = new TabCollection({tabs});
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
214 console.log('created tab collection:', tabCollection);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
215
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
216 // store tab collection
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
217 console.log('storing tab collection:', tabCollection);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
218 await browser.storage.sync.set({
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
219 [`collection:${tabCollection.uuid}`]: tabCollection.serialize()
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
220 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
221
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
222 // remove tabs
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
223 await browser.tabs.remove(browserTabs.map(browserTab => browserTab.id));
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
224 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
225
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
226 async removeTab(tabCollectionUuid, tabUuid) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
227 console.log('removing tab %s from collection %s', tabUuid,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
228 tabCollectionUuid);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
229 let tabCollection = this.tabCollections.get(tabCollectionUuid);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
230 // create shallow clone
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
231 let newTabCollection = new TabCollection(tabCollection);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
232 newTabCollection.tabs.delete(tabUuid);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
233 // remove tab collection if there are no more tabs
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
234 if (newTabCollection.tabs.size === 0) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
235 return this.removeTabCollection(tabCollectionUuid);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
236 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
237 await browser.storage.sync.set({
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
238 [`collection:${tabCollectionUuid}`]: newTabCollection.serialize()
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
239 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
240 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
241
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
242 async restoreTab(tabCollectionUuid, tabUuid, windowId) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
243 console.log('restoring tab %s from collection %s in window %d', tabUuid,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
244 tabCollectionUuid, windowId);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
245 let tab = this.tabCollections.get(tabCollectionUuid).tabs.get(tabUuid);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
246 let tabProperties = {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
247 active: false,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
248 url: tab.url,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
249 windowId
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
250 };
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
251 if (this.browserVersion.major >= 63) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
252 tabProperties.discarded = true;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
253 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
254 await browser.tabs.create(tabProperties);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
255 await this.removeTab(tabCollectionUuid, tabUuid);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
256 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
257
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
258 async removeTabCollection(tabCollectionUuid) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
259 console.log('removing tab collection %s', tabCollectionUuid);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
260 await browser.storage.sync.remove(`collection:${tabCollectionUuid}`);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
261 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
262
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
263 async restoreTabCollection(tabCollectionUuid, windowId) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
264 console.log('restoring tab collection %s in window %s',
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
265 tabCollectionUuid, windowId);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
266 let tabProperties = {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
267 active: false,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
268 windowId
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
269 };
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
270 if (this.browserVersion.major >= 63) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
271 tabProperties.discarded = true;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
272 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
273 let creatingTabs =
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
274 Array.from(this.tabCollections.get(tabCollectionUuid).tabs,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
275 ([, tab]) => browser.tabs.create(Object.assign({
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
276 url: tab.url
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
277 }, tabProperties)));
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
278 await Promise.all(creatingTabs);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
279 await this.removeTabCollection(tabCollectionUuid);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
280 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
281
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
282 onStorageChanged(changes, areaName) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
283 if (areaName !== 'sync') {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
284 return;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
285 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
286
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
287 console.group('sync storage area changed:', changes);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
288 console.table(Object.entries(changes)[0][1])
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
289 console.groupEnd();
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
290
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
291 let [key, {oldValue, newValue}] = Object.entries(changes)[0];
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
292 if (!GROUP_KEY_RE.test(key)) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
293 return;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
294 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
295
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
296 let tabCollectionUuid = key.replace('collection:', '');
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
297 if (typeof oldValue === 'undefined') {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
298 // a new collection was created
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
299 let newTabCollection = TabCollection.deserialize(newValue);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
300 this.tabCollections.set(tabCollectionUuid, newTabCollection);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
301
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
302 this.broadcastMessage({
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
303 type: 'tabCollectionCreated',
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
304 tabCollection: newTabCollection
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
305 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
306 } else if (typeof newValue === 'undefined') {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
307 // a collection has been removed
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
308 this.tabCollections.delete(tabCollectionUuid);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
309
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
310 this.broadcastMessage({
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
311 type: 'tabCollectionRemoved',
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
312 tabCollectionUuid
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
313 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
314 } else {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
315 // a collection has changed
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
316 let newTabCollection = TabCollection.deserialize(newValue);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
317 this.tabCollections.set(tabCollectionUuid, newTabCollection);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
318
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
319 this.broadcastMessage({
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
320 type: 'tabCollectionChanged',
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
321 tabCollection: newTabCollection
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
322 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
323 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
324 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
325
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
326 broadcastMessage(message) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
327 for (let port of this.ports) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
328 port.postMessage(message);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
329 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
330 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
331
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
332 onConnect(port) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
333 console.log('port connected:', port)
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
334 this.ports.add(port);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
335 port.onMessage.addListener(this.onMessage.bind(this));
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
336 port.onDisconnect.addListener(this.onDisconnect.bind(this));
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
337 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
338
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
339 onDisconnect(port) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
340 if (port.error) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
341 console.log(`port connection error: ${port.error}\n`);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
342 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
343 console.log('port disconnected:', port);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
344 this.ports.delete(port);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
345 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
346
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
347 onMessage(message, port) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
348 if (!this.isInitialized) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
349 console.log('queued message', message, 'from port', port);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
350 this.messageQueue.push([message, port]);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
351 return;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
352 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
353
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
354 console.log('received message', message, 'on port', port);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
355 switch (message.type) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
356 case 'getTabCollections':
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
357 port.postMessage({
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
358 type: 'tabCollections',
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
359 tabCollections: this.tabCollections
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
360 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
361 break;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
362 case 'removeTab':
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
363 this.removeTab(message.tabCollectionUuid, message.tabUuid);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
364 break;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
365 case 'restoreTab':
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
366 this.restoreTab(message.tabCollectionUuid, message.tabUuid,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
367 message.windowId);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
368 break;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
369 case 'removeTabCollection':
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
370 this.removeTabCollection(message.tabCollectionUuid);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
371 break;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
372 case 'restoreTabCollection':
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
373 this.restoreTabCollection(message.tabCollectionUuid,
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
374 message.windowId);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
375 break;
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
376 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
377 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
378 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
379
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
380 // browser action context menu entry for opening the sidebar
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
381 browser.menus.create({
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
382 contexts: ['browser_action'],
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
383 onclick: (info, tab) => browser.sidebarAction.open(),
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
384 title: browser.i18n.getMessage('showTabsMenuItem')
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
385 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
386
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
387 // disable the browser action for new incognito tabs
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
388 browser.tabs.onCreated.addListener(tab => {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
389 if (tab.incognito) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
390 // this does not work, it seems that the browser action is re-enabled
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
391 // on every update
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
392 browser.browserAction.disable(tab.id);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
393 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
394 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
395
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
396 (async () => {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
397 // disable the browser action for existing incognito tabs
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
398 let tabs = await browser.tabs.query({});
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
399 await Promise.all(tabs.filter(tab => tab.incognito)
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
400 .map(tab => browser.browserAction.disable(tab.id)))
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
401
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
402 tabCollectionsProxy = new TabCollectionsStorageProxy();
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
403 await tabCollectionsProxy.init();
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
404
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
405 browser.browserAction.onClicked.addListener(async targetTab => {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
406 // prevent browser action from being activated while a collection is
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
407 // being created
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
408 let tabs = await browser.tabs.query({windowId: targetTab.windowId});
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
409 await Promise.all(tabs.map(tab =>
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
410 browser.browserAction.disable(tab.id)));
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
411
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
412 try {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
413 await tabCollectionsProxy.createTabCollection(targetTab.windowId);
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
414 } catch (e) {
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
415 tabs = await browser.tabs.query({windowId: targetTab.windowId});
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
416 await Promise.all(tabs.map(tab =>
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
417 browser.browserAction.enable(tab.id)));
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
418 throw e
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
419 }
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
420
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
421 tabs = await browser.tabs.query({windowId: targetTab.windowId});
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
422 await Promise.all(tabs.map(tab =>
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
423 browser.browserAction.enable(tab.id)));
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
424 });
d13d59494613 Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff changeset
425 })();