MailPoet Newsletters (New) - Version 3.0.0-beta.31

Version Description

  • 2017-05-16 =
  • Improved: automated latest content/post search boxes in the editor now return up to 50 results;
  • Improved: sending progress bar got a new look;
  • Improved: added plugin translation to Persian (Iran) language. Thanks Ali Reza Karami!;
  • Fixed: submission of subscription forms with list selection or non-text custom fields works again. Thanks Stefan!;
  • Fixed: subscription management form works fine again;
  • Fixed: invalid license key warnings are temporary hidden if a key is empty;
  • Fixed: newsletter link hashes are much less likely to collide. Thanks Sherrie!
Download this release

Release Info

Developer wysija
Plugin Icon 128x128 MailPoet Newsletters (New)
Version 3.0.0-beta.31
Comparing to
See all releases

Code changes from version 3.0.0-beta.30 to 3.0.0-beta.31

assets/css/admin.css CHANGED
@@ -2848,6 +2848,7 @@ textarea.parsley-error {
2848
  padding: 0;
2849
  width: 100%;
2850
  margin: 0;
 
2851
  border-radius: 5px;
2852
  position: relative;
2853
  }
@@ -2873,12 +2874,12 @@ textarea.parsley-error {
2873
  background-image: linear-gradient(to bottom, #34c2e3, #1ba4c4);
2874
  }
2875
  .mailpoet_progress_complete .mailpoet_progress_bar {
2876
- background-color: #fecf23;
2877
- background-image: -webkit-linear-gradient(top, #fecf23, #fd9215);
2878
- background-image: -moz-linear-gradient(top, #fecf23, #fd9215);
2879
- background-image: -o-linear-gradient(top, #fecf23, #fd9215);
2880
- background-image: -ms-linear-gradient(top, #fecf23, #fd9215);
2881
- background-image: linear-gradient(to bottom, #fecf23, #fd9215);
2882
  }
2883
  #subscribers_container .mailpoet_segments_unsubscribed {
2884
  color: #a9a9a9;
2848
  padding: 0;
2849
  width: 100%;
2850
  margin: 0;
2851
+ margin-bottom: 10px;
2852
  border-radius: 5px;
2853
  position: relative;
2854
  }
2874
  background-image: linear-gradient(to bottom, #34c2e3, #1ba4c4);
2875
  }
2876
  .mailpoet_progress_complete .mailpoet_progress_bar {
2877
+ background-color: #a4e5f4;
2878
+ background-image: -webkit-linear-gradient(top, hsla(191,78%,80%,1), hsla(191,76%,67%,1));
2879
+ background-image: -moz-linear-gradient(top, hsla(191,78%,80%,1), hsla(191,76%,67%,1));
2880
+ background-image: -o-linear-gradient(top, hsla(191,78%,80%,1), hsla(191,76%,67%,1));
2881
+ background-image: -ms-linear-gradient(top, hsla(191,78%,80%,1), hsla(191,76%,67%,1));
2882
+ background-image: linear-gradient(to bottom, hsla(191,78%,80%,1), hsla(191,76%,67%,1));
2883
  }
2884
  #subscribers_container .mailpoet_segments_unsubscribed {
2885
  color: #a9a9a9;
assets/js/mailpoet.js CHANGED
@@ -19057,7 +19057,7 @@ webpackJsonp([3],[
19057
 
19058
  /* WEBPACK VAR INJECTION */(function(global) {/*!
19059
  * Parsley.js
19060
- * Version 2.7.2 - built Tue, May 9th 2017, 11:21 am
19061
  * http://parsleyjs.org
19062
  * Guillaume Potier - <guillaume@wisembly.com>
19063
  * Marc-Andre Lafortune - <petroselinum@marc-andre.ca>
@@ -19071,8 +19071,6 @@ webpackJsonp([3],[
19071
 
19072
  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
19073
 
19074
- var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
19075
-
19076
  function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }
19077
 
19078
  (function (global, factory) {
@@ -19083,10 +19081,10 @@ webpackJsonp([3],[
19083
  var globalID = 1;
19084
  var pastWarnings = {};
19085
 
19086
- var Utils = {
19087
  // Parsley DOM-API
19088
  // returns object from dom attributes and values
19089
- attr: function attr(element, namespace, obj) {
19090
  var i;
19091
  var attribute;
19092
  var attributes;
@@ -19099,9 +19097,9 @@ webpackJsonp([3],[
19099
  }
19100
  }
19101
 
19102
- if (!element) return obj;
19103
 
19104
- attributes = element.attributes;
19105
  for (i = attributes.length; i--;) {
19106
  attribute = attributes[i];
19107
 
@@ -19113,12 +19111,12 @@ webpackJsonp([3],[
19113
  return obj;
19114
  },
19115
 
19116
- checkAttr: function checkAttr(element, namespace, _checkAttr) {
19117
- return element.hasAttribute(namespace + _checkAttr);
19118
  },
19119
 
19120
- setAttr: function setAttr(element, namespace, attr, value) {
19121
- element.setAttribute(this.dasherize(namespace + attr), String(value));
19122
  },
19123
 
19124
  generateID: function generateID() {
@@ -19205,7 +19203,7 @@ webpackJsonp([3],[
19205
  return !/^\s*false\s*$/i.test(string);
19206
  },
19207
  object: function object(string) {
19208
- return Utils.deserializeValue(string);
19209
  },
19210
  regexp: function regexp(_regexp) {
19211
  var flags = '';
@@ -19277,6 +19275,8 @@ webpackJsonp([3],[
19277
  _SubmitSelector: 'input[type="submit"], button:submit'
19278
  };
19279
 
 
 
19280
  // All these options could be overriden and specified directly in DOM using
19281
  // `data-parsley-` default DOM-API
19282
  // eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
@@ -19343,7 +19343,7 @@ webpackJsonp([3],[
19343
  };
19344
 
19345
  var Base = function Base() {
19346
- this.__id__ = Utils.generateID();
19347
  };
19348
 
19349
  Base.prototype = {
@@ -19361,14 +19361,14 @@ webpackJsonp([3],[
19361
  },
19362
 
19363
  actualizeOptions: function actualizeOptions() {
19364
- Utils.attr(this.element, this.options.namespace, this.domOptions);
19365
  if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions();
19366
  return this;
19367
  },
19368
 
19369
  _resetOptions: function _resetOptions(initOptions) {
19370
- this.domOptions = Utils.objectCreate(this.parent.options);
19371
- this.options = Utils.objectCreate(this.domOptions);
19372
  // Shallow copy of ownProperties of initOptions:
19373
  for (var i in initOptions) {
19374
  if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i];
@@ -19434,19 +19434,19 @@ webpackJsonp([3],[
19434
  },
19435
 
19436
  asyncIsValid: function asyncIsValid(group, force) {
19437
- Utils.warnOnce("asyncIsValid is deprecated; please use whenValid instead");
19438
  return this.whenValid({ group: group, force: force });
19439
  },
19440
 
19441
  _findRelated: function _findRelated() {
19442
- return this.options.multiple ? $(this.parent.element.querySelectorAll('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]')) : this.$element;
19443
  }
19444
  };
19445
 
19446
  var convertArrayRequirement = function convertArrayRequirement(string, length) {
19447
  var m = string.match(/^\s*\[(.*)\]\s*$/);
19448
  if (!m) throw 'Requirement is not an array: "' + string + '"';
19449
- var values = m[1].split(',').map(Utils.trimString);
19450
  if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';
19451
  return values;
19452
  };
@@ -19457,10 +19457,10 @@ webpackJsonp([3],[
19457
  for (var key in requirementSpec) {
19458
  if (key) {
19459
  var value = extraOptionReader(key);
19460
- if ('string' === typeof value) value = Utils.parseRequirement(requirementSpec[key], value);
19461
  extra[key] = value;
19462
  } else {
19463
- main = Utils.parseRequirement(requirementSpec[key], string);
19464
  }
19465
  }
19466
  return [main, extra];
@@ -19483,13 +19483,13 @@ webpackJsonp([3],[
19483
  return this.fn(value, requirementFirstArg);
19484
  }
19485
 
19486
- if (Array.isArray(value)) {
19487
  if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values';
19488
  return this.validateMultiple.apply(this, arguments);
19489
  } else {
19490
  var instance = arguments[arguments.length - 1];
19491
  if (this.validateDate && instance._isDateInput()) {
19492
- arguments[0] = Utils.parse.date(arguments[0]);
19493
  if (arguments[0] === null) return false;
19494
  return this.validateDate.apply(this, arguments);
19495
  }
@@ -19511,17 +19511,17 @@ webpackJsonp([3],[
19511
  if ('string' !== typeof requirements) {
19512
  // Assume requirement already parsed
19513
  // but make sure we return an array
19514
- return Array.isArray(requirements) ? requirements : [requirements];
19515
  }
19516
  var type = this.requirementType;
19517
- if (Array.isArray(type)) {
19518
  var values = convertArrayRequirement(requirements, type.length);
19519
- for (var i = 0; i < values.length; i++) values[i] = Utils.parseRequirement(type[i], values[i]);
19520
  return values;
19521
  } else if ($.isPlainObject(type)) {
19522
  return convertExtraOptionRequirement(type, requirements, extraOptionReader);
19523
  } else {
19524
- return [Utils.parseRequirement(type, requirements)];
19525
  }
19526
  },
19527
  // Defaults:
@@ -19554,7 +19554,7 @@ webpackJsonp([3],[
19554
 
19555
  date: {
19556
  test: function test(value) {
19557
- return Utils.parse.date(value) !== null;
19558
  }
19559
  },
19560
 
@@ -19602,7 +19602,7 @@ webpackJsonp([3],[
19602
 
19603
  // parseArguments('number', ['1', '2']) => [1, 2]
19604
  var ValidatorRegistry__parseArguments = function ValidatorRegistry__parseArguments(type, args) {
19605
- return args.map(Utils.parse[type]);
19606
  };
19607
  // operatorToValidator returns a validating function for an operator function, applied to the given type
19608
  var ValidatorRegistry__operatorToValidator = function ValidatorRegistry__operatorToValidator(type, operator) {
@@ -19629,7 +19629,7 @@ webpackJsonp([3],[
19629
  init: function init(validators, catalog) {
19630
  this.catalog = catalog;
19631
  // Copy prototype's validators:
19632
- this.validators = _extends({}, this.validators);
19633
 
19634
  for (var name in validators) this.addValidator(name, validators[name].fn, validators[name].priority);
19635
 
@@ -19685,8 +19685,8 @@ webpackJsonp([3],[
19685
  // Old API was addValidator(name, function, priority)
19686
  //
19687
  addValidator: function addValidator(name, arg1, arg2) {
19688
- if (this.validators[name]) Utils.warn('Validator "' + name + '" is already defined.');else if (Defaults.hasOwnProperty(name)) {
19689
- Utils.warn('"' + name + '" is a restricted keyword and is not a valid validator name.');
19690
  return;
19691
  }
19692
  return this._setValidator.apply(this, arguments);
@@ -19694,14 +19694,14 @@ webpackJsonp([3],[
19694
 
19695
  updateValidator: function updateValidator(name, arg1, arg2) {
19696
  if (!this.validators[name]) {
19697
- Utils.warn('Validator "' + name + '" is not already defined.');
19698
  return this.addValidator.apply(this, arguments);
19699
  }
19700
  return this._setValidator.apply(this, arguments);
19701
  },
19702
 
19703
  removeValidator: function removeValidator(name) {
19704
- if (!this.validators[name]) Utils.warn('Validator "' + name + '" is not defined.');
19705
 
19706
  delete this.validators[name];
19707
 
@@ -19910,14 +19910,14 @@ webpackJsonp([3],[
19910
  this.$element.on('submit.Parsley', function (evt) {
19911
  _this2.onSubmitValidate(evt);
19912
  });
19913
- this.$element.on('click.Parsley', Utils._SubmitSelector, function (evt) {
19914
  _this2.onSubmitButton(evt);
19915
  });
19916
 
19917
  // UI could be disabled
19918
  if (false === this.options.uiEnabled) return;
19919
 
19920
- this.element.setAttribute('novalidate', '');
19921
  },
19922
 
19923
  focus: function focus() {
@@ -20094,7 +20094,7 @@ webpackJsonp([3],[
20094
  var _ui = {};
20095
 
20096
  // Give field its Parsley id in DOM
20097
- this.element.setAttribute(this.options.namespace + 'id', this.__id__);
20098
 
20099
  /** Generate important UI elements and store them in this **/
20100
  // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
@@ -20115,15 +20115,10 @@ webpackJsonp([3],[
20115
  // Determine which element will have `parsley-error` and `parsley-success` classes
20116
  _manageClassHandler: function _manageClassHandler() {
20117
  // An element selector could be passed through DOM with `data-parsley-class-handler=#foo`
20118
- if ('string' === typeof this.options.classHandler) {
20119
- if ($(this.options.classHandler).length === 0) ParsleyUtils.warn('No elements found that match the selector `' + this.options.classHandler + '` set in options.classHandler or data-parsley-class-handler');
20120
-
20121
- //return element or empty set
20122
- return $(this.options.classHandler);
20123
- }
20124
 
20125
  // Class handled could also be determined by function given in Parsley options
20126
- if ('function' === typeof this.options.classHandler) var $handler = this.options.classHandler.call(this, this);
20127
 
20128
  // If this function returned a valid existing DOM element, go for it
20129
  if ('undefined' !== typeof $handler && $handler.length) return $handler;
@@ -20133,7 +20128,7 @@ webpackJsonp([3],[
20133
 
20134
  _inputHolder: function _inputHolder() {
20135
  // if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container
20136
- if (!this.options.multiple || this.element.nodeName === 'SELECT') return this.$element;
20137
 
20138
  // But if multiple element (radio, checkbox), that would be their parent
20139
  return this.$element.parent();
@@ -20146,7 +20141,7 @@ webpackJsonp([3],[
20146
  if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent();
20147
 
20148
  if ('string' === typeof this.options.errorsContainer) {
20149
- if ($(this.options.errorsContainer).length) return $(this.options.errorsContainer).append(this._ui.$errorsWrapper);else Utils.warn('The errors container `' + this.options.errorsContainer + '` does not exist in DOM');
20150
  } else if ('function' === typeof this.options.errorsContainer) $errorsContainer = this.options.errorsContainer.call(this, this);
20151
 
20152
  if ('undefined' !== typeof $errorsContainer && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper);
@@ -20162,9 +20157,9 @@ webpackJsonp([3],[
20162
 
20163
  // Remove Parsley events already bound on this field
20164
  $toBind.off('.Parsley');
20165
- if (this._failedOnce) $toBind.on(Utils.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () {
20166
  _this3._validateIfNeeded();
20167
- });else if (trigger = Utils.namespaceEvents(this.options.trigger, 'Parsley')) {
20168
  $toBind.on(trigger, function (event) {
20169
  _this3._validateIfNeeded(event);
20170
  });
@@ -20230,7 +20225,6 @@ webpackJsonp([3],[
20230
  var Form = function Form(element, domOptions, options) {
20231
  this.__class__ = 'Form';
20232
 
20233
- this.element = element;
20234
  this.$element = $(element);
20235
  this.domOptions = domOptions;
20236
  this.options = options;
@@ -20250,12 +20244,10 @@ webpackJsonp([3],[
20250
  if (true === event.parsley) return;
20251
 
20252
  // If we didn't come here through a submit button, use the first one in the form
20253
- var submitSource = this._submitSource || this.$element.find(Utils._SubmitSelector)[0];
20254
- this._submitSource = null;
20255
  this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);
20256
- if (submitSource && null !== submitSource.getAttribute('formnovalidate')) return;
20257
-
20258
- window.Parsley._remoteCache = {};
20259
 
20260
  var promise = this.whenValidate({ event: event });
20261
 
@@ -20267,30 +20259,30 @@ webpackJsonp([3],[
20267
  event.stopImmediatePropagation();
20268
  event.preventDefault();
20269
  if ('pending' === promise.state()) promise.done(function () {
20270
- _this5._submit(submitSource);
20271
  });
20272
  }
20273
  },
20274
 
20275
  onSubmitButton: function onSubmitButton(event) {
20276
- this._submitSource = event.currentTarget;
20277
  },
20278
  // internal
20279
  // _submit submits the form, this time without going through the validations.
20280
  // Care must be taken to "fake" the actual submit button being clicked.
20281
- _submit: function _submit(submitSource) {
20282
  if (false === this._trigger('submit')) return;
20283
  // Add submit button's data
20284
- if (submitSource) {
20285
  var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);
20286
  if (0 === $synthetic.length) $synthetic = $('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element);
20287
  $synthetic.attr({
20288
- name: submitSource.getAttribute('name'),
20289
- value: submitSource.getAttribute('value')
20290
  });
20291
  }
20292
 
20293
- this.$element.trigger(_extends($.Event('submit'), { parsley: true }));
20294
  },
20295
 
20296
  // Performs validation on fields while triggering events.
@@ -20300,7 +20292,7 @@ webpackJsonp([3],[
20300
  // Consider using `whenValidate` instead.
20301
  validate: function validate(options) {
20302
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
20303
- Utils.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');
20304
 
20305
  var _arguments = _slice.call(arguments);
20306
 
@@ -20314,7 +20306,7 @@ webpackJsonp([3],[
20314
  },
20315
 
20316
  whenValidate: function whenValidate() {
20317
- var _Utils$all$done$fail$always,
20318
  _this6 = this;
20319
 
20320
  var _ref7 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
@@ -20325,8 +20317,8 @@ webpackJsonp([3],[
20325
 
20326
  this.submitEvent = event;
20327
  if (event) {
20328
- this.submitEvent = _extends({}, event, { preventDefault: function preventDefault() {
20329
- Utils.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
20330
  _this6.validationResult = false;
20331
  } });
20332
  }
@@ -20344,7 +20336,7 @@ webpackJsonp([3],[
20344
  });
20345
  });
20346
 
20347
- return (_Utils$all$done$fail$always = Utils.all(promises).done(function () {
20348
  _this6._trigger('success');
20349
  }).fail(function () {
20350
  _this6.validationResult = false;
@@ -20352,7 +20344,7 @@ webpackJsonp([3],[
20352
  _this6._trigger('error');
20353
  }).always(function () {
20354
  _this6._trigger('validated');
20355
- })).pipe.apply(_Utils$all$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
20356
  },
20357
 
20358
  // Iterate over refreshed fields, and stop on first failure.
@@ -20361,7 +20353,7 @@ webpackJsonp([3],[
20361
  // Prefer using `whenValid` instead.
20362
  isValid: function isValid(options) {
20363
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
20364
- Utils.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');
20365
 
20366
  var _arguments2 = _slice.call(arguments);
20367
 
@@ -20391,7 +20383,7 @@ webpackJsonp([3],[
20391
  return field.whenValid({ group: group, force: force });
20392
  });
20393
  });
20394
- return Utils.all(promises);
20395
  },
20396
 
20397
  // Reset UI
@@ -20440,7 +20432,7 @@ webpackJsonp([3],[
20440
  }
20441
  });
20442
 
20443
- $.each(Utils.difference(oldFields, _this8.fields), function (_, field) {
20444
  field.reset();
20445
  });
20446
  });
@@ -20476,15 +20468,13 @@ webpackJsonp([3],[
20476
  var Constraint = function Constraint(parsleyField, name, requirements, priority, isDomConstraint) {
20477
  var validatorSpec = window.Parsley._validatorRegistry.validators[name];
20478
  var validator = new Validator(validatorSpec);
20479
- priority = priority || parsleyField.options[name + 'Priority'] || validator.priority;
20480
- isDomConstraint = true === isDomConstraint;
20481
 
20482
- _extends(this, {
20483
  validator: validator,
20484
  name: name,
20485
  requirements: requirements,
20486
- priority: priority,
20487
- isDomConstraint: isDomConstraint
20488
  });
20489
  this._parseRequirements(parsleyField.options);
20490
  };
@@ -20513,7 +20503,6 @@ webpackJsonp([3],[
20513
  var Field = function Field(field, domOptions, options, parsleyFormInstance) {
20514
  this.__class__ = 'Field';
20515
 
20516
- this.element = field;
20517
  this.$element = $(field);
20518
 
20519
  // Set parent if we have one
@@ -20542,7 +20531,7 @@ webpackJsonp([3],[
20542
  // `null` if validation is not finished. Prefer using whenValidate
20543
  validate: function validate(options) {
20544
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
20545
- Utils.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');
20546
  options = { options: options };
20547
  }
20548
  var promise = this.whenValidate(options);
@@ -20606,7 +20595,7 @@ webpackJsonp([3],[
20606
  },
20607
 
20608
  _isInGroup: function _isInGroup(group) {
20609
- if (Array.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group);
20610
  return this.options.group === group;
20611
  },
20612
 
@@ -20616,7 +20605,7 @@ webpackJsonp([3],[
20616
  // See also `whenValid`.
20617
  isValid: function isValid(options) {
20618
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
20619
- Utils.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');
20620
 
20621
  var _arguments3 = _slice.call(arguments);
20622
 
@@ -20667,13 +20656,13 @@ webpackJsonp([3],[
20667
  $.each(groupedConstraints, function (_, constraints) {
20668
  // Process one group of constraints at a time, we validate the constraints
20669
  // and combine the promises together.
20670
- var promise = Utils.all($.map(constraints, function (constraint) {
20671
  return _this11._validateConstraint(value, constraint);
20672
  }));
20673
  promises.push(promise);
20674
  if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed
20675
  });
20676
- return Utils.all(promises);
20677
  },
20678
 
20679
  // @returns a promise
@@ -20684,7 +20673,7 @@ webpackJsonp([3],[
20684
  // Map false to a failed promise
20685
  if (false === result) result = $.Deferred().reject();
20686
  // Make sure we return a promise and that we record failures
20687
- return Utils.all([result]).fail(function (errorMessage) {
20688
  if (!(_this12.validationResult instanceof Array)) _this12.validationResult = [];
20689
  _this12.validationResult.push({
20690
  assert: constraint,
@@ -20793,39 +20782,39 @@ webpackJsonp([3],[
20793
  // Bind specific HTML5 constraints to be HTML5 compliant
20794
  _bindHtml5Constraints: function _bindHtml5Constraints() {
20795
  // html5 required
20796
- if (null !== this.element.getAttribute('required')) this.addConstraint('required', true, undefined, true);
20797
 
20798
  // html5 pattern
20799
- if (null !== this.element.getAttribute('pattern')) this.addConstraint('pattern', this.element.getAttribute('pattern'), undefined, true);
20800
 
20801
  // range
20802
- var min = this.element.getAttribute('min');
20803
- var max = this.element.getAttribute('max');
20804
- if (null !== min && null !== max) this.addConstraint('range', [min, max], undefined, true);
20805
 
20806
  // HTML5 min
20807
- else if (null !== min) this.addConstraint('min', min, undefined, true);
20808
 
20809
  // HTML5 max
20810
- else if (null !== max) this.addConstraint('max', max, undefined, true);
20811
 
20812
  // length
20813
- if (null !== this.element.getAttribute('minlength') && null !== this.element.getAttribute('maxlength')) this.addConstraint('length', [this.element.getAttribute('minlength'), this.element.getAttribute('maxlength')], undefined, true);
20814
 
20815
  // HTML5 minlength
20816
- else if (null !== this.element.getAttribute('minlength')) this.addConstraint('minlength', this.element.getAttribute('minlength'), undefined, true);
20817
 
20818
  // HTML5 maxlength
20819
- else if (null !== this.element.getAttribute('maxlength')) this.addConstraint('maxlength', this.element.getAttribute('maxlength'), undefined, true);
20820
 
20821
  // html5 types
20822
- var type = this.element.type;
 
 
20823
 
20824
  // Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
20825
  if ('number' === type) {
20826
  return this.addConstraint('type', ['number', {
20827
- step: this.element.getAttribute('step') || '1',
20828
- base: min || this.element.getAttribute('value')
20829
  }], undefined, true);
20830
  // Regular other HTML5 supported types
20831
  } else if (/^(email|url|range|date)$/i.test(type)) {
@@ -20853,11 +20842,11 @@ webpackJsonp([3],[
20853
  // Use `data-parsley-whitespace="squish"` to auto squish input value
20854
  // Use `data-parsley-whitespace="trim"` to auto trim input value
20855
  _handleWhitespace: function _handleWhitespace(value) {
20856
- if (true === this.options.trimValue) Utils.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"');
20857
 
20858
  if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' ');
20859
 
20860
- if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = Utils.trimString(value);
20861
 
20862
  return value;
20863
  },
@@ -20913,7 +20902,7 @@ webpackJsonp([3],[
20913
  this.constraints = [];
20914
 
20915
  // Select multiple special treatment
20916
- if (this.element.nodeName === 'SELECT') {
20917
  this.actualizeOptions()._bindConstraints();
20918
 
20919
  return this;
@@ -20942,23 +20931,21 @@ webpackJsonp([3],[
20942
  if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value;
20943
 
20944
  // Radio input case
20945
- if (this.element.nodeName === 'INPUT') {
20946
- if (this.element.type === 'radio') return this._findRelated().filter(':checked').val() || '';
20947
 
20948
- // checkbox input case
20949
- if (this.element.type === 'checkbox') {
20950
- var values = [];
20951
 
20952
- this._findRelated().filter(':checked').each(function () {
20953
- values.push($(this).val());
20954
- });
20955
 
20956
- return values;
20957
- }
20958
  }
20959
 
20960
  // Select multiple case
20961
- if (this.element.nodeName === 'SELECT' && null === this.$element.val()) return [];
20962
 
20963
  // Default case that should never happen
20964
  return this.$element.val();
@@ -20972,7 +20959,6 @@ webpackJsonp([3],[
20972
  };
20973
 
20974
  var Factory = function Factory(element, options, parsleyFormInstance) {
20975
- this.element = element;
20976
  this.$element = $(element);
20977
 
20978
  // If the element has already been bound, returns its saved Parsley instance
@@ -20986,7 +20972,7 @@ webpackJsonp([3],[
20986
  }
20987
 
20988
  if ('object' === typeof options) {
20989
- _extends(savedparsleyFormInstance.options, options);
20990
  }
20991
 
20992
  return savedparsleyFormInstance;
@@ -21004,21 +20990,21 @@ webpackJsonp([3],[
21004
  Factory.prototype = {
21005
  init: function init(options) {
21006
  this.__class__ = 'Parsley';
21007
- this.__version__ = '2.7.2';
21008
- this.__id__ = Utils.generateID();
21009
 
21010
  // Pre-compute options
21011
  this._resetOptions(options);
21012
 
21013
  // A Form instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute
21014
- if (this.element.nodeName === 'FORM' || Utils.checkAttr(this.element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)) return this.bind('parsleyForm');
21015
 
21016
  // Every other element is bound as a `Field` or `FieldMultiple`
21017
  return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');
21018
  },
21019
 
21020
  isMultiple: function isMultiple() {
21021
- return this.element.type === 'radio' || this.element.type === 'checkbox' || this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple');
21022
  },
21023
 
21024
  // Multiples fields are a real nightmare :(
@@ -21031,16 +21017,17 @@ webpackJsonp([3],[
21031
  var parsleyMultipleInstance;
21032
 
21033
  // Handle multiple name
21034
- this.options.multiple = this.options.multiple || (name = this.element.getAttribute('name')) || this.element.getAttribute('id');
 
21035
 
21036
  // Special select multiple input
21037
- if (this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple')) {
21038
  this.options.multiple = this.options.multiple || this.__id__;
21039
  return this.bind('parsleyFieldMultiple');
21040
 
21041
  // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
21042
  } else if (!this.options.multiple) {
21043
- Utils.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
21044
  return this;
21045
  }
21046
 
@@ -21048,9 +21035,9 @@ webpackJsonp([3],[
21048
  this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
21049
 
21050
  // Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
21051
- if (name) {
21052
  $('input[name="' + name + '"]').each(function (i, input) {
21053
- if (input.type === 'radio' || input.type === 'checkbox') input.setAttribute(_this13.options.namespace + 'multiple', _this13.options.multiple);
21054
  });
21055
  }
21056
 
@@ -21081,19 +21068,19 @@ webpackJsonp([3],[
21081
 
21082
  switch (type) {
21083
  case 'parsleyForm':
21084
- parsleyInstance = $.extend(new Form(this.element, this.domOptions, this.options), new Base(), window.ParsleyExtend)._bindFields();
21085
  break;
21086
  case 'parsleyField':
21087
- parsleyInstance = $.extend(new parsley_field(this.element, this.domOptions, this.options, this.parent), new Base(), window.ParsleyExtend);
21088
  break;
21089
  case 'parsleyFieldMultiple':
21090
- parsleyInstance = $.extend(new parsley_field(this.element, this.domOptions, this.options, this.parent), new Multiple(), new Base(), window.ParsleyExtend)._init();
21091
  break;
21092
  default:
21093
  throw new Error(type + 'is not a supported Parsley type');
21094
  }
21095
 
21096
- if (this.options.multiple) Utils.setAttr(this.element, this.options.namespace, 'multiple', this.options.multiple);
21097
 
21098
  if ('undefined' !== typeof doNotStore) {
21099
  this.$element.data('FieldMultiple', parsleyInstance);
@@ -21117,24 +21104,23 @@ webpackJsonp([3],[
21117
  throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.";
21118
  }
21119
  if (!vernums.forEach) {
21120
- Utils.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');
21121
  }
21122
  // Inherit `on`, `off` & `trigger` to Parsley:
21123
- var Parsley = _extends(new Base(), {
21124
- element: document,
21125
  $element: $(document),
21126
  actualizeOptions: null,
21127
  _resetOptions: null,
21128
  Factory: Factory,
21129
- version: '2.7.2'
21130
  });
21131
 
21132
  // Supplement Field and Form with Base
21133
  // This way, the constructors will have access to those methods
21134
- _extends(parsley_field.prototype, UI.Field, Base.prototype);
21135
- _extends(Form.prototype, UI.Form, Base.prototype);
21136
  // Inherit actualizeOptions and _resetOptions:
21137
- _extends(Factory.prototype, Base.prototype);
21138
 
21139
  // ### jQuery API
21140
  // `$('.elem').parsley(options)` or `$('.elem').psly(options)`
@@ -21151,12 +21137,12 @@ webpackJsonp([3],[
21151
 
21152
  // Return undefined if applied to non existing DOM element
21153
  if (!$(this).length) {
21154
- Utils.warn('You must bind Parsley on an existing element.');
21155
 
21156
  return;
21157
  }
21158
 
21159
- return new Factory(this[0], options);
21160
  };
21161
 
21162
  // ### Field and Form extension
@@ -21165,18 +21151,18 @@ webpackJsonp([3],[
21165
 
21166
  // ### Parsley config
21167
  // Inherit from ParsleyDefault, and copy over any existing values
21168
- Parsley.options = _extends(Utils.objectCreate(Defaults), window.ParsleyConfig);
21169
  window.ParsleyConfig = Parsley.options; // Old way of accessing global options
21170
 
21171
  // ### Globals
21172
  window.Parsley = window.psly = Parsley;
21173
- Parsley.Utils = Utils;
21174
  window.ParsleyUtils = {};
21175
- $.each(Utils, function (key, value) {
21176
  if ('function' === typeof value) {
21177
  window.ParsleyUtils[key] = function () {
21178
- Utils.warnOnce('Accessing `window.ParsleyUtils` is deprecated. Use `window.Parsley.Utils` instead.');
21179
- return Utils[key].apply(Utils, arguments);
21180
  };
21181
  }
21182
  });
@@ -21185,13 +21171,11 @@ webpackJsonp([3],[
21185
  var registry = window.Parsley._validatorRegistry = new ValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
21186
  window.ParsleyValidator = {};
21187
  $.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator'.split(' '), function (i, method) {
21188
- window.Parsley[method] = function () {
21189
- return registry[method].apply(registry, arguments);
21190
- };
21191
  window.ParsleyValidator[method] = function () {
21192
  var _window$Parsley;
21193
 
21194
- Utils.warnOnce('Accessing the method \'' + method + '\' through Validator is deprecated. Simply call \'window.Parsley.' + method + '(...)\'');
21195
  return (_window$Parsley = window.Parsley)[method].apply(_window$Parsley, arguments);
21196
  };
21197
  });
@@ -21202,18 +21186,18 @@ webpackJsonp([3],[
21202
  window.ParsleyUI = {
21203
  removeError: function removeError(instance, name, doNotUpdateClass) {
21204
  var updateClass = true !== doNotUpdateClass;
21205
- Utils.warnOnce('Accessing UI is deprecated. Call \'removeError\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
21206
  return instance.removeError(name, { updateClass: updateClass });
21207
  },
21208
  getErrorsMessages: function getErrorsMessages(instance) {
21209
- Utils.warnOnce('Accessing UI is deprecated. Call \'getErrorsMessages\' on the instance directly.');
21210
  return instance.getErrorsMessages();
21211
  }
21212
  };
21213
  $.each('addError updateError'.split(' '), function (i, method) {
21214
  window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {
21215
  var updateClass = true !== doNotUpdateClass;
21216
- Utils.warnOnce('Accessing UI is deprecated. Call \'' + method + '\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
21217
  return instance[method](name, { message: message, assert: assert, updateClass: updateClass });
21218
  };
21219
  });
@@ -21229,7 +21213,7 @@ webpackJsonp([3],[
21229
 
21230
  var o = $({});
21231
  var deprecated = function deprecated() {
21232
- Utils.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley");
21233
  };
21234
 
21235
  // Returns an event handler that calls `fn` with the arguments it expects
@@ -21369,7 +21353,7 @@ webpackJsonp([3],[
21369
  if (url.indexOf('{value}') > -1) {
21370
  url = url.replace('{value}', encodeURIComponent(value));
21371
  } else {
21372
- data[instance.element.getAttribute('name') || instance.element.getAttribute('id')] = value;
21373
  }
21374
 
21375
  // Merge options passed in from the function with the ones in the attribute
@@ -21410,7 +21394,7 @@ webpackJsonp([3],[
21410
  Parsley._remoteCache = {};
21411
  });
21412
 
21413
- Base.prototype.addAsyncValidator = function () {
21414
  Utils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');
21415
  return Parsley.addAsyncValidator.apply(Parsley, arguments);
21416
  };
@@ -21459,7 +21443,7 @@ webpackJsonp([3],[
21459
 
21460
  // Slightly odd way construct our object. This way methods are force bound.
21461
  // Used to test for duplicate library.
21462
- _extends(this, {
21463
 
21464
  // For browsers that do not support isTrusted, assumes event is native.
21465
  isNativeEvent: function isNativeEvent(evt) {
19057
 
19058
  /* WEBPACK VAR INJECTION */(function(global) {/*!
19059
  * Parsley.js
19060
+ * Version 2.7.0 - built Wed, Mar 1st 2017, 3:53 pm
19061
  * http://parsleyjs.org
19062
  * Guillaume Potier - <guillaume@wisembly.com>
19063
  * Marc-Andre Lafortune - <petroselinum@marc-andre.ca>
19071
 
19072
  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
19073
 
 
 
19074
  function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }
19075
 
19076
  (function (global, factory) {
19081
  var globalID = 1;
19082
  var pastWarnings = {};
19083
 
19084
+ var Utils__Utils = {
19085
  // Parsley DOM-API
19086
  // returns object from dom attributes and values
19087
+ attr: function attr($element, namespace, obj) {
19088
  var i;
19089
  var attribute;
19090
  var attributes;
19097
  }
19098
  }
19099
 
19100
+ if ('undefined' === typeof $element || 'undefined' === typeof $element[0]) return obj;
19101
 
19102
+ attributes = $element[0].attributes;
19103
  for (i = attributes.length; i--;) {
19104
  attribute = attributes[i];
19105
 
19111
  return obj;
19112
  },
19113
 
19114
+ checkAttr: function checkAttr($element, namespace, _checkAttr) {
19115
+ return $element.is('[' + namespace + _checkAttr + ']');
19116
  },
19117
 
19118
+ setAttr: function setAttr($element, namespace, attr, value) {
19119
+ $element[0].setAttribute(this.dasherize(namespace + attr), String(value));
19120
  },
19121
 
19122
  generateID: function generateID() {
19203
  return !/^\s*false\s*$/i.test(string);
19204
  },
19205
  object: function object(string) {
19206
+ return Utils__Utils.deserializeValue(string);
19207
  },
19208
  regexp: function regexp(_regexp) {
19209
  var flags = '';
19275
  _SubmitSelector: 'input[type="submit"], button:submit'
19276
  };
19277
 
19278
+ var Utils__default = Utils__Utils;
19279
+
19280
  // All these options could be overriden and specified directly in DOM using
19281
  // `data-parsley-` default DOM-API
19282
  // eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
19343
  };
19344
 
19345
  var Base = function Base() {
19346
+ this.__id__ = Utils__default.generateID();
19347
  };
19348
 
19349
  Base.prototype = {
19361
  },
19362
 
19363
  actualizeOptions: function actualizeOptions() {
19364
+ Utils__default.attr(this.$element, this.options.namespace, this.domOptions);
19365
  if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions();
19366
  return this;
19367
  },
19368
 
19369
  _resetOptions: function _resetOptions(initOptions) {
19370
+ this.domOptions = Utils__default.objectCreate(this.parent.options);
19371
+ this.options = Utils__default.objectCreate(this.domOptions);
19372
  // Shallow copy of ownProperties of initOptions:
19373
  for (var i in initOptions) {
19374
  if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i];
19434
  },
19435
 
19436
  asyncIsValid: function asyncIsValid(group, force) {
19437
+ Utils__default.warnOnce("asyncIsValid is deprecated; please use whenValid instead");
19438
  return this.whenValid({ group: group, force: force });
19439
  },
19440
 
19441
  _findRelated: function _findRelated() {
19442
+ return this.options.multiple ? this.parent.$element.find('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]') : this.$element;
19443
  }
19444
  };
19445
 
19446
  var convertArrayRequirement = function convertArrayRequirement(string, length) {
19447
  var m = string.match(/^\s*\[(.*)\]\s*$/);
19448
  if (!m) throw 'Requirement is not an array: "' + string + '"';
19449
+ var values = m[1].split(',').map(Utils__default.trimString);
19450
  if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';
19451
  return values;
19452
  };
19457
  for (var key in requirementSpec) {
19458
  if (key) {
19459
  var value = extraOptionReader(key);
19460
+ if ('string' === typeof value) value = Utils__default.parseRequirement(requirementSpec[key], value);
19461
  extra[key] = value;
19462
  } else {
19463
+ main = Utils__default.parseRequirement(requirementSpec[key], string);
19464
  }
19465
  }
19466
  return [main, extra];
19483
  return this.fn(value, requirementFirstArg);
19484
  }
19485
 
19486
+ if ($.isArray(value)) {
19487
  if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values';
19488
  return this.validateMultiple.apply(this, arguments);
19489
  } else {
19490
  var instance = arguments[arguments.length - 1];
19491
  if (this.validateDate && instance._isDateInput()) {
19492
+ arguments[0] = Utils__default.parse.date(arguments[0]);
19493
  if (arguments[0] === null) return false;
19494
  return this.validateDate.apply(this, arguments);
19495
  }
19511
  if ('string' !== typeof requirements) {
19512
  // Assume requirement already parsed
19513
  // but make sure we return an array
19514
+ return $.isArray(requirements) ? requirements : [requirements];
19515
  }
19516
  var type = this.requirementType;
19517
+ if ($.isArray(type)) {
19518
  var values = convertArrayRequirement(requirements, type.length);
19519
+ for (var i = 0; i < values.length; i++) values[i] = Utils__default.parseRequirement(type[i], values[i]);
19520
  return values;
19521
  } else if ($.isPlainObject(type)) {
19522
  return convertExtraOptionRequirement(type, requirements, extraOptionReader);
19523
  } else {
19524
+ return [Utils__default.parseRequirement(type, requirements)];
19525
  }
19526
  },
19527
  // Defaults:
19554
 
19555
  date: {
19556
  test: function test(value) {
19557
+ return Utils__default.parse.date(value) !== null;
19558
  }
19559
  },
19560
 
19602
 
19603
  // parseArguments('number', ['1', '2']) => [1, 2]
19604
  var ValidatorRegistry__parseArguments = function ValidatorRegistry__parseArguments(type, args) {
19605
+ return args.map(Utils__default.parse[type]);
19606
  };
19607
  // operatorToValidator returns a validating function for an operator function, applied to the given type
19608
  var ValidatorRegistry__operatorToValidator = function ValidatorRegistry__operatorToValidator(type, operator) {
19629
  init: function init(validators, catalog) {
19630
  this.catalog = catalog;
19631
  // Copy prototype's validators:
19632
+ this.validators = $.extend({}, this.validators);
19633
 
19634
  for (var name in validators) this.addValidator(name, validators[name].fn, validators[name].priority);
19635
 
19685
  // Old API was addValidator(name, function, priority)
19686
  //
19687
  addValidator: function addValidator(name, arg1, arg2) {
19688
+ if (this.validators[name]) Utils__default.warn('Validator "' + name + '" is already defined.');else if (Defaults.hasOwnProperty(name)) {
19689
+ Utils__default.warn('"' + name + '" is a restricted keyword and is not a valid validator name.');
19690
  return;
19691
  }
19692
  return this._setValidator.apply(this, arguments);
19694
 
19695
  updateValidator: function updateValidator(name, arg1, arg2) {
19696
  if (!this.validators[name]) {
19697
+ Utils__default.warn('Validator "' + name + '" is not already defined.');
19698
  return this.addValidator.apply(this, arguments);
19699
  }
19700
  return this._setValidator.apply(this, arguments);
19701
  },
19702
 
19703
  removeValidator: function removeValidator(name) {
19704
+ if (!this.validators[name]) Utils__default.warn('Validator "' + name + '" is not defined.');
19705
 
19706
  delete this.validators[name];
19707
 
19910
  this.$element.on('submit.Parsley', function (evt) {
19911
  _this2.onSubmitValidate(evt);
19912
  });
19913
+ this.$element.on('click.Parsley', Utils__default._SubmitSelector, function (evt) {
19914
  _this2.onSubmitButton(evt);
19915
  });
19916
 
19917
  // UI could be disabled
19918
  if (false === this.options.uiEnabled) return;
19919
 
19920
+ this.$element.attr('novalidate', '');
19921
  },
19922
 
19923
  focus: function focus() {
20094
  var _ui = {};
20095
 
20096
  // Give field its Parsley id in DOM
20097
+ this.$element.attr(this.options.namespace + 'id', this.__id__);
20098
 
20099
  /** Generate important UI elements and store them in this **/
20100
  // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
20115
  // Determine which element will have `parsley-error` and `parsley-success` classes
20116
  _manageClassHandler: function _manageClassHandler() {
20117
  // An element selector could be passed through DOM with `data-parsley-class-handler=#foo`
20118
+ if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length) return $(this.options.classHandler);
 
 
 
 
 
20119
 
20120
  // Class handled could also be determined by function given in Parsley options
20121
+ var $handler = this.options.classHandler.call(this, this);
20122
 
20123
  // If this function returned a valid existing DOM element, go for it
20124
  if ('undefined' !== typeof $handler && $handler.length) return $handler;
20128
 
20129
  _inputHolder: function _inputHolder() {
20130
  // if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container
20131
+ if (!this.options.multiple || this.$element.is('select')) return this.$element;
20132
 
20133
  // But if multiple element (radio, checkbox), that would be their parent
20134
  return this.$element.parent();
20141
  if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent();
20142
 
20143
  if ('string' === typeof this.options.errorsContainer) {
20144
+ if ($(this.options.errorsContainer).length) return $(this.options.errorsContainer).append(this._ui.$errorsWrapper);else Utils__default.warn('The errors container `' + this.options.errorsContainer + '` does not exist in DOM');
20145
  } else if ('function' === typeof this.options.errorsContainer) $errorsContainer = this.options.errorsContainer.call(this, this);
20146
 
20147
  if ('undefined' !== typeof $errorsContainer && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper);
20157
 
20158
  // Remove Parsley events already bound on this field
20159
  $toBind.off('.Parsley');
20160
+ if (this._failedOnce) $toBind.on(Utils__default.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () {
20161
  _this3._validateIfNeeded();
20162
+ });else if (trigger = Utils__default.namespaceEvents(this.options.trigger, 'Parsley')) {
20163
  $toBind.on(trigger, function (event) {
20164
  _this3._validateIfNeeded(event);
20165
  });
20225
  var Form = function Form(element, domOptions, options) {
20226
  this.__class__ = 'Form';
20227
 
 
20228
  this.$element = $(element);
20229
  this.domOptions = domOptions;
20230
  this.options = options;
20244
  if (true === event.parsley) return;
20245
 
20246
  // If we didn't come here through a submit button, use the first one in the form
20247
+ var $submitSource = this._$submitSource || this.$element.find(Utils__default._SubmitSelector).first();
20248
+ this._$submitSource = null;
20249
  this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);
20250
+ if ($submitSource.is('[formnovalidate]')) return;
 
 
20251
 
20252
  var promise = this.whenValidate({ event: event });
20253
 
20259
  event.stopImmediatePropagation();
20260
  event.preventDefault();
20261
  if ('pending' === promise.state()) promise.done(function () {
20262
+ _this5._submit($submitSource);
20263
  });
20264
  }
20265
  },
20266
 
20267
  onSubmitButton: function onSubmitButton(event) {
20268
+ this._$submitSource = $(event.currentTarget);
20269
  },
20270
  // internal
20271
  // _submit submits the form, this time without going through the validations.
20272
  // Care must be taken to "fake" the actual submit button being clicked.
20273
+ _submit: function _submit($submitSource) {
20274
  if (false === this._trigger('submit')) return;
20275
  // Add submit button's data
20276
+ if ($submitSource) {
20277
  var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);
20278
  if (0 === $synthetic.length) $synthetic = $('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element);
20279
  $synthetic.attr({
20280
+ name: $submitSource.attr('name'),
20281
+ value: $submitSource.attr('value')
20282
  });
20283
  }
20284
 
20285
+ this.$element.trigger($.extend($.Event('submit'), { parsley: true }));
20286
  },
20287
 
20288
  // Performs validation on fields while triggering events.
20292
  // Consider using `whenValidate` instead.
20293
  validate: function validate(options) {
20294
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
20295
+ Utils__default.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');
20296
 
20297
  var _arguments = _slice.call(arguments);
20298
 
20306
  },
20307
 
20308
  whenValidate: function whenValidate() {
20309
+ var _Utils__default$all$done$fail$always,
20310
  _this6 = this;
20311
 
20312
  var _ref7 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
20317
 
20318
  this.submitEvent = event;
20319
  if (event) {
20320
+ this.submitEvent = $.extend({}, event, { preventDefault: function preventDefault() {
20321
+ Utils__default.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
20322
  _this6.validationResult = false;
20323
  } });
20324
  }
20336
  });
20337
  });
20338
 
20339
+ return (_Utils__default$all$done$fail$always = Utils__default.all(promises).done(function () {
20340
  _this6._trigger('success');
20341
  }).fail(function () {
20342
  _this6.validationResult = false;
20344
  _this6._trigger('error');
20345
  }).always(function () {
20346
  _this6._trigger('validated');
20347
+ })).pipe.apply(_Utils__default$all$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
20348
  },
20349
 
20350
  // Iterate over refreshed fields, and stop on first failure.
20353
  // Prefer using `whenValid` instead.
20354
  isValid: function isValid(options) {
20355
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
20356
+ Utils__default.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');
20357
 
20358
  var _arguments2 = _slice.call(arguments);
20359
 
20383
  return field.whenValid({ group: group, force: force });
20384
  });
20385
  });
20386
+ return Utils__default.all(promises);
20387
  },
20388
 
20389
  // Reset UI
20432
  }
20433
  });
20434
 
20435
+ $.each(Utils__default.difference(oldFields, _this8.fields), function (_, field) {
20436
  field.reset();
20437
  });
20438
  });
20468
  var Constraint = function Constraint(parsleyField, name, requirements, priority, isDomConstraint) {
20469
  var validatorSpec = window.Parsley._validatorRegistry.validators[name];
20470
  var validator = new Validator(validatorSpec);
 
 
20471
 
20472
+ $.extend(this, {
20473
  validator: validator,
20474
  name: name,
20475
  requirements: requirements,
20476
+ priority: priority || parsleyField.options[name + 'Priority'] || validator.priority,
20477
+ isDomConstraint: true === isDomConstraint
20478
  });
20479
  this._parseRequirements(parsleyField.options);
20480
  };
20503
  var Field = function Field(field, domOptions, options, parsleyFormInstance) {
20504
  this.__class__ = 'Field';
20505
 
 
20506
  this.$element = $(field);
20507
 
20508
  // Set parent if we have one
20531
  // `null` if validation is not finished. Prefer using whenValidate
20532
  validate: function validate(options) {
20533
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
20534
+ Utils__default.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');
20535
  options = { options: options };
20536
  }
20537
  var promise = this.whenValidate(options);
20595
  },
20596
 
20597
  _isInGroup: function _isInGroup(group) {
20598
+ if ($.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group);
20599
  return this.options.group === group;
20600
  },
20601
 
20605
  // See also `whenValid`.
20606
  isValid: function isValid(options) {
20607
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
20608
+ Utils__default.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');
20609
 
20610
  var _arguments3 = _slice.call(arguments);
20611
 
20656
  $.each(groupedConstraints, function (_, constraints) {
20657
  // Process one group of constraints at a time, we validate the constraints
20658
  // and combine the promises together.
20659
+ var promise = Utils__default.all($.map(constraints, function (constraint) {
20660
  return _this11._validateConstraint(value, constraint);
20661
  }));
20662
  promises.push(promise);
20663
  if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed
20664
  });
20665
+ return Utils__default.all(promises);
20666
  },
20667
 
20668
  // @returns a promise
20673
  // Map false to a failed promise
20674
  if (false === result) result = $.Deferred().reject();
20675
  // Make sure we return a promise and that we record failures
20676
+ return Utils__default.all([result]).fail(function (errorMessage) {
20677
  if (!(_this12.validationResult instanceof Array)) _this12.validationResult = [];
20678
  _this12.validationResult.push({
20679
  assert: constraint,
20782
  // Bind specific HTML5 constraints to be HTML5 compliant
20783
  _bindHtml5Constraints: function _bindHtml5Constraints() {
20784
  // html5 required
20785
+ if (this.$element.attr('required')) this.addConstraint('required', true, undefined, true);
20786
 
20787
  // html5 pattern
20788
+ if ('string' === typeof this.$element.attr('pattern')) this.addConstraint('pattern', this.$element.attr('pattern'), undefined, true);
20789
 
20790
  // range
20791
+ if ('undefined' !== typeof this.$element.attr('min') && 'undefined' !== typeof this.$element.attr('max')) this.addConstraint('range', [this.$element.attr('min'), this.$element.attr('max')], undefined, true);
 
 
20792
 
20793
  // HTML5 min
20794
+ else if ('undefined' !== typeof this.$element.attr('min')) this.addConstraint('min', this.$element.attr('min'), undefined, true);
20795
 
20796
  // HTML5 max
20797
+ else if ('undefined' !== typeof this.$element.attr('max')) this.addConstraint('max', this.$element.attr('max'), undefined, true);
20798
 
20799
  // length
20800
+ if ('undefined' !== typeof this.$element.attr('minlength') && 'undefined' !== typeof this.$element.attr('maxlength')) this.addConstraint('length', [this.$element.attr('minlength'), this.$element.attr('maxlength')], undefined, true);
20801
 
20802
  // HTML5 minlength
20803
+ else if ('undefined' !== typeof this.$element.attr('minlength')) this.addConstraint('minlength', this.$element.attr('minlength'), undefined, true);
20804
 
20805
  // HTML5 maxlength
20806
+ else if ('undefined' !== typeof this.$element.attr('maxlength')) this.addConstraint('maxlength', this.$element.attr('maxlength'), undefined, true);
20807
 
20808
  // html5 types
20809
+ var type = this.$element.attr('type');
20810
+
20811
+ if ('undefined' === typeof type) return this;
20812
 
20813
  // Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
20814
  if ('number' === type) {
20815
  return this.addConstraint('type', ['number', {
20816
+ step: this.$element.attr('step') || '1',
20817
+ base: this.$element.attr('min') || this.$element.attr('value')
20818
  }], undefined, true);
20819
  // Regular other HTML5 supported types
20820
  } else if (/^(email|url|range|date)$/i.test(type)) {
20842
  // Use `data-parsley-whitespace="squish"` to auto squish input value
20843
  // Use `data-parsley-whitespace="trim"` to auto trim input value
20844
  _handleWhitespace: function _handleWhitespace(value) {
20845
+ if (true === this.options.trimValue) Utils__default.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"');
20846
 
20847
  if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' ');
20848
 
20849
+ if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = Utils__default.trimString(value);
20850
 
20851
  return value;
20852
  },
20902
  this.constraints = [];
20903
 
20904
  // Select multiple special treatment
20905
+ if (this.$element.is('select')) {
20906
  this.actualizeOptions()._bindConstraints();
20907
 
20908
  return this;
20931
  if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value;
20932
 
20933
  // Radio input case
20934
+ if (this.$element.is('input[type=radio]')) return this._findRelated().filter(':checked').val() || '';
 
20935
 
20936
+ // checkbox input case
20937
+ if (this.$element.is('input[type=checkbox]')) {
20938
+ var values = [];
20939
 
20940
+ this._findRelated().filter(':checked').each(function () {
20941
+ values.push($(this).val());
20942
+ });
20943
 
20944
+ return values;
 
20945
  }
20946
 
20947
  // Select multiple case
20948
+ if (this.$element.is('select') && null === this.$element.val()) return [];
20949
 
20950
  // Default case that should never happen
20951
  return this.$element.val();
20959
  };
20960
 
20961
  var Factory = function Factory(element, options, parsleyFormInstance) {
 
20962
  this.$element = $(element);
20963
 
20964
  // If the element has already been bound, returns its saved Parsley instance
20972
  }
20973
 
20974
  if ('object' === typeof options) {
20975
+ $.extend(savedparsleyFormInstance.options, options);
20976
  }
20977
 
20978
  return savedparsleyFormInstance;
20990
  Factory.prototype = {
20991
  init: function init(options) {
20992
  this.__class__ = 'Parsley';
20993
+ this.__version__ = '2.7.0';
20994
+ this.__id__ = Utils__default.generateID();
20995
 
20996
  // Pre-compute options
20997
  this._resetOptions(options);
20998
 
20999
  // A Form instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute
21000
+ if (this.$element.is('form') || Utils__default.checkAttr(this.$element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)) return this.bind('parsleyForm');
21001
 
21002
  // Every other element is bound as a `Field` or `FieldMultiple`
21003
  return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');
21004
  },
21005
 
21006
  isMultiple: function isMultiple() {
21007
+ return this.$element.is('input[type=radio], input[type=checkbox]') || this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple');
21008
  },
21009
 
21010
  // Multiples fields are a real nightmare :(
21017
  var parsleyMultipleInstance;
21018
 
21019
  // Handle multiple name
21020
+ if (this.options.multiple) ; // We already have our 'multiple' identifier
21021
+ else if ('undefined' !== typeof this.$element.attr('name') && this.$element.attr('name').length) this.options.multiple = name = this.$element.attr('name');else if ('undefined' !== typeof this.$element.attr('id') && this.$element.attr('id').length) this.options.multiple = this.$element.attr('id');
21022
 
21023
  // Special select multiple input
21024
+ if (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple')) {
21025
  this.options.multiple = this.options.multiple || this.__id__;
21026
  return this.bind('parsleyFieldMultiple');
21027
 
21028
  // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
21029
  } else if (!this.options.multiple) {
21030
+ Utils__default.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
21031
  return this;
21032
  }
21033
 
21035
  this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
21036
 
21037
  // Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
21038
+ if ('undefined' !== typeof name) {
21039
  $('input[name="' + name + '"]').each(function (i, input) {
21040
+ if ($(input).is('input[type=radio], input[type=checkbox]')) $(input).attr(_this13.options.namespace + 'multiple', _this13.options.multiple);
21041
  });
21042
  }
21043
 
21068
 
21069
  switch (type) {
21070
  case 'parsleyForm':
21071
+ parsleyInstance = $.extend(new Form(this.$element, this.domOptions, this.options), new Base(), window.ParsleyExtend)._bindFields();
21072
  break;
21073
  case 'parsleyField':
21074
+ parsleyInstance = $.extend(new parsley_field(this.$element, this.domOptions, this.options, this.parent), new Base(), window.ParsleyExtend);
21075
  break;
21076
  case 'parsleyFieldMultiple':
21077
+ parsleyInstance = $.extend(new parsley_field(this.$element, this.domOptions, this.options, this.parent), new Multiple(), new Base(), window.ParsleyExtend)._init();
21078
  break;
21079
  default:
21080
  throw new Error(type + 'is not a supported Parsley type');
21081
  }
21082
 
21083
+ if (this.options.multiple) Utils__default.setAttr(this.$element, this.options.namespace, 'multiple', this.options.multiple);
21084
 
21085
  if ('undefined' !== typeof doNotStore) {
21086
  this.$element.data('FieldMultiple', parsleyInstance);
21104
  throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.";
21105
  }
21106
  if (!vernums.forEach) {
21107
+ Utils__default.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');
21108
  }
21109
  // Inherit `on`, `off` & `trigger` to Parsley:
21110
+ var Parsley = $.extend(new Base(), {
 
21111
  $element: $(document),
21112
  actualizeOptions: null,
21113
  _resetOptions: null,
21114
  Factory: Factory,
21115
+ version: '2.7.0'
21116
  });
21117
 
21118
  // Supplement Field and Form with Base
21119
  // This way, the constructors will have access to those methods
21120
+ $.extend(parsley_field.prototype, UI.Field, Base.prototype);
21121
+ $.extend(Form.prototype, UI.Form, Base.prototype);
21122
  // Inherit actualizeOptions and _resetOptions:
21123
+ $.extend(Factory.prototype, Base.prototype);
21124
 
21125
  // ### jQuery API
21126
  // `$('.elem').parsley(options)` or `$('.elem').psly(options)`
21137
 
21138
  // Return undefined if applied to non existing DOM element
21139
  if (!$(this).length) {
21140
+ Utils__default.warn('You must bind Parsley on an existing element.');
21141
 
21142
  return;
21143
  }
21144
 
21145
+ return new Factory(this, options);
21146
  };
21147
 
21148
  // ### Field and Form extension
21151
 
21152
  // ### Parsley config
21153
  // Inherit from ParsleyDefault, and copy over any existing values
21154
+ Parsley.options = $.extend(Utils__default.objectCreate(Defaults), window.ParsleyConfig);
21155
  window.ParsleyConfig = Parsley.options; // Old way of accessing global options
21156
 
21157
  // ### Globals
21158
  window.Parsley = window.psly = Parsley;
21159
+ Parsley.Utils = Utils__default;
21160
  window.ParsleyUtils = {};
21161
+ $.each(Utils__default, function (key, value) {
21162
  if ('function' === typeof value) {
21163
  window.ParsleyUtils[key] = function () {
21164
+ Utils__default.warnOnce('Accessing `window.ParsleyUtils` is deprecated. Use `window.Parsley.Utils` instead.');
21165
+ return Utils__default[key].apply(Utils__default, arguments);
21166
  };
21167
  }
21168
  });
21171
  var registry = window.Parsley._validatorRegistry = new ValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
21172
  window.ParsleyValidator = {};
21173
  $.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator'.split(' '), function (i, method) {
21174
+ window.Parsley[method] = $.proxy(registry, method);
 
 
21175
  window.ParsleyValidator[method] = function () {
21176
  var _window$Parsley;
21177
 
21178
+ Utils__default.warnOnce('Accessing the method \'' + method + '\' through Validator is deprecated. Simply call \'window.Parsley.' + method + '(...)\'');
21179
  return (_window$Parsley = window.Parsley)[method].apply(_window$Parsley, arguments);
21180
  };
21181
  });
21186
  window.ParsleyUI = {
21187
  removeError: function removeError(instance, name, doNotUpdateClass) {
21188
  var updateClass = true !== doNotUpdateClass;
21189
+ Utils__default.warnOnce('Accessing UI is deprecated. Call \'removeError\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
21190
  return instance.removeError(name, { updateClass: updateClass });
21191
  },
21192
  getErrorsMessages: function getErrorsMessages(instance) {
21193
+ Utils__default.warnOnce('Accessing UI is deprecated. Call \'getErrorsMessages\' on the instance directly.');
21194
  return instance.getErrorsMessages();
21195
  }
21196
  };
21197
  $.each('addError updateError'.split(' '), function (i, method) {
21198
  window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {
21199
  var updateClass = true !== doNotUpdateClass;
21200
+ Utils__default.warnOnce('Accessing UI is deprecated. Call \'' + method + '\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
21201
  return instance[method](name, { message: message, assert: assert, updateClass: updateClass });
21202
  };
21203
  });
21213
 
21214
  var o = $({});
21215
  var deprecated = function deprecated() {
21216
+ Utils__default.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley");
21217
  };
21218
 
21219
  // Returns an event handler that calls `fn` with the arguments it expects
21353
  if (url.indexOf('{value}') > -1) {
21354
  url = url.replace('{value}', encodeURIComponent(value));
21355
  } else {
21356
+ data[instance.$element.attr('name') || instance.$element.attr('id')] = value;
21357
  }
21358
 
21359
  // Merge options passed in from the function with the ones in the attribute
21394
  Parsley._remoteCache = {};
21395
  });
21396
 
21397
+ window.ParsleyExtend.addAsyncValidator = function () {
21398
  Utils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');
21399
  return Parsley.addAsyncValidator.apply(Parsley, arguments);
21400
  };
21443
 
21444
  // Slightly odd way construct our object. This way methods are force bound.
21445
  // Used to test for duplicate library.
21446
+ $.extend(this, {
21447
 
21448
  // For browsers that do not support isTrusted, assumes event is native.
21449
  isNativeEvent: function isNativeEvent(evt) {
assets/js/public.js CHANGED
@@ -1948,7 +1948,7 @@
1948
 
1949
  /* WEBPACK VAR INJECTION */(function(global) {/*!
1950
  * Parsley.js
1951
- * Version 2.7.2 - built Tue, May 9th 2017, 11:21 am
1952
  * http://parsleyjs.org
1953
  * Guillaume Potier - <guillaume@wisembly.com>
1954
  * Marc-Andre Lafortune - <petroselinum@marc-andre.ca>
@@ -1962,8 +1962,6 @@
1962
 
1963
  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
1964
 
1965
- var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
1966
-
1967
  function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }
1968
 
1969
  (function (global, factory) {
@@ -1974,10 +1972,10 @@
1974
  var globalID = 1;
1975
  var pastWarnings = {};
1976
 
1977
- var Utils = {
1978
  // Parsley DOM-API
1979
  // returns object from dom attributes and values
1980
- attr: function attr(element, namespace, obj) {
1981
  var i;
1982
  var attribute;
1983
  var attributes;
@@ -1990,9 +1988,9 @@
1990
  }
1991
  }
1992
 
1993
- if (!element) return obj;
1994
 
1995
- attributes = element.attributes;
1996
  for (i = attributes.length; i--;) {
1997
  attribute = attributes[i];
1998
 
@@ -2004,12 +2002,12 @@
2004
  return obj;
2005
  },
2006
 
2007
- checkAttr: function checkAttr(element, namespace, _checkAttr) {
2008
- return element.hasAttribute(namespace + _checkAttr);
2009
  },
2010
 
2011
- setAttr: function setAttr(element, namespace, attr, value) {
2012
- element.setAttribute(this.dasherize(namespace + attr), String(value));
2013
  },
2014
 
2015
  generateID: function generateID() {
@@ -2096,7 +2094,7 @@
2096
  return !/^\s*false\s*$/i.test(string);
2097
  },
2098
  object: function object(string) {
2099
- return Utils.deserializeValue(string);
2100
  },
2101
  regexp: function regexp(_regexp) {
2102
  var flags = '';
@@ -2168,6 +2166,8 @@
2168
  _SubmitSelector: 'input[type="submit"], button:submit'
2169
  };
2170
 
 
 
2171
  // All these options could be overriden and specified directly in DOM using
2172
  // `data-parsley-` default DOM-API
2173
  // eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
@@ -2234,7 +2234,7 @@
2234
  };
2235
 
2236
  var Base = function Base() {
2237
- this.__id__ = Utils.generateID();
2238
  };
2239
 
2240
  Base.prototype = {
@@ -2252,14 +2252,14 @@
2252
  },
2253
 
2254
  actualizeOptions: function actualizeOptions() {
2255
- Utils.attr(this.element, this.options.namespace, this.domOptions);
2256
  if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions();
2257
  return this;
2258
  },
2259
 
2260
  _resetOptions: function _resetOptions(initOptions) {
2261
- this.domOptions = Utils.objectCreate(this.parent.options);
2262
- this.options = Utils.objectCreate(this.domOptions);
2263
  // Shallow copy of ownProperties of initOptions:
2264
  for (var i in initOptions) {
2265
  if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i];
@@ -2325,19 +2325,19 @@
2325
  },
2326
 
2327
  asyncIsValid: function asyncIsValid(group, force) {
2328
- Utils.warnOnce("asyncIsValid is deprecated; please use whenValid instead");
2329
  return this.whenValid({ group: group, force: force });
2330
  },
2331
 
2332
  _findRelated: function _findRelated() {
2333
- return this.options.multiple ? $(this.parent.element.querySelectorAll('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]')) : this.$element;
2334
  }
2335
  };
2336
 
2337
  var convertArrayRequirement = function convertArrayRequirement(string, length) {
2338
  var m = string.match(/^\s*\[(.*)\]\s*$/);
2339
  if (!m) throw 'Requirement is not an array: "' + string + '"';
2340
- var values = m[1].split(',').map(Utils.trimString);
2341
  if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';
2342
  return values;
2343
  };
@@ -2348,10 +2348,10 @@
2348
  for (var key in requirementSpec) {
2349
  if (key) {
2350
  var value = extraOptionReader(key);
2351
- if ('string' === typeof value) value = Utils.parseRequirement(requirementSpec[key], value);
2352
  extra[key] = value;
2353
  } else {
2354
- main = Utils.parseRequirement(requirementSpec[key], string);
2355
  }
2356
  }
2357
  return [main, extra];
@@ -2374,13 +2374,13 @@
2374
  return this.fn(value, requirementFirstArg);
2375
  }
2376
 
2377
- if (Array.isArray(value)) {
2378
  if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values';
2379
  return this.validateMultiple.apply(this, arguments);
2380
  } else {
2381
  var instance = arguments[arguments.length - 1];
2382
  if (this.validateDate && instance._isDateInput()) {
2383
- arguments[0] = Utils.parse.date(arguments[0]);
2384
  if (arguments[0] === null) return false;
2385
  return this.validateDate.apply(this, arguments);
2386
  }
@@ -2402,17 +2402,17 @@
2402
  if ('string' !== typeof requirements) {
2403
  // Assume requirement already parsed
2404
  // but make sure we return an array
2405
- return Array.isArray(requirements) ? requirements : [requirements];
2406
  }
2407
  var type = this.requirementType;
2408
- if (Array.isArray(type)) {
2409
  var values = convertArrayRequirement(requirements, type.length);
2410
- for (var i = 0; i < values.length; i++) values[i] = Utils.parseRequirement(type[i], values[i]);
2411
  return values;
2412
  } else if ($.isPlainObject(type)) {
2413
  return convertExtraOptionRequirement(type, requirements, extraOptionReader);
2414
  } else {
2415
- return [Utils.parseRequirement(type, requirements)];
2416
  }
2417
  },
2418
  // Defaults:
@@ -2445,7 +2445,7 @@
2445
 
2446
  date: {
2447
  test: function test(value) {
2448
- return Utils.parse.date(value) !== null;
2449
  }
2450
  },
2451
 
@@ -2493,7 +2493,7 @@
2493
 
2494
  // parseArguments('number', ['1', '2']) => [1, 2]
2495
  var ValidatorRegistry__parseArguments = function ValidatorRegistry__parseArguments(type, args) {
2496
- return args.map(Utils.parse[type]);
2497
  };
2498
  // operatorToValidator returns a validating function for an operator function, applied to the given type
2499
  var ValidatorRegistry__operatorToValidator = function ValidatorRegistry__operatorToValidator(type, operator) {
@@ -2520,7 +2520,7 @@
2520
  init: function init(validators, catalog) {
2521
  this.catalog = catalog;
2522
  // Copy prototype's validators:
2523
- this.validators = _extends({}, this.validators);
2524
 
2525
  for (var name in validators) this.addValidator(name, validators[name].fn, validators[name].priority);
2526
 
@@ -2576,8 +2576,8 @@
2576
  // Old API was addValidator(name, function, priority)
2577
  //
2578
  addValidator: function addValidator(name, arg1, arg2) {
2579
- if (this.validators[name]) Utils.warn('Validator "' + name + '" is already defined.');else if (Defaults.hasOwnProperty(name)) {
2580
- Utils.warn('"' + name + '" is a restricted keyword and is not a valid validator name.');
2581
  return;
2582
  }
2583
  return this._setValidator.apply(this, arguments);
@@ -2585,14 +2585,14 @@
2585
 
2586
  updateValidator: function updateValidator(name, arg1, arg2) {
2587
  if (!this.validators[name]) {
2588
- Utils.warn('Validator "' + name + '" is not already defined.');
2589
  return this.addValidator.apply(this, arguments);
2590
  }
2591
  return this._setValidator.apply(this, arguments);
2592
  },
2593
 
2594
  removeValidator: function removeValidator(name) {
2595
- if (!this.validators[name]) Utils.warn('Validator "' + name + '" is not defined.');
2596
 
2597
  delete this.validators[name];
2598
 
@@ -2801,14 +2801,14 @@
2801
  this.$element.on('submit.Parsley', function (evt) {
2802
  _this2.onSubmitValidate(evt);
2803
  });
2804
- this.$element.on('click.Parsley', Utils._SubmitSelector, function (evt) {
2805
  _this2.onSubmitButton(evt);
2806
  });
2807
 
2808
  // UI could be disabled
2809
  if (false === this.options.uiEnabled) return;
2810
 
2811
- this.element.setAttribute('novalidate', '');
2812
  },
2813
 
2814
  focus: function focus() {
@@ -2985,7 +2985,7 @@
2985
  var _ui = {};
2986
 
2987
  // Give field its Parsley id in DOM
2988
- this.element.setAttribute(this.options.namespace + 'id', this.__id__);
2989
 
2990
  /** Generate important UI elements and store them in this **/
2991
  // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
@@ -3006,15 +3006,10 @@
3006
  // Determine which element will have `parsley-error` and `parsley-success` classes
3007
  _manageClassHandler: function _manageClassHandler() {
3008
  // An element selector could be passed through DOM with `data-parsley-class-handler=#foo`
3009
- if ('string' === typeof this.options.classHandler) {
3010
- if ($(this.options.classHandler).length === 0) ParsleyUtils.warn('No elements found that match the selector `' + this.options.classHandler + '` set in options.classHandler or data-parsley-class-handler');
3011
-
3012
- //return element or empty set
3013
- return $(this.options.classHandler);
3014
- }
3015
 
3016
  // Class handled could also be determined by function given in Parsley options
3017
- if ('function' === typeof this.options.classHandler) var $handler = this.options.classHandler.call(this, this);
3018
 
3019
  // If this function returned a valid existing DOM element, go for it
3020
  if ('undefined' !== typeof $handler && $handler.length) return $handler;
@@ -3024,7 +3019,7 @@
3024
 
3025
  _inputHolder: function _inputHolder() {
3026
  // if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container
3027
- if (!this.options.multiple || this.element.nodeName === 'SELECT') return this.$element;
3028
 
3029
  // But if multiple element (radio, checkbox), that would be their parent
3030
  return this.$element.parent();
@@ -3037,7 +3032,7 @@
3037
  if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent();
3038
 
3039
  if ('string' === typeof this.options.errorsContainer) {
3040
- if ($(this.options.errorsContainer).length) return $(this.options.errorsContainer).append(this._ui.$errorsWrapper);else Utils.warn('The errors container `' + this.options.errorsContainer + '` does not exist in DOM');
3041
  } else if ('function' === typeof this.options.errorsContainer) $errorsContainer = this.options.errorsContainer.call(this, this);
3042
 
3043
  if ('undefined' !== typeof $errorsContainer && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper);
@@ -3053,9 +3048,9 @@
3053
 
3054
  // Remove Parsley events already bound on this field
3055
  $toBind.off('.Parsley');
3056
- if (this._failedOnce) $toBind.on(Utils.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () {
3057
  _this3._validateIfNeeded();
3058
- });else if (trigger = Utils.namespaceEvents(this.options.trigger, 'Parsley')) {
3059
  $toBind.on(trigger, function (event) {
3060
  _this3._validateIfNeeded(event);
3061
  });
@@ -3121,7 +3116,6 @@
3121
  var Form = function Form(element, domOptions, options) {
3122
  this.__class__ = 'Form';
3123
 
3124
- this.element = element;
3125
  this.$element = $(element);
3126
  this.domOptions = domOptions;
3127
  this.options = options;
@@ -3141,12 +3135,10 @@
3141
  if (true === event.parsley) return;
3142
 
3143
  // If we didn't come here through a submit button, use the first one in the form
3144
- var submitSource = this._submitSource || this.$element.find(Utils._SubmitSelector)[0];
3145
- this._submitSource = null;
3146
  this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);
3147
- if (submitSource && null !== submitSource.getAttribute('formnovalidate')) return;
3148
-
3149
- window.Parsley._remoteCache = {};
3150
 
3151
  var promise = this.whenValidate({ event: event });
3152
 
@@ -3158,30 +3150,30 @@
3158
  event.stopImmediatePropagation();
3159
  event.preventDefault();
3160
  if ('pending' === promise.state()) promise.done(function () {
3161
- _this5._submit(submitSource);
3162
  });
3163
  }
3164
  },
3165
 
3166
  onSubmitButton: function onSubmitButton(event) {
3167
- this._submitSource = event.currentTarget;
3168
  },
3169
  // internal
3170
  // _submit submits the form, this time without going through the validations.
3171
  // Care must be taken to "fake" the actual submit button being clicked.
3172
- _submit: function _submit(submitSource) {
3173
  if (false === this._trigger('submit')) return;
3174
  // Add submit button's data
3175
- if (submitSource) {
3176
  var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);
3177
  if (0 === $synthetic.length) $synthetic = $('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element);
3178
  $synthetic.attr({
3179
- name: submitSource.getAttribute('name'),
3180
- value: submitSource.getAttribute('value')
3181
  });
3182
  }
3183
 
3184
- this.$element.trigger(_extends($.Event('submit'), { parsley: true }));
3185
  },
3186
 
3187
  // Performs validation on fields while triggering events.
@@ -3191,7 +3183,7 @@
3191
  // Consider using `whenValidate` instead.
3192
  validate: function validate(options) {
3193
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
3194
- Utils.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');
3195
 
3196
  var _arguments = _slice.call(arguments);
3197
 
@@ -3205,7 +3197,7 @@
3205
  },
3206
 
3207
  whenValidate: function whenValidate() {
3208
- var _Utils$all$done$fail$always,
3209
  _this6 = this;
3210
 
3211
  var _ref7 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
@@ -3216,8 +3208,8 @@
3216
 
3217
  this.submitEvent = event;
3218
  if (event) {
3219
- this.submitEvent = _extends({}, event, { preventDefault: function preventDefault() {
3220
- Utils.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
3221
  _this6.validationResult = false;
3222
  } });
3223
  }
@@ -3235,7 +3227,7 @@
3235
  });
3236
  });
3237
 
3238
- return (_Utils$all$done$fail$always = Utils.all(promises).done(function () {
3239
  _this6._trigger('success');
3240
  }).fail(function () {
3241
  _this6.validationResult = false;
@@ -3243,7 +3235,7 @@
3243
  _this6._trigger('error');
3244
  }).always(function () {
3245
  _this6._trigger('validated');
3246
- })).pipe.apply(_Utils$all$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
3247
  },
3248
 
3249
  // Iterate over refreshed fields, and stop on first failure.
@@ -3252,7 +3244,7 @@
3252
  // Prefer using `whenValid` instead.
3253
  isValid: function isValid(options) {
3254
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
3255
- Utils.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');
3256
 
3257
  var _arguments2 = _slice.call(arguments);
3258
 
@@ -3282,7 +3274,7 @@
3282
  return field.whenValid({ group: group, force: force });
3283
  });
3284
  });
3285
- return Utils.all(promises);
3286
  },
3287
 
3288
  // Reset UI
@@ -3331,7 +3323,7 @@
3331
  }
3332
  });
3333
 
3334
- $.each(Utils.difference(oldFields, _this8.fields), function (_, field) {
3335
  field.reset();
3336
  });
3337
  });
@@ -3367,15 +3359,13 @@
3367
  var Constraint = function Constraint(parsleyField, name, requirements, priority, isDomConstraint) {
3368
  var validatorSpec = window.Parsley._validatorRegistry.validators[name];
3369
  var validator = new Validator(validatorSpec);
3370
- priority = priority || parsleyField.options[name + 'Priority'] || validator.priority;
3371
- isDomConstraint = true === isDomConstraint;
3372
 
3373
- _extends(this, {
3374
  validator: validator,
3375
  name: name,
3376
  requirements: requirements,
3377
- priority: priority,
3378
- isDomConstraint: isDomConstraint
3379
  });
3380
  this._parseRequirements(parsleyField.options);
3381
  };
@@ -3404,7 +3394,6 @@
3404
  var Field = function Field(field, domOptions, options, parsleyFormInstance) {
3405
  this.__class__ = 'Field';
3406
 
3407
- this.element = field;
3408
  this.$element = $(field);
3409
 
3410
  // Set parent if we have one
@@ -3433,7 +3422,7 @@
3433
  // `null` if validation is not finished. Prefer using whenValidate
3434
  validate: function validate(options) {
3435
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
3436
- Utils.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');
3437
  options = { options: options };
3438
  }
3439
  var promise = this.whenValidate(options);
@@ -3497,7 +3486,7 @@
3497
  },
3498
 
3499
  _isInGroup: function _isInGroup(group) {
3500
- if (Array.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group);
3501
  return this.options.group === group;
3502
  },
3503
 
@@ -3507,7 +3496,7 @@
3507
  // See also `whenValid`.
3508
  isValid: function isValid(options) {
3509
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
3510
- Utils.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');
3511
 
3512
  var _arguments3 = _slice.call(arguments);
3513
 
@@ -3558,13 +3547,13 @@
3558
  $.each(groupedConstraints, function (_, constraints) {
3559
  // Process one group of constraints at a time, we validate the constraints
3560
  // and combine the promises together.
3561
- var promise = Utils.all($.map(constraints, function (constraint) {
3562
  return _this11._validateConstraint(value, constraint);
3563
  }));
3564
  promises.push(promise);
3565
  if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed
3566
  });
3567
- return Utils.all(promises);
3568
  },
3569
 
3570
  // @returns a promise
@@ -3575,7 +3564,7 @@
3575
  // Map false to a failed promise
3576
  if (false === result) result = $.Deferred().reject();
3577
  // Make sure we return a promise and that we record failures
3578
- return Utils.all([result]).fail(function (errorMessage) {
3579
  if (!(_this12.validationResult instanceof Array)) _this12.validationResult = [];
3580
  _this12.validationResult.push({
3581
  assert: constraint,
@@ -3684,39 +3673,39 @@
3684
  // Bind specific HTML5 constraints to be HTML5 compliant
3685
  _bindHtml5Constraints: function _bindHtml5Constraints() {
3686
  // html5 required
3687
- if (null !== this.element.getAttribute('required')) this.addConstraint('required', true, undefined, true);
3688
 
3689
  // html5 pattern
3690
- if (null !== this.element.getAttribute('pattern')) this.addConstraint('pattern', this.element.getAttribute('pattern'), undefined, true);
3691
 
3692
  // range
3693
- var min = this.element.getAttribute('min');
3694
- var max = this.element.getAttribute('max');
3695
- if (null !== min && null !== max) this.addConstraint('range', [min, max], undefined, true);
3696
 
3697
  // HTML5 min
3698
- else if (null !== min) this.addConstraint('min', min, undefined, true);
3699
 
3700
  // HTML5 max
3701
- else if (null !== max) this.addConstraint('max', max, undefined, true);
3702
 
3703
  // length
3704
- if (null !== this.element.getAttribute('minlength') && null !== this.element.getAttribute('maxlength')) this.addConstraint('length', [this.element.getAttribute('minlength'), this.element.getAttribute('maxlength')], undefined, true);
3705
 
3706
  // HTML5 minlength
3707
- else if (null !== this.element.getAttribute('minlength')) this.addConstraint('minlength', this.element.getAttribute('minlength'), undefined, true);
3708
 
3709
  // HTML5 maxlength
3710
- else if (null !== this.element.getAttribute('maxlength')) this.addConstraint('maxlength', this.element.getAttribute('maxlength'), undefined, true);
3711
 
3712
  // html5 types
3713
- var type = this.element.type;
 
 
3714
 
3715
  // Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
3716
  if ('number' === type) {
3717
  return this.addConstraint('type', ['number', {
3718
- step: this.element.getAttribute('step') || '1',
3719
- base: min || this.element.getAttribute('value')
3720
  }], undefined, true);
3721
  // Regular other HTML5 supported types
3722
  } else if (/^(email|url|range|date)$/i.test(type)) {
@@ -3744,11 +3733,11 @@
3744
  // Use `data-parsley-whitespace="squish"` to auto squish input value
3745
  // Use `data-parsley-whitespace="trim"` to auto trim input value
3746
  _handleWhitespace: function _handleWhitespace(value) {
3747
- if (true === this.options.trimValue) Utils.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"');
3748
 
3749
  if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' ');
3750
 
3751
- if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = Utils.trimString(value);
3752
 
3753
  return value;
3754
  },
@@ -3804,7 +3793,7 @@
3804
  this.constraints = [];
3805
 
3806
  // Select multiple special treatment
3807
- if (this.element.nodeName === 'SELECT') {
3808
  this.actualizeOptions()._bindConstraints();
3809
 
3810
  return this;
@@ -3833,23 +3822,21 @@
3833
  if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value;
3834
 
3835
  // Radio input case
3836
- if (this.element.nodeName === 'INPUT') {
3837
- if (this.element.type === 'radio') return this._findRelated().filter(':checked').val() || '';
3838
 
3839
- // checkbox input case
3840
- if (this.element.type === 'checkbox') {
3841
- var values = [];
3842
 
3843
- this._findRelated().filter(':checked').each(function () {
3844
- values.push($(this).val());
3845
- });
3846
 
3847
- return values;
3848
- }
3849
  }
3850
 
3851
  // Select multiple case
3852
- if (this.element.nodeName === 'SELECT' && null === this.$element.val()) return [];
3853
 
3854
  // Default case that should never happen
3855
  return this.$element.val();
@@ -3863,7 +3850,6 @@
3863
  };
3864
 
3865
  var Factory = function Factory(element, options, parsleyFormInstance) {
3866
- this.element = element;
3867
  this.$element = $(element);
3868
 
3869
  // If the element has already been bound, returns its saved Parsley instance
@@ -3877,7 +3863,7 @@
3877
  }
3878
 
3879
  if ('object' === typeof options) {
3880
- _extends(savedparsleyFormInstance.options, options);
3881
  }
3882
 
3883
  return savedparsleyFormInstance;
@@ -3895,21 +3881,21 @@
3895
  Factory.prototype = {
3896
  init: function init(options) {
3897
  this.__class__ = 'Parsley';
3898
- this.__version__ = '2.7.2';
3899
- this.__id__ = Utils.generateID();
3900
 
3901
  // Pre-compute options
3902
  this._resetOptions(options);
3903
 
3904
  // A Form instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute
3905
- if (this.element.nodeName === 'FORM' || Utils.checkAttr(this.element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)) return this.bind('parsleyForm');
3906
 
3907
  // Every other element is bound as a `Field` or `FieldMultiple`
3908
  return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');
3909
  },
3910
 
3911
  isMultiple: function isMultiple() {
3912
- return this.element.type === 'radio' || this.element.type === 'checkbox' || this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple');
3913
  },
3914
 
3915
  // Multiples fields are a real nightmare :(
@@ -3922,16 +3908,17 @@
3922
  var parsleyMultipleInstance;
3923
 
3924
  // Handle multiple name
3925
- this.options.multiple = this.options.multiple || (name = this.element.getAttribute('name')) || this.element.getAttribute('id');
 
3926
 
3927
  // Special select multiple input
3928
- if (this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple')) {
3929
  this.options.multiple = this.options.multiple || this.__id__;
3930
  return this.bind('parsleyFieldMultiple');
3931
 
3932
  // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
3933
  } else if (!this.options.multiple) {
3934
- Utils.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
3935
  return this;
3936
  }
3937
 
@@ -3939,9 +3926,9 @@
3939
  this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
3940
 
3941
  // Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
3942
- if (name) {
3943
  $('input[name="' + name + '"]').each(function (i, input) {
3944
- if (input.type === 'radio' || input.type === 'checkbox') input.setAttribute(_this13.options.namespace + 'multiple', _this13.options.multiple);
3945
  });
3946
  }
3947
 
@@ -3972,19 +3959,19 @@
3972
 
3973
  switch (type) {
3974
  case 'parsleyForm':
3975
- parsleyInstance = $.extend(new Form(this.element, this.domOptions, this.options), new Base(), window.ParsleyExtend)._bindFields();
3976
  break;
3977
  case 'parsleyField':
3978
- parsleyInstance = $.extend(new parsley_field(this.element, this.domOptions, this.options, this.parent), new Base(), window.ParsleyExtend);
3979
  break;
3980
  case 'parsleyFieldMultiple':
3981
- parsleyInstance = $.extend(new parsley_field(this.element, this.domOptions, this.options, this.parent), new Multiple(), new Base(), window.ParsleyExtend)._init();
3982
  break;
3983
  default:
3984
  throw new Error(type + 'is not a supported Parsley type');
3985
  }
3986
 
3987
- if (this.options.multiple) Utils.setAttr(this.element, this.options.namespace, 'multiple', this.options.multiple);
3988
 
3989
  if ('undefined' !== typeof doNotStore) {
3990
  this.$element.data('FieldMultiple', parsleyInstance);
@@ -4008,24 +3995,23 @@
4008
  throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.";
4009
  }
4010
  if (!vernums.forEach) {
4011
- Utils.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');
4012
  }
4013
  // Inherit `on`, `off` & `trigger` to Parsley:
4014
- var Parsley = _extends(new Base(), {
4015
- element: document,
4016
  $element: $(document),
4017
  actualizeOptions: null,
4018
  _resetOptions: null,
4019
  Factory: Factory,
4020
- version: '2.7.2'
4021
  });
4022
 
4023
  // Supplement Field and Form with Base
4024
  // This way, the constructors will have access to those methods
4025
- _extends(parsley_field.prototype, UI.Field, Base.prototype);
4026
- _extends(Form.prototype, UI.Form, Base.prototype);
4027
  // Inherit actualizeOptions and _resetOptions:
4028
- _extends(Factory.prototype, Base.prototype);
4029
 
4030
  // ### jQuery API
4031
  // `$('.elem').parsley(options)` or `$('.elem').psly(options)`
@@ -4042,12 +4028,12 @@
4042
 
4043
  // Return undefined if applied to non existing DOM element
4044
  if (!$(this).length) {
4045
- Utils.warn('You must bind Parsley on an existing element.');
4046
 
4047
  return;
4048
  }
4049
 
4050
- return new Factory(this[0], options);
4051
  };
4052
 
4053
  // ### Field and Form extension
@@ -4056,18 +4042,18 @@
4056
 
4057
  // ### Parsley config
4058
  // Inherit from ParsleyDefault, and copy over any existing values
4059
- Parsley.options = _extends(Utils.objectCreate(Defaults), window.ParsleyConfig);
4060
  window.ParsleyConfig = Parsley.options; // Old way of accessing global options
4061
 
4062
  // ### Globals
4063
  window.Parsley = window.psly = Parsley;
4064
- Parsley.Utils = Utils;
4065
  window.ParsleyUtils = {};
4066
- $.each(Utils, function (key, value) {
4067
  if ('function' === typeof value) {
4068
  window.ParsleyUtils[key] = function () {
4069
- Utils.warnOnce('Accessing `window.ParsleyUtils` is deprecated. Use `window.Parsley.Utils` instead.');
4070
- return Utils[key].apply(Utils, arguments);
4071
  };
4072
  }
4073
  });
@@ -4076,13 +4062,11 @@
4076
  var registry = window.Parsley._validatorRegistry = new ValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
4077
  window.ParsleyValidator = {};
4078
  $.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator'.split(' '), function (i, method) {
4079
- window.Parsley[method] = function () {
4080
- return registry[method].apply(registry, arguments);
4081
- };
4082
  window.ParsleyValidator[method] = function () {
4083
  var _window$Parsley;
4084
 
4085
- Utils.warnOnce('Accessing the method \'' + method + '\' through Validator is deprecated. Simply call \'window.Parsley.' + method + '(...)\'');
4086
  return (_window$Parsley = window.Parsley)[method].apply(_window$Parsley, arguments);
4087
  };
4088
  });
@@ -4093,18 +4077,18 @@
4093
  window.ParsleyUI = {
4094
  removeError: function removeError(instance, name, doNotUpdateClass) {
4095
  var updateClass = true !== doNotUpdateClass;
4096
- Utils.warnOnce('Accessing UI is deprecated. Call \'removeError\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
4097
  return instance.removeError(name, { updateClass: updateClass });
4098
  },
4099
  getErrorsMessages: function getErrorsMessages(instance) {
4100
- Utils.warnOnce('Accessing UI is deprecated. Call \'getErrorsMessages\' on the instance directly.');
4101
  return instance.getErrorsMessages();
4102
  }
4103
  };
4104
  $.each('addError updateError'.split(' '), function (i, method) {
4105
  window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {
4106
  var updateClass = true !== doNotUpdateClass;
4107
- Utils.warnOnce('Accessing UI is deprecated. Call \'' + method + '\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
4108
  return instance[method](name, { message: message, assert: assert, updateClass: updateClass });
4109
  };
4110
  });
@@ -4120,7 +4104,7 @@
4120
 
4121
  var o = $({});
4122
  var deprecated = function deprecated() {
4123
- Utils.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley");
4124
  };
4125
 
4126
  // Returns an event handler that calls `fn` with the arguments it expects
@@ -4260,7 +4244,7 @@
4260
  if (url.indexOf('{value}') > -1) {
4261
  url = url.replace('{value}', encodeURIComponent(value));
4262
  } else {
4263
- data[instance.element.getAttribute('name') || instance.element.getAttribute('id')] = value;
4264
  }
4265
 
4266
  // Merge options passed in from the function with the ones in the attribute
@@ -4301,7 +4285,7 @@
4301
  Parsley._remoteCache = {};
4302
  });
4303
 
4304
- Base.prototype.addAsyncValidator = function () {
4305
  Utils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');
4306
  return Parsley.addAsyncValidator.apply(Parsley, arguments);
4307
  };
@@ -4350,7 +4334,7 @@
4350
 
4351
  // Slightly odd way construct our object. This way methods are force bound.
4352
  // Used to test for duplicate library.
4353
- _extends(this, {
4354
 
4355
  // For browsers that do not support isTrusted, assumes event is native.
4356
  isNativeEvent: function isNativeEvent(evt) {
1948
 
1949
  /* WEBPACK VAR INJECTION */(function(global) {/*!
1950
  * Parsley.js
1951
+ * Version 2.7.0 - built Wed, Mar 1st 2017, 3:53 pm
1952
  * http://parsleyjs.org
1953
  * Guillaume Potier - <guillaume@wisembly.com>
1954
  * Marc-Andre Lafortune - <petroselinum@marc-andre.ca>
1962
 
1963
  var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
1964
 
 
 
1965
  function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }
1966
 
1967
  (function (global, factory) {
1972
  var globalID = 1;
1973
  var pastWarnings = {};
1974
 
1975
+ var Utils__Utils = {
1976
  // Parsley DOM-API
1977
  // returns object from dom attributes and values
1978
+ attr: function attr($element, namespace, obj) {
1979
  var i;
1980
  var attribute;
1981
  var attributes;
1988
  }
1989
  }
1990
 
1991
+ if ('undefined' === typeof $element || 'undefined' === typeof $element[0]) return obj;
1992
 
1993
+ attributes = $element[0].attributes;
1994
  for (i = attributes.length; i--;) {
1995
  attribute = attributes[i];
1996
 
2002
  return obj;
2003
  },
2004
 
2005
+ checkAttr: function checkAttr($element, namespace, _checkAttr) {
2006
+ return $element.is('[' + namespace + _checkAttr + ']');
2007
  },
2008
 
2009
+ setAttr: function setAttr($element, namespace, attr, value) {
2010
+ $element[0].setAttribute(this.dasherize(namespace + attr), String(value));
2011
  },
2012
 
2013
  generateID: function generateID() {
2094
  return !/^\s*false\s*$/i.test(string);
2095
  },
2096
  object: function object(string) {
2097
+ return Utils__Utils.deserializeValue(string);
2098
  },
2099
  regexp: function regexp(_regexp) {
2100
  var flags = '';
2166
  _SubmitSelector: 'input[type="submit"], button:submit'
2167
  };
2168
 
2169
+ var Utils__default = Utils__Utils;
2170
+
2171
  // All these options could be overriden and specified directly in DOM using
2172
  // `data-parsley-` default DOM-API
2173
  // eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
2234
  };
2235
 
2236
  var Base = function Base() {
2237
+ this.__id__ = Utils__default.generateID();
2238
  };
2239
 
2240
  Base.prototype = {
2252
  },
2253
 
2254
  actualizeOptions: function actualizeOptions() {
2255
+ Utils__default.attr(this.$element, this.options.namespace, this.domOptions);
2256
  if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions();
2257
  return this;
2258
  },
2259
 
2260
  _resetOptions: function _resetOptions(initOptions) {
2261
+ this.domOptions = Utils__default.objectCreate(this.parent.options);
2262
+ this.options = Utils__default.objectCreate(this.domOptions);
2263
  // Shallow copy of ownProperties of initOptions:
2264
  for (var i in initOptions) {
2265
  if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i];
2325
  },
2326
 
2327
  asyncIsValid: function asyncIsValid(group, force) {
2328
+ Utils__default.warnOnce("asyncIsValid is deprecated; please use whenValid instead");
2329
  return this.whenValid({ group: group, force: force });
2330
  },
2331
 
2332
  _findRelated: function _findRelated() {
2333
+ return this.options.multiple ? this.parent.$element.find('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]') : this.$element;
2334
  }
2335
  };
2336
 
2337
  var convertArrayRequirement = function convertArrayRequirement(string, length) {
2338
  var m = string.match(/^\s*\[(.*)\]\s*$/);
2339
  if (!m) throw 'Requirement is not an array: "' + string + '"';
2340
+ var values = m[1].split(',').map(Utils__default.trimString);
2341
  if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';
2342
  return values;
2343
  };
2348
  for (var key in requirementSpec) {
2349
  if (key) {
2350
  var value = extraOptionReader(key);
2351
+ if ('string' === typeof value) value = Utils__default.parseRequirement(requirementSpec[key], value);
2352
  extra[key] = value;
2353
  } else {
2354
+ main = Utils__default.parseRequirement(requirementSpec[key], string);
2355
  }
2356
  }
2357
  return [main, extra];
2374
  return this.fn(value, requirementFirstArg);
2375
  }
2376
 
2377
+ if ($.isArray(value)) {
2378
  if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values';
2379
  return this.validateMultiple.apply(this, arguments);
2380
  } else {
2381
  var instance = arguments[arguments.length - 1];
2382
  if (this.validateDate && instance._isDateInput()) {
2383
+ arguments[0] = Utils__default.parse.date(arguments[0]);
2384
  if (arguments[0] === null) return false;
2385
  return this.validateDate.apply(this, arguments);
2386
  }
2402
  if ('string' !== typeof requirements) {
2403
  // Assume requirement already parsed
2404
  // but make sure we return an array
2405
+ return $.isArray(requirements) ? requirements : [requirements];
2406
  }
2407
  var type = this.requirementType;
2408
+ if ($.isArray(type)) {
2409
  var values = convertArrayRequirement(requirements, type.length);
2410
+ for (var i = 0; i < values.length; i++) values[i] = Utils__default.parseRequirement(type[i], values[i]);
2411
  return values;
2412
  } else if ($.isPlainObject(type)) {
2413
  return convertExtraOptionRequirement(type, requirements, extraOptionReader);
2414
  } else {
2415
+ return [Utils__default.parseRequirement(type, requirements)];
2416
  }
2417
  },
2418
  // Defaults:
2445
 
2446
  date: {
2447
  test: function test(value) {
2448
+ return Utils__default.parse.date(value) !== null;
2449
  }
2450
  },
2451
 
2493
 
2494
  // parseArguments('number', ['1', '2']) => [1, 2]
2495
  var ValidatorRegistry__parseArguments = function ValidatorRegistry__parseArguments(type, args) {
2496
+ return args.map(Utils__default.parse[type]);
2497
  };
2498
  // operatorToValidator returns a validating function for an operator function, applied to the given type
2499
  var ValidatorRegistry__operatorToValidator = function ValidatorRegistry__operatorToValidator(type, operator) {
2520
  init: function init(validators, catalog) {
2521
  this.catalog = catalog;
2522
  // Copy prototype's validators:
2523
+ this.validators = $.extend({}, this.validators);
2524
 
2525
  for (var name in validators) this.addValidator(name, validators[name].fn, validators[name].priority);
2526
 
2576
  // Old API was addValidator(name, function, priority)
2577
  //
2578
  addValidator: function addValidator(name, arg1, arg2) {
2579
+ if (this.validators[name]) Utils__default.warn('Validator "' + name + '" is already defined.');else if (Defaults.hasOwnProperty(name)) {
2580
+ Utils__default.warn('"' + name + '" is a restricted keyword and is not a valid validator name.');
2581
  return;
2582
  }
2583
  return this._setValidator.apply(this, arguments);
2585
 
2586
  updateValidator: function updateValidator(name, arg1, arg2) {
2587
  if (!this.validators[name]) {
2588
+ Utils__default.warn('Validator "' + name + '" is not already defined.');
2589
  return this.addValidator.apply(this, arguments);
2590
  }
2591
  return this._setValidator.apply(this, arguments);
2592
  },
2593
 
2594
  removeValidator: function removeValidator(name) {
2595
+ if (!this.validators[name]) Utils__default.warn('Validator "' + name + '" is not defined.');
2596
 
2597
  delete this.validators[name];
2598
 
2801
  this.$element.on('submit.Parsley', function (evt) {
2802
  _this2.onSubmitValidate(evt);
2803
  });
2804
+ this.$element.on('click.Parsley', Utils__default._SubmitSelector, function (evt) {
2805
  _this2.onSubmitButton(evt);
2806
  });
2807
 
2808
  // UI could be disabled
2809
  if (false === this.options.uiEnabled) return;
2810
 
2811
+ this.$element.attr('novalidate', '');
2812
  },
2813
 
2814
  focus: function focus() {
2985
  var _ui = {};
2986
 
2987
  // Give field its Parsley id in DOM
2988
+ this.$element.attr(this.options.namespace + 'id', this.__id__);
2989
 
2990
  /** Generate important UI elements and store them in this **/
2991
  // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
3006
  // Determine which element will have `parsley-error` and `parsley-success` classes
3007
  _manageClassHandler: function _manageClassHandler() {
3008
  // An element selector could be passed through DOM with `data-parsley-class-handler=#foo`
3009
+ if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length) return $(this.options.classHandler);
 
 
 
 
 
3010
 
3011
  // Class handled could also be determined by function given in Parsley options
3012
+ var $handler = this.options.classHandler.call(this, this);
3013
 
3014
  // If this function returned a valid existing DOM element, go for it
3015
  if ('undefined' !== typeof $handler && $handler.length) return $handler;
3019
 
3020
  _inputHolder: function _inputHolder() {
3021
  // if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container
3022
+ if (!this.options.multiple || this.$element.is('select')) return this.$element;
3023
 
3024
  // But if multiple element (radio, checkbox), that would be their parent
3025
  return this.$element.parent();
3032
  if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent();
3033
 
3034
  if ('string' === typeof this.options.errorsContainer) {
3035
+ if ($(this.options.errorsContainer).length) return $(this.options.errorsContainer).append(this._ui.$errorsWrapper);else Utils__default.warn('The errors container `' + this.options.errorsContainer + '` does not exist in DOM');
3036
  } else if ('function' === typeof this.options.errorsContainer) $errorsContainer = this.options.errorsContainer.call(this, this);
3037
 
3038
  if ('undefined' !== typeof $errorsContainer && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper);
3048
 
3049
  // Remove Parsley events already bound on this field
3050
  $toBind.off('.Parsley');
3051
+ if (this._failedOnce) $toBind.on(Utils__default.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () {
3052
  _this3._validateIfNeeded();
3053
+ });else if (trigger = Utils__default.namespaceEvents(this.options.trigger, 'Parsley')) {
3054
  $toBind.on(trigger, function (event) {
3055
  _this3._validateIfNeeded(event);
3056
  });
3116
  var Form = function Form(element, domOptions, options) {
3117
  this.__class__ = 'Form';
3118
 
 
3119
  this.$element = $(element);
3120
  this.domOptions = domOptions;
3121
  this.options = options;
3135
  if (true === event.parsley) return;
3136
 
3137
  // If we didn't come here through a submit button, use the first one in the form
3138
+ var $submitSource = this._$submitSource || this.$element.find(Utils__default._SubmitSelector).first();
3139
+ this._$submitSource = null;
3140
  this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);
3141
+ if ($submitSource.is('[formnovalidate]')) return;
 
 
3142
 
3143
  var promise = this.whenValidate({ event: event });
3144
 
3150
  event.stopImmediatePropagation();
3151
  event.preventDefault();
3152
  if ('pending' === promise.state()) promise.done(function () {
3153
+ _this5._submit($submitSource);
3154
  });
3155
  }
3156
  },
3157
 
3158
  onSubmitButton: function onSubmitButton(event) {
3159
+ this._$submitSource = $(event.currentTarget);
3160
  },
3161
  // internal
3162
  // _submit submits the form, this time without going through the validations.
3163
  // Care must be taken to "fake" the actual submit button being clicked.
3164
+ _submit: function _submit($submitSource) {
3165
  if (false === this._trigger('submit')) return;
3166
  // Add submit button's data
3167
+ if ($submitSource) {
3168
  var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);
3169
  if (0 === $synthetic.length) $synthetic = $('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element);
3170
  $synthetic.attr({
3171
+ name: $submitSource.attr('name'),
3172
+ value: $submitSource.attr('value')
3173
  });
3174
  }
3175
 
3176
+ this.$element.trigger($.extend($.Event('submit'), { parsley: true }));
3177
  },
3178
 
3179
  // Performs validation on fields while triggering events.
3183
  // Consider using `whenValidate` instead.
3184
  validate: function validate(options) {
3185
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
3186
+ Utils__default.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');
3187
 
3188
  var _arguments = _slice.call(arguments);
3189
 
3197
  },
3198
 
3199
  whenValidate: function whenValidate() {
3200
+ var _Utils__default$all$done$fail$always,
3201
  _this6 = this;
3202
 
3203
  var _ref7 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
3208
 
3209
  this.submitEvent = event;
3210
  if (event) {
3211
+ this.submitEvent = $.extend({}, event, { preventDefault: function preventDefault() {
3212
+ Utils__default.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
3213
  _this6.validationResult = false;
3214
  } });
3215
  }
3227
  });
3228
  });
3229
 
3230
+ return (_Utils__default$all$done$fail$always = Utils__default.all(promises).done(function () {
3231
  _this6._trigger('success');
3232
  }).fail(function () {
3233
  _this6.validationResult = false;
3235
  _this6._trigger('error');
3236
  }).always(function () {
3237
  _this6._trigger('validated');
3238
+ })).pipe.apply(_Utils__default$all$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
3239
  },
3240
 
3241
  // Iterate over refreshed fields, and stop on first failure.
3244
  // Prefer using `whenValid` instead.
3245
  isValid: function isValid(options) {
3246
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
3247
+ Utils__default.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');
3248
 
3249
  var _arguments2 = _slice.call(arguments);
3250
 
3274
  return field.whenValid({ group: group, force: force });
3275
  });
3276
  });
3277
+ return Utils__default.all(promises);
3278
  },
3279
 
3280
  // Reset UI
3323
  }
3324
  });
3325
 
3326
+ $.each(Utils__default.difference(oldFields, _this8.fields), function (_, field) {
3327
  field.reset();
3328
  });
3329
  });
3359
  var Constraint = function Constraint(parsleyField, name, requirements, priority, isDomConstraint) {
3360
  var validatorSpec = window.Parsley._validatorRegistry.validators[name];
3361
  var validator = new Validator(validatorSpec);
 
 
3362
 
3363
+ $.extend(this, {
3364
  validator: validator,
3365
  name: name,
3366
  requirements: requirements,
3367
+ priority: priority || parsleyField.options[name + 'Priority'] || validator.priority,
3368
+ isDomConstraint: true === isDomConstraint
3369
  });
3370
  this._parseRequirements(parsleyField.options);
3371
  };
3394
  var Field = function Field(field, domOptions, options, parsleyFormInstance) {
3395
  this.__class__ = 'Field';
3396
 
 
3397
  this.$element = $(field);
3398
 
3399
  // Set parent if we have one
3422
  // `null` if validation is not finished. Prefer using whenValidate
3423
  validate: function validate(options) {
3424
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
3425
+ Utils__default.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');
3426
  options = { options: options };
3427
  }
3428
  var promise = this.whenValidate(options);
3486
  },
3487
 
3488
  _isInGroup: function _isInGroup(group) {
3489
+ if ($.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group);
3490
  return this.options.group === group;
3491
  },
3492
 
3496
  // See also `whenValid`.
3497
  isValid: function isValid(options) {
3498
  if (arguments.length >= 1 && !$.isPlainObject(options)) {
3499
+ Utils__default.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');
3500
 
3501
  var _arguments3 = _slice.call(arguments);
3502
 
3547
  $.each(groupedConstraints, function (_, constraints) {
3548
  // Process one group of constraints at a time, we validate the constraints
3549
  // and combine the promises together.
3550
+ var promise = Utils__default.all($.map(constraints, function (constraint) {
3551
  return _this11._validateConstraint(value, constraint);
3552
  }));
3553
  promises.push(promise);
3554
  if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed
3555
  });
3556
+ return Utils__default.all(promises);
3557
  },
3558
 
3559
  // @returns a promise
3564
  // Map false to a failed promise
3565
  if (false === result) result = $.Deferred().reject();
3566
  // Make sure we return a promise and that we record failures
3567
+ return Utils__default.all([result]).fail(function (errorMessage) {
3568
  if (!(_this12.validationResult instanceof Array)) _this12.validationResult = [];
3569
  _this12.validationResult.push({
3570
  assert: constraint,
3673
  // Bind specific HTML5 constraints to be HTML5 compliant
3674
  _bindHtml5Constraints: function _bindHtml5Constraints() {
3675
  // html5 required
3676
+ if (this.$element.attr('required')) this.addConstraint('required', true, undefined, true);
3677
 
3678
  // html5 pattern
3679
+ if ('string' === typeof this.$element.attr('pattern')) this.addConstraint('pattern', this.$element.attr('pattern'), undefined, true);
3680
 
3681
  // range
3682
+ if ('undefined' !== typeof this.$element.attr('min') && 'undefined' !== typeof this.$element.attr('max')) this.addConstraint('range', [this.$element.attr('min'), this.$element.attr('max')], undefined, true);
 
 
3683
 
3684
  // HTML5 min
3685
+ else if ('undefined' !== typeof this.$element.attr('min')) this.addConstraint('min', this.$element.attr('min'), undefined, true);
3686
 
3687
  // HTML5 max
3688
+ else if ('undefined' !== typeof this.$element.attr('max')) this.addConstraint('max', this.$element.attr('max'), undefined, true);
3689
 
3690
  // length
3691
+ if ('undefined' !== typeof this.$element.attr('minlength') && 'undefined' !== typeof this.$element.attr('maxlength')) this.addConstraint('length', [this.$element.attr('minlength'), this.$element.attr('maxlength')], undefined, true);
3692
 
3693
  // HTML5 minlength
3694
+ else if ('undefined' !== typeof this.$element.attr('minlength')) this.addConstraint('minlength', this.$element.attr('minlength'), undefined, true);
3695
 
3696
  // HTML5 maxlength
3697
+ else if ('undefined' !== typeof this.$element.attr('maxlength')) this.addConstraint('maxlength', this.$element.attr('maxlength'), undefined, true);
3698
 
3699
  // html5 types
3700
+ var type = this.$element.attr('type');
3701
+
3702
+ if ('undefined' === typeof type) return this;
3703
 
3704
  // Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
3705
  if ('number' === type) {
3706
  return this.addConstraint('type', ['number', {
3707
+ step: this.$element.attr('step') || '1',
3708
+ base: this.$element.attr('min') || this.$element.attr('value')
3709
  }], undefined, true);
3710
  // Regular other HTML5 supported types
3711
  } else if (/^(email|url|range|date)$/i.test(type)) {
3733
  // Use `data-parsley-whitespace="squish"` to auto squish input value
3734
  // Use `data-parsley-whitespace="trim"` to auto trim input value
3735
  _handleWhitespace: function _handleWhitespace(value) {
3736
+ if (true === this.options.trimValue) Utils__default.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"');
3737
 
3738
  if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' ');
3739
 
3740
+ if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = Utils__default.trimString(value);
3741
 
3742
  return value;
3743
  },
3793
  this.constraints = [];
3794
 
3795
  // Select multiple special treatment
3796
+ if (this.$element.is('select')) {
3797
  this.actualizeOptions()._bindConstraints();
3798
 
3799
  return this;
3822
  if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value;
3823
 
3824
  // Radio input case
3825
+ if (this.$element.is('input[type=radio]')) return this._findRelated().filter(':checked').val() || '';
 
3826
 
3827
+ // checkbox input case
3828
+ if (this.$element.is('input[type=checkbox]')) {
3829
+ var values = [];
3830
 
3831
+ this._findRelated().filter(':checked').each(function () {
3832
+ values.push($(this).val());
3833
+ });
3834
 
3835
+ return values;
 
3836
  }
3837
 
3838
  // Select multiple case
3839
+ if (this.$element.is('select') && null === this.$element.val()) return [];
3840
 
3841
  // Default case that should never happen
3842
  return this.$element.val();
3850
  };
3851
 
3852
  var Factory = function Factory(element, options, parsleyFormInstance) {
 
3853
  this.$element = $(element);
3854
 
3855
  // If the element has already been bound, returns its saved Parsley instance
3863
  }
3864
 
3865
  if ('object' === typeof options) {
3866
+ $.extend(savedparsleyFormInstance.options, options);
3867
  }
3868
 
3869
  return savedparsleyFormInstance;
3881
  Factory.prototype = {
3882
  init: function init(options) {
3883
  this.__class__ = 'Parsley';
3884
+ this.__version__ = '2.7.0';
3885
+ this.__id__ = Utils__default.generateID();
3886
 
3887
  // Pre-compute options
3888
  this._resetOptions(options);
3889
 
3890
  // A Form instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute
3891
+ if (this.$element.is('form') || Utils__default.checkAttr(this.$element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)) return this.bind('parsleyForm');
3892
 
3893
  // Every other element is bound as a `Field` or `FieldMultiple`
3894
  return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');
3895
  },
3896
 
3897
  isMultiple: function isMultiple() {
3898
+ return this.$element.is('input[type=radio], input[type=checkbox]') || this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple');
3899
  },
3900
 
3901
  // Multiples fields are a real nightmare :(
3908
  var parsleyMultipleInstance;
3909
 
3910
  // Handle multiple name
3911
+ if (this.options.multiple) ; // We already have our 'multiple' identifier
3912
+ else if ('undefined' !== typeof this.$element.attr('name') && this.$element.attr('name').length) this.options.multiple = name = this.$element.attr('name');else if ('undefined' !== typeof this.$element.attr('id') && this.$element.attr('id').length) this.options.multiple = this.$element.attr('id');
3913
 
3914
  // Special select multiple input
3915
+ if (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple')) {
3916
  this.options.multiple = this.options.multiple || this.__id__;
3917
  return this.bind('parsleyFieldMultiple');
3918
 
3919
  // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
3920
  } else if (!this.options.multiple) {
3921
+ Utils__default.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
3922
  return this;
3923
  }
3924
 
3926
  this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
3927
 
3928
  // Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
3929
+ if ('undefined' !== typeof name) {
3930
  $('input[name="' + name + '"]').each(function (i, input) {
3931
+ if ($(input).is('input[type=radio], input[type=checkbox]')) $(input).attr(_this13.options.namespace + 'multiple', _this13.options.multiple);
3932
  });
3933
  }
3934
 
3959
 
3960
  switch (type) {
3961
  case 'parsleyForm':
3962
+ parsleyInstance = $.extend(new Form(this.$element, this.domOptions, this.options), new Base(), window.ParsleyExtend)._bindFields();
3963
  break;
3964
  case 'parsleyField':
3965
+ parsleyInstance = $.extend(new parsley_field(this.$element, this.domOptions, this.options, this.parent), new Base(), window.ParsleyExtend);
3966
  break;
3967
  case 'parsleyFieldMultiple':
3968
+ parsleyInstance = $.extend(new parsley_field(this.$element, this.domOptions, this.options, this.parent), new Multiple(), new Base(), window.ParsleyExtend)._init();
3969
  break;
3970
  default:
3971
  throw new Error(type + 'is not a supported Parsley type');
3972
  }
3973
 
3974
+ if (this.options.multiple) Utils__default.setAttr(this.$element, this.options.namespace, 'multiple', this.options.multiple);
3975
 
3976
  if ('undefined' !== typeof doNotStore) {
3977
  this.$element.data('FieldMultiple', parsleyInstance);
3995
  throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.";
3996
  }
3997
  if (!vernums.forEach) {
3998
+ Utils__default.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');
3999
  }
4000
  // Inherit `on`, `off` & `trigger` to Parsley:
4001
+ var Parsley = $.extend(new Base(), {
 
4002
  $element: $(document),
4003
  actualizeOptions: null,
4004
  _resetOptions: null,
4005
  Factory: Factory,
4006
+ version: '2.7.0'
4007
  });
4008
 
4009
  // Supplement Field and Form with Base
4010
  // This way, the constructors will have access to those methods
4011
+ $.extend(parsley_field.prototype, UI.Field, Base.prototype);
4012
+ $.extend(Form.prototype, UI.Form, Base.prototype);
4013
  // Inherit actualizeOptions and _resetOptions:
4014
+ $.extend(Factory.prototype, Base.prototype);
4015
 
4016
  // ### jQuery API
4017
  // `$('.elem').parsley(options)` or `$('.elem').psly(options)`
4028
 
4029
  // Return undefined if applied to non existing DOM element
4030
  if (!$(this).length) {
4031
+ Utils__default.warn('You must bind Parsley on an existing element.');
4032
 
4033
  return;
4034
  }
4035
 
4036
+ return new Factory(this, options);
4037
  };
4038
 
4039
  // ### Field and Form extension
4042
 
4043
  // ### Parsley config
4044
  // Inherit from ParsleyDefault, and copy over any existing values
4045
+ Parsley.options = $.extend(Utils__default.objectCreate(Defaults), window.ParsleyConfig);
4046
  window.ParsleyConfig = Parsley.options; // Old way of accessing global options
4047
 
4048
  // ### Globals
4049
  window.Parsley = window.psly = Parsley;
4050
+ Parsley.Utils = Utils__default;
4051
  window.ParsleyUtils = {};
4052
+ $.each(Utils__default, function (key, value) {
4053
  if ('function' === typeof value) {
4054
  window.ParsleyUtils[key] = function () {
4055
+ Utils__default.warnOnce('Accessing `window.ParsleyUtils` is deprecated. Use `window.Parsley.Utils` instead.');
4056
+ return Utils__default[key].apply(Utils__default, arguments);
4057
  };
4058
  }
4059
  });
4062
  var registry = window.Parsley._validatorRegistry = new ValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
4063
  window.ParsleyValidator = {};
4064
  $.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator'.split(' '), function (i, method) {
4065
+ window.Parsley[method] = $.proxy(registry, method);
 
 
4066
  window.ParsleyValidator[method] = function () {
4067
  var _window$Parsley;
4068
 
4069
+ Utils__default.warnOnce('Accessing the method \'' + method + '\' through Validator is deprecated. Simply call \'window.Parsley.' + method + '(...)\'');
4070
  return (_window$Parsley = window.Parsley)[method].apply(_window$Parsley, arguments);
4071
  };
4072
  });
4077
  window.ParsleyUI = {
4078
  removeError: function removeError(instance, name, doNotUpdateClass) {
4079
  var updateClass = true !== doNotUpdateClass;
4080
+ Utils__default.warnOnce('Accessing UI is deprecated. Call \'removeError\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
4081
  return instance.removeError(name, { updateClass: updateClass });
4082
  },
4083
  getErrorsMessages: function getErrorsMessages(instance) {
4084
+ Utils__default.warnOnce('Accessing UI is deprecated. Call \'getErrorsMessages\' on the instance directly.');
4085
  return instance.getErrorsMessages();
4086
  }
4087
  };
4088
  $.each('addError updateError'.split(' '), function (i, method) {
4089
  window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {
4090
  var updateClass = true !== doNotUpdateClass;
4091
+ Utils__default.warnOnce('Accessing UI is deprecated. Call \'' + method + '\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
4092
  return instance[method](name, { message: message, assert: assert, updateClass: updateClass });
4093
  };
4094
  });
4104
 
4105
  var o = $({});
4106
  var deprecated = function deprecated() {
4107
+ Utils__default.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley");
4108
  };
4109
 
4110
  // Returns an event handler that calls `fn` with the arguments it expects
4244
  if (url.indexOf('{value}') > -1) {
4245
  url = url.replace('{value}', encodeURIComponent(value));
4246
  } else {
4247
+ data[instance.$element.attr('name') || instance.$element.attr('id')] = value;
4248
  }
4249
 
4250
  // Merge options passed in from the function with the ones in the attribute
4285
  Parsley._remoteCache = {};
4286
  });
4287
 
4288
+ window.ParsleyExtend.addAsyncValidator = function () {
4289
  Utils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');
4290
  return Parsley.addAsyncValidator.apply(Parsley, arguments);
4291
  };
4334
 
4335
  // Slightly odd way construct our object. This way methods are force bound.
4336
  // Used to test for duplicate library.
4337
+ $.extend(this, {
4338
 
4339
  // For browsers that do not support isTrusted, assumes event is native.
4340
  isNativeEvent: function isNativeEvent(evt) {
lang/index.php CHANGED
@@ -0,0 +1,3 @@
 
 
 
1
+ <?php
2
+
3
+ // Silence is golden
lang/mailpoet.pot CHANGED
@@ -4,7 +4,7 @@ msgid ""
4
  msgstr ""
5
  "Project-Id-Version: \n"
6
  "Report-Msgid-Bugs-To: http://support.mailpoet.com/\n"
7
- "POT-Creation-Date: 2017-05-09 20:32:39+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -1267,17 +1267,17 @@ msgstr ""
1267
  msgid "Please specify a name."
1268
  msgstr ""
1269
 
1270
- #: lib/Models/CustomField.php:17 lib/Models/Newsletter.php:27
1271
  #: views/form/templates/settings/field_form.hbs:16
1272
  msgid "Please specify a type."
1273
  msgstr ""
1274
 
1275
- #: lib/Models/Form.php:93 lib/Models/Newsletter.php:544
1276
  #: lib/Models/Segment.php:131 lib/Models/Subscriber.php:345
1277
  msgid "All"
1278
  msgstr ""
1279
 
1280
- #: lib/Models/Form.php:98 lib/Models/Newsletter.php:614
1281
  #: lib/Models/Segment.php:136 lib/Models/Subscriber.php:370 views/forms.html:57
1282
  #: views/newsletters.html:76 views/segments.html:50
1283
  #: views/subscribers/subscribers.html:34
@@ -1288,38 +1288,38 @@ msgstr ""
1288
  msgid "Another record already exists. Please specify a different \"%1$s\"."
1289
  msgstr ""
1290
 
1291
- #: lib/Models/Newsletter.php:317
1292
  msgid "Deleted list"
1293
  msgstr ""
1294
 
1295
- #: lib/Models/Newsletter.php:445 lib/Models/Subscriber.php:281
1296
  #: lib/Subscribers/ImportExport/Export/Export.php:170
1297
  msgid "All Lists"
1298
  msgstr ""
1299
 
1300
- #: lib/Models/Newsletter.php:556
1301
  #: views/newsletter/templates/blocks/posts/settingsSelection.hbs:12
1302
  msgid "Draft"
1303
  msgstr ""
1304
 
1305
- #: lib/Models/Newsletter.php:564
1306
  #: views/newsletter/templates/blocks/posts/settingsSelection.hbs:11
1307
  msgid "Scheduled"
1308
  msgstr ""
1309
 
1310
- #: lib/Models/Newsletter.php:572
1311
  msgid "Sending"
1312
  msgstr ""
1313
 
1314
- #: lib/Models/Newsletter.php:580
1315
  msgid "Sent"
1316
  msgstr ""
1317
 
1318
- #: lib/Models/Newsletter.php:594 views/newsletters.html:84
1319
  msgid "Active"
1320
  msgstr ""
1321
 
1322
- #: lib/Models/Newsletter.php:602
1323
  msgid "Not active"
1324
  msgstr ""
1325
 
4
  msgstr ""
5
  "Project-Id-Version: \n"
6
  "Report-Msgid-Bugs-To: http://support.mailpoet.com/\n"
7
+ "POT-Creation-Date: 2017-05-16 14:14:17+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
1267
  msgid "Please specify a name."
1268
  msgstr ""
1269
 
1270
+ #: lib/Models/CustomField.php:17 lib/Models/Newsletter.php:26
1271
  #: views/form/templates/settings/field_form.hbs:16
1272
  msgid "Please specify a type."
1273
  msgstr ""
1274
 
1275
+ #: lib/Models/Form.php:93 lib/Models/Newsletter.php:543
1276
  #: lib/Models/Segment.php:131 lib/Models/Subscriber.php:345
1277
  msgid "All"
1278
  msgstr ""
1279
 
1280
+ #: lib/Models/Form.php:98 lib/Models/Newsletter.php:613
1281
  #: lib/Models/Segment.php:136 lib/Models/Subscriber.php:370 views/forms.html:57
1282
  #: views/newsletters.html:76 views/segments.html:50
1283
  #: views/subscribers/subscribers.html:34
1288
  msgid "Another record already exists. Please specify a different \"%1$s\"."
1289
  msgstr ""
1290
 
1291
+ #: lib/Models/Newsletter.php:316
1292
  msgid "Deleted list"
1293
  msgstr ""
1294
 
1295
+ #: lib/Models/Newsletter.php:444 lib/Models/Subscriber.php:281
1296
  #: lib/Subscribers/ImportExport/Export/Export.php:170
1297
  msgid "All Lists"
1298
  msgstr ""
1299
 
1300
+ #: lib/Models/Newsletter.php:555
1301
  #: views/newsletter/templates/blocks/posts/settingsSelection.hbs:12
1302
  msgid "Draft"
1303
  msgstr ""
1304
 
1305
+ #: lib/Models/Newsletter.php:563
1306
  #: views/newsletter/templates/blocks/posts/settingsSelection.hbs:11
1307
  msgid "Scheduled"
1308
  msgstr ""
1309
 
1310
+ #: lib/Models/Newsletter.php:571
1311
  msgid "Sending"
1312
  msgstr ""
1313
 
1314
+ #: lib/Models/Newsletter.php:579
1315
  msgid "Sent"
1316
  msgstr ""
1317
 
1318
+ #: lib/Models/Newsletter.php:593 views/newsletters.html:84
1319
  msgid "Active"
1320
  msgstr ""
1321
 
1322
+ #: lib/Models/Newsletter.php:601
1323
  msgid "Not active"
1324
  msgstr ""
1325
 
lib/API/Endpoints/v1/AutomatedLatestContent.php CHANGED
@@ -28,7 +28,7 @@ class AutomatedLatestContent extends APIEndpoint {
28
  function getTerms($data = array()) {
29
  $taxonomies = (isset($data['taxonomies'])) ? $data['taxonomies'] : array();
30
  $search = (isset($data['search'])) ? $data['search'] : '';
31
- $limit = (isset($data['limit'])) ? (int)$data['limit'] : 10;
32
  $page = (isset($data['page'])) ? (int)$data['page'] : 1;
33
 
34
  return $this->successResponse(
@@ -38,7 +38,9 @@ class AutomatedLatestContent extends APIEndpoint {
38
  'hide_empty' => false,
39
  'search' => $search,
40
  'number' => $limit,
41
- 'offset' => $limit * ($page - 1)
 
 
42
  )
43
  )
44
  );
28
  function getTerms($data = array()) {
29
  $taxonomies = (isset($data['taxonomies'])) ? $data['taxonomies'] : array();
30
  $search = (isset($data['search'])) ? $data['search'] : '';
31
+ $limit = (isset($data['limit'])) ? (int)$data['limit'] : 50;
32
  $page = (isset($data['page'])) ? (int)$data['page'] : 1;
33
 
34
  return $this->successResponse(
38
  'hide_empty' => false,
39
  'search' => $search,
40
  'number' => $limit,
41
+ 'offset' => $limit * ($page - 1),
42
+ 'orderby' => 'name',
43
+ 'order' => 'ASC'
44
  )
45
  )
46
  );
lib/Config/ServicesChecker.php CHANGED
@@ -55,7 +55,7 @@ class ServicesChecker {
55
  $premium_plugin_active = License::getLicense();
56
  $premium_key = Setting::getValue(Bridge::PREMIUM_KEY_STATE_SETTING_NAME);
57
 
58
- if(!$premium_plugin_active) {
59
  $display_error_notice = false;
60
  }
61
 
55
  $premium_plugin_active = License::getLicense();
56
  $premium_key = Setting::getValue(Bridge::PREMIUM_KEY_STATE_SETTING_NAME);
57
 
58
+ if(!$premium_plugin_active || !$premium_key_specified) {
59
  $display_error_notice = false;
60
  }
61
 
lib/Form/Block/Checkbox.php CHANGED
@@ -8,7 +8,7 @@ class Checkbox extends Base {
8
  static function render($block) {
9
  $html = '';
10
 
11
- $field_name = static::getFieldName($block);
12
  $field_validation = static::getInputValidation($block);
13
 
14
  $html .= '<p class="mailpoet_paragraph">';
8
  static function render($block) {
9
  $html = '';
10
 
11
+ $field_name = 'data[' . static::getFieldName($block) . ']';
12
  $field_validation = static::getInputValidation($block);
13
 
14
  $html .= '<p class="mailpoet_paragraph">';
lib/Form/Block/Date.php CHANGED
@@ -20,7 +20,7 @@ class Date extends Base {
20
  private static function renderDateSelect($block = array()) {
21
  $html = '';
22
 
23
- $field_name = static::getFieldName($block);
24
 
25
  $date_formats = static::getDateFormats();
26
 
20
  private static function renderDateSelect($block = array()) {
21
  $html = '';
22
 
23
+ $field_name = 'data[' . static::getFieldName($block) . ']';
24
 
25
  $date_formats = static::getDateFormats();
26
 
lib/Form/Block/Radio.php CHANGED
@@ -8,7 +8,7 @@ class Radio extends Base {
8
  static function render($block) {
9
  $html = '';
10
 
11
- $field_name = static::getFieldName($block);
12
  $field_validation = static::getInputValidation($block);
13
 
14
  $html .= '<p class="mailpoet_paragraph">';
8
  static function render($block) {
9
  $html = '';
10
 
11
+ $field_name = 'data[' . static::getFieldName($block) . ']';
12
  $field_validation = static::getInputValidation($block);
13
 
14
  $html .= '<p class="mailpoet_paragraph">';
lib/Form/Block/Segment.php CHANGED
@@ -8,7 +8,7 @@ class Segment extends Base {
8
  static function render($block) {
9
  $html = '';
10
 
11
- $field_name = static::getFieldName($block);
12
  $field_validation = static::getInputValidation($block);
13
 
14
  $html .= '<p class="mailpoet_paragraph">';
8
  static function render($block) {
9
  $html = '';
10
 
11
+ $field_name = 'data[' . static::getFieldName($block) . ']';
12
  $field_validation = static::getInputValidation($block);
13
 
14
  $html .= '<p class="mailpoet_paragraph">';
lib/Form/Block/Select.php CHANGED
@@ -8,7 +8,7 @@ class Select extends Base {
8
  static function render($block) {
9
  $html = '';
10
 
11
- $field_name = static::getFieldName($block);
12
  $field_validation = static::getInputValidation($block);
13
 
14
  $html .= '<p class="mailpoet_paragraph">';
8
  static function render($block) {
9
  $html = '';
10
 
11
+ $field_name = 'data[' . static::getFieldName($block) . ']';
12
  $field_validation = static::getInputValidation($block);
13
 
14
  $html .= '<p class="mailpoet_paragraph">';
lib/Form/Block/Textarea.php CHANGED
@@ -15,7 +15,7 @@ class Textarea extends Base {
15
 
16
  $html .= '<textarea class="mailpoet_textarea" rows="'.$lines.'" ';
17
 
18
- $html .= 'name="'.static::getFieldName($block).'"';
19
 
20
  $html .= static::renderInputPlaceholder($block);
21
 
15
 
16
  $html .= '<textarea class="mailpoet_textarea" rows="'.$lines.'" ';
17
 
18
+ $html .= 'name="data['.static::getFieldName($block).']"';
19
 
20
  $html .= static::renderInputPlaceholder($block);
21
 
lib/Models/Newsletter.php CHANGED
@@ -19,7 +19,6 @@ class Newsletter extends Model {
19
  const STATUS_SENT = 'sent';
20
  // automatic newsletters status
21
  const STATUS_ACTIVE = 'active';
22
- const NEWSLETTER_HASH_LENGTH = 6;
23
 
24
  function __construct() {
25
  parent::__construct();
@@ -80,7 +79,7 @@ class Newsletter extends Model {
80
  $this->set('hash',
81
  ($this->hash)
82
  ? $this->hash
83
- : self::generateHash()
84
  );
85
  return parent::save();
86
  }
@@ -787,12 +786,4 @@ class Newsletter extends Model {
787
  return parent::where('hash', $hash)
788
  ->findOne();
789
  }
790
-
791
- static function generateHash() {
792
- return substr(
793
- md5(AUTH_KEY . Security::generateRandomString(15)),
794
- 0,
795
- self::NEWSLETTER_HASH_LENGTH
796
- );
797
- }
798
  }
19
  const STATUS_SENT = 'sent';
20
  // automatic newsletters status
21
  const STATUS_ACTIVE = 'active';
 
22
 
23
  function __construct() {
24
  parent::__construct();
79
  $this->set('hash',
80
  ($this->hash)
81
  ? $this->hash
82
+ : Security::generateHash()
83
  );
84
  return parent::save();
85
  }
786
  return parent::where('hash', $hash)
787
  ->findOne();
788
  }
 
 
 
 
 
 
 
 
789
  }
lib/Models/NewsletterLink.php CHANGED
@@ -5,9 +5,4 @@ if(!defined('ABSPATH')) exit;
5
 
6
  class NewsletterLink extends Model {
7
  public static $_table = MP_NEWSLETTER_LINKS_TABLE;
8
-
9
- static function getByHash($hash) {
10
- return parent::where('hash', $hash)
11
- ->findOne();
12
- }
13
  }
5
 
6
  class NewsletterLink extends Model {
7
  public static $_table = MP_NEWSLETTER_LINKS_TABLE;
 
 
 
 
 
8
  }
lib/Models/Subscriber.php CHANGED
@@ -491,14 +491,16 @@ class Subscriber extends Model {
491
  unset($data['segments']);
492
  }
493
 
494
- // fields that must exist
495
- $not_null_fields = array(
496
- 'first_name' => '',
497
- 'last_name' => ''
498
- );
499
- foreach($not_null_fields as $field => $value) {
500
- if(!isset($data[$field])) {
501
- $data[$field] = $value;
 
 
502
  }
503
  }
504
 
491
  unset($data['segments']);
492
  }
493
 
494
+ if($subscriber === false) {
495
+ // fields that must exist
496
+ $not_null_fields = array(
497
+ 'first_name' => '',
498
+ 'last_name' => ''
499
+ );
500
+ foreach($not_null_fields as $field => $value) {
501
+ if(!isset($data[$field])) {
502
+ $data[$field] = $value;
503
+ }
504
  }
505
  }
506
 
lib/Newsletter/Links/Links.php CHANGED
@@ -12,7 +12,6 @@ use MailPoet\Util\Security;
12
  class Links {
13
  const DATA_TAG_CLICK = '[mailpoet_click_data]';
14
  const DATA_TAG_OPEN = '[mailpoet_open_data]';
15
- const HASH_LENGTH = 5;
16
 
17
  const LINK_TYPE_SHORTCODE = 'shortcode';
18
  const LINK_TYPE_LINK = 'link';
@@ -72,7 +71,7 @@ class Links {
72
  static function hash($extracted_links) {
73
  $processed_links = array();
74
  foreach($extracted_links as $extracted_link) {
75
- $hash = Security::generateRandomString(self::HASH_LENGTH);
76
  // Use URL as a key to map between extracted and processed links
77
  // regardless of their sequential position (useful for link skips etc.)
78
  $key = $extracted_link['link'];
@@ -167,13 +166,15 @@ class Links {
167
  }
168
  }
169
 
170
- static function convertHashedLinksToShortcodesAndUrls($content, $convert_all = false) {
171
  preg_match_all(self::getLinkRegex(), $content, $links);
172
  $links = array_unique(Helpers::flattenArray($links));
173
  foreach($links as $link) {
174
  $link_hash = explode('-', $link);
175
  if(!isset($link_hash[1])) continue;
176
- $newsletter_link = NewsletterLink::getByHash($link_hash[1]);
 
 
177
  // convert either only link shortcodes or all hashes links if "convert all"
178
  // option is specified
179
  if($newsletter_link &&
@@ -216,4 +217,4 @@ class Links {
216
  $transformed_data['preview'] = (!empty($data[4])) ? $data[4] : false;
217
  return $transformed_data;
218
  }
219
- }
12
  class Links {
13
  const DATA_TAG_CLICK = '[mailpoet_click_data]';
14
  const DATA_TAG_OPEN = '[mailpoet_open_data]';
 
15
 
16
  const LINK_TYPE_SHORTCODE = 'shortcode';
17
  const LINK_TYPE_LINK = 'link';
71
  static function hash($extracted_links) {
72
  $processed_links = array();
73
  foreach($extracted_links as $extracted_link) {
74
+ $hash = Security::generateHash();
75
  // Use URL as a key to map between extracted and processed links
76
  // regardless of their sequential position (useful for link skips etc.)
77
  $key = $extracted_link['link'];
166
  }
167
  }
168
 
169
+ static function convertHashedLinksToShortcodesAndUrls($content, $queue_id, $convert_all = false) {
170
  preg_match_all(self::getLinkRegex(), $content, $links);
171
  $links = array_unique(Helpers::flattenArray($links));
172
  foreach($links as $link) {
173
  $link_hash = explode('-', $link);
174
  if(!isset($link_hash[1])) continue;
175
+ $newsletter_link = NewsletterLink::where('hash', $link_hash[1])
176
+ ->where('queue_id', $queue_id)
177
+ ->findOne();
178
  // convert either only link shortcodes or all hashes links if "convert all"
179
  // option is specified
180
  if($newsletter_link &&
217
  $transformed_data['preview'] = (!empty($data[4])) ? $data[4] : false;
218
  return $transformed_data;
219
  }
220
+ }
lib/Newsletter/ViewInBrowser.php CHANGED
@@ -31,6 +31,7 @@ class ViewInBrowser {
31
  if($wp_user_preview && preg_match(Links::getLinkRegex(), $newsletter_body)) {
32
  $newsletter_body = Links::convertHashedLinksToShortcodesAndUrls(
33
  $newsletter_body,
 
34
  $convert_all = true
35
  );
36
  // remove open tracking link
31
  if($wp_user_preview && preg_match(Links::getLinkRegex(), $newsletter_body)) {
32
  $newsletter_body = Links::convertHashedLinksToShortcodesAndUrls(
33
  $newsletter_body,
34
+ $queue_id = $queue->id,
35
  $convert_all = true
36
  );
37
  // remove open tracking link
lib/Router/Endpoints/Track.php CHANGED
@@ -49,7 +49,9 @@ class Track {
49
  Newsletter::findOne($data->queue->newsletter_id) :
50
  false;
51
  if(!empty($data->link_hash)) {
52
- $data->link = NewsletterLink::getByHash($data->link_hash);
 
 
53
  }
54
  return $this->_validateTrackData($data);
55
  }
49
  Newsletter::findOne($data->queue->newsletter_id) :
50
  false;
51
  if(!empty($data->link_hash)) {
52
+ $data->link = NewsletterLink::where('hash', $data->link_hash)
53
+ ->where('queue_id', $data->queue_id)
54
+ ->findOne();
55
  }
56
  return $this->_validateTrackData($data);
57
  }
lib/Subscription/Manage.php CHANGED
@@ -9,19 +9,12 @@ class Manage {
9
  $action = (isset($_POST['action']) ? $_POST['action'] : null);
10
  $token = (isset($_POST['token']) ? $_POST['token'] : null);
11
 
12
- if($action !== 'mailpoet_subscription_update') {
13
  Url::redirectBack();
14
  }
 
15
 
16
- $reserved_keywords = array('action', 'token', 'mailpoet_redirect');
17
- $subscriber_data = array_diff_key(
18
- $_POST,
19
- array_flip($reserved_keywords)
20
- );
21
-
22
- if(
23
- isset($subscriber_data['email'])
24
- &&
25
  Subscriber::verifyToken($subscriber_data['email'], $token)
26
  ) {
27
  if($subscriber_data['email'] !== Pages::DEMO_EMAIL) {
@@ -30,7 +23,7 @@ class Manage {
30
  }
31
  }
32
 
33
- // TBD: success/error messages (not present in MP2)
34
  Url::redirectBack();
35
  }
36
  }
9
  $action = (isset($_POST['action']) ? $_POST['action'] : null);
10
  $token = (isset($_POST['token']) ? $_POST['token'] : null);
11
 
12
+ if($action !== 'mailpoet_subscription_update' || empty($_POST['data'])) {
13
  Url::redirectBack();
14
  }
15
+ $subscriber_data = $_POST['data'];
16
 
17
+ if(!empty($subscriber_data['email']) &&
 
 
 
 
 
 
 
 
18
  Subscriber::verifyToken($subscriber_data['email'], $token)
19
  ) {
20
  if($subscriber_data['email'] !== Pages::DEMO_EMAIL) {
23
  }
24
  }
25
 
26
+ // TODO: success/error messages (not present in MP2)
27
  Url::redirectBack();
28
  }
29
  }
lib/Subscription/Pages.php CHANGED
@@ -344,10 +344,10 @@ class Pages {
344
  'novalidate>';
345
  $form_html .= '<input type="hidden" name="action"'.
346
  ' value="mailpoet_subscription_update" />';
347
- $form_html .= '<input type="hidden" name="segments" value="" />';
348
  $form_html .= '<input type="hidden" name="mailpoet_redirect" '.
349
  'value="'.Url::getCurrentUrl().'" />';
350
- $form_html .= '<input type="hidden" name="email" value="'.
351
  $subscriber->email.
352
  '" />';
353
  $form_html .= '<input type="hidden" name="token" value="'.
344
  'novalidate>';
345
  $form_html .= '<input type="hidden" name="action"'.
346
  ' value="mailpoet_subscription_update" />';
347
+ $form_html .= '<input type="hidden" name="data[segments]" value="" />';
348
  $form_html .= '<input type="hidden" name="mailpoet_redirect" '.
349
  'value="'.Url::getCurrentUrl().'" />';
350
+ $form_html .= '<input type="hidden" name="data[email]" value="'.
351
  $subscriber->email.
352
  '" />';
353
  $form_html .= '<input type="hidden" name="token" value="'.
lib/Util/Security.php CHANGED
@@ -5,6 +5,8 @@ if(!defined('ABSPATH')) exit;
5
  require_once(ABSPATH . 'wp-includes/pluggable.php');
6
 
7
  class Security {
 
 
8
  static function generateToken($action = 'mailpoet_token') {
9
  return wp_create_nonce($action);
10
  }
@@ -17,4 +19,13 @@ class Security {
17
  min(max(5, (int)$length), 32)
18
  );
19
  }
 
 
 
 
 
 
 
 
 
20
  }
5
  require_once(ABSPATH . 'wp-includes/pluggable.php');
6
 
7
  class Security {
8
+ const HASH_LENGTH = 12;
9
+
10
  static function generateToken($action = 'mailpoet_token') {
11
  return wp_create_nonce($action);
12
  }
19
  min(max(5, (int)$length), 32)
20
  );
21
  }
22
+
23
+ static function generateHash($length = false) {
24
+ $length = ($length) ? $length : self::HASH_LENGTH;
25
+ return substr(
26
+ md5(AUTH_KEY . self::generateRandomString(64)),
27
+ 0,
28
+ $length
29
+ );
30
+ }
31
  }
mailpoet.php CHANGED
@@ -4,7 +4,7 @@ if(!defined('ABSPATH')) exit;
4
 
5
  /*
6
  * Plugin Name: MailPoet
7
- * Version: 3.0.0-beta.30
8
  * Plugin URI: http://www.mailpoet.com
9
  * Description: Create and send beautiful email newsletters, autoresponders, and post notifications without leaving WordPress. This is a beta version of our brand new plugin!
10
  * Author: MailPoet
@@ -21,7 +21,7 @@ if(!defined('ABSPATH')) exit;
21
  */
22
 
23
  $mailpoet_plugin = array(
24
- 'version' => '3.0.0-beta.30',
25
  'filename' => __FILE__,
26
  'path' => dirname(__FILE__),
27
  'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
4
 
5
  /*
6
  * Plugin Name: MailPoet
7
+ * Version: 3.0.0-beta.31
8
  * Plugin URI: http://www.mailpoet.com
9
  * Description: Create and send beautiful email newsletters, autoresponders, and post notifications without leaving WordPress. This is a beta version of our brand new plugin!
10
  * Author: MailPoet
21
  */
22
 
23
  $mailpoet_plugin = array(
24
+ 'version' => '3.0.0-beta.31',
25
  'filename' => __FILE__,
26
  'path' => dirname(__FILE__),
27
  'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: mailpoet, wysija
3
  Tags: newsletter, email, welcome email, post notification, autoresponder, signup, subscription, SMTP
4
  Requires at least: 4.6
5
  Tested up to: 4.7.4
6
- Stable tag: 3.0.0-beta.30
7
  Create and send beautiful emails and newsletters from WordPress.
8
 
9
  == Description ==
@@ -39,12 +39,14 @@ Not available yet. Limited stats in free version.
39
  = Translations =
40
 
41
  * French
 
42
  * Italian
43
  * Spanish
44
  * Dutch
45
  * Portuguese (BR and PT)
46
  * British
47
  * Russian
 
48
 
49
  We welcome translators to translate directly on [our Transifex project](https://www.transifex.com/wysija/mp3/). Please note that any translations submitted via the "Translating WordPress" web site will not work!
50
 
@@ -89,6 +91,15 @@ Our [support site](https://beta.docs.mailpoet.com) has plenty of articles. You c
89
 
90
  == Changelog ==
91
 
 
 
 
 
 
 
 
 
 
92
  = 3.0.0-beta.30 - 2017-05-09 =
93
  * Fixed: list buttons (ordered/unordered) were added back to the newsletter designer's WYSIWYG editor;
94
  * Fixed: form editor properly displays custom field names when notifying of a completed action (add/update/delete).
3
  Tags: newsletter, email, welcome email, post notification, autoresponder, signup, subscription, SMTP
4
  Requires at least: 4.6
5
  Tested up to: 4.7.4
6
+ Stable tag: 3.0.0-beta.31
7
  Create and send beautiful emails and newsletters from WordPress.
8
 
9
  == Description ==
39
  = Translations =
40
 
41
  * French
42
+ * German
43
  * Italian
44
  * Spanish
45
  * Dutch
46
  * Portuguese (BR and PT)
47
  * British
48
  * Russian
49
+ * Persian (IR)
50
 
51
  We welcome translators to translate directly on [our Transifex project](https://www.transifex.com/wysija/mp3/). Please note that any translations submitted via the "Translating WordPress" web site will not work!
52
 
91
 
92
  == Changelog ==
93
 
94
+ = 3.0.0-beta.31 - 2017-05-16 =
95
+ * Improved: automated latest content/post search boxes in the editor now return up to 50 results;
96
+ * Improved: sending progress bar got a new look;
97
+ * Improved: added plugin translation to Persian (Iran) language. Thanks Ali Reza Karami!;
98
+ * Fixed: submission of subscription forms with list selection or non-text custom fields works again. Thanks Stefan!;
99
+ * Fixed: subscription management form works fine again;
100
+ * Fixed: invalid license key warnings are temporary hidden if a key is empty;
101
+ * Fixed: newsletter link hashes are much less likely to collide. Thanks Sherrie!
102
+
103
  = 3.0.0-beta.30 - 2017-05-09 =
104
  * Fixed: list buttons (ordered/unordered) were added back to the newsletter designer's WYSIWYG editor;
105
  * Fixed: form editor properly displays custom field names when notifying of a completed action (add/update/delete).
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit2860a3f31c703d0aa440de30e6589f01::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInitc76a9eae629b371d4ea958147a147184::getLoader();
vendor/composer/ClassLoader.php CHANGED
@@ -55,7 +55,6 @@ class ClassLoader
55
  private $classMap = array();
56
  private $classMapAuthoritative = false;
57
  private $missingClasses = array();
58
- private $apcuPrefix;
59
 
60
  public function getPrefixes()
61
  {
@@ -272,26 +271,6 @@ class ClassLoader
272
  return $this->classMapAuthoritative;
273
  }
274
 
275
- /**
276
- * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
277
- *
278
- * @param string|null $apcuPrefix
279
- */
280
- public function setApcuPrefix($apcuPrefix)
281
- {
282
- $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
283
- }
284
-
285
- /**
286
- * The APCu prefix in use, or null if APCu caching is not enabled.
287
- *
288
- * @return string|null
289
- */
290
- public function getApcuPrefix()
291
- {
292
- return $this->apcuPrefix;
293
- }
294
-
295
  /**
296
  * Registers this instance as an autoloader.
297
  *
@@ -334,6 +313,11 @@ class ClassLoader
334
  */
335
  public function findFile($class)
336
  {
 
 
 
 
 
337
  // class map lookup
338
  if (isset($this->classMap[$class])) {
339
  return $this->classMap[$class];
@@ -341,12 +325,6 @@ class ClassLoader
341
  if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
342
  return false;
343
  }
344
- if (null !== $this->apcuPrefix) {
345
- $file = apcu_fetch($this->apcuPrefix.$class, $hit);
346
- if ($hit) {
347
- return $file;
348
- }
349
- }
350
 
351
  $file = $this->findFileWithExtension($class, '.php');
352
 
@@ -355,10 +333,6 @@ class ClassLoader
355
  $file = $this->findFileWithExtension($class, '.hh');
356
  }
357
 
358
- if (null !== $this->apcuPrefix) {
359
- apcu_add($this->apcuPrefix.$class, $file);
360
- }
361
-
362
  if (false === $file) {
363
  // Remember that this class does not exist.
364
  $this->missingClasses[$class] = true;
55
  private $classMap = array();
56
  private $classMapAuthoritative = false;
57
  private $missingClasses = array();
 
58
 
59
  public function getPrefixes()
60
  {
271
  return $this->classMapAuthoritative;
272
  }
273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  /**
275
  * Registers this instance as an autoloader.
276
  *
313
  */
314
  public function findFile($class)
315
  {
316
+ // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
317
+ if ('\\' == $class[0]) {
318
+ $class = substr($class, 1);
319
+ }
320
+
321
  // class map lookup
322
  if (isset($this->classMap[$class])) {
323
  return $this->classMap[$class];
325
  if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
326
  return false;
327
  }
 
 
 
 
 
 
328
 
329
  $file = $this->findFileWithExtension($class, '.php');
330
 
333
  $file = $this->findFileWithExtension($class, '.hh');
334
  }
335
 
 
 
 
 
336
  if (false === $file) {
337
  // Remember that this class does not exist.
338
  $this->missingClasses[$class] = true;
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit2860a3f31c703d0aa440de30e6589f01
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit2860a3f31c703d0aa440de30e6589f01
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit2860a3f31c703d0aa440de30e6589f01', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit2860a3f31c703d0aa440de30e6589f01', 'loadClassLoader'));
25
 
26
- $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
- call_user_func(\Composer\Autoload\ComposerStaticInit2860a3f31c703d0aa440de30e6589f01::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ class ComposerAutoloaderInit2860a3f31c703d0aa440de30e6589f01
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
- $includeFiles = Composer\Autoload\ComposerStaticInit2860a3f31c703d0aa440de30e6589f01::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
- composerRequire2860a3f31c703d0aa440de30e6589f01($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
- function composerRequire2860a3f31c703d0aa440de30e6589f01($fileIdentifier, $file)
64
  {
65
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInitc76a9eae629b371d4ea958147a147184
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInitc76a9eae629b371d4ea958147a147184', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitc76a9eae629b371d4ea958147a147184', 'loadClassLoader'));
25
 
26
+ $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION');
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
+ call_user_func(\Composer\Autoload\ComposerStaticInitc76a9eae629b371d4ea958147a147184::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
+ $includeFiles = Composer\Autoload\ComposerStaticInitc76a9eae629b371d4ea958147a147184::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
+ composerRequirec76a9eae629b371d4ea958147a147184($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
+ function composerRequirec76a9eae629b371d4ea958147a147184($fileIdentifier, $file)
64
  {
65
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
  require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit2860a3f31c703d0aa440de30e6589f01
8
  {
9
  public static $files = array (
10
  '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
@@ -615,10 +615,10 @@ class ComposerStaticInit2860a3f31c703d0aa440de30e6589f01
615
  public static function getInitializer(ClassLoader $loader)
616
  {
617
  return \Closure::bind(function () use ($loader) {
618
- $loader->prefixLengthsPsr4 = ComposerStaticInit2860a3f31c703d0aa440de30e6589f01::$prefixLengthsPsr4;
619
- $loader->prefixDirsPsr4 = ComposerStaticInit2860a3f31c703d0aa440de30e6589f01::$prefixDirsPsr4;
620
- $loader->prefixesPsr0 = ComposerStaticInit2860a3f31c703d0aa440de30e6589f01::$prefixesPsr0;
621
- $loader->classMap = ComposerStaticInit2860a3f31c703d0aa440de30e6589f01::$classMap;
622
 
623
  }, null, ClassLoader::class);
624
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInitc76a9eae629b371d4ea958147a147184
8
  {
9
  public static $files = array (
10
  '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
615
  public static function getInitializer(ClassLoader $loader)
616
  {
617
  return \Closure::bind(function () use ($loader) {
618
+ $loader->prefixLengthsPsr4 = ComposerStaticInitc76a9eae629b371d4ea958147a147184::$prefixLengthsPsr4;
619
+ $loader->prefixDirsPsr4 = ComposerStaticInitc76a9eae629b371d4ea958147a147184::$prefixDirsPsr4;
620
+ $loader->prefixesPsr0 = ComposerStaticInitc76a9eae629b371d4ea958147a147184::$prefixesPsr0;
621
+ $loader->classMap = ComposerStaticInitc76a9eae629b371d4ea958147a147184::$classMap;
622
 
623
  }, null, ClassLoader::class);
624
  }
vendor/composer/installed.json CHANGED
@@ -14,7 +14,7 @@
14
  "reference": "b0c1bda3be5a35da44ba1ac28cc61c67d2ada465",
15
  "shasum": ""
16
  },
17
- "time": "2015-11-28T21:47:43+00:00",
18
  "type": "library",
19
  "installation-source": "dist",
20
  "autoload": {
@@ -55,7 +55,7 @@
55
  "require-dev": {
56
  "phpunit/phpunit": "^5.6"
57
  },
58
- "time": "2016-12-14T06:28:26+00:00",
59
  "type": "library",
60
  "installation-source": "dist",
61
  "autoload": {
@@ -116,7 +116,7 @@
116
  "j4mie/idiorm": "1.5.*",
117
  "php": ">=5.2.0"
118
  },
119
- "time": "2014-09-23T10:49:36+00:00",
120
  "type": "library",
121
  "installation-source": "dist",
122
  "autoload": {
@@ -180,7 +180,7 @@
180
  "require-dev": {
181
  "phpunit/phpunit": "~4.0|~5.0"
182
  },
183
- "time": "2017-01-23T04:29:33+00:00",
184
  "type": "library",
185
  "installation-source": "dist",
186
  "autoload": {
@@ -226,7 +226,7 @@
226
  "suggest": {
227
  "ext-mbstring": "For best performance"
228
  },
229
- "time": "2016-11-14T01:06:16+00:00",
230
  "type": "library",
231
  "extra": {
232
  "branch-alias": {
@@ -299,7 +299,7 @@
299
  "symfony/config": "",
300
  "symfony/yaml": ""
301
  },
302
- "time": "2017-03-04T12:20:59+00:00",
303
  "type": "library",
304
  "extra": {
305
  "branch-alias": {
@@ -355,7 +355,7 @@
355
  "friendsofphp/php-cs-fixer": "~2",
356
  "phpunit/phpunit": "~4.0 || ~5.0"
357
  },
358
- "time": "2017-01-16T07:55:07+00:00",
359
  "type": "library",
360
  "extra": {
361
  "branch-alias": {
@@ -408,7 +408,7 @@
408
  "require-dev": {
409
  "phpunit/phpunit": "*"
410
  },
411
- "time": "2016-07-19T19:14:21+00:00",
412
  "type": "library",
413
  "installation-source": "dist",
414
  "autoload": {
@@ -457,7 +457,7 @@
457
  "phpunit/phpunit": ">=4.0",
458
  "soundasleep/component-tests": "dev-master"
459
  },
460
- "time": "2016-06-09T04:56:16+00:00",
461
  "type": "library",
462
  "installation-source": "dist",
463
  "autoload": {
@@ -509,7 +509,7 @@
509
  "mockery/mockery": "~0.9.1",
510
  "symfony/phpunit-bridge": "~3.2"
511
  },
512
- "time": "2017-02-13T07:52:53+00:00",
513
  "type": "library",
514
  "extra": {
515
  "branch-alias": {
@@ -564,7 +564,7 @@
564
  "require-dev": {
565
  "htmlawed/htmlawed": "dev-master"
566
  },
567
- "time": "2016-01-14T20:55:00+00:00",
568
  "type": "library",
569
  "installation-source": "dist",
570
  "autoload": {
@@ -620,7 +620,7 @@
620
  "symfony/debug": "~2.7",
621
  "symfony/phpunit-bridge": "~3.2"
622
  },
623
- "time": "2017-02-27T00:07:03+00:00",
624
  "type": "library",
625
  "extra": {
626
  "branch-alias": {
14
  "reference": "b0c1bda3be5a35da44ba1ac28cc61c67d2ada465",
15
  "shasum": ""
16
  },
17
+ "time": "2015-11-28 21:47:43",
18
  "type": "library",
19
  "installation-source": "dist",
20
  "autoload": {
55
  "require-dev": {
56
  "phpunit/phpunit": "^5.6"
57
  },
58
+ "time": "2016-12-14 06:28:26",
59
  "type": "library",
60
  "installation-source": "dist",
61
  "autoload": {
116
  "j4mie/idiorm": "1.5.*",
117
  "php": ">=5.2.0"
118
  },
119
+ "time": "2014-09-23 10:49:36",
120
  "type": "library",
121
  "installation-source": "dist",
122
  "autoload": {
180
  "require-dev": {
181
  "phpunit/phpunit": "~4.0|~5.0"
182
  },
183
+ "time": "2017-01-23 04:29:33",
184
  "type": "library",
185
  "installation-source": "dist",
186
  "autoload": {
226
  "suggest": {
227
  "ext-mbstring": "For best performance"
228
  },
229
+ "time": "2016-11-14 01:06:16",
230
  "type": "library",
231
  "extra": {
232
  "branch-alias": {
299
  "symfony/config": "",
300
  "symfony/yaml": ""
301
  },
302
+ "time": "2017-03-04 12:20:59",
303
  "type": "library",
304
  "extra": {
305
  "branch-alias": {
355
  "friendsofphp/php-cs-fixer": "~2",
356
  "phpunit/phpunit": "~4.0 || ~5.0"
357
  },
358
+ "time": "2017-01-16 07:55:07",
359
  "type": "library",
360
  "extra": {
361
  "branch-alias": {
408
  "require-dev": {
409
  "phpunit/phpunit": "*"
410
  },
411
+ "time": "2016-07-19 19:14:21",
412
  "type": "library",
413
  "installation-source": "dist",
414
  "autoload": {
457
  "phpunit/phpunit": ">=4.0",
458
  "soundasleep/component-tests": "dev-master"
459
  },
460
+ "time": "2016-06-09 04:56:16",
461
  "type": "library",
462
  "installation-source": "dist",
463
  "autoload": {
509
  "mockery/mockery": "~0.9.1",
510
  "symfony/phpunit-bridge": "~3.2"
511
  },
512
+ "time": "2017-02-13 07:52:53",
513
  "type": "library",
514
  "extra": {
515
  "branch-alias": {
564
  "require-dev": {
565
  "htmlawed/htmlawed": "dev-master"
566
  },
567
+ "time": "2016-01-14 20:55:00",
568
  "type": "library",
569
  "installation-source": "dist",
570
  "autoload": {
620
  "symfony/debug": "~2.7",
621
  "symfony/phpunit-bridge": "~3.2"
622
  },
623
+ "time": "2017-02-27 00:07:03",
624
  "type": "library",
625
  "extra": {
626
  "branch-alias": {
views/layout.html CHANGED
@@ -72,7 +72,8 @@ jQuery('.toplevel_page_mailpoet-newsletters.menu-top-last')
72
  HS.beacon.config({
73
  icon: 'message',
74
  zIndex: 50000,
75
- instructions: "<%= __('Want to give feedback to the MailPoet team? Contact us here. Please provide as much information as possible!') %>"
 
76
  });
77
 
78
  // HelpScout Beacon: Custom information
72
  HS.beacon.config({
73
  icon: 'message',
74
  zIndex: 50000,
75
+ instructions: "<%= __('Want to give feedback to the MailPoet team? Contact us here. Please provide as much information as possible!') %>",
76
+ showContactFields: true
77
  });
78
 
79
  // HelpScout Beacon: Custom information