@formio/js 5.4.0 → 5.4.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 (48) hide show
  1. package/dist/formio.builder.css +11 -5
  2. package/dist/formio.builder.min.css +1 -1
  3. package/dist/formio.embed.js +1 -1
  4. package/dist/formio.embed.min.js +1 -1
  5. package/dist/formio.embed.min.js.LICENSE.txt +1 -1
  6. package/dist/formio.form.css +11 -5
  7. package/dist/formio.form.js +2768 -2774
  8. package/dist/formio.form.min.css +1 -1
  9. package/dist/formio.form.min.js +1 -1
  10. package/dist/formio.form.min.js.LICENSE.txt +1 -1
  11. package/dist/formio.full.css +11 -5
  12. package/dist/formio.full.js +3368 -3374
  13. package/dist/formio.full.min.css +1 -1
  14. package/dist/formio.full.min.js +1 -1
  15. package/dist/formio.full.min.js.LICENSE.txt +1 -1
  16. package/dist/formio.js +1118 -1124
  17. package/dist/formio.min.js +1 -1
  18. package/dist/formio.min.js.LICENSE.txt +1 -1
  19. package/dist/formio.utils.js +1050 -1056
  20. package/dist/formio.utils.min.js +1 -1
  21. package/dist/formio.utils.min.js.LICENSE.txt +1 -1
  22. package/lib/cjs/Embed.js +1 -1
  23. package/lib/cjs/Formio.js +1 -1
  24. package/lib/cjs/components/_classes/component/Component.d.ts +5 -0
  25. package/lib/cjs/components/_classes/component/Component.js +16 -2
  26. package/lib/cjs/components/button/Button.d.ts +1 -0
  27. package/lib/cjs/components/button/Button.js +22 -1
  28. package/lib/cjs/components/datagrid/DataGrid.js +4 -5
  29. package/lib/cjs/components/select/Select.js +2 -3
  30. package/lib/cjs/package.json +1 -1
  31. package/lib/cjs/providers/address/GoogleAddressProvider.js +1 -1
  32. package/lib/cjs/translations/en.d.ts +1 -0
  33. package/lib/cjs/translations/en.js +3 -1
  34. package/lib/cjs/utils/utils.js +5 -5
  35. package/lib/mjs/Embed.js +1 -1
  36. package/lib/mjs/Formio.js +1 -1
  37. package/lib/mjs/components/_classes/component/Component.d.ts +5 -0
  38. package/lib/mjs/components/_classes/component/Component.js +16 -2
  39. package/lib/mjs/components/button/Button.d.ts +1 -0
  40. package/lib/mjs/components/button/Button.js +21 -1
  41. package/lib/mjs/components/datagrid/DataGrid.js +5 -6
  42. package/lib/mjs/components/select/Select.js +2 -3
  43. package/lib/mjs/package.json +1 -1
  44. package/lib/mjs/providers/address/GoogleAddressProvider.js +1 -1
  45. package/lib/mjs/translations/en.d.ts +1 -0
  46. package/lib/mjs/translations/en.js +3 -1
  47. package/lib/mjs/utils/utils.js +5 -5
  48. package/package.json +5 -5
@@ -20,7 +20,7 @@
20
20
 
21
21
  /*! @license DOMPurify 3.4.0 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.0/LICENSE */
22
22
 
23
- /*! formiojs v5.4.0 | https://unpkg.com/formiojs@5.4.0/LICENSE.txt */
23
+ /*! formiojs v5.4.1 | https://unpkg.com/formiojs@5.4.1/LICENSE.txt */
24
24
 
25
25
  /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
26
26
 
package/lib/cjs/Embed.js CHANGED
@@ -508,7 +508,7 @@ Formio.formioReady = new Promise((ready, reject) => {
508
508
  _a._formioReady = ready;
509
509
  _a._formioReadyReject = reject;
510
510
  });
511
- Formio.version = '5.4.0';
511
+ Formio.version = '5.4.1';
512
512
  // Create a report.
