Search code examples
javascriptgreasemonkeystoring-data

GM_setvalue not carrying values over every time,only some times...need help


I'm currently trying to carry variables over in a GM script when a page refreshes. Basically I'm using the script from "Using Greasemonkey and jQuery to intercept JSON/AJAX data from a page, and process it." -- which I used and added to quite a bit already.

I've singled out some of the variables, and would like to carry them over when the page refreshes, but they don't. It resets the variables to 0 every time it refreshes, and doesn't carry over.

This is basically what I've got...or rather the important pieces, the script is too getting too long to paste the whole script for this question.

var A12_old1 = GM_getValue('A12_old1', 0);
var A12_old2 = GM_getValue('A12_old2', 0);
var A12_old3 = GM_getValue('A12_old3', 0);

//then further on...
A12_current = parseFloat(singleAuctionData[8]);
A12_rest = singleAuctionData[1];
if (t_int < 1) {
    if (t_test) {
        alert_test = true;
        t_test = false;
        A12reset_go = true;
        A12_old3 = A12_old2;
        A12_old2 = A12_old1;
        A12_old1 = A12_current;
    }
}

/* so basically doing some calculations as to what the values should be then to
     carry them over, at almost the end of the script, but still running every
     second, there is:
*/
if (alert_test) {
    alert_test = false;
    alert(A12_old1 + '  ' + A12_old2 + '  ' + A12_old3);
}

GM_setValue('A12_old1', A12_old1);
GM_setValue('A12_old2', A12_old2);
GM_setValue('A12_old3', A12_old3);
}

/*but it isn't carrying the 3 values over when the page refreshes.
    It resets to '0'....
*/

Can anyone please just show me where I might be going wrong?

Update:

Right.. here is a shortened version of the script that gives me trouble, still with the same problems:

// ==UserScript==
// @name            setvalue test
// @include         http://www.trada.net/*
// @require         http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js
// ==/UserScript==
var auctiontyp = 0;
var my_test = GM_getValue("tsttst", 0);
var my_test2 = GM_getValue("tsttst2", 0);
var h = 0;
var m = 0;
var s = 0;
var t_int = 0;
var t_str = '';
var A12_current = 0;
var a_tst = true;
var a_tst2 = true;
var A12_old1 = GM_getValue("A12_old1", 0);
var A12_old2 = GM_getValue("A12_old2", 0);
var A12_old3 = GM_getValue("A12_old3", 0);

if (a_tst) {
    alert(my_test);
    GM_setValue("tsttst", 5);
    a_tst = false;
}
//--- Create a cell for transmitting the date from page scope to GM scope.
$('body').prepend('<div id="LatestJSON_Data"></div>');

var J_DataCell = $('#LatestJSON_Data');

//--- Evesdrop on the page's AJAX calls and paste the data into our special div.
unsafeWindow.$('body').ajaxSuccess(

function (event, requestData) {
    J_DataCell.text(requestData.responseText);
} );

//--- Listen for changes to the special div and parse the data.
J_DataCell.bind('DOMSubtreeModified', ParseJSON_Data);

function ParseJSON_Data() {
    //--- Get the latest data from the special cell and parse it.
    var myJson = J_DataCell.text();
    var jsonObj = $.parseJSON(myJson);

    //--- The JSON should return a 2-D array, named "d".
    var AuctionDataArray = jsonObj.d;

    //--- Loop over each row in the array.
    $.each(AuctionDataArray, function (rowIndex, singleAuctionData) {

        //--- Print the 7th column.
        console.log('Row: ' + (parseInt(rowIndex) + 1) + ' Column: 7  Value: ' + singleAuctionData[6]);

        if (a_tst2) {
            alert(my_test2);
            GM_setValue("tsttst2", 15);

            alert(A12_old1 + '  ' + A12_old2 + '  ' + A12_old3);
            a_tst2 = false;
        }

        t_str = singleAuctionData[10];
        var time = t_str.split(":");
        h = 3600 * parseInt(time[0], 10);
        m = 60 * parseInt(time[1], 10);
        s = parseInt(time[2], 10);
        t_int = h + m + s;

        auctiontyp = parseInt(singleAuctionData[4]);
        if (auctiontyp == 4) {
            A12_current = parseFloat(singleAuctionData[8]);

            if (t_int < 1) {
                A12_old3 = A12_old2;
                A12_old2 = A12_old1;
                A12_old1 = A12_current;
                GM_setValue("A12_old1", A12_old1);
                GM_setValue("A12_old2", A12_old2);
                GM_setValue("A12_old3", A12_old3);
            }
        }
    });
}


The variable "my_test" is carried over, but "my_test2", which run in the json array, as well as my other variables isn't carried over by GM_setvalue. I'm unsure why, but this is to what I was able to narrow it down to.


