@formio/js 5.5.2 → 5.6.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 (67) 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 +29 -29
  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 +31 -31
  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 +14 -14
  18. package/dist/formio.min.js +1 -1
  19. package/dist/formio.min.js.LICENSE.txt +1 -1
  20. package/dist/formio.utils.js +12 -12
  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/Components.js +1 -5
  26. package/lib/cjs/components/_classes/component/Component.d.ts +14 -0
  27. package/lib/cjs/components/_classes/component/Component.js +35 -1
  28. package/lib/cjs/components/_classes/nested/NestedComponent.js +6 -8
  29. package/lib/cjs/components/address/Address.js +5 -2
  30. package/lib/cjs/components/address/editForm/Address.edit.provider.d.ts +24 -0
  31. package/lib/cjs/components/address/editForm/Address.edit.provider.js +13 -0
  32. package/lib/cjs/components/datagrid/DataGrid.js +4 -7
  33. package/lib/cjs/components/file/File.js +17 -8
  34. package/lib/cjs/components/file/editForm/File.edit.file.d.ts +44 -0
  35. package/lib/cjs/components/file/editForm/File.edit.file.js +2 -1
  36. package/lib/cjs/components/form/Form.d.ts +7 -0
  37. package/lib/cjs/components/form/Form.js +24 -2
  38. package/lib/cjs/components/signature/Signature.js +2 -2
  39. package/lib/cjs/package.json +1 -1
  40. package/lib/cjs/providers/address/GoogleAddressProvider.d.ts +9 -1
  41. package/lib/cjs/providers/address/GoogleAddressProvider.js +116 -32
  42. package/lib/cjs/utils/formUtils.d.ts +3 -0
  43. package/lib/cjs/utils/formUtils.js +5 -2
  44. package/lib/cjs/utils/index.d.ts +3 -0
  45. package/lib/mjs/Embed.js +1 -1
  46. package/lib/mjs/Formio.js +1 -1
  47. package/lib/mjs/components/Components.js +1 -5
  48. package/lib/mjs/components/_classes/component/Component.d.ts +14 -0
  49. package/lib/mjs/components/_classes/component/Component.js +34 -1
  50. package/lib/mjs/components/_classes/nested/NestedComponent.js +6 -8
  51. package/lib/mjs/components/address/Address.js +5 -2
  52. package/lib/mjs/components/address/editForm/Address.edit.provider.d.ts +24 -0
  53. package/lib/mjs/components/address/editForm/Address.edit.provider.js +13 -0
  54. package/lib/mjs/components/datagrid/DataGrid.js +4 -7
  55. package/lib/mjs/components/file/File.js +17 -8
  56. package/lib/mjs/components/file/editForm/File.edit.file.d.ts +44 -0
  57. package/lib/mjs/components/file/editForm/File.edit.file.js +2 -1
  58. package/lib/mjs/components/form/Form.d.ts +7 -0
  59. package/lib/mjs/components/form/Form.js +24 -2
  60. package/lib/mjs/components/signature/Signature.js +2 -2
  61. package/lib/mjs/package.json +1 -1
  62. package/lib/mjs/providers/address/GoogleAddressProvider.d.ts +9 -1
  63. package/lib/mjs/providers/address/GoogleAddressProvider.js +94 -32
  64. package/lib/mjs/utils/formUtils.d.ts +3 -0
  65. package/lib/mjs/utils/formUtils.js +2 -2
  66. package/lib/mjs/utils/index.d.ts +3 -0
  67. package/package.json +7 -7
@@ -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.
@@ -29,6 +29,9 @@ export const findComponents: typeof Utils.findComponents;
29
29
  export const eachComponentDataAsync: (components: import("@formio/core").Component[], data: import("@formio/core").DataObject, fn: import("@formio/core").EachComponentDataAsyncCallback, includeAll?: boolean | undefined, local?: boolean | undefined, parent?: import("@formio/core").Component | undefined, parentPaths?: import("@formio/core").ComponentPaths | undefined, noScopeReset?: boolean | undefined, afterFn?: import("@formio/core").EachComponentDataAsyncCallback | undefined, localRoot?: import("@formio/core").LocalRoot | undefined) => Promise<void>;
