@elementor/editor-canvas 0.15.4 → 0.17.0

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.
Files changed (33) hide show
  1. package/.turbo/turbo-build.log +10 -10
  2. package/CHANGELOG.md +38 -0
  3. package/dist/index.d.mts +4 -1
  4. package/dist/index.d.ts +4 -1
  5. package/dist/index.js +448 -281
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +437 -267
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +6 -5
  10. package/src/__tests__/styles-prop-resolver.test.ts +1 -0
  11. package/src/components/__tests__/style-renderer.test.tsx +65 -0
  12. package/src/components/style-renderer.tsx +32 -0
  13. package/src/hooks/__tests__/use-style-items.test.ts +136 -0
  14. package/src/hooks/__tests__/use-style-prop-resolver.test.ts +51 -0
  15. package/src/hooks/use-on-mount.ts +13 -0
  16. package/src/hooks/use-style-items.ts +78 -0
  17. package/src/hooks/use-style-prop-resolver.ts +22 -0
  18. package/src/hooks/use-style-renderer.ts +19 -0
  19. package/src/index.ts +1 -0
  20. package/src/init.tsx +9 -2
  21. package/src/legacy/create-element-type.ts +14 -0
  22. package/src/legacy/create-templated-element-type.ts +1 -1
  23. package/src/legacy/types.ts +9 -0
  24. package/src/prevent-link-in-link-commands.ts +132 -0
  25. package/src/renderers/__tests__/{render-styles.test.ts → create-styles-renderer.test.ts} +35 -19
  26. package/src/renderers/{render-styles.ts → create-styles-renderer.ts} +35 -32
  27. package/src/sync/{get-canvas-iframe-body.ts → get-canvas-iframe-head.ts} +2 -2
  28. package/src/sync/types.ts +7 -0
  29. package/src/utils/abort-previous-runs.ts +16 -0
  30. package/src/__tests__/init-styles-renderer.test.ts +0 -112
  31. package/src/init-styles-renderer.ts +0 -84
  32. /package/src/{legacy → utils}/__tests__/signalized-process.test.ts +0 -0
  33. /package/src/{legacy → utils}/signalized-process.ts +0 -0
package/dist/index.js CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ createTransformer: () => createTransformer,
33
34
  settingsTransformersRegistry: () => settingsTransformersRegistry,
34
35
  styleTransformersRegistry: () => styleTransformersRegistry
35
36
  });
@@ -164,6 +165,149 @@ function useElementsDom() {
164
165
  );
165
166
  }
166
167
 
168
+ // src/components/style-renderer.tsx
169
+ var React3 = __toESM(require("react"));
170
+ var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
171
+ var import_ui2 = require("@elementor/ui");
172
+
173
+ // src/hooks/use-style-items.ts
174
+ var import_react8 = require("react");
175
+ var import_editor_styles_repository = require("@elementor/editor-styles-repository");
176
+ var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
177
+
178
+ // src/utils/abort-previous-runs.ts
179
+ function abortPreviousRuns(cb) {
180
+ let abortController = null;
181
+ return (...args) => {
182
+ if (abortController) {
183
+ abortController.abort();
184
+ }
185
+ abortController = new AbortController();
186
+ return cb(abortController, ...args);
187
+ };
188
+ }
189
+
190
+ // src/utils/signalized-process.ts
191
+ function signalizedProcess(signal, steps = []) {
192
+ return {
193
+ then: (cb) => {
194
+ steps.push(cb);
195
+ return signalizedProcess(signal, steps);
196
+ },
197
+ execute: async () => {
198
+ let lastResult;
199
+ for (const step of steps) {
200
+ if (signal.aborted) {
201
+ break;
202
+ }
203
+ lastResult = await step(lastResult, signal);
204
+ }
205
+ }
206
+ };
207
+ }
208
+
209
+ // src/hooks/use-on-mount.ts
210
+ var import_react5 = require("react");
211
+ function useOnMount(cb) {
212
+ const mounted = (0, import_react5.useRef)(false);
213
+ (0, import_react5.useEffect)(() => {
214
+ if (!mounted.current) {
215
+ mounted.current = true;
216
+ cb();
217
+ }
218
+ }, []);
219
+ }
220
+
221
+ // src/hooks/use-style-prop-resolver.ts
222
+ var import_react6 = require("react");
223
+ var import_editor_styles = require("@elementor/editor-styles");
224
+
225
+ // src/renderers/create-props-resolver.ts
226
+ var import_editor_props = require("@elementor/editor-props");
227
+
228
+ // src/renderers/multi-props.ts
229
+ var isMultiProps = (propValue) => {
230
+ return !!propValue && typeof propValue === "object" && "$$multi-props" in propValue && propValue["$$multi-props"] === true;
231
+ };
232
+ var createMultiPropsValue = (props) => {
233
+ return {
234
+ "$$multi-props": true,
235
+ value: props
236
+ };
237
+ };
238
+ var getMultiPropsValue = (multiProps) => {
239
+ return multiProps.value;
240
+ };
241
+
242
+ // src/renderers/create-props-resolver.ts
243
+ var TRANSFORM_DEPTH_LIMIT = 3;
244
+ function createPropsResolver({ transformers, schema: initialSchema, onPropResolve }) {
245
+ async function resolve({ props, schema, signal }) {
246
+ schema = schema ?? initialSchema;
247
+ const promises = Promise.all(
248
+ Object.entries(schema).map(async ([key, type]) => {
249
+ const value = props[key] ?? type.default;
250
+ const transformed = await transform({ value, key, type, signal });
251
+ onPropResolve?.({ key, value: transformed });
252
+ if (isMultiProps(transformed)) {
253
+ return getMultiPropsValue(transformed);
254
+ }
255
+ return { [key]: transformed };
256
+ })
257
+ );
258
+ return Object.assign({}, ...(await promises).filter(Boolean));
259
+ }
260
+ async function transform({ value, key, type, signal, depth = 0 }) {
261
+ if (value === null || value === void 0) {
262
+ return null;
263
+ }
264
+ if (!(0, import_editor_props.isTransformable)(value)) {
265
+ return value;
266
+ }
267
+ if (depth > TRANSFORM_DEPTH_LIMIT) {
268
+ return null;
269
+ }
270
+ if (value.disabled === true) {
271
+ return null;
272
+ }
273
+ if (type.kind === "union") {
274
+ type = type.prop_types[value.$$type];
275
+ if (!type) {
276
+ return null;
277
+ }
278
+ }
279
+ if (value.$$type !== type.key) {
280
+ return null;
281
+ }
282
+ let resolvedValue = value.value;
283
+ if (type.kind === "object") {
284
+ resolvedValue = await resolve({
285
+ props: resolvedValue,
286
+ schema: type.shape,
287
+ signal
288
+ });
289
+ }
290
+ if (type.kind === "array") {
291
+ resolvedValue = await Promise.all(
292
+ resolvedValue.map(
293
+ (item) => transform({ value: item, key, type: type.item_prop_type, depth, signal })
294
+ )
295
+ );
296
+ }
297
+ const transformer = transformers.get(value.$$type);
298
+ if (!transformer) {
299
+ return null;
300
+ }
301
+ try {
302
+ const transformed = await transformer(resolvedValue, { key, signal });
303
+ return transform({ value: transformed, key, type, signal, depth: depth + 1 });
304
+ } catch {
305
+ return null;
306
+ }
307
+ }
308
+ return resolve;
309
+ }
310
+
167
311
  // src/transformers/create-transformers-registry.ts
