1/* 2 Masked Input plugin for jQuery 3 Copyright (c) 2007-2011 Josh Bush (digitalbush.com) 4 Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license) 5 Version: 1.3 6*/ 7(function($) { 8 var pasteEventName = ($.browser.msie ? 'paste' : 'input') + ".mask"; 9 var iPhone = (window.orientation != undefined); 10 11 $.mask = { 12 //Predefined character definitions 13 definitions: { 14 '9': "[0-9]", 15 'a': "[A-Za-z]", 16 '*': "[A-Za-z0-9]" 17 }, 18 dataName:"rawMaskFn" 19 }; 20 21 $.fn.extend({ 22 //Helper Function for Caret positioning 23 caret: function(begin, end) { 24 if (this.length == 0) return; 25 if (typeof begin == 'number') { 26 end = (typeof end == 'number') ? end : begin; 27 return this.each(function() { 28 if (this.setSelectionRange) { 29 this.setSelectionRange(begin, end); 30 } else if (this.createTextRange) { 31 var range = this.createTextRange(); 32 range.collapse(true); 33 range.moveEnd('character', end); 34 range.moveStart('character', begin); 35 range.select(); 36 } 37 }); 38 } else { 39 if (this[0].setSelectionRange) { 40 begin = this[0].selectionStart; 41 end = this[0].selectionEnd; 42 } else if (document.selection && document.selection.createRange) { 43 var range = document.selection.createRange(); 44 begin = 0 - range.duplicate().moveStart('character', -100000); 45 end = begin + range.text.length; 46 } 47 return { begin: begin, end: end }; 48 } 49 }, 50 unmask: function() { return this.trigger("unmask"); }, 51 mask: function(mask, settings) { 52 if (!mask && this.length > 0) { 53 var input = $(this[0]); 54 return input.data($.mask.dataName)(); 55 } 56 settings = $.extend({ 57 placeholder: "_", 58 completed: null 59 }, settings); 60 61 var defs = $.mask.definitions; 62 var tests = []; 63 var partialPosition = mask.length; 64 var firstNonMaskPos = null; 65 var len = mask.length; 66 67 $.each(mask.split(""), function(i, c) { 68 if (c == '?') { 69 len--; 70 partialPosition = i; 71 } else if (defs[c]) { 72 tests.push(new RegExp(defs[c])); 73 if(firstNonMaskPos==null) 74 firstNonMaskPos = tests.length - 1; 75 } else { 76 tests.push(null); 77 } 78 }); 79 80 return this.trigger("unmask").each(function() { 81 var input = $(this); 82 var buffer = $.map(mask.split(""), function(c, i) { if (c != '?') return defs[c] ? settings.placeholder : c }); 83 var focusText = input.val(); 84 85 function seekNext(pos) { 86 while (++pos <= len && !tests[pos]); 87 return pos; 88 }; 89 function seekPrev(pos) { 90 while (--pos >= 0 && !tests[pos]); 91 return pos; 92 }; 93 94 function shiftL(begin,end) { 95 if(begin<0) 96 return; 97 for (var i = begin,j = seekNext(end); i < len; i++) { 98 if (tests[i]) { 99 if (j < len && tests[i].test(buffer[j])) { 100 buffer[i] = buffer[j]; 101 buffer[j] = settings.placeholder; 102 } else 103 break; 104 j = seekNext(j); 105 } 106 } 107 writeBuffer(); 108 input.caret(Math.max(firstNonMaskPos, begin)); 109 }; 110 111 function shiftR(pos) { 112 for (var i = pos, c = settings.placeholder; i < len; i++) { 113 if (tests[i]) { 114 var j = seekNext(i); 115 var t = buffer[i]; 116 buffer[i] = c; 117 if (j < len && tests[j].test(t)) 118 c = t; 119 else 120 break; 121 } 122 } 123 }; 124 125 function keydownEvent(e) { 126 var k=e.which; 127 128 //backspace, delete, and escape get special treatment 129 if(k == 8 || k == 46 || (iPhone && k == 127)){ 130 var pos = input.caret(), 131 begin = pos.begin, 132 end = pos.end; 133 134 if(end-begin==0){ 135 begin=k!=46?seekPrev(begin):(end=seekNext(begin-1)); 136 end=k==46?seekNext(end):end; 137 } 138 clearBuffer(begin, end); 139 shiftL(begin,end-1); 140 141 return false; 142 } else if (k == 27) {//escape 143 input.val(focusText); 144 input.caret(0, checkVal()); 145 return false; 146 } 147 }; 148 149 function keypressEvent(e) { 150 var k = e.which, 151 pos = input.caret(); 152 if (e.ctrlKey || e.altKey || e.metaKey || k<32) {//Ignore 153 return true; 154 } else if (k) { 155 if(pos.end-pos.begin!=0){ 156 clearBuffer(pos.begin, pos.end); 157 shiftL(pos.begin, pos.end-1); 158 } 159 160 var p = seekNext(pos.begin - 1); 161 if (p < len) { 162 var c = String.fromCharCode(k); 163 if (tests[p].test(c)) { 164 shiftR(p); 165 buffer[p] = c; 166 writeBuffer(); 167 var next = seekNext(p); 168 input.caret(next); 169 if (settings.completed && next >= len) 170 settings.completed.call(input); 171 } 172 } 173 return false;
174 } 175 }; 176 177 function clearBuffer(start, end) { 178 for (var i = start; i < end && i < len; i++) { 179 if (tests[i]) 180 buffer[i] = settings.placeholder; 181 } 182 }; 183 184 function writeBuffer() { return input.val(buffer.join('')).val(); }; 185 186 function checkVal(allow) { 187 //try to place characters where they belong 188 var test = input.val(); 189 var lastMatch = -1; 190 for (var i = 0, pos = 0; i < len; i++) { 191 if (tests[i]) { 192 buffer[i] = settings.placeholder; 193 while (pos++ < test.length) { 194 var c = test.charAt(pos - 1); 195 if (tests[i].test(c)) { 196 buffer[i] = c; 197 lastMatch = i; 198 break; 199 } 200 } 201 if (pos > test.length) 202 break; 203 } else if (buffer[i] == test.charAt(pos) && i!=partialPosition) { 204 pos++; 205 lastMatch = i; 206 } 207 } 208 if (!allow && lastMatch + 1 < partialPosition) { 209 input.val(""); 210 clearBuffer(0, len); 211 } else if (allow || lastMatch + 1 >= partialPosition) { 212 writeBuffer(); 213 if (!allow) input.val(input.val().substring(0, lastMatch + 1)); 214 } 215 return (partialPosition ? i : firstNonMaskPos); 216 }; 217 218 input.data($.mask.dataName,function(){ 219 return $.map(buffer, function(c, i) { 220 return tests[i]&&c!=settings.placeholder ? c : null; 221 }).join(''); 222 }) 223 224 if (!input.attr("readonly")) 225 input 226 .one("unmask", function() { 227 input 228 .unbind(".mask") 229 .removeData($.mask.dataName); 230 }) 231 .bind("focus.mask", function() { 232 focusText = input.val(); 233 var pos = checkVal(); 234 writeBuffer(); 235 var moveCaret=function(){ 236 if (pos == mask.length) 237 input.caret(0, pos); 238 else 239 input.caret(pos); 240 }; 241 ($.browser.msie ? moveCaret:function(){setTimeout(moveCaret,0)})(); 242 }) 243 .bind("blur.mask", function() { 244 checkVal(); 245 if (input.val() != focusText) 246 input.change(); 247 }) 248 .bind("keydown.mask", keydownEvent) 249 .bind("keypress.mask", keypressEvent) 250 .bind(pasteEventName, function() { 251 setTimeout(function() { input.caret(checkVal(true)); }, 0); 252 }); 253 254 checkVal(); //Perform initial check for existing values 255 }); 256 } 257 }); 258})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.