0

I need to combine these 2 scripts for GM. One opens new pages from a list, and the other clicks on the 'follow' button.

Script 1: How to open a list of pages automatically and sequentially?

Script 2: How do I click on this button with Greasemonkey?

I've tried to combine them by myself but failed to create a working script that fully reloads pages, even they are put sequentially in the list (if you read the other question you'll understand what I mean).

This is what I've tried but it doesn't work as expected since it doesn't reload properly the page and go on with its tasks:

// ==UserScript==
// @name    Follow People on INK361
// @description Follow People from our FB Page's list INK361
// @include     http://ink361.com*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant       GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a major design
    change introduced in GM 1.0.
    It restores the sandbox.
*/

var urlsToLoad  = [
'http://ink361.com/#/users/30742610/photos',
'http://ink361.com/#/users/193869245/photos',
'http://ink361.com/#/users/215062853/photos',
'http://ink361.com/#/users/218295575/photos'
];

/*--- Since many of these sites load large pictures, Chrome's and 
    Firefox's injection may fire a good deal before the image(s) 
    finish loading.
    So, insure script fires after load:
*/

//--- Catch new pages loaded by WELL BEHAVED ajax.
window.addEventListener ("hashchange", FireTimerA,  false);

function FiretimerA () {
    waitForKeyElements ("a.simplebutton:contains('follow')", FireTimer());
}


function FireTimer (jNode) {

    if ( ! /^\s*follow\s*$/i.test () ) {   
        return false;
    }

    var clickEvent  = document.createEvent ('MouseEvents');
    clickEvent.initEvent ('click', true, true);
    jNode[0].dispatchEvent (clickEvent);
    GotoNextURL();
}

function GotoNextURL () {
    var numUrls     = urlsToLoad.length;
    var urlIdx      = urlsToLoad.indexOf (location.href);
    urlIdx++;
    if (urlIdx >= numUrls)
        urlIdx = 0;

    location.href   = urlsToLoad[urlIdx];
}
Community
  • 1
  • 1
