Created
September 8, 2017 01:43
-
-
Save MatthiasPortzel/6f61696c7fa4ad2c0d48ebfe202702dc to your computer and use it in GitHub Desktop.
A bookmarklet to improve voting on Khan Academy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
//The element that we mess with | |
var base = document.getElementsByClassName("voting-wrap")[0]; | |
//No voting base means we're looking at a child account program or a tutorial/offical video | |
if (!base) { | |
//Try just adding a whole new thing | |
var wrap = document.getElementsByClassName("buttons_vponqv"); | |
//If we're on an offical program there will be a share button and we can add it next to that | |
if (wrap.length) { | |
wrap = wrap[0]; | |
base = document.createElement("span"); | |
//If we're on a child account program we need to add it above the tabs | |
}else { | |
wrap = document.getElementById("scratchpad-tabs").parentNode; | |
base = document.createElement("div"); | |
base.style.textAlign = "center"; | |
} | |
wrap.insertBefore(base, wrap.childNodes[0]); | |
base.classList.add("voting-wrap"); | |
}else { | |
base = base.getElementsByClassName("discussion-meta-controls")[0].childNodes[0]; | |
} | |
var attr = KAdefine.require("./javascript/scratchpads-package/scratchpad-ui.js").ScratchpadUI.scratchpad.attributes; | |
var cookie = KAdefine.require("./javascript/shared-package/cookies.js").readCookie("fkey"); | |
var key = attr.key; | |
var id = attr.id; | |
var orgVotes = attr.sumVotesIncremented; //The number of votes, not including our own | |
var loaded = false; | |
//Our vote | |
var voteType = 0; | |
base.innerHTML = ` | |
<div class="discussion-vote"> | |
<div id="m-vote-up" class="vote-for vote-for-js vote-up" style="margin: 0 5px;"></div> | |
<span id="m-vote-count" style="font-size: 17px; color: rgb(33, 36, 44);">${orgVotes}</span> | |
<div id="m-vote-down" class="vote-for vote-for-js vote-down" style="margin: 0 5px"></div> | |
</div>`; | |
var voteUp = document.getElementById("m-vote-up"); | |
var voteDn = document.getElementById("m-vote-down"); | |
var mVote = function () { | |
if (!loaded) return; | |
//If we clicked the vote up button we assume we're voting it. | |
if (this.classList.contains("vote-up")) { | |
voteType = 1; | |
voteDn.classList.remove("voted");//Can't vote up and down | |
} | |
if (this.classList.contains("vote-down")) { | |
voteType = -1; | |
voteUp.classList.remove("voted"); | |
} | |
//If we already were voted, then set our vote to neutral | |
if (this.classList.contains("voted")) { | |
voteType = 0; | |
} | |
this.classList.toggle("voted"); | |
//Show the orignal votes, plus ours | |
document.getElementById("m-vote-count").innerText = orgVotes + voteType; | |
var req = new XMLHttpRequest(); | |
req.addEventListener("load", function () { | |
if (this.status === 204) return; //204. No Content. | |
var res = JSON.parse(this.response); | |
if (res.error) { | |
alert("Failed with error:\n\n" + res.error); | |
} | |
}); | |
//Send our vote | |
req.open("POST", `https://www.khanacademy.org/api/internal/discussions/voteentity?entity_key=${key}&vote_type=${voteType}`); | |
req.setRequestHeader("X-KA-FKey", cookie); | |
req.send(); | |
}; | |
voteUp.addEventListener("click", mVote); | |
voteDn.addEventListener("click", mVote); | |
//Fetch if we previously upvoted or downvoted the program | |
var req = new XMLHttpRequest(); | |
req.addEventListener("load", function () { | |
var res = JSON.parse(this.response); | |
//Makes sure we have the most recent vote count | |
orgVotes = res.scratchpad.sumVotesIncremented; | |
document.getElementById("m-vote-count").innerText = orgVotes; | |
if (res.upVoted) { | |
voteType = 1; | |
orgVotes -= 1; | |
voteUp.classList.add("voted"); | |
} | |
if (res.downVoted) { | |
voteType = -1; | |
orgVotes += 1; | |
voteDn.classList.add("voted"); | |
} | |
loaded = true; | |
}); | |
req.open("GET", `https://www.khanacademy.org/api/internal/show_scratchpad?scratchpad_id=${id}&projection={"upVoted":1,"downVoted":1,"scratchpad":{"sumVotesIncremented":1}}`); | |
req.setRequestHeader("X-KA-FKey", cookie); | |
req.send(); | |
})("©Matthias") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(){var base=document.getElementsByClassName("voting-wrap")[0];if(!base){var wrap=document.getElementsByClassName("buttons_vponqv");if(wrap.length){wrap=wrap[0];base=document.createElement("span")}else{wrap=document.getElementById("scratchpad-tabs").parentNode;base=document.createElement("div");base.style.textAlign="center"}wrap.insertBefore(base,wrap.childNodes[0]);base.classList.add("voting-wrap")}else{base=base.getElementsByClassName("discussion-meta-controls")[0].childNodes[0]}var attr=KAdefine.require("./javascript/scratchpads-package/scratchpad-ui.js").ScratchpadUI.scratchpad.attributes;var cookie=KAdefine.require("./javascript/shared-package/cookies.js").readCookie("fkey");var key=attr.key;var id=attr.id;var orgVotes=attr.sumVotesIncremented;var loaded=false,voteType=0;base.innerHTML=`<div class="discussion-vote"><div id="m-vote-up" class="vote-for vote-for-js vote-up" style="margin: 0 5px;"></div><span id="m-vote-count" style="font-size:17px;color:rgb(33,36,44);">${orgVotes}</span><div id="m-vote-down" class="vote-for vote-for-js vote-down" style="margin: 0 5px"></div></div>`;var voteUp=document.getElementById("m-vote-up");var voteDn=document.getElementById("m-vote-down");var mVote=function(){if(!loaded)return;if(this.classList.contains("vote-up")){voteType=1;voteDn.classList.remove("voted")}if(this.classList.contains("vote-down")){voteType=-1;voteUp.classList.remove("voted")}if(this.classList.contains("voted")){voteType=0}this.classList.toggle("voted");document.getElementById("m-vote-count").innerText=orgVotes+voteType;var req=new XMLHttpRequest;req.addEventListener("load",function(){if(this.status===204)return;var res=JSON.parse(this.response);if(res.error){alert("Failed with error:\n\n"+res.error)}});req.open("POST",`https://www.khanacademy.org/api/internal/discussions/voteentity?entity_key=${key}&vote_type=${voteType}`);req.setRequestHeader("X-KA-FKey",cookie);req.send()};voteUp.addEventListener("click",mVote);voteDn.addEventListener("click",mVote);var req=new XMLHttpRequest;req.addEventListener("load",function(){var res=JSON.parse(this.response);orgVotes=res.scratchpad.sumVotesIncremented;document.getElementById("m-vote-count").innerText=orgVotes;if(res.upVoted){voteType=1;orgVotes-=1;voteUp.classList.add("voted")}if(res.downVoted){voteType=-1;orgVotes+=1;voteDn.classList.add("voted")}loaded=true});req.open("GET",`https://www.khanacademy.org/api/internal/show_scratchpad?scratchpad_id=${id}&projection={"upVoted":1,"downVoted":1,"scratchpad":{"sumVotesIncremented":1}}`);req.setRequestHeader("X-KA-FKey",cookie);req.send()})("©Matthias"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment