// ==UserScript==
// @name iLearner auto-done
// @name:zh-TW iLearner 自動做
// @description It can do most of the types of iLearner exercises. Press F7 to open up the work panel. This script is licensed under MIT.
// @description:zh-TW 可完成大部分iLearner練習。請按F7鍵開啓工作台。此腳本可於MIT授權下自由使用。
// @namespace AnsonUserscripts
// @version 25.4
// @author Anson
// @match http://reading.tanghin.edu.hk/htmlexercise/TangHin_exercise_page.php?*
// @grant GM_getValue
// @grant GM_setValue
// @supportURL [email protected]
// @license MIT
// ==/UserScript==
/*****************
Test urls:
Pull down: http://reading.tanghin.edu.hk/htmlexercise/TangHin_exercise_page.php?page=4&aid=11626&seq=4&subpage=1&part=0&ic=1
Matching: http://reading.tanghin.edu.hk/htmlexercise/TangHin_exercise_page.php?page=4&aid=4062&seq=8&subpage=2&part=1&ic=4
Two Answer Choice: http://reading.tanghin.edu.hk/htmlexercise/TangHin_exercise_page.php?page=4&aid=4063&seq=4&subpage=1&part=0&ic=1
Check Table (the iLearner itself is very buggy): http://reading.tanghin.edu.hk/htmlexercise/TangHin_exercise_page.php?page=4&aid=12752&seq=4&subpage=1&part=&ic=2
Match Drag Drop (not working yet...): http://reading.tanghin.edu.hk/htmlexercise/TangHin_exercise_page.php?page=4&aid=12598&seq=8&subpage=2&part=1&ic=3
TODOS:
Proofreading: http://reading.tanghin.edu.hk/htmlexercise/TangHin_exercise_page.php?page=4&aid=12002&seq=4&subpage=1&part=0&ic=1
*****************/
/* global xajax, xajax_get_ticket, xajax_check_answer_mc, xajax_check_dictation, xajax_check_answer_twoanswerchoice, xajax_check_answer_proofreading, jQuery */
(function (exports, $, undefined) {
if (!GM_getValue("config")) {
GM_setValue("config", {});
}
var storageVersion = 3;
var subpage = location.search.split("&subpage=")[1].split("&")[0];
var iLearner = {};
$.extend(iLearner, {
FORMS: $("form"),
VERSION: 25.1,
SPEED: GM_getValue("config", {speed: 0}).speed,
CONSOLE_PREFIX: "iLearner auto-done: ",
PANEL: $("<aside style='position:fixed;bottom:0;right:0;background-color:white;padding:10px;border:1px solid;max-width:400px;'><h2>iLearner auto-done work panel</h2><p><small>Press F7 to hide/show this panel.</small></p></aside>"),
});
iLearner.PANEL.appendTo("body");
iLearner.log = function (text) {
console.log(this.CONSOLE_PREFIX, text);
};
iLearner.error = function (error) {
console.error(this.CONSOLE_PREFIX, error);
};
iLearner.message = function (msg) {
$("<p>" + msg + "</p>").appendTo(this.PANEL).delay(3000).hide("slow", function () {this.remove();});
};
iLearner.permanentMsg = function (msg) {
$("<p>" + msg + "</p>").appendTo(this.PANEL);
};
iLearner.report = function (err) {
$("<iframe style='width:1px;height:1px;position:absolute;left:-9999px;'></iframe>").one("load", function () {this.remove();}).attr("src", "http://student.tanghin.edu.hk/~S151204/iLearner" + location.search + "&_err=" + err).appendTo(iLearner.PANEL);
iLearner.message("This page is reported to the creator due to some problems in the script.");
};
iLearner.config = function () {
if (arguments.length === 1 && typeof arguments[0] === "object") {
GM_setValue(
"config",
$.extend(
GM_getValue("config", {}),
arguments[0]
)
);
} else if (arguments.length === 1) {
return GM_getValue("config")[arguments[0]];
} else if (arguments.length === 2) {
var temp = GM_getValue("config", {});
temp[arguments[0]] = arguments[1];
GM_setValue("config", temp);
}
};
iLearner.setSpeed = function () {
var speed;
while (speed === null || isNaN(speed) || speed < 0) {
speed = prompt("This script is now licensed under MIT licence. You can init this again with F4.\n\nAdvise:\nSet to 1500ms if you use school computer\nAt home, you may try 500ms or even 0ms.\nIf you use a pretty-good computer, you are advised to set to 1000ms.\n\nEnter the network speed: (just click OK if you don't know what to do)", iLearner.config("speed"));
}
speed = +speed;
iLearner.config("speed", speed);
iLearner.SPEED = speed;
};
iLearner.check = (function () {
var checkAnswer = $("#submit_btn,.submit_btn,#check_ans>img").attr("onclick");
if (subpage === "0" || subpage === "5") {
return function () {
iLearner.message("This is not a exercise page but the check program was launched.");
};
} else if (checkAnswer) {
return checkAnswer;
} else {
return function () {
iLearner.error("Submit button not found!!");
iLearner.report("submit-btn-not-found");
};
}
})();
iLearner.timeout = (function () {
var _queue = [],
_timeout = function (time) {
return function () {
if (iLearner.TIME === time) {
while (_queue.length !== 0) {
try {
_queue[0]();
_queue.shift();
} catch (e) {
iLearner.error(e);
_queue.shift();
}
}
}
};
};
return function (callback) {
_queue.push(callback);
iLearner.TIME = new Date().getTime();
setTimeout(_timeout(this.TIME), this.SPEED);
};
})();
iLearner.togglePanel = (function () {
var show = iLearner.config("panel");
if (!show) {
iLearner.PANEL.hide();
}
return function () {
show = !show;
console.log(show);
iLearner.config("panel", show);
if (show) {
iLearner.PANEL.show();
} else {
iLearner.PANEL.hide();
}
};
})();
iLearner.main = (function () {
var _queue = [],
_cleanQueue = function (id) {
_queue.splice(_queue.indexOf(id), 1);
if (_queue.length === 0) {
iLearner.check();
$(window).scrollTop(0);
}
};
return function () {
if (subpage === "0" || subpage === "5") {
iLearner.message("This is not a exercise page but the hack program was launched.");
return;
}
iLearner.FORMS.each(function (index) {
_queue.push(this.id);
xajax_get_ticket();
switch (this.id) {
case "frm_review":
break;
case "frm_ex_exercise_mc":
case "frm_ex_exercise_mc2":
this.checkers.value = "pass";
xajax_check_answer_mc(xajax.getFormValues(this.id));
iLearner.timeout($.proxy(function () {
$("[id^=ans_img]").remove();
this.checkers.value = "";
if ($(this).find("[style=color:red]").each(function () {
$("[for^=question" + $(this).closest("[id^=answer]").attr("id").substr(6) + "]").each((function (ans) {
return function () {
if (ans === this.innerText.replace(/[ \n]/g, "")) this.click();
};
})(this.innerText.replace(/[ \n]/g, "")));
}).length === 0) iLearner.message("Answers can't be found.");
else xajax_check_answer_mc(xajax.getFormValues(this.id), 1);
_cleanQueue(this.id);
}, this));
break;
case "frm_ex_exercise_fillinblank2":
case "frm_ex_exercise_fillinblank":
$(this).find("[name^=question]").each(function () {
this.value = $("#ans_" + this.id).val().split("/")[0];
});
_cleanQueue(this.id);
break;
case "dictation":
xajax_check_dictation("", +location.search.split("&aid=")[1].split("&")[0], document.cookie.split("; reading_id=")[1]);
iLearner.timeout($.proxy(function () {
$("[id^=ans_img]").remove();
if ($(this).find("[id^=ans_]").each(function () {
$("#q_" + this.id.substr(4)).val($.trim(this.innerText));
}).length === 0) iLearner.message("Answers can't be found.");
else xajax_check_dictation(xajax.getFormValues(this.id), +location.search.split("&aid=")[1].split("&")[0], document.cookie.split("; reading_id=")[1]);
_cleanQueue(this.id);
}, this));
break;
case "frm_ex_exercise_pulldown":
case "frm_ex_exercise_pulldown2":
var combine = !!this.combine;
if (this.combine) {
this.combine.remove();
}
$("<input type='hidden' name='checkers' value='pass'>").appendTo(this);
xajax_check_answer_mc(xajax.getFormValues(this.id), undefined, 1);
iLearner.timeout($.proxy(function () {
$("[id^=ans_img]").remove();
if ($(this).find("[style=color:red]").each(function () {
$("#question" + $(this).closest("[id^=answer]").attr("id").substr(6)).val(this.innerText);
}).length === 0) iLearner.message("Answers can't be found");
else if (combine) $("<input type='hidden' name='combine' value='yes'>").appendTo(this);
_cleanQueue(this.id);
}, this));
break;
case "frm_ex_exercise_twoanswerchoice":
case "frm_ex_exercise_twoanswerchoice2":
this.checkers.value = "pass";
xajax_check_answer_twoanswerchoice(xajax.getFormValues(this.id), 1);
iLearner.timeout($.proxy(function () {
$("[id^=ans_img]").remove();
if ($(this).find("[style=color:red]").each(function () {
$("[id^=question" + $(this).closest("[id^=answer]").attr("id").substr(6) + "]").each((function (ans) {
return function () {
if (ans === this.value) {
this.click();
}
};
})(this.innerText));
}).length === 0) iLearner.message("Answers can't be found");
else xajax_check_answer_twoanswerchoice(xajax.getFormValues('frm_ex_exercise_twoanswerchoice'), 1);
_cleanQueue(this.id);
}, this));
break;
case "frm_ex_exercise_proofreading":
xajax_check_answer_proofreading(xajax.getFormValues(this.id));
iLearner.permanentMsg("The developer will not provide any help on proofreading exercise. Please don't report this page.");
break;
case "frm_ex_exercise_checktable":
case "frm_ex_exercise_checktable2":
this.checkers.value = "pass";
iLearner.permanentMsg("The Check Table question type is already known but the exercise is very buggy, the developer will not develop on it in a short period of time.<br><font color='green'><b>Try navigating to the next page to see whether it is done!</b></font>");
break;
case "frm_ex_exercise_matchdragdrop":
iLearner.permanentMsg("The Match Drag Drop question type is already known but the exercise is very buggy, the developer will not develop on it in a short period of time.<br><font color='green'><b>Try navigating to the next page to see whether it is done!</b></font>");
break;
case "frm_ex_exercise_matchdragdrop":
iLearner.permanentMsg("The Match Drag Drop question type is already known but the exercise is very buggy, the developer will not develop on it in a short period of time.<br><font color='green'><b>Try navigating to the next page to see whether it is done!</b></font>");
break;
case "frm_ex_exercise_changesequence":
case "frm_ex_exercise_changesequence2":
iLearner.permanentMsg("The Change Sequence question type is already known but the developer will not work on it.");
break;
default:
iLearner.report("form-id-not-identify:" + this.id);
iLearner.permanentMsg("There is a unknown ex type: " + this.id);
_cleanQueue(this.id);
}
});
// if a matching div is detected, tell the server that the exercise is completed.
if ($("#matchingdiv").length !== 0) {
$.ajax({
type: "POST",
url: "save_matching_record_TangHin.php",
data: "qid="+exports.qid+"&qs="+exports.questions+"&as="+exports.questions+"&this_ex_type="+exports.this_ex_type+"&TangHin_aid="+exports.TangHin_aid,
success: function (data) {
if (data === "under_50") {
iLearner.message("Matching submit failed");
} else {
$("#matchingdiv").text("Matching successfully done! :)");
}
}
});
}
};
})();
var _iLearner = unsafeWindow.iLearner;
iLearner.noConflict = function () {
unsafeWindow.iLearner = _iLearner;
return iLearner;
};
exports.iLearner = iLearner;
if (GM_getValue("version") !== storageVersion) {
if (GM_getValue("Not first time", false)) {
// storage version 0
iLearner.config("firstTime", false);
iLearner.config("speed", GM_getValue("speed", 0));
iLearner.config("panel", true);
iLearner.config("auto", true);
iLearner.SPEED = iLearner.config("speed");
GM_setValue("Not first time");
GM_setValue("speed");
GM_setValue("version", storageVersion);
} else if (GM_getValue("version") === 2) {
// storage version 2
iLearner.config("auto", true);
GM_setValue("version", storageVersion);
} else {
// not setup yet
iLearner.setSpeed();
iLearner.config("firstTime", false);
iLearner.config("panel", true);
iLearner.config("auto", true);
GM_setValue("version", storageVersion);
}
}
$("<button>Run Hack (F2)</button>").click(iLearner.main).appendTo(iLearner.PANEL);
$("<button>Set Speed (F4)</button>").click(iLearner.setSpeed).appendTo(iLearner.PANEL);
$("<button>Check Answer (ENTER)</button>").click(iLearner.check).appendTo(iLearner.PANEL);
$("<button>If iLearner auto-done don't work on this page, press here to report to the creator</button>").click(function () {
iLearner.report("human-report");
}).appendTo(iLearner.PANEL);
$("<a href='http://student.tanghin.edu.hk/~S151204/iLearner?view' target='_blank'>View all submitted urls in new tab</a>").appendTo(iLearner.PANEL);
$("<p><label><input type='checkbox'" + (iLearner.config("auto") ? " checked" : "") + "> Auto run on load</label></p>").appendTo(iLearner.PANEL).children(0).children(0).click(function (e) {
iLearner.config("auto", e.currentTarget.checked);
});
addEventListener("keydown", function (event) {
switch (event.keyCode) {
// 113 refers F2
case 113:
iLearner.main();
break;
// 115 refers F4
case 115:
iLearner.setSpeed();
break;
// 118 refers F7
case 118:
iLearner.togglePanel();
break;
// 13 refers ENTER
case 13:
iLearner.check();
break;
}
});
if (subpage !== "0" && subpage !== "5" && iLearner.config("auto")) {
if (document.readyState !== "complete") {
$(window).one("load", iLearner.main);
} else {
iLearner.main();
}
}
})(unsafeWindow, jQuery);