Skip to content

Commit

Permalink
chore(all): prepare release 0.13.0
Browse files Browse the repository at this point in the history
  • Loading branch information
EisenbergEffect committed Sep 29, 2016
1 parent 70b1176 commit b664812
Show file tree
Hide file tree
Showing 82 changed files with 1,742 additions and 839 deletions.
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "aurelia-validation",
"version": "0.12.5",
"version": "0.13.0",
"description": "Validation for Aurelia applications",
"keywords": [
"aurelia",
Expand Down
7 changes: 7 additions & 0 deletions dist/amd/implementation/rule.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { Expression } from 'aurelia-binding';
/**
* Information related to a property that is the subject of validation.
*/
export interface RuleProperty {
/**
* The property name. null indicates the rule targets the object itself.
Expand All @@ -9,6 +12,9 @@ export interface RuleProperty {
*/
displayName: string | null;
}
/**
* A rule definition. Associations a rule with a property or object.
*/
export interface Rule<TObject, TValue> {
property: RuleProperty;
condition: (value: TValue, object?: TObject) => boolean | Promise<boolean>;
Expand All @@ -18,5 +24,6 @@ export interface Rule<TObject, TValue> {
} | null;
messageKey: string;
message: Expression | null;
sequence: number;
tag?: string;
}
4 changes: 2 additions & 2 deletions dist/amd/implementation/rules.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ export declare class Rules {
/**
* Applies the rules to a target.
*/
static set(target: any, rules: Rule<any, any>[]): void;
static set(target: any, rules: Rule<any, any>[][]): void;
/**
* Removes rules from a target.
*/
static unset(target: any): void;
/**
* Retrieves the target's rules.
*/
static get(target: any): Rule<any, any>[] | null;
static get(target: any): Rule<any, any>[][] | null;
}
1 change: 1 addition & 0 deletions dist/amd/implementation/standard-validator.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export declare class StandardValidator extends Validator {
private getDisplayName;
constructor(messageProvider: ValidationMessageProvider, resources: ViewResources);
private getMessage(rule, object, value);
private validateRuleSequence(object, propertyName, ruleSequence, sequence);
private validate(object, propertyName, rules);
/**
* Validates the specified property.
Expand Down
58 changes: 30 additions & 28 deletions dist/amd/implementation/standard-validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,12 @@ define(["require", "exports", 'aurelia-templating', '../validator', '../validati
};
return expression.evaluate({ bindingContext: object, overrideContext: overrideContext }, this.lookupFunctions);
};
StandardValidator.prototype.validate = function (object, propertyName, rules) {
StandardValidator.prototype.validateRuleSequence = function (object, propertyName, ruleSequence, sequence) {
var _this = this;
var errors = [];
// rules specified?
if (!rules) {
// no. locate the rules via metadata.
rules = rules_1.Rules.get(object);
}
// any rules?
if (!rules) {
return Promise.resolve(errors);
}
// are we validating all properties or a single property?
var validateAllProperties = propertyName === null || propertyName === undefined;
var addError = function (rule, value) {
var message = _this.getMessage(rule, object, value);
errors.push(new validation_error_1.ValidationError(rule, message, object, rule.property.name));
};
var rules = ruleSequence[sequence];
var errors = [];
// validate each rule.
var promises = [];
var _loop_1 = function(i) {
Expand All @@ -66,25 +54,39 @@ define(["require", "exports", 'aurelia-templating', '../validator', '../validati
// validate.
var value = rule.property.name === null ? object : object[rule.property.name];
var promiseOrBoolean = rule.condition(value, object);
if (promiseOrBoolean instanceof Promise) {
promises.push(promiseOrBoolean.then(function (isValid) {
if (!isValid) {
addError(rule, value);
}
}));
return "continue";
}
if (!promiseOrBoolean) {
addError(rule, value);
if (!(promiseOrBoolean instanceof Promise)) {
promiseOrBoolean = Promise.resolve(promiseOrBoolean);
}
promises.push(promiseOrBoolean.then(function (isValid) {
if (!isValid) {
var message = _this.getMessage(rule, object, value);
errors.push(new validation_error_1.ValidationError(rule, message, object, rule.property.name));
}
}));
};
for (var i = 0; i < rules.length; i++) {
_loop_1(i);
}
if (promises.length === 0) {
return Promise.resolve(errors);
return Promise.all(promises)
.then(function () {
sequence++;
if (errors.length === 0 && sequence < ruleSequence.length) {
return _this.validateRuleSequence(object, propertyName, ruleSequence, sequence);
}
return errors;
});
};
StandardValidator.prototype.validate = function (object, propertyName, rules) {
// rules specified?
if (!rules) {
// no. attempt to locate the rules.
rules = rules_1.Rules.get(object);
}
// any rules?
if (!rules) {
return Promise.resolve([]);
}
return Promise.all(promises).then(function () { return errors; });
return this.validateRuleSequence(object, propertyName, rules, 0);
};
/**
* Validates the specified property.
Expand Down
7 changes: 2 additions & 5 deletions dist/amd/implementation/validation-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,10 @@ define(["require", "exports", 'aurelia-binding', 'aurelia-templating', './util',
return this.parser.parse(match[1]);
};
ValidationParser.prototype.parseProperty = function (property) {
var accessor;
if (util_1.isString(property)) {
accessor = this.parser.parse(property);
}
else {
accessor = this.getAccessorExpression(property.toString());
return { name: property, displayName: null };
}
var accessor = this.getAccessorExpression(property.toString());
if (accessor instanceof aurelia_binding_1.AccessScope
|| accessor instanceof aurelia_binding_1.AccessMember && accessor.object instanceof aurelia_binding_1.AccessScope) {
return {
Expand Down
17 changes: 14 additions & 3 deletions dist/amd/implementation/validation-rules.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ export declare class FluentRuleCustomizer<TObject, TValue> {
private parser;
private rule;
constructor(property: RuleProperty, condition: (value: TValue, object?: TObject) => boolean | Promise<boolean>, config: Object, fluentEnsure: FluentEnsure<TObject>, fluentRules: FluentRules<TObject, TValue>, parser: ValidationParser);
/**
* Validate subsequent rules after previously declared rules have
* been validated successfully. Use to postpone validation of costly
* rules until less expensive rules pass validation.
*/
then(): this;
/**
* Specifies the key to use when looking up the rule's validation message.
*/
Expand Down Expand Up @@ -42,7 +48,7 @@ export declare class FluentRuleCustomizer<TObject, TValue> {
/**
* Rules that have been defined using the fluent API.
*/
readonly rules: Rule<TObject, any>[];
readonly rules: Rule<TObject, any>[][];
/**
* Applies the rules to a class or object, making them discoverable by the StandardValidator.
* @param target A class or object.
Expand Down Expand Up @@ -184,7 +190,8 @@ export declare class FluentEnsure<TObject> {
/**
* Rules that have been defined using the fluent API.
*/
rules: Rule<TObject, any>[];
rules: Rule<TObject, any>[][];
_sequence: number;
constructor(parser: ValidationParser);
/**
* Target a property with validation rules.
Expand All @@ -200,6 +207,10 @@ export declare class FluentEnsure<TObject> {
* @param target A class or object.
*/
on(target: any): this;
/**
* Adds a rule definition to the sequenced ruleset.
*/
_addRule(rule: Rule<TObject, any>): void;
private assertInitialized();
}
/**
Expand Down Expand Up @@ -230,7 +241,7 @@ export declare class ValidationRules {
* @param rules The rules to search.
* @param tag The tag to search for.
*/
static taggedRules(rules: Rule<any, any>[], tag: string): Rule<any, any>[];
static taggedRules(rules: Rule<any, any>[][], tag: string): Rule<any, any>[][];
/**
* Removes the rules from a class or object.
* @param target A class or object.
Expand Down
28 changes: 24 additions & 4 deletions dist/amd/implementation/validation-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,20 @@ define(["require", "exports", './util', './rules', './validation-messages'], fun
config: config,
when: null,
messageKey: 'default',
message: null
message: null,
sequence: fluentEnsure._sequence
};
this.fluentEnsure.rules.push(this.rule);
this.fluentEnsure._addRule(this.rule);
}
/**
* Validate subsequent rules after previously declared rules have
* been validated successfully. Use to postpone validation of costly
* rules until less expensive rules pass validation.
*/
FluentRuleCustomizer.prototype.then = function () {
this.fluentEnsure._sequence++;
return this;
};
/**
* Specifies the key to use when looking up the rule's validation message.
*/
Expand Down Expand Up @@ -240,7 +250,7 @@ define(["require", "exports", './util', './rules', './validation-messages'], fun
* null, undefined and empty-string values are considered valid.
*/
FluentRules.prototype.email = function () {
return this.matches(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/)
return this.matches(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i)
.withMessageKey('email');
};
/**
Expand Down Expand Up @@ -297,6 +307,7 @@ define(["require", "exports", './util', './rules', './validation-messages'], fun
* Rules that have been defined using the fluent API.
*/
this.rules = [];
this._sequence = 0;
}
/**
* Target a property with validation rules.
Expand All @@ -321,6 +332,15 @@ define(["require", "exports", './util', './rules', './validation-messages'], fun
rules_1.Rules.set(target, this.rules);
return this;
};
/**
* Adds a rule definition to the sequenced ruleset.
*/
FluentEnsure.prototype._addRule = function (rule) {
while (this.rules.length < rule.sequence + 1) {
this.rules.push([]);
}
this.rules[rule.sequence].push(rule);
};
FluentEnsure.prototype.assertInitialized = function () {
if (this.parser) {
return;
Expand Down Expand Up @@ -369,7 +389,7 @@ define(["require", "exports", './util', './rules', './validation-messages'], fun
* @param tag The tag to search for.
*/
ValidationRules.taggedRules = function (rules, tag) {
return rules.filter(function (r) { return r.tag === tag; });
return rules.map(function (x) { return x.filter(function (r) { return r.tag === tag; }); });
};
/**
* Removes the rules from a class or object.
Expand Down
19 changes: 19 additions & 0 deletions dist/amd/validate-binding-behavior-base.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { TaskQueue } from 'aurelia-task-queue';
import { ValidationController } from './validation-controller';
/**
* Binding behavior. Indicates the bound property should be validated.
*/
export declare abstract class ValidateBindingBehaviorBase {
private taskQueue;
constructor(taskQueue: TaskQueue);
protected abstract getValidateTrigger(controller: ValidationController): number;
/**
* Gets the DOM element associated with the data-binding. Most of the time it's
* the binding.target but sometimes binding.target is an aurelia custom element,
* or custom attribute which is a javascript "class" instance, so we need to use
* the controller's container to retrieve the actual DOM element.
*/
getTarget(binding: any, view: any): any;
bind(binding: any, source: any, rulesOrController?: ValidationController | any, rules?: any): void;
unbind(binding: any): void;
}
97 changes: 97 additions & 0 deletions dist/amd/validate-binding-behavior-base.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
define(["require", "exports", 'aurelia-dependency-injection', 'aurelia-pal', './validation-controller', './validate-trigger'], function (require, exports, aurelia_dependency_injection_1, aurelia_pal_1, validation_controller_1, validate_trigger_1) {
"use strict";
/**
* Binding behavior. Indicates the bound property should be validated.
*/
var ValidateBindingBehaviorBase = (function () {
function ValidateBindingBehaviorBase(taskQueue) {
this.taskQueue = taskQueue;
}
/**
* Gets the DOM element associated with the data-binding. Most of the time it's
* the binding.target but sometimes binding.target is an aurelia custom element,
* or custom attribute which is a javascript "class" instance, so we need to use
* the controller's container to retrieve the actual DOM element.
*/
ValidateBindingBehaviorBase.prototype.getTarget = function (binding, view) {
var target = binding.target;
// DOM element
if (target instanceof Element) {
return target;
}
// custom element or custom attribute
for (var i = 0, ii = view.controllers.length; i < ii; i++) {
var controller = view.controllers[i];
if (controller.viewModel === target) {
var element = controller.container.get(aurelia_pal_1.DOM.Element);
if (element) {
return element;
}
throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\".");
}
}
throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\".");
};
ValidateBindingBehaviorBase.prototype.bind = function (binding, source, rulesOrController, rules) {
var _this = this;
// identify the target element.
var target = this.getTarget(binding, source);
// locate the controller.
var controller;
if (rulesOrController instanceof validation_controller_1.ValidationController) {
controller = rulesOrController;
}
else {
controller = source.container.get(aurelia_dependency_injection_1.Optional.of(validation_controller_1.ValidationController));
rules = rulesOrController;
}
if (controller === null) {
throw new Error("A ValidationController has not been registered.");
}
controller.registerBinding(binding, target, rules);
binding.validationController = controller;
var trigger = this.getValidateTrigger(controller);
if (trigger & validate_trigger_1.validateTrigger.change) {
binding.standardUpdateSource = binding.updateSource;
binding.updateSource = function (value) {
this.standardUpdateSource(value);
this.validationController.validateBinding(this);
};
}
if (trigger & validate_trigger_1.validateTrigger.blur) {
binding.validateBlurHandler = function () {
_this.taskQueue.queueMicroTask(function () { return controller.validateBinding(binding); });
};
binding.validateTarget = target;
target.addEventListener('blur', binding.validateBlurHandler);
}
if (trigger !== validate_trigger_1.validateTrigger.manual) {
binding.standardUpdateTarget = binding.updateTarget;
binding.updateTarget = function (value) {
this.standardUpdateTarget(value);
this.validationController.resetBinding(this);
};
}
};
ValidateBindingBehaviorBase.prototype.unbind = function (binding) {
// reset the binding to it's original state.
if (binding.standardUpdateSource) {
binding.updateSource = binding.standardUpdateSource;
binding.standardUpdateSource = null;
}
if (binding.standardUpdateTarget) {
binding.updateTarget = binding.standardUpdateTarget;
binding.standardUpdateTarget = null;
}
if (binding.validateBlurHandler) {
binding.validateTarget.removeEventListener('blur', binding.validateBlurHandler);
binding.validateBlurHandler = null;
binding.validateTarget = null;
}
binding.validationController.unregisterBinding(binding);
binding.validationController = null;
};
return ValidateBindingBehaviorBase;
}());
exports.ValidateBindingBehaviorBase = ValidateBindingBehaviorBase;
});
Loading

0 comments on commit b664812

Please sign in to comment.