[e-typing]打鍵音の追加 (ログアウト専用)

e-typingに打鍵音を追加したい

// ==UserScript==
// @name         [e-typing]打鍵音の追加 (ログアウト専用)
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  e-typingに打鍵音を追加したい
// @author       xyu
// @match        https://www.e-typing.ne.jp/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=e-typing.ne.jp
// @grant        none
// @license MIT
// ==/UserScript==
window.AudioContext = window.AudioContext || window.webkitAudioContext;
let key_type = new AudioContext();
let clear_type = new AudioContext();
let audioBuffer = {}

		fetch("https://dl.dropboxusercontent.com/s/ffeunovtfylnlsy/key_type.mp3?dl=0").then(function(response) {
			return response.arrayBuffer();
		}).then(function(arrayBuffer) {
			key_type.decodeAudioData(arrayBuffer, function(buffer) {
				audioBuffer.KeyType = buffer;
			});
		})
		fetch("https://dl.dropboxusercontent.com/s/cbwfyhbs8fmkg5d/clear_type.mp3?dl=0").then(function(response) {
			return response.arrayBuffer();
		}).then(function(arrayBuffer) {
			clear_type.decodeAudioData(arrayBuffer, function(buffer) {
				audioBuffer.ClearType = buffer;
			});
		})
function key_type_play(){
	let key_type_gain = key_type.createGain();
	let key_type_source = key_type.createBufferSource();
	key_type_source.buffer = audioBuffer.KeyType;
	key_type_source.connect(key_type_gain);
	key_type_gain.connect(key_type.destination);
			key_type_gain.gain.value = 70/100

	key_type_source.start(0,0.0005);
}
function clear_type_play(){
	let clear_type_gain = clear_type.createGain();
	let clear_type_source = clear_type.createBufferSource();
	clear_type_source.buffer = audioBuffer.ClearType;
	clear_type_source.connect(clear_type_gain);
	clear_type_gain.connect(clear_type.destination);
	clear_type_gain.gain.value = 70/100

	clear_type_source.start(0);
}


let typingAppModInterval
let createOptionInterval

let wordReload = false
let soundEffectSwitch = true
let typingMode = "roma"
let enteredClass = 2
if(location.href.match(/kana\.1/)){
	typingMode = "kana"
	enteredClass = 1
}else if(location.href.match(/std\.2/) || location.href.match(/lstn\.4/)){
	typingMode = "eng"
	enteredClass = 1
}else{
	typingMode = "roma"
	enteredClass = 2
}

const createOption = () => {
console.log("createOption")
const FUNC_VIEW = document.getElementById("func_view")
const DISABLE_OPTION = document.getElementById("disable-option")
	if(FUNC_VIEW){
		soundEffectSwitch = localStorage.getItem("sound-effect-option") == "false" ? false : true;
		FUNC_VIEW.style.height = document.getElementById("func_view").clientHeight + 30 + "px"
		FUNC_VIEW.insertAdjacentHTML('beforeend' , `<div>
<div><label><small>打鍵音</small><input id="sound-effect-option" type="checkbox" style="display:none;" ${soundEffectSwitch == false ? "" : "checked"}><div id="sound-effect-btn" style="margin-left:4px;" class="switch_btn"><a class="on_btn btn show">ON</a><a class="off_btn btn" style="display:${soundEffectSwitch == false ? "block" : ""};">OFF</a></div></label></div>
</div>`)

		document.getElementById("sound-effect-option").addEventListener("change" , event => {
			localStorage.setItem("sound-effect-option" , event.target.checked);

			if(event.target.checked){
				document.querySelector("#sound-effect-btn .off_btn").style.display = ""
				soundEffectSwitch = true;
			}else{
				document.querySelector("#sound-effect-btn .off_btn").style.display = "block"
				soundEffectSwitch = false;
			}
		})
		clearInterval(createOptionInterval)
	}
}


