/*** This file is dynamically generated *** █████▄ ▄████▄ █████▄ ▄████▄ ██████ ███████▄ ▄████▄ █████▄ ██ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██▀▀ ▀▀▀▀██ █████▀ ▀████▀ ██ ██ ▀████▀ ██ ██ ██ ██ ▀████▀ █████▀ ██ ██ █████▀ */ /*! jQuery UI Virtual Keyboard - ALL Extensions + Mousewheel */ /*! jQuery UI Virtual Keyboard Alt Key Popup v1.0.1 *//* * for Keyboard v1.18+ only (7/7/2015) * * By Rob Garrison (aka Mottie) * Licensed under the MIT License * */ /*jshint browser:true, jquery:true, unused:false */ /*global require:false, define:false, module:false */ ;( function( factory ) { if ( typeof define === 'function' && define.amd ) { define( [ 'jquery' ], factory ); } else if ( typeof module === 'object' && typeof module.exports === 'object' ) { module.exports = factory( require( 'jquery' ) ); } else { factory( jQuery ); } }( function( $ ) { 'use strict'; var $keyboard = $.keyboard; $.extend( $keyboard.css, { altKeyPopup : 'ui-keyboard-popup', altKeyOverlay : 'ui-keyboard-overlay' }); $keyboard.altKeys = $.extend({ a : '\u00e5 \u00e6 \u0101 \u0103 \u0105 \u00e0 \u00e1 \u00e2 \u00e3 \u00e4', // å æ ā ă ą à á â ã ä A : '\u00c5 \u00c6 \u0100 \u0102 \u0104 \u00c0 \u00c1 \u00c2 \u00c3 \u00c4', // Å Æ Ā Ă Ą À Á Â Ã Ä c : '\u00e7 \u0107 \u0109 \u010b \u010d', // ç ć ĉ ċ č C : '\u00c7 \u0106 \u0108 \u010a \u010c', // Ç Ć Ĉ Ċ Č d : '\u010f \u00f0 \u010f', // ď ð ď D : '\u010e \u00d0 \u010e', // Ď Ð Ď e : '\u0117 \u0119 \u0115 \u011b \u0259 \u00e8 \u00e9 \u00ea \u00eb \u0113', // ė ę ĕ ě ə è é ê ë ē E : '\u0116 \u0118 \u0114 \u011a \u018e \u00c8 \u00c9 \u00ca \u00cb \u0112', // Ė Ę Ĕ Ě Ǝ È É Ê Ë Ē g : '\u0123 \u011f \u011d \u0121', // ģ ğ ĝ ġ G : '\u0122 \u011e \u011c \u0120', // Ģ Ğ Ĝ Ġ h : '\u0125 \u0127', // ĥ ħ H : '\u0124 \u0126', // Ĥ Ħ i : '\u0131 \u012f \u012b \u00ef \u00ee \u00ed \u00ec \u0129 \u012d', // ı į ī ï î í ì ĩ ĭ I : '\u0130 \u012e \u012a \u00cf \u00ce \u00cd \u00cc \u0128 \u012c', // İ Į Ī Ï Î Í Ì Ĩ Ĭ j : '\u0135', // ĵ J : '\u0134', // Ĵ k : '\u0137', // ķ K : '\u0136', // Ķ l : '\u0141 \u013d \u013b \u0139 \u013f', // Ł Ľ Ļ Ĺ Ŀ L : '\u0142 \u013e \u013c \u013a \u0140', // ł ľ ļ ĺ ŀ n : '\u0149 \u0148 \u0146 \u0144 \u00f1', // ʼn ň ņ ń ñ N : '\u0149 \u0147 \u0145 \u0143 \u00d1', // ʼn Ň Ņ Ń Ñ o : '\u0153 \u0151 \u00f8 \u00f6 \u00f5 \u00f4 \u00f3 \u00f2 \u014d \u014f', // œ ő ø ö õ ô ó ò ō ŏ O : '\u0152 \u0150 \u00d8 \u00d6 \u00d5 \u00d4 \u00d3 \u00d2 \u014c \u014e', // Œ Ő Ø Ö Õ Ô Ó Ò Ō Ŏ r : '\u0155 \u0159 \u0157', // ŕ ř ŗ R : '\u0154 \u0158 \u0156', // Ŕ Ř Ŗ s : '\u015b \u0161 \u015f \u00df \u00a7 \u015d', // ś š ş ß § ŝ S : '\u015a \u0160 \u015e \u1e9e \u00a7 \u015c', // Ś Š Ş ẞ § Ŝ t : '\u00fe \u0165 \u021b \u0163 \u0167', // þ ť ț ţ ŧ T : '\u00de \u0164 \u021a \u0162 \u0166', // Þ Ť Ț Ţ Ŧ u : '\u0173 \u0171 \u016f \u016b \u00fc \u00fb \u00fa \u00f9 \u0169 \u016d', // ų ű ů ū ü û ú ù ũ ŭ U : '\u0172 \u0170 \u016e \u016a \u00dc \u00db \u00da \u00d9 \u0168 \u016c', // Ų Ű Ů Ū Ü Û Ú Ù Ũ Ŭ w : '\u0175', // ŵ W : '\u0174', // Ŵ y : '\u00fd', // ý Y : '\u00dd', // Ý z : '\u017a \u017c \u017e', // ź ż ž Z : '\u0179 \u017b \u017d', // Ź Ż Ž '!' : '\u00a1', // ¡ '$' : '\u20ac \u00a3 \u00a4 \u00a5 \u00a2 \u20a1 \u20b1 \u20a9 \u20b9 \u20aa \u20ad \u20ae \u20a6 \u20a4', // €£¤¥¢₡₱₩₹₪₭₮₦₤ '?' : '\u00bf', // ¿ "'" : '\u3008 \u300c \u300e \u201c', // 〈 「 『 “ '"' : '\u3009 \u300d \u300f \u201d', // 〉 」 』 ” '(' : '\u300a \u3010 \u3014', // « 【 〔 ')' : '\u300b \u3011 \u3015' // » 】 〕 }, $keyboard.altKeys ); $.fn.addAltKeyPopup = function( options ) { //Set the default values, use comma to separate the settings, example: var defaults = { // time to hold down a button in ms to trigger a popup holdTime : 500, // event triggered when popup is visible popupVisible : 'popup-visible' }; return this.each( function() { // make sure a keyboard is attached var namespace, base = $( this ).data( 'keyboard' ); if (!base) { return; } // variables base.altkeypopup_options = $.extend( {}, defaults, options ); namespace = base.altkeypopup_namespace = base.namespace + 'AltKeyPopup'; base.extensionNamespace.push( namespace ); base.altkeypopup_setup = function() { var timer, start = 'mousedown touchstart '.split( ' ' ).join( namespace + ' ' ), end = 'mouseup touchend touchcancel '.split( ' ' ).join( namespace + ' ' ); // force disable repeat keys base.options.repeatRate = 0; // add hold key functionality for popups base.$allKeys .bind( start, function() { clearTimeout( timer ); var $key = $( this ), key = $key.attr( 'data-action' ) || ''; if ( key in $keyboard.altKeys ) { timer = setTimeout( function() { base.altKeyPopup_popup( key, $key ); }, base.altkeypopup_options.holdTime ); } }) .bind( end, function() { clearTimeout( timer ); }); }; base.altKeyPopup_popup = function( key, $key ) { var keys, $keys, positionHoriz, positionVert, top, kbcss = $keyboard.css, kbWidth = base.$keyboard.outerWidth(), kbHeight = base.$keyboard.outerHeight(); // overlay keyboard base.altKeyPopup_$overlay = $( '
' ) .css({ width : kbWidth, height: kbHeight }) .appendTo( base.$keyboard ) .bind( 'click touchstart', function() { base.altKeyPopup_$overlay.remove(); }); // remove character added when key was initially pressed, unless it was a backspace key if ( key !== 'bksp' ) { $keyboard.keyaction.bksp( base ); } // make popup; use the same classes as the keyboard container $keys = $( '
' ); keys = $keyboard.altKeys[ key ].split( /\s+/ ); // make popup keys base.buildRow( $keys, 0, keys, [] ); // add popup & add bindings $keys .appendTo( base.altKeyPopup_$overlay ) .children() .bind( 'mousedown touchstart', function( event ) { var action = $( this ).attr( 'data-action' ); // make action keys work in popup if ( action in $keyboard.keyaction && $.isFunction($keyboard.keyaction[ action ] ) ) { $keyboard.keyaction[ action ]( base, this, event ); } else { base.insertText( action ); } base.altKeyPopup_$overlay.remove(); }) .bind( 'mouseover mouseleave', function( event ){ $( this ).toggleClass( base.options.css.buttonHover, event.type === 'mouseover' ); }); // position popup within $keyboard container positionHoriz = $key.position().left - ( $keys.outerWidth() / 2 ) + ( $key.outerWidth() / 2 ); if ( positionHoriz + $keys.outerWidth() > kbWidth ) { positionHoriz = kbWidth - $keys.outerWidth(); if ( positionHoriz < 0 ) { $keys.css({ width : kbWidth, height : 'auto' }); } } positionVert = $key.position().top - $key.outerHeight() - 5; top = base.$keyboard.find( '.' + kbcss.keySet ).position().top; if ( positionVert + $keys.outerHeight() > kbHeight ) { positionVert = kbHeight - $keys.outerHeight(); if ( positionVert < top ) { $keys.css({ height : kbHeight - top, width : 'auto' }); } } $keys.css({ position : 'relative', top : positionVert < top ? top : positionVert, left : positionHoriz < 0 ? 0 : positionHoriz }); // trigger popup visible event base.$el.trigger( base.altkeypopup_options.popupVisible, [ base ] ); }; // visible event is fired before this extension is initialized, so check! if ( base.options.alwaysOpen && base.isVisible() ) { base.altkeypopup_setup(); } // setup altkey popup base.$el .unbind( $keyboard.events.kbBeforeVisible + namespace ) .bind( $keyboard.events.kbBeforeVisible + namespace, function() { base.altkeypopup_setup(); }); }); }; })); /*! jQuery UI Virtual Keyboard Autocomplete v1.9.2 *//* * for Keyboard v1.18+ only (8/17/2015) * * By Rob Garrison (aka Mottie & Fudgey) * Licensed under the MIT License * * Use this extension with the Virtual Keyboard to get * the jQuery UI Autocomplete widget to work seamlessly * * Requires: * jQuery * jQuery UI & css * Keyboard plugin : https://github.com/Mottie/Keyboard * * Setup: * $('.ui-keyboard-input') * .keyboard(options) * .autocomplete(options) * .addAutoComplete(); * * // or if targeting a specific keyboard * $('#keyboard1') * .keyboard(options) // keyboard plugin * .autocomplete(options) // jQuery UI autocomplete * .addAutoComplete(); // this keyboard extension * */ /*jshint browser:true, jquery:true, unused:false */ /*global require:false, define:false, module:false */ ;(function(factory) { if (typeof define === 'function' && define.amd) { define(['jquery'], factory); } else if (typeof module === 'object' && typeof module.exports === 'object') { module.exports = factory(require('jquery')); } else { factory(jQuery); } }(function($) { 'use strict'; $.fn.addAutocomplete = function(options){ var defaults = { position : { of : null, my : 'right top', at : 'left top', collision: 'flip' } }; return this.each(function(){ // make sure a keyboard is attached var o, base = $(this).data('keyboard'); if (!base) { return; } base.autocomplete_namespace = base.namespace + 'Autocomplete'; base.extensionNamespace.push( base.autocomplete_namespace ); // Setup base.autocomplete_init = function(){ // variables o = base.autocomplete_options = $.extend( true, {}, defaults, options ); // visible event is fired before this extension is initialized, so check! if (base.options.alwaysOpen && base.isVisible()) { base.autocomplete_setup(); } base.$el .unbind(base.autocomplete_namespace) .bind($.keyboard.events.kbVisible + base.autocomplete_namespace,function(){ base.autocomplete_setup(); }) .bind($.keyboard.events.kbChange + base.autocomplete_namespace,function(){ if (base.hasAutocomplete && base.isVisible()) { base.$el .val(base.$preview.val()) .trigger('keydown.autocomplete'); } }) .bind($.keyboard.events.kbHidden + base.autocomplete_namespace, function(){ base.$el.autocomplete('close'); }) .bind('autocompleteopen' + base.autocomplete_namespace, function() { if (base.hasAutocomplete){ // default to $keyboard if no position.of defined var position = $.extend( {}, o.position ); // refresh base.$keyboard (it gets destroyed after use); fixes #382 position.of = position.of || base.$keyboard; // reposition autocomplete window next to the keyboard base.$autocomplete.menu.element.position( position ); } }) .bind('autocompleteselect' + base.autocomplete_namespace, function(e, ui){ var v = ui.item && ui.item.value || ''; if (base.hasAutocomplete && v !== ''){ base.$preview .val( v ) .focus(); // see issue #95 - thanks banku! base.last.start = v.length; base.last.end = v.length; } }); }; // set up after keyboard is visible base.autocomplete_setup = function(){ // look for autocomplete base.$autocomplete = base.$el.data('autocomplete') || base.$el.data('uiAutocomplete') || base.$el.data('ui-autocomplete'); base.hasAutocomplete = (typeof(base.$autocomplete) === 'undefined') ? false : (base.$autocomplete.options.disabled) ? false : true; // only bind to keydown once if (base.hasAutocomplete) { base.$preview.bind('keydown' + base.autocomplete_namespace, function(e){ // send keys to the autocomplete widget (arrow, pageup/down, etc) base.$el.val( base.$preview.val() ).triggerHandler(e); }); base.$allKeys.bind('mouseup mousedown mouseleave touchstart touchend touchcancel '.split(' ').join(base.autocomplete_namespace + ' '),function(event){ clearTimeout( base.$autocomplete.searching ); var evt = event; base.$autocomplete.searching = setTimeout(function() { // only search if the value has changed if ( base.$autocomplete.term !== base.$autocomplete.element.val() ) { base.$autocomplete.selectedItem = null; base.$autocomplete.search( null, evt ); } }, base.$autocomplete.options.delay ); }); } }; base.origEscClose = base.escClose; // replace original function with this one base.escClose = function(e){ // prevent selecting an item in autocomplete from closing keyboard if ( base.hasAutocomplete && (e.target.id === 'ui-active-menuitem' || $(e.target).closest('ul').hasClass('ui-autocomplete')) ) { return; } base.origEscClose(e); }; base.autocomplete_init(); }); }; })); /*! jQuery UI Virtual Keyboard Virtual Caret v1.1.3 (beta) *//* * for Keyboard v1.18+ only (9/24/2015) * modified from https://github.com/component/textarea-caret-position * * By Rob Garrison (aka Mottie) * Licensed under the MIT License * * CSS changes * NOTE: caret margin-top => is added to the caret height (top & bottom) * .ui-keyboard-preview-wrapper { position: relative; overflow: hidden; } * .ui-keyboard-caret { background: red; width: 1px; margin-top: 3px; } */ /*jshint browser:true, jquery:true, unused:false */ /*global require:false, define:false, module:false */ ;( function( factory ) { if ( typeof define === 'function' && define.amd ) { define( [ 'jquery' ], factory ); } else if ( typeof module === 'object' && typeof module.exports === 'object' ) { module.exports = factory( require( 'jquery' ) ); } else { factory( jQuery ); } }( function( $ ) { 'use strict'; var $keyboard = $.keyboard; $keyboard.firefox = typeof window.mozInnerScreenX !== 'undefined'; $.extend( $keyboard.css, { caret : 'ui-keyboard-caret' }); $.fn.addCaret = function( options ) { var defaults = { caretClass : '', // *** for future use *** // data-attribute containing the character(s) next to the caret charAttr : 'data-character', // # character(s) next to the caret (can be negative for RTL) charIndex : 1, offsetX : 0, offsetY : 0, adjustHt : 0 }; return this.each( function() { // make sure a keyboard is attached var o, namespace, kbevents = $keyboard.events, base = $( this ).data( 'keyboard' ); if ( !base ) { return; } // variables o = base.caret_options = $.extend( {}, defaults, options ); namespace = base.caret_namespace = base.namespace + 'caret'; base.extensionNamespace.push( namespace ); // modified from https://github.com/component/textarea-caret-position // The properties that we copy into a mirrored div. // Note that some browsers, such as Firefox, // do not concatenate properties, i.e. padding-top, bottom etc. -> padding, // so we have to do every single property specifically. base.textareaCaretProperties = [ 'direction', 'boxSizing', 'width', 'height', 'overflowX', 'overflowY', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'borderStyle', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch', 'fontSize', 'fontSizeAdjust', 'lineHeight', 'fontFamily', 'textAlign', 'textTransform', 'textIndent', 'textDecoration', 'letterSpacing', 'wordSpacing', 'tabSize', 'MozTabSize' ]; base.caret_setup = function() { var events = 'keyup keypress mouseup mouseleave '.split( ' ' ).join( namespace + ' ' ), style = 'position:absolute;visibility:hidden;top:-9999em;left:-9999em;' + 'white-space:pre-wrap;' + ( base.preview.nodeName === 'INPUT' ? '' : 'word-wrap:break-word;' ); // add mirrored div base.caret_$div = $( '
' ) .appendTo( base.$keyboard ); // remove caret, just-in-case if (base.$caret) { base.$caret.remove(); } base.$caret = $( '
' ) .insertAfter( base.$preview ); base.$el .unbind( kbevents.kbChange + namespace ) .bind( kbevents.kbChange + namespace, function() { base.findCaretPos(); }); base.$preview .unbind( events ) .bind( events, function() { base.findCaretPos(); }); }; // getCaretCoordinatesFn = function (element, position, recalculate) { base.findCaretPos = function() { if ( !base.caret_$div ) { return; } var style, computed, margin, pos, position, txt, span, offset, element = base.preview, isInput = element.nodeName === 'INPUT', div = base.caret_$div[0]; style = div.style; // getComputedStyle with null - fixes #384 computed = window.getComputedStyle ? getComputedStyle( element, null ) : element.currentStyle; // get caret position based on text-direction pos = $keyboard.caret( base.$preview ); position = Math[ computed.direction === 'ltr' ? 'max' : 'min' ]( pos.start, pos.end ); // transfer the element's properties to the div base.textareaCaretProperties.forEach(function ( prop ) { style[ prop ] = computed[ prop ]; }); if ( $keyboard.firefox ) { // Firefox adds 2 pixels to the padding - https://bugzilla.mozilla.org/show_bug.cgi?id=753662 style.width = parseInt( computed.width, 10 ) - 2 + 'px'; // Firefox lies about the overflow property for textareas: // https://bugzilla.mozilla.org/show_bug.cgi?id=984275 if ( element.scrollHeight > parseInt( computed.height, 10 ) ) { style.overflowY = 'scroll'; } } else { // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll' // style.overflow = 'hidden'; style.width = parseInt( isInput ? element.scrollWidth : computed.width, 10 ) + // add 50 extra px if it's an input to prevent wrap ( isInput ? 50 : 0 ) + 'px'; } div.textContent = element.value.substring( 0, position ); // the second special handling for input type="text" vs textarea: // spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037 if ( element.nodeName === 'INPUT' ) { div.textContent = div.textContent.replace( /\x20/g, '\xa0' ); } span = document.createElement( 'span' ); // Wrapping must be replicated *exactly*, including when a long word gets // onto the next line, with whitespace at the end of the line before (#7). // The *only* reliable way to do that is to copy the *entire* rest of the // textarea's content into the created at the caret position. // for inputs, just '.' would be enough, but why bother? // || because a completely empty faux span doesn't render at all span.textContent = element.value.substring( position ) || '.'; div.appendChild( span ); offset = $(span).position(); base.caretPos = { top: offset.top + parseInt( computed.borderTopWidth, 10 ) + o.offsetY, left: offset.left + parseInt( computed.borderLeftWidth, 10 ) + o.offsetX }; // make caret height = font-size + any margin-top x2 added by the css margin = parseInt( base.$caret.css( 'margin-top' ), 10 ); style = Math.round( parseFloat( base.$preview.css( 'font-size' ) ) + margin * 2 ) + o.adjustHt; offset = base.$preview.position(); base.$caret.css({ top: offset.top - element.scrollTop + base.caretPos.top - margin, left: offset.left - element.scrollLeft + base.caretPos.left, height: style }); txt = element.value.substring( position, position + o.charIndex ).replace(/\s/, '\xa0' ) || '\xa0'; base.$caret.attr( o.charAttr, txt ); }; // setup caret when keyboard is visible base.$el .unbind( namespace ) .bind( kbevents.kbBeforeVisible + namespace, function() { base.caret_setup(); }) .bind( kbevents.kbVisible + namespace, function() { base.findCaretPos(); }) .bind( kbevents.kbHidden + namespace, function() { // unbind events in case usePreview: false; see #376 var events = 'keyup keypress mouseup mouseleave '.split( ' ' ).join( namespace + ' ' ); base.$preview.unbind( events ); base.$caret.remove(); base.$caret = null; base.caret_$div = null; }); // visible event is fired before this extension is initialized, so check! if ( base.options.alwaysOpen && base.isVisible() ) { base.caret_setup(); base.findCaretPos(); } }); }; })); /*! jQuery UI Virtual Keyboard Extender v1.0.1 *//* * for Keyboard v1.18+ only (7/7/2015) * * By Rob Garrison (aka Mottie) * Licensed under the MIT License * */ /*jshint browser:true, jquery:true, unused:false */ /*global require:false, define:false, module:false */ ;(function(factory) { if (typeof define === 'function' && define.amd) { define(['jquery'], factory); } else if (typeof module === 'object' && typeof module.exports === 'object') { module.exports = factory(require('jquery')); } else { factory(jQuery); } }(function($) { 'use strict'; var $keyboard = $.keyboard; $.extend( $keyboard.css, { extender : 'ui-keyboard-extender' }); $.extend( $keyboard.layouts, { 'numpad' : { 'normal' : [ '{clear} / * -', '7 8 9 +', '4 5 6 %', '1 2 3 =', '0 {dec} {left} {right}' ] } }); // add {extender} keyaction $.extend( $keyboard.keyaction, { extender: function( base, el ) { base.extender_toggle(); return false; } }); $.fn.addExtender = function(options) { //Set the default values, use comma to separate the settings, example: var defaults = { layout : 'numpad', showing : false, reposition : true }; return this.each( function() { // make sure a keyboard is attached var o, base = $( this ).data( 'keyboard' ); if (!base) { return; } // variables o = base.extender_options = $.extend( {}, defaults, options ); $.extend( true, $keyboard.language.en, { display : { 'extender' : ' ' } }); base.extender_namespace = base.namespace + 'extender'; base.extensionNamespace.push( base.extender_namespace ); base.extender_setup = function() { var $kb, layout = o.layout; if ( typeof $keyboard.builtLayouts[ layout ] === 'undefined' ) { base.buildKeyboard( layout ); } $kb = $keyboard.builtLayouts[ layout ].$keyboard.find( '.' + $keyboard.css.keySet + '-normal' ).clone(); $kb .removeClass() .removeAttr('name') .addClass( $keyboard.css.extender ) .toggle( o.showing ) .children('button') .removeAttr('data-pos'); base.$keyboard.append( $kb ); base.extender_toggle( base.extender_options.showing ); base.bindKeys(); }; base.extender_toggle = function(set) { base.extender_options.showing = typeof set === 'undefined' ? !base.extender_options.showing : set; base.$keyboard .find( 'div.' + $keyboard.css.extender ) .toggle( base.extender_options.showing ) .end() .find( '.' + $keyboard.css.keySet ) .css('float', base.extender_options.showing ? 'left' : 'none') .end() .find( 'button.' + $keyboard.css.extender ) .toggleClass( base.options.css.buttonActive, base.extender_options.showing ); // force keyboard reposition if (base.extender_options.reposition) { $(window).trigger('resize'); } }; // visible event is fired before this extension is initialized, so check! if (base.options.alwaysOpen && base.isVisible()) { base.extender_setup(); } // setup extender base.$el .unbind( $keyboard.events.kbBeforeVisible + base.extender_namespace ) .bind( $keyboard.events.kbBeforeVisible + base.extender_namespace, function() { base.extender_setup(); }); }); }; })); /*! jQuery UI Virtual Keyboard for jQuery Mobile Themes v1.4.1 *//* * for Keyboard v1.18+ (updated 7/7/2015) * * By Rob Garrison (aka Mottie & Fudgey) * Licensed under the MIT License * * Use this extension with the Virtual Keyboard to apply * the necessary themes to make the keyboard compatible with * jQuery Mobile themes * * Requires: * jQuery - http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js * jQuery Mobile - http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js * jQuery Mobile themes - http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css * * Setup: * $('.ui-keyboard-input') * .keyboard(options) * .addMobile(mobile-options); * * // or if targeting a specific keyboard * $('#keyboard1') * .keyboard(options) // keyboard plugin * .addMobile(mobile-options); // this keyboard extension * */ /*jshint browser:true, jquery:true, unused:false */ /*global require:false, define:false, module:false */ ;(function(factory) { if (typeof define === 'function' && define.amd) { define(['jquery'], factory); } else if (typeof module === 'object' && typeof module.exports === 'object') { module.exports = factory(require('jquery')); } else { factory(jQuery); } }(function($) { $.fn.addMobile = function(options){ var o, defaults = { // keyboard wrapper theme container : { theme:'b', cssClass:'ui-body' }, // keyboard duplicate input input : { theme:'b', cssClass:'' }, // theme added to all regular buttons buttonMarkup : { theme:'b', cssClass:'ui-btn', shadow:'true', corners:'true' }, // theme added to all buttons when they are being hovered buttonHover : { theme:'b', cssClass:'ui-btn-hover' }, // theme added to action buttons (e.g. tab, shift, accept, cancel); // parameters here will override the settings in the buttonMarkup buttonAction : { theme:'b', cssClass:'ui-btn-active' }, // theme added to button when it is active (e.g. shift is down) // All extra parameters will be ignored buttonActive : { theme:'b', cssClass:'ui-btn-active' }, // if more than 3 mobile themes are used, add them here allThemes : 'a b c' }; return this.each(function(){ var base = $(this).data('keyboard'); // Stop if no keyboard attached or if jQuery Mobile isn't loaded if (!base || typeof($.fn.textinput) === 'undefined') { return; } base.mobile_options = o = $.extend(true, {}, defaults, options); // create a list of theme class names to remove base.mobile_themes = $.trim( (' ' + o.allThemes).split(' ').join(' ' + o.buttonMarkup.cssClass + '-') + (' ' + o.allThemes).split(' ').join(' ' + o.buttonAction.cssClass + '-') + (' ' + o.allThemes).split(' ').join(' ' + o.buttonActive.cssClass + '-') ); // save original action class because it gets removed when this theme switches swatches if (typeof base.options.mobile_savedActiveClass === 'undefined') { base.options.mobile_savedActiveClass = '' + base.options.css.buttonActive; } // Setup base.mobile_init = function() { var namespace = base.namespace + 'Mobile'; // Add theme to input - if not already done through the markup $('.' + $.keyboard.css.input).textinput(); // visible event is fired before this extension is initialized, so check! if (base.options.alwaysOpen && base.isVisible) { base.mobile_setup(); } base.extensionNamespace.push( namespace ); // Setup mobile theme on keyboard once it is visible. // Note: There is a 10ms delay after the keyboard is displayed before it actually fires 'visible.keyboard'. // Since we are restyling here, the user will experience FlashOfUnstyledContent (FOUC). // This is avoided by first setting the visibility to hidden, then after the mobile styles are applied we // set it visible. base.$el .unbind(namespace) .bind($.keyboard.events.kbBeforeVisible + namespace, function() { if ( base && base.el.active && base.$keyboard.length ) { base.$keyboard.css('visibility', 'hidden'); } }) .bind($.keyboard.events.kbVisible + namespace, function() { if ( base && base.el.active && base.$keyboard.length ) { base.mobile_setup(); base.$keyboard.css('visibility', 'visible'); base.$preview.focus(); } }); }; base.mobile_setup = function(){ var p, kbcss = $.keyboard.css, opts = base.options, themes = base.mobile_themes; base.mobile_$actionKeys = base.$keyboard.find('.' + base.options.css.buttonAction); opts.css.buttonActive = opts.mobile_savedActiveClass + ' ' + base.modOptions(o.buttonActive, o.buttonMarkup); base.$keyboard // 'ui-body ui-body-a' classes to apply swatch theme .addClass( base.modOptions(o.container, o.container) ) // preview input .find('.' + kbcss.preview) // removing 'ui-widget-content' will prevent jQuery UI theme from applying to the keyboard .removeClass('ui-widget ui-widget-content') .addClass( base.modOptions(o.input, o.input) ).end() // apply jQuery Mobile button markup // removed call to jQuery Mobile buttonMarkup function; replaced with base.modOptions .find('button') .removeClass( $.trim('ui-corner-all ui-state-default ' + themes) ) .addClass( base.modOptions(o.buttonMarkup, o.buttonMarkup) ) .not( base.mobile_$actionKeys ) .hover(function(){ $(this) .removeClass( themes ) .addClass( base.modOptions(o.buttonHover, o.buttonMarkup) ); },function(){ $(this) .removeClass( themes + ' ' + o.buttonHover.cssClass ) .addClass( base.modOptions(o.buttonMarkup, o.buttonMarkup) ); }); base.mobile_$actionKeys .removeClass( themes ) .addClass( base.modOptions(o.buttonAction, o.buttonMarkup) ); // update keyboard width if preview is showing... after applying mobile theme if (base.msie && base.$preview[0] !== base.el) { base.$preview.hide(); base.$keyboard.css('width',''); base.width = base.$keyboard.outerWidth(); // add about 1em to input width for extra padding base.$keyboard.width(base.width + parseInt(base.$preview.css('fontSize'),10)); base.$preview.width(base.width); base.$preview.show(); } // adjust keyboard position after applying mobile theme if ($.ui && $.ui.position) { p = opts.position; p.of = p.of || base.$el.data('keyboardPosition') || base.$el; p.collision = p.collision || 'flipfit flipfit'; base.$keyboard.position(p); } }; base.modOptions = function(t, btn){ var css = ' ' + ( t.cssClass || '' ); // Using this instead of the jQuery Mobile buttonMarkup because it is expecting 's instead of