Greasy Fork

Greasy Fork is available in English.

Bunpro Toolbox

Adds various search options from Japanese resources

当前为 2023-09-01 提交的版本,查看 最新版本

 // ==UserScript==
// @name         Bunpro Toolbox
// @version      1.5.21
// @description  Adds various search options from Japanese resources
// @author       Ambo100
// @match        *bunpro.jp/grammar_points/*
// @match        *bunpro.jp/learn*
// @grant        none
// @namespace    http://greasyfork.icu/users/230700
// @changelog    Hotfix to tackle UI changes;
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    var grammarPoint;
    var grammarDiv;
    var toolboxDiv;

    window.addEventListener('load', function() {
        AddToolbox();

        //TOOKBOX SETUP START//

        // Dictionaries, References
        AddLink("Jisho", "https://jisho.org/search/");
        AddLink("Wikitionary", "https://en.wiktionary.org/wiki/","#Japanese");
        AddLink("Eijirou", "https://eow.alc.co.jp/search?q=","");

        AddDivider();

        //YouTube
        AddLink("YouGlish", "https://youglish.com/pronounce/","/japanese?");
        AddLink("YouTube", "https://www.youtube.com/results?search_query=","+Japanese");

        AddDivider();

        //Q&A, Communities
        AddLink("Stack Exchange", "https://japanese.stackexchange.com/search?q=");
        AddLink("HiNative", "https://hinative.com/en-US/search/questions?language_id=45&q=");
        AddLink("Reddit", "https://www.reddit.com/r/LearnJapanese/search?q=","&restrict_sr=on&sort=relevance&t=all");
        AddLink("WK Forum", "https://community.wanikani.com/search?q=","%20category%3A17");
        AddBunproLink("Discussion");

        //TOOLBOX SETUP END//

        FixBrokenLinks();
    }, false);

    function AddToolbox() {
        grammarPoint = document.getElementsByClassName("bp-ddw undefined")[0].innerText;
        grammarDiv = document.getElementsByClassName("mx-auto w-full max-w-max-content-width px-24 md:px-28 py-24 block")[0];

        console.log(grammarPoint);

        if (!grammarDiv) {
            console.error("Grammar Div not found.");
            return;
        }

        toolboxDiv = document.createElement("div");
        grammarDiv.prepend(toolboxDiv);

        // toolboxDiv.innerHTML = "test";


        //Toolbox CSS classes
        toolboxDiv.classList.add('rounded');
        toolboxDiv.classList.add('border');
        toolboxDiv.classList.add('border-rim');
        toolboxDiv.classList.add('bg-secondary-bg');
        toolboxDiv.classList.add('h-full');
        toolboxDiv.classList.add('md:col-span-3');
        toolboxDiv.classList.add('p-24');
    }
    
    /**
     * @global
     * @description This function has three parameters, a link name, prefix (main URL) and an optional suffix parameter. The current grammar point will be placed between the prefix and suffix of the link.
     * @param {string} linkName Link Name
     * @param {string} urlPrefix URL Prefix
     * @param {string} [urlSuffix] Can be used for adding additional search queries
     * @example //Search Jisho.org
     * AddLink("Jisho", "https://jisho.org/search/");
     * @example //Search Wikitionary.org, add #Japanese anchor link
     * AddLink("Wikitionary", "https://en.wiktionary.org/wiki/","#Japanese");
     */
    function AddLink(linkName, urlPrefix = '', urlSuffix = '') {
        // Create a new anchor element
        const link = document.createElement('a');
    
        // Set the link's attributes
        link.classList.add(
            'inline-flex',
            'items-center',
            'justify-center',
            'py-4',
            'px-12',
            'rounded',
            'text-center',
            'border',
            'transition-colors',
            'border-secondary-fg',
            'bg-transparent',
            'bg-secondary-fg',
            'text-secondary-fg'
        );

        link.style.margin = '5px';

        link.href = `${urlPrefix}${grammarPoint}${urlSuffix}`;
        link.target = '_blank';
        link.textContent = linkName;
    
        toolboxDiv.appendChild(link);
    }
    
    function AddBunproLink(linkName) {
        // Corrected Bunpro grammar forum link URL
        const bunproGrammarForumLink = 'https://community.bunpro.jp/t/grammar-discussion/475';
    
        // Create a new anchor element
        const link = document.createElement('a');
    
        // Set the link's attributes and classes
        link.classList.add(
            'inline-flex',
            'items-center',
            'justify-center',
            'py-4',
            'px-12',
            'rounded',
            'text-center',
            'border',
            'transition-colors',
            'border-secondary-fg',
            'bg-transparent',
            'bg-secondary-fg',
            'text-secondary-fg'
        );
    
        link.style.margin = '5px'; // Add margin to the link
    
        link.href = bunproGrammarForumLink; // Set the correct URL
        link.target = '_blank';
        link.textContent = linkName;
    
        // Append the link to the toolboxDiv
        toolboxDiv.appendChild(link);
    }
    

    /**
     * @global
     * @description Adds a vertical divider between links with set spacing.
     * @param {int} [padding=10] Measured in pixels (px).
     * @param {string} [dividerSymbol=|]
     * @example //Standard 10px divider
     * AddDivider();
     * @example //30px divider with the character "-".
     * AddDivider(30, "-");
     */
    function AddDivider(padding = '10', dividerSymbol = ' ') {
        toolboxDiv.innerHTML += '<span class="" style="padding: ' + padding + 'px">' + dividerSymbol + '</span>';
    }
    
    /**
     * @global
     * @description Clears all default links and dividers from the toolbox.
     */
    function ClearToolbox(){
        toolboxDiv.innerHTML = "";
    }

    /**
     * @global
     * @description This function has three parameters, a PDF title, local PDF URL and a parameter for optional PDF parameters. </br></br>
     * <b>Warning</b> </br> This feature is experimental, modern browsers will block links to local URLs for security purposes.
     * An browser extension, such as this <a href="https://chrome.google.com/webstore/detail/enable-local-file-links/nikfmfgobenbhmocjaaboihbeocackld?hl=en">extension</a> for Google Chrome can enable this feature.
     * @param {string} pdfTitle The name of the linK, this must match exactly with the names used on Bunpro (excludes non alphanumeric characters).
     * @param {string} pdfURL The local URL of your PDF file. Must be preceeded with 'file://'
     * @param {string} [pdfParameters] May be used for adding additional PDF parameters
     * @example //Adds a link to the PDF that matches 'Genki II 2nd Edition'.
     * AddPDFLink("Genki II 2nd Edition","file:///C:/Users/YOUR_USER/Documents/GenkiElementaryII.pdf");
     * @example //Adds a link to the PDF that matches 'DAJB'.
     * AddPDFLink("DAJG","file:///C:/Users/YOUR_USER/Documents/DAJG.pdf");
     * @example //Adds a link to the PDF that matches 'AIAIJ', includes optional query to set zoom level.
     * AddPDFLink("AIAIJ","file:///C:/Users/YOUR_USER/Documents/AIAIJ.pdf", "zoom=120");
     */
    function AddPDFLink(pdfTitle = '', pdfURL = '', pdfParameters = ''){
        var booksDivContainer = document.getElementsByClassName("grammar-point__container--resources-card-main-text-new");

        var regexBookTitle = new RegExp('(.*' + pdfTitle + '.*)','i');
        var regexPageNumber = new RegExp('Page\\s(\\d+)','i');

        for (var i = 0; i < booksDivContainer.length; i++) {
            var result = regexBookTitle.exec(booksDivContainer[i].innerText);

            if (result != null) {
                var bookPageNumberDiv = booksDivContainer[i].parentElement.getElementsByTagName('div')[1].innerText;
                var bookPageNumber = regexPageNumber.exec(bookPageNumberDiv);

                //Replace book title with link
                var pageLink = document.createElement("a");
                pageLink.setAttribute('href', pdfURL + "#page=" + bookPageNumber[1] + "&" + pdfParameters);
                pageLink.innerText = booksDivContainer[i].innerText.trim();
                booksDivContainer[i].textContent = "";
                booksDivContainer[i].appendChild(pageLink);
                booksDivContainer[i].innerHTML += " ";

                //Add link icon
                var externalLink = document.createElement("i");
                externalLink.classList.add("fas", "fa-external-link-alt");
                booksDivContainer[i].appendChild(externalLink);
            }   
        }
    }

    function FixBrokenLinks() {
        var links = document.getElementsByTagName("a");
        var regex = /^(http?:\/\/)[^.]+\.(jgram|tanos|99bako)(.+)$/i;
        for (var i = 0, iMax = links.length; i < iMax; i++) {
            links[i].href = links[i].href.replace(regex, "https://web.archive.org/web/" + links[i].href);
        }
    }
}
)();