@@ -16,6 +16,11 @@ const backgroundPage = browser.runtime.getBackgroundPage();
16
16
17
17
if ( ! backgroundPage )
18
18
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" ) ;
19
24
20
25
function debug ( ) {
21
26
//console.debug.apply(console, arguments);
@@ -32,6 +37,18 @@ function handleError() {
32
37
console . error . apply ( console , message ) ;
33
38
}
34
39
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
+
35
52
function logFunction ( name , ...args ) {
36
53
debug ( name , ...args ) ;
37
54
}
@@ -78,22 +95,18 @@ const watchedTabs = {};
78
95
79
96
async function reopenIn ( originTab , targetTab ) {
80
97
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 ) ;
87
104
const updateRequest = {
88
- active : originTab . active
105
+ active : activate
89
106
} ;
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 ) ;
97
110
}
98
111
99
112
async function findDuplicate ( tab ) {
@@ -143,7 +156,7 @@ tabs.onCreated.addListener(tab => {
143
156
setTimeout ( ( ) => delete watchedTabs [ tabId ] , 10000 ) ;
144
157
} ) ;
145
158
146
- tabs . onUpdated . addListener ( ( tabId , change , tab ) => {
159
+ tabs . onUpdated . addListener ( wrapErrors ( async ( tabId , change , tab ) => {
147
160
if ( ! change . url )
148
161
return ;
149
162
const watched = watchedTabs [ tabId ] ;
@@ -152,12 +165,40 @@ tabs.onUpdated.addListener((tabId, change, tab) => {
152
165
return ;
153
166
}
154
167
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" ] ) ;
161
202
162
203
getMatcher ( ) . catch ( handleError ) ;
163
204
0 commit comments