1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-11-20 01:12:38 +01:00

[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:
Raymond Hill 2023-08-11 13:22:25 -04:00
parent 5ec0550581
commit bb41d9594f
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
7 changed files with 89 additions and 21 deletions

View File

@ -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);

View File

@ -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 ) {
return Array.from(PSelectorSpathTask.qsa(input, this.selector)); const c0 = this.selector.charCodeAt(0);
if ( c0 === 0x2B /* + */ || c0 === 0x7E /* ~ */ ) {
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));
} }

View File

@ -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 ];

View File

@ -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$',

View File

@ -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
})(); })();
/******************************************************************************/ /******************************************************************************/

View File

@ -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 ) {
return Array.from(PSelectorSpathTask.qsa(input, this.selector)); const c0 = this.selector.charCodeAt(0);
if ( c0 === 0x2B /* + */ || c0 === 0x7E /* ~ */ ) {
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));
} }

View File

@ -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"
echo "*** uBOLite.mv3: Fetching uBO $UBO_VERSION from $UBO_REPO into $UBO_DIR" UBO_DIR=$(mktemp -d)
git clone -q --depth 1 --branch "$UBO_VERSION" "$UBO_REPO" "$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"
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/