@formio/js 5.5.2 → 5.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +2 -2
  2. package/dist/formio.builder.css +3 -0
  3. package/dist/formio.builder.min.css +1 -1
  4. package/dist/formio.embed.js +1 -1
  5. package/dist/formio.embed.min.js +1 -1
  6. package/dist/formio.embed.min.js.LICENSE.txt +1 -1
  7. package/dist/formio.form.css +3 -0
  8. package/dist/formio.form.js +23 -23
  9. package/dist/formio.form.min.css +1 -1
  10. package/dist/formio.form.min.js +1 -1
  11. package/dist/formio.form.min.js.LICENSE.txt +1 -1
  12. package/dist/formio.full.css +3 -0
  13. package/dist/formio.full.js +25 -25
  14. package/dist/formio.full.min.css +1 -1
  15. package/dist/formio.full.min.js +1 -1
  16. package/dist/formio.full.min.js.LICENSE.txt +1 -1
  17. package/dist/formio.js +10 -10
  18. package/dist/formio.min.js +1 -1
  19. package/dist/formio.min.js.LICENSE.txt +1 -1
  20. package/dist/formio.utils.js +8 -8
  21. package/dist/formio.utils.min.js +1 -1
  22. package/dist/formio.utils.min.js.LICENSE.txt +1 -1
  23. package/lib/cjs/Embed.js +1 -1
  24. package/lib/cjs/Formio.js +1 -1
  25. package/lib/cjs/components/_classes/component/Component.js +2 -1
  26. package/lib/cjs/components/address/Address.js +5 -2
  27. package/lib/cjs/components/address/editForm/Address.edit.provider.d.ts +24 -0
  28. package/lib/cjs/components/address/editForm/Address.edit.provider.js +13 -0
  29. package/lib/cjs/components/datagrid/DataGrid.js +2 -1
  30. package/lib/cjs/components/file/File.js +17 -8
  31. package/lib/cjs/components/file/editForm/File.edit.file.d.ts +44 -0
  32. package/lib/cjs/components/file/editForm/File.edit.file.js +2 -1
  33. package/lib/cjs/components/form/Form.d.ts +7 -0
  34. package/lib/cjs/components/form/Form.js +24 -2
  35. package/lib/cjs/components/signature/Signature.js +2 -2
  36. package/lib/cjs/package.json +1 -1
  37. package/lib/cjs/providers/address/GoogleAddressProvider.d.ts +9 -1
  38. package/lib/cjs/providers/address/GoogleAddressProvider.js +116 -32
  39. package/lib/mjs/Embed.js +1 -1
  40. package/lib/mjs/Formio.js +1 -1
  41. package/lib/mjs/components/_classes/component/Component.js +1 -1
  42. package/lib/mjs/components/address/Address.js +5 -2
  43. package/lib/mjs/components/address/editForm/Address.edit.provider.d.ts +24 -0
  44. package/lib/mjs/components/address/editForm/Address.edit.provider.js +13 -0
  45. package/lib/mjs/components/datagrid/DataGrid.js +2 -1
  46. package/lib/mjs/components/file/File.js +17 -8
  47. package/lib/mjs/components/file/editForm/File.edit.file.d.ts +44 -0
  48. package/lib/mjs/components/file/editForm/File.edit.file.js +2 -1
  49. package/lib/mjs/components/form/Form.d.ts +7 -0
  50. package/lib/mjs/components/form/Form.js +24 -2
  51. package/lib/mjs/components/signature/Signature.js +2 -2
  52. package/lib/mjs/package.json +1 -1
  53. package/lib/mjs/providers/address/GoogleAddressProvider.d.ts +9 -1
  54. package/lib/mjs/providers/address/GoogleAddressProvider.js +94 -32
  55. package/package.json +7 -7
@@ -20,7 +20,7 @@
20
20
 
21
21
  /*! @license DOMPurify 3.4.13 | (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.13/LICENSE */
22
22
 
