Mercurial > addons > firefox-addons > set-aside
annotate background.js @ 4:8f8a0b35515b
Added tag version-1 for changeset 48b036902118
author | Guido Berhoerster <guido+set-aside@berhoerster.name> |
---|---|
date | Thu, 22 Nov 2018 15:52:42 +0100 |
parents | b0827360b8e4 |
children | 9d699dc7823d |
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 |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
61 class ObjectStoreDB { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
62 constructor(dbName = 'defaultDatabase', objectStoreName = 'objectStore') { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
63 this.dbName = dbName; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
64 this.objectStoreName = objectStoreName; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
65 this._db = undefined; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
66 this.openingDB = new Promise((resolve, reject) => { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
67 let request = indexedDB.open(this.dbName); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
68 request.addEventListener('error', ev => { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
69 reject(request.error); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
70 }); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
71 request.addEventListener('success', ev => { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
72 resolve(request.result); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
73 }); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
74 request.addEventListener('upgradeneeded', ev => { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
75 request.result.createObjectStore(this.objectStoreName); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
76 }); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
77 }); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
78 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
79 |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
80 async _execTransaction(method, ...methodArguments) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
81 if (typeof this._db === 'undefined') { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
82 this._db = await this.openingDB; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
83 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
84 return new Promise((resolve, reject) => { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
85 let transaction = this._db.transaction(this.objectStoreName, |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
86 method.startsWith('get') ? 'readonly' : 'readwrite'); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
87 let objectStore = transaction.objectStore(this.objectStoreName); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
88 let request = objectStore[method](...methodArguments); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
89 transaction.addEventListener('complete', ev => |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
90 method.startsWith('get') ? |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
91 resolve(request.result) : |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
92 resolve()); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
93 transaction.addEventListener('abort', ev => |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
94 reject(transaction.error)); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
95 transaction.addEventListener('error', ev => |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
96 reject(transaction.error)); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
97 }); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
98 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
99 |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
100 async get(key) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
101 return key === null || typeof key === 'undefined' ? |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
102 this._execTransaction('getAll') : |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
103 this._execTransaction('get', key); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
104 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
105 |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
106 async keys() { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
107 return this._execTransaction('getAllKeys'); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
108 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
109 |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
110 async set(key, value) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
111 return this._execTransaction('put', value, key) |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
112 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
113 |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
114 async delete(key) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
115 return this._execTransaction('delete', key) |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
116 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
117 |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
118 async clear(key) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
119 return this._execTransaction('clear') |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
120 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
121 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
122 |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
123 class Tab { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
124 static deserialize(object) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
125 return new Tab(object); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
126 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
127 |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
128 constructor({url, title, uuid = generateUuidV4String(), favIcon = null, |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
129 thumbnail = null}) { |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
130 this.uuid = uuid; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
131 this.url = url; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
132 this.title = title; |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
133 this.favIcon = favIcon; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
134 this.thumbnail = thumbnail; |
0
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 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
137 serialize() { |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
138 return Object.assign({}, this, {favIcon: null, thumbnail: null}); |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
139 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
140 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
141 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
142 class TabCollection { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
143 static deserialize(object) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
144 object.tabs = Array.from(object.tabs, |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
145 ([, tab]) => [tab.uuid, Tab.deserialize(tab)]); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
146 return new TabCollection(object); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
147 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
148 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
149 constructor({tabs, uuid = generateUuidV4String(), date = new Date()}) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
150 this.uuid = uuid; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
151 this.date = new Date(date); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
152 this.tabs = new Map(); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
153 // allow any type which allows iteration |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
154 for (let [, tab] of tabs) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
155 this.tabs.set(tab.uuid, tab); |
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 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
158 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
159 serialize() { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
160 let serializedTabs = []; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
161 for (let [tabUuid, tab] of this.tabs) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
162 serializedTabs.push([tab.uuid, tab.serialize()]); |
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 return { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
165 uuid: this.uuid, |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
166 date: this.date.toJSON(), |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
167 tabs: serializedTabs |
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 } |
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 class TabCollectionsStorageProxy { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
173 constructor() { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
174 this.tabCollections = new Map(); |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
175 this.objectStoreDB = new ObjectStoreDB('tabCollections'); |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
176 this.ports = new Set(); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
177 this.browserVersion = undefined; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
178 this.messageQueue = []; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
179 this.isInitialized = false; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
180 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
181 browser.runtime.onConnect.addListener(this.onConnect.bind(this)); |
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 async init() { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
185 let browserInfo = await browser.runtime.getBrowserInfo(); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
186 this.browserVersion = parseFirefoxVersion(browserInfo.version); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
187 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
188 // get all tab collections and deserialize them in a Map |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
189 let storageEntries = Object.entries(await browser.storage.sync.get()) |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
190 .filter(([key, value]) => GROUP_KEY_RE.test(key)) |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
191 .map(([key, tabCollection]) => |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
192 [tabCollection.uuid, TabCollection.deserialize(tabCollection)]); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
193 this.tabCollections = new Map(storageEntries); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
194 console.log('tab collections from storage'); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
195 console.table(this.tabCollections); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
196 console.groupEnd(); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
197 browser.storage.onChanged.addListener(this.onStorageChanged.bind(this)); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
198 |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
199 // get favicon and thumbnail data from local database |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
200 let updatingTabData = []; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
201 for (let tabCollectionUuid of this.tabCollections.keys()) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
202 updatingTabData.push(this.updateTabData(tabCollectionUuid)); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
203 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
204 await Promise.all(updatingTabData); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
205 |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
206 // remove stale data from local database |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
207 for (let tabCollectionUuid of await this.objectStoreDB.keys()) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
208 if (!this.tabCollections.has(tabCollectionUuid)) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
209 console.log('removing data for stale tab collection', |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
210 tabCollectionUuid); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
211 this.objectStoreDB.delete(tabCollectionUuid); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
212 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
213 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
214 |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
215 this.isInitialized = true; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
216 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
217 while (this.messageQueue.length > 0) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
218 let [message, port] = this.messageQueue.pop(); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
219 if (this.ports.has(port)) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
220 this.onMessage(message, port); |
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 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
223 } |
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 async createTabThumbnail(tabId) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
226 let captureUrl = await browser.tabs.captureTab(tabId); |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
227 let thumbnailBlob = await new Promise((resolve, reject) => { |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
228 let image = new Image(); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
229 image.addEventListener('load', ev => { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
230 let canvas = document.createElement('canvas'); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
231 canvas.width = THUMBNAIL_WIDTH; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
232 canvas.height = THUMBNAIL_HEIGHT; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
233 let dWidth = canvas.width; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
234 let dHeight = dWidth * (image.height / image.width); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
235 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
236 let ctx = canvas.getContext('2d'); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
237 ctx.fillStyle = '#fff'; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
238 ctx.fillRect(0, 0, canvas.width, canvas.height); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
239 ctx.drawImage(image, 0, 0, dWidth, dHeight); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
240 |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
241 canvas.toBlob(resolve, 'image/jpeg', 0.75); |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
242 }); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
243 image.addEventListener('error', e => { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
244 reject(e); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
245 }); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
246 image.src = captureUrl; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
247 }); |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
248 return thumbnailBlob; |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
249 } |
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 async createTabCollection(windowId) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
252 let browserTabs = await browser.tabs.query({ |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
253 windowId, |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
254 hidden: false, |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
255 pinned:false |
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 // sanity check to prevent saving tabs from incognito windows |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
259 if (browserTabs.length === 0 || browserTabs[0].incognito) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
260 return; |
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 // filter out tabs which cannot be restored |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
264 browserTabs = browserTabs.filter(browserTab => |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
265 SUPPORTED_PROTOCOLS.includes(new URL(browserTab.url).protocol)); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
266 if (browserTabs.length === 0) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
267 return; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
268 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
269 |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
270 let tabs = await Promise.all(browserTabs.map(async browserTab => { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
271 // convert favicon data URI to blob |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
272 let favIcon = null; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
273 if (!browserTab.discarded) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
274 try { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
275 let response = await fetch(browserTab.favIconUrl); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
276 favIcon = await response.blob(); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
277 } catch (e) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
278 if (!(e instanceof AbortError)) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
279 throw e; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
280 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
281 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
282 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
283 |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
284 let tab = new Tab({ |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
285 url: browserTab.url, |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
286 title: browserTab.title, |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
287 favIcon |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
288 }); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
289 return [tab.uuid, tab]; |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
290 })); |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
291 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
292 // create empty tab which becomes the new active tab |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
293 await browser.tabs.create({active: true}); |
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 // 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
|
296 // captured after they have been restored, e.g. through user |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
297 // interaction, and thus might hang the capture process indefinetly |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
298 let thumbnails = await Promise.all(browserTabs.map(browserTab => |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
299 !browserTab.discarded ? |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
300 this.createTabThumbnail(browserTab.id) : null)); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
301 for (let [, tab] of tabs) { |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
302 tab.thumbnail = thumbnails.shift(); |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
303 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
304 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
305 let tabCollection = new TabCollection({tabs}); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
306 console.log('created tab collection:', tabCollection); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
307 |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
308 // store tab favicons and thumbnails |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
309 let tabCollectionData = { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
310 uuid: tabCollection.uuid, |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
311 tabs: new Map() |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
312 }; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
313 for (let [uuid, tab] of tabs) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
314 tabCollectionData.tabs.set(uuid, { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
315 favIcon: tab.favIcon, |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
316 thumbnail: tab.thumbnail |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
317 }); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
318 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
319 await this.objectStoreDB.set(tabCollectionData.uuid, tabCollectionData); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
320 |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
321 // store tab collection |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
322 console.log('storing tab collection:', tabCollection); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
323 await browser.storage.sync.set({ |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
324 [`collection:${tabCollection.uuid}`]: tabCollection.serialize() |
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 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
327 // remove tabs |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
328 await browser.tabs.remove(browserTabs.map(browserTab => browserTab.id)); |
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 async removeTab(tabCollectionUuid, tabUuid) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
332 console.log('removing tab %s from collection %s', tabUuid, |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
333 tabCollectionUuid); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
334 let tabCollection = this.tabCollections.get(tabCollectionUuid); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
335 // create shallow clone |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
336 let newTabCollection = new TabCollection(tabCollection); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
337 newTabCollection.tabs.delete(tabUuid); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
338 // remove tab collection if there are no more tabs |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
339 if (newTabCollection.tabs.size === 0) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
340 return this.removeTabCollection(tabCollectionUuid); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
341 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
342 await browser.storage.sync.set({ |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
343 [`collection:${tabCollectionUuid}`]: newTabCollection.serialize() |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
344 }); |
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 async restoreTab(tabCollectionUuid, tabUuid, windowId) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
348 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
|
349 tabCollectionUuid, windowId); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
350 let tab = this.tabCollections.get(tabCollectionUuid).tabs.get(tabUuid); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
351 let tabProperties = { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
352 active: false, |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
353 url: tab.url, |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
354 windowId |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
355 }; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
356 if (this.browserVersion.major >= 63) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
357 tabProperties.discarded = true; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
358 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
359 await browser.tabs.create(tabProperties); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
360 await this.removeTab(tabCollectionUuid, tabUuid); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
361 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
362 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
363 async removeTabCollection(tabCollectionUuid) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
364 console.log('removing tab collection %s', tabCollectionUuid); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
365 await browser.storage.sync.remove(`collection:${tabCollectionUuid}`); |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
366 this.objectStoreDB.delete(tabCollectionUuid); |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
367 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
368 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
369 async restoreTabCollection(tabCollectionUuid, windowId) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
370 console.log('restoring tab collection %s in window %s', |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
371 tabCollectionUuid, windowId); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
372 let tabProperties = { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
373 active: false, |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
374 windowId |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
375 }; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
376 if (this.browserVersion.major >= 63) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
377 tabProperties.discarded = true; |
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 let creatingTabs = |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
380 Array.from(this.tabCollections.get(tabCollectionUuid).tabs, |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
381 ([, tab]) => browser.tabs.create(Object.assign({ |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
382 url: tab.url |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
383 }, tabProperties))); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
384 await Promise.all(creatingTabs); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
385 await this.removeTabCollection(tabCollectionUuid); |
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 |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
388 async updateTabData(tabCollectionUuid) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
389 let tabCollectionDataObject; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
390 try { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
391 tabCollectionDataObject = |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
392 await this.objectStoreDB.get(tabCollectionUuid); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
393 } catch (e) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
394 console.error(`Failed to get data from database: e.message`); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
395 return; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
396 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
397 if (typeof tabCollectionDataObject === 'undefined') { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
398 // does not exist in database |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
399 console.log('no data stored for tab collection', tabCollectionUuid); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
400 return; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
401 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
402 |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
403 console.log(`updating tab collection ${tabCollectionUuid} with data`, |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
404 tabCollectionDataObject); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
405 let tabCollection = this.tabCollections.get(tabCollectionUuid); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
406 for (let [tabUuid, tab] of tabCollection.tabs) { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
407 let tabDataObject = tabCollectionDataObject.tabs.get(tabUuid); |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
408 if (typeof tabDataObject === 'undefined') { |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
409 continue; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
410 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
411 tab.favIcon = tabDataObject.favIcon; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
412 tab.thumbnail = tabDataObject.thumbnail; |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
413 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
414 } |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
415 |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
416 async onStorageChanged(changes, areaName) { |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
417 if (areaName !== 'sync') { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
418 return; |
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 console.group('sync storage area changed:', changes); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
422 console.table(Object.entries(changes)[0][1]) |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
423 console.groupEnd(); |
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 let [key, {oldValue, newValue}] = Object.entries(changes)[0]; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
426 if (!GROUP_KEY_RE.test(key)) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
427 return; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
428 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
429 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
430 let tabCollectionUuid = key.replace('collection:', ''); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
431 if (typeof oldValue === 'undefined') { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
432 // a new collection was created |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
433 let newTabCollection = TabCollection.deserialize(newValue); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
434 this.tabCollections.set(tabCollectionUuid, newTabCollection); |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
435 // try to get tab favicons and thumbnails |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
436 await this.updateTabData(tabCollectionUuid); |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
437 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
438 this.broadcastMessage({ |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
439 type: 'tabCollectionCreated', |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
440 tabCollection: newTabCollection |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
441 }); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
442 } else if (typeof newValue === 'undefined') { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
443 // a collection has been removed |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
444 this.tabCollections.delete(tabCollectionUuid); |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
445 this.objectStoreDB.delete(tabCollectionUuid); |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
446 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
447 this.broadcastMessage({ |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
448 type: 'tabCollectionRemoved', |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
449 tabCollectionUuid |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
450 }); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
451 } else { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
452 // a collection has changed |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
453 let newTabCollection = TabCollection.deserialize(newValue); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
454 this.tabCollections.set(tabCollectionUuid, newTabCollection); |
1
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
455 // try to get tab favicons and thumbnails |
b0827360b8e4
Store favicons and thumbnails in local database
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
0
diff
changeset
|
456 await this.updateTabData(tabCollectionUuid); |
0
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
457 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
458 this.broadcastMessage({ |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
459 type: 'tabCollectionChanged', |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
460 tabCollection: newTabCollection |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
461 }); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
462 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
463 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
464 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
465 broadcastMessage(message) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
466 for (let port of this.ports) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
467 port.postMessage(message); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
468 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
469 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
470 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
471 onConnect(port) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
472 console.log('port connected:', port) |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
473 this.ports.add(port); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
474 port.onMessage.addListener(this.onMessage.bind(this)); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
475 port.onDisconnect.addListener(this.onDisconnect.bind(this)); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
476 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
477 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
478 onDisconnect(port) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
479 if (port.error) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
480 console.log(`port connection error: ${port.error}\n`); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
481 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
482 console.log('port disconnected:', port); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
483 this.ports.delete(port); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
484 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
485 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
486 onMessage(message, port) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
487 if (!this.isInitialized) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
488 console.log('queued message', message, 'from port', port); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
489 this.messageQueue.push([message, port]); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
490 return; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
491 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
492 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
493 console.log('received message', message, 'on port', port); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
494 switch (message.type) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
495 case 'getTabCollections': |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
496 port.postMessage({ |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
497 type: 'tabCollections', |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
498 tabCollections: this.tabCollections |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
499 }); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
500 break; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
501 case 'removeTab': |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
502 this.removeTab(message.tabCollectionUuid, message.tabUuid); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
503 break; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
504 case 'restoreTab': |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
505 this.restoreTab(message.tabCollectionUuid, message.tabUuid, |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
506 message.windowId); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
507 break; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
508 case 'removeTabCollection': |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
509 this.removeTabCollection(message.tabCollectionUuid); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
510 break; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
511 case 'restoreTabCollection': |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
512 this.restoreTabCollection(message.tabCollectionUuid, |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
513 message.windowId); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
514 break; |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
515 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
516 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
517 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
518 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
519 // browser action context menu entry for opening the sidebar |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
520 browser.menus.create({ |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
521 contexts: ['browser_action'], |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
522 onclick: (info, tab) => browser.sidebarAction.open(), |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
523 title: browser.i18n.getMessage('showTabsMenuItem') |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
524 }); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
525 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
526 // disable the browser action for new incognito tabs |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
527 browser.tabs.onCreated.addListener(tab => { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
528 if (tab.incognito) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
529 // 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
|
530 // on every update |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
531 browser.browserAction.disable(tab.id); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
532 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
533 }); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
534 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
535 (async () => { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
536 // disable the browser action for existing incognito tabs |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
537 let tabs = await browser.tabs.query({}); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
538 await Promise.all(tabs.filter(tab => tab.incognito) |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
539 .map(tab => browser.browserAction.disable(tab.id))) |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
540 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
541 tabCollectionsProxy = new TabCollectionsStorageProxy(); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
542 await tabCollectionsProxy.init(); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
543 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
544 browser.browserAction.onClicked.addListener(async targetTab => { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
545 // prevent browser action from being activated while a collection is |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
546 // being created |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
547 let tabs = await browser.tabs.query({windowId: targetTab.windowId}); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
548 await Promise.all(tabs.map(tab => |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
549 browser.browserAction.disable(tab.id))); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
550 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
551 try { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
552 await tabCollectionsProxy.createTabCollection(targetTab.windowId); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
553 } catch (e) { |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
554 tabs = await browser.tabs.query({windowId: targetTab.windowId}); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
555 await Promise.all(tabs.map(tab => |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
556 browser.browserAction.enable(tab.id))); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
557 throw e |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
558 } |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
559 |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
560 tabs = await browser.tabs.query({windowId: targetTab.windowId}); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
561 await Promise.all(tabs.map(tab => |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
562 browser.browserAction.enable(tab.id))); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
563 }); |
d13d59494613
Initial revision
Guido Berhoerster <guido+set-aside@berhoerster.name>
parents:
diff
changeset
|
564 })(); |