Permalink
Browse files

proposed fix for #388 using math.js

Make math.js an optional dependency. Also add support for decimal.js
  • Loading branch information...
Adam Bloomston authored and jdorn committed Jun 16, 2015
1 parent cfd3419 commit ac4728b019848d62e43991b2dd93d0cc110f5eec
Showing with 87 additions and 41 deletions.
  1. +12 −12 Gruntfile.js
  2. +5 −1 README.md
  3. +54 −20 src/validator.js
  4. +16 −8 tests/validation.html
View
@@ -7,25 +7,25 @@ module.exports = function(grunt) {
sourcesContent: true
},
target: {
files: {
files: {
'dist/jsoneditor.js': [
// License & version info, start the containing closure
'src/intro.js',
// Simple inheritance
'src/class.js',
// IE9 polyfills
'src/ie9.js',
// Utils like extend, each, and trigger
'src/utilities.js',
// The main JSONEditor class
'src/core.js',
// JSON Schema validator
'src/validator.js',
// All the editors
'src/editor.js',
'src/editors/null.js',
@@ -54,10 +54,10 @@ module.exports = function(grunt) {
// Set the defaults
'src/defaults.js',
// Wrapper for $.fn style initialization
'src/jquery.js',
// End the closure
'src/outro.js'
],
@@ -91,20 +91,20 @@ module.exports = function(grunt) {
beforeconcat: [
'src/class.js',
'src/ie9.js',
// Utils like extend, each, and trigger
'src/utilities.js',
// The main JSONEditor class
'src/core.js',
// JSON Schema validator
'src/validator.js',
// All the editors
'src/editor.js',
'src/editors/*.js',
// All the themes and iconlibs
'src/theme.js',
'src/themes/*.js',
@@ -116,7 +116,7 @@ module.exports = function(grunt) {
// Set the defaults
'src/defaults.js',
// Wrapper for $.fn style initialization
'src/jquery.js'
],
View
@@ -16,7 +16,11 @@ Download the [production version][min] (22K when gzipped) or the [development ve
Requirements
-----------------
JSON Editor has no required dependencies. It only needs a modern browser (tested in Chrome and Firefox).
JSON Schema has the following dependencies:
* [math.js](http://mathjs.org/) for floating point math
It needs a modern browser (tested in Chrome and Firefox).
### Optional Requirements
View
@@ -208,48 +208,82 @@ JSONEditor.Validator = Class.extend({
if(typeof value === "number") {
// `multipleOf` and `divisibleBy`
if(schema.multipleOf || schema.divisibleBy) {
valid = value / (schema.multipleOf || schema.divisibleBy);
if(valid !== Math.floor(valid)) {
var divisor = schema.multipleOf || schema.divisibleBy;
// Vanilla JS, prone to floating point rounding errors (e.g. 1.14 / .01 == 113.99999)
valid = (value/divisor === Math.floor(value/divisor));
// Use math.js is available
if(window.math) {
valid = window.math.mod(window.math.bignumber(value), window.math.bignumber(divisor)).equals(0);
}
// Use decimal.js is available
else if(window.Decimal) {
valid = (new window.Decimal(value)).mod(new window.Decimal(divisor)).equals(0);
}
if(!valid) {
errors.push({
path: path,
property: schema.multipleOf? 'multipleOf' : 'divisibleBy',
message: this.translate('error_multipleOf', [schema.multipleOf || schema.divisibleBy])
message: this.translate('error_multipleOf', [divisor])
});
}
}
// `maximum`
if(schema.hasOwnProperty('maximum')) {
if(schema.exclusiveMaximum && value >= schema.maximum) {
errors.push({
path: path,
property: 'maximum',
message: this.translate('error_maximum_excl', [schema.maximum])
});
// Vanilla JS, prone to floating point rounding errors (e.g. .999999999999999 == 1)
valid = schema.exclusiveMaximum? (value < schema.maximum) : (value <= schema.maximum);
// Use math.js is available
if(window.math) {
valid = window.math[schema.exclusiveMaximum?'smaller':'smallerEq'](
window.math.bignumber(value),
window.math.bignumber(schema.maximum)
);
}
// Use Decimal.js if available
else if(window.Decimal) {
valid = (new window.Decimal(value))[schema.exclusiveMaximum?'lt':'lte'](new window.Decimal(schema.maximum));
}
else if(!schema.exclusiveMaximum && value > schema.maximum) {
if(!valid) {
errors.push({
path: path,
property: 'maximum',
message: this.translate('error_maximum_incl', [schema.maximum])
message: this.translate(
(schema.exclusiveMaximum?'error_maximum_excl':'error_maximum_incl'),
[schema.maximum]
)
});
}
}
// `minimum`
if(schema.hasOwnProperty('minimum')) {
if(schema.exclusiveMinimum && value <= schema.minimum) {
errors.push({
path: path,
property: 'minimum',
message: this.translate('error_minimum_excl', [schema.minimum])
});
// Vanilla JS, prone to floating point rounding errors (e.g. .999999999999999 == 1)
valid = schema.exclusiveMinimum? (value > schema.minimum) : (value >= schema.minimum);
// Use math.js is available
if(window.math) {
valid = window.math[schema.exclusiveMinimum?'larger':'largerEq'](
window.math.bignumber(value),
window.math.bignumber(schema.minimum)
);
}
// Use Decimal.js if available
else if(window.Decimal) {
valid = (new window.Decimal(value))[schema.exclusiveMinimum?'gt':'gte'](new window.Decimal(schema.minimum));
}
else if(!schema.exclusiveMinimum && value < schema.minimum) {
if(!valid) {
errors.push({
path: path,
property: 'minimum',
message: this.translate('error_minimum_incl', [schema.minimum])
message: this.translate(
(schema.exclusiveMinimum?'error_minimum_excl':'error_minimum_incl'),
[schema.minimum]
)
});
}
}
@@ -269,7 +303,7 @@ JSONEditor.Validator = Class.extend({
// `minLength`
if(schema.minLength) {
if((value+"").length < schema.minLength) {
if((value+"").length < schema.minLength) {
errors.push({
path: path,
property: 'minLength',
View
@@ -5,6 +5,7 @@
<title>JSON Editor Validation Example</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src='../dist/jsoneditor.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjs/2.7.0/math.min.js'></script>
</head>
<body>
<div id='output'></div>
@@ -217,6 +218,13 @@
valid: [5,0,10],
invalid: [5.5,8,1]
},
multipleOfDecimal: {
schema: {
multipleOf: .01
},
valid: [1,1.14,3.57,56],
invalid: [1.012]
},
minmax: {
schema: {
type: "object",
@@ -530,7 +538,7 @@
schema: "",
schema2: 2
}
]
]
},
definitions: {
schema: {
@@ -545,7 +553,7 @@
},
definitions: {
diskDevice: {
pattern: "^/dev/[^/]+(/[^/]+)*$"
pattern: "^/dev/[^/]+(/[^/]+)*$"
},
external: {
"$ref": "http://localhost/json-editor/tests/string.json"
@@ -667,7 +675,7 @@
}
]
},
disallow: {
schema: {
type: "object",
@@ -677,7 +685,7 @@
"string",
{
type: "number",
maximum: 5
maximum: 5
}
]
},
@@ -717,7 +725,7 @@
invalid: ["1999","abc","abc 1999-01-01","1999-01-01 abc"]
}
};
// Custom validators must return an array of errors or an empty array if valid
$.jsoneditor.custom_validators.push(function(schema, value, path) {
var errors = [];
@@ -733,13 +741,13 @@
}
return errors;
});
var num = 0;
var animel = $("<div></div>");
$.each(tests,function(i,test) {
animel.queue(function(next) {
console.log(i);
try {
var editor = new JSONEditor(document.createElement('div'),{
schema: test.schema,
@@ -750,7 +758,7 @@
console.log(test.schema);
throw e;
}
editor.on('ready',function() {
$.each(test.valid,function(j,value) {
try {

0 comments on commit ac4728b

Please sign in to comment.