mirror of https://github.com/gorhill/uBlock.git
[mv3] Use workaround to inject scriptlets in Firefox
Additionally: Use `export UBO_VERSION=local` at the console to build MV3 extension using current version of uBO code base. By default, the version is taken from `./platform/mv3/ubo-version' and usually set to last stable release.
This commit is contained in:
parent
5ec0550581
commit
bb41d9594f
|
@ -417,10 +417,6 @@ function registerSpecific(context) {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
function registerScriptlet(context, scriptletDetails) {
|
function registerScriptlet(context, scriptletDetails) {
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1736575
|
|
||||||
// `MAIN` world not yet supported in Firefox
|
|
||||||
if ( isGecko ) { return; }
|
|
||||||
|
|
||||||
const { before, filteringModeDetails, rulesetsDetails } = context;
|
const { before, filteringModeDetails, rulesetsDetails } = context;
|
||||||
|
|
||||||
const hasBroadHostPermission =
|
const hasBroadHostPermission =
|
||||||
|
@ -476,9 +472,14 @@ function registerScriptlet(context, scriptletDetails) {
|
||||||
matches,
|
matches,
|
||||||
excludeMatches,
|
excludeMatches,
|
||||||
runAt: 'document_start',
|
runAt: 'document_start',
|
||||||
world: 'MAIN',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1736575
|
||||||
|
// `MAIN` world not yet supported in Firefox
|
||||||
|
if ( isGecko === false ) {
|
||||||
|
directive.world = 'MAIN';
|
||||||
|
}
|
||||||
|
|
||||||
// register
|
// register
|
||||||
if ( registered === undefined ) {
|
if ( registered === undefined ) {
|
||||||
context.toAdd.push(directive);
|
context.toAdd.push(directive);
|
||||||
|
|
|
@ -485,8 +485,13 @@ class PSelector {
|
||||||
prime(input) {
|
prime(input) {
|
||||||
const root = input || document;
|
const root = input || document;
|
||||||
if ( this.selector === '' ) { return [ root ]; }
|
if ( this.selector === '' ) { return [ root ]; }
|
||||||
if ( input !== document && /^ [>+~]/.test(this.selector) ) {
|
if ( input !== document ) {
|
||||||
|
const c0 = this.selector.charCodeAt(0);
|
||||||
|
if ( c0 === 0x2B /* + */ || c0 === 0x7E /* ~ */ ) {
|
||||||
return Array.from(PSelectorSpathTask.qsa(input, this.selector));
|
return Array.from(PSelectorSpathTask.qsa(input, this.selector));
|
||||||
|
} else if ( c0 === 0x3E /* > */ ) {
|
||||||
|
return Array.from(input.querySelectorAll(`:scope ${this.selector}`));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return Array.from(root.querySelectorAll(this.selector));
|
return Array.from(root.querySelectorAll(this.selector));
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,19 +53,23 @@ const commandLineArgs = (( ) => {
|
||||||
return args;
|
return args;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
const platform = commandLineArgs.get('platform') || 'chromium';
|
||||||
const outputDir = commandLineArgs.get('output') || '.';
|
const outputDir = commandLineArgs.get('output') || '.';
|
||||||
const cacheDir = `${outputDir}/../mv3-data`;
|
const cacheDir = `${outputDir}/../mv3-data`;
|
||||||
const rulesetDir = `${outputDir}/rulesets`;
|
const rulesetDir = `${outputDir}/rulesets`;
|
||||||
const scriptletDir = `${rulesetDir}/scripting`;
|
const scriptletDir = `${rulesetDir}/scripting`;
|
||||||
const env = [
|
const env = [
|
||||||
'chromium',
|
platform,
|
||||||
'mv3',
|
'mv3',
|
||||||
'native_css_has',
|
|
||||||
'ublock',
|
'ublock',
|
||||||
'ubol',
|
'ubol',
|
||||||
'user_stylesheet',
|
'user_stylesheet',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if ( platform !== 'firefox' ) {
|
||||||
|
env.push('native_css_has');
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const jsonSetMapReplacer = (k, v) => {
|
const jsonSetMapReplacer = (k, v) => {
|
||||||
|
@ -1222,7 +1226,7 @@ async function main() {
|
||||||
resources: Array.from(requiredRedirectResources).map(path => `/${path}`),
|
resources: Array.from(requiredRedirectResources).map(path => `/${path}`),
|
||||||
matches: [ '<all_urls>' ],
|
matches: [ '<all_urls>' ],
|
||||||
};
|
};
|
||||||
if ( commandLineArgs.get('platform') === 'chromium' ) {
|
if ( platform === 'chromium' ) {
|
||||||
web_accessible_resources.use_dynamic_url = true;
|
web_accessible_resources.use_dynamic_url = true;
|
||||||
}
|
}
|
||||||
manifest.web_accessible_resources = [ web_accessible_resources ];
|
manifest.web_accessible_resources = [ web_accessible_resources ];
|
||||||
|
|
|
@ -167,7 +167,7 @@ export async function commit(rulesetId, path, writeFn) {
|
||||||
content = safeReplace(content, /\$scriptletName\$/, details.name, 0);
|
content = safeReplace(content, /\$scriptletName\$/, details.name, 0);
|
||||||
content = safeReplace(content,
|
content = safeReplace(content,
|
||||||
'self.$argsList$',
|
'self.$argsList$',
|
||||||
JSON.stringify(Array.from(details.args.keys()))
|
JSON.stringify(Array.from(details.args.keys()).map(a => JSON.parse(a)))
|
||||||
);
|
);
|
||||||
content = safeReplace(content,
|
content = safeReplace(content,
|
||||||
'self.$hostnamesMap$',
|
'self.$hostnamesMap$',
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* jshint esversion:11 */
|
/* jshint esversion:11 */
|
||||||
|
/* global cloneInto */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
@ -31,10 +32,14 @@
|
||||||
// Important!
|
// Important!
|
||||||
// Isolate from global scope
|
// Isolate from global scope
|
||||||
|
|
||||||
(function uBOL_$scriptletName$() {
|
// Start of local scope
|
||||||
|
(( ) => {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// Start of injected code
|
||||||
|
const uBOL_$scriptletName$ = function() {
|
||||||
|
|
||||||
const scriptletGlobals = new Map(); // jshint ignore: line
|
const scriptletGlobals = new Map(); // jshint ignore: line
|
||||||
|
|
||||||
const argsList = self.$argsList$;
|
const argsList = self.$argsList$;
|
||||||
|
@ -109,13 +114,58 @@ if ( entitiesMap.size !== 0 ) {
|
||||||
|
|
||||||
// Apply scriplets
|
// Apply scriplets
|
||||||
for ( const i of todoIndices ) {
|
for ( const i of todoIndices ) {
|
||||||
try { $scriptletName$(...JSON.parse(argsList[i])); }
|
try { $scriptletName$(...argsList[i]); }
|
||||||
catch(ex) {}
|
catch(ex) {}
|
||||||
}
|
}
|
||||||
argsList.length = 0;
|
argsList.length = 0;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
};
|
||||||
|
// End of injected code
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// Inject code
|
||||||
|
|
||||||
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1736575
|
||||||
|
// `MAIN` world not yet supported in Firefox, so we inject the code into
|
||||||
|
// 'MAIN' ourself when enviroment in Firefox.
|
||||||
|
|
||||||
|
// Not Firefox
|
||||||
|
if ( typeof wrappedJSObject !== 'object' ) {
|
||||||
|
return uBOL_$scriptletName$();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Firefox
|
||||||
|
{
|
||||||
|
const page = self.wrappedJSObject;
|
||||||
|
let script, url;
|
||||||
|
try {
|
||||||
|
page.uBOL_$scriptletName$ = cloneInto([
|
||||||
|
[ '(', uBOL_$scriptletName$.toString(), ')();' ],
|
||||||
|
{ type: 'text/javascript; charset=utf-8' },
|
||||||
|
], self);
|
||||||
|
const blob = new page.Blob(...page.uBOL_$scriptletName$);
|
||||||
|
url = page.URL.createObjectURL(blob);
|
||||||
|
const doc = page.document;
|
||||||
|
script = doc.createElement('script');
|
||||||
|
script.async = false;
|
||||||
|
script.src = url;
|
||||||
|
(doc.head || doc.documentElement || doc).append(script);
|
||||||
|
} catch (ex) {
|
||||||
|
console.error(ex);
|
||||||
|
}
|
||||||
|
if ( url ) {
|
||||||
|
if ( script ) { script.remove(); }
|
||||||
|
page.URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
|
delete page.uBOL_$scriptletName$;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// End of local scope
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
|
@ -378,8 +378,13 @@ class PSelector {
|
||||||
prime(input) {
|
prime(input) {
|
||||||
const root = input || document;
|
const root = input || document;
|
||||||
if ( this.selector === '' ) { return [ root ]; }
|
if ( this.selector === '' ) { return [ root ]; }
|
||||||
if ( input !== document && /^ ?[>+~]/.test(this.selector) ) {
|
if ( input !== document ) {
|
||||||
|
const c0 = this.selector.charCodeAt(0);
|
||||||
|
if ( c0 === 0x2B /* + */ || c0 === 0x7E /* ~ */ ) {
|
||||||
return Array.from(PSelectorSpathTask.qsa(input, this.selector));
|
return Array.from(PSelectorSpathTask.qsa(input, this.selector));
|
||||||
|
} else if ( c0 === 0x3E /* > */ ) {
|
||||||
|
return Array.from(input.querySelectorAll(`:scope ${this.selector}`));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return Array.from(root.querySelectorAll(this.selector));
|
return Array.from(root.querySelectorAll(this.selector));
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ if [ "$QUICK" != "yes" ]; then
|
||||||
rm -rf $DES
|
rm -rf $DES
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
mkdir -p $DES
|
mkdir -p $DES
|
||||||
cd $DES
|
cd $DES
|
||||||
DES=$(pwd)
|
DES=$(pwd)
|
||||||
|
@ -45,11 +44,15 @@ mkdir -p $DES/css/fonts
|
||||||
mkdir -p $DES/js
|
mkdir -p $DES/js
|
||||||
mkdir -p $DES/img
|
mkdir -p $DES/img
|
||||||
|
|
||||||
UBO_DIR=$(mktemp -d)
|
if [ "$UBO_VERSION" != "local" ]; then
|
||||||
UBO_REPO="https://github.com/gorhill/uBlock.git"
|
|
||||||
UBO_VERSION=$(cat platform/mv3/ubo-version)
|
UBO_VERSION=$(cat platform/mv3/ubo-version)
|
||||||
|
UBO_REPO="https://github.com/gorhill/uBlock.git"
|
||||||
|
UBO_DIR=$(mktemp -d)
|
||||||
echo "*** uBOLite.mv3: Fetching uBO $UBO_VERSION from $UBO_REPO into $UBO_DIR"
|
echo "*** uBOLite.mv3: Fetching uBO $UBO_VERSION from $UBO_REPO into $UBO_DIR"
|
||||||
git clone -q --depth 1 --branch "$UBO_VERSION" "$UBO_REPO" "$UBO_DIR"
|
git clone -q --depth 1 --branch "$UBO_VERSION" "$UBO_REPO" "$UBO_DIR"
|
||||||
|
else
|
||||||
|
UBO_DIR=.
|
||||||
|
fi
|
||||||
|
|
||||||
echo "*** uBOLite.mv3: Copying common files"
|
echo "*** uBOLite.mv3: Copying common files"
|
||||||
cp -R $UBO_DIR/src/css/fonts/* $DES/css/fonts/
|
cp -R $UBO_DIR/src/css/fonts/* $DES/css/fonts/
|
||||||
|
|
Loading…
Reference in New Issue