@elementor/editor-canvas 3.33.0-196 → 3.33.0-197

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.d.mts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as _elementor_editor_props from '@elementor/editor-props';
2
2
  import { AnyTransformable, PropTypeKey, PropsSchema, Props } from '@elementor/editor-props';
3
- import { V1ElementModelProps } from '@elementor/editor-elements';
3
+ import { V1ElementModelProps, V1ElementConfig } from '@elementor/editor-elements';
4
+ import { TwingArrayLoader, TwingEnvironment } from '@elementor/twing';
4
5
 
5
6
  declare function init(): void;
6
7
 
@@ -63,8 +64,14 @@ declare function createPropsResolver({ transformers, schema: initialSchema, onPr
63
64
  declare const startDragElementFromPanel: (props: Omit<V1ElementModelProps, "id">) => void;
64
65
  declare const endDragElementFromPanel: () => void;
65
66
 
67
+ type DomRenderer = {
68
+ register: TwingArrayLoader['setTemplate'];
69
+ render: TwingEnvironment['render'];
70
+ };
71
+
66
72
  type LegacyWindow = Window & {
67
73
  elementor: {
74
+ createBackboneElementsCollection: (children: unknown) => BackboneCollection<ElementModel>;
68
75
  modules: {
69
76
  elements: {
70
77
  types: {
@@ -94,6 +101,8 @@ declare class ElementType {
94
101
  declare class ElementView {
95
102
  $el: JQueryElement;
96
103
  model: BackboneModel<ElementModel>;
104
+ collection: BackboneCollection<ElementModel>;
105
+ constructor(...args: unknown[]);
97
106
  onRender(...args: unknown[]): void;
98
107
  onDestroy(...args: unknown[]): void;
99
108
  attributes(): Record<string, unknown>;
@@ -108,11 +117,15 @@ declare class ElementView {
108
117
  renderOnChange(): void;
109
118
  render(): void;
110
119
  _renderTemplate(): void;
120
+ _renderChildren(): void;
121
+ attachBuffer(collectionView: this, buffer: DocumentFragment): void;
111
122
  triggerMethod(method: string): void;
112
123
  bindUIElements(): void;
113
124
  options?: {
114
125
  model: BackboneModel<ElementModel>;
115
126
  };
127
+ ui(): Record<string, unknown>;
128
+ events(): Record<string, unknown>;
116
129
  }
117
130
  type JQueryElement = {
118
131
  find: (selector: string) => JQueryElement;
@@ -123,6 +136,9 @@ type BackboneModel<Model extends object> = {
123
136
  get: <T extends keyof Model>(key: T) => Model[T];
124
137
  toJSON: () => ToJSON<Model>;
125
138
  };
139
+ type BackboneCollection<Model extends object> = {
140
+ models: BackboneModel<Model>[];
141
+ };
126
142
  type ElementModel = {
127
143
  id: string;
128
144
  settings: BackboneModel<Props>;
@@ -136,8 +152,17 @@ type ContextMenuGroup = {
136
152
  actions: unknown[];
137
153
  };
138
154
 
139
- declare function registerElementType(type: string, componentClass: () => typeof ElementType): void;
155
+ type CreateTemplatedElementTypeOptions = {
156
+ type: string;
157
+ renderer: DomRenderer;
158
+ element: TemplatedElementConfig;
159
+ };
160
+ type TemplatedElementConfig = Required<Pick<V1ElementConfig, 'twig_templates' | 'twig_main_template' | 'atomic_props_schema' | 'base_styles_dictionary'>>;
161
+ declare function createTemplatedElementView({ type, renderer, element, }: CreateTemplatedElementTypeOptions): typeof ElementView;
140
162
 
141
- declare function createElementViewClassDeclaration(): typeof ElementView;
163
+ type ElementLegacyType = {
164
+ [key: string]: (options: CreateTemplatedElementTypeOptions) => typeof ElementType;
165
+ };
166
+ declare function registerElementType(type: string, elementTypeGenerator: ElementLegacyType[keyof ElementLegacyType]): void;
142
167
 
143
- export { ElementType, ElementView, type LegacyWindow, type PropsResolver, createElementViewClassDeclaration, createPropsResolver, createTransformer, createTransformersRegistry, endDragElementFromPanel, init, registerElementType, settingsTransformersRegistry, startDragElementFromPanel, styleTransformersRegistry };
168
+ export { type CreateTemplatedElementTypeOptions, ElementType, ElementView, type LegacyWindow, type PropsResolver, createPropsResolver, createTemplatedElementView, createTransformer, createTransformersRegistry, endDragElementFromPanel, init, registerElementType, settingsTransformersRegistry, startDragElementFromPanel, styleTransformersRegistry };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as _elementor_editor_props from '@elementor/editor-props';
2
2
  import { AnyTransformable, PropTypeKey, PropsSchema, Props } from '@elementor/editor-props';
3
- import { V1ElementModelProps } from '@elementor/editor-elements';
3
+ import { V1ElementModelProps, V1ElementConfig } from '@elementor/editor-elements';
4
+ import { TwingArrayLoader, TwingEnvironment } from '@elementor/twing';
4
5
 
5
6
  declare function init(): void;
6
7
 
@@ -63,8 +64,14 @@ declare function createPropsResolver({ transformers, schema: initialSchema, onPr
63
64
  declare const startDragElementFromPanel: (props: Omit<V1ElementModelProps, "id">) => void;
64
65
  declare const endDragElementFromPanel: () => void;
65
66
 
67
+ type DomRenderer = {
68
+ register: TwingArrayLoader['setTemplate'];
69
+ render: TwingEnvironment['render'];
70
+ };
71
+
66
72
  type LegacyWindow = Window & {
67
73
  elementor: {
74
+ createBackboneElementsCollection: (children: unknown) => BackboneCollection<ElementModel>;
68
75
  modules: {
69
76
  elements: {
70
77
  types: {
@@ -94,6 +101,8 @@ declare class ElementType {
94
101
  declare class ElementView {
95
102
  $el: JQueryElement;
96
103
  model: BackboneModel<ElementModel>;
104
+ collection: BackboneCollection<ElementModel>;
105
+ constructor(...args: unknown[]);
97
106
  onRender(...args: unknown[]): void;
98
107
  onDestroy(...args: unknown[]): void;
99
108
  attributes(): Record<string, unknown>;
@@ -108,11 +117,15 @@ declare class ElementView {
108
117
  renderOnChange(): void;
109
118
  render(): void;
110
119
  _renderTemplate(): void;
120
+ _renderChildren(): void;
121
+ attachBuffer(collectionView: this, buffer: DocumentFragment): void;
111
122
  triggerMethod(method: string): void;
112
123
  bindUIElements(): void;
113
124
  options?: {
114
125
  model: BackboneModel<ElementModel>;
115
126
  };
127
+ ui(): Record<string, unknown>;
128
+ events(): Record<string, unknown>;
116
129
  }
117
130
  type JQueryElement = {
118
131
  find: (selector: string) => JQueryElement;
@@ -123,6 +136,9 @@ type BackboneModel<Model extends object> = {
123
136
  get: <T extends keyof Model>(key: T) => Model[T];
124
137
  toJSON: () => ToJSON<Model>;
125
138
  };
139
+ type BackboneCollection<Model extends object> = {
140
+ models: BackboneModel<Model>[];
141
+ };
126
142
  type ElementModel = {
127
143
  id: string;
128
144
  settings: BackboneModel<Props>;
@@ -136,8 +152,17 @@ type ContextMenuGroup = {
136
152
  actions: unknown[];
137
153
  };
138
154
 
139
- declare function registerElementType(type: string, componentClass: () => typeof ElementType): void;
155
+ type CreateTemplatedElementTypeOptions = {
156
+ type: string;
157
+ renderer: DomRenderer;
158
+ element: TemplatedElementConfig;
159
+ };
160
+ type TemplatedElementConfig = Required<Pick<V1ElementConfig, 'twig_templates' | 'twig_main_template' | 'atomic_props_schema' | 'base_styles_dictionary'>>;
161
+ declare function createTemplatedElementView({ type, renderer, element, }: CreateTemplatedElementTypeOptions): typeof ElementView;
140
162
 
141
- declare function createElementViewClassDeclaration(): typeof ElementView;
163
+ type ElementLegacyType = {
164
+ [key: string]: (options: CreateTemplatedElementTypeOptions) => typeof ElementType;
165
+ };
166
+ declare function registerElementType(type: string, elementTypeGenerator: ElementLegacyType[keyof ElementLegacyType]): void;
142
167
 
143
- export { ElementType, ElementView, type LegacyWindow, type PropsResolver, createElementViewClassDeclaration, createPropsResolver, createTransformer, createTransformersRegistry, endDragElementFromPanel, init, registerElementType, settingsTransformersRegistry, startDragElementFromPanel, styleTransformersRegistry };
168
+ export { type CreateTemplatedElementTypeOptions, ElementType, ElementView, type LegacyWindow, type PropsResolver, createPropsResolver, createTemplatedElementView, createTransformer, createTransformersRegistry, endDragElementFromPanel, init, registerElementType, settingsTransformersRegistry, startDragElementFromPanel, styleTransformersRegistry };
package/dist/index.js CHANGED
@@ -30,8 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
- createElementViewClassDeclaration: () => createElementViewClassDeclaration,
34
33
  createPropsResolver: () => createPropsResolver,
34
+ createTemplatedElementView: () => createTemplatedElementView,
35
35
  createTransformer: () => createTransformer,
36
36
  createTransformersRegistry: () => createTransformersRegistry,
37
37
  endDragElementFromPanel: () => endDragElementFromPanel,
@@ -1182,26 +1182,21 @@ function createElementViewClassDeclaration() {
1182
1182
  }
1183
1183
 
1184
1184
  // src/legacy/create-templated-element-type.ts
1185
- function createTemplatedElementType({ type, renderer, element }) {
1185
+ function createTemplatedElementType({
1186
+ type,
1187
+ renderer,
1188
+ element
1189
+ }) {
1186
1190
  const legacyWindow = window;
1187
- Object.entries(element.twig_templates).forEach(([key, template]) => {
1188
- renderer.register(key, template);
1189
- });
1190
- const propsResolver = createPropsResolver({
1191
- transformers: settingsTransformersRegistry,
1192
- schema: element.atomic_props_schema
1193
- });
1194
1191
  return class extends legacyWindow.elementor.modules.elements.types.Widget {
1195
1192
  getType() {
1196
1193
  return type;
1197
1194
  }
1198
1195
  getView() {
1199
- return createTemplatedElementViewClassDeclaration({
1196
+ return createTemplatedElementView({
1200
1197
  type,
1201
1198
  renderer,
1202
- propsResolver,
1203
- baseStylesDictionary: element.base_styles_dictionary,
1204
- templateKey: element.twig_main_template
1199
+ element
1205
1200
  });
1206
1201
  }
1207
1202
  };
@@ -1209,16 +1204,30 @@ function createTemplatedElementType({ type, renderer, element }) {
1209
1204
  function canBeTemplated(element) {
1210
1205
  return !!(element.atomic_props_schema && element.twig_templates && element.twig_main_template && element.base_styles_dictionary);
1211
1206
  }
1212
- function createTemplatedElementViewClassDeclaration({
1207
+ function createTemplatedElementView({
1213
1208
  type,
1214
1209
  renderer,
1215
- propsResolver: resolveProps,
1216
- templateKey,
1217
- baseStylesDictionary
1210
+ element
1218
1211
  }) {
1219
1212
  const BaseView = createElementViewClassDeclaration();
1213
+ const templateKey = element.twig_main_template;
1214
+ const baseStylesDictionary = element.base_styles_dictionary;
1215
+ Object.entries(element.twig_templates).forEach(([key, template]) => {
1216
+ renderer.register(key, template);
1217
+ });
1218
+ const resolveProps = createPropsResolver({
1219
+ transformers: settingsTransformersRegistry,
1220
+ schema: element.atomic_props_schema
1221
+ });
1220
1222
  return class extends BaseView {
1221
1223
  #abortController = null;
1224
+ __renderChildren;
1225
+ constructor(...args) {
1226
+ super(...args);
1227
+ this.__renderChildren = this._renderChildren;
1228
+ this._renderChildren = () => {
1229
+ };
1230
+ }
1222
1231
  getTemplateType() {
1223
1232
  return "twig";
1224
1233
  }
@@ -1236,18 +1245,23 @@ function createTemplatedElementViewClassDeclaration({
1236
1245
  props: settings,
1237
1246
  signal
1238
1247
  });
1239
- }).then((resolvedSettings) => {
1248
+ }).then((settings) => {
1249
+ return this.afterSettingsResolve(settings);
1250
+ }).then(async (settings) => {
1240
1251
  const context = {
1241
1252
  id: this.model.get("id"),
1242
1253
  type,
1243
- settings: resolvedSettings,
1254
+ settings,
1244
1255
  base_styles: baseStylesDictionary
1245
1256
  };
1246
1257
  return renderer.render(templateKey, context);
1247
- }).then((html) => this.$el.html(html));
1258
+ }).then((html) => this.$el.html(html)).then(() => this.__renderChildren());
1248
1259
  await process.execute();
1249
1260
  this.#afterRenderTemplate();
1250
1261
  }
1262
+ afterSettingsResolve(settings) {
1263
+ return settings;
1264
+ }
1251
1265
  // Emulating the original Marionette behavior.
1252
1266
  #beforeRenderTemplate() {
1253
1267
  this.triggerMethod("before:render:template");
@@ -1261,8 +1275,8 @@ function createTemplatedElementViewClassDeclaration({
1261
1275
 
1262
1276
  // src/legacy/init-legacy-views.ts
1263
1277
  var elementsLegacyTypes = {};
1264
- function registerElementType(type, componentClass) {
1265
- elementsLegacyTypes[type] = componentClass;
1278
+ function registerElementType(type, elementTypeGenerator) {
1279
+ elementsLegacyTypes[type] = elementTypeGenerator;
1266
1280
  }
1267
1281
  function initLegacyViews() {
1268
1282
  (0, import_editor_v1_adapters5.__privateListenTo)((0, import_editor_v1_adapters5.v1ReadyEvent)(), () => {
@@ -1273,12 +1287,14 @@ function initLegacyViews() {
1273
1287
  if (!element.atomic) {
1274
1288
  return;
1275
1289
  }
1276
- if (elementsLegacyTypes[type]) {
1277
- const registeredElementTypeClass = elementsLegacyTypes[type]();
1278
- legacyWindow.elementor.elementsManager.registerElementType(new registeredElementTypeClass());
1279
- return;
1290
+ let ElementType;
1291
+ if (!!elementsLegacyTypes[type] && canBeTemplated(element)) {
1292
+ ElementType = elementsLegacyTypes[type]({ type, renderer, element });
1293
+ } else if (canBeTemplated(element)) {
1294
+ ElementType = createTemplatedElementType({ type, renderer, element });
1295
+ } else {
1296
+ ElementType = createElementType(type);
1280
1297
  }
1281
- const ElementType = canBeTemplated(element) ? createTemplatedElementType({ type, renderer, element }) : createElementType(type);
1282
1298
  legacyWindow.elementor.elementsManager.registerElementType(new ElementType());
1283
1299
  });
1284
1300
  });
@@ -1656,8 +1672,8 @@ var getLegacyPanelElementView = ({ settings, ...rest }) => {
1656
1672
  };
1657
1673
  // Annotate the CommonJS export names for ESM import in node:
1658
1674
  0 && (module.exports = {
1659
- createElementViewClassDeclaration,
1660
1675
  createPropsResolver,
1676
+ createTemplatedElementView,
1661
1677
  createTransformer,
1662
1678
  createTransformersRegistry,
1663
1679
  endDragElementFromPanel,
package/dist/index.mjs CHANGED
@@ -1144,26 +1144,21 @@ function createElementViewClassDeclaration() {
1144
1144
  }
1145
1145
 
1146
1146
  // src/legacy/create-templated-element-type.ts
1147
- function createTemplatedElementType({ type, renderer, element }) {
1147
+ function createTemplatedElementType({
1148
+ type,
1149
+ renderer,
1150
+ element
1151
+ }) {
1148
1152
  const legacyWindow = window;
1149
- Object.entries(element.twig_templates).forEach(([key, template]) => {
1150
- renderer.register(key, template);
1151
- });
1152
- const propsResolver = createPropsResolver({
1153
- transformers: settingsTransformersRegistry,
1154
- schema: element.atomic_props_schema
1155
- });
1156
1153
  return class extends legacyWindow.elementor.modules.elements.types.Widget {
1157
1154
  getType() {
1158
1155
  return type;
1159
1156
  }
1160
1157
  getView() {
1161
- return createTemplatedElementViewClassDeclaration({
1158
+ return createTemplatedElementView({
1162
1159
  type,
1163
1160
  renderer,
1164
- propsResolver,
1165
- baseStylesDictionary: element.base_styles_dictionary,
1166
- templateKey: element.twig_main_template
1161
+ element
1167
1162
  });
1168
1163
  }
1169
1164
  };
@@ -1171,16 +1166,30 @@ function createTemplatedElementType({ type, renderer, element }) {
1171
1166
  function canBeTemplated(element) {
1172
1167
  return !!(element.atomic_props_schema && element.twig_templates && element.twig_main_template && element.base_styles_dictionary);
1173
1168
  }
1174
- function createTemplatedElementViewClassDeclaration({
1169
+ function createTemplatedElementView({
1175
1170
  type,
1176
1171
  renderer,
1177
- propsResolver: resolveProps,
1178
- templateKey,
1179
- baseStylesDictionary
1172
+ element
1180
1173
  }) {
1181
1174
  const BaseView = createElementViewClassDeclaration();
1175
+ const templateKey = element.twig_main_template;
1176
+ const baseStylesDictionary = element.base_styles_dictionary;
1177
+ Object.entries(element.twig_templates).forEach(([key, template]) => {
1178
+ renderer.register(key, template);
1179
+ });
1180
+ const resolveProps = createPropsResolver({
1181
+ transformers: settingsTransformersRegistry,
1182
+ schema: element.atomic_props_schema
1183
+ });
1182
1184
  return class extends BaseView {
1183
1185
  #abortController = null;
1186
+ __renderChildren;
1187
+ constructor(...args) {
1188
+ super(...args);
1189
+ this.__renderChildren = this._renderChildren;
1190
+ this._renderChildren = () => {
1191
+ };
1192
+ }
1184
1193
  getTemplateType() {
1185
1194
  return "twig";
1186
1195
  }
@@ -1198,18 +1207,23 @@ function createTemplatedElementViewClassDeclaration({
1198
1207
  props: settings,
1199
1208
  signal
1200
1209
  });
1201
- }).then((resolvedSettings) => {
1210
+ }).then((settings) => {
1211
+ return this.afterSettingsResolve(settings);
1212
+ }).then(async (settings) => {
1202
1213
  const context = {
1203
1214
  id: this.model.get("id"),
1204
1215
  type,
1205
- settings: resolvedSettings,
1216
+ settings,
1206
1217
  base_styles: baseStylesDictionary
1207
1218
  };
1208
1219
  return renderer.render(templateKey, context);
1209
- }).then((html) => this.$el.html(html));
1220
+ }).then((html) => this.$el.html(html)).then(() => this.__renderChildren());
1210
1221
  await process.execute();
1211
1222
  this.#afterRenderTemplate();
1212
1223
  }
1224
+ afterSettingsResolve(settings) {
1225
+ return settings;
1226
+ }
1213
1227
  // Emulating the original Marionette behavior.
1214
1228
  #beforeRenderTemplate() {
1215
1229
  this.triggerMethod("before:render:template");
@@ -1223,8 +1237,8 @@ function createTemplatedElementViewClassDeclaration({
1223
1237
 
1224
1238
  // src/legacy/init-legacy-views.ts
1225
1239
  var elementsLegacyTypes = {};
1226
- function registerElementType(type, componentClass) {
1227
- elementsLegacyTypes[type] = componentClass;
1240
+ function registerElementType(type, elementTypeGenerator) {
1241
+ elementsLegacyTypes[type] = elementTypeGenerator;
1228
1242
  }
1229
1243
  function initLegacyViews() {
1230
1244
  __privateListenTo(v1ReadyEvent(), () => {
@@ -1235,12 +1249,14 @@ function initLegacyViews() {
1235
1249
  if (!element.atomic) {
1236
1250
  return;
1237
1251
  }
1238
- if (elementsLegacyTypes[type]) {
1239
- const registeredElementTypeClass = elementsLegacyTypes[type]();
1240
- legacyWindow.elementor.elementsManager.registerElementType(new registeredElementTypeClass());
1241
- return;
1252
+ let ElementType;
1253
+ if (!!elementsLegacyTypes[type] && canBeTemplated(element)) {
1254
+ ElementType = elementsLegacyTypes[type]({ type, renderer, element });
1255
+ } else if (canBeTemplated(element)) {
1256
+ ElementType = createTemplatedElementType({ type, renderer, element });
1257
+ } else {
1258
+ ElementType = createElementType(type);
1242
1259
  }
1243
- const ElementType = canBeTemplated(element) ? createTemplatedElementType({ type, renderer, element }) : createElementType(type);
1244
1260
  legacyWindow.elementor.elementsManager.registerElementType(new ElementType());
1245
1261
  });
1246
1262
  });
@@ -1634,8 +1650,8 @@ var getLegacyPanelElementView = ({ settings, ...rest }) => {
1634
1650
  return { model: elementModel };
1635
1651
  };
1636
1652
  export {
1637
- createElementViewClassDeclaration,
1638
1653
  createPropsResolver,
1654
+ createTemplatedElementView,
1639
1655
  createTransformer,
1640
1656
  createTransformersRegistry,
1641
1657
  endDragElementFromPanel,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elementor/editor-canvas",
3
3
  "description": "Elementor Editor Canvas",
4
- "version": "3.33.0-196",
4
+ "version": "3.33.0-197",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -37,19 +37,19 @@
37
37
  "react-dom": "^18.3.1"
38
38
  },
39
39
  "dependencies": {
40
- "@elementor/editor": "3.33.0-196",
41
- "@elementor/editor-notifications": "3.33.0-196",
42
- "@elementor/editor-documents": "3.33.0-196",
43
- "@elementor/editor-elements": "3.33.0-196",
44
- "@elementor/editor-props": "3.33.0-196",
45
- "@elementor/editor-responsive": "3.33.0-196",
46
- "@elementor/editor-styles": "3.33.0-196",
47
- "@elementor/editor-styles-repository": "3.33.0-196",
48
- "@elementor/editor-v1-adapters": "3.33.0-196",
49
- "@elementor/twing": "3.33.0-196",
40
+ "@elementor/editor": "3.33.0-197",
41
+ "@elementor/editor-notifications": "3.33.0-197",
42
+ "@elementor/editor-documents": "3.33.0-197",
43
+ "@elementor/editor-elements": "3.33.0-197",
44
+ "@elementor/editor-props": "3.33.0-197",
45
+ "@elementor/editor-responsive": "3.33.0-197",
46
+ "@elementor/editor-styles": "3.33.0-197",
47
+ "@elementor/editor-styles-repository": "3.33.0-197",
48
+ "@elementor/editor-v1-adapters": "3.33.0-197",
49
+ "@elementor/twing": "3.33.0-197",
50
50
  "@elementor/ui": "1.36.12",
51
- "@elementor/utils": "3.33.0-196",
52
- "@elementor/wp-media": "3.33.0-196",
51
+ "@elementor/utils": "3.33.0-197",
52
+ "@elementor/wp-media": "3.33.0-197",
53
53
  "@floating-ui/react": "^0.27.5",
54
54
  "@wordpress/i18n": "^5.13.0"
55
55
  },
package/src/index.ts CHANGED
@@ -7,5 +7,8 @@ export { createTransformersRegistry } from './transformers/create-transformers-r
7
7
  export { createPropsResolver, type PropsResolver } from './renderers/create-props-resolver';
8
8
  export { startDragElementFromPanel, endDragElementFromPanel } from './sync/drag-element-from-panel';
9
9
  export { registerElementType } from './legacy/init-legacy-views';
10
- export { createElementViewClassDeclaration } from './legacy/create-element-type';
10
+ export {
11
+ createTemplatedElementView,
12
+ type CreateTemplatedElementTypeOptions,
13
+ } from './legacy/create-templated-element-type';
11
14
  export * from './legacy/types';
@@ -1,13 +1,13 @@
1
1
  import type { V1ElementConfig } from '@elementor/editor-elements';
2
2
 
3
3
  import { type DomRenderer } from '../renderers/create-dom-renderer';
4
- import { createPropsResolver, type PropsResolver } from '../renderers/create-props-resolver';
4
+ import { createPropsResolver } from '../renderers/create-props-resolver';
5
5
  import { settingsTransformersRegistry } from '../settings-transformers-registry';
6
6
  import { signalizedProcess } from '../utils/signalized-process';
7
7
  import { createElementViewClassDeclaration } from './create-element-type';
8
8
  import { type ElementType, type ElementView, type LegacyWindow } from './types';
9
9
 
10
- type CreateTypeOptions = {
10
+ export type CreateTemplatedElementTypeOptions = {
11
11
  type: string;
12
12
  renderer: DomRenderer;
13
13
  element: TemplatedElementConfig;
@@ -17,30 +17,23 @@ type TemplatedElementConfig = Required<
17
17
  Pick< V1ElementConfig, 'twig_templates' | 'twig_main_template' | 'atomic_props_schema' | 'base_styles_dictionary' >
18
18
  >;
19
19
 
20
- export function createTemplatedElementType( { type, renderer, element }: CreateTypeOptions ): typeof ElementType {
20
+ export function createTemplatedElementType( {
21
+ type,
22
+ renderer,
23
+ element,
24
+ }: CreateTemplatedElementTypeOptions ): typeof ElementType {
21
25
  const legacyWindow = window as unknown as LegacyWindow;
22
26
 
23
- Object.entries( element.twig_templates ).forEach( ( [ key, template ] ) => {
24
- renderer.register( key, template );
25
- } );
26
-
27
- const propsResolver = createPropsResolver( {
28
- transformers: settingsTransformersRegistry,
29
- schema: element.atomic_props_schema,
30
- } );
31
-
32
27
  return class extends legacyWindow.elementor.modules.elements.types.Widget {
33
28
  getType() {
34
29
  return type;
35
30
  }
36
31
 
37
32
  getView() {
38
- return createTemplatedElementViewClassDeclaration( {
33
+ return createTemplatedElementView( {
39
34
  type,
40
35
  renderer,
41
- propsResolver,
42
- baseStylesDictionary: element.base_styles_dictionary,
43
- templateKey: element.twig_main_template,
36
+ element,
44
37
  } );
45
38
  }
46
39
  };
@@ -55,26 +48,41 @@ export function canBeTemplated( element: Partial< TemplatedElementConfig > ): el
55
48
  );
56
49
  }
57
50
 
58
- type CreateViewOptions = {
59
- type: string;
60
- renderer: DomRenderer;
61
- propsResolver: PropsResolver;
62
- templateKey: string;
63
- baseStylesDictionary: Record< string, string >;
64
- };
65
-
66
- function createTemplatedElementViewClassDeclaration( {
51
+ export function createTemplatedElementView( {
67
52
  type,
68
53
  renderer,
69
- propsResolver: resolveProps,
70
- templateKey,
71
- baseStylesDictionary,
72
- }: CreateViewOptions ): typeof ElementView {
54
+ element,
55
+ }: CreateTemplatedElementTypeOptions ): typeof ElementView {
73
56
  const BaseView = createElementViewClassDeclaration();
74
57
 
58
+ const templateKey = element.twig_main_template;
59
+
60
+ const baseStylesDictionary = element.base_styles_dictionary;
61
+
62
+ Object.entries( element.twig_templates ).forEach( ( [ key, template ] ) => {
63
+ renderer.register( key, template );
64
+ } );
65
+
66
+ const resolveProps = createPropsResolver( {
67
+ transformers: settingsTransformersRegistry,
68
+ schema: element.atomic_props_schema,
69
+ } );
70
+
75
71
  return class extends BaseView {
76
72
  #abortController: AbortController | null = null;
77
73
 
74
+ __renderChildren: () => void;
75
+
76
+ constructor( ...args: unknown[] ) {
77
+ super( ...args );
78
+
79
+ // This override blocks the regular usage of `_renderChildren` method,
80
+ // and assigns it to another method which will be called later in the `_renderTemplate` method.
81
+ this.__renderChildren = this._renderChildren;
82
+
83
+ this._renderChildren = () => {};
84
+ }
85
+
78
86
  getTemplateType() {
79
87
  return 'twig';
80
88
  }
@@ -99,24 +107,32 @@ function createTemplatedElementViewClassDeclaration( {
99
107
  signal,
100
108
  } );
101
109
  } )
102
- .then( ( resolvedSettings ) => {
110
+ .then( ( settings ) => {
111
+ return this.afterSettingsResolve( settings );
112
+ } )
113
+ .then( async ( settings ) => {
103
114
  // Same as the Backend.
104
115
  const context = {
105
116
  id: this.model.get( 'id' ),
106
117
  type,
107
- settings: resolvedSettings,
118
+ settings,
108
119
  base_styles: baseStylesDictionary,
109
120
  };
110
121
 
111
122
  return renderer.render( templateKey, context );
112
123
  } )
113
- .then( ( html ) => this.$el.html( html ) );
124
+ .then( ( html ) => this.$el.html( html ) )
125
+ .then( () => this.__renderChildren() );
114
126
 
115
127
  await process.execute();
116
128
 
117
129
  this.#afterRenderTemplate();
118
130
  }
119
131
 
132
+ afterSettingsResolve( settings: { [ key: string ]: unknown } ) {
133
+ return settings;
134
+ }
135
+
120
136
  // Emulating the original Marionette behavior.
121
137
  #beforeRenderTemplate() {
122
138
  this.triggerMethod( 'before:render:template' );
@@ -3,16 +3,23 @@ import { __privateListenTo, v1ReadyEvent } from '@elementor/editor-v1-adapters';
3
3
 
4
4
  import { createDomRenderer } from '../renderers/create-dom-renderer';
5
5
  import { createElementType } from './create-element-type';
6
- import { canBeTemplated, createTemplatedElementType } from './create-templated-element-type';
6
+ import {
7
+ canBeTemplated,
8
+ createTemplatedElementType,
9
+ type CreateTemplatedElementTypeOptions,
10
+ } from './create-templated-element-type';
7
11
  import type { ElementType, LegacyWindow } from './types';
8
12
 
9
13
  type ElementLegacyType = {
10
- [ key: string ]: () => typeof ElementType;
14
+ [ key: string ]: ( options: CreateTemplatedElementTypeOptions ) => typeof ElementType;
11
15
  };
12
16
  export const elementsLegacyTypes: ElementLegacyType = {};
13
17
 
14
- export function registerElementType( type: string, componentClass: () => typeof ElementType ) {
15
- elementsLegacyTypes[ type ] = componentClass;
18
+ export function registerElementType(
19
+ type: string,
20
+ elementTypeGenerator: ElementLegacyType[ keyof ElementLegacyType ]
21
+ ) {
22
+ elementsLegacyTypes[ type ] = elementTypeGenerator;
16
23
  }
17
24
 
18
25
  export function initLegacyViews() {
@@ -27,15 +34,15 @@ export function initLegacyViews() {
27
34
  return;
28
35
  }
29
36
 
30
- if ( elementsLegacyTypes[ type ] ) {
31
- const registeredElementTypeClass = elementsLegacyTypes[ type ]();
32
- legacyWindow.elementor.elementsManager.registerElementType( new registeredElementTypeClass() );
33
- return;
34
- }
37
+ let ElementType;
35
38
 
36
- const ElementType = canBeTemplated( element )
37
- ? createTemplatedElementType( { type, renderer, element } )
38
- : createElementType( type );
39
+ if ( !! elementsLegacyTypes[ type ] && canBeTemplated( element ) ) {
40
+ ElementType = elementsLegacyTypes[ type ]( { type, renderer, element } );
41
+ } else if ( canBeTemplated( element ) ) {
42
+ ElementType = createTemplatedElementType( { type, renderer, element } );
43
+ } else {
44
+ ElementType = createElementType( type );
45
+ }
39
46
 
40
47
  legacyWindow.elementor.elementsManager.registerElementType( new ElementType() );
41
48
  } );
@@ -2,6 +2,8 @@ import { type Props } from '@elementor/editor-props';
2
2
 
3
3
  export type LegacyWindow = Window & {
4
4
  elementor: {
5
+ createBackboneElementsCollection: ( children: unknown ) => BackboneCollection< ElementModel >;
6
+
5
7
  modules: {
6
8
  elements: {
7
9
  types: {
@@ -36,6 +38,10 @@ export declare class ElementView {
36
38
 
37
39
  model: BackboneModel< ElementModel >;
38
40
 
41
+ collection: BackboneCollection< ElementModel >;
42
+
43
+ constructor( ...args: unknown[] );
44
+
39
45
  onRender( ...args: unknown[] ): void;
40
46
 
41
47
  onDestroy( ...args: unknown[] ): void;
@@ -61,6 +67,10 @@ export declare class ElementView {
61
67
 
62
68
  _renderTemplate(): void;
63
69
 
70
+ _renderChildren(): void;
71
+
72
+ attachBuffer( collectionView: this, buffer: DocumentFragment ): void;
73
+
64
74
  triggerMethod( method: string ): void;
65
75
 
66
76
  bindUIElements(): void;
@@ -68,6 +78,10 @@ export declare class ElementView {
68
78
  options?: {
69
79
  model: BackboneModel< ElementModel >;
70
80
  };
81
+
82
+ ui(): Record< string, unknown >;
83
+
84
+ events(): Record< string, unknown >;
71
85
  }
72
86
 
73
87
  type JQueryElement = {
@@ -81,6 +95,10 @@ type BackboneModel< Model extends object > = {
81
95
  toJSON: () => ToJSON< Model >;
82
96
  };
83
97
 
98
+ type BackboneCollection< Model extends object > = {
99
+ models: BackboneModel< Model >[];
100
+ };
101
+
84
102
  type ElementModel = {
85
103
  id: string;
86
104
  settings: BackboneModel< Props >;