setTimeout not working in Greasemonkey user script when JS disabled in browser

前端 未结 3 2099
不知归路
不知归路 2021-02-15 23:25

I\'m working on a project that requires my user script be run on pages as they are rendered without executing any of the page\'s JavaScript. That is to say, we need to browse wi

3条回答
  •  夕颜
    夕颜 (楼主)
    2021-02-16 00:00

    this can be patched like this:

    You can say NO to NoScript + setTimeout = failed

    In greasemonkey.js: find [ injectScripts ]: function..... add our GM-api.....

    Add this code:

    sandbox.setTimeOut = function (callback, timeout, p1,p2,p3/*....*/){
        var args = Array.prototype.slice.call(arguments,2);
        return  sandbox.window.setTimeout(function(){
            return callback.apply(sandbox, args);
        } ,timeout);
    }
    

    or

    sandbox.setInterval = function (callback, timeout, p1,p2,p3/*....*/){
        var args = Array.prototype.slice.call(arguments,2);
        return sandbox.window.setInterval(function(){
            return callback.apply(sandbox, args);
        } ,timeout);
    }
    

    This code is working fine, I have used it since May 2010.

    In user.js you can test it like this:

    setTimeout(alert,1000, 'i am happy');
    var loopid = setInterval(alert, 1000, 'I am happy again');
    setTimeout(clearInterval, 5000, loopid);
    
    var j=300;
    for(;~j;j--){ //running perfectly!
        setTimeout(alert, 1000+20*j, 'I am happy' )
    }
    

    Solution 2

    sandbox.kk_setTimeout = function (func, timeout, repeat_type, p1,p2,p3/*....*/){
        var callback = { k100: sandbox };
        var args = Array.slice.call(arguments,3);
    
        // repeat_type:  0=once  1=repeatng, after fired stopped    2=always repeat
        if(repeat_type!=2){
            callback.notify = function (timer){ func.apply(this.k100,args); }
            var timerCC = Components.Constructor("@mozilla.org/timer;1", "nsITimer", 'initWithCallback');
            var R = repeat_type?1:0;
        } else {
            callback.observe = function (subject, topic, data) { func.call(this.k100); };
            var timerCC = Components.Constructor("@mozilla.org/timer;1", "nsITimer", 'init'); 
            var R = 2; 
        }
        return new timerCC(callback, timeout, R);
    }
    
    // now have to test it:
    
    var test100 = kk_setTimeout(alert, 1000, 0, 'i am timer');  //running = setTimeout
    var test100 = kk_setTimeout(alert, 1000, 2, 'i am timer');  //running = setInterval
    test100.cancal() ;   //clear it by cancel() method
    
    kk_setTimeout(alert, 1000+20*j, 2, 'i am happy' );
    var j=300;
    for(;~j;j--){
        kk_setTimeout(alert, 1000+20*j, 0, 'i am happy 2' );
    }
    
    //bug:
    //this solution 2 running after about 3-8 times differently stop, why bug ? i don't know.
    // you will fail to use many times(over 3-8 time) kk_timeout(); or using repeat_type = 2 after fired 3-8 times timeout
    //or running total time max about 20-30 seconds stop 
    //--- this maybe stop by option in about:config -- about [max javascript run time]
    

    china-kkmove patched


    edit to add…

    Sorry everyone,

    There are still a few patches to the code that I forgot to write:

    sandbox.window = sandbox._proto_; // add this line also to the solution 1#
    

    This error just came to my mind this morning.

提交回复
热议问题