Solution

  • A few things:

    1. Those scripts are trying to store floats. GM_setValue() only works on: strings, integers and booleans.
      Fortunately, there is an extension for that; more below.

    2. The later calls to GM_setValue failed because they were inside an event handler.
      If you had been watching with the Firebug console (always debug that way!), a red error message scrolls past:

      Greasemonkey access violation: unsafeWindow cannot call GM_setValue.
      
    3. On a similar vein, isn't testing with the alerts() annoying? Use the console functions and the script won't have to stop, and you won't have those pesky popups.

    So, how to fix:

    1. First, a test.

      1. Install this script:

        // ==UserScript==
        // @name            Super GM_setValue and GM_getValue TEST SHELL
        // @namespace       DEBUG
        // @include         https://stackoverflow.com/questions/*
        // @require         http://userscripts.org/scripts/source/107941.user.js
        // ==/UserScript==
        
        /*--- Run the test cases to make sure that the GM_setValue and GM_getValue
            extensions are able to run on this browser.
        */
        GM_SuperValue.runTestCases  (0);
        
      2. Then navigate to this page (stackoverflow.com/q/6802750/).

      3. With Firebug's console open, reload the page.

      4. What are the results?


    2. Use the enhanced GM_setValue library.   Add this line to your script(s):

      // @require http://userscripts.org/scripts/source/107941.user.js
      
    3. Replace all GM_setValue with GM_SuperValue.set

    4. Replace all GM_getValue with GM_SuperValue.get

    5. To address the fact that GM won't let GM_setValue run in event handlers set from the GM scope (this may be a bug), change the way ParseJSON_Data is called...

      1. Comment out the J_DataCell.bind ('DOMSubtreeModified' ... line.
      2. Add timerHandle = setInterval (function() { ParseJSON_Data (); }, 444);, below it.
      3. Add some more logic around J_DataCell.

    Putting it all together, the test script becomes:

    // ==UserScript==
    // @name            _setvalue test
    // @include         http://www.trada.net/*
    // @require         http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js
    // @require         http://userscripts.org/scripts/source/107941.user.js
    // ==/UserScript==
    
    var auctiontyp  = 0;
    var my_test     = GM_SuperValue.get("tsttst", 0);
    var my_test2    = GM_SuperValue.get("tsttst2", 0);
    var h           = 0;
    var m           = 0;
    var s           = 0;
    var t_int       = 0;
    var t_str       = '';
    var A12_current = 0;
    var a_tst       = true;
    var a_tst2      = true;
    var A12_old1    = GM_SuperValue.get("A12_old1", 0);
    var A12_old2    = GM_SuperValue.get("A12_old2", 0);
    var A12_old3    = GM_SuperValue.get("A12_old3", 0);
    
    if (a_tst) {
        console.log(my_test);
        GM_SuperValue.set("tsttst", 5);
        a_tst = false;
    }
    //--- Create a cell for transmitting the date from page scope to GM scope.
    $('body').prepend('<div id="LatestJSON_Data"></div>');
    
    var J_DataCell = $('#LatestJSON_Data');
    
    //--- Evesdrop on the page's AJAX calls and paste the data into our special div.
    unsafeWindow.$('body').ajaxSuccess(
        function (event, requestData) {
            J_DataCell.text(requestData.responseText);
    } );
    
    //--- Listen for changes to the special div and parse the data.
    //J_DataCell.bind ('DOMSubtreeModified', {StoreValFunc: GM_SuperValue.set}, ParseJSON_Data);
    
    timerHandle = setInterval (function() { ParseJSON_Data (); }, 444);
    
    function ParseJSON_Data () {
        //--- Get the latest data from the special cell and parse it.
        var myJson  = J_DataCell.text();
        if (!myJson  ||  /^\s*$/.test (myJson) )
            return
        else
            J_DataCell.text (" ");
    
        var jsonObj = $.parseJSON(myJson);
    
        //--- The JSON should return a 2-D array, named "d".
        var AuctionDataArray = jsonObj.d;
    
        //--- Loop over each row in the array.
        $.each(AuctionDataArray, function (rowIndex, singleAuctionData) {
    
            //--- Print the 7th column.
            //console.log('Row: ' + (parseInt(rowIndex) + 1) + ' Column: 7  Value: ' + singleAuctionData[6]);
    
            if (a_tst2) {
                console.log('******** ', my_test2);
                GM_SuperValue.set ("tsttst2", 15);
    
                console.log (A12_old1 + '  ' + A12_old2 + '  ' + A12_old3);
                a_tst2 = false;
            }
    
            t_str       = singleAuctionData[10];
            var time    = t_str.split(":");
            h           = 3600 * parseInt(time[0], 10);
            m           = 60 * parseInt(time[1], 10);
            s           = parseInt(time[2], 10);
            t_int       = h + m + s;
    
            auctiontyp = parseInt(singleAuctionData[4]);
            if (auctiontyp == 4) {
                A12_current = parseFloat(singleAuctionData[8]);
    
                if (t_int < 1) {
                    A12_old3 = A12_old2;
                    A12_old2 = A12_old1;
                    A12_old1 = A12_current;
                    GM_SuperValue.set ("A12_old1", A12_old1);
                    GM_SuperValue.set ("A12_old2", A12_old2);
                    GM_SuperValue.set ("A12_old3", A12_old2);
                }
            }
        });
    }
    
    GM_addStyle ('#LatestJSON_Data {display:none;}');