Greasy Fork is available in English.

Quizlet Question Bypass

Gives you the images of the solutions on the bottom. Works best with auto-login quizlet.

  1. // ==UserScript==
  2. // @name Quizlet Question Bypass
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.31
  5. // @description Gives you the images of the solutions on the bottom. Works best with auto-login quizlet.
  6. // @author DevT02
  7. // @license MIT
  8. // @match http*://www.quizlet.com/explanations/questions/*
  9. // @match http*://quizlet.com/explanations/questions/*
  10. // @match http*://www.quizlet.com/explanations/textbook-solutions/*
  11. // @match http*://quizlet.com/explanations/textbook-solutions/*
  12. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  13. // @require https://code.jquery.com/jquery-3.6.0.min.js
  14. // @grant none
  15.  
  16. // ==/UserScript==
  17. /* globals jQuery, $, waitForKeyElements */
  18.  
  19. window.addEventListener('load', function() {
  20. 'use strict';
  21. const NEW_METHOD = localStorage.getItem("newMethod")==='true' // when slider is clicked, local storage will get result (keep scrolling for if-else on NEW_METHOD)
  22. let LOGGED_IN = false // assume we are not logged in
  23.  
  24. if ($("div[class^='SiteAvatar'],div[class*=' SiteAvatar']").length > 0){
  25. LOGGED_IN = true // if we find an avatar, we're logged in
  26. }
  27.  
  28.  
  29. var paywall = document.getElementById('__NEXT_DATA__'); // get paywall
  30. var data = paywall.outerHTML == null ? location.reload() : paywall.outerHTML; // outer json html (RELOAD IF NO HTML IS AVAILABLE, THIS IS FOR FIREFOX)
  31. console.log('Pre-checks completed! QuizletQuestionBypass by DevT02')
  32. console.log('Check out my other projects at https://github.com/DevT02/') // START PROGRAM
  33.  
  34. // add new method for unblur (requires to not be logged in) this adds the LABEL and the SLIDER.
  35. var headers = document.getElementsByTagName('header');
  36. headers[0].insertAdjacentHTML('beforeend', '<div id=antiLogindiv> <h2 id=method>Use NoLogin?</h2> <label class="switch"> <input type="checkbox"> <div class="slider round"></div> </label> </div>');
  37. headers[0].insertAdjacentHTML('beforeend', '<style type="text/css" id=centerDiv>#method{position:relative,top:15px;padding-bottom: 40px;margin:auto;white-space: nowrap; font-size: 22px;color: orange;}</style>')
  38. headers[0].insertAdjacentHTML('beforeend', '<style type="text/css" id=toggleSwitchStyle>.switch {position:absolute;top:37px;display: inline-block;width: 60px;height: 34px;}.switch input {display:none;}.slider {position: absolute;cursor: pointer;top: 0;left: 0;right: 0;bottom: 0;background-color: #ccc;-webkit-transition: .4s;transition: .4s;}.slider:before {position: absolute;content: "";height: 26px;width: 26px;left: 4px;bottom: 4px;background-color: white;-webkit-transition: .4s;transition: .4s;}input:checked + .slider {background-color: #2196F3;}input:focus + .slider {box-shadow: 0 0 1px #2196F3;}input:checked + .slider:before {-webkit-transform: translateX(26px);-ms-transform: translateX(26px);transform: translateX(26px);}.slider.round {border-radius: 34px;}.slider.round:before {border-radius: 50%;}</style>')
  39.  
  40. // if ALREADY was clicked, ensure it is in the correct spot!
  41. if (NEW_METHOD){
  42. $('input[type="checkbox"]').attr('checked', '')
  43. }
  44. else{
  45. $('input[type="checkbox"]').removeAttr('checked')
  46. }
  47.  
  48. // IF we CLICK the slider, store what position it is in (incase we move to next page!!!)
  49. $('.slider.round').click(function() {
  50. var checkbox = $('input[type="checkbox"]');
  51. if (!$(checkbox).prop('checked')) {
  52. localStorage.setItem("newMethod", true);
  53. } else {
  54. localStorage.setItem("newMethod", false);
  55. }
  56. });
  57.  
  58. // DO THE NEW METHOD
  59. if (NEW_METHOD && !LOGGED_IN){
  60. var selectElementContainer = $("div[class^='ExplanationSolutionsContainer'],div[class*=' ExplanationSolutionsContainer']")
  61. $(selectElementContainer).eq(0).css("max-height","10000rem") // best for when not logged in
  62. $(selectElementContainer).eq(0).css("overflow", "visible")
  63. selectElementContainer.each(function (index, element){
  64. $(selectElementContainer).eq(0).children().removeAttr('hidden') // show hidden divs (again best when not logged in)
  65. });
  66. }
  67.  
  68. // OLD KATEX UNBLUR METHOD
  69.  
  70. // split urls into an array named "data"
  71. data = data.split("https://").map(val => { return "https://"+val }).slice(1);
  72. function dataIncludes(a1, i){
  73. return data[i].includes(a1)
  74. }
  75.  
  76. var selectEachElement = $("div[class^='ExplanationsSolutionCard'],div[class*=' ExplanationsSolutionCard']")
  77. // Actually unblur KATEX
  78. selectEachElement.each(function (index, element){
  79. $(selectEachElement).eq(index).children().eq(1).children().first().children().first().removeAttr('style').css("filter","blur(0)")
  80.  
  81. });
  82.  
  83. var data2 = [];
  84. for(let i = 0; i < data.length; i++){
  85. data[i] = data[i].substring(0, data[i].indexOf("\""))
  86. if (dataIncludes("lateximg.png", i) || dataIncludes("assets", i) || dataIncludes("textbook_covers", i) || dataIncludes("cache", i)){
  87. data.splice(i, 1)
  88. i--
  89. }
  90. else if (dataIncludes("textbook-solutions", i)){
  91. data2.push(data[i])
  92. }
  93. }
  94.  
  95.  
  96. // add bottom buttons
  97.  
  98. var buttonCont = document.createElement("div");
  99. buttonCont.setAttribute('id', 'buttonContainer');
  100. buttonCont.style.backgroundColor = "white";
  101. document.body.appendChild(buttonCont);
  102.  
  103. var buttonContainer = document.getElementById('buttonContainer');
  104. var buttonFrag = document.createDocumentFragment();
  105.  
  106. // skip question buttons if logged in (WIP)
  107. data2.forEach(function(url, index, originalArray) {
  108. var btn = document.createElement('button');
  109. btn.style.textAlign = 'center';
  110. btn.style.transitionDuration = '0.4s'; // if i decide to add a hover event (unfortunately requires a css file)
  111. btn.style.display = 'inline-block';
  112. btn.style.margin= '6px 8px';
  113. switch (true){
  114. case (index == 0):
  115. btn.innerText = "Next Problem";
  116. break;
  117. case (index == 1):
  118. btn.innerText = "Skip 2 Problems";
  119. break;
  120. case (index == 2):
  121. btn.innerText = "Previous Problem";
  122. break;
  123. case (index == 3):
  124. btn.innerText = "Reload";
  125. break;
  126. case (index == originalArray.length - 1):
  127. btn.innerText = "Back to Textbook";
  128. break;
  129. default:
  130. return;
  131. }
  132. btn.style.padding = '20px 40px';
  133. btn.style.background = 'white'; // setting the background color to white
  134. btn.style.color = 'black'; // setting the color to black
  135. btn.style.border = '2px solid #f44336'
  136. btn.style.fontSize = '20px'; // setting the font size to 20px
  137. btn.onclick = function() {
  138. if (index != 3)
  139. location.href = url;
  140. else
  141. location.reload()
  142. }
  143. buttonContainer.appendChild(btn);
  144. });
  145. buttonContainer.appendChild(buttonFrag);
  146. document.getElementById("buttonContainer").style.display = "flex";
  147. document.getElementById("buttonContainer").style.alignItems = "center";
  148. document.getElementById("buttonContainer").style.justifyContent = "center";
  149.  
  150.  
  151.  
  152.  
  153. // remove popups
  154. var paywallremover = [ document.getElementsByClassName("hideBelow--s"), document.getElementsByClassName("hideBelow--s"), document.getElementsByClassName("hideBelow--m")]
  155. try{
  156. paywallremover.forEach(element => element[0].remove())
  157. }
  158. catch (err){
  159. console.log(err)
  160. }
  161.  
  162.  
  163.  
  164.  
  165. // add new container for images
  166. var imgCont = document.createElement("div");
  167. imgCont.setAttribute('id', 'imageContainer')
  168. imgCont.style.backgroundColor = "white";
  169. document.body.appendChild(imgCont);
  170.  
  171. var container = document.getElementById('imageContainer');
  172. var docFrag = document.createDocumentFragment();
  173.  
  174. data.forEach(function(url, index, originalArray) {
  175. var img = document.createElement('img');
  176. img.src = url;
  177. docFrag.appendChild(img);
  178. });
  179. container.appendChild(docFrag);
  180.  
  181.  
  182. // to work in tandem with quizlet bypass
  183. let div = document.createElement('div');
  184. div.classList.add('hideBelow--s');
  185. document.body.appendChild(div)
  186. let div2 = document.createElement('div');
  187. div2.classList.add('hideAbove--s');
  188. document.body.appendChild(div2)
  189. }, false);