mirror of
https://github.com/codeninjasgg/code-sensei.git
synced 2024-11-27 01:35:35 -05:00
added bookmarklet distro to github
This commit is contained in:
parent
4adcbd1c36
commit
763e2a601f
4 changed files with 134 additions and 9 deletions
|
@ -1,7 +1,14 @@
|
|||
# `sensei-grading-bookmarklet`
|
||||
|
||||
[![Bookmarklet Size][bookmarklet_size_badge]][bookmarklet_file]
|
||||
|
||||
> A bookmarklet to enhance the grading experience of code ninja assignments.
|
||||
|
||||
## Purpose
|
||||
|
||||
Grading code ninjas' submissions is slow and tedious because the current site has a poor user experience.
|
||||
My goal is to make an entirely keyboard-navigable enhancement in the form of a bookmarklet.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Visit the [grading console][grading_console] while logged in as a code sensei.
|
||||
|
@ -10,6 +17,16 @@
|
|||
1. Click <kbd>enter</kbd> to execute the bookmarklet code.
|
||||
1. Grade.
|
||||
|
||||
## Keybinds
|
||||
|
||||
| Key | Action |
|
||||
| ---------------- | ------------------------------ |
|
||||
| <kbd>i</kbd> | Marks assignment as incomplete |
|
||||
| <kbd>1</kbd> | Rates assignment as 1-star |
|
||||
| <kbd>2</kbd> | Rates assignment as 2-star |
|
||||
| <kbd>3</kbd> | Rates assignment as 3-star |
|
||||
| <kbd>enter</kbd> | Submits assigment grade |
|
||||
|
||||
## Development
|
||||
|
||||
This [bookmarklet][bookmarklet_definition] is compiled using [NodeJS][node_installation].
|
||||
|
@ -18,11 +35,6 @@ Upon cloning this project, execute `npm i` to install of the necessary dependenc
|
|||
To run in development mode, run `npm run dev`.
|
||||
To generate the bookmarklet, run `npm start`.
|
||||
|
||||
## Purpose
|
||||
|
||||
Grading code ninjas' submissions is slow and tedious because the current site has a poor user experience.
|
||||
My goal is to make an entirely keyboard-navigable enhancement in the form of a bookmarklet.
|
||||
|
||||
## Security
|
||||
|
||||
For security reasons, modern browsers will make you type out the prefix (`javascript:`) manually.
|
||||
|
@ -32,3 +44,5 @@ This code, however, is non-malicious, so no worries in this case.
|
|||
[grading_console]: https://gdp.code.ninja/Grading
|
||||
[bookmarklet_definition]: https://en.wikipedia.org/wiki/Bookmarklet
|
||||
[node_installation]: https://nodejs.org/en/download/
|
||||
[bookmarklet_size_badge]: https://img.badgesize.io/EthanThatOneKid/code-sensei/main/sensei-grading-bookmarklet/bookmarklet.txt
|
||||
[bookmarklet_file]: bookmarklet.txt
|
||||
|
|
|
@ -1,3 +1,112 @@
|
|||
// https://gist.github.com/EthanThatOneKid/95e8393c0afc1a35efda6f514d4ee6ea
|
||||
|
||||
alert("Hello, World!");
|
||||
const selectors = {
|
||||
incompleteBtn: "#IsIncompleteYes",
|
||||
notesTextarea:
|
||||
"#gradingNode > div > div:nth-child(1) > table > tbody > tr:nth-child(8) > td:nth-child(2) > textarea",
|
||||
star1:
|
||||
"#gradingNode > div > div:nth-child(1) > table > tbody > tr:nth-child(7) > td:nth-child(2) > span.pull-left.ml-3.mt-1.stars > i:nth-child(1)",
|
||||
star2:
|
||||
"#gradingNode > div > div:nth-child(1) > table > tbody > tr:nth-child(7) > td:nth-child(2) > span.pull-left.ml-3.mt-1.stars > i:nth-child(2)",
|
||||
star3:
|
||||
"#gradingNode > div > div:nth-child(1) > table > tbody > tr:nth-child(7) > td:nth-child(2) > span.pull-left.ml-3.mt-1.stars > i:nth-child(3)",
|
||||
submit: "#grade-form > button",
|
||||
previewContainer: "#gradingNode > div > div:nth-child(2)",
|
||||
assignmentBtn:
|
||||
"body > div.body-content > div:nth-child(2) > div:nth-child(3) > table > tbody > tr > td:nth-child(7) > a",
|
||||
assignmentLink: "#gradingNode > div > div:nth-child(2) > div > a",
|
||||
};
|
||||
|
||||
let currentAssignmentOnPage = 0;
|
||||
|
||||
const defaultIdleTimeout = 5e3,
|
||||
assignmentLoadDelay = 1e3;
|
||||
|
||||
const setIdleTimeout = (...args) => {
|
||||
let timeoutId = setTimeout(...args);
|
||||
const alertUserAction = () => {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(...args);
|
||||
};
|
||||
return alertUserAction;
|
||||
};
|
||||
|
||||
const actions = {
|
||||
incomplete() {
|
||||
// Sensei declares game incomplete.
|
||||
document.querySelector(selectors.incompleteBtn).click();
|
||||
const textarea = document.querySelector(selectors.notesTextarea);
|
||||
textarea.focus();
|
||||
const updateTextarea = setIdleTimeout(
|
||||
() => document.querySelector(selectors.submit).focus(),
|
||||
defaultIdleTimeout
|
||||
);
|
||||
textarea.addEventListener("keypress", updateTextarea);
|
||||
},
|
||||
rate(stars) {
|
||||
// Sensei gives a rating out of 3 stars.
|
||||
const selectorKey = `star${stars}`;
|
||||
if (selectorKey in selectors) {
|
||||
document.querySelector(selectors[selectorKey]).click();
|
||||
this.submit();
|
||||
}
|
||||
},
|
||||
submit() {
|
||||
document.querySelector(selectors.submit).click();
|
||||
currentAssignmentOnPage++;
|
||||
this.nextAssignment();
|
||||
},
|
||||
nextAssignment() {
|
||||
document
|
||||
.querySelectorAll(selectors.assignmentBtn)
|
||||
[currentAssignmentOnPage].click();
|
||||
setTimeout(() => {
|
||||
const preview = document.createElement("iframe");
|
||||
preview.width = "1600px";
|
||||
preview.height = "1400px";
|
||||
preview.src = document.querySelector(selectors.assignmentLink).href;
|
||||
document.querySelector(selectors.previewContainer).innerHTML = "";
|
||||
document.querySelector(selectors.previewContainer).appendChild(preview);
|
||||
document
|
||||
.querySelector(selectors.previewContainer)
|
||||
.parentElement.scrollIntoView();
|
||||
}, assignmentLoadDelay);
|
||||
},
|
||||
};
|
||||
|
||||
document.addEventListener("keypress", (event) => {
|
||||
try {
|
||||
switch (event.key) {
|
||||
case "i":
|
||||
actions.incomplete();
|
||||
break;
|
||||
|
||||
case "1":
|
||||
actions.rate(1);
|
||||
break;
|
||||
|
||||
case "2":
|
||||
actions.rate(2);
|
||||
break;
|
||||
|
||||
case "3":
|
||||
actions.rate(3);
|
||||
break;
|
||||
|
||||
case "enter":
|
||||
actions.submit();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(`Sensei Error: ${error}`);
|
||||
}
|
||||
});
|
||||
|
||||
const main = () => {
|
||||
actions.nextAssignment();
|
||||
};
|
||||
|
||||
main();
|
||||
|
|
1
sensei-grading-bookmarklet/bookmarklet.txt
Normal file
1
sensei-grading-bookmarklet/bookmarklet.txt
Normal file
|
@ -0,0 +1 @@
|
|||
javascript:(function()%7B%22use%20strict%22%3Bvar%20selectors%3D%7BincompleteBtn%3A%22%23IsIncompleteYes%22%2CnotesTextarea%3A%22%23gradingNode%20%3E%20div%20%3E%20div%3Anth-child(1)%20%3E%20table%20%3E%20tbody%20%3E%20tr%3Anth-child(8)%20%3E%20td%3Anth-child(2)%20%3E%20textarea%22%2Cstar1%3A%22%23gradingNode%20%3E%20div%20%3E%20div%3Anth-child(1)%20%3E%20table%20%3E%20tbody%20%3E%20tr%3Anth-child(7)%20%3E%20td%3Anth-child(2)%20%3E%20span.pull-left.ml-3.mt-1.stars%20%3E%20i%3Anth-child(1)%22%2Cstar2%3A%22%23gradingNode%20%3E%20div%20%3E%20div%3Anth-child(1)%20%3E%20table%20%3E%20tbody%20%3E%20tr%3Anth-child(7)%20%3E%20td%3Anth-child(2)%20%3E%20span.pull-left.ml-3.mt-1.stars%20%3E%20i%3Anth-child(2)%22%2Cstar3%3A%22%23gradingNode%20%3E%20div%20%3E%20div%3Anth-child(1)%20%3E%20table%20%3E%20tbody%20%3E%20tr%3Anth-child(7)%20%3E%20td%3Anth-child(2)%20%3E%20span.pull-left.ml-3.mt-1.stars%20%3E%20i%3Anth-child(3)%22%2Csubmit%3A%22%23grade-form%20%3E%20button%22%2CpreviewContainer%3A%22%23gradingNode%20%3E%20div%20%3E%20div%3Anth-child(2)%22%2CassignmentBtn%3A%22body%20%3E%20div.body-content%20%3E%20div%3Anth-child(2)%20%3E%20div%3Anth-child(3)%20%3E%20table%20%3E%20tbody%20%3E%20tr%20%3E%20td%3Anth-child(7)%20%3E%20a%22%2CassignmentLink%3A%22%23gradingNode%20%3E%20div%20%3E%20div%3Anth-child(2)%20%3E%20div%20%3E%20a%22%7D%2CcurrentAssignmentOnPage%3D0%2CdefaultIdleTimeout%3D5e3%2CassignmentLoadDelay%3D1e3%2CsetIdleTimeout%3Dfunction()%7Bfor(var%20e%3Darguments.length%2Ct%3DArray(e)%2Cn%3D0%3Bn%3Ce%3Bn%2B%2B)t%5Bn%5D%3Darguments%5Bn%5D%3Bvar%20i%3DsetTimeout.apply(void%200%2Ct)%3Breturn%20function()%7BclearTimeout(i)%2Ci%3DsetTimeout.apply(void%200%2Ct)%7D%7D%2Cactions%3D%7Bincomplete%3Afunction()%7Bdocument.querySelector(selectors.incompleteBtn).click()%3Bvar%20e%3Ddocument.querySelector(selectors.notesTextarea)%3Be.focus()%3Bvar%20t%3DsetIdleTimeout(function()%7Breturn%20document.querySelector(selectors.submit).focus()%7D%2CdefaultIdleTimeout)%3Be.addEventListener(%22keypress%22%2Ct)%7D%2Crate%3Afunction(e)%7Be%3D%22star%22%2Be%3Be%20in%20selectors%26%26(document.querySelector(selectors%5Be%5D).click()%2Cthis.submit())%7D%2Csubmit%3Afunction()%7Bdocument.querySelector(selectors.submit).click()%2CcurrentAssignmentOnPage%2B%2B%2Cthis.nextAssignment()%7D%2CnextAssignment%3Afunction()%7Bdocument.querySelectorAll(selectors.assignmentBtn)%5BcurrentAssignmentOnPage%5D.click()%2CsetTimeout(function()%7Bvar%20e%3Ddocument.createElement(%22iframe%22)%3Be.width%3D%221600px%22%2Ce.height%3D%221400px%22%2Ce.src%3Ddocument.querySelector(selectors.assignmentLink).href%2Cdocument.querySelector(selectors.previewContainer).innerHTML%3D%22%22%2Cdocument.querySelector(selectors.previewContainer).appendChild(e)%2Cdocument.querySelector(selectors.previewContainer).parentElement.scrollIntoView()%7D%2CassignmentLoadDelay)%7D%7D%3Bdocument.addEventListener(%22keypress%22%2Cfunction(e)%7Btry%7Bswitch(e.key)%7Bcase%22i%22%3Aactions.incomplete()%3Bbreak%3Bcase%221%22%3Aactions.rate(1)%3Bbreak%3Bcase%222%22%3Aactions.rate(2)%3Bbreak%3Bcase%223%22%3Aactions.rate(3)%3Bbreak%3Bcase%22enter%22%3Aactions.submit()%7D%7Dcatch(e)%7Bconsole.log(%22Sensei%20Error%3A%20%22%2Be)%7D%7D)%3Bvar%20main%3Dfunction()%7Bactions.nextAssignment()%7D%3Bmain()%3B%7D)()
|
|
@ -1,6 +1,5 @@
|
|||
// https://github.com/mrcoles/bookmarklet
|
||||
const fs = require("fs");
|
||||
const bookmarklet = require("bookmarklet");
|
||||
const bookmarklet = require("bookmarklet"); // https://github.com/mrcoles/bookmarklet
|
||||
|
||||
fs.readFile("./app.js", "utf8", (error, content) => {
|
||||
if (error !== null) {
|
||||
|
@ -8,5 +7,7 @@ fs.readFile("./app.js", "utf8", (error, content) => {
|
|||
}
|
||||
const { code, options } = bookmarklet.parseFile(content);
|
||||
const dist = bookmarklet.convert(code, options);
|
||||
fs.writeFile("bookmarklet.txt", dist, undefined, () => {
|
||||
console.log(`Here is your bookmarklet:\n${dist}`);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue