Repository navigation
Expand file tree
/
Copy pathbackground.js
More file actions
187 lines (149 loc) · 5.48 KB
/
Copy pathbackground.js
File metadata and controls
187 lines (149 loc) · 5.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
const LOG_LEVEL = !('update_url' in chrome.runtime.getManifest()) ? 'debug' : null;
const RELOAD_TRIGGER_HOSTNAME = 'reload.extensions';
async function reloadExtensions() {
// Check if a specific extension is selected
const storageData = await chrome.storage.sync.get('selectedExtension');
const selectedExtensionId = storageData.selectedExtension || '';
if (selectedExtensionId) {
// Reload only the selected extension
try {
const ext = await chrome.management.get(selectedExtensionId);
if (ext && ext.installType === 'development' && ext.enabled === true && ext.name !== 'Extensions Reloader') {
await chrome.management.setEnabled(selectedExtensionId, false);
await chrome.management.setEnabled(selectedExtensionId, true);
// re-launch packaged app
if (ext.type === 'packaged_app') {
chrome.management.launchApp(selectedExtensionId);
}
console.log(ext.name + ' reloaded');
}
} catch (error) {
console.error('Error reloading extension:', error);
}
} else {
// find all unpacked extensions and reload them (original behavior)
chrome.management.getAll(async function (extensions) {
for (const ext of extensions) {
if ((ext.installType === 'development') &&
(ext.enabled === true) &&
(ext.name !== 'Extensions Reloader')) {
const extensionId = ext.id;
const extensionType = ext.type;
await chrome.management.setEnabled(extensionId, false);
await chrome.management.setEnabled(extensionId, true);
// re-launch packaged app
if (extensionType === 'packaged_app') {
chrome.management.launchApp(extensionId);
}
console.log(ext.name + ' reloaded');
}
}
});
}
// Reload the current tab based on option value
chrome.storage.sync.get('reloadPage', async function (item) {
if (!item.reloadPage) { return; }
const tab = await getCurrentTab() || {};
const currentUrl = tab.url ? new URL(tab.url) : {};
if (currentUrl.hostname !== RELOAD_TRIGGER_HOSTNAME) {
const storedCurrentTabId = await getStoredCurrentTabId();
chrome.tabs.reload(storedCurrentTabId);
}
});
// show an "OK" badge
chrome.action.setBadgeText({ text: 'OK' });
chrome.action.setBadgeBackgroundColor({ color: '#4cb749' });
// normally setTimeout is unreliable in a service worker, but 1 second should work fine
setTimeout(() => chrome.action.setBadgeText({ text: '' }), 1000);
}
chrome.windows.onFocusChanged.addListener(function (windowId) {
if (windowId !== chrome.windows.WINDOW_ID_NONE) {
refreshState();
}
});
chrome.tabs.onActivated.addListener(async function ({ tabId }) {
await setCurrentTab(tabId);
});
async function getCurrentTab() {
return new Promise(function (resolve) {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
resolve((tabs.length > 0) ? tabs[0] : null);
});
});
}
async function getCurrentTabId() {
const tab = await getCurrentTab();
return tab ? tab.id : 0;
}
async function setCurrentTab(id) {
const storedCurrentTabId = await getStoredCurrentTabId();
if (storedCurrentTabId === id) {
log('skipped setCurrentTab');
return;
}
const previousTabId = storedCurrentTabId;
const currentTabId = id;
await chrome.storage.local.set({ currentTabId, previousTabId });
log('previousTabId', previousTabId, 'currentTabId', currentTabId);
}
chrome.commands.onCommand.addListener(function (command) {
if (command === 'reload') {
reloadExtensions();
}
});
// intercept url
chrome.webRequest.onBeforeRequest.addListener(
function (details) {
if (details.url.indexOf(`http://${RELOAD_TRIGGER_HOSTNAME}`) >= 0) {
chrome.tabs.get(details.tabId, async function (tab) {
const storedCurrentTabId = await getStoredCurrentTabId();
const storedPreviousTabId = await getStoredPreviousTabId();
const pendingURL = tab.pendingUrl ? new URL(tab.pendingUrl) : {};
const isSafeToCloseTab =
pendingURL.hostname === RELOAD_TRIGGER_HOSTNAME &&
!tab.url; // tab has not yet committed => a newly created tab
if (isSafeToCloseTab) {
let tabId = await getCurrentTabId();
log('before close: ', tabId);
await chrome.tabs.remove(details.tabId);
tabId = await getCurrentTabId();
log('after close: ', tabId);
if (tabId !== storedCurrentTabId) {
await setCurrentTab(storedPreviousTabId);
await chrome.tabs.update(storedCurrentTabId, { highlighted: true });
tabId = await getCurrentTabId();
log('after focus tab: ', tabId);
}
await refreshState();
}
reloadExtensions();
});
}
return { cancel: true };
},
{
urls: [`http://${RELOAD_TRIGGER_HOSTNAME}/`],
types: ['main_frame']
}
);
chrome.action.onClicked.addListener(function (/*tab*/) {
reloadExtensions();
});
function log(...args) {
if (LOG_LEVEL === 'debug') {
console.log(...args);
}
}
async function refreshState() {
const tabId = await getCurrentTabId();
await setCurrentTab(tabId);
}
async function getStoredCurrentTabId() {
const storedCurrentTabId = (await chrome.storage.local.get('currentTabId'))['currentTabId'] || 0;
return storedCurrentTabId;
}
async function getStoredPreviousTabId() {
const savedPreviousTabId = (await chrome.storage.local.get('previousTabId'))['previousTabId'] || 0;
return savedPreviousTabId;
}
refreshState();