30
30
  export const eachComponentData: (components: import("@formio/core").Component[], data: import("@formio/core").DataObject, fn: import("@formio/core").EachComponentDataCallback, includeAll?: boolean | undefined, local?: boolean | undefined, parent?: import("@formio/core").Component | undefined, parentPaths?: import("@formio/core").ComponentPaths | undefined, noScopeReset?: boolean | undefined, afterFn?: import("@formio/core").EachComponentDataCallback | undefined, localRoot?: import("@formio/core").LocalRoot | undefined) => void;
31
31
  export const getComponentKey: typeof Utils.getComponentKey;
32
+ export const getSharedPathKey: typeof Utils.getSharedPathKey;
33
+ export const registerInstanceAtPath: typeof Utils.registerInstanceAtPath;
34
+ export const resolveInstanceAtPath: typeof Utils.resolveInstanceAtPath;
32
35
  export const getContextualRowPath: any;
33
36
  export const getContextualRowData: typeof Utils.getContextualRowData;
34
37
  export const componentInfo: typeof Utils.componentInfo;
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getItemTemplateKeys = exports.compareSelectResourceWithObjectTypeValues = exports.isSelectResourceWithObjectValue = exports.isComponentDataEmpty = exports.getEmptyValue = exports.findComponent = exports.applyFormChanges = exports.generateFormChange = exports.getStrings = exports.getValue = exports.escapeRegExCharacters = exports.formatAsCurrency = exports.parseFloatExt = exports.hasCondition = exports.removeComponent = exports.searchComponents = exports.getComponent = exports.matchComponent = exports.isLayoutComponent = exports.getComponentActualValue = exports.getComponentData = exports.eachComponentAsync = exports.eachComponent = exports.componentInfo = exports.getContextualRowData = exports.getContextualRowPath = exports.getComponentKey = exports.eachComponentData = exports.eachComponentDataAsync = exports.findComponents = exports.getComponentValue = exports.getComponentFromPath = exports.getBestMatch = exports.componentMatches = exports.getComponentPaths = exports.componentPath = exports.isComponentNestedDataType = exports.resetComponentScope = exports.setComponentScope = exports.getComponentPath = exports.getModelType = exports.MODEL_TYPES_OF_KNOWN_COMPONENTS = exports.uniqueName = exports.guid = exports.flattenComponents = void 0;
3
+ exports.getItemTemplateKeys = exports.compareSelectResourceWithObjectTypeValues = exports.isSelectResourceWithObjectValue = exports.isComponentDataEmpty = exports.getEmptyValue = exports.findComponent = exports.applyFormChanges = exports.generateFormChange = exports.getStrings = exports.getValue = exports.escapeRegExCharacters = exports.formatAsCurrency = exports.parseFloatExt = exports.hasCondition = exports.removeComponent = exports.searchComponents = exports.getComponent = exports.matchComponent = exports.isLayoutComponent = exports.getComponentActualValue = exports.getComponentData = exports.eachComponentAsync = exports.eachComponent = exports.componentInfo = exports.getContextualRowData = exports.getContextualRowPath = exports.resolveInstanceAtPath = exports.registerInstanceAtPath = exports.getSharedPathKey = exports.getComponentKey = exports.eachComponentData = exports.eachComponentDataAsync = exports.findComponents = exports.getComponentValue = exports.getComponentFromPath = exports.getBestMatch = exports.componentMatches = exports.getComponentPaths = exports.componentPath = exports.isComponentNestedDataType = exports.resetComponentScope = exports.setComponentScope = exports.getComponentPath = exports.getModelType = exports.MODEL_TYPES_OF_KNOWN_COMPONENTS = exports.uniqueName = exports.guid = exports.flattenComponents = void 0;
4
4
  const core_1 = require("@formio/core");
