@elementor/editor-canvas 3.33.0-99 → 3.35.0-324
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 +133 -10
- package/dist/index.d.ts +133 -10
- package/dist/index.js +1409 -212
- package/dist/index.mjs +1393 -179
- package/package.json +18 -14
- package/src/__tests__/settings-props-resolver.test.ts +0 -40
- package/src/__tests__/styles-prop-resolver.test.ts +13 -0
- package/src/components/__tests__/__snapshots__/style-renderer.test.tsx.snap +2 -6
- package/src/components/__tests__/elements-overlays.test.tsx +96 -12
- package/src/components/__tests__/inline-editor-overlay.test.tsx +245 -0
- package/src/components/__tests__/style-renderer.test.tsx +2 -2
- package/src/components/elements-overlays.tsx +33 -10
- package/src/components/inline-editor-overlay.tsx +79 -0
- package/src/components/interactions-renderer.tsx +33 -0
- package/src/components/{element-overlay.tsx → outline-overlay.tsx} +8 -7
- package/src/components/style-renderer.tsx +2 -4
- package/src/hooks/__tests__/use-has-overlapping.test.ts +187 -0
- package/src/hooks/use-floating-on-element.ts +11 -8
- package/src/hooks/use-has-overlapping.ts +21 -0
- package/src/hooks/use-interactions-items.ts +108 -0
- package/src/hooks/use-style-items.ts +34 -8
- package/src/index.ts +9 -0
- package/src/init-settings-transformers.ts +4 -0
- package/src/init.tsx +18 -0
- package/src/legacy/create-templated-element-type.ts +67 -42
- package/src/legacy/init-legacy-views.ts +27 -5
- package/src/legacy/types.ts +44 -4
- package/src/mcp/canvas-mcp.ts +17 -0
- package/src/mcp/mcp-description.ts +40 -0
- package/src/mcp/resources/widgets-schema-resource.ts +173 -0
- package/src/mcp/tools/build-composition/prompt.ts +128 -0
- package/src/mcp/tools/build-composition/schema.ts +31 -0
- package/src/mcp/tools/build-composition/tool.ts +163 -0
- package/src/mcp/tools/configure-element/prompt.ts +93 -0
- package/src/mcp/tools/configure-element/schema.ts +25 -0
- package/src/mcp/tools/configure-element/tool.ts +67 -0
- package/src/mcp/tools/get-element-config/tool.ts +69 -0
- package/src/mcp/utils/do-update-element-property.ts +129 -0
- package/src/mcp/utils/generate-available-tags.ts +23 -0
- package/src/renderers/__tests__/__snapshots__/create-styles-renderer.test.ts.snap +2 -0
- package/src/renderers/__tests__/create-styles-renderer.test.ts +25 -0
- package/src/renderers/create-styles-renderer.ts +20 -9
- package/src/renderers/errors.ts +6 -0
- package/src/sync/drag-element-from-panel.ts +49 -0
- package/src/sync/types.ts +32 -1
- package/src/transformers/settings/__tests__/attributes-transformer.test.ts +15 -0
- package/src/transformers/settings/__tests__/classes-transformer.test.ts +83 -0
- package/src/transformers/settings/attributes-transformer.ts +1 -23
- package/src/transformers/settings/classes-transformer.ts +21 -21
- package/src/transformers/settings/date-time-transformer.ts +12 -0
- package/src/transformers/settings/query-transformer.ts +10 -0
- package/src/transformers/styles/__tests__/transform-origin-transformer.test.ts +24 -0
- package/src/transformers/styles/__tests__/transition-transformer.test.ts +52 -0
- package/src/transformers/styles/background-transformer.ts +3 -1
- package/src/transformers/styles/transform-origin-transformer.ts +12 -2
- package/src/transformers/styles/transition-transformer.ts +34 -4
- package/src/types/element-overlay.ts +18 -0
- package/src/utils/inline-editing-utils.ts +43 -0
package/dist/index.js
CHANGED
|
@@ -31,16 +31,23 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
createPropsResolver: () => createPropsResolver,
|
|
34
|
+
createTemplatedElementView: () => createTemplatedElementView,
|
|
34
35
|
createTransformer: () => createTransformer,
|
|
35
36
|
createTransformersRegistry: () => createTransformersRegistry,
|
|
37
|
+
endDragElementFromPanel: () => endDragElementFromPanel,
|
|
38
|
+
getCanvasIframeDocument: () => getCanvasIframeDocument,
|
|
36
39
|
init: () => init,
|
|
40
|
+
registerElementType: () => registerElementType,
|
|
37
41
|
settingsTransformersRegistry: () => settingsTransformersRegistry,
|
|
42
|
+
startDragElementFromPanel: () => startDragElementFromPanel,
|
|
38
43
|
styleTransformersRegistry: () => styleTransformersRegistry
|
|
39
44
|
});
|
|
40
45
|
module.exports = __toCommonJS(index_exports);
|
|
41
46
|
|
|
42
47
|
// src/init.tsx
|
|
43
48
|
var import_editor = require("@elementor/editor");
|
|
49
|
+
var import_editor_interactions2 = require("@elementor/editor-interactions");
|
|
50
|
+
var import_editor_mcp3 = require("@elementor/editor-mcp");
|
|
44
51
|
|
|
45
52
|
// src/components/classes-rename.tsx
|
|
46
53
|
var import_react = require("react");
|
|
@@ -85,19 +92,102 @@ var renameClass = (oldClassName, newClassName) => {
|
|
|
85
92
|
};
|
|
86
93
|
|
|
87
94
|
// src/components/elements-overlays.tsx
|
|
88
|
-
var
|
|
89
|
-
var
|
|
95
|
+
var React3 = __toESM(require("react"));
|
|
96
|
+
var import_editor_elements3 = require("@elementor/editor-elements");
|
|
90
97
|
var import_editor_v1_adapters = require("@elementor/editor-v1-adapters");
|
|
91
98
|
|
|
92
|
-
// src/
|
|
99
|
+
// src/utils/inline-editing-utils.ts
|
|
100
|
+
var import_editor_elements = require("@elementor/editor-elements");
|
|
101
|
+
var WIDGET_PROPERTY_MAP = {
|
|
102
|
+
"e-heading": "title",
|
|
103
|
+
"e-paragraph": "paragraph"
|
|
104
|
+
};
|
|
105
|
+
var getHtmlPropertyName = (container) => {
|
|
106
|
+
const widgetType = container?.model?.get("widgetType") ?? container?.model?.get("elType");
|
|
107
|
+
if (!widgetType) {
|
|
108
|
+
return "";
|
|
109
|
+
}
|
|
110
|
+
if (WIDGET_PROPERTY_MAP[widgetType]) {
|
|
111
|
+
return WIDGET_PROPERTY_MAP[widgetType];
|
|
112
|
+
}
|
|
113
|
+
const propsSchema = (0, import_editor_elements.getElementType)(widgetType)?.propsSchema;
|
|
114
|
+
if (!propsSchema) {
|
|
115
|
+
return "";
|
|
116
|
+
}
|
|
117
|
+
const entry = Object.entries(propsSchema).find(([, propType]) => propType.key === "html");
|
|
118
|
+
return entry?.[0] ?? "";
|
|
119
|
+
};
|
|
120
|
+
var hasInlineEditableProperty = (containerId) => {
|
|
121
|
+
const container = (0, import_editor_elements.getContainer)(containerId);
|
|
122
|
+
const widgetType = container?.model?.get("widgetType") ?? container?.model?.get("elType");
|
|
123
|
+
if (!widgetType) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
return widgetType in WIDGET_PROPERTY_MAP;
|
|
127
|
+
};
|
|
128
|
+
var getInlineEditablePropertyName = (container) => {
|
|
129
|
+
return getHtmlPropertyName(container);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// src/components/inline-editor-overlay.tsx
|
|
133
|
+
var React2 = __toESM(require("react"));
|
|
134
|
+
var import_editor_controls = require("@elementor/editor-controls");
|
|
135
|
+
var import_editor_elements2 = require("@elementor/editor-elements");
|
|
136
|
+
var import_editor_props = require("@elementor/editor-props");
|
|
137
|
+
var import_ui2 = require("@elementor/ui");
|
|
138
|
+
var import_utils2 = require("@elementor/utils");
|
|
139
|
+
var import_react6 = require("@floating-ui/react");
|
|
140
|
+
|
|
141
|
+
// src/hooks/use-floating-on-element.ts
|
|
142
|
+
var import_react2 = require("react");
|
|
143
|
+
var import_react3 = require("@floating-ui/react");
|
|
144
|
+
function useFloatingOnElement({ element, isSelected }) {
|
|
145
|
+
const [isOpen, setIsOpen] = (0, import_react2.useState)(false);
|
|
146
|
+
const sizeModifier = 2;
|
|
147
|
+
const { refs, floatingStyles, context } = (0, import_react3.useFloating)({
|
|
148
|
+
// Must be controlled for interactions (like hover) to work.
|
|
149
|
+
open: isOpen || isSelected,
|
|
150
|
+
onOpenChange: setIsOpen,
|
|
151
|
+
whileElementsMounted: import_react3.autoUpdate,
|
|
152
|
+
middleware: [
|
|
153
|
+
// Match the floating element's size to the reference element.
|
|
154
|
+
(0, import_react3.size)(() => {
|
|
155
|
+
return {
|
|
156
|
+
apply({ elements, rects }) {
|
|
157
|
+
Object.assign(elements.floating.style, {
|
|
158
|
+
width: `${rects.reference.width + sizeModifier}px`,
|
|
159
|
+
height: `${rects.reference.height + sizeModifier}px`
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
}),
|
|
164
|
+
// Center the floating element on the reference element.
|
|
165
|
+
(0, import_react3.offset)(({ rects }) => -rects.reference.height / 2 - rects.floating.height / 2)
|
|
166
|
+
]
|
|
167
|
+
});
|
|
168
|
+
(0, import_react2.useEffect)(() => {
|
|
169
|
+
refs.setReference(element);
|
|
170
|
+
}, [element, refs]);
|
|
171
|
+
return {
|
|
172
|
+
isVisible: isOpen || isSelected,
|
|
173
|
+
context,
|
|
174
|
+
floating: {
|
|
175
|
+
setRef: refs.setFloating,
|
|
176
|
+
ref: refs.floating,
|
|
177
|
+
styles: floatingStyles
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// src/components/outline-overlay.tsx
|
|
93
183
|
var React = __toESM(require("react"));
|
|
94
184
|
var import_ui = require("@elementor/ui");
|
|
95
185
|
var import_react5 = require("@floating-ui/react");
|
|
96
186
|
|
|
97
187
|
// src/hooks/use-bind-react-props-to-element.ts
|
|
98
|
-
var
|
|
188
|
+
var import_react4 = require("react");
|
|
99
189
|
function useBindReactPropsToElement(element, getProps) {
|
|
100
|
-
(0,
|
|
190
|
+
(0, import_react4.useEffect)(() => {
|
|
101
191
|
const el = element;
|
|
102
192
|
const { events, attrs } = groupProps(getProps());
|
|
103
193
|
events.forEach(([eventName, listener]) => el.addEventListener(eventName, listener));
|
|
@@ -128,45 +218,24 @@ function groupProps(props) {
|
|
|
128
218
|
);
|
|
129
219
|
}
|
|
130
220
|
|
|
131
|
-
// src/hooks/use-
|
|
132
|
-
var
|
|
133
|
-
var
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
height: `${rects.reference.height + 2}px`
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
}),
|
|
151
|
-
// Center the floating element on the reference element.
|
|
152
|
-
(0, import_react4.offset)(({ rects }) => -rects.reference.height / 2 - rects.floating.height / 2)
|
|
153
|
-
]
|
|
154
|
-
});
|
|
155
|
-
(0, import_react3.useEffect)(() => {
|
|
156
|
-
refs.setReference(element);
|
|
157
|
-
}, [element, refs]);
|
|
158
|
-
return {
|
|
159
|
-
isVisible: isOpen || isSelected,
|
|
160
|
-
context,
|
|
161
|
-
floating: {
|
|
162
|
-
setRef: refs.setFloating,
|
|
163
|
-
ref: refs.floating,
|
|
164
|
-
styles: floatingStyles
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
}
|
|
221
|
+
// src/hooks/use-has-overlapping.ts
|
|
222
|
+
var possibleOverlappingSelectors = [".e-off-canvas"];
|
|
223
|
+
var useHasOverlapping = () => {
|
|
224
|
+
const preview = window.elementor?.$preview?.[0];
|
|
225
|
+
if (!preview) {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
const hasOverlapping = possibleOverlappingSelectors.map((selector) => Array.from(preview?.contentWindow?.document.body.querySelectorAll(selector) ?? [])).flat().some(
|
|
229
|
+
(elem) => elem.checkVisibility({
|
|
230
|
+
opacityProperty: true,
|
|
231
|
+
visibilityProperty: true,
|
|
232
|
+
contentVisibilityAuto: true
|
|
233
|
+
})
|
|
234
|
+
);
|
|
235
|
+
return hasOverlapping;
|
|
236
|
+
};
|
|
168
237
|
|
|
169
|
-
// src/components/
|
|
238
|
+
// src/components/outline-overlay.tsx
|
|
170
239
|
var CANVAS_WRAPPER_ID = "elementor-preview-responsive-wrapper";
|
|
171
240
|
var OverlayBox = (0, import_ui.styled)(import_ui.Box, {
|
|
172
241
|
shouldForwardProp: (prop) => prop !== "isSelected" && prop !== "isSmallerOffset"
|
|
@@ -175,12 +244,13 @@ var OverlayBox = (0, import_ui.styled)(import_ui.Box, {
|
|
|
175
244
|
outlineOffset: isSelected && !isSmallerOffset ? "-2px" : "-1px",
|
|
176
245
|
pointerEvents: "none"
|
|
177
246
|
}));
|
|
178
|
-
|
|
247
|
+
var OutlineOverlay = ({ element, isSelected, id }) => {
|
|
179
248
|
const { context, floating, isVisible } = useFloatingOnElement({ element, isSelected });
|
|
180
249
|
const { getFloatingProps, getReferenceProps } = (0, import_react5.useInteractions)([(0, import_react5.useHover)(context)]);
|
|
250
|
+
const hasOverlapping = useHasOverlapping();
|
|
181
251
|
useBindReactPropsToElement(element, getReferenceProps);
|
|
182
252
|
const isSmallerOffset = element.offsetHeight <= 1;
|
|
183
|
-
return isVisible && /* @__PURE__ */ React.createElement(import_react5.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React.createElement(
|
|
253
|
+
return isVisible && !hasOverlapping && /* @__PURE__ */ React.createElement(import_react5.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React.createElement(
|
|
184
254
|
OverlayBox,
|
|
185
255
|
{
|
|
186
256
|
ref: floating.setRef,
|
|
@@ -192,49 +262,238 @@ function ElementOverlay({ element, isSelected, id }) {
|
|
|
192
262
|
...getFloatingProps()
|
|
193
263
|
}
|
|
194
264
|
));
|
|
195
|
-
}
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
// src/components/inline-editor-overlay.tsx
|
|
268
|
+
var OVERLAY_Z_INDEX = 1e3;
|
|
269
|
+
var DEBOUNCE_DELAY = 100;
|
|
270
|
+
var InlineEditorOverlay = ({ element, isSelected, id }) => {
|
|
271
|
+
const { floating, isVisible } = useFloatingOnElement({ element, isSelected });
|
|
272
|
+
const propertyName = React2.useMemo(() => {
|
|
273
|
+
const container = (0, import_editor_elements2.getContainer)(id);
|
|
274
|
+
return getInlineEditablePropertyName(container);
|
|
275
|
+
}, [id]);
|
|
276
|
+
const contentProp = (0, import_editor_elements2.useElementSetting)(id, propertyName);
|
|
277
|
+
const value = React2.useMemo(() => import_editor_props.htmlPropTypeUtil.extract(contentProp) || "", [contentProp]);
|
|
278
|
+
const debouncedUpdateRef = React2.useRef(null);
|
|
279
|
+
const lastValueRef = React2.useRef("");
|
|
280
|
+
React2.useEffect(() => {
|
|
281
|
+
debouncedUpdateRef.current = (0, import_utils2.debounce)((newValue) => {
|
|
282
|
+
const textContent = newValue.replace(/<[^>]*>/g, "").trim();
|
|
283
|
+
const valueToSave = textContent === "" ? " " : newValue;
|
|
284
|
+
(0, import_editor_elements2.updateElementSettings)({
|
|
285
|
+
id,
|
|
286
|
+
props: {
|
|
287
|
+
[propertyName]: import_editor_props.htmlPropTypeUtil.create(valueToSave)
|
|
288
|
+
},
|
|
289
|
+
withHistory: true
|
|
290
|
+
});
|
|
291
|
+
}, DEBOUNCE_DELAY);
|
|
292
|
+
return () => {
|
|
293
|
+
debouncedUpdateRef.current?.cancel?.();
|
|
294
|
+
};
|
|
295
|
+
}, [id, propertyName]);
|
|
296
|
+
const handleValueChange = React2.useCallback((newValue) => {
|
|
297
|
+
lastValueRef.current = newValue;
|
|
298
|
+
debouncedUpdateRef.current?.(newValue);
|
|
299
|
+
}, []);
|
|
300
|
+
React2.useEffect(() => {
|
|
301
|
+
if (!isVisible && debouncedUpdateRef.current?.pending?.()) {
|
|
302
|
+
debouncedUpdateRef.current.flush(lastValueRef.current);
|
|
303
|
+
}
|
|
304
|
+
}, [isVisible]);
|
|
305
|
+
if (!isVisible) {
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
return /* @__PURE__ */ React2.createElement(import_react6.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React2.createElement(
|
|
309
|
+
import_ui2.Box,
|
|
310
|
+
{
|
|
311
|
+
ref: floating.setRef,
|
|
312
|
+
style: {
|
|
313
|
+
...floating.styles,
|
|
314
|
+
zIndex: OVERLAY_Z_INDEX,
|
|
315
|
+
pointerEvents: "auto"
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
/* @__PURE__ */ React2.createElement(import_editor_controls.InlineEditor, { value, setValue: handleValueChange, showToolbar: isSelected })
|
|
319
|
+
));
|
|
320
|
+
};
|
|
196
321
|
|
|
197
322
|
// src/components/elements-overlays.tsx
|
|
323
|
+
var ELEMENTS_DATA_ATTR = "atomic";
|
|
324
|
+
var overlayRegistry = [
|
|
325
|
+
{
|
|
326
|
+
component: OutlineOverlay,
|
|
327
|
+
shouldRender: () => true
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
component: InlineEditorOverlay,
|
|
331
|
+
shouldRender: ({ id, isSelected }) => isSelected && hasInlineEditableProperty(id) && (0, import_editor_v1_adapters.isExperimentActive)("v4-inline-text-editing")
|
|
332
|
+
}
|
|
333
|
+
];
|
|
198
334
|
function ElementsOverlays() {
|
|
199
|
-
const selected = (0,
|
|
335
|
+
const selected = (0, import_editor_elements3.useSelectedElement)();
|
|
200
336
|
const elements = useElementsDom();
|
|
201
337
|
const currentEditMode = (0, import_editor_v1_adapters.useEditMode)();
|
|
202
338
|
const isEditMode = currentEditMode === "edit";
|
|
203
339
|
const isKitRouteActive = (0, import_editor_v1_adapters.__privateUseIsRouteActive)("panel/global");
|
|
204
340
|
const isActive = isEditMode && !isKitRouteActive;
|
|
205
|
-
|
|
341
|
+
if (!isActive) {
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
return elements.map(([id, element]) => {
|
|
345
|
+
const isSelected = selected.element?.id === id;
|
|
346
|
+
return overlayRegistry.map(
|
|
347
|
+
({ shouldRender, component: Overlay }, index) => shouldRender({ id, element, isSelected }) && /* @__PURE__ */ React3.createElement(Overlay, { key: `${id}-${index}`, id, element, isSelected })
|
|
348
|
+
);
|
|
349
|
+
});
|
|
206
350
|
}
|
|
207
|
-
var ELEMENTS_DATA_ATTR = "atomic";
|
|
208
351
|
function useElementsDom() {
|
|
209
352
|
return (0, import_editor_v1_adapters.__privateUseListenTo)(
|
|
210
353
|
[(0, import_editor_v1_adapters.windowEvent)("elementor/editor/element-rendered"), (0, import_editor_v1_adapters.windowEvent)("elementor/editor/element-destroyed")],
|
|
211
354
|
() => {
|
|
212
|
-
return (0,
|
|
355
|
+
return (0, import_editor_elements3.getElements)().filter((el) => ELEMENTS_DATA_ATTR in (el.view?.el?.dataset ?? {})).map((element) => [element.id, element.view?.getDomElement?.()?.get?.(0)]).filter((item) => !!item[1]);
|
|
213
356
|
}
|
|
214
357
|
);
|
|
215
358
|
}
|
|
216
359
|
|
|
217
|
-
// src/components/
|
|
218
|
-
var
|
|
219
|
-
var
|
|
220
|
-
var
|
|
360
|
+
// src/components/interactions-renderer.tsx
|
|
361
|
+
var React4 = __toESM(require("react"));
|
|
362
|
+
var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
|
|
363
|
+
var import_ui3 = require("@elementor/ui");
|
|
221
364
|
|
|
222
|
-
// src/hooks/use-
|
|
365
|
+
// src/hooks/use-interactions-items.ts
|
|
366
|
+
var import_react8 = require("react");
|
|
367
|
+
var import_editor_interactions = require("@elementor/editor-interactions");
|
|
223
368
|
var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
|
|
224
369
|
|
|
370
|
+
// src/hooks/use-on-mount.ts
|
|
371
|
+
var import_react7 = require("react");
|
|
372
|
+
function useOnMount(cb) {
|
|
373
|
+
const mounted = (0, import_react7.useRef)(false);
|
|
374
|
+
(0, import_react7.useEffect)(() => {
|
|
375
|
+
if (!mounted.current) {
|
|
376
|
+
mounted.current = true;
|
|
377
|
+
cb();
|
|
378
|
+
}
|
|
379
|
+
}, []);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// src/hooks/use-interactions-items.ts
|
|
383
|
+
function useInteractionsItems() {
|
|
384
|
+
const [interactionItems, setInteractionItems] = (0, import_react8.useState)({});
|
|
385
|
+
const providerAndSubscribers = (0, import_react8.useMemo)(() => {
|
|
386
|
+
try {
|
|
387
|
+
const providers = import_editor_interactions.interactionsRepository.getProviders();
|
|
388
|
+
const mapped = providers.map((provider) => {
|
|
389
|
+
return {
|
|
390
|
+
provider,
|
|
391
|
+
subscriber: createProviderSubscriber({
|
|
392
|
+
provider,
|
|
393
|
+
setInteractionItems
|
|
394
|
+
})
|
|
395
|
+
};
|
|
396
|
+
});
|
|
397
|
+
return mapped;
|
|
398
|
+
} catch {
|
|
399
|
+
return [];
|
|
400
|
+
}
|
|
401
|
+
}, []);
|
|
402
|
+
(0, import_react8.useEffect)(() => {
|
|
403
|
+
if (providerAndSubscribers.length === 0) {
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
const unsubscribes = providerAndSubscribers.map(({ provider, subscriber }) => {
|
|
407
|
+
const safeSubscriber = () => {
|
|
408
|
+
try {
|
|
409
|
+
subscriber();
|
|
410
|
+
} catch {
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
const unsubscribe = provider.subscribe(safeSubscriber);
|
|
414
|
+
return unsubscribe;
|
|
415
|
+
});
|
|
416
|
+
return () => {
|
|
417
|
+
unsubscribes.forEach((unsubscribe) => unsubscribe());
|
|
418
|
+
};
|
|
419
|
+
}, [providerAndSubscribers]);
|
|
420
|
+
useOnMount(() => {
|
|
421
|
+
if (providerAndSubscribers.length === 0) {
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
(0, import_editor_v1_adapters2.registerDataHook)("after", "editor/documents/attach-preview", async () => {
|
|
425
|
+
providerAndSubscribers.forEach(({ subscriber }) => {
|
|
426
|
+
try {
|
|
427
|
+
subscriber();
|
|
428
|
+
} catch {
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
});
|
|
432
|
+
});
|
|
433
|
+
return (0, import_react8.useMemo)(() => {
|
|
434
|
+
const result = Object.values(interactionItems).sort(sortByProviderPriority).flatMap(({ items }) => items);
|
|
435
|
+
return result;
|
|
436
|
+
}, [interactionItems]);
|
|
437
|
+
}
|
|
438
|
+
function sortByProviderPriority({ provider: providerA }, { provider: providerB }) {
|
|
439
|
+
return providerA.priority - providerB.priority;
|
|
440
|
+
}
|
|
441
|
+
function createProviderSubscriber({ provider, setInteractionItems }) {
|
|
442
|
+
return () => {
|
|
443
|
+
try {
|
|
444
|
+
const items = provider.actions.all();
|
|
445
|
+
const providerKey = provider.getKey();
|
|
446
|
+
setInteractionItems((prev) => ({
|
|
447
|
+
...prev,
|
|
448
|
+
[providerKey]: { provider, items }
|
|
449
|
+
}));
|
|
450
|
+
} catch {
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
|
|
225
455
|
// src/sync/get-canvas-iframe-document.ts
|
|
226
456
|
function getCanvasIframeDocument() {
|
|
227
457
|
const extendedWindow = window;
|
|
228
458
|
return extendedWindow.elementor?.$preview?.[0]?.contentDocument;
|
|
229
459
|
}
|
|
230
460
|
|
|
461
|
+
// src/components/interactions-renderer.tsx
|
|
462
|
+
function InteractionsRenderer() {
|
|
463
|
+
const container = usePortalContainer();
|
|
464
|
+
const interactionItems = useInteractionsItems();
|
|
465
|
+
if (!container) {
|
|
466
|
+
return null;
|
|
467
|
+
}
|
|
468
|
+
const interactionsData = JSON.stringify(Array.isArray(interactionItems) ? interactionItems : []);
|
|
469
|
+
return /* @__PURE__ */ React4.createElement(import_ui3.Portal, { container }, /* @__PURE__ */ React4.createElement(
|
|
470
|
+
"script",
|
|
471
|
+
{
|
|
472
|
+
type: "application/json",
|
|
473
|
+
"data-e-interactions": "true",
|
|
474
|
+
dangerouslySetInnerHTML: {
|
|
475
|
+
__html: interactionsData
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
));
|
|
479
|
+
}
|
|
480
|
+
function usePortalContainer() {
|
|
481
|
+
return (0, import_editor_v1_adapters3.__privateUseListenTo)((0, import_editor_v1_adapters3.commandEndEvent)("editor/documents/attach-preview"), () => getCanvasIframeDocument()?.head);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// src/components/style-renderer.tsx
|
|
485
|
+
var React5 = __toESM(require("react"));
|
|
486
|
+
var import_editor_v1_adapters6 = require("@elementor/editor-v1-adapters");
|
|
487
|
+
var import_ui4 = require("@elementor/ui");
|
|
488
|
+
|
|
231
489
|
// src/hooks/use-documents-css-links.ts
|
|
490
|
+
var import_editor_v1_adapters4 = require("@elementor/editor-v1-adapters");
|
|
232
491
|
var REMOVED_ATTR = "data-e-removed";
|
|
233
492
|
var DOCUMENT_WRAPPER_ATTR = "data-elementor-id";
|
|
234
493
|
var CSS_LINK_ID_PREFIX = "elementor-post-";
|
|
235
494
|
var CSS_LINK_ID_SUFFIX = "-css";
|
|
236
495
|
function useDocumentsCssLinks() {
|
|
237
|
-
return (0,
|
|
496
|
+
return (0, import_editor_v1_adapters4.__privateUseListenTo)((0, import_editor_v1_adapters4.commandEndEvent)("editor/documents/attach-preview"), () => {
|
|
238
497
|
const iframeDocument = getCanvasIframeDocument();
|
|
239
498
|
if (!iframeDocument) {
|
|
240
499
|
return [];
|
|
@@ -275,10 +534,11 @@ function getLinkAttrs(el) {
|
|
|
275
534
|
}
|
|
276
535
|
|
|
277
536
|
// src/hooks/use-style-items.ts
|
|
278
|
-
var
|
|
537
|
+
var import_react11 = require("react");
|
|
279
538
|
var import_editor_responsive2 = require("@elementor/editor-responsive");
|
|
539
|
+
var import_editor_styles3 = require("@elementor/editor-styles");
|
|
280
540
|
var import_editor_styles_repository2 = require("@elementor/editor-styles-repository");
|
|
281
|
-
var
|
|
541
|
+
var import_editor_v1_adapters5 = require("@elementor/editor-v1-adapters");
|
|
282
542
|
|
|
283
543
|
// src/utils/abort-previous-runs.ts
|
|
284
544
|
function abortPreviousRuns(cb) {
|
|
@@ -311,24 +571,12 @@ function signalizedProcess(signal, steps = []) {
|
|
|
311
571
|
};
|
|
312
572
|
}
|
|
313
573
|
|
|
314
|
-
// src/hooks/use-on-mount.ts
|
|
315
|
-
var import_react6 = require("react");
|
|
316
|
-
function useOnMount(cb) {
|
|
317
|
-
const mounted = (0, import_react6.useRef)(false);
|
|
318
|
-
(0, import_react6.useEffect)(() => {
|
|
319
|
-
if (!mounted.current) {
|
|
320
|
-
mounted.current = true;
|
|
321
|
-
cb();
|
|
322
|
-
}
|
|
323
|
-
}, []);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
574
|
// src/hooks/use-style-prop-resolver.ts
|
|
327
|
-
var
|
|
575
|
+
var import_react9 = require("react");
|
|
328
576
|
var import_editor_styles = require("@elementor/editor-styles");
|
|
329
577
|
|
|
330
578
|
// src/renderers/create-props-resolver.ts
|
|
331
|
-
var
|
|
579
|
+
var import_editor_props2 = require("@elementor/editor-props");
|
|
332
580
|
|
|
333
581
|
// src/renderers/multi-props.ts
|
|
334
582
|
var isMultiProps = (propValue) => {
|
|
@@ -347,10 +595,10 @@ var getMultiPropsValue = (multiProps) => {
|
|
|
347
595
|
// src/renderers/create-props-resolver.ts
|
|
348
596
|
var TRANSFORM_DEPTH_LIMIT = 3;
|
|
349
597
|
function createPropsResolver({ transformers, schema: initialSchema, onPropResolve }) {
|
|
350
|
-
async function resolve({ props, schema, signal }) {
|
|
351
|
-
|
|
598
|
+
async function resolve({ props, schema: schema2, signal }) {
|
|
599
|
+
schema2 = schema2 ?? initialSchema;
|
|
352
600
|
const promises = Promise.all(
|
|
353
|
-
Object.entries(
|
|
601
|
+
Object.entries(schema2).map(async ([key, type]) => {
|
|
354
602
|
const value = props[key] ?? type.default;
|
|
355
603
|
const transformed = await transform({ value, key, type, signal });
|
|
356
604
|
onPropResolve?.({ key, value: transformed });
|
|
@@ -366,7 +614,7 @@ function createPropsResolver({ transformers, schema: initialSchema, onPropResolv
|
|
|
366
614
|
if (value === null || value === void 0) {
|
|
367
615
|
return null;
|
|
368
616
|
}
|
|
369
|
-
if (!(0,
|
|
617
|
+
if (!(0, import_editor_props2.isTransformable)(value)) {
|
|
370
618
|
return value;
|
|
371
619
|
}
|
|
372
620
|
if (depth > TRANSFORM_DEPTH_LIMIT) {
|
|
@@ -446,7 +694,7 @@ var enqueueFont = (fontFamily, context = "preview") => {
|
|
|
446
694
|
|
|
447
695
|
// src/hooks/use-style-prop-resolver.ts
|
|
448
696
|
function useStylePropResolver() {
|
|
449
|
-
return (0,
|
|
697
|
+
return (0, import_react9.useMemo)(() => {
|
|
450
698
|
return createPropsResolver({
|
|
451
699
|
transformers: styleTransformersRegistry,
|
|
452
700
|
schema: (0, import_editor_styles.getStylesSchema)(),
|
|
@@ -461,19 +709,23 @@ function useStylePropResolver() {
|
|
|
461
709
|
}
|
|
462
710
|
|
|
463
711
|
// src/hooks/use-style-renderer.ts
|
|
464
|
-
var
|
|
712
|
+
var import_react10 = require("react");
|
|
465
713
|
var import_editor_responsive = require("@elementor/editor-responsive");
|
|
466
714
|
|
|
467
715
|
// src/renderers/create-styles-renderer.ts
|
|
468
|
-
var
|
|
469
|
-
var
|
|
716
|
+
var import_editor_styles2 = require("@elementor/editor-styles");
|
|
717
|
+
var import_utils4 = require("@elementor/utils");
|
|
470
718
|
|
|
471
719
|
// src/renderers/errors.ts
|
|
472
|
-
var
|
|
473
|
-
var UnknownStyleTypeError = (0,
|
|
720
|
+
var import_utils3 = require("@elementor/utils");
|
|
721
|
+
var UnknownStyleTypeError = (0, import_utils3.createError)({
|
|
474
722
|
code: "unknown_style_type",
|
|
475
723
|
message: "Unknown style type"
|
|
476
724
|
});
|
|
725
|
+
var UnknownStyleStateError = (0, import_utils3.createError)({
|
|
726
|
+
code: "unknown_style_state",
|
|
727
|
+
message: "Unknown style state"
|
|
728
|
+
});
|
|
477
729
|
|
|
478
730
|
// src/renderers/create-styles-renderer.ts
|
|
479
731
|
var SELECTORS_MAP = {
|
|
@@ -491,7 +743,8 @@ function createStylesRenderer({ resolve, breakpoints, selectorPrefix = "" }) {
|
|
|
491
743
|
return {
|
|
492
744
|
id: style.id,
|
|
493
745
|
breakpoint: style?.variants[0]?.meta?.breakpoint || "desktop",
|
|
494
|
-
value: variantsCss.join("")
|
|
746
|
+
value: variantsCss.join(""),
|
|
747
|
+
state: style?.variants[0]?.meta?.state || null
|
|
495
748
|
};
|
|
496
749
|
});
|
|
497
750
|
return await Promise.all(stylesCssPromises);
|
|
@@ -507,7 +760,18 @@ function createStyleWrapper(value = "", wrapper) {
|
|
|
507
760
|
return createStyleWrapper(`${value}${symbol}${cssName}`, wrapper);
|
|
508
761
|
},
|
|
509
762
|
withPrefix: (prefix) => createStyleWrapper([prefix, value].filter(Boolean).join(" "), wrapper),
|
|
510
|
-
withState: (state) =>
|
|
763
|
+
withState: (state) => {
|
|
764
|
+
if (!state) {
|
|
765
|
+
return createStyleWrapper(value, wrapper);
|
|
766
|
+
}
|
|
767
|
+
if ((0, import_editor_styles2.isClassState)(state)) {
|
|
768
|
+
return createStyleWrapper(`${value}.${state}`, wrapper);
|
|
769
|
+
}
|
|
770
|
+
if ((0, import_editor_styles2.isPseudoState)(state)) {
|
|
771
|
+
return createStyleWrapper(`${value}:${state}`, wrapper);
|
|
772
|
+
}
|
|
773
|
+
throw new UnknownStyleStateError({ context: { state } });
|
|
774
|
+
},
|
|
511
775
|
withMediaQuery: (breakpoint) => {
|
|
512
776
|
if (!breakpoint?.type) {
|
|
513
777
|
return createStyleWrapper(value, wrapper);
|
|
@@ -535,10 +799,7 @@ async function propsToCss({ props, resolve, signal }) {
|
|
|
535
799
|
}, []).join("");
|
|
536
800
|
}
|
|
537
801
|
function customCssToString(customCss) {
|
|
538
|
-
|
|
539
|
-
return "";
|
|
540
|
-
}
|
|
541
|
-
const decoded = (0, import_utils3.decodeString)(customCss.raw);
|
|
802
|
+
const decoded = (0, import_utils4.decodeString)(customCss?.raw || "");
|
|
542
803
|
if (!decoded.trim()) {
|
|
543
804
|
return "";
|
|
544
805
|
}
|
|
@@ -549,7 +810,7 @@ function customCssToString(customCss) {
|
|
|
549
810
|
var SELECTOR_PREFIX = ".elementor";
|
|
550
811
|
function useStyleRenderer(resolve) {
|
|
551
812
|
const breakpoints = (0, import_editor_responsive.useBreakpointsMap)();
|
|
552
|
-
return (0,
|
|
813
|
+
return (0, import_react10.useMemo)(() => {
|
|
553
814
|
return createStylesRenderer({
|
|
554
815
|
selectorPrefix: SELECTOR_PREFIX,
|
|
555
816
|
breakpoints,
|
|
@@ -562,12 +823,12 @@ function useStyleRenderer(resolve) {
|
|
|
562
823
|
function useStyleItems() {
|
|
563
824
|
const resolve = useStylePropResolver();
|
|
564
825
|
const renderStyles = useStyleRenderer(resolve);
|
|
565
|
-
const [styleItems, setStyleItems] = (0,
|
|
566
|
-
const providerAndSubscribers = (0,
|
|
826
|
+
const [styleItems, setStyleItems] = (0, import_react11.useState)({});
|
|
827
|
+
const providerAndSubscribers = (0, import_react11.useMemo)(() => {
|
|
567
828
|
return import_editor_styles_repository2.stylesRepository.getProviders().map((provider) => {
|
|
568
829
|
return {
|
|
569
830
|
provider,
|
|
570
|
-
subscriber:
|
|
831
|
+
subscriber: createProviderSubscriber2({
|
|
571
832
|
provider,
|
|
572
833
|
renderStyles,
|
|
573
834
|
setStyleItems
|
|
@@ -575,7 +836,7 @@ function useStyleItems() {
|
|
|
575
836
|
};
|
|
576
837
|
});
|
|
577
838
|
}, [renderStyles]);
|
|
578
|
-
(0,
|
|
839
|
+
(0, import_react11.useEffect)(() => {
|
|
579
840
|
const unsubscribes = providerAndSubscribers.map(
|
|
580
841
|
({ provider, subscriber }) => provider.subscribe(subscriber)
|
|
581
842
|
);
|
|
@@ -584,22 +845,34 @@ function useStyleItems() {
|
|
|
584
845
|
};
|
|
585
846
|
}, [providerAndSubscribers]);
|
|
586
847
|
useOnMount(() => {
|
|
587
|
-
(0,
|
|
848
|
+
(0, import_editor_v1_adapters5.registerDataHook)("after", "editor/documents/attach-preview", async () => {
|
|
588
849
|
const promises = providerAndSubscribers.map(async ({ subscriber }) => subscriber());
|
|
589
850
|
await Promise.all(promises);
|
|
590
851
|
});
|
|
591
852
|
});
|
|
592
853
|
const breakpointsOrder = (0, import_editor_responsive2.getBreakpoints)().map((breakpoint) => breakpoint.id);
|
|
593
|
-
return (0,
|
|
594
|
-
() => Object.values(styleItems).sort(
|
|
595
|
-
return breakpointsOrder.indexOf(breakpointA) - breakpointsOrder.indexOf(breakpointB);
|
|
596
|
-
}),
|
|
597
|
-
// eslint-disable-next-line
|
|
854
|
+
return (0, import_react11.useMemo)(
|
|
855
|
+
() => Object.values(styleItems).sort(sortByProviderPriority2).flatMap(({ items }) => items).sort(sortByStateType).sort(sortByBreakpoint(breakpointsOrder)),
|
|
598
856
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
599
857
|
[styleItems, breakpointsOrder.join("-")]
|
|
600
858
|
);
|
|
601
859
|
}
|
|
602
|
-
function
|
|
860
|
+
function sortByProviderPriority2({ provider: providerA }, { provider: providerB }) {
|
|
861
|
+
return providerA.priority - providerB.priority;
|
|
862
|
+
}
|
|
863
|
+
function sortByBreakpoint(breakpointsOrder) {
|
|
864
|
+
return ({ breakpoint: breakpointA }, { breakpoint: breakpointB }) => breakpointsOrder.indexOf(breakpointA) - breakpointsOrder.indexOf(breakpointB);
|
|
865
|
+
}
|
|
866
|
+
function sortByStateType({ state: stateA }, { state: stateB }) {
|
|
867
|
+
if ((0, import_editor_styles3.isClassState)(stateA) && !(0, import_editor_styles3.isClassState)(stateB)) {
|
|
868
|
+
return -1;
|
|
869
|
+
}
|
|
870
|
+
if (!(0, import_editor_styles3.isClassState)(stateA) && (0, import_editor_styles3.isClassState)(stateB)) {
|
|
871
|
+
return 1;
|
|
872
|
+
}
|
|
873
|
+
return 0;
|
|
874
|
+
}
|
|
875
|
+
function createProviderSubscriber2({ provider, renderStyles, setStyleItems }) {
|
|
603
876
|
return abortPreviousRuns(
|
|
604
877
|
(abortController) => signalizedProcess(abortController.signal).then((_, signal) => {
|
|
605
878
|
const styles = provider.actions.all().map((__5, index, items) => {
|
|
@@ -645,16 +918,16 @@ function createProviderSubscriber({ provider, renderStyles, setStyleItems }) {
|
|
|
645
918
|
|
|
646
919
|
// src/components/style-renderer.tsx
|
|
647
920
|
function StyleRenderer() {
|
|
648
|
-
const container =
|
|
921
|
+
const container = usePortalContainer2();
|
|
649
922
|
const styleItems = useStyleItems();
|
|
650
923
|
const linksAttrs = useDocumentsCssLinks();
|
|
651
924
|
if (!container) {
|
|
652
925
|
return null;
|
|
653
926
|
}
|
|
654
|
-
return /* @__PURE__ */
|
|
927
|
+
return /* @__PURE__ */ React5.createElement(import_ui4.Portal, { container }, styleItems.map((item, i) => /* @__PURE__ */ React5.createElement("style", { key: `${item.id}-${i}-${item.breakpoint}` }, item.value)), linksAttrs.map((attrs) => /* @__PURE__ */ React5.createElement("link", { ...attrs, key: attrs.id })));
|
|
655
928
|
}
|
|
656
|
-
function
|
|
657
|
-
return (0,
|
|
929
|
+
function usePortalContainer2() {
|
|
930
|
+
return (0, import_editor_v1_adapters6.__privateUseListenTo)((0, import_editor_v1_adapters6.commandEndEvent)("editor/documents/attach-preview"), () => getCanvasIframeDocument()?.head);
|
|
658
931
|
}
|
|
659
932
|
|
|
660
933
|
// src/settings-transformers-registry.ts
|
|
@@ -666,48 +939,39 @@ function createTransformer(cb) {
|
|
|
666
939
|
}
|
|
667
940
|
|
|
668
941
|
// src/transformers/settings/attributes-transformer.ts
|
|
669
|
-
|
|
670
|
-
const specialChars = {
|
|
671
|
-
"&": "&",
|
|
672
|
-
"<": "<",
|
|
673
|
-
">": ">",
|
|
674
|
-
"'": "'",
|
|
675
|
-
'"': """
|
|
676
|
-
};
|
|
677
|
-
return value.replace(/[&<>'"]/g, (char) => specialChars[char] || char);
|
|
678
|
-
}
|
|
679
|
-
var attributesTransformer = createTransformer((values) => {
|
|
680
|
-
return values.map((value) => {
|
|
681
|
-
if (!value.key || !value.value) {
|
|
682
|
-
return "";
|
|
683
|
-
}
|
|
684
|
-
const escapedValue = escapeHtmlAttribute(value.value);
|
|
685
|
-
return `${value.key}="${escapedValue}"`;
|
|
686
|
-
}).join(" ");
|
|
687
|
-
});
|
|
942
|
+
var attributesTransformer = createTransformer(() => "");
|
|
688
943
|
|
|
689
944
|
// src/transformers/settings/classes-transformer.ts
|
|
690
945
|
var import_editor_styles_repository3 = require("@elementor/editor-styles-repository");
|
|
946
|
+
function transformClassId(id, cache) {
|
|
947
|
+
if (!cache.has(id)) {
|
|
948
|
+
const provider2 = import_editor_styles_repository3.stylesRepository.getProviders().find((p) => {
|
|
949
|
+
return p.actions.all().find((style) => style.id === id);
|
|
950
|
+
});
|
|
951
|
+
if (!provider2) {
|
|
952
|
+
return id;
|
|
953
|
+
}
|
|
954
|
+
cache.set(id, provider2.getKey());
|
|
955
|
+
}
|
|
956
|
+
const providerKey = cache.get(id);
|
|
957
|
+
const provider = import_editor_styles_repository3.stylesRepository.getProviderByKey(providerKey);
|
|
958
|
+
return provider?.actions.resolveCssName(id) ?? id;
|
|
959
|
+
}
|
|
691
960
|
function createClassesTransformer() {
|
|
692
961
|
const cache = /* @__PURE__ */ new Map();
|
|
693
962
|
return createTransformer((value) => {
|
|
694
|
-
return value.map((id) =>
|
|
695
|
-
if (!cache.has(id)) {
|
|
696
|
-
cache.set(id, getCssName(id));
|
|
697
|
-
}
|
|
698
|
-
return cache.get(id);
|
|
699
|
-
}).filter(Boolean);
|
|
963
|
+
return value.map((id) => transformClassId(id, cache)).filter(Boolean);
|
|
700
964
|
});
|
|
701
965
|
}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
}
|
|
966
|
+
|
|
967
|
+
// src/transformers/settings/date-time-transformer.ts
|
|
968
|
+
var dateTimeTransformer = createTransformer((values) => {
|
|
969
|
+
return values.map((value) => {
|
|
970
|
+
const date = (value.date || "").trim();
|
|
971
|
+
const time = (value.time || "").trim();
|
|
972
|
+
return !date && !time ? "" : `${date} ${time}`.trim();
|
|
973
|
+
}).join(" ");
|
|
974
|
+
});
|
|
711
975
|
|
|
712
976
|
// src/transformers/settings/link-transformer.ts
|
|
713
977
|
var linkTransformer = createTransformer(({ destination, isTargetBlank }) => {
|
|
@@ -718,6 +982,11 @@ var linkTransformer = createTransformer(({ destination, isTargetBlank }) => {
|
|
|
718
982
|
};
|
|
719
983
|
});
|
|
720
984
|
|
|
985
|
+
// src/transformers/settings/query-transformer.ts
|
|
986
|
+
var queryTransformer = createTransformer(({ id }) => {
|
|
987
|
+
return id ?? null;
|
|
988
|
+
});
|
|
989
|
+
|
|
721
990
|
// src/transformers/shared/image-src-transformer.ts
|
|
722
991
|
var imageSrcTransformer = createTransformer((value) => ({
|
|
723
992
|
id: value.id ?? null,
|
|
@@ -757,7 +1026,7 @@ var plainTransformer = createTransformer((value) => {
|
|
|
757
1026
|
|
|
758
1027
|
// src/init-settings-transformers.ts
|
|
759
1028
|
function initSettingsTransformers() {
|
|
760
|
-
settingsTransformersRegistry.register("classes", createClassesTransformer()).register("link", linkTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).register("attributes", attributesTransformer).registerFallback(plainTransformer);
|
|
1029
|
+
settingsTransformersRegistry.register("classes", createClassesTransformer()).register("link", linkTransformer).register("query", queryTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).register("attributes", attributesTransformer).register("date-time", dateTimeTransformer).registerFallback(plainTransformer);
|
|
761
1030
|
}
|
|
762
1031
|
|
|
763
1032
|
// src/transformers/styles/background-color-overlay-transformer.ts
|
|
@@ -855,10 +1124,11 @@ function getValuesString(items, prop, defaultValue, preventUnification = false)
|
|
|
855
1124
|
|
|
856
1125
|
// src/transformers/styles/background-transformer.ts
|
|
857
1126
|
var backgroundTransformer = createTransformer((value) => {
|
|
858
|
-
const { color = null, "background-overlay": overlays = null } = value;
|
|
1127
|
+
const { color = null, "background-overlay": overlays = null, clip = null } = value;
|
|
859
1128
|
return createMultiPropsValue({
|
|
860
1129
|
...overlays,
|
|
861
|
-
"background-color": color
|
|
1130
|
+
"background-color": color,
|
|
1131
|
+
"background-clip": clip
|
|
862
1132
|
});
|
|
863
1133
|
});
|
|
864
1134
|
|
|
@@ -984,11 +1254,19 @@ var transformMoveTransformer = createTransformer((value) => {
|
|
|
984
1254
|
|
|
985
1255
|
// src/transformers/styles/transform-origin-transformer.ts
|
|
986
1256
|
var EMPTY_VALUE = "0px";
|
|
1257
|
+
var DEFAULT_XY = "50%";
|
|
1258
|
+
var DEFAULT_Z = EMPTY_VALUE;
|
|
987
1259
|
function getVal2(val) {
|
|
988
1260
|
return `${val ?? EMPTY_VALUE}`;
|
|
989
1261
|
}
|
|
990
1262
|
var transformOriginTransformer = createTransformer((value) => {
|
|
991
|
-
|
|
1263
|
+
const x = getVal2(value.x);
|
|
1264
|
+
const y = getVal2(value.y);
|
|
1265
|
+
const z4 = getVal2(value.z);
|
|
1266
|
+
if (x === DEFAULT_XY && y === DEFAULT_XY && z4 === DEFAULT_Z) {
|
|
1267
|
+
return null;
|
|
1268
|
+
}
|
|
1269
|
+
return `${x} ${y} ${z4}`;
|
|
992
1270
|
});
|
|
993
1271
|
|
|
994
1272
|
// src/transformers/styles/transform-rotate-transformer.ts
|
|
@@ -1016,17 +1294,36 @@ var transformSkewTransformer = createTransformer((value) => {
|
|
|
1016
1294
|
});
|
|
1017
1295
|
|
|
1018
1296
|
// src/transformers/styles/transition-transformer.ts
|
|
1297
|
+
var import_editor_controls2 = require("@elementor/editor-controls");
|
|
1298
|
+
var getAllowedProperties = () => {
|
|
1299
|
+
const allowedProperties = /* @__PURE__ */ new Set();
|
|
1300
|
+
import_editor_controls2.transitionProperties.forEach((category) => {
|
|
1301
|
+
category.properties.forEach((property) => {
|
|
1302
|
+
allowedProperties.add(property.value);
|
|
1303
|
+
});
|
|
1304
|
+
});
|
|
1305
|
+
return allowedProperties;
|
|
1306
|
+
};
|
|
1019
1307
|
var transitionTransformer = createTransformer((transitionValues) => {
|
|
1020
1308
|
if (transitionValues?.length < 1) {
|
|
1021
1309
|
return null;
|
|
1022
1310
|
}
|
|
1023
|
-
|
|
1311
|
+
const allowedProperties = getAllowedProperties();
|
|
1312
|
+
const validTransitions = transitionValues.map((value) => mapToTransitionString(value, allowedProperties)).filter(Boolean);
|
|
1313
|
+
if (validTransitions.length === 0) {
|
|
1314
|
+
return null;
|
|
1315
|
+
}
|
|
1316
|
+
return validTransitions.join(", ");
|
|
1024
1317
|
});
|
|
1025
|
-
var mapToTransitionString = (value) => {
|
|
1318
|
+
var mapToTransitionString = (value, allowedProperties) => {
|
|
1026
1319
|
if (!value.selection || !value.size) {
|
|
1027
1320
|
return "";
|
|
1028
1321
|
}
|
|
1029
|
-
|
|
1322
|
+
const property = value.selection.value;
|
|
1323
|
+
if (!allowedProperties.has(property)) {
|
|
1324
|
+
return "";
|
|
1325
|
+
}
|
|
1326
|
+
return `${property} ${value.size}`;
|
|
1030
1327
|
};
|
|
1031
1328
|
|
|
1032
1329
|
// src/init-style-transformers.ts
|
|
@@ -1062,8 +1359,8 @@ function initStyleTransformers() {
|
|
|
1062
1359
|
}
|
|
1063
1360
|
|
|
1064
1361
|
// src/legacy/init-legacy-views.ts
|
|
1065
|
-
var
|
|
1066
|
-
var
|
|
1362
|
+
var import_editor_elements4 = require("@elementor/editor-elements");
|
|
1363
|
+
var import_editor_v1_adapters7 = require("@elementor/editor-v1-adapters");
|
|
1067
1364
|
|
|
1068
1365
|
// src/renderers/create-dom-renderer.ts
|
|
1069
1366
|
var import_twing = require("@elementor/twing");
|
|
@@ -1187,26 +1484,21 @@ function createElementViewClassDeclaration() {
|
|
|
1187
1484
|
}
|
|
1188
1485
|
|
|
1189
1486
|
// src/legacy/create-templated-element-type.ts
|
|
1190
|
-
function createTemplatedElementType({
|
|
1487
|
+
function createTemplatedElementType({
|
|
1488
|
+
type,
|
|
1489
|
+
renderer,
|
|
1490
|
+
element
|
|
1491
|
+
}) {
|
|
1191
1492
|
const legacyWindow = window;
|
|
1192
|
-
Object.entries(element.twig_templates).forEach(([key, template]) => {
|
|
1193
|
-
renderer.register(key, template);
|
|
1194
|
-
});
|
|
1195
|
-
const propsResolver = createPropsResolver({
|
|
1196
|
-
transformers: settingsTransformersRegistry,
|
|
1197
|
-
schema: element.atomic_props_schema
|
|
1198
|
-
});
|
|
1199
1493
|
return class extends legacyWindow.elementor.modules.elements.types.Widget {
|
|
1200
1494
|
getType() {
|
|
1201
1495
|
return type;
|
|
1202
1496
|
}
|
|
1203
1497
|
getView() {
|
|
1204
|
-
return
|
|
1498
|
+
return createTemplatedElementView({
|
|
1205
1499
|
type,
|
|
1206
1500
|
renderer,
|
|
1207
|
-
|
|
1208
|
-
baseStylesDictionary: element.base_styles_dictionary,
|
|
1209
|
-
templateKey: element.twig_main_template
|
|
1501
|
+
element
|
|
1210
1502
|
});
|
|
1211
1503
|
}
|
|
1212
1504
|
};
|
|
@@ -1214,14 +1506,21 @@ function createTemplatedElementType({ type, renderer, element }) {
|
|
|
1214
1506
|
function canBeTemplated(element) {
|
|
1215
1507
|
return !!(element.atomic_props_schema && element.twig_templates && element.twig_main_template && element.base_styles_dictionary);
|
|
1216
1508
|
}
|
|
1217
|
-
function
|
|
1509
|
+
function createTemplatedElementView({
|
|
1218
1510
|
type,
|
|
1219
1511
|
renderer,
|
|
1220
|
-
|
|
1221
|
-
templateKey,
|
|
1222
|
-
baseStylesDictionary
|
|
1512
|
+
element
|
|
1223
1513
|
}) {
|
|
1224
1514
|
const BaseView = createElementViewClassDeclaration();
|
|
1515
|
+
const templateKey = element.twig_main_template;
|
|
1516
|
+
const baseStylesDictionary = element.base_styles_dictionary;
|
|
1517
|
+
Object.entries(element.twig_templates).forEach(([key, template]) => {
|
|
1518
|
+
renderer.register(key, template);
|
|
1519
|
+
});
|
|
1520
|
+
const resolveProps = createPropsResolver({
|
|
1521
|
+
transformers: settingsTransformersRegistry,
|
|
1522
|
+
schema: element.atomic_props_schema
|
|
1523
|
+
});
|
|
1225
1524
|
return class extends BaseView {
|
|
1226
1525
|
#abortController = null;
|
|
1227
1526
|
getTemplateType() {
|
|
@@ -1230,67 +1529,915 @@ function createTemplatedElementViewClassDeclaration({
|
|
|
1230
1529
|
renderOnChange() {
|
|
1231
1530
|
this.render();
|
|
1232
1531
|
}
|
|
1233
|
-
//
|
|
1234
|
-
|
|
1235
|
-
|
|
1532
|
+
// Override `render` function to support async `_renderTemplate`
|
|
1533
|
+
// Note that `_renderChildren` asynchronity is still NOT supported, so only the parent element rendering can be async
|
|
1534
|
+
render() {
|
|
1236
1535
|
this.#abortController?.abort();
|
|
1237
1536
|
this.#abortController = new AbortController();
|
|
1238
|
-
const process = signalizedProcess(this.#abortController.signal).then((
|
|
1537
|
+
const process = signalizedProcess(this.#abortController.signal).then(() => this.#beforeRender()).then(() => this._renderTemplate()).then(() => {
|
|
1538
|
+
this._renderChildren();
|
|
1539
|
+
this.#afterRender();
|
|
1540
|
+
});
|
|
1541
|
+
return process.execute();
|
|
1542
|
+
}
|
|
1543
|
+
// Overriding Marionette original `_renderTemplate` method to inject our renderer.
|
|
1544
|
+
async _renderTemplate() {
|
|
1545
|
+
this.triggerMethod("before:render:template");
|
|
1546
|
+
const process = signalizedProcess(this.#abortController?.signal).then((_, signal) => {
|
|
1239
1547
|
const settings = this.model.get("settings").toJSON();
|
|
1240
1548
|
return resolveProps({
|
|
1241
1549
|
props: settings,
|
|
1242
1550
|
signal
|
|
1243
1551
|
});
|
|
1244
|
-
}).then((
|
|
1552
|
+
}).then((settings) => {
|
|
1553
|
+
return this.afterSettingsResolve(settings);
|
|
1554
|
+
}).then(async (settings) => {
|
|
1245
1555
|
const context = {
|
|
1246
1556
|
id: this.model.get("id"),
|
|
1247
1557
|
type,
|
|
1248
|
-
settings
|
|
1558
|
+
settings,
|
|
1249
1559
|
base_styles: baseStylesDictionary
|
|
1250
1560
|
};
|
|
1251
1561
|
return renderer.render(templateKey, context);
|
|
1252
1562
|
}).then((html) => this.$el.html(html));
|
|
1253
1563
|
await process.execute();
|
|
1254
|
-
this.#afterRenderTemplate();
|
|
1255
|
-
}
|
|
1256
|
-
// Emulating the original Marionette behavior.
|
|
1257
|
-
#beforeRenderTemplate() {
|
|
1258
|
-
this.triggerMethod("before:render:template");
|
|
1259
|
-
}
|
|
1260
|
-
#afterRenderTemplate() {
|
|
1261
1564
|
this.bindUIElements();
|
|
1262
1565
|
this.triggerMethod("render:template");
|
|
1263
1566
|
}
|
|
1567
|
+
afterSettingsResolve(settings) {
|
|
1568
|
+
return settings;
|
|
1569
|
+
}
|
|
1570
|
+
#beforeRender() {
|
|
1571
|
+
this._ensureViewIsIntact();
|
|
1572
|
+
this._isRendering = true;
|
|
1573
|
+
this.resetChildViewContainer();
|
|
1574
|
+
this.triggerMethod("before:render", this);
|
|
1575
|
+
}
|
|
1576
|
+
#afterRender() {
|
|
1577
|
+
this._isRendering = false;
|
|
1578
|
+
this.isRendered = true;
|
|
1579
|
+
this.triggerMethod("render", this);
|
|
1580
|
+
}
|
|
1264
1581
|
};
|
|
1265
1582
|
}
|
|
1266
1583
|
|
|
1267
1584
|
// src/legacy/init-legacy-views.ts
|
|
1585
|
+
var elementsLegacyTypes = {};
|
|
1586
|
+
function registerElementType(type, elementTypeGenerator) {
|
|
1587
|
+
elementsLegacyTypes[type] = elementTypeGenerator;
|
|
1588
|
+
}
|
|
1268
1589
|
function initLegacyViews() {
|
|
1269
|
-
(0,
|
|
1270
|
-
const config = (0,
|
|
1590
|
+
(0, import_editor_v1_adapters7.__privateListenTo)((0, import_editor_v1_adapters7.v1ReadyEvent)(), () => {
|
|
1591
|
+
const config = (0, import_editor_elements4.getWidgetsCache)() ?? {};
|
|
1271
1592
|
const legacyWindow = window;
|
|
1272
1593
|
const renderer = createDomRenderer();
|
|
1273
1594
|
Object.entries(config).forEach(([type, element]) => {
|
|
1274
1595
|
if (!element.atomic) {
|
|
1275
1596
|
return;
|
|
1276
1597
|
}
|
|
1277
|
-
|
|
1598
|
+
let ElementType;
|
|
1599
|
+
if (!!elementsLegacyTypes[type] && canBeTemplated(element)) {
|
|
1600
|
+
ElementType = elementsLegacyTypes[type]({ type, renderer, element });
|
|
1601
|
+
} else if (canBeTemplated(element)) {
|
|
1602
|
+
ElementType = createTemplatedElementType({ type, renderer, element });
|
|
1603
|
+
} else {
|
|
1604
|
+
ElementType = createElementType(type);
|
|
1605
|
+
}
|
|
1278
1606
|
legacyWindow.elementor.elementsManager.registerElementType(new ElementType());
|
|
1279
1607
|
});
|
|
1280
1608
|
});
|
|
1281
1609
|
}
|
|
1282
1610
|
|
|
1611
|
+
// src/mcp/resources/widgets-schema-resource.ts
|
|
1612
|
+
var import_editor_elements5 = require("@elementor/editor-elements");
|
|
1613
|
+
var import_editor_mcp = require("@elementor/editor-mcp");
|
|
1614
|
+
var import_editor_props3 = require("@elementor/editor-props");
|
|
1615
|
+
var import_editor_styles4 = require("@elementor/editor-styles");
|
|
1616
|
+
var WIDGET_SCHEMA_URI = "elementor://widgets/schema/{widgetType}";
|
|
1617
|
+
var STYLE_SCHEMA_URI = "elementor://styles/schema/{category}";
|
|
1618
|
+
var BEST_PRACTICES_URI = "elementor://styles/best-practices";
|
|
1619
|
+
var initWidgetsSchemaResource = (reg) => {
|
|
1620
|
+
const { mcpServer } = reg;
|
|
1621
|
+
mcpServer.resource("styles-best-practices", BEST_PRACTICES_URI, async () => {
|
|
1622
|
+
return {
|
|
1623
|
+
contents: [
|
|
1624
|
+
{
|
|
1625
|
+
uri: BEST_PRACTICES_URI,
|
|
1626
|
+
text: `# Styling best practices
|
|
1627
|
+
Prefer using "em" and "rem" values for text-related sizes, padding and spacing. Use percentages for dynamic sizing relative to parent containers.
|
|
1628
|
+
This flexboxes are by default "flex" with "stretch" alignment. To ensure proper layout, define the "justify-content" and "align-items" as in the schema, or in custom_css, depends on your needs.
|
|
1629
|
+
|
|
1630
|
+
When applicable for styles, use the "custom_css" property for free-form CSS styling. This property accepts a string of CSS rules that will be applied directly to the element.
|
|
1631
|
+
The css string must follow standard CSS syntax, with properties and values separated by semicolons, no selectors, or nesting rules allowed.`
|
|
1632
|
+
}
|
|
1633
|
+
]
|
|
1634
|
+
};
|
|
1635
|
+
});
|
|
1636
|
+
mcpServer.resource(
|
|
1637
|
+
"styles-schema",
|
|
1638
|
+
new import_editor_mcp.ResourceTemplate(STYLE_SCHEMA_URI, {
|
|
1639
|
+
list: () => {
|
|
1640
|
+
const categories = [...Object.keys((0, import_editor_styles4.getStylesSchema)()), "custom_css"];
|
|
1641
|
+
return {
|
|
1642
|
+
resources: categories.map((category) => ({
|
|
1643
|
+
uri: `elementor://styles/schema/${category}`,
|
|
1644
|
+
name: "Style schema for " + category
|
|
1645
|
+
}))
|
|
1646
|
+
};
|
|
1647
|
+
}
|
|
1648
|
+
}),
|
|
1649
|
+
{
|
|
1650
|
+
description: "Common styles schema for the specified category"
|
|
1651
|
+
},
|
|
1652
|
+
async (uri, variables) => {
|
|
1653
|
+
const category = typeof variables.category === "string" ? variables.category : variables.category?.[0];
|
|
1654
|
+
if (category === "custom_css") {
|
|
1655
|
+
return {
|
|
1656
|
+
contents: [
|
|
1657
|
+
{
|
|
1658
|
+
uri: uri.toString(),
|
|
1659
|
+
text: "Free style inline CSS string of properties and their values. Applicable for a single element, only the properties and values are accepted. Use this as a last resort for properties that are not covered with the schema."
|
|
1660
|
+
}
|
|
1661
|
+
]
|
|
1662
|
+
};
|
|
1663
|
+
}
|
|
1664
|
+
const stylesSchema = (0, import_editor_styles4.getStylesSchema)()[category];
|
|
1665
|
+
if (!stylesSchema) {
|
|
1666
|
+
throw new Error(`No styles schema found for category: ${category}`);
|
|
1667
|
+
}
|
|
1668
|
+
const cleanedupPropSchema = cleanupPropType(stylesSchema);
|
|
1669
|
+
const asJson = import_editor_props3.Schema.propTypeToJsonSchema(cleanedupPropSchema);
|
|
1670
|
+
return {
|
|
1671
|
+
contents: [
|
|
1672
|
+
{
|
|
1673
|
+
uri: uri.toString(),
|
|
1674
|
+
text: JSON.stringify(asJson)
|
|
1675
|
+
}
|
|
1676
|
+
]
|
|
1677
|
+
};
|
|
1678
|
+
}
|
|
1679
|
+
);
|
|
1680
|
+
mcpServer.resource(
|
|
1681
|
+
"widget-schema-by-type",
|
|
1682
|
+
new import_editor_mcp.ResourceTemplate(WIDGET_SCHEMA_URI, {
|
|
1683
|
+
list: () => {
|
|
1684
|
+
const cache = (0, import_editor_elements5.getWidgetsCache)() || {};
|
|
1685
|
+
const availableWidgets = Object.keys(cache || {}).filter(
|
|
1686
|
+
(widgetType) => cache[widgetType]?.atomic_props_schema
|
|
1687
|
+
);
|
|
1688
|
+
return {
|
|
1689
|
+
resources: availableWidgets.map((widgetType) => ({
|
|
1690
|
+
uri: `elementor://widgets/schema/${widgetType}`,
|
|
1691
|
+
name: "Widget schema for " + widgetType
|
|
1692
|
+
}))
|
|
1693
|
+
};
|
|
1694
|
+
}
|
|
1695
|
+
}),
|
|
1696
|
+
{
|
|
1697
|
+
description: "PropType schema for the specified widget type"
|
|
1698
|
+
},
|
|
1699
|
+
async (uri, variables) => {
|
|
1700
|
+
const widgetType = typeof variables.widgetType === "string" ? variables.widgetType : variables.widgetType?.[0];
|
|
1701
|
+
const propSchema = (0, import_editor_elements5.getWidgetsCache)()?.[widgetType]?.atomic_props_schema;
|
|
1702
|
+
if (!propSchema) {
|
|
1703
|
+
throw new Error(`No prop schema found for element type: ${widgetType}`);
|
|
1704
|
+
}
|
|
1705
|
+
const cleanedupPropSchema = cleanupPropSchema(propSchema);
|
|
1706
|
+
const asJson = Object.fromEntries(
|
|
1707
|
+
Object.entries(cleanedupPropSchema).map(([key, propType]) => [
|
|
1708
|
+
key,
|
|
1709
|
+
import_editor_props3.Schema.propTypeToJsonSchema(propType)
|
|
1710
|
+
])
|
|
1711
|
+
);
|
|
1712
|
+
import_editor_props3.Schema.nonConfigurablePropKeys.forEach((key) => {
|
|
1713
|
+
delete asJson[key];
|
|
1714
|
+
});
|
|
1715
|
+
return {
|
|
1716
|
+
contents: [
|
|
1717
|
+
{
|
|
1718
|
+
uri: uri.toString(),
|
|
1719
|
+
text: JSON.stringify(asJson)
|
|
1720
|
+
}
|
|
1721
|
+
]
|
|
1722
|
+
};
|
|
1723
|
+
}
|
|
1724
|
+
);
|
|
1725
|
+
};
|
|
1726
|
+
function cleanupPropSchema(propSchema) {
|
|
1727
|
+
const result = {};
|
|
1728
|
+
Object.keys(propSchema).forEach((propName) => {
|
|
1729
|
+
result[propName] = cleanupPropType(propSchema[propName]);
|
|
1730
|
+
});
|
|
1731
|
+
return result;
|
|
1732
|
+
}
|
|
1733
|
+
function cleanupPropType(propType) {
|
|
1734
|
+
const result = {};
|
|
1735
|
+
Object.keys(propType).forEach((property) => {
|
|
1736
|
+
switch (property) {
|
|
1737
|
+
case "key":
|
|
1738
|
+
case "kind":
|
|
1739
|
+
result[property] = propType[property];
|
|
1740
|
+
break;
|
|
1741
|
+
case "meta":
|
|
1742
|
+
case "settings":
|
|
1743
|
+
{
|
|
1744
|
+
if (Object.keys(propType[property] || {}).length > 0) {
|
|
1745
|
+
result[property] = propType[property];
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
break;
|
|
1749
|
+
}
|
|
1750
|
+
});
|
|
1751
|
+
if (result.kind === "plain") {
|
|
1752
|
+
Object.defineProperty(result, "kind", { value: "string" });
|
|
1753
|
+
} else if (result.kind === "array") {
|
|
1754
|
+
result.item_prop_type = cleanupPropType(propType.item_prop_type);
|
|
1755
|
+
} else if (result.kind === "object") {
|
|
1756
|
+
const shape = propType.shape;
|
|
1757
|
+
const cleanedShape = cleanupPropSchema(shape);
|
|
1758
|
+
result.shape = cleanedShape;
|
|
1759
|
+
} else if (result.kind === "union") {
|
|
1760
|
+
const propTypes = propType.prop_types;
|
|
1761
|
+
const cleanedPropTypes = {};
|
|
1762
|
+
Object.keys(propTypes).forEach((key) => {
|
|
1763
|
+
cleanedPropTypes[key] = cleanupPropType(propTypes[key]);
|
|
1764
|
+
});
|
|
1765
|
+
result.prop_types = cleanedPropTypes;
|
|
1766
|
+
}
|
|
1767
|
+
return result;
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
// src/mcp/tools/build-composition/tool.ts
|
|
1771
|
+
var import_editor_elements7 = require("@elementor/editor-elements");
|
|
1772
|
+
|
|
1773
|
+
// src/mcp/utils/do-update-element-property.ts
|
|
1774
|
+
var import_editor_elements6 = require("@elementor/editor-elements");
|
|
1775
|
+
var import_editor_props4 = require("@elementor/editor-props");
|
|
1776
|
+
var import_editor_styles5 = require("@elementor/editor-styles");
|
|
1777
|
+
function resolvePropValue(value, forceKey) {
|
|
1778
|
+
return import_editor_props4.Schema.adjustLlmPropValueSchema(value, forceKey);
|
|
1779
|
+
}
|
|
1780
|
+
var doUpdateElementProperty = (params) => {
|
|
1781
|
+
const { elementId, propertyName, propertyValue, elementType } = params;
|
|
1782
|
+
if (propertyName === "_styles") {
|
|
1783
|
+
const elementStyles = (0, import_editor_elements6.getElementStyles)(elementId) || {};
|
|
1784
|
+
const propertyMapValue = propertyValue;
|
|
1785
|
+
const styleSchema = (0, import_editor_styles5.getStylesSchema)();
|
|
1786
|
+
const transformedStyleValues = Object.fromEntries(
|
|
1787
|
+
Object.entries(propertyMapValue).map(([key, val]) => {
|
|
1788
|
+
if (key === "custom_css") {
|
|
1789
|
+
return [key, val];
|
|
1790
|
+
}
|
|
1791
|
+
const { key: propKey, kind } = styleSchema?.[key] || {};
|
|
1792
|
+
if (!propKey && kind !== "union") {
|
|
1793
|
+
throw new Error(`_styles property ${key} is not supported.`);
|
|
1794
|
+
}
|
|
1795
|
+
return [key, resolvePropValue(val, propKey)];
|
|
1796
|
+
})
|
|
1797
|
+
);
|
|
1798
|
+
let customCss;
|
|
1799
|
+
Object.keys(propertyMapValue).forEach((stylePropName) => {
|
|
1800
|
+
const propertyRawSchema = styleSchema[stylePropName];
|
|
1801
|
+
if (stylePropName === "custom_css") {
|
|
1802
|
+
let customCssValue = propertyMapValue[stylePropName];
|
|
1803
|
+
if (typeof customCssValue === "object") {
|
|
1804
|
+
customCssValue = import_editor_props4.stringPropTypeUtil.extract(customCssValue) || customCssValue?.value || "";
|
|
1805
|
+
}
|
|
1806
|
+
customCss = {
|
|
1807
|
+
raw: btoa(customCssValue)
|
|
1808
|
+
};
|
|
1809
|
+
return;
|
|
1810
|
+
}
|
|
1811
|
+
const isSupported = !!propertyRawSchema;
|
|
1812
|
+
if (!isSupported) {
|
|
1813
|
+
throw new Error(`_styles property ${stylePropName} is not supported.`);
|
|
1814
|
+
}
|
|
1815
|
+
if (propertyRawSchema.kind === "plain") {
|
|
1816
|
+
if (typeof propertyMapValue[stylePropName] !== "object") {
|
|
1817
|
+
const propUtil = (0, import_editor_props4.getPropSchemaFromCache)(propertyRawSchema.key);
|
|
1818
|
+
if (propUtil) {
|
|
1819
|
+
const plainValue = propUtil.create(propertyMapValue[stylePropName]);
|
|
1820
|
+
propertyMapValue[stylePropName] = plainValue;
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
});
|
|
1825
|
+
const localStyle = Object.values(elementStyles).find((style) => style.label === "local");
|
|
1826
|
+
if (!localStyle) {
|
|
1827
|
+
(0, import_editor_elements6.createElementStyle)({
|
|
1828
|
+
elementId,
|
|
1829
|
+
...typeof customCss !== "undefined" ? { custom_css: customCss } : {},
|
|
1830
|
+
classesProp: "classes",
|
|
1831
|
+
label: "local",
|
|
1832
|
+
meta: {
|
|
1833
|
+
breakpoint: "desktop",
|
|
1834
|
+
state: null
|
|
1835
|
+
},
|
|
1836
|
+
props: {
|
|
1837
|
+
...transformedStyleValues
|
|
1838
|
+
}
|
|
1839
|
+
});
|
|
1840
|
+
} else {
|
|
1841
|
+
(0, import_editor_elements6.updateElementStyle)({
|
|
1842
|
+
elementId,
|
|
1843
|
+
styleId: localStyle.id,
|
|
1844
|
+
meta: {
|
|
1845
|
+
breakpoint: "desktop",
|
|
1846
|
+
state: null
|
|
1847
|
+
},
|
|
1848
|
+
...typeof customCss !== "undefined" ? { custom_css: customCss } : {},
|
|
1849
|
+
props: {
|
|
1850
|
+
...transformedStyleValues
|
|
1851
|
+
}
|
|
1852
|
+
});
|
|
1853
|
+
}
|
|
1854
|
+
return;
|
|
1855
|
+
}
|
|
1856
|
+
const elementPropSchema = (0, import_editor_elements6.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
|
|
1857
|
+
if (!elementPropSchema) {
|
|
1858
|
+
throw new Error(`No prop schema found for element type: ${elementType}`);
|
|
1859
|
+
}
|
|
1860
|
+
if (!elementPropSchema[propertyName]) {
|
|
1861
|
+
const propertyNames = Object.keys(elementPropSchema);
|
|
1862
|
+
throw new Error(
|
|
1863
|
+
`Property "${propertyName}" does not exist on element type "${elementType}". Available properties are: ${propertyNames.join(
|
|
1864
|
+
", "
|
|
1865
|
+
)}`
|
|
1866
|
+
);
|
|
1867
|
+
}
|
|
1868
|
+
const value = resolvePropValue(propertyValue);
|
|
1869
|
+
(0, import_editor_elements6.updateElementSettings)({
|
|
1870
|
+
id: elementId,
|
|
1871
|
+
props: {
|
|
1872
|
+
[propertyName]: value
|
|
1873
|
+
},
|
|
1874
|
+
withHistory: false
|
|
1875
|
+
});
|
|
1876
|
+
};
|
|
1877
|
+
|
|
1878
|
+
// src/mcp/tools/build-composition/prompt.ts
|
|
1879
|
+
var import_editor_mcp2 = require("@elementor/editor-mcp");
|
|
1880
|
+
var generatePrompt = () => {
|
|
1881
|
+
const buildCompositionsToolPrompt = (0, import_editor_mcp2.toolPrompts)("build-compositions");
|
|
1882
|
+
buildCompositionsToolPrompt.description(`
|
|
1883
|
+
Build entire elementor widget comositions representing complex structures of nested elements.
|
|
1884
|
+
|
|
1885
|
+
# When to use this tool
|
|
1886
|
+
Always prefer this tool when the user requires to build a composition of elements, such as cards, heros, or inspired from other pages or HTML compositions.
|
|
1887
|
+
Prefer this tool over any other tool for building HTML structure, unless you are specified to use a different tool.
|
|
1888
|
+
|
|
1889
|
+
# **CRITICAL - REQUIRED RESOURCES (Must read before using this tool)**
|
|
1890
|
+
1. [${WIDGET_SCHEMA_URI}]
|
|
1891
|
+
Required to understand which widgets are available, and what are their configuration schemas.
|
|
1892
|
+
Every widgetType (i.e. e-heading, e-button) that is supported has it's own property schema, that you must follow in order to apply property values correctly.
|
|
1893
|
+
2. [${STYLE_SCHEMA_URI}]
|
|
1894
|
+
Required to understand the styles schema for the widgets. All widgets share the same styles schema.
|
|
1895
|
+
3. List of allowed custom tags for building the structure is derived from the list of widgets schema resources.
|
|
1896
|
+
|
|
1897
|
+
# Instructions
|
|
1898
|
+
1. Understand the user requirements carefully.
|
|
1899
|
+
2. Build a valid XML structure using only the allowed custom tags provided. For example, if you
|
|
1900
|
+
use the "e-button" element, it would be represented as <e-button></e-button> in the XML structure.
|
|
1901
|
+
3. Plan the configuration for each element according to the user requirements, using the configuration schema provided for each custom tag.
|
|
1902
|
+
Every widget type has it's own configuration schema, retreivable from the resource [${WIDGET_SCHEMA_URI}].
|
|
1903
|
+
PropValues must follow the exact PropType schema provided in the resource.
|
|
1904
|
+
4. For every element, provide a "configuration-id" attribute. For example:
|
|
1905
|
+
\`<e-flexbox configuration-id="flex1"><e-heading configuration-id="heading2"></e-heading></e-flexbox>\`
|
|
1906
|
+
In the elementConfig property, provide the actual configuration object for each configuration-id used in the XML structure.
|
|
1907
|
+
In the stylesConfig property, provide the actual styles configuration object for each configuration-id used in the XML structure.
|
|
1908
|
+
5. Ensure the XML structure is valid and parsable.
|
|
1909
|
+
6. Do not add any attribute nodes, classes, id's, and no text nodes allowed.
|
|
1910
|
+
Layout properties, such as margin, padding, align, etc. must be applied using the [${STYLE_SCHEMA_URI}] PropValues.
|
|
1911
|
+
7. Some elements allow nesting of other elements, and most of the DO NOT. The allowed elements that can have nested children are "e-div-block" and "e-flexbox".
|
|
1912
|
+
8. Make sure that non-container elements do NOT have any nested elements.
|
|
1913
|
+
9. Unsless the user specifically requires structure only, BE EXPRESSIVE AND VISUALLY CREATIVE AS POSSIBLE IN APPLYING STYLE CONFIGURATION.
|
|
1914
|
+
In the case of doubt, prefer adding more styles to make the composition visually appealing.
|
|
1915
|
+
|
|
1916
|
+
# Additional Guidelines
|
|
1917
|
+
- Most users expect the structure to be well designed and visually appealing.
|
|
1918
|
+
- Use layout properties, ensure "white space" design approach is followed, and make sure the composition is visually balanced.
|
|
1919
|
+
- Use appropriate spacing, alignment, and sizing to create a harmonious layout.
|
|
1920
|
+
- Consider the visual hierarchy of elements to guide the user's attention effectively.
|
|
1921
|
+
- You are encouraged to use colors, typography, and other style properties to enhance the visual appeal, as long as they are part of the configuration schema for the elements used.
|
|
1922
|
+
- Always aim for a clean and professional look that aligns with modern design principles.
|
|
1923
|
+
- When you are required to create placeholder texts, use texts that have a length that fits the goal. When long texts are required, use longer placeholder texts. When the user specifies exact texts, use the exact texts.
|
|
1924
|
+
- Image size does not affect the actual size on the screen, only which quality to use. If you use images, specifically add _styles PropValues to define the image sizes.
|
|
1925
|
+
- Attempt to use layout, margin, padding, size properties from the styles schema.
|
|
1926
|
+
- If your elements library is limited, encourage use of nesting containers to achieve complex layouts.
|
|
1927
|
+
|
|
1928
|
+
# CONSTRAINTS
|
|
1929
|
+
When a tool execution fails, retry up to 10 more times, read the error message carefully, and adjust the XML structure or the configurations accordingly.
|
|
1930
|
+
If a "$$type" is missing, update the invalid object, if the XML has parsing errors, fix it, etc. and RETRY.
|
|
1931
|
+
VALIDATE the XML structure before delivering it as the final result.
|
|
1932
|
+
VALIDATE the JSON structure used in the "configuration" attributes for each element before delivering the final result. The configuration must MATCH the PropValue schemas.
|
|
1933
|
+
NO LINKS ALLOWED. Never apply links to elements, even if they appear in the PropType schema.
|
|
1934
|
+
elementConfig values must align with the widget's PropType schema, available at the resource [${WIDGET_SCHEMA_URI}].
|
|
1935
|
+
stylesConfig values must align with the common styles PropType schema, available at the resource [${STYLE_SCHEMA_URI}].
|
|
1936
|
+
|
|
1937
|
+
# Parameters
|
|
1938
|
+
All parameters are MANDATORY.
|
|
1939
|
+
- xmlStructure
|
|
1940
|
+
- elementConfig
|
|
1941
|
+
- stylesConfig
|
|
1942
|
+
|
|
1943
|
+
If unsure about the configuration of a specific property, read the schema resources carefully.
|
|
1944
|
+
|
|
1945
|
+
|
|
1946
|
+
`);
|
|
1947
|
+
buildCompositionsToolPrompt.example(`
|
|
1948
|
+
A Heading and a button inside a flexbox
|
|
1949
|
+
{
|
|
1950
|
+
xmlStructure: "<e-flexbox configuration-id="flex1"><e-heading configuration-id="heading1"></e-heading><e-button configuration-id="button1"></e-button></e-flexbox>"
|
|
1951
|
+
elementConfig: {
|
|
1952
|
+
"flex1": {
|
|
1953
|
+
"tag": {
|
|
1954
|
+
"$$type": "string",
|
|
1955
|
+
"value": "section"
|
|
1956
|
+
},
|
|
1957
|
+
},
|
|
1958
|
+
stylesConfig: {
|
|
1959
|
+
"heading1": {
|
|
1960
|
+
"font-size": {
|
|
1961
|
+
"$$type": "size",
|
|
1962
|
+
"value": {
|
|
1963
|
+
"size": { "$$type": "number", "value": 24 },
|
|
1964
|
+
"unit": { "$$type": "string", "value": "px" }
|
|
1965
|
+
}
|
|
1966
|
+
},
|
|
1967
|
+
"color": {
|
|
1968
|
+
"$$type": "color",
|
|
1969
|
+
"value": { "$$type": "string", "value": "#333" }
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
},
|
|
1973
|
+
}
|
|
1974
|
+
`);
|
|
1975
|
+
buildCompositionsToolPrompt.parameter(
|
|
1976
|
+
"xmlStructure",
|
|
1977
|
+
`**MANDATORY** A valid XML structure representing the composition to be built, using custom elementor tags, styling and configuration PropValues.`
|
|
1978
|
+
);
|
|
1979
|
+
buildCompositionsToolPrompt.parameter(
|
|
1980
|
+
"elementConfig",
|
|
1981
|
+
`**MANDATORY** A record mapping configuration IDs to their corresponding configuration objects, defining the PropValues for each element created.`
|
|
1982
|
+
);
|
|
1983
|
+
buildCompositionsToolPrompt.parameter(
|
|
1984
|
+
"stylesConfig",
|
|
1985
|
+
`**MANDATORY** A record mapping style PropTypes to their corresponding style configuration objects, defining the PropValues for styles to be applied to elements.`
|
|
1986
|
+
);
|
|
1987
|
+
buildCompositionsToolPrompt.instruction(
|
|
1988
|
+
`You will be provided the XML structure with element IDs. These IDs represent the actual elementor widgets created on the page/post.
|
|
1989
|
+
You should use these IDs as reference for further configuration, styling or changing elements later on.`
|
|
1990
|
+
);
|
|
1991
|
+
buildCompositionsToolPrompt.instruction(
|
|
1992
|
+
`You must use styles/variables/classes that are available in the project resources, you should prefer using them over inline styles, and you are welcome to execute relevant tools AFTER this tool execution, to apply global classes to the created elements.`
|
|
1993
|
+
);
|
|
1994
|
+
return buildCompositionsToolPrompt.prompt();
|
|
1995
|
+
};
|
|
1996
|
+
|
|
1997
|
+
// src/mcp/tools/build-composition/schema.ts
|
|
1998
|
+
var import_schema = require("@elementor/schema");
|
|
1999
|
+
var inputSchema = {
|
|
2000
|
+
xmlStructure: import_schema.z.string().describe("The XML structure representing the composition to be built"),
|
|
2001
|
+
elementConfig: import_schema.z.record(
|
|
2002
|
+
import_schema.z.string().describe("The configuration id"),
|
|
2003
|
+
import_schema.z.record(import_schema.z.string().describe("property name"), import_schema.z.any().describe("The PropValue for the property"))
|
|
2004
|
+
).describe("A record mapping element IDs to their configuration objects. REQUIRED"),
|
|
2005
|
+
stylesConfig: import_schema.z.record(
|
|
2006
|
+
import_schema.z.string().describe("The configuration id"),
|
|
2007
|
+
import_schema.z.record(
|
|
2008
|
+
import_schema.z.string().describe("_styles property name"),
|
|
2009
|
+
import_schema.z.any().describe("The PropValue for the style property. MANDATORY")
|
|
2010
|
+
)
|
|
2011
|
+
).describe(
|
|
2012
|
+
`A record mapping element IDs to their styles configuration objects. Use the actual styles schema from [${STYLE_SCHEMA_URI}].`
|
|
2013
|
+
).default({})
|
|
2014
|
+
};
|
|
2015
|
+
var outputSchema = {
|
|
2016
|
+
errors: import_schema.z.string().describe("Error message if the composition building failed").optional(),
|
|
2017
|
+
xmlStructure: import_schema.z.string().describe("The built XML structure as a string").optional(),
|
|
2018
|
+
llmInstructions: import_schema.z.string().describe("Instructions used to further actions for you").optional()
|
|
2019
|
+
};
|
|
2020
|
+
|
|
2021
|
+
// src/mcp/tools/build-composition/tool.ts
|
|
2022
|
+
var initBuildCompositionsTool = (reg) => {
|
|
2023
|
+
const { addTool } = reg;
|
|
2024
|
+
addTool({
|
|
2025
|
+
name: "build-compositions",
|
|
2026
|
+
description: generatePrompt(),
|
|
2027
|
+
schema: inputSchema,
|
|
2028
|
+
outputSchema,
|
|
2029
|
+
handler: async (params) => {
|
|
2030
|
+
let xml = null;
|
|
2031
|
+
const { xmlStructure, elementConfig, stylesConfig } = params;
|
|
2032
|
+
const errors = [];
|
|
2033
|
+
const softErrors = [];
|
|
2034
|
+
const rootContainers = [];
|
|
2035
|
+
const widgetsCache = (0, import_editor_elements7.getWidgetsCache)() || {};
|
|
2036
|
+
const documentContainer = (0, import_editor_elements7.getContainer)("document");
|
|
2037
|
+
try {
|
|
2038
|
+
const parser = new DOMParser();
|
|
2039
|
+
xml = parser.parseFromString(xmlStructure, "application/xml");
|
|
2040
|
+
const errorNode = xml.querySelector("parsererror");
|
|
2041
|
+
if (errorNode) {
|
|
2042
|
+
throw new Error("Failed to parse XML structure: " + errorNode.textContent);
|
|
2043
|
+
}
|
|
2044
|
+
const children = Array.from(xml.children);
|
|
2045
|
+
const iterate = (node, containerElement = documentContainer) => {
|
|
2046
|
+
const elementTag = node.tagName;
|
|
2047
|
+
if (!widgetsCache[elementTag]) {
|
|
2048
|
+
errors.push(new Error(`Unknown widget type: ${elementTag}`));
|
|
2049
|
+
}
|
|
2050
|
+
const isContainer = elementTag === "e-flexbox" || elementTag === "e-div-block";
|
|
2051
|
+
const newElement = isContainer ? (0, import_editor_elements7.createElement)({
|
|
2052
|
+
containerId: containerElement.id,
|
|
2053
|
+
model: {
|
|
2054
|
+
elType: elementTag,
|
|
2055
|
+
id: (0, import_editor_elements7.generateElementId)()
|
|
2056
|
+
},
|
|
2057
|
+
options: { useHistory: false }
|
|
2058
|
+
}) : (0, import_editor_elements7.createElement)({
|
|
2059
|
+
containerId: containerElement.id,
|
|
2060
|
+
model: {
|
|
2061
|
+
elType: "widget",
|
|
2062
|
+
widgetType: elementTag,
|
|
2063
|
+
id: (0, import_editor_elements7.generateElementId)()
|
|
2064
|
+
},
|
|
2065
|
+
options: { useHistory: false }
|
|
2066
|
+
});
|
|
2067
|
+
if (containerElement === documentContainer) {
|
|
2068
|
+
rootContainers.push(newElement);
|
|
2069
|
+
}
|
|
2070
|
+
node.setAttribute("id", newElement.id);
|
|
2071
|
+
const configId = node.getAttribute("configuration-id") || "";
|
|
2072
|
+
try {
|
|
2073
|
+
const configObject = elementConfig[configId] || {};
|
|
2074
|
+
const styleObject = stylesConfig[configId] || {};
|
|
2075
|
+
configObject._styles = styleObject;
|
|
2076
|
+
for (const [propertyName, propertyValue] of Object.entries(configObject)) {
|
|
2077
|
+
const widgetSchema = widgetsCache[elementTag];
|
|
2078
|
+
if (!widgetSchema?.atomic_props_schema?.[propertyName] && propertyName !== "_styles" && propertyName !== "custom_css") {
|
|
2079
|
+
softErrors.push(
|
|
2080
|
+
new Error(
|
|
2081
|
+
`Property "${propertyName}" does not exist on element type "${elementTag}".`
|
|
2082
|
+
)
|
|
2083
|
+
);
|
|
2084
|
+
continue;
|
|
2085
|
+
}
|
|
2086
|
+
try {
|
|
2087
|
+
doUpdateElementProperty({
|
|
2088
|
+
elementId: newElement.id,
|
|
2089
|
+
propertyName,
|
|
2090
|
+
propertyValue: propertyName === "custom_css" ? { _styles: propertyValue } : propertyValue,
|
|
2091
|
+
elementType: elementTag
|
|
2092
|
+
});
|
|
2093
|
+
} catch (error) {
|
|
2094
|
+
softErrors.push(error);
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
if (isContainer) {
|
|
2098
|
+
for (const child of node.children) {
|
|
2099
|
+
iterate(child, newElement);
|
|
2100
|
+
}
|
|
2101
|
+
} else {
|
|
2102
|
+
node.innerHTML = "";
|
|
2103
|
+
node.removeAttribute("configuration");
|
|
2104
|
+
}
|
|
2105
|
+
} finally {
|
|
2106
|
+
}
|
|
2107
|
+
};
|
|
2108
|
+
for (const childNode of children) {
|
|
2109
|
+
iterate(childNode, documentContainer);
|
|
2110
|
+
try {
|
|
2111
|
+
} catch (error) {
|
|
2112
|
+
errors.push(error);
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
} catch (error) {
|
|
2116
|
+
errors.push(error);
|
|
2117
|
+
}
|
|
2118
|
+
if (errors.length) {
|
|
2119
|
+
rootContainers.forEach((rootContainer) => {
|
|
2120
|
+
(0, import_editor_elements7.deleteElement)({
|
|
2121
|
+
elementId: rootContainer.id,
|
|
2122
|
+
options: { useHistory: false }
|
|
2123
|
+
});
|
|
2124
|
+
});
|
|
2125
|
+
}
|
|
2126
|
+
if (errors.length > 0) {
|
|
2127
|
+
const errorText = `Failed to build composition with the following errors:
|
|
2128
|
+
|
|
2129
|
+
|
|
2130
|
+
${errors.map((e) => typeof e === "string" ? e : e.message).join("\n\n")}
|
|
2131
|
+
"Missing $$type" errors indicate that the configuration objects are invalid. Try again and apply **ALL** object entries with correct $$type.
|
|
2132
|
+
Now that you have these errors, fix them and try again. Errors regarding configuration objects, please check again the PropType schemas`;
|
|
2133
|
+
throw new Error(errorText);
|
|
2134
|
+
}
|
|
2135
|
+
if (!xml) {
|
|
2136
|
+
throw new Error("XML structure is null after parsing.");
|
|
2137
|
+
}
|
|
2138
|
+
return {
|
|
2139
|
+
xmlStructure: new XMLSerializer().serializeToString(xml),
|
|
2140
|
+
llmInstructions: (softErrors.length ? `The composition was built successfully, but there were some issues with the provided configurations:
|
|
2141
|
+
|
|
2142
|
+
${softErrors.map((e) => `- ${e.message}`).join("\n")}
|
|
2143
|
+
|
|
2144
|
+
Please use confiugure-element tool to fix these issues. Now that you have information about these issues, use the configure-element tool to fix them!` : "") + `
|
|
2145
|
+
Next Steps:
|
|
2146
|
+
- Use "apply-global-class" tool as there may be global styles ready to be applied to elements.
|
|
2147
|
+
- Use "configure-element" tool to further configure elements as needed, including styles.
|
|
2148
|
+
`
|
|
2149
|
+
};
|
|
2150
|
+
}
|
|
2151
|
+
});
|
|
2152
|
+
};
|
|
2153
|
+
|
|
2154
|
+
// src/mcp/tools/configure-element/prompt.ts
|
|
2155
|
+
var configureElementToolPrompt = `Configure an existing element on the page.
|
|
2156
|
+
|
|
2157
|
+
# **CRITICAL - REQUIRED INFORMATION (Must read before using this tool)**
|
|
2158
|
+
1. [${WIDGET_SCHEMA_URI}]
|
|
2159
|
+
Required to understand which widgets are available, and what are their configuration schemas.
|
|
2160
|
+
Every widgetType (i.e. e-heading, e-button) that is supported has it's own property schema, that you must follow in order to apply property values correctly.
|
|
2161
|
+
2. [${STYLE_SCHEMA_URI}]
|
|
2162
|
+
Required to understand the styles schema for the widgets. All widgets share the same styles schema, grouped by categories.
|
|
2163
|
+
Use this resource to understand which style properties are available for each element, and how to structure the "_styles" configuration property.
|
|
2164
|
+
3. If not sure about the PropValues schema, you can use the "get-element-configuration-values" tool to retreive the current PropValues configuration of the element.
|
|
2165
|
+
|
|
2166
|
+
Before using this tool, check the definitions of the elements PropTypes at the resource "widget-schema-by-type" at editor-canvas__elementor://widgets/schema/{widgetType}
|
|
2167
|
+
All widgets share a common _style property for styling, which uses the common styles schema.
|
|
2168
|
+
Retreive and check the common styles schema at the resource list "styles-schema" at editor-canvas__elementor://styles/schema/{category}
|
|
2169
|
+
|
|
2170
|
+
# Parameters
|
|
2171
|
+
- propertiesToChange: An object containing the properties to change, with their new values. MANDATORY
|
|
2172
|
+
- elementId: The ID of the element to configure. MANDATORY
|
|
2173
|
+
- elementType: The type of the element to configure (i.e. e-heading, e-button). MANDATORY
|
|
2174
|
+
|
|
2175
|
+
# When to use this tool
|
|
2176
|
+
When a user requires to change anything in an element, such as updating text, colors, sizes, or other configurable properties.
|
|
2177
|
+
This tool handles elements of type "widget".
|
|
2178
|
+
This tool handles styling elements, using the _styles property in the configuration.
|
|
2179
|
+
|
|
2180
|
+
The element's schema must be known before using this tool.
|
|
2181
|
+
|
|
2182
|
+
Attached resource link describing how PropType schema should be parsed as PropValue for this tool.
|
|
2183
|
+
|
|
2184
|
+
Read carefully the PropType Schema of the element and it's styles, then apply correct PropValue according to the schema.
|
|
2185
|
+
|
|
2186
|
+
PropValue structure:
|
|
2187
|
+
{
|
|
2188
|
+
"$$type": string, // MANDATORY as defined in the PropType schema under the "key" property
|
|
2189
|
+
value: unknown // The value according to the PropType schema for kinds of "array", use array with PropValues items inside. For "object", read the shape property of the PropType schema. For "plain", use strings.
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2192
|
+
<IMPORTANT>
|
|
2193
|
+
ALWAYS MAKE SURE you have the PropType schemas for the element you are configuring, and the common-styles schema for styling. If you are not sure, retreive the schema from the resources mentioned above.
|
|
2194
|
+
</IMPORTANT>
|
|
2195
|
+
|
|
2196
|
+
You can use multiple property changes at once by providing multiple entries in the propertiesToChange object, including _style alongside non-style props.
|
|
2197
|
+
Some properties are nested, use the root property name, then objects with nested values inside, as the complete schema suggests.
|
|
2198
|
+
Nested properties, such as for the _styles, should include a "_styles" property with object containing the definitions to change.
|
|
2199
|
+
|
|
2200
|
+
Make sure you have the "widget-schema-by-type" resource available to retreive the PropType schema for the element type you are configuring.
|
|
2201
|
+
|
|
2202
|
+
# How to configure elements
|
|
2203
|
+
We use a dedicated PropType Schema for configuring elements, including styles. When you configure an element, you must use the EXACT PropType Value as defined in the schema.
|
|
2204
|
+
For _styles, use the style schema provided, as it also uses the PropType format.
|
|
2205
|
+
For all non-primitive types, provide the key property as defined in the schema as $$type in the generated objecct, as it is MANDATORY for parsing.
|
|
2206
|
+
|
|
2207
|
+
Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property from the original configuration for every property you are changing.
|
|
2208
|
+
|
|
2209
|
+
# Example
|
|
2210
|
+
\`\`\`json
|
|
2211
|
+
{
|
|
2212
|
+
propertiesToChange: {
|
|
2213
|
+
// List of properties TO CHANGE, following the PropType schema for the element as defined in the resource [${WIDGET_SCHEMA_URI}]
|
|
2214
|
+
title: {
|
|
2215
|
+
$$type: 'string',
|
|
2216
|
+
value: 'New Title Text'
|
|
2217
|
+
},
|
|
2218
|
+
border: {
|
|
2219
|
+
$$type: 'boolean',
|
|
2220
|
+
value: false
|
|
2221
|
+
},
|
|
2222
|
+
_styles: {
|
|
2223
|
+
// List of available keys available at the [${STYLE_SCHEMA_URI}] dynamic resource
|
|
2224
|
+
'line-height': {
|
|
2225
|
+
$$type: 'size', // MANDATORY do not forget to include the correct $$type for every property
|
|
2226
|
+
value: {
|
|
2227
|
+
size: {
|
|
2228
|
+
$$type: 'number',
|
|
2229
|
+
value: 20
|
|
2230
|
+
},
|
|
2231
|
+
unit: {
|
|
2232
|
+
$$type: 'string',
|
|
2233
|
+
value: 'px'
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
};
|
|
2240
|
+
\`\`\`
|
|
2241
|
+
|
|
2242
|
+
<IMPORTANT>
|
|
2243
|
+
The $$type property is MANDATORY for every value, it is required to parse the value and apply application-level effects.
|
|
2244
|
+
</IMPORTANT>
|
|
2245
|
+
`;
|
|
2246
|
+
|
|
2247
|
+
// src/mcp/tools/configure-element/schema.ts
|
|
2248
|
+
var import_schema3 = require("@elementor/schema");
|
|
2249
|
+
var inputSchema2 = {
|
|
2250
|
+
propertiesToChange: import_schema3.z.record(
|
|
2251
|
+
import_schema3.z.string().describe(
|
|
2252
|
+
"The property name. If nested property, provide the root property name, and the object delta only."
|
|
2253
|
+
),
|
|
2254
|
+
import_schema3.z.any().describe("The property's value")
|
|
2255
|
+
).describe("An object record containing property names and their new values to be set on the element").optional(),
|
|
2256
|
+
elementType: import_schema3.z.string().describe("The type of the element to retreive the schema"),
|
|
2257
|
+
elementId: import_schema3.z.string().describe("The unique id of the element to configure")
|
|
2258
|
+
};
|
|
2259
|
+
var outputSchema2 = {
|
|
2260
|
+
success: import_schema3.z.boolean().describe(
|
|
2261
|
+
"Whether the configuration change was successful, only if propertyName and propertyValue are provided"
|
|
2262
|
+
)
|
|
2263
|
+
};
|
|
2264
|
+
|
|
2265
|
+
// src/mcp/tools/configure-element/tool.ts
|
|
2266
|
+
var initConfigureElementTool = (reg) => {
|
|
2267
|
+
const { addTool } = reg;
|
|
2268
|
+
addTool({
|
|
2269
|
+
name: "configure-element",
|
|
2270
|
+
description: configureElementToolPrompt,
|
|
2271
|
+
schema: inputSchema2,
|
|
2272
|
+
outputSchema: outputSchema2,
|
|
2273
|
+
handler: ({ elementId, propertiesToChange, elementType }) => {
|
|
2274
|
+
if (!propertiesToChange) {
|
|
2275
|
+
throw new Error(
|
|
2276
|
+
"propertiesToChange is required to configure an element. Now that you have this information, ensure you have the schema and try again."
|
|
2277
|
+
);
|
|
2278
|
+
}
|
|
2279
|
+
const toUpdate = Object.entries(propertiesToChange);
|
|
2280
|
+
for (const [propertyName, propertyValue] of toUpdate) {
|
|
2281
|
+
if (!propertyName && !elementId && !elementType) {
|
|
2282
|
+
throw new Error(
|
|
2283
|
+
"propertyName, elementId, elementType are required to configure an element. If you want to retreive the schema, use the get-element-configuration-schema tool."
|
|
2284
|
+
);
|
|
2285
|
+
}
|
|
2286
|
+
try {
|
|
2287
|
+
doUpdateElementProperty({
|
|
2288
|
+
elementId,
|
|
2289
|
+
elementType,
|
|
2290
|
+
propertyName,
|
|
2291
|
+
propertyValue
|
|
2292
|
+
});
|
|
2293
|
+
} catch (error) {
|
|
2294
|
+
const errorMessage = createUpdateErrorMessage({
|
|
2295
|
+
propertyName,
|
|
2296
|
+
elementId,
|
|
2297
|
+
elementType,
|
|
2298
|
+
error
|
|
2299
|
+
});
|
|
2300
|
+
throw new Error(errorMessage);
|
|
2301
|
+
}
|
|
2302
|
+
}
|
|
2303
|
+
return {
|
|
2304
|
+
success: true
|
|
2305
|
+
};
|
|
2306
|
+
}
|
|
2307
|
+
});
|
|
2308
|
+
};
|
|
2309
|
+
function createUpdateErrorMessage(opts) {
|
|
2310
|
+
const { propertyName, elementId, elementType, error } = opts;
|
|
2311
|
+
return `Failed to update property "${propertyName}" on element "${elementId}": ${error.message}.
|
|
2312
|
+
Check the element's PropType schema at the resource [${WIDGET_SCHEMA_URI.replace(
|
|
2313
|
+
"{widgetType}",
|
|
2314
|
+
elementType
|
|
2315
|
+
)}] for type "${elementType}" to ensure the property exists and the value matches the expected PropType.
|
|
2316
|
+
Now that you have this information, ensure you have the schema and try again.`;
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
// src/mcp/tools/get-element-config/tool.ts
|
|
2320
|
+
var import_editor_elements8 = require("@elementor/editor-elements");
|
|
2321
|
+
var import_editor_props5 = require("@elementor/editor-props");
|
|
2322
|
+
var import_schema5 = require("@elementor/schema");
|
|
2323
|
+
var schema = {
|
|
2324
|
+
elementId: import_schema5.z.string()
|
|
2325
|
+
};
|
|
2326
|
+
var outputSchema3 = {
|
|
2327
|
+
propValues: import_schema5.z.record(import_schema5.z.string(), import_schema5.z.any()).describe(
|
|
2328
|
+
"A record mapping PropTypes to their corresponding PropValues, with _styles record for style-related PropValues"
|
|
2329
|
+
)
|
|
2330
|
+
};
|
|
2331
|
+
var initGetElementConfigTool = (reg) => {
|
|
2332
|
+
const { addTool } = reg;
|
|
2333
|
+
addTool({
|
|
2334
|
+
name: "get-element-configuration-values",
|
|
2335
|
+
description: "Retrieve the element's configuration PropValues for a specific element by unique ID.",
|
|
2336
|
+
schema,
|
|
2337
|
+
outputSchema: outputSchema3,
|
|
2338
|
+
handler: async ({ elementId }) => {
|
|
2339
|
+
const element = (0, import_editor_elements8.getContainer)(elementId);
|
|
2340
|
+
if (!element) {
|
|
2341
|
+
throw new Error(`Element with ID ${elementId} not found.`);
|
|
2342
|
+
}
|
|
2343
|
+
const elementRawSettings = element.settings;
|
|
2344
|
+
const propSchema = (0, import_editor_elements8.getWidgetsCache)()?.[element.model.get("widgetType") || ""]?.atomic_props_schema;
|
|
2345
|
+
if (!elementRawSettings || !propSchema) {
|
|
2346
|
+
throw new Error(`No settings or prop schema found for element ID: ${elementId}`);
|
|
2347
|
+
}
|
|
2348
|
+
const propValues = {};
|
|
2349
|
+
const stylePropValues = {};
|
|
2350
|
+
import_editor_props5.Schema.configurableKeys(propSchema).forEach((key) => {
|
|
2351
|
+
propValues[key] = structuredClone(elementRawSettings.get(key));
|
|
2352
|
+
});
|
|
2353
|
+
const elementStyles = (0, import_editor_elements8.getElementStyles)(elementId) || {};
|
|
2354
|
+
const localStyle = Object.values(elementStyles).find((style) => style.label === "local");
|
|
2355
|
+
if (localStyle) {
|
|
2356
|
+
const defaultVariant = localStyle.variants.find(
|
|
2357
|
+
(variant) => variant.meta.breakpoint === "desktop" && !variant.meta.state
|
|
2358
|
+
);
|
|
2359
|
+
if (defaultVariant) {
|
|
2360
|
+
const styleProps = defaultVariant.props || {};
|
|
2361
|
+
Object.keys(styleProps).forEach((stylePropName) => {
|
|
2362
|
+
if (typeof styleProps[stylePropName] !== "undefined") {
|
|
2363
|
+
stylePropValues[stylePropName] = structuredClone(styleProps[stylePropName]);
|
|
2364
|
+
}
|
|
2365
|
+
});
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
return {
|
|
2369
|
+
propValues: {
|
|
2370
|
+
...propValues,
|
|
2371
|
+
_styles: stylePropValues
|
|
2372
|
+
}
|
|
2373
|
+
};
|
|
2374
|
+
}
|
|
2375
|
+
});
|
|
2376
|
+
};
|
|
2377
|
+
|
|
2378
|
+
// src/mcp/canvas-mcp.ts
|
|
2379
|
+
var initCanvasMcp = (reg) => {
|
|
2380
|
+
const { setMCPDescription } = reg;
|
|
2381
|
+
setMCPDescription(
|
|
2382
|
+
'Everything related to creative design, layout, styling and building the pages, specifically element of type "widget"'
|
|
2383
|
+
);
|
|
2384
|
+
initWidgetsSchemaResource(reg);
|
|
2385
|
+
initBuildCompositionsTool(reg);
|
|
2386
|
+
initGetElementConfigTool(reg);
|
|
2387
|
+
initConfigureElementTool(reg);
|
|
2388
|
+
};
|
|
2389
|
+
|
|
2390
|
+
// src/mcp/mcp-description.ts
|
|
2391
|
+
var mcpDescription = `Canvas MCP - Working with widgets and styles: how to use the PropType schemas and generate PropValue structures
|
|
2392
|
+
|
|
2393
|
+
# Elementor's PropValue configuration system
|
|
2394
|
+
|
|
2395
|
+
Every widget in Elementor has a set of properties that can be configured, defined in a STRICT SCHEMA we call "PropType".
|
|
2396
|
+
All widget configuration values are represented using a structure we call "PropValue".
|
|
2397
|
+
|
|
2398
|
+
To correctly configure a widget's properties, FOLLOW THE PropType schema defined for that widget. This schema outlines the expected structure and types for each property, ensuring that the values you provide are valid and can be properly interpreted by Elementor.
|
|
2399
|
+
Every widget has it's own PropType schema, retreivable from the resource [${WIDGET_SCHEMA_URI}].
|
|
2400
|
+
ALL WIDGETS share a common _styles property with a uniform styles schema, retreivable from the resource [${STYLE_SCHEMA_URI}].
|
|
2401
|
+
The style schema is grouped by categories, such as "typography", "background", "border", etc.
|
|
2402
|
+
|
|
2403
|
+
# Tools and usage
|
|
2404
|
+
- Use the "get-element-configuration-values" tool to retrieve the current configuration of a specific element, including its PropValues and styles. It is recommended to use this tool when you are required to make changes to an existing element, to ensure you have the correct current configuration schema.
|
|
2405
|
+
If a PropValue changes it's type (only on union PropTypes), read the new schema from the resources mentioned above, and adjust the PropValue structure accordingly.
|
|
2406
|
+
- Use the "build-composition" tool to create a NEW ELEMENTS in a composition on the page. You can use this tool to also create a new single element.
|
|
2407
|
+
- Use the "configure-element" tool to update the configuration of an EXISTING element on the page.
|
|
2408
|
+
|
|
2409
|
+
All array types that can receive union types, are typed as mixed array, which means that each item in the array can be of any of the allowed types defined in the PropType schema.
|
|
2410
|
+
Example: the "background" can have a background-overlay property, which can contain multiple overlays, such as color, gradient, image, etc. Each item in the array must follow the PropType schema for each overlay type.
|
|
2411
|
+
All _style properties are OPTIONAL. When a _style is defined, we MERGE the values with existing styles, so only the properties you define will be changed, and the rest will remain as is.
|
|
2412
|
+
|
|
2413
|
+
# Styling best practices
|
|
2414
|
+
Prefer using "em" and "rem" values for text-related sizes, padding and spacing. Use percentages for dynamic sizing relative to parent containers.
|
|
2415
|
+
This flexboxes are by default "flex" with "stretch" alignment. To ensure proper layout, define the "justify-content" and "align-items" as in the schema.
|
|
2416
|
+
|
|
2417
|
+
Additionaly, some PropTypes have metadata information (meta property) that can help in understaind the PropType usage, such as description or other useful information.
|
|
2418
|
+
|
|
2419
|
+
Example of null values:
|
|
2420
|
+
{
|
|
2421
|
+
$$type: 'as-defined-for-propValue',
|
|
2422
|
+
value: null
|
|
2423
|
+
}
|
|
2424
|
+
|
|
2425
|
+
Example of "image" PropValue structure:
|
|
2426
|
+
{$$type:'image',value:{src:{$$type:'image-src',value:{url:{$$type:'url',value:'https://example.com/image.jpg'}}},size:{$$type:'string',value:'full'}}}
|
|
2427
|
+
|
|
2428
|
+
`;
|
|
2429
|
+
|
|
1283
2430
|
// src/prevent-link-in-link-commands.ts
|
|
1284
|
-
var
|
|
2431
|
+
var import_editor_elements9 = require("@elementor/editor-elements");
|
|
1285
2432
|
var import_editor_notifications = require("@elementor/editor-notifications");
|
|
1286
|
-
var
|
|
2433
|
+
var import_editor_v1_adapters8 = require("@elementor/editor-v1-adapters");
|
|
1287
2434
|
var import_i18n = require("@wordpress/i18n");
|
|
1288
2435
|
function initLinkInLinkPrevention() {
|
|
1289
|
-
(0,
|
|
2436
|
+
(0, import_editor_v1_adapters8.blockCommand)({
|
|
1290
2437
|
command: "document/elements/paste",
|
|
1291
2438
|
condition: blockLinkInLinkPaste
|
|
1292
2439
|
});
|
|
1293
|
-
(0,
|
|
2440
|
+
(0, import_editor_v1_adapters8.blockCommand)({
|
|
1294
2441
|
command: "document/elements/move",
|
|
1295
2442
|
condition: blockLinkInLinkMove
|
|
1296
2443
|
});
|
|
@@ -1352,29 +2499,29 @@ function shouldBlock(sourceElements, targetElements) {
|
|
|
1352
2499
|
return false;
|
|
1353
2500
|
}
|
|
1354
2501
|
const isSourceContainsAnAnchor = sourceElements.some((src) => {
|
|
1355
|
-
return src?.id ? (0,
|
|
2502
|
+
return src?.id ? (0, import_editor_elements9.isElementAnchored)(src.id) || !!(0, import_editor_elements9.getAnchoredDescendantId)(src.id) : false;
|
|
1356
2503
|
});
|
|
1357
2504
|
if (!isSourceContainsAnAnchor) {
|
|
1358
2505
|
return false;
|
|
1359
2506
|
}
|
|
1360
2507
|
const isTargetContainsAnAnchor = targetElements.some((target) => {
|
|
1361
|
-
return target?.id ? (0,
|
|
2508
|
+
return target?.id ? (0, import_editor_elements9.isElementAnchored)(target.id) || !!(0, import_editor_elements9.getAnchoredAncestorId)(target.id) : false;
|
|
1362
2509
|
});
|
|
1363
2510
|
return isTargetContainsAnAnchor;
|
|
1364
2511
|
}
|
|
1365
2512
|
|
|
1366
2513
|
// src/style-commands/paste-style.ts
|
|
1367
|
-
var
|
|
2514
|
+
var import_editor_v1_adapters10 = require("@elementor/editor-v1-adapters");
|
|
1368
2515
|
|
|
1369
2516
|
// src/style-commands/undoable-actions/paste-element-style.ts
|
|
1370
|
-
var
|
|
2517
|
+
var import_editor_elements11 = require("@elementor/editor-elements");
|
|
1371
2518
|
var import_editor_styles_repository4 = require("@elementor/editor-styles-repository");
|
|
1372
|
-
var
|
|
2519
|
+
var import_editor_v1_adapters9 = require("@elementor/editor-v1-adapters");
|
|
1373
2520
|
var import_i18n3 = require("@wordpress/i18n");
|
|
1374
2521
|
|
|
1375
2522
|
// src/style-commands/utils.ts
|
|
1376
|
-
var
|
|
1377
|
-
var
|
|
2523
|
+
var import_editor_elements10 = require("@elementor/editor-elements");
|
|
2524
|
+
var import_editor_props6 = require("@elementor/editor-props");
|
|
1378
2525
|
var import_i18n2 = require("@wordpress/i18n");
|
|
1379
2526
|
function hasAtomicWidgets(args) {
|
|
1380
2527
|
const { containers = [args.container] } = args;
|
|
@@ -1392,13 +2539,13 @@ function getClassesProp(container) {
|
|
|
1392
2539
|
return null;
|
|
1393
2540
|
}
|
|
1394
2541
|
const [propKey] = Object.entries(propsSchema).find(
|
|
1395
|
-
([, propType]) => propType.kind === "plain" && propType.key ===
|
|
2542
|
+
([, propType]) => propType.kind === "plain" && propType.key === import_editor_props6.CLASSES_PROP_KEY
|
|
1396
2543
|
) ?? [];
|
|
1397
2544
|
return propKey ?? null;
|
|
1398
2545
|
}
|
|
1399
2546
|
function getContainerSchema(container) {
|
|
1400
2547
|
const type = container?.model.get("widgetType") || container?.model.get("elType");
|
|
1401
|
-
const widgetsCache = (0,
|
|
2548
|
+
const widgetsCache = (0, import_editor_elements10.getWidgetsCache)();
|
|
1402
2549
|
const elementType = widgetsCache?.[type];
|
|
1403
2550
|
return elementType?.atomic_props_schema ?? null;
|
|
1404
2551
|
}
|
|
@@ -1411,11 +2558,11 @@ function getClipboardElements(storageKey = "clipboard") {
|
|
|
1411
2558
|
}
|
|
1412
2559
|
}
|
|
1413
2560
|
function getTitleForContainers(containers) {
|
|
1414
|
-
return containers.length > 1 ? (0, import_i18n2.__)("Elements", "elementor") : (0,
|
|
2561
|
+
return containers.length > 1 ? (0, import_i18n2.__)("Elements", "elementor") : (0, import_editor_elements10.getElementLabel)(containers[0].id);
|
|
1415
2562
|
}
|
|
1416
2563
|
|
|
1417
2564
|
// src/style-commands/undoable-actions/paste-element-style.ts
|
|
1418
|
-
var undoablePasteElementStyle = () => (0,
|
|
2565
|
+
var undoablePasteElementStyle = () => (0, import_editor_v1_adapters9.undoable)(
|
|
1419
2566
|
{
|
|
1420
2567
|
do: ({ containers, newStyle }) => {
|
|
1421
2568
|
return containers.map((container) => {
|
|
@@ -1424,7 +2571,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters8.undoable)(
|
|
|
1424
2571
|
if (!classesProp) {
|
|
1425
2572
|
return null;
|
|
1426
2573
|
}
|
|
1427
|
-
const originalStyles = (0,
|
|
2574
|
+
const originalStyles = (0, import_editor_elements11.getElementStyles)(container.id);
|
|
1428
2575
|
const [styleId, styleDef] = Object.entries(originalStyles ?? {})[0] ?? [];
|
|
1429
2576
|
const originalStyle = Object.keys(styleDef ?? {}).length ? styleDef : null;
|
|
1430
2577
|
const revertData = {
|
|
@@ -1433,7 +2580,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters8.undoable)(
|
|
|
1433
2580
|
};
|
|
1434
2581
|
if (styleId) {
|
|
1435
2582
|
newStyle.variants.forEach(({ meta, props, custom_css: customCss }) => {
|
|
1436
|
-
(0,
|
|
2583
|
+
(0, import_editor_elements11.updateElementStyle)({
|
|
1437
2584
|
elementId,
|
|
1438
2585
|
styleId,
|
|
1439
2586
|
meta,
|
|
@@ -1444,7 +2591,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters8.undoable)(
|
|
|
1444
2591
|
} else {
|
|
1445
2592
|
const [firstVariant] = newStyle.variants;
|
|
1446
2593
|
const additionalVariants = newStyle.variants.slice(1);
|
|
1447
|
-
revertData.styleId = (0,
|
|
2594
|
+
revertData.styleId = (0, import_editor_elements11.createElementStyle)({
|
|
1448
2595
|
elementId,
|
|
1449
2596
|
classesProp,
|
|
1450
2597
|
label: import_editor_styles_repository4.ELEMENTS_STYLES_RESERVED_LABEL,
|
|
@@ -1462,7 +2609,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters8.undoable)(
|
|
|
1462
2609
|
return;
|
|
1463
2610
|
}
|
|
1464
2611
|
if (!revertData.originalStyle) {
|
|
1465
|
-
(0,
|
|
2612
|
+
(0, import_editor_elements11.deleteElementStyle)(container.id, revertData.styleId);
|
|
1466
2613
|
return;
|
|
1467
2614
|
}
|
|
1468
2615
|
const classesProp = getClassesProp(container);
|
|
@@ -1471,7 +2618,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters8.undoable)(
|
|
|
1471
2618
|
}
|
|
1472
2619
|
const [firstVariant] = revertData.originalStyle.variants;
|
|
1473
2620
|
const additionalVariants = revertData.originalStyle.variants.slice(1);
|
|
1474
|
-
(0,
|
|
2621
|
+
(0, import_editor_elements11.createElementStyle)({
|
|
1475
2622
|
elementId: container.id,
|
|
1476
2623
|
classesProp,
|
|
1477
2624
|
label: import_editor_styles_repository4.ELEMENTS_STYLES_RESERVED_LABEL,
|
|
@@ -1491,12 +2638,12 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters8.undoable)(
|
|
|
1491
2638
|
// src/style-commands/paste-style.ts
|
|
1492
2639
|
function initPasteStyleCommand() {
|
|
1493
2640
|
const pasteElementStyleCommand = undoablePasteElementStyle();
|
|
1494
|
-
(0,
|
|
2641
|
+
(0, import_editor_v1_adapters10.blockCommand)({
|
|
1495
2642
|
command: "document/elements/paste-style",
|
|
1496
2643
|
condition: hasAtomicWidgets
|
|
1497
2644
|
});
|
|
1498
|
-
(0,
|
|
1499
|
-
(0,
|
|
2645
|
+
(0, import_editor_v1_adapters10.__privateListenTo)(
|
|
2646
|
+
(0, import_editor_v1_adapters10.commandStartEvent)("document/elements/paste-style"),
|
|
1500
2647
|
(e) => pasteStyles(e.args, pasteElementStyleCommand)
|
|
1501
2648
|
);
|
|
1502
2649
|
}
|
|
@@ -1520,21 +2667,21 @@ function pasteStyles(args, pasteCallback) {
|
|
|
1520
2667
|
}
|
|
1521
2668
|
|
|
1522
2669
|
// src/style-commands/reset-style.ts
|
|
1523
|
-
var
|
|
2670
|
+
var import_editor_v1_adapters12 = require("@elementor/editor-v1-adapters");
|
|
1524
2671
|
|
|
1525
2672
|
// src/style-commands/undoable-actions/reset-element-style.ts
|
|
1526
|
-
var
|
|
2673
|
+
var import_editor_elements12 = require("@elementor/editor-elements");
|
|
1527
2674
|
var import_editor_styles_repository5 = require("@elementor/editor-styles-repository");
|
|
1528
|
-
var
|
|
2675
|
+
var import_editor_v1_adapters11 = require("@elementor/editor-v1-adapters");
|
|
1529
2676
|
var import_i18n4 = require("@wordpress/i18n");
|
|
1530
|
-
var undoableResetElementStyle = () => (0,
|
|
2677
|
+
var undoableResetElementStyle = () => (0, import_editor_v1_adapters11.undoable)(
|
|
1531
2678
|
{
|
|
1532
2679
|
do: ({ containers }) => {
|
|
1533
2680
|
return containers.map((container) => {
|
|
1534
2681
|
const elementId = container.model.get("id");
|
|
1535
|
-
const containerStyles = (0,
|
|
2682
|
+
const containerStyles = (0, import_editor_elements12.getElementStyles)(elementId);
|
|
1536
2683
|
Object.keys(containerStyles ?? {}).forEach(
|
|
1537
|
-
(styleId) => (0,
|
|
2684
|
+
(styleId) => (0, import_editor_elements12.deleteElementStyle)(elementId, styleId)
|
|
1538
2685
|
);
|
|
1539
2686
|
return containerStyles;
|
|
1540
2687
|
});
|
|
@@ -1550,7 +2697,7 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters10.undoable)(
|
|
|
1550
2697
|
Object.entries(containerStyles ?? {}).forEach(([styleId, style]) => {
|
|
1551
2698
|
const [firstVariant] = style.variants;
|
|
1552
2699
|
const additionalVariants = style.variants.slice(1);
|
|
1553
|
-
(0,
|
|
2700
|
+
(0, import_editor_elements12.createElementStyle)({
|
|
1554
2701
|
elementId,
|
|
1555
2702
|
classesProp,
|
|
1556
2703
|
styleId,
|
|
@@ -1571,12 +2718,12 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters10.undoable)(
|
|
|
1571
2718
|
// src/style-commands/reset-style.ts
|
|
1572
2719
|
function initResetStyleCommand() {
|
|
1573
2720
|
const resetElementStyles = undoableResetElementStyle();
|
|
1574
|
-
(0,
|
|
2721
|
+
(0, import_editor_v1_adapters12.blockCommand)({
|
|
1575
2722
|
command: "document/elements/reset-style",
|
|
1576
2723
|
condition: hasAtomicWidgets
|
|
1577
2724
|
});
|
|
1578
|
-
(0,
|
|
1579
|
-
(0,
|
|
2725
|
+
(0, import_editor_v1_adapters12.__privateListenTo)(
|
|
2726
|
+
(0, import_editor_v1_adapters12.commandStartEvent)("document/elements/reset-style"),
|
|
1580
2727
|
(e) => resetStyles(e.args, resetElementStyles)
|
|
1581
2728
|
);
|
|
1582
2729
|
}
|
|
@@ -1602,6 +2749,7 @@ function init() {
|
|
|
1602
2749
|
initLinkInLinkPrevention();
|
|
1603
2750
|
initLegacyViews();
|
|
1604
2751
|
initSettingsTransformers();
|
|
2752
|
+
(0, import_editor_interactions2.init)();
|
|
1605
2753
|
(0, import_editor.injectIntoTop)({
|
|
1606
2754
|
id: "elements-overlays",
|
|
1607
2755
|
component: ElementsOverlays
|
|
@@ -1610,18 +2758,67 @@ function init() {
|
|
|
1610
2758
|
id: "canvas-style-render",
|
|
1611
2759
|
component: StyleRenderer
|
|
1612
2760
|
});
|
|
2761
|
+
(0, import_editor.injectIntoTop)({
|
|
2762
|
+
id: "canvas-interactions-render",
|
|
2763
|
+
component: InteractionsRenderer
|
|
2764
|
+
});
|
|
1613
2765
|
(0, import_editor.injectIntoLogic)({
|
|
1614
2766
|
id: "classes-rename",
|
|
1615
2767
|
component: ClassesRename
|
|
1616
2768
|
});
|
|
2769
|
+
initCanvasMcp(
|
|
2770
|
+
(0, import_editor_mcp3.getMCPByDomain)("canvas", {
|
|
2771
|
+
instructions: mcpDescription
|
|
2772
|
+
})
|
|
2773
|
+
);
|
|
1617
2774
|
}
|
|
2775
|
+
|
|
2776
|
+
// src/sync/drag-element-from-panel.ts
|
|
2777
|
+
var startDragElementFromPanel = (props) => {
|
|
2778
|
+
const channels = getElementorChannels();
|
|
2779
|
+
channels?.editor.reply("element:dragged", null);
|
|
2780
|
+
channels?.panelElements.reply("element:selected", getLegacyPanelElementView(props)).trigger("element:drag:start");
|
|
2781
|
+
};
|
|
2782
|
+
var endDragElementFromPanel = () => {
|
|
2783
|
+
getElementorChannels()?.panelElements?.trigger("element:drag:end");
|
|
2784
|
+
};
|
|
2785
|
+
var getElementorChannels = () => {
|
|
2786
|
+
const extendedWindow = window;
|
|
2787
|
+
const channels = extendedWindow.elementor?.channels;
|
|
2788
|
+
if (!channels) {
|
|
2789
|
+
throw new Error(
|
|
2790
|
+
"Elementor channels not found: Elementor editor is not initialized or channels are unavailable."
|
|
2791
|
+
);
|
|
2792
|
+
}
|
|
2793
|
+
return channels;
|
|
2794
|
+
};
|
|
2795
|
+
var getLegacyPanelElementView = ({ settings, ...rest }) => {
|
|
2796
|
+
const extendedWindow = window;
|
|
2797
|
+
const LegacyElementModel = extendedWindow.elementor?.modules?.elements?.models?.Element;
|
|
2798
|
+
if (!LegacyElementModel) {
|
|
2799
|
+
throw new Error("Elementor legacy Element model not found in editor modules");
|
|
2800
|
+
}
|
|
2801
|
+
const elementModel = new LegacyElementModel({
|
|
2802
|
+
...rest,
|
|
2803
|
+
custom: {
|
|
2804
|
+
isPreset: !!settings,
|
|
2805
|
+
preset_settings: settings
|
|
2806
|
+
}
|
|
2807
|
+
});
|
|
2808
|
+
return { model: elementModel };
|
|
2809
|
+
};
|
|
1618
2810
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1619
2811
|
0 && (module.exports = {
|
|
1620
2812
|
createPropsResolver,
|
|
2813
|
+
createTemplatedElementView,
|
|
1621
2814
|
createTransformer,
|
|
1622
2815
|
createTransformersRegistry,
|
|
2816
|
+
endDragElementFromPanel,
|
|
2817
|
+
getCanvasIframeDocument,
|
|
1623
2818
|
init,
|
|
2819
|
+
registerElementType,
|
|
1624
2820
|
settingsTransformersRegistry,
|
|
2821
|
+
startDragElementFromPanel,
|
|
1625
2822
|
styleTransformersRegistry
|
|
1626
2823
|
});
|
|
1627
2824
|
//# sourceMappingURL=index.js.map
|