Skip to content
Permalink
Browse files
Improve window.open-defuser scriptlet
The new syntax deprecate the old syntax, though the
old syntax will still be supported until it's no
longer used in mainstream filter lists.

The new syntax is:

    example.com##+js(window.open-defuser, pattern, seconds)

`pattern`:

A pattern to match for the defusing to take place.
Patterns which starts and ends with `/` will be
interpreted as regular expressions. To NOT match a
pattern, prefix with `!`.

`seconds`:

If not present, no window will be opened and the
scriptlet will return `null`.

If present and a valid integer value, the defuser
will return a valid window object even though no
popup window is opened. The returned window object
will cease to be valid after the specified number
of seconds.
  • Loading branch information
gorhill authored and JustOff committed Jun 18, 2020
1 parent 105578d commit 503d45961e92108935cd12a105ca0fb0fb11bc66
Showing with 57 additions and 17 deletions.
  1. +57 −17 assets/resources/resources.txt
@@ -1547,30 +1547,70 @@ abort-current-inline-script.js application/javascript
})();


# https://github.com/uBlockOrigin/uAssets/commit/a6c77af4afb45800d4fd7c268a2a5eab5a64daf3#commitcomment-24611606
# https://github.com/gorhill/uBlock/commit/b27848a060eee961e2403192097448467b3bc7b5
window.open-defuser.js application/javascript
(function() {
var wo = window.open,
target = '{{1}}',
needle = '{{2}}';
if ( target === '' || target === '{{1}}' ) {
target = false;
let arg1 = '{{1}}';
if ( arg1 === '{{1}}' ) { arg1 = ''; }
let arg2 = '{{2}}';
if ( arg2 === '{{2}}' ) { arg2 = ''; }
let arg3 = '{{3}}';
if ( arg3 === '{{3}}' ) { arg3 = ''; }
const newSyntax = /^[01]?$/.test(arg1) === false;
let pattern = '';
let targetResult = true;
let autoRemoveAfter = -1;
if ( newSyntax ) {
pattern = arg1;
if ( pattern.startsWith('!') ) {
targetResult = false;
pattern = pattern.slice(1);
}
autoRemoveAfter = parseInt(arg2);
if ( isNaN(autoRemoveAfter) ) {
autoRemoveAfter = -1;
}
} else {
target = !(+target);
pattern = arg2;
if ( arg1 === '0' ) {
targetResult = false;
}
}
if ( needle === '' || needle === '{{2}}' ) {
needle = '.?';
} else if ( /^\/.+\/$/.test(needle) ) {
needle = needle.slice(1,-1);
if ( pattern === '' ) {
pattern = '.?';
} else if ( /^\/.+\/$/.test(pattern) ) {
pattern = pattern.slice(1,-1);
} else {
needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
pattern = pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
needle = new RegExp(needle);
window.open = (function(a) {
if ( needle.test(a) === target ) {
return wo.apply(window, arguments);
const rePattern = new RegExp(pattern);
window.open = new Proxy(window.open, {
apply: function(target, thisArg, args) {
const url = args[0];
if ( rePattern.test(url) !== targetResult ) {
return target.apply(thisArg, args);
}
if ( autoRemoveAfter < 0 ) { return null; }
const iframe = document.createElement('iframe');
iframe.src = url;
iframe.style.setProperty('display','none', 'important');
iframe.style.setProperty('height','1px', 'important');
iframe.style.setProperty('width','1px', 'important');
document.body.appendChild(iframe);
setTimeout(( ) => iframe.remove(), autoRemoveAfter * 1000);
if ( arg3 === '' ) { return iframe.contentWindow; }
return new Proxy(iframe.contentWindow, {
get: function(target, prop) {
console.log('get', prop, '===', target[prop]);
return target[prop];
},
set: function(target, prop, value) {
console.log('set', prop, '=', value);
target[prop] = value;
},
});
}
}).bind(window);
});
})();


0 comments on commit 503d459

Please sign in to comment.