- // ==UserScript==
- // @name AnkiWeb Quiz
- // @namespace https://greasyfork.org/users/102866
- // @description Shows quiz on ankiweb
- // @include https://ankiweb.net/*
- // @include http://ankiweb.net/*
- // @require https://code.jquery.com/jquery-3.1.1.min.js
- // @author TiLied
- // @version 0.2.1
- // @grant GM_getResourceText
- // @grant GM_listValues
- // @grant GM_deleteValue
- // @grant GM_getValue
- // @grant GM_setValue
- // @resource ankiDeck Japanese.txt
- // @resource ankiDeck1 JLPTN5.txt
- // @resource ankiDeck2 TheKodanshaKanjiLearnersCourse.txt
- // ==/UserScript==
-
- //not empty val
- var originAnkiDeck = GM_getResourceText("ankiDeck");
-
- //const
- const inBstring = "<awq>",
- inEstring = "</awq>",
- inBegAnswer = "<awq_answer>",
- inEndAnswer = "</awq_answer>";
-
- //arrays
- var stringArray = [],
- tempStrings = [],
- falseAnswers = [],
- inB = [],
- inE = [],
- buttons = [],
- tempArr = [];
-
- //empty val
- var searchFor,
- trueAnswer,
- trueId,
- id,
- rubyVal;
-
- //prefs
- var amountButtons,
- debug;
-
- Main();
-
- function Main()
- {
- inB = FindIndexes(inBstring, originAnkiDeck);
- inE = FindIndexes(inEstring, originAnkiDeck);
- console.log(inB);
- console.log(inE);
-
- for (var i = 0; i < inB.length; i++)
- {
- tempStrings[i] = originAnkiDeck.slice(inB[i] + 5, inE[i]);
- //console.log(tempStrings[i]);
- }
- console.log(tempStrings);
- CssAdd();
- SetSettings();
- }
-
- //Settings
- function SetSettings()
- {
- const settings = $("<li class=nav-item></li>").html("<a id=awq_settings class=nav-link>Settings Ankiweb Quiz " + GM_info.script.version + "</a> \
- <div id=awq_settingsPanel class=awq_settingsP>\
- <form> \
- <br> \
- Debug: <input type=checkbox name=debug id=awq_debug></input>\
- </form>\
- <button class=awq_style>Hide</button>\
- </div>\
- ");
-
- $(".navbar-nav:first").append(settings);
- $("#awq_settings").addClass("awq_settings");
- $("#awq_settingsPanel").hide();
- SetEventSettings();
- LoadSettings();
- }
-
- function LoadSettings()
- {
- //THIS IS ABOUT DEBUG
- if (HasValue("awq_debug", false))
- {
- debug = GM_getValue("awq_debug");
- $("#awq_debug").prop("checked", debug);
- }
-
- //THIS IS ABOUT BUTTONS
- if (HasValue("awq_amountButtons", 8))
- {
- amountButtons = GM_getValue("awq_amountButtons");
- }
-
- //Console log prefs with value
- console.log("*prefs:");
- console.log("*-----*");
- var vals = [];
- for (var i = 0; i < GM_listValues().length; i++)
- {
- vals[i] = GM_listValues()[i];
- }
- for (var i = 0; i < vals.length; i++)
- {
- console.log("*" + vals[i] + ":" + GM_getValue(vals[i]));
- }
- console.log("*-----*");
- }
-
- //Check if value exists or not. optValue = Optional
- function HasValue(nameVal, optValue)
- {
- var vals = [];
- for (var i = 0; i < GM_listValues().length; i++)
- {
- vals[i] = GM_listValues()[i];
- }
-
- if (vals.length === 0)
- {
- if (optValue != undefined)
- {
- GM_setValue(nameVal, optValue);
- return true;
- } else
- {
- return false;
- }
- }
-
- for (var i = 0; i < vals.length; i++)
- {
- if (vals[i] === nameVal)
- {
- return true;
- }
- }
-
- if (optValue != undefined)
- {
- GM_setValue(nameVal, optValue);
- return true;
- } else
- {
- return false;
- }
- }
-
- //Delete Values
- function DeleteValues(nameVal)
- {
- var vals = [];
- for (var i = 0; i < GM_listValues().length; i++)
- {
- vals[i] = GM_listValues()[i];
- }
-
- if (vals.length === 0 || typeof nameVal != "string")
- {
- return;
- }
-
- switch (nameVal)
- {
- case "all":
- for (var i = 0; i < vals.length; i++)
- {
- GM_deleteValue(vals[i]);
- }
- break;
- case "old":
- for (var i = 0; i < vals.length; i++)
- {
- if (vals[i] === "debug" || vals[i] === "debugA")
- {
- GM_deleteValue(vals[i]);
- }
- }
- break;
- default:
- for (var i = 0; i < vals.length; i++)
- {
- if (vals[i] === nameVal)
- {
- GM_deleteValue(nameVal);
- }
- }
- break;
- }
- }
-
- function SetEventSettings()
- {
- $("#awq_settings").click(function ()
- {
- $("#awq_settingsPanel").toggle(1000);
- });
-
- $("#awq_debug").change(function ()
- {
- GM_setValue("awq_debug", $(this).prop("checked"));
- debug = $(this).prop("checked");
- alert("Settings has been changed. Please reload the page.");
- });
- }
-
- function FindIndexes(searchStr, str, caseSensitive)
- {
- var searchStrLen = searchStr.length;
- if (searchStrLen == 0) {
- return [];
- }
- var startIndex = 0, index, indices = [];
- if (!caseSensitive) {
- str = str.toLowerCase();
- searchStr = searchStr.toLowerCase();
- }
- while ((index = str.indexOf(searchStr, startIndex)) > -1) {
- indices.push(index);
- startIndex = index + searchStrLen;
- }
- return indices;
- }
-
- //css styles adds
- function CssAdd()
- {
- $("head").append($("<!--Start of AnkiWeb Quiz v" + GM_info.script.version + " CSS-->"));
-
- $("head").append($("<style type=text/css></style>").text("button.awq_btn { \
- \
- }"));
-
- $("head").append($("<style type=text/css></style>").text("a.awq_settings { \
- cursor: pointer;\
- }"));
-
- $("head").append($("<style type=text/css></style>").text("div.awq_settingsP { \
- position:absolute; width:300px; background-color: #fff; border-color: #eee!important; border-radius: .3rem; border: 2px solid transparent; z-index: 150;\
- }"));
-
- $("head").append($("<style type=text/css></style>").text("button.awq_style { \
- cursor: pointer; color: #fff; background-color: #0275d8; border-color: #0275d8; padding: .75rem 1.5rem; font-size: 1rem; border-radius: .3rem; border: 1px solid transparent; max-width:200px; margin:5px;\
- }"));
-
- $("head").append($("<style type=text/css></style>").text("button.awq_style:hover { \
- cursor: pointer; color: #fff; background-color: #025aa5; border-color: #01549b; padding: .75rem 1.5rem; font-size: 1rem; border-radius: .3rem; border: 1px solid transparent;\
- }"));
-
- $("head").append($("<style type=text/css></style>").text("div.awq_rstyle { \
- width:100%; margin-top:30px; z-index: 100;\
- }"));
-
- $("head").append($("<style type=text/css></style>").text("button.awq_true { \
- background-color: #75d802; border-color: #75d802;\
- }"));
-
- $("head").append($("<style type=text/css></style>").text("button.awq_true:hover { \
- background-color: #5aa502; border-color: #5aa502;\
- }"));
-
- $("head").append($("<style type=text/css></style>").text("button.awq_false { \
- background-color: #d80275; border-color: #d80275;\
- }"));
-
- $("head").append($("<style type=text/css></style>").text("button.awq_false:hover { \
- background-color: #a5025a; border-color: #a5025a;\
- }"));
-
- $("head").append($("<!--End of AnkiWeb Quiz v" + GM_info.script.version + " CSS-->"));
- }
-
- $(document).ready(function () {
-
- // Append some text to the element with id someText using the jQuery library.
- //$("#studynow").append(" more text...................");
-
- $("#studynow").click(function () {
- setTimeout(function ()
- {
- SetUI();
- searchFor = SearchQuestion();
- if (debug)
- {
- console.log("searchFor:" + searchFor);
- }
- GetTrueAnswer(searchFor);
- if (debug) {
- console.log('Study Click');
- }
- }, 1500);
- });
-
- function SetUI()
- {
- const buttonP = $("<button id=awq_quiz class=btn style=margin-left:4px></button>").text("Quiz");
- const button = $("<div class=awq_rstyle></div>").html("<button class=awq_btn></button><button class=awq_btn></button><button class=awq_btn></button><button class=awq_btn></button><button class=awq_btn></button><button class=awq_btn></button><button class=awq_btn></button><button class=awq_btn></button>");
-
- $(".pt-1").before("<br>");
- $(".pt-1").before(button);
-
- $("#leftStudyMenu").after(buttonP);
-
- SettingsEvents();
-
- $("#awq_quiz").addClass("btn-secondary");
- $(".awq_btn").addClass("awq_style");
- $(".awq_rstyle").hide();
- }
-
- function SettingsEvents()
- {
-
- $("#awq_quiz").click(function () {
- $(".awq_rstyle").toggle();
- });
-
- $("#ansbuta").click(function ()
- {
- setTimeout(function ()
- {
- if (debug)
- {
- console.log("Button check");
- }
- $("#ease1").click(function ()
- {
- OtherEvent();
- });
- $("#ease2").click(function ()
- {
- OtherEvent();
- });
- $("#ease3").click(function ()
- {
- OtherEvent();
- });
- $("#ease4").click(function ()
- {
- OtherEvent();
- });
- }, 500);
- });
-
- $(".awq_btn").click(function ()
- {
- if (debug)
- {
- if ($(this).attr("title"))
- {
- console.log("html:" + $(this).attr("title"));
- console.log("true:" + trueAnswer);
- } else
- {
- console.log("html:" + $(this).html());
- console.log("text:" + $(this).text());
- console.log("------------------------");
- console.log("true:" + trueAnswer);
- console.log("************************");
- }
- }
-
- if ($(this).attr("title"))
- {
- if (trueAnswer == $(this).attr("title"))
- {
- $(this).addClass("awq_true");
- } else
- {
- $(this).addClass("awq_false");
- }
- } else
- {
- if (trueAnswer == $(this).html() || trueAnswer == $(this).text())
- {
- $(this).addClass("awq_true");
- } else
- {
- $(this).addClass("awq_false");
- }
- }
- });
- }
-
- function EscapeRegExp(string)
- {
- return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
- }
-
- function SearchQuestion()
- {
- if (debug)
- {
- console.log("span: ");
- console.log($("awq_question").has("span"));
- }
- if ($("awq_question").has("span").length >= 1)
- {
- var contentText = $("awq_question").contents().filter(function ()
- {
- return this.nodeType == 3;
- });
-
- var contentSpan = $("awq_question").contents().filter("span");
-
- if (debug)
- {
- console.log(contentText);
- console.log(contentSpan);
- }
-
- rubyVal = "";
- var x = 0;
- if (contentText >= contentSpan)
- {
- for (var i = 0; i < contentText.length; i++)
- {
- rubyVal += $.trim(contentText[i].nodeValue);
- if (x < contentSpan.length)
- {
- rubyVal += "<ruby><rb>";
- rubyVal += $.trim($(contentSpan[x]).contents().filter(function ()
- {
- return this.nodeType == 3;
- })[0].nodeValue) + "</rb><rt>";
- rubyVal += $(contentSpan[x]).contents()[0].innerHTML + "</rt></ruby>";
- x++;
- }
- }
- } else
- {
- for (var i = 0; i < contentSpan.length; i++)
- {
- if (x < contentText.length)
- {
- rubyVal += $.trim(contentText[x].nodeValue);
- x++;
- }
- rubyVal += "<ruby><rb>";
- rubyVal += $.trim($(contentSpan[i]).contents().filter(function ()
- {
- return this.nodeType == 3;
- })[0].nodeValue) + "</rb><rt>";
- rubyVal += $(contentSpan[i]).contents()[0].innerHTML + "</rt></ruby>";
- }
- }
- return rubyVal;
- } else
- {
- return $.trim($("awq_question").text());
- }
- }
-
- //Replace wrong <br>'s or other html tags, should work perfectly but it isn't >:( Fixed(probably)
- function ReplaceString(str)
- {
- var trueString = str;
-
- while (trueString.search("<br />") !== -1)
- {
- trueString = str.replace(/<br \/>/g, "<br>");
- }
-
- return trueString;
- }
-
- function GetTrueAnswer(sFor)
- {
- var regex = '(^|\\s|\\b|(n\\>))';
- var tempQuestion;
- var strQ;
- regex += EscapeRegExp(sFor);
- regex += '($|\\s|\\b|(\\<\\/a))';
-
- if (debug)
- {
- console.log(regex);
- }
-
- for (var i = 0; i < tempStrings.length; i++) {
- //console.log('sFor =' + sFor + " leng " + sFor.length + " debug : " + new RegExp(regex, "g").test(tempStrings[i]));
- //contains = tempStrings[i].matches(".*\\bram\\b.*");
- //tempQuestion = '';
- //strQ = '';
- //strQ = tempStrings[i].toString();
- //tempQuestion = $.trim(str.slice(str.indexOf("<awq_question>") + 14, str.indexOf("</awq_question>")));
- //console.log(tempQuestion);
- if (new RegExp(regex, "g").test(tempStrings[i]))
- {
- const str = tempStrings[i].toString();
- trueAnswer = ReplaceString($.trim(str.slice(str.indexOf(inBegAnswer) + 12, str.indexOf(inEndAnswer))));
- trueId = i;
- if (debug)
- {
- //console.log(tempStrings[i - 1]);
- console.log(str);
- //console.log(tempQuestion);
- //console.log(tempStrings[i + 1]);
- console.log("True answer : " + trueAnswer + " id trueAnsw = " + trueId);
- }
- GetFalseAnswers(trueId);
- break;
- }
- }
- }
-
- function GetFalseAnswers(trueId) {
- tempArr.length = 0;
- for (var i = 0; i < 7; i++) {
- id = GetRand(tempStrings);
- if (id != trueId) {
- if (debug) {
- console.log(tempStrings[id]);
- }
- const str = tempStrings[id].toString();
- falseAnswers[i] = str.slice(str.indexOf(inBegAnswer) + 12, str.indexOf(inEndAnswer));
- if (debug) {
- console.log("***False answer " + i + " : " + falseAnswers[i] + " id: " + id);
- //console.log("inBegAnswer: " + str.indexOf(inBegAnswer) + " : " + str.indexOf(inEndAnswer) + " inEndAnswer");
- }
- } else {
- id = GetRand(tempStrings);
- i--;
- }
- }
- RamdomButton();
- }
-
- function OtherEvent()
- {
- if (debug) {
- console.log("Button click");
- console.log("---------------");
- }
- searchFor = "";
- //searchFor = $("awq_question").html();
- searchFor = SearchQuestion();
- if (debug) {
- console.log("searchFor:" + searchFor);
- console.log($("awq").text().length);
- }
- $(".awq_rstyle").hide();
- if (searchFor == "") {
- setTimeout(function () {
- if ($("awq").text().length === 0) {
- setTimeout(function () {
- //searchFor = $("awq_question").html();
- searchFor = SearchQuestion();
- if (debug) {
- console.log("searchFor:::" + searchFor);
- }
- GetTrueAnswer(searchFor);
- }, 3000);
- } else {
- //searchFor = $("awq_question").html();
- searchFor = SearchQuestion();
- if (debug) {
- console.log("searchFor::" + searchFor);
- }
- GetTrueAnswer(searchFor);
- }
- }, 1000);
- } else {
- GetTrueAnswer(searchFor);
- }
- }
-
- //random functions
- function InArray(array, el) {
- for (var i = 0 ; i < array.length; i++)
- if (array[i] == el) return true;
- return false;
- }
-
- function GetRand(array) {
- var rand = Math.floor(Math.random() * array.length);
- if (!InArray(tempArr, rand)) {
- tempArr.push(rand);
- return rand;
- }
- return GetRand(array);
- }
- //end of random functions
-
- function RamdomButton()
- {
- buttons.length = 0;
- tempArr.length = 0;
- var allAnswers = [];
- allAnswers[0] = trueAnswer;
- for (var i = 1; i <= falseAnswers.length; i++) {
- allAnswers[i] = falseAnswers[i - 1];
- }
- if (debug) {
- console.log("False answers :");
- console.log(falseAnswers);
- console.log("ALL answers :");
- console.log(allAnswers);
- }
- for (var i = 0; i < allAnswers.length; i++) {
- buttons[i] = $.trim(allAnswers[GetRand(allAnswers)]);
- }
- if (debug) {
- console.log("Random order :) = " + buttons);
- // console.log($(".awq_LeftSide").html());
- }
- UiButtons();
- }
-
- function UiButtons()
- {
- const sel = document.querySelectorAll("button.awq_btn");
- if (debug)
- {
- console.log("*HERE UI BUTTONS :");
- }
-
- for (var i = 0; i < buttons.length; i++)
- {
- //Delete arttribute
- if ($(sel[i]).attr("title"))
- {
- $(sel[i]).removeAttr("title");
- }
-
- if (buttons[i].length <= 40 || buttons[i].includes("</ruby>"))
- {
- $(sel[i]).html(buttons[i]);
- } else
- {
- $(sel[i]).html(buttons[i].slice(0, 40) + "...");
- $(sel[i]).attr("title", buttons[i]);
- }
-
- if (debug)
- {
- //console.log(sel[i]);
- console.log(buttons[i] + " Length: " + buttons[i].length);
- console.log(buttons[i].includes("</ruby>"));
- }
- }
-
- CheckPresedButtons();
- }
-
- function CheckPresedButtons()
- {
- $(".awq_btn").removeClass("awq_true");
- $(".awq_btn").removeClass("awq_false");
- }
-
- console.log("AnkiWeb Quiz v" + GM_info.script.version + " Initialized");
- });
-
-
- // ------------
- // TODO
- // ------------
-
- /* TODO STARTS
- ✓ 1)Make it only one element of buttons //DONE 0.0.9
- 1.1)Increase numbers of buttons to 10-12(optional through settings???)
- ✓ 2)Make it limit of length answer and put whole in attribute title //DONE 0.1.0
- ✓ 3)Make it settings, almost done in 0.1.0 //DONE 0.2.0
- ✓ 3.1)Debug //DONE 0.1.0
- 3.2)Add txt file ***RESEARCH NEEDED***
- 3.2.1)Choose them
- 3.3)Make it always show quiz
- ✓ 4)Make it full functionality of Japanese deck, partial done in 0.0.8 //DONE 0.0.9 Happy with that :)
- 5)Search question in between tags <awq_question> and </awq_question> not in whole sentence, almost done in 0.1.2
- ✓ 6)TODO for loop in finding question NEED TEST IT //DONE 0.1.7 BROKEN //DONE 0.1.9
- TODO ENDS */