var VKI_attach, VKI_close; (function VKI_buildKeyboardInputs() { var self = this; this.VKI_version = "1.43"; this.VKI_showVersion = false; this.VKI_target = false; this.VKI_shift = this.VKI_shiftlock = false; this.VKI_altgr = this.VKI_altgrlock = false; this.VKI_dead = false; this.VKI_deadBox = false; // Show the dead keys checkbox this.VKI_deadkeysOn = false; // Turn dead keys on by default this.VKI_numberPad = false; // Allow user to open and close the number pad this.VKI_numberPadOn = false; // Show number pad by default this.VKI_kts = this.VKI_kt = "US International"; // Default keyboard layout this.VKI_langAdapt = true; // Use lang attribute of input to select keyboard this.VKI_size = 4; // Default keyboard size (1-5) this.VKI_maxSize = 4; // Default keyboard size (1-5) this.VKI_minSize = 3; // Default keyboard size (1-5) this.VKI_sizeAdj = true; // Allow user to adjust keyboard size this.VKI_clearPasswords = true; // Clear password fields on focus this.VKI_imageURI = "client/skins/default/login/images/keyboard.gif"; // If empty string, use imageless mode this.VKI_clickless = 0; // 0 = disabled, > 0 = delay in ms this.VKI_keyCenter = 3; this.VKI_showLanguages = false; this.VKI_isIE = /*@cc_on!@*/false; this.VKI_isIE6 = /*@if(@_jscript_version == 5.6)!@end@*/false; this.VKI_isIElt8 = /*@if(@_jscript_version < 5.8)!@end@*/false; this.VKI_isWebKit = RegExp("KHTML").test(navigator.userAgent); this.VKI_isOpera = RegExp("Opera").test(navigator.userAgent); this.VKI_isMoz = (!this.VKI_isWebKit && navigator.product == "Gecko"); /* ***** i18n text strings ************************************* */ if (document.getElementById('vk_lang')) { var lang=document.getElementById('vk_lang').value.split('^'); this.VKI_i18n = { '00': lang[0], '01': lang[1], '02': lang[2], '03': lang[3], '04': lang[4], '05': lang[5], '06': lang[6], '07': lang[7], '08': lang[8], '09': lang[9], '10': lang[10], '11': lang[11] }; } else { this.VKI_i18n = { '00': "", '01': "Display virtual keyboard interface", '02': "Select keyboard layout", '03': "Dead keys", '04': "On", '05': "Off", '06': "Close the keyboard", '07': "Clear", '08': "Clear this input", '09': "Version", '10': "Decrease keyboard size", '11': "Increase keyboard size" }; } /* ***** Create keyboards ************************************** */ this.VKI_layout = {}; /**/ this.VKI_layout['US International'] = { 'name': "US International", 'keys': [ [["`", "~"], ["1", "!", "\u00a1", "\u00b9"], ["2", "@", "\u00b2"], ["3", "#", "\u00b3"], ["4", "$", "\u00a4", "\u00a3"], ["5", "%", "\u20ac"], ["6", "^", "\u00bc"], ["7", "&", "\u00bd"], ["8", "*", "\u00be"], ["9", "(", "\u2018"], ["0", ")", "\u2019"], ["-", "_", "\u00a5"], ["=", "+", "\u00d7", "\u00f7"], ["Bksp", "Bksp"]], [["Tab", "Tab"], ["q", "Q", "\u00e4", "\u00c4"], ["w", "W", "\u00e5", "\u00c5"], ["e", "E", "\u00e9", "\u00c9"], ["r", "R", "\u00ae"], ["t", "T", "\u00fe", "\u00de"], ["y", "Y", "\u00fc", "\u00dc"], ["u", "U", "\u00fa", "\u00da"], ["i", "I", "\u00ed", "\u00cd"], ["o", "O", "\u00f3", "\u00d3"], ["p", "P", "\u00f6", "\u00d6"], ["[", "{", "\u00ab"], ["]", "}", "\u00bb"], ["\\", "|", "\u00ac", "\u00a6"]], [["Caps", "Caps"], ["a", "A", "\u00e1", "\u00c1"], ["s", "S", "\u00df", "\u00a7"], ["d", "D", "\u00f0", "\u00d0"], ["f", "F"], ["g", "G"], ["h", "H"], ["j", "J"], ["k", "K"], ["l", "L", "\u00f8", "\u00d8"], [";", ":", "\u00b6", "\u00b0"], ["'", '"', "\u00b4", "\u00a8"], ["Enter", "Enter"]], [["Shift", "Shift"], ["z", "Z", "\u00e6", "\u00c6"], ["x", "X"], ["c", "C", "\u00a9", "\u00a2"], ["v", "V"], ["b", "B"], ["n", "N", "\u00f1", "\u00d1"], ["m", "M", "\u00b5"], [",", "<", "\u00e7", "\u00c7"], [".", ">"], ["/", "?", "\u00bf"], ["Shift", "Shift"]], [[" ", " ", " ", " "], ["Alt", "Alt"]] ], 'lang': ["en"] }; /* this.VKI_layout['Login'] = { 'name': "US International", 'keys': [ [["", ""], ["1", "", "", ""], ["2", "", ""], ["3", "", ""], ["4", "", "", ""], ["5", "", ""], ["6", "", ""], ["7", "", ""], ["8", "", ""], ["9", "", ""], ["0", "", ""], ["-", "_", ""], ["", "", "", ""], ["Bksp", "Bksp"]], [["Tab", "Tab"], ["q", "Q", "", ""], ["w", "W", "", ""], ["e", "E", "", ""], ["r", "R", ""], ["t", "T", "", ""], ["y", "Y", "", ""], ["u", "U", "", ""], ["i", "I", "", ""], ["o", "O", "", ""], ["p", "P", "", ""], ["", "", ""], ["", "", ""], ["", "|", "", ""]], [["Caps", "Caps"], ["a", "A", "", ""], ["s", "S", "", ""], ["d", "D", "", ""], ["f", "F"], ["g", "G"], ["h", "H"], ["j", "J"], ["k", "K"], ["l", "L", "", ""], ["", ":", "", ""], ["", '', "", ""], ["Enter", "Enter"]], [["Shift", "Shift"], ["z", "Z", "", ""], ["x", "X"], ["c", "C", "", ""], ["v", "V"], ["b", "B"], ["n", "N", "", ""], ["m", "M", ""], ["", "", "", ""], [".", ""], ["", "", ""], ["Shift", "Shift"]], [[" ", " ", " ", " "], ["Alt", "Alt"]] ], 'lang': ["en"] }; */ /* ***** Define Dead Keys ************************************** */ this.VKI_deadkey = {}; // - Lay out each dead key set as an object of property/value // pairs. The rows below are wrapped so uppercase letters are // below their lowercase equivalents. // // - The property name is the letter pressed after the diacritic. // The property value is the letter this key-combo will generate. // // - Note that if you have created a new keyboard layout and want // it included in the distributed script, PLEASE TELL ME if you // have added additional dead keys to the ones below. /* ***** Define Symbols **************************************** */ this.VKI_symbol = { '\u00a0': "NB\nSP", '\u200b': "ZW\nSP", '\u200c': "ZW\nNJ", '\u200d': "ZW\nJ" }; /* ***** Layout Number Pad ************************************* */ this.VKI_numpad = [ [["$"], ["\u00a3"], ["\u20ac"], ["\u00a5"]], [["7"], ["8"], ["9"], ["/"]], [["4"], ["5"], ["6"], ["*"]], [["1"], ["2"], ["3"], ["-"]], [["0"], ["."], ["="], ["+"]] ]; /* **************************************************************** * Attach the keyboard to an element * */ this.VKI_attachKeyboard = VKI_attach = function(elem) { if (elem.getAttribute("VKI_attached")) return false; if (this.VKI_imageURI) { var keybut = document.createElement('img'); keybut.src = this.VKI_imageURI; keybut.alt = this.VKI_i18n['00']; keybut.className = "keyboardInputInitiator kb_for_"+elem.id; keybut.title = this.VKI_i18n['01']; keybut.elem = elem; keybut.onclick = function(e) { e = e || event; if (e.stopPropagation) { e.stopPropagation(); } else e.cancelBubble = true; self.VKI_show(this.elem); }; elem.parentNode.insertBefore(keybut, (elem.dir == "rtl") ? elem : elem.nextSibling); } else elem.onfocus = function() { if (self.VKI_target != this) self.VKI_show(this); }; elem.setAttribute("VKI_attached", 'true'); if (this.VKI_isIE) { elem.onclick = elem.onselect = elem.onkeyup = function(e) { if ((e || event).type != "keyup" || !this.readOnly) this.range = document.selection.createRange(); }; } VKI_addListener(elem, 'click', function(e) { if (self.VKI_target == this) { e = e || event; if (e.stopPropagation) { e.stopPropagation(); } else e.cancelBubble = true; } return false; }, false); }; /* ***** Find tagged input & textarea elements ***************** */ var inputElems = [ document.getElementsByTagName('input'), document.getElementsByTagName('textarea') ]; for (var x = 0, elem; elem = inputElems[x++];) for (var y = 0, ex; ex = elem[y++];) if ((ex.nodeName == "TEXTAREA" || ex.type == "text" || ex.type == "password") && ex.className.indexOf("keyboardInput") > -1) this.VKI_attachKeyboard(ex); VKI_addListener(document.documentElement, 'click', function(e) { self.VKI_close(); }, false); /* **************************************************************** * Common mouse event actions * */ function VKI_mouseEvents(elem) { if (elem.nodeName == "TD") { if (!elem.click) elem.click = function() { var evt = this.ownerDocument.createEvent('MouseEvents'); evt.initMouseEvent('click', true, true, this.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null); this.dispatchEvent(evt); }; elem.VKI_clickless = 0; VKI_addListener(elem, 'dblclick', function() { return false; }, false); } VKI_addListener(elem, 'mouseover', function() { if (this.nodeName == "TD" && self.VKI_clickless) { var _self = this; clearTimeout(this.VKI_clickless); this.VKI_clickless = setTimeout(function() { _self.click(); }, self.VKI_clickless); } if (self.VKI_isIE) this.className += " hover"; }, false); VKI_addListener(elem, 'mouseout', function() { if (this.nodeName == "TD") clearTimeout(this.VKI_clickless); if (self.VKI_isIE) this.className = this.className.replace(/ ?(hover|pressed) ?/g, ""); }, false); VKI_addListener(elem, 'mousedown', function() { if (this.nodeName == "TD") clearTimeout(this.VKI_clickless); if (self.VKI_isIE) this.className += " pressed"; }, false); VKI_addListener(elem, 'mouseup', function() { if (this.nodeName == "TD") clearTimeout(this.VKI_clickless); if (self.VKI_isIE) this.className = this.className.replace(/ ?pressed ?/g, ""); }, false); } /* ***** Build the keyboard interface ************************** */ this.VKI_keyboard = document.createElement('table'); this.VKI_keyboard.id = "keyboardInputMaster"; this.VKI_keyboard.dir = "ltr"; this.VKI_keyboard.cellSpacing = "0"; this.VKI_keyboard.reflow = function() { this.style.width = "50px"; var foo = this.offsetWidth; this.style.width = ""; }; VKI_addListener(this.VKI_keyboard, 'click', function(e) { e = e || event; if (e.stopPropagation) { e.stopPropagation(); } else e.cancelBubble = true; return false; }, false); if (!this.VKI_layout[this.VKI_kt]) return alert('No keyboard named "' + this.VKI_kt + '"'); var thead = document.createElement('thead'); var tr = document.createElement('tr'); var th = document.createElement('th'); th.colSpan = "2"; var kbSelect = document.createElement('div'); kbSelect.title = this.VKI_i18n['02']; if (!this.VKI_showLanguages) { kbSelect.style.display='none'; } VKI_addListener(kbSelect, 'click', function() { var ol = this.getElementsByTagName('ol')[0]; if (!ol.style.display) { ol.style.display = "block"; var li = ol.getElementsByTagName('li'); for (var x = 0, scr = 0; x < li.length; x++) { if (VKI_kt == li[x].firstChild.nodeValue) { li[x].className = "selected"; scr = li[x].offsetTop - li[x].offsetHeight * 2; } else li[x].className = ""; } setTimeout(function() { ol.scrollTop = scr; }, 0); } else ol.style.display = ""; }, false); kbSelect.appendChild(document.createTextNode(this.VKI_kt)); kbSelect.appendChild(document.createTextNode(this.VKI_isIE6 ? " \u2193" : " \u25be")); var ol = document.createElement('ol'); for (ktype in this.VKI_layout) { if (typeof this.VKI_layout[ktype] == "object") { if (!this.VKI_layout[ktype].lang) this.VKI_layout[ktype].lang = []; var li = document.createElement('li'); li.title = this.VKI_layout[ktype].name; VKI_addListener(li, 'click', function(e) { e = e || event; if (e.stopPropagation) { e.stopPropagation(); } else e.cancelBubble = true; this.parentNode.style.display = ""; self.VKI_kts = self.VKI_kt = kbSelect.firstChild.nodeValue = this.firstChild.nodeValue; self.VKI_buildKeys(); self.VKI_position(true); }, false); VKI_mouseEvents(li); li.appendChild(document.createTextNode(ktype)); ol.appendChild(li); } } kbSelect.appendChild(ol); th.appendChild(kbSelect); if (this.VKI_numberPad) { var span = document.createElement('span'); span.appendChild(document.createTextNode("#")); span.title = this.VKI_i18n['00']; VKI_addListener(span, 'click', function() { kbNumpad.style.display = (!kbNumpad.style.display) ? "none" : ""; self.VKI_position(true); }, false); VKI_mouseEvents(span); th.appendChild(span); } this.VKI_kbsize = function(e) { self.VKI_size = Math.min(self.VKI_maxSize, Math.max(self.VKI_minSize, self.VKI_size)); self.VKI_keyboard.className = self.VKI_keyboard.className.replace(/ ?keyboardInputSize\d ?/, ""); if (self.VKI_size != 2) self.VKI_keyboard.className += " keyboardInputSize" + self.VKI_size; self.VKI_position(true); if (self.VKI_isOpera) self.VKI_keyboard.reflow(); }; if (this.VKI_sizeAdj) { var small = document.createElement('small'); small.title = this.VKI_i18n['10']; VKI_addListener(small, 'click', function() { --self.VKI_size; self.VKI_kbsize(); }, false); VKI_mouseEvents(small); small.appendChild(document.createTextNode(this.VKI_isIE6 ? "\u2193" : "\u21d3")); th.appendChild(small); var big = document.createElement('big'); big.title = this.VKI_i18n['11']; VKI_addListener(big, 'click', function() { ++self.VKI_size; self.VKI_kbsize(); }, false); VKI_mouseEvents(big); big.appendChild(document.createTextNode(this.VKI_isIE6 ? "\u2191" : "\u21d1")); th.appendChild(big); } var span = document.createElement('span'); span.appendChild(document.createTextNode(this.VKI_i18n['07'])); span.title = this.VKI_i18n['08']; VKI_addListener(span, 'click', function() { self.VKI_target.value = ""; self.VKI_target.focus(); return false; }, false); VKI_mouseEvents(span); th.appendChild(span); var strong = document.createElement('strong'); strong.appendChild(document.createTextNode('X')); strong.title = this.VKI_i18n['06']; VKI_addListener(strong, 'click', function() { self.VKI_close(); }, false); VKI_mouseEvents(strong); th.appendChild(strong); tr.appendChild(th); thead.appendChild(tr); this.VKI_keyboard.appendChild(thead); var tbody = document.createElement('tbody'); var tr = document.createElement('tr'); var td = document.createElement('td'); var div = document.createElement('div'); if (this.VKI_deadBox) { var label = document.createElement('label'); var checkbox = document.createElement('input'); checkbox.type = "checkbox"; checkbox.title = this.VKI_i18n['03'] + ": " + ((this.VKI_deadkeysOn) ? this.VKI_i18n['04'] : this.VKI_i18n['05']); checkbox.defaultChecked = this.VKI_deadkeysOn; VKI_addListener(checkbox, 'click', function() { this.title = self.VKI_i18n['03'] + ": " + ((this.checked) ? self.VKI_i18n['04'] : self.VKI_i18n['05']); self.VKI_modify(""); return true; }, false); label.appendChild(checkbox); checkbox.checked = this.VKI_deadkeysOn; div.appendChild(label); this.VKI_deadkeysOn = checkbox; } else this.VKI_deadkeysOn.checked = this.VKI_deadkeysOn; if (this.VKI_showVersion) { var vr = document.createElement('var'); vr.title = this.VKI_i18n['09'] + " " + this.VKI_version; vr.appendChild(document.createTextNode("v" + this.VKI_version)); div.appendChild(vr); } td.appendChild(div); tr.appendChild(td); var kbNumpad = document.createElement('td'); kbNumpad.id = "keyboardInputNumpad"; if (!this.VKI_numberPadOn) kbNumpad.style.display = "none"; var ntable = document.createElement('table'); ntable.cellSpacing = "0"; var ntbody = document.createElement('tbody'); for (var x = 0; x < this.VKI_numpad.length; x++) { var ntr = document.createElement('tr'); for (var y = 0; y < this.VKI_numpad[x].length; y++) { var ntd = document.createElement('td'); VKI_addListener(ntd, 'click', VKI_keyClick, false); VKI_mouseEvents(ntd); ntd.appendChild(document.createTextNode(this.VKI_numpad[x][y])); ntr.appendChild(ntd); } ntbody.appendChild(ntr); } ntable.appendChild(ntbody); kbNumpad.appendChild(ntable); tr.appendChild(kbNumpad); tbody.appendChild(tr); this.VKI_keyboard.appendChild(tbody); if (this.VKI_isIE6) { this.VKI_iframe = document.createElement('iframe'); this.VKI_iframe.style.position = "absolute"; this.VKI_iframe.style.border = "0px none"; this.VKI_iframe.style.filter = "mask()"; this.VKI_iframe.style.zIndex = "999999"; this.VKI_iframe.src = this.VKI_imageURI; } /* **************************************************************** * Private table cell attachment function for generic characters * */ function VKI_keyClick() { var done = false, character = "\xa0"; if (this.firstChild.nodeName.toLowerCase() != "small") { if ((character = this.firstChild.nodeValue) == "\xa0") return false; } else character = this.firstChild.getAttribute('char'); if (self.VKI_deadkeysOn.checked && self.VKI_dead) { if (self.VKI_dead != character) { if (character != " ") { if (self.VKI_deadkey[self.VKI_dead][character]) { self.VKI_insert(self.VKI_deadkey[self.VKI_dead][character]); done = true; } } else { self.VKI_insert(self.VKI_dead); done = true; } } else done = true; } self.VKI_dead = false; if (!done) { if (self.VKI_deadkeysOn.checked && self.VKI_deadkey[character]) { self.VKI_dead = character; this.className += " dead"; if (self.VKI_shift) self.VKI_modify("Shift"); if (self.VKI_altgr) self.VKI_modify("AltGr"); } else self.VKI_insert(character); } self.VKI_modify(""); return false; } /* **************************************************************** * Build or rebuild the keyboard keys * */ this.VKI_buildKeys = function() { this.VKI_shift = this.VKI_shiftlock = this.VKI_altgr = this.VKI_altgrlock = this.VKI_dead = false; var container = this.VKI_keyboard.tBodies[0].getElementsByTagName('div')[0]; var tables = container.getElementsByTagName('table'); for (var x = tables.length - 1; x >= 0; x--) container.removeChild(tables[x]); for (var x = 0, hasDeadKey = false, lyt; lyt = this.VKI_layout[this.VKI_kt].keys[x++];) { var table = document.createElement('table'); table.cellSpacing = "0"; if (lyt.length <= this.VKI_keyCenter) table.className = "keyboardInputCenter"; var tbody = document.createElement('tbody'); var tr = document.createElement('tr'); for (var y = 0, lkey; lkey = lyt[y++];) { var td = document.createElement('td'); if (this.VKI_symbol[lkey[0]]) { var text = this.VKI_symbol[lkey[0]].split("\n"); var small = document.createElement('small'); small.setAttribute('char', lkey[0]); for (var z = 0; z < text.length; z++) { if (z) small.appendChild(document.createElement("br")); small.appendChild(document.createTextNode(text[z])); } td.appendChild(small); } else td.appendChild(document.createTextNode(lkey[0] || "\xa0")); var className = []; if (this.VKI_deadkeysOn.checked) for (key in this.VKI_deadkey) if (key === lkey[0]) { className.push("deadkey"); break; } if (lyt.length > this.VKI_keyCenter && y == lyt.length) className.push("last"); if (lkey[0] == " " || lkey[1] == " ") className.push("space"); td.className = className.join(" "); switch (lkey[1]) { case "Caps": case "Shift": case "Alt": case "AltGr": case "AltLk": VKI_addListener(td, 'click', (function(type) { return function() { self.VKI_modify(type); return false; }})(lkey[1]), false); break; case "Tab": VKI_addListener(td, 'click', function() { self.VKI_insert("\t"); return false; }, false); break; case "Bksp": VKI_addListener(td, 'click', function() { self.VKI_target.focus(); if (self.VKI_target.setSelectionRange && !self.VKI_target.readOnly) { var rng = [self.VKI_target.selectionStart, self.VKI_target.selectionEnd]; if (rng[0] < rng[1]) rng[0]++; self.VKI_target.value = self.VKI_target.value.substr(0, rng[0] - 1) + self.VKI_target.value.substr(rng[1]); self.VKI_target.setSelectionRange(rng[0] - 1, rng[0] - 1); } else if (self.VKI_target.createTextRange && !self.VKI_target.readOnly) { try { self.VKI_target.range.select(); } catch(e) { self.VKI_target.range = document.selection.createRange(); } if (!self.VKI_target.range.text.length) self.VKI_target.range.moveStart('character', -1); self.VKI_target.range.text = ""; } else self.VKI_target.value = self.VKI_target.value.substr(0, self.VKI_target.value.length - 1); if (self.VKI_shift) self.VKI_modify("Shift"); if (self.VKI_altgr) self.VKI_modify("AltGr"); self.VKI_target.focus(); return true; }, false); break; case "Enter": VKI_addListener(td, 'click', function() { if (self.VKI_target.nodeName != "TEXTAREA") { if (self.VKI_target.form) { for (var z = 0, subm = false; z < self.VKI_target.form.elements.length; z++) if (self.VKI_target.form.elements[z].type == "submit") subm = true; if (!subm) self.VKI_target.form.submit(); } self.VKI_close(); } else self.VKI_insert("\n"); return true; }, false); break; default: VKI_addListener(td, 'click', VKI_keyClick, false); } VKI_mouseEvents(td); tr.appendChild(td); for (var z = 0; z < 4; z++) if (this.VKI_deadkey[lkey[z] = lkey[z] || ""]) hasDeadKey = true; } tbody.appendChild(tr); table.appendChild(tbody); container.appendChild(table); } if (this.VKI_deadBox) this.VKI_deadkeysOn.style.display = (hasDeadKey) ? "inline" : "none"; if (this.VKI_isIE6) { this.VKI_iframe.style.width = this.VKI_keyboard.offsetWidth + "px"; this.VKI_iframe.style.height = this.VKI_keyboard.offsetHeight + "px"; } }; this.VKI_buildKeys(); VKI_addListener(this.VKI_keyboard, 'selectstart', function() { return false; }, false); this.VKI_keyboard.unselectable = "on"; if (this.VKI_isOpera) VKI_addListener(this.VKI_keyboard, 'mousedown', function() { return false; }, false); /* **************************************************************** * Controls modifier keys * */ this.VKI_modify = function(type) { switch (type) { case "Alt": case "AltGr": this.VKI_altgr = !this.VKI_altgr; break; case "AltLk": this.VKI_altgr = 0; this.VKI_altgrlock = !this.VKI_altgrlock; break; case "Caps": this.VKI_shift = 0; this.VKI_shiftlock = !this.VKI_shiftlock; break; case "Shift": this.VKI_shift = !this.VKI_shift; break; } var vchar = 0; if (!this.VKI_shift != !this.VKI_shiftlock) vchar += 1; if (!this.VKI_altgr != !this.VKI_altgrlock) vchar += 2; var tables = this.VKI_keyboard.tBodies[0].getElementsByTagName('div')[0].getElementsByTagName('table'); for (var x = 0; x < tables.length; x++) { var tds = tables[x].getElementsByTagName('td'); for (var y = 0; y < tds.length; y++) { var className = [], lkey = this.VKI_layout[this.VKI_kt].keys[x][y]; switch (lkey[1]) { case "Alt": case "AltGr": if (this.VKI_altgr) className.push("pressed"); break; case "AltLk": if (this.VKI_altgrlock) className.push("pressed"); break; case "Shift": if (this.VKI_shift) className.push("pressed"); break; case "Caps": if (this.VKI_shiftlock) className.push("pressed"); break; case "Tab": case "Enter": case "Bksp": break; default: if (type) { tds[y].removeChild(tds[y].firstChild); if (this.VKI_symbol[lkey[vchar]]) { var text = this.VKI_symbol[lkey[vchar]].split("\n"); var small = document.createElement('small'); small.setAttribute('char', lkey[vchar]); for (var z = 0; z < text.length; z++) { if (z) small.appendChild(document.createElement("br")); small.appendChild(document.createTextNode(text[z])); } tds[y].appendChild(small); } else tds[y].appendChild(document.createTextNode(lkey[vchar] || "\xa0")); } if (this.VKI_deadkeysOn.checked) { var character = tds[y].firstChild.nodeValue || tds[y].firstChild.className; if (this.VKI_dead) { if (character == this.VKI_dead) className.push("pressed"); if (this.VKI_deadkey[this.VKI_dead][character]) className.push("target"); } if (this.VKI_deadkey[character]) className.push("deadkey"); } } if (y == tds.length - 1 && tds.length > this.VKI_keyCenter) className.push("last"); if (lkey[0] == " " || lkey[1] == " ") className.push("space"); tds[y].className = className.join(" "); } } }; /* **************************************************************** * Insert text at the cursor * */ this.VKI_insert = function(text) { this.VKI_target.focus(); if (this.VKI_target.maxLength) this.VKI_target.maxlength = this.VKI_target.maxLength; if (typeof this.VKI_target.maxlength == "undefined" || this.VKI_target.maxlength < 0 || this.VKI_target.value.length < this.VKI_target.maxlength) { if (this.VKI_target.setSelectionRange && !this.VKI_target.readOnly) { var rng = [this.VKI_target.selectionStart, this.VKI_target.selectionEnd]; this.VKI_target.value = this.VKI_target.value.substr(0, rng[0]) + text + this.VKI_target.value.substr(rng[1]); if (text == "\n" && this.VKI_isOpera) rng[0]++; this.VKI_target.setSelectionRange(rng[0] + text.length, rng[0] + text.length); } else if (this.VKI_target.createTextRange && !this.VKI_target.readOnly) { try { this.VKI_target.range.select(); } catch(e) { this.VKI_target.range = document.selection.createRange(); } this.VKI_target.range.text = text; this.VKI_target.range.collapse(true); this.VKI_target.range.select(); } else this.VKI_target.value += text; if (this.VKI_shift) this.VKI_modify("Shift"); if (this.VKI_altgr) this.VKI_modify("AltGr"); this.VKI_target.focus(); } else if (this.VKI_target.createTextRange && this.VKI_target.range) this.VKI_target.range.select(); }; /* **************************************************************** * Show the keyboard interface * */ this.VKI_show = function(elem) { if (!this.VKI_target) { this.VKI_target = elem; if (this.VKI_langAdapt && this.VKI_target.lang) { var chg = false, sub = []; for (ktype in this.VKI_layout) { if (typeof this.VKI_layout[ktype] == "object") { for (var x = 0; x < this.VKI_layout[ktype].lang.length; x++) { if (this.VKI_layout[ktype].lang[x].toLowerCase() == this.VKI_target.lang.toLowerCase()) { chg = kbSelect.firstChild.nodeValue = this.VKI_kt = ktype; break; } else if (this.VKI_layout[ktype].lang[x].toLowerCase().indexOf(this.VKI_target.lang.toLowerCase()) == 0) sub.push([this.VKI_layout[ktype].lang[x], ktype]); } } if (chg) break; } if (sub.length) { sub.sort(function (a, b) { return a[0].length - b[0].length; }); chg = kbSelect.firstChild.nodeValue = this.VKI_kt = sub[0][1]; } if (chg) this.VKI_buildKeys(); } if (this.VKI_isIE) { if (!this.VKI_target.range) { this.VKI_target.range = this.VKI_target.createTextRange(); this.VKI_target.range.moveStart('character', this.VKI_target.value.length); } this.VKI_target.range.select(); } try { this.VKI_keyboard.parentNode.removeChild(this.VKI_keyboard); } catch (e) {} if (this.VKI_clearPasswords && this.VKI_target.type == "password") this.VKI_target.value = ""; var elem = this.VKI_target; this.VKI_target.keyboardPosition = "absolute"; do { if (VKI_getStyle(elem, "position") == "fixed") { this.VKI_target.keyboardPosition = "fixed"; break; } } while (elem = elem.offsetParent); if (this.VKI_isIE6) document.body.appendChild(this.VKI_iframe); document.body.appendChild(this.VKI_keyboard); this.VKI_keyboard.style.position = this.VKI_target.keyboardPosition; if (this.VKI_isOpera) this.VKI_keyboard.reflow(); this.VKI_position(true); if (self.VKI_isMoz || self.VKI_isWebKit) this.VKI_position(true); this.VKI_target.blur(); this.VKI_target.focus(); } else this.VKI_close(); }; /* **************************************************************** * Position the keyboard * */ this.VKI_position = function(force) { if (self.VKI_target) { var kPos = VKI_findPos(self.VKI_keyboard), wDim = VKI_innerDimensions(), sDis = VKI_scrollDist(); var place = false, fudge = self.VKI_target.offsetHeight + 3; if (force !== true) { if (kPos[1] + self.VKI_keyboard.offsetHeight - sDis[1] - wDim[1] > 0) { place = true; fudge = -self.VKI_keyboard.offsetHeight - 3; } else if (kPos[1] - sDis[1] < 0) place = true; } if (place || force === true) { var iPos = VKI_findPos(self.VKI_target); self.VKI_keyboard.style.top = iPos[1] - ((self.VKI_target.keyboardPosition == "fixed" && !self.VKI_isIE && !self.VKI_isMoz) ? sDis[1] : 0) + fudge + "px"; self.VKI_keyboard.style.left = Math.max(10, Math.min(wDim[0] - self.VKI_keyboard.offsetWidth - 25, iPos[0])) + "px"; if (self.VKI_isIE6) { self.VKI_iframe.style.width = self.VKI_keyboard.offsetWidth + "px"; self.VKI_iframe.style.height = self.VKI_keyboard.offsetHeight + "px"; self.VKI_iframe.style.top = self.VKI_keyboard.style.top; self.VKI_iframe.style.left = self.VKI_keyboard.style.left; } } if (force === true) self.VKI_position(); } }; /* **************************************************************** * Close the keyboard interface * */ this.VKI_close = VKI_close = function() { if (this.VKI_target) { try { this.VKI_keyboard.parentNode.removeChild(this.VKI_keyboard); if (this.VKI_isIE6) this.VKI_iframe.parentNode.removeChild(this.VKI_iframe); } catch (e) {} if (this.VKI_kt != this.VKI_kts) { kbSelect.firstChild.nodeValue = this.VKI_kt = this.VKI_kts; this.VKI_buildKeys(); } kbSelect.getElementsByTagName('ol')[0].style.display = "";; this.VKI_target.focus(); if (this.VKI_isIE) { setTimeout(function() { self.VKI_target = false; }, 0); } else this.VKI_target = false; } }; /* ***** Private functions *************************************** */ function VKI_addListener(elem, type, func, cap) { if (elem.addEventListener) { elem.addEventListener(type, function(e) { func.call(elem, e); }, cap); } else if (elem.attachEvent) elem.attachEvent('on' + type, function() { func.call(elem); }); } function VKI_findPos(obj) { var curleft = curtop = 0; do { curleft += obj.offsetLeft; curtop += obj.offsetTop; } while (obj = obj.offsetParent); return [curleft, curtop]; } function VKI_innerDimensions() { if (self.innerHeight) { return [self.innerWidth, self.innerHeight]; } else if (document.documentElement && document.documentElement.clientHeight) { return [document.documentElement.clientWidth, document.documentElement.clientHeight]; } else if (document.body) return [document.body.clientWidth, document.body.clientHeight]; return [0, 0]; } function VKI_scrollDist() { var html = document.getElementsByTagName('html')[0]; if (html.scrollTop && document.documentElement.scrollTop) { return [html.scrollLeft, html.scrollTop]; } else if (html.scrollTop || document.documentElement.scrollTop) { return [html.scrollLeft + document.documentElement.scrollLeft, html.scrollTop + document.documentElement.scrollTop]; } else if (document.body.scrollTop) return [document.body.scrollLeft, document.body.scrollTop]; return [0, 0]; } function VKI_getStyle(obj, styleProp) { if (obj.currentStyle) { var y = obj.currentStyle[styleProp]; } else if (window.getComputedStyle) var y = window.getComputedStyle(obj, null)[styleProp]; return y; } VKI_addListener(window, 'resize', this.VKI_position, false); VKI_addListener(window, 'scroll', this.VKI_position, false); this.VKI_kbsize(); VKI_addListener(window, 'load', VKI_buildKeyboardInputs, false); })();