[Japanese] Memrise Kana Detection

Warns you to answer in either Hiragana or Katakana when answering kana-based tests

As of 2017-08-04. See the latest version.

// ==UserScript==
// @name           [Japanese] Memrise Kana Detection
// @description    Warns you to answer in either Hiragana or Katakana when answering kana-based tests
// @author         Kai Krause (kaikrause95@gmail.com)
// @match          http://*.memrise.com/*
// @match          https://*.memrise.com/*
// @version        0.2.4
// @grant          none
// @namespace https://greasyfork.org/users/3656
// ==/UserScript==
// Forked from memrise-forgive-typos by raneksi <https://github.com/raneksi/memrise-forgive-typos>

var onLoad = function($) {
	var get_question = function() {
		return $('.qquestion')[0].childNodes[0].nodeValue.trim();
	};

	var things, thingusers;
	var get_things = function() {
		if (things === undefined) {
			things     = MEMRISE.garden.things;
			thingusers = MEMRISE.garden.thingusers._list;
		}
	};

	var get_thinguser = function(id) {
		return thingusers.filter(function(e) {
			return e.thing_id === id;
		})[0];
	};

	var get_thing_by_q = function(str) {
		get_things();

		for (var id in things) {
			var thing = things[id];
			var thinguser = get_thinguser(thing.id);
			if (thinguser) {
				// Get the 'question' for the current `thing` based on the
				// column_b from `thinguser` for this particular `thing.
				// Compare the `question` with the given question str and if
				// they match, we can pick the current `thing`.
				//
				// Sometimes the 'question' seems to have trailing
				// whitespace, perhaps because they are written by users who
				// may accidentally put spaces in the end
				var question = thing.columns[thinguser.column_b].val;
				if ($.trim(question) === $.trim(str)) {
					return {
						answer   : thing.columns[thinguser.column_a].val,
						question : thing.columns[thinguser.column_b].val
					};
				}
			}
		}
	};

// Majority of the below authored by Kai
	
	var disableKey = function(bool){
		if (bool == true){
			$('input').on('keydown', function(event) {
				if (event.which == 13){
					return false;
				}
			});
		}
		
		else{
			$('input').off('keydown');
		}
	}
	
	var calculateKanaType = function(){
		answerhiragana = false;
		answerkatakana = false;
		$( ".kanaError" ).remove();
		
		for (var i = 0; i < qanswer.length; ++i) {
			//Hiragana check
			if (qanswer.charCodeAt(i) >= 12353 && qanswer.charCodeAt(i) <= 12435 ) {
				answerhiragana = true;
			}
			
			//Katakana check
			else if (qanswer.charCodeAt(i) >= 12443 && qanswer.charCodeAt(i) <= 12532 ) {
				answerkatakana = true;
			}
		}
	}
	
	var compareAnswer = function(){
	givenhiragana = 0;
	givenkatakana = 0;
	givenenglish = 0;
		for (var i = 0; i < given.length; ++i) {
		
		//Calculate user's answer for Kana type
		if (given.length != 0){
				if (given.charCodeAt(i) >= 12353 && given.charCodeAt(i) <= 12435) {
					++givenhiragana;
				}
				
				if (given.charCodeAt(i) >= 12443 && given.charCodeAt(i) <= 12532 ) {
					++givenkatakana;
				}
				
				//Actual English
				if (given.charCodeAt(i) >= 65 && given.charCodeAt(i) <= 122 ) {
					++givenenglish;
				}
				
				//Kana inputted English
				if (given.charCodeAt(i) >= 65346 && given.charCodeAt(i) <= 65370){
					++givenenglish;
				}

			//Compare our two kana types, the expected answer and the user's
			
				if (answerhiragana && answerkatakana){
					if (givenhiragana == 0 || givenkatakana == 0 || givenenglish > 0){
						//Error message
						$( ".kanaError" ).remove();
						$( "body" ).append( "<div class='kanaError' align='center' style='font-weight: bold; font-size:34px; color:#FF0000;'>Hiragana & Katakana!</div>" );
						//Disable the enter key
						disableKey(true);
					}
					
					if (givenhiragana > 0 && givenkatakana > 0 && givenenglish == 0){
						//Remove error message and enable the enter key
						$( ".kanaError" ).remove();
						disableKey(false);
					}
				}
				
				else if (answerhiragana){
					if (givenhiragana == 0 || givenkatakana > 0 || givenenglish > 0){
						//Error message
						$( ".kanaError" ).remove();
						$( "body" ).append( "<div class='kanaError' align='center' style='font-weight: bold; font-size:34px; color:#FF0000;'>Hiragana!</div>" );
						//Disable the enter key
						disableKey(true);
					}
					
					if (givenhiragana > 0 && givenkatakana == 0 && givenenglish == 0){
						//Remove error message and enable the enter key
						$( ".kanaError" ).remove();
						disableKey(false);
					}
				}
				
				else if (answerkatakana){
					if (givenkatakana == 0 || givenhiragana > 0 || givenenglish > 0){
						//Error message
						$( ".kanaError" ).remove();
						$( "body" ).append( "<div class='kanaError' align='center' style='font-weight: bold; font-size:34px; color:#FF0000;'>Katakana!</div>" );
						//Disable the enter key
						disableKey(true);
					}
					
					if (givenkatakana > 0 && givenhiragana == 0 && givenenglish == 0){
						//Remove error message and enable the enter key
						$( ".kanaError" ).remove();
						disableKey(false);
					}
				}	
			}
		}
	}
	
	var questionArray = [];
	var check_answer = function() {
		var q = get_question();
		given    = $('.typing-type-here').val();
		qanswer 	 = get_thing_by_q(q).answer;
		
		//Make sure we don't keep evaluating the type of kana
		if (q != questionArray[1]){
			questionArray[0] = questionArray[1];
			questionArray[1] = q ;
			//window.alert(questionArray)
			calculateKanaType();
		}
		
		compareAnswer();
	};
	
	
	var setup = function() {
		$('body').on('keyup', function(e) {
			check_answer();
		});
	};
	
	setup();
	
};

var injectWithJQ = function(f) {
	var script = document.createElement('script');
	script.textContent = '$(' + f.toString() + '($));';
	document.body.appendChild(script);
};

injectWithJQ(onLoad);