23
- /*! formiojs v5.5.2 | https://unpkg.com/formiojs@5.5.2/LICENSE.txt */
23
+ /*! formiojs v5.6.0 | https://unpkg.com/formiojs@5.6.0/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
@@ -500,7 +500,7 @@ Formio.formioReady = new Promise((ready, reject) => {
500
500
  _a._formioReady = ready;
501
501
  _a._formioReadyReject = reject;
502
502
  });
503
- Formio.version = '5.5.2';
503
+ Formio.version = '5.6.0';
504
504
  // Create a report.
505
505
  Formio.Report = {
506
506
  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.5.2';
14
+ sdk_1.Formio.version = '5.6.0';
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';
@@ -925,11 +925,12 @@ class Component extends Element_1.default {
925
925
  * @returns {string} - The translated text.
926
926
  */
927
927
  t(text, params = {}, ...args) {
928
+ var _a;
928
929
  if (!text) {
929
930
  return '';
930
931
  }
931
932
  // Use _userInput: true to ignore translations from defaults
932
- if (text in en_1.default && params._userInput) {
933
+ if (((_a = this.i18next) === null || _a === void 0 ? void 0 : _a.language) === 'en' && text in en_1.default && params._userInput) {
933
934
  return text;
934
935
  }
935
936
  params.data = params.data || this.rootValue;
@@ -417,8 +417,12 @@ class AddressComponent extends Container_1.default {
417
417
  this.searchInput.forEach((element, index) => {
418
418
  if (!this.builderMode && element && this.provider) {
419
419
  if (this.component.provider === 'google') {
420
+ if (this.component.enableNewPlacesApi) {
421
+ this.provider.options.version = 'newPlacesApi';
422
+ }
420
423
  this.googlePlacesCleanups = [];
421
- this.provider.attachAutocomplete(element, index, this.onSelectAddress.bind(this))
424
+ this.provider
425
+ .attachAutocomplete(element, index, this.onSelectAddress.bind(this), this.disabled)
422
426
  .then((cleanup) => {
423
427
  if (typeof cleanup === 'function') {
424
428
  this.googlePlacesCleanups.push(cleanup);
@@ -514,7 +518,6 @@ class AddressComponent extends Container_1.default {
514
518
  if (this.autocompleterWidget && typeof this.autocompleterWidget.destroy === 'function') {
515
519
  this.autocompleterWidget.destroy();
516
520
  }
517
- ;
518
521
  (this.googlePlacesCleanups || []).forEach((cleanup) => {
519
522
  cleanup();
520
523
  });
@@ -118,6 +118,30 @@ declare const _default: ({
118
118
  validate?: undefined;
119
119
  defaultValue?: undefined;
120
120
  description?: undefined;
121
+ } | {
122
+ weight: number;
123
+ type: string;
124
+ input: boolean;
125
+ key: string;
126
+ label: string;
127
+ tooltip: string;
128
+ conditional: {
129
+ json: {
130
+ '===': (string | {
131
+ var: string;
132
+ })[];
133
+ };
134
+ };
135
+ placeholder?: undefined;
136
+ valueProperty?: undefined;
137
+ dataSrc?: undefined;
138
+ data?: undefined;
139
+ validate?: undefined;
140
+ defaultValue?: undefined;
141
+ rows?: undefined;
142
+ editor?: undefined;
143
+ as?: undefined;
144
+ description?: undefined;
121
145
  } | {
122
146
  type: string;
123
147
  input: boolean;
@@ -141,6 +141,19 @@ exports.default = [
141
141
  },
142
142
  },
143
143
  },
144
+ {
145
+ weight: 10,
146
+ type: 'checkbox',
147
+ input: true,
148
+ key: 'enableNewPlacesApi',
149
+ label: 'Places API (New)',
150
+ tooltip: 'Enable the new Google Places API instead of the legacy version.',
151
+ conditional: {
152
+ json: {
153
+ '===': [{ var: 'data.provider' }, 'google'],
154
+ },
155
+ },
156
+ },
144
157
  {
145
158
  type: 'textarea',
146
159
  input: true,
@@ -547,7 +547,8 @@ class DataGridComponent extends NestedArrayComponent_1.default {
547
547
  }, modified);
548
548
  this.triggerRootChange(flags, changed, modified);
549
549
  }
550
- this.processRow('checkData', null, Object.assign(Object.assign({}, flags), { changed }), row, lodash_1.default.toArray(this.rows[rowIndex]));
550
+ const rowData = this.dataValue[rowIndex];
551
+ this.processRow('checkData', null, Object.assign(Object.assign({}, flags), { changed }), rowData, lodash_1.default.toArray(this.rows[rowIndex]));
551
552
  };
552
553
  let columnComponent;
553
554
  if (this.builderMode) {
@@ -103,6 +103,11 @@ class FileComponent extends Field_1.default {
103
103
  this.abortUploads = [];
104
104
  this.pendingfiles = [];
105
105
  this.resolvedFiles = [];
106
+ const imageSize = Number(this.component.imageSize);
107
+ const isValidImageSize = imageSize > 0;
108
+ if (!isValidImageSize) {
109
+ this.component.imageSize = '200';
110
+ }
106
111
  }
107
112
  get dataReady() {
108
113
  return this.filesReady || Promise.resolve();
@@ -637,7 +642,7 @@ class FileComponent extends Field_1.default {
637
642
  fileKey: this.component.fileKey || 'file',
638
643
  storage: this.component.storage,
639
644
  options: this.component.storage === 'url'
640
- ? (this.component.urlRequestOptions || this.component.options)
645
+ ? this.component.urlRequestOptions || this.component.options
641
646
  : this.component.options,
642
647
  file,
643
648
  size: file.size,
@@ -673,7 +678,9 @@ class FileComponent extends Field_1.default {
673
678
  return fileWithSameNameUploaded || fileWithSameNameUploading
674
679
  ? {
675
680
  status: 'error',
676
- message: this.t(fileWithSameNameUploading ? 'fileWithDuplicatedNameInProgress' : 'fileWithDuplicatedNameLoaded'),
681
+ message: this.t(fileWithSameNameUploading
682
+ ? 'fileWithDuplicatedNameInProgress'
683
+ : 'fileWithDuplicatedNameLoaded'),
677
684
  }
678
685
  : {};
679
686
  }
@@ -872,8 +879,8 @@ class FileComponent extends Field_1.default {
872
879
  deleteFile(fileInfo) {
873
880
  return __awaiter(this, void 0, void 0, function* () {
874
881
  const options = this.component.storage === 'url'
875
- ? (this.component.urlRequestOptions || this.component.options || {})
876
- : (this.component.options || {});
882
+ ? this.component.urlRequestOptions || this.component.options || {}
883
+ : this.component.options || {};
877
884
  if (fileInfo &&
878
885
  ['url', 'indexeddb', 's3', 'azure', 'googledrive'].includes(this.component.storage)) {
879
886
  const { fileService } = this;
@@ -1013,7 +1020,7 @@ class FileComponent extends Field_1.default {
1013
1020
  delete fileToSync.progress;
1014
1021
  this.redraw();
1015
1022
  if (fileInfo) {
1016
- const fileExists = this.resolvedFiles.find(x => x.fileInfo.originalName === fileToSync.originalName);
1023
+ const fileExists = this.resolvedFiles.find((x) => x.fileInfo.originalName === fileToSync.originalName);
1017
1024
  if (!fileExists && fileToSync.status !== 'error') {
1018
1025
  this.resolvedFiles.push({ fileToSync, fileInfo });
1019
1026
  }
@@ -1071,8 +1078,8 @@ class FileComponent extends Field_1.default {
1071
1078
  }
1072
1079
  getFile(fileInfo) {
1073
1080
  const options = this.component.storage === 'url'
1074
- ? (this.component.urlRequestOptions || this.component.options || {})
1075
- : (this.component.options || {});
1081
+ ? this.component.urlRequestOptions || this.component.options || {}
1082
+ : this.component.options || {};
1076
1083
  const { fileService } = this;
1077
1084
  if (!fileService) {
1078
1085
  return alert(this.t('noFileService'));
@@ -1113,7 +1120,9 @@ class FileComponent extends Field_1.default {
1113
1120
  return Promise.resolve();
1114
1121
  }
1115
1122
  yield this.syncFiles();
1116
- return this.shouldSyncFiles ? Promise.reject(this.t('synchronizationFailed')) : Promise.resolve();
1123
+ return this.shouldSyncFiles
1124
+ ? Promise.reject(this.t('synchronizationFailed'))
1125
+ : Promise.resolve();
1117
1126
  }
1118
1127
  catch (error) {
1119
1128
  return Promise.reject(error.message);
@@ -18,6 +18,7 @@ declare const _default: ({
18
18
  editor?: undefined;
19
19
  as?: undefined;
20
20
  logic?: undefined;
21
+ clearOnHide?: undefined;
21
22
  optionsLabelPosition?: undefined;
22
23
  inline?: undefined;
23
24
  defaultValue?: undefined;
@@ -48,6 +49,7 @@ declare const _default: ({
48
49
  editor?: undefined;
49
50
  as?: undefined;
50
51
  logic?: undefined;
52
+ clearOnHide?: undefined;
51
53
  optionsLabelPosition?: undefined;
52
54
  inline?: undefined;
53
55
  defaultValue?: undefined;
@@ -95,6 +97,7 @@ declare const _default: ({
95
97
  editor?: undefined;
96
98
  as?: undefined;
97
99
  logic?: undefined;
100
+ clearOnHide?: undefined;
98
101
  optionsLabelPosition?: undefined;
99
102
  inline?: undefined;
100
103
  defaultValue?: undefined;
@@ -125,6 +128,7 @@ declare const _default: ({
125
128
  editor?: undefined;
126
129
  as?: undefined;
127
130
  logic?: undefined;
131
+ clearOnHide?: undefined;
128
132
  optionsLabelPosition?: undefined;
129
133
  inline?: undefined;
130
134
  defaultValue?: undefined;
@@ -161,6 +165,7 @@ declare const _default: ({
161
165
  editor?: undefined;
162
166
  as?: undefined;
163
167
  logic?: undefined;
168
+ clearOnHide?: undefined;
164
169
  optionsLabelPosition?: undefined;
165
170
  inline?: undefined;
166
171
  defaultValue?: undefined;
@@ -191,6 +196,7 @@ declare const _default: ({
191
196
  tableView?: undefined;
192
197
  components?: undefined;
193
198
  logic?: undefined;
199
+ clearOnHide?: undefined;
194
200
  optionsLabelPosition?: undefined;
195
201
  inline?: undefined;
196
202
  defaultValue?: undefined;
@@ -237,6 +243,7 @@ declare const _default: ({
237
243
  rows?: undefined;
238
244
  editor?: undefined;
239
245
  as?: undefined;
246
+ clearOnHide?: undefined;
240
247
  optionsLabelPosition?: undefined;
241
248
  inline?: undefined;
242
249
  defaultValue?: undefined;
@@ -259,6 +266,7 @@ declare const _default: ({
259
266
  editor?: undefined;
260
267
  as?: undefined;
261
268
  logic?: undefined;
269
+ clearOnHide?: undefined;
262
270
  optionsLabelPosition?: undefined;
263
271
  inline?: undefined;
264
272
  defaultValue?: undefined;
@@ -281,6 +289,7 @@ declare const _default: ({
281
289
  editor?: undefined;
282
290
  as?: undefined;
283
291
  logic?: undefined;
292
+ clearOnHide?: undefined;
284
293
  optionsLabelPosition?: undefined;
285
294
  inline?: undefined;
286
295
  defaultValue?: undefined;
@@ -311,6 +320,7 @@ declare const _default: ({
311
320
  editor?: undefined;
312
321
  as?: undefined;
313
322
  logic?: undefined;
323
+ clearOnHide?: undefined;
314
324
  optionsLabelPosition?: undefined;
315
325
  inline?: undefined;
316
326
  defaultValue?: undefined;
@@ -323,6 +333,7 @@ declare const _default: ({
323
333
  placeholder: string;
324
334
  tooltip: string;
325
335
  weight: number;
336
+ clearOnHide: boolean;
326
337
  conditional: {
327
338
  json: {
328
339
  '==': (boolean | {
@@ -345,6 +356,37 @@ declare const _default: ({
345
356
  inline?: undefined;
346
357
  defaultValue?: undefined;
347
358
  values?: undefined;
359
+ } | {
360
+ type: string;
361
+ input: boolean;
362
+ key: string;
363
+ label: string;
364
+ placeholder: string;
365
+ tooltip: string;
366
+ weight: number;
367
+ conditional: {
368
+ json: {
369
+ '==': (boolean | {
370
+ var: string;
371
+ })[];
372
+ '==='?: undefined;
373
+ in?: undefined;
374
+ };
375
+ };
376
+ valueProperty?: undefined;
377
+ dataSrc?: undefined;
378
+ data?: undefined;
379
+ tableView?: undefined;
380
+ components?: undefined;
381
+ rows?: undefined;
382
+ editor?: undefined;
383
+ as?: undefined;
384
+ logic?: undefined;
385
+ clearOnHide?: undefined;
386
+ optionsLabelPosition?: undefined;
387
+ inline?: undefined;
388
+ defaultValue?: undefined;
389
+ values?: undefined;
348
390
  } | {
349
391
  type: string;
350
392
  input: boolean;
@@ -370,6 +412,7 @@ declare const _default: ({
370
412
  editor?: undefined;
371
413
  as?: undefined;
372
414
  logic?: undefined;
415
+ clearOnHide?: undefined;
373
416
  } | {
374
417
  type: string;
375
418
  input: boolean;
@@ -393,6 +436,7 @@ declare const _default: ({
393
436
  editor?: undefined;
394
437
  as?: undefined;
395
438
  logic?: undefined;
439
+ clearOnHide?: undefined;
396
440
  optionsLabelPosition?: undefined;
397
441
  inline?: undefined;
398
442
  defaultValue?: undefined;
@@ -295,8 +295,9 @@ exports.default = [
295
295
  key: 'imageSize',
296
296
  label: 'Image Size',
297
297
  placeholder: '100',
298
- tooltip: 'The image size for previewing images.',
298
+ tooltip: 'The image size, in square pixels, for previewing images.',
299
299
  weight: 40,
300
+ clearOnHide: false,
300
301
  conditional: {
301
302
  json: {
302
303
  '==': [{ var: 'data.image' }, true],
@@ -63,6 +63,13 @@ export default class FormComponent extends Component {
63
63
  checkComponentConditions(data: any, flags: any, row: any): any;
64
64
  calculateValue(data: any, flags: any, row: any): any;
65
65
  setPristine(pristine: any): void;
66
+ /**
67
+ * Determine if an ancestor is hidden by the `hidden` JSON flag alone. An ancestor that has its
68
+ * own condition is governed by that condition instead and is left to `parentConditionallyHidden`
69
+ * — the `hidden` flag and conditionally-hidden are distinct states (FIO-11691).
70
+ * @returns {boolean} - TRUE if an ancestor is hidden in the JSON and has no condition.
71
+ */
72
+ hasAncestorHiddenInJsonOnly(): boolean;
66
73
  /**
67
74
  * Determine if the subform should be submitted.
68
75
  * @returns {*|boolean} - TRUE if the subform should be submitted, FALSE if it should not.
@@ -564,16 +564,38 @@ class FormComponent extends Component_1.default {
564
564
  this.subForm.setPristine(pristine);
565
565
  }
566
566
  }
567
+ /**
568
+ * Determine if an ancestor is hidden by the `hidden` JSON flag alone. An ancestor that has its
569
+ * own condition is governed by that condition instead and is left to `parentConditionallyHidden`
570
+ * — the `hidden` flag and conditionally-hidden are distinct states (FIO-11691).
571
+ * @returns {boolean} - TRUE if an ancestor is hidden in the JSON and has no condition.
572
+ */
573
+ hasAncestorHiddenInJsonOnly() {
574
+ let currentParent = this.parent;
575
+ while (currentParent) {
576
+ if (currentParent.component.hidden && !currentParent.hasCondition()) {
577
+ return true;
578
+ }
579
+ currentParent = currentParent.parent;
580
+ }
581
+ return false;
582
+ }
567
583
  /**
568
584
  * Determine if the subform should be submitted.
569
585
  * @returns {*|boolean} - TRUE if the subform should be submitted, FALSE if it should not.
570
586
  */
571
587
  get shouldSubmit() {
588
+ const savesAsReference = !this.component.hasOwnProperty('reference') || this.component.reference;
572
589
  const hiddenByJsonOnly = !this.hasCondition() && this.component.hidden;
590
+ // Layout ancestors (fieldset, panel, tabs...) hide us without appearing in our data path, so
591
+ // their hidden state is only reachable by walking the instance chain (FIO-9879).
592
+ const hiddenByAncestor = this.hasAncestorHiddenInJsonOnly() || this.parentConditionallyHidden();
593
+ // Gate on our own clearOnHide, never an ancestor's.
594
+ const clearedWhileHidden = (hiddenByJsonOnly || hiddenByAncestor) && this.component.clearOnHide;
573
595
  return (this.subFormReady &&
574
- (!this.component.hasOwnProperty('reference') || this.component.reference) &&
596
+ savesAsReference &&
575
597
  !this.shouldConditionallyClear() &&
576
- !(hiddenByJsonOnly && this.component.clearOnHide));
598
+ !clearedWhileHidden);
577
599
  }
578
600
  /**
579
601
  * Returns the data for the subform.
@@ -203,7 +203,7 @@ class SignatureComponent extends Input_1.default {
203
203
  penColor: this.component.penColor,
204
204
  backgroundColor: this.component.backgroundColor,
205
205
  });
206
- this.signaturePad.addEventListener('endStroke', () => this.setValue(this.signaturePad.toDataURL()));
206
+ this.signaturePad.addEventListener('endStroke', () => this.setValue(this.signaturePad.toDataURL(), { modified: true }));
207
207
  this.refs.signatureImage.setAttribute('src', this.signaturePad.toDataURL());
208
208
  this.onDisabled();
209
209
  // Ensure the signature is always the size of its container.
@@ -232,7 +232,7 @@ class SignatureComponent extends Input_1.default {
232
232
  event.preventDefault();
233
233
  this.showCanvas(true);
234
234
  this.signaturePad.clear();
235
- this.setValue(this.defaultValue);
235
+ this.setValue(this.defaultValue, { modified: true });
236
236
  });
237
237
  this.setValue(this.dataValue);
238
238
  return superAttach;
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "type": "commonjs",
3
- "version": "5.5.2"
3
+ "version": "5.6.0"
4
4
  }
@@ -39,6 +39,14 @@ export class GoogleAddressProvider extends AddressProvider {
39
39
  * @returns {string} The alternative property to use for display value.
40
40
  */
41
41
  get alternativeDisplayValueProperty(): string;
42
+ /**
43
+ * @returns {string} The property to use for display value on places returned by the new Places API.
44
+ */
45
+ get newApiDisplayValueProperty(): string;
46
+ /**
47
+ * @returns {boolean} Whether the provider is configured to use the new Places API.
48
+ */
49
+ get usesNewPlacesApi(): boolean;
42
50
  /**
43
51
  * @param {AutocompleteOptions} options - The autocomplete options.
44
52
  */
@@ -78,7 +86,7 @@ export class GoogleAddressProvider extends AddressProvider {
78
86
  */
79
87
  addRequiredProviderOptions(options: AutocompleteOptions): void;
80
88
  filterPlace(place: any): {};
81
- attachAutocomplete(elem: any, index: any, onSelectAddress: any): any;
89
+ attachAutocomplete(elem: any, index: any, onSelectAddress: any, disable?: boolean): any;
82
90
  search(): Promise<void>;
83
91
  makeRequest(): Promise<void>;
84
92
  getDisplayValue(address: any): any;
@@ -1,4 +1,24 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
2
22
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
23
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
24
  };
@@ -11,6 +31,7 @@ const AddressProvider_1 = require("./AddressProvider");
11
31
  const GOOGLE_MAPS_BASE_URL = 'https://maps.googleapis.com';
12
32
  const GOOGLE_MAPS_JS_URL = `${GOOGLE_MAPS_BASE_URL}/maps/api/js`;
13
33
  const GOOGLE_MAPS_JS_WITH_PARAMS_URL = `${GOOGLE_MAPS_JS_URL}?v=quarterly&libraries=places&loading=async&callback=googleMapsCallback`;
34
+ const NEW_PLACES_API_VERSION = 'newPlacesApi';
14
35
  /**
15
36
  * @typedef {object} AutocompleteOptions
16
37
  * @property {string[]} fields - The fields to include in the autocomplete response.
@@ -78,6 +99,19 @@ class GoogleAddressProvider extends AddressProvider_1.AddressProvider {
78
99
  get alternativeDisplayValueProperty() {
79
100
  return 'formatted_address';
80
101
  }
102
+ /**
103
+ * @returns {string} The property to use for display value on places returned by the new Places API.
104
+ */
105
+ get newApiDisplayValueProperty() {
106
+ return 'formattedAddress';
107
+ }
108
+ /**
109
+ * @returns {boolean} Whether the provider is configured to use the new Places API.
110
+ */
111
+ get usesNewPlacesApi() {
112
+ var _a;
113
+ return ((_a = this.options) === null || _a === void 0 ? void 0 : _a.version) === NEW_PLACES_API_VERSION;
114
+ }
81
115
  /**
82
116
  * @param {AutocompleteOptions} options - The autocomplete options.
83
117
  */
@@ -95,10 +129,11 @@ class GoogleAddressProvider extends AddressProvider_1.AddressProvider {
95
129
 
96
130
  */
97
131
  setAutocompleteOptions() {
98
- let options = lodash_1.default.get(this.options, 'autocompleteOptions', {});
99
- if (!lodash_1.default.isObject(options)) {
100
- options = {};
101
- }
132
+ // Clone so the stored provider options are never mutated: the required fields
133
+ // differ per Places API version, and stale fields from a previous computation
134
+ // must not leak into the next one (FIO-10428).
135
+ const storedOptions = lodash_1.default.get(this.options, 'autocompleteOptions', {});
136
+ const options = lodash_1.default.isObject(storedOptions) ? lodash_1.default.cloneDeep(storedOptions) : {};
102
137
  this.addRequiredProviderOptions(options);
103
138
  this.autocompleteOptions = options;
104
139
  }
@@ -138,14 +173,9 @@ class GoogleAddressProvider extends AddressProvider_1.AddressProvider {
138
173
  * @returns {string[]} The required address properties.
139
174
  */
140
175
  getRequiredAddressProperties() {
141
- return [
142
- 'address_components',
143
- 'formatted_address',
144
- 'geometry',
145
- 'place_id',
146
- 'plus_code',
147
- 'types',
148
- ];
176
+ return this.usesNewPlacesApi
177
+ ? ['addressComponents', 'formattedAddress', 'location', 'viewport', 'id', 'plusCode', 'types']
178
+ : ['address_components', 'formatted_address', 'geometry', 'place_id', 'plus_code', 'types'];
149
179
  }
150
180
  /**
151
181
  * Adds the required provider options to the options.
@@ -174,25 +204,77 @@ class GoogleAddressProvider extends AddressProvider_1.AddressProvider {
174
204
  }
175
205
  return filteredPlace;
176
206
  }
177
- attachAutocomplete(elem, index, onSelectAddress) {
207
+ attachAutocomplete(elem, index, onSelectAddress, disable = false) {
208
+ if (disable) {
209
+ return Promise.resolve();
210
+ }
178
211
  return Formio_1.Formio.libraryReady(this.getLibraryName()).then(() => {
179
- const autocomplete = new google.maps.places.Autocomplete(elem, this.autocompleteOptions);
180
- const listener = autocomplete.addListener('place_changed', () => {
181
- const place = this.filterPlace(autocomplete.getPlace());
182
- place.formattedPlace = lodash_1.default.get(autocomplete, 'gm_accessors_.place.se.formattedPrediction', place[this.alternativeDisplayValueProperty]);
183
- onSelectAddress(place, elem, index);
212
+ this.setAutocompleteOptions();
213
+ if (!this.usesNewPlacesApi) {
214
+ const autocomplete = new google.maps.places.Autocomplete(elem, this.autocompleteOptions);
215
+ const listener = autocomplete.addListener('place_changed', () => {
216
+ const place = this.filterPlace(autocomplete.getPlace());
217
+ place.formattedPlace = lodash_1.default.get(autocomplete, 'gm_accessors_.place.se.formattedPrediction', place[this.alternativeDisplayValueProperty]);
218
+ onSelectAddress(place, elem, index);
219
+ });
220
+ return () => {
221
+ var _a;
222
+ if ((_a = google === null || google === void 0 ? void 0 : google.maps) === null || _a === void 0 ? void 0 : _a.event) {
223
+ google.maps.event.clearInstanceListeners(autocomplete);
224
+ google.maps.event.removeListener(listener);
225
+ }
226
+ document.querySelectorAll('.pac-container').forEach((node) => {
227
+ if (node.parentNode) {
228
+ node.parentNode.removeChild(node);
229
+ }
230
+ });
231
+ };
232
+ }
233
+ const _a = this.autocompleteOptions, { fields, componentRestrictions } = _a, elementOptions = __rest(_a, ["fields", "componentRestrictions"]);
234
+ const country = componentRestrictions === null || componentRestrictions === void 0 ? void 0 : componentRestrictions.country;
235
+ if (country) {
236
+ // The new element spells legacy componentRestrictions.country as includedRegionCodes.
237
+ elementOptions.includedRegionCodes = lodash_1.default.castArray(country);
238
+ }
239
+ elementOptions.noInputIcon = true;
240
+ const autocomplete = new google.maps.places.PlaceAutocompleteElement(elementOptions);
241
+ if (elem === null || elem === void 0 ? void 0 : elem.value) {
242
+ autocomplete.value = elem.value;
243
+ }
244
+ autocomplete.classList.add('form-control');
245
+ // Replace the existing element with the autocomplete element
246
+ elem.parentNode.replaceChildren(autocomplete);
247
+ const handlePlaceSelect = (event) => __awaiter(this, void 0, void 0, function* () {
248
+ var _b, _c;
249
+ let selectedPlace;
250
+ try {
251
+ const place = event.placePrediction.toPlace();
252
+ yield place.fetchFields({
253
+ fields: fields || this.getRequiredAddressProperties(),
254
+ });
255
+ const convertedPlace = {
256
+ addressComponents: place.addressComponents || [],
257
+ formattedAddress: place.formattedAddress || '',
258
+ location: place.location || {},
259
+ viewport: place.viewport || {},
260
+ id: place.id || '',
261
+ plusCode: place.plusCode || {},
262
+ types: place.types || [],
263
+ };
264
+ selectedPlace = this.filterPlace(convertedPlace);
265
+ selectedPlace.formattedPlace = convertedPlace.formattedAddress;
266
+ }
267
+ catch (err) {
268
+ // fetchFields rejections are otherwise swallowed by the Maps event
269
+ // dispatcher; never let a failed details request drop the selection.
270
+ console.warn(`Unable to fetch the selected place's details: ${err}`);
271
+ selectedPlace = { formattedPlace: String((_c = (_b = event.placePrediction) === null || _b === void 0 ? void 0 : _b.text) !== null && _c !== void 0 ? _c : '') };
272
+ }
273
+ onSelectAddress(selectedPlace, elem, index);
184
274
  });
275
+ autocomplete.addEventListener('gmp-select', handlePlaceSelect);
185
276
  return () => {
186
- var _a;
187
- if ((_a = google === null || google === void 0 ? void 0 : google.maps) === null || _a === void 0 ? void 0 : _a.event) {
188
- google.maps.event.clearInstanceListeners(autocomplete);
189
- google.maps.event.removeListener(listener);
190
- }
191
- document.querySelectorAll('.pac-container').forEach((node) => {
192
- if (node.parentNode) {
193
- node.parentNode.removeChild(node);
194
- }
195
- });
277
+ autocomplete.removeEventListener('gmp-select', handlePlaceSelect);
196
278
  };
197
279
  });
198
280
  }
@@ -203,10 +285,12 @@ class GoogleAddressProvider extends AddressProvider_1.AddressProvider {
203
285
  return Promise.resolve();
204
286
  }
205
287
  getDisplayValue(address) {
206
- const displayedProperty = lodash_1.default.has(address, this.displayValueProperty)
207
- ? this.displayValueProperty
208
- : this.alternativeDisplayValueProperty;
209
- return lodash_1.default.get(address, displayedProperty, '');
288
+ const displayedProperty = [
289
+ this.displayValueProperty,
290
+ this.alternativeDisplayValueProperty,
291
+ this.newApiDisplayValueProperty,
292
+ ].find((property) => lodash_1.default.has(address, property));
293
+ return displayedProperty ? lodash_1.default.get(address, displayedProperty, '') : '';
210
294
  }
211
295
  /**
212
296
  * Tries to remove the library if api key for loaded script is different.