@es-joy/jsoe 0.15.0 → 0.16.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/.nyc_output/out.json +5113 -2727
- package/CHANGES.md +5 -0
- package/README.md +1 -1
- package/demo/index-instrumented.js +644 -0
- package/demo/index.js +3 -432
- package/dist/index.js +1 -1
- package/package.json +28 -29
- package/rollup.config.js +1 -1
- package/src/fundamentalTypes/regexpType.js +1 -1
package/CHANGES.md
CHANGED
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ Formats are a collection of allowed types.
|
|
|
14
14
|
|
|
15
15
|
Supported formats include:
|
|
16
16
|
|
|
17
|
-
- Structured Cloning (using [typeson](https://github.com/dfahlander/typeson)) (e.g., IndexedDB)
|
|
17
|
+
- Structured Cloning (using [typeson](https://github.com/dfahlander/typeson)) (e.g., IndexedDB values)
|
|
18
18
|
- JSON
|
|
19
19
|
- IndexedDB keys
|
|
20
20
|
|
|
@@ -0,0 +1,644 @@
|
|
|
1
|
+
import {jml, body, $} from '../src/vendor-imports.js';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
typeChoices,
|
|
5
|
+
getFormatAndSchemaChoices,
|
|
6
|
+
formatAndTypeChoices,
|
|
7
|
+
Types
|
|
8
|
+
} from '../src/index.js';
|
|
9
|
+
|
|
10
|
+
const types = new Types();
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
*/
|
|
15
|
+
const makeNoneditableType = () => {
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
class NonEditableType {
|
|
20
|
+
/* eslint-disable class-methods-use-this -- `this` not needed */
|
|
21
|
+
/**
|
|
22
|
+
* @returns {string}
|
|
23
|
+
*/
|
|
24
|
+
get [Symbol.toStringTag] () {
|
|
25
|
+
/* eslint-enable class-methods-use-this -- `this` not needed */
|
|
26
|
+
return 'NonEditableType';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return new NonEditableType();
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const keyPathNotExpectedTypeChoices = formatAndTypeChoices({
|
|
33
|
+
hasKeyPath: false,
|
|
34
|
+
typeNamespace: 'demo-keypath-not-expected'
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
setTimeout(async function () {
|
|
38
|
+
jml('section', {role: 'main'}, [
|
|
39
|
+
['h1', [
|
|
40
|
+
'Jsoe testing'
|
|
41
|
+
]],
|
|
42
|
+
['h2', [
|
|
43
|
+
'Format and type choices: No key path expected (type can vary at root)'
|
|
44
|
+
]],
|
|
45
|
+
|
|
46
|
+
// Put inside form so can validate
|
|
47
|
+
['form', {id: 'formatAndTypeChoices'}, [
|
|
48
|
+
...keyPathNotExpectedTypeChoices.domArray
|
|
49
|
+
]],
|
|
50
|
+
|
|
51
|
+
['button', {
|
|
52
|
+
id: 'getType',
|
|
53
|
+
$on: {
|
|
54
|
+
click () {
|
|
55
|
+
// eslint-disable-next-line no-alert -- Simple demo
|
|
56
|
+
alert(keyPathNotExpectedTypeChoices.getType());
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}, ['Get type']],
|
|
60
|
+
|
|
61
|
+
['button', {
|
|
62
|
+
id: 'isValid',
|
|
63
|
+
$on: {
|
|
64
|
+
click () {
|
|
65
|
+
// eslint-disable-next-line no-alert -- Simple demo
|
|
66
|
+
alert(keyPathNotExpectedTypeChoices.validValuesSet());
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}, ['Is valid']],
|
|
70
|
+
|
|
71
|
+
['button', {
|
|
72
|
+
id: 'logValue',
|
|
73
|
+
$on: {
|
|
74
|
+
click () {
|
|
75
|
+
console.log(keyPathNotExpectedTypeChoices.getValue());
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}, ['Log value']],
|
|
79
|
+
|
|
80
|
+
['button', {
|
|
81
|
+
id: 'viewUI',
|
|
82
|
+
$on: {
|
|
83
|
+
async click () {
|
|
84
|
+
const controls =
|
|
85
|
+
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
86
|
+
await keyPathNotExpectedTypeChoices.formats.getControlsForFormatAndValue(
|
|
87
|
+
keyPathNotExpectedTypeChoices.types,
|
|
88
|
+
$('#useIndexedDBKey').checked
|
|
89
|
+
? 'indexedDBKey'
|
|
90
|
+
: 'structuredCloning',
|
|
91
|
+
keyPathNotExpectedTypeChoices.getValue(),
|
|
92
|
+
{
|
|
93
|
+
readonly: true
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
$('#viewUIResults').firstChild?.remove();
|
|
97
|
+
$('#viewUIResults').append(controls);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}, ['view UI']],
|
|
101
|
+
|
|
102
|
+
['div', {id: 'viewUIResults'}],
|
|
103
|
+
|
|
104
|
+
['button', {
|
|
105
|
+
id: 'initializeWithValue',
|
|
106
|
+
$on: {
|
|
107
|
+
async click () {
|
|
108
|
+
await keyPathNotExpectedTypeChoices.setValue(42);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}, ['Initialize with a value']],
|
|
112
|
+
|
|
113
|
+
['button', {
|
|
114
|
+
id: 'initializeWithComplexValue',
|
|
115
|
+
$on: {
|
|
116
|
+
async click () {
|
|
117
|
+
const a = {
|
|
118
|
+
bbb: {},
|
|
119
|
+
xxx: {yyy: []}
|
|
120
|
+
};
|
|
121
|
+
a.bbb.ccc = a;
|
|
122
|
+
a.zzz = a.xxx.yyy;
|
|
123
|
+
await keyPathNotExpectedTypeChoices.setValue(a);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}, ['Initialize with a complex value']],
|
|
127
|
+
|
|
128
|
+
['button', {
|
|
129
|
+
id: 'initializeWithNoneditableValue',
|
|
130
|
+
$on: {
|
|
131
|
+
click () {
|
|
132
|
+
const a = makeNoneditableType();
|
|
133
|
+
const root = $(
|
|
134
|
+
'#formatAndTypeChoices div[data-type="resurrectable"]'
|
|
135
|
+
);
|
|
136
|
+
keyPathNotExpectedTypeChoices.types.setValue({
|
|
137
|
+
type: 'resurrectable',
|
|
138
|
+
root,
|
|
139
|
+
value: a
|
|
140
|
+
});
|
|
141
|
+
keyPathNotExpectedTypeChoices.types.validate({
|
|
142
|
+
type: 'resurrectable',
|
|
143
|
+
root
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
setTimeout(() => {
|
|
147
|
+
keyPathNotExpectedTypeChoices.types.setValue({
|
|
148
|
+
type: 'resurrectable',
|
|
149
|
+
root,
|
|
150
|
+
value: undefined
|
|
151
|
+
});
|
|
152
|
+
keyPathNotExpectedTypeChoices.types.validate({
|
|
153
|
+
type: 'resurrectable',
|
|
154
|
+
root
|
|
155
|
+
});
|
|
156
|
+
}, 3000);
|
|
157
|
+
// await keyPathNotExpectedTypeChoices.setValue(a);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}, ['Initialize with noneditable value then change']],
|
|
161
|
+
|
|
162
|
+
['button', {
|
|
163
|
+
id: 'programmaticallySetFormatToJSON',
|
|
164
|
+
$on: {
|
|
165
|
+
click () {
|
|
166
|
+
keyPathNotExpectedTypeChoices.formatChoices.$setFormat('json');
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}, [
|
|
170
|
+
'Programmatically set format (to JSON)'
|
|
171
|
+
]],
|
|
172
|
+
|
|
173
|
+
['button', {
|
|
174
|
+
id: 'setCustomValidateAllReferences',
|
|
175
|
+
$on: {
|
|
176
|
+
click () {
|
|
177
|
+
keyPathNotExpectedTypeChoices.types.customValidateAllReferences =
|
|
178
|
+
() => {
|
|
179
|
+
// eslint-disable-next-line no-alert -- Simple demo
|
|
180
|
+
alert('customValidateAllReferences set');
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}, [
|
|
185
|
+
'Set custom all reference validation'
|
|
186
|
+
]],
|
|
187
|
+
|
|
188
|
+
['button', {
|
|
189
|
+
id: 'showRootFormControl',
|
|
190
|
+
$on: {
|
|
191
|
+
click () {
|
|
192
|
+
const root = $(
|
|
193
|
+
'#formatAndTypeChoices > .typesHolder > ' +
|
|
194
|
+
'.typeContainer > div[data-type]'
|
|
195
|
+
);
|
|
196
|
+
const formControl =
|
|
197
|
+
keyPathNotExpectedTypeChoices.types.getFormControlForRoot(root);
|
|
198
|
+
formControl.style.backgroundColor = 'red';
|
|
199
|
+
setTimeout(() => {
|
|
200
|
+
formControl.style.backgroundColor = 'white';
|
|
201
|
+
}, 3000);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}, ['Show root form control']],
|
|
205
|
+
|
|
206
|
+
['button', {
|
|
207
|
+
id: 'getValueFromRootAncestor',
|
|
208
|
+
$on: {
|
|
209
|
+
click () {
|
|
210
|
+
const val =
|
|
211
|
+
keyPathNotExpectedTypeChoices.types.getValueFromRootAncestor(
|
|
212
|
+
'#formatAndTypeChoices > .typesHolder > ' +
|
|
213
|
+
'.typeContainer'
|
|
214
|
+
);
|
|
215
|
+
console.log(val);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}, [
|
|
219
|
+
'Get value from root ancestor'
|
|
220
|
+
]],
|
|
221
|
+
|
|
222
|
+
['button', {
|
|
223
|
+
id: 'showFormControlFromRootAncestor',
|
|
224
|
+
$on: {
|
|
225
|
+
click () {
|
|
226
|
+
const formControl =
|
|
227
|
+
keyPathNotExpectedTypeChoices.types.getFormControlFromRootAncestor(
|
|
228
|
+
'#formatAndTypeChoices > .typesHolder > ' +
|
|
229
|
+
'.typeContainer'
|
|
230
|
+
);
|
|
231
|
+
formControl.style.backgroundColor = 'red';
|
|
232
|
+
setTimeout(() => {
|
|
233
|
+
formControl.style.backgroundColor = 'initial';
|
|
234
|
+
}, 3000);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}, [
|
|
238
|
+
'Show form control from root ancestor'
|
|
239
|
+
]],
|
|
240
|
+
|
|
241
|
+
['h2', [
|
|
242
|
+
'Format and type choices: Key path expected (object required at root)'
|
|
243
|
+
]],
|
|
244
|
+
...formatAndTypeChoices({
|
|
245
|
+
hasKeyPath: true,
|
|
246
|
+
typeNamespace: 'demo-keypath-expected'
|
|
247
|
+
}).domArray,
|
|
248
|
+
|
|
249
|
+
['h2', [
|
|
250
|
+
'Format choices without type selection ' +
|
|
251
|
+
'(might use as retrieval return format)'
|
|
252
|
+
]],
|
|
253
|
+
['select', {id: 'formatAndSchemaChoices'}, [
|
|
254
|
+
getFormatAndSchemaChoices()
|
|
255
|
+
]],
|
|
256
|
+
|
|
257
|
+
['h2', [
|
|
258
|
+
'Type choices only'
|
|
259
|
+
]],
|
|
260
|
+
|
|
261
|
+
(() => {
|
|
262
|
+
const typeSelection = typeChoices({
|
|
263
|
+
format: 'structuredCloning',
|
|
264
|
+
typeNamespace: 'demo-type-choices-only'
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
return ['form', {
|
|
268
|
+
id: 'typeChoicesOnly',
|
|
269
|
+
$on: {
|
|
270
|
+
submit (e) {
|
|
271
|
+
e.preventDefault();
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}, [
|
|
275
|
+
...typeSelection.domArray,
|
|
276
|
+
['button', {
|
|
277
|
+
id: 'typeChoicesOnly-getType',
|
|
278
|
+
$on: {
|
|
279
|
+
click () {
|
|
280
|
+
// eslint-disable-next-line no-alert -- Simple demo
|
|
281
|
+
alert(typeSelection.getType());
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}, ['Get type']],
|
|
285
|
+
|
|
286
|
+
['button', {
|
|
287
|
+
id: 'typeChoicesOnly-isValid',
|
|
288
|
+
$on: {
|
|
289
|
+
click () {
|
|
290
|
+
// eslint-disable-next-line no-alert -- Simple demo
|
|
291
|
+
alert(typeSelection.validValuesSet());
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}, ['Is valid']],
|
|
295
|
+
|
|
296
|
+
['button', {
|
|
297
|
+
id: 'validateInitialType',
|
|
298
|
+
$on: {
|
|
299
|
+
click () {
|
|
300
|
+
// eslint-disable-next-line no-alert -- Simple demo
|
|
301
|
+
alert(typeSelection.domArray[0].$validate());
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}, [
|
|
305
|
+
'Validate initial type'
|
|
306
|
+
]],
|
|
307
|
+
|
|
308
|
+
['button', {
|
|
309
|
+
id: 'typeChoicesOnly-logValue',
|
|
310
|
+
$on: {
|
|
311
|
+
click () {
|
|
312
|
+
console.log(typeSelection.getValue());
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}, ['Log value']],
|
|
316
|
+
|
|
317
|
+
['button', {
|
|
318
|
+
id: 'typeChoicesOnly-initializeWithValue',
|
|
319
|
+
$on: {
|
|
320
|
+
async click () {
|
|
321
|
+
await typeSelection.setValue(42);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}, ['Initialize with a value']]
|
|
325
|
+
]];
|
|
326
|
+
})(),
|
|
327
|
+
|
|
328
|
+
['h2', [
|
|
329
|
+
'Type choices with initial value set'
|
|
330
|
+
]],
|
|
331
|
+
|
|
332
|
+
(() => {
|
|
333
|
+
const badDate = new Date('Bad date');
|
|
334
|
+
const cause = new Error('some cause');
|
|
335
|
+
const error = new Error('msg');
|
|
336
|
+
error.cause = cause;
|
|
337
|
+
|
|
338
|
+
// eslint-disable-next-line unicorn/error-message -- Testing empty
|
|
339
|
+
const error2 = new Error();
|
|
340
|
+
error2.message = undefined; // Needed to force (at least in Chrome)
|
|
341
|
+
error2.fileName = 'abc';
|
|
342
|
+
error2.name = undefined;
|
|
343
|
+
error2.stack = undefined;
|
|
344
|
+
error2.lineNumber = 10;
|
|
345
|
+
error2.columnNumber = 20;
|
|
346
|
+
|
|
347
|
+
const typeError = new TypeError('msg');
|
|
348
|
+
const typeCause = new RangeError('some cause');
|
|
349
|
+
typeError.cause = typeCause;
|
|
350
|
+
|
|
351
|
+
// eslint-disable-next-line unicorn/error-message -- Testing empty
|
|
352
|
+
const error3 = new TypeError();
|
|
353
|
+
error3.message = undefined; // Needed to force (at least in Chrome)
|
|
354
|
+
error3.fileName = 'abc';
|
|
355
|
+
error3.name = undefined;
|
|
356
|
+
error3.stack = undefined;
|
|
357
|
+
error3.lineNumber = 10;
|
|
358
|
+
error3.columnNumber = 20;
|
|
359
|
+
|
|
360
|
+
const aggregate1 = new RangeError('agg err1');
|
|
361
|
+
const aggregate2 = new TypeError('agg err2');
|
|
362
|
+
const aggregate3 = new Error('agg err3');
|
|
363
|
+
const errAggregate = new AggregateError(
|
|
364
|
+
[aggregate1, aggregate2, aggregate3], 'agg msg'
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
const typeSelection = typeChoices({
|
|
368
|
+
format: 'structuredCloning',
|
|
369
|
+
setValue: true,
|
|
370
|
+
value: [
|
|
371
|
+
42, 123n, 'test123', new Date('1999-01-01'), badDate,
|
|
372
|
+
// eslint-disable-next-line require-unicode-regexp -- Testing
|
|
373
|
+
/.*?/,
|
|
374
|
+
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
375
|
+
// eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins -- Testing
|
|
376
|
+
new Boolean(false),
|
|
377
|
+
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
378
|
+
// eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins -- Testing
|
|
379
|
+
new Boolean(true),
|
|
380
|
+
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
381
|
+
// eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins -- Testing
|
|
382
|
+
new Number(42),
|
|
383
|
+
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
384
|
+
// eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins -- Testing
|
|
385
|
+
new String('test123'),
|
|
386
|
+
Number.NaN,
|
|
387
|
+
-0,
|
|
388
|
+
new Blob(['<b>Testing</b>'], {type: 'text/html'}),
|
|
389
|
+
new Map([
|
|
390
|
+
[null, 3],
|
|
391
|
+
[true, new Map([[false, 5]])],
|
|
392
|
+
[new Map([[6, 4]]), 7]
|
|
393
|
+
]),
|
|
394
|
+
error,
|
|
395
|
+
error2,
|
|
396
|
+
error3,
|
|
397
|
+
typeError,
|
|
398
|
+
errAggregate,
|
|
399
|
+
new File(['abc'], 'someName', {
|
|
400
|
+
lastModified: 1231231230,
|
|
401
|
+
type: 'text/plain'
|
|
402
|
+
}),
|
|
403
|
+
new Blob(['abc'], {
|
|
404
|
+
type: 'text/plain'
|
|
405
|
+
}),
|
|
406
|
+
new DOMException('some message', 'someName'),
|
|
407
|
+
new DOMRect(1, 2, 3, 4),
|
|
408
|
+
new DOMRectReadOnly(1, 2, 3, 4),
|
|
409
|
+
new DOMPoint(1, 2, 3, 4),
|
|
410
|
+
new DOMPointReadOnly(1, 2, 3, 4),
|
|
411
|
+
new DOMMatrix([1, 2, 3, 4, 5, 6]),
|
|
412
|
+
new DOMMatrixReadOnly([1, 2, 3, 4, 5, 6]),
|
|
413
|
+
new DOMMatrix([
|
|
414
|
+
1, 2, 3, 4,
|
|
415
|
+
5, 6, 7, 8,
|
|
416
|
+
9, 10, 11, 12,
|
|
417
|
+
13, 14, 15, 16
|
|
418
|
+
]),
|
|
419
|
+
new ArrayBuffer(8),
|
|
420
|
+
new DataView(new ArrayBuffer(8), 2, 4),
|
|
421
|
+
new Uint8Array(new ArrayBuffer(8), 2, 4),
|
|
422
|
+
makeNoneditableType()
|
|
423
|
+
],
|
|
424
|
+
typeNamespace: 'demo-type-choices-only-initial-value'
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
const typeSelectionBlobHTML = typeChoices({
|
|
428
|
+
format: 'structuredCloning',
|
|
429
|
+
setValue: true,
|
|
430
|
+
value: new Blob(['<b>Testing</b>'], {type: 'text/html'}),
|
|
431
|
+
typeNamespace: 'demo-type-choices-only-initial-value'
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
const error4 = new Error('msg2');
|
|
435
|
+
const cause4 = new Error('some cause2');
|
|
436
|
+
error4.cause = cause4;
|
|
437
|
+
const typeSelectionErrorWithCause = typeChoices({
|
|
438
|
+
format: 'structuredCloning',
|
|
439
|
+
setValue: true,
|
|
440
|
+
value: error4,
|
|
441
|
+
typeNamespace: 'demo-type-choices-only-initial-value-ErrorCause'
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
const error5 = new TypeError('msg2');
|
|
445
|
+
const cause5 = new RangeError('some cause2');
|
|
446
|
+
error5.cause = cause5;
|
|
447
|
+
const typeSelectionTypeErrorWithCause = typeChoices({
|
|
448
|
+
format: 'structuredCloning',
|
|
449
|
+
setValue: true,
|
|
450
|
+
value: error5,
|
|
451
|
+
typeNamespace: 'demo-type-choices-only-initial-value-ErrorsCause'
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
const typeSelectionIndexedDBKey = typeChoices({
|
|
455
|
+
format: 'indexedDBKey',
|
|
456
|
+
setValue: true,
|
|
457
|
+
value: [-0, Number.NEGATIVE_INFINITY],
|
|
458
|
+
typeNamespace: 'demo-type-choices-only-initial-value',
|
|
459
|
+
keySelectClass: 'only-initial'
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
const agg1 = new RangeError('some err1');
|
|
463
|
+
const agg2 = new TypeError('some err2');
|
|
464
|
+
const agg3 = new Error('some err3');
|
|
465
|
+
const errorAggregate = new AggregateError([agg1, agg2, agg3], 'msg2');
|
|
466
|
+
errorAggregate.stack = undefined; // For coverage
|
|
467
|
+
const typeSelectionTypeErrorWithAggregate = typeChoices({
|
|
468
|
+
format: 'structuredCloning',
|
|
469
|
+
setValue: true,
|
|
470
|
+
value: errorAggregate,
|
|
471
|
+
typeNamespace: 'demo-type-choices-only-initial-value-ErrorsAggregate'
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
const typeSelectionFile = typeChoices({
|
|
475
|
+
format: 'structuredCloning',
|
|
476
|
+
setValue: true,
|
|
477
|
+
value: new File(['abc'], 'anotherName', {
|
|
478
|
+
lastModified: 1231231230,
|
|
479
|
+
type: 'text/plain'
|
|
480
|
+
}),
|
|
481
|
+
typeNamespace: 'demo-type-choices-only-initial-value'
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
const typeSelectionBlob = typeChoices({
|
|
485
|
+
format: 'structuredCloning',
|
|
486
|
+
setValue: true,
|
|
487
|
+
value: new Blob(['abc'], {
|
|
488
|
+
type: 'text/plain'
|
|
489
|
+
}),
|
|
490
|
+
typeNamespace: 'demo-type-choices-only-initial-value'
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
const typeSelectionNoneditable = typeChoices({
|
|
494
|
+
format: 'structuredCloning',
|
|
495
|
+
setValue: true,
|
|
496
|
+
value: makeNoneditableType(),
|
|
497
|
+
typeNamespace: 'demo-type-choices-only-initial-value'
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
const typeSelectionArrayBuffer = typeChoices({
|
|
501
|
+
format: 'structuredCloning',
|
|
502
|
+
setValue: true,
|
|
503
|
+
value: new ArrayBuffer(8),
|
|
504
|
+
typeNamespace: 'demo-type-choices-only-initial-value'
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
return ['form', [
|
|
508
|
+
...typeSelection.domArray,
|
|
509
|
+
...typeSelectionBlobHTML.domArray,
|
|
510
|
+
...typeSelectionErrorWithCause.domArray,
|
|
511
|
+
...typeSelectionIndexedDBKey.domArray,
|
|
512
|
+
...typeSelectionTypeErrorWithCause.domArray,
|
|
513
|
+
...typeSelectionTypeErrorWithAggregate.domArray,
|
|
514
|
+
...typeSelectionFile.domArray,
|
|
515
|
+
...typeSelectionBlob.domArray,
|
|
516
|
+
...typeSelectionNoneditable.domArray,
|
|
517
|
+
...typeSelectionArrayBuffer.domArray
|
|
518
|
+
]];
|
|
519
|
+
})(),
|
|
520
|
+
|
|
521
|
+
['button', {
|
|
522
|
+
id: 'validValuesSet',
|
|
523
|
+
$on: {
|
|
524
|
+
click () {
|
|
525
|
+
// eslint-disable-next-line no-alert -- Simple demo
|
|
526
|
+
alert(Types.validValuesSet({
|
|
527
|
+
form: this.previousElementSibling,
|
|
528
|
+
typeNamespace: 'demo-type-choices-only-initial-value',
|
|
529
|
+
keySelectClass: 'only-initial'
|
|
530
|
+
}));
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}, [
|
|
534
|
+
'Valid values set?'
|
|
535
|
+
]],
|
|
536
|
+
|
|
537
|
+
['h2', [
|
|
538
|
+
'Convert arbitrary value to an editable menu'
|
|
539
|
+
]],
|
|
540
|
+
|
|
541
|
+
await types.getControlsForFormatAndValue(
|
|
542
|
+
'structuredCloning',
|
|
543
|
+
new Date('1999-01-01')
|
|
544
|
+
),
|
|
545
|
+
|
|
546
|
+
['h2', [
|
|
547
|
+
'Convert arbitrary value to a readonly menu'
|
|
548
|
+
]],
|
|
549
|
+
|
|
550
|
+
await types.getControlsForFormatAndValue(
|
|
551
|
+
'structuredCloning',
|
|
552
|
+
new Date('1999-01-01'), {
|
|
553
|
+
readonly: true
|
|
554
|
+
}
|
|
555
|
+
),
|
|
556
|
+
|
|
557
|
+
['h2', [
|
|
558
|
+
'Convert structured cloning string representation to value and log'
|
|
559
|
+
]],
|
|
560
|
+
['input', {
|
|
561
|
+
id: 'getValueForString',
|
|
562
|
+
placeholder: 'e.g., ["abc", 17]',
|
|
563
|
+
$on: {
|
|
564
|
+
change () {
|
|
565
|
+
const types = new Types();
|
|
566
|
+
const value = types.getValueForString(this.value, {
|
|
567
|
+
format: $('#useIndexedDBKey').checked
|
|
568
|
+
? 'indexedDBKey'
|
|
569
|
+
: 'structuredCloning'
|
|
570
|
+
})[0];
|
|
571
|
+
console.log(value);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}],
|
|
575
|
+
|
|
576
|
+
(() => {
|
|
577
|
+
return ['form', {
|
|
578
|
+
$on: {
|
|
579
|
+
submit (e) {
|
|
580
|
+
e.preventDefault();
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}, [
|
|
584
|
+
['button', {
|
|
585
|
+
id: 'attemptBadIndexedDBKey',
|
|
586
|
+
$on: {
|
|
587
|
+
click () {
|
|
588
|
+
const badDate = new Date('Bad date');
|
|
589
|
+
typeChoices({
|
|
590
|
+
format: 'indexedDBKey',
|
|
591
|
+
setValue: true,
|
|
592
|
+
value: [badDate],
|
|
593
|
+
typeNamespace: 'demo-type-choices-only-initial-value'
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}, [
|
|
598
|
+
'Attempt bad indexedDBKey (invalid Date)'
|
|
599
|
+
]],
|
|
600
|
+
['button', {
|
|
601
|
+
id: 'attemptBadIndexedDBKeyStringObject',
|
|
602
|
+
$on: {
|
|
603
|
+
click () {
|
|
604
|
+
typeChoices({
|
|
605
|
+
format: 'indexedDBKey',
|
|
606
|
+
setValue: true,
|
|
607
|
+
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
608
|
+
// eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins -- Testing
|
|
609
|
+
value: [new String('Bad value')],
|
|
610
|
+
typeNamespace: 'demo-type-choices-only-initial-value'
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}, [
|
|
615
|
+
'Attempt bad indexedDBKey (String object)'
|
|
616
|
+
]],
|
|
617
|
+
['button', {
|
|
618
|
+
id: 'attemptBadJSON',
|
|
619
|
+
$on: {
|
|
620
|
+
click () {
|
|
621
|
+
typeChoices({
|
|
622
|
+
format: 'json',
|
|
623
|
+
setValue: true,
|
|
624
|
+
// eslint-disable-next-line no-sparse-arrays -- Testing
|
|
625
|
+
value: [,],
|
|
626
|
+
typeNamespace: 'demo-type-choices-only-initial-value'
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}, [
|
|
631
|
+
'Attempt bad JSON (sparse array)'
|
|
632
|
+
]]
|
|
633
|
+
]];
|
|
634
|
+
})(),
|
|
635
|
+
|
|
636
|
+
['label', [
|
|
637
|
+
'Use indexedDBKey (valid dates only)',
|
|
638
|
+
['input', {
|
|
639
|
+
id: 'useIndexedDBKey',
|
|
640
|
+
type: 'checkbox'
|
|
641
|
+
}]
|
|
642
|
+
]]
|
|
643
|
+
], body);
|
|
644
|
+
}, 500);
|