// ==UserScript== // @name Bunpro Custom Layout For Vocab Reading Reviews // @namespace bunpro-custom-layout-vocab-reading // @match https://bunpro.jp/* // @grant none // @version 1.6 // @author - // @description 11/28/2024, 6:43:44 AM // @run-at document-idle // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; // Handle navigation to this page window.onload = observeUrlChange(setup); // Handle direct loading of the page setup(); })(); function observeUrlChange(onChange) { // Whole purpose of this function is to run setup() when we navigate to the review page let oldHref = document.location.href; const body = document.querySelector("body"); const observer = new MutationObserver(mutations => { mutations.forEach(() => { if (oldHref !== document.location.href && document.location.href.toLowerCase().startsWith("https://bunpro.jp/reviews")) { oldHref = document.location.href; onChange(); } }); }); observer.observe(body, { childList: true, subtree: true }); } // function showFuriganaOnReview(showFurigana) { // const rts = document.querySelectorAll("#js-tour-quiz-question > div.bp-quiz-question > span.text-primary-accent > span > ruby > rt"); // if (!rts) return; // for (const rt of rts) { // if (showFurigana) { // rt.classList.remove('bp-js-hide-furi'); // } else { // rt.classList.add('bp-js-hide-furi'); // } // } // } function setup() { console.log("Setup called"); // Setup an observer to determine whether the english sentence is hidden const body = document.querySelector("body"); const observer = new MutationObserver(() => { // console.log("Changed"); // Look for page elements // const metadata = document.querySelector("#quiz-metadata-element"); const engSentenceDivs = document.querySelectorAll("#js-tour-quiz-question > div.bp-quiz-trans-wrap > div"); const displayLocation = document.querySelector("#js-tour-quiz-question"); // Return immediately if we can't find our elements if (engSentenceDivs == null || displayLocation == null) { // console.log(`metadata: ${metadata}\nengSentenceDivs: ${engSentenceDivs}\ndisplayLocation: ${displayLocation}\nitemToAddOrig: ${itemToAddOrig}`) return; } // Make sure that we are doing vocab reviews in reading mode if (!document.location.href.includes("reviews?only_review=vocab")) { return; } // Decide whether the english sentence is visible or not let visible = false; for (const engSentenceDiv of engSentenceDivs) { if (!engSentenceDiv.className.includes("invisible")) { visible = true; break; } } // Do something if the english sentence is visible/invisible if (visible) { // console.log("Visible!"); // showFuriganaOnReview(true); // Copy the definition and pitch to the area above the good/hard buttons if (document.querySelector("#bunpro-custom-layout-vocab-reading") != null) { // console.log("Already added.") return; } const pitchAccent = document.querySelector("#js-tour-learn-details > ul > li:nth-child(1) > div > ul"); const vocabInfo = document.querySelector("#js-rev-header > div.flex.items-start.justify-between > div > div > p.text-primary-contrast.md\\:text-primary-fg"); const dictionaryInfo = document.querySelector("#js-struct-details > section.border-b.p-24.md\\:rounded.md\\:border.border-rim.bg-secondary-bg.w-full.md\\:w-3\\/5.lg\\:w-full.xl\\:w-3\\/5") // Make sure we have at least the dictonary info if (dictionaryInfo == null) { return } // Create a new div and store everything in it var divCustom = document.createElement("div"); divCustom.id = "bunpro-custom-layout-vocab-reading"; divCustom.className = "flex flex-col md:flex-row md:gap-16 lg:flex-col xl:flex-row"; divCustom.style = "scroll-margin-top: calc(53px + 2.5rem)"; // Create a "box" to store the pitch and Noun Info var section = document.createElement("section"); section.className = "border-b p-24 md:rounded md:border border-rim bg-secondary-bg flex-1"; section.appendChild(pitchAccent.cloneNode(true)); section.appendChild(vocabInfo.cloneNode(true)); divCustom.appendChild(section); // Add the dictionaryInfo Box divCustom.appendChild(dictionaryInfo.cloneNode(true)); // Add the entire div to the display displayLocation.insertAdjacentElement('afterend', divCustom); } else { // console.log("Not Visible!"); // showFuriganaOnReview(false); // Clean Up - Remove objects that we added const itemAdded = document.querySelector("#bunpro-custom-layout-vocab-reading"); if (itemAdded != null) { itemAdded.remove(); } } }); observer.observe(body, { childList: true, subtree: true }); }