Greasemonkey: mock the new GM4 promises based API.

Based on the gm4-polyfill.js script from the greasemonkey devs. But not
the same because that script doesn't work for us for a couple of
reasons:

* It assumes all GM_* functions are attributes of `this` which in
this case is the global window object. Which breaks it out of our iife.
It is possible to change what `this` is within the iife but then we
would have to do something weird to ensure the functions were available
with the leading `this.`. And I don't think user javascripts tend to
call GM functions like that anyway, that polyfill script is just making
weird assumptions and then claiming it'll work for "any user script
engine".

* It tries to provide implementations of GM_registerMenuCommand and
GM_getResource text which do unexpected thins or implement a circular
dependency on the new version, respectively.
This commit is contained in:
Jimmy 2018-01-01 16:10:20 +13:00
parent a76c0067e1
commit 33d66676c9

View File

@ -110,6 +110,42 @@
}
}
// Stub these two so that the gm4 polyfill script doesn't try to
// create broken versions as attributes of window.
function GM_getResourceText(caption, commandFunc, accessKey) {
console.error(`${GM_info.script.name} called unimplemented GM_getResourceText`);
}
function GM_registerMenuCommand(caption, commandFunc, accessKey) {
console.error(`${GM_info.script.name} called unimplemented GM_registerMenuCommand`);
}
// Mock the greasemonkey 4.0 async API.
const GM = {};
GM.info = GM_info;
Object.entries({
'log': GM_log,
'addStyle': GM_addStyle,
'deleteValue': GM_deleteValue,
'getValue': GM_getValue,
'listValues': GM_listValues,
'openInTab': GM_openInTab,
'setValue': GM_setValue,
'xmlHttpRequest': GM_xmlhttpRequest,
}).forEach(([newKey, old]) => {
if (old && (typeof GM[newKey] == 'undefined')) {
GM[newKey] = function(...args) {
return new Promise((resolve, reject) => {
try {
resolve(old(...args));
} catch (e) {
reject(e);
}
});
};
}
});
const unsafeWindow = window;
// ====== The actual user script source ====== //