// ==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.1.3 // @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 // @downloadURL none // ==/UserScript==//// Generated by Haxe 3.4.7 (function () { "use strict"; var HxOverrides = function() { }; HxOverrides.__name__ = true; 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.observerTargetSelector = "._1zuqL"; this.ereg = new RegExp("duolingo\\.com/skill|practice"); this.isObserved = false; var _gthis = this; this.document = window.document; this.console = { }; Object.assign(this.console,window.console); this.originalTrace = haxe_Log.trace; haxe_Log.trace = function(v,i) { _gthis.console.log("" + i.className + ":" + i.lineNumber + ":",v); }; this.initLanguages(); if(this.document.readyState == "interactive" || this.document.readyState == "complete") { this.onready(); } else { this.document.addEventListener("DOMContentLoaded",$bind(this,this.onready)); } }; Main.__name__ = true; 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 inited"); window.setInterval($bind(this,this.checkPage),1000); } ,checkPage: function() { var isThatPage = this.ereg.test(window.location.href); if(isThatPage) { if(!this.isObserved) { this.startObserver(); } } if(this.isObserved && (!isThatPage || window.document.querySelector(this.observerTargetSelector) == null)) { this.disconnectObserver(); } } ,startObserver: function(e) { var obsTarget = window.document.querySelector(this.observerTargetSelector); if(obsTarget == null) { this.console.error("There is no Node with selector \"" + this.observerTargetSelector + "\" , so nothing to observe "); return; } this.observer = new MutationObserver($bind(this,this.checkMutation)); this.observer.observe(obsTarget,{ childList : true, subtree : true, attributes : true}); this.isObserved = true; } ,disconnectObserver: function() { this.isObserved = false; if(this.observer == null) { return; } this.observer.disconnect(); } ,checkMutation: function(records,obs) { this.nativeLanguage = "ru"; this.foreignLanguage = "en"; var translationInput = window.document.querySelector("textarea[data-test=challenge-translate-input]"); if(translationInput != null) { var lang = translationInput.getAttribute("lang"); if(lang == this.nativeLanguage) { this.initInput(translationInput,"ru","en"); } else if(lang == this.foreignLanguage) { this.initInput(translationInput,"en","ru"); } return; } var listenInput = window.document.querySelector("textarea[data-test=challenge-listen-input]"); if(listenInput != null) { this.initInput(listenInput,"en","ru"); return; } var nameInput = window.document.querySelector("input[data-test=challenge-name-input]"); if(nameInput != null) { this.initInput(nameInput,"en","ru"); } } ,initInput: function(input,targetLanguage,sourceLanguage) { this.targetLanguage = targetLanguage; this.sourceLanguage = sourceLanguage; input.addEventListener("keypress",$bind(this,this.onInput)); input.addEventListener("keydown",$bind(this,this.refocus)); } ,refocus: function(e) { if(e.keyCode == 13 || e.code == "Enter") { e.currentTarget.blur(); } } ,onInput: function(e) { if(e.ctrlKey) { 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 = e.currentTarget; window.setTimeout($bind(this,this.replaceChar),1,input,targetChar,input.selectionStart); } } ,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); } }; Math.__name__ = true; var Reflect = function() { }; Reflect.__name__ = true; 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 haxe_Log = function() { }; haxe_Log.__name__ = true; haxe_Log.trace = function(v,infos) { js_Boot.__trace(v,infos); }; var js_Boot = function() { }; js_Boot.__name__ = true; js_Boot.__unhtml = function(s) { return s.split("&").join("&").split("<").join("<").split(">").join(">"); }; js_Boot.__trace = function(v,i) { var msg = i != null ? i.fileName + ":" + i.lineNumber + ": " : ""; msg += js_Boot.__string_rec(v,""); if(i != null && i.customParams != null) { var _g = 0; var _g1 = i.customParams; while(_g < _g1.length) { var v1 = _g1[_g]; ++_g; msg += "," + js_Boot.__string_rec(v1,""); } } var d; var tmp; if(typeof(document) != "undefined") { d = document.getElementById("haxe:trace"); tmp = d != null; } else { tmp = false; } if(tmp) { d.innerHTML += js_Boot.__unhtml(msg) + "
"; } else if(typeof console != "undefined" && console.log != null) { console.log(msg); } }; js_Boot.__string_rec = function(o,s) { if(o == null) { return "null"; } if(s.length >= 5) { return "<...>"; } var t = typeof(o); if(t == "function" && (o.__name__ || o.__ename__)) { t = "object"; } switch(t) { case "function": return ""; case "object": if(o instanceof Array) { if(o.__enum__) { if(o.length == 2) { return o[0]; } var str = o[0] + "("; s += "\t"; var _g1 = 2; var _g = o.length; while(_g1 < _g) { var i = _g1++; if(i != 2) { str += "," + js_Boot.__string_rec(o[i],s); } else { str += js_Boot.__string_rec(o[i],s); } } return str + ")"; } var l = o.length; var i1; var str1 = "["; s += "\t"; var _g11 = 0; var _g2 = l; while(_g11 < _g2) { var i2 = _g11++; str1 += (i2 > 0 ? "," : "") + js_Boot.__string_rec(o[i2],s); } str1 += "]"; return str1; } var tostr; try { tostr = o.toString; } catch( e ) { return "???"; } if(tostr != null && tostr != Object.toString && typeof(tostr) == "function") { var s2 = o.toString(); if(s2 != "[object Object]") { return s2; } } var k = null; var str2 = "{\n"; s += "\t"; var hasp = o.hasOwnProperty != null; for( var k in o ) { if(hasp && !o.hasOwnProperty(k)) { continue; } if(k == "prototype" || k == "__class__" || k == "__super__" || k == "__interfaces__" || k == "__properties__") { continue; } if(str2.length != 2) { str2 += ", \n"; } str2 += s + k + " : " + js_Boot.__string_rec(o[k],s); } s = s.substring(1); str2 += "\n" + s + "}"; return str2; case "string": return o; default: return String(o); } }; 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; } String.__name__ = true; Array.__name__ = true; Main.main(); })();