1/*jslint unparam: true, browser: true, indent: 2 */ 2 3;(function ($, window, document, undefined) { 4 'use strict'; 5 6 Foundation.libs.abide = { 7 name : 'abide', 8 9 version : '4.3.0', 10 11 settings : { 12 live_validate : true, 13 focus_on_invalid : true, 14 timeout : 1000, 15 patterns : { 16 alpha: /[a-zA-Z]+/, 17 alpha_numeric : /[a-zA-Z0-9]+/, 18 integer: /-?\d+/, 19 number: /-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?/, 20 21 // generic password: upper-case, lower-case, number/special character, and min 8 characters 22 password : /(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/, 23 24 // amex, visa, diners 25 card : /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/, 26 cvv : /^([0-9]){3,4}$/, 27 28 // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address 29 email : /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/, 30 31 url: /(https?|ftp|file|ssh):\/\/(((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?/, 32 // abc.de 33 domain: /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$/, 34 35 datetime: /([0-2][0-9]{3})\-([0-1][0-9])\-([0-3][0-9])T([0-5][0-9])\:([0-5][0-9])\:([0-5][0-9])(Z|([\-\+]([0-1][0-9])\:00))/, 36 // YYYY-MM-DD 37 date: /(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))/, 38 // HH:MM:SS 39 time : /(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}/, 40 dateISO: /\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}/, 41 // MM/DD/YYYY 42 month_day_year : /(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d/, 43 44 // #FFF or #FFFFFF 45 color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/ 46 } 47 }, 48 49 timer : null, 50 51 init : function (scope, method, options) { 52 if (typeof method === 'object') { 53 $.extend(true, this.settings, method); 54 } 55 56 if (typeof method !== 'string') { 57 if (!this.settings.init) { this.events(); } 58 59 } else { 60 return this[method].call(this, options); 61 } 62 }, 63 64 events : function () { 65 var self = this, 66 forms = $('form[data-abide]', this.scope).attr('novalidate', 'novalidate'); 67 68 forms 69 .on('submit validate', function (e) { 70 return self.validate($(this).find('input, textarea, select').get(), e); 71 }); 72 73 this.settings.init = true; 74 75 if (!this.settings.live_validate) return; 76 77 forms 78 .find('input, textarea, select') 79 .on('blur change', function (e) { 80 self.validate([this], e); 81 }) 82 .on('keydown', function (e) { 83 clearTimeout(self.timer); 84 self.timer = setTimeout(function () { 85 self.validate([this], e); 86 }.bind(this), self.settings.timeout); 87 }); 88 }, 89 90 validate : function (els, e) {
91 var validations = this.parse_patterns(els), 92 validation_count = validations.length, 93 form = $(els[0]).closest('form'); 94 95 while (validation_count--) { 96 if (!validations[validation_count] && /submit/.test(e.type)) { 97 if (this.settings.focus_on_invalid) els[validation_count].focus(); 98 form.trigger('invalid'); 99 $(els[validation_count]).closest('form').attr('data-invalid', ''); 100 return false; 101 } 102 } 103 104 if (/submit/.test(e.type)) { 105 form.trigger('valid'); 106 } 107 108 form.removeAttr('data-invalid'); 109 110 return true; 111 }, 112 113 parse_patterns : function (els) { 114 var count = els.length, 115 el_patterns = []; 116 117 for (var i = count - 1; i >= 0; i--) { 118 el_patterns.push(this.pattern(els[i])); 119 } 120 121 return this.check_validation_and_apply_styles(el_patterns); 122 }, 123 124 pattern : function (el) { 125 var type = el.getAttribute('type'), 126 required = typeof el.getAttribute('required') === 'string'; 127 128 if (this.settings.patterns.hasOwnProperty(type)) { 129 return [el, this.settings.patterns[type], required]; 130 } 131 132 var pattern = el.getAttribute('pattern') || ''; 133 134 if (this.settings.patterns.hasOwnProperty(pattern) && pattern.length > 0) { 135 return [el, this.settings.patterns[pattern], required]; 136 } else if (pattern.length > 0) { 137 return [el, new RegExp(pattern), required]; 138 } 139 140 pattern = /.*/; 141 142 return [el, pattern, required]; 143 }, 144 145 check_validation_and_apply_styles : function (el_patterns) { 146 var count = el_patterns.length, 147 validations = []; 148 149 for (var i = count - 1; i >= 0; i--) { 150 var el = el_patterns[i][0], 151 required = el_patterns[i][2], 152 value = el.value, 153 is_radio = el.type === "radio", 154 valid_length = (required) ? (el.value.length > 0) : true; 155 156 if (is_radio && required) { 157 validations.push(this.valid_radio(el, required)); 158 } else { 159 if (el_patterns[i][1].test(value) && valid_length || 160 !required && el.value.length < 1) { 161 $(el).removeAttr('data-invalid').parent().removeClass('error'); 162 validations.push(true); 163 } else { 164 $(el).attr('data-invalid', '').parent().addClass('error'); 165 validations.push(false); 166 } 167 } 168 } 169 170 return validations; 171 }, 172 173 valid_radio : function (el, required) { 174 var name = el.getAttribute('name'), 175 group = document.getElementsByName(name), 176 count = group.length, 177 valid = false; 178 179 for (var i=0; i < count; i++) { 180 if (group[i].checked) valid = true; 181 } 182 183 for (var i=0; i < count; i++) { 184 if (valid) { 185 $(group[i]).removeAttr('data-invalid').parent().removeClass('error'); 186 } else { 187 $(group[i]).attr('data-invalid', '').parent().addClass('error'); 188 } 189 } 190 191 return valid; 192 } 193 }; 194}(Foundation.zj, this, this.document));
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.