513
513
  Formio.Report = {
514
514
  create: (element, submission, options = {}) => __awaiter(void 0, void 0, void 0, function* () {
package/lib/cjs/Formio.js CHANGED
@@ -11,7 +11,7 @@ const CDN_1 = __importDefault(require("./CDN"));
11
11
  const providers_1 = __importDefault(require("./providers"));
12
12
  sdk_1.Formio.cdn = new CDN_1.default();
13
13
  sdk_1.Formio.Providers = providers_1.default;
14
- sdk_1.Formio.version = '5.4.0';
14
+ sdk_1.Formio.version = '5.4.1';
15
15
  CDN_1.default.defaultCDN = sdk_1.Formio.version.includes('rc')
16
16
  ? 'https://cdn.test-form.io'
17
17
  : 'https://cdn.form.io';
@@ -396,6 +396,11 @@ declare class Component extends Element {
396
396
  * @param {string} [referenceAttributeName] - The attribute name to use for the reference.
397
397
  */
398
398
  loadRefs(element: HTMLElement, refs: object, referenceAttributeName?: string | undefined): void;
399
+ /**
400
+ * Announces a message to screen readers via the component's live region.
401
+ * @param {string} message - The message to announce.
402
+ */
403
+ announce(message: string): void;
399
404
  /**
400
405
  * Opens the modal element.
401
406
  * @param {string} template - The template to use for the modal dialog.
@@ -1219,6 +1219,19 @@ class Component extends Element_1.default {
1219
1219
  }
1220
1220
  }
1221
1221
  }
1222
+ /**
1223
+ * Announces a message to screen readers via the component's live region.
1224
+ * @param {string} message - The message to announce.
1225
+ */
1226
+ announce(message) {
1227
+ const liveRegion = this.refs.liveRegion;
1228
+ if (liveRegion) {
1229
+ liveRegion.textContent = '';
1230
+ setTimeout(() => {
1231
+ liveRegion.textContent = message;
1232
+ }, 50);
1233
+ }
1234
+ }
1222
1235
  /**
1223
1236
  * Opens the modal element.
1224
1237
  * @param {string} template - The template to use for the modal dialog.
@@ -1352,6 +1365,7 @@ class Component extends Element_1.default {
1352
1365
  this.loadRefs(element, {
1353
1366
  messageContainer: 'single',
1354
1367
  tooltip: 'multiple',
1368
+ liveRegion: 'single',
1355
1369
  });
1356
1370
  this.attachTooltips(this.refs.tooltip);
1357
1371
  // Attach logic.
@@ -1596,13 +1610,13 @@ class Component extends Element_1.default {
1596
1610
  value.forEach((val, index) => {
1597
1611
  const widget = this.refs.input[index] && this.refs.input[index].widget;
1598
1612
  if (widget) {
1599
- values.push(widget.getValueAsString(val, options));
1613
+ values.push(widget.getValueAsString(val));
1600
1614
  }
1601
1615
  });
1602
1616
  return values;
1603
1617
  }
1604
1618
  const widget = this.refs.input[0].widget;
1605
- return widget.getValueAsString(value, options);
1619
+ return widget.getValueAsString(value);
1606
1620
  }
1607
1621
  /**
1608
1622
  * Returns the value of the component as a string.
@@ -29,6 +29,7 @@ export default class ButtonComponent extends Field {
29
29
  detach(element: any): void;
30
30
  onClick(event: any): void;
31
31
  openOauth(settings: any): void;
32
+ _handleOauthSessionExpired(): void;
32
33
  get oauthComponentPath(): any;
33
34
  focus(): void;
34
35
  triggerCaptcha(): void;
@@ -371,6 +371,12 @@ class ButtonComponent extends Field_1.default {
371
371
  }
372
372
  openOauth(settings) {
373
373
  var _a;
374
+ // this is if the temp session (storing the state and code verifiers) expires in the db
375
+ // and we need to fetch new oauth state
376
+ if (settings.sessionExpireAt && Date.now() >= settings.sessionExpireAt) {
377
+ this._handleOauthSessionExpired();
378
+ return;
379
+ }
374
380
  if (!((_a = this.root) === null || _a === void 0 ? void 0 : _a.formio)) {
375
381
  console.warn('You must attach a Form API url to your form in order to use OAuth buttons.');
376
382
  return;
@@ -386,7 +392,8 @@ class ButtonComponent extends Field_1.default {
386
392
  if (settings.state) {
387
393
  params.state = settings.state;
388
394
  }
389
- else if (settings.code_challenge) {
395
+ // okta requires both a state and a code challenge for PKCE
396
+ if (settings.code_challenge) {
390
397
  params.code_challenge = settings.code_challenge;
391
398
  params.code_challenge_method = 'S256';
392
399
  }
@@ -429,6 +436,9 @@ class ButtonComponent extends Field_1.default {
429
436
  (_b = this.root) === null || _b === void 0 ? void 0 : _b.setAlert('danger', 'OAuth state does not match. Please try logging in again.');
430
437
  return;
431
438
  }
439
+ if (settings.sessionId) {
440
+ params.sessionId = settings.sessionId;
441
+ }
432
442
  // Depending on where the settings came from, submit to either the submission endpoint (old) or oauth endpoint (new).
433
443
  let requestPromise = Promise.resolve();
434
444
  if (lodash_1.default.has(this, 'root.form.config.oauth') &&
@@ -457,6 +467,11 @@ class ButtonComponent extends Field_1.default {
457
467
  })
458
468
  .catch((err) => {
459
469
  var _a;
470
+ console.log(err);
471
+ if (settings.sessionExpireAt && Date.now() >= settings.sessionExpireAt) {
472
+ this._handleOauthSessionExpired();
473
+ return;
474
+ }
460
475
  (_a = this.root) === null || _a === void 0 ? void 0 : _a.onSubmissionError(err);
461
476
  });
462
477
  }
@@ -472,6 +487,12 @@ class ButtonComponent extends Field_1.default {
472
487
  }
473
488
  }, 100);
474
489
  }
490
+ _handleOauthSessionExpired() {
491
+ var _a;
492
+ (_a = this.root) === null || _a === void 0 ? void 0 : _a.setAlert('warning', this.t('oauthSessionExpired'));
493
+ this.loading = true;
494
+ setTimeout(() => window.location.reload(), 2000);
495
+ }
475
496
  get oauthComponentPath() {
476
497
  const pathArray = (0, utils_1.getArrayFromComponentPath)(this.path);
477
498
  return lodash_1.default.chain(pathArray)
@@ -446,11 +446,11 @@ class DataGridComponent extends NestedArrayComponent_1.default {
446
446
  component: this.component,
447
447
  row,
448
448
  });
449
- (0, utils_1.screenReaderSpeech)('Row has been added');
450
449
  this.checkConditions();
451
450
  (_a = this.triggerChange) === null || _a === void 0 ? void 0 : _a.call(this, { modified: true, noPristineChangeOnModified: true });
452
451
  this.redraw().then(() => {
453
452
  this.focusOnNewRowElement(this.rows[index]);
453
+ this.announce(this.t('Row has been added'));
454
454
  });
455
455
  }
456
456
  updateComponentsRowIndex(components, rowIndex) {
@@ -493,15 +493,14 @@ class DataGridComponent extends NestedArrayComponent_1.default {
493
493
  const flags = { isReordered: !makeEmpty, resetValue: makeEmpty };
494
494
  this.splice(index, flags);
495
495
  this.emit('dataGridDeleteRow', { index });
496
- if (this.rows.length > 1) {
497
- (0, utils_1.screenReaderSpeech)('Row has been deleted');
498
- }
499
496
  const [row,] = this.rows.splice(index, 1);
500
497
  this.removeSubmissionMetadataRow(index);
501
498
  this.removeRowComponents(row);
502
499
  this.updateRowsComponents(index);
503
500
  this.setValue(this.dataValue, flags);
504
- this.redraw();
501
+ this.redraw().then(() => {
502
+ this.announce(this.t('Row has been deleted'));
503
+ });
505
504
  }
506
505
  removeRowComponents(row) {
507
506
  lodash_1.default.each(row, (component) => this.removeComponent(component));
@@ -1299,8 +1299,7 @@ class SelectComponent extends ListComponent_1.default {
1299
1299
  }
1300
1300
  setMetadata(value, flags = {}) {
1301
1301
  var _a, _b;
1302
- if (lodash_1.default.isNil(value) ||
1303
- (this.inDataTable && this.component.dataSrc === 'values')) {
1302
+ if (lodash_1.default.isNil(value)) {
1304
1303
  return;
1305
1304
  }
1306
1305
  const valueIsObject = lodash_1.default.isObject(value);
@@ -1605,7 +1604,7 @@ class SelectComponent extends ListComponent_1.default {
1605
1604
  if (this.inDataTable) {
1606
1605
  value = this.undoValueTyping(value);
1607
1606
  }
1608
- const templateValue = this.isEntireObjectDisplay() && !lodash_1.default.isObject(value.data) ? { data: value } : value;
1607
+ const templateValue = !lodash_1.default.isEmpty(value) && this.isEntireObjectDisplay() && !lodash_1.default.isObject(value.data) ? { data: value } : value;
1609
1608
  const template = this.itemTemplate(templateValue, value, options);
1610
1609
  return template;
1611
1610
  }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "type": "commonjs",
3
- "version": "5.4.0"
3
+ "version": "5.4.1"
4
4
  }
@@ -95,7 +95,7 @@ class GoogleAddressProvider extends AddressProvider_1.AddressProvider {
95
95
 
96
96
  */
97
97
  setAutocompleteOptions() {
98
- let options = lodash_1.default.get(this.options, 'params.autocompleteOptions', {});
98
+ let options = lodash_1.default.get(this.options, 'autocompleteOptions', {});
99
99
  if (!lodash_1.default.isObject(options)) {
100
100
  options = {};
101
101
  }
@@ -78,5 +78,6 @@ declare namespace _default {
78
78
  let requiredYearField: string;
79
79
  let fileTooSmall: string;
80
80
  let fileTooBig: string;
81
+ let oauthSessionExpired: string;
81
82
  }
82
83
  export default _default;
@@ -79,5 +79,7 @@ exports.default = {
79
79
  requiredMonthField: '{{ field }} is required',
80
80
  requiredYearField: '{{ field }} is required',
81
81
  fileTooSmall: 'File is too small; it must be at least {{ size }}',
82
- fileTooBig: 'File is too big; it must be at most {{ size }}'
82
+ fileTooBig: 'File is too big; it must be at most {{ size }}',
83
+ // when temp document storing oauth state and code verifier is cleared by ttl before the user completes login
84
+ oauthSessionExpired: 'Login attempt expired; please try again. Refreshing...',
83
85
  };
@@ -159,7 +159,7 @@ function getConditionalPathsRecursive(conditionPaths, data) {
159
159
  }
160
160
  else {
161
161
  currentData.forEach((x, index) => {
162
- if (!lodash_1.default.isNil(x[conditionPaths[currentLocalIndex]])) {
162
+ if (x && conditionPaths && !lodash_1.default.isNil(x[conditionPaths[currentLocalIndex]])) {
163
163
  const compDataPath = `${currentPath}[${index}].${conditionPaths[currentLocalIndex]}`;
164
164
  conditionalPathsArray.push(compDataPath);
165
165
  }
@@ -1823,18 +1823,18 @@ function announceScreenReaderMessage(component, value, index = 0, forFocus = fal
1823
1823
  if (forFocus) {
1824
1824
  setTimeout(() => {
1825
1825
  el.textContent = "";
1826
- requestAnimationFrame(() => {
1826
+ setTimeout(() => {
1827
1827
  el.textContent = combinedMessage;
1828
- });
1828
+ }, 50);
1829
1829
  }, 150);
1830
1830
  return;
1831
1831
  }
1832
1832
  clearTimeout(el._announceTimer);
1833
1833
  el._announceTimer = setTimeout(() => {
1834
1834
  el.textContent = "";
1835
- requestAnimationFrame(() => {
1835
+ setTimeout(() => {
1836
1836
  el.textContent = combinedMessage;
1837
- });
1837
+ }, 50);
1838
1838
  }, 500);
1839
1839
  }
1840
1840
  exports.announceScreenReaderMessage = announceScreenReaderMessage;
package/lib/mjs/Embed.js CHANGED
@@ -14,7 +14,7 @@ export class Formio {
14
14
  Formio._formioReady = ready;
15
15
  Formio._formioReadyReject = reject;
16
16
  });
17
- static version = '5.4.0';
17
+ static version = '5.4.1';
18
18
  static setLicense(license, norecurse = false) {
19
19
  Formio.license = license;
20
20
  if (!norecurse && Formio.FormioClass) {
package/lib/mjs/Formio.js CHANGED
@@ -4,7 +4,7 @@ import CDN from './CDN';
4
4
  import Providers from './providers';
5
5
  FormioCore.cdn = new CDN();
6
6
  FormioCore.Providers = Providers;
7
- FormioCore.version = '5.4.0';
7
+ FormioCore.version = '5.4.1';
8
8
  CDN.defaultCDN = FormioCore.version.includes('rc')
9
9
  ? 'https://cdn.test-form.io'
10
10
  : 'https://cdn.form.io';
@@ -396,6 +396,11 @@ declare class Component extends Element {
396
396
  * @param {string} [referenceAttributeName] - The attribute name to use for the reference.
397
397
  */
398
398
  loadRefs(element: HTMLElement, refs: object, referenceAttributeName?: string | undefined): void;
399
+ /**
400
+ * Announces a message to screen readers via the component's live region.
401
+ * @param {string} message - The message to announce.
402
+ */
403
+ announce(message: string): void;
399
404
  /**
400
405
  * Opens the modal element.
401
406
  * @param {string} template - The template to use for the modal dialog.
@@ -1212,6 +1212,19 @@ export default class Component extends Element {
1212
1212
  }
1213
1213
  }
1214
1214
  }
1215
+ /**
1216
+ * Announces a message to screen readers via the component's live region.
1217
+ * @param {string} message - The message to announce.
1218
+ */
1219
+ announce(message) {
1220
+ const liveRegion = this.refs.liveRegion;
1221
+ if (liveRegion) {
1222
+ liveRegion.textContent = '';
1223
+ setTimeout(() => {
1224
+ liveRegion.textContent = message;
1225
+ }, 50);
1226
+ }
1227
+ }
1215
1228
  /**
1216
1229
  * Opens the modal element.
1217
1230
  * @param {string} template - The template to use for the modal dialog.
@@ -1352,6 +1365,7 @@ export default class Component extends Element {
1352
1365
  this.loadRefs(element, {
1353
1366
  messageContainer: 'single',
1354
1367
  tooltip: 'multiple',
1368
+ liveRegion: 'single',
1355
1369
  });
1356
1370
  this.attachTooltips(this.refs.tooltip);
1357
1371
  // Attach logic.
@@ -1591,13 +1605,13 @@ export default class Component extends Element {
1591
1605
  value.forEach((val, index) => {
1592
1606
  const widget = this.refs.input[index] && this.refs.input[index].widget;
1593
1607
  if (widget) {
1594
- values.push(widget.getValueAsString(val, options));
1608
+ values.push(widget.getValueAsString(val));
1595
1609
  }
1596
1610
  });
1597
1611
  return values;
1598
1612
  }
1599
1613
  const widget = this.refs.input[0].widget;
1600
- return widget.getValueAsString(value, options);
1614
+ return widget.getValueAsString(value);
1601
1615
  }
1602
1616
  /**
1603
1617
  * Returns the value of the component as a string.
@@ -29,6 +29,7 @@ export default class ButtonComponent extends Field {
29
29
  detach(element: any): void;
30
30
  onClick(event: any): void;
31
31
  openOauth(settings: any): void;
32
+ _handleOauthSessionExpired(): void;
32
33
  get oauthComponentPath(): any;
33
34
  focus(): void;
34
35
  triggerCaptcha(): void;
@@ -363,6 +363,12 @@ export default class ButtonComponent extends Field {
363
363
  }
364
364
  }
365
365
  openOauth(settings) {
366
+ // this is if the temp session (storing the state and code verifiers) expires in the db
367
+ // and we need to fetch new oauth state
368
+ if (settings.sessionExpireAt && Date.now() >= settings.sessionExpireAt) {
369
+ this._handleOauthSessionExpired();
370
+ return;
371
+ }
366
372
  if (!this.root?.formio) {
367
373
  console.warn('You must attach a Form API url to your form in order to use OAuth buttons.');
368
374
  return;
@@ -378,7 +384,8 @@ export default class ButtonComponent extends Field {
378
384
  if (settings.state) {
379
385
  params.state = settings.state;
380
386
  }
381
- else if (settings.code_challenge) {
387
+ // okta requires both a state and a code challenge for PKCE
388
+ if (settings.code_challenge) {
382
389
  params.code_challenge = settings.code_challenge;
383
390
  params.code_challenge_method = 'S256';
384
391
  }
@@ -420,6 +427,9 @@ export default class ButtonComponent extends Field {
420
427
  this.root?.setAlert('danger', 'OAuth state does not match. Please try logging in again.');
421
428
  return;
422
429
  }
430
+ if (settings.sessionId) {
431
+ params.sessionId = settings.sessionId;
432
+ }
423
433
  // Depending on where the settings came from, submit to either the submission endpoint (old) or oauth endpoint (new).
424
434
  let requestPromise = Promise.resolve();
425
435
  if (_.has(this, 'root.form.config.oauth') &&
@@ -446,6 +456,11 @@ export default class ButtonComponent extends Field {
446
456
  this.root?.onSubmit(result, true);
447
457
  })
448
458
  .catch((err) => {
459
+ console.log(err);
460
+ if (settings.sessionExpireAt && Date.now() >= settings.sessionExpireAt) {
461
+ this._handleOauthSessionExpired();
462
+ return;
463
+ }
449
464
  this.root?.onSubmissionError(err);
450
465
  });
451
466
  }
@@ -461,6 +476,11 @@ export default class ButtonComponent extends Field {
461
476
  }
462
477
  }, 100);
463
478
  }
479
+ _handleOauthSessionExpired() {
480
+ this.root?.setAlert('warning', this.t('oauthSessionExpired'));
481
+ this.loading = true;
482
+ setTimeout(() => window.location.reload(), 2000);
483
+ }
464
484
  get oauthComponentPath() {
465
485
  const pathArray = getArrayFromComponentPath(this.path);
466
486
  return _.chain(pathArray)
@@ -1,6 +1,6 @@
1
1
  import _ from 'lodash';
2
2
  import NestedArrayComponent from '../_classes/nestedarray/NestedArrayComponent';
3
- import { fastCloneDeep, getFocusableElements, getComponent, eachComponent, screenReaderSpeech } from '../../utils';
3
+ import { fastCloneDeep, getFocusableElements, getComponent, eachComponent } from '../../utils';
4
4
  import dragula from 'dragula';
5
5
  export default class DataGridComponent extends NestedArrayComponent {
6
6
  static schema(...extend) {
@@ -441,11 +441,11 @@ export default class DataGridComponent extends NestedArrayComponent {
441
441
  component: this.component,
442
442
  row,
443
443
  });
444
- screenReaderSpeech('Row has been added');
445
444
  this.checkConditions();
446
445
  this.triggerChange?.({ modified: true, noPristineChangeOnModified: true });
447
446
  this.redraw().then(() => {
448
447
  this.focusOnNewRowElement(this.rows[index]);
448
+ this.announce(this.t('Row has been added'));
449
449
  });
450
450
  }
451
451
  updateComponentsRowIndex(components, rowIndex) {
@@ -487,15 +487,14 @@ export default class DataGridComponent extends NestedArrayComponent {
487
487
  const flags = { isReordered: !makeEmpty, resetValue: makeEmpty };
488
488
  this.splice(index, flags);
489
489
  this.emit('dataGridDeleteRow', { index });
490
- if (this.rows.length > 1) {
491
- screenReaderSpeech('Row has been deleted');
492
- }
493
490
  const [row,] = this.rows.splice(index, 1);
494
491
  this.removeSubmissionMetadataRow(index);
495
492
  this.removeRowComponents(row);
496
493
  this.updateRowsComponents(index);
497
494
  this.setValue(this.dataValue, flags);
498
- this.redraw();
495
+ this.redraw().then(() => {
496
+ this.announce(this.t('Row has been deleted'));
497
+ });
499
498
  }
500
499
  removeRowComponents(row) {
501
500
  _.each(row, (component) => this.removeComponent(component));
@@ -1326,8 +1326,7 @@ export default class SelectComponent extends ListComponent {
1326
1326
  return super.normalizeValue(this.normalizeSingleValue(value));
1327
1327
  }
1328
1328
  setMetadata(value, flags = {}) {
1329
- if (_.isNil(value) ||
1330
- (this.inDataTable && this.component.dataSrc === 'values')) {
1329
+ if (_.isNil(value)) {
1331
1330
  return;
1332
1331
  }
1333
1332
  const valueIsObject = _.isObject(value);
@@ -1631,7 +1630,7 @@ export default class SelectComponent extends ListComponent {
1631
1630
  if (this.inDataTable) {
1632
1631
  value = this.undoValueTyping(value);
1633
1632
  }
1634
- const templateValue = this.isEntireObjectDisplay() && !_.isObject(value.data) ? { data: value } : value;
1633
+ const templateValue = !_.isEmpty(value) && this.isEntireObjectDisplay() && !_.isObject(value.data) ? { data: value } : value;
1635
1634
  const template = this.itemTemplate(templateValue, value, options);
1636
1635
  return template;
1637
1636
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "type": "module",
3
- "version": "5.4.0"
3
+ "version": "5.4.1"
4
4
 
5
5
  }
@@ -88,7 +88,7 @@ export class GoogleAddressProvider extends AddressProvider {
88
88
 
89
89
  */
90
90
  setAutocompleteOptions() {
91
- let options = _.get(this.options, 'params.autocompleteOptions', {});
91
+ let options = _.get(this.options, 'autocompleteOptions', {});
92
92
  if (!_.isObject(options)) {
93
93
  options = {};
94
94
  }
@@ -78,5 +78,6 @@ declare namespace _default {
78
78
  let requiredYearField: string;
79
79
  let fileTooSmall: string;
80
80
  let fileTooBig: string;
81
+ let oauthSessionExpired: string;
81
82
  }
82
83
  export default _default;
@@ -77,5 +77,7 @@ export default {
77
77
  requiredMonthField: '{{ field }} is required',
78
78
  requiredYearField: '{{ field }} is required',
79
79
  fileTooSmall: 'File is too small; it must be at least {{ size }}',
80
- fileTooBig: 'File is too big; it must be at most {{ size }}'
80
+ fileTooBig: 'File is too big; it must be at most {{ size }}',
81
+ // when temp document storing oauth state and code verifier is cleared by ttl before the user completes login
82
+ oauthSessionExpired: 'Login attempt expired; please try again. Refreshing...',
81
83
  };
@@ -144,7 +144,7 @@ function getConditionalPathsRecursive(conditionPaths, data) {
144
144
  }
145
145
  else {
146
146
  currentData.forEach((x, index) => {
147
- if (!_.isNil(x[conditionPaths[currentLocalIndex]])) {
147
+ if (x && conditionPaths && !_.isNil(x[conditionPaths[currentLocalIndex]])) {
148
148
  const compDataPath = `${currentPath}[${index}].${conditionPaths[currentLocalIndex]}`;
149
149
  conditionalPathsArray.push(compDataPath);
150
150
  }
@@ -1750,18 +1750,18 @@ export function announceScreenReaderMessage(component, value, index = 0, forFocu
1750
1750
  if (forFocus) {
1751
1751
  setTimeout(() => {
1752
1752
  el.textContent = "";
1753
- requestAnimationFrame(() => {
1753
+ setTimeout(() => {
1754
1754
  el.textContent = combinedMessage;
1755
- });
1755
+ }, 50);
1756
1756
  }, 150);
1757
1757
  return;
1758
1758
  }
1759
1759
  clearTimeout(el._announceTimer);
1760
1760
  el._announceTimer = setTimeout(() => {
1761
1761
  el.textContent = "";
1762
- requestAnimationFrame(() => {
1762
+ setTimeout(() => {
1763
1763
  el.textContent = combinedMessage;
1764
- });
1764
+ }, 50);
1765
1765
  }, 500);
1766
1766
  }
1767
1767
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formio/js",
3
- "version": "5.4.0",
3
+ "version": "5.4.1",
4
4
  "description": "JavaScript powered Forms with JSON Form Builder",
5
5
  "main": "lib/cjs/index.js",
6
6
  "exports": {
@@ -68,7 +68,7 @@
68
68
  "core-js": "^3.37.1",
69
69
  "dialog-polyfill": "^0.5.6",
70
70
  "dom-autoscroller": "^2.3.4",
71
- "dompurify": "^3.3.3",
71
+ "dompurify": "^3.4.0",
72
72
  "downloadjs": "^1.4.7",
73
73
  "dragula": "^3.7.3",
74
74
  "eventemitter3": "^5.0.1",
@@ -83,14 +83,14 @@
83
83
  "lodash": "^4.17.23",
84
84
  "moment": "^2.29.4",
85
85
  "moment-timezone": "^0.5.44",
86
- "quill": "^2.0.2",
86
+ "quill": "2.0.2",
87
87
  "signature_pad": "^4.2.0",
88
88
  "string-hash": "^1.1.3",
89
89
  "tippy.js": "^6.3.7",
90
90
  "uuid": "^9.0.0",
91
91
  "vanilla-picker": "^2.12.3",
92
- "@formio/bootstrap": "^4.0.0",
93
- "@formio/core": "^2.7.0"
92
+ "@formio/core": "^2.7.1",
93
+ "@formio/bootstrap": "^4.0.1"
94
94
  },
95
95
  "devDependencies": {
96
96
  "@types/node": "^22.15.19",