1
+ /*
2
+ jQuery Masked Input Plugin
3
+ Copyright (c) 2007 - 2015 Josh Bush (digitalbush.com)
4
+ Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license)
5
+ Version: 1.4.1
6
+ */
7
+ ! function ( factory ) {
8
+ "function" == typeof define && define . amd ? define ( [ "jquery" ] , factory ) : factory ( "object" == typeof exports ? require ( "jquery" ) : jQuery ) ;
9
+ } ( function ( $ ) {
10
+ var caretTimeoutId , ua = navigator . userAgent , iPhone = / i p h o n e / i. test ( ua ) , chrome = / c h r o m e / i. test ( ua ) , android = / a n d r o i d / i. test ( ua ) ;
11
+ $ . mask = {
12
+ definitions : {
13
+ "9" : "[0-9]" ,
14
+ a : "[A-Za-z]" ,
15
+ "*" : "[A-Za-z0-9]"
16
+ } ,
17
+ autoclear : ! 0 ,
18
+ dataName : "rawMaskFn" ,
19
+ placeholder : "_"
20
+ } , $ . fn . extend ( {
21
+ caret : function ( begin , end ) {
22
+ var range ;
23
+ if ( 0 !== this . length && ! this . is ( ":hidden" ) ) return "number" == typeof begin ? ( end = "number" == typeof end ? end : begin ,
24
+ this . each ( function ( ) {
25
+ this . setSelectionRange ? this . setSelectionRange ( begin , end ) : this . createTextRange && ( range = this . createTextRange ( ) ,
26
+ range . collapse ( ! 0 ) , range . moveEnd ( "character" , end ) , range . moveStart ( "character" , begin ) ,
27
+ range . select ( ) ) ;
28
+ } ) ) : ( this [ 0 ] . setSelectionRange ? ( begin = this [ 0 ] . selectionStart , end = this [ 0 ] . selectionEnd ) : document . selection && document . selection . createRange && ( range = document . selection . createRange ( ) ,
29
+ begin = 0 - range . duplicate ( ) . moveStart ( "character" , - 1e5 ) , end = begin + range . text . length ) ,
30
+ {
31
+ begin : begin ,
32
+ end : end
33
+ } ) ;
34
+ } ,
35
+ unmask : function ( ) {
36
+ return this . trigger ( "unmask" ) ;
37
+ } ,
38
+ mask : function ( mask , settings ) {
39
+ var input , defs , tests , partialPosition , firstNonMaskPos , lastRequiredNonMaskPos , len , oldVal ;
40
+ if ( ! mask && this . length > 0 ) {
41
+ input = $ ( this [ 0 ] ) ;
42
+ var fn = input . data ( $ . mask . dataName ) ;
43
+ return fn ? fn ( ) : void 0 ;
44
+ }
45
+ return settings = $ . extend ( {
46
+ autoclear : $ . mask . autoclear ,
47
+ placeholder : $ . mask . placeholder ,
48
+ completed : null
49
+ } , settings ) , defs = $ . mask . definitions , tests = [ ] , partialPosition = len = mask . length ,
50
+ firstNonMaskPos = null , $ . each ( mask . split ( "" ) , function ( i , c ) {
51
+ "?" == c ? ( len -- , partialPosition = i ) : defs [ c ] ? ( tests . push ( new RegExp ( defs [ c ] ) ) ,
52
+ null === firstNonMaskPos && ( firstNonMaskPos = tests . length - 1 ) , partialPosition > i && ( lastRequiredNonMaskPos = tests . length - 1 ) ) : tests . push ( null ) ;
53
+ } ) , this . trigger ( "unmask" ) . each ( function ( ) {
54
+ function tryFireCompleted ( ) {
55
+ if ( settings . completed ) {
56
+ for ( var i = firstNonMaskPos ; lastRequiredNonMaskPos >= i ; i ++ ) if ( tests [ i ] && buffer [ i ] === getPlaceholder ( i ) ) return ;
57
+ settings . completed . call ( input ) ;
58
+ }
59
+ }
60
+ function getPlaceholder ( i ) {
61
+ return settings . placeholder . charAt ( i < settings . placeholder . length ? i : 0 ) ;
62
+ }
63
+ function seekNext ( pos ) {
64
+ for ( ; ++ pos < len && ! tests [ pos ] ; ) ;
65
+ return pos ;
66
+ }
67
+ function seekPrev ( pos ) {
68
+ for ( ; -- pos >= 0 && ! tests [ pos ] ; ) ;
69
+ return pos ;
70
+ }
71
+ function shiftL ( begin , end ) {
72
+ var i , j ;
73
+ if ( ! ( 0 > begin ) ) {
74
+ for ( i = begin , j = seekNext ( end ) ; len > i ; i ++ ) if ( tests [ i ] ) {
75
+ if ( ! ( len > j && tests [ i ] . test ( buffer [ j ] ) ) ) break ;
76
+ buffer [ i ] = buffer [ j ] , buffer [ j ] = getPlaceholder ( j ) , j = seekNext ( j ) ;
77
+ }
78
+ writeBuffer ( ) , input . caret ( Math . max ( firstNonMaskPos , begin ) ) ;
79
+ }
80
+ }
81
+ function shiftR ( pos ) {
82
+ var i , c , j , t ;
83
+ for ( i = pos , c = getPlaceholder ( pos ) ; len > i ; i ++ ) if ( tests [ i ] ) {
84
+ if ( j = seekNext ( i ) , t = buffer [ i ] , buffer [ i ] = c , ! ( len > j && tests [ j ] . test ( t ) ) ) break ;
85
+ c = t ;
86
+ }
87
+ }
88
+ function androidInputEvent ( ) {
89
+ var curVal = input . val ( ) , pos = input . caret ( ) ;
90
+ if ( oldVal && oldVal . length && oldVal . length > curVal . length ) {
91
+ for ( checkVal ( ! 0 ) ; pos . begin > 0 && ! tests [ pos . begin - 1 ] ; ) pos . begin -- ;
92
+ if ( 0 === pos . begin ) for ( ; pos . begin < firstNonMaskPos && ! tests [ pos . begin ] ; ) pos . begin ++ ;
93
+ input . caret ( pos . begin , pos . begin ) ;
94
+ } else {
95
+ for ( checkVal ( ! 0 ) ; pos . begin < len && ! tests [ pos . begin ] ; ) pos . begin ++ ;
96
+ input . caret ( pos . begin , pos . begin ) ;
97
+ }
98
+ tryFireCompleted ( ) ;
99
+ }
100
+ function blurEvent ( ) {
101
+ checkVal ( ) , input . val ( ) != focusText && input . change ( ) ;
102
+ }
103
+ function keydownEvent ( e ) {
104
+ if ( ! input . prop ( "readonly" ) ) {
105
+ var pos , begin , end , k = e . which || e . keyCode ;
106
+ oldVal = input . val ( ) , 8 === k || 46 === k || iPhone && 127 === k ? ( pos = input . caret ( ) ,
107
+ begin = pos . begin , end = pos . end , end - begin === 0 && ( begin = 46 !== k ? seekPrev ( begin ) : end = seekNext ( begin - 1 ) ,
108
+ end = 46 === k ? seekNext ( end ) : end ) , clearBuffer ( begin , end ) , shiftL ( begin , end - 1 ) ,
109
+ e . preventDefault ( ) ) : 13 === k ? blurEvent . call ( this , e ) : 27 === k && ( input . val ( focusText ) ,
110
+ input . caret ( 0 , checkVal ( ) ) , e . preventDefault ( ) ) ;
111
+ }
112
+ }
113
+ function keypressEvent ( e ) {
114
+ if ( ! input . prop ( "readonly" ) ) {
115
+ var p , c , next , k = e . which || e . keyCode , pos = input . caret ( ) ;
116
+ if ( ! ( e . ctrlKey || e . altKey || e . metaKey || 32 > k ) && k && 13 !== k ) {
117
+ if ( pos . end - pos . begin !== 0 && ( clearBuffer ( pos . begin , pos . end ) , shiftL ( pos . begin , pos . end - 1 ) ) ,
118
+ p = seekNext ( pos . begin - 1 ) , len > p && ( c = String . fromCharCode ( k ) , tests [ p ] . test ( c ) ) ) {
119
+ if ( shiftR ( p ) , buffer [ p ] = c , writeBuffer ( ) , next = seekNext ( p ) , android ) {
120
+ var proxy = function ( ) {
121
+ $ . proxy ( $ . fn . caret , input , next ) ( ) ;
122
+ } ;
123
+ setTimeout ( proxy , 0 ) ;
124
+ } else input . caret ( next ) ;
125
+ pos . begin <= lastRequiredNonMaskPos && tryFireCompleted ( ) ;
126
+ }
127
+ e . preventDefault ( ) ;
128
+ }
129
+ }
130
+ }
131
+ function clearBuffer ( start , end ) {
132
+ var i ;
133
+ for ( i = start ; end > i && len > i ; i ++ ) tests [ i ] && ( buffer [ i ] = getPlaceholder ( i ) ) ;
134
+ }
135
+ function writeBuffer ( ) {
136
+ input . val ( buffer . join ( "" ) ) ;
137
+ }
138
+ function checkVal ( allow ) {
139
+ var i , c , pos , test = input . val ( ) , lastMatch = - 1 ;
140
+ for ( i = 0 , pos = 0 ; len > i ; i ++ ) if ( tests [ i ] ) {
141
+ for ( buffer [ i ] = getPlaceholder ( i ) ; pos ++ < test . length ; ) if ( c = test . charAt ( pos - 1 ) ,
142
+ tests [ i ] . test ( c ) ) {
143
+ buffer [ i ] = c , lastMatch = i ;
144
+ break ;
145
+ }
146
+ if ( pos > test . length ) {
147
+ clearBuffer ( i + 1 , len ) ;
148
+ break ;
149
+ }
150
+ } else buffer [ i ] === test . charAt ( pos ) && pos ++ , partialPosition > i && ( lastMatch = i ) ;
151
+ return allow ? writeBuffer ( ) : partialPosition > lastMatch + 1 ? settings . autoclear || buffer . join ( "" ) === defaultBuffer ? ( input . val ( ) && input . val ( "" ) ,
152
+ clearBuffer ( 0 , len ) ) : writeBuffer ( ) : ( writeBuffer ( ) , input . val ( input . val ( ) . substring ( 0 , lastMatch + 1 ) ) ) ,
153
+ partialPosition ? i : firstNonMaskPos ;
154
+ }
155
+ var input = $ ( this ) , buffer = $ . map ( mask . split ( "" ) , function ( c , i ) {
156
+ return "?" != c ? defs [ c ] ? getPlaceholder ( i ) : c : void 0 ;
157
+ } ) , defaultBuffer = buffer . join ( "" ) , focusText = input . val ( ) ;
158
+ input . data ( $ . mask . dataName , function ( ) {
159
+ return $ . map ( buffer , function ( c , i ) {
160
+ return tests [ i ] && c != getPlaceholder ( i ) ? c : null ;
161
+ } ) . join ( "" ) ;
162
+ } ) , input . one ( "unmask" , function ( ) {
163
+ input . off ( ".mask" ) . removeData ( $ . mask . dataName ) ;
164
+ } ) . on ( "focus.mask" , function ( ) {
165
+ if ( ! input . prop ( "readonly" ) ) {
166
+ clearTimeout ( caretTimeoutId ) ;
167
+ var pos ;
168
+ focusText = input . val ( ) , pos = checkVal ( ) , caretTimeoutId = setTimeout ( function ( ) {
169
+ input . get ( 0 ) === document . activeElement && ( writeBuffer ( ) , pos == mask . replace ( "?" , "" ) . length ? input . caret ( 0 , pos ) : input . caret ( pos ) ) ;
170
+ } , 10 ) ;
171
+ }
172
+ } ) . on ( "blur.mask" , blurEvent ) . on ( "keydown.mask" , keydownEvent ) . on ( "keypress.mask" , keypressEvent ) . on ( "input.mask paste.mask" , function ( ) {
173
+ input . prop ( "readonly" ) || setTimeout ( function ( ) {
174
+ var pos = checkVal ( ! 0 ) ;
175
+ input . caret ( pos ) , tryFireCompleted ( ) ;
176
+ } , 0 ) ;
177
+ } ) , chrome && android && input . off ( "input.mask" ) . on ( "input.mask" , androidInputEvent ) ,
178
+ checkVal ( ) ;
179
+ } ) ;
180
+ }
181
+ } ) ;
182
+ } ) ;
0 commit comments