Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: Perlmonks AJAX Voting (greasemonkey plugin)

by eric256 (Parson)
on Dec 13, 2007 at 02:16 UTC ( #656736=note: print w/ replies, xml ) Need Help??


in reply to Perlmonks AJAX Voting

  • Updated 12-17-07: Added a refresh link to the XP Nodelet (click the @ to get a refreshed count of votes)
  • Updated 12-15-07: removed the need for javascript in a big string, fixed issues with voting booth and picked some better XPath's.
  • Updated 12-14-07: fix error with parent_node_id that caused it to be detected as a bot
  • Updated 12-13-07: use local XMLHttpRequest objects and removed extraneous code.

// // ==UserScript== // @name Perlmonks AJAX Vote // @namespace http://www.perlmonks.org/?node_id=398318 // @description Allow background voting via AJAX // @include http://www.perlmonks.* // @include http://perlmonks.* // @exclude http://www.perlmonks.*/?node=Fullpage%20Chat // @exclude http://perlmonks.*/?node=Fullpage%20Chat // ==/UserScript== function postRequest (url, params, onLoad) { var xmlHttpReq = new XMLHttpRequest(); xmlHttpReq.open('POST', url, true); xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-for +m-urlencoded'); xmlHttpReq.onreadystatechange = function() { if (xmlHttpReq.readyState == 4) { onLoad(xmlHttpReq.responseText); }; }; xmlHttpReq.send(params); } function _cast_vote(node_id, voteString, vc, vote) { document.getElementById('pm_'+voteString).innerHTML='<b>Casting Vote. +..</b>'; postRequest('/?', 'displaytype=xml&vc='+vc+'&op=vote&.cgifields='+vot +eString+'&'+voteString+'='+vote, function () { document.getElementById('pm_'+voteString).innerHTML = 'Retriev +ing Node Reputation...'; postRequest('/?', 'displaytype=xml&node_id=' + node_id, function (retHTML) { var parser=new DOMParser(); var doc=parser.parseFromString(retHTML,'text/xml'); var x=doc.getElementsByTagName('field'); for(i=0;i<x.length;i++) { var item=x.item(i); if (item.attributes.getNamedItem('name').value == +'reputation') { document.getElementById('pm_'+voteString).inne +rHTML = 'Reputation: ' + item.childNodes[0].nodeValue; } }; }); }); }; function getNode_byPath (path) { var temp = document.evaluate(path, document, null, XPathResult.FIR +ST_ORDERED_NODE_TYPE, null); if (temp) { return temp.singleNodeValue; } else { return null; } } function getNodes_byPath(path,context) { var nodes = document.evaluate(path,context, null, XPathResult.ORDE +RED_NODE_SNAPSHOT_TYPE, null); var ret = []; for (var i = 0; i < nodes.snapshotLength; i++) { ret.push(nodes.snapshotItem(i)); } return ret; } function remove_byPath (path, context) { var nodes = getNodes_byPath(path, context); for (i in nodes) { nodes[i].parentNode.removeChild(nodes[i]); } } function cast_vote (node_id, voteString, vc, vote) { return function () { _cast_vote(node_id, voteString, vc, vote); }; } function _refresh_votes () { postRequest('/?', 'node_id=16046', function (retHTML) { var parser=new DOMParser(); var doc=parser.parseFromString(retHTML,'text/xml'); var x=doc.getElementsByTagName('XP'); for(i=0;i<x.length;i++) { var item=x.item(i); var xpNodelet = getNode_byPath("//tr[@id='nodelet_body +_row_XP_Nodelet']/td"); if (xpNodelet) xpNodelet.innerHTML = "You have " + item.attribut +es.getNamedItem('votesleft').value + ' votes left today.'; }; }); } function refresh_votes () { return function () { _refresh_votes() } } var xpNodelet = getNode_byPath("//tr[@id='nodelet_head_row_XP_Nodelet' +]/th"); if (xpNodelet) var refresh = document.createElement('a'); refresh.setAttribute("href",'javascript:void(0);'); refresh.removeAttribute("onclick"); refresh.addEventListener("click", refresh_votes(), true); refresh.innerHTML = " @"; xpNodelet.appendChild(refresh); } var inputNode = getNode_byPath("//input[@name='op' and @value='vote']" +); if (inputNode) { var formNode = inputNode.parentNode; var vc; var inputVC = getNode_byPath("//input[@name='vc']", formNode); if (inputVC) { vc = inputVC.value; } var votinginputs = getNodes_byPath("//label/input[@type='radio']", + formNode); for (var i in votinginputs) { var thisInput = votinginputs[i]; if (thisInput.value == 0) { var voteString = thisInput.name; var node_id = voteString.substring(6); var voting_both = document.createElement("div"); voting_both.class = 'reputation'; voting_both.id = "pm_" + voteString; var up_vote = document.createElement('a'); up_vote.setAttribute("href",'javascript:void(0);'); up_vote.removeAttribute("onclick"); up_vote.addEventListener("click", cast_vote(node_id, voteS +tring, vc, 1), true); up_vote.innerHTML = "++"; voting_both.appendChild(up_vote); var spacer = document.createElement("span"); spacer.innerHTML = "&nbsp;"; voting_both.appendChild(spacer); var down_vote = document.createElement('a'); down_vote.setAttribute("href",'javascript:void(0);'); down_vote.removeAttribute("onclick"); down_vote.addEventListener("click", cast_vote(node_id, vot +eString, vc, -1), true); down_vote.innerHTML = "--"; voting_both.appendChild(down_vote); thisInput.parentNode.insertBefore(voting_both, thisInput); } thisInput.parentNode.removeChild(thisInput); } // remove the original voting labels remove_byPath("//div[@class='vote']//tt", formNode); // delete the submit button remove_byPath("//input[@name='sexisgreat']", document); }

___________
Eric Hodges


Comment on Re: Perlmonks AJAX Voting (greasemonkey plugin)
Download Code
Re^2: Perlmonks AJAX Voting (greasemonkey plugin)
by ikegami (Pope) on Dec 13, 2007 at 03:01 UTC
    Greasemonkey isn't needed since PerlMonks already allows you to inject HTML and scripts via the Free Nodelet. Perhaps I'll take a stab at converting the code next week.
Re^2: Perlmonks AJAX Voting (greasemonkey plugin)
by citromatik (Curate) on Dec 13, 2007 at 11:17 UTC

    Maybe I'm wrong, but I see that you are using global xmlHttpReq objects in asynchronous requests. This could lead into problems, because a second (and successive) asynchronous request (i.e. a second vote in the page) will overwrite previous ones if they are not finished and you'll never receive a response from them.

    There are some ways of solving this, for example, putting multiple xmlHttpReq objects in an array.

    Sorry if I misread your code

    citromatik

      Thanks for that catch, I updated the code to use local variables, some testing shows that this works now. Guess I never though of anyone voting that fast!


      ___________
      Eric Hodges
Re^2: Perlmonks AJAX Voting (greasemonkey plugin)
by eric256 (Parson) on Dec 17, 2007 at 21:18 UTC

    Updated 12-17-07: Added a refresh link to the XP Nodelet (click the @ to get a refreshed count of votes)


    ___________
    Eric Hodges

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://656736]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (6)
As of 2015-07-02 01:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (25 votes), past polls