AnkiWeb Quiz

Shows quiz on ankiweb

当前为 2017-09-30 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name AnkiWeb Quiz
  3. // @namespace https://greasyfork.org/users/102866
  4. // @description Shows quiz on ankiweb
  5. // @include https://ankiweb.net/*
  6. // @include http://ankiweb.net/*
  7. // @require https://code.jquery.com/jquery-3.1.1.min.js
  8. // @author TiLied
  9. // @version 1.1.2
  10. // @grant GM_listValues
  11. // @grant GM_deleteValue
  12. // @grant GM_getValue
  13. // @grant GM_setValue
  14. // ==/UserScript==
  15.  
  16. //not empty val
  17. var std = window.eval("require('study').default;"),
  18. defaultDeck = new Deck("question default", "answer default", 10001, 20002),
  19. defaultDecks =
  20. {
  21. defaultId : new Decks(defaultDeck)
  22. }
  23.  
  24. //const
  25. const inBstring = "<awq>",
  26. inEstring = "</awq>",
  27. inBegAnswer = "<awq_answer>",
  28. inEndAnswer = "</awq_answer>",
  29. textDefault = "You need to use this deck more to get more variations";
  30.  
  31. //arrays
  32. var stringArray = [],
  33. tempStrings = [],
  34. falseAnswers = [],
  35. inB = [],
  36. inE = [],
  37. buttons = [],
  38. tempArr = [];
  39.  
  40. //empty val
  41. var searchFor,
  42. trueAnswer,
  43. trueId,
  44. id,
  45. rubyVal,
  46. deck;
  47.  
  48. //prefs
  49. var amountButtons,
  50. debug,
  51. decks,
  52. lastIdChosen;
  53.  
  54. void function Main()
  55. {
  56. //Place CSS in head
  57. CssAdd();
  58. //Set settings or create
  59. SetSettings();
  60. //Set event on decks page
  61. SetEventsOnDecks(document.URL);
  62. }();
  63.  
  64. //Settings
  65. function SetSettings()
  66. {
  67. const settings = $("<li class=nav-item></li>").html("<a id=awq_settings class=nav-link>Settings Ankiweb Quiz " + GM_info.script.version + "</a> \
  68. <div id=awq_settingsPanel class=awq_settingsP>\
  69. <form> \
  70. <br> \
  71. Amount Buttons(4-20):<input type=number name=amountBtn id=awq_amountBtn min=4 max=20 value=4></input><br> \
  72. Debug: <input type=checkbox name=debug id=awq_debug></input>\
  73. </form>\
  74. <button id=hideButton class=awq_style>Hide</button>\
  75. </div>\
  76. ");
  77.  
  78. $(".navbar-nav:first").append(settings);
  79. $("#awq_settings").addClass("awq_settings");
  80. $("#awq_settingsPanel").hide();
  81. SetEventSettings();
  82. LoadSettings();
  83. }
  84.  
  85. function LoadSettings()
  86. {
  87.  
  88. DeleteValues("old");
  89.  
  90. //THIS IS ABOUT DEBUG
  91. if (HasValue("awq_debug", false))
  92. {
  93. debug = GM_getValue("awq_debug");
  94. $("#awq_debug").prop("checked", debug);
  95. }
  96.  
  97. //THIS IS ABOUT DECKS
  98. if (HasValue("awq_decks", JSON.stringify(defaultDecks)))
  99. {
  100. decks = JSON.parse(GM_getValue("awq_decks"));
  101. //console.log(decks);
  102. }
  103.  
  104. //THIS IS ABOUT lastIdChosen
  105. if (HasValue("awq_lastIdChosen", 000))
  106. {
  107. lastIdChosen = GM_getValue("awq_lastIdChosen");
  108. GetDeck(lastIdChosen);
  109. }
  110.  
  111. //THIS IS ABOUT BUTTONS
  112. if (HasValue("awq_amountButtons", 8))
  113. {
  114. amountButtons = GM_getValue("awq_amountButtons");
  115. $("#awq_amountBtn").prop("value", amountButtons);
  116. }
  117.  
  118. //Console log prefs with value
  119. console.log("*prefs:");
  120. console.log("*-----*");
  121. var vals = [];
  122. for (var i = 0; i < GM_listValues().length; i++)
  123. {
  124. vals[i] = GM_listValues()[i];
  125. }
  126. for (var i = 0; i < vals.length; i++)
  127. {
  128. console.log("*" + vals[i] + ":" + GM_getValue(vals[i]));
  129. }
  130. console.log("*-----*");
  131. }
  132.  
  133. //Check if value exists or not. optValue = Optional
  134. function HasValue(nameVal, optValue)
  135. {
  136. var vals = [];
  137. for (var i = 0; i < GM_listValues().length; i++)
  138. {
  139. vals[i] = GM_listValues()[i];
  140. }
  141.  
  142. if (vals.length === 0)
  143. {
  144. if (optValue != undefined)
  145. {
  146. GM_setValue(nameVal, optValue);
  147. return true;
  148. } else
  149. {
  150. return false;
  151. }
  152. }
  153.  
  154. for (var i = 0; i < vals.length; i++)
  155. {
  156. if (vals[i] === nameVal)
  157. {
  158. return true;
  159. }
  160. }
  161.  
  162. if (optValue != undefined)
  163. {
  164. GM_setValue(nameVal, optValue);
  165. return true;
  166. } else
  167. {
  168. return false;
  169. }
  170. }
  171.  
  172. //Delete Values
  173. function DeleteValues(nameVal)
  174. {
  175. var vals = [];
  176. for (var i = 0; i < GM_listValues().length; i++)
  177. {
  178. vals[i] = GM_listValues()[i];
  179. }
  180.  
  181. if (vals.length === 0 || typeof nameVal != "string")
  182. {
  183. return;
  184. }
  185.  
  186. switch (nameVal)
  187. {
  188. case "all":
  189. for (var i = 0; i < vals.length; i++)
  190. {
  191. GM_deleteValue(vals[i]);
  192. }
  193. break;
  194. case "old":
  195. for (var i = 0; i < vals.length; i++)
  196. {
  197. if (vals[i] === "debug" || vals[i] === "debugA" || vals[i] === "awq_amountBtn")
  198. {
  199. GM_deleteValue(vals[i]);
  200. }
  201. }
  202. break;
  203. default:
  204. for (var i = 0; i < vals.length; i++)
  205. {
  206. if (vals[i] === nameVal)
  207. {
  208. GM_deleteValue(nameVal);
  209. }
  210. }
  211. break;
  212. }
  213. }
  214.  
  215. //Construction of Deck
  216. function Deck(question, answer, idTimeOne, idTimeTwo)
  217. {
  218. this.question = [question];
  219. this.answer = [answer];
  220. this.idTimeOne = [idTimeOne];
  221. this.idTimeTwo = [idTimeTwo];
  222. }
  223.  
  224. //Construction of Decks
  225. function Decks(cards)
  226. {
  227. this.cards = cards;
  228. this.updateDeck = false;
  229. this.firstTime = true;
  230. this.customSettings = {};
  231. };
  232.  
  233. function SetEventSettings()
  234. {
  235. $("#awq_settings").click(function ()
  236. {
  237. $("#awq_settingsPanel").toggle(1000);
  238. });
  239.  
  240. $("#hideButton").click(function ()
  241. {
  242. $("#awq_settingsPanel").toggle(1000);
  243. });
  244.  
  245. $("#awq_debug").change(function ()
  246. {
  247. GM_setValue("awq_debug", $(this).prop("checked"));
  248. debug = $(this).prop("checked");
  249. alert("Settings has been changed. Please reload the page.");
  250. });
  251.  
  252. $("#awq_amountBtn").change(function ()
  253. {
  254. GM_setValue("awq_amountButtons", $(this).prop("value"));
  255. amountButtons = $(this).prop("value");
  256. alert("Settings has been changed. Please reload the page.");
  257. });
  258. }
  259.  
  260. function SetEventsOnDecks(url)
  261. {
  262. if (url.match(/http:\/\/ankiweb\.net\/decks/i) || url.match(/https:\/\/ankiweb\.net\/decks/i))
  263. {
  264. $("div.light-bottom-border > div:first-child > button").on("mousedown", function ()
  265. {
  266. lastIdChosen = this.id;
  267. GM_setValue("awq_lastIdChosen", lastIdChosen);
  268. });
  269. } else
  270. {
  271. return;
  272. }
  273. }
  274.  
  275. function SetEventsOnStudy(url)
  276. {
  277. if (url.match(/http:\/\/ankiweb\.net\/study/i) || url.match(/https:\/\/ankiweb\.net\/study/i))
  278. {
  279. $("#leftStudyMenu a:first-child").on("mouseover", function ()
  280. {
  281. try
  282. {
  283. UpdateGMDecks();
  284. console.log("UpdateGM");
  285. } catch (e) { console.log(e);}
  286. });
  287. } else
  288. {
  289. return;
  290. }
  291. }
  292.  
  293. function FindIndexes(searchStr, str, caseSensitive)
  294. {
  295. var searchStrLen = searchStr.length;
  296. if (searchStrLen == 0) {
  297. return [];
  298. }
  299. var startIndex = 0, index, indices = [];
  300. if (!caseSensitive) {
  301. str = str.toLowerCase();
  302. searchStr = searchStr.toLowerCase();
  303. }
  304. while ((index = str.indexOf(searchStr, startIndex)) > -1) {
  305. indices.push(index);
  306. startIndex = index + searchStrLen;
  307. }
  308. return indices;
  309. }
  310.  
  311. //css styles adds
  312. function CssAdd()
  313. {
  314. $("head").append($("<!--Start of AnkiWeb Quiz v" + GM_info.script.version + " CSS-->"));
  315.  
  316. $("head").append($("<style type=text/css></style>").text("button.awq_btn { \
  317. \
  318. }"));
  319.  
  320. $("head").append($("<style type=text/css></style>").text("a.awq_settings { \
  321. cursor: pointer;\
  322. }"));
  323.  
  324. $("head").append($("<style type=text/css></style>").text("div.awq_settingsP { \
  325. position:absolute; width:300px; background-color: #fff; border-color: #eee!important; border-radius: .3rem; border: 2px solid transparent; z-index: 150;\
  326. }"));
  327.  
  328. $("head").append($("<style type=text/css></style>").text("button.awq_style { \
  329. 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;\
  330. }"));
  331.  
  332. $("head").append($("<style type=text/css></style>").text("button.awq_style:hover { \
  333. cursor: pointer; color: #fff; background-color: #025aa5; border-color: #01549b; padding: .75rem 1.5rem; font-size: 1rem; border-radius: .3rem; border: 1px solid transparent;\
  334. }"));
  335.  
  336. $("head").append($("<style type=text/css></style>").text("div.awq_rstyle { \
  337. width:100%; margin-top:30px; z-index: 100;\
  338. }"));
  339.  
  340. $("head").append($("<style type=text/css></style>").text("button.awq_true { \
  341. background-color: #75d802; border-color: #75d802;\
  342. }"));
  343.  
  344. $("head").append($("<style type=text/css></style>").text("button.awq_true:hover { \
  345. background-color: #5aa502; border-color: #5aa502;\
  346. }"));
  347.  
  348. $("head").append($("<style type=text/css></style>").text("button.awq_false { \
  349. background-color: #d80275; border-color: #d80275;\
  350. }"));
  351.  
  352. $("head").append($("<style type=text/css></style>").text("button.awq_first { \
  353. background-color: #000; border-color: #000;\
  354. }"));
  355.  
  356. $("head").append($("<style type=text/css></style>").text("button.awq_false:hover { \
  357. background-color: #a5025a; border-color: #a5025a;\
  358. }"));
  359.  
  360. $("head").append($("<!--End of AnkiWeb Quiz v" + GM_info.script.version + " CSS-->"));
  361. }
  362.  
  363. function GetDeck(idDeck)
  364. {
  365. var keyNames = Object.keys(decks);
  366. for (var i in keyNames)
  367. {
  368. if (idDeck == keyNames[i])
  369. {
  370. deck = decks[idDeck].cards;
  371. return;
  372. }
  373. }
  374.  
  375. if(deck == undefined)
  376. {
  377. decks[idDeck] = new Decks(defaultDeck);
  378. deck = decks[idDeck].cards;
  379. return;
  380. }
  381. }
  382.  
  383. //THIS FUNC FOR UPDATING Greasemonkey value JSON OBJECT
  384. function UpdateGMDecks()
  385. {
  386. try
  387. {
  388. if (deck["answer"].length < amountButtons)
  389. {
  390. decks[lastIdChosen].firstTime = true;
  391. }
  392.  
  393. var gmDecks = JSON.stringify(decks);
  394. GM_setValue("awq_decks", gmDecks);
  395. }
  396. catch (e)
  397. {
  398. console.log(e);
  399. }
  400. }
  401.  
  402. $(document).ready(function () {
  403.  
  404. // Append some text to the element with id someText using the jQuery library.
  405. //$("#studynow").append(" more text...................");
  406.  
  407. $("#studynow").click(function () {
  408. setTimeout(function ()
  409. {
  410. SetUI();
  411. SetEventsOnStudy(document.URL);
  412. if (decks[lastIdChosen].firstTime == true)
  413. {
  414. FirstTimeDeck(std.currentCard, std["deck"].cards);
  415. } else
  416. {
  417. var question = $.trim(StripNewLines(StripTags(std.currentCard[1].replace(/<style>[\s\S]*?<\/style>/ig, '')))),
  418. answer = $.trim(StripNewLines(StripTags(std.currentCard[2].replace(/[\s\S]*?(<hr id=answer>)/ig, '').replace(/<style>[\s\S]*?<\/style>/ig, '')))),
  419. idTimeOne = std.currentCard[0],
  420. idTimeTwo = std.currentCard[4];
  421. UpdateDeck(question, answer, idTimeOne, idTimeTwo);
  422. }
  423. //searchFor = SearchQuestion();
  424. if (debug)
  425. {
  426. console.log(std);
  427. console.log("---");
  428. //console.log($.trim(StripNewLines(StripTags(asd[1].replace(/<style>[\s\S]*?<\/style>/ig, '')))));
  429. //console.log($.trim(StripNewLines(StripTags(asd[2].replace(/[\s\S]*?(<hr id=answer>)/ig, '').replace(/<style>[\s\S]*?<\/style>/ig, '')))));
  430. console.log("---");
  431. //console.log("FirstTime:" + decks[lastIdChosen].firstTime);
  432. console.log(decks);
  433. console.log($.trim($("#rightStudyMenu").text()).split("+"));
  434. //console.log("searchFor:" + searchFor);
  435. }
  436. //GetTrueAnswer(searchFor);
  437. GetTrueAnswerU(std.currentCard[0], std.currentCard[4]);
  438. if (debug) {
  439. console.log('Study Click');
  440. }
  441. }, 1500);
  442. });
  443.  
  444. function NumberOfButtons()
  445. {
  446. var buttons = "";
  447. for (var i = 0; i < amountButtons; i++)
  448. {
  449. buttons += "<button class=awq_btn></button>";
  450. }
  451. return buttons;
  452. }
  453.  
  454. //THIS FUNC FOR FIRST TIME USING DECK AFteR INSTALL SCRIPT
  455. function FirstTimeDeck(currentCard, nextCards)
  456. {
  457. var questions = [$.trim(StripNewLines(StripTags(currentCard[1].replace(/<style>[\s\S]*?<\/style>/ig, ''))))],
  458. answers = [$.trim(StripNewLines(StripTags(currentCard[2].replace(/[\s\S]*?(<hr id=answer>)/ig, '').replace(/<style>[\s\S]*?<\/style>/ig, ''))))],
  459. idTimeOnes = [currentCard[0]],
  460. idTimeTwos = [currentCard[4]];
  461.  
  462. for (var i = 0; i < nextCards.length; i++)
  463. {
  464. questions.push($.trim(StripNewLines(StripTags(nextCards[i][1].replace(/<style>[\s\S]*?<\/style>/ig, '')))));
  465. answers.push($.trim(StripNewLines(StripTags(nextCards[i][2].replace(/[\s\S]*?(<hr id=answer>)/ig, '').replace(/<style>[\s\S]*?<\/style>/ig, '')))));
  466. idTimeOnes.push(nextCards[i][0]);
  467. idTimeTwos.push(nextCards[i][4]);
  468. }
  469.  
  470. for (var i = 0; i < questions.length; i++)
  471. {
  472. UpdateDeck(questions[i], answers[i], idTimeOnes[i], idTimeTwos[i]);
  473. }
  474.  
  475. decks[lastIdChosen].firstTime = false;
  476. }
  477.  
  478. //THIS FUNC FOR UPDATING DECK OBJECT
  479. function UpdateDeck(question, answer, idTimeOne, idTimeTwo)
  480. {
  481. //TODO FORCE UPDATE
  482. if (question.length >= 350)
  483. {
  484. question = "CARD TOO LONG: " + question.slice(0, 350);
  485. }
  486.  
  487. if (answer.length >= 350)
  488. {
  489. answer = "CARD TOO LONG: " + answer.slice(0, 350);
  490. }
  491.  
  492. //CHECK FOR REPEAT
  493. for (var i = 0; i < deck["idTimeOne"].length; i++)
  494. {
  495. if (idTimeOne === deck["idTimeOne"][i] && idTimeTwo === deck["idTimeTwo"][i])
  496. {
  497. return;
  498. }
  499. }
  500.  
  501. //First time deck detected(delete default card)
  502. if (deck["idTimeOne"][0] === 10001 && deck["idTimeTwo"][0] === 20002)
  503. {
  504. deck["question"][0] = question;
  505. deck["answer"][0] = answer;
  506. deck["idTimeOne"][0] = idTimeOne;
  507. deck["idTimeTwo"][0] = idTimeTwo;
  508. } else
  509. {
  510. deck["question"].push(question);
  511. deck["answer"].push(answer);
  512. deck["idTimeOne"].push(idTimeOne);
  513. deck["idTimeTwo"].push(idTimeTwo);
  514. }
  515. }
  516.  
  517. function SetUI()
  518. {
  519. const buttonP = $("<button id=awq_quiz class=btn style=margin-left:4px></button>").text("Quiz");
  520. const button = $("<div class=awq_rstyle></div>").html(NumberOfButtons());
  521.  
  522. $(".pt-1").before("<br>");
  523. $(".pt-1").before(button);
  524.  
  525. $("#leftStudyMenu").after(buttonP);
  526.  
  527. SettingsEvents();
  528.  
  529. $("#awq_quiz").addClass("btn-secondary");
  530. $(".awq_btn").addClass("awq_style");
  531. $(".awq_rstyle").hide();
  532. }
  533.  
  534. function SettingsEvents()
  535. {
  536.  
  537. $("#awq_quiz").click(function () {
  538. $(".awq_rstyle").toggle();
  539. });
  540.  
  541. $("#ansbuta").click(function ()
  542. {
  543. CheckStatus($.trim($("#rightStudyMenu").text()).split("+"));
  544. setTimeout(function ()
  545. {
  546. if (debug)
  547. {
  548. console.log("Button check");
  549. }
  550. $("#ease1").click(function ()
  551. {
  552. OtherEventU();
  553. //OtherEvent();
  554. });
  555. $("#ease2").click(function ()
  556. {
  557. OtherEventU();
  558. //OtherEvent();
  559. });
  560. $("#ease3").click(function ()
  561. {
  562. OtherEventU();
  563. //OtherEvent();
  564. });
  565. $("#ease4").click(function ()
  566. {
  567. OtherEventU();
  568. //OtherEvent();
  569. });
  570. }, 250);
  571. });
  572.  
  573. $(".awq_btn").click(function ()
  574. {
  575. if (debug)
  576. {
  577. if ($(this).attr("title"))
  578. {
  579. console.log("html:" + $(this).attr("title"));
  580. console.log("true:" + trueAnswer);
  581. } else
  582. {
  583. console.log("html:" + $(this).html());
  584. console.log("text:" + $(this).text());
  585. console.log("------------------------");
  586. console.log("true:" + trueAnswer);
  587. console.log("************************");
  588. }
  589. }
  590.  
  591. if ($(this).attr("title"))
  592. {
  593. if (trueAnswer == $(this).attr("title"))
  594. {
  595. $(this).addClass("awq_true");
  596. } else
  597. {
  598. $(this).addClass("awq_false");
  599. }
  600. } else
  601. {
  602. if (trueAnswer == $(this).html() || trueAnswer == $(this).text())
  603. {
  604. $(this).addClass("awq_true");
  605. } else
  606. {
  607. $(this).addClass("awq_false");
  608. }
  609. }
  610. });
  611. }
  612.  
  613. function CheckStatus(statusArr)
  614. {
  615. var one = parseInt(statusArr[0]),
  616. two = parseInt(statusArr[1]),
  617. tree = parseInt(statusArr[2]);
  618. if (debug)
  619. {
  620. console.log(one);
  621. console.log(two);
  622. console.log(tree);
  623. }
  624. if ((one + two + tree) === 0)
  625. {
  626. UpdateGMDecks();
  627. } else
  628. {
  629. return;
  630. }
  631. }
  632.  
  633. function EscapeRegExp(string)
  634. {
  635. return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
  636. }
  637.  
  638. function SearchQuestion()
  639. {
  640. if (debug)
  641. {
  642. console.log("span: ");
  643. console.log($("awq_question").has("span"));
  644. }
  645. if ($("awq_question").has("span").length >= 1)
  646. {
  647. var contentText = $("awq_question").contents().filter(function ()
  648. {
  649. return this.nodeType == 3;
  650. });
  651.  
  652. var contentSpan = $("awq_question").contents().filter("span");
  653.  
  654. if (debug)
  655. {
  656. console.log(contentText);
  657. console.log(contentSpan);
  658. }
  659.  
  660. rubyVal = "";
  661. var x = 0;
  662. if (contentText >= contentSpan)
  663. {
  664. for (var i = 0; i < contentText.length; i++)
  665. {
  666. rubyVal += $.trim(contentText[i].nodeValue);
  667. if (x < contentSpan.length)
  668. {
  669. rubyVal += "<ruby><rb>";
  670. rubyVal += $.trim($(contentSpan[x]).contents().filter(function ()
  671. {
  672. return this.nodeType == 3;
  673. })[0].nodeValue) + "</rb><rt>";
  674. rubyVal += $(contentSpan[x]).contents()[0].innerHTML + "</rt></ruby>";
  675. x++;
  676. }
  677. }
  678. } else
  679. {
  680. for (var i = 0; i < contentSpan.length; i++)
  681. {
  682. if (x < contentText.length)
  683. {
  684. rubyVal += $.trim(contentText[x].nodeValue);
  685. x++;
  686. }
  687. rubyVal += "<ruby><rb>";
  688. rubyVal += $.trim($(contentSpan[i]).contents().filter(function ()
  689. {
  690. return this.nodeType == 3;
  691. })[0].nodeValue) + "</rb><rt>";
  692. rubyVal += $(contentSpan[i]).contents()[0].innerHTML + "</rt></ruby>";
  693. }
  694. }
  695. return rubyVal;
  696. } else
  697. {
  698. return $.trim($("awq_question").text());
  699. }
  700. }
  701.  
  702. //Replace wrong <br>'s or other html tags, should work perfectly but it isn't >:( Fixed(probably)
  703. function ReplaceString(str)
  704. {
  705. var trueString = str;
  706.  
  707. while (trueString.search("<br />") !== -1)
  708. {
  709. trueString = str.replace(/<br \/>/g, "<br>");
  710. }
  711.  
  712. return trueString;
  713. }
  714.  
  715. function GetTrueAnswerU(idOne, idTwo)
  716. {
  717. for (var i = 0; i < deck["idTimeOne"].length; i++)
  718. {
  719. if (idOne === deck["idTimeOne"][i] && idTwo === deck["idTimeTwo"][i])
  720. {
  721. trueAnswer = deck["answer"][i];
  722. trueId = i;
  723. GetFalseAnswersU(trueId);
  724. return;
  725. }
  726. }
  727. }
  728.  
  729. function GetFalseAnswersU(trueId)
  730. {
  731. tempArr.length = 0;
  732. if (deck["answer"].length <= amountButtons)
  733. {
  734. var temp = [];
  735. temp = temp.concat(deck["answer"]);
  736. if (debug)
  737. {
  738. console.log(temp);
  739. }
  740. for (var i = 0; i < (amountButtons - (deck["answer"].length - 1)); i++)
  741. {
  742. temp.push(textDefault);
  743. }
  744. if (debug)
  745. {
  746. console.log(temp);
  747. }
  748. }
  749. for (var i = 0; i < (amountButtons - 1); i++)
  750. {
  751. if (deck["answer"].length > amountButtons)
  752. {
  753. id = GetRand(deck["answer"]);
  754. if (id != trueId)
  755. {
  756. if (debug)
  757. {
  758. console.log(deck["answer"][id]);
  759. }
  760. falseAnswers[i] = deck["answer"][id];
  761. if (debug)
  762. {
  763. console.log("***False answer " + i + " : " + falseAnswers[i] + " id: " + id);
  764. //console.log("inBegAnswer: " + str.indexOf(inBegAnswer) + " : " + str.indexOf(inEndAnswer) + " inEndAnswer");
  765. }
  766. } else if(id === 0 || id === trueId)
  767. {
  768. id = GetRand(deck["answer"]);
  769. i--;
  770. }
  771. } else
  772. {
  773. id = GetRand(temp);
  774. if (id != trueId)
  775. {
  776. if (debug)
  777. {
  778. console.log(temp[id]);
  779. }
  780. falseAnswers[i] = temp[id];
  781. if (debug)
  782. {
  783. console.log("***False answer " + i + " : " + falseAnswers[i] + " id: " + id);
  784. //console.log("inBegAnswer: " + str.indexOf(inBegAnswer) + " : " + str.indexOf(inEndAnswer) + " inEndAnswer");
  785. }
  786. } else
  787. {
  788. id = GetRand(temp);
  789. i--;
  790. }
  791. }
  792. }
  793. RamdomButton();
  794. }
  795.  
  796. function OtherEventU()
  797. {
  798. if (debug)
  799. {
  800. console.log("Button click");
  801. console.log("---------------");
  802. //console.log(std.currentCard);
  803. //console.log($("awq").text().length);
  804. }
  805.  
  806. //event on Edit button
  807. SetEventsOnStudy(document.URL);
  808.  
  809. $(".awq_rstyle").hide();
  810. $(".awq_btn").removeClass("awq_first");
  811. if (std.currentCard == undefined)
  812. {
  813. setTimeout(function ()
  814. {
  815. if (std.currentCard == undefined)
  816. {
  817. setTimeout(function ()
  818. {
  819. var question = $.trim(StripNewLines(StripTags(std.currentCard[1].replace(/<style>[\s\S]*?<\/style>/ig, '')))),
  820. answer = $.trim(StripNewLines(StripTags(std.currentCard[2].replace(/[\s\S]*?(<hr id=answer>)/ig, '').replace(/<style>[\s\S]*?<\/style>/ig, '')))),
  821. idTimeOne = std.currentCard[0],
  822. idTimeTwo = std.currentCard[4];
  823. UpdateDeck(question, answer, idTimeOne, idTimeTwo);
  824. GetTrueAnswerU(idTimeOne, idTimeTwo);
  825. }, 3000);
  826. } else
  827. {
  828. var question = $.trim(StripNewLines(StripTags(std.currentCard[1].replace(/<style>[\s\S]*?<\/style>/ig, '')))),
  829. answer = $.trim(StripNewLines(StripTags(std.currentCard[2].replace(/[\s\S]*?(<hr id=answer>)/ig, '').replace(/<style>[\s\S]*?<\/style>/ig, '')))),
  830. idTimeOne = std.currentCard[0],
  831. idTimeTwo = std.currentCard[4];
  832. UpdateDeck(question, answer, idTimeOne, idTimeTwo);
  833. GetTrueAnswerU(idTimeOne, idTimeTwo);
  834. }
  835. }, 1000);
  836. } else
  837. {
  838. var question = $.trim(StripNewLines(StripTags(std.currentCard[1].replace(/<style>[\s\S]*?<\/style>/ig, '')))),
  839. answer = $.trim(StripNewLines(StripTags(std.currentCard[2].replace(/[\s\S]*?(<hr id=answer>)/ig, '').replace(/<style>[\s\S]*?<\/style>/ig, '')))),
  840. idTimeOne = std.currentCard[0],
  841. idTimeTwo = std.currentCard[4];
  842. UpdateDeck(question, answer, idTimeOne, idTimeTwo);
  843. GetTrueAnswerU(idTimeOne, idTimeTwo);
  844. }
  845. }
  846.  
  847. //
  848. //random functions
  849. function InArray(array, el) {
  850. for (var i = 0; i < array.length; i++)
  851. if (array[i] == el) return true;
  852. return false;
  853. }
  854.  
  855. function GetRand(array) {
  856. var rand = Math.floor(Math.random() * array.length);
  857. if (!InArray(tempArr, rand)) {
  858. tempArr.push(rand);
  859. return rand;
  860. }
  861. return GetRand(array);
  862. }
  863. //end of random functions
  864. //
  865.  
  866. function RamdomButton()
  867. {
  868. var allAnswers = [];
  869. buttons.length = 0;
  870. tempArr.length = 0;
  871. allAnswers[0] = trueAnswer;
  872. for (var i = 1; i <= falseAnswers.length; i++) {
  873. allAnswers[i] = falseAnswers[i - 1];
  874. }
  875. if (debug) {
  876. console.log("False answers :");
  877. console.log(falseAnswers);
  878. console.log("ALL answers :");
  879. console.log(allAnswers);
  880. }
  881. for (var i = 0; i < allAnswers.length; i++) {
  882. buttons[i] = $.trim(allAnswers[GetRand(allAnswers)]);
  883. }
  884. if (debug) {
  885. console.log("Random order :) = " + buttons);
  886. // console.log($(".awq_LeftSide").html());
  887. }
  888. UiButtons();
  889. }
  890.  
  891. function UiButtons()
  892. {
  893. const sel = document.querySelectorAll("button.awq_btn");
  894. if (debug)
  895. {
  896. console.log("*HERE UI BUTTONS :");
  897. }
  898.  
  899. for (var i = 0; i < buttons.length; i++)
  900. {
  901. //Delete arttribute
  902. if ($(sel[i]).attr("title"))
  903. {
  904. $(sel[i]).removeAttr("title");
  905. }
  906.  
  907. if (buttons[i].length <= 40 || buttons[i].includes("</ruby>"))
  908. {
  909. $(sel[i]).html(buttons[i]);
  910. } else
  911. {
  912. $(sel[i]).html(buttons[i].slice(0, 40) + "...");
  913. $(sel[i]).attr("title", buttons[i]);
  914.  
  915. //change color of button with textDefault
  916. if ($(sel[i]).attr("title") == textDefault)
  917. {
  918. $(sel[i]).addClass("awq_first");
  919. }
  920. }
  921.  
  922. if (debug)
  923. {
  924. //console.log($(sel[i]).attr("title"));
  925. console.log(buttons[i] + " Length: " + buttons[i].length);
  926. console.log(buttons[i].includes("</ruby>"));
  927. }
  928. }
  929.  
  930.  
  931. CheckPresedButtons();
  932. }
  933.  
  934. function CheckPresedButtons()
  935. {
  936. $(".awq_btn").removeClass("awq_true");
  937. $(".awq_btn").removeClass("awq_false");
  938. //$(".awq_btn").removeClass("awq_first");
  939. }
  940.  
  941. console.log("AnkiWeb Quiz v" + GM_info.script.version + " Initialized");
  942. });
  943.  
  944. function StripTags(string)
  945. {
  946. return string.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?(\/)?>|<\/\w+>/gi, '');
  947. }
  948.  
  949. function StripNewLines(string)
  950. {
  951. return string.replace(/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/gi, '\n');
  952. }
  953.  
  954. // ------------
  955. // TODO
  956. // ------------
  957.  
  958. /* TODO STARTS
  959. ✓ 0)REWRITE EVERYTHING WITHOUT USING GETRESOURCE AND CHANGING CODE //DONE 1.0.0
  960. 0.1)Make custom settings
  961. 0.2)Make force update deck (Because once you updated card, in gm_value will be old version of card)
  962. ✓ 1)Make it only one element of buttons //DONE 0.0.9
  963. ✓ 1.1)Increase numbers of buttons to 10-12(optional through settings???) //DONE 1.1.0
  964. ✓ 2)Make it limit of length answer and put whole in attribute title //DONE 0.1.0
  965. ✓ 3)Make it settings, almost done in 0.1.0 //DONE 0.2.0
  966. ✓ 3.1)Debug //DONE 0.1.0
  967. 3.2)Add txt file ***RESEARCH NEEDED***
  968. 3.2.1)Choose them
  969. 3.3)Make it always show quiz
  970. ✓ 4)Make it full functionality of Japanese deck, partial done in 0.0.8 //DONE 0.0.9 Happy with that :)
  971. 5)Search question in between tags <awq_question> and </awq_question> not in whole sentence, almost done in 0.1.2
  972. ✓ 6)TODO for loop in finding question NEED TEST IT //DONE 0.1.7 BROKEN //DONE 0.1.9
  973. TODO ENDS */