From 83ac6d482d8676adc39fd9bb23295bb48a286884 Mon Sep 17 00:00:00 2001
From: Jarid Margolin <jaridmargolin@gmail.com>
Date: Tue, 29 Oct 2013 16:04:50 -0700
Subject: [PATCH] arrow key error

---
 lib/formatter.js            | 16 +++++++++-------
 lib/formatter.min.js        |  2 +-
 lib/jquery.formatter.js     | 16 +++++++++-------
 lib/jquery.formatter.min.js |  2 +-
 src/formatter.js            | 12 ++++++++----
 src/utils.js                |  4 +---
 test/fake-user/keys.js      |  2 +-
 test/fake-user/user.js      |  4 ++--
 8 files changed, 32 insertions(+), 26 deletions(-)

diff --git a/lib/formatter.js b/lib/formatter.js
index 746a87d..2c3fbe0 100644
--- a/lib/formatter.js
+++ b/lib/formatter.js
@@ -113,13 +113,17 @@ Formatter.prototype._keyDown = function (evt) {
 //
 Formatter.prototype._keyPress = function (evt) {
   // The first thing we need is the character code
-  var k;
+  var k, isSpecial;
   // Mozilla will trigger on special keys and assign the the value 0
   // We want to use that 0 rather than the keyCode it assigns.
-  k = (evt.which || evt.which === 0) ? evt.which : evt.keyCode;
-
+  if (evt.which) {
+    k = evt.which;
+  } else {
+    k = evt.keyCode;
+    isSpecial = utils.isSpecialKey(k);
+  }
   // Process the keyCode and prevent default
-  if (!utils.isSpecialKey(k) && !utils.isModifier(evt)) {
+  if (!utils.isDelKey(k) && !isSpecial && !utils.isModifier(evt)) {
     this._processKey(String.fromCharCode(k), false);
     return utils.preventDefault(evt);
   }
@@ -567,9 +571,7 @@ utils.isSpecialKey = function (k) {
     '40': 'downarrow'
   };
   // If del or special key
-  return (this.isDelKey(k) || codes[k])
-    ? true
-    : false;
+  return codes[k];
 };
 
 //
diff --git a/lib/formatter.min.js b/lib/formatter.min.js
index 1a95e00..65d0af8 100644
--- a/lib/formatter.min.js
+++ b/lib/formatter.min.js
@@ -6,4 +6,4 @@
  * thanks to digitalBush/jquery.maskedinput for some of the trickier
  * keycode handling
  */
-!function(a,b){function c(a,b){var c=this;if(c.el=a,!c.el)throw new TypeError("Must provide an existing element");if(c.opts=k.extend({},d,b),"undefined"==typeof c.opts.pattern)throw new TypeError("Must provide a pattern");var e=f.parse(c.opts.pattern);c.mLength=e.mLength,c.chars=e.chars,c.inpts=e.inpts,c.hldrs={},c.focus=0,k.addListener(c.el,"keydown",function(a){c._keyDown(a)}),k.addListener(c.el,"keypress",function(a){c._keyPress(a)}),k.addListener(c.el,"paste",function(a){c._paste(a)}),c.opts.persistent&&(c._processKey(null,!0),c.el.blur(),k.addListener(c.el,"focus",function(a){c._focus(a)}),k.addListener(c.el,"click",function(a){c._focus(a)}),k.addListener(c.el,"touchstart",function(a){c._focus(a)}))}"undefined"!=typeof a&&(a.Formatter=c);var d={persistent:!1,repeat:!1,placeholder:" "},e={9:new RegExp("[0-9]"),a:new RegExp("[A-Za-z]"),"*":new RegExp("[A-Za-z0-9]")};c.prototype._keyDown=function(a){var b=a.which||a.keyCode;return b&&k.isDelKey(b)?(this._processKey(null,b),k.preventDefault(a)):void 0},c.prototype._keyPress=function(a){var b;return b=a.which||0===a.which?a.which:a.keyCode,k.isSpecialKey(b)||k.isModifier(a)?void 0:(this._processKey(String.fromCharCode(b),!1),k.preventDefault(a))},c.prototype._paste=function(a){return this._processKey(k.getClip(a),!1),k.preventDefault(a)},c.prototype._focus=function(){var a=this;setTimeout(function(){var b=j.get(a.el),c=b.end>a.focus;isFirstChar=0===b.end,(c||isFirstChar)&&j.set(a.el,a.focus)},0)},c.prototype._processKey=function(a,b){this.sel=j.get(this.el),this.val=this.el.value,this.delta=0,this.sel.begin!==this.sel.end?(this.delta=-1*Math.abs(this.sel.begin-this.sel.end),this.val=k.removeChars(this.val,this.sel.begin,this.sel.end)):b&&(46==b&&this.sel.begin+1<this.val.length?(this.sel.end++,this.sel.begin++,this.val=k.removeChars(this.val,this.sel.end-1,this.sel.end),this.delta=-1):this.sel.begin-1>=0&&(this.val=k.removeChars(this.val,this.sel.end-1,this.sel.end),this.delta=-1)),b||(this.val=k.addChars(this.val,a,this.sel.begin),this.delta+=a.length),this._formatValue()},c.prototype._formatValue=function(){this.curPos=this.sel.end,this.newPos=this.curPos+this.delta,this._removeChars(),this._validateInpts(),this._addChars(),this.el.value=this.val.substr(0,this.mLength),j.set(this.el,this.newPos)},c.prototype._removeChars=function(){this.sel.end>this.focus&&(this.delta+=this.sel.end-this.focus);for(var a=0,b=0;b<=this.mLength;b++){var c,d=this.chars[b],e=this.hldrs[b],f=b+a;f=b>=this.sel.begin?f+this.delta:f,c=this.val[f],(d&&d==c||e&&e==c)&&(this.val=k.removeChars(this.val,f,f+1),a--)}this.hldrs={},this.focus=this.val.length},c.prototype._validateInpts=function(){for(var a=0;a<this.val.length;a++){var b=this.inpts[a];e[b]&&e[b].test(this.val[a])||this.inpts[a]&&(this.val=k.removeChars(this.val,a,a+1),this.focusStart--,this.newPos--,this.delta--,a--)}},c.prototype._addChars=function(){if(this.opts.persistent){for(var a=0;a<=this.mLength;a++)this.val[a]||(this.val=k.addChars(this.val,this.opts.placeholder,a),this.hldrs[a]=this.opts.placeholder),this._addChar(a);for(;this.chars[this.focus];)this.focus++}else for(var b=0;b<=this.val.length;b++)this._addChar(b)},c.prototype._addChar=function(a){var b=this.chars[a];return b?(k.isBetween(a,[this.sel.begin-1,this.newPos+1])&&(this.newPos++,this.delta++),a<=this.focus&&this.focus++,this.delta<0&&this.val[a]==b?!0:(this.hldrs[a]&&(delete this.hldrs[a],this.hldrs[a+1]=this.opts.placeholder),this.val=k.addChars(this.val,b,a),void 0)):!0};var f={},g=4,h=new RegExp("{{([^}]+)}}","g"),i=function(a){for(var b,c=[];b=h.exec(a);)c.push(b);return c};f.parse=function(a){var b={inpts:{},chars:{}},c=i(a),d=a.length,e=0,f=0,h=0,j=function(a){for(var c=a.length,d=0;c>d;d++)b.inpts[f]=a[d],f++;e++,h+=a.length+g-1};for(h;d>h;h++)h==c[e].index?j(c[e][1]):b.chars[h-e*g]=a[h];return b.mLength=h-e*g,b};var j={};j.get=function(a){if("number"==typeof a.selectionStart)return{begin:a.selectionStart,end:a.selectionEnd};var c=b.selection.createRange();if(c&&c.parentElement()==a){var d=a.createTextRange(),e=a.createTextRange(),f=a.value.length;return d.moveToBookmark(c.getBookmark()),e.collapse(!1),d.compareEndPoints("StartToEnd",e)>-1?{begin:f,end:f}:{begin:-d.moveStart("character",-f),end:-d.moveEnd("character",-f)}}return{begin:0,end:0}},j.set=function(a,b){if(a.setSelectionRange)a.focus(),a.setSelectionRange(b,b);else if(a.createTextRange){var c=a.createTextRange();c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",b),c.select()}};var k={},l="undefined"!=typeof navigator?navigator.userAgent:null,m=/iphone/i.test(l);k.extend=function(a){for(var b=1;b<arguments.length;b++)for(var c in arguments[b])a[c]=arguments[b][c];return a},k.addChars=function(a,b,c){return a.substr(0,c)+b+a.substr(c,a.length)},k.removeChars=function(a,b,c){return a.substr(0,b)+a.substr(c,a.length)},k.isBetween=function(a,b){return b.sort(function(a,b){return a-b}),a>b[0]&&a<b[1]},k.addListener=function(a,b,c){return"undefined"!=typeof a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent("on"+b,c)},k.preventDefault=function(a){return a.preventDefault?a.preventDefault():a.returnValue=!1},k.getClip=function(b){return b.clipboardData?b.clipboardData.getData("Text"):a.clipboardData?a.clipboardData.getData("Text"):void 0},k.isDelKey=function(a){return 8===a||46===a||m&&127===a},k.isSpecialKey=function(a){var b={35:"end",36:"home",37:"leftarrow",38:"uparrow",39:"rightarrow",40:"downarrow"};return this.isDelKey(a)||b[a]?!0:!1},k.isModifier=function(a){return a.ctrlKey||a.altKey||a.metaKey}}(window,document);
\ No newline at end of file
+!function(a,b){function c(a,b){var c=this;if(c.el=a,!c.el)throw new TypeError("Must provide an existing element");if(c.opts=k.extend({},d,b),"undefined"==typeof c.opts.pattern)throw new TypeError("Must provide a pattern");var e=f.parse(c.opts.pattern);c.mLength=e.mLength,c.chars=e.chars,c.inpts=e.inpts,c.hldrs={},c.focus=0,k.addListener(c.el,"keydown",function(a){c._keyDown(a)}),k.addListener(c.el,"keypress",function(a){c._keyPress(a)}),k.addListener(c.el,"paste",function(a){c._paste(a)}),c.opts.persistent&&(c._processKey(null,!0),c.el.blur(),k.addListener(c.el,"focus",function(a){c._focus(a)}),k.addListener(c.el,"click",function(a){c._focus(a)}),k.addListener(c.el,"touchstart",function(a){c._focus(a)}))}"undefined"!=typeof a&&(a.Formatter=c);var d={persistent:!1,repeat:!1,placeholder:" "},e={9:new RegExp("[0-9]"),a:new RegExp("[A-Za-z]"),"*":new RegExp("[A-Za-z0-9]")};c.prototype._keyDown=function(a){var b=a.which||a.keyCode;return b&&k.isDelKey(b)?(this._processKey(null,b),k.preventDefault(a)):void 0},c.prototype._keyPress=function(a){var b,c;return a.which?b=a.which:(b=a.keyCode,c=k.isSpecialKey(b)),k.isDelKey(b)||c||k.isModifier(a)?void 0:(this._processKey(String.fromCharCode(b),!1),k.preventDefault(a))},c.prototype._paste=function(a){return this._processKey(k.getClip(a),!1),k.preventDefault(a)},c.prototype._focus=function(){var a=this;setTimeout(function(){var b=j.get(a.el),c=b.end>a.focus;isFirstChar=0===b.end,(c||isFirstChar)&&j.set(a.el,a.focus)},0)},c.prototype._processKey=function(a,b){this.sel=j.get(this.el),this.val=this.el.value,this.delta=0,this.sel.begin!==this.sel.end?(this.delta=-1*Math.abs(this.sel.begin-this.sel.end),this.val=k.removeChars(this.val,this.sel.begin,this.sel.end)):b&&(46==b&&this.sel.begin+1<this.val.length?(this.sel.end++,this.sel.begin++,this.val=k.removeChars(this.val,this.sel.end-1,this.sel.end),this.delta=-1):this.sel.begin-1>=0&&(this.val=k.removeChars(this.val,this.sel.end-1,this.sel.end),this.delta=-1)),b||(this.val=k.addChars(this.val,a,this.sel.begin),this.delta+=a.length),this._formatValue()},c.prototype._formatValue=function(){this.curPos=this.sel.end,this.newPos=this.curPos+this.delta,this._removeChars(),this._validateInpts(),this._addChars(),this.el.value=this.val.substr(0,this.mLength),j.set(this.el,this.newPos)},c.prototype._removeChars=function(){this.sel.end>this.focus&&(this.delta+=this.sel.end-this.focus);for(var a=0,b=0;b<=this.mLength;b++){var c,d=this.chars[b],e=this.hldrs[b],f=b+a;f=b>=this.sel.begin?f+this.delta:f,c=this.val[f],(d&&d==c||e&&e==c)&&(this.val=k.removeChars(this.val,f,f+1),a--)}this.hldrs={},this.focus=this.val.length},c.prototype._validateInpts=function(){for(var a=0;a<this.val.length;a++){var b=this.inpts[a];e[b]&&e[b].test(this.val[a])||this.inpts[a]&&(this.val=k.removeChars(this.val,a,a+1),this.focusStart--,this.newPos--,this.delta--,a--)}},c.prototype._addChars=function(){if(this.opts.persistent){for(var a=0;a<=this.mLength;a++)this.val[a]||(this.val=k.addChars(this.val,this.opts.placeholder,a),this.hldrs[a]=this.opts.placeholder),this._addChar(a);for(;this.chars[this.focus];)this.focus++}else for(var b=0;b<=this.val.length;b++)this._addChar(b)},c.prototype._addChar=function(a){var b=this.chars[a];return b?(k.isBetween(a,[this.sel.begin-1,this.newPos+1])&&(this.newPos++,this.delta++),a<=this.focus&&this.focus++,this.delta<0&&this.val[a]==b?!0:(this.hldrs[a]&&(delete this.hldrs[a],this.hldrs[a+1]=this.opts.placeholder),this.val=k.addChars(this.val,b,a),void 0)):!0};var f={},g=4,h=new RegExp("{{([^}]+)}}","g"),i=function(a){for(var b,c=[];b=h.exec(a);)c.push(b);return c};f.parse=function(a){var b={inpts:{},chars:{}},c=i(a),d=a.length,e=0,f=0,h=0,j=function(a){for(var c=a.length,d=0;c>d;d++)b.inpts[f]=a[d],f++;e++,h+=a.length+g-1};for(h;d>h;h++)h==c[e].index?j(c[e][1]):b.chars[h-e*g]=a[h];return b.mLength=h-e*g,b};var j={};j.get=function(a){if("number"==typeof a.selectionStart)return{begin:a.selectionStart,end:a.selectionEnd};var c=b.selection.createRange();if(c&&c.parentElement()==a){var d=a.createTextRange(),e=a.createTextRange(),f=a.value.length;return d.moveToBookmark(c.getBookmark()),e.collapse(!1),d.compareEndPoints("StartToEnd",e)>-1?{begin:f,end:f}:{begin:-d.moveStart("character",-f),end:-d.moveEnd("character",-f)}}return{begin:0,end:0}},j.set=function(a,b){if(a.setSelectionRange)a.focus(),a.setSelectionRange(b,b);else if(a.createTextRange){var c=a.createTextRange();c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",b),c.select()}};var k={},l="undefined"!=typeof navigator?navigator.userAgent:null,m=/iphone/i.test(l);k.extend=function(a){for(var b=1;b<arguments.length;b++)for(var c in arguments[b])a[c]=arguments[b][c];return a},k.addChars=function(a,b,c){return a.substr(0,c)+b+a.substr(c,a.length)},k.removeChars=function(a,b,c){return a.substr(0,b)+a.substr(c,a.length)},k.isBetween=function(a,b){return b.sort(function(a,b){return a-b}),a>b[0]&&a<b[1]},k.addListener=function(a,b,c){return"undefined"!=typeof a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent("on"+b,c)},k.preventDefault=function(a){return a.preventDefault?a.preventDefault():a.returnValue=!1},k.getClip=function(b){return b.clipboardData?b.clipboardData.getData("Text"):a.clipboardData?a.clipboardData.getData("Text"):void 0},k.isDelKey=function(a){return 8===a||46===a||m&&127===a},k.isSpecialKey=function(a){var b={35:"end",36:"home",37:"leftarrow",38:"uparrow",39:"rightarrow",40:"downarrow"};return b[a]},k.isModifier=function(a){return a.ctrlKey||a.altKey||a.metaKey}}(window,document);
\ No newline at end of file
diff --git a/lib/jquery.formatter.js b/lib/jquery.formatter.js
index b8d5172..c287349 100644
--- a/lib/jquery.formatter.js
+++ b/lib/jquery.formatter.js
@@ -110,13 +110,17 @@ Formatter.prototype._keyDown = function (evt) {
 //
 Formatter.prototype._keyPress = function (evt) {
   // The first thing we need is the character code
-  var k;
+  var k, isSpecial;
   // Mozilla will trigger on special keys and assign the the value 0
   // We want to use that 0 rather than the keyCode it assigns.
-  k = (evt.which || evt.which === 0) ? evt.which : evt.keyCode;
-
+  if (evt.which) {
+    k = evt.which;
+  } else {
+    k = evt.keyCode;
+    isSpecial = utils.isSpecialKey(k);
+  }
   // Process the keyCode and prevent default
-  if (!utils.isSpecialKey(k) && !utils.isModifier(evt)) {
+  if (!utils.isDelKey(k) && !isSpecial && !utils.isModifier(evt)) {
     this._processKey(String.fromCharCode(k), false);
     return utils.preventDefault(evt);
   }
@@ -564,9 +568,7 @@ utils.isSpecialKey = function (k) {
     '40': 'downarrow'
   };
   // If del or special key
-  return (this.isDelKey(k) || codes[k])
-    ? true
-    : false;
+  return codes[k];
 };
 
 //
diff --git a/lib/jquery.formatter.min.js b/lib/jquery.formatter.min.js
index d9568b4..b710dda 100644
--- a/lib/jquery.formatter.min.js
+++ b/lib/jquery.formatter.min.js
@@ -6,4 +6,4 @@
  * thanks to digitalBush/jquery.maskedinput for some of the trickier
  * keycode handling
  */
-!function(a,b,c){function d(a,b){var c=this;if(c.el=a,!c.el)throw new TypeError("Must provide an existing element");if(c.opts=l.extend({},e,b),"undefined"==typeof c.opts.pattern)throw new TypeError("Must provide a pattern");var d=g.parse(c.opts.pattern);c.mLength=d.mLength,c.chars=d.chars,c.inpts=d.inpts,c.hldrs={},c.focus=0,l.addListener(c.el,"keydown",function(a){c._keyDown(a)}),l.addListener(c.el,"keypress",function(a){c._keyPress(a)}),l.addListener(c.el,"paste",function(a){c._paste(a)}),c.opts.persistent&&(c._processKey(null,!0),c.el.blur(),l.addListener(c.el,"focus",function(a){c._focus(a)}),l.addListener(c.el,"click",function(a){c._focus(a)}),l.addListener(c.el,"touchstart",function(a){c._focus(a)}))}var e={persistent:!1,repeat:!1,placeholder:" "},f={9:new RegExp("[0-9]"),a:new RegExp("[A-Za-z]"),"*":new RegExp("[A-Za-z0-9]")};d.prototype._keyDown=function(a){var b=a.which||a.keyCode;return b&&l.isDelKey(b)?(this._processKey(null,b),l.preventDefault(a)):void 0},d.prototype._keyPress=function(a){var b;return b=a.which||0===a.which?a.which:a.keyCode,l.isSpecialKey(b)||l.isModifier(a)?void 0:(this._processKey(String.fromCharCode(b),!1),l.preventDefault(a))},d.prototype._paste=function(a){return this._processKey(l.getClip(a),!1),l.preventDefault(a)},d.prototype._focus=function(){var a=this;setTimeout(function(){var b=k.get(a.el),c=b.end>a.focus;isFirstChar=0===b.end,(c||isFirstChar)&&k.set(a.el,a.focus)},0)},d.prototype._processKey=function(a,b){this.sel=k.get(this.el),this.val=this.el.value,this.delta=0,this.sel.begin!==this.sel.end?(this.delta=-1*Math.abs(this.sel.begin-this.sel.end),this.val=l.removeChars(this.val,this.sel.begin,this.sel.end)):b&&(46==b&&this.sel.begin+1<this.val.length?(this.sel.end++,this.sel.begin++,this.val=l.removeChars(this.val,this.sel.end-1,this.sel.end),this.delta=-1):this.sel.begin-1>=0&&(this.val=l.removeChars(this.val,this.sel.end-1,this.sel.end),this.delta=-1)),b||(this.val=l.addChars(this.val,a,this.sel.begin),this.delta+=a.length),this._formatValue()},d.prototype._formatValue=function(){this.curPos=this.sel.end,this.newPos=this.curPos+this.delta,this._removeChars(),this._validateInpts(),this._addChars(),this.el.value=this.val.substr(0,this.mLength),k.set(this.el,this.newPos)},d.prototype._removeChars=function(){this.sel.end>this.focus&&(this.delta+=this.sel.end-this.focus);for(var a=0,b=0;b<=this.mLength;b++){var c,d=this.chars[b],e=this.hldrs[b],f=b+a;f=b>=this.sel.begin?f+this.delta:f,c=this.val[f],(d&&d==c||e&&e==c)&&(this.val=l.removeChars(this.val,f,f+1),a--)}this.hldrs={},this.focus=this.val.length},d.prototype._validateInpts=function(){for(var a=0;a<this.val.length;a++){var b=this.inpts[a];f[b]&&f[b].test(this.val[a])||this.inpts[a]&&(this.val=l.removeChars(this.val,a,a+1),this.focusStart--,this.newPos--,this.delta--,a--)}},d.prototype._addChars=function(){if(this.opts.persistent){for(var a=0;a<=this.mLength;a++)this.val[a]||(this.val=l.addChars(this.val,this.opts.placeholder,a),this.hldrs[a]=this.opts.placeholder),this._addChar(a);for(;this.chars[this.focus];)this.focus++}else for(var b=0;b<=this.val.length;b++)this._addChar(b)},d.prototype._addChar=function(a){var b=this.chars[a];return b?(l.isBetween(a,[this.sel.begin-1,this.newPos+1])&&(this.newPos++,this.delta++),a<=this.focus&&this.focus++,this.delta<0&&this.val[a]==b?!0:(this.hldrs[a]&&(delete this.hldrs[a],this.hldrs[a+1]=this.opts.placeholder),this.val=l.addChars(this.val,b,a),void 0)):!0};var g={},h=4,i=new RegExp("{{([^}]+)}}","g"),j=function(a){for(var b,c=[];b=i.exec(a);)c.push(b);return c};g.parse=function(a){var b={inpts:{},chars:{}},c=j(a),d=a.length,e=0,f=0,g=0,i=function(a){for(var c=a.length,d=0;c>d;d++)b.inpts[f]=a[d],f++;e++,g+=a.length+h-1};for(g;d>g;g++)g==c[e].index?i(c[e][1]):b.chars[g-e*h]=a[g];return b.mLength=g-e*h,b};var k={};k.get=function(a){if("number"==typeof a.selectionStart)return{begin:a.selectionStart,end:a.selectionEnd};var b=c.selection.createRange();if(b&&b.parentElement()==a){var d=a.createTextRange(),e=a.createTextRange(),f=a.value.length;return d.moveToBookmark(b.getBookmark()),e.collapse(!1),d.compareEndPoints("StartToEnd",e)>-1?{begin:f,end:f}:{begin:-d.moveStart("character",-f),end:-d.moveEnd("character",-f)}}return{begin:0,end:0}},k.set=function(a,b){if(a.setSelectionRange)a.focus(),a.setSelectionRange(b,b);else if(a.createTextRange){var c=a.createTextRange();c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",b),c.select()}};var l={},m="undefined"!=typeof navigator?navigator.userAgent:null,n=/iphone/i.test(m);l.extend=function(a){for(var b=1;b<arguments.length;b++)for(var c in arguments[b])a[c]=arguments[b][c];return a},l.addChars=function(a,b,c){return a.substr(0,c)+b+a.substr(c,a.length)},l.removeChars=function(a,b,c){return a.substr(0,b)+a.substr(c,a.length)},l.isBetween=function(a,b){return b.sort(function(a,b){return a-b}),a>b[0]&&a<b[1]},l.addListener=function(a,b,c){return"undefined"!=typeof a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent("on"+b,c)},l.preventDefault=function(a){return a.preventDefault?a.preventDefault():a.returnValue=!1},l.getClip=function(a){return a.clipboardData?a.clipboardData.getData("Text"):b.clipboardData?b.clipboardData.getData("Text"):void 0},l.isDelKey=function(a){return 8===a||46===a||n&&127===a},l.isSpecialKey=function(a){var b={35:"end",36:"home",37:"leftarrow",38:"uparrow",39:"rightarrow",40:"downarrow"};return this.isDelKey(a)||b[a]?!0:!1},l.isModifier=function(a){return a.ctrlKey||a.altKey||a.metaKey};var o="formatter";a.fn[o]=function(b){return this.each(function(){a.data(this,"plugin_"+o)||a.data(this,"plugin_"+o,new d(this,b))})}}(jQuery,window,document);
\ No newline at end of file
+!function(a,b,c){function d(a,b){var c=this;if(c.el=a,!c.el)throw new TypeError("Must provide an existing element");if(c.opts=l.extend({},e,b),"undefined"==typeof c.opts.pattern)throw new TypeError("Must provide a pattern");var d=g.parse(c.opts.pattern);c.mLength=d.mLength,c.chars=d.chars,c.inpts=d.inpts,c.hldrs={},c.focus=0,l.addListener(c.el,"keydown",function(a){c._keyDown(a)}),l.addListener(c.el,"keypress",function(a){c._keyPress(a)}),l.addListener(c.el,"paste",function(a){c._paste(a)}),c.opts.persistent&&(c._processKey(null,!0),c.el.blur(),l.addListener(c.el,"focus",function(a){c._focus(a)}),l.addListener(c.el,"click",function(a){c._focus(a)}),l.addListener(c.el,"touchstart",function(a){c._focus(a)}))}var e={persistent:!1,repeat:!1,placeholder:" "},f={9:new RegExp("[0-9]"),a:new RegExp("[A-Za-z]"),"*":new RegExp("[A-Za-z0-9]")};d.prototype._keyDown=function(a){var b=a.which||a.keyCode;return b&&l.isDelKey(b)?(this._processKey(null,b),l.preventDefault(a)):void 0},d.prototype._keyPress=function(a){var b,c;return a.which?b=a.which:(b=a.keyCode,c=l.isSpecialKey(b)),l.isDelKey(b)||c||l.isModifier(a)?void 0:(this._processKey(String.fromCharCode(b),!1),l.preventDefault(a))},d.prototype._paste=function(a){return this._processKey(l.getClip(a),!1),l.preventDefault(a)},d.prototype._focus=function(){var a=this;setTimeout(function(){var b=k.get(a.el),c=b.end>a.focus;isFirstChar=0===b.end,(c||isFirstChar)&&k.set(a.el,a.focus)},0)},d.prototype._processKey=function(a,b){this.sel=k.get(this.el),this.val=this.el.value,this.delta=0,this.sel.begin!==this.sel.end?(this.delta=-1*Math.abs(this.sel.begin-this.sel.end),this.val=l.removeChars(this.val,this.sel.begin,this.sel.end)):b&&(46==b&&this.sel.begin+1<this.val.length?(this.sel.end++,this.sel.begin++,this.val=l.removeChars(this.val,this.sel.end-1,this.sel.end),this.delta=-1):this.sel.begin-1>=0&&(this.val=l.removeChars(this.val,this.sel.end-1,this.sel.end),this.delta=-1)),b||(this.val=l.addChars(this.val,a,this.sel.begin),this.delta+=a.length),this._formatValue()},d.prototype._formatValue=function(){this.curPos=this.sel.end,this.newPos=this.curPos+this.delta,this._removeChars(),this._validateInpts(),this._addChars(),this.el.value=this.val.substr(0,this.mLength),k.set(this.el,this.newPos)},d.prototype._removeChars=function(){this.sel.end>this.focus&&(this.delta+=this.sel.end-this.focus);for(var a=0,b=0;b<=this.mLength;b++){var c,d=this.chars[b],e=this.hldrs[b],f=b+a;f=b>=this.sel.begin?f+this.delta:f,c=this.val[f],(d&&d==c||e&&e==c)&&(this.val=l.removeChars(this.val,f,f+1),a--)}this.hldrs={},this.focus=this.val.length},d.prototype._validateInpts=function(){for(var a=0;a<this.val.length;a++){var b=this.inpts[a];f[b]&&f[b].test(this.val[a])||this.inpts[a]&&(this.val=l.removeChars(this.val,a,a+1),this.focusStart--,this.newPos--,this.delta--,a--)}},d.prototype._addChars=function(){if(this.opts.persistent){for(var a=0;a<=this.mLength;a++)this.val[a]||(this.val=l.addChars(this.val,this.opts.placeholder,a),this.hldrs[a]=this.opts.placeholder),this._addChar(a);for(;this.chars[this.focus];)this.focus++}else for(var b=0;b<=this.val.length;b++)this._addChar(b)},d.prototype._addChar=function(a){var b=this.chars[a];return b?(l.isBetween(a,[this.sel.begin-1,this.newPos+1])&&(this.newPos++,this.delta++),a<=this.focus&&this.focus++,this.delta<0&&this.val[a]==b?!0:(this.hldrs[a]&&(delete this.hldrs[a],this.hldrs[a+1]=this.opts.placeholder),this.val=l.addChars(this.val,b,a),void 0)):!0};var g={},h=4,i=new RegExp("{{([^}]+)}}","g"),j=function(a){for(var b,c=[];b=i.exec(a);)c.push(b);return c};g.parse=function(a){var b={inpts:{},chars:{}},c=j(a),d=a.length,e=0,f=0,g=0,i=function(a){for(var c=a.length,d=0;c>d;d++)b.inpts[f]=a[d],f++;e++,g+=a.length+h-1};for(g;d>g;g++)g==c[e].index?i(c[e][1]):b.chars[g-e*h]=a[g];return b.mLength=g-e*h,b};var k={};k.get=function(a){if("number"==typeof a.selectionStart)return{begin:a.selectionStart,end:a.selectionEnd};var b=c.selection.createRange();if(b&&b.parentElement()==a){var d=a.createTextRange(),e=a.createTextRange(),f=a.value.length;return d.moveToBookmark(b.getBookmark()),e.collapse(!1),d.compareEndPoints("StartToEnd",e)>-1?{begin:f,end:f}:{begin:-d.moveStart("character",-f),end:-d.moveEnd("character",-f)}}return{begin:0,end:0}},k.set=function(a,b){if(a.setSelectionRange)a.focus(),a.setSelectionRange(b,b);else if(a.createTextRange){var c=a.createTextRange();c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",b),c.select()}};var l={},m="undefined"!=typeof navigator?navigator.userAgent:null,n=/iphone/i.test(m);l.extend=function(a){for(var b=1;b<arguments.length;b++)for(var c in arguments[b])a[c]=arguments[b][c];return a},l.addChars=function(a,b,c){return a.substr(0,c)+b+a.substr(c,a.length)},l.removeChars=function(a,b,c){return a.substr(0,b)+a.substr(c,a.length)},l.isBetween=function(a,b){return b.sort(function(a,b){return a-b}),a>b[0]&&a<b[1]},l.addListener=function(a,b,c){return"undefined"!=typeof a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent("on"+b,c)},l.preventDefault=function(a){return a.preventDefault?a.preventDefault():a.returnValue=!1},l.getClip=function(a){return a.clipboardData?a.clipboardData.getData("Text"):b.clipboardData?b.clipboardData.getData("Text"):void 0},l.isDelKey=function(a){return 8===a||46===a||n&&127===a},l.isSpecialKey=function(a){var b={35:"end",36:"home",37:"leftarrow",38:"uparrow",39:"rightarrow",40:"downarrow"};return b[a]},l.isModifier=function(a){return a.ctrlKey||a.altKey||a.metaKey};var o="formatter";a.fn[o]=function(b){return this.each(function(){a.data(this,"plugin_"+o)||a.data(this,"plugin_"+o,new d(this,b))})}}(jQuery,window,document);
\ No newline at end of file
diff --git a/src/formatter.js b/src/formatter.js
index e3fa29e..fe536ee 100644
--- a/src/formatter.js
+++ b/src/formatter.js
@@ -115,13 +115,17 @@ Formatter.prototype._keyDown = function (evt) {
 //
 Formatter.prototype._keyPress = function (evt) {
   // The first thing we need is the character code
-  var k;
+  var k, isSpecial;
   // Mozilla will trigger on special keys and assign the the value 0
   // We want to use that 0 rather than the keyCode it assigns.
-  k = (evt.which || evt.which === 0) ? evt.which : evt.keyCode;
-
+  if (evt.which) {
+    k = evt.which;
+  } else {
+    k = evt.keyCode;
+    isSpecial = utils.isSpecialKey(k);
+  }
   // Process the keyCode and prevent default
-  if (!utils.isSpecialKey(k) && !utils.isModifier(evt)) {
+  if (!utils.isDelKey(k) && !isSpecial && !utils.isModifier(evt)) {
     this._processKey(String.fromCharCode(k), false);
     return utils.preventDefault(evt);
   }
diff --git a/src/utils.js b/src/utils.js
index af09eff..a7292d2 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -91,9 +91,7 @@ utils.isSpecialKey = function (k) {
     '40': 'downarrow'
   };
   // If del or special key
-  return (this.isDelKey(k) || codes[k])
-    ? true
-    : false;
+  return codes[k];
 };
 
 //
diff --git a/test/fake-user/keys.js b/test/fake-user/keys.js
index 6b44f5e..8355db5 100644
--- a/test/fake-user/keys.js
+++ b/test/fake-user/keys.js
@@ -26,7 +26,7 @@ var fixChar = function (char) {
 // Method to get key press obj
 //
 keys.getPress = function (char) {
-  return keys.down[fixChar(char)];
+  return keys.press[fixChar(char)];
 };
 
 //
diff --git a/test/fake-user/user.js b/test/fake-user/user.js
index 49ad8f8..1a89b28 100644
--- a/test/fake-user/user.js
+++ b/test/fake-user/user.js
@@ -38,13 +38,13 @@ User.prototype.key = function (char, opts) {
   // If no opts passed, create blank obj
   if (!opts) { opts = {}; }
 
-  if (keyPress.which || keyPress.keyCode) {
+  if (keyPress) {
     opts.which = keyPress.which;
     opts.keyCode = keyPress.keyCode;
     opts.shiftKey = keyPress.shiftKey;
     this.emit('keypress', new events.KeyEvent(opts));
   }
-  if (keyDown.which || keyDown.keyCode) {
+  if (keyDown.which) {
     opts.which = keyDown.which;
     opts.keyCode = keyDown.keyCode;
     opts.shiftKey = keyDown.shiftKey;
