6

I have written a GreaseMonkey (javascript) userscript that runs in a browser (Firefox) tab directed at www.site1.com/stuff. Another tab is directed at www.site1.com (without the stuff), and is not a child window of the first (e.g., was not opened through the userscript running on the first tab). The userscript runs (independently?) on both tabs.

I would like the userscript execution on the first browser tab to pass a string variable to the second browser tab. While GM_setValue and GM_getValue work well for storage/retrieval within a single userscript, that storage area does not seem to be accessible to the other execution of the userscript. localStorage suffers the same failure. For an explicit example:

  • When the userscript detects that it is running on www.site1.com/stuff, it places a value into storage: GM_setValue('parValue', 'aaabbbccc');

  • After the first tab is fully loaded and has ample time to place this value into storage, the second tab is opened manually. When the userscript detects that this second tab is running on www.site1.com (without stuff), the code tries to retrieve the value: var parVal = GM_getValue('parValue'). In my userscript, parVal would have a null value; each userscript execution appears to use different storage areas.

How do I achieve this seemingly simple task of getting both executions of this same userscript to safe/retrieve from a common storage area under the following constraints:

  • The stuff at the end of the URL of the first tab can change at-will by the user (writing separate userscripts tailored for every conceivable stuff possibility would be impossible).
  • The tabs will never have a parent/child relationship, as they were generated independently (technically, the second tab is a grandchild of the first tab, but I have no idea of what the window names of the 2 tabs are or how to reference them in code).
  • using javascript running in GreaseMonkey userscript

Is there some kind of global, cross-tab storage area that can be used, that could be implemented in a GreaseMonkey userscript? In theory, should GM_setValue be applicable to this situation? I've spent substantial time poring over the answers to the following related SO questions, but was unable to find a solution that works for the above set of conditions and/or can be implemented into a GreaseMonkey userscript: Communication between tabs or windows, JavaScript: sharing data between tabs, https://superuser.com/questions/1005448/can-a-greasemonkey-script-know-whats-been-loaded-into-another-tab, Sending a message to all open windows/tabs using JavaScript,

ᄂ ᄀ
  • 5,669
  • 6
  • 43
  • 57
PMM
  • 176
  • 2
  • 12
  • 4
    `that storage area does not seem to be accessible to the other execution of the userscript` - you are mistaken ... GM_setValue stores values per script, regardless of URL - same script, same storage – Jaromanda X Oct 17 '17 at 05:52
  • 1
    `localStorage` works and provides the `message` event on `window`, making for a great "IPC" solution – dandavis Oct 17 '17 at 06:17
  • 1
    Thanks @JaromandaX. I just didn't see that expected behavior in my code. I will make a pared-down userscript that just tests this functionality and post here. I could very well be using `GM_setValue` and `GM_getValue` incorrectly. – PMM Oct 17 '17 at 06:35
  • 1
    Thanks @dandavis. For my particular application, having a message event isn't necessary (I don't think), but thanks for your comment, as I was wondering how `localStorage` and `GM_getValue/setValue` differ. And who knows, as I dig further into my code development, maybe I will discover that I indeed need `message` event on `window`. – PMM Oct 17 '17 at 06:38
  • 1
    To my surprise, my stripped-down userscript that focuses on 'GM_setValue` functionality works exactly as @JaromandaX describes. (I haven't done the same test with `localStorage`). The test was added to the re-edited question above (in case it helps others). – PMM Oct 17 '17 at 07:15

1 Answers1

6

Turns out that 'GM_setValue/getValue' indeed allow information to be shared between 2 tabs in which the same userscript is running in parallel. I proved it with the following test code. I started with a tab directed to www.google.com, got the alerts, and then opened up another tab in the same browser window and directed the URL to www.yahoo.com. The alert indicated that the value was successfully retrieved from storage from where the userscript executing on the google.com had placed it.

// ==UserScript==
// @name        hello world
// @namespace   http://www.sharelatex.com
// @include     https://www.google.com/*
// @include     https://www.yahoo.com/*
// @grant       GM_setValue
// @grant       GM_getValue
// ==/UserScript==

if (window.location.href.indexOf("google.com") != -1) {  // on Google URL 
    alert("on Google site, storing value");
   // you will see the above alert verifying that code understands  
   // the code is running on the google.com tab
    GM_setValue('passValue', 'aabbcc'); 
} else { 
    alert("on Yahoo site, retrieving value");
   // the above alert will be seen, verifying that the code 
   // understands the code is running on the yahoo.com tab
    var pvalue = GM_getValue('passValue'); 
    alert("The retrieved value is " + pvalue);
   // the above alert should show aabbcc, verifying that the 
   // userscript running on google.com successfully stored the value 
  // and the script on yahoo.com successfully retrieved it. 
}
PMM
  • 176
  • 2
  • 12