JR Crowdsource keyword/ranking mturk.com scripts

A userscript for crowdsource keyword and ranking hits. It should be working for the keywords for any Google location. Also it will work for the ranking hits. It will even work for the choose the best URL hits.

נכון ליום 14-11-2014. ראה הגרסה האחרונה.

// ==UserScript==
// @name            JR Crowdsource keyword/ranking mturk.com scripts
// @version         0.71
// @description     A userscript for crowdsource keyword and ranking hits. It should be working for the keywords for any Google location. Also it will work for the ranking hits. It will even work for the choose the best URL hits.
// @author          John Ramirez (JohnnyRS)
// @include         *
// @require         http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js
// @require         http://ajax.googleapis.com/ajax/libs/jqueryui/1.5.2/jquery-ui.min.js
// @run-at          document-end
// @grant       	GM_setClipboard
// @grant           GM_addStyle
// @namespace       https://greasyfork.org/users/6406
// ==/UserScript==

// Version 0.71 - A quick fix due to a conflict with turkmaster script. Also made the URL matching bit better.
// -- A weird glitch on the search page has been fixed as well. Changed button text on preview mode.
// --Keywords on Google (version 2)   
//   These are the ones which ask you to fill in the page and rank of a keyword. Then they ask a question you need to find on the URL
//   page they want you to search for. This script adds a button to each task which will open up a new window with the Google search page.
//   On the search page it should show 50 URLs down the page. There will be a select button on the right of the site names.
//   If the color of the button is red then that it is an exact match and it's your lucky day. Purple buttons are pages that have same domain names
//   but not an exact match to the URL. Click on it to fill in the page and rank numbers automatically. It will open the new page in the same window.
//     Pressing F9 will hide/show the instruction box if it gets in the way of the page.
//     Pressing n will fill in None automatically if you can't find the URL on the page.
//     Pressing p will close the search window and return you to the hit page without filling in anything.
//   There will be an instruction box to the right floating over the page. It shows the question to be answered and an input text to fill in if you
//   need to fill it in yourself. There are buttons you can use to submit the URL or selection as the answer. You can close the page to go back to
//   the Google page with the close button. The submit button will submit anything you typed in the text field as the answer. For easier submits you can use
//   keyboard shortcuts as well:
//     Pressing F9 will hide/show the instruction box if it gets in the way of the page.
//     Pressing w will take the URL of the page as the answer and fill it in the hit automatically.
//     Pressing e will focus on the input text field where you can type in your own answer. Pressing ENTER in the field will submit the text as the answer.
//     Pressing p will close that window and return you to the Google search page so you can select another site or go back to the hit.
//     Pressing s will submit whatever you selected as the answer. I took out the submit button for selections because it caused problems on some pages.
// --Keywords on Google (version 1)   
//   Another hit which it will work is the version 1 of these where it asks you to fill in the best sentence for the keyword.
//   It does everything like version 2 but it won't have a question so just select a sentence and submit.
// --Keywords on Google (URL version)
//   These are the ones where it asks for the best URL for the keywords. These are very fast. Nothing to match so press the select button
//   next to the best site and it will fill in the URL automatically and close the search page.
//
//  This should work on firefox and chrome. Had to fight chrome to make it work but finally tamed it. Should work with Pale Moon also.
//  Because this script has to run for every page I recommend you to disable it after you use it. Makes things go faster.
//  It shouldn't interfere with any page in normal situations. But some rare situations can occur so disable it.
//  Best to disable scripts for individual requesters or hits anyway. Makes browsers go much faster and won't give problems like
//  not letting you type in letters or submit automatically by mistake.
//
// Version 0.4 - Added instruction box UI for the question and answer phase. Didn't like using alert boxes for that section. Added new keyboard shortcuts also.
//  -- Took out the submit box for selections. Press s to submit selection as answer or push the button in the instruction box.
// Version 0.6 - Fixed some instructions which were wrong for different versions of the hit. Refined some coding to be more efficient.
// -- Fixed a few bugs on the Google pages where ads where counted. Added new version for Google.cz hits.
// Version 0.7 - Fixed some bugs when matching URLs. Re-coded the messaging system to be more secure and compact.
// -- Fixed code to work on newest pale moon browsers. Makes text selectable in all crowdsource hits.
// -- Script now clicks on the link in the Google search to simulate a real click and loads page in same page.
// -- Can work with the zip code ranking hits also but not sure if it will work for everyone.