168
312
  function createTransformersRegistry() {
169
313
  const transformers = {};
@@ -183,6 +327,176 @@ function createTransformersRegistry() {
183
327
  };
184
328
  }
185
329
 
330
+ // src/style-transformers-registry.ts
331
+ var styleTransformersRegistry = createTransformersRegistry();
332
+
333
+ // src/sync/enqueue-font.ts
334
+ var enqueueFont = (fontFamily, context = "preview") => {
335
+ const extendedWindow = window;
336
+ return extendedWindow.elementor?.helpers?.enqueueFont?.(fontFamily, context) ?? null;
337
+ };
338
+
339
+ // src/hooks/use-style-prop-resolver.ts
340
+ function useStylePropResolver() {
341
+ return (0, import_react6.useMemo)(() => {
342
+ return createPropsResolver({
343
+ transformers: styleTransformersRegistry,
344
+ schema: (0, import_editor_styles.getStylesSchema)(),
345
+ onPropResolve: ({ key, value }) => {
346
+ if (key !== "font-family" || typeof value !== "string") {
347
+ return;
348
+ }
349
+ enqueueFont(value);
350
+ }
351
+ });
352
+ }, []);
353
+ }
354
+
355
+ // src/hooks/use-style-renderer.ts
356
+ var import_react7 = require("react");
357
+ var import_editor_responsive = require("@elementor/editor-responsive");
358
+
359
+ // src/renderers/errors.ts
360
+ var import_utils = require("@elementor/utils");
361
+ var UnknownStyleTypeError = (0, import_utils.createError)({
362
+ code: "unknown_style_type",
363
+ message: "Unknown style type"
364
+ });
365
+
366
+ // src/renderers/create-styles-renderer.ts
367
+ var SELECTORS_MAP = {
368
+ class: "."
369
+ };
370
+ function createStylesRenderer({ resolve, breakpoints, selectorPrefix = "" }) {
371
+ return async ({ styles, signal }) => {
372
+ const stylesCssPromises = styles.map(async (style) => {
373
+ const variantCssPromises = Object.values(style.variants).map(async (variant) => {
374
+ const css = await propsToCss({ props: variant.props, resolve, signal });
375
+ return createStyleWrapper().forStyle(style).withPrefix(selectorPrefix).withState(variant.meta.state).withMediaQuery(variant.meta.breakpoint ? breakpoints[variant.meta.breakpoint] : null).wrap(css);
376
+ });
377
+ const variantsCss = await Promise.all(variantCssPromises);
378
+ return {
379
+ id: style.id,
380
+ value: variantsCss.join("")
381
+ };
382
+ });
383
+ return await Promise.all(stylesCssPromises);
384
+ };
385
+ }
386
+ function createStyleWrapper(value = "", wrapper) {
387
+ return {
388
+ forStyle: ({ id, type }) => {
389
+ const symbol = SELECTORS_MAP[type];
390
+ if (!symbol) {
391
+ throw new UnknownStyleTypeError({ context: { type } });
392
+ }
393
+ return createStyleWrapper(`${value}${symbol}${id}`, wrapper);
394
+ },
395
+ withPrefix: (prefix) => createStyleWrapper([prefix, value].filter(Boolean).join(" "), wrapper),
396
+ withState: (state) => createStyleWrapper(state ? `${value}:${state}` : value, wrapper),
397
+ withMediaQuery: (breakpoint) => {
398
+ if (!breakpoint?.type) {
399
+ return createStyleWrapper(value, wrapper);
400
+ }
401
+ const size2 = `${breakpoint.type}:${breakpoint.width}px`;
402
+ return createStyleWrapper(value, (css) => `@media(${size2}){${css}}`);
403
+ },
404
+ wrap: (css) => {
405
+ const res = `${value}{${css}}`;
406
+ if (!wrapper) {
407
+ return res;
408
+ }
409
+ return wrapper(res);
410
+ }
411
+ };
412
+ }
413
+ async function propsToCss({ props, resolve, signal }) {
414
+ const transformed = await resolve({ props, signal });
415
+ return Object.entries(transformed).reduce((acc, [propName, propValue]) => {
416
+ if (propValue === null) {
417
+ return acc;
418
+ }
419
+ acc.push(propName + ":" + propValue + ";");
420
+ return acc;
421
+ }, []).join("");
422
+ }
423
+
424
+ // src/hooks/use-style-renderer.ts
425
+ var SELECTOR_PREFIX = ".elementor";
426
+ function useStyleRenderer(resolve) {
427
+ const breakpoints = (0, import_editor_responsive.useBreakpointsMap)();
428
+ return (0, import_react7.useMemo)(() => {
429
+ return createStylesRenderer({
430
+ selectorPrefix: SELECTOR_PREFIX,
431
+ breakpoints,
432
+ resolve
433
+ });
434
+ }, [resolve, breakpoints]);
435
+ }
436
+
437
+ // src/hooks/use-style-items.ts
438
+ function useStyleItems() {
439
+ const resolve = useStylePropResolver();
440
+ const renderStyles = useStyleRenderer(resolve);
441
+ const [styleItems, setStyleItems] = (0, import_react8.useState)({});
442
+ const providerAndSubscribers = (0, import_react8.useMemo)(() => {
443
+ return import_editor_styles_repository.stylesRepository.getProviders().map((provider) => {
444
+ return {
445
+ provider,
446
+ subscriber: createProviderSubscriber({
447
+ provider,
448
+ renderStyles,
449
+ setStyleItems
450
+ })
451
+ };
452
+ });
453
+ }, [renderStyles]);
454
+ (0, import_react8.useEffect)(() => {
455
+ const unsubscribes = providerAndSubscribers.map(
456
+ ({ provider, subscriber }) => provider.subscribe(subscriber)
457
+ );
458
+ return () => {
459
+ unsubscribes.forEach((unsubscribe) => unsubscribe());
460
+ };
461
+ }, [providerAndSubscribers]);
462
+ useOnMount(() => {
463
+ (0, import_editor_v1_adapters2.registerDataHook)("after", "editor/documents/attach-preview", async () => {
464
+ const promises = providerAndSubscribers.map(async ({ subscriber }) => subscriber());
465
+ await Promise.all(promises);
466
+ });
467
+ });
468
+ return Object.values(styleItems).sort(({ provider: providerA }, { provider: providerB }) => providerA.priority - providerB.priority).flatMap(({ items }) => items);
469
+ }
470
+ function createProviderSubscriber({ provider, renderStyles, setStyleItems }) {
471
+ return abortPreviousRuns(
472
+ (abortController) => signalizedProcess(abortController.signal).then((_, signal) => renderStyles({ styles: provider.actions.get(), signal })).then((items) => {
473
+ setStyleItems((prev) => ({
474
+ ...prev,
475
+ [provider.key]: { provider, items }
476
+ }));
477
+ }).execute()
478
+ );
479
+ }
480
+
481
+ // src/sync/get-canvas-iframe-head.ts
482
+ function getCanvasIframeHead() {
483
+ const extendedWindow = window;
484
+ return extendedWindow.elementor?.$preview?.[0]?.contentDocument?.head;
485
+ }
486
+
487
+ // src/components/style-renderer.tsx
488
+ function StyleRenderer() {
489
+ const container = usePortalContainer();
490
+ const styleItems = useStyleItems();
491
+ if (!container) {
492
+ return null;
493
+ }
494
+ return /* @__PURE__ */ React3.createElement(import_ui2.Portal, { container }, /* @__PURE__ */ React3.createElement(React3.Fragment, null, styleItems.map((item) => /* @__PURE__ */ React3.createElement("style", { "data-e-style-id": item.id, key: item.id }, item.value))));
495
+ }
496
+ function usePortalContainer() {
497
+ return (0, import_editor_v1_adapters3.__privateUseListenTo)((0, import_editor_v1_adapters3.commandEndEvent)("editor/documents/attach-preview"), () => getCanvasIframeHead());
498
+ }
499
+
186
500
  // src/settings-transformers-registry.ts
