Skip to content

Commit 7006b41

Browse files
author
Riccardo Di Benedetto
committed
refactor
1 parent dd0f585 commit 7006b41

File tree

12 files changed

+221
-54
lines changed

12 files changed

+221
-54
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,16 @@ Here are all the available options:
276276
<td>Preserve value at Move Up or Down.(No value is selected automatically upon deletion.)</td>
277277
<td><code>true</code></td>
278278
</tr>
279+
<tr>
280+
<td>max_depth</td>
281+
<td>Max depth of an object that have to be rendered. The missing of this option could cause "maximum call stack size exceeded" in case of recursive object properties</td>
282+
<td><code>infinite</code></td>
283+
</tr>
284+
<tr>
285+
<td>use_default_values</td>
286+
<td>True if have to be used default values based on the "type" of the property</td>
287+
<td><code>true</code></td>
288+
</tr>
279289
</tbody>
280290
</table>
281291

config/karma.conf.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module.exports = function (config) {
1313

1414
// list of files / patterns to load in the browser
1515
files: [
16-
{ pattern: './tests/unit/**/*.spec.js', watched: false }
16+
{ pattern: './tests/unit/core.spec.js', watched: false }
1717
],
1818

1919
// preprocess matching files before serving them to the browser

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"title": "JSONEditor",
44
"description": "JSON Schema based editor",
55
"version": "2.2.1",
6-
"main": "dist/jsoneditor.js",
6+
"main": "dist/nonmin/jsoneditor.js",
77
"author": {
88
"name": "Jeremy Dorn",
99
"email": "jeremy@jeremydorn.com",

src/core.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ export class JSONEditor {
2626
const themeName = this.options.theme || JSONEditor.defaults.theme
2727
const themeClass = JSONEditor.defaults.themes[themeName]
2828

29-
this.MAX_RECURSIONS = this.options.maxRecursions
30-
3129
/* Load editors and selected theme style rules */
3230
if (!themeClass) throw new Error(`Unknown theme ${themeName}`)
3331
this.element.setAttribute('data-theme', themeName)
@@ -208,17 +206,15 @@ export class JSONEditor {
208206
classname = resolver(schema)
209207
return classname && JSONEditor.defaults.editors[classname]
210208
})
211-
212209
if (!classname) throw new Error(`Unknown editor for schema ${JSON.stringify(schema)}`)
213210
if (!JSONEditor.defaults.editors[classname]) throw new Error(`Unknown editor ${classname}`)
214-
215211
return JSONEditor.defaults.editors[classname]
216212
}
217213

218-
createEditor (editorClass, options, recursion = 0) {
214+
createEditor (editorClass, options, depthCounter = 0) {
219215
options = extend({}, editorClass.options || {}, options)
220216
// eslint-disable-next-line new-cap
221-
return new editorClass(options, JSONEditor.defaults, recursion)
217+
return new editorClass(options, JSONEditor.defaults, depthCounter)
222218
}
223219

224220
onChange () {

src/defaults.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,7 @@ function translate (key, variables) {
284284
const options = {
285285
upload,
286286
prompt_before_delete: true,
287-
useDefault: true,
288-
maxRecursions: 99999
287+
use_default_values: true
289288
}
290289

291290
/* This assignment was previously in index.js but makes more sense here */

src/editor.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -519,15 +519,15 @@ export class AbstractEditor {
519519
this.parent = null
520520
}
521521

522+
isDefaultRequired () {
523+
return this.isRequired() || !!this.jsoneditor.options.use_default_values
524+
}
525+
522526
getDefault () {
523527
if (typeof this.schema.default !== 'undefined') {
524528
return this.schema.default
525529
}
526530

527-
if (!this.jsoneditor.options.useDefault) {
528-
return null
529-
}
530-
531531
if (typeof this.schema.enum !== 'undefined') {
532532
return this.schema.enum[0]
533533
}
@@ -538,9 +538,9 @@ export class AbstractEditor {
538538
if (type && Array.isArray(type)) type = type[0]
539539

540540
if (typeof type === 'string') {
541-
if (type === 'number') return 0.0
542-
if (type === 'boolean') return false
543-
if (type === 'integer') return 0
541+
if (type === 'number') return this.isDefaultRequired() ? 0.0 : undefined
542+
if (type === 'boolean') return this.isDefaultRequired() ? false : undefined
543+
if (type === 'integer') return this.isDefaultRequired() ? 0 : undefined
544544
if (type === 'string') return ''
545545
if (type === 'object') return {}
546546
if (type === 'array') return []

src/editors/multiple.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,6 @@ export class MultipleEditor extends AbstractEditor {
208208
schema.required = this.schema.required.concat(type.required)
209209
}
210210
}
211-
212211
this.validators[i] = new Validator(this.jsoneditor, schema, validatorOptions, this.defaults)
213212
})
214213

src/editors/object.js

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ import { AbstractEditor } from '../editor.js'
22
import { extend, trigger, hasOwnProperty } from '../utilities.js'
33

44
export class ObjectEditor extends AbstractEditor {
5-
constructor (options, defaults, recursions) {
5+
constructor (options, defaults, depth) {
66
super(options, defaults)
7-
this.currentRecursions = recursions
8-
this.collapsed = null
7+
this.currentDepth = depth
98
}
109

1110
getDefault () {
@@ -391,7 +390,7 @@ export class ObjectEditor extends AbstractEditor {
391390
parent: this,
392391
compact: true,
393392
required: true
394-
}, this.currentRecursions + 1)
393+
}, this.currentDepth + 1)
395394
this.editors[key].preBuild()
396395

397396
const width = this.editors[key].options.hidden ? 0 : (this.editors[key].options.grid_columns || this.editors[key].getNumColumns())
@@ -962,6 +961,23 @@ export class ObjectEditor extends AbstractEditor {
962961
}
963962
}
964963

964+
getSchemaOnMaxDepth (schema) {
965+
return Object.keys(schema).reduce((acc, key) => {
966+
switch (key) {
967+
case '$ref':
968+
return acc
969+
case 'properties':
970+
case 'items':
971+
return {}
972+
default:
973+
return {
974+
...acc,
975+
[key]: schema[key]
976+
}
977+
}
978+
}, {})
979+
}
980+
965981
addObjectProperty (name, prebuildOnly) {
966982
/* Property is already added */
967983
if (this.editors[name]) return
@@ -986,12 +1002,14 @@ export class ObjectEditor extends AbstractEditor {
9861002
/* Add the property */
9871003
const editor = this.jsoneditor.getEditorClass(schema)
9881004

1005+
const { max_depth: maxDepth } = this.jsoneditor.options
1006+
9891007
this.editors[name] = this.jsoneditor.createEditor(editor, {
9901008
jsoneditor: this.jsoneditor,
991-
schema: this.currentRecursions >= this.jsoneditor.MAX_RECURSIONS ? { type: schema.type || null } : schema,
1009+
schema: maxDepth !== undefined && this.currentDepth >= maxDepth ? this.getSchemaOnMaxDepth(schema) : schema,
9921010
path: `${this.path}.${name}`,
9931011
parent: this
994-
}, this.currentRecursions + 1)
1012+
}, this.currentDepth + 1)
9951013
this.editors[name].preBuild()
9961014

9971015
if (!prebuildOnly) {

src/editors/select.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,17 @@ import { extend } from '../utilities.js'
33

44
export class SelectEditor extends AbstractEditor {
55
setValue (value, initial) {
6-
const correctValue = initial && value === null && this.value === undefined ? 'undefined' : value
76
/* Sanitize value before setting it */
8-
let sanitized = this.typecast(correctValue || '')
7+
let sanitized = this.typecast(value)
98

10-
if (!this.enum_values.includes(sanitized)) sanitized = this.enum_values[0]
9+
const haveToUseDefaultValue = !!this.jsoneditor.options.use_default_values || typeof this.schema.default !== 'undefined'
10+
11+
if (
12+
!this.enum_values.includes(sanitized) ||
13+
(initial && !this.isRequired() && !haveToUseDefaultValue)
14+
) {
15+
sanitized = this.enum_values[0]
16+
}
1117

1218
if (this.value === sanitized) return
1319

@@ -46,6 +52,7 @@ export class SelectEditor extends AbstractEditor {
4652
if (this.schema.type === 'boolean') return value === 'undefined' || value === undefined ? undefined : !!value
4753
else if (this.schema.type === 'number') return 1 * value || 0
4854
else if (this.schema.type === 'integer') return Math.floor(value * 1 || 0)
55+
else if (this.schema.enum && value === undefined) return undefined
4956
return `${value}`
5057
}
5158

tests/fixtures/some_types.json

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"boolean": {
5+
"type": "boolean",
6+
"description": "This description should only appear once"
7+
},
8+
"enum": {
9+
"type": "string",
10+
"enum": ["foo", "bar"]
11+
},
12+
"integer": {
13+
"type": "integer"
14+
},
15+
"number": {
16+
"type": "number"
17+
},
18+
"string": {
19+
"type": "string"
20+
},
21+
"object": {
22+
"type": "object",
23+
"properties": {}
24+
},
25+
"array": {
26+
"type": "array",
27+
"items": {
28+
"type": "string"
29+
}
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)