// Constant variables used to verify it's working for only the correct hit.
// Also to check if it's in preview mode or not.
// gTag allows multiple sessions of this script without sending wrong messages to the wrong script.
var VERIFY1 = "copy and paste the url of the most relevant result";
var VERIFY2 = "return information about a keyword search in";
var VERIFY3 = "record a url's search ranking on";
var VERIFY4 = "open google.cz, and search the provided keyword";
var VERIFY5 = "Click \"Search Tools\" then \"Search near...\"";
var PREVIEW1 = "You are currently in preview mode";
var ONPREVIEW = false;									  
var MYVERIFY = "feetsmell";                               // used for all my scripts to verify messages originating from my script.
var SCRIPTNAME = "JR Crowdsource keyword/ranking";        // used to make sure this script answers to messages originating from this script only.
var gMyWindow = null, gSearchURLs = [], gTaskNumber = 0, gQuestions = [], gTag = -1, gMouseTimer = null, gSearchVersion = 0;
var gGoogleDomain = "google.com", gKbShortcutFired = false, gMyInstructionsBox = null, gLocation = document.URL.toString();
var gSearchUrl = ""; gHostName="", gZipCodes=[];
var gLogging = true, gDebugging = false;
if (typeof console.log !== 'function') { gDebugging=false; gLogging=false; }
else { gLogging = (gLogging) ? gLogging : gDebugging; }

