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
|
* So let's try to use a Proxy on window and the possibly deprecated
|
||||||
* `with` function to make that proxy shadow the global scope.
|
* `with` function to make that proxy shadow the global scope.
|
||||||
* unsafeWindow should still be the actual global page window.
|
* 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;
|
const unsafeWindow = window;
|
||||||
let myWindow = {};
|
const qute_gm_window_shadow = {}; // stores local changes to window
|
||||||
var windowProxyHandler = {
|
const qute_gm_windowProxyHandler = {
|
||||||
get: function(obj, prop) {
|
get: function(obj, prop) {
|
||||||
if (prop in myWindow)
|
if (prop in qute_gm_window_shadow)
|
||||||
return myWindow[prop];
|
return qute_gm_window_shadow[prop];
|
||||||
if (prop in obj) {
|
if (prop in obj) {
|
||||||
if (typeof obj[prop] === 'function' && typeof obj[prop].prototype == 'undefined')
|
if (typeof obj[prop] === 'function' && typeof obj[prop].prototype == 'undefined')
|
||||||
// Getting TypeError: Illegal Execution when callers try to execute
|
// Getting TypeError: Illegal Execution when callers try to execute
|
||||||
@ -178,20 +181,28 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
set: function(target, prop, val) {
|
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 (qute_gm_window_proxy) {
|
||||||
with (myProxy) {
|
// We can't return `this` or `qute_gm_window_proxy` from
|
||||||
// can't assign window directly in with() scope because proxy doesn't
|
// `qute_gm_window_proxy.get('window')` because the Proxy implementation
|
||||||
// allow assinging to things that a readonly on the target.
|
// does typechecking on read-only things. So we have to shadow `window`
|
||||||
function blarg() { // why can't this be anonymous?
|
// more conventionally here. Except we can't do it directly within
|
||||||
var window = myProxy;
|
// 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 }}
|
{{ scriptSource }}
|
||||||
|
// ====== End User Script ====== //
|
||||||
};
|
};
|
||||||
blarg();
|
qute_gm_window_scope();
|
||||||
};
|
};
|
||||||
// ====== End User Script ====== //
|
|
||||||
})();
|
})();
|
||||||
|
Loading…
Reference in New Issue
Block a user