@json-editor/json-editor 2.5.4 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/.github/workflows/build.yml +12 -3
  2. package/CHANGELOG.md +51 -14
  3. package/README.md +159 -20
  4. package/dist/jsoneditor.js +2 -2
  5. package/dist/nonmin/jsoneditor.js +5483 -3610
  6. package/dist/nonmin/jsoneditor.js.map +1 -1
  7. package/docs/cleave.html +1 -1
  8. package/docs/datetime.html +1 -1
  9. package/docs/describedby.html +1 -1
  10. package/docs/form-submission.html +76 -0
  11. package/docs/index.html +2 -2
  12. package/docs/materialize_css.html +1 -1
  13. package/docs/meta_schema.json +0 -1
  14. package/docs/radio.html +1 -1
  15. package/docs/select2.html +1 -1
  16. package/docs/selectize.html +1 -1
  17. package/docs/starrating.html +1 -1
  18. package/docs/wysiwyg.html +1 -1
  19. package/package.json +28 -26
  20. package/release-notes.md +5 -3
  21. package/src/core.js +36 -37
  22. package/src/defaults.js +9 -2
  23. package/src/editor.js +6 -2
  24. package/src/editors/array.js +12 -1
  25. package/src/editors/autocomplete.js +4 -3
  26. package/src/editors/button.js +1 -1
  27. package/src/editors/multiple.js +2 -0
  28. package/src/editors/multiselect.js +14 -5
  29. package/src/editors/object.js +10 -6
  30. package/src/editors/radio.js +6 -1
  31. package/src/editors/string.js +7 -1
  32. package/src/editors/table.js +21 -2
  33. package/src/editors/upload.js +1 -1
  34. package/src/editors/uuid.js +2 -12
  35. package/src/iconlib.js +1 -1
  36. package/src/schemaloader.js +232 -109
  37. package/src/style.css +3 -0
  38. package/src/style.css.js +1 -1
  39. package/src/theme.js +5 -4
  40. package/src/themes/bootstrap3.js +3 -2
  41. package/src/themes/bootstrap4.js +7 -0
  42. package/src/themes/spectre.js +2 -1
  43. package/src/utilities.js +18 -0
  44. package/src/validator.js +65 -47
  45. package/tests/codeceptjs/codecept.json +1 -1
  46. package/tests/codeceptjs/core_test.js +98 -0
  47. package/tests/codeceptjs/editors/advanced_test.js +1 -1
  48. package/tests/codeceptjs/editors/array_test.js +74 -0
  49. package/tests/codeceptjs/editors/autocomplete_test.js +16 -0
  50. package/tests/codeceptjs/editors/button_test.js +11 -4
  51. package/tests/codeceptjs/editors/integer_test.js +7 -2
  52. package/tests/codeceptjs/editors/jodit_test.js +3 -3
  53. package/tests/codeceptjs/editors/object_test.js +84 -13
  54. package/tests/codeceptjs/editors/range_test.js +12 -0
  55. package/tests/codeceptjs/editors/stepper_test.js +12 -0
  56. package/tests/codeceptjs/editors/uuid_test.js +31 -4
  57. package/tests/codeceptjs/editors/validation_test.js +1 -1
  58. package/tests/docker-compose.yml +1 -1
  59. package/tests/fixtures/definitions.json +22 -0
  60. package/tests/fixtures/properties.json +20 -0
  61. package/tests/fixtures/validation.json +207 -0
  62. package/tests/pages/array-checkboxes-infotext.html +52 -0
  63. package/tests/pages/array-move-events.html +4 -2
  64. package/tests/pages/array-unique-items-sort.html +78 -0
  65. package/tests/pages/autocomplete.html +69 -0
  66. package/tests/pages/button-icons.html +38 -0
  67. package/tests/pages/core.html +4 -2
  68. package/tests/pages/error-messages.html +47 -0
  69. package/tests/pages/grid-strict.html +6 -10
  70. package/tests/pages/grid.html +0 -4
  71. package/tests/pages/issues/issue-gh-812.html +4 -2
  72. package/tests/pages/meta_schema.json +14 -1
  73. package/tests/pages/object-required-properties.html +37 -14
  74. package/tests/pages/object-show-opt-in.html +110 -0
  75. package/tests/pages/object-with-dependencies-array.html +29 -19
  76. package/tests/pages/range.html +60 -0
  77. package/tests/pages/ready.html +43 -0
  78. package/tests/pages/references.html +162 -0
  79. package/tests/pages/stepper-manual.html +57 -0
  80. package/tests/pages/string-simplemde-editor.html +81 -0
  81. package/tests/pages/table-move-events.html +4 -1
  82. package/tests/pages/urn.html +11 -8
  83. package/tests/pages/uuid.html +89 -50
  84. package/tests/pages/validation-messages.json +705 -0
  85. package/tests/unit/core.spec.js +79 -66
  86. package/tests/unit/editor.spec.js +20 -8
  87. package/tests/unit/editors/array.spec.js +3 -2
  88. package/tests/unit/editors/object.spec.js +3 -1
  89. package/tests/unit/editors/table.spec.js +4 -2
  90. package/tests/unit/schemaloader.spec.js +77 -105
  91. package/tests/unit/validator.spec.js +10 -0
