mirror of https://github.com/gorhill/uBlock.git
Add logging ability to `acs` scriptlet, for the benefit of filter list
maintainers. To enable logging, use the JSON approach to pass parameters to `acs` scriptlet. Example: ..##+js(acs, { "target": "document.oncontextmenu", "log": true }) Whereas "target", "needle", and "context" correspond to their respective positional argument. Using JSON form to pass parameters allows to specify extra paramters to facilitate debugging of that scriptlet: - `"log": true` => output useful information at the dev console. - `"debug": true` => break at key locations in the scriptlet. The added logging/debugging capabilities work only in the dev build of uBO or if the advanced setting `filterAuthorMode` is set to `true`.
This commit is contained in:
parent
95bd52d01f
commit
edbe96a401
|
@ -49,6 +49,12 @@ function safeSelf() {
|
|||
'RegExp': self.RegExp,
|
||||
'RegExp_test': self.RegExp.prototype.test,
|
||||
'RegExp_exec': self.RegExp.prototype.exec,
|
||||
'safeLog': console.log.bind(console),
|
||||
'uboLog': function(msg) {
|
||||
if ( msg !== '' ) {
|
||||
this.safeLog(`[uBO] ${msg}`);
|
||||
}
|
||||
},
|
||||
};
|
||||
scriptletGlobals.set('safeSelf', safe);
|
||||
return safe;
|
||||
|
@ -90,6 +96,28 @@ function getExceptionToken() {
|
|||
return token;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
builtinScriptlets.push({
|
||||
name: 'should-debug.fn',
|
||||
fn: shouldDebug,
|
||||
});
|
||||
function shouldDebug(details) {
|
||||
if ( details instanceof Object === false ) { return false; }
|
||||
return scriptletGlobals.has('canDebug') && details.debug;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
builtinScriptlets.push({
|
||||
name: 'should-log.fn',
|
||||
fn: shouldLog,
|
||||
});
|
||||
function shouldLog(details) {
|
||||
if ( details instanceof Object === false ) { return false; }
|
||||
return scriptletGlobals.has('canDebug') && details.log;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Injectable scriptlets
|
||||
|
@ -105,6 +133,9 @@ builtinScriptlets.push({
|
|||
dependencies: [
|
||||
'pattern-to-regex.fn',
|
||||
'get-exception-token.fn',
|
||||
'safe-self.fn',
|
||||
'should-debug.fn',
|
||||
'should-log.fn',
|
||||
],
|
||||
});
|
||||
// Issues to mind before changing anything:
|
||||
|
@ -117,9 +148,10 @@ function abortCurrentScript(
|
|||
const details = typeof arg1 !== 'object'
|
||||
? { target: arg1, needle: arg2, context: arg3 }
|
||||
: arg1;
|
||||
const { target, needle, context } = details;
|
||||
const { target = '', needle = '', context = '' } = details;
|
||||
if ( typeof target !== 'string' ) { return; }
|
||||
if ( target === '' ) { return; }
|
||||
const safe = safeSelf();
|
||||
const reNeedle = patternToRegex(needle);
|
||||
const reContext = patternToRegex(context);
|
||||
const thisScript = document.currentScript;
|
||||
|
@ -141,6 +173,8 @@ function abortCurrentScript(
|
|||
value = owner[prop];
|
||||
desc = undefined;
|
||||
}
|
||||
const log = shouldLog(details);
|
||||
const debug = shouldDebug(details);
|
||||
const exceptionToken = getExceptionToken();
|
||||
const scriptTexts = new WeakMap();
|
||||
const getScriptText = elem => {
|
||||
|
@ -165,13 +199,19 @@ function abortCurrentScript(
|
|||
return text;
|
||||
};
|
||||
const validate = ( ) => {
|
||||
if ( debug ) { debugger; } // jshint ignore: line
|
||||
const e = document.currentScript;
|
||||
if ( e instanceof HTMLScriptElement === false ) { return; }
|
||||
if ( e === thisScript ) { return; }
|
||||
if ( e.src !== '' && log ) { safe.uboLog(`src: ${e.src}`); }
|
||||
if ( reContext.test(e.src) === false ) { return; }
|
||||
if ( reNeedle.test(getScriptText(e)) === false ) { return; }
|
||||
const scriptText = getScriptText(e);
|
||||
if ( log ) { safe.uboLog(`script text: ${scriptText}`); }
|
||||
if ( reNeedle.test(scriptText) === false ) { return; }
|
||||
throw new ReferenceError(exceptionToken);
|
||||
};
|
||||
if ( debug ) { debugger; } // jshint ignore: line
|
||||
try {
|
||||
Object.defineProperty(owner, prop, {
|
||||
get: function() {
|
||||
validate();
|
||||
|
@ -188,6 +228,9 @@ function abortCurrentScript(
|
|||
}
|
||||
}
|
||||
});
|
||||
} catch(ex) {
|
||||
if ( log ) { safe.uboLog(ex); }
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -298,7 +341,6 @@ function abortOnStackTrace(
|
|||
const safe = safeSelf();
|
||||
const reNeedle = patternToRegex(needle);
|
||||
const exceptionToken = getExceptionToken();
|
||||
const log = console.log.bind(console);
|
||||
const ErrorCtor = self.Error;
|
||||
const mustAbort = function(err) {
|
||||
let docURL = self.location.href;
|
||||
|
@ -336,7 +378,7 @@ function abortOnStackTrace(
|
|||
logLevel === '2' && r ||
|
||||
logLevel === '3' && !r
|
||||
) {
|
||||
log(stack.replace(/\t/g, '\n'));
|
||||
safe.uboLog(stack.replace(/\t/g, '\n'));
|
||||
}
|
||||
return r;
|
||||
};
|
||||
|
@ -392,6 +434,8 @@ builtinScriptlets.push({
|
|||
dependencies: [
|
||||
'pattern-to-regex.fn',
|
||||
'safe-self.fn',
|
||||
'should-debug.fn',
|
||||
'should-log.fn',
|
||||
],
|
||||
});
|
||||
// https://github.com/uBlockOrigin/uAssets/issues/9123#issuecomment-848255120
|
||||
|
@ -408,7 +452,8 @@ function addEventListenerDefuser(
|
|||
const safe = safeSelf();
|
||||
const reType = patternToRegex(type);
|
||||
const rePattern = patternToRegex(pattern);
|
||||
const logfn = console.log.bind(console);
|
||||
const log = shouldLog(details);
|
||||
const debug = shouldDebug(details);
|
||||
const proto = self.EventTarget.prototype;
|
||||
proto.addEventListener = new Proxy(proto.addEventListener, {
|
||||
apply: function(target, thisArg, args) {
|
||||
|
@ -422,17 +467,10 @@ function addEventListenerDefuser(
|
|||
const matchesHandler = safe.RegExp_test.call(rePattern, handler);
|
||||
const matchesEither = matchesType || matchesHandler;
|
||||
const matchesBoth = matchesType && matchesHandler;
|
||||
if (
|
||||
details.log === 1 && matchesBoth ||
|
||||
details.log === 2 && matchesEither ||
|
||||
details.log === 3
|
||||
) {
|
||||
logfn(`uBO: addEventListener('${type}', ${handler})`);
|
||||
if ( log === 1 && matchesBoth || log === 2 && matchesEither || log === 3 ) {
|
||||
safe.uboLog(`addEventListener('${type}', ${handler})`);
|
||||
}
|
||||
if (
|
||||
details.debug === 1 && matchesBoth ||
|
||||
details.debug === 2 && matchesEither
|
||||
) {
|
||||
if ( debug === 1 && matchesBoth || debug === 2 && matchesEither ) {
|
||||
debugger; // jshint ignore:line
|
||||
}
|
||||
if ( matchesBoth ) { return; }
|
||||
|
|
|
@ -47,6 +47,8 @@ const scriptletDB = new StaticExtFilteringHostnameDB(1);
|
|||
let acceptedCount = 0;
|
||||
let discardedCount = 0;
|
||||
|
||||
let isDevBuild;
|
||||
|
||||
const scriptletFilteringEngine = {
|
||||
get acceptedCount() {
|
||||
return acceptedCount;
|
||||
|
@ -386,6 +388,15 @@ scriptletFilteringEngine.retrieve = function(request, options = {}) {
|
|||
|
||||
if ( cacheDetails.code === '' ) { return; }
|
||||
|
||||
const scriptletGlobals = [];
|
||||
|
||||
if ( isDevBuild === undefined ) {
|
||||
isDevBuild = vAPI.webextFlavor.soup.has('devbuild');
|
||||
}
|
||||
if ( isDevBuild || µb.hiddenSettings.filterAuthorMode ) {
|
||||
scriptletGlobals.push([ 'canDebug', true ]);
|
||||
}
|
||||
|
||||
const out = [
|
||||
'(function() {',
|
||||
'// >>>> start of private namespace',
|
||||
|
@ -393,7 +404,7 @@ scriptletFilteringEngine.retrieve = function(request, options = {}) {
|
|||
µb.hiddenSettings.debugScriptlets ? 'debugger;' : ';',
|
||||
'',
|
||||
// For use by scriptlets to share local data among themselves
|
||||
'const scriptletGlobals = new Map();',
|
||||
`const scriptletGlobals = new Map(${JSON.stringify(scriptletGlobals, null, 2)});`,
|
||||
'',
|
||||
cacheDetails.code,
|
||||
'',
|
||||
|
|
Loading…
Reference in New Issue