@elementor/editor-canvas 4.0.0-683 → 4.0.0-beta5
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 +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +260 -79
- package/dist/index.mjs +261 -80
- package/package.json +19 -18
- package/src/components/__tests__/style-renderer.test.tsx +4 -0
- package/src/hooks/__tests__/use-style-items.test.ts +119 -0
- package/src/hooks/use-style-items.ts +39 -15
- package/src/init-settings-transformers.ts +2 -0
- package/src/legacy/create-nested-templated-element-type.ts +15 -2
- package/src/legacy/create-templated-element-type.ts +8 -0
- package/src/legacy/replacements/base.ts +4 -0
- package/src/legacy/replacements/inline-editing/canvas-inline-editor.tsx +49 -27
- package/src/legacy/replacements/inline-editing/inline-editing-elements.tsx +16 -10
- package/src/legacy/replacements/inline-editing/inline-editing-utils.ts +12 -1
- package/src/legacy/replacements/manager.ts +13 -0
- package/src/legacy/types.ts +4 -0
- package/src/mcp/canvas-mcp.ts +5 -7
- package/src/mcp/resources/breakpoints-resource.ts +11 -4
- package/src/mcp/resources/document-structure-resource.ts +18 -13
- package/src/mcp/tools/build-composition/tool.ts +5 -1
- package/src/mcp/utils/__tests__/get-composition-target-container.test.ts +59 -0
- package/src/mcp/utils/get-composition-target-container.ts +15 -0
- package/src/renderers/__tests__/create-styles-renderer.test.ts +117 -0
- package/src/renderers/create-styles-renderer.ts +13 -3
- package/src/transformers/shared/__tests__/svg-src-transformer.test.ts +184 -0
- package/src/transformers/shared/svg-src-transformer.ts +87 -0
- package/src/transformers/styles/__tests__/size-transformer.test.ts +24 -0
- package/src/transformers/styles/size-transformer.ts +3 -0
package/dist/index.js
CHANGED
|
@@ -59,7 +59,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
59
59
|
var import_editor_v1_adapters = require("@elementor/editor-v1-adapters");
|
|
60
60
|
var BREAKPOINTS_SCHEMA_URI = "elementor://breakpoints/list";
|
|
61
61
|
var initBreakpointsResource = (reg) => {
|
|
62
|
-
const {
|
|
62
|
+
const { resource, sendResourceUpdated } = reg;
|
|
63
63
|
const getBreakpointsList = () => {
|
|
64
64
|
const { breakpoints } = window.elementor?.config?.responsive || {};
|
|
65
65
|
if (!breakpoints) {
|
|
@@ -83,9 +83,16 @@ var initBreakpointsResource = (reg) => {
|
|
|
83
83
|
}
|
|
84
84
|
]
|
|
85
85
|
});
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
resource(
|
|
87
|
+
"breakpoints ",
|
|
88
|
+
BREAKPOINTS_SCHEMA_URI,
|
|
89
|
+
{
|
|
90
|
+
description: "Breakpoints list."
|
|
91
|
+
},
|
|
92
|
+
() => {
|
|
93
|
+
return buildResourceResponse();
|
|
94
|
+
}
|
|
95
|
+
);
|
|
89
96
|
window.addEventListener((0, import_editor_v1_adapters.v1ReadyEvent)().name, () => {
|
|
90
97
|
sendResourceUpdated({
|
|
91
98
|
uri: BREAKPOINTS_SCHEMA_URI,
|
|
@@ -833,14 +840,22 @@ var UnknownStyleStateError = (0, import_utils2.createError)({
|
|
|
833
840
|
var SELECTORS_MAP = {
|
|
834
841
|
class: "."
|
|
835
842
|
};
|
|
843
|
+
var DEFAULT_BREAKPOINT = "desktop";
|
|
844
|
+
var DEFAULT_STATE = "normal";
|
|
845
|
+
function getStyleUniqueKey(style) {
|
|
846
|
+
const breakpoint = style.variants[0]?.meta?.breakpoint ?? DEFAULT_BREAKPOINT;
|
|
847
|
+
const state = style.variants[0]?.meta?.state ?? DEFAULT_STATE;
|
|
848
|
+
return `${style.id}-${breakpoint}-${state}`;
|
|
849
|
+
}
|
|
836
850
|
function createStylesRenderer({ resolve, breakpoints, selectorPrefix = "" }) {
|
|
837
851
|
return async ({ styles, signal }) => {
|
|
838
|
-
const
|
|
852
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
839
853
|
const uniqueStyles = styles.filter((style) => {
|
|
840
|
-
|
|
854
|
+
const key = getStyleUniqueKey(style);
|
|
855
|
+
if (seenKeys.has(key)) {
|
|
841
856
|
return false;
|
|
842
857
|
}
|
|
843
|
-
|
|
858
|
+
seenKeys.add(key);
|
|
844
859
|
return true;
|
|
845
860
|
});
|
|
846
861
|
const stylesCssPromises = uniqueStyles.map(async (style) => {
|
|
@@ -929,22 +944,30 @@ function useStyleItems() {
|
|
|
929
944
|
const [styleItems, setStyleItems] = (0, import_react10.useState)({});
|
|
930
945
|
const styleItemsCacheRef = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
|
|
931
946
|
const providerAndSubscribers = (0, import_react10.useMemo)(() => {
|
|
932
|
-
|
|
933
|
-
|
|
947
|
+
const createEmptyCache = () => {
|
|
948
|
+
return { orderedIds: [], itemsById: /* @__PURE__ */ new Map() };
|
|
949
|
+
};
|
|
950
|
+
const getCache = (provider) => {
|
|
951
|
+
const providerKey = safeGetKey(provider);
|
|
952
|
+
if (!providerKey) {
|
|
953
|
+
return createEmptyCache();
|
|
954
|
+
}
|
|
934
955
|
if (!styleItemsCacheRef.current.has(providerKey)) {
|
|
935
|
-
styleItemsCacheRef.current.set(providerKey,
|
|
956
|
+
styleItemsCacheRef.current.set(providerKey, createEmptyCache());
|
|
936
957
|
}
|
|
937
|
-
|
|
938
|
-
|
|
958
|
+
return styleItemsCacheRef.current.get(providerKey);
|
|
959
|
+
};
|
|
960
|
+
return import_editor_styles_repository2.stylesRepository.getProviders().map(
|
|
961
|
+
(provider) => ({
|
|
939
962
|
provider,
|
|
940
963
|
subscriber: createProviderSubscriber2({
|
|
941
964
|
provider,
|
|
942
965
|
renderStyles,
|
|
943
966
|
setStyleItems,
|
|
944
|
-
|
|
967
|
+
getCache: () => getCache(provider)
|
|
945
968
|
})
|
|
946
|
-
}
|
|
947
|
-
|
|
969
|
+
})
|
|
970
|
+
);
|
|
948
971
|
}, [renderStyles]);
|
|
949
972
|
(0, import_react10.useEffect)(() => {
|
|
950
973
|
const unsubscribes = providerAndSubscribers.map(
|
|
@@ -984,15 +1007,23 @@ function stateSorter({ state: stateA }, { state: stateB }) {
|
|
|
984
1007
|
function createBreakpointSorter(breakpointsOrder) {
|
|
985
1008
|
return ({ breakpoint: breakpointA }, { breakpoint: breakpointB }) => breakpointsOrder.indexOf(breakpointA) - breakpointsOrder.indexOf(breakpointB);
|
|
986
1009
|
}
|
|
987
|
-
function
|
|
1010
|
+
function safeGetKey(provider) {
|
|
1011
|
+
try {
|
|
1012
|
+
return provider.getKey();
|
|
1013
|
+
} catch {
|
|
1014
|
+
return null;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
function createProviderSubscriber2({ provider, renderStyles, setStyleItems, getCache }) {
|
|
988
1018
|
return abortPreviousRuns(
|
|
989
1019
|
(abortController, previous, current) => signalizedProcess(abortController.signal).then((_, signal) => {
|
|
1020
|
+
const cache = getCache();
|
|
990
1021
|
const hasDiffInfo = current !== void 0 && previous !== void 0;
|
|
991
1022
|
const hasCache = cache.orderedIds.length > 0;
|
|
992
1023
|
if (hasDiffInfo && hasCache) {
|
|
993
|
-
return updateItems(previous, current, signal);
|
|
1024
|
+
return updateItems(cache, previous, current, signal);
|
|
994
1025
|
}
|
|
995
|
-
return createItems(signal);
|
|
1026
|
+
return createItems(cache, signal);
|
|
996
1027
|
}).then((items) => {
|
|
997
1028
|
setStyleItems((prev) => ({
|
|
998
1029
|
...prev,
|
|
@@ -1000,7 +1031,7 @@ function createProviderSubscriber2({ provider, renderStyles, setStyleItems, cach
|
|
|
1000
1031
|
}));
|
|
1001
1032
|
}).execute()
|
|
1002
1033
|
);
|
|
1003
|
-
async function updateItems(previous, current, signal) {
|
|
1034
|
+
async function updateItems(cache, previous, current, signal) {
|
|
1004
1035
|
const changedIds = getChangedStyleIds(previous, current);
|
|
1005
1036
|
cache.orderedIds = provider.actions.all().map((style) => style.id).reverse();
|
|
1006
1037
|
if (changedIds.length > 0) {
|
|
@@ -1015,7 +1046,7 @@ function createProviderSubscriber2({ provider, renderStyles, setStyleItems, cach
|
|
|
1015
1046
|
}
|
|
1016
1047
|
return getOrderedItems(cache);
|
|
1017
1048
|
}
|
|
1018
|
-
async function createItems(signal) {
|
|
1049
|
+
async function createItems(cache, signal) {
|
|
1019
1050
|
const allStyles = provider.actions.all();
|
|
1020
1051
|
const styles = [...allStyles].reverse().map((style) => {
|
|
1021
1052
|
return {
|
|
@@ -1025,7 +1056,7 @@ function createProviderSubscriber2({ provider, renderStyles, setStyleItems, cach
|
|
|
1025
1056
|
});
|
|
1026
1057
|
return renderStyles({ styles: breakToBreakpoints(styles), signal }).then((rendered) => {
|
|
1027
1058
|
rebuildCache(cache, allStyles, rendered);
|
|
1028
|
-
return
|
|
1059
|
+
return getOrderedItems(cache);
|
|
1029
1060
|
});
|
|
1030
1061
|
}
|
|
1031
1062
|
function breakToBreakpoints(styles) {
|
|
@@ -1410,14 +1441,74 @@ var plainTransformer = createTransformer((value) => {
|
|
|
1410
1441
|
return value;
|
|
1411
1442
|
});
|
|
1412
1443
|
|
|
1413
|
-
// src/transformers/shared/
|
|
1444
|
+
// src/transformers/shared/svg-src-transformer.ts
|
|
1445
|
+
var import_dompurify = __toESM(require("dompurify"));
|
|
1414
1446
|
var import_wp_media2 = require("@elementor/wp-media");
|
|
1447
|
+
var SVG_INLINE_STYLES = "width: 100%; height: 100%; overflow: unset;";
|
|
1448
|
+
function processSvgContent(svgText) {
|
|
1449
|
+
const sanitized = import_dompurify.default.sanitize(svgText, {
|
|
1450
|
+
USE_PROFILES: { svg: true, svgFilters: true }
|
|
1451
|
+
});
|
|
1452
|
+
const parser = new DOMParser();
|
|
1453
|
+
const doc = parser.parseFromString(sanitized, "image/svg+xml");
|
|
1454
|
+
const svgElement = doc.querySelector("svg");
|
|
1455
|
+
if (!svgElement) {
|
|
1456
|
+
return null;
|
|
1457
|
+
}
|
|
1458
|
+
svgElement.setAttribute("fill", "currentColor");
|
|
1459
|
+
const existingStyle = svgElement.getAttribute("style") ?? "";
|
|
1460
|
+
const trimmed = existingStyle.trim();
|
|
1461
|
+
const merged = trimmed ? `${trimmed.replace(/;$/, "")}; ${SVG_INLINE_STYLES}` : SVG_INLINE_STYLES;
|
|
1462
|
+
svgElement.setAttribute("style", merged);
|
|
1463
|
+
return svgElement.outerHTML;
|
|
1464
|
+
}
|
|
1465
|
+
async function fetchSvgContent(url, signal) {
|
|
1466
|
+
try {
|
|
1467
|
+
const response = await fetch(url, { signal });
|
|
1468
|
+
if (!response.ok) {
|
|
1469
|
+
return null;
|
|
1470
|
+
}
|
|
1471
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
1472
|
+
const isSvg = contentType.includes("svg") || contentType.includes("xml") || url.endsWith(".svg");
|
|
1473
|
+
if (!isSvg) {
|
|
1474
|
+
return null;
|
|
1475
|
+
}
|
|
1476
|
+
return await response.text();
|
|
1477
|
+
} catch {
|
|
1478
|
+
return null;
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
function resolveSvgSrcId(id) {
|
|
1482
|
+
if (typeof id !== "number" || id <= 0) {
|
|
1483
|
+
return null;
|
|
1484
|
+
}
|
|
1485
|
+
return id;
|
|
1486
|
+
}
|
|
1487
|
+
var svgSrcTransformer = createTransformer(async (value, { signal }) => {
|
|
1488
|
+
const id = resolveSvgSrcId(value.id);
|
|
1489
|
+
const urlFromValue = typeof value.url === "string" ? value.url : null;
|
|
1490
|
+
let url = urlFromValue;
|
|
1491
|
+
if (id && !urlFromValue) {
|
|
1492
|
+
const attachment = await (0, import_wp_media2.getMediaAttachment)({ id });
|
|
1493
|
+
url = attachment?.url ?? null;
|
|
1494
|
+
}
|
|
1495
|
+
const resolvedUrl = typeof url === "string" ? url : null;
|
|
1496
|
+
if (!resolvedUrl) {
|
|
1497
|
+
return { html: null, url: null };
|
|
1498
|
+
}
|
|
1499
|
+
const svgText = await fetchSvgContent(resolvedUrl, signal);
|
|
1500
|
+
const html = svgText ? processSvgContent(svgText) : null;
|
|
1501
|
+
return { html, url: resolvedUrl };
|
|
1502
|
+
});
|
|
1503
|
+
|
|
1504
|
+
// src/transformers/shared/video-src-transformer.ts
|
|
1505
|
+
var import_wp_media3 = require("@elementor/wp-media");
|
|
1415
1506
|
var videoSrcTransformer = createTransformer(async (value) => {
|
|
1416
1507
|
const { id, url } = value;
|
|
1417
1508
|
if (!id) {
|
|
1418
1509
|
return { id: null, url };
|
|
1419
1510
|
}
|
|
1420
|
-
const attachment = await (0,
|
|
1511
|
+
const attachment = await (0, import_wp_media3.getMediaAttachment)({ id });
|
|
1421
1512
|
return {
|
|
1422
1513
|
id,
|
|
1423
1514
|
url: attachment?.url ?? url
|
|
@@ -1426,7 +1517,7 @@ var videoSrcTransformer = createTransformer(async (value) => {
|
|
|
1426
1517
|
|
|
1427
1518
|
// src/init-settings-transformers.ts
|
|
1428
1519
|
function initSettingsTransformers() {
|
|
1429
|
-
settingsTransformersRegistry.register("classes", createClassesTransformer()).register("link", linkTransformer).register("query", queryTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).register("video-src", videoSrcTransformer).register("attributes", attributesTransformer).register("date-time", dateTimeTransformer).register("html-v2", htmlV2Transformer).register("html-v3", htmlV3Transformer).registerFallback(plainTransformer);
|
|
1520
|
+
settingsTransformersRegistry.register("classes", createClassesTransformer()).register("link", linkTransformer).register("query", queryTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).register("svg-src", svgSrcTransformer).register("video-src", videoSrcTransformer).register("attributes", attributesTransformer).register("date-time", dateTimeTransformer).register("html-v2", htmlV2Transformer).register("html-v3", htmlV3Transformer).registerFallback(plainTransformer);
|
|
1430
1521
|
}
|
|
1431
1522
|
|
|
1432
1523
|
// src/transformers/styles/background-color-overlay-transformer.ts
|
|
@@ -1625,6 +1716,9 @@ var shadowTransformer = createTransformer((value) => {
|
|
|
1625
1716
|
|
|
1626
1717
|
// src/transformers/styles/size-transformer.ts
|
|
1627
1718
|
var sizeTransformer = createTransformer((value) => {
|
|
1719
|
+
if (value.unit === "auto") {
|
|
1720
|
+
return "auto";
|
|
1721
|
+
}
|
|
1628
1722
|
return value.unit === "custom" ? value.size : `${value.size}${value.unit}`;
|
|
1629
1723
|
});
|
|
1630
1724
|
|
|
@@ -2008,6 +2102,7 @@ function createTemplatedElementView({
|
|
|
2008
2102
|
this._lastResolvedSettingsHash = settingsHash;
|
|
2009
2103
|
const context = {
|
|
2010
2104
|
id: this.model.get("id"),
|
|
2105
|
+
interaction_id: this.getInteractionId(),
|
|
2011
2106
|
type,
|
|
2012
2107
|
settings,
|
|
2013
2108
|
base_styles: baseStylesDictionary
|
|
@@ -2042,6 +2137,11 @@ function createTemplatedElementView({
|
|
|
2042
2137
|
_openEditingPanel(options) {
|
|
2043
2138
|
this._doAfterRender(() => super._openEditingPanel(options));
|
|
2044
2139
|
}
|
|
2140
|
+
getInteractionId() {
|
|
2141
|
+
const originId = this.model.get("originId");
|
|
2142
|
+
const id = this.model.get("id");
|
|
2143
|
+
return originId ?? id;
|
|
2144
|
+
}
|
|
2045
2145
|
};
|
|
2046
2146
|
}
|
|
2047
2147
|
|
|
@@ -2074,10 +2174,11 @@ function createNestedTemplatedElementType({
|
|
|
2074
2174
|
}
|
|
2075
2175
|
function buildEditorAttributes(model) {
|
|
2076
2176
|
const id = model.get("id");
|
|
2177
|
+
const originId = model.get("originId");
|
|
2077
2178
|
const cid = model.cid ?? "";
|
|
2078
2179
|
const attrs = {
|
|
2079
2180
|
"data-model-cid": cid,
|
|
2080
|
-
"data-interaction-id": id,
|
|
2181
|
+
"data-interaction-id": originId ?? id,
|
|
2081
2182
|
"x-ignore": "true"
|
|
2082
2183
|
};
|
|
2083
2184
|
return Object.entries(attrs).map(([key, value]) => `${key}="${value}"`).join(" ");
|
|
@@ -2111,6 +2212,9 @@ function createNestedTemplatedElementView({
|
|
|
2111
2212
|
invalidateRenderCache() {
|
|
2112
2213
|
this._lastResolvedSettingsHash = null;
|
|
2113
2214
|
},
|
|
2215
|
+
renderOnChange() {
|
|
2216
|
+
this.render();
|
|
2217
|
+
},
|
|
2114
2218
|
render() {
|
|
2115
2219
|
this._abortController?.abort();
|
|
2116
2220
|
this._abortController = new AbortController();
|
|
@@ -2154,6 +2258,7 @@ function createNestedTemplatedElementView({
|
|
|
2154
2258
|
this._lastResolvedSettingsHash = settingsHash;
|
|
2155
2259
|
const context = {
|
|
2156
2260
|
id: model.get("id"),
|
|
2261
|
+
interaction_id: this.getInteractionId(),
|
|
2157
2262
|
type,
|
|
2158
2263
|
settings,
|
|
2159
2264
|
base_styles: baseStylesDictionary,
|
|
@@ -2283,13 +2388,20 @@ function createNestedTemplatedElementView({
|
|
|
2283
2388
|
},
|
|
2284
2389
|
_openEditingPanel(options) {
|
|
2285
2390
|
this._doAfterRender(() => parentOpenEditingPanel.call(this, options));
|
|
2391
|
+
},
|
|
2392
|
+
getInteractionId() {
|
|
2393
|
+
const originId = this.model.get("originId");
|
|
2394
|
+
const id = this.model.get("id");
|
|
2395
|
+
return originId ?? id;
|
|
2286
2396
|
}
|
|
2287
2397
|
});
|
|
2288
2398
|
}
|
|
2289
2399
|
|
|
2400
|
+
// src/legacy/replacements/manager.ts
|
|
2401
|
+
var import_client = require("react-dom/client");
|
|
2402
|
+
|
|
2290
2403
|
// src/legacy/replacements/inline-editing/inline-editing-elements.tsx
|
|
2291
2404
|
var React6 = __toESM(require("react"));
|
|
2292
|
-
var import_client = require("react-dom/client");
|
|
2293
2405
|
var import_editor_elements5 = require("@elementor/editor-elements");
|
|
2294
2406
|
var import_editor_props4 = require("@elementor/editor-props");
|
|
2295
2407
|
var import_editor_v1_adapters11 = require("@elementor/editor-v1-adapters");
|
|
@@ -2308,6 +2420,8 @@ var ReplacementBase = class {
|
|
|
2308
2420
|
type;
|
|
2309
2421
|
id;
|
|
2310
2422
|
refreshView;
|
|
2423
|
+
reactRoot;
|
|
2424
|
+
reactContainer;
|
|
2311
2425
|
constructor(settings) {
|
|
2312
2426
|
this.getSetting = settings.getSetting;
|
|
2313
2427
|
this.setSetting = settings.setSetting;
|
|
@@ -2315,6 +2429,8 @@ var ReplacementBase = class {
|
|
|
2315
2429
|
this.type = settings.type;
|
|
2316
2430
|
this.id = settings.id;
|
|
2317
2431
|
this.refreshView = settings.refreshView;
|
|
2432
|
+
this.reactRoot = settings.reactRoot;
|
|
2433
|
+
this.reactContainer = settings.reactContainer;
|
|
2318
2434
|
}
|
|
2319
2435
|
static getTypes() {
|
|
2320
2436
|
return null;
|
|
@@ -2365,7 +2481,8 @@ var INLINE_EDITING_PROPERTY_PER_TYPE = {
|
|
|
2365
2481
|
"e-button": "text",
|
|
2366
2482
|
"e-form-label": "text",
|
|
2367
2483
|
"e-heading": "title",
|
|
2368
|
-
"e-paragraph": "paragraph"
|
|
2484
|
+
"e-paragraph": "paragraph",
|
|
2485
|
+
"e-form-submit-button": "text"
|
|
2369
2486
|
};
|
|
2370
2487
|
var getInlineEditorElement = (elementWrapper, expectedTag) => {
|
|
2371
2488
|
return !expectedTag ? null : elementWrapper.querySelector(expectedTag);
|
|
@@ -2383,6 +2500,11 @@ var useOnClickOutsideIframe = (handleUnmount) => {
|
|
|
2383
2500
|
};
|
|
2384
2501
|
var useRenderToolbar = (ownerDocument, id) => {
|
|
2385
2502
|
const [anchor, setAnchor] = (0, import_react11.useState)(null);
|
|
2503
|
+
(0, import_react11.useEffect)(() => {
|
|
2504
|
+
if (!anchor) {
|
|
2505
|
+
removeToolbarAnchor(ownerDocument, id);
|
|
2506
|
+
}
|
|
2507
|
+
}, [anchor, ownerDocument, id]);
|
|
2386
2508
|
const onSelectionEnd = (view) => {
|
|
2387
2509
|
const hasSelection = !view.state.selection.empty;
|
|
2388
2510
|
removeToolbarAnchor(ownerDocument, id);
|
|
@@ -2392,7 +2514,10 @@ var useRenderToolbar = (ownerDocument, id) => {
|
|
|
2392
2514
|
setAnchor(null);
|
|
2393
2515
|
}
|
|
2394
2516
|
};
|
|
2395
|
-
|
|
2517
|
+
const clearAnchor = (0, import_react11.useCallback)(() => {
|
|
2518
|
+
setAnchor(null);
|
|
2519
|
+
}, []);
|
|
2520
|
+
return { onSelectionEnd, anchor, clearAnchor };
|
|
2396
2521
|
};
|
|
2397
2522
|
var createAnchorBasedOnSelection = (ownerDocument, id) => {
|
|
2398
2523
|
const frameWindow = ownerDocument.defaultView;
|
|
@@ -2459,46 +2584,59 @@ var horizontalShifterMiddleware = {
|
|
|
2459
2584
|
};
|
|
2460
2585
|
|
|
2461
2586
|
// src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
|
|
2462
|
-
var EDITOR_WRAPPER_SELECTOR = "inline-editor-wrapper";
|
|
2463
2587
|
var CanvasInlineEditor = ({
|
|
2464
2588
|
elementClasses,
|
|
2465
2589
|
initialValue,
|
|
2466
2590
|
expectedTag,
|
|
2467
2591
|
rootElement,
|
|
2592
|
+
contentElement,
|
|
2468
2593
|
id,
|
|
2469
2594
|
setValue,
|
|
2470
|
-
|
|
2595
|
+
requestDestroy
|
|
2471
2596
|
}) => {
|
|
2597
|
+
const [active, setActive] = (0, import_react12.useState)(true);
|
|
2472
2598
|
const [editor, setEditor] = (0, import_react12.useState)(null);
|
|
2473
|
-
const { onSelectionEnd, anchor: toolbarAnchor } = useRenderToolbar(rootElement.ownerDocument, id);
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2599
|
+
const { onSelectionEnd, anchor: toolbarAnchor, clearAnchor } = useRenderToolbar(rootElement.ownerDocument, id);
|
|
2600
|
+
(0, import_react12.useEffect)(() => {
|
|
2601
|
+
if (!active) {
|
|
2602
|
+
clearAnchor();
|
|
2603
|
+
requestDestroy();
|
|
2604
|
+
}
|
|
2605
|
+
}, [active, clearAnchor, requestDestroy]);
|
|
2606
|
+
const dismiss = (0, import_react12.useCallback)(() => {
|
|
2607
|
+
setEditor(null);
|
|
2608
|
+
setActive(false);
|
|
2609
|
+
}, []);
|
|
2610
|
+
useOnClickOutsideIframe(dismiss);
|
|
2611
|
+
(0, import_react12.useEffect)(() => {
|
|
2612
|
+
const ownerDocument = contentElement.ownerDocument;
|
|
2613
|
+
const handleClickAway = (event) => {
|
|
2614
|
+
if (contentElement.contains(event.target)) {
|
|
2615
|
+
return;
|
|
2616
|
+
}
|
|
2617
|
+
dismiss();
|
|
2618
|
+
};
|
|
2619
|
+
ownerDocument.addEventListener("mousedown", handleClickAway);
|
|
2620
|
+
return () => ownerDocument.removeEventListener("mousedown", handleClickAway);
|
|
2621
|
+
}, [contentElement, dismiss]);
|
|
2622
|
+
if (!active) {
|
|
2623
|
+
return null;
|
|
2624
|
+
}
|
|
2625
|
+
return /* @__PURE__ */ React5.createElement(import_ui4.ThemeProvider, null, /* @__PURE__ */ React5.createElement(InlineEditingOverlay, { expectedTag, rootElement, id }), /* @__PURE__ */ React5.createElement(
|
|
2488
2626
|
import_editor_controls2.InlineEditor,
|
|
2489
2627
|
{
|
|
2490
2628
|
onEditorCreate: setEditor,
|
|
2629
|
+
mountElement: contentElement,
|
|
2491
2630
|
editorProps: {
|
|
2492
2631
|
attributes: {
|
|
2493
|
-
style: "outline: none;
|
|
2632
|
+
style: "outline: none; display: inherit; justify-content: inherit; align-items: inherit; flex-direction: inherit; text-align: inherit;"
|
|
2494
2633
|
}
|
|
2495
2634
|
},
|
|
2496
2635
|
elementClasses,
|
|
2497
2636
|
value: initialValue,
|
|
2498
2637
|
setValue,
|
|
2499
|
-
onBlur,
|
|
2638
|
+
onBlur: dismiss,
|
|
2500
2639
|
autofocus: true,
|
|
2501
|
-
expectedTag,
|
|
2502
2640
|
onSelectionEnd
|
|
2503
2641
|
}
|
|
2504
2642
|
), toolbarAnchor && editor && /* @__PURE__ */ React5.createElement(InlineEditingToolbar, { anchor: toolbarAnchor, editor, id }));
|
|
@@ -2527,7 +2665,18 @@ var InlineEditingToolbar = ({ anchor, editor, id }) => {
|
|
|
2527
2665
|
refs.setReference(anchor);
|
|
2528
2666
|
return () => refs.setReference(null);
|
|
2529
2667
|
}, [anchor, refs]);
|
|
2530
|
-
return /* @__PURE__ */ React5.createElement(import_react13.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React5.createElement(
|
|
2668
|
+
return /* @__PURE__ */ React5.createElement(import_react13.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React5.createElement(
|
|
2669
|
+
import_ui4.Box,
|
|
2670
|
+
{
|
|
2671
|
+
ref: refs.setFloating,
|
|
2672
|
+
role: "presentation",
|
|
2673
|
+
style: {
|
|
2674
|
+
...floatingStyles,
|
|
2675
|
+
pointerEvents: "none"
|
|
2676
|
+
}
|
|
2677
|
+
},
|
|
2678
|
+
/* @__PURE__ */ React5.createElement(import_editor_controls2.InlineEditorToolbar, { editor, elementId: id })
|
|
2679
|
+
));
|
|
2531
2680
|
};
|
|
2532
2681
|
|
|
2533
2682
|
// src/legacy/replacements/inline-editing/inline-editing-eligibility.ts
|
|
@@ -2561,8 +2710,8 @@ var isInlineEditingAllowed = ({ rawValue, propTypeFromSchema }) => {
|
|
|
2561
2710
|
// src/legacy/replacements/inline-editing/inline-editing-elements.tsx
|
|
2562
2711
|
var HISTORY_DEBOUNCE_WAIT = 800;
|
|
2563
2712
|
var InlineEditingReplacement = class extends ReplacementBase {
|
|
2564
|
-
inlineEditorRoot = null;
|
|
2565
2713
|
handlerAttached = false;
|
|
2714
|
+
editing = false;
|
|
2566
2715
|
getReplacementKey() {
|
|
2567
2716
|
return "inline-editing";
|
|
2568
2717
|
}
|
|
@@ -2570,7 +2719,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
2570
2719
|
return Object.keys(INLINE_EDITING_PROPERTY_PER_TYPE);
|
|
2571
2720
|
}
|
|
2572
2721
|
isEditingModeActive() {
|
|
2573
|
-
return
|
|
2722
|
+
return this.editing;
|
|
2574
2723
|
}
|
|
2575
2724
|
shouldRenderReplacement() {
|
|
2576
2725
|
return this.isInlineEditingEligible() && (0, import_editor_v1_adapters11.getCurrentEditMode)() === "edit";
|
|
@@ -2613,8 +2762,8 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
2613
2762
|
resetInlineEditorRoot() {
|
|
2614
2763
|
this.element.removeEventListener("click", this.handleRenderInlineEditor);
|
|
2615
2764
|
this.handlerAttached = false;
|
|
2616
|
-
this.
|
|
2617
|
-
this.
|
|
2765
|
+
this.reactRoot.render(null);
|
|
2766
|
+
this.editing = false;
|
|
2618
2767
|
}
|
|
2619
2768
|
unmountInlineEditor() {
|
|
2620
2769
|
this.resetInlineEditorRoot();
|
|
@@ -2725,12 +2874,16 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
2725
2874
|
if (this.isEditingModeActive()) {
|
|
2726
2875
|
this.resetInlineEditorRoot();
|
|
2727
2876
|
}
|
|
2728
|
-
const
|
|
2877
|
+
const contentElement = this.element.children?.[0];
|
|
2878
|
+
if (!contentElement) {
|
|
2879
|
+
return;
|
|
2880
|
+
}
|
|
2881
|
+
const elementClasses = contentElement.classList.toString();
|
|
2729
2882
|
const propValue = this.getExtractedContentValue();
|
|
2730
2883
|
const expectedTag = this.getExpectedTag();
|
|
2731
|
-
|
|
2732
|
-
this.
|
|
2733
|
-
this.
|
|
2884
|
+
contentElement.innerHTML = "";
|
|
2885
|
+
this.editing = true;
|
|
2886
|
+
this.reactRoot.render(
|
|
2734
2887
|
/* @__PURE__ */ React6.createElement(
|
|
2735
2888
|
CanvasInlineEditor,
|
|
2736
2889
|
{
|
|
@@ -2738,9 +2891,10 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
2738
2891
|
initialValue: propValue,
|
|
2739
2892
|
expectedTag,
|
|
2740
2893
|
rootElement: this.element,
|
|
2894
|
+
contentElement,
|
|
2741
2895
|
id: this.id,
|
|
2742
2896
|
setValue: this.setContentValue.bind(this),
|
|
2743
|
-
|
|
2897
|
+
requestDestroy: this.unmountInlineEditor.bind(this)
|
|
2744
2898
|
}
|
|
2745
2899
|
)
|
|
2746
2900
|
);
|
|
@@ -2769,16 +2923,24 @@ var createViewWithReplacements = (options) => {
|
|
|
2769
2923
|
return class extends TemplatedView {
|
|
2770
2924
|
#replacement = null;
|
|
2771
2925
|
#config;
|
|
2926
|
+
#reactContainer;
|
|
2927
|
+
#reactRoot;
|
|
2772
2928
|
constructor(...args) {
|
|
2773
2929
|
super(...args);
|
|
2774
2930
|
const settings = this.model.get("settings");
|
|
2931
|
+
this.#reactContainer = this.el.ownerDocument.createElement("div");
|
|
2932
|
+
this.#reactContainer.style.display = "none";
|
|
2933
|
+
this.el.ownerDocument.body.appendChild(this.#reactContainer);
|
|
2934
|
+
this.#reactRoot = (0, import_client.createRoot)(this.#reactContainer);
|
|
2775
2935
|
this.#config = {
|
|
2776
2936
|
getSetting: settings.get.bind(settings),
|
|
2777
2937
|
setSetting: settings.set.bind(settings),
|
|
2778
2938
|
element: this.el,
|
|
2779
2939
|
type: this?.model?.get("widgetType") ?? this.container?.model?.get("elType") ?? null,
|
|
2780
2940
|
id: this?.model?.get("id") ?? null,
|
|
2781
|
-
refreshView: this.refreshView.bind(this)
|
|
2941
|
+
refreshView: this.refreshView.bind(this),
|
|
2942
|
+
reactRoot: this.#reactRoot,
|
|
2943
|
+
reactContainer: this.#reactContainer
|
|
2782
2944
|
};
|
|
2783
2945
|
}
|
|
2784
2946
|
refreshView() {
|
|
@@ -2799,6 +2961,8 @@ var createViewWithReplacements = (options) => {
|
|
|
2799
2961
|
}
|
|
2800
2962
|
onDestroy() {
|
|
2801
2963
|
this.#triggerAltMethod("onDestroy");
|
|
2964
|
+
this.#reactRoot.unmount();
|
|
2965
|
+
this.#reactContainer.remove();
|
|
2802
2966
|
}
|
|
2803
2967
|
_afterRender() {
|
|
2804
2968
|
this.#triggerAltMethod("_afterRender");
|
|
@@ -2937,7 +3101,7 @@ function initTabsModelExtensions() {
|
|
|
2937
3101
|
var import_editor_v1_adapters13 = require("@elementor/editor-v1-adapters");
|
|
2938
3102
|
var DOCUMENT_STRUCTURE_URI = "elementor://document/structure";
|
|
2939
3103
|
var initDocumentStructureResource = (reg) => {
|
|
2940
|
-
const {
|
|
3104
|
+
const { resource, sendResourceUpdated } = reg;
|
|
2941
3105
|
let currentDocumentStructure = null;
|
|
2942
3106
|
const updateDocumentStructure = () => {
|
|
2943
3107
|
const structure = getDocumentStructure();
|
|
@@ -2959,17 +3123,23 @@ var initDocumentStructureResource = (reg) => {
|
|
|
2959
3123
|
updateDocumentStructure
|
|
2960
3124
|
);
|
|
2961
3125
|
updateDocumentStructure();
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
3126
|
+
resource(
|
|
3127
|
+
"document-structure",
|
|
3128
|
+
DOCUMENT_STRUCTURE_URI,
|
|
3129
|
+
{
|
|
3130
|
+
description: "Document structure."
|
|
3131
|
+
},
|
|
3132
|
+
async () => {
|
|
3133
|
+
return {
|
|
3134
|
+
contents: [
|
|
3135
|
+
{
|
|
3136
|
+
uri: DOCUMENT_STRUCTURE_URI,
|
|
3137
|
+
text: JSON.stringify(getDocumentStructure(), null, 2)
|
|
3138
|
+
}
|
|
3139
|
+
]
|
|
3140
|
+
};
|
|
3141
|
+
}
|
|
3142
|
+
);
|
|
2973
3143
|
};
|
|
2974
3144
|
function getDocumentStructure() {
|
|
2975
3145
|
const extendedWindow = window;
|
|
@@ -3009,6 +3179,7 @@ function extractElementData(element) {
|
|
|
3009
3179
|
}
|
|
3010
3180
|
|
|
3011
3181
|
// src/mcp/tools/build-composition/tool.ts
|
|
3182
|
+
var import_editor_documents3 = require("@elementor/editor-documents");
|
|
3012
3183
|
var import_editor_elements10 = require("@elementor/editor-elements");
|
|
3013
3184
|
|
|
3014
3185
|
// src/composition-builder/composition-builder.ts
|
|
@@ -3423,6 +3594,16 @@ var CompositionBuilder = class _CompositionBuilder {
|
|
|
3423
3594
|
}
|
|
3424
3595
|
};
|
|
3425
3596
|
|
|
3597
|
+
// src/mcp/utils/get-composition-target-container.ts
|
|
3598
|
+
var import_editor_documents2 = require("@elementor/editor-documents");
|
|
3599
|
+
function getCompositionTargetContainer(documentContainer, documentType) {
|
|
3600
|
+
const firstChild = documentContainer.children?.[0];
|
|
3601
|
+
if (documentType === import_editor_documents2.COMPONENT_DOCUMENT_TYPE && firstChild) {
|
|
3602
|
+
return firstChild;
|
|
3603
|
+
}
|
|
3604
|
+
return documentContainer;
|
|
3605
|
+
}
|
|
3606
|
+
|
|
3426
3607
|
// src/mcp/tools/build-composition/prompt.ts
|
|
3427
3608
|
var import_editor_mcp2 = require("@elementor/editor-mcp");
|
|
3428
3609
|
var generatePrompt = () => {
|
|
@@ -3618,6 +3799,8 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
3618
3799
|
const errors = [];
|
|
3619
3800
|
const rootContainers = [];
|
|
3620
3801
|
const documentContainer = (0, import_editor_elements10.getContainer)("document");
|
|
3802
|
+
const currentDocument = (0, import_editor_documents3.getCurrentDocument)();
|
|
3803
|
+
const targetContainer = getCompositionTargetContainer(documentContainer, currentDocument?.type.value);
|
|
3621
3804
|
try {
|
|
3622
3805
|
const compositionBuilder = CompositionBuilder.fromXMLString(xmlStructure, {
|
|
3623
3806
|
createElement: import_editor_elements10.createElement,
|
|
@@ -3630,7 +3813,7 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
3630
3813
|
configErrors,
|
|
3631
3814
|
invalidStyles,
|
|
3632
3815
|
rootContainers: generatedRootContainers
|
|
3633
|
-
} = compositionBuilder.build(
|
|
3816
|
+
} = compositionBuilder.build(targetContainer);
|
|
3634
3817
|
rootContainers.push(...generatedRootContainers);
|
|
3635
3818
|
generatedXML = new XMLSerializer().serializeToString(compositionBuilder.getXML());
|
|
3636
3819
|
if (configErrors.length) {
|
|
@@ -4014,14 +4197,12 @@ var initGetElementConfigTool = (reg) => {
|
|
|
4014
4197
|
var initCanvasMcp = (reg) => {
|
|
4015
4198
|
const { setMCPDescription } = reg;
|
|
4016
4199
|
setMCPDescription(
|
|
4017
|
-
`Everything related to
|
|
4200
|
+
`Everything related to V4 ( Atomic ) canvas.
|
|
4018
4201
|
# Canvas workflow for new compositions
|
|
4019
|
-
-
|
|
4020
|
-
-
|
|
4021
|
-
-
|
|
4022
|
-
|
|
4023
|
-
- Build valid XML with minimal inline styles (layout/positioning only)
|
|
4024
|
-
- Apply global classes to elements`
|
|
4202
|
+
- Configure elements settings and styles
|
|
4203
|
+
- Build compositions/sections out of V4 atomic elements using context aware designs using the website resources
|
|
4204
|
+
- Get and retrieve element configuration values
|
|
4205
|
+
`
|
|
4025
4206
|
);
|
|
4026
4207
|
initWidgetsSchemaResource(reg);
|
|
4027
4208
|
initDocumentStructureResource(reg);
|