Skip to content

Commit

Permalink
chore(all): prepare release 0.12.3
Browse files Browse the repository at this point in the history
  • Loading branch information
EisenbergEffect committed Sep 7, 2016
1 parent e793987 commit 9bb0db9
Show file tree
Hide file tree
Showing 68 changed files with 670 additions and 293 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.2",
"version": "0.12.3",
"description": "Validation for Aurelia applications",
"keywords": [
"aurelia",
Expand Down
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 @@ -10,6 +10,7 @@ export declare class StandardValidator extends Validator {
static inject: (typeof ValidationMessageProvider | typeof ViewResources)[];
private messageProvider;
private lookupFunctions;
private getDisplayName;
constructor(messageProvider: ValidationMessageProvider, resources: ViewResources);
private getMessage(rule, object, value);
private validate(object, propertyName, rules);
Expand Down
6 changes: 4 additions & 2 deletions dist/amd/implementation/standard-validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,21 @@ define(["require", "exports", 'aurelia-templating', '../validator', '../validati
_super.call(this);
this.messageProvider = messageProvider;
this.lookupFunctions = resources.lookupFunctions;
this.getDisplayName = messageProvider.getDisplayName.bind(messageProvider);
}
StandardValidator.prototype.getMessage = function (rule, object, value) {
var expression = rule.message || this.messageProvider.getMessage(rule.messageKey);
var _a = rule.property, propertyName = _a.name, displayName = _a.displayName;
if (displayName === null && propertyName !== null) {
displayName = this.messageProvider.computeDisplayName(propertyName);
displayName = this.messageProvider.getDisplayName(propertyName);
}
var overrideContext = {
$displayName: displayName,
$propertyName: propertyName,
$value: value,
$object: object,
$config: rule.config
$config: rule.config,
$getDisplayName: this.getDisplayName
};
return expression.evaluate({ bindingContext: object, overrideContext: overrideContext }, this.lookupFunctions);
};
Expand Down
2 changes: 1 addition & 1 deletion dist/amd/implementation/validation-messages.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ export declare class ValidationMessageProvider {
* Override this with your own custom logic.
* @param propertyName The property name.
*/
computeDisplayName(propertyName: string): string;
getDisplayName(propertyName: string): string;
}
3 changes: 2 additions & 1 deletion dist/amd/implementation/validation-messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ define(["require", "exports", './validation-parser'], function (require, exports
maxLength: "${$displayName} cannot be longer than ${$config.length} character${$config.length === 1 ? '' : 's'}.",
minItems: "${$displayName} must contain at least ${$config.count} item${$config.count === 1 ? '' : 's'}.",
maxItems: "${$displayName} cannot contain more than ${$config.count} item${$config.count === 1 ? '' : 's'}.",
equals: "${$displayName} must be ${$config.expectedValue}.",
};
/**
* Retrieves validation messages and property display names.
Expand Down Expand Up @@ -43,7 +44,7 @@ define(["require", "exports", './validation-parser'], function (require, exports
* Override this with your own custom logic.
* @param propertyName The property name.
*/
ValidationMessageProvider.prototype.computeDisplayName = function (propertyName) {
ValidationMessageProvider.prototype.getDisplayName = function (propertyName) {
// split on upper-case letters.
var words = propertyName.split(/(?=[A-Z])/).join(' ');
// capitalize first letter.
Expand Down
12 changes: 9 additions & 3 deletions dist/amd/implementation/validation-parser.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Parser, Expression } from 'aurelia-binding';
import { Parser, Expression, AccessScope, Unparser } from 'aurelia-binding';
import { BindingLanguage } from 'aurelia-templating';
import { RuleProperty } from './rule';
export interface PropertyAccessor<TObject, TValue> {
Expand All @@ -11,10 +11,16 @@ export declare class ValidationParser {
private emptyStringExpression;
private nullExpression;
private undefinedExpression;
private cache;
constructor(parser: Parser, bindinqLanguage: BindingLanguage);
private coalesce(part);
parseMessage(message: string): Expression;
private getFunctionBody(f);
private getAccessorExpression(f);
private getAccessorExpression(fn);
parseProperty<TObject, TValue>(property: string | PropertyAccessor<TObject, TValue>): RuleProperty;
}
export declare class MessageExpressionValidator extends Unparser {
private originalMessage;
static validate(expression: Expression, originalMessage: string): void;
constructor(originalMessage: string);
visitAccessScope(access: AccessScope): void;
}
56 changes: 42 additions & 14 deletions dist/amd/implementation/validation-parser.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
define(["require", "exports", 'aurelia-binding', 'aurelia-templating', './util'], function (require, exports, aurelia_binding_1, aurelia_templating_1, util_1) {
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
define(["require", "exports", 'aurelia-binding', 'aurelia-templating', './util', 'aurelia-logging'], function (require, exports, aurelia_binding_1, aurelia_templating_1, util_1, LogManager) {
"use strict";
var ValidationParser = (function () {
function ValidationParser(parser, bindinqLanguage) {
Expand All @@ -7,12 +12,16 @@ define(["require", "exports", 'aurelia-binding', 'aurelia-templating', './util']
this.emptyStringExpression = new aurelia_binding_1.LiteralString('');
this.nullExpression = new aurelia_binding_1.LiteralPrimitive(null);
this.undefinedExpression = new aurelia_binding_1.LiteralPrimitive(undefined);
this.cache = {};
}
ValidationParser.prototype.coalesce = function (part) {
// part === null || part === undefined ? '' : part
return new aurelia_binding_1.Conditional(new aurelia_binding_1.Binary('||', new aurelia_binding_1.Binary('===', part, this.nullExpression), new aurelia_binding_1.Binary('===', part, this.undefinedExpression)), this.emptyStringExpression, new aurelia_binding_1.CallMember(part, 'toString', []));
};
ValidationParser.prototype.parseMessage = function (message) {
if (this.cache[message] !== undefined) {
return this.cache[message];
}
var parts = this.bindinqLanguage.parseInterpolation(null, message);
if (parts === null) {
return new aurelia_binding_1.LiteralString(message);
Expand All @@ -21,29 +30,26 @@ define(["require", "exports", 'aurelia-binding', 'aurelia-templating', './util']
for (var i = 1; i < parts.length; i += 2) {
expression = new aurelia_binding_1.Binary('+', expression, new aurelia_binding_1.Binary('+', this.coalesce(parts[i]), new aurelia_binding_1.LiteralString(parts[i + 1])));
}
MessageExpressionValidator.validate(expression, message);
this.cache[message] = expression;
return expression;
};
ValidationParser.prototype.getFunctionBody = function (f) {
function removeCommentsFromSource(str) {
return str.replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:([\s;])+\/\/(?:.*)$)/gm, '$1');
ValidationParser.prototype.getAccessorExpression = function (fn) {
var classic = /^function\s*\([$_\w\d]+\)\s*\{\s*return\s+[$_\w\d]+\.([$_\w\d]+)\s*;?\s*\}$/;
var arrow = /^[$_\w\d]+\s*=>\s*[$_\w\d]+\.([$_\w\d]+)$/;
var match = classic.exec(fn) || arrow.exec(fn);
if (match === null) {
throw new Error("Unable to parse accessor function:\n" + fn);
}
var s = removeCommentsFromSource(f.toString());
return s.substring(s.indexOf('{') + 1, s.lastIndexOf('}'));
};
ValidationParser.prototype.getAccessorExpression = function (f) {
var body = this.getFunctionBody(f).trim();
body = body.replace(/^['"]use strict['"];/, '').trim();
body = body.substr('return'.length).trim();
body = body.replace(/;$/, '');
return this.parser.parse(body);
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);
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) {
Expand All @@ -58,4 +64,26 @@ define(["require", "exports", 'aurelia-binding', 'aurelia-templating', './util']
return ValidationParser;
}());
exports.ValidationParser = ValidationParser;
var MessageExpressionValidator = (function (_super) {
__extends(MessageExpressionValidator, _super);
function MessageExpressionValidator(originalMessage) {
_super.call(this, []);
this.originalMessage = originalMessage;
}
MessageExpressionValidator.validate = function (expression, originalMessage) {
var visitor = new MessageExpressionValidator(originalMessage);
expression.accept(visitor);
};
MessageExpressionValidator.prototype.visitAccessScope = function (access) {
if (access.ancestor !== 0) {
throw new Error('$parent is not permitted in validation message expressions.');
}
if (['displayName', 'propertyName', 'value', 'object', 'config', 'getDisplayName'].indexOf(access.name) !== -1) {
LogManager.getLogger('aurelia-validation')
.warn("Did you mean to use \"$" + access.name + "\" instead of \"" + access.name + "\" in this validation message template: \"" + this.originalMessage + "\"?");
}
};
return MessageExpressionValidator;
}(aurelia_binding_1.Unparser));
exports.MessageExpressionValidator = MessageExpressionValidator;
});
10 changes: 10 additions & 0 deletions dist/amd/implementation/validation-rules.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ export declare class FluentRuleCustomizer<TObject, TValue> {
* null and undefined values are considered valid.
*/
maxItems(count: number): FluentRuleCustomizer<TObject, TValue>;
/**
* Applies the "equals" validation rule to the property.
* null, undefined and empty-string values are considered valid.
*/
equals(expectedValue: TValue): FluentRuleCustomizer<TObject, TValue>;
}
/**
* Part of the fluent rule API. Enables applying rules to properties and objects.
Expand Down Expand Up @@ -165,6 +170,11 @@ export declare class FluentRules<TObject, TValue> {
* null and undefined values are considered valid.
*/
maxItems(count: number): FluentRuleCustomizer<TObject, TValue>;
/**
* Applies the "equals" validation rule to the property.
* null and undefined values are considered valid.
*/
equals(expectedValue: TValue): FluentRuleCustomizer<TObject, TValue>;
}
/**
* Part of the fluent rule API. Enables targeting properties and objects with rules.
Expand Down
15 changes: 15 additions & 0 deletions dist/amd/implementation/validation-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,13 @@ define(["require", "exports", './util', './rules', './validation-messages'], fun
FluentRuleCustomizer.prototype.maxItems = function (count) {
return this.fluentRules.maxItems(count);
};
/**
* Applies the "equals" validation rule to the property.
* null, undefined and empty-string values are considered valid.
*/
FluentRuleCustomizer.prototype.equals = function (expectedValue) {
return this.fluentRules.equals(expectedValue);
};
return FluentRuleCustomizer;
}());
exports.FluentRuleCustomizer = FluentRuleCustomizer;
Expand Down Expand Up @@ -268,6 +275,14 @@ define(["require", "exports", './util', './rules', './validation-messages'], fun
return this.satisfies(function (value) { return value === null || value === undefined || value.length <= count; }, { count: count })
.withMessageKey('maxItems');
};
/**
* Applies the "equals" validation rule to the property.
* null and undefined values are considered valid.
*/
FluentRules.prototype.equals = function (expectedValue) {
return this.satisfies(function (value) { return value === null || value === undefined || value === '' || value === expectedValue; }, { expectedValue: expectedValue })
.withMessageKey('equals');
};
FluentRules.customRules = {};
return FluentRules;
}());
Expand Down
4 changes: 2 additions & 2 deletions dist/amd/validate-binding-behavior.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export declare class ValidateBindingBehavior {
/**
* 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,
* which is a javascript "class" instance, so we need to use the controller to
* locate the actual DOM 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;
Expand Down
21 changes: 13 additions & 8 deletions dist/amd/validate-binding-behavior.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
define(["require", "exports", 'aurelia-dependency-injection', 'aurelia-task-queue', './validation-controller', './validate-trigger'], function (require, exports, aurelia_dependency_injection_1, aurelia_task_queue_1, validation_controller_1, validate_trigger_1) {
define(["require", "exports", 'aurelia-dependency-injection', 'aurelia-pal', 'aurelia-task-queue', './validation-controller', './validate-trigger'], function (require, exports, aurelia_dependency_injection_1, aurelia_pal_1, aurelia_task_queue_1, validation_controller_1, validate_trigger_1) {
"use strict";
/**
* Binding behavior. Indicates the bound property should be validated.
Expand All @@ -10,22 +10,27 @@ define(["require", "exports", 'aurelia-dependency-injection', 'aurelia-task-queu
/**
* 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,
* which is a javascript "class" instance, so we need to use the controller to
* locate the actual DOM 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.
*/
ValidateBindingBehavior.prototype.getTarget = function (binding, view) {
var target = binding.target;
// DOM element
if (target instanceof Element) {
return target;
}
var controller;
for (var id in view.controllers) {
controller = view.controllers[id];
// 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) {
break;
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 + "\".");
}
}
return controller.view.firstChild.parentNode;
throw new Error("Unable to locate target element for \"" + binding.sourceExpression + "\".");
};
ValidateBindingBehavior.prototype.bind = function (binding, source, rulesOrController, rules) {
var _this = this;
Expand Down
2 changes: 1 addition & 1 deletion dist/amd/validation-controller.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export declare class ValidationController {
* Gets the elements associated with an object and propertyName (if any).
*/
private getAssociatedElements({object, propertyName});
private processErrorDelta(oldErrors, newErrors);
private processErrorDelta(kind, oldErrors, newErrors);
/**
* Validates the property associated with a binding.
*/
Expand Down
15 changes: 9 additions & 6 deletions dist/amd/validation-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,22 @@ define(["require", "exports", './validator', './validate-trigger', './property-i
*/
ValidationController.prototype.removeObject = function (object) {
this.objects.delete(object);
this.processErrorDelta(this.errors.filter(function (error) { return error.object === object; }), []);
this.processErrorDelta('reset', this.errors.filter(function (error) { return error.object === object; }), []);
};
/**
* Adds and renders a ValidationError.
*/
ValidationController.prototype.addError = function (message, object, propertyName) {
var error = new validation_error_1.ValidationError({}, message, object, propertyName);
this.processErrorDelta([], [error]);
this.processErrorDelta('validate', [], [error]);
return error;
};
/**
* Removes and unrenders a ValidationError.
*/
ValidationController.prototype.removeError = function (error) {
if (this.errors.indexOf(error) !== -1) {
this.processErrorDelta([error], []);
this.processErrorDelta('reset', [error], []);
}
};
/**
Expand All @@ -71,6 +71,7 @@ define(["require", "exports", './validator', './validate-trigger', './property-i
var _this = this;
this.renderers.push(renderer);
renderer.render({
kind: 'validate',
render: this.errors.map(function (error) { return ({ error: error, elements: _this.elements.get(error) }); }),
unrender: []
});
Expand All @@ -83,6 +84,7 @@ define(["require", "exports", './validator', './validate-trigger', './property-i
var _this = this;
this.renderers.splice(this.renderers.indexOf(renderer), 1);
renderer.render({
kind: 'reset',
render: [],
unrender: this.errors.map(function (error) { return ({ error: error, elements: _this.elements.get(error) }); })
});
Expand Down Expand Up @@ -176,7 +178,7 @@ define(["require", "exports", './validator', './validate-trigger', './property-i
.then(function (newErrors) {
var predicate = _this.getInstructionPredicate(instruction);
var oldErrors = _this.errors.filter(predicate);
_this.processErrorDelta(oldErrors, newErrors);
_this.processErrorDelta('validate', oldErrors, newErrors);
if (result === _this.finishValidating) {
_this.validating = false;
}
Expand All @@ -198,7 +200,7 @@ define(["require", "exports", './validator', './validate-trigger', './property-i
ValidationController.prototype.reset = function (instruction) {
var predicate = this.getInstructionPredicate(instruction);
var oldErrors = this.errors.filter(predicate);
this.processErrorDelta(oldErrors, []);
this.processErrorDelta('reset', oldErrors, []);
};
/**
* Gets the elements associated with an object and propertyName (if any).
Expand All @@ -215,9 +217,10 @@ define(["require", "exports", './validator', './validate-trigger', './property-i
}
return elements;
};
ValidationController.prototype.processErrorDelta = function (oldErrors, newErrors) {
ValidationController.prototype.processErrorDelta = function (kind, oldErrors, newErrors) {
// prepare the instruction.
var instruction = {
kind: kind,
render: [],
unrender: []
};
Expand Down
Loading

0 comments on commit 9bb0db9

Please sign in to comment.