The dupe candidate is for previous GM versions. The problem is likely somewhere around the different scopes where the userscripts can run, as described here. However, as described here, this functionality is currently undocumented for Greasemonkey 4.0.
I have this Greasemonkey demo script:
// ==UserScript==
// @name GM_getValue, GM_setValue don't work demo
// @version 0.2
// @author You
// @include /^https:\/\/stackoverflow.com/$/
// @grant GM_getValue
// @grant GM_setValue
// @run-at document-end
// ==/UserScript==
console.log('script started');
var id = GM_getValue('testName', 0);
console.log('got ' + id);
id++;
GM_setValue('testName', id);
Calling this with the https://stackoverflow.com/, it is well visible that it is called.
However, I get this error on the console:
Script error:
ReferenceError: GM_getValue is not defined
Stack trace:
userScript@user-script:demosrv/GM_getValue%2C%20GM_setValue%20don%27t%20work%20demo:372:5
scopeWrapper@user-script:demosrv/GM_getValue%2C%20GM_setValue%20don%27t%20work%20demo:381:9
@user-script:demosrv/GM_getValue%2C%20GM_setValue%20don%27t%20work%20demo:361:17
I've digged docs a lot, but it seems GM_{get,set}Value
simply don't want to exist.
Why is it so? How to make it working?
I am using Firefox.
GM_getValue
and GM_setValue
are now obsolete in the GreaseMonkey. The correct methods are GM.setValue
and GM.getValue
.
The GreaseMonkey documentation uses often the old API call names, which is a continuous error in it. Probably it wasn't correctly updated.
As the documentation here says, GM functions can run in different scopes. Unfortunately, I didn't find any info until now, which scopes are existing and how can we switch between them.
The old references manywhere on the net, using GM_getValue
are all obsolete.
The important things:
GM_getValue
were functions with a return value, GM.getValue
and GM.setValue
return Promise
s.await
call.This example on the remote link, works:
// ==UserScript==
// @name Greasemonkey set-and-get Example
// @description Stores and logs a counter of executions.
// @grant GM.setValue
// @grant GM.getValue
// ==/UserScript==
(async () => {
let count_before = await GM.getValue('count', 0);
// Note awaiting the set -- required so the next get sees this set.
await GM.setValue('count', count_before + 1);
// Get the value again, just to demonstrate order-of-operations.
let count_after = await GM.getValue('count');
console.log('Greasemonkey set-and-get Example has run', count_after, 'times');
})();
However, there is still no more clear documentation about the scopes and how can we interact with them.
It seems, there are at least two scopes:
GM.*
API.GM.*
API (and thus, you can make script-local persistent storage), but don't have access to the DOM.Thus, the way to develop new GreaseMonkey scripts for 4.0, is to start with their example script and then follow an incremental trial & error path.
Extension: another trouble I've found: the existence of await
in the script seems to make greasemonkey to ignore the whole script et al. In the example, it doesn't seem to happen, but in more complex scripts, it does. I didn't debug it too deeply - I simply ignore await
and use the Promises on the old way (GM.getValue("myValue").then(function(myValue) { ... });
). It makes the code more crappy, but so is it.