@elementor/editor-components 4.3.0-1034 → 4.3.0-1035

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elementor/editor-components",
3
3
  "description": "Elementor editor components",
4
- "version": "4.3.0-1034",
4
+ "version": "4.3.0-1035",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -40,31 +40,31 @@
40
40
  "dev": "tsup --config=../../tsup.dev.ts"
41
41
  },
42
42
  "dependencies": {
43
- "@elementor/editor": "4.3.0-1034",
44
- "@elementor/editor-canvas": "4.3.0-1034",
45
- "@elementor/editor-controls": "4.3.0-1034",
46
- "@elementor/editor-documents": "4.3.0-1034",
47
- "@elementor/editor-editing-panel": "4.3.0-1034",
48
- "@elementor/editor-elements": "4.3.0-1034",
49
- "@elementor/editor-elements-panel": "4.3.0-1034",
50
- "@elementor/editor-mcp": "4.3.0-1034",
51
- "@elementor/editor-templates": "4.3.0-1034",
52
- "@elementor/editor-panels": "4.3.0-1034",
53
- "@elementor/editor-props": "4.3.0-1034",
54
- "@elementor/editor-ui": "4.3.0-1034",
55
- "@elementor/editor-v1-adapters": "4.3.0-1034",
56
- "@elementor/http-client": "4.3.0-1034",
43
+ "@elementor/editor": "4.3.0-1035",
44
+ "@elementor/editor-canvas": "4.3.0-1035",
45
+ "@elementor/editor-controls": "4.3.0-1035",
46
+ "@elementor/editor-documents": "4.3.0-1035",
47
+ "@elementor/editor-editing-panel": "4.3.0-1035",
48
+ "@elementor/editor-elements": "4.3.0-1035",
49
+ "@elementor/editor-elements-panel": "4.3.0-1035",
50
+ "@elementor/editor-mcp": "4.3.0-1035",
51
+ "@elementor/editor-templates": "4.3.0-1035",
52
+ "@elementor/editor-panels": "4.3.0-1035",
53
+ "@elementor/editor-props": "4.3.0-1035",
54
+ "@elementor/editor-ui": "4.3.0-1035",
55
+ "@elementor/editor-v1-adapters": "4.3.0-1035",
56
+ "@elementor/http-client": "4.3.0-1035",
57
57
  "@elementor/icons": "~1.75.1",
58
- "@elementor/events": "4.3.0-1034",
59
- "@elementor/query": "4.3.0-1034",
60
- "@elementor/schema": "4.3.0-1034",
61
- "@elementor/store": "4.3.0-1034",
58
+ "@elementor/events": "4.3.0-1035",
59
+ "@elementor/query": "4.3.0-1035",
60
+ "@elementor/schema": "4.3.0-1035",
61
+ "@elementor/store": "4.3.0-1035",
62
62
  "@elementor/ui": "1.37.5",
63
- "@elementor/utils": "4.3.0-1034",
63
+ "@elementor/utils": "4.3.0-1035",
64
64
  "@wordpress/i18n": "^5.13.0",
65
- "@elementor/editor-notifications": "4.3.0-1034",
66
- "@elementor/editor-current-user": "4.3.0-1034",
67
- "@elementor/editor-embedded-documents-manager": "4.3.0-1034"
65
+ "@elementor/editor-notifications": "4.3.0-1035",
66
+ "@elementor/editor-current-user": "4.3.0-1035",
67
+ "@elementor/editor-embedded-documents-manager": "4.3.0-1035"
68
68
  },
