1/* 2 * Copyright (c) 2007-2008 Josh Bush (digitalbush.com) 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, 8 * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 * copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following 11 * conditions: 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25/* 26 * Version: 1.1.4 27 * Release: 2008-07-29 28 */ 29(function($) { 30 31 //Helper Function for Caret positioning 32 $.fn.caret = function(begin, end) { 33 if (this.length == 0) return; 34 if (typeof begin == 'number') { 35 end = (typeof end == 'number') ? end : begin; 36 return this.each(function() { 37 if (this.setSelectionRange) { 38 this.focus(); 39 this.setSelectionRange(begin, end); 40 } else if (this.createTextRange) { 41 var range = this.createTextRange(); 42 range.collapse(true); 43 range.moveEnd('character', end); 44 range.moveStart('character', begin); 45 range.select(); 46 } 47 }); 48 } else { 49 if (this[0].setSelectionRange) { 50 begin = this[0].selectionStart; 51 end = this[0].selectionEnd; 52 } else if (document.selection && document.selection.createRange) { 53 var range = document.selection.createRange(); 54 begin = 0 - range.duplicate().moveStart('character', -100000); 55 end = begin + range.text.length; 56 } 57 return { begin: begin, end: end }; 58 } 59 }; 60 61 //Predefined character definitions 62 var charMap = { 63 '9': "[0-9]", 64 'a': "[A-Za-z]", 65 '*': "[A-Za-z0-9]" 66 }; 67 68 //Helper method to inject character definitions 69 $.mask = { 70 addPlaceholder: function(c, r) { 71 charMap[c] = r; 72 } 73 }; 74 75 $.fn.unmask = function() { 76 return this.trigger("unmask"); 77 }; 78 79 //Main Method 80 $.fn.mask = function(mask, settings) { 81 settings = $.extend({ 82 placeholder: "_", 83 completed: null 84 }, settings); 85 86 //Build Regex for format validation 87 var re = new RegExp("^" + 88 $.map(mask.split(""), function(c, i) { 89 return charMap[c] || ((/[A-Za-z0-9]/.test(c) ? "" : "\\") + c); 90 }).join('') + 91 "$"); 92 93 return this.each(function() { 94 var input = $(this); 95 var buffer = new Array(mask.length); 96 var locked = new Array(mask.length); 97 var valid = false; 98 var ignore = false; //Variable for ignoring control keys 99 var firstNonMaskPos = null; 100 101 //Build buffer layout from mask & determine the first non masked character 102 $.each(mask.split(""), function(i, c) { 103 locked[i] = (charMap[c] == null); 104 buffer[i] = locked[i] ? c : settings.placeholder; 105 if (!locked[i] && firstNonMaskPos == null) 106 firstNonMaskPos = i; 107 }); 108 109 function focusEvent() { 110 checkVal(); 111 writeBuffer(); 112 setTimeout(function() { 113 $(input[0]).caret(valid ? mask.length : firstNonMaskPos);
114 }, 0); 115 }; 116 117 function keydownEvent(e) { 118 var pos = $(this).caret(); 119 var k = e.keyCode; 120 ignore = (k < 16 || (k > 16 && k < 32) || (k > 32 && k < 41)); 121 122 //delete selection before proceeding 123 if ((pos.begin - pos.end) != 0 && (!ignore || k == 8 || k == 46)) { 124 clearBuffer(pos.begin, pos.end); 125 } 126 //backspace and delete get special treatment 127 if (k == 8) {//backspace 128 while (pos.begin-- >= 0) { 129 if (!locked[pos.begin]) { 130 buffer[pos.begin] = settings.placeholder; 131 if ($.browser.opera) { 132 //Opera won't let you cancel the backspace, so we'll let it backspace over a dummy character. 133 s = writeBuffer(); 134 input.val(s.substring(0, pos.begin) + " " + s.substring(pos.begin)); 135 $(this).caret(pos.begin + 1); 136 } else { 137 writeBuffer(); 138 $(this).caret(Math.max(firstNonMaskPos, pos.begin)); 139 } 140 return false; 141 } 142 } 143 } else if (k == 46) {//delete 144 clearBuffer(pos.begin, pos.begin + 1); 145 writeBuffer(); 146 $(this).caret(Math.max(firstNonMaskPos, pos.begin)); 147 return false; 148 } else if (k == 27) {//escape 149 clearBuffer(0, mask.length); 150 writeBuffer(); 151 $(this).caret(firstNonMaskPos); 152 return false; 153 } 154 }; 155 156 function keypressEvent(e) { 157 if (ignore) { 158 ignore = false; 159 //Fixes Mac FF bug on backspace 160 return (e.keyCode == 8) ? false : null; 161 } 162 e = e || window.event; 163 var k = e.charCode || e.keyCode || e.which; 164 var pos = $(this).caret(); 165 166 if (e.ctrlKey || e.altKey) {//Ignore 167 return true; 168 } else if ((k >= 41 && k <= 122) || k == 32 || k > 186) {//typeable characters 169 var p = seekNext(pos.begin - 1); 170 if (p < mask.length) { 171 if (new RegExp(charMap[mask.charAt(p)]).test(String.fromCharCode(k))) { 172 buffer[p] = String.fromCharCode(k); 173 writeBuffer(); 174 var next = seekNext(p); 175 $(this).caret(next); 176 if (settings.completed && next == mask.length) 177 settings.completed.call(input); 178 } 179 } 180 } 181 return false; 182 }; 183 184 function clearBuffer(start, end) { 185 for (var i = start; i < end && i < mask.length; i++) { 186 if (!locked[i]) 187 buffer[i] = settings.placeholder; 188 } 189 }; 190 191 function writeBuffer() { 192 return input.val(buffer.join('')).val(); 193 }; 194 195 function checkVal(init) { 196 //try to place charcters where they belong 197 var test = input.val(); 198 var pos = firstNonMaskPos; 199 for (var i = 0; i < mask.length; i++) { 200 if (!locked[i]) { 201 buffer[i] = settings.placeholder; 202 while (pos++ < test.length) { 203 //Regex Test each char here. 204 var reChar = new RegExp(charMap[mask.charAt(i)]); 205 if (test.charAt(pos - 1).match(reChar)) { 206 buffer[i] = test.charAt(pos - 1); 207 break; 208 } 209 } 210 } 211 } 212 var s = writeBuffer(); 213 if (!s.match(re)) { 214 //CHANGED HERE 215 if (init === true) { 216 input.val(""); 217 } 218 clearBuffer(0, mask.length); 219 valid = false; 220 } else 221 valid = true; 222 }; 223 224 function seekNext(pos) { 225 while (++pos < mask.length) { 226 if (!locked[pos]) 227 return pos; 228 } 229 return mask.length; 230 }; 231 232 input.one("unmask", function() { 233 input.unbind("focus", focusEvent); 234 input.unbind("blur", checkVal);
235 input.unbind("keydown", keydownEvent); 236 input.unbind("keypress", keypressEvent); 237 if ($.browser.msie) 238 this.onpaste = null; 239 else if ($.browser.mozilla) 240 this.removeEventListener('input', checkVal, false); 241 }); 242 input.bind("focus", focusEvent); 243 input.bind("blur", checkVal); 244 input.bind("keydown", keydownEvent); 245 input.bind("keypress", keypressEvent); 246 //Paste events for IE and Mozilla thanks to Kristinn Sigmundsson 247 if ($.browser.msie) 248 this.onpaste = function() { setTimeout(checkVal, 0); }; 249 else if ($.browser.mozilla) 250 this.addEventListener('input', checkVal, false); 251 252 //CHANGED HERE 253 checkVal(true); //Perform initial check for existing values 254 }); 255 }; 256})(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.