Number.prototype.isQuestionVersion = function() {
    if (this==2 || this==3 || this==5) return true;
    else return false;
};
Number.prototype.isZipCodeVersion = function() {
    if (this==5) return true;
    else return false;
};
Number.prototype.hasSelectNone = function() {
    if (this==3) return false;
    else return true;
};
function getHostName(url) {
    var match = url.match(/(.+:\/\/)?([^\/]+)(\/.*)*/i);
    if (match !== null && match.length > 2 && typeof match[2] === 'string' && match[2].length > 0) return match[2].replace("www.","");
    else return "";
}
function getDomainName(url) {
    var hostName = getHostName(url);
    var splitHostName = hostName.split('.');
    if ( splitHostName.length > 2 ) return splitHostName[splitHostName.length-2] + "." + splitHostName[splitHostName.length-1];
    else return hostName;
}
function dataFill(action, data1, data2, data3, data4, data5) {
    if(typeof(data1)==='undefined') data1 = "";
    if(typeof(data2)==='undefined') data2 = "";
    if(typeof(data3)==='undefined') data3 = "";
    if(typeof(data4)==='undefined') data4 = "";
    if(typeof(data5)==='undefined') data5 = "";
    var tempe = {"verify": MYVERIFY, "scriptName": SCRIPTNAME, "tag": gTag, "action": action,
            "data1": data1, "data2": data2, "data3": data3, "data4": data4, "data5": data5};
    return tempe;
}
function verifyMessage(e,thisLocation) {
    if (e.data.verify === MYVERIFY && e.data.scriptName === SCRIPTNAME) return true;
    else return false;
}
function urlMatch(url1, url2) {
    if(typeof(url1)==='undefined' || typeof(url2)==='undefined') return 0;
    var hostName1 = getHostName(url1);
    var hostName2 = getHostName(url2);
    url1 = url1.replace(/(^http.?:\/\/)|(\/$)/g,'');
    url2 = url2.replace(/(^http.?:\/\/)|(\/$)/g,'');
    if ( url1.toLowerCase() == url2.toLowerCase() ) return 1;
    else if ( hostName1.toLowerCase() == hostName2.toLowerCase() ) return 2;
    else return 0;
}
function createButton(theId,theValue,theName) {
    var theButton = document.createElement("INPUT"); theButton.id = theId;
    theButton.value = theValue;
    theButton.type = "button";
	if (typeof theName !== "undefined") theButton.name = theName;
    return theButton;
}
function createTextInput(theId,theValue,theSize) {
    var theInput = document.createElement("INPUT"); theInput.id = theId;
    theInput.value = theValue;
    theInput.size = theSize;
    theInput.type = "text";
    return theInput;
}
function answerURL() {
    data = dataFill( "found answer", gTaskNumber, document.URL.toString() );
    parent.window.opener.postMessage(data,"*");
}
function answerSel() {
    data = dataFill( "found answer", gTaskNumber, window.getSelection().toString() );
	GM_setClipboard( window.getSelection().toString() );
    parent.window.opener.postMessage(data,"*");
}
function answerInput() {
    data = dataFill( "found answer", gTaskNumber, document.getElementById("enterAnswer").value );
    parent.window.opener.postMessage(data,"*");
}
function answerNone() {
    data = dataFill( "found page and rank", gTaskNumber, "None", "None", "None" );
    parent.window.opener.postMessage(data,"*");
}
function goToSearch() {
    data = dataFill( "initialize google" );
    parent.window.opener.postMessage(data,"*");
}
function textInputFocus() {
    var gRightSideBar    = $('#myInstructionsBox');
    gKbShortcutFired = false;
    gRightSideBar.stop (true, false).fadeTo (50,  1  );
}
function textInputFocusout() {
    var gRightSideBar    = $('#myInstructionsBox');
    if ( !gRightSideBar.is(":hover") ) gRightSideBar.stop (true, false).fadeTo (2900, 0.1);
}
function attrInstructionsBox() {
    gMyInstructionsBox    = $('#myInstructionsBox');
    GM_addStyle ( "                                                     \
        #myInstructionsBox {                                            \
            position:               fixed;                              \
            top:                    100px;                              \
            right:                  0;                                  \
            margin:                 1ex;                                \
            padding:                1em;                                \
            background:             #0B0B3B;                            \
            width:                  460px;                              \
            z-index:                99999;                              \
            opacity:                0.9;                                \
            color:                  #F7F8E0;                            \
            text-align:             left;                               \
            line-height:            18px;                               \
            font-family:            Helvetica,Arial,Sans-Serif;         \
        }                                                               \
        #myInstructionsBox p {                                          \
            font-size:              14px;                               \
        }                                                               \
        #myInstructionsBox #myInstructions {                            \
            font-size:              14px;                               \
            color:                  #F7F8E0;                            \
            padding:                2px 0 10px 8px;                     \
        }                                                               \
        #myInstructionsBox #theQuestion {                               \
            font-size:              18px;                               \
            color:                  cyan;                               \
            margin-top:             8px;                                \
            padding:                12px 0 15px 5px;                    \
            background:             #000000;                            \
        }                                                               \
        #myInstructionsBox #theControls {                               \
            padding:                0 0 0 15px;                         \
        }                                                               \
        #myInstructionsBox #textinput {                                 \
            font-size:              16px;                               \
            padding:                12px 0 15px 5px;                    \
            color:                  #000000;                            \
        }                                                               \
        #myInstructionsBox ul {                                         \
            margin:                 0ex;                                \
        }                                                               \
        #myInstructionsBox input {                                      \
            margin:                 2px;                                \
            color:                  #000000;                            \
            font-size:              16px;                               \
            padding:                1px 6px;                            \
        }                                                               \
        #myInstructionsBox input[type=text] {                           \
            height:                 15px;                               \
            padding:                1px, 2px;                           \
            width:                  440px;                              \
            font-size:              12px;                               \
        }                                                               \
        #myInstructionsBox a {                                          \
            color:                  white;                              \
        }                                                               \
    " );
    gKbShortcutFired = false;
    gMyInstructionsBox.draggable();
    //-- Fade panel when not in use
    gMyInstructionsBox.hover (
        function () {
            $(this).stop (true, false).fadeTo (50,  1  );
            gKbShortcutFired = false;
        },
        function () {
            if ( !$("#enterAnswer").is(":focus") ) {
                if ( ! gKbShortcutFired ) {
                    $(this).stop (true, false).fadeTo (2900, 0.1);
                }
                gKbShortcutFired = false;
            }
        }
    );
    gMyInstructionsBox.fadeTo (2900, 0.1);
    $(window).keydown ( function(e) {
        if (e.keyCode == 120) { // F9 to toggle box
            gKbShortcutFired = true;
    
            if (gMyInstructionsBox.is (":visible") ) {
                gMyInstructionsBox.stop (true, false).hide ();
            }
            else {
                //-- Reappear opaque to start
                gMyInstructionsBox.stop (true, false).show ();
                gMyInstructionsBox.fadeTo (0, 1);
                if ( !$("#enterAnswer").is(":focus") ) gRightSideBar.fadeTo (3900, 0.1);
            }
    
            e.preventDefault ();
            e.stopPropagation ();
            return false;
        }
    },false);
}
function GoogleInstructionsBox(instructions) {
    var closeButton = createButton("closeMe","Close page (p)");
    closeButton.onclick = function () { self.close(); }
    var frag = document.createDocumentFragment();
    var instructionsBox = document.createElement("div"); instructionsBox.id = "myInstructionsBox";
    var instructionsH3 = document.createElement("div"); instructionsH3.id = "myInstructions";
    instructionsH3.innerHTML = "[ F9 toggles visibility ] [ Box is draggable ]<br>" + instructions;
    var controlsH4 = document.createElement("div"); controlsH4.id = "theControls";
    if (gSearchVersion.isQuestionVersion()) {
        var noneButton = createButton("noneAnswer","None (n)");
        noneButton.onclick = function () { answerNone(); }
        controlsH4.appendChild(noneButton);
    }
    controlsH4.appendChild(closeButton);
    var questionH4 = document.createElement("div"); questionH4.id = "theQuestion";
    instructionsBox.appendChild(instructionsH3);
    instructionsBox.appendChild(controlsH4);
    if (gSearchVersion.isQuestionVersion()) {
        questionH4.innerHTML = "URL: " + gSearchURLs[0];
        instructionsBox.appendChild(questionH4);
    }
    frag.appendChild(instructionsBox);
    document.body.appendChild(frag);
    
    attrInstructionsBox();
    document.onkeydown = function (e) {
        if (e.keyCode == 78) answerNone(); // n = Can't find URL.
        else if (e.keyCode == 80) self.close(); // p = close this window and go back to google search.
    };
}
function URLInstructionsBox(instructions,question) {
    var urlButton = createButton("urlAnswer","URL (w)");
    urlButton.onclick = function () { answerURL(); }
    var selButton = createButton("selAnswer","Selection (s)");
    selButton.onclick = function () { answerSel(); }
    var closeButton = createButton("closeMe","Close page (p)");
    closeButton.onclick = function () { location.replace(gSearchUrl); }
    var submitButton = createButton("submitInput","Send Answer");
    submitButton.onclick = function () { answerInput(); }
    var textInput = createTextInput("enterAnswer","","70");
    var frag = document.createDocumentFragment();
    var instructionsBox = document.createElement("div"); instructionsBox.id = "myInstructionsBox";
    var instructionsH3 = document.createElement("div"); instructionsH3.id = "myInstructions";
    instructionsH3.innerHTML = "[ F9 toggles visibility ] [ Box is draggable ]<br>" + instructions;
    var questionH4 = document.createElement("div"); questionH4.id = "theQuestion";
    questionH4.innerHTML = "Question: " + question;
    var controlsH4 = document.createElement("div"); controlsH4.id = "theControls";
    controlsH4.innerHTML = "Answer: ";
    controlsH4.appendChild(selButton);
    controlsH4.appendChild(urlButton);
    controlsH4.appendChild(closeButton);
    var answerH4 = document.createElement("div"); answerH4.id = "yourAnswer";
    answerH4.innerHTML = "Type in Answer:<br>";
    answerH4.appendChild(textInput);
    answerH4.appendChild(submitButton);
    instructionsBox.appendChild(instructionsH3);
    instructionsBox.appendChild(controlsH4);
    instructionsBox.appendChild(questionH4);
    instructionsBox.appendChild(answerH4);
    frag.appendChild(instructionsBox);
    document.body.appendChild(frag);
    textInput.onfocus = function(){ textInputFocus(); };
    textInput.onblur = function(){ textInputFocusout(); };
    
    attrInstructionsBox();
    document.onkeydown = function (e) {
        if (e.target.id !="enterAnswer") {
            if (e.keyCode == 87) answerURL(); // w = Use URL for answer.
            else if (e.keyCode == 83) answerSel(); // s = to use your selection for answer.
            else if (e.keyCode == 80) location.replace(gSearchUrl); // p = close this window and go back to google search.
            else if (e.keyCode == 69) { // e = Type in answer
                textInput.focus(); 
                e.preventDefault ();
                e.stopPropagation ();
                return false;
            }
        } else if ( e.keyCode == 13 ) answerInput(); // enter in input text will submit input value.
    };
}
function getGoogleResultsPointer() {
    var results = document.getElementsByClassName("g");
    var i=0, pointers=[];
    if (results.length>0) {
        for (var i = 0, len=results.length; i < len; i++) {
            if ( results[i].getElementsByClassName("r").length>0 && results[i].getElementsByClassName("_SWb").length>0 && 
                    results[i].getElementsByClassName("_YM").length==0 && results[i].getElementsByClassName("kno-fb").length==0) {
                pointers.push(i);
            }
        }
    }
    return pointers;
}
function initializeGoogle(timer) {
    var theData = dataFill( "Hello", gTaskNumber );
    if (gSearchVersion.isQuestionVersion())
	   theData = dataFill( "search URL", gSearchVersion, gSearchURLs[gTaskNumber-1], gQuestions[gTaskNumber-1],
	           gTaskNumber, gZipCodes[gTaskNumber-1] );
	else theData = dataFill( "find best URL", gSearchVersion, gTaskNumber );
	if (typeof timer==="undefined") gMyWindow.postMessage(theData,"*");
	else window.setTimeout( function() { gMyWindow.postMessage(theData,"*"); }, timer );
}
function initializeQuestion(timer) {
    var theData = dataFill( "answer question", gSearchUrl, gQuestions[gTaskNumber-1], gTaskNumber  );
	if (typeof timer==="undefined") gMyWindow.postMessage(theData,"*");
	else window.setTimeout( function() { gMyWindow.postMessage(theData,"*"); }, timer );
}
function doFrameMessage(e) {
    if (gDebugging && gLogging) console.log("..F Received message action - " + e.data.action);
    if (e.data.action == "initialize google") initializeGoogle();
    else if (e.data.action == "initialize the question") initializeQuestion();
    else if (e.data.action == "found page and rank" && e.data.tag == gTag) {
        if (!gSearchVersion.hasSelectNone() && (e.data.data2=="None" || e.data.data3=="None")) {
            document.getElementById("PageNumber-"+e.data.data1).value = "";
            document.getElementById("Ranking-"+e.data.data1).value = "";
            document.getElementById("BeyondPage5-"+e.data.data1).click();
            document.getElementById("Sentence-"+e.data.data1).value = "";
        } else {
            document.getElementById("PageNumber-"+e.data.data1).value = e.data.data2;
            document.getElementById("Ranking-"+e.data.data1).value = e.data.data3;
            if (document.getElementById("BeyondPage5-"+e.data.data1)!==null) {
                document.getElementById("BeyondPage5-"+e.data.data1).checked = false;
            }
            if (e.data.data4 !== "") document.getElementById("WorkerResponse-"+e.data.data1).value = e.data.data4;
        }
        if (e.data.data2 == "None") gMyWindow.close();
        else initializeQuestion(2000);
    } else if (e.data.action == "found url" && e.data.tag == gTag) { // This is for version 1 of the keyword search
        document.getElementById("URL-"+e.data.data1).value = e.data.data2;
        gMyWindow.close();
    } else if (e.data.action == "found answer" && e.data.tag == gTag) {
        if (!gSearchVersion.hasSelectNone()) document.getElementById("Sentence-"+e.data.data1).value = e.data.data2;
        else document.getElementById("WorkerResponse-"+e.data.data1).value = e.data.data2;
        gMyWindow.close();
    }
}
function doZipCode() {
    var divTools = document.getElementById("hdtb_tls");
    divTools.click();
    var zipTextDiv = document.getElementsByClassName("mn-hd-txt")[3];
    if (zipTextDiv.innerHTML.indexOf(gZipCodes[0])==-1) {
        zipTextDiv.click();
        var zipCodeInput = document.getElementById("lc-input");
        var divZipCode = document.getElementById("_Zpd");
        var zipCodeSubmit = divZipCode.getElementsByClassName("ksb")[0];
        zipCodeInput.value = gZipCodes[0];
        zipCodeSubmit.click();
        return true;
    } else return false;
}
function doGoogleButtons() {
    var urlPointers = getGoogleResultsPointer();
    var results = document.getElementsByClassName("g");
    var pageNum=1, rankNum=1;
    for (var i = 0, len=urlPointers.length; i < len; i++) {
        var url = results[urlPointers[i]].getElementsByTagName("a")[0];
        var btn = document.createElement("BUTTON");
        btn.innerHTML = "Select";
        btn.type = "button";
        btn.style.marginRight = "6px";
        btn.name = "B," + pageNum + "," + rankNum + "," + (urlPointers[i]) + "," + url.href;
        matching = urlMatch( url.href, gSearchURLs[0] );
        if ( matching == 1 ) {
            btn.style.background='red';
            btn.style.color='#FFFFFF';
        } else if ( matching == 2 ) {
            btn.style.background="Purple";
            btn.style.color="#FFFFFF";
        } else if ( matching == 3 ) {
            btn.style.background="#F8E0F7";
            btn.style.color="#000000";
        }
            btn.style.fontSize="small";
        btn.onclick = function() {
            var splitName = this.name.split(',');
            if (gSearchVersion.isQuestionVersion()) {
                var theData = dataFill( "found page and rank", gTaskNumber, splitName[1], splitName[2] );
                parent.window.opener.postMessage(theData,"*");
                results[splitName[3]].getElementsByTagName("a")[0].click();
            } else {
                var theData = dataFill( "found url", gTaskNumber, splitName[4] );
                parent.window.opener.postMessage(theData,"*");
            }
        };
        url.parentNode.insertBefore(btn,url);
        rankNum++;
        if ( rankNum>10 ) {
            rankNum=1; pageNum++;
        }
    }
    var myInstructions = "[ p to go back ]<br>";
    if (gSearchVersion.isQuestionVersion()) myInstructions = "[ n to fill in nothing found ] [ p to go back ]<br><br>" + 
        "Red buttons are perfect matches<br>Purple buttons have same hostnames.";
    GoogleInstructionsBox(myInstructions);
}
function doGoogleMessage(e) {
    if (gDebugging && gLogging) console.log("..G Received message action - " + e.data.action);
    if (gTag == -1 && e.data.action == "answer question") {
        gSearchUrl = e.data.data1;
        gQuestions[0] = e.data.data2;
        gTaskNumber = e.data.data3
        gTag = e.data.tag;
        var myInstructions = "[ w to use the URL for the answer ] ";
        myInstructions += "[ e to fill in answer ]<br />[ s to use selection as answer ] [ p to go back to google ]\n";
        URLInstructionsBox(myInstructions,gQuestions[0]);
    } else if (gTag == -1 && (e.data.action == "search URL" || e.data.action == "find best URL")) {
        gSearchVersion = e.data.data1;
        if (gSearchVersion.isQuestionVersion()) {
            gSearchURLs[0] = e.data.data2;
            gQuestions[0] = e.data.data3;
            gTaskNumber = e.data.data4;
            gZipCodes[0] = e.data.data5;
            gTag = e.data.tag;
        } else {
            gTag = e.data.tag;
            gTaskNumber = e.data.data2;
            gZipCodes[0] = "";
        }
        if (gZipCodes[0]!="") doZipCode();
		doGoogleButtons();
    }
}
function verifyGotTag(page) {
    if (gTag==-1) {
        var theData = dataFill( "initialize google" );
        if (page == "other" ) var theData = dataFill( "initialize the question" );
        parent.window.opener.postMessage(theData,"*");
    } else return true;
}
function getGoogleDomain() {
    if (gSearchVersion==0) return;
    var title = document.getElementsByClassName("projectTitle")[0].innerHTML;
    if (title.length>0 && title!="Search: Ranking of a Url") {
        var title = title.replace("Search: Keywords on ","");
        title = title.replace("Search: Ranking of a Url on ","");
        title = title.replace("Search: Location and Keywords on ","");
        var splitTitle = title.split(' ');
        gGoogleDomain = splitTitle[0];
    }
}
RegExp.escape= function(s) {
    return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};
