PageSourceSearch

https://link-elearning.com/site/public//javascript/ui.mask.js

js link-elearning.com collected 2026-10-02 13:38:30 UTC 11,018 bytes, 414 lines download raw bytes

1/*
2 * jQuery UI Mask @VERSION
3 *
4 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
5 * Dual licensed under the MIT (MIT-LICENSE.txt)
6 * and GPL (GPL-LICENSE.txt) licenses.
7 *
8 * Based on the jquery.maskedinput.js plugin by Josh Bush (digitalbush.com)
9 *
10 * http://docs.jquery.com/UI/Mask
11 *
12 * Depends:
13 *   ui.core.js
14 */
15(function($) {
16
17var pasteEventName = ($.browser.msie ? 'paste' : 'input') + ".mask";
18
19$.widget("ui.mask", {
20	
21	_init: function() {
22
23		var options = this.options, self = this;
24
25		$.extend(this, { caret: function(begin, end){ return $.ui.mask.caret(self.element, begin, end); } });
26
27		if(!options.mask || !options.mask.length){ return; } //no mask pattern defined. no point in continuing.
28		if(!options.placeholder || !options.placeholder.length){
29			options.placeholder = '_'; //in case the user decided to nix a placeholder. 
30		}
31
32		this._prepareBuffer();
33		this._bindEvents();
34		this._checkVal((this.element.val().length && options.allowPartials)); //Perform initial check for existing values
35	},
36
37	destroy: function() {
38		this.element
39			.unbind('.mask')
40			.removeData('mask');
41	},
42
43	value: function() {
44		var input = this.element,
45			self = this,
46			res = $.map(self.buffer, function(c, i){ return self.tests[i] ? c : null; }).join(''),
47			r = new RegExp('\\'+this.options.placeholder, 'gi');
48		return res.replace(r, '');
49	},
50	
51	formatted: function(){
52		var r = new RegExp('\\'+this.options.placeholder, 'gi'),
53			res = this.element.val();
54		return res.replace(r, '');
55	},
56	
57	apply: function(){
58		this.element.trigger('apply.mask');
59	},
60	
61	_setData: function(key, value) {
62
63		$.widget.prototype._setData.apply(this, arguments);
64		var options = this.options;
65
66		switch (key) {
67			case 'mask':
68				//no mask pattern defined. no point in continuing.
69				if(!options.mask || !options.mask.length){ 
70					this.element.unbind('.mask')
71					break;
72				}
73			case 'placeholder':
74				if(!options.placeholder || !options.placeholder.length){
75					options.placeholder = '_'; //in case the user decided to nix a placeholder.
76				}
77				this.element.val('');
78				this._prepareBuffer();
79				!this.eventsBound && this._bindEvents();
80				break;
81		}
82
83	},
84
85	_prepareBuffer: function(){
86		
87		this._escapeMask();
88
89		var self = this, 
90			input = this.element,
91			options = this.options,
92			mask = options.mask,
93			defs = $.ui.mask.definitions,
94			tests = [],
95			partialPosition = mask.length,
96			firstNonMaskPos = null,
97			len = mask.length;
98
99		//if we're applying the mask to an element which is not an input, it won't have a val() method. fake one for our purposes.
100		if(!input.is(':input')) input.val = input.html;
101
102		$.each(mask.split(""), function(i, c) {
103			if (c == '?') {
104				len--;
105				partialPosition = i;
106			}
107			else if (defs[c]){
108				tests.push(new RegExp(defs[c]));
109				if(firstNonMaskPos==null)
110					firstNonMaskPos =  tests.length - 1;
111			}
112			else{
113				tests.push(null);
114			}
115		});
116
117		$.extend(this, {
118			buffer: $.map(mask.split(""), function(c, i){
119				if (c != '?'){
120					return defs[c] ? options.placeholder : c;
121				}
122			}),
123			tests: tests,
124			firstNonMaskPos: firstNonMaskPos,
125			partialPosition: partialPosition
126		});
127
128		this.buffer = $.map(this.buffer, function(c, i){
129			if(c == "\t"){
130				return self.maskEscaped[i];
131			}
132			return c;
133		});
134
135		this.options.mask = mask = this.maskEscaped;		
136	},	
137
138	_bindEvents: function(){
139		
140		var self = this,
141			input = this.element,
142			ignore = false,  			//Variable for ignoring control keys
143			focusText = input.val();
144			
145		function keydownEvent(e) {
146			e = e || window.event;
147			var pos = self.caret(),
148				k = e.keyCode,
149				keyCode = $.ui.keyCode;
150				
151			ignore = (k < keyCode.SHIFT || (k > keyCode.SHIFT && k < keyCode.SPACE) || (k > keyCode.SPACE && k < 41));
152
153			//delete selection before proceeding
154			if ((pos.begin - pos.end) != 0 && (!ignore || k == keyCode.BACKSPACE || k == keyCode.DELETE))
155				self._clearBuffer(pos.begin, pos.end);
156
157			//backspace, delete, and escape get special treatment
158			if (k == keyCode.BACKSPACE || k == keyCode.DELETE) {//backspace/delete
159				self._shiftL(pos.begin + ((k == keyCode.DELETE || (k == keyCode.BACKSPACE && pos.begin!=pos.end))  ? 0 : -1), Math.abs(pos.begin - pos.end));
160				return false;
161			}
162			else if (k == keyCode.ESCAPE) {//escape
163				input.val(focusText);
164				self.caret(0, self._checkVal());
165				return false;
166			}
167		};
168
169		function keypressEvent(e) {
170
171			e = e || window.event;
172			
173			var k = e.charCode || e.keyCode || e.which, 
174				keyCode = $.ui.keyCode,
175				len = self.options.mask.length;
176
177			if (ignore) {
178				ignore = false;
179				//Fixes Mac FF bug on backspace
180				return (e.keyCode == keyCode.BACKSPACE) ? false : null;
181			}
182			
183			var pos = self.caret();
184
185			if (e.ctrlKey || e.altKey || e.metaKey) {//Ignore
186				return true;
187			}
188			else if ((k >= keyCode.SPACE && k <= 125) || k > 186) {//typeable characters
189				var p = self._seekNext(pos.begin - 1);
190				if (p < len) {
191					var c = String.fromCharCode(k);
192					if (self.tests[p] && self.tests[p].test(c)) {
193						self._shiftR(p);
194						self.buffer[p] = c;
195						self._writeBuffer();
196						var next = self._seekNext(p);
197						self.caret(next);
198						self.options.completed && next == len && self.options.completed.call(input);
199					}
200				}
201			}
202			return false;
203		};
204
205		if (!input.attr("readonly")){
206			input
207				.bind("focus.mask", function() {
208					focusText = input.val();
209					var pos = 0;//self._checkVal();
210					self._writeBuffer();
211					setTimeout(function() {
212						if (pos == self.options.mask.length)
213							self.caret(0, pos);
214						else
215							self.caret(pos);
216					}, 0);
217				})
218				.bind("blur.mask", function() {
219					//self._checkVal();
220					if (input.val() != focusText)
221						input.change();
222				})
223				.bind('apply.mask', function(){ //changing the value of an input without keyboard input requires re-applying the mask.
224					focusText = input.val();
225					var pos = self._checkVal();
226					self._writeBuffer();					
227				})				
228				.bind("keydown.mask", keydownEvent)
229				.bind("keypress.mask", keypressEvent)
230				.bind(pasteEventName, function() {
231					setTimeout(function() { self.caret(self._checkVal(true)); }, 0);
232				});
233			this.eventsBound = true;
234		}
235	},
236	
237	_writeBuffer: function(){
238		return this.element.val(this.buffer.join('')).val(); 
239	},
240	
241	_clearBuffer: function(start, end){
242		var len = this.options.mask.length;
243		for (var i = start; i < end && i < len; i++) {
244			if (this.tests[i])
245				this.buffer[i] = this.options.placeholder;
246		}
247	},
248	
249	_seekNext: function(pos){
250		var len = this.options.mask.length;
251		while (++pos <= len && !this.tests[pos]);
252		return pos;
253	},
254	
255	_shiftR: function(pos){
256		var len = this.options.mask.length;
257		for (var i = pos, c = this.options.placeholder; i < len; i++) {
258			if (this.tests[i]) {
259				var j = this._seekNext(i);
260				var t = this.buffer[i];
261				this.buffer[i] = c;
262				if (j < len && this.tests[j].test(t)){
263					c = t;
264				}
265				else{
266					break;
267				}
268			}
269		}
270	},
271	
272	_shiftL: function(pos, length){
273
274		while (!this.tests[pos] && --pos >= 0);
275	
276		var originalPos = pos,
277			len = this.options.mask.length,
278			placeholder = this.options.placeholder;
279		
280		for(var i = pos; i < len && (i >= 0 || length > 1); i++) {
281			if (this.tests[i]) {
282				this.buffer[i] = placeholder;
283				var j = this._seekNext(i);
284				if (j < len && this.tests[i].test(this.buffer[j])) {
285					this.buffer[pos] = this.buffer[j];
286					this.buffer[j] = placeholder;
287					pos++;
288					while(!this.tests[pos]) pos++;
289				}
290			}
291		}			
292		this._writeBuffer();
293		this.caret(Math.max(this.firstNonMaskPos, originalPos));
294	},
295	
296	_checkVal: function(allow){
297		//try to place characters where they belong
298		var input = this.element,
299			test = input.val(),
300			len = this.options.mask.length,
301			lastMatch = -1;
302			
303		for (var i = 0, pos = 0; i < len; i++) {
304			if (this.tests[i]) {
305				this.buffer[i] = this.options.placeholder;
306				while (pos++ < test.length) {
307					var c = test.charAt(pos - 1);
308					if (this.tests[i].test(c)) {
309						this.buffer[i] = c;
310						lastMatch = i;
311						break;
312					}
313				}
314				if (pos > test.length)
315					break;
316			}
317			else if (this.buffer[i] == test[pos] && i != this.partialPosition) {
318				pos++;
319				lastMatch = i;
320			} 
321		}
322		if (!allow && lastMatch + 1 < this.partialPosition) {
323			if(!this.options.allowPartials || !this.value().length){
324				input.val("");
325				this._clearBuffer(0, len);
326			}
327			else //if we're allowing partial input/inital values, and the element we're masking isnt an input, then we need to allow the mask to apply.
328				if(!input.is(':input')) this._writeBuffer();
329				
330		}
331		else if (allow || lastMatch + 1 >= this.partialPosition) {
332			this._writeBuffer();
333			if (!allow) input.val(input.val().substring(0, lastMatch + 1));
334		}
335		return (this.partialPosition ? i : this.firstNonMaskPos);
336	},
337	
338	_escapeMask: function(){
339		var mask = this.options.mask,
340			literals = [],
341			replacements = [];
342				
343		for(var i = 0; i < mask.length; i++){
344			var c, temp = mask[i] || mask.charAt(i);
345			if(temp != "\\" || mask[i-1] == "\\"){
346				if(mask[i-1] == "\\"){
347					c = "\t";
348					replacements[literals.length] = temp;
349				}
350				else{
351					c = temp;
352				}
353				literals[literals.length] = c;
354			}
355		}
356		
357		this.options.mask = literals.join('');
358		
359		for(var i = 0; i < literals.length; i++){
360			if(replacements[i] !== undefined){
361				literals[i] = replacements[i];
362			}
363		}
364		
365		this.maskEscaped = literals.join('');
366	}	
367	
368});
369
370$.extend($.ui.mask, {
371	version: "@VERSION",
372	getter: "value formatted",
373	defaults: {
374		mask: '',
375		placeholder: '_',
376		completed: null,
377		allowPartials: false
378	},
379	definitions: { //Predefined character definitions
380		'#': "[\\d]",
381		'a': "[A-Za-z]",
382		'*': "[A-Za-z0-9]"
383	},
384	caret: function(element, begin, end) {	//Helper Function for Caret positioning
385		var input = element[0];
386		if (typeof begin == 'number') {
387			end = (typeof end == 'number') ? end : begin;
388			if (input.setSelectionRange) {
389				input.focus();
390				input.setSelectionRange(begin, end);
391			} else if (input.createTextRange) {
392				var range = input.createTextRange();
393				range.collapse(true);
394				range.moveEnd('character', end);
395				range.moveStart('character', begin);
396				range.select();
397			}
398			return element;
399		} else {
400			if (input.setSelectionRange) {
401				begin = input.selectionStart;
402				end = input.selectionEnd;
403			}
404			else if (document.selection && document.selection.createRange) {
405				var range = document.selection.createRange();
406				begin = 0 - range.duplicate().moveStart('character', -100000);
407				end = begin + range.text.length;
408			}
409			return { begin: begin, end: end };
410		}
411	}		
412});
413
414})(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.