mirror of
https://github.com/gorhill/uBlock.git
synced 2026-03-11 09:04:36 +00:00
Mind potential race condition when dynamically registering scriptlets
In Firefox, scriptlets are dynamically registered as content scripts
to ensure they execute in a timely manner.
The race condition could lead to scriptlet injection failing at
browser launch time in Firefox when the setting "Suspend network
activity until all filter lists are loaded" had been disabled[1],
even after forcing a page reload. Causing the filter lists to
reload would make the issue go away.
[1] Default is enabled in Firefox and it is strongly advised to NOT
change this.
This commit is contained in:
parent
3d2f70ac56
commit
15e832da8a
1 changed files with 8 additions and 4 deletions
|
|
@ -38,6 +38,7 @@ import µb from './background.js';
|
|||
/******************************************************************************/
|
||||
|
||||
const contentScriptRegisterer = {
|
||||
id: 1,
|
||||
hostnameToDetails: new Map(),
|
||||
register(hostname, code) {
|
||||
if ( browser.contentScripts === undefined ) { return false; }
|
||||
|
|
@ -47,9 +48,10 @@ const contentScriptRegisterer = {
|
|||
if ( code === details.code ) {
|
||||
return details.handle instanceof Promise === false;
|
||||
}
|
||||
details.handle.unregister();
|
||||
this.unregisterHandle(details.handle);
|
||||
this.hostnameToDetails.delete(hostname);
|
||||
}
|
||||
const id = this.id++;
|
||||
const promise = browser.contentScripts.register({
|
||||
js: [ { code } ],
|
||||
allFrames: true,
|
||||
|
|
@ -57,12 +59,14 @@ const contentScriptRegisterer = {
|
|||
matchAboutBlank: true,
|
||||
runAt: 'document_start',
|
||||
}).then(handle => {
|
||||
this.hostnameToDetails.set(hostname, { handle, code });
|
||||
return handle;
|
||||
const details = this.hostnameToDetails.get(hostname);
|
||||
if ( details === undefined ) { return; }
|
||||
if ( details.id !== id ) { return; }
|
||||
details.handle = handle;
|
||||
}).catch(( ) => {
|
||||
this.hostnameToDetails.delete(hostname);
|
||||
});
|
||||
this.hostnameToDetails.set(hostname, { handle: promise, code });
|
||||
this.hostnameToDetails.set(hostname, { id, handle: promise, code });
|
||||
return false;
|
||||
},
|
||||
unregister(hostname) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue