Enables the quiz button without having to go through any of the lessons.
当前为
// ==UserScript==
// @name Wanikani: Skip to Quiz
// @namespace http://tampermonkey.net/
// @version 1.1.2
// @description Enables the quiz button without having to go through any of the lessons.
// @author Kumirei
// @match https://www.wanikani.com/lesson/session
// @match https://preview.wanikani.com/lesson/session
// @grant none
// ==/UserScript==
;(function ($) {
// Make quiz button look clickable
add_css(
'#lesson #batch-items ul li[data-index="quiz"] span {background-color: #004fdd; cursor: pointer !important;}',
'skip-to-quiz-css',
)
// Enable clicking quiz button by adding class that the existing
// click handler / keyup handler checks for before it fires
onEachElementReady('li[data-index="quiz"] > span', null, function (e) {
e = $(e)
const p = e.parent()
bindFirst(e, 'click', function () {
console.log('click', e, p)
p.addClass('active-quiz')
})
bindFirst($('body'), 'keyup', function (evt) {
if (evt.key == 'q') p.addClass('active-quiz')
})
})
// Library Functions
// Adds CSS to document
// Does not escape its input
function add_css(css, id = '') {
document.getElementsByTagName('head')[0].insertAdjacentHTML('beforeend', `<style id="${id}">${css}</style>`)
}
// Calls callback once on each element matching selector that is added
// to the DOM, including existing elements at the time the function is first called.
// options is options for the MutationObserver (optional, is merged with default options {childList: true, subtree: true})
function onEachElementReady(selector, options, callback) {
if (!options) options = {}
let els_found = new Set()
function check_available() {
for (const el of document.querySelectorAll(selector)) {
if (!els_found.has(el)) {
els_found.add(el)
callback(el)
}
}
}
queueMicrotask(check_available)
let mo = new MutationObserver(check_available)
mo.observe(document.documentElement, {
childList: true,
subtree: true,
...options,
})
}
// Adds a jQuery event listener that runs before all ones added so far
// Based on https://stackoverflow.com/questions/2360655/jquery-event-handlers-always-execute-in-order-they-were-bound-any-way-around-t
// [name] is the name of the event "click", "mouseover", ..
// same as you'd pass it to bind()
// [fn] is the handler function
let bindFirst = function (jqel, name, fn) {
// bind as you normally would
// don't want to miss out on any jQuery magic
jqel.on(name, fn)
// Thanks to a comment by @Martin, adding support for
// namespaced events too.
jqel.each(function () {
var handlers = $._data(this, 'events')[name.split('.')[0]]
// take out the handler we just inserted from the end
var handler = handlers.pop()
// move it at the beginning
handlers.splice(0, 0, handler)
})
}
})(window.jQuery)