@json-editor/json-editor 2.11.0 → 2.12.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.
- package/.env +1 -1
- package/CHANGELOG.md +11 -0
- package/README.md +77 -1
- package/README_ADDON.md +5 -1
- package/dist/jsoneditor.js +1 -1
- package/dist/jsoneditor.js.LICENSE.txt +1 -1
- package/dist/nonmin/jsoneditor.js +330 -169
- package/dist/nonmin/jsoneditor.js.map +1 -1
- package/docs/cleave.html +1 -1
- package/docs/datetime.html +1 -1
- package/docs/describedby.html +1 -1
- package/docs/index.html +5 -3
- package/docs/meta_schema.json +5 -1
- package/docs/radio.html +1 -1
- package/docs/select2.html +1 -1
- package/docs/selectize.html +2 -5
- package/docs/signature.html +12 -11
- package/docs/wysiwyg.html +1 -1
- package/package.json +1 -1
- package/src/core.js +10 -1
- package/src/defaults.js +3 -1
- package/src/editor.js +1 -1
- package/src/editors/array/selectize.js +0 -2
- package/src/editors/array.js +24 -13
- package/src/editors/base64.js +9 -0
- package/src/editors/integer.js +3 -2
- package/src/editors/multiple.js +3 -0
- package/src/editors/number.js +4 -2
- package/src/editors/object.js +71 -3
- package/src/editors/signature.js +16 -16
- package/src/editors/string.js +4 -0
- package/src/editors/table.js +17 -14
- package/src/resolvers.js +6 -2
- package/src/schemaloader.js +13 -0
- package/src/theme.js +4 -0
- package/src/themes/bootstrap3.js +6 -0
- package/src/themes/bootstrap4.js +6 -0
- package/src/themes/bootstrap5.js +6 -0
- package/src/validator.js +28 -0
- package/tests/codeceptjs/constrains/dependentRequired_test.js +33 -0
- package/tests/codeceptjs/core_test.js +10 -0
- package/tests/codeceptjs/editors/array_test.js +52 -0
- package/tests/codeceptjs/editors/object_test.js +20 -0
- package/tests/codeceptjs/issues/issue-gh-1330_test.js +8 -0
- package/tests/codeceptjs/issues/issue-gh-1338_test.js +2 -0
- package/tests/codeceptjs/issues/issue-gh-1364_test.js +13 -0
- package/tests/codeceptjs/issues/issue-gh-1367_test.js +11 -0
- package/tests/codeceptjs/issues/issue-gh-1383_test.js +9 -0
- package/tests/codeceptjs/issues/issue-gh-1384_test.js +9 -0
- package/tests/codeceptjs/issues/issue-gh-1410_test.js +13 -0
- package/tests/codeceptjs/issues/issue-gh-1422_test.js +9 -0
- package/tests/docker-compose-local.yml +4 -0
- package/tests/pages/array-selectize-create.html +62 -0
- package/tests/pages/array-table-responsive.html +65 -0
- package/tests/pages/button_state_mode_1.html +34 -0
- package/tests/pages/button_state_mode_2.html +35 -0
- package/tests/pages/dependentRequired.html +71 -0
- package/tests/pages/issues/issue-gh-1330.html +52 -0
- package/tests/pages/issues/issue-gh-1364.html +64 -0
- package/tests/pages/issues/issue-gh-1367.html +49 -0
- package/tests/pages/issues/issue-gh-1383.html +31 -0
- package/tests/pages/issues/issue-gh-1383.json +14 -0
- package/tests/pages/issues/issue-gh-1384.html +31 -0
- package/tests/pages/issues/issue-gh-1384.json +36 -0
- package/tests/pages/issues/issue-gh-1410.html +57 -0
- package/tests/pages/issues/issue-gh-1422.html +68 -0
- package/tests/pages/keep_only_existing_values.html +1 -1
- package/tests/pages/load-events.html +60 -0
- package/tests/pages/meta-schema.html +5 -1
- package/tests/pages/meta_schema.json +5 -1
- package/tests/pages/object-case-sensitive-property-search-false.html +41 -0
- package/tests/pages/object-case-sensitive-property-search-true.html +41 -0
- package/dist/dev/jsoneditor.js +0 -3687
- package/dist/jsoneditor.js.map +0 -1
package/src/editors/table.js
CHANGED
|
@@ -36,8 +36,11 @@ export class TableEditor extends ArrayEditor {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
build () {
|
|
39
|
+
this.tableContainer = this.theme.getTableContainer()
|
|
39
40
|
this.table = this.theme.getTable()
|
|
40
|
-
this.
|
|
41
|
+
this.tableContainer.appendChild(this.table)
|
|
42
|
+
|
|
43
|
+
this.container.appendChild(this.tableContainer)
|
|
41
44
|
this.thead = this.theme.getTableHead()
|
|
42
45
|
this.table.appendChild(this.thead)
|
|
43
46
|
this.header_row = this.theme.getTableRow()
|
|
@@ -74,7 +77,7 @@ export class TableEditor extends ArrayEditor {
|
|
|
74
77
|
this.container.appendChild(this.panel)
|
|
75
78
|
}
|
|
76
79
|
|
|
77
|
-
this.panel.appendChild(this.
|
|
80
|
+
this.panel.appendChild(this.tableContainer)
|
|
78
81
|
this.controls = this.theme.getButtonHolder()
|
|
79
82
|
if (this.array_controls_top) {
|
|
80
83
|
this.title.appendChild(this.controls)
|
|
@@ -232,28 +235,28 @@ export class TableEditor extends ArrayEditor {
|
|
|
232
235
|
if (editor.delete_button) {
|
|
233
236
|
/* Hide the delete button if we have minItems items */
|
|
234
237
|
const display = !minItems
|
|
235
|
-
this.
|
|
238
|
+
this.setButtonState(editor.delete_button, display)
|
|
236
239
|
needRowButtons.push(display)
|
|
237
240
|
}
|
|
238
241
|
|
|
239
242
|
if (editor.copy_button) {
|
|
240
243
|
/* Hide the copy button if we have maxItems items */
|
|
241
244
|
const display = !maxItems
|
|
242
|
-
this.
|
|
245
|
+
this.setButtonState(editor.copy_button, display)
|
|
243
246
|
needRowButtons.push(display)
|
|
244
247
|
}
|
|
245
248
|
|
|
246
249
|
if (editor.moveup_button) {
|
|
247
250
|
/* Hide the moveup button for the first row */
|
|
248
251
|
const display = i !== 0
|
|
249
|
-
this.
|
|
252
|
+
this.setButtonState(editor.moveup_button, display)
|
|
250
253
|
needRowButtons.push(display)
|
|
251
254
|
}
|
|
252
255
|
|
|
253
256
|
if (editor.movedown_button) {
|
|
254
257
|
/* Hide the movedown button for the last row */
|
|
255
258
|
const display = i !== this.rows.length - 1
|
|
256
|
-
this.
|
|
259
|
+
this.setButtonState(editor.movedown_button, display)
|
|
257
260
|
needRowButtons.push(display)
|
|
258
261
|
}
|
|
259
262
|
})
|
|
@@ -261,26 +264,26 @@ export class TableEditor extends ArrayEditor {
|
|
|
261
264
|
const need = needRowButtons.some(e => e)
|
|
262
265
|
/* Show/hide controls column in table */
|
|
263
266
|
this.rows.forEach((editor) =>
|
|
264
|
-
this.
|
|
267
|
+
this.setButtonState(editor.controls_cell, need)
|
|
265
268
|
)
|
|
266
|
-
this.
|
|
269
|
+
this.setButtonState(this.controls_header_cell, need)
|
|
267
270
|
|
|
268
|
-
this.
|
|
271
|
+
this.setButtonState(this.table, this.value.length)
|
|
269
272
|
|
|
270
273
|
/* If there are maxItems items in the array, or configured to hide the add_row_button button, hide the button beneath the rows */
|
|
271
274
|
const display1 = !(maxItems || this.hide_add_button)
|
|
272
|
-
this.
|
|
275
|
+
this.setButtonState(this.add_row_button, display1)
|
|
273
276
|
|
|
274
277
|
/* If there are minItems items in the array, or configured to hide the delete_last_row button, hide the button beneath the rows */
|
|
275
278
|
const display2 = !(!this.value.length || minItems || this.hide_delete_last_row_buttons)
|
|
276
|
-
this.
|
|
279
|
+
this.setButtonState(this.delete_last_row_button, display2)
|
|
277
280
|
|
|
278
281
|
/* If there are minItems items in the array, or configured to hide the remove_all_rows_button button, hide the button beneath the rows */
|
|
279
282
|
const display3 = !(this.value.length <= 1 || minItems || this.hide_delete_all_rows_buttons)
|
|
280
|
-
this.
|
|
283
|
+
this.setButtonState(this.remove_all_rows_button, display3)
|
|
281
284
|
|
|
282
285
|
const controlsNeeded = display1 || display2 || display3
|
|
283
|
-
this.
|
|
286
|
+
this.setButtonState(this.controls, controlsNeeded)
|
|
284
287
|
}
|
|
285
288
|
|
|
286
289
|
refreshValue () {
|
|
@@ -439,7 +442,7 @@ export class TableEditor extends ArrayEditor {
|
|
|
439
442
|
e.preventDefault()
|
|
440
443
|
e.stopPropagation()
|
|
441
444
|
|
|
442
|
-
this.
|
|
445
|
+
this.setButtonState(this.panel, this.collapsed)
|
|
443
446
|
if (this.collapsed) {
|
|
444
447
|
this.collapsed = false
|
|
445
448
|
this.setButtonText(e.currentTarget, '', 'collapse', 'button_collapse')
|
package/src/resolvers.js
CHANGED
|
@@ -61,7 +61,11 @@ const enumeratedProperties = schema => {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/* Specialized editors for arrays of strings */
|
|
64
|
-
const arraysOfStrings = schema => {
|
|
64
|
+
const arraysOfStrings = (schema, je) => {
|
|
65
|
+
if (schema.items) {
|
|
66
|
+
schema.items = je.expandSchema(schema.items)
|
|
67
|
+
}
|
|
68
|
+
|
|
65
69
|
if (schema.type === 'array' && schema.items && !(Array.isArray(schema.items)) && ['string', 'number', 'integer'].includes(schema.items.type)) {
|
|
66
70
|
if (schema.format === 'choices') return 'arrayChoices'
|
|
67
71
|
if (schema.uniqueItems) {
|
|
@@ -117,7 +121,7 @@ const markdown = schema => schema.type === 'string' && schema.format === 'markdo
|
|
|
117
121
|
const xhtml = schema => schema.type === 'string' && ['xhtml', 'bbcode'].includes(schema.format) && 'sceditor'
|
|
118
122
|
|
|
119
123
|
/* Use the ace editor for schemas with format equals any of ace editor modes */
|
|
120
|
-
const aceModes = ['actionscript', 'batchfile', 'c', 'c++', 'cpp', 'coffee', 'csharp', 'css', 'dart', 'django', 'ejs', 'erlang', 'golang', 'groovy', 'handlebars', 'haskell', 'haxe', 'html', 'ini', 'jade', 'java', 'javascript', 'json', 'less', 'lisp', 'lua', 'makefile', 'matlab', 'mysql', 'objectivec', 'pascal', 'perl', 'pgsql', 'php', 'python', 'r', 'ruby', 'sass', 'scala', 'scss', 'sh', 'smarty', 'sql', 'sqlserver', 'stylus', 'svg', 'twig', 'vbscript', 'xml', 'yaml']
|
|
124
|
+
const aceModes = ['actionscript', 'batchfile', 'c', 'c++', 'cpp', 'coffee', 'csharp', 'css', 'dart', 'django', 'ejs', 'erlang', 'golang', 'groovy', 'handlebars', 'haskell', 'haxe', 'html', 'ini', 'jade', 'java', 'javascript', 'json', 'less', 'lisp', 'lua', 'makefile', 'matlab', 'mysql', 'objectivec', 'pascal', 'perl', 'pgsql', 'php', 'python', 'prql', 'r', 'ruby', 'rust', 'sass', 'scala', 'scss', 'sh', 'smarty', 'sql', 'sqlserver', 'stylus', 'svg', 'typescript', 'twig', 'vbscript', 'xml', 'yaml', 'zig']
|
|
121
125
|
const ace = schema => schema.type === 'string' && aceModes.includes(schema.format) && 'ace'
|
|
122
126
|
|
|
123
127
|
const ip = schema => schema.type === 'string' && ['ip', 'ipv4', 'ipv6', 'hostname'].includes(schema.format) && 'ip'
|
package/src/schemaloader.js
CHANGED
|
@@ -449,6 +449,12 @@ export class SchemaLoader {
|
|
|
449
449
|
if (typeof response === 'undefined') throw new Error(`Failed to fetch ref via ajax - ${uri}`)
|
|
450
450
|
try {
|
|
451
451
|
externalSchema = JSON.parse(response.responseText)
|
|
452
|
+
|
|
453
|
+
this.onSchemaLoaded({
|
|
454
|
+
schema: externalSchema,
|
|
455
|
+
schemaUrl: url
|
|
456
|
+
})
|
|
457
|
+
|
|
452
458
|
if (this.options.ajax_cache_responses) {
|
|
453
459
|
this.cacheSet(url, externalSchema)
|
|
454
460
|
}
|
|
@@ -472,11 +478,18 @@ export class SchemaLoader {
|
|
|
472
478
|
}
|
|
473
479
|
await this._asyncloadExternalRefs(externalSchema, url, newfileBase)
|
|
474
480
|
}
|
|
481
|
+
|
|
475
482
|
if (!waiting) {
|
|
476
483
|
return true
|
|
477
484
|
}
|
|
485
|
+
|
|
486
|
+
this.onAllSchemasLoaded()
|
|
478
487
|
}
|
|
479
488
|
|
|
489
|
+
onSchemaLoaded (payload) {}
|
|
490
|
+
|
|
491
|
+
onAllSchemasLoaded () {}
|
|
492
|
+
|
|
480
493
|
extendSchemas (obj1, obj2) {
|
|
481
494
|
obj1 = extend({}, obj1)
|
|
482
495
|
obj2 = extend({}, obj2)
|
package/src/theme.js
CHANGED
|
@@ -414,6 +414,10 @@ export class AbstractTheme {
|
|
|
414
414
|
if (title) button.setAttribute('title', title)
|
|
415
415
|
}
|
|
416
416
|
|
|
417
|
+
getTableContainer () {
|
|
418
|
+
return document.createElement('div')
|
|
419
|
+
}
|
|
420
|
+
|
|
417
421
|
/* Table functions */
|
|
418
422
|
getTable () {
|
|
419
423
|
return document.createElement('table')
|
package/src/themes/bootstrap3.js
CHANGED
|
@@ -136,6 +136,12 @@ export class bootstrap3Theme extends AbstractTheme {
|
|
|
136
136
|
return el
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
getTableContainer () {
|
|
140
|
+
const el = super.getTableContainer()
|
|
141
|
+
el.classList.add('table-responsive')
|
|
142
|
+
return el
|
|
143
|
+
}
|
|
144
|
+
|
|
139
145
|
getTable () {
|
|
140
146
|
const el = document.createElement('table')
|
|
141
147
|
el.classList.add('table', 'table-bordered')
|
package/src/themes/bootstrap4.js
CHANGED
|
@@ -454,6 +454,12 @@ export class bootstrap4Theme extends AbstractTheme {
|
|
|
454
454
|
return el
|
|
455
455
|
}
|
|
456
456
|
|
|
457
|
+
getTableContainer () {
|
|
458
|
+
const el = super.getTableContainer()
|
|
459
|
+
el.classList.add('table-responsive')
|
|
460
|
+
return el
|
|
461
|
+
}
|
|
462
|
+
|
|
457
463
|
getTable () {
|
|
458
464
|
const el = document.createElement('table')
|
|
459
465
|
el.classList.add('table', 'table-sm')
|
package/src/themes/bootstrap5.js
CHANGED
|
@@ -390,6 +390,12 @@ export class bootstrap5Theme extends AbstractTheme {
|
|
|
390
390
|
return el
|
|
391
391
|
}
|
|
392
392
|
|
|
393
|
+
getTableContainer () {
|
|
394
|
+
const el = super.getTableContainer()
|
|
395
|
+
el.classList.add('table-responsive')
|
|
396
|
+
return el
|
|
397
|
+
}
|
|
398
|
+
|
|
393
399
|
getTable () {
|
|
394
400
|
const el = document.createElement('table')
|
|
395
401
|
el.classList.add('table', 'table-sm')
|
package/src/validator.js
CHANGED
|
@@ -11,6 +11,34 @@ export class Validator {
|
|
|
11
11
|
this.defaults = defaults
|
|
12
12
|
|
|
13
13
|
this._validateSubSchema = {
|
|
14
|
+
dependentRequired (schema, value, path) {
|
|
15
|
+
const errors = []
|
|
16
|
+
|
|
17
|
+
if (typeof schema.dependentRequired !== 'undefined') {
|
|
18
|
+
let missingProperties = []
|
|
19
|
+
|
|
20
|
+
Object.keys(schema.dependentRequired).forEach((key) => {
|
|
21
|
+
if (typeof value[key] !== 'undefined') {
|
|
22
|
+
const requiredProperties = schema.dependentRequired[key]
|
|
23
|
+
|
|
24
|
+
missingProperties = requiredProperties.filter((property) => {
|
|
25
|
+
return !hasOwnProperty(value, property)
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const invalid = missingProperties.length > 0
|
|
31
|
+
|
|
32
|
+
if (invalid) {
|
|
33
|
+
errors.push({
|
|
34
|
+
message: 'Must have the required properties: ' + missingProperties.join(', '),
|
|
35
|
+
path: path
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return errors
|
|
41
|
+
},
|
|
14
42
|
dependentSchemas (schema, value, path) {
|
|
15
43
|
let errors = []
|
|
16
44
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* global Feature Scenario */
|
|
2
|
+
|
|
3
|
+
Feature('dependentRequired')
|
|
4
|
+
|
|
5
|
+
Scenario('@dependentRequired should display validation errors', ({ I }) => {
|
|
6
|
+
I.amOnPage('dependentRequired.html')
|
|
7
|
+
I.waitForElement('.je-ready')
|
|
8
|
+
I.waitForValue('#textarea-value', '{"name":""}')
|
|
9
|
+
|
|
10
|
+
I.click('[data-schemapath="root.credit_card"] .json-editor-opt-in')
|
|
11
|
+
I.waitForValue('#textarea-value', '{"name":"","credit_card":0,"billing_address_1":"","billing_address_2":""}')
|
|
12
|
+
I.waitForText('Must have the required properties: billing_address_3')
|
|
13
|
+
|
|
14
|
+
I.click('[data-schemapath="root.billing_address_1"] .json-editor-opt-in')
|
|
15
|
+
I.waitForValue('#textarea-value', '{"name":"","credit_card":0,"billing_address_1":"","billing_address_2":""}')
|
|
16
|
+
I.waitForText('Must have the required properties: billing_address_3')
|
|
17
|
+
|
|
18
|
+
I.click('[data-schemapath="root.billing_address_2"] .json-editor-opt-in')
|
|
19
|
+
I.waitForValue('#textarea-value', '{"name":"","credit_card":0,"billing_address_1":"","billing_address_2":""}')
|
|
20
|
+
I.waitForText('Must have the required properties: billing_address_3')
|
|
21
|
+
|
|
22
|
+
I.click('[data-schemapath="root.credit_card"] .json-editor-opt-in')
|
|
23
|
+
I.waitForValue('#textarea-value', '{"name":"","billing_address_1":"","billing_address_2":""}')
|
|
24
|
+
I.waitForText('Must have the required properties: billing_address_3')
|
|
25
|
+
|
|
26
|
+
I.click('[data-schemapath="root.billing_address_1"] .json-editor-opt-in')
|
|
27
|
+
I.waitForValue('#textarea-value', '{"name":"","billing_address_2":""}')
|
|
28
|
+
I.waitForText('Must have the required properties: billing_address_3')
|
|
29
|
+
|
|
30
|
+
I.click('[data-schemapath="root.billing_address_2"] .json-editor-opt-in')
|
|
31
|
+
I.waitForValue('#textarea-value', '{"name":""}')
|
|
32
|
+
I.dontSee('Must have the required properties: billing_address_3')
|
|
33
|
+
})
|
|
@@ -5,6 +5,16 @@ const { DEFAULT_WAIT_TIME } = require('./test-config')
|
|
|
5
5
|
|
|
6
6
|
Feature('core')
|
|
7
7
|
|
|
8
|
+
Scenario('should listen to @load-events', async ({ I }) => {
|
|
9
|
+
I.amOnPage('load-events.html')
|
|
10
|
+
I.waitForElement('.je-ready')
|
|
11
|
+
I.waitForText('/tests/pages/../fixtures/basic_person.json')
|
|
12
|
+
I.waitForText('{"title":"Person","type":"object","id":"person","properties":{"name":{"type":"string","description":"First and Last name","minLength":4},"age":{"type":"integer","default":21,"minimum":18,"maximum":99},"gender":{"type":"string","enum":["male","female","other"]}}}')
|
|
13
|
+
I.waitForText('/tests/pages/../fixtures/person.json')
|
|
14
|
+
I.waitForText('{"$ref":"../fixtures/basic_person.json","properties":{"location":{"type":"object","title":"Location","properties":{"city":{"type":"string"},"state":{"type":"string"},"citystate":{"type":"string","description":"This is generated automatically from the previous two fields","template":"{{city}}, {{state}}","watch":{"city":"person.location.city","state":"person.location.state"}}}},"pets":{"type":"array","format":"table","title":"Pets","uniqueItems":true,"items":{"type":"object","properties":{"type":{"type":"string","enum":["cat","dog","bird","reptile","other"],"default":"dog"},"name":{"type":"string"},"fixed":{"type":"boolean","title":"spayed / neutered"}}}}}}')
|
|
15
|
+
I.waitForText('All schemas loaded')
|
|
16
|
+
})
|
|
17
|
+
|
|
8
18
|
Scenario('should set per-editor options @per-editor-options', async ({ I }) => {
|
|
9
19
|
I.amOnPage('per-editor-options.html')
|
|
10
20
|
I.waitForElement('.je-ready')
|
|
@@ -4,6 +4,36 @@ const { DEFAULT_WAIT_TIME } = require('../test-config')
|
|
|
4
4
|
|
|
5
5
|
Feature('array')
|
|
6
6
|
|
|
7
|
+
Scenario('Should set buttons states correctly @button_state_mode', async ({ I }) => {
|
|
8
|
+
I.amOnPage('button_state_mode_1.html')
|
|
9
|
+
I.waitForElement('.je-ready', DEFAULT_WAIT_TIME)
|
|
10
|
+
I.waitForElement('.json-editor-btntype-add', DEFAULT_WAIT_TIME)
|
|
11
|
+
I.waitForElement('.json-editor-btn-movedown', DEFAULT_WAIT_TIME)
|
|
12
|
+
I.waitForElement('.json-editor-btn-moveup', DEFAULT_WAIT_TIME)
|
|
13
|
+
I.dontSeeElement('.json-editor-btntype-delete')
|
|
14
|
+
I.dontSeeElement('.json-editor-btntype-deletelast')
|
|
15
|
+
I.dontSeeElement('.json-editor-btntype-deleteall')
|
|
16
|
+
I.click('.json-editor-btntype-add')
|
|
17
|
+
I.waitForElement('.json-editor-btntype-delete')
|
|
18
|
+
I.waitForElement('.json-editor-btntype-deletelast')
|
|
19
|
+
I.waitForElement('.json-editor-btntype-deleteall')
|
|
20
|
+
|
|
21
|
+
I.amOnPage('button_state_mode_2.html')
|
|
22
|
+
I.waitForElement('.je-ready', DEFAULT_WAIT_TIME)
|
|
23
|
+
I.waitForElement('.json-editor-btntype-add', DEFAULT_WAIT_TIME)
|
|
24
|
+
I.waitForElement('.json-editor-btn-movedown', DEFAULT_WAIT_TIME)
|
|
25
|
+
I.waitForElement('.json-editor-btn-moveup', DEFAULT_WAIT_TIME)
|
|
26
|
+
I.waitForElement('.json-editor-btntype-delete', DEFAULT_WAIT_TIME)
|
|
27
|
+
I.waitForElement('.json-editor-btntype-deletelast', DEFAULT_WAIT_TIME)
|
|
28
|
+
I.seeDisabledAttribute('.json-editor-btntype-delete')
|
|
29
|
+
I.seeDisabledAttribute('.json-editor-btntype-deletelast')
|
|
30
|
+
I.seeDisabledAttribute('.json-editor-btntype-deleteall')
|
|
31
|
+
I.click('.json-editor-btntype-add')
|
|
32
|
+
I.dontSeeDisabledAttribute('.json-editor-btntype-delete')
|
|
33
|
+
I.dontSeeDisabledAttribute('.json-editor-btntype-deletelast')
|
|
34
|
+
I.dontSeeDisabledAttribute('.json-editor-btntype-deleteall')
|
|
35
|
+
})
|
|
36
|
+
|
|
7
37
|
Scenario('should have correct initial value', async ({ I }) => {
|
|
8
38
|
I.amOnPage('array.html')
|
|
9
39
|
I.click('.get-value')
|
|
@@ -963,3 +993,25 @@ Scenario('should work well with selectize multiselect editors', async ({ I }) =>
|
|
|
963
993
|
I.seeElement('[data-schemapath="root.0"] .selectize-dropdown-content [data-value="3"]')
|
|
964
994
|
I.seeElement('[data-schemapath="root.0"] .selectize-dropdown-content [data-value="4"]')
|
|
965
995
|
})
|
|
996
|
+
|
|
997
|
+
Scenario('should be possible to add items to selectize array @selectize-add', async ({ I }) => {
|
|
998
|
+
I.amOnPage('array-selectize-create.html')
|
|
999
|
+
I.click('.selectize-input')
|
|
1000
|
+
I.pressKey('g')
|
|
1001
|
+
I.pressKey('Enter')
|
|
1002
|
+
I.pressKey('r')
|
|
1003
|
+
I.pressKey('Enter')
|
|
1004
|
+
I.pressKey('e')
|
|
1005
|
+
I.pressKey('Enter')
|
|
1006
|
+
I.pressKey('a')
|
|
1007
|
+
I.pressKey('Enter')
|
|
1008
|
+
I.pressKey('t')
|
|
1009
|
+
I.pressKey('Enter')
|
|
1010
|
+
I.waitForValue('#value', '["g","r","e","a","t"]')
|
|
1011
|
+
})
|
|
1012
|
+
|
|
1013
|
+
Scenario('Tables should have a container parent that makes tables responsive @array-table', async ({ I }) => {
|
|
1014
|
+
I.amOnPage('array-table-responsive.html')
|
|
1015
|
+
I.waitForElement('.je-ready', DEFAULT_WAIT_TIME)
|
|
1016
|
+
I.waitForElement('.table-responsive')
|
|
1017
|
+
})
|
|
@@ -5,6 +5,26 @@ const { DEFAULT_WAIT_TIME } = require('../test-config')
|
|
|
5
5
|
|
|
6
6
|
Feature('object')
|
|
7
7
|
|
|
8
|
+
Scenario('@case-sensitive-property-search', async ({ I }) => {
|
|
9
|
+
I.amOnPage('object-case-sensitive-property-search-true.html')
|
|
10
|
+
I.click('.json-editor-btn-edit_properties')
|
|
11
|
+
I.fillField('.property-selector-input', 'aaa')
|
|
12
|
+
I.see('aaa', '.form-check label')
|
|
13
|
+
I.dontSee('AAA', '.form-check label')
|
|
14
|
+
I.fillField('.property-selector-input', 'AAA')
|
|
15
|
+
I.see('AAA', '.form-check label')
|
|
16
|
+
I.dontSee('aaa', '.form-check label')
|
|
17
|
+
|
|
18
|
+
I.amOnPage('object-case-sensitive-property-search-false.html')
|
|
19
|
+
I.click('.json-editor-btn-edit_properties')
|
|
20
|
+
I.fillField('.property-selector-input', 'aaa')
|
|
21
|
+
I.see('aaa', '.form-check label')
|
|
22
|
+
I.see('AAA', '.form-check label')
|
|
23
|
+
I.fillField('.property-selector-input', 'AAA')
|
|
24
|
+
I.see('AAA', '.form-check label')
|
|
25
|
+
I.see('aaa', '.form-check label')
|
|
26
|
+
})
|
|
27
|
+
|
|
8
28
|
Scenario('should respect property orders', async ({ I }) => {
|
|
9
29
|
I.amOnPage('object.html')
|
|
10
30
|
assert.strictEqual(await I.grabAttributeFrom('[data-schemapath^="root"] .row:nth-of-type(1) [data-schemapath^="root."]', 'data-schemapath'), 'root.age')
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/* global Feature Scenario */
|
|
2
|
+
|
|
3
|
+
Feature('issues')
|
|
4
|
+
|
|
5
|
+
Scenario('GitHub issue 1330 should remain fixed @issue-1330 @multiselect', async ({ I }) => {
|
|
6
|
+
I.amOnPage('issues/issue-gh-1330.html')
|
|
7
|
+
I.waitForElement('[data-schemapath="root.test"] input[type="checkbox"]')
|
|
8
|
+
})
|
|
@@ -7,10 +7,12 @@ Scenario('GitHub issue 1338 should remain fixed @issue-1338', async ({ I }) => {
|
|
|
7
7
|
I.waitForText('Value required')
|
|
8
8
|
I.fillField('[id="root[field_a]"]', 'test')
|
|
9
9
|
I.pressKey('Tab')
|
|
10
|
+
I.waitForElement('.invalid-feedback')
|
|
10
11
|
I.dontSee('Value required')
|
|
11
12
|
I.refreshPage()
|
|
12
13
|
I.waitForText('Value required')
|
|
13
14
|
I.fillField('[id="root[field_b]"]', 'test')
|
|
14
15
|
I.pressKey('Tab')
|
|
16
|
+
I.waitForElement('.invalid-feedback')
|
|
15
17
|
I.dontSee('Value required')
|
|
16
18
|
})
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/* global Feature Scenario */
|
|
2
|
+
|
|
3
|
+
Feature('GitHub issue 1364')
|
|
4
|
+
|
|
5
|
+
Scenario('GitHub issue 1364 should remain fixed @issue-1364', ({ I }) => {
|
|
6
|
+
I.amOnPage('issues/issue-gh-1364.html')
|
|
7
|
+
I.waitForElement('.je-ready')
|
|
8
|
+
I.waitForValue('#value', '{"engine":"none","child1":{}}')
|
|
9
|
+
I.selectOption('[id="root[engine]"]', 'test1')
|
|
10
|
+
I.waitForValue('#value', '{"engine":"test1","child1":{"L2Name":""},"L1Name":""}')
|
|
11
|
+
I.selectOption('[id="root[engine]"]', 'none')
|
|
12
|
+
I.waitForValue('#value', '{"engine":"none","child1":{}}')
|
|
13
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/* global Feature Scenario */
|
|
2
|
+
const assert = require('assert')
|
|
3
|
+
|
|
4
|
+
Feature('GitHub issue 1367')
|
|
5
|
+
|
|
6
|
+
Scenario('GitHub issue 1367 should remain fixed @issue-1367', async ({ I }) => {
|
|
7
|
+
I.amOnPage('issues/issue-gh-1367.html')
|
|
8
|
+
I.waitForElement('.je-ready')
|
|
9
|
+
I.click('canvas')
|
|
10
|
+
assert.match(await I.grabValueFrom('#value'), /base64/)
|
|
11
|
+
})
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/* global Feature Scenario */
|
|
2
|
+
|
|
3
|
+
Feature('issues')
|
|
4
|
+
|
|
5
|
+
Scenario('GitHub issue 1384 should remain fixed @issue-1384 @optional', async ({ I }) => {
|
|
6
|
+
I.amOnPage('issues/issue-gh-1384.html')
|
|
7
|
+
I.waitForElement('.je-ready')
|
|
8
|
+
I.waitForText('Zope layout definition')
|
|
9
|
+
})
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/* global Feature Scenario */
|
|
2
|
+
|
|
3
|
+
Feature('issues')
|
|
4
|
+
|
|
5
|
+
Scenario('GitHub issue 1410 should remain fixed @issue-1410', async ({ I }) => {
|
|
6
|
+
I.amOnPage('issues/issue-gh-1410.html')
|
|
7
|
+
I.waitForElement('.je-ready')
|
|
8
|
+
I.click('[data-schemapath="root.standard"] .json-editor-btn-edit_properties')
|
|
9
|
+
I.waitForInvisible('[data-schemapath="root.standard"] .json-editor-btn-add')
|
|
10
|
+
I.click('[data-schemapath="root.standard"] .json-editor-btn-edit_properties')
|
|
11
|
+
I.click('[data-schemapath="root.extras"] .json-editor-btn-edit_properties')
|
|
12
|
+
I.waitForVisible('[data-schemapath="root.extras"] .json-editor-btn-add')
|
|
13
|
+
})
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/* global Feature Scenario */
|
|
2
|
+
|
|
3
|
+
Feature('issues')
|
|
4
|
+
|
|
5
|
+
Scenario('GitHub issue 1422 should remain fixed @issue-1422', async ({ I }) => {
|
|
6
|
+
I.amOnPage('issues/issue-gh-1422.html')
|
|
7
|
+
I.waitForElement('.je-ready')
|
|
8
|
+
I.waitForValue('#value', '{"req":5,"opt":5,"req_with_default":5}')
|
|
9
|
+
})
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8"/>
|
|
5
|
+
<title>Selectize add item</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
|
+
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.4/css/selectize.bootstrap3.css">
|
|
9
|
+
<script src="../../dist/jsoneditor.js"></script>
|
|
10
|
+
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
|
|
11
|
+
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.4/js/standalone/selectize.js"></script>
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
|
|
15
|
+
<div class="container">
|
|
16
|
+
<div class="row">
|
|
17
|
+
<div class="col-xs-12 col-md-6">
|
|
18
|
+
<div id='editor-container'></div>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="col-xs-12 col-md-6">
|
|
21
|
+
<label for="value">value</label>
|
|
22
|
+
<textarea class="form-control" id="value" cols="30" rows="10"></textarea>
|
|
23
|
+
<button id="set-value">Set value</button>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<script>
|
|
29
|
+
var schema = {
|
|
30
|
+
"type": "array",
|
|
31
|
+
"format":"selectize",
|
|
32
|
+
"uniqueItems": true,
|
|
33
|
+
"items": {
|
|
34
|
+
"type": "string"
|
|
35
|
+
},
|
|
36
|
+
"options": {
|
|
37
|
+
"selectize": {
|
|
38
|
+
"create": true,
|
|
39
|
+
"plugins": ["remove_button"],
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
var editorContainer = document.querySelector('#editor-container')
|
|
44
|
+
var value = document.querySelector('#value')
|
|
45
|
+
var setValue = document.querySelector('#set-value')
|
|
46
|
+
var editor = new JSONEditor(editorContainer, {
|
|
47
|
+
schema: schema,
|
|
48
|
+
theme: 'bootstrap4',
|
|
49
|
+
iconlib: 'fontawesome'
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
editor.on('change', function () {
|
|
53
|
+
value.value = JSON.stringify(editor.getValue())
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
setValue.addEventListener('click', function () {
|
|
57
|
+
editor.setValue(JSON.parse(value.value))
|
|
58
|
+
})
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
</body>
|
|
62
|
+
</html>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8"/>
|
|
5
|
+
<title>dependentSchemas</title>
|
|
6
|
+
<script src="../../dist/jsoneditor.js"></script>
|
|
7
|
+
<link rel="stylesheet" id="theme-link" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
|
|
8
|
+
<link rel="stylesheet" id="iconlib-link" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
|
|
12
|
+
<div class="container">
|
|
13
|
+
<div id='editor-container'></div>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<style>
|
|
17
|
+
th {
|
|
18
|
+
white-space: nowrap;
|
|
19
|
+
}
|
|
20
|
+
</style>
|
|
21
|
+
|
|
22
|
+
<script>
|
|
23
|
+
var editorContainer = document.querySelector('#editor-container')
|
|
24
|
+
var schema = {
|
|
25
|
+
"title": "Array table responsive",
|
|
26
|
+
"format": "table",
|
|
27
|
+
"type": "array",
|
|
28
|
+
"minItems": 1,
|
|
29
|
+
"items": {
|
|
30
|
+
"title": "item",
|
|
31
|
+
"type": "object",
|
|
32
|
+
"properties": {
|
|
33
|
+
"property_a": {
|
|
34
|
+
"title": "A very long title",
|
|
35
|
+
"type": "string"
|
|
36
|
+
},
|
|
37
|
+
"property_b": {
|
|
38
|
+
"title": "Another long title",
|
|
39
|
+
"type": "string"
|
|
40
|
+
},
|
|
41
|
+
"property_c": {
|
|
42
|
+
"title": "Another long title too",
|
|
43
|
+
"type": "string"
|
|
44
|
+
},
|
|
45
|
+
"property_d": {
|
|
46
|
+
"title": "Another long title too",
|
|
47
|
+
"type": "string"
|
|
48
|
+
},
|
|
49
|
+
"property_e": {
|
|
50
|
+
"title": "Another long title too",
|
|
51
|
+
"type": "string"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
var editor = new JSONEditor(editorContainer, {
|
|
58
|
+
schema: schema,
|
|
59
|
+
theme: 'bootstrap4',
|
|
60
|
+
iconlib: 'fontawesome',
|
|
61
|
+
})
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
</body>
|
|
65
|
+
</html>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8"/>
|
|
5
|
+
<title>button_state_mode</title>
|
|
6
|
+
<script src="../../dist/jsoneditor.js"></script>
|
|
7
|
+
<link rel="stylesheet" id="theme-link" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
|
|
8
|
+
<link rel="stylesheet" id="iconlib-link" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
|
|
12
|
+
<div class="container">
|
|
13
|
+
<div id='editor-container'></div>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<script>
|
|
17
|
+
var editorContainer = document.querySelector('#editor-container')
|
|
18
|
+
var schema = {
|
|
19
|
+
'title': 'button_state_mode',
|
|
20
|
+
'type': 'array',
|
|
21
|
+
'items': {
|
|
22
|
+
'type': 'number'
|
|
23
|
+
},
|
|
24
|
+
'minItems': 3
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var editor = new JSONEditor(editorContainer, {
|
|
28
|
+
schema: schema,
|
|
29
|
+
theme: 'bootstrap4'
|
|
30
|
+
})
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
</body>
|
|
34
|
+
</html>
|