@@ -20,19 +20,19 @@ describe('SchemaLoader', () => {
20
20
  expect(loader).toBeTruthy()
21
21
  })
22
22
 
23
- it('load schema without $ref', () => {
23
+ it('load schema without $ref', async () => {
24
24
  const schema = {
25
25
  type: 'object',
26
26
  properties: {
27
27
  name: { type: 'string' }
28
28
  }
29
29
  }
30
- loader.load(schema, schema => {}, fetchUrl, fileBase)
30
+ await loader.load(schema, fetchUrl, fileBase)
31
31
  const urls = Object.keys(loader.refs)
32
32
  expect(urls.length).toEqual(0)
33
33
  })
34
34
 
35
- it('load schema with $ref', () => {
35
+ it('load schema with $ref', async () => {
36
36
  const schema = {
37
37
  definitions: {
38
38
  name: {
@@ -46,12 +46,12 @@ describe('SchemaLoader', () => {
46
46
  lname: { $ref: '#/definitions/name' }
47
47
  }
48
48
  }
49
- loader.load(schema, schema => {}, fetchUrl, fileBase)
49
+ await loader.load(schema, fetchUrl, fileBase)
50
50
  const urls = Object.keys(loader.refs)
51
- expect(urls.length).toEqual(1)
51
+ expect(urls.length).toEqual(0)
52
52
  })
53
53
 
54
- it('load schema with urn: $ref', () => {
54
+ it('load schema with urn: $ref', async () => {
55
55
  const schema = {
56
56
  definitions: {
57
57
  fname: {
@@ -73,14 +73,14 @@ describe('SchemaLoader', () => {
73
73
  lname: { $ref: 'urn:lname' }
74
74
  }
75
75
  }
76
- loader.load(schema, schema => {}, fetchUrl, fileBase)
76
+ await loader.load(schema, fetchUrl, fileBase)
77
77
  const urls = Object.keys(loader.refs)
78
- expect(urls.length).toEqual(4)
78
+ expect(urls.length).toEqual(2)
79
79
  })
80
80
  })
81
81
 
82
82
  describe('when external absolute ref exists', () => {
83
- it('should set oprion { ajax: true }', done => {
83
+ it('should set oprion { ajax: true }', async () => {
84
84
  const response = {
85
85
  type: 'string',
86
86
  minLength: 4
@@ -105,22 +105,19 @@ describe('SchemaLoader', () => {
105
105
  lname: { $ref: '/string.json' }
106
106
  }
107
107
  }
108
- loader.load(
108
+ await loader.load(
109
109
  schema,
110
- schema => {
111
- const urls = Object.keys(loader.refs)
112
- expect(urls.length).toEqual(1)
113
- done()
114
- server.restore()
115
- },
116
110
  fetchUrl,
117
111
  fileBase
118
112
  )
113
+ const urls = Object.keys(loader.refs)
114
+ expect(urls.length).toEqual(1)
115
+ server.restore()
119
116
  })
120
117
  })
121
118
 
122
119
  describe('when external relative $ref exists', () => {
123
- it('should set oprion { ajax: true }', done => {
120
+ it('should set oprion { ajax: true }', async () => {
124
121
  const response = {
125
122
  type: 'string',
126
123
  minLength: 4
@@ -145,22 +142,20 @@ describe('SchemaLoader', () => {
145
142
  lname: { $ref: 'string.json' }
146
143
  }
147
144
  }
148
- loader.load(
145
+ await loader.load(
149
146
  schema,
150
- schema => {
151
- const urls = Object.keys(loader.refs)
152
- expect(urls.length).toEqual(1)
153
- done()
154
- server.restore()
155
- },
147
+
156
148
  fetchUrl,
157
149
  fileBase
158
150
  )
151
+ const urls = Object.keys(loader.refs)
152
+ expect(urls.length).toEqual(1)
153
+ server.restore()
159
154
  })
160
155
  })
161
156
 
162
157
  describe('when external absolute-to-relative $ref exists', () => {
163
- it('can get refs recursively', done => {
158
+ it('can get refs recursively', async () => {
164
159
  const schema1 = {
165
160
  type: 'object',
166
161
  properties: {
@@ -192,21 +187,18 @@ describe('SchemaLoader', () => {
192
187
  document.location.origin + document.location.pathname.toString()
193
188
  loader = new SchemaLoader({ ajax: true })
194
189
  fileBase = loader._getFileBase(document.location.toString())
195
- loader.load(
190
+ await loader.load(
196
191
  schema1,
197
- schema => {
198
- expect(Object.keys(loader.refs).length).toBe(2)
199
- done()
200
- server.restore()
201
- },
202
192
  fetchUrl,
203
193
  fileBase
204
194
  )
195
+ expect(Object.keys(loader.refs).length).toBe(2)
196
+ server.restore()
205
197
  })
206
198
  })
207
199
 
208
200
  describe('when external relative-to-relative $ref exists', () => {
209
- it('can get refs recursively', done => {
201
+ it('can get refs recursively', async () => {
210
202
  const schema1 = {
211
203
  type: 'object',
212
204
  properties: {
@@ -238,22 +230,19 @@ describe('SchemaLoader', () => {
238
230
  document.location.origin + document.location.pathname.toString()
239
231
  loader = new SchemaLoader({ ajax: true })
240
232
  fileBase = loader._getFileBase(document.location.toString())
241
- loader.load(
233
+ await loader.load(
242
234
  schema1,
243
- schema => {
244
- console.log(loader.refs)
245
- expect(Object.keys(loader.refs).length).toBe(2)
246
- done()
247
- server.restore()
248
- },
249
235
  fetchUrl,
250
236
  fileBase
251
237
  )
238
+ expect(Object.keys(loader.refs).length).toBe(2)
239
+
240
+ server.restore()
252
241
  })
253
242
  })
254
243
 
255
244
  describe('when external absolute $ref with json pointer exists', () => {
256
- it('can get refs', done => {
245
+ it('can get refs', async () => {
257
246
  const schema1 = {
258
247
  type: 'object',
259
248
  properties: {
@@ -264,7 +253,8 @@ describe('SchemaLoader', () => {
264
253
  properties: {
265
254
  Product: { $ref: '/common.schema.json#/definitions/known-product' }
266
255
  }
267
- }
256
+ },
257
+ 'test-4': { $ref: '/common.schema.json#/properties/customer' }
268
258
  }
269
259
  }
270
260
  const schema2 = {
@@ -272,7 +262,7 @@ describe('SchemaLoader', () => {
272
262
  'known-product': {
273
263
  title: 'product',
274
264
  type: 'string',
275
- enum: [ 'power', 'hydrogen', 'heat' ]
265
+ enum: ['power', 'hydrogen', 'heat']
276
266
  }
277
267
  },
278
268
  title: 'test',
@@ -293,22 +283,18 @@ describe('SchemaLoader', () => {
293
283
  document.location.origin + document.location.pathname.toString()
294
284
  loader = new SchemaLoader({ ajax: true })
295
285
  fileBase = loader._getFileBase(document.location.toString())
296
- loader.load(
286
+ await loader.load(
297
287
  schema1,
298
- schema => {
299
- console.log(loader.refs)
300
- expect(Object.keys(loader.refs).length).toBe(2)
301
- done()
302
- server.restore()
303
- },
304
288
  fetchUrl,
305
289
  fileBase
306
290
  )
291
+ expect(Object.keys(loader.refs).length).toBe(1)
292
+ server.restore()
307
293
  })
308
294
  })
309
295
 
310
296
  describe('when external relative $ref with json pointer exists', () => {
311
- it('can get refs', done => {
297
+ it('can get refs', async () => {
312
298
  const schema1 = {
313
299
  type: 'object',
314
300
  properties: {
@@ -319,7 +305,8 @@ describe('SchemaLoader', () => {
319
305
  properties: {
320
306
  Product: { $ref: 'common.schema.json#/definitions/known-product' }
321
307
  }
322
- }
308
+ },
309
+ 'test-4': { $ref: '/common.schema.json#/properties/customer' }
323
310
  }
324
311
  }
325
312
  const schema2 = {
@@ -327,7 +314,7 @@ describe('SchemaLoader', () => {
327
314
  'known-product': {
328
315
  title: 'product',
329
316
  type: 'string',
330
- enum: [ 'power', 'hydrogen', 'heat' ]
317
+ enum: ['power', 'hydrogen', 'heat']
331
318
  }
332
319
  },
333
320
  title: 'test',
@@ -348,22 +335,18 @@ describe('SchemaLoader', () => {
348
335
  document.location.origin + document.location.pathname.toString()
349
336
  loader = new SchemaLoader({ ajax: true })
350
337
  fileBase = loader._getFileBase(document.location.toString())
351
- loader.load(
338
+ await loader.load(
352
339
  schema1,
353
- schema => {
354
- console.log(loader.refs)
355
- expect(Object.keys(loader.refs).length).toBe(2)
356
- done()
357
- server.restore()
358
- },
359
340
  fetchUrl,
360
341
  fileBase
361
342
  )
343
+ expect(Object.keys(loader.refs).length).toBe(2)
344
+ server.restore()
362
345
  })
363
346
  })
364
347
 
365
348
  describe('when external ref exists with json pointer', () => {
366
- it('should get ref and resolve json pointer', done => {
349
+ it('should get ref and resolve json pointer', async () => {
367
350
  const response = {
368
351
  definitions: {
369
352
  fruits: {
@@ -394,24 +377,21 @@ describe('SchemaLoader', () => {
394
377
  fruits: { $ref: '/fruits.json#/definitions/fruits' }
395
378
  }
396
379
  }
397
- loader.load(
380
+ await loader.load(
398
381
  schema,
399
- schema => {
400
- const urls = Object.keys(loader.refs)
401
- expect(urls.length).toEqual(1)
402
- expect(urls[0]).toEqual('/fruits.json#/definitions/fruits')
403
- expect(loader.refs['/fruits.json#/definitions/fruits']).toEqual({ enum: ['apple', 'banana', 'cherry'] })
404
- done()
405
- server.restore()
406
- },
407
382
  fetchUrl,
408
383
  fileBase
409
384
  )
385
+ const urls = Object.keys(loader.refs)
386
+ expect(urls.length).toEqual(1)
387
+ expect(urls[0]).toEqual('/fruits.json')
388
+ expect(loader.refs['/fruits.json'].definitions.fruits).toEqual({ enum: ['apple', 'banana', 'cherry'] })
389
+ server.restore()
410
390
  })
411
391
  })
412
392
 
413
393
  describe('when resolving undeclared URN $ref', () => {
414
- it('can get refs recursively', done => {
394
+ it('can get refs recursively', async () => {
415
395
  const schema1 = {
416
396
  type: 'object',
417
397
  properties: {
@@ -421,9 +401,9 @@ describe('SchemaLoader', () => {
421
401
  }
422
402
  const schema2 = {
423
403
  definitions: {
424
- name: {
425
- id: 'urn:main',
426
- $ref: 'urn:sub'
404
+ name: {
405
+ id: 'urn:main',
406
+ $ref: 'urn:sub'
427
407
  }
428
408
  }
429
409
  }
@@ -437,30 +417,27 @@ describe('SchemaLoader', () => {
437
417
  }
438
418
  }
439
419
  }
440
- loader = new SchemaLoader({ urn_resolver: (urn, callback) => {
441
- if (urn === 'urn:main') {
442
- callback(JSON.stringify(schema2))
443
- return true
444
- }
445
- if (urn === 'urn:sub') {
446
- callback(JSON.stringify(schema3))
447
- return true
448
- }
449
- return false
450
- }})
451
- loader.load(
452
- schema1,
453
- schema => {
454
- console.log(loader.refs_with_info)
455
- expect(Object.keys(loader.refs).length).toBe(4)
456
- done()
420
+
421
+ loader = new SchemaLoader({
422
+ urn_resolver: async (urn) => {
423
+ if (urn === 'urn:main') {
424
+ return JSON.stringify(schema2)
425
+ }
426
+ if (urn === 'urn:sub') {
427
+ return (JSON.stringify(schema3))
428
+ }
429
+ return false
457
430
  }
431
+ })
432
+ await loader.load(
433
+ schema1
458
434
  )
435
+ expect(Object.keys(loader.refs).length).toBe(2)
459
436
  })
460
437
  })
461
438
 
462
439
  describe('when resolving undeclared URN $ref with fragment', () => {
463
- it('can get refs recursively', done => {
440
+ it('can get refs recursively', async () => {
464
441
  const schema1 = {
465
442
  type: 'object',
466
443
  properties: {
@@ -478,21 +455,16 @@ describe('SchemaLoader', () => {
478
455
  }
479
456
  }
480
457
  }
481
- loader = new SchemaLoader({ urn_resolver: (urn, callback) => {
482
- if (urn === 'urn:main') {
483
- callback(JSON.stringify(schema2))
484
- return true
485
- }
486
- return false
487
- }})
488
- loader.load(
489
- schema1,
490
- schema => {
491
- console.log(loader.refs_with_info)
492
- expect(Object.keys(loader.refs).length).toBe(2)
493
- done()
458
+ loader = new SchemaLoader({
459
+ urn_resolver: async (urn) => {
460
+ if (urn === 'urn:main') {
461
+ return JSON.stringify(schema2)
462
+ }
463
+ return false
494
464
  }
495
- )
465
+ })
466
+ await loader.load(schema1)
467
+ expect(Object.keys(loader.refs).length).toBe(1)
496
468
  })
497
469
  })
498
470
  })
@@ -8,6 +8,7 @@ import fixtureString from '../fixtures/string.json'
8
8
  import fixtureRecursive from '../fixtures/recursive.json'
9
9
  import * as math from 'mathjs'
10
10
  import { createFakeServer } from 'sinon'
11
+ import * as deepEqual from 'fast-deep-equal'
11
12
 
12
13
  describe('Validator', () => {
13
14
  it('mathjs test', () => {
@@ -79,7 +80,16 @@ describe('Validation Test', () => {
79
80
  done()
80
81
  })
81
82
  })
83
+
84
+ it(`does not change valid data ${i + 1}`, (done) => {
85
+ editor.on('ready', () => {
86
+ editor.setValue(v)
87
+ expect(deepEqual(editor.getValue(), v)).toBe(true)
88
+ done()
89
+ })
90
+ })
82
91
  })
92
+
83
93
  spec.invalid.forEach((v, i) => {
84
94
  it(`invalid data ${i + 1}`, (done) => {
85
95
  editor.on('ready', () => {