String.prototype.getTextAfter = function(afterThis,stripand) {
    if ( typeof stripand === "undefined" ) stripand=true;
    var retText="";
    var regex = new RegExp("^" + RegExp.escape(afterThis) + "\s{0,1}","i");
    retText = this.replace(/(<([^>]+)>)/ig, "");                    // strips out html codes.
    retText = retText.replace(regex,"");
    if (stripand) retText = retText.replace(/&amp;/,"%26");
    else retText = retText.replace(/&amp;/g,"&");
    retText = retText.trim();                          // remove spaces at end of string
    return retText;
}
function taskSearchButtons() {
    if (gSearchVersion==0) return;
    var tasks = document.getElementsByClassName("task cf");
    var i=0;
    for (var i = 0, len=tasks.length; i < len; i++) {
		var theTextReps = tasks[i].getElementsByClassName("text-rep");
        var theTextRep = theTextReps[0].innerHTML.trim();
        var splitTextRep = theTextRep.split('<br>');
        theKeyword = splitTextRep[0].getTextAfter("keyword:");
        var btn = createButton("searchBut" + (i+1),"Search","B," + (i+1) + "," + theKeyword)
        btn.style.fontSize="small";
        btn.style.marginLeft = "5px";
        btn.style.padding = "4px 12px";
        btn.disabled = false;
		if (isPreviewMode() && !ONPREVIEW) { 
			btn.value = "You haven't accepted this hit";
			btn.style.color = "red";
		} else {
			btn.onclick = function() {
				var splitName = this.name.split(',');
				gSearchUrl = "http://www." + gGoogleDomain + "/search?ion=0&num=50&q=" + splitName[2].replace(/\s+/g,"+") +
					"&jrio=feetwalk&ttt=" + splitName[1];
				gMyWindow = window.open(gSearchUrl);
				gTaskNumber = splitName[1];
				initializeGoogle(2000);
				initializeGoogle(5000);
			};
		}
        if (gSearchVersion.isQuestionVersion()) {    // Version 2 and 3 and 5 needs the URL and question.
            var theZipCode="";
            var theURL="";
            var theQuestion="";
            if (splitTextRep.length>1) {
				theURL = splitTextRep[1];
                theQuestion = "Click Url and record one sentence on webpage that relates to the keyword: " + theKeyword;
                theTextReps[0].innerHTML = "";
                var text1 = document.createElement("span");
                text1.innerHTML=splitTextRep[0];
                theTextReps[0].appendChild(text1);
                theTextReps[0].appendChild(btn);
                var text2 = document.createElement("span");
                text2.innerHTML="<br>" + splitTextRep[1];
                theTextReps[0].appendChild(text2);
            } else {
                var x=1;
                if (gSearchVersion==5) {
                    theZipCode = theTextReps[x++].innerHTML;
                }
                theURL = theTextReps[x++].innerHTML;
                theQuestion = splitTextRep[0].getTextAfter("keyword:");
                theQuestion = theTextReps[x++].innerHTML.replace("Instructions: ","");
                theQuestion = theQuestion.trim();
                theTextReps[0].appendChild(btn);
            }
            theZipCode = theZipCode.getTextAfter("zipcode:");
            theURL = theURL.getTextAfter("url:",false);
            gSearchURLs[i] = theURL;
            gQuestions[i] = theQuestion;
            gZipCodes[i] = theZipCode;
        } else theTextReps[0].appendChild(btn);
    }
}
function mainListener(e) { 					// Just a repeater to the frame (Google Chrome fix because messaging to the frame wasn't working.)
    if (gDebugging && gLogging) console.log("..M Received message action - " + e.data.action);
    if ( verifyMessage(e,"main") ) {
		var doc=document.getElementsByTagName("iframe")[0].contentWindow;
    	doc.postMessage(e.data,"*");
    }
}
function frameListener(e) {
    if ( verifyMessage(e,"frame") ) {
        doFrameMessage(e);
    }
}
function enableTextSelections(className) {
    results = document.getElementsByClassName(className);
    for (var i = 0, len=results.length; i < len; i++) {
        results[i].setAttribute("unselectable", "off");
        var theStyle=results[i].getAttribute("style");
        if (theStyle !== null) {
			theStyle = theStyle.replace("-moz-user-select: none;","");
			theStyle = theStyle.replace("-webkit-user-select: none;","");
			results[i].setAttribute("style", theStyle);
		}
    }
}
function isPreviewMode() {
    if (!document.getElementById("preview")) return false;
    if (document.getElementById("preview").innerHTML.indexOf(PREVIEW1)==-1) return false;
    else return true;
}
function withPages_jQuery(NAMED_FunctionToRun) {
  var funcText        = NAMED_FunctionToRun.toString ();
  var funcName        = funcText.replace (/^function\s+(\w+)\s*\((.|\n|\r)+$/, "$1");
  var script          = document.createElement("script");
  script.textContent  = funcText + "\n\n";
  script.textContent += 'jQuery(document).ready(function() {'+funcName+'(jQuery);});';
  document.body.appendChild(script);
};
 function main0($) {  
  $.extend($.fn.enableTextSelect = function() {
    return this.each(function() { $(this).unbind("mousedown"); });
  });
  $("h2.text-rep").enableTextSelect();
  $("h1.text-rep").enableTextSelect();
}

var gHostName = getHostName(gLocation);
// Check if page is on crowdsource or google. If not then check if page was opened by script. If not then exit.
if ( gHostName === "work.crowdsource.com" || gLocation.indexOf("jrio=feetwalk") != -1 || gHostName === "mturk.com" || window.opener ) {
	if (gLogging) console.log (".JR crowdsource keyword/ranking script starts...");
	// The magic begins here by first making sure I am on a crowdsource page
	// and then checking if it's a crowdsource hit that it will work with.
	// After I set up the buttons to make the search for keywords easier.
	if (gHostName=="work.crowdsource.com"){ // Make sure this is on the crowdsource site.
		var inPreview = isPreviewMode();
		withPages_jQuery(main0);
		window.addEventListener("message", function(e){ frameListener(e); }, false);
		gTag = new Date().getTime(); // A unique global tag used to pass messages only for this session.
		var instructions = document.getElementById("instructions").innerHTML;
		if (instructions.toLowerCase().indexOf(VERIFY1.toLowerCase()) != -1) gSearchVersion = 1;
		else if (instructions.toLowerCase().indexOf(VERIFY2.toLowerCase()) != -1) gSearchVersion = 2;
		else if (instructions.toLowerCase().indexOf(VERIFY3.toLowerCase()) != -1) gSearchVersion = 3;
		else if (instructions.toLowerCase().indexOf(VERIFY4.toLowerCase()) != -1) gSearchVersion = 4;
		else if (instructions.toLowerCase().indexOf(VERIFY5.toLowerCase()) != -1) gSearchVersion = 5;
		if (gSearchVersion!=0) {
			if (gDebugging && gLogging) console.log("..Found version " + gSearchVersion);
			window.addEventListener("load", function(){ 
				enableTextSelections("text-rep");
				getGoogleDomain();
				taskSearchButtons();
			}, false);
		}
	} else if (gLocation.search(/^http.?:\/\/[^.]*\.google\./i) != -1 ) {
	  if (gLocation.indexOf("jrio=feetwalk") != -1) {
		if (gDebugging && gLogging) console.log("..Google Url - " + gLocation);
		window.addEventListener("load", function(){
			window.addEventListener("message", function(e){ if ( verifyMessage(e,"google") ) doGoogleMessage(e); }, false);
			window.setTimeout( function() { verifyGotTag("google"); }, 1800 );
			window.setTimeout( function() { verifyGotTag("google"); }, 5000 );
		}, false);
	  }
	} else if (gHostName=="mturk.com") {
		window.addEventListener("message", function(e){ mainListener(e); }, false);
	} else {
		if (gDebugging && gLogging) console.log("..Other Url - " + gLocation);
		window.addEventListener("load", function(){
			window.addEventListener("message", function(e){ if ( verifyMessage(e,"url") ) doGoogleMessage(e); }, false);
			window.setTimeout( function() { verifyGotTag("other"); }, 1800 );
			window.setTimeout( function() { verifyGotTag("other"); }, 6000 );
		}, false);
	}
}