Greasemonkey: fix window proxy for new attributes
Previously scripts were failing to find attributes that they assigned to window and then tried to use from the global scope. Eg window.newthing = function() {...}; newthing(...); // newthing is not defined error This wasn't the case for things that already existed in the global scope and were just being overwritten. This change just overrides the `Proxy.has()` function which seems to fix it. Probably the `while` implementation was failing to pick up new attributes because of the lack. I also tweaked some comments and variable names and const-ness to be a little more production ready.
This commit is contained in:
parent
ab50ad735b
commit
23bfe6daa2
@ -161,13 +161,16 @@
|
||||
* So let's try to use a Proxy on window and the possibly deprecated
|
||||
* `with` function to make that proxy shadow the global scope.
|
||||
* unsafeWindow should still be the actual global page window.
|
||||
*
|
||||
* There are other Proxy functions that we may need to override.
|
||||
* set, get and has are definitely required.
|
||||
*/
|
||||
const unsafeWindow = window;
|
||||
let myWindow = {};
|
||||
var windowProxyHandler = {
|
||||
const qute_gm_window_shadow = {}; // stores local changes to window
|
||||
const qute_gm_windowProxyHandler = {
|
||||
get: function(obj, prop) {
|
||||
if (prop in myWindow)
|
||||
return myWindow[prop];
|
||||
if (prop in qute_gm_window_shadow)
|
||||
return qute_gm_window_shadow[prop];
|
||||
if (prop in obj) {
|
||||
if (typeof obj[prop] === 'function' && typeof obj[prop].prototype == 'undefined')
|
||||
// Getting TypeError: Illegal Execution when callers try to execute
|
||||
@ -178,20 +181,28 @@
|
||||
}
|
||||
},
|
||||
set: function(target, prop, val) {
|
||||
return myWindow[prop] = val;
|
||||
return qute_gm_window_shadow[prop] = val;
|
||||
},
|
||||
has: function(target, key) {
|
||||
return key in qute_gm_window_shadow || key in target;
|
||||
}
|
||||
};
|
||||
var myProxy = new Proxy(unsafeWindow, windowProxyHandler);
|
||||
const qute_gm_window_proxy = new Proxy(unsafeWindow, qute_gm_windowProxyHandler);
|
||||
|
||||
// ====== The actual user script source ====== //
|
||||
with (myProxy) {
|
||||
// can't assign window directly in with() scope because proxy doesn't
|
||||
// allow assinging to things that a readonly on the target.
|
||||
function blarg() { // why can't this be anonymous?
|
||||
var window = myProxy;
|
||||
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`
|
||||
// more conventionally here. Except we can't do it directly within
|
||||
// with `with` scope because then it would get assigned to the
|
||||
// proxy and we would get the same problem, so we have to make yet
|
||||
// another nested scope.
|
||||
function qute_gm_window_scope() { // why can't this be anonymous?
|
||||
let window = qute_gm_window_proxy;
|
||||
// ====== The actual user script source ====== //
|
||||
{{ scriptSource }}
|
||||
// ====== End User Script ====== //
|
||||
};
|
||||
blarg();
|
||||
qute_gm_window_scope();
|
||||
};
|
||||
// ====== End User Script ====== //
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user