5
- const { flattenComponents, guid, uniqueName, MODEL_TYPES_OF_KNOWN_COMPONENTS, getModelType, getComponentPath, setComponentScope, resetComponentScope, isComponentNestedDataType, componentPath, getComponentPaths, componentMatches, getBestMatch, getComponentFromPath, getComponentValue, findComponents, eachComponentDataAsync, eachComponentData, getComponentKey, getContextualRowPath, getContextualRowData, componentInfo, eachComponent, eachComponentAsync, getComponentData, getComponentActualValue, isLayoutComponent, matchComponent, getComponent, searchComponents, removeComponent, hasCondition, parseFloatExt, formatAsCurrency, escapeRegExCharacters, getValue, getStrings, generateFormChange, applyFormChanges, findComponent, getEmptyValue, isComponentDataEmpty, isSelectResourceWithObjectValue, compareSelectResourceWithObjectTypeValues, getItemTemplateKeys, } = core_1.Utils;
5
+ const { flattenComponents, guid, uniqueName, MODEL_TYPES_OF_KNOWN_COMPONENTS, getModelType, getComponentPath, setComponentScope, resetComponentScope, isComponentNestedDataType, componentPath, getComponentPaths, componentMatches, getBestMatch, getComponentFromPath, getComponentValue, findComponents, eachComponentDataAsync, eachComponentData, getComponentKey, getSharedPathKey, registerInstanceAtPath, resolveInstanceAtPath, getContextualRowPath, getContextualRowData, componentInfo, eachComponent, eachComponentAsync, getComponentData, getComponentActualValue, isLayoutComponent, matchComponent, getComponent, searchComponents, removeComponent, hasCondition, parseFloatExt, formatAsCurrency, escapeRegExCharacters, getValue, getStrings, generateFormChange, applyFormChanges, findComponent, getEmptyValue, isComponentDataEmpty, isSelectResourceWithObjectValue, compareSelectResourceWithObjectTypeValues, getItemTemplateKeys, } = core_1.Utils;
6
6
  exports.flattenComponents = flattenComponents;
7
7
  exports.guid = guid;
8
8
  exports.uniqueName = uniqueName;
@@ -22,6 +22,9 @@ exports.findComponents = findComponents;
22
22
  exports.eachComponentDataAsync = eachComponentDataAsync;
23
23
  exports.eachComponentData = eachComponentData;
24
24
  exports.getComponentKey = getComponentKey;
25
+ exports.getSharedPathKey = getSharedPathKey;
26
+ exports.registerInstanceAtPath = registerInstanceAtPath;
27
+ exports.resolveInstanceAtPath = resolveInstanceAtPath;
25
28
  exports.getContextualRowPath = getContextualRowPath;
26
29
  exports.getContextualRowData = getContextualRowData;
27
30
  exports.componentInfo = componentInfo;
