@elementor/editor-components 4.3.0-998 → 4.4.0-1064
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/dist/index.js +110 -43
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +79 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +23 -23
- package/src/create-component-type.ts +6 -1
- package/src/utils/component-document-data.ts +25 -8
- package/src/utils/reconcile-component-instance-elements.ts +107 -0
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.
|
|
4
|
+
"version": "4.4.0-1064",
|
|
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.
|
|
44
|
-
"@elementor/editor-canvas": "4.
|
|
45
|
-
"@elementor/editor-controls": "4.
|
|
46
|
-
"@elementor/editor-documents": "4.
|
|
47
|
-
"@elementor/editor-editing-panel": "4.
|
|
48
|
-
"@elementor/editor-elements": "4.
|
|
49
|
-
"@elementor/editor-elements-panel": "4.
|
|
50
|
-
"@elementor/editor-mcp": "4.
|
|
51
|
-
"@elementor/editor-templates": "4.
|
|
52
|
-
"@elementor/editor-panels": "4.
|
|
53
|
-
"@elementor/editor-props": "4.
|
|
54
|
-
"@elementor/editor-ui": "4.
|
|
55
|
-
"@elementor/editor-v1-adapters": "4.
|
|
56
|
-
"@elementor/http-client": "4.
|
|
43
|
+
"@elementor/editor": "4.4.0-1064",
|
|
44
|
+
"@elementor/editor-canvas": "4.4.0-1064",
|
|
45
|
+
"@elementor/editor-controls": "4.4.0-1064",
|
|
46
|
+
"@elementor/editor-documents": "4.4.0-1064",
|
|
47
|
+
"@elementor/editor-editing-panel": "4.4.0-1064",
|
|
48
|
+
"@elementor/editor-elements": "4.4.0-1064",
|
|
49
|
+
"@elementor/editor-elements-panel": "4.4.0-1064",
|
|
50
|
+
"@elementor/editor-mcp": "4.4.0-1064",
|
|
51
|
+
"@elementor/editor-templates": "4.4.0-1064",
|
|
52
|
+
"@elementor/editor-panels": "4.4.0-1064",
|
|
53
|
+
"@elementor/editor-props": "4.4.0-1064",
|
|
54
|
+
"@elementor/editor-ui": "4.4.0-1064",
|
|
55
|
+
"@elementor/editor-v1-adapters": "4.4.0-1064",
|
|
56
|
+
"@elementor/http-client": "4.4.0-1064",
|
|
57
57
|
"@elementor/icons": "~1.75.1",
|
|
58
|
-
"@elementor/events": "4.
|
|
59
|
-
"@elementor/query": "4.
|
|
60
|
-
"@elementor/schema": "4.
|
|
61
|
-
"@elementor/store": "4.
|
|
58
|
+
"@elementor/events": "4.4.0-1064",
|
|
59
|
+
"@elementor/query": "4.4.0-1064",
|
|
60
|
+
"@elementor/schema": "4.4.0-1064",
|
|
61
|
+
"@elementor/store": "4.4.0-1064",
|
|
62
62
|
"@elementor/ui": "1.37.5",
|
|
63
|
-
"@elementor/utils": "4.
|
|
63
|
+
"@elementor/utils": "4.4.0-1064",
|
|
64
64
|
"@wordpress/i18n": "^5.13.0",
|
|
65
|
-
"@elementor/editor-notifications": "4.
|
|
66
|
-
"@elementor/editor-current-user": "4.
|
|
67
|
-
"@elementor/editor-embedded-documents-manager": "4.
|
|
65
|
+
"@elementor/editor-notifications": "4.4.0-1064",
|
|
66
|
+
"@elementor/editor-current-user": "4.4.0-1064",
|
|
67
|
+
"@elementor/editor-embedded-documents-manager": "4.4.0-1064"
|
|
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
|
|
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
|
|
|
@@ -1,13 +1,30 @@
|
|
|
1
|
-
import { type Document
|
|
1
|
+
import { type Document } from '@elementor/editor-documents';
|
|
2
|
+
import { ajax } from '@elementor/editor-v1-adapters';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
// Mirrors the v1 documents manager request args so both share one ajax cache entry, keeping
|
|
5
|
+
// `elementor.documents.invalidateCache()` effective. Unlike the manager, this omits `immediately`,
|
|
6
|
+
// so component fetches triggered together merge into a single batched request.
|
|
7
|
+
const getComponentDocumentParams = ( id: number ) => ( {
|
|
8
|
+
action: 'get_document_config',
|
|
9
|
+
unique_id: `document-${ id }`,
|
|
10
|
+
data: { id },
|
|
11
|
+
} );
|
|
4
12
|
|
|
5
|
-
|
|
6
|
-
const documentManager = getV1DocumentsManager();
|
|
13
|
+
const pendingRequests = new Map< number, Promise< Document | null > >();
|
|
7
14
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
export const getComponentDocumentData = ( id: number ): Promise< Document | null > => {
|
|
16
|
+
const pendingRequest = pendingRequests.get( id );
|
|
17
|
+
|
|
18
|
+
if ( pendingRequest ) {
|
|
19
|
+
return pendingRequest;
|
|
12
20
|
}
|
|
21
|
+
|
|
22
|
+
const request = ajax
|
|
23
|
+
.load< { id: number }, Document >( getComponentDocumentParams( id ) )
|
|
24
|
+
.catch( () => null )
|
|
25
|
+
.finally( () => pendingRequests.delete( id ) );
|
|
26
|
+
|
|
27
|
+
pendingRequests.set( id, request );
|
|
28
|
+
|
|
29
|
+
return request;
|
|
13
30
|
};
|
|
@@ -0,0 +1,107 @@
|
|
|
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
|
+
elements: reconciledChildren,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function reconcileComponentInstanceElements(
|
|
101
|
+
elements: V1ElementData[],
|
|
102
|
+
overrides: Record< string, unknown > = {}
|
|
103
|
+
): V1ElementData[] {
|
|
104
|
+
const overridesMapping = overridesRecordToMapping( overrides );
|
|
105
|
+
|
|
106
|
+
return elements.map( ( element ) => reconcileElementTree( element, overridesMapping ) );
|
|
107
|
+
}
|