Greasy Fork 还支持 简体中文。

Duolingo input language switcher

This script allows you to type letters appropriate for current task without changing keyboard's layout

Fra 23.06.2018. Se den seneste versjonen.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name Duolingo input language switcher
// @namespace https://www.duolingo.com/IVrL9
// @author T1mL3arn
// @match https://www.duolingo.com/*
// @match https://www.example.com/*
// @match https://example.com/*
// @version 1.4
// @description This script allows you to type letters appropriate for current task without changing keyboard's layout
// @run-at document-start
// @grant none
// @license GPLv3
// @homepageURL https://github.com/T1mL3arn/Duolingo-input-language-switcher
// @supportURL https://greasyfork.org/en/scripts/37693-duolingo-input-language-switcher/feedback
// ==/UserScript==/// Generated by Haxe 3.4.7
(function () { "use strict";
var HxOverrides = function() { };
HxOverrides.substr = function(s,pos,len) {
	if(len == null) {
		len = s.length;
	} else if(len < 0) {
		if(pos == 0) {
			len = s.length + len;
		} else {
			return "";
		}
	}
	return s.substr(pos,len);
};
var Main = function() {
	this.document = window.document;
	this.console = { };
	this.initLanguages();
	if(this.document.readyState == "interactive" || this.document.readyState == "complete") {
		this.onready();
	} else {
		this.document.addEventListener("DOMContentLoaded",$bind(this,this.onready));
	}
};
Main.main = function() {
	new Main();
};
Main.prototype = {
	initLanguages: function() {
		this.keyCodes = ["Backquote","Digit1","Digit2","Digit3","Digit4","Digit5","Digit6","Digit7","Digit8","Digit9","Digit0","Minus","Equal","Backslash","KeyQ","KeyW","KeyE","KeyR","KeyT","KeyY","KeyU","KeyI","KeyO","KeyP","BracketLeft","BracketRight","KeyA","KeyS","KeyD","KeyF","KeyG","KeyH","KeyJ","KeyK","KeyL","Semicolon","Quote","KeyZ","KeyX","KeyC","KeyV","KeyB","KeyN","KeyM","Comma","Period","Slash"];
		this.languages = { };
		this.languages.ru = "ё1234567890-=\\йцукенгшщзхъфывапролджэячсмитьбю.Ё!\"№;%:?*()_+/ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,";
		this.languages.en = "`1234567890-=\\qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+|QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?";
		var len = this.languages.ru.length;
		var _g = 0;
		var _g1 = Reflect.fields(this.languages);
		while(_g < _g1.length) {
			var f = _g1[_g];
			++_g;
			var act = this.languages[f].length;
			if(act != len) {
				this.console.error("LangString test failed: expected len " + len + "; actual len " + act + "; lang name " + f);
				this.console.error(this.languages[f]);
				return;
			}
			if(act != this.keyCodes.length * 2) {
				this.console.error("KeyCodes and LangString test failed: expected lang string len " + this.keyCodes.length * 2 + "; actual len " + act + "; lang name " + f);
				return;
			}
		}
	}
	,onready: function(e) {
		this.document.removeEventListener("DOMContentLoaded",$bind(this,this.onready));
		this.console.log("Duolingo input switcher is ready");
		window.document.body.addEventListener("keypress",$bind(this,this.onKeyPress));
		window.document.body.addEventListener("keydown",$bind(this,this.refocus));
	}
	,onKeyPress: function(e) {
		if(e.ctrlKey) {
			return;
		}
		var sourceElt = e.target;
		if(this.isInput(sourceElt)) {
			var challengeType = sourceElt.dataset.test;
			switch(challengeType) {
			case "challenge-listen-input":case "challenge-listentap-input":case "challenge-name-input":
				this.setLanguagePair("en","ru");
				break;
			case "challenge-translate-input":
				this.nativeLanguage = "ru";
				this.foreignLanguage = "en";
				var lang = sourceElt.getAttribute("lang");
				if(lang == this.nativeLanguage) {
					this.setLanguagePair("ru","en");
				} else if(lang == this.foreignLanguage) {
					this.setLanguagePair("en","ru");
				}
				break;
			default:
				return;
			}
			var targetLangStr = this.languages[this.targetLanguage];
			var keyCodeInd = this.keyCodes.indexOf(e.code);
			if(keyCodeInd != -1) {
				var targetChar = e.shiftKey ? targetLangStr.charAt(keyCodeInd + this.keyCodes.length) : targetLangStr.charAt(keyCodeInd);
				var input = sourceElt;
				window.setTimeout($bind(this,this.replaceChar),1,input,targetChar,input.selectionStart);
			}
		}
	}
	,isInput: function(elt) {
		if(elt.tagName != "TEXTAREA") {
			if(elt.tagName == "INPUT") {
				return elt.getAttribute("type") == "text";
			} else {
				return false;
			}
		} else {
			return true;
		}
	}
	,setLanguagePair: function(target,source) {
		this.targetLanguage = target;
		this.sourceLanguage = source;
	}
	,refocus: function(e) {
		if(this.isInput(e.target)) {
			if(e.keyCode == 13 || e.code == "Enter") {
				e.target.blur();
			}
		}
	}
	,replaceChar: function(target,newChar,position) {
		var val = target.value;
		val = val.substring(0,position) + newChar + HxOverrides.substr(val,position + 1,null);
		target.innerText = val;
		target.value = val;
		target.setSelectionRange(position + 1,position + 1);
	}
};
var Reflect = function() { };
Reflect.fields = function(o) {
	var a = [];
	if(o != null) {
		var hasOwnProperty = Object.prototype.hasOwnProperty;
		for( var f in o ) {
		if(f != "__id__" && f != "hx__closures__" && hasOwnProperty.call(o,f)) {
			a.push(f);
		}
		}
	}
	return a;
};
var $_, $fid = 0;
function $bind(o,m) { if( m == null ) return null; if( m.__id__ == null ) m.__id__ = $fid++; var f; if( o.hx__closures__ == null ) o.hx__closures__ = {}; else f = o.hx__closures__[m.__id__]; if( f == null ) { f = function(){ return f.method.apply(f.scope, arguments); }; f.scope = o; f.method = m; o.hx__closures__[m.__id__] = f; } return f; }
Main.main();
})();