Giorgio
  • 1,603
  • 5
  • 29
  • 52
  • What error messages and difficulties did you encounter? Those two scripts are simple enough to combine. Keep in mind that JavaScript can only run one statement at a time (excluding asynchronous network requests). So, basically for each, you need to: 1) Open the page. 2) Wait for it to finish loading. 3) Click the button in that page. 4) Repeat to step 1 until all pages are processed. – Jay Sep 09 '12 at 16:52
  • I've combined the 2 scripts and they run as expected on the first page; however, when the second page is loaded, the script doesn't click the button. I bet because it hasn't been loaded yet (or because the page has not fully reloaded). – Giorgio Sep 09 '12 at 17:29
  • Interacting on another window may not be allowed due to cross domain restriction (security issue). The opened pages must be from the same host name as the page that opened them. – Jay Sep 09 '12 at 17:50
  • @jay -- Cross Domain Restrict doesn't apply to GreaseMonkey scripts. They run at a access level much higher than the web documents yet much lower than chrome. – Jeremy J Starcher Sep 09 '12 at 19:20
  • @JeremyJStarcher: Ah, I forgot about that. :) – Jay Sep 10 '12 at 00:09
  • @Giorgio: Perhaps you should put your code in the question and describe which website and button you're having trouble with. – Jay Sep 10 '12 at 00:14
  • Huh, I didn't see this question (usually I get alerts). I'll attempt to answer it this weekend, **IF you put the code you tried -- or a link to it -- in the question**. (PS: Not Including the code you attempted, may be why someone downvoted you (it wasn't me).) This comment will "self destruct" in 3 days. – Brock Adams Sep 14 '12 at 17:13
  • @BrockAdams I've just noticed your comment, glad you've seen this question since you already know the situation in depth. I've posted the code I've written so far (it you're code rearranged). Hope you could help me this time too. Greetings. – Giorgio Sep 15 '12 at 23:13

1 Answers1

1

Merging those scripts should be straightforward: Just standardize the metadata block and paste one script's javascript after the other's.

After determining the true purpose of the merged script, we get:

// ==UserScript==
// @name        _Follow People on INK361
// @description Follow People from our FB Page's list INK361
// @include     http://ink361.com/#/users/*
// @exclude     http://ink361.com/#/users/223888036*
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @require     https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant       GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a major design
    change introduced in GM 1.0.
    It restores the sandbox.
*/

var urlsToLoad  = [
    'http://ink361.com/#/users/14565576/photos'
    , 'http://ink361.com/#/users/218217815/photos'
    , 'http://ink361.com/#/users/202670894/photos'
    , 'http://ink361.com/#/users/201771644/photos'
    , 'http://ink361.com/#/users/217243779/photos'
    , 'http://ink361.com/#/users/218295748/photos'
    , 'http://ink361.com/#/users/218273533/photos'
    , 'http://ink361.com/#/users/30742610/photos'
    , 'http://ink361.com/#/users/193869245/photos'
    , 'http://ink361.com/#/users/215062853/photos'
];

/*--- Operation:
    1) If the button is "follow" then it clicks it.
    2) If the button is, or becomes "unfollow", then go to the next page.
    3) If there is no button or the button stops working, it stays on the current page.
*/

//--- Note that contains() is CASE-SENSITIVE.
waitForKeyElements (
    "#relationship a.simplebutton:contains('follow')",
    clickOnFollowButton
);

function clickOnFollowButton (jNode) {

    if ( /^\s*follow\s*$/i.test (jNode.text() ) ) {
        //--- Button is "follow"; click it.

        var clickEvent  = document.createEvent ('MouseEvents');
        clickEvent.initEvent ('click', true, true);
        jNode[0].dispatchEvent (clickEvent);
    }
    else if ( /^\s*unfollow\s*$/i.test (jNode.text() ) ) {
        //--- Unfollow button is already (or now) set.  Go to next page.
        jNode.text ("palate cleanser");
        GotoNextURL ();
    }

    return true;    //--- This node is reused, never mark it as found.
}


function GotoNextURL () {
    var numUrls     = urlsToLoad.length;
    var urlIdx      = urlsToLoad.indexOf (location.href);
    urlIdx++;

    //-- Don't loop the list of sites.
    if (urlIdx < numUrls) {
        location.assign (urlsToLoad[urlIdx]);
    }
}

But this assumes that clicking the "Follow" button keeps the screen on the same page. Does it? (Yes)

I can't login to that site, so I can't test the script fully. If it doesn't work, please list any error messages displayed by the console (Firebug or Firefox), and describe exactly how it behaves.

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • I got the accnt info, you should probably delete that comment now. You don't want the list of pages to loop after the last one is loaded? – Brock Adams Sep 17 '12 at 12:39
  • Gaaah! As far as coding and performance goes, that site **BLOWS CHUNKS!** It keeps crashing my test rig and is slooow. Anywho, I had a typo in the button-click code. That's fixed. The revised script seems to work -- at least when the website isn't stalling Firefox. – Brock Adams Sep 17 '12 at 14:18
  • :( It's still not working as expected. As you said it's probably a website problem, the script is not as solid as it should be (obviously it's not your fault, it's theirs) since it works sometimes and sometimes doesn't. However thanks for your efforts. I've really appreciated them. – Giorgio Sep 17 '12 at 14:50
  • I made another tweak that seems to help (between crashes). If that doesn't do it, describe *how* it doesn't work as expected. ... It *should* cycle through the list once, following anyone who is not followed. Or, spending 5 seconds on pages that are followed. But it will do this anytime you go to the site, stopping only on `@excluded` pages or the last page in the list. – Brock Adams Sep 17 '12 at 15:03
  • It starts as expected but after 5-6 correct pages loaded/followed it 'becomes mad' keeping loading new pages at the speed of light (less than a second, when we expect it to stay for 5 secs) and of course it doesn't have the time to click 'follow'. Isn't better to check if the button has been clicked instead of having a timer? – Giorgio Sep 17 '12 at 15:39
  • I use this list, when reaching the sixth place it starts to load faster and stops clicking: 'http://ink361.com/#/users/14565576/photos', 'http://ink361.com/#/users/218217815/photos', 'http://ink361.com/#/users/202670894/photos', 'http://ink361.com/#/users/201771644/photos', 'http://ink361.com/#/users/217243779/photos', 'http://ink361.com/#/users/218295748/photos', 'http://ink361.com/#/users/218273533/photos', 'http://ink361.com/#/users/30742610/photos', 'http://ink361.com/#/users/193869245/photos', 'http://ink361.com/#/users/215062853/photos', – Giorgio Sep 17 '12 at 15:39
  • Don't use more than 5 pages, then! ;) Seriously, are you just wanting it to follow users, and don't care if it pauses on a page? And yes, it's better to check the button, I just took the easy way for that. It's probably the 5-second timer that's multiplying, though. Based on how you respond, I'll revisit this in about 12 hours or so. – Brock Adams Sep 17 '12 at 15:51
  • I don't care if it pauses on the pages (the timer was needed in the old script if you remember). This one should just follow users in the list ;) As soon as it has followed the user it should go to the next page. – Giorgio Sep 17 '12 at 17:54
  • Okay, I made one last modification, and it seems to work better. But the site still stalls FF, and the ***follow*** button stops working -- even when hand-clicked! ... I'm sorry, but I've had it with that site. This is the best I can do for that site, for this question, for now. – Brock Adams Sep 18 '12 at 06:46
  • Hey man! You know what? The script works perfectly fine now! Thanks a lot! ;) There's just another little thing to make it perfect: it stops working when there's a page with no 'follow' button at all. It should be perfect if we can give a timeout to waitForKeyElements ( I mean, if it doesn't find any button in like 3 seconds, then go to the next page). However I'm marking yours as the accepted answer to thank you for your efforts, you really rock! – Giorgio Sep 18 '12 at 07:28
  • 1
    I'd recommend 6 seconds, based on my observations, and it may not be as straightforward as it should be. Ask another question for that (but try to do it yourself, so you have code to post). Wait a few days, to post, if you want me to look at it. I'm tired of that site for now. – Brock Adams Sep 18 '12 at 09:04