jQuery Masked Input

Work In Progress - Try to fix Android issues.

by Patrick Thurmond

HTML

<!-- Broken Credit Card Input (in Android) -->
<input type="text" id="ccInput" maxlength="19" size="60" pattern="/d" mask="9999-9999-9999-9999">
<br>
<!-- Working Phone Input (in Android) -->
<input type="tel" id="phone" class="form-text" size="60" maxlength="14">
<br>
<!-- Broken Phone Input (in Android - Well it was, now I am not sure) -->
<input type="tel" id="phoneParen" class="form-text" size="60" maxlength="14">

JavaScript

/**
 * Based on (copied from): https://github.com/JBlond/jquery.maskedinput
 */
(function (factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(['jquery'], factory);
  }
  else if (typeof exports === 'object') {
    // Node/CommonJS
    factory(require('jquery'));
  }
  else {
    // Browser globals
    factory(jQuery);
  }
}(function ($) {

  var ua = navigator.userAgent,
    iPhone = /iphone/i.test(ua),
    chrome = /chrome/i.test(ua),
    android = /android/i.test(ua),
    caretTimeoutId;

  $.mask = {
    //Predefined character definitions
    definitions: {
      '9': "[0-9]",
      'a': "[A-Za-z]",
      '*': "[A-Za-z0-9]"
    },
    autoclear: true,
    dataName: "rawMaskFn",
    placeholder: '_'
  };

  $.fn.extend({
    //Helper Function for Caret positioning
    caret: function (begin, end) {
      var range;

      if (this.length === 0 || this.is(":hidden") || this.get(0) !== document.activeElement) {
        return;
      }

      if (typeof begin === 'number') {
        end = (typeof end === 'number') ? end : begin;

        return this.each(function () {
          if (this.setSelectionRange) {
            this.setSelectionRange(begin, end);
          }
          else if (this.createTextRange) {
            range = this.createTextRange();
            range.collapse(true);
            range.moveEnd('character', end);
            range.moveStart('character', begin);
            range.select();
          }
        });
      }
      else {
        if (this[0].setSelectionRange) {
          begin = this[0].selectionStart;
          end = this[0].selectionEnd;
        }
        else if (document.selection && document.selection.createRange) {
          range = document.selection.createRange();
          begin = 0 - range.duplicate().moveStart('character', -100000);
          end = begin + range.text.length;
        }

        return {begin: begin, end: end};
      }
    },

    unmask:...