6

There does not appear to be any information on how these functions work. I presume these are Tampermonkey exclusive functions?
It looks like they are designed to allow communication between currently running Tampermonkey scripts; An alternative to continually polling GM_Value storage for changes. Which is a really interesting idea.

But I have no idea how to use them; What values they take in, and what sort of object you get back?
How do you use these three functions, and am I right in their purpose?

GM_getTab(cb)
Get a object that is persistent as long as this tab is open.

GM_saveTab(tab)
Save the tab object to reopen it after a page unload.

GM_getTabs(cb)
Get all tab objects in an array to communicate with other scrips instances.

(http://forum.tampermonkey.net/viewtopic.php?f=16&t=74)

Jonathon
  • 2,571
  • 5
  • 28
  • 49
  • 2
    I think the way to avoid continually polling is actually `GM_addValueChangeListener` like so: `GM_addValueChangeListener("foobar", function(key, oldval, fval){console.info(key + " previous: "+oldval +" value:" + fval);});` but these 3 functions help you if you want to send simple key:values as notifiers (like [tabId]:[tab_version]++ or newTabOnline:[tabId]) and then rely on them for the shared state. – lossleader Sep 20 '14 at 12:53

2 Answers2

8

I'd never attempted to use them, but looking at the code these appear to be the ability to store/get whatever you would like from each tab and also get everything stored in this fashion by all tabs.

On two chrome consoles, I have run the following:

var this_tab_data, all_tabs, n;

GM_getTab(function (o) {
    this_tab_data = o;
    n = this_tab_data.rand = Math.random();
    GM_saveTab(this_tab_data);
    console.info(this_tab_data);

    GM_getTabs(function (db) {
        all_tabs = db;
        console.info(n);
        for (var i in all_tabs) {
            if (all_tabs[i].rand === n) console.info("I bet I am the tab named: " + i);
            else console.info("Other tab: " + i + " has value: " + all_tabs[i].rand);
        }
    });
});

Result (in tab 2):

Object {rand: 0.9303610376082361}
VM779:11 0.9303610376082361
VM779:14 Other tab: 366 has value: 0.417106909211725
VM779:13 I bet I am the tab named: 371

I added access in the chrome console using this user script, (based on the instructions on the indicated @match page):

// ==UserScript==
// @name       My Fancy New Userscript
// @namespace  http://use.i.E.your.homepage/
// @version    0.1
// @description  enter something useful
// @match      http://stackoverflow.com/questions/14059078/use-the-tampermonkey-api-from-the-chrome-console
// @copyright  2012+, You
// ==/UserScript==

unsafeWindow.GM_getTab = GM_getTab;
unsafeWindow.GM_saveTab = GM_saveTab;
unsafeWindow.GM_getTabs = GM_getTabs;

As a side note, I see that this data remains accessible with GM_getTabs() after I close the tabs that set it. I'm not sure I would count on that, but I probably would minimize what I left behind.

lossleader
  • 13,182
  • 2
  • 31
  • 45
0

lossleader's answer is complete. In short, GM_getTab() passes a copy of the "tab object" to cb (It's now callback in the latest doc of Tampermonkey), GM_saveTab() saves the tab object into the real "tab object", and GM_getTabs() passes all the tabs running the current script to cb, as a hash.

So the procedure of identifying a browser tab should be:

// Get it
GM_getTab(function(tabObj) {
  // Modify it
  tabObj.id = genID();
  // And store it
  GM_saveTab(tabObj);
})

Or with Promise:

new Promise(r => GM_getTab(r)).then(function(tabObj) {
  tabObj.id = genID();
  GM_saveTab(TabObj);
})

(In addition) what the GM_getTab() & GM_getTabs() passes to the callback is like:

getTab():  {…}
​            + id: "166471588778160035"
            + <prototype>: Object { … }

getTabs():  {…}
​             + 9: Object { id: "166471588778160035" }
​             + 25: Object { id: "599671588779026059" }
​             + 26: Object { id: "154331588779031451" }
​             + 31: Object { id: "622271588779033558" }
​             + 33: Object { id: "542881588779039564" }
             + 36: Object { id: "112571588779028937" }
​             + 38: Object { id: "549981588779038186" }
​             + <prototype>: Object { … }

(Update) The "tab object" being passed to the callback are isolated between scripts, so scriptA gets a "tab object" different from scriptB

setTabExpr1.user.js:26:15 {…}
​                           + a: 1234567
                           + <prototype>: Object { … }
​
setTabExpr2.user.js:26:15 {…}
​                           + b: 7654321
​                           + <prototype>: Object { … }
K_AEI
  • 51
  • 3