@@ -40,6 +40,9 @@ declare const FormioUtils: {
40
40
  eachComponentDataAsync: (components: import("@formio/core").Component[], data: import("@formio/core").DataObject, fn: import("@formio/core").EachComponentDataAsyncCallback, includeAll?: boolean | undefined, local?: boolean | undefined, parent?: import("@formio/core").Component | undefined, parentPaths?: import("@formio/core").ComponentPaths | undefined, noScopeReset?: boolean | undefined, afterFn?: import("@formio/core").EachComponentDataAsyncCallback | undefined, localRoot?: import("@formio/core").LocalRoot | undefined) => Promise<void>;
41
41
  eachComponentData: (components: import("@formio/core").Component[], data: import("@formio/core").DataObject, fn: import("@formio/core").EachComponentDataCallback, includeAll?: boolean | undefined, local?: boolean | undefined, parent?: import("@formio/core").Component | undefined, parentPaths?: import("@formio/core").ComponentPaths | undefined, noScopeReset?: boolean | undefined, afterFn?: import("@formio/core").EachComponentDataCallback | undefined, localRoot?: import("@formio/core").LocalRoot | undefined) => void;
42
42
  getComponentKey: typeof import("@formio/core/lib/utils/formUtil").getComponentKey;
43
+ getSharedPathKey: typeof import("@formio/core/lib/utils/formUtil").getSharedPathKey;
44
+ registerInstanceAtPath: typeof import("@formio/core/lib/utils/formUtil").registerInstanceAtPath;
45
+ resolveInstanceAtPath: typeof import("@formio/core/lib/utils/formUtil").resolveInstanceAtPath;
43
46
  getContextualRowPath: any;
44
47
  getContextualRowData: typeof import("@formio/core/lib/utils/formUtil").getContextualRowData;
45
48
  componentInfo: typeof import("@formio/core/lib/utils/formUtil").componentInfo;
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.5.2';
17
+ static version = '5.6.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.5.2';
7
+ FormioCore.version = '5.6.1';
8
8
  CDN.defaultCDN = FormioCore.version.includes('rc')
9
9
  ? 'https://cdn.test-form.io'
10
10
  : 'https://cdn.form.io';
@@ -65,11 +65,7 @@ export default class Components {
65
65
  else {
66
66
  comp = new Component(component, options, data);
67
67
  }
68
- if (comp.path) {
69
- comp.eachRootChildComponentsMap((map) => {
70
- map[comp.path] = comp;
71
- });
72
- }
68
+ comp.registerComponentInstance();
73
69
  // Reset the componentMatches on the root element if any new component is created.
74
70
  let parent = comp.parent;
75
71
  while (parent) {
@@ -171,6 +171,20 @@ declare class Component extends Element {
171
171
  * @param {(map: object) => void} fn - Called once per root that exposes a `childComponentsMap`.
172
172
  */
173
173
  eachRootChildComponentsMap(fn: (map: object) => void): void;
174
+ /**
175
+ * Registers this instance in every root's `childComponentsMap`. Several components can resolve
176
+ * to one data path — see `getSharedPathKey` in `@formio/core` for the rule this follows.
177
+ * @returns {void}
178
+ */
179
+ registerComponentInstance(): void;
180
+ sharedPathKey: string | undefined;
181
+ /**
182
+ * Removes this instance from every root's `childComponentsMap`.
183
+ * @param {string} [path] - The path this instance was registered under, when it has since
184
+ * been re-keyed (a DataGrid row index change regenerates paths before unregistering).
185
+ * @returns {void}
186
+ */
187
+ unregisterComponentInstance(path?: string | undefined): void;
174
188
  /**
175
189
  * Returns if the parent should conditionally clear.
176
190
  *
@@ -437,6 +437,39 @@ export default class Component extends Element {
437
437
  currentRoot = currentRoot.root;
438
438
  }
439
439
  }
440
+ /**
441
+ * Registers this instance in every root's `childComponentsMap`. Several components can resolve
442
+ * to one data path — see `getSharedPathKey` in `@formio/core` for the rule this follows.
443
+ * @returns {void}
444
+ */
445
+ registerComponentInstance() {
446
+ const path = this.path;
447
+ if (!path) {
448
+ return;
449
+ }
450
+ // Recorded on every instance, not just the ones that lose the race for the path: it names
451
+ // this registration for `unregisterComponentInstance()`, which can run after `path` changed.
452
+ this.sharedPathKey = FormioUtils.getSharedPathKey(path, this.component.key);
453
+ this.eachRootChildComponentsMap((map) => {
454
+ FormioUtils.registerInstanceAtPath(map, path, this.component.key, this);
455
+ });
456
+ }
457
+ /**
458
+ * Removes this instance from every root's `childComponentsMap`.
459
+ * @param {string} [path] - The path this instance was registered under, when it has since
460
+ * been re-keyed (a DataGrid row index change regenerates paths before unregistering).
461
+ * @returns {void}
462
+ */
463
+ unregisterComponentInstance(path = this.path) {
464
+ this.eachRootChildComponentsMap((map) => {
465
+ if (map[path] === this) {
466
+ delete map[path];
467
+ }
468
+ if (this.sharedPathKey && map[this.sharedPathKey] === this) {
469
+ delete map[this.sharedPathKey];
470
+ }
471
+ });
472
+ }
440
473
  /**
441
474
  * Returns if the parent should conditionally clear.
442
475
  *
@@ -924,7 +957,7 @@ export default class Component extends Element {
924
957
  return '';
925
958
  }
926
959
  // Use _userInput: true to ignore translations from defaults
927
- if (text in enTranslation && params._userInput) {
960
+ if (this.i18next?.language === 'en' && text in enTranslation && params._userInput) {
928
961
  return text;
929
962
  }
930
963
  params.data = params.data || this.rootValue;
@@ -553,11 +553,7 @@ export default class NestedComponent extends Field {
553
553
  components = components || this.components;
554
554
  component.destroy(all);
555
555
  _.remove(components, { id: component.id });
556
- component.eachRootChildComponentsMap((map) => {
557
- if (map[component.path]) {
558
- delete map[component.path];
559
- }
560
- });
556
+ component.unregisterComponentInstance();
561
557
  }
562
558
  /**
563
559
  * Removes a component provided the API key of that component.
@@ -666,9 +662,11 @@ export default class NestedComponent extends Field {
666
662
  validationProcessor({ scope, data, row, instance, paths }, flags) {
667
663
  const { dirty } = flags;
668
664
  if (this.root && this.root.hasSubWizards && this.page !== this.root.page) {
669
- instance = this.componentsMap?.hasOwnProperty(paths.dataPath)
670
- ? this.componentsMap[paths.dataPath]
671
- : this.getComponent(paths.dataPath);
665
+ // `instance` was resolved by @formio/core against this very map, shared-path rule and
666
+ // all, so only fill in what that lookup cannot reach: components keyed by their data
667
+ // path where core looked under a full path, and components absent from the map.
668
+ instance =
669
+ instance || this.componentsMap?.[paths.dataPath] || this.getComponent(paths.dataPath);
672
670
  }
673
671
  if (!instance) {
674
672
  return;
@@ -414,8 +414,12 @@ export default class AddressComponent extends ContainerComponent {
414
414
  this.searchInput.forEach((element, index) => {
415
415
  if (!this.builderMode && element && this.provider) {
416
416
  if (this.component.provider === 'google') {
417
+ if (this.component.enableNewPlacesApi) {
418
+ this.provider.options.version = 'newPlacesApi';
419
+ }
417
420
  this.googlePlacesCleanups = [];
418
- this.provider.attachAutocomplete(element, index, this.onSelectAddress.bind(this))
421
+ this.provider
422
+ .attachAutocomplete(element, index, this.onSelectAddress.bind(this), this.disabled)
419
423
  .then((cleanup) => {
420
424
  if (typeof cleanup === 'function') {
421
425
  this.googlePlacesCleanups.push(cleanup);
@@ -516,7 +520,6 @@ export default class AddressComponent extends ContainerComponent {
516
520
  if (this.autocompleterWidget && typeof this.autocompleterWidget.destroy === 'function') {
517
521
  this.autocompleterWidget.destroy();
518
522
  }
519
- ;
520
523
  (this.googlePlacesCleanups || []).forEach((cleanup) => {
521
524
  cleanup();
522
525
  });
@@ -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;
@@ -136,6 +136,19 @@ export default [
136
136
  },
137
137
  },
138
138
  },
139
+ {
140
+ weight: 10,
141
+ type: 'checkbox',
142
+ input: true,
143
+ key: 'enableNewPlacesApi',
144
+ label: 'Places API (New)',
145
+ tooltip: 'Enable the new Google Places API instead of the legacy version.',
146
+ conditional: {
147
+ json: {
148
+ '===': [{ var: 'data.provider' }, 'google'],
149
+ },
150
+ },
151
+ },
139
152
  {
140
153
  type: 'textarea',
141
154
  input: true,
@@ -430,12 +430,8 @@ export default class DataGridComponent extends NestedArrayComponent {
430
430
  component.rowIndex = rowIndex;
431
431
  component.row = `${rowIndex}-${colIndex}`;
432
432
  entries.forEach(({ instance, oldPath }) => {
433
- instance.eachRootChildComponentsMap((map) => {
434
- if (map[oldPath] === instance) {
435
- delete map[oldPath];
436
- }
437
- map[instance.paths.dataPath] = instance;
438
- });
433
+ instance.unregisterComponentInstance(oldPath);
434
+ instance.registerComponentInstance();
439
435
  });
440
436
  });
441
437
  }
@@ -539,10 +535,11 @@ export default class DataGridComponent extends NestedArrayComponent {
539
535
  }, modified);
540
536
  this.triggerRootChange(flags, changed, modified);
541
537
  }
538
+ const rowData = this.dataValue[rowIndex];
542
539
  this.processRow('checkData', null, {
543
540
  ...flags,
544
541
  changed,
545
- }, row, _.toArray(this.rows[rowIndex]));
542
+ }, rowData, _.toArray(this.rows[rowIndex]));
546
543
  };
547
544
  let columnComponent;
548
545
  if (this.builderMode) {
@@ -92,6 +92,11 @@ export default class FileComponent extends Field {
92
92
  this.abortUploads = [];
93
93
  this.pendingfiles = [];
94
94
  this.resolvedFiles = [];
95
+ const imageSize = Number(this.component.imageSize);
96
+ const isValidImageSize = imageSize > 0;
97
+ if (!isValidImageSize) {
98
+ this.component.imageSize = '200';
99
+ }
95
100
  }
96
101
  get dataReady() {
97
102
  return this.filesReady || Promise.resolve();
@@ -635,7 +640,7 @@ export default class FileComponent extends Field {
635
640
  fileKey: this.component.fileKey || 'file',
636
641
  storage: this.component.storage,
637
642
  options: this.component.storage === 'url'
638
- ? (this.component.urlRequestOptions || this.component.options)
643
+ ? this.component.urlRequestOptions || this.component.options
639
644
  : this.component.options,
640
645
  file,
641
646
  size: file.size,
@@ -668,7 +673,9 @@ export default class FileComponent extends Field {
668
673
  return fileWithSameNameUploaded || fileWithSameNameUploading
669
674
  ? {
670
675
  status: 'error',
671
- message: this.t(fileWithSameNameUploading ? 'fileWithDuplicatedNameInProgress' : 'fileWithDuplicatedNameLoaded'),
676
+ message: this.t(fileWithSameNameUploading
677
+ ? 'fileWithDuplicatedNameInProgress'
678
+ : 'fileWithDuplicatedNameLoaded'),
672
679
  }
673
680
  : {};
674
681
  }
@@ -866,8 +873,8 @@ export default class FileComponent extends Field {
866
873
  }
867
874
  async deleteFile(fileInfo) {
868
875
  const options = this.component.storage === 'url'
869
- ? (this.component.urlRequestOptions || this.component.options || {})
870
- : (this.component.options || {});
876
+ ? this.component.urlRequestOptions || this.component.options || {}
877
+ : this.component.options || {};
871
878
  if (fileInfo &&
872
879
  ['url', 'indexeddb', 's3', 'azure', 'googledrive'].includes(this.component.storage)) {
873
880
  const { fileService } = this;
@@ -1006,7 +1013,7 @@ export default class FileComponent extends Field {
1006
1013
  delete fileToSync.progress;
1007
1014
  this.redraw();
1008
1015
  if (fileInfo) {
1009
- const fileExists = this.resolvedFiles.find(x => x.fileInfo.originalName === fileToSync.originalName);
1016
+ const fileExists = this.resolvedFiles.find((x) => x.fileInfo.originalName === fileToSync.originalName);
1010
1017
  if (!fileExists && fileToSync.status !== 'error') {
1011
1018
  this.resolvedFiles.push({ fileToSync, fileInfo });
1012
1019
  }
@@ -1060,8 +1067,8 @@ export default class FileComponent extends Field {
1060
1067
  }
1061
1068
  getFile(fileInfo) {
1062
1069
  const options = this.component.storage === 'url'
1063
- ? (this.component.urlRequestOptions || this.component.options || {})
1064
- : (this.component.options || {});
1070
+ ? this.component.urlRequestOptions || this.component.options || {}
1071
+ : this.component.options || {};
1065
1072
  const { fileService } = this;
1066
1073
  if (!fileService) {
1067
1074
  return alert(this.t('noFileService'));
@@ -1101,7 +1108,9 @@ export default class FileComponent extends Field {
1101
1108
  return Promise.resolve();
1102
1109
  }
1103
1110
  await this.syncFiles();
1104
- return this.shouldSyncFiles ? Promise.reject(this.t('synchronizationFailed')) : Promise.resolve();
1111
+ return this.shouldSyncFiles
1112
+ ? Promise.reject(this.t('synchronizationFailed'))
1113
+ : Promise.resolve();
1105
1114
  }
1106
1115
  catch (error) {
1107
1116
  return Promise.reject(error.message);