Skip to content

Commit fa3f803

Browse files
committed
Fixes #16. Intercept _self anchor navigation
1 parent 575a126 commit fa3f803

File tree

2 files changed

+67
-23
lines changed

2 files changed

+67
-23
lines changed

background.js

+62-21
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ const backgroundPage = browser.runtime.getBackgroundPage();
1616

1717
if (!backgroundPage)
1818
throw new Error("Background page is not found");
19+
20+
const onBeforeRequest = browser.webRequest.onBeforeRequest;
21+
22+
if (!onBeforeRequest)
23+
throw new Error("onBeforeRequest is not available");
1924

2025
function debug() {
2126
//console.debug.apply(console, arguments);
@@ -32,6 +37,18 @@ function handleError() {
3237
console.error.apply(console, message);
3338
}
3439

40+
function wrapErrors(asyncFunction) {
41+
function wrapper(...args) {
42+
try {
43+
return Promise.resolve(asyncFunction(...args)).catch(handleError);
44+
} catch (e) {
45+
handleError(e);
46+
}
47+
}
48+
return wrapper;
49+
}
50+
51+
3552
function logFunction(name, ...args) {
3653
debug(name, ...args);
3754
}
@@ -78,22 +95,18 @@ const watchedTabs = {};
7895

7996
async function reopenIn(originTab, targetTab) {
8097
logFunction("reopenIn", originTab, targetTab);
81-
try {
82-
await tabs.remove(originTab.id);
83-
} catch (e) {
84-
handleError("Failed to remove a tab: ", e);
85-
return;
86-
}
98+
await tabs.remove(originTab.id);
99+
await navigate(targetTab, originTab.url, originTab.active);
100+
}
101+
102+
async function navigate(targetTab, url, activate) {
103+
logFunction("navigate", targetTab, url, activate);
87104
const updateRequest = {
88-
active: originTab.active
105+
active: activate
89106
};
90-
if (targetTab.url !== originTab.url)
91-
updateRequest.url = originTab.url;
92-
try {
93-
await tabs.update(targetTab.id, updateRequest);
94-
} catch (e) {
95-
handleError("Failed to perform navigation", e);
96-
}
107+
if (targetTab.url !== url)
108+
updateRequest.url = url;
109+
await tabs.update(targetTab.id, updateRequest);
97110
}
98111

99112
async function findDuplicate(tab) {
@@ -143,7 +156,7 @@ tabs.onCreated.addListener(tab => {
143156
setTimeout(() => delete watchedTabs[tabId], 10000);
144157
});
145158

146-
tabs.onUpdated.addListener((tabId, change, tab) => {
159+
tabs.onUpdated.addListener(wrapErrors(async (tabId, change, tab) => {
147160
if (!change.url)
148161
return;
149162
const watched = watchedTabs[tabId];
@@ -152,12 +165,40 @@ tabs.onUpdated.addListener((tabId, change, tab) => {
152165
return;
153166
}
154167
logFunction("onUpdated", tabId, change, tab);
155-
tryReuseTab(tab)
156-
.then((wasReused) => {
157-
if (wasReused) delete watchedTabs[tabId];
158-
})
159-
.catch(e => handleError(e))
160-
});
168+
const wasReused = await tryReuseTab(tab);
169+
if (wasReused) delete watchedTabs[tabId];
170+
}));
171+
172+
onBeforeRequest.addListener(wrapErrors(async requestDetails => {
173+
const tabId = requestDetails.tabId;
174+
if (tabId == -1) {
175+
return;
176+
}
177+
const sourceTab = await tabs.get(tabId);
178+
if (!sourceTab)
179+
throw new Error(`Invalid tabId: ${tabId}`);
180+
logFunction("onBeforeRequest", requestDetails, sourceTab);
181+
const targetState = {
182+
id: sourceTab.id,
183+
openerTabId: sourceTab.openerTabId,
184+
url: requestDetails.url,
185+
pinned: sourceTab.pinned,
186+
active: sourceTab.active,
187+
hidden: sourceTab.hidden
188+
};
189+
const duplicate = await findDuplicate(targetState);
190+
if (duplicate) {
191+
if (watchedTabs[tabId]) {
192+
await tabs.remove(tabId);
193+
}
194+
await navigate(duplicate, requestDetails.url, sourceTab.active);
195+
debug(`Cancelling in-tab navigation to ${requestDetails.url}`);
196+
return {
197+
redirectUrl:"javascript:"
198+
};
199+
}
200+
return {};
201+
}), {urls: ["<all_urls>"], types: ["main_frame"]}, ["blocking"]);
161202

162203
getMatcher().catch(handleError);
163204

manifest.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
"name": "Reuse Tab",
66
"permissions": [
77
"tabs",
8-
"storage"
8+
"storage",
9+
"webRequest",
10+
"webRequestBlocking",
11+
"<all_urls>"
912
],
1013
"incognito": "not_allowed",
1114
"background": {
@@ -14,7 +17,7 @@
1417
"options_ui": {
1518
"page": "options.html"
1619
},
17-
"version": "0.12",
20+
"version": "1.0",
1821
"author": "Vasili Gulevich",
1922
"icons": {
2023
"48": "icon.png"

0 commit comments

Comments
 (0)