const typingAppMod = () => {

const example_container = document.getElementById("example_container") //iframe内の要素を取得


	if(example_container){

let keyJudge = event => {
	setTimeout( () => {
		const sentenceText = document.getElementsByClassName("entered")[enteredClass]
		let judge_key
		if(sentenceText){
			if(typingMode == "roma"){
				judge_key = sentenceText.textContent.slice(-1).toLowerCase() == event.key ? true:false
			}else if(typingMode == "eng"){
				judge_key = sentenceText.textContent.slice(-1).replace("␣", " ") == event.key ? true:false
			}else if(typingMode == "kana"){
let kana_keymap = {
					0: ["わ"],
					1: ["ぬ"],
					"!": ["ぬ"],
					2: ["ふ"],
					3: ["あ"],
					4: ["う"],
					5: ["え"],
					6: ["お"],
					7: ["や"],
					8: ["ゆ"],
					9: ["よ"],
					"-": ["ほ","-"],
					"q": ["た"],
					"Q": ["た"],
					"w": ["て"],
					"W": ["て"],
					"e": ["い"],
					"E": ["い"],
					"r": ["す"],
					"R": ["す"],
					"t": ["か"],
					"T": ["か"],
					"y": ["ん"],
					"Y": ["ん"],
					"u": ["な"],
					"U": ["な"],
					"i": ["に"],
					"I": ["に"],
					"o": ["ら"],
					"O": ["ら"],
					"p": ["せ"],
					"P": ["せ"],
					"a": ["ち"],
					"A": ["ち"],
					"s": ["と"],
					"S": ["と"],
					"d": ["し"],
					"D": ["し"],
					"f": ["は"],
					"F": ["は"],
					"g": ["き"],
					"G": ["き"],
					"h": ["く"],
					"H": ["く"],
					"j": ["ま"],
					"J": ["ま"],
					"k": ["の"],
					"K": ["の"],
					"l": ["り"],
					"L": ["り"],
					"z": ["つ"],
					"Z": ["つ"],
					"x": ["さ"],
					"X": ["さ"],
					"c": ["そ"],
					"C": ["そ"],
					"v": ["ひ"],
					"V": ["ひ"],
					"b": ["こ"],
					"B": ["こ"],
					"n": ["み"],
					"N": ["み"],
					"m": ["も"],
					"M": ["も"],
					",": ["ね",","],
					"<": ["、"],
					".": ["る","."],
					">": ["。"],
					"/": ["め","/"],
					"?": ["・"],
					"#": ["ぁ"],
					"$": ["ぅ"],
					"%": ["ぇ"],
					"'": ["ゃ","’","'"],
					"^": ["へ"],
					"~": ["へ"],
					"&": ["ぉ"],
					"(": ["ゅ"],
					")": ["ょ"],
					'|': ["ー"],
					"_": ["ろ"],
					"=": ["ほ"],
					"+": ["れ"],
					";": ["れ"],
					'"': ["ふ","”","“","\""],
					"@": ["゛"],
					'`': ["゛"],
					"[": ["゜"],
					']': ["む"],
					"{": ["「"],
					'}': ["」"],
					":": ["け"],
					"*": ["け"]
				}
let windows_keymap = {
					'IntlYen': ["ー","¥","\\"],
					"IntlRo": ["ろ","¥","\\"],
					"Space": [" "],
					"Numpad1": [],
					"Numpad2": [],
					"Numpad3": [],
					"Numpad4": [],
					"Numpad5": [],
					"Numpad6": [],
					"Numpad7": [],
					"Numpad8": [],
					"Numpad9": [],
					"Numpad0": [],
					"NumpadDivide": [],
					"NumpadMultiply": [],
					"NumpadSubtract": [],
					"NumpadAdd": [],
					"NumpadDecimal": []
				}
				let char = windows_keymap[event.code] ? windows_keymap[event.code] : kana_keymap[event.key];
				if(event.shiftKey){
					if(event.code == "KeyE"){char[0] = "ぃ";}
					if(event.code == "KeyZ"){char[0] = "っ";}

					//ATOK入力 https://support.justsystems.com/faq/1032/app/servlet/qadoc?QID=024273
					if(event.code == "KeyV"){char.push("ゐ","ヰ")}
					if(event.code == "Equal"){char.push("ゑ","ヱ")}
					if(event.code == "KeyT"){char.push("ヵ")}
					if(event.code == "Quote"){char.push("ヶ")}
					if(event.code == "KeyF"){char.push("ゎ")}
				}
				if(event.shiftKey && event.key === "0"){char = ["を"];}
				judge_key = char.includes(sentenceText.textContent.slice(-1))
			}
		}
		if(event.key == "Escape"){
			wordReload = false
		}
		if(!sentenceText && wordReload){
			clear_type_play()
			wordReload = true
			if(!sentenceText){
				wordReload = false
			}
		}else if(sentenceText && judge_key){
			key_type_play()
			wordReload = true
			if(!sentenceText){
				wordReload = false
			}
		}
	},0)
}
if(soundEffectSwitch){
	document.addEventListener("keydown",keyJudge,false)
}

		clearInterval(typingAppModInterval)
		typingAppModInterval = null
	}

		console.log("searching for example_container")
}





const createEventInTypingApp = (() => {

	// https://www.e-typing.ne.jp/app/jsa_std/typing.asp タイピング画面のiframe URL
	if( location.href.match(/app\/jsa_.*u=&.*/)){

		typingAppModInterval = setInterval(typingAppMod , 50)
		createOptionInterval = setInterval(createOption , 100)

/*
		//タイピング中にEscキーを押したらtypingAppModを実行
		window.addEventListener("keydown", event => {
			// document.getElementById("miss_type_screen") {タイピングワードが表示される要素}
			// document.getElementById("miss_type_screen") 要素が存在する場合のみ即時リトライを適用。(打ち切り時の結果画面等では無効化。)
			if(!typingAppModInterval && event.key == "Escape" && document.getElementById("exampleText") != null && document.getElementById("miss_type_screen") != null){
				typingAppModInterval = setInterval(typingAppMod , 50)
			}
			if(!typingAppModInterval && event.code == "KeyR" && document.getElementById("replay_btn") != null){
				typingAppModInterval = setInterval(typingAppMod , 50)
			}
		},true)

		//打ち切り時にやり直しボタン or ミスだけボタンをクリックしたらtypingAppModを実行
		window.addEventListener("click", event => {

			if(!typingAppModInterval && event.target.id == "replay_btn" || event.target.id == "miss_only_btn"){
				typingAppModInterval = setInterval(typingAppMod , 50)
			}
		},true)
*/
	}

})()