diff options
author | Jordan Cannon <LiteracyFanatic@gmail.com> | 2020-03-04 08:43:40 -0600 |
---|---|---|
committer | Jordan Cannon <LiteracyFanatic@gmail.com> | 2020-03-07 07:24:52 -0600 |
commit | b308f5693bbe80975346c8972525aa900ff04195 (patch) | |
tree | 2b6b3247f42afbf2e0fbd3b3857aec1d38eeb394 /qutebrowser/javascript | |
parent | df45e7401ee76a5243a260179a32e0a11c330a9b (diff) | |
download | qutebrowser-b308f5693bbe80975346c8972525aa900ff04195.tar.gz qutebrowser-b308f5693bbe80975346c8972525aa900ff04195.zip |
Use a shared window proxy for Greasemonkey scripts
Using a new proxy for each script causes incompatability with some
Greasemonkey scripts. See #5266.
Diffstat (limited to 'qutebrowser/javascript')
-rw-r--r-- | qutebrowser/javascript/greasemonkey_wrapper.js | 86 |
1 files changed, 43 insertions, 43 deletions
diff --git a/qutebrowser/javascript/greasemonkey_wrapper.js b/qutebrowser/javascript/greasemonkey_wrapper.js index 440a11904..7bfabc635 100644 --- a/qutebrowser/javascript/greasemonkey_wrapper.js +++ b/qutebrowser/javascript/greasemonkey_wrapper.js @@ -145,47 +145,47 @@ } }; + const unsafeWindow = window; {% if use_proxy %} - /* - * Try to give userscripts an environment that they expect. Which - * seems to be that the global window object should look the same as - * the page's one and that if a script writes to an attribute of - * window it should be able to access that variable in the global - * scope. - * Use a Proxy to stop scripts from actually changing the global - * window (that's what unsafeWindow is for). - * Use the "with" statement to make the proxy provide what looks - * like global scope. - * - * There are other Proxy functions that we may need to override. - * set, get and has are definitely required. - */ - const unsafeWindow = window; - const qute_gm_window_shadow = {}; // stores local changes to window - const qute_gm_windowProxyHandler = { - get: function(target, prop) { - if (prop in qute_gm_window_shadow) - return qute_gm_window_shadow[prop]; - if (prop in target) { - if (typeof target[prop] === 'function' && typeof target[prop].prototype == 'undefined') - // Getting TypeError: Illegal Execution when callers try to execute - // eg addEventListener from here because they were returned - // unbound - return target[prop].bind(target); - return target[prop]; - } - }, - set: function(target, prop, val) { - return qute_gm_window_shadow[prop] = val; - }, - has: function(target, key) { - return key in qute_gm_window_shadow || key in target; - } - }; - const qute_gm_window_proxy = new Proxy( - unsafeWindow, qute_gm_windowProxyHandler); - - with (qute_gm_window_proxy) { + /* + * Try to give userscripts an environment that they expect. Which seems + * to be that the global window object should look the same as the page's + * one and that if a script writes to an attribute of window all other + * scripts should be able to access that variable in the global scope. + * Use a Proxy to stop scripts from actually changing the global window + * (that's what unsafeWindow is for). Use the "with" statement to make + * the proxy provide what looks like global scope. + * + * There are other Proxy functions that we may need to override. set, + * get and has are definitely required. + */ + + if (!window._qute_gm_window_proxy) { + const qute_gm_window_shadow = {}; // stores local changes to window + const qute_gm_windowProxyHandler = { + get: function (target, prop) { + if (prop in qute_gm_window_shadow) + return qute_gm_window_shadow[prop]; + if (prop in target) { + if (typeof target[prop] === 'function' && typeof target[prop].prototype == 'undefined') + // Getting TypeError: Illegal Execution when callers try + // to execute eg addEventListener from here because they + // were returned unbound + return target[prop].bind(target); + return target[prop]; + } + }, + set: function(target, prop, val) { + return qute_gm_window_shadow[prop] = val; + }, + has: function(target, key) { + return key in qute_gm_window_shadow || key in target; + } + }; + window._qute_gm_window_proxy = new Proxy(unsafeWindow, qute_gm_windowProxyHandler); + } + const qute_gm_window_proxy = window._qute_gm_window_proxy; + with (qute_gm_window_proxy) { // We can't return `this` or `qute_gm_window_proxy` from // `qute_gm_window_proxy.get('window')` because the Proxy implementation // does typechecking on read-only things. So we have to shadow `window` @@ -194,10 +194,10 @@ // ====== The actual user script source ====== // {{ scriptSource }} // ====== End User Script ====== // - }; + }; {% else %} - // ====== The actual user script source ====== // + // ====== The actual user script source ====== // {{ scriptSource }} - // ====== End User Script ====== // + // ====== End User Script ====== // {% endif %} })(); |