您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Plays random chapters from a study
// ==UserScript== // @name Study Lichess // @description Plays random chapters from a study // @license public domain // @version 1 // @namespace jlxip // @grant none // @include https://lichess.org/study/* // @include https://lichess.org/study/*/* // ==/UserScript== // Source: https://stackoverflow.com/a/12646864/23750873 function shuffleArray(array) { for (let i = array.length - 1; i >= 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } } // Source: https://stackoverflow.com/a/61511955/23750873 function waitForElm(selector) { return new Promise(resolve => { if (document.querySelector(selector)) { return resolve(document.querySelector(selector)); } const observer = new MutationObserver(mutations => { if (document.querySelector(selector)) { observer.disconnect(); resolve(document.querySelector(selector)); } }); observer.observe(document.body, { childList: true, subtree: true }); }); } // --- let chapters = null; const exercises = []; // Waits for something to have the class "active" function waitActive(x, f, cb) { setTimeout(() => { let e = x; if (typeof(x) === "function") e = x(); if (e.classList.contains("active")) { cb(); } else { if (f != null) f(e); waitActive(x, f, cb); } }, 10); } function play() { if (exercises.length == 0) { alert("🎉"); return; } const e = exercises.pop(); chapters[e].click(); // Wait for chapter to become active waitActive(chapters[e], null, () => { // Click preview button (repeatedly until it works) waitActive(() => document.getElementsByClassName("preview")[0], x => x.click(), () => { // That's it, wait for solve waitForElm(".retry").then(play); }); }); } waitForElm(".study__side").then((x) => { const but = document.createElement("span"); but.classList.add("more"); but.classList.add("narrow"); but.setAttribute("data-icon", "🧐"); but.onclick = () => { // Get exercises chapters = document.getElementsByClassName("study__chapters")[0].children; for (let i=0; i<chapters.length - 1; ++i) exercises.push(i); // Shuffle shuffleArray(exercises); // Play the first play(); }; x.children[0].append(but); });