AnkiWeb Quiz

Shows quiz on ankiweb

目前为 2017-11-16 提交的版本,查看 最新版本

  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.2.1.min.js
  8. // @author TiLied
  9. // @version 1.2.3
  10. // @grant GM_listValues
  11. // @grant GM_deleteValue
  12. // @grant GM_getValue
  13. // @grant GM_setValue
  14. // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
  15. // @grant GM.listValues
  16. // @grant GM.getValue
  17. // @grant GM.setValue
  18. // @grant GM.deleteValue
  19. // ==/UserScript==
  20.  
  21. //not empty val
  22. var std = window.eval("require('study').default;"),
  23. defaultDeck = new Deck("question default", "answer default", 10001, 20002),
  24. defaultDecks =
  25. {
  26. defaultId: new Decks(defaultDeck)
  27. }
  28.  
  29. //const
  30. const inBstring = "<awq>",
  31. inEstring = "</awq>",
  32. inBegAnswer = "<awq_answer>",
  33. inEndAnswer = "</awq_answer>",
  34. textDefault = "You need to use this deck more to get more variations";
  35.  
  36. //arrays
  37. var stringArray = [],
  38. tempStrings = [],
  39. falseAnswers = [],
  40. inB = [],
  41. inE = [],
  42. buttons = [],
  43. tempArr = [];
  44.  
  45. //empty val
  46. var searchFor,
  47. trueAnswer,
  48. trueId,
  49. id,
  50. rubyVal,
  51. deck;
  52.  
  53. //prefs
  54. var amountButtons,
  55. debug,
  56. decks,
  57. lastIdChosen;
  58.  
  59. void function Main()
  60. {
  61. //Place CSS in head
  62. CssAdd();
  63. //Set settings or create
  64. SetSettings();
  65. //Set event on decks page
  66. SetEventsOnDecks(document.URL);
  67. }();
  68.  
  69. //Settings
  70. function SetSettings()
  71. {
  72. const settings = $("<li class=nav-item></li>").html("<a id=awq_settings class=nav-link>Settings Ankiweb Quiz " + GM.info.script.version + "</a> \
  73. <div id=awq_settingsPanel class=awq_settingsP>\
  74. <form> \
  75. <br> \
  76. Amount Buttons(4-20):<input type=number name=amountBtn id=awq_amountBtn min=4 max=20 value=4></input><br> \
  77. Debug: <input type=checkbox name=debug id=awq_debug></input>\
  78. </form>\
  79. <button id=hideButton class=awq_style>Hide</button>\
  80. </div>\
  81. ");
  82.  
  83. $(".navbar-nav:first").append(settings);
  84. $("#awq_settings").addClass("awq_settings");
  85. $("#awq_settingsPanel").hide();
  86. SetEventSettings();
  87. LoadSettings();
  88. }
  89.  
  90. async function LoadSettings()
  91. {
  92.  
  93. DeleteValues("old");
  94.  
  95. //THIS IS ABOUT DEBUG
  96. if (await HasValue("awq_debug", false))
  97. {
  98. debug = await GM.getValue("awq_debug");
  99. $("#awq_debug").prop("checked", debug);
  100. }
  101.  
  102. //THIS IS ABOUT DECKS
  103. if (await HasValue("awq_decks", JSON.stringify(defaultDecks)))
  104. {
  105. decks = JSON.parse(await GM.getValue("awq_decks"));
  106. //console.log(decks);
  107. }
  108.  
  109. //THIS IS ABOUT lastIdChosen
  110. if (await HasValue("awq_lastIdChosen", 000))
  111. {
  112. lastIdChosen = await GM.getValue("awq_lastIdChosen");
  113. GetDeck(lastIdChosen);
  114. }
  115.  
  116. //THIS IS ABOUT BUTTONS
  117. if (await HasValue("awq_amountButtons", 8))
  118. {
  119. amountButtons = await GM.getValue("awq_amountButtons");
  120. $("#awq_amountBtn").prop("value", amountButtons);
  121. }
  122.  
  123. //Console log prefs with value
  124. console.log("*prefs:");
  125. console.log("*-----*");
  126. var vals = await GM.listValues();
  127.  
  128. for (var i = 0; i < vals.length; i++)
  129. {
  130. console.log("*" + vals[i] + ":" + await GM.getValue(vals[i]));
  131. }
  132. console.log("*-----*");
  133. }
  134.  
  135. //Check if value exists or not. optValue = Optional
  136. async function HasValue(nameVal, optValue)
  137. {
  138. var vals = await GM.listValues();
  139.  
  140. if (vals.length === 0)
  141. {
  142. if (optValue != undefined)
  143. {
  144. GM.setValue(nameVal, optValue);
  145. return true;
  146. } else
  147. {
  148. return false;
  149. }
  150. }
  151.  
  152. for (var i = 0; i < vals.length; i++)
  153. {
  154. if (vals[i] === nameVal)
  155. {
  156. return true;
  157. }
  158. }
  159.  
  160. if (optValue != undefined)
  161. {
  162. GM.setValue(nameVal, optValue);
  163. return true;
  164. } else
  165. {
  166. return false;
  167. }
  168. }
  169.  
  170. //Delete Values
  171. async function DeleteValues(nameVal)
  172. {
  173. var vals = await GM.listValues();
  174.  
  175. if (vals.length === 0 || typeof nameVal != "string")
  176. {
  177. return;
  178. }
  179.  
  180. switch (nameVal)
  181. {
  182. case "all":
  183. for (var i = 0; i < vals.length; i++)
  184. {
  185. GM.deleteValue(vals[i]);
  186. }
  187. break;
  188. case "old":
  189. for (var i = 0; i < vals.length; i++)
  190. {
  191. if (vals[i] === "debug" || vals[i] === "debugA" || vals[i] === "awq_amountBtn")
  192. {
  193. GM.deleteValue(vals[i]);
  194. }
  195. }
  196. break;
  197. default:
  198. for (var i = 0; i < vals.length; i++)
  199. {
  200. if (vals[i] === nameVal)
  201. {
  202. GM.deleteValue(nameVal);
  203. }
  204. }
  205. break;
  206. }
  207. }
  208.  
  209. //Construction of Deck
  210. function Deck(question, answer, idTimeOne, idTimeTwo)
  211. {
  212. this.question = [question];
  213. this.answer = [answer];
  214. this.idTimeOne = [idTimeOne];
  215. this.idTimeTwo = [idTimeTwo];
  216. }
  217.  
  218. //Construction of Decks
  219. function Decks(cards)
  220. {
  221. this.cards = cards;
  222. this.updateDeck = false;
  223. this.firstTime = true;
  224. this.customSettings = {};
  225. };
  226.  
  227. function SetEventSettings()
  228. {
  229. $("#awq_settings").click(function ()
  230. {
  231. $("#awq_settingsPanel").toggle(1000);
  232. });
  233.  
  234. $("#hideButton").click(function ()
  235. {
  236. $("#awq_settingsPanel").toggle(1000);
  237. });
  238.  
  239. $("#awq_debug").change(function ()
  240. {
  241. GM.setValue("awq_debug", $(this).prop("checked"));
  242. debug = $(this).prop("checked");
  243. alert("Settings has been changed. Please reload the page.");
  244. });
  245.  
  246. $("#awq_amountBtn").change(function ()
  247. {
  248. GM.setValue("awq_amountButtons", $(this).prop("value"));
  249. amountButtons = $(this).prop("value");
  250. alert("Settings has been changed. Please reload the page.");
  251. });
  252. }
  253.  
  254. function SetEventsOnDecks(url)
  255. {
  256. if (url.match(/http:\/\/ankiweb\.net\/decks/i) || url.match(/https:\/\/ankiweb\.net\/decks/i))
  257. {
  258. $("div.light-bottom-border > div:first-child > button").on("mousedown", function ()
  259. {
  260. lastIdChosen = this.id;
  261. GM.setValue("awq_lastIdChosen", lastIdChosen);
  262. });
  263. } else
  264. {
  265. return;
  266. }
  267. }
  268.  
  269. function SetEventsOnStudy(url)
  270. {
  271. if (url.match(/http:\/\/ankiweb\.net\/study/i) || url.match(/https:\/\/ankiweb\.net\/study/i))
  272. {
  273. $("#leftStudyMenu a:first-child").on("mouseover", function ()
  274. {
  275. try
  276. {
  277. UpdateGMDecks();
  278. console.log("UpdateGM");
  279. } catch (e) { console.log(e); }
  280. });
  281. } else
  282. {
  283. return;
  284. }
  285. }
  286.  
  287. function FindIndexes(searchStr, str, caseSensitive)
  288. {
  289. var searchStrLen = searchStr.length;
  290. if (searchStrLen == 0)
  291. {
  292. return [];
  293. }
  294. var startIndex = 0, index, indices = [];
  295. if (!caseSensitive)
  296. {
  297. str = str.toLowerCase();
  298. searchStr = searchStr.toLowerCase();
  299. }
  300. while ((index = str.indexOf(searchStr, startIndex)) > -1)
  301. {
  302. indices.push(index);
  303. startIndex = index + searchStrLen;
  304. }
  305. return indices;
  306. }
  307.  
  308. //css styles adds
  309. function CssAdd()
  310. {
  311. $("head").append($("<!--Start of AnkiWeb Quiz v" + GM.info.script.version + " CSS-->"));
  312.  
  313. $("head").append($("<style type=text/css></style>").text("button.awq_btn { \
  314. \
  315. }"));
  316.  
  317. $("head").append($("<style type=text/css></style>").text("a.awq_settings { \
  318. cursor: pointer;\
  319. }"));
  320.  
  321. $("head").append($("<style type=text/css></style>").text("div.awq_settingsP { \
  322. position:absolute; width:300px; background-color: #fff; border-color: #eee!important; border-radius: .3rem; border: 2px solid transparent; z-index: 150;\
  323. }"));
  324.  
  325. $("head").append($("<style type=text/css></style>").text("button.awq_style { \
  326. 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;\
  327. }"));
  328.  
  329. $("head").append($("<style type=text/css></style>").text("button.awq_style:hover { \
  330. cursor: pointer; color: #fff; background-color: #025aa5; border-color: #01549b; padding: .75rem 1.5rem; font-size: 1rem; border-radius: .3rem; border: 1px solid transparent;\
  331. }"));
  332.  
  333. $("head").append($("<style type=text/css></style>").text("div.awq_rstyle { \
  334. width:100%; margin-top:30px; z-index: 100;\
  335. }"));
  336.  
  337. $("head").append($("<style type=text/css></style>").text("button.awq_true { \
  338. background-color: #75d802; border-color: #75d802;\
  339. }"));
  340.  
  341. $("head").append($("<style type=text/css></style>").text("button.awq_true:hover { \
  342. background-color: #5aa502; border-color: #5aa502;\
  343. }"));
  344.  
  345. $("head").append($("<style type=text/css></style>").text("button.awq_false { \
  346. background-color: #d80275; border-color: #d80275;\
  347. }"));
  348.  
  349. $("head").append($("<style type=text/css></style>").text("button.awq_first { \
  350. background-color: #000; border-color: #000;\
  351. }"));
  352.  
  353. $("head").append($("<style type=text/css></style>").text("button.awq_false:hover { \
  354. background-color: #a5025a; border-color: #a5025a;\
  355. }"));
  356.  
  357. $("head").append($("<!--End of AnkiWeb Quiz v" + GM.info.script.version + " CSS-->"));
  358. }
  359.  
  360. function GetDeck(idDeck)
  361. {
  362. var keyNames = Object.keys(decks);
  363. for (var i in keyNames)
  364. {
  365. if (idDeck == keyNames[i])
  366. {
  367. deck = decks[idDeck].cards;
  368. return;
  369. }
  370. }
  371.  
  372. if (deck == undefined)
  373. {
  374. decks[idDeck] = new Decks(defaultDeck);
  375. deck = decks[idDeck].cards;
  376. return;
  377. }
  378. }
  379.  
  380. //THIS FUNC FOR UPDATING Greasemonkey value JSON OBJECT
  381. function UpdateGMDecks()
  382. {
  383. try
  384. {
  385. if (deck["answer"].length < amountButtons)
  386. {
  387. decks[lastIdChosen].firstTime = true;
  388. }
  389.  
  390. var gmDecks = JSON.stringify(decks);
  391. GM.setValue("awq_decks", gmDecks);
  392. }
  393. catch (e)
  394. {
  395. console.log(e);
  396. }
  397. }
  398.  
  399. $(document).ready(function ()
  400. {
  401.  
  402. // Append some text to the element with id someText using the jQuery library.
  403. //$("#studynow").append(" more text...................");
  404. $("#studynow").click(function ()
  405. {
  406. setTimeout(function ()
  407. {
  408. SetUI();
  409. SetEventsOnStudy(document.URL);
  410. if (decks[lastIdChosen].firstTime == true)
  411. {
  412. FirstTimeDeck(std.currentCard, std["deck"].cards);
  413. } else
  414. {
  415. var question = $.trim(StripNewLines(StripTags(std.currentCard[1].replace(/<style>[\s\S]*?<\/style>/ig, '')))),
  416. answer = $.trim(StripNewLines(StripTags(std.currentCard[2].replace(/[\s\S]*?(<hr id=answer>)/ig, '').replace(/<style>[\s\S]*?<\/style>/ig, '')))),
  417. idTimeOne = std.currentCard[0],
  418. idTimeTwo = std.currentCard[4];
  419. UpdateDeck(question, answer, idTimeOne, idTimeTwo);
  420. }
  421. //searchFor = SearchQuestion();
  422. if (debug)
  423. {
  424. console.log(std);
  425. console.log("---");
  426. //console.log($.trim(StripNewLines(StripTags(asd[1].replace(/<style>[\s\S]*?<\/style>/ig, '')))));
  427. //console.log($.trim(StripNewLines(StripTags(asd[2].replace(/[\s\S]*?(<hr id=answer>)/ig, '').replace(/<style>[\s\S]*?<\/style>/ig, '')))));
  428. console.log("---");
  429. //console.log("FirstTime:" + decks[lastIdChosen].firstTime);
  430. console.log(decks);
  431. console.log($.trim($("#rightStudyMenu").text()).split("+"));
  432. //console.log("searchFor:" + searchFor);
  433. }
  434. //GetTrueAnswer(searchFor);
  435. GetTrueAnswerU(std.currentCard[0], std.currentCard[4]);
  436. if (debug)
  437. {
  438. console.log('Study Click');
  439. }
  440. }, 1500);
  441. });
  442.  
  443. function NumberOfButtons()
  444. {
  445. var buttons = "";
  446. for (var i = 0; i < amountButtons; i++)
  447. {
  448. buttons += "<button class=awq_btn></button>";
  449. }
  450. return buttons;
  451. }
  452.  
  453. //THIS FUNC FOR FIRST TIME USING DECK AFteR INSTALL SCRIPT
  454. function FirstTimeDeck(currentCard, nextCards)
  455. {
  456. var questions = [$.trim(StripNewLines(StripTags(currentCard[1].replace(/<style>[\s\S]*?<\/style>/ig, ''))))],
  457. answers = [$.trim(StripNewLines(StripTags(currentCard[2].replace(/[\s\S]*?(<hr id=answer>)/ig, '').replace(/<style>[\s\S]*?<\/style>/ig, ''))))],
  458. idTimeOnes = [currentCard[0]],
  459. idTimeTwos = [currentCard[4]];
  460.  
  461. for (var i = 0; i < nextCards.length; i++)
  462. {
  463. questions.push($.trim(StripNewLines(StripTags(nextCards[i][1].replace(/<style>[\s\S]*?<\/style>/ig, '')))));
  464. answers.push($.trim(StripNewLines(StripTags(nextCards[i][2].replace(/[\s\S]*?(<hr id=answer>)/ig, '').replace(/<style>[\s\S]*?<\/style>/ig, '')))));
  465. idTimeOnes.push(nextCards[i][0]);
  466. idTimeTwos.push(nextCards[i][4]);
  467. }
  468.  
  469. for (var i = 0; i < questions.length; i++)
  470. {
  471. UpdateDeck(questions[i], answers[i], idTimeOnes[i], idTimeTwos[i]);
  472. }
  473.  
  474. decks[lastIdChosen].firstTime = false;
  475. }
  476.  
  477. //THIS FUNC FOR UPDATING DECK OBJECT
  478. function UpdateDeck(question, answer, idTimeOne, idTimeTwo)
  479. {
  480. //TODO FORCE UPDATE
  481. if (question.length >= 350)
  482. {
  483. question = "CARD TOO LONG: " + question.slice(0, 350);
  484. }
  485.  
  486. if (answer.length >= 350)
  487. {
  488. answer = "CARD TOO LONG: " + answer.slice(0, 350);
  489. }
  490.  
  491. //CHECK FOR REPEAT
  492. for (var i = 0; i < deck["idTimeOne"].length; i++)
  493. {
  494. if (idTimeOne === deck["idTimeOne"][i] && idTimeTwo === deck["idTimeTwo"][i])
  495. {
  496. return;
  497. }
  498. }
  499.  
  500. //First time deck detected(delete default card)
  501. if (deck["idTimeOne"][0] === 10001 && deck["idTimeTwo"][0] === 20002)
  502. {
  503. deck["question"][0] = question;
  504. deck["answer"][0] = answer;
  505. deck["idTimeOne"][0] = idTimeOne;
  506. deck["idTimeTwo"][0] = idTimeTwo;
  507. } else
  508. {
  509. deck["question"].push(question);
  510. deck["answer"].push(answer);
  511. deck["idTimeOne"].push(idTimeOne);
  512. deck["idTimeTwo"].push(idTimeTwo);
  513. }
  514. }
  515.  
  516. function SetUI()
  517. {
  518. const buttonP = $("<button id=awq_quiz class=btn style=margin-left:4px></button>").text("Quiz");
  519. const button = $("<div class=awq_rstyle></div>").html(NumberOfButtons());
  520.  
  521. $(".pt-1").before("<br>");
  522. $(".pt-1").before(button);
  523.  
  524. $("#leftStudyMenu").after(buttonP);
  525.  
  526. SettingsEvents();
  527.  
  528. $("#awq_quiz").addClass("btn-secondary");
  529. $(".awq_btn").addClass("awq_style");
  530. $(".awq_rstyle").hide();
  531. }
  532.  
  533. function SettingsEvents()
  534. {
  535.  
  536. $("#awq_quiz").click(function ()
  537. {
  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. {
  851. for (var i = 0; i < array.length; i++)
  852. if (array[i] == el) return true;
  853. return false;
  854. }
  855.  
  856. function GetRand(array)
  857. {
  858. var rand = Math.floor(Math.random() * array.length);
  859. if (!InArray(tempArr, rand))
  860. {
  861. tempArr.push(rand);
  862. return rand;
  863. }
  864. return GetRand(array);
  865. }
  866. //end of random functions
  867. //
  868.  
  869. function RamdomButton()
  870. {
  871. var allAnswers = [];
  872. buttons.length = 0;
  873. tempArr.length = 0;
  874. allAnswers[0] = trueAnswer;
  875. for (var i = 1; i <= falseAnswers.length; i++)
  876. {
  877. allAnswers[i] = falseAnswers[i - 1];
  878. }
  879. if (debug)
  880. {
  881. console.log("False answers :");
  882. console.log(falseAnswers);
  883. console.log("ALL answers :");
  884. console.log(allAnswers);
  885. }
  886. for (var i = 0; i < allAnswers.length; i++)
  887. {
  888. buttons[i] = $.trim(allAnswers[GetRand(allAnswers)]);
  889. }
  890. if (debug)
  891. {
  892. console.log("Random order :) = " + buttons);
  893. // console.log($(".awq_LeftSide").html());
  894. }
  895. UiButtons();
  896. }
  897.  
  898. function UiButtons()
  899. {
  900. const sel = document.querySelectorAll("button.awq_btn");
  901. if (debug)
  902. {
  903. console.log("*HERE UI BUTTONS :");
  904. }
  905.  
  906. for (var i = 0; i < buttons.length; i++)
  907. {
  908. //Delete arttribute
  909. if ($(sel[i]).attr("title"))
  910. {
  911. $(sel[i]).removeAttr("title");
  912. }
  913.  
  914. if (buttons[i].length <= 40 || buttons[i].includes("</ruby>"))
  915. {
  916. $(sel[i]).html(buttons[i]);
  917. } else
  918. {
  919. $(sel[i]).html(buttons[i].slice(0, 40) + "...");
  920. $(sel[i]).attr("title", buttons[i]);
  921.  
  922. //change color of button with textDefault
  923. if ($(sel[i]).attr("title") == textDefault)
  924. {
  925. $(sel[i]).addClass("awq_first");
  926. }
  927. }
  928.  
  929. if (debug)
  930. {
  931. //console.log($(sel[i]).attr("title"));
  932. console.log(buttons[i] + " Length: " + buttons[i].length);
  933. console.log(buttons[i].includes("</ruby>"));
  934. }
  935. }
  936.  
  937.  
  938. CheckPresedButtons();
  939. }
  940.  
  941. function CheckPresedButtons()
  942. {
  943. $(".awq_btn").removeClass("awq_true");
  944. $(".awq_btn").removeClass("awq_false");
  945. //$(".awq_btn").removeClass("awq_first");
  946. }
  947.  
  948. console.log("AnkiWeb Quiz v" + GM.info.script.version + " initialization");
  949. });
  950.  
  951. function StripTags(string)
  952. {
  953. return string.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?(\/)?>|<\/\w+>/gi, '');
  954. }
  955.  
  956. function StripNewLines(string)
  957. {
  958. return string.replace(/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/gi, '\n');
  959. }
  960. // ------------
  961. // TODO
  962. // ------------
  963.  
  964. /* TODO STARTS
  965. ✓ 0)REWRITE EVERYTHING WITHOUT USING GETRESOURCE AND CHANGING CODE //DONE 1.0.0
  966. 0.1)Make custom settings
  967. 0.2)Make force update deck (Because once you updated card, in gm_value will be old version of card)
  968. ✓ 1)Make it only one element of buttons //DONE 0.0.9
  969. ✓ 1.1)Increase numbers of buttons to 10-12(optional through settings???) //DONE 1.1.0
  970. ✓ 2)Make it limit of length answer and put whole in attribute title //DONE 0.1.0
  971. ✓ 3)Make it settings, almost done in 0.1.0 //DONE 0.2.0
  972. ✓ 3.1)Debug //DONE 0.1.0
  973. 3.2)Add txt file ***RESEARCH NEEDED***
  974. 3.2.1)Choose them
  975. 3.3)Make it always show quiz
  976. ✓ 4)Make it full functionality of Japanese deck, partial done in 0.0.8 //DONE 0.0.9 Happy with that :)
  977. 5)Search question in between tags <awq_question> and </awq_question> not in whole sentence, almost done in 0.1.2
  978. ✓ 6)TODO for loop in finding question NEED TEST IT //DONE 0.1.7 BROKEN //DONE 0.1.9
  979. ✓ 7)Support GM4+, GM3 and other userscript extensions, beta 1.2.0 //DONE 1.2.3
  980. 7.1)DELETE CALLBACK!!!
  981. TODO ENDS */