Skip to content

Commit 54820e2

Browse files
authored
Merge pull request jdorn#759 from mia-platform/align-with-json-editor-master
feat: Option "max_depth" and "use_default_values"
2 parents 5396510 + 8362060 commit 54820e2

File tree

12 files changed

+282
-17
lines changed

12 files changed

+282
-17
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### Unreleased
2+
- added option `max_depth` used to specify the maximum depth of level's schema that have to be rendered
3+
- added option `use_default_values` used to specify if default values based on the "type" of the property have to be used
4+
15
### 2.3.0-dev
26

37
- Removed codeception container, use `codeceptjs` as node-dev module

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 the nested properties to be rendered of provided json schema. The missing of this option could cause "maximum call stack size exceeded" in case of object properties with circular references. <code>0</code> value means "render all".</td>
282+
<td><code>0</code></td>
283+
</tr>
284+
<tr>
285+
<td>use_default_values</td>
286+
<td>If true default values based on the "type" of the property will be used</td>
287+
<td><code>true</code></td>
288+
</tr>
279289
</tbody>
280290
</table>
281291

config/karma.conf.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ module.exports = function (config) {
1919
// preprocess matching files before serving them to the browser
2020
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
2121
preprocessors: {
22-
'./src/core.js': [ 'webpack', 'sourcemap' ], // Same as entrypoint specified in webpack.config.js
23-
'./tests/unit/**/*.spec.js': [ 'webpack', 'sourcemap']
22+
'./src/core.js': ['webpack', 'sourcemap'], // Same as entrypoint specified in webpack.config.js
23+
'./tests/unit/**/*.spec.js': ['webpack', 'sourcemap']
2424
},
2525

2626
// list of files / patterns to exclude

src/core.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ export class JSONEditor {
3232
// eslint-disable-next-line new-cap
3333
this.theme = new themeClass(this)
3434
const rules = extend(themeClass.rules, this.getEditorsRules())
35-
3635
if (!this.theme.options.disable_theme_rules) {
3736
/* Attempt to locate a shadowRoot parent (i.e. in Web Components) */
3837
const shadowRoot = getShadowParent(this.element)
@@ -207,17 +206,15 @@ export class JSONEditor {
207206
classname = resolver(schema)
208207
return classname && JSONEditor.defaults.editors[classname]
209208
})
210-
211209
if (!classname) throw new Error(`Unknown editor for schema ${JSON.stringify(schema)}`)
212210
if (!JSONEditor.defaults.editors[classname]) throw new Error(`Unknown editor ${classname}`)
213-
214211
return JSONEditor.defaults.editors[classname]
215212
}
216213

217-
createEditor (editorClass, options) {
214+
createEditor (editorClass, options, depthCounter = 1) {
218215
options = extend({}, editorClass.options || {}, options)
219216
// eslint-disable-next-line new-cap
220-
return new editorClass(options, JSONEditor.defaults)
217+
return new editorClass(options, JSONEditor.defaults, depthCounter)
221218
}
222219

223220
onChange () {

src/defaults.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,9 @@ function translate (key, variables) {
287287
/* Default options when initializing JSON Editor */
288288
const options = {
289289
upload,
290-
prompt_before_delete: true
290+
prompt_before_delete: true,
291+
use_default_values: true,
292+
max_depth: 0
291293
}
292294

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

src/editor.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,10 @@ 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
@@ -534,9 +538,9 @@ export class AbstractEditor {
534538
if (type && Array.isArray(type)) type = type[0]
535539

536540
if (typeof type === 'string') {
537-
if (type === 'number') return 0.0
538-
if (type === 'boolean') return false
539-
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
540544
if (type === 'string') return ''
541545
if (type === 'object') return {}
542546
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: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import { AbstractEditor } from '../editor.js'
22
import { extend, trigger, hasOwnProperty } from '../utilities.js'
33

44
export class ObjectEditor extends AbstractEditor {
5+
constructor (options, defaults, depth) {
6+
super(options, defaults)
7+
this.currentDepth = depth
8+
}
9+
510
getDefault () {
611
return extend({}, this.schema.default || {})
712
}
@@ -385,7 +390,7 @@ export class ObjectEditor extends AbstractEditor {
385390
parent: this,
386391
compact: true,
387392
required: true
388-
})
393+
}, this.currentDepth + 1)
389394
this.editors[key].preBuild()
390395

391396
const width = this.editors[key].options.hidden ? 0 : (this.editors[key].options.grid_columns || this.editors[key].getNumColumns())
@@ -956,6 +961,31 @@ export class ObjectEditor extends AbstractEditor {
956961
}
957962
}
958963

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+
...acc,
973+
[key]: {}
974+
}
975+
case 'additionalProperties':
976+
return {
977+
...acc,
978+
[key]: true
979+
}
980+
default:
981+
return {
982+
...acc,
983+
[key]: schema[key]
984+
}
985+
}
986+
}, {})
987+
}
988+
959989
addObjectProperty (name, prebuildOnly) {
960990
/* Property is already added */
961991
if (this.editors[name]) return
@@ -980,12 +1010,14 @@ export class ObjectEditor extends AbstractEditor {
9801010
/* Add the property */
9811011
const editor = this.jsoneditor.getEditorClass(schema)
9821012

1013+
const { max_depth: maxDepth } = this.jsoneditor.options
1014+
9831015
this.editors[name] = this.jsoneditor.createEditor(editor, {
9841016
jsoneditor: this.jsoneditor,
985-
schema,
1017+
schema: !!maxDepth && this.currentDepth >= maxDepth ? this.getSchemaOnMaxDepth(schema) : schema,
9861018
path: `${this.path}.${name}`,
9871019
parent: this
988-
})
1020+
}, this.currentDepth + 1)
9891021
this.editors[name].preBuild()
9901022

9911023
if (!prebuildOnly) {

src/editors/select.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,16 @@ import { extend } from '../utilities.js'
44
export class SelectEditor extends AbstractEditor {
55
setValue (value, initial) {
66
/* Sanitize value before setting it */
7-
let sanitized = this.typecast(value || '')
7+
let sanitized = this.typecast(value)
88

9-
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+
}
1017

1118
if (this.value === sanitized) return
1219

@@ -45,6 +52,7 @@ export class SelectEditor extends AbstractEditor {
4552
if (this.schema.type === 'boolean') return value === 'undefined' || value === undefined ? undefined : !!value
4653
else if (this.schema.type === 'number') return 1 * value || 0
4754
else if (this.schema.type === 'integer') return Math.floor(value * 1 || 0)
55+
else if (this.schema.enum && value === undefined) return undefined
4856
return `${value}`
4957
}
5058

tests/fixtures/nested_object.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"foo1": {
5+
"type": "object",
6+
"properties": {
7+
"foo2": {
8+
"type": "object",
9+
"properties": {
10+
"foo3": {
11+
"type": "object",
12+
"properties": {
13+
"foo4": {
14+
"type": "object",
15+
"properties": {
16+
"bar": {"type": "string", "default": "end schema"}
17+
}
18+
}
19+
}
20+
}
21+
}
22+
}
23+
}
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)