Skip to content

Instantly share code, notes, and snippets.

@felipemarinho97
Last active September 6, 2020 19:03
Show Gist options
  • Save felipemarinho97/5bc631a855fbadf2f1437e94c21f8a52 to your computer and use it in GitHub Desktop.
Save felipemarinho97/5bc631a855fbadf2f1437e94c21f8a52 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name JinbuPal Hack
// @version 1.4
// @grant none
// @match https://beta.jinbupal.com/*
// @require https://cdn.jsdelivr.net/npm/hanzi-writer@2.2/dist/hanzi-writer.min.js
// ==/UserScript==
var jq = document.createElement('script');
jq.src = "https://cdn.jsdelivr.net/npm/hanzi-writer@2.2/dist/hanzi-writer.min.js";
document.getElementsByTagName('head')[0].appendChild(jq);
function createLink(link, text) {
const elm = document.createElement('a');
elm.href = link;
elm.target = "_blank";
elm.text = text;
elm.style.setProperty('padding', '0 15px')
elm.style.setProperty('margin-top', '10px')
elm.style.setProperty('font-style', 'italic')
elm.style.setProperty('text-decoration', 'underline')
return elm;
}
function addDefinitions(word) {
const defNode = document.getElementsByClassName('definitions')[0];
const fragment = document.createDocumentFragment();
fetch(`https://pinyin-word-api.vercel.app/api/links/${encodeURI(word)}`).then(r => r.json())
.then(res => {
Object.keys(res).forEach((key) => {
fragment.appendChild(createLink(res[key], key))
})
defNode.parentNode.insertBefore(fragment,defNode.nextSibling);
}).catch(console.log)
}
function playPinyin() {
document.querySelector('.pinyin-wrapper button').click();
}
function wordAudio() {
let word = document.getElementsByClassName('word')[0];
addDefinitions(word.textContent);
const audio = new Audio(`https://pinyin-word-api.vercel.app/api/audio/${word.textContent}`);
audio.crossOrigin = true;
const audioPod = new Audio(`https://pinyin-word-api.vercel.app/api/audio/pod/${word.textContent}`);
audioPod.crossOrigin = true;
word.addEventListener('click', () => audio.play())
word.addEventListener('contextmenu', (e) => {
e.preventDefault();
audioPod.play();
})
audio.play();
}
function subs() {
let char = document.getElementsByClassName('character')[0];
addDefinitions(char.textContent);
var writer = HanziWriter.create(char, char.textContent, {
width: 100,
height: 100,
padding: 0
});
char.removeChild(char.childNodes[0])
let quizRunning = false;
char.addEventListener('click', () => {
if (!quizRunning) {
writer.loopCharacterAnimation();
playPinyin();
}
});
char.addEventListener('contextmenu', (e) => {
e.preventDefault();
});
char.addEventListener('dblclick', () => {
if (!quizRunning) {
writer.quiz();
quizRunning = true;
}
else {
writer.cancelQuiz();
quizRunning = false;
}
});
playPinyin();
return writer;
}
function observeWords() {
var wordsObserver = new MutationObserver((mutations) => {
wordAudio();
})
runIfExists('app-word-modal', element => {
wordsObserver.observe(element, {
childList: true
, subtree: false
, attributes: false
, characterData: false
});
wordAudio();
})
}
function observeChars() {
var charsObserver = new MutationObserver((mutations) => {
subs();
})
runIfExists('app-char-modal', element => {
charsObserver.observe(element, {
childList: true
, subtree: false
, attributes: false
, characterData: false
});
subs();
})
}
let observerTabs = new MutationObserver((mutations) => {
if (location.pathname.includes('characters')) {
observeChars();
wordsObserver.disconnect();
} else if (location.pathname.includes('words')) {
observeWords();
charsObserver.disconnect();
}
})
function runIfExists(selector, callback) {
const existCondition = setInterval(function() {
const element = document.querySelector(selector);
if (element != null) {
console.log(`"${selector}" exists!`);
clearInterval(existCondition);
callback(element)
}
}, 100); // check every 100ms
}
runIfExists('app-root > div', element => {
observerTabs.observe(element, {
childList: true
, subtree: false
, attributes: false
, characterData: false
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment