@json-editor/json-editor 2.8.0 → 2.9.0-beta.1

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 (59) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/README.md +30 -9
  3. package/dist/jsoneditor.js +2 -2
  4. package/dist/nonmin/jsoneditor.js +1211 -126
  5. package/dist/nonmin/jsoneditor.js.map +1 -1
  6. package/docs/index.html +22 -10
  7. package/docs/meta_schema.json +3 -2
  8. package/docs/starrating.html +2 -6
  9. package/package.json +4 -2
  10. package/src/defaults.js +9 -1
  11. package/src/editor.js +17 -3
  12. package/src/editors/array.js +7 -4
  13. package/src/editors/multiselect.js +1 -0
  14. package/src/editors/object.css +3 -3
  15. package/src/editors/object.css.js +1 -1
  16. package/src/editors/object.js +5 -2
  17. package/src/editors/table.js +11 -4
  18. package/src/editors/upload.js +3 -2
  19. package/src/schemaloader.js +112 -19
  20. package/src/themes/barebones.js +3 -1
  21. package/src/themes/bootstrap5.css +97 -0
  22. package/src/themes/bootstrap5.css.js +3 -0
  23. package/src/themes/bootstrap5.js +623 -0
  24. package/src/themes/index.js +2 -0
  25. package/src/themes/tailwind.js +2 -2
  26. package/tests/codeceptjs/core_test.js +128 -17
  27. package/tests/codeceptjs/editors/array_test.js +6 -5
  28. package/tests/codeceptjs/editors/button_test.js +7 -6
  29. package/tests/codeceptjs/editors/checkbox_test.js +3 -2
  30. package/tests/codeceptjs/editors/integer_test.js +3 -2
  31. package/tests/codeceptjs/editors/issues/issue-gh-1158_test.js +10 -0
  32. package/tests/codeceptjs/editors/issues/issue-gh-1257_test.js +13 -0
  33. package/tests/codeceptjs/editors/number_test.js +2 -1
  34. package/tests/codeceptjs/editors/object_test.js +39 -38
  35. package/tests/codeceptjs/editors/option-no_default_values_test.js +1 -1
  36. package/tests/codeceptjs/editors/programmatic-changes_test.js +3 -2
  37. package/tests/codeceptjs/editors/tabs_test.js +5 -3
  38. package/tests/codeceptjs/editors/validation_test.js +3 -1
  39. package/tests/codeceptjs/meta-schema_test.js +72 -4
  40. package/tests/codeceptjs/schemaloader_test.js +2 -1
  41. package/tests/codeceptjs/test-config.js +3 -0
  42. package/tests/codeceptjs/themes_test.js +14 -0
  43. package/tests/pages/anyof-2.html +90 -0
  44. package/tests/pages/anyof.html +1 -1
  45. package/tests/pages/{table-move-events.html → array-events-table.html} +0 -0
  46. package/tests/pages/{array-move-events.html → array-events.html} +0 -0
  47. package/tests/pages/container-attributes.html +50 -0
  48. package/tests/pages/issues/issue-gh-1158.html +50 -0
  49. package/tests/pages/issues/issue-gh-1233-failing.html +46 -0
  50. package/tests/pages/issues/issue-gh-1233-passing.html +49 -0
  51. package/tests/pages/issues/issue-gh-1257.html +77 -0
  52. package/tests/pages/meta-schema.html +747 -0
  53. package/tests/pages/meta_schema.json +3 -16
  54. package/tests/pages/oneof-2.html +90 -0
  55. package/tests/pages/per-editor-options.html +44 -0
  56. package/tests/pages/references.html +6 -0
  57. package/tests/pages/stepper.html +2 -2
  58. package/tests/pages/themes.html +2 -0
  59. package/tests/unit/schemaloader.spec.js +108 -2
@@ -625,20 +625,6 @@
625
625
  "tilte":"title"
626
626
  }
627
627
  },
628
- "enum": {
629
- "type": "array",
630
- "items": {
631
- "type": "object",
632
- "properties": {
633
- "title": {
634
- "type": "string"
635
- },
636
- "infoText":{
637
- "type": "string"
638
- }
639
- }
640
- }
641
- },
642
628
  "grid_columns":{
643
629
  "type":"integer",
644
630
  "default": 1,
@@ -655,9 +641,10 @@
655
641
  }
656
642
  }
657
643
  },
658
-
659
644
  "schema":{
660
- "$ref":"#/definitions/schemaBase",
645
+ "allOf":[{
646
+ "$ref":"#/definitions/schemaBase"
647
+ }],
661
648
  "options":{
662
649
  "keep_oneof_values":false
663
650
  },
@@ -0,0 +1,90 @@
1
+ <!DOCTYPE html>
2
+ <html lang="de">
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <title>oneOf</title>
6
+ <link rel="stylesheet" id="theme-link" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
7
+ <link rel="stylesheet" id="iconlib-link" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css">
8
+ <script src="../../dist/jsoneditor.js"></script>
9
+ </head>
10
+ <body>
11
+
12
+ <div class="container">
13
+ <label for="value">Value</label>
14
+ <textarea class="form-control" id="value" rows="12" style="font-size: 12px; font-family: monospace;"></textarea>
15
+ <button id="set-value">Set Value</button>
16
+ <div class='json-editor-container'></div>
17
+ </div>
18
+
19
+ <script>
20
+ var jsonEditorContainer = document.querySelector('.json-editor-container')
21
+ var value = document.querySelector('#value')
22
+ var setValue = document.querySelector('#set-value')
23
+ var schema = {
24
+ 'title': 'oneOf',
25
+ 'type': 'object',
26
+ 'properties': {
27
+ 'test': {
28
+ 'oneOf': [
29
+ {
30
+ 'type': 'string',
31
+ 'title': 'Value, string',
32
+ 'const': 'test'
33
+ },
34
+ {
35
+ 'type': 'boolean',
36
+ 'title': 'Value, boolean',
37
+ 'const': true
38
+ },
39
+ {
40
+ 'type': 'array',
41
+ 'title': 'Value, array',
42
+ 'const': [0]
43
+ },
44
+ {
45
+ 'type': 'object',
46
+ 'title': 'Value, object',
47
+ 'required': ['test'],
48
+ 'const': { 'test': 'test' }
49
+ },
50
+ {
51
+ 'type': 'number',
52
+ 'title': 'Value, number',
53
+ 'const': 1.1
54
+ },
55
+ {
56
+ 'type': 'integer',
57
+ 'title': 'Value, integer',
58
+ 'const': 1.1
59
+ },
60
+ {
61
+ 'type': 'null',
62
+ 'title': 'Value, null'
63
+ }
64
+ ]
65
+ }
66
+ }
67
+ }
68
+
69
+ var editor = new JSONEditor(jsonEditorContainer, {
70
+ schema: schema,
71
+ theme: 'bootstrap4',
72
+ show_errors: 'always',
73
+ iconlib: 'fontawesome5',
74
+ disable_collapse: true,
75
+ disable_edit_json: true,
76
+ disable_properties: true,
77
+ keep_oneof_values: false
78
+ })
79
+
80
+ editor.on('change', function () {
81
+ value.value = JSON.stringify(editor.getValue())
82
+ })
83
+
84
+ setValue.addEventListener('click', function () {
85
+ editor.setValue(JSON.parse(value.value))
86
+ })
87
+ </script>
88
+
89
+ </body>
90
+ </html>
@@ -0,0 +1,44 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <title>Per Editor Options</title>
6
+ <link rel="stylesheet" id="theme-link" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
7
+ <link rel="stylesheet" id="iconlib-link" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css">
8
+ <script src="../../dist/jsoneditor.js"></script>
9
+ </head>
10
+ <body>
11
+
12
+ <div class="container">
13
+ <h1>Test: Per Editor Options</h1>
14
+ <div class='json-editor-container'></div>
15
+ </div>
16
+
17
+ <script>
18
+ JSONEditor.defaults.editors.object.options.collapsed = true;
19
+
20
+ var jsonEditorContainer = document.querySelector('.json-editor-container');
21
+ var value = document.querySelector('.value');
22
+
23
+ var schema = {
24
+ "title": "Configuration",
25
+ "type": "object",
26
+ "properties": {
27
+ "test": {
28
+ "type": "boolean",
29
+ "title": "test"
30
+ }
31
+ }
32
+ }
33
+
34
+ var editor = new JSONEditor(jsonEditorContainer, {
35
+ schema: schema,
36
+ theme: 'bootstrap4',
37
+ disable_edit_json: true,
38
+ disable_properties: true,
39
+ array_controls_top: true,
40
+ iconlib: 'fontawesome5'
41
+ })
42
+ </script>
43
+ </body>
44
+ </html>
@@ -58,6 +58,12 @@
58
58
  // Enable fetching schemas via ajax
59
59
  ajax: true,
60
60
 
61
+ // Enable caching schemas from via ajax
62
+ ajax_cache_responses: true,
63
+
64
+ // The cache-buster for cached caches
65
+ ajax_cache_buster: 'abc123',
66
+
61
67
  // The schema for the editor
62
68
  schema: {
63
69
  $schema: "https://json-schema.org/draft-04/schema",
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8"/>
5
5
  <title>Stepper</title>
6
- <link rel="stylesheet" id="theme-link" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
6
+ <link rel="stylesheet" id="theme-link" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css">
7
7
  <link rel="stylesheet" id="iconlib-link" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css">
8
8
  <script src="https://cdn.jsdelivr.net/npm/mathjs@5.3.1/dist/math.min.js" class="external_mathjs"></script>
9
9
  <script src="../../dist/jsoneditor.js"></script>
@@ -38,7 +38,7 @@
38
38
 
39
39
  var editor = new JSONEditor(jsonEditorContainer, {
40
40
  schema: schema,
41
- theme: 'bootstrap4',
41
+ theme: 'bootstrap5',
42
42
  use_default_values: false,
43
43
  required_by_default: true,
44
44
  show_errors: 'always'
@@ -16,6 +16,7 @@
16
16
  <option value='bootstrap2'>Bootstrap 2</option>
17
17
  <option value='bootstrap3'>Bootstrap 3</option>
18
18
  <option value='bootstrap4'>Bootstrap 4</option>
19
+ <option value='bootstrap5'>Bootstrap 5</option>
19
20
  <option value='foundation3'>Foundation 3</option>
20
21
  <option value='foundation4'>Foundation 4</option>
21
22
  <option value='foundation5'>Foundation 5</option>
@@ -487,6 +488,7 @@
487
488
  bootstrap2: 'https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css',
488
489
  bootstrap3: 'https://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css',
489
490
  bootstrap4: 'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css',
491
+ bootstrap5: 'https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css',
490
492
  foundation3: 'https://cdnjs.cloudflare.com/ajax/libs/foundation/3.2.5/stylesheets/foundation.css',
491
493
  foundation4: 'https://cdnjs.cloudflare.com/ajax/libs/foundation/4.3.2/css/foundation.min.css',
492
494
  foundation5: 'https://cdnjs.cloudflare.com/ajax/libs/foundation/5.5.3/css/foundation.min.css',
@@ -80,7 +80,7 @@ describe('SchemaLoader', () => {
80
80
  })
81
81
 
82
82
  describe('when external absolute ref exists', () => {
83
- it('should set oprion { ajax: true }', async () => {
83
+ it('should set option { ajax: true }', async () => {
84
84
  const response = {
85
85
  type: 'string',
86
86
  minLength: 4
@@ -117,7 +117,7 @@ describe('SchemaLoader', () => {
117
117
  })
118
118
 
119
119
  describe('when external relative $ref exists', () => {
120
- it('should set oprion { ajax: true }', async () => {
120
+ it('should set option { ajax: true }', async () => {
121
121
  const response = {
122
122
  type: 'string',
123
123
  minLength: 4
@@ -467,4 +467,110 @@ describe('SchemaLoader', () => {
467
467
  expect(Object.keys(loader.refs).length).toBe(1)
468
468
  })
469
469
  })
470
+
471
+ describe('when schemas caching is enabled', () => {
472
+ beforeEach(() => {
473
+ // Mocks window.localStorage system.
474
+ // Thanks to https://stackoverflow.com/a/32911774.
475
+ var localStorageMock = (function () {
476
+ var store = {}
477
+ return {
478
+ getItem: function (key) {
479
+ return store[key]
480
+ },
481
+ setItem: function (key, value) {
482
+ store[key] = value.toString()
483
+ },
484
+ clear: function () {
485
+ store = {}
486
+ },
487
+ removeItem: function (key) {
488
+ delete store[key]
489
+ }
490
+ }
491
+ })()
492
+ Object.defineProperty(window, 'localStorage', { value: localStorageMock })
493
+ })
494
+ it('should store and retrieve cached items', async () => {
495
+ const schema = {
496
+ type: 'string',
497
+ minLength: 4
498
+ }
499
+ const cacheKey = 'myItem'
500
+ loader = new SchemaLoader({ ajax: true, ajax_cache_responses: true, ajax_cache_buster: 'abc123' })
501
+ loader.cacheSet(cacheKey, schema)
502
+
503
+ const schemaCached = loader.cacheGet(cacheKey)
504
+ expect(schemaCached).toEqual(schema)
505
+ })
506
+ it('should not retrieve cached item with invalid cache buster', async () => {
507
+ const schema = {
508
+ type: 'string',
509
+ minLength: 4
510
+ }
511
+ const cacheKey = 'myItem'
512
+ loader = new SchemaLoader({ ajax: true, ajax_cache_responses: true, ajax_cache_buster: 'abc123' })
513
+ loader.cacheSet(cacheKey, schema)
514
+
515
+ loader.options.ajax_cache_buster = 'not-abc123'
516
+ const schemaCached = loader.cacheGet(cacheKey)
517
+ expect(schemaCached).toBeUndefined()
518
+ })
519
+ it('should fetch schemas from cache { ajax: true, ajax_cache_responses: true }', async () => {
520
+ // Runs two passes, the first to warm cache and second to fetch from cache.
521
+ const response = {
522
+ type: 'string',
523
+ minLength: 4
524
+ }
525
+ const server = createFakeServer()
526
+ server.autoRespond = true
527
+ window.XMLHttpRequest = server.xhr
528
+ server.respondWith('/string.json', [
529
+ 200,
530
+ { 'Content-Type': 'application/json' },
531
+ JSON.stringify(response)
532
+ ])
533
+ fetchUrl =
534
+ document.location.origin + document.location.pathname.toString()
535
+ loader = new SchemaLoader({ ajax: true, ajax_cache_responses: true })
536
+ fileBase = loader._getFileBase(document.location.toString())
537
+
538
+ // Pass one: Warm the cache.
539
+ const schema = {
540
+ type: 'object',
541
+ properties: {
542
+ fname: { $ref: '/string.json' },
543
+ lname: { $ref: '/string.json' }
544
+ }
545
+ }
546
+ await loader.load(
547
+ schema,
548
+ fetchUrl,
549
+ fileBase
550
+ )
551
+ const urls = Object.keys(loader.refs)
552
+ expect(urls.length).toEqual(1)
553
+
554
+ // Tears down the mock Ajax endpoint to ensure any schemas get fetched from cache.
555
+ server.restore()
556
+
557
+ // Pass two: Should fetch external schemas from cache.
558
+ // Requires a fresh loader because SchemaLoader.refs can return stale data.
559
+ const loaderFresh = new SchemaLoader({ ajax: true, ajax_cache_responses: true })
560
+ const schemaFromCache = {
561
+ type: 'object',
562
+ properties: {
563
+ fname: { $ref: '/string.json' },
564
+ lname: { $ref: '/string.json' }
565
+ }
566
+ }
567
+ await loaderFresh.load(
568
+ schemaFromCache,
569
+ fetchUrl,
570
+ fileBase
571
+ )
572
+ const urlsFromCache = Object.keys(loaderFresh.refs)
573
+ expect(urlsFromCache.length).toEqual(1)
574
+ })
575
+ })
470
576
  })