PageSourceSearch

https://www.aceba.cat/comu/js/jquery.mask.js

js aceba.cat collected 2026-10-03 20:28:22 UTC 18,429 bytes, 489 lines download raw bytes

vendor: 6,606 bytes, lines 1-169
1/**
2 * jquery.mask.js
3 * @version: v1.13.4
4 * @author: Igor Escobar
5 *
6 * Created by Igor Escobar on 2012-03-10. Please report any bug at http://blog.igorescobar.com
7 *
8 * Copyright (c) 2012 Igor Escobar http://blog.igorescobar.com
9 *
10 * The MIT License (http://www.opensource.org/licenses/mit-license.php)
11 *
12 * Permission is hereby granted, free of charge, to any person
13 * obtaining a copy of this software and associated documentation
14 * files (the "Software"), to deal in the Software without
15 * restriction, including without limitation the rights to use,
16 * copy, modify, merge, publish, distribute, sublicense, and/or sell
17 * copies of the Software, and to permit persons to whom the
18 * Software is furnished to do so, subject to the following
19 * conditions:
20 *
21 * The above copyright notice and this permission notice shall be
22 * included in all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
26 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
28 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
29 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
31 * OTHER DEALINGS IN THE SOFTWARE.
32 */
33
34/* jshint laxbreak: true */
35/* global define, jQuery, Zepto */
36
37'use strict';
38
39// UMD (Universal Module Definition) patterns for JavaScript modules that work everywhere.
40// https://github.com/umdjs/umd/blob/master/jqueryPluginCommonjs.js
41(function (factory) {
42
43    if (typeof define === 'function' && define.amd) {
44        define(['jquery'], factory);
45    } else if (typeof exports === 'object') {
46        module.exports = factory(require('jquery'));
47    } else {
48        factory(jQuery || Zepto);
49    }
50
51}(function ($) {
52
53    var Mask = function (el, mask, options) {
54        el = $(el);
55
56        var jMask = this, oldValue = el.val(), regexMask;
57
58        mask = typeof mask === 'function' ? mask(el.val(), undefined, el,  options) : mask;
59
60        var p = {
61            invalid: [],
62            getCaret: function () {
63                try {
64                    var sel,
65                        pos = 0,
66                        ctrl = el.get(0),
67                        dSel = document.selection,
68                        cSelStart = ctrl.selectionStart;
69
70                    // IE Support
71                    if (dSel && navigator.appVersion.indexOf('MSIE 10') === -1) {
72                        sel = dSel.createRange();
73                        sel.moveStart('character', el.is('input') ? -el.val().length : -el.text().length);
74                        pos = sel.text.length;
75                    }
76                    // Firefox support
77                    else if (cSelStart || cSelStart === '0') {
78                        pos = cSelStart;
79                    }
80
81                    return pos;
82                } catch (e) {}
83            },
84            setCaret: function(pos) {
85                try {
86                    if (el.is(':focus')) {
87                        var range, ctrl = el.get(0);
88
89                        if (ctrl.setSelectionRange) {
90                            ctrl.setSelectionRange(pos,pos);
91                        } else if (ctrl.createTextRange) {
92                            range = ctrl.createTextRange();
93                            range.collapse(true);
94                            range.moveEnd('character', pos);
95                            range.moveStart('character', pos);
96                            range.select();
97                        }
98                    }
99                } catch (e) {}
100            },
101            events: function() {
102                el
103                .on('input.mask keyup.mask', p.behaviour)
104                .on('paste.mask drop.mask', function() {
105                    setTimeout(function() {
106                        el.keydown().keyup();
107                    }, 100);
108                })
109                .on('change.mask', function(){
110                    el.data('changed', true);
111                })
112                .on('blur.mask', function(){
113                    if (oldValue !== el.val() && !el.data('changed')) {
114                        el.triggerHandler('change');
115                    }
116                    el.data('changed', false);
117                })
118                // it's very important that this callback remains in this position
119                // otherwhise oldValue it's going to work buggy
120                .on('blur.mask', function() {
121                    oldValue = el.val();
122                })
123                // select all text on focus
124                .on('focus.mask', function (e) {
125                    if (options.selectOnFocus === true) {
126                        $(e.target).select();
127                    }
128                })
129                // clear the value if it not complete the mask
130                .on('focusout.mask', function() {
131                    if (options.clearIfNotMatch && !regexMask.test(p.val())) {
132                       p.val('');
133                   }
134                });
135            },
136            getRegexMask: function() {
137                var maskChunks = [], translation, pattern, optional, recursive, oRecursive, r;
138
139                for (var i = 0; i < mask.length; i++) {
140                    translation = jMask.translation[mask.charAt(i)];
141
142                    if (translation) {
143
144                        pattern = translation.pattern.toString().replace(/.{1}$|^.{1}/g, '');
145                        optional = translation.optional;
146                        recursive = translation.recursive;
147
148                        if (recursive) {
149                            maskChunks.push(mask.charAt(i));
150                            oRecursive = {digit: mask.charAt(i), pattern: pattern};
151                        } else {
152                            maskChunks.push(!optional && !recursive ? pattern : (pattern + '?'));
153                        }
154
155                    } else {
156                        maskChunks.push(mask.charAt(i).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'));
157                    }
158                }
159
160                r = maskChunks.join('');
161
162                if (oRecursive) {
163                    r = r.replace(new RegExp('(' + oRecursive.digit + '(.*' + oRecursive.digit + ')?)'), '($1)?')
164                         .replace(new RegExp(oRecursive.digit, 'g'), oRecursive.pattern);
165                }
166
167                return new RegExp(r);
168            },
169            destroyEvents: function() {
170                el.off(['input', 'keydown', 'keyup', 'paste', 'drop', 'blur', 'focusout', ''].join('.mask '));
171            },
172            val: function(v) {
173                var isInput = el.is('input'),
174                    method = isInput ? 'val' : 'text',
175                    r;
176
177                if (arguments.length > 0) {
178                    if (el[method]() !== v) {
179                        el[method](v);
180                    }
181                    r = el;
182                } else {
183                    r = el[method]();
184                }
185
186                return r;
187            },
188            getMCharsBeforeCount: function(index, onCleanVal) {
189                for (var count = 0, i = 0, maskL = mask.length; i < maskL && i < index; i++) {
190                    if (!jMask.translation[mask.charAt(i)]) {
191                        index = onCleanVal ? index + 1 : index;
192                        count++;
193                    }
194                }
195                return count;
196            },
197            caretPos: function (originalCaretPos, oldLength, newLength, maskDif) {
198                var translation = jMask.translation[mask.charAt(Math.min(originalCaretPos - 1, mask.length - 1))];
199
200                return !translation ? p.caretPos(originalCaretPos + 1, oldLength, newLength, maskDif)
201                                    : Math.min(originalCaretPos + newLength - oldLength - maskDif, newLength);
202            },
203            behaviour: function(e) {
204                e = e || window.event;
205                p.invalid = [];
206                var keyCode = e.keyCode || e.which;
207                if ($.inArray(keyCode, jMask.byPassKeys) === -1) {
208
209                    var caretPos = p.getCaret(),
210                        currVal = p.val(),
211                        currValL = currVal.length,
212                        changeCaret = caretPos < currValL,
213                        newVal = p.getMasked(),
214                        newValL = newVal.length,
215                        maskDif = p.getMCharsBeforeCount(newValL - 1) - p.getMCharsBeforeCount(currValL - 1);
216
217                    p.val(newVal);
218
219                    // change caret but avoid CTRL+A
220                    if (changeCaret && !(keyCode === 65 && e.ctrlKey)) {
221                        // Avoid adjusting caret on backspace or delete
222                        if (!(keyCode === 8 || keyCode === 46)) {
223                            caretPos = p.caretPos(caretPos, currValL, newValL, maskDif);
224                        }
225                        p.setCaret(caretPos);
226                    }
227
228                    return p.callbacks(e);
229                }
230            },
231            getMasked: function(skipMaskChars) {
232                var buf = [],
233                    value = p.val(),
234                    m = 0, maskLen = mask.length,
235                    v = 0, valLen = value.length,
236                    offset = 1, addMethod = 'push',
237                    resetPos = -1,
238                    lastMaskChar,
239                    check;
240
241                if (options.reverse) {
242                    addMethod = 'unshift';
243                    offset = -1;
244                    lastMaskChar = 0;
245                    m = maskLen - 1;
246                    v = valLen - 1;
247                    check = function () {
248                        return m > -1 && v > -1;
249                    };
250                } else {
251                    lastMaskChar = maskLen - 1;
252                    check = function () {
253                        return m < maskLen && v < valLen;
254                    };
255                }
256
257                while (check()) {
258                    var maskDigit = mask.charAt(m),
259                        valDigit = value.charAt(v),
260                        translation = jMask.translation[maskDigit];
261
262                    if (translation) {
263                        if (valDigit.match(translation.pattern)) {
264                            buf[addMethod](valDigit);
265                             if (translation.recursive) {
266                                if (resetPos === -1) {
267                                    resetPos = m;
268                                } else if (m === lastMaskChar) {
269                                    m = resetPos - offset;
270                                }
271
272                                if (lastMaskChar === resetPos) {
273                                    m -= offset;
274                                }
275                            }
276                            m += offset;
277                        } else if (translation.optional) {
278                            m += offset;
279                            v -= offset;
280                        } else if (translation.fallback) {
281                            buf[addMethod](translation.fallback);
282                            m += offset;
283                            v -= offset;
284                        } else {
285                          p.invalid.push({p: v, v: valDigit, e: translation.pattern});
286                        }
287                        v += offset;
288                    } else {
289                        if (!skipMaskChars) {
290                            buf[addMethod](maskDigit);
291                        }
292
293                        if (valDigit === maskDigit) {
294                            v += offset;
295                        }
296
297                        m += offset;
298                    }
299                }
300
301                var lastMaskCharDigit = mask.charAt(lastMaskChar);
302                if (maskLen === valLen + 1 && !jMask.translation[lastMaskCharDigit]) {
303                    buf.push(lastMaskCharDigit);
304                }
305
306                return buf.join('');
307            },
308            callbacks: function (e) {
309                var val = p.val(),
310                    changed = val !== oldValue,
311                    defaultArgs = [val, e, el, options],
312                    callback = function(name, criteria, args) {
313                        if (typeof options[name] === 'function' && criteria) {
314                            options[name].apply(this, args);
315                        }
316                    };
317
318                callback('onChange', changed === true, defaultArgs);
319                callback('onKeyPress', changed === true, defaultArgs);
320                callback('onComplete', val.length === mask.length, defaultArgs);
321                callback('onInvalid', p.invalid.length > 0, [val, e, el, p.invalid, options]);
322            }
323        };
324
325
326        // public methods
327        jMask.mask = mask;
328        jMask.options = options;
329        jMask.remove = function() {
330            var caret = p.getCaret();
331            p.destroyEvents();
332            p.val(jMask.getCleanVal());
333            p.setCaret(caret - p.getMCharsBeforeCount(caret));
334            return el;
335        };
336
337        // get value without mask
338        jMask.getCleanVal = function() {
339           return p.getMasked(true);
340        };
341
342       jMask.init = function(onlyMask) {
343            onlyMask = onlyMask || false;
344            options = options || {};
345
346            jMask.byPassKeys = $.jMaskGlobals.byPassKeys;
347            jMask.translation = $.jMaskGlobals.translation;
348
349            jMask.translation = $.extend({}, jMask.translation, options.translation);
350            jMask = $.extend(true, {}
350, jMask, options);
351
352            regexMask = p.getRegexMask();
353
354            if (onlyMask === false) {
355
356                if (options.placeholder) {
357                    el.attr('placeholder' , options.placeholder);
358                }
359
360                // this is necessary, otherwise if the user submit the form
361                // and then press the "back" button, the autocomplete will erase
362                // the data. Works fine on IE9+, FF, Opera, Safari.
363                if ($('input').length && 'oninput' in $('input')[0] === false && el.attr('autocomplete') === 'on') {
364                  el.attr('autocomplete', 'off');
365                }
366
367                p.destroyEvents();
368                p.events();
369
370                var caret = p.getCaret();
371                p.val(p.getMasked());
372                p.setCaret(caret + p.getMCharsBeforeCount(caret, true));
373
374            } else {
375                p.events();
376                p.val(p.getMasked());
377            }
378        };
379
380        jMask.init(!el.is('input'));
381    };
382
383    $.maskWatchers = {};
384    var HTMLAttributes = function () {
385            var input = $(this),
386                options = {},
387                prefix = 'data-mask-',
388                mask = input.attr('data-mask');
389
390            if (input.attr(prefix + 'reverse')) {
391                options.reverse = true;
392            }
393
394            if (input.attr(prefix + 'clearifnotmatch')) {
395                options.clearIfNotMatch = true;
396            }
397
398            if (input.attr(prefix + 'selectonfocus') === 'true') {
399               options.selectOnFocus = true;
400            }
401
402            if (notSameMaskObject(input, mask, options)) {
403                return input.data('mask', new Mask(this, mask, options));
404            }
405        },
406        notSameMaskObject = function(field, mask, options) {
407            options = options || {};
408            var maskObject = $(field).data('mask'),
409                stringify = JSON.stringify,
410                value = $(field).val() || $(field).text();
411            try {
412                if (typeof mask === 'function') {
413                    mask = mask(value);
414                }
415                return typeof maskObject !== 'object' || stringify(maskObject.options) !== stringify(options) || maskObject.mask !== mask;
416            } catch (e) {}
417        };
418
419
420    $.fn.mask = function(mask, options) {
421        options = options || {};
422        var selector = this.selector,
423            globals = $.jMaskGlobals,
424            interval = $.jMaskGlobals.watchInterval,
425            maskFunction = function() {
426                if (notSameMaskObject(this, mask, options)) {
427                    return $(this).data('mask', new Mask(this, mask, options));
428                }
429            };
430
431        $(this).each(maskFunction);
432
433        if (selector && selector !== '' && globals.watchInputs) {
434            clearInterval($.maskWatchers[selector]);
435            $.maskWatchers[selector] = setInterval(function(){
436                $(document).find(selector).each(maskFunction);
437            }, interval);
438        }
439        return this;
440    };
441
442    $.fn.unmask = function() {
443        clearInterval($.maskWatchers[this.selector]);
444        delete $.maskWatchers[this.selector];
445        return this.each(function() {
446            var dataMask = $(this).data('mask');
447            if (dataMask) {
448                dataMask.remove().removeData('mask');
449            }
450        });
451    };
452
453    $.fn.cleanVal = function() {
454        return this.data('mask').getCleanVal();
455    };
456
457    $.applyDataMask = function(selector) {
458        selector = selector || $.jMaskGlobals.maskElements;
459        var $selector = (selector instanceof $) ? selector : $(selector);
460        $selector.filter($.jMaskGlobals.dataMaskAttr).each(HTMLAttributes);
461    };
462
463    var globals = {
464        maskElements: 'input,td,span,div',
465        dataMaskAttr: '*[data-mask]',
466        dataMask: true,
467        watchInterval: 300,
468        watchInputs: true,
469        watchDataMask: false,
470        byPassKeys: [9, 16, 17, 18, 36, 37, 38, 39, 40, 91],
471        translation: {
472            '0': {pattern: /\d/},
473            '9': {pattern: /\d/, optional: true},
474            '#': {pattern: /\d/, recursive: true},
475            'A': {pattern: /[a-zA-Z0-9]/},
476            'S': {pattern: /[a-zA-Z]/}
477        }
478    };
479
480    $.jMaskGlobals = $.jMaskGlobals || {};
481    globals = $.jMaskGlobals = $.extend(true, {}, globals, $.jMaskGlobals);
482
483    // looking for inputs with data-mask attribute
484    if (globals.dataMask) { $.applyDataMask(); }
485
486    setInterval(function(){
487        if ($.jMaskGlobals.watchDataMask) { $.applyDataMask(); }
488    }, globals.watchInterval);
489}));

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.