From 8c1a3ea4e20501ed94c194d152376e8cef0238e2 Mon Sep 17 00:00:00 2001 From: Nicolas Cusan Date: Mon, 8 Feb 2021 17:07:24 +0100 Subject: [PATCH 01/11] Checkout validator lib --- dist/pristine.js | 662 +++++++++++++++++++++-------------------- dist/pristine.min.js | 2 +- package-lock.json | 2 +- src/pristine.js | 694 ++++++++++++++++++++++++------------------- 4 files changed, 733 insertions(+), 627 deletions(-) diff --git a/dist/pristine.js b/dist/pristine.js index e873ea7..eb3478f 100644 --- a/dist/pristine.js +++ b/dist/pristine.js @@ -17,7 +17,8 @@ min: "Minimum value for this field is ${1}", max: "Maximum value for this field is ${1}", pattern: "Please match the requested format", - equals: "The two fields do not match" + equals: "The two fields do not match", + default: "Please enter a correct value" } }; @@ -48,349 +49,370 @@ } var defaultConfig = { - classTo: 'form-group', - errorClass: 'has-danger', - successClass: 'has-success', - errorTextParent: 'form-group', - errorTextTag: 'div', - errorTextClass: 'text-help' + classTo: "form-group", + errorClass: "has-danger", + successClass: "has-success", + errorTextParent: "form-group", + errorTextTag: "div", + errorTextClass: "text-help" }; - var PRISTINE_ERROR = 'pristine-error'; + var PRISTINE_ERROR = "pristine-error"; var SELECTOR = "input:not([type^=hidden]):not([type^=submit]), select, textarea"; - var ALLOWED_ATTRIBUTES = ["required", "min", "max", 'minlength', 'maxlength', 'pattern']; + var ALLOWED_ATTRIBUTES = ["required", "min", "max", "minlength", "maxlength", "pattern"]; var EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; var MESSAGE_REGEX = /-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/; // matches, -message, -message-en, -message-en_US - var currentLocale = 'en'; + var currentLocale = "en"; var validators = {}; var _ = function _(name, validator) { - validator.name = name; - if (validator.priority === undefined) validator.priority = 1; - validators[name] = validator; + validator.name = name; + if (validator.priority === undefined) validator.priority = 1; + validators[name] = validator; }; - _('text', { fn: function fn(val) { - return true; - }, priority: 0 }); - _('required', { fn: function fn(val) { - return this.type === 'radio' || this.type === 'checkbox' ? groupedElemCount(this) : val !== undefined && val !== ''; - }, priority: 99, halt: true }); - _('email', { fn: function fn(val) { - return !val || EMAIL_REGEX.test(val); - } }); - _('number', { fn: function fn(val) { - return !val || !isNaN(parseFloat(val)); - }, priority: 2 }); - _('integer', { fn: function fn(val) { - return !val || /^\d+$/.test(val); - } }); - _('minlength', { fn: function fn(val, length) { - return !val || val.length >= parseInt(length); - } }); - _('maxlength', { fn: function fn(val, length) { - return !val || val.length <= parseInt(length); - } }); - _('min', { fn: function fn(val, limit) { - return !val || (this.type === 'checkbox' ? groupedElemCount(this) >= parseInt(limit) : parseFloat(val) >= parseFloat(limit)); - } }); - _('max', { fn: function fn(val, limit) { - return !val || (this.type === 'checkbox' ? groupedElemCount(this) <= parseInt(limit) : parseFloat(val) <= parseFloat(limit)); - } }); - _('pattern', { fn: function fn(val, pattern) { - var m = pattern.match(new RegExp('^/(.*?)/([gimy]*)$'));return !val || new RegExp(m[1], m[2]).test(val); - } }); - _('equals', { fn: function fn(val, otherFieldSelector) { - var other = document.querySelector(otherFieldSelector);return other && (!val && !other.value || other.value === val); - } }); + _("text", { fn: function fn(val) { + return true; + }, priority: 0 }); + _("required", { + fn: function fn(val) { + return this.type === "radio" || this.type === "checkbox" ? groupedElemCount(this) : val !== undefined && val !== ""; + }, + priority: 99, + halt: true + }); + _("email", { fn: function fn(val) { + return !val || EMAIL_REGEX.test(val); + } }); + _("number", { fn: function fn(val) { + return !val || !isNaN(parseFloat(val)); + }, priority: 2 }); + _("integer", { fn: function fn(val) { + return !val || /^\d+$/.test(val); + } }); + _("minlength", { fn: function fn(val, length) { + return !val || val.length >= parseInt(length); + } }); + _("maxlength", { fn: function fn(val, length) { + return !val || val.length <= parseInt(length); + } }); + _("min", { + fn: function fn(val, limit) { + return !val || (this.type === "checkbox" ? groupedElemCount(this) >= parseInt(limit) : parseFloat(val) >= parseFloat(limit)); + } + }); + _("max", { + fn: function fn(val, limit) { + return !val || (this.type === "checkbox" ? groupedElemCount(this) <= parseInt(limit) : parseFloat(val) <= parseFloat(limit)); + } + }); + _("pattern", { + fn: function fn(val, pattern) { + var m = pattern.match(new RegExp("^/(.*?)/([gimy]*)$")); + return !val || new RegExp(m[1], m[2]).test(val); + } + }); + _("equals", { + fn: function fn(val, otherFieldSelector) { + var other = document.querySelector(otherFieldSelector); + return other && (!val && !other.value || other.value === val); + } + }); + + console.log(_); function Pristine(form, config, live) { - - var self = this; - - init(form, config, live); - - function init(form, config, live) { - - form.setAttribute("novalidate", "true"); - - self.form = form; - self.config = mergeConfig(config || {}, defaultConfig); - self.live = !(live === false); - self.fields = Array.from(form.querySelectorAll(SELECTOR)).map(function (input) { - - var fns = []; - var params = {}; - var messages = {}; - - [].forEach.call(input.attributes, function (attr) { - if (/^data-pristine-/.test(attr.name)) { - var name = attr.name.substr(14); - var messageMatch = name.match(MESSAGE_REGEX); - if (messageMatch !== null) { - var locale = messageMatch[1] === undefined ? 'en' : messageMatch[1]; - if (!messages.hasOwnProperty(locale)) messages[locale] = {}; - messages[locale][name.slice(0, name.length - messageMatch[0].length)] = attr.value; - return; - } - if (name === 'type') name = attr.value; - _addValidatorToField(fns, params, name, attr.value); - } else if (~ALLOWED_ATTRIBUTES.indexOf(attr.name)) { - _addValidatorToField(fns, params, attr.name, attr.value); - } else if (attr.name === 'type') { - _addValidatorToField(fns, params, attr.value); - } - }); - - fns.sort(function (a, b) { - return b.priority - a.priority; - }); - - self.live && input.addEventListener(!~['radio', 'checkbox'].indexOf(input.getAttribute('type')) ? 'input' : 'change', function (e) { - self.validate(e.target); - }.bind(self)); - - return input.pristine = { input: input, validators: fns, params: params, messages: messages, self: self }; - }.bind(self)); - } - - function _addValidatorToField(fns, params, name, value) { - var validator = validators[name]; - if (validator) { - fns.push(validator); - if (value) { - var valueParams = name === "pattern" ? [value] : value.split(','); - valueParams.unshift(null); // placeholder for input's value - params[name] = valueParams; - } + var self = this; + + init(form, config, live); + + function init(form, config, live) { + form.setAttribute("novalidate", "true"); + + self.form = form; + self.config = mergeConfig(config || {}, defaultConfig); + self.live = !(live === false); + self.fields = Array.from(form.querySelectorAll(SELECTOR)).map(function (input) { + var fns = []; + var params = {}; + var messages = {}; + + [].forEach.call(input.attributes, function (attr) { + if (/^data-pristine-/.test(attr.name)) { + var name = attr.name.substr(14); + var messageMatch = name.match(MESSAGE_REGEX); + if (messageMatch !== null) { + var locale = messageMatch[1] === undefined ? "en" : messageMatch[1]; + if (!messages.hasOwnProperty(locale)) messages[locale] = {}; + messages[locale][name.slice(0, name.length - messageMatch[0].length)] = attr.value; + return; + } + if (name === "type") name = attr.value; + _addValidatorToField(fns, params, name, attr.value); + } else if (~ALLOWED_ATTRIBUTES.indexOf(attr.name)) { + _addValidatorToField(fns, params, attr.name, attr.value); + } else if (attr.name === "type") { + _addValidatorToField(fns, params, attr.value); } + }); + + fns.sort(function (a, b) { + return b.priority - a.priority; + }); + + self.live && input.addEventListener(!~["radio", "checkbox"].indexOf(input.getAttribute("type")) ? "input" : "change", function (e) { + self.validate(e.target); + }.bind(self)); + + return input.pristine = { + input: input, + validators: fns, + params: params, + messages: messages, + self: self + }; + }.bind(self)); + } + + function _addValidatorToField(fns, params, name, value) { + var validator = validators[name]; + if (validator) { + fns.push(validator); + if (value) { + var valueParams = name === "pattern" ? [value] : value.split(","); + valueParams.unshift(null); // placeholder for input's value + params[name] = valueParams; + } + } + } + + /*** + * Checks whether the form/input elements are valid + * @param input => input element(s) or a jquery selector, null for full form validation + * @param silent => do not show error messages, just return true/false + * @returns {boolean} return true when valid false otherwise + */ + self.validate = function (input, silent) { + silent = input && silent === true || input === true; + var fields = self.fields; + if (input !== true && input !== false) { + if (input instanceof HTMLElement) { + fields = [input.pristine]; + } else if (input instanceof NodeList || input instanceof (window.$ || Array) || input instanceof Array) { + fields = Array.from(input).map(function (el) { + return el.pristine; + }); + } } - /*** - * Checks whether the form/input elements are valid - * @param input => input element(s) or a jquery selector, null for full form validation - * @param silent => do not show error messages, just return true/false - * @returns {boolean} return true when valid false otherwise - */ - self.validate = function (input, silent) { - silent = input && silent === true || input === true; - var fields = self.fields; - if (input !== true && input !== false) { - if (input instanceof HTMLElement) { - fields = [input.pristine]; - } else if (input instanceof NodeList || input instanceof (window.$ || Array) || input instanceof Array) { - fields = Array.from(input).map(function (el) { - return el.pristine; - }); - } - } - - var valid = true; + var valid = true; - for (var i = 0; fields[i]; i++) { - var field = fields[i]; - if (_validateField(field)) { - !silent && _showSuccess(field); - } else { - valid = false; - !silent && _showError(field); - } - } - return valid; - }; - - /*** - * Get errors of a specific field or the whole form - * @param input - * @returns {Array|*} - */ - self.getErrors = function (input) { - if (!input) { - var erroneousFields = []; - for (var i = 0; i < self.fields.length; i++) { - var field = self.fields[i]; - if (field.errors.length) { - erroneousFields.push({ input: field.input, errors: field.errors }); - } - } - return erroneousFields; - } - if (input.tagName && input.tagName.toLowerCase() === "select") { - return input.pristine.errors; - } - return input.length ? input[0].pristine.errors : input.pristine.errors; - }; - - /*** - * Validates a single field, all validator functions are called and error messages are generated - * when a validator fails - * @param field - * @returns {boolean} - * @private - */ - function _validateField(field) { - var errors = []; - var valid = true; - for (var i = 0; field.validators[i]; i++) { - var validator = field.validators[i]; - var params = field.params[validator.name] ? field.params[validator.name] : []; - params[0] = field.input.value; - if (!validator.fn.apply(field.input, params)) { - valid = false; - - if (typeof validator.msg === "function") { - errors.push(validator.msg(field.input.value, params)); - } else if (typeof validator.msg === "string") { - errors.push(tmpl.apply(validator.msg, params)); - } else if (validator.msg === Object(validator.msg) && validator.msg[currentLocale]) { - // typeof generates unnecessary babel code - errors.push(tmpl.apply(validator.msg[currentLocale], params)); - } else if (field.messages[currentLocale] && field.messages[currentLocale][validator.name]) { - errors.push(tmpl.apply(field.messages[currentLocale][validator.name], params)); - } else if (lang[currentLocale] && lang[currentLocale][validator.name]) { - errors.push(tmpl.apply(lang[currentLocale][validator.name], params)); - } - - if (validator.halt === true) { - break; - } - } - } - field.errors = errors; - return valid; + for (var i = 0; fields[i]; i++) { + var field = fields[i]; + if (_validateField(field)) { + !silent && _showSuccess(field); + } else { + valid = false; + !silent && _showError(field); + } } - - /*** - * Add a validator to a specific dom element in a form - * @param elem => The dom element where the validator is applied to - * @param fn => validator function - * @param msg => message to show when validation fails. Supports templating. ${0} for the input's value, ${1} and - * so on are for the attribute values - * @param priority => priority of the validator function, higher valued function gets called first. - * @param halt => whether validation should stop for this field after current validation function - */ - self.addValidator = function (elem, fn, msg, priority, halt) { - if (elem instanceof HTMLElement) { - elem.pristine.validators.push({ fn: fn, msg: msg, priority: priority, halt: halt }); - elem.pristine.validators.sort(function (a, b) { - return b.priority - a.priority; - }); - } else { - console.warn("The parameter elem must be a dom element"); + return valid; + }; + + /*** + * Get errors of a specific field or the whole form + * @param input + * @returns {Array|*} + */ + self.getErrors = function (input) { + if (!input) { + var erroneousFields = []; + for (var i = 0; i < self.fields.length; i++) { + var field = self.fields[i]; + if (field.errors.length) { + erroneousFields.push({ input: field.input, errors: field.errors }); } - }; - - /*** - * An utility function that returns a 2-element array, first one is the element where error/success class is - * applied. 2nd one is the element where error message is displayed. 2nd element is created if doesn't exist and cached. - * @param field - * @returns {*} - * @private - */ - function _getErrorElements(field) { - if (field.errorElements) { - return field.errorElements; - } - var errorClassElement = findAncestor(field.input, self.config.classTo); - var errorTextParent = null, - errorTextElement = null; - if (self.config.classTo === self.config.errorTextParent) { - errorTextParent = errorClassElement; + } + return erroneousFields; + } + if (input.tagName && input.tagName.toLowerCase() === "select") { + return input.pristine.errors; + } + return input.length ? input[0].pristine.errors : input.pristine.errors; + }; + + /*** + * Validates a single field, all validator functions are called and error messages are generated + * when a validator fails + * @param field + * @returns {boolean} + * @private + */ + function _validateField(field) { + var errors = []; + var valid = true; + for (var i = 0; field.validators[i]; i++) { + var validator = field.validators[i]; + var params = field.params[validator.name] ? field.params[validator.name] : []; + params[0] = field.input.value; + if (!validator.fn.apply(field.input, params)) { + valid = false; + + if (typeof validator.msg === "function") { + errors.push(validator.msg(field.input.value, params)); + } else if (typeof validator.msg === "string") { + errors.push(tmpl.apply(validator.msg, params)); + } else if (validator.msg === Object(validator.msg) && validator.msg[currentLocale]) { + // typeof generates unnecessary babel code + errors.push(tmpl.apply(validator.msg[currentLocale], params)); + } else if (field.messages[currentLocale] && field.messages[currentLocale][validator.name]) { + errors.push(tmpl.apply(field.messages[currentLocale][validator.name], params)); + } else if (lang[currentLocale] && lang[currentLocale][validator.name]) { + errors.push(tmpl.apply(lang[currentLocale][validator.name], params)); } else { - errorTextParent = errorClassElement.querySelector('.' + self.config.errorTextParent); + errors.push(tmpl.apply(lang[currentLocale].default, params)); } - if (errorTextParent) { - errorTextElement = errorTextParent.querySelector('.' + PRISTINE_ERROR); - if (!errorTextElement) { - errorTextElement = document.createElement(self.config.errorTextTag); - errorTextElement.className = PRISTINE_ERROR + ' ' + self.config.errorTextClass; - errorTextParent.appendChild(errorTextElement); - errorTextElement.pristineDisplay = errorTextElement.style.display; - } + + if (validator.halt === true) { + break; } - return field.errorElements = [errorClassElement, errorTextElement]; + } + } + field.errors = errors; + return valid; + } + + /*** + * Add a validator to a specific dom element in a form + * @param elem => The dom element where the validator is applied to + * @param fn => validator function + * @param msg => message to show when validation fails. Supports templating. ${0} for the input's value, ${1} and + * so on are for the attribute values + * @param priority => priority of the validator function, higher valued function gets called first. + * @param halt => whether validation should stop for this field after current validation function + */ + self.addValidator = function (elem, fn, msg, priority, halt) { + if (elem instanceof HTMLElement) { + elem.pristine.validators.push({ fn: fn, msg: msg, priority: priority, halt: halt }); + elem.pristine.validators.sort(function (a, b) { + return b.priority - a.priority; + }); + } else { + console.warn("The parameter elem must be a dom element"); + } + }; + + /*** + * An utility function that returns a 2-element array, first one is the element where error/success class is + * applied. 2nd one is the element where error message is displayed. 2nd element is created if doesn't exist and cached. + * @param field + * @returns {*} + * @private + */ + function _getErrorElements(field) { + if (field.errorElements) { + return field.errorElements; } + var errorClassElement = findAncestor(field.input, self.config.classTo); + var errorTextParent = null, + errorTextElement = null; + if (self.config.classTo === self.config.errorTextParent) { + errorTextParent = errorClassElement; + } else { + errorTextParent = errorClassElement.querySelector("." + self.config.errorTextParent); + } + if (errorTextParent) { + errorTextElement = errorTextParent.querySelector("." + PRISTINE_ERROR); + if (!errorTextElement) { + errorTextElement = document.createElement(self.config.errorTextTag); + errorTextElement.className = PRISTINE_ERROR + " " + self.config.errorTextClass; + errorTextParent.appendChild(errorTextElement); + errorTextElement.pristineDisplay = errorTextElement.style.display; + } + } + return field.errorElements = [errorClassElement, errorTextElement]; + } - function _showError(field) { - var errorElements = _getErrorElements(field); - var errorClassElement = errorElements[0], - errorTextElement = errorElements[1]; + function _showError(field) { + var errorElements = _getErrorElements(field); + var errorClassElement = errorElements[0], + errorTextElement = errorElements[1]; - if (errorClassElement) { - errorClassElement.classList.remove(self.config.successClass); - errorClassElement.classList.add(self.config.errorClass); - } - if (errorTextElement) { - errorTextElement.innerHTML = field.errors.join('
'); - errorTextElement.style.display = errorTextElement.pristineDisplay || ''; - } + if (errorClassElement) { + errorClassElement.classList.remove(self.config.successClass); + errorClassElement.classList.add(self.config.errorClass); } - - /*** - * Adds error to a specific field - * @param input - * @param error - */ - self.addError = function (input, error) { - input = input.length ? input[0] : input; - input.pristine.errors.push(error); - _showError(input.pristine); - }; - - function _removeError(field) { - var errorElements = _getErrorElements(field); - var errorClassElement = errorElements[0], - errorTextElement = errorElements[1]; - if (errorClassElement) { - // IE > 9 doesn't support multiple class removal - errorClassElement.classList.remove(self.config.errorClass); - errorClassElement.classList.remove(self.config.successClass); - } - if (errorTextElement) { - errorTextElement.innerHTML = ''; - errorTextElement.style.display = 'none'; - } - return errorElements; + if (errorTextElement) { + errorTextElement.innerHTML = field.errors.join("
"); + errorTextElement.style.display = errorTextElement.pristineDisplay || ""; } - - function _showSuccess(field) { - var errorClassElement = _removeError(field)[0]; - errorClassElement && errorClassElement.classList.add(self.config.successClass); + } + + /*** + * Adds error to a specific field + * @param input + * @param error + */ + self.addError = function (input, error) { + input = input.length ? input[0] : input; + input.pristine.errors.push(error); + _showError(input.pristine); + }; + + function _removeError(field) { + var errorElements = _getErrorElements(field); + var errorClassElement = errorElements[0], + errorTextElement = errorElements[1]; + if (errorClassElement) { + // IE > 9 doesn't support multiple class removal + errorClassElement.classList.remove(self.config.errorClass); + errorClassElement.classList.remove(self.config.successClass); } + if (errorTextElement) { + errorTextElement.innerHTML = ""; + errorTextElement.style.display = "none"; + } + return errorElements; + } + + function _showSuccess(field) { + var errorClassElement = _removeError(field)[0]; + errorClassElement && errorClassElement.classList.add(self.config.successClass); + } + + /*** + * Resets the errors + */ + self.reset = function () { + for (var i = 0; self.fields[i]; i++) { + self.fields[i].errorElements = null; + } + Array.from(self.form.querySelectorAll("." + PRISTINE_ERROR)).map(function (elem) { + elem.parentNode.removeChild(elem); + }); + Array.from(self.form.querySelectorAll("." + self.config.classTo)).map(function (elem) { + elem.classList.remove(self.config.successClass); + elem.classList.remove(self.config.errorClass); + }); + }; + + /*** + * Resets the errors and deletes all pristine fields + */ + self.destroy = function () { + self.reset(); + self.fields.forEach(function (field) { + delete field.input.pristine; + }); + self.fields = []; + }; - /*** - * Resets the errors - */ - self.reset = function () { - for (var i = 0; self.fields[i]; i++) { - self.fields[i].errorElements = null; - } - Array.from(self.form.querySelectorAll('.' + PRISTINE_ERROR)).map(function (elem) { - elem.parentNode.removeChild(elem); - }); - Array.from(self.form.querySelectorAll('.' + self.config.classTo)).map(function (elem) { - elem.classList.remove(self.config.successClass); - elem.classList.remove(self.config.errorClass); - }); - }; - - /*** - * Resets the errors and deletes all pristine fields - */ - self.destroy = function () { - self.reset(); - self.fields.forEach(function (field) { - delete field.input.pristine; - }); - self.fields = []; - }; - - self.setGlobalConfig = function (config) { - defaultConfig = config; - }; + self.setGlobalConfig = function (config) { + defaultConfig = config; + }; - return self; + return self; } /*** @@ -403,19 +425,19 @@ * @param halt => whether validation should stop for this field after current validation function */ Pristine.addValidator = function (name, fn, msg, priority, halt) { - _(name, { fn: fn, msg: msg, priority: priority, halt: halt }); + _(name, { fn: fn, msg: msg, priority: priority, halt: halt }); }; Pristine.addMessages = function (locale, messages) { - var langObj = lang.hasOwnProperty(locale) ? lang[locale] : lang[locale] = {}; + var langObj = lang.hasOwnProperty(locale) ? lang[locale] : lang[locale] = {}; - Object.keys(messages).forEach(function (key, index) { - langObj[key] = messages[key]; - }); + Object.keys(messages).forEach(function (key, index) { + langObj[key] = messages[key]; + }); }; Pristine.setLocale = function (locale) { - currentLocale = locale; + currentLocale = locale; }; return Pristine; diff --git a/dist/pristine.min.js b/dist/pristine.min.js index 75030ff..8c2656d 100644 --- a/dist/pristine.min.js +++ b/dist/pristine.min.js @@ -1 +1 @@ -!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).Pristine=r()}(this,(function(){"use strict";var e={en:{required:"This field is required",email:"This field requires a valid e-mail address",number:"This field requires a number",integer:"This field requires an integer value",url:"This field requires a valid website URL",tel:"This field requires a valid telephone number",maxlength:"This fields length must be < ${1}",minlength:"This fields length must be > ${1}",min:"Minimum value for this field is ${1}",max:"Maximum value for this field is ${1}",pattern:"Please match the requested format",equals:"The two fields do not match"}};function r(e){var r=arguments;return this.replace(/\${([^{}]*)}/g,(function(e,t){return r[t]}))}function t(e){return e.pristine.self.form.querySelectorAll('input[name="'+e.getAttribute("name")+'"]:checked').length}var n={classTo:"form-group",errorClass:"has-danger",successClass:"has-success",errorTextParent:"form-group",errorTextTag:"div",errorTextClass:"text-help"},i=["required","min","max","minlength","maxlength","pattern"],s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,a=/-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/,o="en",l={},u=function(e,r){r.name=e,void 0===r.priority&&(r.priority=1),l[e]=r};function f(t,s,u){var f=this;function c(e,r,t,n){var i=l[t];if(i&&(e.push(i),n)){var s="pattern"===t?[n]:n.split(",");s.unshift(null),r[t]=s}}function p(t){for(var n=[],i=!0,s=0;t.validators[s];s++){var a=t.validators[s],l=t.params[a.name]?t.params[a.name]:[];if(l[0]=t.input.value,!a.fn.apply(t.input,l)&&(i=!1,"function"==typeof a.msg?n.push(a.msg(t.input.value,l)):"string"==typeof a.msg?n.push(r.apply(a.msg,l)):a.msg===Object(a.msg)&&a.msg[o]?n.push(r.apply(a.msg[o],l)):t.messages[o]&&t.messages[o][a.name]?n.push(r.apply(t.messages[o][a.name],l)):e[o]&&e[o][a.name]&&n.push(r.apply(e[o][a.name],l)),!0===a.halt))break}return t.errors=n,i}function m(e){if(e.errorElements)return e.errorElements;var r=function(e,r){for(;(e=e.parentElement)&&!e.classList.contains(r););return e}(e.input,f.config.classTo),t=null,n=null;return(t=f.config.classTo===f.config.errorTextParent?r:r.querySelector("."+f.config.errorTextParent))&&((n=t.querySelector(".pristine-error"))||((n=document.createElement(f.config.errorTextTag)).className="pristine-error "+f.config.errorTextClass,t.appendChild(n),n.pristineDisplay=n.style.display)),e.errorElements=[r,n]}function d(e){var r=m(e),t=r[0],n=r[1];t&&(t.classList.remove(f.config.successClass),t.classList.add(f.config.errorClass)),n&&(n.innerHTML=e.errors.join("
"),n.style.display=n.pristineDisplay||"")}function h(e){var r=function(e){var r=m(e),t=r[0],n=r[1];return t&&(t.classList.remove(f.config.errorClass),t.classList.remove(f.config.successClass)),n&&(n.innerHTML="",n.style.display="none"),r}(e)[0];r&&r.classList.add(f.config.successClass)}return function(e,r,t){e.setAttribute("novalidate","true"),f.form=e,f.config=function(e,r){for(var t in r)t in e||(e[t]=r[t]);return e}(r||{},n),f.live=!(!1===t),f.fields=Array.from(e.querySelectorAll("input:not([type^=hidden]):not([type^=submit]), select, textarea")).map(function(e){var r=[],t={},n={};return[].forEach.call(e.attributes,(function(e){if(/^data-pristine-/.test(e.name)){var s=e.name.substr(14),o=s.match(a);if(null!==o){var l=void 0===o[1]?"en":o[1];return n.hasOwnProperty(l)||(n[l]={}),void(n[l][s.slice(0,s.length-o[0].length)]=e.value)}"type"===s&&(s=e.value),c(r,t,s,e.value)}else~i.indexOf(e.name)?c(r,t,e.name,e.value):"type"===e.name&&c(r,t,e.value)})),r.sort((function(e,r){return r.priority-e.priority})),f.live&&e.addEventListener(~["radio","checkbox"].indexOf(e.getAttribute("type"))?"change":"input",function(e){f.validate(e.target)}.bind(f)),e.pristine={input:e,validators:r,params:t,messages:n,self:f}}.bind(f))}(t,s,u),f.validate=function(e,r){r=e&&!0===r||!0===e;var t=f.fields;!0!==e&&!1!==e&&(e instanceof HTMLElement?t=[e.pristine]:(e instanceof NodeList||e instanceof(window.$||Array)||e instanceof Array)&&(t=Array.from(e).map((function(e){return e.pristine}))));for(var n=!0,i=0;t[i];i++){var s=t[i];p(s)?!r&&h(s):(n=!1,!r&&d(s))}return n},f.getErrors=function(e){if(!e){for(var r=[],t=0;t=parseInt(r)}}),u("maxlength",{fn:function(e,r){return!e||e.length<=parseInt(r)}}),u("min",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)>=parseInt(r):parseFloat(e)>=parseFloat(r))}}),u("max",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)<=parseInt(r):parseFloat(e)<=parseFloat(r))}}),u("pattern",{fn:function(e,r){var t=r.match(new RegExp("^/(.*?)/([gimy]*)$"));return!e||new RegExp(t[1],t[2]).test(e)}}),u("equals",{fn:function(e,r){var t=document.querySelector(r);return t&&(!e&&!t.value||t.value===e)}}),f.addValidator=function(e,r,t,n,i){u(e,{fn:r,msg:t,priority:n,halt:i})},f.addMessages=function(r,t){var n=e.hasOwnProperty(r)?e[r]:e[r]={};Object.keys(t).forEach((function(e,r){n[e]=t[e]}))},f.setLocale=function(e){o=e},f})); +!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).Pristine=r()}(this,(function(){"use strict";var e={en:{required:"This field is required",email:"This field requires a valid e-mail address",number:"This field requires a number",integer:"This field requires an integer value",url:"This field requires a valid website URL",tel:"This field requires a valid telephone number",maxlength:"This fields length must be < ${1}",minlength:"This fields length must be > ${1}",min:"Minimum value for this field is ${1}",max:"Maximum value for this field is ${1}",pattern:"Please match the requested format",equals:"The two fields do not match",default:"Please enter a correct value"}};function r(e){var r=arguments;return this.replace(/\${([^{}]*)}/g,(function(e,t){return r[t]}))}function t(e){return e.pristine.self.form.querySelectorAll('input[name="'+e.getAttribute("name")+'"]:checked').length}var n={classTo:"form-group",errorClass:"has-danger",successClass:"has-success",errorTextParent:"form-group",errorTextTag:"div",errorTextClass:"text-help"},i=["required","min","max","minlength","maxlength","pattern"],s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,a=/-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/,o="en",l={},u=function(e,r){r.name=e,void 0===r.priority&&(r.priority=1),l[e]=r};function f(t,s,u){var f=this;function c(e,r,t,n){var i=l[t];if(i&&(e.push(i),n)){var s="pattern"===t?[n]:n.split(",");s.unshift(null),r[t]=s}}function p(t){for(var n=[],i=!0,s=0;t.validators[s];s++){var a=t.validators[s],l=t.params[a.name]?t.params[a.name]:[];if(l[0]=t.input.value,!a.fn.apply(t.input,l)&&(i=!1,"function"==typeof a.msg?n.push(a.msg(t.input.value,l)):"string"==typeof a.msg?n.push(r.apply(a.msg,l)):a.msg===Object(a.msg)&&a.msg[o]?n.push(r.apply(a.msg[o],l)):t.messages[o]&&t.messages[o][a.name]?n.push(r.apply(t.messages[o][a.name],l)):e[o]&&e[o][a.name]?n.push(r.apply(e[o][a.name],l)):n.push(r.apply(e[o].default,l)),!0===a.halt))break}return t.errors=n,i}function m(e){if(e.errorElements)return e.errorElements;var r=function(e,r){for(;(e=e.parentElement)&&!e.classList.contains(r););return e}(e.input,f.config.classTo),t=null,n=null;return(t=f.config.classTo===f.config.errorTextParent?r:r.querySelector("."+f.config.errorTextParent))&&((n=t.querySelector(".pristine-error"))||((n=document.createElement(f.config.errorTextTag)).className="pristine-error "+f.config.errorTextClass,t.appendChild(n),n.pristineDisplay=n.style.display)),e.errorElements=[r,n]}function d(e){var r=m(e),t=r[0],n=r[1];t&&(t.classList.remove(f.config.successClass),t.classList.add(f.config.errorClass)),n&&(n.innerHTML=e.errors.join("
"),n.style.display=n.pristineDisplay||"")}function h(e){var r=function(e){var r=m(e),t=r[0],n=r[1];return t&&(t.classList.remove(f.config.errorClass),t.classList.remove(f.config.successClass)),n&&(n.innerHTML="",n.style.display="none"),r}(e)[0];r&&r.classList.add(f.config.successClass)}return function(e,r,t){e.setAttribute("novalidate","true"),f.form=e,f.config=function(e,r){for(var t in r)t in e||(e[t]=r[t]);return e}(r||{},n),f.live=!(!1===t),f.fields=Array.from(e.querySelectorAll("input:not([type^=hidden]):not([type^=submit]), select, textarea")).map(function(e){var r=[],t={},n={};return[].forEach.call(e.attributes,(function(e){if(/^data-pristine-/.test(e.name)){var s=e.name.substr(14),o=s.match(a);if(null!==o){var l=void 0===o[1]?"en":o[1];return n.hasOwnProperty(l)||(n[l]={}),void(n[l][s.slice(0,s.length-o[0].length)]=e.value)}"type"===s&&(s=e.value),c(r,t,s,e.value)}else~i.indexOf(e.name)?c(r,t,e.name,e.value):"type"===e.name&&c(r,t,e.value)})),r.sort((function(e,r){return r.priority-e.priority})),f.live&&e.addEventListener(~["radio","checkbox"].indexOf(e.getAttribute("type"))?"change":"input",function(e){f.validate(e.target)}.bind(f)),e.pristine={input:e,validators:r,params:t,messages:n,self:f}}.bind(f))}(t,s,u),f.validate=function(e,r){r=e&&!0===r||!0===e;var t=f.fields;!0!==e&&!1!==e&&(e instanceof HTMLElement?t=[e.pristine]:(e instanceof NodeList||e instanceof(window.$||Array)||e instanceof Array)&&(t=Array.from(e).map((function(e){return e.pristine}))));for(var n=!0,i=0;t[i];i++){var s=t[i];p(s)?!r&&h(s):(n=!1,!r&&d(s))}return n},f.getErrors=function(e){if(!e){for(var r=[],t=0;t=parseInt(r)}}),u("maxlength",{fn:function(e,r){return!e||e.length<=parseInt(r)}}),u("min",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)>=parseInt(r):parseFloat(e)>=parseFloat(r))}}),u("max",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)<=parseInt(r):parseFloat(e)<=parseFloat(r))}}),u("pattern",{fn:function(e,r){var t=r.match(new RegExp("^/(.*?)/([gimy]*)$"));return!e||new RegExp(t[1],t[2]).test(e)}}),u("equals",{fn:function(e,r){var t=document.querySelector(r);return t&&(!e&&!t.value||t.value===e)}}),console.log(u),f.addValidator=function(e,r,t,n,i){u(e,{fn:r,msg:t,priority:n,halt:i})},f.addMessages=function(r,t){var n=e.hasOwnProperty(r)?e[r]:e[r]={};Object.keys(t).forEach((function(e,r){n[e]=t[e]}))},f.setLocale=function(e){o=e},f})); diff --git a/package-lock.json b/package-lock.json index 13709d2..1da603b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "pristinejs", - "version": "0.1.8", + "version": "0.1.9", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/pristine.js b/src/pristine.js index 6fd296a..916f604 100755 --- a/src/pristine.js +++ b/src/pristine.js @@ -1,325 +1,407 @@ -import { lang } from './lang'; -import { tmpl, findAncestor, groupedElemCount, mergeConfig } from './utils'; +import { lang } from "./lang"; +import { tmpl, findAncestor, groupedElemCount, mergeConfig } from "./utils"; let defaultConfig = { - classTo: 'form-group', - errorClass: 'has-danger', - successClass: 'has-success', - errorTextParent: 'form-group', - errorTextTag: 'div', - errorTextClass: 'text-help' + classTo: "form-group", + errorClass: "has-danger", + successClass: "has-success", + errorTextParent: "form-group", + errorTextTag: "div", + errorTextClass: "text-help", }; -const PRISTINE_ERROR = 'pristine-error'; -const SELECTOR = "input:not([type^=hidden]):not([type^=submit]), select, textarea"; -const ALLOWED_ATTRIBUTES = ["required", "min", "max", 'minlength', 'maxlength', 'pattern']; -const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ +const PRISTINE_ERROR = "pristine-error"; +const SELECTOR = + "input:not([type^=hidden]):not([type^=submit]), select, textarea"; +const ALLOWED_ATTRIBUTES = [ + "required", + "min", + "max", + "minlength", + "maxlength", + "pattern", +]; +const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; const MESSAGE_REGEX = /-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/; // matches, -message, -message-en, -message-en_US -let currentLocale = 'en'; +let currentLocale = "en"; const validators = {}; const _ = function (name, validator) { - validator.name = name; - if (validator.priority === undefined) - validator.priority = 1; - validators[name] = validator; + validator.name = name; + if (validator.priority === undefined) validator.priority = 1; + validators[name] = validator; }; -_('text', { fn: (val) => true, priority: 0}); -_('required', { fn: function(val){ return (this.type === 'radio' || this.type === 'checkbox') ? groupedElemCount(this) : val !== undefined && val !== ''}, priority: 99, halt: true}); -_('email', { fn: (val) => !val || EMAIL_REGEX.test(val)}); -_('number', { fn: (val) => !val || !isNaN(parseFloat(val)), priority: 2 }); -_('integer', { fn: (val) => !val || /^\d+$/.test(val) }); -_('minlength', { fn: (val, length) => !val || val.length >= parseInt(length) }); -_('maxlength', { fn: (val, length) => !val || val.length <= parseInt(length) }); -_('min', { fn: function(val, limit){ return !val || (this.type === 'checkbox' ? groupedElemCount(this) >= parseInt(limit) : parseFloat(val) >= parseFloat(limit)); } }); -_('max', { fn: function(val, limit){ return !val || (this.type === 'checkbox' ? groupedElemCount(this) <= parseInt(limit) : parseFloat(val) <= parseFloat(limit)); } }); -_('pattern', { fn: (val, pattern) => { let m = pattern.match(new RegExp('^/(.*?)/([gimy]*)$')); return !val || (new RegExp(m[1], m[2])).test(val);} }); -_('equals', { fn: (val, otherFieldSelector) => { let other = document.querySelector(otherFieldSelector); return (other) && ((!val && !other.value) || (other.value === val)); } }); - -export default function Pristine(form, config, live){ - - let self = this; - - init(form, config, live); - - function init(form, config, live){ - - form.setAttribute("novalidate", "true"); - - self.form = form; - self.config = mergeConfig(config || {}, defaultConfig); - self.live = !(live === false); - self.fields = Array.from(form.querySelectorAll(SELECTOR)).map(function (input) { - - let fns = []; - let params = {}; - let messages = {}; - - [].forEach.call(input.attributes, function (attr) { - if (/^data-pristine-/.test(attr.name)) { - let name = attr.name.substr(14); - let messageMatch = name.match(MESSAGE_REGEX); - if (messageMatch !== null){ - let locale = messageMatch[1] === undefined ? 'en' : messageMatch[1]; - if (!messages.hasOwnProperty(locale)) - messages[locale] = {}; - messages[locale][name.slice(0, name.length - messageMatch[0].length)] = attr.value; - return; - } - if (name === 'type') name = attr.value; - _addValidatorToField(fns, params, name, attr.value); - } else if (~ALLOWED_ATTRIBUTES.indexOf(attr.name)){ - _addValidatorToField(fns, params, attr.name, attr.value); - } else if (attr.name === 'type'){ - _addValidatorToField(fns, params, attr.value); - } - }); - - fns.sort( (a, b) => b.priority - a.priority); - - self.live && input.addEventListener((!~['radio', 'checkbox'].indexOf(input.getAttribute('type')) ? 'input':'change'), function(e) { - self.validate(e.target); - }.bind(self)); - - return input.pristine = {input, validators: fns, params, messages, self}; - - }.bind(self)); - } - - function _addValidatorToField(fns, params, name, value) { - let validator = validators[name]; - if (validator) { - fns.push(validator); - if (value) { - let valueParams = (name === "pattern" ? [value]: value.split(',')); - valueParams.unshift(null); // placeholder for input's value - params[name] = valueParams; +_("text", { fn: (val) => true, priority: 0 }); +_("required", { + fn: function (val) { + return this.type === "radio" || this.type === "checkbox" + ? groupedElemCount(this) + : val !== undefined && val !== ""; + }, + priority: 99, + halt: true, +}); +_("email", { fn: (val) => !val || EMAIL_REGEX.test(val) }); +_("number", { fn: (val) => !val || !isNaN(parseFloat(val)), priority: 2 }); +_("integer", { fn: (val) => !val || /^\d+$/.test(val) }); +_("minlength", { fn: (val, length) => !val || val.length >= parseInt(length) }); +_("maxlength", { fn: (val, length) => !val || val.length <= parseInt(length) }); +_("min", { + fn: function (val, limit) { + return ( + !val || + (this.type === "checkbox" + ? groupedElemCount(this) >= parseInt(limit) + : parseFloat(val) >= parseFloat(limit)) + ); + }, +}); +_("max", { + fn: function (val, limit) { + return ( + !val || + (this.type === "checkbox" + ? groupedElemCount(this) <= parseInt(limit) + : parseFloat(val) <= parseFloat(limit)) + ); + }, +}); +_("pattern", { + fn: (val, pattern) => { + let m = pattern.match(new RegExp("^/(.*?)/([gimy]*)$")); + return !val || new RegExp(m[1], m[2]).test(val); + }, +}); +_("equals", { + fn: (val, otherFieldSelector) => { + let other = document.querySelector(otherFieldSelector); + return other && ((!val && !other.value) || other.value === val); + }, +}); + +console.log(_); + +export default function Pristine(form, config, live) { + let self = this; + + init(form, config, live); + + function init(form, config, live) { + form.setAttribute("novalidate", "true"); + + self.form = form; + self.config = mergeConfig(config || {}, defaultConfig); + self.live = !(live === false); + self.fields = Array.from(form.querySelectorAll(SELECTOR)).map( + function (input) { + let fns = []; + let params = {}; + let messages = {}; + + [].forEach.call(input.attributes, function (attr) { + if (/^data-pristine-/.test(attr.name)) { + let name = attr.name.substr(14); + let messageMatch = name.match(MESSAGE_REGEX); + if (messageMatch !== null) { + let locale = + messageMatch[1] === undefined ? "en" : messageMatch[1]; + if (!messages.hasOwnProperty(locale)) messages[locale] = {}; + messages[locale][ + name.slice(0, name.length - messageMatch[0].length) + ] = attr.value; + return; } - } - } + if (name === "type") name = attr.value; + _addValidatorToField(fns, params, name, attr.value); + } else if (~ALLOWED_ATTRIBUTES.indexOf(attr.name)) { + _addValidatorToField(fns, params, attr.name, attr.value); + } else if (attr.name === "type") { + _addValidatorToField(fns, params, attr.value); + } + }); - /*** - * Checks whether the form/input elements are valid - * @param input => input element(s) or a jquery selector, null for full form validation - * @param silent => do not show error messages, just return true/false - * @returns {boolean} return true when valid false otherwise - */ - self.validate = function(input, silent){ - silent = (input && silent === true) || input === true; - let fields = self.fields; - if (input !== true && input !== false){ - if (input instanceof HTMLElement) { - fields = [input.pristine]; - } else if (input instanceof NodeList || input instanceof (window.$ || Array) || input instanceof Array){ - fields = Array.from(input).map(el => el.pristine); - } - } + fns.sort((a, b) => b.priority - a.priority); + + self.live && + input.addEventListener( + !~["radio", "checkbox"].indexOf(input.getAttribute("type")) + ? "input" + : "change", + function (e) { + self.validate(e.target); + }.bind(self) + ); + + return (input.pristine = { + input, + validators: fns, + params, + messages, + self, + }); + }.bind(self) + ); + } + + function _addValidatorToField(fns, params, name, value) { + let validator = validators[name]; + if (validator) { + fns.push(validator); + if (value) { + let valueParams = name === "pattern" ? [value] : value.split(","); + valueParams.unshift(null); // placeholder for input's value + params[name] = valueParams; + } + } + } + + /*** + * Checks whether the form/input elements are valid + * @param input => input element(s) or a jquery selector, null for full form validation + * @param silent => do not show error messages, just return true/false + * @returns {boolean} return true when valid false otherwise + */ + self.validate = function (input, silent) { + silent = (input && silent === true) || input === true; + let fields = self.fields; + if (input !== true && input !== false) { + if (input instanceof HTMLElement) { + fields = [input.pristine]; + } else if ( + input instanceof NodeList || + input instanceof (window.$ || Array) || + input instanceof Array + ) { + fields = Array.from(input).map((el) => el.pristine); + } + } - let valid = true; + let valid = true; - for(let i = 0; fields[i]; i++) { - let field = fields[i]; - if (_validateField(field)){ - !silent && _showSuccess(field); - } else { - valid = false; - !silent && _showError(field); - } - } - return valid; - }; - - /*** - * Get errors of a specific field or the whole form - * @param input - * @returns {Array|*} - */ - self.getErrors = function(input) { - if (!input){ - let erroneousFields = []; - for(let i=0; i The dom element where the validator is applied to - * @param fn => validator function - * @param msg => message to show when validation fails. Supports templating. ${0} for the input's value, ${1} and - * so on are for the attribute values - * @param priority => priority of the validator function, higher valued function gets called first. - * @param halt => whether validation should stop for this field after current validation function - */ - self.addValidator = function(elem, fn, msg, priority, halt){ - if (elem instanceof HTMLElement){ - elem.pristine.validators.push({fn, msg, priority, halt}); - elem.pristine.validators.sort( (a, b) => b.priority - a.priority); - } else { - console.warn("The parameter elem must be a dom element"); - } - }; - - /*** - * An utility function that returns a 2-element array, first one is the element where error/success class is - * applied. 2nd one is the element where error message is displayed. 2nd element is created if doesn't exist and cached. - * @param field - * @returns {*} - * @private - */ - function _getErrorElements(field) { - if (field.errorElements){ - return field.errorElements; + return valid; + }; + + /*** + * Get errors of a specific field or the whole form + * @param input + * @returns {Array|*} + */ + self.getErrors = function (input) { + if (!input) { + let erroneousFields = []; + for (let i = 0; i < self.fields.length; i++) { + let field = self.fields[i]; + if (field.errors.length) { + erroneousFields.push({ input: field.input, errors: field.errors }); } - let errorClassElement = findAncestor(field.input, self.config.classTo); - let errorTextParent = null, errorTextElement = null; - if (self.config.classTo === self.config.errorTextParent){ - errorTextParent = errorClassElement; + } + return erroneousFields; + } + if (input.tagName && input.tagName.toLowerCase() === "select") { + return input.pristine.errors; + } + return input.length ? input[0].pristine.errors : input.pristine.errors; + }; + + /*** + * Validates a single field, all validator functions are called and error messages are generated + * when a validator fails + * @param field + * @returns {boolean} + * @private + */ + function _validateField(field) { + let errors = []; + let valid = true; + for (let i = 0; field.validators[i]; i++) { + let validator = field.validators[i]; + let params = field.params[validator.name] + ? field.params[validator.name] + : []; + params[0] = field.input.value; + if (!validator.fn.apply(field.input, params)) { + valid = false; + + if (typeof validator.msg === "function") { + errors.push(validator.msg(field.input.value, params)); + } else if (typeof validator.msg === "string") { + errors.push(tmpl.apply(validator.msg, params)); + } else if ( + validator.msg === Object(validator.msg) && + validator.msg[currentLocale] + ) { + // typeof generates unnecessary babel code + errors.push(tmpl.apply(validator.msg[currentLocale], params)); + } else if ( + field.messages[currentLocale] && + field.messages[currentLocale][validator.name] + ) { + errors.push( + tmpl.apply(field.messages[currentLocale][validator.name], params) + ); + } else if (lang[currentLocale] && lang[currentLocale][validator.name]) { + errors.push(tmpl.apply(lang[currentLocale][validator.name], params)); } else { - errorTextParent = errorClassElement.querySelector('.' + self.config.errorTextParent); - } - if (errorTextParent){ - errorTextElement = errorTextParent.querySelector('.' + PRISTINE_ERROR); - if (!errorTextElement){ - errorTextElement = document.createElement(self.config.errorTextTag); - errorTextElement.className = PRISTINE_ERROR + ' ' + self.config.errorTextClass; - errorTextParent.appendChild(errorTextElement); - errorTextElement.pristineDisplay = errorTextElement.style.display; - } + errors.push(tmpl.apply(lang[currentLocale].default, params)); } - return field.errorElements = [errorClassElement, errorTextElement] - } - - function _showError(field){ - let errorElements = _getErrorElements(field); - let errorClassElement = errorElements[0], errorTextElement = errorElements[1]; - if(errorClassElement){ - errorClassElement.classList.remove(self.config.successClass); - errorClassElement.classList.add(self.config.errorClass); - } - if (errorTextElement){ - errorTextElement.innerHTML = field.errors.join('
'); - errorTextElement.style.display = errorTextElement.pristineDisplay || ''; + if (validator.halt === true) { + break; } + } } - - /*** - * Adds error to a specific field - * @param input - * @param error - */ - self.addError = function(input, error) { - input = input.length ? input[0] : input; - input.pristine.errors.push(error); - _showError(input.pristine); - }; - - function _removeError(field){ - let errorElements = _getErrorElements(field); - let errorClassElement = errorElements[0], errorTextElement = errorElements[1]; - if (errorClassElement){ - // IE > 9 doesn't support multiple class removal - errorClassElement.classList.remove(self.config.errorClass); - errorClassElement.classList.remove(self.config.successClass); - } - if (errorTextElement){ - errorTextElement.innerHTML = ''; - errorTextElement.style.display = 'none'; - } - return errorElements; + field.errors = errors; + return valid; + } + + /*** + * Add a validator to a specific dom element in a form + * @param elem => The dom element where the validator is applied to + * @param fn => validator function + * @param msg => message to show when validation fails. Supports templating. ${0} for the input's value, ${1} and + * so on are for the attribute values + * @param priority => priority of the validator function, higher valued function gets called first. + * @param halt => whether validation should stop for this field after current validation function + */ + self.addValidator = function (elem, fn, msg, priority, halt) { + if (elem instanceof HTMLElement) { + elem.pristine.validators.push({ fn, msg, priority, halt }); + elem.pristine.validators.sort((a, b) => b.priority - a.priority); + } else { + console.warn("The parameter elem must be a dom element"); } - - function _showSuccess(field){ - let errorClassElement = _removeError(field)[0]; - errorClassElement && errorClassElement.classList.add(self.config.successClass); + }; + + /*** + * An utility function that returns a 2-element array, first one is the element where error/success class is + * applied. 2nd one is the element where error message is displayed. 2nd element is created if doesn't exist and cached. + * @param field + * @returns {*} + * @private + */ + function _getErrorElements(field) { + if (field.errorElements) { + return field.errorElements; } + let errorClassElement = findAncestor(field.input, self.config.classTo); + let errorTextParent = null, + errorTextElement = null; + if (self.config.classTo === self.config.errorTextParent) { + errorTextParent = errorClassElement; + } else { + errorTextParent = errorClassElement.querySelector( + "." + self.config.errorTextParent + ); + } + if (errorTextParent) { + errorTextElement = errorTextParent.querySelector("." + PRISTINE_ERROR); + if (!errorTextElement) { + errorTextElement = document.createElement(self.config.errorTextTag); + errorTextElement.className = + PRISTINE_ERROR + " " + self.config.errorTextClass; + errorTextParent.appendChild(errorTextElement); + errorTextElement.pristineDisplay = errorTextElement.style.display; + } + } + return (field.errorElements = [errorClassElement, errorTextElement]); + } - /*** - * Resets the errors - */ - self.reset = function () { - for(let i = 0; self.fields[i]; i++) { - self.fields[i].errorElements = null; - } - Array.from(self.form.querySelectorAll('.' + PRISTINE_ERROR)).map(function (elem) { - elem.parentNode.removeChild(elem); - }); - Array.from(self.form.querySelectorAll('.' + self.config.classTo)).map(function (elem) { - elem.classList.remove(self.config.successClass); - elem.classList.remove(self.config.errorClass); - }); - - }; - - /*** - * Resets the errors and deletes all pristine fields - */ - self.destroy = function(){ - self.reset(); - self.fields.forEach(function (field) { - delete field.input.pristine; - }); - self.fields = []; - }; + function _showError(field) { + let errorElements = _getErrorElements(field); + let errorClassElement = errorElements[0], + errorTextElement = errorElements[1]; - self.setGlobalConfig = function (config) { - defaultConfig = config; - }; + if (errorClassElement) { + errorClassElement.classList.remove(self.config.successClass); + errorClassElement.classList.add(self.config.errorClass); + } + if (errorTextElement) { + errorTextElement.innerHTML = field.errors.join("
"); + errorTextElement.style.display = errorTextElement.pristineDisplay || ""; + } + } + + /*** + * Adds error to a specific field + * @param input + * @param error + */ + self.addError = function (input, error) { + input = input.length ? input[0] : input; + input.pristine.errors.push(error); + _showError(input.pristine); + }; + + function _removeError(field) { + let errorElements = _getErrorElements(field); + let errorClassElement = errorElements[0], + errorTextElement = errorElements[1]; + if (errorClassElement) { + // IE > 9 doesn't support multiple class removal + errorClassElement.classList.remove(self.config.errorClass); + errorClassElement.classList.remove(self.config.successClass); + } + if (errorTextElement) { + errorTextElement.innerHTML = ""; + errorTextElement.style.display = "none"; + } + return errorElements; + } + + function _showSuccess(field) { + let errorClassElement = _removeError(field)[0]; + errorClassElement && + errorClassElement.classList.add(self.config.successClass); + } + + /*** + * Resets the errors + */ + self.reset = function () { + for (let i = 0; self.fields[i]; i++) { + self.fields[i].errorElements = null; + } + Array.from(self.form.querySelectorAll("." + PRISTINE_ERROR)).map(function ( + elem + ) { + elem.parentNode.removeChild(elem); + }); + Array.from(self.form.querySelectorAll("." + self.config.classTo)).map( + function (elem) { + elem.classList.remove(self.config.successClass); + elem.classList.remove(self.config.errorClass); + } + ); + }; + + /*** + * Resets the errors and deletes all pristine fields + */ + self.destroy = function () { + self.reset(); + self.fields.forEach(function (field) { + delete field.input.pristine; + }); + self.fields = []; + }; - return self; + self.setGlobalConfig = function (config) { + defaultConfig = config; + }; + return self; + return {}; } /*** @@ -331,18 +413,20 @@ export default function Pristine(form, config, live){ * @param priority => priority of the validator function, higher valued function gets called first. * @param halt => whether validation should stop for this field after current validation function */ -Pristine.addValidator = function(name, fn, msg, priority, halt){ - _(name, {fn, msg, priority, halt}); +Pristine.addValidator = function (name, fn, msg, priority, halt) { + _(name, { fn, msg, priority, halt }); }; -Pristine.addMessages = function(locale, messages){ - let langObj = lang.hasOwnProperty(locale) ? lang[locale] : lang[locale] = {}; +Pristine.addMessages = function (locale, messages) { + let langObj = lang.hasOwnProperty(locale) + ? lang[locale] + : (lang[locale] = {}); - Object.keys(messages).forEach(function(key, index) { - langObj[key] = messages[key]; - }); -} + Object.keys(messages).forEach(function (key, index) { + langObj[key] = messages[key]; + }); +}; -Pristine.setLocale = function (locale){ - currentLocale = locale; -} +Pristine.setLocale = function (locale) { + currentLocale = locale; +}; From 583a0134c5a4795c1c41d71428cbf3907f7f0bc1 Mon Sep 17 00:00:00 2001 From: Nicolas Cusan Date: Mon, 8 Feb 2021 18:23:02 +0100 Subject: [PATCH 02/11] bring back previous coding style --- dist/pristine.js | 671 +++++++++++++++++++++-------------------- dist/pristine.min.js | 2 +- src/pristine.js | 694 +++++++++++++++++++------------------------ 3 files changed, 637 insertions(+), 730 deletions(-) diff --git a/dist/pristine.js b/dist/pristine.js index eb3478f..38024c6 100644 --- a/dist/pristine.js +++ b/dist/pristine.js @@ -49,370 +49,361 @@ } var defaultConfig = { - classTo: "form-group", - errorClass: "has-danger", - successClass: "has-success", - errorTextParent: "form-group", - errorTextTag: "div", - errorTextClass: "text-help" + classTo: 'form-group', + errorClass: 'has-danger', + successClass: 'has-success', + errorTextParent: 'form-group', + errorTextTag: 'div', + errorTextClass: 'text-help', + liveAfterFirstValitation: true }; - var PRISTINE_ERROR = "pristine-error"; + var PRISTINE_ERROR = 'pristine-error'; var SELECTOR = "input:not([type^=hidden]):not([type^=submit]), select, textarea"; - var ALLOWED_ATTRIBUTES = ["required", "min", "max", "minlength", "maxlength", "pattern"]; + var ALLOWED_ATTRIBUTES = ["required", "min", "max", 'minlength', 'maxlength', 'pattern']; var EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; var MESSAGE_REGEX = /-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/; // matches, -message, -message-en, -message-en_US - var currentLocale = "en"; + var currentLocale = 'en'; var validators = {}; var _ = function _(name, validator) { - validator.name = name; - if (validator.priority === undefined) validator.priority = 1; - validators[name] = validator; + validator.name = name; + if (validator.priority === undefined) validator.priority = 1; + validators[name] = validator; }; - _("text", { fn: function fn(val) { - return true; - }, priority: 0 }); - _("required", { - fn: function fn(val) { - return this.type === "radio" || this.type === "checkbox" ? groupedElemCount(this) : val !== undefined && val !== ""; - }, - priority: 99, - halt: true - }); - _("email", { fn: function fn(val) { - return !val || EMAIL_REGEX.test(val); - } }); - _("number", { fn: function fn(val) { - return !val || !isNaN(parseFloat(val)); - }, priority: 2 }); - _("integer", { fn: function fn(val) { - return !val || /^\d+$/.test(val); - } }); - _("minlength", { fn: function fn(val, length) { - return !val || val.length >= parseInt(length); - } }); - _("maxlength", { fn: function fn(val, length) { - return !val || val.length <= parseInt(length); - } }); - _("min", { - fn: function fn(val, limit) { - return !val || (this.type === "checkbox" ? groupedElemCount(this) >= parseInt(limit) : parseFloat(val) >= parseFloat(limit)); - } - }); - _("max", { - fn: function fn(val, limit) { - return !val || (this.type === "checkbox" ? groupedElemCount(this) <= parseInt(limit) : parseFloat(val) <= parseFloat(limit)); - } - }); - _("pattern", { - fn: function fn(val, pattern) { - var m = pattern.match(new RegExp("^/(.*?)/([gimy]*)$")); - return !val || new RegExp(m[1], m[2]).test(val); - } - }); - _("equals", { - fn: function fn(val, otherFieldSelector) { - var other = document.querySelector(otherFieldSelector); - return other && (!val && !other.value || other.value === val); - } - }); - - console.log(_); + _('text', { fn: function fn(val) { + return true; + }, priority: 0 }); + _('required', { fn: function fn(val) { + return this.type === 'radio' || this.type === 'checkbox' ? groupedElemCount(this) : val !== undefined && val !== ''; + }, priority: 99, halt: true }); + _('email', { fn: function fn(val) { + return !val || EMAIL_REGEX.test(val); + } }); + _('number', { fn: function fn(val) { + return !val || !isNaN(parseFloat(val)); + }, priority: 2 }); + _('integer', { fn: function fn(val) { + return !val || /^\d+$/.test(val); + } }); + _('minlength', { fn: function fn(val, length) { + return !val || val.length >= parseInt(length); + } }); + _('maxlength', { fn: function fn(val, length) { + return !val || val.length <= parseInt(length); + } }); + _('min', { fn: function fn(val, limit) { + return !val || (this.type === 'checkbox' ? groupedElemCount(this) >= parseInt(limit) : parseFloat(val) >= parseFloat(limit)); + } }); + _('max', { fn: function fn(val, limit) { + return !val || (this.type === 'checkbox' ? groupedElemCount(this) <= parseInt(limit) : parseFloat(val) <= parseFloat(limit)); + } }); + _('pattern', { fn: function fn(val, pattern) { + var m = pattern.match(new RegExp('^/(.*?)/([gimy]*)$'));return !val || new RegExp(m[1], m[2]).test(val); + } }); + _('equals', { fn: function fn(val, otherFieldSelector) { + var other = document.querySelector(otherFieldSelector);return other && (!val && !other.value || other.value === val); + } }); function Pristine(form, config, live) { - var self = this; - - init(form, config, live); - - function init(form, config, live) { - form.setAttribute("novalidate", "true"); - - self.form = form; - self.config = mergeConfig(config || {}, defaultConfig); - self.live = !(live === false); - self.fields = Array.from(form.querySelectorAll(SELECTOR)).map(function (input) { - var fns = []; - var params = {}; - var messages = {}; - - [].forEach.call(input.attributes, function (attr) { - if (/^data-pristine-/.test(attr.name)) { - var name = attr.name.substr(14); - var messageMatch = name.match(MESSAGE_REGEX); - if (messageMatch !== null) { - var locale = messageMatch[1] === undefined ? "en" : messageMatch[1]; - if (!messages.hasOwnProperty(locale)) messages[locale] = {}; - messages[locale][name.slice(0, name.length - messageMatch[0].length)] = attr.value; - return; - } - if (name === "type") name = attr.value; - _addValidatorToField(fns, params, name, attr.value); - } else if (~ALLOWED_ATTRIBUTES.indexOf(attr.name)) { - _addValidatorToField(fns, params, attr.name, attr.value); - } else if (attr.name === "type") { - _addValidatorToField(fns, params, attr.value); - } - }); - - fns.sort(function (a, b) { - return b.priority - a.priority; - }); - - self.live && input.addEventListener(!~["radio", "checkbox"].indexOf(input.getAttribute("type")) ? "input" : "change", function (e) { - self.validate(e.target); - }.bind(self)); - - return input.pristine = { - input: input, - validators: fns, - params: params, - messages: messages, - self: self - }; - }.bind(self)); - } - - function _addValidatorToField(fns, params, name, value) { - var validator = validators[name]; - if (validator) { - fns.push(validator); - if (value) { - var valueParams = name === "pattern" ? [value] : value.split(","); - valueParams.unshift(null); // placeholder for input's value - params[name] = valueParams; - } - } - } - - /*** - * Checks whether the form/input elements are valid - * @param input => input element(s) or a jquery selector, null for full form validation - * @param silent => do not show error messages, just return true/false - * @returns {boolean} return true when valid false otherwise - */ - self.validate = function (input, silent) { - silent = input && silent === true || input === true; - var fields = self.fields; - if (input !== true && input !== false) { - if (input instanceof HTMLElement) { - fields = [input.pristine]; - } else if (input instanceof NodeList || input instanceof (window.$ || Array) || input instanceof Array) { - fields = Array.from(input).map(function (el) { - return el.pristine; - }); - } - } - - var valid = true; - for (var i = 0; fields[i]; i++) { - var field = fields[i]; - if (_validateField(field)) { - !silent && _showSuccess(field); - } else { - valid = false; - !silent && _showError(field); - } + var self = this; + var wasValitated = false; + + init(form, config, live); + + function init(form, config, live) { + + form.setAttribute("novalidate", "true"); + + self.form = form; + self.config = mergeConfig(config || {}, defaultConfig); + self.live = !(live === false); + self.fields = Array.from(form.querySelectorAll(SELECTOR)).map(function (input) { + + var fns = []; + var params = {}; + var messages = {}; + + [].forEach.call(input.attributes, function (attr) { + if (/^data-pristine-/.test(attr.name)) { + var name = attr.name.substr(14); + var messageMatch = name.match(MESSAGE_REGEX); + if (messageMatch !== null) { + var locale = messageMatch[1] === undefined ? 'en' : messageMatch[1]; + if (!messages.hasOwnProperty(locale)) messages[locale] = {}; + messages[locale][name.slice(0, name.length - messageMatch[0].length)] = attr.value; + return; + } + if (name === 'type') name = attr.value; + _addValidatorToField(fns, params, name, attr.value); + } else if (~ALLOWED_ATTRIBUTES.indexOf(attr.name)) { + _addValidatorToField(fns, params, attr.name, attr.value); + } else if (attr.name === 'type') { + _addValidatorToField(fns, params, attr.value); + } + }); + + fns.sort(function (a, b) { + return b.priority - a.priority; + }); + + self.live && input.addEventListener(!~['radio', 'checkbox'].indexOf(input.getAttribute('type')) ? 'input' : 'change', function (e) { + if (self.config.liveAfterFirstValitation && wasValitated) { + self.validate(e.target); + } else if (!self.config.liveAfterFirstValitation) { + self.validate(e.target); + } + }.bind(self)); + + return input.pristine = { input: input, validators: fns, params: params, messages: messages, self: self }; + }.bind(self)); } - return valid; - }; - - /*** - * Get errors of a specific field or the whole form - * @param input - * @returns {Array|*} - */ - self.getErrors = function (input) { - if (!input) { - var erroneousFields = []; - for (var i = 0; i < self.fields.length; i++) { - var field = self.fields[i]; - if (field.errors.length) { - erroneousFields.push({ input: field.input, errors: field.errors }); + + function _addValidatorToField(fns, params, name, value) { + var validator = validators[name]; + if (validator) { + fns.push(validator); + if (value) { + var valueParams = name === "pattern" ? [value] : value.split(','); + valueParams.unshift(null); // placeholder for input's value + params[name] = valueParams; + } } - } - return erroneousFields; - } - if (input.tagName && input.tagName.toLowerCase() === "select") { - return input.pristine.errors; } - return input.length ? input[0].pristine.errors : input.pristine.errors; - }; - - /*** - * Validates a single field, all validator functions are called and error messages are generated - * when a validator fails - * @param field - * @returns {boolean} - * @private - */ - function _validateField(field) { - var errors = []; - var valid = true; - for (var i = 0; field.validators[i]; i++) { - var validator = field.validators[i]; - var params = field.params[validator.name] ? field.params[validator.name] : []; - params[0] = field.input.value; - if (!validator.fn.apply(field.input, params)) { - valid = false; - - if (typeof validator.msg === "function") { - errors.push(validator.msg(field.input.value, params)); - } else if (typeof validator.msg === "string") { - errors.push(tmpl.apply(validator.msg, params)); - } else if (validator.msg === Object(validator.msg) && validator.msg[currentLocale]) { - // typeof generates unnecessary babel code - errors.push(tmpl.apply(validator.msg[currentLocale], params)); - } else if (field.messages[currentLocale] && field.messages[currentLocale][validator.name]) { - errors.push(tmpl.apply(field.messages[currentLocale][validator.name], params)); - } else if (lang[currentLocale] && lang[currentLocale][validator.name]) { - errors.push(tmpl.apply(lang[currentLocale][validator.name], params)); + + /*** + * Checks whether the form/input elements are valid + * @param input => input element(s) or a jquery selector, null for full form validation + * @param silent => do not show error messages, just return true/false + * @returns {boolean} return true when valid false otherwise + */ + self.validate = function () { + var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var silent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var fields = self.fields; + if (input) { + if (input instanceof HTMLElement) { + fields = [input.pristine]; + } else if (input instanceof NodeList || input instanceof (window.$ || Array) || input instanceof Array) { + fields = Array.from(input).map(function (el) { + return el.pristine; + }); + } } else { - errors.push(tmpl.apply(lang[currentLocale].default, params)); + wasValitated = true; } - if (validator.halt === true) { - break; + var valid = true; + + for (var i = 0; fields[i]; i++) { + var field = fields[i]; + if (_validateField(field)) { + !silent && _showSuccess(field); + } else { + valid = false; + !silent && _showError(field); + } } - } - } - field.errors = errors; - return valid; - } - - /*** - * Add a validator to a specific dom element in a form - * @param elem => The dom element where the validator is applied to - * @param fn => validator function - * @param msg => message to show when validation fails. Supports templating. ${0} for the input's value, ${1} and - * so on are for the attribute values - * @param priority => priority of the validator function, higher valued function gets called first. - * @param halt => whether validation should stop for this field after current validation function - */ - self.addValidator = function (elem, fn, msg, priority, halt) { - if (elem instanceof HTMLElement) { - elem.pristine.validators.push({ fn: fn, msg: msg, priority: priority, halt: halt }); - elem.pristine.validators.sort(function (a, b) { - return b.priority - a.priority; - }); - } else { - console.warn("The parameter elem must be a dom element"); - } - }; - - /*** - * An utility function that returns a 2-element array, first one is the element where error/success class is - * applied. 2nd one is the element where error message is displayed. 2nd element is created if doesn't exist and cached. - * @param field - * @returns {*} - * @private - */ - function _getErrorElements(field) { - if (field.errorElements) { - return field.errorElements; - } - var errorClassElement = findAncestor(field.input, self.config.classTo); - var errorTextParent = null, - errorTextElement = null; - if (self.config.classTo === self.config.errorTextParent) { - errorTextParent = errorClassElement; - } else { - errorTextParent = errorClassElement.querySelector("." + self.config.errorTextParent); + return valid; + }; + + /*** + * Get errors of a specific field or the whole form + * @param input + * @returns {Array|*} + */ + self.getErrors = function (input) { + if (!input) { + var erroneousFields = []; + for (var i = 0; i < self.fields.length; i++) { + var field = self.fields[i]; + if (field.errors.length) { + erroneousFields.push({ input: field.input, errors: field.errors }); + } + } + return erroneousFields; + } + if (input.tagName && input.tagName.toLowerCase() === "select") { + return input.pristine.errors; + } + return input.length ? input[0].pristine.errors : input.pristine.errors; + }; + + /*** + * Validates a single field, all validator functions are called and error messages are generated + * when a validator fails + * @param field + * @returns {boolean} + * @private + */ + function _validateField(field) { + var errors = []; + var valid = true; + for (var i = 0; field.validators[i]; i++) { + var validator = field.validators[i]; + var params = field.params[validator.name] ? field.params[validator.name] : []; + params[0] = field.input.value; + if (!validator.fn.apply(field.input, params)) { + valid = false; + + if (typeof validator.msg === "function") { + errors.push(validator.msg(field.input.value, params)); + } else if (typeof validator.msg === "string") { + errors.push(tmpl.apply(validator.msg, params)); + } else if (validator.msg === Object(validator.msg) && validator.msg[currentLocale]) { + // typeof generates unnecessary babel code + errors.push(tmpl.apply(validator.msg[currentLocale], params)); + } else if (field.messages[currentLocale] && field.messages[currentLocale][validator.name]) { + errors.push(tmpl.apply(field.messages[currentLocale][validator.name], params)); + } else if (lang[currentLocale] && lang[currentLocale][validator.name]) { + errors.push(tmpl.apply(lang[currentLocale][validator.name], params)); + } else { + errors.push(tmpl.apply(lang[currentLocale].default, params)); + } + + if (validator.halt === true) { + break; + } + } + } + field.errors = errors; + return valid; } - if (errorTextParent) { - errorTextElement = errorTextParent.querySelector("." + PRISTINE_ERROR); - if (!errorTextElement) { - errorTextElement = document.createElement(self.config.errorTextTag); - errorTextElement.className = PRISTINE_ERROR + " " + self.config.errorTextClass; - errorTextParent.appendChild(errorTextElement); - errorTextElement.pristineDisplay = errorTextElement.style.display; - } + + /*** + * Add a validator to a specific dom element in a form + * @param elem => The dom element where the validator is applied to + * @param fn => validator function + * @param msg => message to show when validation fails. Supports templating. ${0} for the input's value, ${1} and + * so on are for the attribute values + * @param priority => priority of the validator function, higher valued function gets called first. + * @param halt => whether validation should stop for this field after current validation function + */ + self.addValidator = function (elem, fn, msg, priority, halt) { + if (elem instanceof HTMLElement) { + elem.pristine.validators.push({ fn: fn, msg: msg, priority: priority, halt: halt }); + elem.pristine.validators.sort(function (a, b) { + return b.priority - a.priority; + }); + } else { + console.warn("The parameter elem must be a dom element"); + } + }; + + /*** + * An utility function that returns a 2-element array, first one is the element where error/success class is + * applied. 2nd one is the element where error message is displayed. 2nd element is created if doesn't exist and cached. + * @param field + * @returns {*} + * @private + */ + function _getErrorElements(field) { + if (field.errorElements) { + return field.errorElements; + } + var errorClassElement = findAncestor(field.input, self.config.classTo); + var errorTextParent = null, + errorTextElement = null; + if (self.config.classTo === self.config.errorTextParent) { + errorTextParent = errorClassElement; + } else { + errorTextParent = errorClassElement.querySelector('.' + self.config.errorTextParent); + } + if (errorTextParent) { + errorTextElement = errorTextParent.querySelector('.' + PRISTINE_ERROR); + if (!errorTextElement) { + errorTextElement = document.createElement(self.config.errorTextTag); + errorTextElement.className = PRISTINE_ERROR + ' ' + self.config.errorTextClass; + errorTextParent.appendChild(errorTextElement); + errorTextElement.pristineDisplay = errorTextElement.style.display; + } + } + return field.errorElements = [errorClassElement, errorTextElement]; } - return field.errorElements = [errorClassElement, errorTextElement]; - } - function _showError(field) { - var errorElements = _getErrorElements(field); - var errorClassElement = errorElements[0], - errorTextElement = errorElements[1]; + function _showError(field) { + var errorElements = _getErrorElements(field); + var errorClassElement = errorElements[0], + errorTextElement = errorElements[1]; - if (errorClassElement) { - errorClassElement.classList.remove(self.config.successClass); - errorClassElement.classList.add(self.config.errorClass); - } - if (errorTextElement) { - errorTextElement.innerHTML = field.errors.join("
"); - errorTextElement.style.display = errorTextElement.pristineDisplay || ""; - } - } - - /*** - * Adds error to a specific field - * @param input - * @param error - */ - self.addError = function (input, error) { - input = input.length ? input[0] : input; - input.pristine.errors.push(error); - _showError(input.pristine); - }; - - function _removeError(field) { - var errorElements = _getErrorElements(field); - var errorClassElement = errorElements[0], - errorTextElement = errorElements[1]; - if (errorClassElement) { - // IE > 9 doesn't support multiple class removal - errorClassElement.classList.remove(self.config.errorClass); - errorClassElement.classList.remove(self.config.successClass); + if (errorClassElement) { + errorClassElement.classList.remove(self.config.successClass); + errorClassElement.classList.add(self.config.errorClass); + } + if (errorTextElement) { + errorTextElement.innerHTML = field.errors.join('
'); + errorTextElement.style.display = errorTextElement.pristineDisplay || ''; + } } - if (errorTextElement) { - errorTextElement.innerHTML = ""; - errorTextElement.style.display = "none"; + + /*** + * Adds error to a specific field + * @param input + * @param error + */ + self.addError = function (input, error) { + input = input.length ? input[0] : input; + input.pristine.errors.push(error); + _showError(input.pristine); + }; + + function _removeError(field) { + var errorElements = _getErrorElements(field); + var errorClassElement = errorElements[0], + errorTextElement = errorElements[1]; + if (errorClassElement) { + // IE > 9 doesn't support multiple class removal + errorClassElement.classList.remove(self.config.errorClass); + errorClassElement.classList.remove(self.config.successClass); + } + if (errorTextElement) { + errorTextElement.innerHTML = ''; + errorTextElement.style.display = 'none'; + } + return errorElements; } - return errorElements; - } - - function _showSuccess(field) { - var errorClassElement = _removeError(field)[0]; - errorClassElement && errorClassElement.classList.add(self.config.successClass); - } - - /*** - * Resets the errors - */ - self.reset = function () { - for (var i = 0; self.fields[i]; i++) { - self.fields[i].errorElements = null; + + function _showSuccess(field) { + var errorClassElement = _removeError(field)[0]; + errorClassElement && errorClassElement.classList.add(self.config.successClass); } - Array.from(self.form.querySelectorAll("." + PRISTINE_ERROR)).map(function (elem) { - elem.parentNode.removeChild(elem); - }); - Array.from(self.form.querySelectorAll("." + self.config.classTo)).map(function (elem) { - elem.classList.remove(self.config.successClass); - elem.classList.remove(self.config.errorClass); - }); - }; - - /*** - * Resets the errors and deletes all pristine fields - */ - self.destroy = function () { - self.reset(); - self.fields.forEach(function (field) { - delete field.input.pristine; - }); - self.fields = []; - }; - self.setGlobalConfig = function (config) { - defaultConfig = config; - }; + /*** + * Resets the errors + */ + self.reset = function () { + for (var i = 0; self.fields[i]; i++) { + self.fields[i].errorElements = null; + } + Array.from(self.form.querySelectorAll('.' + PRISTINE_ERROR)).map(function (elem) { + elem.parentNode.removeChild(elem); + }); + Array.from(self.form.querySelectorAll('.' + self.config.classTo)).map(function (elem) { + elem.classList.remove(self.config.successClass); + elem.classList.remove(self.config.errorClass); + }); + }; + + /*** + * Resets the errors and deletes all pristine fields + */ + self.destroy = function () { + self.reset(); + self.fields.forEach(function (field) { + delete field.input.pristine; + }); + self.fields = []; + }; - return self; + self.setGlobalConfig = function (config) { + defaultConfig = config; + }; + + return self; } /*** @@ -425,19 +416,19 @@ * @param halt => whether validation should stop for this field after current validation function */ Pristine.addValidator = function (name, fn, msg, priority, halt) { - _(name, { fn: fn, msg: msg, priority: priority, halt: halt }); + _(name, { fn: fn, msg: msg, priority: priority, halt: halt }); }; Pristine.addMessages = function (locale, messages) { - var langObj = lang.hasOwnProperty(locale) ? lang[locale] : lang[locale] = {}; + var langObj = lang.hasOwnProperty(locale) ? lang[locale] : lang[locale] = {}; - Object.keys(messages).forEach(function (key, index) { - langObj[key] = messages[key]; - }); + Object.keys(messages).forEach(function (key, index) { + langObj[key] = messages[key]; + }); }; Pristine.setLocale = function (locale) { - currentLocale = locale; + currentLocale = locale; }; return Pristine; diff --git a/dist/pristine.min.js b/dist/pristine.min.js index 8c2656d..2455278 100644 --- a/dist/pristine.min.js +++ b/dist/pristine.min.js @@ -1 +1 @@ -!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).Pristine=r()}(this,(function(){"use strict";var e={en:{required:"This field is required",email:"This field requires a valid e-mail address",number:"This field requires a number",integer:"This field requires an integer value",url:"This field requires a valid website URL",tel:"This field requires a valid telephone number",maxlength:"This fields length must be < ${1}",minlength:"This fields length must be > ${1}",min:"Minimum value for this field is ${1}",max:"Maximum value for this field is ${1}",pattern:"Please match the requested format",equals:"The two fields do not match",default:"Please enter a correct value"}};function r(e){var r=arguments;return this.replace(/\${([^{}]*)}/g,(function(e,t){return r[t]}))}function t(e){return e.pristine.self.form.querySelectorAll('input[name="'+e.getAttribute("name")+'"]:checked').length}var n={classTo:"form-group",errorClass:"has-danger",successClass:"has-success",errorTextParent:"form-group",errorTextTag:"div",errorTextClass:"text-help"},i=["required","min","max","minlength","maxlength","pattern"],s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,a=/-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/,o="en",l={},u=function(e,r){r.name=e,void 0===r.priority&&(r.priority=1),l[e]=r};function f(t,s,u){var f=this;function c(e,r,t,n){var i=l[t];if(i&&(e.push(i),n)){var s="pattern"===t?[n]:n.split(",");s.unshift(null),r[t]=s}}function p(t){for(var n=[],i=!0,s=0;t.validators[s];s++){var a=t.validators[s],l=t.params[a.name]?t.params[a.name]:[];if(l[0]=t.input.value,!a.fn.apply(t.input,l)&&(i=!1,"function"==typeof a.msg?n.push(a.msg(t.input.value,l)):"string"==typeof a.msg?n.push(r.apply(a.msg,l)):a.msg===Object(a.msg)&&a.msg[o]?n.push(r.apply(a.msg[o],l)):t.messages[o]&&t.messages[o][a.name]?n.push(r.apply(t.messages[o][a.name],l)):e[o]&&e[o][a.name]?n.push(r.apply(e[o][a.name],l)):n.push(r.apply(e[o].default,l)),!0===a.halt))break}return t.errors=n,i}function m(e){if(e.errorElements)return e.errorElements;var r=function(e,r){for(;(e=e.parentElement)&&!e.classList.contains(r););return e}(e.input,f.config.classTo),t=null,n=null;return(t=f.config.classTo===f.config.errorTextParent?r:r.querySelector("."+f.config.errorTextParent))&&((n=t.querySelector(".pristine-error"))||((n=document.createElement(f.config.errorTextTag)).className="pristine-error "+f.config.errorTextClass,t.appendChild(n),n.pristineDisplay=n.style.display)),e.errorElements=[r,n]}function d(e){var r=m(e),t=r[0],n=r[1];t&&(t.classList.remove(f.config.successClass),t.classList.add(f.config.errorClass)),n&&(n.innerHTML=e.errors.join("
"),n.style.display=n.pristineDisplay||"")}function h(e){var r=function(e){var r=m(e),t=r[0],n=r[1];return t&&(t.classList.remove(f.config.errorClass),t.classList.remove(f.config.successClass)),n&&(n.innerHTML="",n.style.display="none"),r}(e)[0];r&&r.classList.add(f.config.successClass)}return function(e,r,t){e.setAttribute("novalidate","true"),f.form=e,f.config=function(e,r){for(var t in r)t in e||(e[t]=r[t]);return e}(r||{},n),f.live=!(!1===t),f.fields=Array.from(e.querySelectorAll("input:not([type^=hidden]):not([type^=submit]), select, textarea")).map(function(e){var r=[],t={},n={};return[].forEach.call(e.attributes,(function(e){if(/^data-pristine-/.test(e.name)){var s=e.name.substr(14),o=s.match(a);if(null!==o){var l=void 0===o[1]?"en":o[1];return n.hasOwnProperty(l)||(n[l]={}),void(n[l][s.slice(0,s.length-o[0].length)]=e.value)}"type"===s&&(s=e.value),c(r,t,s,e.value)}else~i.indexOf(e.name)?c(r,t,e.name,e.value):"type"===e.name&&c(r,t,e.value)})),r.sort((function(e,r){return r.priority-e.priority})),f.live&&e.addEventListener(~["radio","checkbox"].indexOf(e.getAttribute("type"))?"change":"input",function(e){f.validate(e.target)}.bind(f)),e.pristine={input:e,validators:r,params:t,messages:n,self:f}}.bind(f))}(t,s,u),f.validate=function(e,r){r=e&&!0===r||!0===e;var t=f.fields;!0!==e&&!1!==e&&(e instanceof HTMLElement?t=[e.pristine]:(e instanceof NodeList||e instanceof(window.$||Array)||e instanceof Array)&&(t=Array.from(e).map((function(e){return e.pristine}))));for(var n=!0,i=0;t[i];i++){var s=t[i];p(s)?!r&&h(s):(n=!1,!r&&d(s))}return n},f.getErrors=function(e){if(!e){for(var r=[],t=0;t=parseInt(r)}}),u("maxlength",{fn:function(e,r){return!e||e.length<=parseInt(r)}}),u("min",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)>=parseInt(r):parseFloat(e)>=parseFloat(r))}}),u("max",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)<=parseInt(r):parseFloat(e)<=parseFloat(r))}}),u("pattern",{fn:function(e,r){var t=r.match(new RegExp("^/(.*?)/([gimy]*)$"));return!e||new RegExp(t[1],t[2]).test(e)}}),u("equals",{fn:function(e,r){var t=document.querySelector(r);return t&&(!e&&!t.value||t.value===e)}}),console.log(u),f.addValidator=function(e,r,t,n,i){u(e,{fn:r,msg:t,priority:n,halt:i})},f.addMessages=function(r,t){var n=e.hasOwnProperty(r)?e[r]:e[r]={};Object.keys(t).forEach((function(e,r){n[e]=t[e]}))},f.setLocale=function(e){o=e},f})); +!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).Pristine=r()}(this,(function(){"use strict";var e={en:{required:"This field is required",email:"This field requires a valid e-mail address",number:"This field requires a number",integer:"This field requires an integer value",url:"This field requires a valid website URL",tel:"This field requires a valid telephone number",maxlength:"This fields length must be < ${1}",minlength:"This fields length must be > ${1}",min:"Minimum value for this field is ${1}",max:"Maximum value for this field is ${1}",pattern:"Please match the requested format",equals:"The two fields do not match",default:"Please enter a correct value"}};function r(e){var r=arguments;return this.replace(/\${([^{}]*)}/g,(function(e,t){return r[t]}))}function t(e){return e.pristine.self.form.querySelectorAll('input[name="'+e.getAttribute("name")+'"]:checked').length}var n={classTo:"form-group",errorClass:"has-danger",successClass:"has-success",errorTextParent:"form-group",errorTextTag:"div",errorTextClass:"text-help",liveAfterFirstValitation:!0},i=["required","min","max","minlength","maxlength","pattern"],s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,a=/-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/,o="en",l={},u=function(e,r){r.name=e,void 0===r.priority&&(r.priority=1),l[e]=r};function f(t,s,u){var f=this,c=!1;function p(e,r,t,n){var i=l[t];if(i&&(e.push(i),n)){var s="pattern"===t?[n]:n.split(",");s.unshift(null),r[t]=s}}function m(t){for(var n=[],i=!0,s=0;t.validators[s];s++){var a=t.validators[s],l=t.params[a.name]?t.params[a.name]:[];if(l[0]=t.input.value,!a.fn.apply(t.input,l)&&(i=!1,"function"==typeof a.msg?n.push(a.msg(t.input.value,l)):"string"==typeof a.msg?n.push(r.apply(a.msg,l)):a.msg===Object(a.msg)&&a.msg[o]?n.push(r.apply(a.msg[o],l)):t.messages[o]&&t.messages[o][a.name]?n.push(r.apply(t.messages[o][a.name],l)):e[o]&&e[o][a.name]?n.push(r.apply(e[o][a.name],l)):n.push(r.apply(e[o].default,l)),!0===a.halt))break}return t.errors=n,i}function d(e){if(e.errorElements)return e.errorElements;var r=function(e,r){for(;(e=e.parentElement)&&!e.classList.contains(r););return e}(e.input,f.config.classTo),t=null,n=null;return(t=f.config.classTo===f.config.errorTextParent?r:r.querySelector("."+f.config.errorTextParent))&&((n=t.querySelector(".pristine-error"))||((n=document.createElement(f.config.errorTextTag)).className="pristine-error "+f.config.errorTextClass,t.appendChild(n),n.pristineDisplay=n.style.display)),e.errorElements=[r,n]}function h(e){var r=d(e),t=r[0],n=r[1];t&&(t.classList.remove(f.config.successClass),t.classList.add(f.config.errorClass)),n&&(n.innerHTML=e.errors.join("
"),n.style.display=n.pristineDisplay||"")}function g(e){var r=function(e){var r=d(e),t=r[0],n=r[1];return t&&(t.classList.remove(f.config.errorClass),t.classList.remove(f.config.successClass)),n&&(n.innerHTML="",n.style.display="none"),r}(e)[0];r&&r.classList.add(f.config.successClass)}return function(e,r,t){e.setAttribute("novalidate","true"),f.form=e,f.config=function(e,r){for(var t in r)t in e||(e[t]=r[t]);return e}(r||{},n),f.live=!(!1===t),f.fields=Array.from(e.querySelectorAll("input:not([type^=hidden]):not([type^=submit]), select, textarea")).map(function(e){var r=[],t={},n={};return[].forEach.call(e.attributes,(function(e){if(/^data-pristine-/.test(e.name)){var s=e.name.substr(14),o=s.match(a);if(null!==o){var l=void 0===o[1]?"en":o[1];return n.hasOwnProperty(l)||(n[l]={}),void(n[l][s.slice(0,s.length-o[0].length)]=e.value)}"type"===s&&(s=e.value),p(r,t,s,e.value)}else~i.indexOf(e.name)?p(r,t,e.name,e.value):"type"===e.name&&p(r,t,e.value)})),r.sort((function(e,r){return r.priority-e.priority})),f.live&&e.addEventListener(~["radio","checkbox"].indexOf(e.getAttribute("type"))?"change":"input",function(e){f.config.liveAfterFirstValitation&&c?f.validate(e.target):f.config.liveAfterFirstValitation||f.validate(e.target)}.bind(f)),e.pristine={input:e,validators:r,params:t,messages:n,self:f}}.bind(f))}(t,s,u),f.validate=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1],t=f.fields;e?e instanceof HTMLElement?t=[e.pristine]:(e instanceof NodeList||e instanceof(window.$||Array)||e instanceof Array)&&(t=Array.from(e).map((function(e){return e.pristine}))):c=!0;for(var n=!0,i=0;t[i];i++){var s=t[i];m(s)?!r&&g(s):(n=!1,!r&&h(s))}return n},f.getErrors=function(e){if(!e){for(var r=[],t=0;t=parseInt(r)}}),u("maxlength",{fn:function(e,r){return!e||e.length<=parseInt(r)}}),u("min",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)>=parseInt(r):parseFloat(e)>=parseFloat(r))}}),u("max",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)<=parseInt(r):parseFloat(e)<=parseFloat(r))}}),u("pattern",{fn:function(e,r){var t=r.match(new RegExp("^/(.*?)/([gimy]*)$"));return!e||new RegExp(t[1],t[2]).test(e)}}),u("equals",{fn:function(e,r){var t=document.querySelector(r);return t&&(!e&&!t.value||t.value===e)}}),f.addValidator=function(e,r,t,n,i){u(e,{fn:r,msg:t,priority:n,halt:i})},f.addMessages=function(r,t){var n=e.hasOwnProperty(r)?e[r]:e[r]={};Object.keys(t).forEach((function(e,r){n[e]=t[e]}))},f.setLocale=function(e){o=e},f})); diff --git a/src/pristine.js b/src/pristine.js index 916f604..cfc5576 100755 --- a/src/pristine.js +++ b/src/pristine.js @@ -1,407 +1,325 @@ -import { lang } from "./lang"; -import { tmpl, findAncestor, groupedElemCount, mergeConfig } from "./utils"; +import { lang } from './lang'; +import { tmpl, findAncestor, groupedElemCount, mergeConfig } from './utils'; let defaultConfig = { - classTo: "form-group", - errorClass: "has-danger", - successClass: "has-success", - errorTextParent: "form-group", - errorTextTag: "div", - errorTextClass: "text-help", + classTo: 'form-group', + errorClass: 'has-danger', + successClass: 'has-success', + errorTextParent: 'form-group', + errorTextTag: 'div', + errorTextClass: 'text-help' }; -const PRISTINE_ERROR = "pristine-error"; -const SELECTOR = - "input:not([type^=hidden]):not([type^=submit]), select, textarea"; -const ALLOWED_ATTRIBUTES = [ - "required", - "min", - "max", - "minlength", - "maxlength", - "pattern", -]; -const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; +const PRISTINE_ERROR = 'pristine-error'; +const SELECTOR = "input:not([type^=hidden]):not([type^=submit]), select, textarea"; +const ALLOWED_ATTRIBUTES = ["required", "min", "max", 'minlength', 'maxlength', 'pattern']; +const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ const MESSAGE_REGEX = /-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/; // matches, -message, -message-en, -message-en_US -let currentLocale = "en"; +let currentLocale = 'en'; const validators = {}; const _ = function (name, validator) { - validator.name = name; - if (validator.priority === undefined) validator.priority = 1; - validators[name] = validator; + validator.name = name; + if (validator.priority === undefined) + validator.priority = 1; + validators[name] = validator; }; -_("text", { fn: (val) => true, priority: 0 }); -_("required", { - fn: function (val) { - return this.type === "radio" || this.type === "checkbox" - ? groupedElemCount(this) - : val !== undefined && val !== ""; - }, - priority: 99, - halt: true, -}); -_("email", { fn: (val) => !val || EMAIL_REGEX.test(val) }); -_("number", { fn: (val) => !val || !isNaN(parseFloat(val)), priority: 2 }); -_("integer", { fn: (val) => !val || /^\d+$/.test(val) }); -_("minlength", { fn: (val, length) => !val || val.length >= parseInt(length) }); -_("maxlength", { fn: (val, length) => !val || val.length <= parseInt(length) }); -_("min", { - fn: function (val, limit) { - return ( - !val || - (this.type === "checkbox" - ? groupedElemCount(this) >= parseInt(limit) - : parseFloat(val) >= parseFloat(limit)) - ); - }, -}); -_("max", { - fn: function (val, limit) { - return ( - !val || - (this.type === "checkbox" - ? groupedElemCount(this) <= parseInt(limit) - : parseFloat(val) <= parseFloat(limit)) - ); - }, -}); -_("pattern", { - fn: (val, pattern) => { - let m = pattern.match(new RegExp("^/(.*?)/([gimy]*)$")); - return !val || new RegExp(m[1], m[2]).test(val); - }, -}); -_("equals", { - fn: (val, otherFieldSelector) => { - let other = document.querySelector(otherFieldSelector); - return other && ((!val && !other.value) || other.value === val); - }, -}); - -console.log(_); - -export default function Pristine(form, config, live) { - let self = this; - - init(form, config, live); - - function init(form, config, live) { - form.setAttribute("novalidate", "true"); - - self.form = form; - self.config = mergeConfig(config || {}, defaultConfig); - self.live = !(live === false); - self.fields = Array.from(form.querySelectorAll(SELECTOR)).map( - function (input) { - let fns = []; - let params = {}; - let messages = {}; - - [].forEach.call(input.attributes, function (attr) { - if (/^data-pristine-/.test(attr.name)) { - let name = attr.name.substr(14); - let messageMatch = name.match(MESSAGE_REGEX); - if (messageMatch !== null) { - let locale = - messageMatch[1] === undefined ? "en" : messageMatch[1]; - if (!messages.hasOwnProperty(locale)) messages[locale] = {}; - messages[locale][ - name.slice(0, name.length - messageMatch[0].length) - ] = attr.value; - return; - } - if (name === "type") name = attr.value; - _addValidatorToField(fns, params, name, attr.value); - } else if (~ALLOWED_ATTRIBUTES.indexOf(attr.name)) { - _addValidatorToField(fns, params, attr.name, attr.value); - } else if (attr.name === "type") { - _addValidatorToField(fns, params, attr.value); - } - }); - - fns.sort((a, b) => b.priority - a.priority); - - self.live && - input.addEventListener( - !~["radio", "checkbox"].indexOf(input.getAttribute("type")) - ? "input" - : "change", - function (e) { - self.validate(e.target); - }.bind(self) - ); - - return (input.pristine = { - input, - validators: fns, - params, - messages, - self, - }); - }.bind(self) - ); - } - - function _addValidatorToField(fns, params, name, value) { - let validator = validators[name]; - if (validator) { - fns.push(validator); - if (value) { - let valueParams = name === "pattern" ? [value] : value.split(","); - valueParams.unshift(null); // placeholder for input's value - params[name] = valueParams; - } +_('text', { fn: (val) => true, priority: 0}); +_('required', { fn: function(val){ return (this.type === 'radio' || this.type === 'checkbox') ? groupedElemCount(this) : val !== undefined && val !== ''}, priority: 99, halt: true}); +_('email', { fn: (val) => !val || EMAIL_REGEX.test(val)}); +_('number', { fn: (val) => !val || !isNaN(parseFloat(val)), priority: 2 }); +_('integer', { fn: (val) => !val || /^\d+$/.test(val) }); +_('minlength', { fn: (val, length) => !val || val.length >= parseInt(length) }); +_('maxlength', { fn: (val, length) => !val || val.length <= parseInt(length) }); +_('min', { fn: function(val, limit){ return !val || (this.type === 'checkbox' ? groupedElemCount(this) >= parseInt(limit) : parseFloat(val) >= parseFloat(limit)); } }); +_('max', { fn: function(val, limit){ return !val || (this.type === 'checkbox' ? groupedElemCount(this) <= parseInt(limit) : parseFloat(val) <= parseFloat(limit)); } }); +_('pattern', { fn: (val, pattern) => { let m = pattern.match(new RegExp('^/(.*?)/([gimy]*)$')); return !val || (new RegExp(m[1], m[2])).test(val);} }); +_('equals', { fn: (val, otherFieldSelector) => { let other = document.querySelector(otherFieldSelector); return (other) && ((!val && !other.value) || (other.value === val)); } }); + +export default function Pristine(form, config, live){ + + let self = this; + + init(form, config, live); + + function init(form, config, live){ + + form.setAttribute("novalidate", "true"); + + self.form = form; + self.config = mergeConfig(config || {}, defaultConfig); + self.live = !(live === false); + self.fields = Array.from(form.querySelectorAll(SELECTOR)).map(function (input) { + + let fns = []; + let params = {}; + let messages = {}; + + [].forEach.call(input.attributes, function (attr) { + if (/^data-pristine-/.test(attr.name)) { + let name = attr.name.substr(14); + let messageMatch = name.match(MESSAGE_REGEX); + if (messageMatch !== null){ + let locale = messageMatch[1] === undefined ? 'en' : messageMatch[1]; + if (!messages.hasOwnProperty(locale)) + messages[locale] = {}; + messages[locale][name.slice(0, name.length - messageMatch[0].length)] = attr.value; + return; + } + if (name === 'type') name = attr.value; + _addValidatorToField(fns, params, name, attr.value); + } else if (~ALLOWED_ATTRIBUTES.indexOf(attr.name)){ + _addValidatorToField(fns, params, attr.name, attr.value); + } else if (attr.name === 'type'){ + _addValidatorToField(fns, params, attr.value); + } + }); + + fns.sort( (a, b) => b.priority - a.priority); + + self.live && input.addEventListener((!~['radio', 'checkbox'].indexOf(input.getAttribute('type')) ? 'input':'change'), function(e) { + self.validate(e.target); + }.bind(self)); + + return input.pristine = {input, validators: fns, params, messages, self}; + + }.bind(self)); } - } - - /*** - * Checks whether the form/input elements are valid - * @param input => input element(s) or a jquery selector, null for full form validation - * @param silent => do not show error messages, just return true/false - * @returns {boolean} return true when valid false otherwise - */ - self.validate = function (input, silent) { - silent = (input && silent === true) || input === true; - let fields = self.fields; - if (input !== true && input !== false) { - if (input instanceof HTMLElement) { - fields = [input.pristine]; - } else if ( - input instanceof NodeList || - input instanceof (window.$ || Array) || - input instanceof Array - ) { - fields = Array.from(input).map((el) => el.pristine); - } + + function _addValidatorToField(fns, params, name, value) { + let validator = validators[name]; + if (validator) { + fns.push(validator); + if (value) { + let valueParams = (name === "pattern" ? [value]: value.split(',')); + valueParams.unshift(null); // placeholder for input's value + params[name] = valueParams; + } + } } - let valid = true; + /*** + * Checks whether the form/input elements are valid + * @param input => input element(s) or a jquery selector, null for full form validation + * @param silent => do not show error messages, just return true/false + * @returns {boolean} return true when valid false otherwise + */ + self.validate = function(input, silent){ + silent = (input && silent === true) || input === true; + let fields = self.fields; + if (input !== true && input !== false){ + if (input instanceof HTMLElement) { + fields = [input.pristine]; + } else if (input instanceof NodeList || input instanceof (window.$ || Array) || input instanceof Array){ + fields = Array.from(input).map(el => el.pristine); + } + } - for (let i = 0; fields[i]; i++) { - let field = fields[i]; - if (_validateField(field)) { - !silent && _showSuccess(field); - } else { - valid = false; - !silent && _showError(field); - } - } - return valid; - }; - - /*** - * Get errors of a specific field or the whole form - * @param input - * @returns {Array|*} - */ - self.getErrors = function (input) { - if (!input) { - let erroneousFields = []; - for (let i = 0; i < self.fields.length; i++) { - let field = self.fields[i]; - if (field.errors.length) { - erroneousFields.push({ input: field.input, errors: field.errors }); + let valid = true; + + for(let i = 0; fields[i]; i++) { + let field = fields[i]; + if (_validateField(field)){ + !silent && _showSuccess(field); + } else { + valid = false; + !silent && _showError(field); + } } - } - return erroneousFields; - } - if (input.tagName && input.tagName.toLowerCase() === "select") { - return input.pristine.errors; + return valid; + }; + + /*** + * Get errors of a specific field or the whole form + * @param input + * @returns {Array|*} + */ + self.getErrors = function(input) { + if (!input){ + let erroneousFields = []; + for(let i=0; i The dom element where the validator is applied to + * @param fn => validator function + * @param msg => message to show when validation fails. Supports templating. ${0} for the input's value, ${1} and + * so on are for the attribute values + * @param priority => priority of the validator function, higher valued function gets called first. + * @param halt => whether validation should stop for this field after current validation function + */ + self.addValidator = function(elem, fn, msg, priority, halt){ + if (elem instanceof HTMLElement){ + elem.pristine.validators.push({fn, msg, priority, halt}); + elem.pristine.validators.sort( (a, b) => b.priority - a.priority); } else { - errors.push(tmpl.apply(lang[currentLocale].default, params)); + console.warn("The parameter elem must be a dom element"); } - - if (validator.halt === true) { - break; + }; + + /*** + * An utility function that returns a 2-element array, first one is the element where error/success class is + * applied. 2nd one is the element where error message is displayed. 2nd element is created if doesn't exist and cached. + * @param field + * @returns {*} + * @private + */ + function _getErrorElements(field) { + if (field.errorElements){ + return field.errorElements; } - } - } - field.errors = errors; - return valid; - } - - /*** - * Add a validator to a specific dom element in a form - * @param elem => The dom element where the validator is applied to - * @param fn => validator function - * @param msg => message to show when validation fails. Supports templating. ${0} for the input's value, ${1} and - * so on are for the attribute values - * @param priority => priority of the validator function, higher valued function gets called first. - * @param halt => whether validation should stop for this field after current validation function - */ - self.addValidator = function (elem, fn, msg, priority, halt) { - if (elem instanceof HTMLElement) { - elem.pristine.validators.push({ fn, msg, priority, halt }); - elem.pristine.validators.sort((a, b) => b.priority - a.priority); - } else { - console.warn("The parameter elem must be a dom element"); - } - }; - - /*** - * An utility function that returns a 2-element array, first one is the element where error/success class is - * applied. 2nd one is the element where error message is displayed. 2nd element is created if doesn't exist and cached. - * @param field - * @returns {*} - * @private - */ - function _getErrorElements(field) { - if (field.errorElements) { - return field.errorElements; - } - let errorClassElement = findAncestor(field.input, self.config.classTo); - let errorTextParent = null, - errorTextElement = null; - if (self.config.classTo === self.config.errorTextParent) { - errorTextParent = errorClassElement; - } else { - errorTextParent = errorClassElement.querySelector( - "." + self.config.errorTextParent - ); - } - if (errorTextParent) { - errorTextElement = errorTextParent.querySelector("." + PRISTINE_ERROR); - if (!errorTextElement) { - errorTextElement = document.createElement(self.config.errorTextTag); - errorTextElement.className = - PRISTINE_ERROR + " " + self.config.errorTextClass; - errorTextParent.appendChild(errorTextElement); - errorTextElement.pristineDisplay = errorTextElement.style.display; - } + let errorClassElement = findAncestor(field.input, self.config.classTo); + let errorTextParent = null, errorTextElement = null; + if (self.config.classTo === self.config.errorTextParent){ + errorTextParent = errorClassElement; + } else { + errorTextParent = errorClassElement.querySelector('.' + self.config.errorTextParent); + } + if (errorTextParent){ + errorTextElement = errorTextParent.querySelector('.' + PRISTINE_ERROR); + if (!errorTextElement){ + errorTextElement = document.createElement(self.config.errorTextTag); + errorTextElement.className = PRISTINE_ERROR + ' ' + self.config.errorTextClass; + errorTextParent.appendChild(errorTextElement); + errorTextElement.pristineDisplay = errorTextElement.style.display; + } + } + return field.errorElements = [errorClassElement, errorTextElement] } - return (field.errorElements = [errorClassElement, errorTextElement]); - } - function _showError(field) { - let errorElements = _getErrorElements(field); - let errorClassElement = errorElements[0], - errorTextElement = errorElements[1]; + function _showError(field){ + let errorElements = _getErrorElements(field); + let errorClassElement = errorElements[0], errorTextElement = errorElements[1]; - if (errorClassElement) { - errorClassElement.classList.remove(self.config.successClass); - errorClassElement.classList.add(self.config.errorClass); - } - if (errorTextElement) { - errorTextElement.innerHTML = field.errors.join("
"); - errorTextElement.style.display = errorTextElement.pristineDisplay || ""; - } - } - - /*** - * Adds error to a specific field - * @param input - * @param error - */ - self.addError = function (input, error) { - input = input.length ? input[0] : input; - input.pristine.errors.push(error); - _showError(input.pristine); - }; - - function _removeError(field) { - let errorElements = _getErrorElements(field); - let errorClassElement = errorElements[0], - errorTextElement = errorElements[1]; - if (errorClassElement) { - // IE > 9 doesn't support multiple class removal - errorClassElement.classList.remove(self.config.errorClass); - errorClassElement.classList.remove(self.config.successClass); + if(errorClassElement){ + errorClassElement.classList.remove(self.config.successClass); + errorClassElement.classList.add(self.config.errorClass); + } + if (errorTextElement){ + errorTextElement.innerHTML = field.errors.join('
'); + errorTextElement.style.display = errorTextElement.pristineDisplay || ''; + } } - if (errorTextElement) { - errorTextElement.innerHTML = ""; - errorTextElement.style.display = "none"; + + /*** + * Adds error to a specific field + * @param input + * @param error + */ + self.addError = function(input, error) { + input = input.length ? input[0] : input; + input.pristine.errors.push(error); + _showError(input.pristine); + }; + + function _removeError(field){ + let errorElements = _getErrorElements(field); + let errorClassElement = errorElements[0], errorTextElement = errorElements[1]; + if (errorClassElement){ + // IE > 9 doesn't support multiple class removal + errorClassElement.classList.remove(self.config.errorClass); + errorClassElement.classList.remove(self.config.successClass); + } + if (errorTextElement){ + errorTextElement.innerHTML = ''; + errorTextElement.style.display = 'none'; + } + return errorElements; } - return errorElements; - } - - function _showSuccess(field) { - let errorClassElement = _removeError(field)[0]; - errorClassElement && - errorClassElement.classList.add(self.config.successClass); - } - - /*** - * Resets the errors - */ - self.reset = function () { - for (let i = 0; self.fields[i]; i++) { - self.fields[i].errorElements = null; + + function _showSuccess(field){ + let errorClassElement = _removeError(field)[0]; + errorClassElement && errorClassElement.classList.add(self.config.successClass); } - Array.from(self.form.querySelectorAll("." + PRISTINE_ERROR)).map(function ( - elem - ) { - elem.parentNode.removeChild(elem); - }); - Array.from(self.form.querySelectorAll("." + self.config.classTo)).map( - function (elem) { - elem.classList.remove(self.config.successClass); - elem.classList.remove(self.config.errorClass); - } - ); - }; - - /*** - * Resets the errors and deletes all pristine fields - */ - self.destroy = function () { - self.reset(); - self.fields.forEach(function (field) { - delete field.input.pristine; - }); - self.fields = []; - }; - self.setGlobalConfig = function (config) { - defaultConfig = config; - }; + /*** + * Resets the errors + */ + self.reset = function () { + for(let i = 0; self.fields[i]; i++) { + self.fields[i].errorElements = null; + } + Array.from(self.form.querySelectorAll('.' + PRISTINE_ERROR)).map(function (elem) { + elem.parentNode.removeChild(elem); + }); + Array.from(self.form.querySelectorAll('.' + self.config.classTo)).map(function (elem) { + elem.classList.remove(self.config.successClass); + elem.classList.remove(self.config.errorClass); + }); + + }; + + /*** + * Resets the errors and deletes all pristine fields + */ + self.destroy = function(){ + self.reset(); + self.fields.forEach(function (field) { + delete field.input.pristine; + }); + self.fields = []; + }; + + self.setGlobalConfig = function (config) { + defaultConfig = config; + }; + + return self; - return self; - return {}; } /*** @@ -413,20 +331,18 @@ export default function Pristine(form, config, live) { * @param priority => priority of the validator function, higher valued function gets called first. * @param halt => whether validation should stop for this field after current validation function */ -Pristine.addValidator = function (name, fn, msg, priority, halt) { - _(name, { fn, msg, priority, halt }); +Pristine.addValidator = function(name, fn, msg, priority, halt){ + _(name, {fn, msg, priority, halt}); }; -Pristine.addMessages = function (locale, messages) { - let langObj = lang.hasOwnProperty(locale) - ? lang[locale] - : (lang[locale] = {}); +Pristine.addMessages = function(locale, messages){ + let langObj = lang.hasOwnProperty(locale) ? lang[locale] : lang[locale] = {}; - Object.keys(messages).forEach(function (key, index) { - langObj[key] = messages[key]; - }); -}; + Object.keys(messages).forEach(function(key, index) { + langObj[key] = messages[key]; + }); +} -Pristine.setLocale = function (locale) { - currentLocale = locale; -}; +Pristine.setLocale = function (locale){ + currentLocale = locale; +} \ No newline at end of file From fc317a3e414805b00dec5ae14ea93a84cfd13063 Mon Sep 17 00:00:00 2001 From: Nicolas Cusan Date: Mon, 8 Feb 2021 18:27:48 +0100 Subject: [PATCH 03/11] Add liveAfterFirstValitation option --- dist/pristine.js | 6 +++--- src/pristine.js | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/dist/pristine.js b/dist/pristine.js index 38024c6..240514a 100644 --- a/dist/pristine.js +++ b/dist/pristine.js @@ -110,7 +110,7 @@ function Pristine(form, config, live) { var self = this; - var wasValitated = false; + var wasValidated = false; init(form, config, live); @@ -151,7 +151,7 @@ }); self.live && input.addEventListener(!~['radio', 'checkbox'].indexOf(input.getAttribute('type')) ? 'input' : 'change', function (e) { - if (self.config.liveAfterFirstValitation && wasValitated) { + if (self.config.liveAfterFirstValitation && wasValidated) { self.validate(e.target); } else if (!self.config.liveAfterFirstValitation) { self.validate(e.target); @@ -194,7 +194,7 @@ }); } } else { - wasValitated = true; + wasValidated = true; } var valid = true; diff --git a/src/pristine.js b/src/pristine.js index cfc5576..5342cfc 100755 --- a/src/pristine.js +++ b/src/pristine.js @@ -7,7 +7,8 @@ let defaultConfig = { successClass: 'has-success', errorTextParent: 'form-group', errorTextTag: 'div', - errorTextClass: 'text-help' + errorTextClass: 'text-help', + liveAfterFirstValitation: true, }; const PRISTINE_ERROR = 'pristine-error'; @@ -41,6 +42,7 @@ _('equals', { fn: (val, otherFieldSelector) => { let other = document.querySelec export default function Pristine(form, config, live){ let self = this; + let wasValidated = false; init(form, config, live); @@ -80,7 +82,11 @@ export default function Pristine(form, config, live){ fns.sort( (a, b) => b.priority - a.priority); self.live && input.addEventListener((!~['radio', 'checkbox'].indexOf(input.getAttribute('type')) ? 'input':'change'), function(e) { - self.validate(e.target); + if (self.config.liveAfterFirstValitation && wasValidated) { + self.validate(e.target); + } else if (!self.config.liveAfterFirstValitation) { + self.validate(e.target); + } }.bind(self)); return input.pristine = {input, validators: fns, params, messages, self}; @@ -106,15 +112,16 @@ export default function Pristine(form, config, live){ * @param silent => do not show error messages, just return true/false * @returns {boolean} return true when valid false otherwise */ - self.validate = function(input, silent){ - silent = (input && silent === true) || input === true; + self.validate = function(input = null, silent = false){ let fields = self.fields; - if (input !== true && input !== false){ + if (input){ if (input instanceof HTMLElement) { fields = [input.pristine]; } else if (input instanceof NodeList || input instanceof (window.$ || Array) || input instanceof Array){ fields = Array.from(input).map(el => el.pristine); } + } else { + wasValidated = true; } let valid = true; From 612de0bd6e386061c150f6a16a50ffc39a1cd717 Mon Sep 17 00:00:00 2001 From: Nicolas Cusan Date: Mon, 8 Feb 2021 18:40:13 +0100 Subject: [PATCH 04/11] update readme --- README.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index cb2ffdd..ee8c405 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Some examples of use can be found [here](http://pristine.js.org/demo.html). Include the javascript file in your html head or just before the closing body tag -```html +```html ``` @@ -27,7 +27,7 @@ window.onload = function () { form.addEventListener('submit', function (e) { e.preventDefault(); - + // check if the form is valid var valid = pristine.validate(); // returns true or false @@ -40,13 +40,13 @@ window.onload = function () { It automatically validates `required, min, max, minlength, maxlength` attributes and the value of type attributes like `email, number` and more.. - + `Pristine` takes `3` parameters - **form** The form element -- **config** An object containing the configuration. Default is bootstrap's configuration which is +- **config** An object containing the configuration. Default is bootstrap's configuration which is @@ -61,7 +61,9 @@ let defaultConfig = { // type of element to create for the error text errorTextTag: 'div', // class of the error text element - errorTextClass: 'text-help' + errorTextClass: 'text-help', + // enable live validation after first form submission (requires live parameter to be true) + liveAfterFirstValitation: true }; ``` @@ -106,11 +108,11 @@ pristine.addValidator(elem, function(value) { Pristine.addValidator("my-range", function(value, param1, param2) { // here `this` refers to the respective input element return parseInt(param1) <= value && value <= parseInt(param2) - + }, "The value (${0}) must be between ${1} and ${2}", 5, false); ``` -Now you can assign it to your inputs like this +Now you can assign it to your inputs like this ```html @@ -142,7 +144,7 @@ Add an attribute like `data-pristine--message`with the custom mes ## API **Pristine(form, config, live)**
*Constructor* - + | Parameter | Default | Required? | Description| | --- | ---- | ----- | ---- | | `form`| - |
✔
|The form element| @@ -236,15 +238,15 @@ Add an attribute like `data-pristine--message`with the custom mes **pristine.reset()**
*Reset the errors in the form* - - + +
**pristine.destroy()**
*Destroy the pristine object* - +

-> The goal of this library is not to provide every possible type of validation and thus becoming a bloat. +> The goal of this library is not to provide every possible type of validation and thus becoming a bloat. > The goal is to provide most common types of validations and a neat way to add custom validators. ## License From 39954cbc07d4d5c1585c4be838a33f04dbf999b4 Mon Sep 17 00:00:00 2001 From: Nicolas Cusan Date: Sat, 8 Jan 2022 00:44:48 +0100 Subject: [PATCH 05/11] Remove input type button from allowed selectors --- src/pristine.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pristine.js b/src/pristine.js index 5342cfc..2888829 100755 --- a/src/pristine.js +++ b/src/pristine.js @@ -12,7 +12,7 @@ let defaultConfig = { }; const PRISTINE_ERROR = 'pristine-error'; -const SELECTOR = "input:not([type^=hidden]):not([type^=submit]), select, textarea"; +const SELECTOR = "input:not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea"; const ALLOWED_ATTRIBUTES = ["required", "min", "max", 'minlength', 'maxlength', 'pattern']; const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ @@ -352,4 +352,4 @@ Pristine.addMessages = function(locale, messages){ Pristine.setLocale = function (locale){ currentLocale = locale; -} \ No newline at end of file +} From 8933654eb64345985272e02838eb28c7ea9366aa Mon Sep 17 00:00:00 2001 From: Nicolas Cusan Date: Sat, 8 Jan 2022 00:45:29 +0100 Subject: [PATCH 06/11] Remove input type button from allowed selectors --- dist/pristine.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/pristine.js b/dist/pristine.js index 240514a..6e43dac 100644 --- a/dist/pristine.js +++ b/dist/pristine.js @@ -59,7 +59,7 @@ }; var PRISTINE_ERROR = 'pristine-error'; - var SELECTOR = "input:not([type^=hidden]):not([type^=submit]), select, textarea"; + var SELECTOR = "input:not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea"; var ALLOWED_ATTRIBUTES = ["required", "min", "max", 'minlength', 'maxlength', 'pattern']; var EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; From c1b8f25190278a9ed3e3a5ef74763e8e4550951f Mon Sep 17 00:00:00 2001 From: Nicolas Cusan Date: Sat, 8 Jan 2022 00:46:21 +0100 Subject: [PATCH 07/11] Remove input type button from allowed selectors --- dist/pristine.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/pristine.min.js b/dist/pristine.min.js index 2455278..5d394a3 100644 --- a/dist/pristine.min.js +++ b/dist/pristine.min.js @@ -1 +1 @@ -!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).Pristine=r()}(this,(function(){"use strict";var e={en:{required:"This field is required",email:"This field requires a valid e-mail address",number:"This field requires a number",integer:"This field requires an integer value",url:"This field requires a valid website URL",tel:"This field requires a valid telephone number",maxlength:"This fields length must be < ${1}",minlength:"This fields length must be > ${1}",min:"Minimum value for this field is ${1}",max:"Maximum value for this field is ${1}",pattern:"Please match the requested format",equals:"The two fields do not match",default:"Please enter a correct value"}};function r(e){var r=arguments;return this.replace(/\${([^{}]*)}/g,(function(e,t){return r[t]}))}function t(e){return e.pristine.self.form.querySelectorAll('input[name="'+e.getAttribute("name")+'"]:checked').length}var n={classTo:"form-group",errorClass:"has-danger",successClass:"has-success",errorTextParent:"form-group",errorTextTag:"div",errorTextClass:"text-help",liveAfterFirstValitation:!0},i=["required","min","max","minlength","maxlength","pattern"],s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,a=/-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/,o="en",l={},u=function(e,r){r.name=e,void 0===r.priority&&(r.priority=1),l[e]=r};function f(t,s,u){var f=this,c=!1;function p(e,r,t,n){var i=l[t];if(i&&(e.push(i),n)){var s="pattern"===t?[n]:n.split(",");s.unshift(null),r[t]=s}}function m(t){for(var n=[],i=!0,s=0;t.validators[s];s++){var a=t.validators[s],l=t.params[a.name]?t.params[a.name]:[];if(l[0]=t.input.value,!a.fn.apply(t.input,l)&&(i=!1,"function"==typeof a.msg?n.push(a.msg(t.input.value,l)):"string"==typeof a.msg?n.push(r.apply(a.msg,l)):a.msg===Object(a.msg)&&a.msg[o]?n.push(r.apply(a.msg[o],l)):t.messages[o]&&t.messages[o][a.name]?n.push(r.apply(t.messages[o][a.name],l)):e[o]&&e[o][a.name]?n.push(r.apply(e[o][a.name],l)):n.push(r.apply(e[o].default,l)),!0===a.halt))break}return t.errors=n,i}function d(e){if(e.errorElements)return e.errorElements;var r=function(e,r){for(;(e=e.parentElement)&&!e.classList.contains(r););return e}(e.input,f.config.classTo),t=null,n=null;return(t=f.config.classTo===f.config.errorTextParent?r:r.querySelector("."+f.config.errorTextParent))&&((n=t.querySelector(".pristine-error"))||((n=document.createElement(f.config.errorTextTag)).className="pristine-error "+f.config.errorTextClass,t.appendChild(n),n.pristineDisplay=n.style.display)),e.errorElements=[r,n]}function h(e){var r=d(e),t=r[0],n=r[1];t&&(t.classList.remove(f.config.successClass),t.classList.add(f.config.errorClass)),n&&(n.innerHTML=e.errors.join("
"),n.style.display=n.pristineDisplay||"")}function g(e){var r=function(e){var r=d(e),t=r[0],n=r[1];return t&&(t.classList.remove(f.config.errorClass),t.classList.remove(f.config.successClass)),n&&(n.innerHTML="",n.style.display="none"),r}(e)[0];r&&r.classList.add(f.config.successClass)}return function(e,r,t){e.setAttribute("novalidate","true"),f.form=e,f.config=function(e,r){for(var t in r)t in e||(e[t]=r[t]);return e}(r||{},n),f.live=!(!1===t),f.fields=Array.from(e.querySelectorAll("input:not([type^=hidden]):not([type^=submit]), select, textarea")).map(function(e){var r=[],t={},n={};return[].forEach.call(e.attributes,(function(e){if(/^data-pristine-/.test(e.name)){var s=e.name.substr(14),o=s.match(a);if(null!==o){var l=void 0===o[1]?"en":o[1];return n.hasOwnProperty(l)||(n[l]={}),void(n[l][s.slice(0,s.length-o[0].length)]=e.value)}"type"===s&&(s=e.value),p(r,t,s,e.value)}else~i.indexOf(e.name)?p(r,t,e.name,e.value):"type"===e.name&&p(r,t,e.value)})),r.sort((function(e,r){return r.priority-e.priority})),f.live&&e.addEventListener(~["radio","checkbox"].indexOf(e.getAttribute("type"))?"change":"input",function(e){f.config.liveAfterFirstValitation&&c?f.validate(e.target):f.config.liveAfterFirstValitation||f.validate(e.target)}.bind(f)),e.pristine={input:e,validators:r,params:t,messages:n,self:f}}.bind(f))}(t,s,u),f.validate=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1],t=f.fields;e?e instanceof HTMLElement?t=[e.pristine]:(e instanceof NodeList||e instanceof(window.$||Array)||e instanceof Array)&&(t=Array.from(e).map((function(e){return e.pristine}))):c=!0;for(var n=!0,i=0;t[i];i++){var s=t[i];m(s)?!r&&g(s):(n=!1,!r&&h(s))}return n},f.getErrors=function(e){if(!e){for(var r=[],t=0;t=parseInt(r)}}),u("maxlength",{fn:function(e,r){return!e||e.length<=parseInt(r)}}),u("min",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)>=parseInt(r):parseFloat(e)>=parseFloat(r))}}),u("max",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)<=parseInt(r):parseFloat(e)<=parseFloat(r))}}),u("pattern",{fn:function(e,r){var t=r.match(new RegExp("^/(.*?)/([gimy]*)$"));return!e||new RegExp(t[1],t[2]).test(e)}}),u("equals",{fn:function(e,r){var t=document.querySelector(r);return t&&(!e&&!t.value||t.value===e)}}),f.addValidator=function(e,r,t,n,i){u(e,{fn:r,msg:t,priority:n,halt:i})},f.addMessages=function(r,t){var n=e.hasOwnProperty(r)?e[r]:e[r]={};Object.keys(t).forEach((function(e,r){n[e]=t[e]}))},f.setLocale=function(e){o=e},f})); +!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).Pristine=r()}(this,(function(){"use strict";var e={en:{required:"This field is required",email:"This field requires a valid e-mail address",number:"This field requires a number",integer:"This field requires an integer value",url:"This field requires a valid website URL",tel:"This field requires a valid telephone number",maxlength:"This fields length must be < ${1}",minlength:"This fields length must be > ${1}",min:"Minimum value for this field is ${1}",max:"Maximum value for this field is ${1}",pattern:"Please match the requested format",equals:"The two fields do not match",default:"Please enter a correct value"}};function r(e){var r=arguments;return this.replace(/\${([^{}]*)}/g,(function(e,t){return r[t]}))}function t(e){return e.pristine.self.form.querySelectorAll('input[name="'+e.getAttribute("name")+'"]:checked').length}var n={classTo:"form-group",errorClass:"has-danger",successClass:"has-success",errorTextParent:"form-group",errorTextTag:"div",errorTextClass:"text-help",liveAfterFirstValitation:!0},i=["required","min","max","minlength","maxlength","pattern"],s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,a=/-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/,o="en",l={},u=function(e,r){r.name=e,void 0===r.priority&&(r.priority=1),l[e]=r};function f(t,s,u){var f=this,c=!1;function p(e,r,t,n){var i=l[t];if(i&&(e.push(i),n)){var s="pattern"===t?[n]:n.split(",");s.unshift(null),r[t]=s}}function m(t){for(var n=[],i=!0,s=0;t.validators[s];s++){var a=t.validators[s],l=t.params[a.name]?t.params[a.name]:[];if(l[0]=t.input.value,!a.fn.apply(t.input,l)&&(i=!1,"function"==typeof a.msg?n.push(a.msg(t.input.value,l)):"string"==typeof a.msg?n.push(r.apply(a.msg,l)):a.msg===Object(a.msg)&&a.msg[o]?n.push(r.apply(a.msg[o],l)):t.messages[o]&&t.messages[o][a.name]?n.push(r.apply(t.messages[o][a.name],l)):e[o]&&e[o][a.name]?n.push(r.apply(e[o][a.name],l)):n.push(r.apply(e[o].default,l)),!0===a.halt))break}return t.errors=n,i}function d(e){if(e.errorElements)return e.errorElements;var r=function(e,r){for(;(e=e.parentElement)&&!e.classList.contains(r););return e}(e.input,f.config.classTo),t=null,n=null;return(t=f.config.classTo===f.config.errorTextParent?r:r.querySelector("."+f.config.errorTextParent))&&((n=t.querySelector(".pristine-error"))||((n=document.createElement(f.config.errorTextTag)).className="pristine-error "+f.config.errorTextClass,t.appendChild(n),n.pristineDisplay=n.style.display)),e.errorElements=[r,n]}function h(e){var r=d(e),t=r[0],n=r[1];t&&(t.classList.remove(f.config.successClass),t.classList.add(f.config.errorClass)),n&&(n.innerHTML=e.errors.join("
"),n.style.display=n.pristineDisplay||"")}function g(e){var r=function(e){var r=d(e),t=r[0],n=r[1];return t&&(t.classList.remove(f.config.errorClass),t.classList.remove(f.config.successClass)),n&&(n.innerHTML="",n.style.display="none"),r}(e)[0];r&&r.classList.add(f.config.successClass)}return function(e,r,t){e.setAttribute("novalidate","true"),f.form=e,f.config=function(e,r){for(var t in r)t in e||(e[t]=r[t]);return e}(r||{},n),f.live=!(!1===t),f.fields=Array.from(e.querySelectorAll("input:not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea")).map(function(e){var r=[],t={},n={};return[].forEach.call(e.attributes,(function(e){if(/^data-pristine-/.test(e.name)){var s=e.name.substr(14),o=s.match(a);if(null!==o){var l=void 0===o[1]?"en":o[1];return n.hasOwnProperty(l)||(n[l]={}),void(n[l][s.slice(0,s.length-o[0].length)]=e.value)}"type"===s&&(s=e.value),p(r,t,s,e.value)}else~i.indexOf(e.name)?p(r,t,e.name,e.value):"type"===e.name&&p(r,t,e.value)})),r.sort((function(e,r){return r.priority-e.priority})),f.live&&e.addEventListener(~["radio","checkbox"].indexOf(e.getAttribute("type"))?"change":"input",function(e){f.config.liveAfterFirstValitation&&c?f.validate(e.target):f.config.liveAfterFirstValitation||f.validate(e.target)}.bind(f)),e.pristine={input:e,validators:r,params:t,messages:n,self:f}}.bind(f))}(t,s,u),f.validate=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1],t=f.fields;e?e instanceof HTMLElement?t=[e.pristine]:(e instanceof NodeList||e instanceof(window.$||Array)||e instanceof Array)&&(t=Array.from(e).map((function(e){return e.pristine}))):c=!0;for(var n=!0,i=0;t[i];i++){var s=t[i];m(s)?!r&&g(s):(n=!1,!r&&h(s))}return n},f.getErrors=function(e){if(!e){for(var r=[],t=0;t=parseInt(r)}}),u("maxlength",{fn:function(e,r){return!e||e.length<=parseInt(r)}}),u("min",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)>=parseInt(r):parseFloat(e)>=parseFloat(r))}}),u("max",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)<=parseInt(r):parseFloat(e)<=parseFloat(r))}}),u("pattern",{fn:function(e,r){var t=r.match(new RegExp("^/(.*?)/([gimy]*)$"));return!e||new RegExp(t[1],t[2]).test(e)}}),u("equals",{fn:function(e,r){var t=document.querySelector(r);return t&&(!e&&!t.value||t.value===e)}}),f.addValidator=function(e,r,t,n,i){u(e,{fn:r,msg:t,priority:n,halt:i})},f.addMessages=function(r,t){var n=e.hasOwnProperty(r)?e[r]:e[r]={};Object.keys(t).forEach((function(e,r){n[e]=t[e]}))},f.setLocale=function(e){o=e},f})); From cac6b65b25ec7ea53bdb9daaa2d081a2c591281c Mon Sep 17 00:00:00 2001 From: Nicolas Cusan Date: Mon, 10 Jan 2022 12:10:56 +0100 Subject: [PATCH 08/11] ignore disabled fields, listen only to change events --- dist/pristine.js | 4 ++-- dist/pristine.min.js | 2 +- src/pristine.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dist/pristine.js b/dist/pristine.js index 6e43dac..7bdf071 100644 --- a/dist/pristine.js +++ b/dist/pristine.js @@ -59,7 +59,7 @@ }; var PRISTINE_ERROR = 'pristine-error'; - var SELECTOR = "input:not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea"; + var SELECTOR = "input:not([disabled]):not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea"; var ALLOWED_ATTRIBUTES = ["required", "min", "max", 'minlength', 'maxlength', 'pattern']; var EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; @@ -150,7 +150,7 @@ return b.priority - a.priority; }); - self.live && input.addEventListener(!~['radio', 'checkbox'].indexOf(input.getAttribute('type')) ? 'input' : 'change', function (e) { + self.live && input.addEventListener('change', function (e) { if (self.config.liveAfterFirstValitation && wasValidated) { self.validate(e.target); } else if (!self.config.liveAfterFirstValitation) { diff --git a/dist/pristine.min.js b/dist/pristine.min.js index 5d394a3..2a88061 100644 --- a/dist/pristine.min.js +++ b/dist/pristine.min.js @@ -1 +1 @@ -!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).Pristine=r()}(this,(function(){"use strict";var e={en:{required:"This field is required",email:"This field requires a valid e-mail address",number:"This field requires a number",integer:"This field requires an integer value",url:"This field requires a valid website URL",tel:"This field requires a valid telephone number",maxlength:"This fields length must be < ${1}",minlength:"This fields length must be > ${1}",min:"Minimum value for this field is ${1}",max:"Maximum value for this field is ${1}",pattern:"Please match the requested format",equals:"The two fields do not match",default:"Please enter a correct value"}};function r(e){var r=arguments;return this.replace(/\${([^{}]*)}/g,(function(e,t){return r[t]}))}function t(e){return e.pristine.self.form.querySelectorAll('input[name="'+e.getAttribute("name")+'"]:checked').length}var n={classTo:"form-group",errorClass:"has-danger",successClass:"has-success",errorTextParent:"form-group",errorTextTag:"div",errorTextClass:"text-help",liveAfterFirstValitation:!0},i=["required","min","max","minlength","maxlength","pattern"],s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,a=/-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/,o="en",l={},u=function(e,r){r.name=e,void 0===r.priority&&(r.priority=1),l[e]=r};function f(t,s,u){var f=this,c=!1;function p(e,r,t,n){var i=l[t];if(i&&(e.push(i),n)){var s="pattern"===t?[n]:n.split(",");s.unshift(null),r[t]=s}}function m(t){for(var n=[],i=!0,s=0;t.validators[s];s++){var a=t.validators[s],l=t.params[a.name]?t.params[a.name]:[];if(l[0]=t.input.value,!a.fn.apply(t.input,l)&&(i=!1,"function"==typeof a.msg?n.push(a.msg(t.input.value,l)):"string"==typeof a.msg?n.push(r.apply(a.msg,l)):a.msg===Object(a.msg)&&a.msg[o]?n.push(r.apply(a.msg[o],l)):t.messages[o]&&t.messages[o][a.name]?n.push(r.apply(t.messages[o][a.name],l)):e[o]&&e[o][a.name]?n.push(r.apply(e[o][a.name],l)):n.push(r.apply(e[o].default,l)),!0===a.halt))break}return t.errors=n,i}function d(e){if(e.errorElements)return e.errorElements;var r=function(e,r){for(;(e=e.parentElement)&&!e.classList.contains(r););return e}(e.input,f.config.classTo),t=null,n=null;return(t=f.config.classTo===f.config.errorTextParent?r:r.querySelector("."+f.config.errorTextParent))&&((n=t.querySelector(".pristine-error"))||((n=document.createElement(f.config.errorTextTag)).className="pristine-error "+f.config.errorTextClass,t.appendChild(n),n.pristineDisplay=n.style.display)),e.errorElements=[r,n]}function h(e){var r=d(e),t=r[0],n=r[1];t&&(t.classList.remove(f.config.successClass),t.classList.add(f.config.errorClass)),n&&(n.innerHTML=e.errors.join("
"),n.style.display=n.pristineDisplay||"")}function g(e){var r=function(e){var r=d(e),t=r[0],n=r[1];return t&&(t.classList.remove(f.config.errorClass),t.classList.remove(f.config.successClass)),n&&(n.innerHTML="",n.style.display="none"),r}(e)[0];r&&r.classList.add(f.config.successClass)}return function(e,r,t){e.setAttribute("novalidate","true"),f.form=e,f.config=function(e,r){for(var t in r)t in e||(e[t]=r[t]);return e}(r||{},n),f.live=!(!1===t),f.fields=Array.from(e.querySelectorAll("input:not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea")).map(function(e){var r=[],t={},n={};return[].forEach.call(e.attributes,(function(e){if(/^data-pristine-/.test(e.name)){var s=e.name.substr(14),o=s.match(a);if(null!==o){var l=void 0===o[1]?"en":o[1];return n.hasOwnProperty(l)||(n[l]={}),void(n[l][s.slice(0,s.length-o[0].length)]=e.value)}"type"===s&&(s=e.value),p(r,t,s,e.value)}else~i.indexOf(e.name)?p(r,t,e.name,e.value):"type"===e.name&&p(r,t,e.value)})),r.sort((function(e,r){return r.priority-e.priority})),f.live&&e.addEventListener(~["radio","checkbox"].indexOf(e.getAttribute("type"))?"change":"input",function(e){f.config.liveAfterFirstValitation&&c?f.validate(e.target):f.config.liveAfterFirstValitation||f.validate(e.target)}.bind(f)),e.pristine={input:e,validators:r,params:t,messages:n,self:f}}.bind(f))}(t,s,u),f.validate=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1],t=f.fields;e?e instanceof HTMLElement?t=[e.pristine]:(e instanceof NodeList||e instanceof(window.$||Array)||e instanceof Array)&&(t=Array.from(e).map((function(e){return e.pristine}))):c=!0;for(var n=!0,i=0;t[i];i++){var s=t[i];m(s)?!r&&g(s):(n=!1,!r&&h(s))}return n},f.getErrors=function(e){if(!e){for(var r=[],t=0;t=parseInt(r)}}),u("maxlength",{fn:function(e,r){return!e||e.length<=parseInt(r)}}),u("min",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)>=parseInt(r):parseFloat(e)>=parseFloat(r))}}),u("max",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)<=parseInt(r):parseFloat(e)<=parseFloat(r))}}),u("pattern",{fn:function(e,r){var t=r.match(new RegExp("^/(.*?)/([gimy]*)$"));return!e||new RegExp(t[1],t[2]).test(e)}}),u("equals",{fn:function(e,r){var t=document.querySelector(r);return t&&(!e&&!t.value||t.value===e)}}),f.addValidator=function(e,r,t,n,i){u(e,{fn:r,msg:t,priority:n,halt:i})},f.addMessages=function(r,t){var n=e.hasOwnProperty(r)?e[r]:e[r]={};Object.keys(t).forEach((function(e,r){n[e]=t[e]}))},f.setLocale=function(e){o=e},f})); +!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).Pristine=r()}(this,(function(){"use strict";var e={en:{required:"This field is required",email:"This field requires a valid e-mail address",number:"This field requires a number",integer:"This field requires an integer value",url:"This field requires a valid website URL",tel:"This field requires a valid telephone number",maxlength:"This fields length must be < ${1}",minlength:"This fields length must be > ${1}",min:"Minimum value for this field is ${1}",max:"Maximum value for this field is ${1}",pattern:"Please match the requested format",equals:"The two fields do not match",default:"Please enter a correct value"}};function r(e){var r=arguments;return this.replace(/\${([^{}]*)}/g,(function(e,t){return r[t]}))}function t(e){return e.pristine.self.form.querySelectorAll('input[name="'+e.getAttribute("name")+'"]:checked').length}var n={classTo:"form-group",errorClass:"has-danger",successClass:"has-success",errorTextParent:"form-group",errorTextTag:"div",errorTextClass:"text-help",liveAfterFirstValitation:!0},i=["required","min","max","minlength","maxlength","pattern"],s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,a=/-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/,o="en",l={},u=function(e,r){r.name=e,void 0===r.priority&&(r.priority=1),l[e]=r};function f(t,s,u){var f=this,c=!1;function p(e,r,t,n){var i=l[t];if(i&&(e.push(i),n)){var s="pattern"===t?[n]:n.split(",");s.unshift(null),r[t]=s}}function m(t){for(var n=[],i=!0,s=0;t.validators[s];s++){var a=t.validators[s],l=t.params[a.name]?t.params[a.name]:[];if(l[0]=t.input.value,!a.fn.apply(t.input,l)&&(i=!1,"function"==typeof a.msg?n.push(a.msg(t.input.value,l)):"string"==typeof a.msg?n.push(r.apply(a.msg,l)):a.msg===Object(a.msg)&&a.msg[o]?n.push(r.apply(a.msg[o],l)):t.messages[o]&&t.messages[o][a.name]?n.push(r.apply(t.messages[o][a.name],l)):e[o]&&e[o][a.name]?n.push(r.apply(e[o][a.name],l)):n.push(r.apply(e[o].default,l)),!0===a.halt))break}return t.errors=n,i}function d(e){if(e.errorElements)return e.errorElements;var r=function(e,r){for(;(e=e.parentElement)&&!e.classList.contains(r););return e}(e.input,f.config.classTo),t=null,n=null;return(t=f.config.classTo===f.config.errorTextParent?r:r.querySelector("."+f.config.errorTextParent))&&((n=t.querySelector(".pristine-error"))||((n=document.createElement(f.config.errorTextTag)).className="pristine-error "+f.config.errorTextClass,t.appendChild(n),n.pristineDisplay=n.style.display)),e.errorElements=[r,n]}function h(e){var r=d(e),t=r[0],n=r[1];t&&(t.classList.remove(f.config.successClass),t.classList.add(f.config.errorClass)),n&&(n.innerHTML=e.errors.join("
"),n.style.display=n.pristineDisplay||"")}function g(e){var r=function(e){var r=d(e),t=r[0],n=r[1];return t&&(t.classList.remove(f.config.errorClass),t.classList.remove(f.config.successClass)),n&&(n.innerHTML="",n.style.display="none"),r}(e)[0];r&&r.classList.add(f.config.successClass)}return function(e,r,t){e.setAttribute("novalidate","true"),f.form=e,f.config=function(e,r){for(var t in r)t in e||(e[t]=r[t]);return e}(r||{},n),f.live=!(!1===t),f.fields=Array.from(e.querySelectorAll("input:not([disabled]):not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea")).map(function(e){var r=[],t={},n={};return[].forEach.call(e.attributes,(function(e){if(/^data-pristine-/.test(e.name)){var s=e.name.substr(14),o=s.match(a);if(null!==o){var l=void 0===o[1]?"en":o[1];return n.hasOwnProperty(l)||(n[l]={}),void(n[l][s.slice(0,s.length-o[0].length)]=e.value)}"type"===s&&(s=e.value),p(r,t,s,e.value)}else~i.indexOf(e.name)?p(r,t,e.name,e.value):"type"===e.name&&p(r,t,e.value)})),r.sort((function(e,r){return r.priority-e.priority})),f.live&&e.addEventListener("change",function(e){f.config.liveAfterFirstValitation&&c?f.validate(e.target):f.config.liveAfterFirstValitation||f.validate(e.target)}.bind(f)),e.pristine={input:e,validators:r,params:t,messages:n,self:f}}.bind(f))}(t,s,u),f.validate=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1],t=f.fields;e?e instanceof HTMLElement?t=[e.pristine]:(e instanceof NodeList||e instanceof(window.$||Array)||e instanceof Array)&&(t=Array.from(e).map((function(e){return e.pristine}))):c=!0;for(var n=!0,i=0;t[i];i++){var s=t[i];m(s)?!r&&g(s):(n=!1,!r&&h(s))}return n},f.getErrors=function(e){if(!e){for(var r=[],t=0;t=parseInt(r)}}),u("maxlength",{fn:function(e,r){return!e||e.length<=parseInt(r)}}),u("min",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)>=parseInt(r):parseFloat(e)>=parseFloat(r))}}),u("max",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)<=parseInt(r):parseFloat(e)<=parseFloat(r))}}),u("pattern",{fn:function(e,r){var t=r.match(new RegExp("^/(.*?)/([gimy]*)$"));return!e||new RegExp(t[1],t[2]).test(e)}}),u("equals",{fn:function(e,r){var t=document.querySelector(r);return t&&(!e&&!t.value||t.value===e)}}),f.addValidator=function(e,r,t,n,i){u(e,{fn:r,msg:t,priority:n,halt:i})},f.addMessages=function(r,t){var n=e.hasOwnProperty(r)?e[r]:e[r]={};Object.keys(t).forEach((function(e,r){n[e]=t[e]}))},f.setLocale=function(e){o=e},f})); diff --git a/src/pristine.js b/src/pristine.js index 2888829..24196fc 100755 --- a/src/pristine.js +++ b/src/pristine.js @@ -12,7 +12,7 @@ let defaultConfig = { }; const PRISTINE_ERROR = 'pristine-error'; -const SELECTOR = "input:not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea"; +const SELECTOR = "input:not([disabled]):not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea"; const ALLOWED_ATTRIBUTES = ["required", "min", "max", 'minlength', 'maxlength', 'pattern']; const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ @@ -81,7 +81,7 @@ export default function Pristine(form, config, live){ fns.sort( (a, b) => b.priority - a.priority); - self.live && input.addEventListener((!~['radio', 'checkbox'].indexOf(input.getAttribute('type')) ? 'input':'change'), function(e) { + self.live && input.addEventListener('change', function(e) { if (self.config.liveAfterFirstValitation && wasValidated) { self.validate(e.target); } else if (!self.config.liveAfterFirstValitation) { From f6a8632fb6d8083b5da75230e3c11652ac4e796f Mon Sep 17 00:00:00 2001 From: Nicolas Cusan Date: Wed, 12 Jan 2022 16:00:07 +0100 Subject: [PATCH 09/11] listen to both input and change on text input fields --- dist/pristine.js | 670 +++++++------- dist/pristine.min.js | 2 +- src/pristine.js | 688 ++++++++------- yarn.lock | 1998 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 2731 insertions(+), 627 deletions(-) create mode 100644 yarn.lock diff --git a/dist/pristine.js b/dist/pristine.js index 7bdf071..108e832 100644 --- a/dist/pristine.js +++ b/dist/pristine.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Pristine = factory()); -}(this, (function () { 'use strict'; +})(this, (function () { 'use strict'; var lang = { en: { @@ -49,18 +49,18 @@ } var defaultConfig = { - classTo: 'form-group', - errorClass: 'has-danger', - successClass: 'has-success', - errorTextParent: 'form-group', - errorTextTag: 'div', - errorTextClass: 'text-help', - liveAfterFirstValitation: true + classTo: 'form-group', + errorClass: 'has-danger', + successClass: 'has-success', + errorTextParent: 'form-group', + errorTextTag: 'div', + errorTextClass: 'text-help', + liveAfterFirstValitation: true }; var PRISTINE_ERROR = 'pristine-error'; - var SELECTOR = "input:not([disabled]):not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea"; - var ALLOWED_ATTRIBUTES = ["required", "min", "max", 'minlength', 'maxlength', 'pattern']; + var SELECTOR = 'input:not([disabled]):not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea'; + var ALLOWED_ATTRIBUTES = ['required', 'min', 'max', 'minlength', 'maxlength', 'pattern']; var EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; var MESSAGE_REGEX = /-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/; // matches, -message, -message-en, -message-en_US @@ -68,342 +68,366 @@ var validators = {}; var _ = function _(name, validator) { - validator.name = name; - if (validator.priority === undefined) validator.priority = 1; - validators[name] = validator; + validator.name = name; + if (validator.priority === undefined) validator.priority = 1; + validators[name] = validator; }; _('text', { fn: function fn(val) { - return true; - }, priority: 0 }); - _('required', { fn: function fn(val) { - return this.type === 'radio' || this.type === 'checkbox' ? groupedElemCount(this) : val !== undefined && val !== ''; - }, priority: 99, halt: true }); + return true; + }, priority: 0 }); + _('required', { + fn: function fn(val) { + return this.type === 'radio' || this.type === 'checkbox' ? groupedElemCount(this) : val !== undefined && val !== ''; + }, + priority: 99, + halt: true + }); _('email', { fn: function fn(val) { - return !val || EMAIL_REGEX.test(val); - } }); + return !val || EMAIL_REGEX.test(val); + } }); _('number', { fn: function fn(val) { - return !val || !isNaN(parseFloat(val)); - }, priority: 2 }); + return !val || !isNaN(parseFloat(val)); + }, priority: 2 }); _('integer', { fn: function fn(val) { - return !val || /^\d+$/.test(val); - } }); + return !val || /^\d+$/.test(val); + } }); _('minlength', { fn: function fn(val, length) { - return !val || val.length >= parseInt(length); - } }); + return !val || val.length >= parseInt(length); + } }); _('maxlength', { fn: function fn(val, length) { - return !val || val.length <= parseInt(length); - } }); - _('min', { fn: function fn(val, limit) { - return !val || (this.type === 'checkbox' ? groupedElemCount(this) >= parseInt(limit) : parseFloat(val) >= parseFloat(limit)); - } }); - _('max', { fn: function fn(val, limit) { - return !val || (this.type === 'checkbox' ? groupedElemCount(this) <= parseInt(limit) : parseFloat(val) <= parseFloat(limit)); - } }); - _('pattern', { fn: function fn(val, pattern) { - var m = pattern.match(new RegExp('^/(.*?)/([gimy]*)$'));return !val || new RegExp(m[1], m[2]).test(val); - } }); - _('equals', { fn: function fn(val, otherFieldSelector) { - var other = document.querySelector(otherFieldSelector);return other && (!val && !other.value || other.value === val); - } }); + return !val || val.length <= parseInt(length); + } }); + _('min', { + fn: function fn(val, limit) { + return !val || (this.type === 'checkbox' ? groupedElemCount(this) >= parseInt(limit) : parseFloat(val) >= parseFloat(limit)); + } + }); + _('max', { + fn: function fn(val, limit) { + return !val || (this.type === 'checkbox' ? groupedElemCount(this) <= parseInt(limit) : parseFloat(val) <= parseFloat(limit)); + } + }); + _('pattern', { + fn: function fn(val, pattern) { + var m = pattern.match(new RegExp('^/(.*?)/([gimy]*)$')); + return !val || new RegExp(m[1], m[2]).test(val); + } + }); + _('equals', { + fn: function fn(val, otherFieldSelector) { + var other = document.querySelector(otherFieldSelector); + return other && (!val && !other.value || other.value === val); + } + }); function Pristine(form, config, live) { + var self = this; + var wasValidated = false; + + init(form, config, live); + + function init(form, config, live) { + form.setAttribute('novalidate', 'true'); + + self.form = form; + self.config = mergeConfig(config || {}, defaultConfig); + self.live = !(live === false); + self.fields = Array.from(form.querySelectorAll(SELECTOR)).map(function (input) { + var fns = []; + var params = {}; + var messages = {}; + + [].forEach.call(input.attributes, function (attr) { + if (/^data-pristine-/.test(attr.name)) { + var name = attr.name.substr(14); + var messageMatch = name.match(MESSAGE_REGEX); + if (messageMatch !== null) { + var locale = messageMatch[1] === undefined ? 'en' : messageMatch[1]; + if (!messages.hasOwnProperty(locale)) messages[locale] = {}; + messages[locale][name.slice(0, name.length - messageMatch[0].length)] = attr.value; + return; + } + if (name === 'type') name = attr.value; + _addValidatorToField(fns, params, name, attr.value); + } else if (~ALLOWED_ATTRIBUTES.indexOf(attr.name)) { + _addValidatorToField(fns, params, attr.name, attr.value); + } else if (attr.name === 'type') { + _addValidatorToField(fns, params, attr.value); + } + }); - var self = this; - var wasValidated = false; - - init(form, config, live); - - function init(form, config, live) { - - form.setAttribute("novalidate", "true"); - - self.form = form; - self.config = mergeConfig(config || {}, defaultConfig); - self.live = !(live === false); - self.fields = Array.from(form.querySelectorAll(SELECTOR)).map(function (input) { - - var fns = []; - var params = {}; - var messages = {}; - - [].forEach.call(input.attributes, function (attr) { - if (/^data-pristine-/.test(attr.name)) { - var name = attr.name.substr(14); - var messageMatch = name.match(MESSAGE_REGEX); - if (messageMatch !== null) { - var locale = messageMatch[1] === undefined ? 'en' : messageMatch[1]; - if (!messages.hasOwnProperty(locale)) messages[locale] = {}; - messages[locale][name.slice(0, name.length - messageMatch[0].length)] = attr.value; - return; - } - if (name === 'type') name = attr.value; - _addValidatorToField(fns, params, name, attr.value); - } else if (~ALLOWED_ATTRIBUTES.indexOf(attr.name)) { - _addValidatorToField(fns, params, attr.name, attr.value); - } else if (attr.name === 'type') { - _addValidatorToField(fns, params, attr.value); - } - }); - - fns.sort(function (a, b) { - return b.priority - a.priority; - }); - - self.live && input.addEventListener('change', function (e) { - if (self.config.liveAfterFirstValitation && wasValidated) { - self.validate(e.target); - } else if (!self.config.liveAfterFirstValitation) { - self.validate(e.target); - } - }.bind(self)); - - return input.pristine = { input: input, validators: fns, params: params, messages: messages, self: self }; - }.bind(self)); - } + fns.sort(function (a, b) { + return b.priority - a.priority; + }); - function _addValidatorToField(fns, params, name, value) { - var validator = validators[name]; - if (validator) { - fns.push(validator); - if (value) { - var valueParams = name === "pattern" ? [value] : value.split(','); - valueParams.unshift(null); // placeholder for input's value - params[name] = valueParams; - } + var listener = function (e) { + if (self.config.liveAfterFirstValitation && wasValidated) { + self.validate(e.target); + } else if (!self.config.liveAfterFirstValitation) { + self.validate(e.target); } - } + }.bind(self); - /*** - * Checks whether the form/input elements are valid - * @param input => input element(s) or a jquery selector, null for full form validation - * @param silent => do not show error messages, just return true/false - * @returns {boolean} return true when valid false otherwise - */ - self.validate = function () { - var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - var silent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - var fields = self.fields; - if (input) { - if (input instanceof HTMLElement) { - fields = [input.pristine]; - } else if (input instanceof NodeList || input instanceof (window.$ || Array) || input instanceof Array) { - fields = Array.from(input).map(function (el) { - return el.pristine; - }); - } - } else { - wasValidated = true; + if (self.live) { + input.addEventListener('change', listener); + if (!~['radio', 'checkbox'].indexOf(input.getAttribute('type'))) { + input.addEventListener('inllut', listener); } + } + + return input.pristine = { + input: input, + validators: fns, + params: params, + messages: messages, + self: self + }; + }.bind(self)); + } + + function _addValidatorToField(fns, params, name, value) { + var validator = validators[name]; + if (validator) { + fns.push(validator); + if (value) { + var valueParams = name === 'pattern' ? [value] : value.split(','); + valueParams.unshift(null); // placeholder for input's value + params[name] = valueParams; + } + } + } + + /*** + * Checks whether the form/input elements are valid + * @param input => input element(s) or a jquery selector, null for full form validation + * @param silent => do not show error messages, just return true/false + * @returns {boolean} return true when valid false otherwise + */ + self.validate = function () { + var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var silent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var fields = self.fields; + if (input) { + if (input instanceof HTMLElement) { + fields = [input.pristine]; + } else if (input instanceof NodeList || input instanceof (window.$ || Array) || input instanceof Array) { + fields = Array.from(input).map(function (el) { + return el.pristine; + }); + } + } else { + wasValidated = true; + } - var valid = true; + var valid = true; - for (var i = 0; fields[i]; i++) { - var field = fields[i]; - if (_validateField(field)) { - !silent && _showSuccess(field); - } else { - valid = false; - !silent && _showError(field); - } - } - return valid; - }; - - /*** - * Get errors of a specific field or the whole form - * @param input - * @returns {Array|*} - */ - self.getErrors = function (input) { - if (!input) { - var erroneousFields = []; - for (var i = 0; i < self.fields.length; i++) { - var field = self.fields[i]; - if (field.errors.length) { - erroneousFields.push({ input: field.input, errors: field.errors }); - } - } - return erroneousFields; - } - if (input.tagName && input.tagName.toLowerCase() === "select") { - return input.pristine.errors; - } - return input.length ? input[0].pristine.errors : input.pristine.errors; - }; - - /*** - * Validates a single field, all validator functions are called and error messages are generated - * when a validator fails - * @param field - * @returns {boolean} - * @private - */ - function _validateField(field) { - var errors = []; - var valid = true; - for (var i = 0; field.validators[i]; i++) { - var validator = field.validators[i]; - var params = field.params[validator.name] ? field.params[validator.name] : []; - params[0] = field.input.value; - if (!validator.fn.apply(field.input, params)) { - valid = false; - - if (typeof validator.msg === "function") { - errors.push(validator.msg(field.input.value, params)); - } else if (typeof validator.msg === "string") { - errors.push(tmpl.apply(validator.msg, params)); - } else if (validator.msg === Object(validator.msg) && validator.msg[currentLocale]) { - // typeof generates unnecessary babel code - errors.push(tmpl.apply(validator.msg[currentLocale], params)); - } else if (field.messages[currentLocale] && field.messages[currentLocale][validator.name]) { - errors.push(tmpl.apply(field.messages[currentLocale][validator.name], params)); - } else if (lang[currentLocale] && lang[currentLocale][validator.name]) { - errors.push(tmpl.apply(lang[currentLocale][validator.name], params)); - } else { - errors.push(tmpl.apply(lang[currentLocale].default, params)); - } - - if (validator.halt === true) { - break; - } - } - } - field.errors = errors; - return valid; + for (var i = 0; fields[i]; i++) { + var field = fields[i]; + if (_validateField(field)) { + !silent && _showSuccess(field); + } else { + valid = false; + !silent && _showError(field); + } } - - /*** - * Add a validator to a specific dom element in a form - * @param elem => The dom element where the validator is applied to - * @param fn => validator function - * @param msg => message to show when validation fails. Supports templating. ${0} for the input's value, ${1} and - * so on are for the attribute values - * @param priority => priority of the validator function, higher valued function gets called first. - * @param halt => whether validation should stop for this field after current validation function - */ - self.addValidator = function (elem, fn, msg, priority, halt) { - if (elem instanceof HTMLElement) { - elem.pristine.validators.push({ fn: fn, msg: msg, priority: priority, halt: halt }); - elem.pristine.validators.sort(function (a, b) { - return b.priority - a.priority; - }); - } else { - console.warn("The parameter elem must be a dom element"); + return valid; + }; + + /*** + * Get errors of a specific field or the whole form + * @param input + * @returns {Array|*} + */ + self.getErrors = function (input) { + if (!input) { + var erroneousFields = []; + for (var i = 0; i < self.fields.length; i++) { + var field = self.fields[i]; + if (field.errors.length) { + erroneousFields.push({ input: field.input, errors: field.errors }); } - }; - - /*** - * An utility function that returns a 2-element array, first one is the element where error/success class is - * applied. 2nd one is the element where error message is displayed. 2nd element is created if doesn't exist and cached. - * @param field - * @returns {*} - * @private - */ - function _getErrorElements(field) { - if (field.errorElements) { - return field.errorElements; - } - var errorClassElement = findAncestor(field.input, self.config.classTo); - var errorTextParent = null, - errorTextElement = null; - if (self.config.classTo === self.config.errorTextParent) { - errorTextParent = errorClassElement; + } + return erroneousFields; + } + if (input.tagName && input.tagName.toLowerCase() === 'select') { + return input.pristine.errors; + } + return input.length ? input[0].pristine.errors : input.pristine.errors; + }; + + /*** + * Validates a single field, all validator functions are called and error messages are generated + * when a validator fails + * @param field + * @returns {boolean} + * @private + */ + function _validateField(field) { + var errors = []; + var valid = true; + for (var i = 0; field.validators[i]; i++) { + var validator = field.validators[i]; + var params = field.params[validator.name] ? field.params[validator.name] : []; + params[0] = field.input.value; + if (!validator.fn.apply(field.input, params)) { + valid = false; + + if (typeof validator.msg === 'function') { + errors.push(validator.msg(field.input.value, params)); + } else if (typeof validator.msg === 'string') { + errors.push(tmpl.apply(validator.msg, params)); + } else if (validator.msg === Object(validator.msg) && validator.msg[currentLocale]) { + // typeof generates unnecessary babel code + errors.push(tmpl.apply(validator.msg[currentLocale], params)); + } else if (field.messages[currentLocale] && field.messages[currentLocale][validator.name]) { + errors.push(tmpl.apply(field.messages[currentLocale][validator.name], params)); + } else if (lang[currentLocale] && lang[currentLocale][validator.name]) { + errors.push(tmpl.apply(lang[currentLocale][validator.name], params)); } else { - errorTextParent = errorClassElement.querySelector('.' + self.config.errorTextParent); + errors.push(tmpl.apply(lang[currentLocale].default, params)); } - if (errorTextParent) { - errorTextElement = errorTextParent.querySelector('.' + PRISTINE_ERROR); - if (!errorTextElement) { - errorTextElement = document.createElement(self.config.errorTextTag); - errorTextElement.className = PRISTINE_ERROR + ' ' + self.config.errorTextClass; - errorTextParent.appendChild(errorTextElement); - errorTextElement.pristineDisplay = errorTextElement.style.display; - } + + if (validator.halt === true) { + break; } - return field.errorElements = [errorClassElement, errorTextElement]; + } + } + field.errors = errors; + return valid; + } + + /*** + * Add a validator to a specific dom element in a form + * @param elem => The dom element where the validator is applied to + * @param fn => validator function + * @param msg => message to show when validation fails. Supports templating. ${0} for the input's value, ${1} and + * so on are for the attribute values + * @param priority => priority of the validator function, higher valued function gets called first. + * @param halt => whether validation should stop for this field after current validation function + */ + self.addValidator = function (elem, fn, msg, priority, halt) { + if (elem instanceof HTMLElement) { + elem.pristine.validators.push({ fn: fn, msg: msg, priority: priority, halt: halt }); + elem.pristine.validators.sort(function (a, b) { + return b.priority - a.priority; + }); + } else { + console.warn('The parameter elem must be a dom element'); + } + }; + + /*** + * An utility function that returns a 2-element array, first one is the element where error/success class is + * applied. 2nd one is the element where error message is displayed. 2nd element is created if doesn't exist and cached. + * @param field + * @returns {*} + * @private + */ + function _getErrorElements(field) { + if (field.errorElements) { + return field.errorElements; } + var errorClassElement = findAncestor(field.input, self.config.classTo); + var errorTextParent = null, + errorTextElement = null; + if (self.config.classTo === self.config.errorTextParent) { + errorTextParent = errorClassElement; + } else { + errorTextParent = errorClassElement.querySelector('.' + self.config.errorTextParent); + } + if (errorTextParent) { + errorTextElement = errorTextParent.querySelector('.' + PRISTINE_ERROR); + if (!errorTextElement) { + errorTextElement = document.createElement(self.config.errorTextTag); + errorTextElement.className = PRISTINE_ERROR + ' ' + self.config.errorTextClass; + errorTextParent.appendChild(errorTextElement); + errorTextElement.pristineDisplay = errorTextElement.style.display; + } + } + return field.errorElements = [errorClassElement, errorTextElement]; + } - function _showError(field) { - var errorElements = _getErrorElements(field); - var errorClassElement = errorElements[0], - errorTextElement = errorElements[1]; + function _showError(field) { + var errorElements = _getErrorElements(field); + var errorClassElement = errorElements[0], + errorTextElement = errorElements[1]; - if (errorClassElement) { - errorClassElement.classList.remove(self.config.successClass); - errorClassElement.classList.add(self.config.errorClass); - } - if (errorTextElement) { - errorTextElement.innerHTML = field.errors.join('
'); - errorTextElement.style.display = errorTextElement.pristineDisplay || ''; - } + if (errorClassElement) { + errorClassElement.classList.remove(self.config.successClass); + errorClassElement.classList.add(self.config.errorClass); } - - /*** - * Adds error to a specific field - * @param input - * @param error - */ - self.addError = function (input, error) { - input = input.length ? input[0] : input; - input.pristine.errors.push(error); - _showError(input.pristine); - }; - - function _removeError(field) { - var errorElements = _getErrorElements(field); - var errorClassElement = errorElements[0], - errorTextElement = errorElements[1]; - if (errorClassElement) { - // IE > 9 doesn't support multiple class removal - errorClassElement.classList.remove(self.config.errorClass); - errorClassElement.classList.remove(self.config.successClass); - } - if (errorTextElement) { - errorTextElement.innerHTML = ''; - errorTextElement.style.display = 'none'; - } - return errorElements; + if (errorTextElement) { + errorTextElement.innerHTML = field.errors.join('
'); + errorTextElement.style.display = errorTextElement.pristineDisplay || ''; } - - function _showSuccess(field) { - var errorClassElement = _removeError(field)[0]; - errorClassElement && errorClassElement.classList.add(self.config.successClass); + } + + /*** + * Adds error to a specific field + * @param input + * @param error + */ + self.addError = function (input, error) { + input = input.length ? input[0] : input; + input.pristine.errors.push(error); + _showError(input.pristine); + }; + + function _removeError(field) { + var errorElements = _getErrorElements(field); + var errorClassElement = errorElements[0], + errorTextElement = errorElements[1]; + if (errorClassElement) { + // IE > 9 doesn't support multiple class removal + errorClassElement.classList.remove(self.config.errorClass); + errorClassElement.classList.remove(self.config.successClass); } + if (errorTextElement) { + errorTextElement.innerHTML = ''; + errorTextElement.style.display = 'none'; + } + return errorElements; + } + + function _showSuccess(field) { + var errorClassElement = _removeError(field)[0]; + errorClassElement && errorClassElement.classList.add(self.config.successClass); + } + + /*** + * Resets the errors + */ + self.reset = function () { + for (var i = 0; self.fields[i]; i++) { + self.fields[i].errorElements = null; + } + Array.from(self.form.querySelectorAll('.' + PRISTINE_ERROR)).map(function (elem) { + elem.parentNode.removeChild(elem); + }); + Array.from(self.form.querySelectorAll('.' + self.config.classTo)).map(function (elem) { + elem.classList.remove(self.config.successClass); + elem.classList.remove(self.config.errorClass); + }); + }; + + /*** + * Resets the errors and deletes all pristine fields + */ + self.destroy = function () { + self.reset(); + self.fields.forEach(function (field) { + delete field.input.pristine; + }); + self.fields = []; + }; - /*** - * Resets the errors - */ - self.reset = function () { - for (var i = 0; self.fields[i]; i++) { - self.fields[i].errorElements = null; - } - Array.from(self.form.querySelectorAll('.' + PRISTINE_ERROR)).map(function (elem) { - elem.parentNode.removeChild(elem); - }); - Array.from(self.form.querySelectorAll('.' + self.config.classTo)).map(function (elem) { - elem.classList.remove(self.config.successClass); - elem.classList.remove(self.config.errorClass); - }); - }; - - /*** - * Resets the errors and deletes all pristine fields - */ - self.destroy = function () { - self.reset(); - self.fields.forEach(function (field) { - delete field.input.pristine; - }); - self.fields = []; - }; - - self.setGlobalConfig = function (config) { - defaultConfig = config; - }; + self.setGlobalConfig = function (config) { + defaultConfig = config; + }; - return self; + return self; } /*** @@ -416,21 +440,21 @@ * @param halt => whether validation should stop for this field after current validation function */ Pristine.addValidator = function (name, fn, msg, priority, halt) { - _(name, { fn: fn, msg: msg, priority: priority, halt: halt }); + _(name, { fn: fn, msg: msg, priority: priority, halt: halt }); }; Pristine.addMessages = function (locale, messages) { - var langObj = lang.hasOwnProperty(locale) ? lang[locale] : lang[locale] = {}; + var langObj = lang.hasOwnProperty(locale) ? lang[locale] : lang[locale] = {}; - Object.keys(messages).forEach(function (key, index) { - langObj[key] = messages[key]; - }); + Object.keys(messages).forEach(function (key, index) { + langObj[key] = messages[key]; + }); }; Pristine.setLocale = function (locale) { - currentLocale = locale; + currentLocale = locale; }; return Pristine; -}))); +})); diff --git a/dist/pristine.min.js b/dist/pristine.min.js index 2a88061..aba3517 100644 --- a/dist/pristine.min.js +++ b/dist/pristine.min.js @@ -1 +1 @@ -!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).Pristine=r()}(this,(function(){"use strict";var e={en:{required:"This field is required",email:"This field requires a valid e-mail address",number:"This field requires a number",integer:"This field requires an integer value",url:"This field requires a valid website URL",tel:"This field requires a valid telephone number",maxlength:"This fields length must be < ${1}",minlength:"This fields length must be > ${1}",min:"Minimum value for this field is ${1}",max:"Maximum value for this field is ${1}",pattern:"Please match the requested format",equals:"The two fields do not match",default:"Please enter a correct value"}};function r(e){var r=arguments;return this.replace(/\${([^{}]*)}/g,(function(e,t){return r[t]}))}function t(e){return e.pristine.self.form.querySelectorAll('input[name="'+e.getAttribute("name")+'"]:checked').length}var n={classTo:"form-group",errorClass:"has-danger",successClass:"has-success",errorTextParent:"form-group",errorTextTag:"div",errorTextClass:"text-help",liveAfterFirstValitation:!0},i=["required","min","max","minlength","maxlength","pattern"],s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,a=/-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/,o="en",l={},u=function(e,r){r.name=e,void 0===r.priority&&(r.priority=1),l[e]=r};function f(t,s,u){var f=this,c=!1;function p(e,r,t,n){var i=l[t];if(i&&(e.push(i),n)){var s="pattern"===t?[n]:n.split(",");s.unshift(null),r[t]=s}}function m(t){for(var n=[],i=!0,s=0;t.validators[s];s++){var a=t.validators[s],l=t.params[a.name]?t.params[a.name]:[];if(l[0]=t.input.value,!a.fn.apply(t.input,l)&&(i=!1,"function"==typeof a.msg?n.push(a.msg(t.input.value,l)):"string"==typeof a.msg?n.push(r.apply(a.msg,l)):a.msg===Object(a.msg)&&a.msg[o]?n.push(r.apply(a.msg[o],l)):t.messages[o]&&t.messages[o][a.name]?n.push(r.apply(t.messages[o][a.name],l)):e[o]&&e[o][a.name]?n.push(r.apply(e[o][a.name],l)):n.push(r.apply(e[o].default,l)),!0===a.halt))break}return t.errors=n,i}function d(e){if(e.errorElements)return e.errorElements;var r=function(e,r){for(;(e=e.parentElement)&&!e.classList.contains(r););return e}(e.input,f.config.classTo),t=null,n=null;return(t=f.config.classTo===f.config.errorTextParent?r:r.querySelector("."+f.config.errorTextParent))&&((n=t.querySelector(".pristine-error"))||((n=document.createElement(f.config.errorTextTag)).className="pristine-error "+f.config.errorTextClass,t.appendChild(n),n.pristineDisplay=n.style.display)),e.errorElements=[r,n]}function h(e){var r=d(e),t=r[0],n=r[1];t&&(t.classList.remove(f.config.successClass),t.classList.add(f.config.errorClass)),n&&(n.innerHTML=e.errors.join("
"),n.style.display=n.pristineDisplay||"")}function g(e){var r=function(e){var r=d(e),t=r[0],n=r[1];return t&&(t.classList.remove(f.config.errorClass),t.classList.remove(f.config.successClass)),n&&(n.innerHTML="",n.style.display="none"),r}(e)[0];r&&r.classList.add(f.config.successClass)}return function(e,r,t){e.setAttribute("novalidate","true"),f.form=e,f.config=function(e,r){for(var t in r)t in e||(e[t]=r[t]);return e}(r||{},n),f.live=!(!1===t),f.fields=Array.from(e.querySelectorAll("input:not([disabled]):not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea")).map(function(e){var r=[],t={},n={};return[].forEach.call(e.attributes,(function(e){if(/^data-pristine-/.test(e.name)){var s=e.name.substr(14),o=s.match(a);if(null!==o){var l=void 0===o[1]?"en":o[1];return n.hasOwnProperty(l)||(n[l]={}),void(n[l][s.slice(0,s.length-o[0].length)]=e.value)}"type"===s&&(s=e.value),p(r,t,s,e.value)}else~i.indexOf(e.name)?p(r,t,e.name,e.value):"type"===e.name&&p(r,t,e.value)})),r.sort((function(e,r){return r.priority-e.priority})),f.live&&e.addEventListener("change",function(e){f.config.liveAfterFirstValitation&&c?f.validate(e.target):f.config.liveAfterFirstValitation||f.validate(e.target)}.bind(f)),e.pristine={input:e,validators:r,params:t,messages:n,self:f}}.bind(f))}(t,s,u),f.validate=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1],t=f.fields;e?e instanceof HTMLElement?t=[e.pristine]:(e instanceof NodeList||e instanceof(window.$||Array)||e instanceof Array)&&(t=Array.from(e).map((function(e){return e.pristine}))):c=!0;for(var n=!0,i=0;t[i];i++){var s=t[i];m(s)?!r&&g(s):(n=!1,!r&&h(s))}return n},f.getErrors=function(e){if(!e){for(var r=[],t=0;t=parseInt(r)}}),u("maxlength",{fn:function(e,r){return!e||e.length<=parseInt(r)}}),u("min",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)>=parseInt(r):parseFloat(e)>=parseFloat(r))}}),u("max",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)<=parseInt(r):parseFloat(e)<=parseFloat(r))}}),u("pattern",{fn:function(e,r){var t=r.match(new RegExp("^/(.*?)/([gimy]*)$"));return!e||new RegExp(t[1],t[2]).test(e)}}),u("equals",{fn:function(e,r){var t=document.querySelector(r);return t&&(!e&&!t.value||t.value===e)}}),f.addValidator=function(e,r,t,n,i){u(e,{fn:r,msg:t,priority:n,halt:i})},f.addMessages=function(r,t){var n=e.hasOwnProperty(r)?e[r]:e[r]={};Object.keys(t).forEach((function(e,r){n[e]=t[e]}))},f.setLocale=function(e){o=e},f})); +!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).Pristine=r()}(this,(function(){"use strict";var e={en:{required:"This field is required",email:"This field requires a valid e-mail address",number:"This field requires a number",integer:"This field requires an integer value",url:"This field requires a valid website URL",tel:"This field requires a valid telephone number",maxlength:"This fields length must be < ${1}",minlength:"This fields length must be > ${1}",min:"Minimum value for this field is ${1}",max:"Maximum value for this field is ${1}",pattern:"Please match the requested format",equals:"The two fields do not match",default:"Please enter a correct value"}};function r(e){var r=arguments;return this.replace(/\${([^{}]*)}/g,(function(e,t){return r[t]}))}function t(e){return e.pristine.self.form.querySelectorAll('input[name="'+e.getAttribute("name")+'"]:checked').length}var n={classTo:"form-group",errorClass:"has-danger",successClass:"has-success",errorTextParent:"form-group",errorTextTag:"div",errorTextClass:"text-help",liveAfterFirstValitation:!0},i=["required","min","max","minlength","maxlength","pattern"],s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,a=/-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/,o="en",l={},u=function(e,r){r.name=e,void 0===r.priority&&(r.priority=1),l[e]=r};function f(t,s,u){var f=this,c=!1;function p(e,r,t,n){var i=l[t];if(i&&(e.push(i),n)){var s="pattern"===t?[n]:n.split(",");s.unshift(null),r[t]=s}}function m(t){for(var n=[],i=!0,s=0;t.validators[s];s++){var a=t.validators[s],l=t.params[a.name]?t.params[a.name]:[];if(l[0]=t.input.value,!a.fn.apply(t.input,l)&&(i=!1,"function"==typeof a.msg?n.push(a.msg(t.input.value,l)):"string"==typeof a.msg?n.push(r.apply(a.msg,l)):a.msg===Object(a.msg)&&a.msg[o]?n.push(r.apply(a.msg[o],l)):t.messages[o]&&t.messages[o][a.name]?n.push(r.apply(t.messages[o][a.name],l)):e[o]&&e[o][a.name]?n.push(r.apply(e[o][a.name],l)):n.push(r.apply(e[o].default,l)),!0===a.halt))break}return t.errors=n,i}function d(e){if(e.errorElements)return e.errorElements;var r=function(e,r){for(;(e=e.parentElement)&&!e.classList.contains(r););return e}(e.input,f.config.classTo),t=null,n=null;return(t=f.config.classTo===f.config.errorTextParent?r:r.querySelector("."+f.config.errorTextParent))&&((n=t.querySelector(".pristine-error"))||((n=document.createElement(f.config.errorTextTag)).className="pristine-error "+f.config.errorTextClass,t.appendChild(n),n.pristineDisplay=n.style.display)),e.errorElements=[r,n]}function h(e){var r=d(e),t=r[0],n=r[1];t&&(t.classList.remove(f.config.successClass),t.classList.add(f.config.errorClass)),n&&(n.innerHTML=e.errors.join("
"),n.style.display=n.pristineDisplay||"")}function g(e){var r=function(e){var r=d(e),t=r[0],n=r[1];return t&&(t.classList.remove(f.config.errorClass),t.classList.remove(f.config.successClass)),n&&(n.innerHTML="",n.style.display="none"),r}(e)[0];r&&r.classList.add(f.config.successClass)}return function(e,r,t){e.setAttribute("novalidate","true"),f.form=e,f.config=function(e,r){for(var t in r)t in e||(e[t]=r[t]);return e}(r||{},n),f.live=!(!1===t),f.fields=Array.from(e.querySelectorAll("input:not([disabled]):not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea")).map(function(e){var r=[],t={},n={};[].forEach.call(e.attributes,(function(e){if(/^data-pristine-/.test(e.name)){var s=e.name.substr(14),o=s.match(a);if(null!==o){var l=void 0===o[1]?"en":o[1];return n.hasOwnProperty(l)||(n[l]={}),void(n[l][s.slice(0,s.length-o[0].length)]=e.value)}"type"===s&&(s=e.value),p(r,t,s,e.value)}else~i.indexOf(e.name)?p(r,t,e.name,e.value):"type"===e.name&&p(r,t,e.value)})),r.sort((function(e,r){return r.priority-e.priority}));var s=function(e){f.config.liveAfterFirstValitation&&c?f.validate(e.target):f.config.liveAfterFirstValitation||f.validate(e.target)}.bind(f);return f.live&&(e.addEventListener("change",s),~["radio","checkbox"].indexOf(e.getAttribute("type"))||e.addEventListener("inllut",s)),e.pristine={input:e,validators:r,params:t,messages:n,self:f}}.bind(f))}(t,s,u),f.validate=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1],t=f.fields;e?e instanceof HTMLElement?t=[e.pristine]:(e instanceof NodeList||e instanceof(window.$||Array)||e instanceof Array)&&(t=Array.from(e).map((function(e){return e.pristine}))):c=!0;for(var n=!0,i=0;t[i];i++){var s=t[i];m(s)?!r&&g(s):(n=!1,!r&&h(s))}return n},f.getErrors=function(e){if(!e){for(var r=[],t=0;t=parseInt(r)}}),u("maxlength",{fn:function(e,r){return!e||e.length<=parseInt(r)}}),u("min",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)>=parseInt(r):parseFloat(e)>=parseFloat(r))}}),u("max",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)<=parseInt(r):parseFloat(e)<=parseFloat(r))}}),u("pattern",{fn:function(e,r){var t=r.match(new RegExp("^/(.*?)/([gimy]*)$"));return!e||new RegExp(t[1],t[2]).test(e)}}),u("equals",{fn:function(e,r){var t=document.querySelector(r);return t&&(!e&&!t.value||t.value===e)}}),f.addValidator=function(e,r,t,n,i){u(e,{fn:r,msg:t,priority:n,halt:i})},f.addMessages=function(r,t){var n=e.hasOwnProperty(r)?e[r]:e[r]={};Object.keys(t).forEach((function(e,r){n[e]=t[e]}))},f.setLocale=function(e){o=e},f})); diff --git a/src/pristine.js b/src/pristine.js index 24196fc..dc82684 100755 --- a/src/pristine.js +++ b/src/pristine.js @@ -2,331 +2,411 @@ import { lang } from './lang'; import { tmpl, findAncestor, groupedElemCount, mergeConfig } from './utils'; let defaultConfig = { - classTo: 'form-group', - errorClass: 'has-danger', - successClass: 'has-success', - errorTextParent: 'form-group', - errorTextTag: 'div', - errorTextClass: 'text-help', - liveAfterFirstValitation: true, + classTo: 'form-group', + errorClass: 'has-danger', + successClass: 'has-success', + errorTextParent: 'form-group', + errorTextTag: 'div', + errorTextClass: 'text-help', + liveAfterFirstValitation: true, }; const PRISTINE_ERROR = 'pristine-error'; -const SELECTOR = "input:not([disabled]):not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea"; -const ALLOWED_ATTRIBUTES = ["required", "min", "max", 'minlength', 'maxlength', 'pattern']; -const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ +const SELECTOR = + 'input:not([disabled]):not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea'; +const ALLOWED_ATTRIBUTES = [ + 'required', + 'min', + 'max', + 'minlength', + 'maxlength', + 'pattern', +]; +const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; const MESSAGE_REGEX = /-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/; // matches, -message, -message-en, -message-en_US let currentLocale = 'en'; const validators = {}; const _ = function (name, validator) { - validator.name = name; - if (validator.priority === undefined) - validator.priority = 1; - validators[name] = validator; + validator.name = name; + if (validator.priority === undefined) validator.priority = 1; + validators[name] = validator; }; -_('text', { fn: (val) => true, priority: 0}); -_('required', { fn: function(val){ return (this.type === 'radio' || this.type === 'checkbox') ? groupedElemCount(this) : val !== undefined && val !== ''}, priority: 99, halt: true}); -_('email', { fn: (val) => !val || EMAIL_REGEX.test(val)}); +_('text', { fn: (val) => true, priority: 0 }); +_('required', { + fn: function (val) { + return this.type === 'radio' || this.type === 'checkbox' + ? groupedElemCount(this) + : val !== undefined && val !== ''; + }, + priority: 99, + halt: true, +}); +_('email', { fn: (val) => !val || EMAIL_REGEX.test(val) }); _('number', { fn: (val) => !val || !isNaN(parseFloat(val)), priority: 2 }); _('integer', { fn: (val) => !val || /^\d+$/.test(val) }); _('minlength', { fn: (val, length) => !val || val.length >= parseInt(length) }); _('maxlength', { fn: (val, length) => !val || val.length <= parseInt(length) }); -_('min', { fn: function(val, limit){ return !val || (this.type === 'checkbox' ? groupedElemCount(this) >= parseInt(limit) : parseFloat(val) >= parseFloat(limit)); } }); -_('max', { fn: function(val, limit){ return !val || (this.type === 'checkbox' ? groupedElemCount(this) <= parseInt(limit) : parseFloat(val) <= parseFloat(limit)); } }); -_('pattern', { fn: (val, pattern) => { let m = pattern.match(new RegExp('^/(.*?)/([gimy]*)$')); return !val || (new RegExp(m[1], m[2])).test(val);} }); -_('equals', { fn: (val, otherFieldSelector) => { let other = document.querySelector(otherFieldSelector); return (other) && ((!val && !other.value) || (other.value === val)); } }); - -export default function Pristine(form, config, live){ - - let self = this; - let wasValidated = false; - - init(form, config, live); - - function init(form, config, live){ - - form.setAttribute("novalidate", "true"); - - self.form = form; - self.config = mergeConfig(config || {}, defaultConfig); - self.live = !(live === false); - self.fields = Array.from(form.querySelectorAll(SELECTOR)).map(function (input) { - - let fns = []; - let params = {}; - let messages = {}; - - [].forEach.call(input.attributes, function (attr) { - if (/^data-pristine-/.test(attr.name)) { - let name = attr.name.substr(14); - let messageMatch = name.match(MESSAGE_REGEX); - if (messageMatch !== null){ - let locale = messageMatch[1] === undefined ? 'en' : messageMatch[1]; - if (!messages.hasOwnProperty(locale)) - messages[locale] = {}; - messages[locale][name.slice(0, name.length - messageMatch[0].length)] = attr.value; - return; - } - if (name === 'type') name = attr.value; - _addValidatorToField(fns, params, name, attr.value); - } else if (~ALLOWED_ATTRIBUTES.indexOf(attr.name)){ - _addValidatorToField(fns, params, attr.name, attr.value); - } else if (attr.name === 'type'){ - _addValidatorToField(fns, params, attr.value); - } - }); - - fns.sort( (a, b) => b.priority - a.priority); - - self.live && input.addEventListener('change', function(e) { - if (self.config.liveAfterFirstValitation && wasValidated) { - self.validate(e.target); - } else if (!self.config.liveAfterFirstValitation) { - self.validate(e.target); - } - }.bind(self)); - - return input.pristine = {input, validators: fns, params, messages, self}; - - }.bind(self)); - } - - function _addValidatorToField(fns, params, name, value) { - let validator = validators[name]; - if (validator) { - fns.push(validator); - if (value) { - let valueParams = (name === "pattern" ? [value]: value.split(',')); - valueParams.unshift(null); // placeholder for input's value - params[name] = valueParams; +_('min', { + fn: function (val, limit) { + return ( + !val || + (this.type === 'checkbox' + ? groupedElemCount(this) >= parseInt(limit) + : parseFloat(val) >= parseFloat(limit)) + ); + }, +}); +_('max', { + fn: function (val, limit) { + return ( + !val || + (this.type === 'checkbox' + ? groupedElemCount(this) <= parseInt(limit) + : parseFloat(val) <= parseFloat(limit)) + ); + }, +}); +_('pattern', { + fn: (val, pattern) => { + let m = pattern.match(new RegExp('^/(.*?)/([gimy]*)$')); + return !val || new RegExp(m[1], m[2]).test(val); + }, +}); +_('equals', { + fn: (val, otherFieldSelector) => { + let other = document.querySelector(otherFieldSelector); + return other && ((!val && !other.value) || other.value === val); + }, +}); + +export default function Pristine(form, config, live) { + let self = this; + let wasValidated = false; + + init(form, config, live); + + function init(form, config, live) { + form.setAttribute('novalidate', 'true'); + + self.form = form; + self.config = mergeConfig(config || {}, defaultConfig); + self.live = !(live === false); + self.fields = Array.from(form.querySelectorAll(SELECTOR)).map( + function (input) { + let fns = []; + let params = {}; + let messages = {}; + + [].forEach.call(input.attributes, function (attr) { + if (/^data-pristine-/.test(attr.name)) { + let name = attr.name.substr(14); + let messageMatch = name.match(MESSAGE_REGEX); + if (messageMatch !== null) { + let locale = + messageMatch[1] === undefined ? 'en' : messageMatch[1]; + if (!messages.hasOwnProperty(locale)) messages[locale] = {}; + messages[locale][ + name.slice(0, name.length - messageMatch[0].length) + ] = attr.value; + return; } - } - } + if (name === 'type') name = attr.value; + _addValidatorToField(fns, params, name, attr.value); + } else if (~ALLOWED_ATTRIBUTES.indexOf(attr.name)) { + _addValidatorToField(fns, params, attr.name, attr.value); + } else if (attr.name === 'type') { + _addValidatorToField(fns, params, attr.value); + } + }); - /*** - * Checks whether the form/input elements are valid - * @param input => input element(s) or a jquery selector, null for full form validation - * @param silent => do not show error messages, just return true/false - * @returns {boolean} return true when valid false otherwise - */ - self.validate = function(input = null, silent = false){ - let fields = self.fields; - if (input){ - if (input instanceof HTMLElement) { - fields = [input.pristine]; - } else if (input instanceof NodeList || input instanceof (window.$ || Array) || input instanceof Array){ - fields = Array.from(input).map(el => el.pristine); - } - } else { - wasValidated = true; + fns.sort((a, b) => b.priority - a.priority); + + const listener = function (e) { + if (self.config.liveAfterFirstValitation && wasValidated) { + self.validate(e.target); + } else if (!self.config.liveAfterFirstValitation) { + self.validate(e.target); + } + }.bind(self); + + if (self.live) { + input.addEventListener('change', listener); + if (!~['radio', 'checkbox'].indexOf(input.getAttribute('type'))) { + input.addEventListener('inllut', listener); + } } - let valid = true; - - for(let i = 0; fields[i]; i++) { - let field = fields[i]; - if (_validateField(field)){ - !silent && _showSuccess(field); - } else { - valid = false; - !silent && _showError(field); - } - } - return valid; - }; - - /*** - * Get errors of a specific field or the whole form - * @param input - * @returns {Array|*} - */ - self.getErrors = function(input) { - if (!input){ - let erroneousFields = []; - for(let i=0; i The dom element where the validator is applied to - * @param fn => validator function - * @param msg => message to show when validation fails. Supports templating. ${0} for the input's value, ${1} and - * so on are for the attribute values - * @param priority => priority of the validator function, higher valued function gets called first. - * @param halt => whether validation should stop for this field after current validation function - */ - self.addValidator = function(elem, fn, msg, priority, halt){ - if (elem instanceof HTMLElement){ - elem.pristine.validators.push({fn, msg, priority, halt}); - elem.pristine.validators.sort( (a, b) => b.priority - a.priority); - } else { - console.warn("The parameter elem must be a dom element"); - } - }; - - /*** - * An utility function that returns a 2-element array, first one is the element where error/success class is - * applied. 2nd one is the element where error message is displayed. 2nd element is created if doesn't exist and cached. - * @param field - * @returns {*} - * @private - */ - function _getErrorElements(field) { - if (field.errorElements){ - return field.errorElements; - } - let errorClassElement = findAncestor(field.input, self.config.classTo); - let errorTextParent = null, errorTextElement = null; - if (self.config.classTo === self.config.errorTextParent){ - errorTextParent = errorClassElement; - } else { - errorTextParent = errorClassElement.querySelector('.' + self.config.errorTextParent); - } - if (errorTextParent){ - errorTextElement = errorTextParent.querySelector('.' + PRISTINE_ERROR); - if (!errorTextElement){ - errorTextElement = document.createElement(self.config.errorTextTag); - errorTextElement.className = PRISTINE_ERROR + ' ' + self.config.errorTextClass; - errorTextParent.appendChild(errorTextElement); - errorTextElement.pristineDisplay = errorTextElement.style.display; - } - } - return field.errorElements = [errorClassElement, errorTextElement] + } + + /*** + * Checks whether the form/input elements are valid + * @param input => input element(s) or a jquery selector, null for full form validation + * @param silent => do not show error messages, just return true/false + * @returns {boolean} return true when valid false otherwise + */ + self.validate = function (input = null, silent = false) { + let fields = self.fields; + if (input) { + if (input instanceof HTMLElement) { + fields = [input.pristine]; + } else if ( + input instanceof NodeList || + input instanceof (window.$ || Array) || + input instanceof Array + ) { + fields = Array.from(input).map((el) => el.pristine); + } + } else { + wasValidated = true; } - function _showError(field){ - let errorElements = _getErrorElements(field); - let errorClassElement = errorElements[0], errorTextElement = errorElements[1]; + let valid = true; - if(errorClassElement){ - errorClassElement.classList.remove(self.config.successClass); - errorClassElement.classList.add(self.config.errorClass); - } - if (errorTextElement){ - errorTextElement.innerHTML = field.errors.join('
'); - errorTextElement.style.display = errorTextElement.pristineDisplay || ''; - } + for (let i = 0; fields[i]; i++) { + let field = fields[i]; + if (_validateField(field)) { + !silent && _showSuccess(field); + } else { + valid = false; + !silent && _showError(field); + } } - - /*** - * Adds error to a specific field - * @param input - * @param error - */ - self.addError = function(input, error) { - input = input.length ? input[0] : input; - input.pristine.errors.push(error); - _showError(input.pristine); - }; - - function _removeError(field){ - let errorElements = _getErrorElements(field); - let errorClassElement = errorElements[0], errorTextElement = errorElements[1]; - if (errorClassElement){ - // IE > 9 doesn't support multiple class removal - errorClassElement.classList.remove(self.config.errorClass); - errorClassElement.classList.remove(self.config.successClass); - } - if (errorTextElement){ - errorTextElement.innerHTML = ''; - errorTextElement.style.display = 'none'; + return valid; + }; + + /*** + * Get errors of a specific field or the whole form + * @param input + * @returns {Array|*} + */ + self.getErrors = function (input) { + if (!input) { + let erroneousFields = []; + for (let i = 0; i < self.fields.length; i++) { + let field = self.fields[i]; + if (field.errors.length) { + erroneousFields.push({ input: field.input, errors: field.errors }); } - return errorElements; + } + return erroneousFields; } - - function _showSuccess(field){ - let errorClassElement = _removeError(field)[0]; - errorClassElement && errorClassElement.classList.add(self.config.successClass); + if (input.tagName && input.tagName.toLowerCase() === 'select') { + return input.pristine.errors; } - - /*** - * Resets the errors - */ - self.reset = function () { - for(let i = 0; self.fields[i]; i++) { - self.fields[i].errorElements = null; + return input.length ? input[0].pristine.errors : input.pristine.errors; + }; + + /*** + * Validates a single field, all validator functions are called and error messages are generated + * when a validator fails + * @param field + * @returns {boolean} + * @private + */ + function _validateField(field) { + let errors = []; + let valid = true; + for (let i = 0; field.validators[i]; i++) { + let validator = field.validators[i]; + let params = field.params[validator.name] + ? field.params[validator.name] + : []; + params[0] = field.input.value; + if (!validator.fn.apply(field.input, params)) { + valid = false; + + if (typeof validator.msg === 'function') { + errors.push(validator.msg(field.input.value, params)); + } else if (typeof validator.msg === 'string') { + errors.push(tmpl.apply(validator.msg, params)); + } else if ( + validator.msg === Object(validator.msg) && + validator.msg[currentLocale] + ) { + // typeof generates unnecessary babel code + errors.push(tmpl.apply(validator.msg[currentLocale], params)); + } else if ( + field.messages[currentLocale] && + field.messages[currentLocale][validator.name] + ) { + errors.push( + tmpl.apply(field.messages[currentLocale][validator.name], params) + ); + } else if (lang[currentLocale] && lang[currentLocale][validator.name]) { + errors.push(tmpl.apply(lang[currentLocale][validator.name], params)); + } else { + errors.push(tmpl.apply(lang[currentLocale].default, params)); } - Array.from(self.form.querySelectorAll('.' + PRISTINE_ERROR)).map(function (elem) { - elem.parentNode.removeChild(elem); - }); - Array.from(self.form.querySelectorAll('.' + self.config.classTo)).map(function (elem) { - elem.classList.remove(self.config.successClass); - elem.classList.remove(self.config.errorClass); - }); - }; + if (validator.halt === true) { + break; + } + } + } + field.errors = errors; + return valid; + } + + /*** + * Add a validator to a specific dom element in a form + * @param elem => The dom element where the validator is applied to + * @param fn => validator function + * @param msg => message to show when validation fails. Supports templating. ${0} for the input's value, ${1} and + * so on are for the attribute values + * @param priority => priority of the validator function, higher valued function gets called first. + * @param halt => whether validation should stop for this field after current validation function + */ + self.addValidator = function (elem, fn, msg, priority, halt) { + if (elem instanceof HTMLElement) { + elem.pristine.validators.push({ fn, msg, priority, halt }); + elem.pristine.validators.sort((a, b) => b.priority - a.priority); + } else { + console.warn('The parameter elem must be a dom element'); + } + }; + + /*** + * An utility function that returns a 2-element array, first one is the element where error/success class is + * applied. 2nd one is the element where error message is displayed. 2nd element is created if doesn't exist and cached. + * @param field + * @returns {*} + * @private + */ + function _getErrorElements(field) { + if (field.errorElements) { + return field.errorElements; + } + let errorClassElement = findAncestor(field.input, self.config.classTo); + let errorTextParent = null, + errorTextElement = null; + if (self.config.classTo === self.config.errorTextParent) { + errorTextParent = errorClassElement; + } else { + errorTextParent = errorClassElement.querySelector( + '.' + self.config.errorTextParent + ); + } + if (errorTextParent) { + errorTextElement = errorTextParent.querySelector('.' + PRISTINE_ERROR); + if (!errorTextElement) { + errorTextElement = document.createElement(self.config.errorTextTag); + errorTextElement.className = + PRISTINE_ERROR + ' ' + self.config.errorTextClass; + errorTextParent.appendChild(errorTextElement); + errorTextElement.pristineDisplay = errorTextElement.style.display; + } + } + return (field.errorElements = [errorClassElement, errorTextElement]); + } - /*** - * Resets the errors and deletes all pristine fields - */ - self.destroy = function(){ - self.reset(); - self.fields.forEach(function (field) { - delete field.input.pristine; - }); - self.fields = []; - }; + function _showError(field) { + let errorElements = _getErrorElements(field); + let errorClassElement = errorElements[0], + errorTextElement = errorElements[1]; - self.setGlobalConfig = function (config) { - defaultConfig = config; - }; + if (errorClassElement) { + errorClassElement.classList.remove(self.config.successClass); + errorClassElement.classList.add(self.config.errorClass); + } + if (errorTextElement) { + errorTextElement.innerHTML = field.errors.join('
'); + errorTextElement.style.display = errorTextElement.pristineDisplay || ''; + } + } + + /*** + * Adds error to a specific field + * @param input + * @param error + */ + self.addError = function (input, error) { + input = input.length ? input[0] : input; + input.pristine.errors.push(error); + _showError(input.pristine); + }; + + function _removeError(field) { + let errorElements = _getErrorElements(field); + let errorClassElement = errorElements[0], + errorTextElement = errorElements[1]; + if (errorClassElement) { + // IE > 9 doesn't support multiple class removal + errorClassElement.classList.remove(self.config.errorClass); + errorClassElement.classList.remove(self.config.successClass); + } + if (errorTextElement) { + errorTextElement.innerHTML = ''; + errorTextElement.style.display = 'none'; + } + return errorElements; + } + + function _showSuccess(field) { + let errorClassElement = _removeError(field)[0]; + errorClassElement && + errorClassElement.classList.add(self.config.successClass); + } + + /*** + * Resets the errors + */ + self.reset = function () { + for (let i = 0; self.fields[i]; i++) { + self.fields[i].errorElements = null; + } + Array.from(self.form.querySelectorAll('.' + PRISTINE_ERROR)).map(function ( + elem + ) { + elem.parentNode.removeChild(elem); + }); + Array.from(self.form.querySelectorAll('.' + self.config.classTo)).map( + function (elem) { + elem.classList.remove(self.config.successClass); + elem.classList.remove(self.config.errorClass); + } + ); + }; + + /*** + * Resets the errors and deletes all pristine fields + */ + self.destroy = function () { + self.reset(); + self.fields.forEach(function (field) { + delete field.input.pristine; + }); + self.fields = []; + }; - return self; + self.setGlobalConfig = function (config) { + defaultConfig = config; + }; + return self; } /*** @@ -338,18 +418,20 @@ export default function Pristine(form, config, live){ * @param priority => priority of the validator function, higher valued function gets called first. * @param halt => whether validation should stop for this field after current validation function */ -Pristine.addValidator = function(name, fn, msg, priority, halt){ - _(name, {fn, msg, priority, halt}); +Pristine.addValidator = function (name, fn, msg, priority, halt) { + _(name, { fn, msg, priority, halt }); }; -Pristine.addMessages = function(locale, messages){ - let langObj = lang.hasOwnProperty(locale) ? lang[locale] : lang[locale] = {}; +Pristine.addMessages = function (locale, messages) { + let langObj = lang.hasOwnProperty(locale) + ? lang[locale] + : (lang[locale] = {}); - Object.keys(messages).forEach(function(key, index) { - langObj[key] = messages[key]; - }); -} + Object.keys(messages).forEach(function (key, index) { + langObj[key] = messages[key]; + }); +}; -Pristine.setLocale = function (locale){ - currentLocale = locale; -} +Pristine.setLocale = function (locale) { + currentLocale = locale; +}; diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..59e77be --- /dev/null +++ b/yarn.lock @@ -0,0 +1,1998 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" + integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== + dependencies: + "@babel/highlight" "^7.16.7" + +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + +"@babel/highlight@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.7.tgz#81a01d7d675046f0d96f82450d9d9578bdfd6b0b" + integrity sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@types/node@*": + version "17.0.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.8.tgz#50d680c8a8a78fe30abe6906453b21ad8ab0ad7b" + integrity sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg== + +accepts@~1.3.4: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" + integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== + +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-external-helpers@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-external-helpers/-/babel-plugin-external-helpers-6.22.0.tgz#2285f48b02bd5dede85175caf8c62e86adccefa1" + integrity sha1-IoX0iwK9Xe3oUXXK+MYuhq3M76E= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= + +babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM= + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg= + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4= + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-preset-env@^1.6.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" + integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^3.2.6" + invariant "^2.2.2" + semver "^5.3.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-arraybuffer@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" + integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= + +base64id@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +blob@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" + integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== + +body-parser@^1.19.0: + version "1.19.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4" + integrity sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA== + dependencies: + bytes "3.1.1" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.9.6" + raw-body "2.4.2" + type-is "~1.6.18" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^3.2.6: + version "3.2.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== + dependencies: + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bytes@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" + integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-lite@^1.0.30000844: + version "1.0.30001299" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001299.tgz#d753bf6444ed401eb503cbbe17aa3e1451b5a68c" + integrity sha512-iujN4+x7QzqA2NCSrS5VUy+4gLmRd4xv6vbBBsmfVqTx8bLAD8097euLqQgKxSVLvxjSDcvF1T/i9ocgnUFexw== + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chokidar@^3.3.1, chokidar@^3.4.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colors@^1.1.2, colors@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= + +component-emitter@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +component-emitter@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +connect@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.5.1: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + +cookie@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +core-js@^2.4.0, core-js@^2.5.0: + version "2.6.12" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= + +date-format@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.1.0.tgz#31d5b5ea211cf5fd764cd38baf9d033df7e125cf" + integrity sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA== + +date-format@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-3.0.0.tgz#eb8780365c7d2b1511078fb491e6479780f3ad95" + integrity sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w== + +debounce@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" + integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== + +debug@2.6.9, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^4.1.1: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= + dependencies: + repeating "^2.0.0" + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= + +dom-serialize@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs= + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +electron-to-chromium@^1.3.47: + version "1.4.43" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.43.tgz#665c0cd8d5e7cce0ba78d90a514c8c813ca3bdbe" + integrity sha512-PO3kEfcxPrti/4STbXvCkNIF4fgWvCKl2508e6UI7KomCDffpIfeBZLXsh5DK/XGsjUw3kwq6WEsi0MJTlGAdg== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +engine.io-client@~3.5.0: + version "3.5.2" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.5.2.tgz#0ef473621294004e9ceebe73cef0af9e36f2f5fa" + integrity sha512-QEqIp+gJ/kMHeUun7f5Vv3bteRHppHH/FMBQX/esFj/fuYfjyUKWGMo3VCvIP/V8bE9KcjHmRZrhIz2Z9oNsDA== + dependencies: + component-emitter "~1.3.0" + component-inherit "0.0.3" + debug "~3.1.0" + engine.io-parser "~2.2.0" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.6" + parseuri "0.0.6" + ws "~7.4.2" + xmlhttprequest-ssl "~1.6.2" + yeast "0.1.2" + +engine.io-parser@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.1.tgz#57ce5611d9370ee94f99641b589f94c97e4f5da7" + integrity sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.4" + blob "0.0.5" + has-binary2 "~1.0.2" + +engine.io@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.5.0.tgz#9d6b985c8a39b1fe87cd91eb014de0552259821b" + integrity sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA== + dependencies: + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + debug "~4.1.0" + engine.io-parser "~2.2.0" + ws "~7.4.2" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +estree-walker@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" + integrity sha1-va/oCVOD2EFNXcLs9MkXO225QS4= + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flatted@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== + +follow-redirects@^1.0.0: + version "1.14.7" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685" + integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ== + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.3, glob@^7.1.6: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + +graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" + integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== + dependencies: + isarray "2.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +http-errors@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= + +isbinaryfile@^4.0.6: + version "4.0.8" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.8.tgz#5d34b94865bd4946633ecc78a026fc76c5b11fcf" + integrity sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +jasmine-core@^3.6.0, jasmine-core@~3.99.0: + version "3.99.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.99.0.tgz#99a3da0d38ba2de82614d9198b7b1bc1c32a5960" + integrity sha512-+ZDaJlEfRopINQqgE+hvzRyDIQDeKfqqTvF8RzXsvU1yE3pBDRud2+Qfh9WvGgRpuzqxyQJVI6Amy5XQ11r/3w== + +jasmine@^3.6.1: + version "3.99.0" + resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-3.99.0.tgz#7cc7aeda7ade2d57694fc818a374f778cbb4ea62" + integrity sha512-YIThBuHzaIIcjxeuLmPD40SjxkEcc8i//sGMDKCgkRMVgIwRJf5qyExtlJpQeh7pkeoBSOe6lQEdg+/9uKg9mw== + dependencies: + glob "^7.1.6" + jasmine-core "~3.99.0" + +jest-worker@^26.2.1: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +karma-chrome-launcher@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz#805a586799a4d05f4e54f72a204979f3f3066738" + integrity sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg== + dependencies: + which "^1.2.1" + +karma-jasmine-html-reporter@^1.5.4: + version "1.7.0" + resolved "https://registry.yarnpkg.com/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.7.0.tgz#52c489a74d760934a1089bfa5ea4a8fcb84cc28b" + integrity sha512-pzum1TL7j90DTE86eFt48/s12hqwQuiD+e5aXx2Dc9wDEn2LfGq6RoAxEZZjFiN0RDSCOnosEKRZWxbQ+iMpQQ== + +karma-jasmine@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/karma-jasmine/-/karma-jasmine-4.0.1.tgz#b99e073b6d99a5196fc4bffc121b89313b0abd82" + integrity sha512-h8XDAhTiZjJKzfkoO1laMH+zfNlra+dEQHUAjpn5JV1zCPtOIVWGQjLBrqhnzQa/hrU2XrZwSyBa6XjEBzfXzw== + dependencies: + jasmine-core "^3.6.0" + +karma-rollup-preprocessor@^7.0.5: + version "7.0.7" + resolved "https://registry.yarnpkg.com/karma-rollup-preprocessor/-/karma-rollup-preprocessor-7.0.7.tgz#d06e587b108273ae564cbd5c5914a75602191a23" + integrity sha512-Y1QwsTCiCBp8sSALZdqmqry/mWIWIy0V6zonUIpy+0/D/Kpb2XZvR+JZrWfacQvcvKQdZFJvg6EwlnKtjepu3Q== + dependencies: + chokidar "^3.3.1" + debounce "^1.2.0" + +karma-spec-reporter@0.0.32: + version "0.0.32" + resolved "https://registry.yarnpkg.com/karma-spec-reporter/-/karma-spec-reporter-0.0.32.tgz#2e9c7207ea726771260259f82becb543209e440a" + integrity sha1-LpxyB+pyZ3EmAln4K+y1QyCeRAo= + dependencies: + colors "^1.1.2" + +karma@^5.1.1: + version "5.2.3" + resolved "https://registry.yarnpkg.com/karma/-/karma-5.2.3.tgz#3264024219bad2728e92542e0058a2492d7a46e4" + integrity sha512-tHdyFADhVVPBorIKCX8A37iLHxc6RBRphkSoQ+MLKdAtFn1k97tD8WUGi1KlEtDZKL3hui0qhsY9HXUfSNDYPQ== + dependencies: + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.4.2" + colors "^1.4.0" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.6" + graceful-fs "^4.2.4" + http-proxy "^1.18.1" + isbinaryfile "^4.0.6" + lodash "^4.17.19" + log4js "^6.2.1" + mime "^2.4.5" + minimatch "^3.0.4" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^2.3.0" + source-map "^0.6.1" + tmp "0.2.1" + ua-parser-js "0.7.22" + yargs "^15.3.1" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash@^4.17.19, lodash@^4.17.4: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log4js@^6.2.1: + version "6.3.0" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.3.0.tgz#10dfafbb434351a3e30277a00b9879446f715bcb" + integrity sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw== + dependencies: + date-format "^3.0.0" + debug "^4.1.1" + flatted "^2.0.1" + rfdc "^1.1.4" + streamroller "^2.2.4" + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +mime-db@1.51.0: + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== + +mime-types@~2.1.24: + version "2.1.34" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== + dependencies: + mime-db "1.51.0" + +mime@^2.4.5: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mkdirp@^0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parseqs@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.6.tgz#8e4bb5a19d1cdc844a08ac974d34e273afa670d5" + integrity sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w== + +parseuri@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.6.tgz#e1496e829e3ac2ff47f39a4dd044b32823c4a25a" + integrity sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow== + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +private@^0.1.6, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +qjobs@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.9.6: + version "6.9.6" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" + integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" + integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== + dependencies: + bytes "3.1.1" + http-errors "1.8.1" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +regenerate@^1.2.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= + dependencies: + jsesc "~0.5.0" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +rfdc@^1.1.4: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rollup-plugin-babel@^3.0.2: + version "3.0.7" + resolved "https://registry.yarnpkg.com/rollup-plugin-babel/-/rollup-plugin-babel-3.0.7.tgz#5b13611f1ab8922497e9d15197ae5d8a23fe3b1e" + integrity sha512-bVe2y0z/V5Ax1qU8NX/0idmzIwJPdUGu8Xx3vXH73h0yGjxfv2gkFI82MBVg49SlsFlLTBadBHb67zy4TWM3hA== + dependencies: + rollup-pluginutils "^1.5.0" + +rollup-plugin-terser@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" + integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== + dependencies: + "@babel/code-frame" "^7.10.4" + jest-worker "^26.2.1" + serialize-javascript "^4.0.0" + terser "^5.0.0" + +rollup-pluginutils@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" + integrity sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg= + dependencies: + estree-walker "^0.2.1" + minimatch "^3.0.2" + +rollup@^2.26.2: + version "2.63.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.63.0.tgz#fe2f7fec2133f3fab9e022b9ac245628d817c6bb" + integrity sha512-nps0idjmD+NXl6OREfyYXMn/dar3WGcyKn+KBzPdaLecub3x/LrId0wUcthcr8oZUAcZAR8NKcfGGFlNgGL1kQ== + optionalDependencies: + fsevents "~2.3.2" + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^5.3.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +socket.io-adapter@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz#ab3f0d6f66b8fc7fca3959ab5991f82221789be9" + integrity sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g== + +socket.io-client@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.4.0.tgz#aafb5d594a3c55a34355562fc8aea22ed9119a35" + integrity sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ== + dependencies: + backo2 "1.0.2" + component-bind "1.0.0" + component-emitter "~1.3.0" + debug "~3.1.0" + engine.io-client "~3.5.0" + has-binary2 "~1.0.2" + indexof "0.0.1" + parseqs "0.0.6" + parseuri "0.0.6" + socket.io-parser "~3.3.0" + to-array "0.1.4" + +socket.io-parser@~3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.2.tgz#ef872009d0adcf704f2fbe830191a14752ad50b6" + integrity sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg== + dependencies: + component-emitter "~1.3.0" + debug "~3.1.0" + isarray "2.0.1" + +socket.io-parser@~3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.4.1.tgz#b06af838302975837eab2dc980037da24054d64a" + integrity sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A== + dependencies: + component-emitter "1.2.1" + debug "~4.1.0" + isarray "2.0.1" + +socket.io@^2.3.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.4.1.tgz#95ad861c9a52369d7f1a68acf0d4a1b16da451d2" + integrity sha512-Si18v0mMXGAqLqCVpTxBa8MGqriHGQh8ccEOhmsmNS3thNCGBwO8WGrwMibANsWtQQ5NStdZwHqZR3naJVFc3w== + dependencies: + debug "~4.1.0" + engine.io "~3.5.0" + has-binary2 "~1.0.2" + socket.io-adapter "~1.1.0" + socket.io-client "2.4.0" + socket.io-parser "~3.4.0" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +streamroller@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.4.tgz#c198ced42db94086a6193608187ce80a5f2b0e53" + integrity sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ== + dependencies: + date-format "^2.1.0" + debug "^4.1.1" + fs-extra "^8.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +terser@^5.0.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc" + integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.20" + +tmp@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +ua-parser-js@0.7.22: + version "0.7.22" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.22.tgz#960df60a5f911ea8f1c818f3747b99c6e177eae3" + integrity sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q== + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@~7.4.2: + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== + +xmlhttprequest-ssl@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz#03b713873b01659dfa2c1c5d056065b27ddc2de6" + integrity sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q== + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^15.3.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= From e8dc30977b1703e19199325a43be510b0a4f7beb Mon Sep 17 00:00:00 2001 From: Nicolas Cusan Date: Wed, 12 Jan 2022 16:04:55 +0100 Subject: [PATCH 10/11] fix typo --- dist/pristine.js | 2 +- dist/pristine.min.js | 2 +- src/pristine.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/pristine.js b/dist/pristine.js index 108e832..a1f1a09 100644 --- a/dist/pristine.js +++ b/dist/pristine.js @@ -172,7 +172,7 @@ if (self.live) { input.addEventListener('change', listener); if (!~['radio', 'checkbox'].indexOf(input.getAttribute('type'))) { - input.addEventListener('inllut', listener); + input.addEventListener('input', listener); } } diff --git a/dist/pristine.min.js b/dist/pristine.min.js index aba3517..e772bc8 100644 --- a/dist/pristine.min.js +++ b/dist/pristine.min.js @@ -1 +1 @@ -!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).Pristine=r()}(this,(function(){"use strict";var e={en:{required:"This field is required",email:"This field requires a valid e-mail address",number:"This field requires a number",integer:"This field requires an integer value",url:"This field requires a valid website URL",tel:"This field requires a valid telephone number",maxlength:"This fields length must be < ${1}",minlength:"This fields length must be > ${1}",min:"Minimum value for this field is ${1}",max:"Maximum value for this field is ${1}",pattern:"Please match the requested format",equals:"The two fields do not match",default:"Please enter a correct value"}};function r(e){var r=arguments;return this.replace(/\${([^{}]*)}/g,(function(e,t){return r[t]}))}function t(e){return e.pristine.self.form.querySelectorAll('input[name="'+e.getAttribute("name")+'"]:checked').length}var n={classTo:"form-group",errorClass:"has-danger",successClass:"has-success",errorTextParent:"form-group",errorTextTag:"div",errorTextClass:"text-help",liveAfterFirstValitation:!0},i=["required","min","max","minlength","maxlength","pattern"],s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,a=/-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/,o="en",l={},u=function(e,r){r.name=e,void 0===r.priority&&(r.priority=1),l[e]=r};function f(t,s,u){var f=this,c=!1;function p(e,r,t,n){var i=l[t];if(i&&(e.push(i),n)){var s="pattern"===t?[n]:n.split(",");s.unshift(null),r[t]=s}}function m(t){for(var n=[],i=!0,s=0;t.validators[s];s++){var a=t.validators[s],l=t.params[a.name]?t.params[a.name]:[];if(l[0]=t.input.value,!a.fn.apply(t.input,l)&&(i=!1,"function"==typeof a.msg?n.push(a.msg(t.input.value,l)):"string"==typeof a.msg?n.push(r.apply(a.msg,l)):a.msg===Object(a.msg)&&a.msg[o]?n.push(r.apply(a.msg[o],l)):t.messages[o]&&t.messages[o][a.name]?n.push(r.apply(t.messages[o][a.name],l)):e[o]&&e[o][a.name]?n.push(r.apply(e[o][a.name],l)):n.push(r.apply(e[o].default,l)),!0===a.halt))break}return t.errors=n,i}function d(e){if(e.errorElements)return e.errorElements;var r=function(e,r){for(;(e=e.parentElement)&&!e.classList.contains(r););return e}(e.input,f.config.classTo),t=null,n=null;return(t=f.config.classTo===f.config.errorTextParent?r:r.querySelector("."+f.config.errorTextParent))&&((n=t.querySelector(".pristine-error"))||((n=document.createElement(f.config.errorTextTag)).className="pristine-error "+f.config.errorTextClass,t.appendChild(n),n.pristineDisplay=n.style.display)),e.errorElements=[r,n]}function h(e){var r=d(e),t=r[0],n=r[1];t&&(t.classList.remove(f.config.successClass),t.classList.add(f.config.errorClass)),n&&(n.innerHTML=e.errors.join("
"),n.style.display=n.pristineDisplay||"")}function g(e){var r=function(e){var r=d(e),t=r[0],n=r[1];return t&&(t.classList.remove(f.config.errorClass),t.classList.remove(f.config.successClass)),n&&(n.innerHTML="",n.style.display="none"),r}(e)[0];r&&r.classList.add(f.config.successClass)}return function(e,r,t){e.setAttribute("novalidate","true"),f.form=e,f.config=function(e,r){for(var t in r)t in e||(e[t]=r[t]);return e}(r||{},n),f.live=!(!1===t),f.fields=Array.from(e.querySelectorAll("input:not([disabled]):not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea")).map(function(e){var r=[],t={},n={};[].forEach.call(e.attributes,(function(e){if(/^data-pristine-/.test(e.name)){var s=e.name.substr(14),o=s.match(a);if(null!==o){var l=void 0===o[1]?"en":o[1];return n.hasOwnProperty(l)||(n[l]={}),void(n[l][s.slice(0,s.length-o[0].length)]=e.value)}"type"===s&&(s=e.value),p(r,t,s,e.value)}else~i.indexOf(e.name)?p(r,t,e.name,e.value):"type"===e.name&&p(r,t,e.value)})),r.sort((function(e,r){return r.priority-e.priority}));var s=function(e){f.config.liveAfterFirstValitation&&c?f.validate(e.target):f.config.liveAfterFirstValitation||f.validate(e.target)}.bind(f);return f.live&&(e.addEventListener("change",s),~["radio","checkbox"].indexOf(e.getAttribute("type"))||e.addEventListener("inllut",s)),e.pristine={input:e,validators:r,params:t,messages:n,self:f}}.bind(f))}(t,s,u),f.validate=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1],t=f.fields;e?e instanceof HTMLElement?t=[e.pristine]:(e instanceof NodeList||e instanceof(window.$||Array)||e instanceof Array)&&(t=Array.from(e).map((function(e){return e.pristine}))):c=!0;for(var n=!0,i=0;t[i];i++){var s=t[i];m(s)?!r&&g(s):(n=!1,!r&&h(s))}return n},f.getErrors=function(e){if(!e){for(var r=[],t=0;t=parseInt(r)}}),u("maxlength",{fn:function(e,r){return!e||e.length<=parseInt(r)}}),u("min",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)>=parseInt(r):parseFloat(e)>=parseFloat(r))}}),u("max",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)<=parseInt(r):parseFloat(e)<=parseFloat(r))}}),u("pattern",{fn:function(e,r){var t=r.match(new RegExp("^/(.*?)/([gimy]*)$"));return!e||new RegExp(t[1],t[2]).test(e)}}),u("equals",{fn:function(e,r){var t=document.querySelector(r);return t&&(!e&&!t.value||t.value===e)}}),f.addValidator=function(e,r,t,n,i){u(e,{fn:r,msg:t,priority:n,halt:i})},f.addMessages=function(r,t){var n=e.hasOwnProperty(r)?e[r]:e[r]={};Object.keys(t).forEach((function(e,r){n[e]=t[e]}))},f.setLocale=function(e){o=e},f})); +!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).Pristine=r()}(this,(function(){"use strict";var e={en:{required:"This field is required",email:"This field requires a valid e-mail address",number:"This field requires a number",integer:"This field requires an integer value",url:"This field requires a valid website URL",tel:"This field requires a valid telephone number",maxlength:"This fields length must be < ${1}",minlength:"This fields length must be > ${1}",min:"Minimum value for this field is ${1}",max:"Maximum value for this field is ${1}",pattern:"Please match the requested format",equals:"The two fields do not match",default:"Please enter a correct value"}};function r(e){var r=arguments;return this.replace(/\${([^{}]*)}/g,(function(e,t){return r[t]}))}function t(e){return e.pristine.self.form.querySelectorAll('input[name="'+e.getAttribute("name")+'"]:checked').length}var n={classTo:"form-group",errorClass:"has-danger",successClass:"has-success",errorTextParent:"form-group",errorTextTag:"div",errorTextClass:"text-help",liveAfterFirstValitation:!0},i=["required","min","max","minlength","maxlength","pattern"],s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,a=/-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/,o="en",l={},u=function(e,r){r.name=e,void 0===r.priority&&(r.priority=1),l[e]=r};function f(t,s,u){var f=this,c=!1;function p(e,r,t,n){var i=l[t];if(i&&(e.push(i),n)){var s="pattern"===t?[n]:n.split(",");s.unshift(null),r[t]=s}}function m(t){for(var n=[],i=!0,s=0;t.validators[s];s++){var a=t.validators[s],l=t.params[a.name]?t.params[a.name]:[];if(l[0]=t.input.value,!a.fn.apply(t.input,l)&&(i=!1,"function"==typeof a.msg?n.push(a.msg(t.input.value,l)):"string"==typeof a.msg?n.push(r.apply(a.msg,l)):a.msg===Object(a.msg)&&a.msg[o]?n.push(r.apply(a.msg[o],l)):t.messages[o]&&t.messages[o][a.name]?n.push(r.apply(t.messages[o][a.name],l)):e[o]&&e[o][a.name]?n.push(r.apply(e[o][a.name],l)):n.push(r.apply(e[o].default,l)),!0===a.halt))break}return t.errors=n,i}function d(e){if(e.errorElements)return e.errorElements;var r=function(e,r){for(;(e=e.parentElement)&&!e.classList.contains(r););return e}(e.input,f.config.classTo),t=null,n=null;return(t=f.config.classTo===f.config.errorTextParent?r:r.querySelector("."+f.config.errorTextParent))&&((n=t.querySelector(".pristine-error"))||((n=document.createElement(f.config.errorTextTag)).className="pristine-error "+f.config.errorTextClass,t.appendChild(n),n.pristineDisplay=n.style.display)),e.errorElements=[r,n]}function h(e){var r=d(e),t=r[0],n=r[1];t&&(t.classList.remove(f.config.successClass),t.classList.add(f.config.errorClass)),n&&(n.innerHTML=e.errors.join("
"),n.style.display=n.pristineDisplay||"")}function g(e){var r=function(e){var r=d(e),t=r[0],n=r[1];return t&&(t.classList.remove(f.config.errorClass),t.classList.remove(f.config.successClass)),n&&(n.innerHTML="",n.style.display="none"),r}(e)[0];r&&r.classList.add(f.config.successClass)}return function(e,r,t){e.setAttribute("novalidate","true"),f.form=e,f.config=function(e,r){for(var t in r)t in e||(e[t]=r[t]);return e}(r||{},n),f.live=!(!1===t),f.fields=Array.from(e.querySelectorAll("input:not([disabled]):not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea")).map(function(e){var r=[],t={},n={};[].forEach.call(e.attributes,(function(e){if(/^data-pristine-/.test(e.name)){var s=e.name.substr(14),o=s.match(a);if(null!==o){var l=void 0===o[1]?"en":o[1];return n.hasOwnProperty(l)||(n[l]={}),void(n[l][s.slice(0,s.length-o[0].length)]=e.value)}"type"===s&&(s=e.value),p(r,t,s,e.value)}else~i.indexOf(e.name)?p(r,t,e.name,e.value):"type"===e.name&&p(r,t,e.value)})),r.sort((function(e,r){return r.priority-e.priority}));var s=function(e){f.config.liveAfterFirstValitation&&c?f.validate(e.target):f.config.liveAfterFirstValitation||f.validate(e.target)}.bind(f);return f.live&&(e.addEventListener("change",s),~["radio","checkbox"].indexOf(e.getAttribute("type"))||e.addEventListener("input",s)),e.pristine={input:e,validators:r,params:t,messages:n,self:f}}.bind(f))}(t,s,u),f.validate=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1],t=f.fields;e?e instanceof HTMLElement?t=[e.pristine]:(e instanceof NodeList||e instanceof(window.$||Array)||e instanceof Array)&&(t=Array.from(e).map((function(e){return e.pristine}))):c=!0;for(var n=!0,i=0;t[i];i++){var s=t[i];m(s)?!r&&g(s):(n=!1,!r&&h(s))}return n},f.getErrors=function(e){if(!e){for(var r=[],t=0;t=parseInt(r)}}),u("maxlength",{fn:function(e,r){return!e||e.length<=parseInt(r)}}),u("min",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)>=parseInt(r):parseFloat(e)>=parseFloat(r))}}),u("max",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)<=parseInt(r):parseFloat(e)<=parseFloat(r))}}),u("pattern",{fn:function(e,r){var t=r.match(new RegExp("^/(.*?)/([gimy]*)$"));return!e||new RegExp(t[1],t[2]).test(e)}}),u("equals",{fn:function(e,r){var t=document.querySelector(r);return t&&(!e&&!t.value||t.value===e)}}),f.addValidator=function(e,r,t,n,i){u(e,{fn:r,msg:t,priority:n,halt:i})},f.addMessages=function(r,t){var n=e.hasOwnProperty(r)?e[r]:e[r]={};Object.keys(t).forEach((function(e,r){n[e]=t[e]}))},f.setLocale=function(e){o=e},f})); diff --git a/src/pristine.js b/src/pristine.js index dc82684..a0c1c16 100755 --- a/src/pristine.js +++ b/src/pristine.js @@ -135,7 +135,7 @@ export default function Pristine(form, config, live) { if (self.live) { input.addEventListener('change', listener); if (!~['radio', 'checkbox'].indexOf(input.getAttribute('type'))) { - input.addEventListener('inllut', listener); + input.addEventListener('input', listener); } } From 542fab0d34e283c35c5dee312b815d14cf8a2940 Mon Sep 17 00:00:00 2001 From: Nicolas Cusan Date: Thu, 24 Feb 2022 15:48:38 +0100 Subject: [PATCH 11/11] updgrade remove error to intance method --- dist/pristine.js | 12 ++++++------ dist/pristine.min.js | 2 +- src/pristine.js | 15 ++++++++------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/dist/pristine.js b/dist/pristine.js index a1f1a09..f082197 100644 --- a/dist/pristine.js +++ b/dist/pristine.js @@ -225,7 +225,7 @@ for (var i = 0; fields[i]; i++) { var field = fields[i]; - if (_validateField(field)) { + if (self.validateField(field)) { !silent && _showSuccess(field); } else { valid = false; @@ -264,7 +264,7 @@ * @returns {boolean} * @private */ - function _validateField(field) { + self.validateField = function (field) { var errors = []; var valid = true; for (var i = 0; field.validators[i]; i++) { @@ -296,7 +296,7 @@ } field.errors = errors; return valid; - } + }; /*** * Add a validator to a specific dom element in a form @@ -375,7 +375,7 @@ _showError(input.pristine); }; - function _removeError(field) { + self.removeError = function (field) { var errorElements = _getErrorElements(field); var errorClassElement = errorElements[0], errorTextElement = errorElements[1]; @@ -389,10 +389,10 @@ errorTextElement.style.display = 'none'; } return errorElements; - } + }; function _showSuccess(field) { - var errorClassElement = _removeError(field)[0]; + var errorClassElement = self.removeError(field)[0]; errorClassElement && errorClassElement.classList.add(self.config.successClass); } diff --git a/dist/pristine.min.js b/dist/pristine.min.js index e772bc8..de702d6 100644 --- a/dist/pristine.min.js +++ b/dist/pristine.min.js @@ -1 +1 @@ -!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).Pristine=r()}(this,(function(){"use strict";var e={en:{required:"This field is required",email:"This field requires a valid e-mail address",number:"This field requires a number",integer:"This field requires an integer value",url:"This field requires a valid website URL",tel:"This field requires a valid telephone number",maxlength:"This fields length must be < ${1}",minlength:"This fields length must be > ${1}",min:"Minimum value for this field is ${1}",max:"Maximum value for this field is ${1}",pattern:"Please match the requested format",equals:"The two fields do not match",default:"Please enter a correct value"}};function r(e){var r=arguments;return this.replace(/\${([^{}]*)}/g,(function(e,t){return r[t]}))}function t(e){return e.pristine.self.form.querySelectorAll('input[name="'+e.getAttribute("name")+'"]:checked').length}var n={classTo:"form-group",errorClass:"has-danger",successClass:"has-success",errorTextParent:"form-group",errorTextTag:"div",errorTextClass:"text-help",liveAfterFirstValitation:!0},i=["required","min","max","minlength","maxlength","pattern"],s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,a=/-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/,o="en",l={},u=function(e,r){r.name=e,void 0===r.priority&&(r.priority=1),l[e]=r};function f(t,s,u){var f=this,c=!1;function p(e,r,t,n){var i=l[t];if(i&&(e.push(i),n)){var s="pattern"===t?[n]:n.split(",");s.unshift(null),r[t]=s}}function m(t){for(var n=[],i=!0,s=0;t.validators[s];s++){var a=t.validators[s],l=t.params[a.name]?t.params[a.name]:[];if(l[0]=t.input.value,!a.fn.apply(t.input,l)&&(i=!1,"function"==typeof a.msg?n.push(a.msg(t.input.value,l)):"string"==typeof a.msg?n.push(r.apply(a.msg,l)):a.msg===Object(a.msg)&&a.msg[o]?n.push(r.apply(a.msg[o],l)):t.messages[o]&&t.messages[o][a.name]?n.push(r.apply(t.messages[o][a.name],l)):e[o]&&e[o][a.name]?n.push(r.apply(e[o][a.name],l)):n.push(r.apply(e[o].default,l)),!0===a.halt))break}return t.errors=n,i}function d(e){if(e.errorElements)return e.errorElements;var r=function(e,r){for(;(e=e.parentElement)&&!e.classList.contains(r););return e}(e.input,f.config.classTo),t=null,n=null;return(t=f.config.classTo===f.config.errorTextParent?r:r.querySelector("."+f.config.errorTextParent))&&((n=t.querySelector(".pristine-error"))||((n=document.createElement(f.config.errorTextTag)).className="pristine-error "+f.config.errorTextClass,t.appendChild(n),n.pristineDisplay=n.style.display)),e.errorElements=[r,n]}function h(e){var r=d(e),t=r[0],n=r[1];t&&(t.classList.remove(f.config.successClass),t.classList.add(f.config.errorClass)),n&&(n.innerHTML=e.errors.join("
"),n.style.display=n.pristineDisplay||"")}function g(e){var r=function(e){var r=d(e),t=r[0],n=r[1];return t&&(t.classList.remove(f.config.errorClass),t.classList.remove(f.config.successClass)),n&&(n.innerHTML="",n.style.display="none"),r}(e)[0];r&&r.classList.add(f.config.successClass)}return function(e,r,t){e.setAttribute("novalidate","true"),f.form=e,f.config=function(e,r){for(var t in r)t in e||(e[t]=r[t]);return e}(r||{},n),f.live=!(!1===t),f.fields=Array.from(e.querySelectorAll("input:not([disabled]):not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea")).map(function(e){var r=[],t={},n={};[].forEach.call(e.attributes,(function(e){if(/^data-pristine-/.test(e.name)){var s=e.name.substr(14),o=s.match(a);if(null!==o){var l=void 0===o[1]?"en":o[1];return n.hasOwnProperty(l)||(n[l]={}),void(n[l][s.slice(0,s.length-o[0].length)]=e.value)}"type"===s&&(s=e.value),p(r,t,s,e.value)}else~i.indexOf(e.name)?p(r,t,e.name,e.value):"type"===e.name&&p(r,t,e.value)})),r.sort((function(e,r){return r.priority-e.priority}));var s=function(e){f.config.liveAfterFirstValitation&&c?f.validate(e.target):f.config.liveAfterFirstValitation||f.validate(e.target)}.bind(f);return f.live&&(e.addEventListener("change",s),~["radio","checkbox"].indexOf(e.getAttribute("type"))||e.addEventListener("input",s)),e.pristine={input:e,validators:r,params:t,messages:n,self:f}}.bind(f))}(t,s,u),f.validate=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1],t=f.fields;e?e instanceof HTMLElement?t=[e.pristine]:(e instanceof NodeList||e instanceof(window.$||Array)||e instanceof Array)&&(t=Array.from(e).map((function(e){return e.pristine}))):c=!0;for(var n=!0,i=0;t[i];i++){var s=t[i];m(s)?!r&&g(s):(n=!1,!r&&h(s))}return n},f.getErrors=function(e){if(!e){for(var r=[],t=0;t=parseInt(r)}}),u("maxlength",{fn:function(e,r){return!e||e.length<=parseInt(r)}}),u("min",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)>=parseInt(r):parseFloat(e)>=parseFloat(r))}}),u("max",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)<=parseInt(r):parseFloat(e)<=parseFloat(r))}}),u("pattern",{fn:function(e,r){var t=r.match(new RegExp("^/(.*?)/([gimy]*)$"));return!e||new RegExp(t[1],t[2]).test(e)}}),u("equals",{fn:function(e,r){var t=document.querySelector(r);return t&&(!e&&!t.value||t.value===e)}}),f.addValidator=function(e,r,t,n,i){u(e,{fn:r,msg:t,priority:n,halt:i})},f.addMessages=function(r,t){var n=e.hasOwnProperty(r)?e[r]:e[r]={};Object.keys(t).forEach((function(e,r){n[e]=t[e]}))},f.setLocale=function(e){o=e},f})); +!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).Pristine=r()}(this,(function(){"use strict";var e={en:{required:"This field is required",email:"This field requires a valid e-mail address",number:"This field requires a number",integer:"This field requires an integer value",url:"This field requires a valid website URL",tel:"This field requires a valid telephone number",maxlength:"This fields length must be < ${1}",minlength:"This fields length must be > ${1}",min:"Minimum value for this field is ${1}",max:"Maximum value for this field is ${1}",pattern:"Please match the requested format",equals:"The two fields do not match",default:"Please enter a correct value"}};function r(e){var r=arguments;return this.replace(/\${([^{}]*)}/g,(function(e,t){return r[t]}))}function t(e){return e.pristine.self.form.querySelectorAll('input[name="'+e.getAttribute("name")+'"]:checked').length}var n={classTo:"form-group",errorClass:"has-danger",successClass:"has-success",errorTextParent:"form-group",errorTextTag:"div",errorTextClass:"text-help",liveAfterFirstValitation:!0},i=["required","min","max","minlength","maxlength","pattern"],s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,a=/-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/,o="en",l={},u=function(e,r){r.name=e,void 0===r.priority&&(r.priority=1),l[e]=r};function f(t,s,u){var f=this,c=!1;function p(e,r,t,n){var i=l[t];if(i&&(e.push(i),n)){var s="pattern"===t?[n]:n.split(",");s.unshift(null),r[t]=s}}function d(e){if(e.errorElements)return e.errorElements;var r=function(e,r){for(;(e=e.parentElement)&&!e.classList.contains(r););return e}(e.input,f.config.classTo),t=null,n=null;return(t=f.config.classTo===f.config.errorTextParent?r:r.querySelector("."+f.config.errorTextParent))&&((n=t.querySelector(".pristine-error"))||((n=document.createElement(f.config.errorTextTag)).className="pristine-error "+f.config.errorTextClass,t.appendChild(n),n.pristineDisplay=n.style.display)),e.errorElements=[r,n]}function m(e){var r=d(e),t=r[0],n=r[1];t&&(t.classList.remove(f.config.successClass),t.classList.add(f.config.errorClass)),n&&(n.innerHTML=e.errors.join("
"),n.style.display=n.pristineDisplay||"")}function h(e){var r=f.removeError(e)[0];r&&r.classList.add(f.config.successClass)}return function(e,r,t){e.setAttribute("novalidate","true"),f.form=e,f.config=function(e,r){for(var t in r)t in e||(e[t]=r[t]);return e}(r||{},n),f.live=!(!1===t),f.fields=Array.from(e.querySelectorAll("input:not([disabled]):not([type^=hidden]):not([type^=submit]):not([type^=button]), select, textarea")).map(function(e){var r=[],t={},n={};[].forEach.call(e.attributes,(function(e){if(/^data-pristine-/.test(e.name)){var s=e.name.substr(14),o=s.match(a);if(null!==o){var l=void 0===o[1]?"en":o[1];return n.hasOwnProperty(l)||(n[l]={}),void(n[l][s.slice(0,s.length-o[0].length)]=e.value)}"type"===s&&(s=e.value),p(r,t,s,e.value)}else~i.indexOf(e.name)?p(r,t,e.name,e.value):"type"===e.name&&p(r,t,e.value)})),r.sort((function(e,r){return r.priority-e.priority}));var s=function(e){f.config.liveAfterFirstValitation&&c?f.validate(e.target):f.config.liveAfterFirstValitation||f.validate(e.target)}.bind(f);return f.live&&(e.addEventListener("change",s),~["radio","checkbox"].indexOf(e.getAttribute("type"))||e.addEventListener("input",s)),e.pristine={input:e,validators:r,params:t,messages:n,self:f}}.bind(f))}(t,s,u),f.validate=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1],t=f.fields;e?e instanceof HTMLElement?t=[e.pristine]:(e instanceof NodeList||e instanceof(window.$||Array)||e instanceof Array)&&(t=Array.from(e).map((function(e){return e.pristine}))):c=!0;for(var n=!0,i=0;t[i];i++){var s=t[i];f.validateField(s)?!r&&h(s):(n=!1,!r&&m(s))}return n},f.getErrors=function(e){if(!e){for(var r=[],t=0;t=parseInt(r)}}),u("maxlength",{fn:function(e,r){return!e||e.length<=parseInt(r)}}),u("min",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)>=parseInt(r):parseFloat(e)>=parseFloat(r))}}),u("max",{fn:function(e,r){return!e||("checkbox"===this.type?t(this)<=parseInt(r):parseFloat(e)<=parseFloat(r))}}),u("pattern",{fn:function(e,r){var t=r.match(new RegExp("^/(.*?)/([gimy]*)$"));return!e||new RegExp(t[1],t[2]).test(e)}}),u("equals",{fn:function(e,r){var t=document.querySelector(r);return t&&(!e&&!t.value||t.value===e)}}),f.addValidator=function(e,r,t,n,i){u(e,{fn:r,msg:t,priority:n,halt:i})},f.addMessages=function(r,t){var n=e.hasOwnProperty(r)?e[r]:e[r]={};Object.keys(t).forEach((function(e,r){n[e]=t[e]}))},f.setLocale=function(e){o=e},f})); diff --git a/src/pristine.js b/src/pristine.js index a0c1c16..db51fd1 100755 --- a/src/pristine.js +++ b/src/pristine.js @@ -22,7 +22,8 @@ const ALLOWED_ATTRIBUTES = [ 'maxlength', 'pattern', ]; -const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; +const EMAIL_REGEX = + /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; const MESSAGE_REGEX = /-message(?:-([a-z]{2}(?:_[A-Z]{2})?))?/; // matches, -message, -message-en, -message-en_US let currentLocale = 'en'; @@ -188,7 +189,7 @@ export default function Pristine(form, config, live) { for (let i = 0; fields[i]; i++) { let field = fields[i]; - if (_validateField(field)) { + if (self.validateField(field)) { !silent && _showSuccess(field); } else { valid = false; @@ -227,7 +228,7 @@ export default function Pristine(form, config, live) { * @returns {boolean} * @private */ - function _validateField(field) { + self.validateField = function (field) { let errors = []; let valid = true; for (let i = 0; field.validators[i]; i++) { @@ -269,7 +270,7 @@ export default function Pristine(form, config, live) { } field.errors = errors; return valid; - } + }; /*** * Add a validator to a specific dom element in a form @@ -349,7 +350,7 @@ export default function Pristine(form, config, live) { _showError(input.pristine); }; - function _removeError(field) { + self.removeError = function (field) { let errorElements = _getErrorElements(field); let errorClassElement = errorElements[0], errorTextElement = errorElements[1]; @@ -363,10 +364,10 @@ export default function Pristine(form, config, live) { errorTextElement.style.display = 'none'; } return errorElements; - } + }; function _showSuccess(field) { - let errorClassElement = _removeError(field)[0]; + let errorClassElement = self.removeError(field)[0]; errorClassElement && errorClassElement.classList.add(self.config.successClass); }