// ==UserScript==
// @name Bunpro Toolbox
// @version 1.2
// @description Adds various search options from Japanese resources
// @author Ambo100
// @match *bunpro.jp/grammar_points/*
// @grant none
// @namespace https://greasyfork.org/en/scripts/418290-bunpro-toolbox
// @changelog Added full documentation for Toolbox customisation; New experimental feature to automatically add page links for textbooks to your own locally hosted PDF files; Added a ClearToolbox() function to remove all links and dividers; AddDivider() now allows a custom symbol with the 'dividerSymbol' attribute; Added toolbox link for HiNative;
// ==/UserScript==
(function() {
'use strict';
let grammarPoint = document.getElementsByClassName("meaning__japanese")[0].innerText;
let toolboxDiv;
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("WK Forum", "https://community.wanikani.com/search?q=","%20category%3A17");
AddLink("Reddit", "https://www.reddit.com/r/LearnJapanese/search?q=","&restrict_sr=on&sort=relevance&t=all");
//TOOLBOX SETUP END//
//???
AddPDFLink("AIAIJ","file:///C:/Users/ambo1/Documents/Japanese/AIAIJ.pdf");
AddPDFLink("DAJG","file:///C:/Users/ambo1/Documents/Japanese/DAJG.pdf");
AddPDFLink("DBJG","file:///C:/Users/ambo1/Documents/Japanese/DBJG.pdf");
AddPDFLink("Genki I 2nd Edition","file:///C:/Users/ambo1/Documents/Japanese/Genki/Genki%20-%20Elementary%20Japanese%20I.pdf", "zoom=120");
AddPDFLink("Genki II 2nd Edition","file:///C:/Users/ambo1/Documents/Japanese/Genki/Genki%20-%20Elementary%20Japanese%20II.pdf", "zoom=120");
//???
FixBrokenLinks();
function AddToolbox() {
let grammarDiv = document.getElementsByClassName("section")[0];
toolboxDiv = document.createElement("div");
grammarDiv.append(toolboxDiv);
//Toolbox styling
toolboxDiv.classList.add('related-grammar__holder');
toolboxDiv.style.marginBottom = "0px";
toolboxDiv.style.paddingBottom = "25px";
}
/**
* @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 = '') {
toolboxDiv.innerHTML += '<a class="related-grammar-tile__link--japanese" style="padding: 30px" href="' + urlPrefix + grammarPoint + urlSuffix + '" target="_blank" >' + linkName + '</a>';
}
/**
* @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="related-grammar-tile__link--japanese" style="padding: ' + padding + 'px">' + dividerSymbol + '</span>';
}
/**
* @global
* @description Clears all default links and dividers from the toolbox.
*/
function ClearToolbox(){
toolboxDiv.innerHTML = "";
}
function FixBrokenLinks() {
let links = document.getElementsByTagName("a");
let regex = /^(http?:\/\/)[^.]+\.(jgram|tanos)(.+)$/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);
}
}
/**
* @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 = ''){
let offlineResourcesDiv = document.getElementsByClassName("offline-resources")[0].getElementsByTagName('div');
let regex = new RegExp('(.*' + pdfTitle + '.*)(Page\\s(\\d+))','i');
for (let i = 0; i < offlineResourcesDiv.length; i++) {
let result = regex.exec(offlineResourcesDiv[i].innerText);
if (result != null) {
offlineResourcesDiv[i].innerHTML = result[1];
let pageLink = document.createElement("a");
pageLink.setAttribute('href', pdfURL + "#page=" + result[3] + "&" + pdfParameters);
pageLink.innerText = result[2];
pageLink.classList.add("supplemental-link__link");
offlineResourcesDiv[i].appendChild(pageLink);
}
}
}
}
)();