187
501
  var settingsTransformersRegistry = createTransformersRegistry();
188
502
 
@@ -247,9 +561,6 @@ function initSettingsTransformers() {
247
561
  settingsTransformersRegistry.register("classes", arrayTransformer).register("link", linkTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).registerFallback(plainTransformer);
248
562
  }
249
563
 
250
- // src/style-transformers-registry.ts
251
- var styleTransformersRegistry = createTransformersRegistry();
252
-
253
564
  // src/transformers/styles/background-color-overlay-transformer.ts
254
565
  var backgroundColorOverlayTransformer = createTransformer((value) => {
255
566
  const { color = null } = value;
@@ -311,20 +622,6 @@ var createCombineArrayTransformer = (delimiter) => {
311
622
  return createTransformer((value) => value.filter(Boolean).join(delimiter));
312
623
  };
313
624
 
314
- // src/renderers/multi-props.ts
315
- var isMultiProps = (propValue) => {
316
- return !!propValue && typeof propValue === "object" && "$$multi-props" in propValue && propValue["$$multi-props"] === true;
317
- };
318
- var createMultiPropsValue = (props) => {
319
- return {
320
- "$$multi-props": true,
321
- value: props
322
- };
323
- };
324
- var getMultiPropsValue = (multiProps) => {
325
- return multiProps.value;
326
- };
327
-
328
625
  // src/transformers/styles/create-multi-props-transformer.ts
329
626
  var createMultiPropsTransformer = (keys, keyGenerator) => {
330
627
  return createTransformer((value, { key: propKey }) => {
@@ -379,221 +676,9 @@ function initStyleTransformers() {
379
676
  ).registerFallback(plainTransformer);
380
677
  }
381
678
 
382
- // src/init-styles-renderer.ts
383
- var import_editor_responsive = require("@elementor/editor-responsive");
384
- var import_editor_styles = require("@elementor/editor-styles");
385
- var import_editor_styles_repository = require("@elementor/editor-styles-repository");
386
- var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
387
-
388
- // src/renderers/create-props-resolver.ts
389
- var import_editor_props = require("@elementor/editor-props");
390
- var TRANSFORM_DEPTH_LIMIT = 3;
391
- function createPropsResolver({ transformers, schema: initialSchema, onPropResolve }) {
392
- async function resolve({ props, schema, signal }) {
393
- schema = schema ?? initialSchema;
394
- const promises = Promise.all(
395
- Object.entries(schema).map(async ([key, type]) => {
396
- const value = props[key] ?? type.default;
397
- const transformed = await transform({ value, key, type, signal });
398
- onPropResolve?.({ key, value: transformed });
399
- if (isMultiProps(transformed)) {
400
- return getMultiPropsValue(transformed);
401
- }
402
- return { [key]: transformed };
403
- })
404
- );
405
- return Object.assign({}, ...(await promises).filter(Boolean));
406
- }
407
- async function transform({ value, key, type, signal, depth = 0 }) {
408
- if (value === null || value === void 0) {
409
- return null;
410
- }
411
- if (!(0, import_editor_props.isTransformable)(value)) {
412
- return value;
413
- }
414
- if (depth > TRANSFORM_DEPTH_LIMIT) {
415
- return null;
416
- }
417
- if (value.disabled === true) {
418
- return null;
419
- }
420
- if (type.kind === "union") {
421
- type = type.prop_types[value.$$type];
422
- if (!type) {
423
- return null;
424
- }
425
- }
426
- if (value.$$type !== type.key) {
427
- return null;
428
- }
429
- let resolvedValue = value.value;
430
- if (type.kind === "object") {
431
- resolvedValue = await resolve({
432
- props: resolvedValue,
433
- schema: type.shape,
434
- signal
435
- });
436
- }
437
- if (type.kind === "array") {
438
- resolvedValue = await Promise.all(
439
- resolvedValue.map(
440
- (item) => transform({ value: item, key, type: type.item_prop_type, depth, signal })
441
- )
442
- );
443
- }
444
- const transformer = transformers.get(value.$$type);
445
- if (!transformer) {
446
- return null;
447
- }
448
- try {
449
- const transformed = await transformer(resolvedValue, { key, signal });
450
- return transform({ value: transformed, key, type, signal, depth: depth + 1 });
451
- } catch {
452
- return null;
453
- }
454
- }
455
- return resolve;
456
- }
457
-
458
- // src/renderers/errors.ts
459
- var import_utils = require("@elementor/utils");
460
- var UnknownStyleTypeError = (0, import_utils.createError)({
461
- code: "unknown_style_type",
462
- message: "Unknown style type"
463
- });
464
-
465
- // src/renderers/render-styles.ts
466
- var SELECTORS_MAP = {
467
- class: "."
468
- };
469
- async function renderStyles({
470
- resolve,
471
- styles,
472
- breakpoints,
473
- selectorPrefix = "",
474
- signal
475
- }) {
476
- const stylesCssPromises = styles.map(async (style) => {
477
- const variantCssPromises = Object.values(style.variants).map(async (variant) => {
478
- const css = await propsToCss({ props: variant.props, resolve, signal });
479
- return createStyleWrapper().forStyle(style).withPrefix(selectorPrefix).withState(variant.meta.state).withMediaQuery(variant.meta.breakpoint ? breakpoints[variant.meta.breakpoint] : null).wrap(css);
480
- });
481
- const variantsCss = await Promise.all(variantCssPromises);
482
- return wrapCssWithStyleElement(style.id, variantsCss.join(""));
483
- });
484
- const stylesCss = await Promise.all(stylesCssPromises);
485
- return stylesCss.join("");
486
- }
487
- function createStyleWrapper(value = "", wrapper) {
488
- return {
489
- forStyle: ({ id, type }) => {
490
- const symbol = SELECTORS_MAP[type];
491
- if (!symbol) {
492
- throw new UnknownStyleTypeError({ context: { type } });
493
- }
494
- return createStyleWrapper(`${value}${symbol}${id}`, wrapper);
495
- },
496
- withPrefix: (prefix) => createStyleWrapper([prefix, value].filter(Boolean).join(" "), wrapper),
497
- withState: (state) => createStyleWrapper(state ? `${value}:${state}` : value, wrapper),
498
- withMediaQuery: (breakpoint) => {
499
- if (!breakpoint?.type) {
500
- return createStyleWrapper(value, wrapper);
501
- }
502
- const size2 = `${breakpoint.type}:${breakpoint.width}px`;
503
- return createStyleWrapper(value, (css) => `@media(${size2}){${css}}`);
504
- },
505
- wrap: (css) => {
506
- const res = `${value}{${css}}`;
507
- if (!wrapper) {
508
- return res;
509
- }
510
- return wrapper(res);
511
- }
512
- };
513
- }
514
- async function propsToCss({ props, resolve, signal }) {
515
- const transformed = await resolve({ props, signal });
516
- return Object.entries(transformed).reduce((acc, [propName, propValue]) => {
517
- if (propValue === null) {
518
- return acc;
519
- }
520
- acc.push(propName + ":" + propValue + ";");
521
- return acc;
522
- }, []).join("");
523
- }
524
- function wrapCssWithStyleElement(id, css) {
525
- return `<style data-style-id="${id}">${css}</style>`;
526
- }
527
-
528
- // src/sync/enqueue-font.ts
529
- var enqueueFont = (fontFamily, context = "preview") => {
530
- const extendedWindow = window;
531
- return extendedWindow.elementor?.helpers?.enqueueFont?.(fontFamily, context) ?? null;
532
- };
533
-
534
- // src/sync/get-canvas-iframe-body.ts
535
- function getCanvasIframeBody() {
536
- const extendedWindow = window;
537
- return extendedWindow.elementor?.$preview?.[0]?.contentDocument?.body;
538
- }
539
-
540
- // src/init-styles-renderer.ts
541
- var WRAPPER_DATA_ATTR = "data-styles-container";
542
- var SELECTOR_PREFIX = ".elementor";
543
- function initStylesRenderer() {
544
- (0, import_editor_v1_adapters2.__privateListenTo)((0, import_editor_v1_adapters2.v1ReadyEvent)(), () => {
545
- let abortController = null;
546
- const resolve = createPropsResolver({
547
- transformers: styleTransformersRegistry,
548
- schema: (0, import_editor_styles.getStylesSchema)(),
549
- onPropResolve: enqueueUsedFonts
550
- });
551
- const injectStyleElements = async () => {
552
- const styleContainer = getStylesContainer();
553
- const styles = import_editor_styles_repository.stylesRepository.all().reverse();
554
- const breakpoints = (0, import_editor_responsive.getBreakpointsMap)();
555
- if (abortController) {
556
- abortController.abort();
557
- }
558
- abortController = new AbortController();
559
- styleContainer.innerHTML = await renderStyles({
560
- styles,
561
- resolve,
562
- breakpoints,
563
- selectorPrefix: SELECTOR_PREFIX,
564
- signal: abortController.signal
565
- });
566
- };
567
- import_editor_styles_repository.stylesRepository.subscribe(injectStyleElements);
568
- (0, import_editor_v1_adapters2.registerDataHook)("after", "editor/documents/attach-preview", injectStyleElements);
569
- });
570
- }
571
- function getStylesContainer() {
572
- const preview = getCanvasIframeBody();
573
- const stylesContainer = preview?.querySelector(`[${WRAPPER_DATA_ATTR}]`);
574
- if (stylesContainer) {
575
- return stylesContainer;
576
- }
577
- const el = createStylesContainer();
578
- preview?.prepend(el);
579
- return el;
580
- }
581
- function createStylesContainer() {
582
- const el = document.createElement("div");
583
- el.style.display = "none";
584
- el.setAttribute(WRAPPER_DATA_ATTR, "");
585
- return el;
586
- }
587
- function enqueueUsedFonts({ key, value }) {
588
- if (key !== "font-family" || typeof value !== "string") {
589
- return;
590
- }
591
- enqueueFont(value);
592
- }
593
-
594
679
  // src/legacy/init-legacy-views.ts
595
680
  var import_editor_elements2 = require("@elementor/editor-elements");
596
- var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
681
+ var import_editor_v1_adapters4 = require("@elementor/editor-v1-adapters");
597
682
 
598
683
  // src/renderers/create-dom-renderer.ts
599
684
  var import_twing = require("@elementor/twing");
@@ -659,11 +744,13 @@ function createElementViewClassDeclaration() {
659
744
  onRender(...args) {
660
745
  super.onRender(...args);
661
746
  this.#dispatchEvent("elementor/preview/atomic-widget/render");
747
+ this.#dispatchPreviewEvent("elementor/element/render");
662
748
  }
663
749
  // Dispatch `destroy` event so the overlay layer will be updated
664
750
  onDestroy(...args) {
665
751
  super.onDestroy(...args);
666
752
  this.#dispatchEvent("elementor/preview/atomic-widget/destroy");
753
+ this.#dispatchPreviewEvent("elementor/element/destroy");
667
754
  }
668
755
  attributes() {
669
756
  return {
@@ -697,31 +784,23 @@ function createElementViewClassDeclaration() {
697
784
  })
698
785
  );
699
786
  }
787
+ #dispatchPreviewEvent(eventType) {
788
+ legacyWindow.elementor?.$preview?.[0]?.contentWindow.dispatchEvent(
789
+ new CustomEvent(eventType, {
790
+ detail: {
791
+ id: this.model.get("id"),
792
+ type: this.model.get("widgetType"),
793
+ element: this.getDomElement().get(0)
794
+ }
795
+ })
796
+ );
797
+ }
700
798
  getContextMenuGroups() {
701
799
  return super.getContextMenuGroups().filter((group) => group.name !== "save");
702
800
  }
703
801
  };
704
802
  }
705
803
 
706
- // src/legacy/signalized-process.ts
707
- function signalizedProcess(signal, steps = []) {
708
- return {
709
- then: (cb) => {
710
- steps.push(cb);
711
- return signalizedProcess(signal, steps);
712
- },
713
- execute: async () => {
714
- let lastResult;
715
- for (const step of steps) {
716
- if (signal.aborted) {
717
- break;
718
- }
719
- lastResult = await step(lastResult, signal);
720
- }
721
- }
722
- };
723
- }
724
-
725
804
  // src/legacy/create-templated-element-type.ts
726
805
  function createTemplatedElementType({ type, renderer, element }) {
727
806
  const legacyWindow = window;
@@ -802,7 +881,7 @@ function createTemplatedElementViewClassDeclaration({
802
881
 
803
882
  // src/legacy/init-legacy-views.ts
804
883
  function initLegacyViews() {
805
- (0, import_editor_v1_adapters3.__privateListenTo)((0, import_editor_v1_adapters3.v1ReadyEvent)(), () => {
884
+ (0, import_editor_v1_adapters4.__privateListenTo)((0, import_editor_v1_adapters4.v1ReadyEvent)(), () => {
806
885
  const config = (0, import_editor_elements2.getWidgetsCache)() ?? {};
807
886
  const legacyWindow = window;
808
887
  const renderer = createDomRenderer();
@@ -816,19 +895,102 @@ function initLegacyViews() {
816
895
  });
817
896
  }
818
897
 
819
- // src/style-commands/paste-style.ts
898
+ // src/prevent-link-in-link-commands.ts
899
+ var import_editor_elements3 = require("@elementor/editor-elements");
900
+ var import_editor_notifications = require("@elementor/editor-notifications");
820
901
  var import_editor_v1_adapters5 = require("@elementor/editor-v1-adapters");
902
+ var import_i18n = require("@wordpress/i18n");
903
+ function initLinkInLinkPrevention() {
904
+ (0, import_editor_v1_adapters5.blockCommand)({
905
+ command: "document/elements/paste",
906
+ condition: blockLinkInLinkPaste
907
+ });
908
+ (0, import_editor_v1_adapters5.blockCommand)({
909
+ command: "document/elements/move",
910
+ condition: blockLinkInLinkMove
911
+ });
912
+ }
913
+ var learnMoreActionProps = {
914
+ href: "https://go.elementor.com/element-link-inside-link-infotip",
915
+ target: "_blank",
916
+ color: "inherit",
917
+ variant: "text",
918
+ sx: {
919
+ marginInlineStart: "20px"
920
+ },
921
+ children: "Learn more"
922
+ };
923
+ function blockLinkInLinkPaste(args) {
924
+ const { containers = [args.container], storageType } = args;
925
+ const targetElements = containers;
926
+ if (storageType !== "localstorage") {
927
+ return false;
928
+ }
929
+ const data = window?.elementorCommon?.storage?.get();
930
+ if (!data?.clipboard?.elements) {
931
+ return false;
932
+ }
933
+ const sourceElements = data.clipboard.elements;
934
+ const notification = {
935
+ type: "default",
936
+ message: (0, import_i18n.__)(
937
+ "To paste a link to this element, first remove the link from it's parent container.",
938
+ "elementor"
939
+ ),
940
+ id: "paste-in-link-blocked",
941
+ additionalActionProps: [learnMoreActionProps]
942
+ };
943
+ const blocked = shouldBlock(sourceElements, targetElements);
944
+ if (blocked) {
945
+ (0, import_editor_notifications.notify)(notification);
946
+ }
947
+ return blocked;
948
+ }
949
+ function blockLinkInLinkMove(args) {
950
+ const { containers = [args.container], target } = args;
951
+ const sourceElements = containers;
952
+ const targetElement = target;
953
+ const notification = {
954
+ type: "default",
955
+ message: (0, import_i18n.__)("To drag a link to this element, first remove the link from it's parent container.", "elementor"),
956
+ id: "move-in-link-blocked",
957
+ additionalActionProps: [learnMoreActionProps]
958
+ };
959
+ const isBlocked = shouldBlock(sourceElements, [targetElement]);
960
+ if (isBlocked) {
961
+ (0, import_editor_notifications.notify)(notification);
962
+ }
963
+ return isBlocked;
964
+ }
965
+ function shouldBlock(sourceElements, targetElements) {
966
+ if (!sourceElements?.length || !targetElements?.length) {
967
+ return false;
968
+ }
969
+ const isSourceContainsAnAnchor = sourceElements.some((src) => {
970
+ return src?.id ? (0, import_editor_elements3.isElementAnchored)(src.id) || !!(0, import_editor_elements3.getAnchoredDescendantId)(src.id) : false;
971
+ });
972
+ if (!isSourceContainsAnAnchor) {
973
+ return false;
974
+ }
975
+ const isTargetContainsAnAnchor = targetElements.some((target) => {
976
+ return target?.id ? (0, import_editor_elements3.isElementAnchored)(target.id) || !!(0, import_editor_elements3.getAnchoredAncestorId)(target.id) : false;
977
+ });
978
+ return isTargetContainsAnAnchor;
979
+ }
980
+
981
+ // src/style-commands/paste-style.ts
982
+ var import_editor_v1_adapters7 = require("@elementor/editor-v1-adapters");
821
983
 
822
984
  // src/style-commands/undoable-actions/paste-element-style.ts
823
- var import_editor_elements4 = require("@elementor/editor-elements");
985
+ var import_editor_elements5 = require("@elementor/editor-elements");
824
986
  var import_editor_styles_repository2 = require("@elementor/editor-styles-repository");
825
- var import_editor_v1_adapters4 = require("@elementor/editor-v1-adapters");
826
- var import_i18n2 = require("@wordpress/i18n");
987
+ var import_editor_v1_adapters6 = require("@elementor/editor-v1-adapters");
988
+ var import_i18n3 = require("@wordpress/i18n");
827
989
 
828
990
  // src/style-commands/utils.ts
829
- var import_editor_elements3 = require("@elementor/editor-elements");
991
+ var import_editor_elements4 = require("@elementor/editor-elements");
830
992
  var import_editor_props2 = require("@elementor/editor-props");
831
- var import_i18n = require("@wordpress/i18n");
993
+ var import_i18n2 = require("@wordpress/i18n");
832
994
  function hasAtomicWidgets(args) {
833
995
  const { containers = [args.container] } = args;
834
996
  return containers.some(isAtomicWidget);
@@ -851,7 +1013,7 @@ function getClassesProp(container) {
851
1013
  }
852
1014
  function getContainerSchema(container) {
853
1015
  const type = container?.model.get("widgetType") || container?.model.get("elType");
854
- const widgetsCache = (0, import_editor_elements3.getWidgetsCache)();
1016
+ const widgetsCache = (0, import_editor_elements4.getWidgetsCache)();
855
1017
  const elementType = widgetsCache?.[type];
856
1018
  return elementType?.atomic_props_schema ?? null;
857
1019
  }
@@ -864,11 +1026,11 @@ function getClipboardElements(storageKey = "clipboard") {
864
1026
  }
865
1027
  }
866
1028
  function getTitleForContainers(containers) {
867
- return containers.length > 1 ? (0, import_i18n.__)("Elements", "elementor") : (0, import_editor_elements3.getElementLabel)(containers[0].id);
1029
+ return containers.length > 1 ? (0, import_i18n2.__)("Elements", "elementor") : (0, import_editor_elements4.getElementLabel)(containers[0].id);
868
1030
  }
869
1031
 
870
1032
  // src/style-commands/undoable-actions/paste-element-style.ts
871
- var undoablePasteElementStyle = () => (0, import_editor_v1_adapters4.undoable)(
1033
+ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters6.undoable)(
872
1034
  {
873
1035
  do: ({ containers, newStyle }) => {
874
1036
  return containers.map((container) => {
@@ -877,7 +1039,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters4.undoable)(
877
1039
  if (!classesProp) {
878
1040
  return null;
879
1041
  }
880
- const originalStyles = (0, import_editor_elements4.getElementStyles)(container.id);
1042
+ const originalStyles = (0, import_editor_elements5.getElementStyles)(container.id);
881
1043
  const [styleId, styleDef] = Object.entries(originalStyles ?? {})[0] ?? [];
882
1044
  const originalStyle = Object.keys(styleDef ?? {}).length ? styleDef : null;
883
1045
  const revertData = {
@@ -886,7 +1048,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters4.undoable)(
886
1048
  };
887
1049
  if (styleId) {
888
1050
  newStyle.variants.forEach(({ meta, props }) => {
889
- (0, import_editor_elements4.updateElementStyle)({
1051
+ (0, import_editor_elements5.updateElementStyle)({
890
1052
  elementId,
891
1053
  styleId,
892
1054
  meta,
@@ -896,7 +1058,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters4.undoable)(
896
1058
  } else {
897
1059
  const [firstVariant] = newStyle.variants;
898
1060
  const additionalVariants = newStyle.variants.slice(1);
899
- revertData.styleId = (0, import_editor_elements4.createElementStyle)({
1061
+ revertData.styleId = (0, import_editor_elements5.createElementStyle)({
900
1062
  elementId,
901
1063
  classesProp,
902
1064
  label: import_editor_styles_repository2.LOCAL_STYLES_RESERVED_LABEL,
@@ -914,7 +1076,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters4.undoable)(
914
1076
  return;
915
1077
  }
916
1078
  if (!revertData.originalStyle) {
917
- (0, import_editor_elements4.deleteElementStyle)(container.id, revertData.styleId);
1079
+ (0, import_editor_elements5.deleteElementStyle)(container.id, revertData.styleId);
918
1080
  return;
919
1081
  }
920
1082
  const classesProp = getClassesProp(container);
@@ -923,7 +1085,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters4.undoable)(
923
1085
  }
924
1086
  const [firstVariant] = revertData.originalStyle.variants;
925
1087
  const additionalVariants = revertData.originalStyle.variants.slice(1);
926
- (0, import_editor_elements4.createElementStyle)({
1088
+ (0, import_editor_elements5.createElementStyle)({
927
1089
  elementId: container.id,
928
1090
  classesProp,
929
1091
  label: import_editor_styles_repository2.LOCAL_STYLES_RESERVED_LABEL,
@@ -936,19 +1098,19 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters4.undoable)(
936
1098
  },
937
1099
  {
938
1100
  title: ({ containers }) => getTitleForContainers(containers),
939
- subtitle: (0, import_i18n2.__)("Style Pasted", "elementor")
1101
+ subtitle: (0, import_i18n3.__)("Style Pasted", "elementor")
940
1102
  }
941
1103
  );
942
1104
 
943
1105
  // src/style-commands/paste-style.ts
944
1106
  function initPasteStyleCommand() {
945
1107
  const pasteElementStyleCommand = undoablePasteElementStyle();
946
- (0, import_editor_v1_adapters5.blockCommand)({
1108
+ (0, import_editor_v1_adapters7.blockCommand)({
947
1109
  command: "document/elements/paste-style",
948
1110
  condition: hasAtomicWidgets
949
1111
  });
950
- (0, import_editor_v1_adapters5.__privateListenTo)(
951
- (0, import_editor_v1_adapters5.commandStartEvent)("document/elements/paste-style"),
1112
+ (0, import_editor_v1_adapters7.__privateListenTo)(
1113
+ (0, import_editor_v1_adapters7.commandStartEvent)("document/elements/paste-style"),
952
1114
  (e) => pasteStyles(e.args, pasteElementStyleCommand)
953
1115
  );
954
1116
  }
@@ -972,21 +1134,21 @@ function pasteStyles(args, pasteCallback) {
972
1134
  }
973
1135
 
974
1136
  // src/style-commands/reset-style.ts
975
- var import_editor_v1_adapters7 = require("@elementor/editor-v1-adapters");
1137
+ var import_editor_v1_adapters9 = require("@elementor/editor-v1-adapters");
976
1138
 
977
1139
  // src/style-commands/undoable-actions/reset-element-style.ts
978
- var import_editor_elements5 = require("@elementor/editor-elements");
1140
+ var import_editor_elements6 = require("@elementor/editor-elements");
979
1141
  var import_editor_styles_repository3 = require("@elementor/editor-styles-repository");
980
- var import_editor_v1_adapters6 = require("@elementor/editor-v1-adapters");
981
- var import_i18n3 = require("@wordpress/i18n");
982
- var undoableResetElementStyle = () => (0, import_editor_v1_adapters6.undoable)(
1142
+ var import_editor_v1_adapters8 = require("@elementor/editor-v1-adapters");
1143
+ var import_i18n4 = require("@wordpress/i18n");
1144
+ var undoableResetElementStyle = () => (0, import_editor_v1_adapters8.undoable)(
983
1145
  {
984
1146
  do: ({ containers }) => {
985
1147
  return containers.map((container) => {
986
1148
  const elementId = container.model.get("id");
987
- const containerStyles = (0, import_editor_elements5.getElementStyles)(elementId);
1149
+ const containerStyles = (0, import_editor_elements6.getElementStyles)(elementId);
988
1150
  Object.keys(containerStyles ?? {}).forEach(
989
- (styleId) => (0, import_editor_elements5.deleteElementStyle)(elementId, styleId)
1151
+ (styleId) => (0, import_editor_elements6.deleteElementStyle)(elementId, styleId)
990
1152
  );
991
1153
  return containerStyles;
992
1154
  });
@@ -1002,7 +1164,7 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters6.undoable)(
1002
1164
  Object.entries(containerStyles ?? {}).forEach(([styleId, style]) => {
1003
1165
  const [firstVariant] = style.variants;
1004
1166
  const additionalVariants = style.variants.slice(1);
1005
- (0, import_editor_elements5.createElementStyle)({
1167
+ (0, import_editor_elements6.createElementStyle)({
1006
1168
  elementId,
1007
1169
  classesProp,
1008
1170
  styleId,
@@ -1016,19 +1178,19 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters6.undoable)(
1016
1178
  },
1017
1179
  {
1018
1180
  title: ({ containers }) => getTitleForContainers(containers),
1019
- subtitle: (0, import_i18n3.__)("Style Reset", "elementor")
1181
+ subtitle: (0, import_i18n4.__)("Style Reset", "elementor")
1020
1182
  }
1021
1183
  );
1022
1184
 
1023
1185
  // src/style-commands/reset-style.ts
1024
1186
  function initResetStyleCommand() {
1025
1187
  const resetElementStyles = undoableResetElementStyle();
1026
- (0, import_editor_v1_adapters7.blockCommand)({
1188
+ (0, import_editor_v1_adapters9.blockCommand)({
1027
1189
  command: "document/elements/reset-style",
1028
1190
  condition: hasAtomicWidgets
1029
1191
  });
1030
- (0, import_editor_v1_adapters7.__privateListenTo)(
1031
- (0, import_editor_v1_adapters7.commandStartEvent)("document/elements/reset-style"),
1192
+ (0, import_editor_v1_adapters9.__privateListenTo)(
1193
+ (0, import_editor_v1_adapters9.commandStartEvent)("document/elements/reset-style"),
1032
1194
  (e) => resetStyles(e.args, resetElementStyles)
1033
1195
  );
1034
1196
  }
@@ -1050,20 +1212,25 @@ function initStyleCommands() {
1050
1212
  // src/init.tsx
1051
1213
  function init() {
1052
1214
  initStyleTransformers();
1053
- initStylesRenderer();
1054
1215
  initStyleCommands();
1216
+ initLinkInLinkPrevention();
1055
1217
  initLegacyViews();
1056
1218
  initSettingsTransformers();
1057
1219
  (0, import_editor.injectIntoTop)({
1058
1220
  id: "elements-overlays",
1059
1221
  component: ElementsOverlays
1060
1222
  });
1223
+ (0, import_editor.injectIntoTop)({
1224
+ id: "canvas-style-render",
1225
+ component: StyleRenderer
1226
+ });
1061
1227
  }
1062
1228
 
1063
1229
  // src/index.ts
1064
1230
  init();
1065
1231
  // Annotate the CommonJS export names for ESM import in node:
1066
1232
  0 && (module.exports = {
1233
+ createTransformer,
1067
1234
  settingsTransformersRegistry,
1068
1235
  styleTransformersRegistry
1069
1236
  });