69
69
  "peerDependencies": {
70
70
  "react": "^18.3.1",
@@ -26,6 +26,7 @@ import { type ComponentRenderContext, type ExtendedWindow } from './types';
26
26
  import { detachComponentInstance } from './utils/detach-component-instance';
27
27
  import { formatComponentElementsId } from './utils/format-component-elements-id';
28
28
  import { isProComponentsSupported, isProOutdatedForComponents } from './utils/is-pro-components-supported';
29
+ import { reconcileComponentInstanceElements } from './utils/reconcile-component-instance-elements';
29
30
  import { switchToComponent } from './utils/switch-to-component';
30
31
  import { trackComponentEvent } from './utils/tracking';
31
32
 
@@ -219,7 +220,11 @@ function createComponentView( options: ComponentTypeOptions ): typeof TemplatedE
219
220
 
220
221
  const instanceId = this.model.get( 'id' );
221
222
  const elements = componentInstance.elements ?? [];
222
- const formattedElements = formatComponentElementsId( elements, [ instanceId ] );
223
+ const reconciledElements = reconcileComponentInstanceElements(
224
+ elements,
225
+ componentInstance.overrides ?? {}
226
+ );
227
+ const formattedElements = formatComponentElementsId( reconciledElements, [ instanceId ] );
223
228
 
224
229
  this.collection = legacyWindow.elementor.createBackboneElementsCollection( formattedElements );
225
230
 
@@ -0,0 +1,108 @@
1
+ import {
2
+ getWidgetsCache,
3
+ reconcileInitialChildren,
4
+ type V1ElementConfig,
5
+ type V1ElementData,
6
+ type V1ElementSettingsProps,
7
+ } from '@elementor/editor-elements';
8
+ import { type AnyTransformable } from '@elementor/editor-props';
9
+ import { hashString } from '@elementor/utils';
10
+
11
+ import {
12
+ applyOverridesToSettings,
13
+ type ElementSettings,
14
+ type OverridesMapping,
15
+ unwrapOverridableSettings,
16
+ } from '../components/instance-editing-panel/utils/resolve-element-settings';
17
+
18
+ const ELEMENT_ID_LENGTH = 7;
19
+
20
+ function overridesRecordToMapping( overrides: Record< string, unknown > ): OverridesMapping {
21
+ const mapping: OverridesMapping = {};
22
+
23
+ for ( const [ key, value ] of Object.entries( overrides ) ) {
24
+ mapping[ key ] = { value: value as AnyTransformable };
25
+ }
26
+
27
+ return mapping;
28
+ }
29
+
30
+ function getElementConfig( element: V1ElementData ): V1ElementConfig | undefined {
31
+ const type = element.elType === 'widget' ? element.widgetType : element.elType;
32
+
33
+ if ( ! type ) {
34
+ return undefined;
35
+ }
36
+
37
+ return getWidgetsCache()?.[ type ];
38
+ }
39
+
40
+ /**
41
+ * Children inserted by dependency rules come from static `default_model` config, so
42
+ * `reconcileInitialChildren` gives them random ids. Replace them with ids derived from the
43
+ * parent id and the position in the subtree, so the instance-scoped hashing applied later by
44
+ * `formatComponentElementsId` is stable across renders. Keep in sync with `derive_ids()` in
45
+ * `modules/components/utils/reconcile-component-instance-elements.php`.
46
+ *
47
+ * Instance children are not directly editable, so overwriting the ids of a model that
48
+ * `reconcileInitialChildren` restored from the stash is safe and keeps the canvas aligned
49
+ * with the render, which has no stash to restore from.
50
+ *
51
+ * @param element The inserted element to assign ids to, recursively.
52
+ * @param seed Stable string the element's id is hashed from.
53
+ */
54
+ function deriveIds( element: V1ElementData, seed: string ): V1ElementData {
55
+ const id = hashString( seed, ELEMENT_ID_LENGTH );
56
+
57
+ return {
58
+ ...element,
59
+ id,
60
+ elements: ( element.elements ?? [] ).map( ( child, index ) => deriveIds( child, `${ id }_${ index }` ) ),
61
+ };
62
+ }
63
+
64
+ function reconcileElementTree( element: V1ElementData, overridesMapping: OverridesMapping ): V1ElementData {
65
+ const elementConfig = getElementConfig( element );
66
+ const withOverrides = applyOverridesToSettings( ( element.settings ?? {} ) as ElementSettings, overridesMapping );
67
+ const effectiveSettings = unwrapOverridableSettings( withOverrides ) as V1ElementSettingsProps;
68
+
69
+ const originalChildren = element.elements ?? [];
70
+ const originalChildIds = new Set( originalChildren.map( ( child ) => child.id ) );
71
+
72
+ const attributes: {
73
+ elements?: V1ElementData[];
74
+ settings?: V1ElementSettingsProps;
75
+ } = {
76
+ elements: [ ...originalChildren ],
77
+ settings: effectiveSettings,
78
+ };
79
+
80
+ if ( elementConfig?.children_dependencies?.length ) {
81
+ reconcileInitialChildren( {
82
+ elementId: element.id,
83
+ elementConfig,
84
+ attributes,
85
+ } );
86
+ }
87
+
88
+ const reconciledChildren = ( attributes.elements ?? [] )
89
+ .map( ( child ) =>
90
+ originalChildIds.has( child.id ) ? child : deriveIds( child, `${ element.id }_${ child.elType }` )
91
+ )
92
+ .map( ( child ) => reconcileElementTree( child, overridesMapping ) );
93
+
94
+ return {
95
+ ...element,
96
+ settings: effectiveSettings,
97
+ elements: reconciledChildren,
98
+ };
99
+ }
100
+
101
+ export function reconcileComponentInstanceElements(
102
+ elements: V1ElementData[],
103
+ overrides: Record< string, unknown > = {}
104
+ ): V1ElementData[] {
105
+ const overridesMapping = overridesRecordToMapping( overrides );
106
+
107
+ return elements.map( ( element ) => reconcileElementTree( element, overridesMapping ) );
108
+ }