Mercurial > addons > firefox-addons > set-aside
comparison sidebar/js/tab-collection-manager.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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:d13d59494613 |
---|---|
1 /* | |
2 * Copyright (C) 2018 Guido Berhoerster <guido+set-aside@berhoerster.name> | |
3 * | |
4 * This Source Code Form is subject to the terms of the Mozilla Public | |
5 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
7 */ | |
8 | |
9 'use strict'; | |
10 | |
11 var tabManager; | |
12 | |
13 class TabManager { | |
14 constructor() { | |
15 this.tabCollectionTemplate = | |
16 document.querySelector('#tab-collection-template'); | |
17 this.tabItemTemplate = document.querySelector('#tab-item-template'); | |
18 this.tabCollectionsElement = document.querySelector('#tab-collections'); | |
19 this.port = browser.runtime.connect({name: 'tab-collection-manager'}); | |
20 this.port.onMessage.addListener(this.onMessage.bind(this)); | |
21 this.port.onDisconnect.addListener(this.onMessage.bind(this)); | |
22 this.port.postMessage({type: 'getTabCollections'}); | |
23 this.isInitialized = false; | |
24 } | |
25 | |
26 initTabCollections(tabCollections) { | |
27 if (this.isInitialized) { | |
28 return; | |
29 } | |
30 | |
31 for (let tabCollection of tabCollections.values()) { | |
32 this.prependTabCollection(tabCollection); | |
33 } | |
34 this.sortTabCollections(); | |
35 | |
36 document.querySelector('#message').textContent = | |
37 browser.i18n.getMessage('emptySidebarMessage'); | |
38 | |
39 document.body.addEventListener('click', this); | |
40 | |
41 this.isInitialized = true; | |
42 } | |
43 | |
44 createTabCollectionNode(tabCollection) { | |
45 let tabCollectionNode = | |
46 document.importNode(this.tabCollectionTemplate.content, true); | |
47 | |
48 tabCollectionNode.querySelector('.tab-collection') | |
49 .dataset.tabCollectionUuid = tabCollection.uuid; | |
50 | |
51 tabCollectionNode.querySelector('.tab-collection-title').textContent = | |
52 browser.i18n.getMessage('collectionTitle', | |
53 tabCollection.tabs.size); | |
54 | |
55 let tabCollectionCtimeElement = | |
56 tabCollectionNode.querySelector('.tab-collection-ctime'); | |
57 tabCollectionCtimeElement.dateTime = tabCollection.date.toISOString(); | |
58 tabCollectionCtimeElement.textContent = | |
59 tabCollection.date.toLocaleString(); | |
60 | |
61 let tabCollectionRestoreElement = | |
62 tabCollectionNode.querySelector('.restore-tab-collection'); | |
63 tabCollectionRestoreElement.title = | |
64 tabCollectionRestoreElement.textContent = | |
65 browser.i18n.getMessage('restoreTabsButtonTitle'); | |
66 tabCollectionNode.querySelector('.remove-tab-collection').title = | |
67 browser.i18n.getMessage('removeTabsButtonTitle'); | |
68 | |
69 let tabListElement = | |
70 tabCollectionNode.querySelector('.tab-collection-tabs'); | |
71 for (let tab of tabCollection.tabs.values()) { | |
72 let tabItemNode = document.importNode(this.tabItemTemplate.content, | |
73 true); | |
74 | |
75 tabItemNode.querySelector('.tab-item').dataset.tabUuid = tab.uuid; | |
76 | |
77 let tabLinkElement = tabItemNode.querySelector('.tab-link'); | |
78 tabLinkElement.href = tab.url; | |
79 tabLinkElement.title = tab.title; | |
80 | |
81 if (tab.thumbnailUrl !== null) { | |
82 tabItemNode.querySelector('.tab-thumbnail').src = | |
83 tab.thumbnailUrl; | |
84 } | |
85 | |
86 if (tab.favIconUrl !== null) { | |
87 tabItemNode.querySelector('.tab-favicon').src = tab.favIconUrl; | |
88 } | |
89 | |
90 tabItemNode.querySelector('.tab-title').textContent = tab.title; | |
91 | |
92 tabItemNode.querySelector('.remove-tab').title = | |
93 browser.i18n.getMessage('removeTabTitle'); | |
94 | |
95 tabListElement.append(tabItemNode); | |
96 } | |
97 | |
98 return tabCollectionNode; | |
99 } | |
100 | |
101 prependTabCollection(tabCollection) { | |
102 console.log('prepending tab collection', tabCollection, | |
103 'to tab collections'); | |
104 this.tabCollectionsElement | |
105 .prepend(this.createTabCollectionNode(tabCollection)); | |
106 } | |
107 | |
108 replaceTabCollection(tabCollection) { | |
109 console.log('replacing tab collection', tabCollection); | |
110 this.tabCollectionsElement.querySelector(`[data-tab-collection-uuid=` + | |
111 `"${tabCollection.uuid}"]`) | |
112 .replaceWith(this.createTabCollectionNode(tabCollection)); | |
113 } | |
114 | |
115 removeTabCollection(tabCollectionUuid) { | |
116 console.log('removing tab collection %s', tabCollectionUuid); | |
117 this.tabCollectionsElement | |
118 .querySelector(`[data-tab-collection-uuid=` + | |
119 `"${tabCollectionUuid}"]`) | |
120 .remove(); | |
121 | |
122 if (this.tabCollectionsElement.childElementCount === 0) { | |
123 // remove any text nodes so that the :empty CSS selectora applies | |
124 while (this.tabCollectionsElement.firstChild !== null) { | |
125 this.tabCollectionsElement | |
126 .removeChild(this.tabCollectionsElement.firstChild); | |
127 } | |
128 } | |
129 } | |
130 | |
131 sortTabCollections() { | |
132 Array.from(this.tabCollectionsElement.children) | |
133 .map(element => | |
134 [element.querySelector('.tab-collection-ctime').dateTime, | |
135 element]) | |
136 .sort((a, b) => a[0] < b[0] ? 1 : a[0] > b[0] ? -1 : 0) | |
137 .forEach(([, element]) => | |
138 this.tabCollectionsElement.append(element)); | |
139 } | |
140 | |
141 onMessage(message, port) { | |
142 console.log('received message', message, 'on port', port); | |
143 switch (message.type) { | |
144 case 'tabCollections': | |
145 this.initTabCollections(message.tabCollections); | |
146 break; | |
147 case 'tabCollectionCreated': | |
148 this.prependTabCollection(message.tabCollection); | |
149 break; | |
150 case 'tabCollectionRemoved': | |
151 this.removeTabCollection(message.tabCollectionUuid); | |
152 break; | |
153 case 'tabCollectionChanged': | |
154 this.replaceTabCollection(message.tabCollection); | |
155 break; | |
156 } | |
157 this.sortTabCollections(); | |
158 } | |
159 | |
160 handleEvent(ev) { | |
161 console.log('DOM event', ev); | |
162 if (ev.type === 'click') { | |
163 ev.preventDefault(); | |
164 if (ev.target.classList.contains('restore-tab-collection')) { | |
165 // restore tab collection | |
166 let tabCollectionUuid = ev.target.closest('.tab-collection') | |
167 .dataset.tabCollectionUuid; | |
168 this.port.postMessage({ | |
169 type: 'restoreTabCollection', | |
170 tabCollectionUuid, | |
171 windowId: browser.windows.WINDOW_ID_CURRENT | |
172 }); | |
173 } else if (ev.target.classList.contains('remove-tab-collection')) { | |
174 // remove tab collection | |
175 let tabCollectionUuid = ev.target.closest('.tab-collection') | |
176 .dataset.tabCollectionUuid; | |
177 this.port.postMessage({ | |
178 type: 'removeTabCollection', | |
179 tabCollectionUuid | |
180 }); | |
181 } else if (ev.target.classList.contains('remove-tab')) { | |
182 // remove tab from collection | |
183 let tabItemElement = ev.target.closest('.tab-item'); | |
184 let tabCollectionUuid = | |
185 tabItemElement.closest('.tab-collection') | |
186 .dataset.tabCollectionUuid; | |
187 let tabUuid = tabItemElement.dataset.tabUuid; | |
188 this.port.postMessage({ | |
189 type: 'removeTab', | |
190 tabCollectionUuid, | |
191 tabUuid | |
192 }); | |
193 } else { | |
194 let tabItemElement = ev.target.closest('.tab-item'); | |
195 if (tabItemElement !== null) { | |
196 // restore tab from collection | |
197 let tabCollectionUuid = | |
198 tabItemElement.closest('.tab-collection') | |
199 .dataset.tabCollectionUuid; | |
200 let tabUuid = tabItemElement.dataset.tabUuid; | |
201 this.port.postMessage({ | |
202 type: 'restoreTab', | |
203 tabCollectionUuid, | |
204 tabUuid, | |
205 windowId: browser.windows.WINDOW_ID_CURRENT | |
206 }); | |
207 } | |
208 } | |
209 } | |
210 } | |
211 } | |
212 | |
213 browser.windows.getCurrent().then(currentWindow => { | |
214 // disable the sidebar for incognito windows | |
215 if (currentWindow.incognito) { | |
216 document.querySelector('#message').textContent = | |
217 browser.i18n.getMessage('incognitoModeMessage'); | |
218 return; | |
219 } | |
220 | |
221 tabManager = new TabManager(); | |
222 }); |