@elementor/editor-canvas 4.4.0-1112 → 4.4.0-1114
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
CHANGED
|
@@ -2835,14 +2835,17 @@ function isRecord(value) {
|
|
|
2835
2835
|
var import_editor_elements5 = require("@elementor/editor-elements");
|
|
2836
2836
|
function createPendingElement(wrapperView, data, options = {}) {
|
|
2837
2837
|
const parentContainer = wrapperView.getContainer();
|
|
2838
|
-
const model = { ...data };
|
|
2839
|
-
if (!model.id) {
|
|
2838
|
+
const model = options.clone ? (0, import_editor_elements5.cloneElementTree)(data) : { ...data };
|
|
2839
|
+
if (!options.clone && !model.id) {
|
|
2840
2840
|
model.id = (0, import_editor_elements5.generateElementId)();
|
|
2841
2841
|
}
|
|
2842
2842
|
if (!model.elements) {
|
|
2843
2843
|
model.elements = [];
|
|
2844
2844
|
}
|
|
2845
|
-
const added = (0, import_editor_elements5.addModelToParent)(parentContainer.id, model,
|
|
2845
|
+
const added = (0, import_editor_elements5.addModelToParent)(parentContainer.id, model, {
|
|
2846
|
+
...options,
|
|
2847
|
+
clone: false
|
|
2848
|
+
});
|
|
2846
2849
|
if (!added) {
|
|
2847
2850
|
return void 0;
|
|
2848
2851
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -2791,20 +2791,24 @@ function isRecord(value) {
|
|
|
2791
2791
|
// src/legacy/create-pending-element.ts
|
|
2792
2792
|
import {
|
|
2793
2793
|
addModelToParent,
|
|
2794
|
+
cloneElementTree,
|
|
2794
2795
|
findModelInDocument,
|
|
2795
2796
|
generateElementId,
|
|
2796
2797
|
getContainer
|
|
2797
2798
|
} from "@elementor/editor-elements";
|
|
2798
2799
|
function createPendingElement(wrapperView, data, options = {}) {
|
|
2799
2800
|
const parentContainer = wrapperView.getContainer();
|
|
2800
|
-
const model = { ...data };
|
|
2801
|
-
if (!model.id) {
|
|
2801
|
+
const model = options.clone ? cloneElementTree(data) : { ...data };
|
|
2802
|
+
if (!options.clone && !model.id) {
|
|
2802
2803
|
model.id = generateElementId();
|
|
2803
2804
|
}
|
|
2804
2805
|
if (!model.elements) {
|
|
2805
2806
|
model.elements = [];
|
|
2806
2807
|
}
|
|
2807
|
-
const added = addModelToParent(parentContainer.id, model,
|
|
2808
|
+
const added = addModelToParent(parentContainer.id, model, {
|
|
2809
|
+
...options,
|
|
2810
|
+
clone: false
|
|
2811
|
+
});
|
|
2808
2812
|
if (!added) {
|
|
2809
2813
|
return void 0;
|
|
2810
2814
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-canvas",
|
|
3
3
|
"description": "Elementor Editor Canvas",
|
|
4
|
-
"version": "4.4.0-
|
|
4
|
+
"version": "4.4.0-1114",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -37,26 +37,26 @@
|
|
|
37
37
|
"react-dom": "^18.3.1"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@elementor/editor": "4.4.0-
|
|
41
|
-
"@elementor/editor-controls": "4.4.0-
|
|
42
|
-
"@elementor/editor-documents": "4.4.0-
|
|
43
|
-
"@elementor/editor-elements": "4.4.0-
|
|
44
|
-
"@elementor/editor-interactions": "4.4.0-
|
|
45
|
-
"@elementor/editor-mcp": "4.4.0-
|
|
46
|
-
"@elementor/editor-notifications": "4.4.0-
|
|
47
|
-
"@elementor/editor-props": "4.4.0-
|
|
48
|
-
"@elementor/editor-responsive": "4.4.0-
|
|
49
|
-
"@elementor/editor-styles": "4.4.0-
|
|
50
|
-
"@elementor/editor-styles-repository": "4.4.0-
|
|
51
|
-
"@elementor/editor-ui": "4.4.0-
|
|
52
|
-
"@elementor/editor-v1-adapters": "4.4.0-
|
|
53
|
-
"@elementor/events": "4.4.0-
|
|
54
|
-
"@elementor/http-client": "4.4.0-
|
|
55
|
-
"@elementor/schema": "4.4.0-
|
|
56
|
-
"@elementor/twing": "4.4.0-
|
|
40
|
+
"@elementor/editor": "4.4.0-1114",
|
|
41
|
+
"@elementor/editor-controls": "4.4.0-1114",
|
|
42
|
+
"@elementor/editor-documents": "4.4.0-1114",
|
|
43
|
+
"@elementor/editor-elements": "4.4.0-1114",
|
|
44
|
+
"@elementor/editor-interactions": "4.4.0-1114",
|
|
45
|
+
"@elementor/editor-mcp": "4.4.0-1114",
|
|
46
|
+
"@elementor/editor-notifications": "4.4.0-1114",
|
|
47
|
+
"@elementor/editor-props": "4.4.0-1114",
|
|
48
|
+
"@elementor/editor-responsive": "4.4.0-1114",
|
|
49
|
+
"@elementor/editor-styles": "4.4.0-1114",
|
|
50
|
+
"@elementor/editor-styles-repository": "4.4.0-1114",
|
|
51
|
+
"@elementor/editor-ui": "4.4.0-1114",
|
|
52
|
+
"@elementor/editor-v1-adapters": "4.4.0-1114",
|
|
53
|
+
"@elementor/events": "4.4.0-1114",
|
|
54
|
+
"@elementor/http-client": "4.4.0-1114",
|
|
55
|
+
"@elementor/schema": "4.4.0-1114",
|
|
56
|
+
"@elementor/twing": "4.4.0-1114",
|
|
57
57
|
"@elementor/ui": "1.37.5",
|
|
58
|
-
"@elementor/utils": "4.4.0-
|
|
59
|
-
"@elementor/wp-media": "4.4.0-
|
|
58
|
+
"@elementor/utils": "4.4.0-1114",
|
|
59
|
+
"@elementor/wp-media": "4.4.0-1114",
|
|
60
60
|
"@floating-ui/react": "^0.27.5",
|
|
61
61
|
"@wordpress/i18n": "^5.13.0",
|
|
62
62
|
"dompurify": "^3.2.6"
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { createMockElement } from 'test-utils';
|
|
2
|
+
import { addModelToParent, findModelInDocument, type V1ElementModelProps } from '@elementor/editor-elements';
|
|
3
|
+
|
|
4
|
+
import { createPendingElement } from '../create-pending-element';
|
|
5
|
+
import { type ElementView } from '../types';
|
|
6
|
+
|
|
7
|
+
jest.mock( '@elementor/editor-elements', () => ( {
|
|
8
|
+
...jest.requireActual( '@elementor/editor-elements' ),
|
|
9
|
+
addModelToParent: jest.fn(),
|
|
10
|
+
findModelInDocument: jest.fn(),
|
|
11
|
+
getContainer: jest.fn(),
|
|
12
|
+
} ) );
|
|
13
|
+
|
|
14
|
+
const mockAddModelToParent = jest.mocked( addModelToParent );
|
|
15
|
+
const mockFindModelInDocument = jest.mocked( findModelInDocument );
|
|
16
|
+
|
|
17
|
+
describe( 'createPendingElement', () => {
|
|
18
|
+
beforeEach( () => {
|
|
19
|
+
(
|
|
20
|
+
window as typeof window & {
|
|
21
|
+
elementorCommon?: { helpers?: { getUniqueId?: jest.Mock } };
|
|
22
|
+
}
|
|
23
|
+
).elementorCommon = {
|
|
24
|
+
helpers: {
|
|
25
|
+
getUniqueId: jest
|
|
26
|
+
.fn()
|
|
27
|
+
.mockReturnValueOnce( 'cloned-parent-id' )
|
|
28
|
+
.mockReturnValueOnce( 'cloned-child-id' ),
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
mockAddModelToParent.mockClear();
|
|
33
|
+
mockFindModelInDocument.mockClear();
|
|
34
|
+
mockAddModelToParent.mockReturnValue( true );
|
|
35
|
+
mockFindModelInDocument.mockReturnValue( createMockElement( {} ) as never );
|
|
36
|
+
} );
|
|
37
|
+
|
|
38
|
+
afterEach( () => {
|
|
39
|
+
delete ( window as typeof window & { elementorCommon?: unknown } ).elementorCommon;
|
|
40
|
+
} );
|
|
41
|
+
|
|
42
|
+
it( 'regenerates ids before pending clone insertion', () => {
|
|
43
|
+
// Arrange.
|
|
44
|
+
const wrapperView = {
|
|
45
|
+
getContainer: () => ( { id: 'parent-id' } ),
|
|
46
|
+
once: jest.fn(),
|
|
47
|
+
model: {
|
|
48
|
+
trigger: jest.fn(),
|
|
49
|
+
},
|
|
50
|
+
} as unknown as ElementView;
|
|
51
|
+
|
|
52
|
+
const source = {
|
|
53
|
+
id: 'original-parent-id',
|
|
54
|
+
elType: 'container',
|
|
55
|
+
settings: { _element_id: 'original-parent-element-id' },
|
|
56
|
+
elements: [
|
|
57
|
+
{
|
|
58
|
+
id: 'original-child-id',
|
|
59
|
+
elType: 'widget',
|
|
60
|
+
widgetType: 'button',
|
|
61
|
+
settings: { _element_id: 'original-child-element-id' },
|
|
62
|
+
elements: [],
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
} as unknown as Partial< V1ElementModelProps >;
|
|
66
|
+
|
|
67
|
+
// Act.
|
|
68
|
+
const pendingElement = createPendingElement( wrapperView, source, { clone: true } );
|
|
69
|
+
|
|
70
|
+
// Assert.
|
|
71
|
+
expect( pendingElement?.getContainer().id ).toBe( 'cloned-parent-id' );
|
|
72
|
+
expect( mockAddModelToParent ).toHaveBeenCalledWith(
|
|
73
|
+
'parent-id',
|
|
74
|
+
expect.objectContaining( {
|
|
75
|
+
id: 'cloned-parent-id',
|
|
76
|
+
settings: expect.objectContaining( { _element_id: '' } ),
|
|
77
|
+
elements: [
|
|
78
|
+
expect.objectContaining( {
|
|
79
|
+
id: 'cloned-child-id',
|
|
80
|
+
settings: expect.objectContaining( { _element_id: '' } ),
|
|
81
|
+
} ),
|
|
82
|
+
],
|
|
83
|
+
} ),
|
|
84
|
+
expect.objectContaining( {
|
|
85
|
+
clone: false,
|
|
86
|
+
} )
|
|
87
|
+
);
|
|
88
|
+
expect( mockFindModelInDocument ).toHaveBeenCalledWith( 'cloned-parent-id' );
|
|
89
|
+
} );
|
|
90
|
+
|
|
91
|
+
it( 'preserves the source id when clone is false', () => {
|
|
92
|
+
// Arrange.
|
|
93
|
+
const wrapperView = {
|
|
94
|
+
getContainer: () => ( { id: 'parent-id' } ),
|
|
95
|
+
once: jest.fn(),
|
|
96
|
+
model: {
|
|
97
|
+
trigger: jest.fn(),
|
|
98
|
+
},
|
|
99
|
+
} as unknown as ElementView;
|
|
100
|
+
|
|
101
|
+
const source = {
|
|
102
|
+
id: 'original-parent-id',
|
|
103
|
+
elType: 'widget',
|
|
104
|
+
widgetType: 'button',
|
|
105
|
+
settings: { _element_id: 'original-parent-element-id' },
|
|
106
|
+
elements: [],
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// Act.
|
|
110
|
+
const pendingElement = createPendingElement( wrapperView, source, { clone: false } );
|
|
111
|
+
|
|
112
|
+
// Assert.
|
|
113
|
+
expect( pendingElement?.getContainer().id ).toBe( 'original-parent-id' );
|
|
114
|
+
expect( mockAddModelToParent ).toHaveBeenCalledWith(
|
|
115
|
+
'parent-id',
|
|
116
|
+
expect.objectContaining( {
|
|
117
|
+
id: 'original-parent-id',
|
|
118
|
+
settings: expect.objectContaining( {
|
|
119
|
+
_element_id: 'original-parent-element-id',
|
|
120
|
+
} ),
|
|
121
|
+
} ),
|
|
122
|
+
expect.objectContaining( {
|
|
123
|
+
clone: false,
|
|
124
|
+
} )
|
|
125
|
+
);
|
|
126
|
+
expect( mockFindModelInDocument ).toHaveBeenCalledWith( 'original-parent-id' );
|
|
127
|
+
} );
|
|
128
|
+
} );
|
|
@@ -422,7 +422,7 @@ export function createNestedTemplatedElementView( {
|
|
|
422
422
|
this._doAfterRender( () => parentOpenEditingPanel.call( this, options ) );
|
|
423
423
|
},
|
|
424
424
|
|
|
425
|
-
addElement( data: Partial< V1ElementModelProps >, options?: { edit?: boolean; at?: number } ) {
|
|
425
|
+
addElement( data: Partial< V1ElementModelProps >, options?: { edit?: boolean; at?: number; clone?: boolean } ) {
|
|
426
426
|
if ( this.isRendered ) {
|
|
427
427
|
return parentAddElement.call( this, data, options );
|
|
428
428
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
addModelToParent,
|
|
3
|
+
cloneElementTree,
|
|
3
4
|
findModelInDocument,
|
|
4
5
|
generateElementId,
|
|
5
6
|
getContainer,
|
|
@@ -12,12 +13,12 @@ import { type ElementView } from './types';
|
|
|
12
13
|
export function createPendingElement(
|
|
13
14
|
wrapperView: ElementView,
|
|
14
15
|
data: Partial< V1ElementModelProps >,
|
|
15
|
-
options: { edit?: boolean; at?: number } = {}
|
|
16
|
+
options: { edit?: boolean; at?: number; clone?: boolean } = {}
|
|
16
17
|
): { getContainer: () => V1Element } | undefined {
|
|
17
18
|
const parentContainer = wrapperView.getContainer();
|
|
18
|
-
const model: Partial< V1ElementModelProps > = { ...data };
|
|
19
|
+
const model: Partial< V1ElementModelProps > = options.clone ? cloneElementTree( data ) : { ...data };
|
|
19
20
|
|
|
20
|
-
if ( ! model.id ) {
|
|
21
|
+
if ( ! options.clone && ! model.id ) {
|
|
21
22
|
model.id = generateElementId();
|
|
22
23
|
}
|
|
23
24
|
|
|
@@ -25,13 +26,16 @@ export function createPendingElement(
|
|
|
25
26
|
model.elements = [];
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
const added = addModelToParent( parentContainer.id, model as V1ElementModelProps,
|
|
29
|
+
const added = addModelToParent( parentContainer.id, model as V1ElementModelProps, {
|
|
30
|
+
...options,
|
|
31
|
+
clone: false,
|
|
32
|
+
} );
|
|
29
33
|
|
|
30
34
|
if ( ! added ) {
|
|
31
35
|
return undefined;
|
|
32
36
|
}
|
|
33
37
|
|
|
34
|
-
const childId = model.id;
|
|
38
|
+
const childId = model.id as string;
|
|
35
39
|
const childModel = findModelInDocument( childId );
|
|
36
40
|
|
|
37
41
|
if ( ! childModel ) {
|