sizzlemctwizzle / GM_config

A lightweight, reusable, cross-browser graphical settings framework for inclusion in user scripts.

Home Page:https://github.com/sizzlemctwizzle/GM_config/wiki

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support GM4+ Async API

kupietools opened this issue · comments

The settings popup appears to only store the values per domain. How do I get it to store values for my script so I can enter them once and have them be constant wherever the script runs?

Looking at the source code, it appears that GM_config doesn't support the new Greasemonkey 4 APIs so, if you're running it on Greasemonkey 4, the answer is "You can't because, if the Greasemonkey 3 APIs are missing, it falls back to site-specific storage."

Here are the relevant lines:

  var isGM = typeof GM_getValue != 'undefined' &&
             typeof GM_getValue('a', 'b') != 'undefined',
      setValue, getValue, stringify, parser;

  // Define value storing and reading API
  if (!isGM) {
    setValue = function (name, value) {
      return localStorage.setItem(name, value);
    };
    getValue = function(name, def){
      var s = localStorage.getItem(name);
      return s == null ? def : s
    };

    // We only support JSON parser outside GM
    stringify = JSON.stringify;
    parser = JSON.parse;
  } else {
    setValue = GM_setValue;
    getValue = GM_getValue;
    stringify = typeof JSON == "undefined" ?
      function(obj) {
        return obj.toSource();
    } : JSON.stringify;
    parser = typeof JSON == "undefined" ?
      function(jsonData) {
        return (new Function('return ' + jsonData + ';'))();
    } : JSON.parse;
}

The Greasemonkey 4 APIs are GM.getValue and GM.setValue and return promises.

You can also @require the polyfill designed for this problem (supporting the new and old APIs in both GM4 and older version): https://openuserjs.org/libs/sizzle/gm4-polyfill

Just make sure to get the metadata correct. Obviously GM_config should eventually handle this on its own.

Just checked the source of the polyfill and I don't think it provides two-way support. Looks like you must use the new API syntax, which GM_config does do yet.

I don't have time to properly test things, but, if you don't beat me to it, I'll probably put up a fork that's been retrofitted to use the Greasemonkey 4 APIs within the next month, since ESR 52 is going to go away soon and my script based on GM_config is one of the few things I still have to migrate over.

@sizzlemctwizzle

Assume you meant "does not do yet"... TM and VM still support the synchronous API as well.

So is anyone working on this? The polyfill doesn't seem to work for me. GM_config keeps using localStorage. I don't think it's possible to be compatible both ways, because you can't really fake a Promise, can you?

Other concerns came up that were more pressing... partly because, at the moment, the only script I've made public which relies on GM_config is specific to a single site where I'm OK with allowing un-privlleged user data to persist.

I don't think it's possible to be compatible both ways, because you can't really fake a Promise, can you?

Of course you can fake a promise. Various libraries (eg. jQuery) provided their own promise implementations before they started to become standardized.

The problem is that you can't use an asynchronous API (the promises provided by GM4) to fake a synchronous API (the blocking calls provided by GM3 and its clones), which is why the polyfill isn't working for you. GM_config has to be upgraded to use the GM4 APIs before the polyfill can be used to make it work on things which only offer the old APIs.

I do still want to do that, but I have various things of my own which are more urgently in need of an update. (eg. a Linux utility which needs to be updated from GTK+ 2.x to GTK+ 3.x before Kubuntu Linux 14.04 LTS falls out of support in a few months.)

PR #111 will finally close this issue once it gets merged.

Closed by #111

@sizzlemctwizzle
Hmm... Doing some further checking I'm still getting local storage (confirmed by storage inspector Ctrl+Shift+I then storage tab) for OUJS-1 and I use the default .save built-in for GMC.

Local Storage tab

Reopening until resolved. (confirmed in a squeeky clean Fx profile too)

Ref:

  1. GM_config/gm_config.js

    Lines 496 to 497 in 2fd07be

    let isGM4 = typeof GM === 'object' && typeof GM.getValue !== 'undefined' &&
    typeof GM.setValue !== 'undefined';

  2. GM_config/gm_config.js

    Lines 498 to 499 in 2fd07be

    let isGM = isGM4 || (typeof GM_getValue !== 'undefined' &&
    typeof GM_getValue('a', 'b') !== 'undefined');

  3. GM_config/gm_config.js

    Lines 513 to 519 in 2fd07be

    let getValue = isGM ? GM_getValue
    : (name, def) => {
    let s = localStorage.getItem(name);
    return s !== null ? s : def;
    };
    let setValue = isGM ? GM_setValue
    : (name, value) => localStorage.setItem(name, value);

Section 1 resultant is showing as undefined at typeof GM with Greasemonkey 4.11 on Fx Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/113.0 and Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0.

NOTE(s):

  • If I do a "this to that" equivalent for GM then I can get some indication that customGM could be in scope for the logic to work out with section 1.
  • If I do the same typeof GM inside of an alert function outside of GMC I get object.

@Martii

Hmm... Doing some further checking I'm still getting local storage

Okay, I got it to use the GM APIs with GM/Fx, TM/Fx, and TM/Chrome. See 7b3922a. I couldn't find a better way to do this. Definitely a case of function over form with this one. Just be happy it works (mostly talking to self here).
Edit: I did find a better way.

@sizzlemctwizzle

Presuming this works (and it doesn't... will tack onto your new issue... when you are finished making changes) in tests can those "global"s identifiers be made into const to prevent tampering?

can those "global"s identifiers be made into const to prevent tampering?

I found a cleaner way to do this. See: e0a1d0f

Presuming this works (and it doesn't...

No idea why it wasn't working for you, but the new way was much easier to test since the code is simpler. So, I was pretty confident that I got it working this time too, but you kind of just took the wind out of my sails.

Retest PASS on SM and Fx with e0a1d0f ... You are the man!! :) Thank you. Now to go trigger an OUJS-1 update so people get the newest whenever you are finished.

No idea why it wasn't working for you...

was an issue with getValue in OUJS-1 however when I was starting to type/paste it, I noticed you found...

... the new way was much easier to test.

... which is awesome. 😺

but you kind of just took the wind out of my sails.

Sorry... just the messenger. It took some wind out of me as well but you rose above the occasion as usual. Thank you again.

Retest PASS on SM and Fx

Glad you could confirm my results (and on SM as well).

whenever you are finished.

I'm finished with this issue now (at least I hope I put this to bed).

but you rose above the occasion

The first implementation just didn't sit right with me. I knew I needed to get GM in scope... so I did.

just the messenger

And I'm glad, because I honestly don't know how long GM_config would have been using local storage without your messages.