@elementor/editor-canvas 4.5.0-1155 → 4.5.0-1156

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1179,7 +1179,7 @@ function usePortalContainer() {
1179
1179
 
1180
1180
  // src/components/style-renderer.tsx
1181
1181
  var React9 = __toESM(require("react"));
1182
- var import_editor_v1_adapters10 = require("@elementor/editor-v1-adapters");
1182
+ var import_editor_v1_adapters11 = require("@elementor/editor-v1-adapters");
1183
1183
  var import_ui4 = require("@elementor/ui");
1184
1184
 
1185
1185
  // src/hooks/use-documents-css-links.ts
@@ -1230,11 +1230,11 @@ function getLinkAttrs(el) {
1230
1230
  }
1231
1231
 
1232
1232
  // src/hooks/use-style-items.ts
1233
- var import_react16 = require("react");
1233
+ var import_react17 = require("react");
1234
1234
  var import_editor_responsive2 = require("@elementor/editor-responsive");
1235
1235
  var import_editor_styles3 = require("@elementor/editor-styles");
1236
1236
  var import_editor_styles_repository2 = require("@elementor/editor-styles-repository");
1237
- var import_editor_v1_adapters9 = require("@elementor/editor-v1-adapters");
1237
+ var import_editor_v1_adapters10 = require("@elementor/editor-v1-adapters");
1238
1238
 
1239
1239
  // src/utils/abort-previous-runs.ts
1240
1240
  function abortPreviousRuns(cb) {
@@ -1291,10 +1291,29 @@ function signalizedProcess(signal, steps = []) {
1291
1291
  };
1292
1292
  }
1293
1293
 
1294
- // src/hooks/use-style-prop-resolver.ts
1294
+ // src/hooks/use-pregenerated-links-handoff.ts
1295
1295
  var import_react14 = require("react");
1296
- var import_editor_styles = require("@elementor/editor-styles");
1297
1296
  var import_editor_v1_adapters8 = require("@elementor/editor-v1-adapters");
1297
+ function usePregeneratedLinksHandoff(canvasHead, renderedProviders) {
1298
+ (0, import_react14.useLayoutEffect)(() => {
1299
+ if (!isCurrentCanvasHead(canvasHead)) {
1300
+ return;
1301
+ }
1302
+ Object.entries(renderedProviders).forEach(([providerKey, { provider, items }]) => {
1303
+ if (items.length > 0 && provider.isPregeneratedLink) {
1304
+ removeProviderPregeneratedLinks(providerKey, provider.isPregeneratedLink);
1305
+ }
1306
+ });
1307
+ }, [canvasHead, renderedProviders]);
1308
+ }
1309
+ function isCurrentCanvasHead(canvasHead) {
1310
+ return !!canvasHead && canvasHead === (0, import_editor_v1_adapters8.getCanvasIframeDocument)()?.head;
1311
+ }
1312
+
1313
+ // src/hooks/use-style-prop-resolver.ts
1314
+ var import_react15 = require("react");
1315
+ var import_editor_styles = require("@elementor/editor-styles");
1316
+ var import_editor_v1_adapters9 = require("@elementor/editor-v1-adapters");
1298
1317
 
1299
1318
  // src/renderers/create-props-resolver.ts
1300
1319
  var import_editor_props = require("@elementor/editor-props");
@@ -1441,19 +1460,19 @@ var styleTransformersRegistry = createTransformersRegistry();
1441
1460
 
1442
1461
  // src/hooks/use-style-prop-resolver.ts
1443
1462
  function useStylePropResolver() {
1444
- return (0, import_react14.useMemo)(() => {
1463
+ return (0, import_react15.useMemo)(() => {
1445
1464
  return createPropsResolver({
1446
1465
  transformers: styleTransformersRegistry,
1447
1466
  schema: (0, import_editor_styles.getStylesSchema)(),
1448
1467
  onPropResolve: ({ propValue, propType }) => {
1449
- maybeEnqueueFontFromStyleProp(propType, propValue, import_editor_v1_adapters8.enqueueFont);
1468
+ maybeEnqueueFontFromStyleProp(propType, propValue, import_editor_v1_adapters9.enqueueFont);
1450
1469
  }
1451
1470
  });
1452
1471
  }, []);
1453
1472
  }
1454
1473
 
1455
1474
  // src/hooks/use-style-renderer.ts
1456
- var import_react15 = require("react");
1475
+ var import_react16 = require("react");
1457
1476
  var import_editor_responsive = require("@elementor/editor-responsive");
1458
1477
 
1459
1478
  // src/renderers/create-styles-renderer.ts
@@ -1562,7 +1581,7 @@ function customCssToString(customCss) {
1562
1581
  var SELECTOR_PREFIX = ".elementor";
1563
1582
  function useStyleRenderer(resolve) {
1564
1583
  const breakpoints = (0, import_editor_responsive.useBreakpointsMap)();
1565
- return (0, import_react15.useMemo)(() => {
1584
+ return (0, import_react16.useMemo)(() => {
1566
1585
  return createStylesRenderer({
1567
1586
  selectorPrefix: SELECTOR_PREFIX,
1568
1587
  breakpoints,
@@ -1572,13 +1591,13 @@ function useStyleRenderer(resolve) {
1572
1591
  }
1573
1592
 
1574
1593
  // src/hooks/use-style-items.ts
1575
- function useStyleItems() {
1594
+ function useStyleItems(canvasHead) {
1576
1595
  const resolve = useStylePropResolver();
1577
1596
  const renderStyles = useStyleRenderer(resolve);
1578
1597
  const breakpoints = (0, import_editor_responsive2.useBreakpoints)();
1579
- const [styleItems, setStyleItems] = (0, import_react16.useState)({});
1580
- const styleItemsCacheRef = (0, import_react16.useRef)(/* @__PURE__ */ new Map());
1581
- const providerAndSubscribers = (0, import_react16.useMemo)(() => {
1598
+ const [styleItems, setStyleItems] = (0, import_react17.useState)({});
1599
+ const styleItemsCacheRef = (0, import_react17.useRef)(/* @__PURE__ */ new Map());
1600
+ const providerAndSubscribers = (0, import_react17.useMemo)(() => {
1582
1601
  const createEmptyCache = () => {
1583
1602
  return { orderedIds: [], itemsById: /* @__PURE__ */ new Map() };
1584
1603
  };
@@ -1604,7 +1623,7 @@ function useStyleItems() {
1604
1623
  })
1605
1624
  );
1606
1625
  }, [renderStyles]);
1607
- (0, import_react16.useEffect)(() => {
1626
+ (0, import_react17.useEffect)(() => {
1608
1627
  const unsubscribes = providerAndSubscribers.map(
1609
1628
  ({ provider, subscriber }) => provider.subscribe(subscriber)
1610
1629
  );
@@ -1613,17 +1632,18 @@ function useStyleItems() {
1613
1632
  };
1614
1633
  }, [providerAndSubscribers]);
1615
1634
  useOnMount(() => {
1616
- (0, import_editor_v1_adapters9.registerDataHook)("after", "editor/documents/attach-preview", async () => {
1635
+ (0, import_editor_v1_adapters10.registerDataHook)("after", "editor/documents/attach-preview", async () => {
1617
1636
  resetRemovedProviders();
1618
1637
  const promises = providerAndSubscribers.map(async ({ subscriber }) => subscriber());
1619
1638
  await Promise.all(promises);
1620
1639
  });
1621
1640
  });
1622
- const breakpointSorter = (0, import_react16.useMemo)(
1641
+ usePregeneratedLinksHandoff(canvasHead, styleItems);
1642
+ const breakpointSorter = (0, import_react17.useMemo)(
1623
1643
  () => createBreakpointSorter(breakpoints.map((breakpoint) => breakpoint.id)),
1624
1644
  [breakpoints]
1625
1645
  );
1626
- return (0, import_react16.useMemo)(
1646
+ return (0, import_react17.useMemo)(
1627
1647
  () => Object.values(styleItems).sort(prioritySorter).flatMap(({ items }) => items).sort(stateSorter).sort(breakpointSorter),
1628
1648
  [styleItems, breakpointSorter]
1629
1649
  );
@@ -1656,9 +1676,6 @@ function createProviderSubscriber2({ provider, renderStyles, setStyleItems, getC
1656
1676
  const cache = getCache();
1657
1677
  const hasDiffInfo = current !== void 0 && previous !== void 0;
1658
1678
  const hasCache = cache.orderedIds.length > 0;
1659
- if (hasCache && provider.isPregeneratedLink) {
1660
- removeProviderPregeneratedLinks(provider.getKey(), provider.isPregeneratedLink);
1661
- }
1662
1679
  if (hasDiffInfo && hasCache) {
1663
1680
  return updateItems(cache, previous, current, signal);
1664
1681
  }
@@ -1760,7 +1777,7 @@ function rebuildCache(cache, allStyles, items) {
1760
1777
  // src/components/style-renderer.tsx
1761
1778
  function StyleRenderer() {
1762
1779
  const container = usePortalContainer2();
1763
- const styleItems = useStyleItems();
1780
+ const styleItems = useStyleItems(container);
1764
1781
  const linksAttrs = useDocumentsCssLinks();
1765
1782
  if (!container) {
1766
1783
  return null;
@@ -1768,7 +1785,7 @@ function StyleRenderer() {
1768
1785
  return /* @__PURE__ */ React9.createElement(import_ui4.Portal, { container }, filterUniqueStyleDefinitions(styleItems).map((item) => /* @__PURE__ */ React9.createElement("style", { key: `${item.id}-${item.breakpoint}-${item.state ?? "normal"}` }, item.value)), linksAttrs.map((attrs) => /* @__PURE__ */ React9.createElement("link", { ...attrs, key: attrs.id })));
1769
1786
  }
1770
1787
  function usePortalContainer2() {
1771
- return (0, import_editor_v1_adapters10.__privateUseListenTo)((0, import_editor_v1_adapters10.commandEndEvent)("editor/documents/attach-preview"), () => (0, import_editor_v1_adapters10.getCanvasIframeDocument)()?.head);
1788
+ return (0, import_editor_v1_adapters11.__privateUseListenTo)((0, import_editor_v1_adapters11.commandEndEvent)("editor/documents/attach-preview"), () => (0, import_editor_v1_adapters11.getCanvasIframeDocument)()?.head);
1772
1789
  }
1773
1790
  function filterUniqueStyleDefinitions(styleItems) {
1774
1791
  const seen = /* @__PURE__ */ new Map();
@@ -1791,7 +1808,7 @@ function filterUniqueStyleDefinitions(styleItems) {
1791
1808
 
1792
1809
  // src/form-structure/enforce-form-ancestor-commands.ts
1793
1810
  var import_editor_notifications = require("@elementor/editor-notifications");
1794
- var import_editor_v1_adapters11 = require("@elementor/editor-v1-adapters");
1811
+ var import_editor_v1_adapters12 = require("@elementor/editor-v1-adapters");
1795
1812
  var import_i18n = require("@wordpress/i18n");
1796
1813
 
1797
1814
  // src/form-structure/utils.ts
@@ -1893,15 +1910,15 @@ var FORM_FIELDS_OUTSIDE_ALERT = {
1893
1910
  id: "form-fields-outside-form-blocked"
1894
1911
  };
1895
1912
  function initFormAncestorEnforcement() {
1896
- (0, import_editor_v1_adapters11.blockCommand)({
1913
+ (0, import_editor_v1_adapters12.blockCommand)({
1897
1914
  command: "document/elements/create",
1898
1915
  condition: blockFormFieldCreate
1899
1916
  });
1900
- (0, import_editor_v1_adapters11.blockCommand)({
1917
+ (0, import_editor_v1_adapters12.blockCommand)({
1901
1918
  command: "document/elements/move",
1902
1919
  condition: blockFormFieldMove
1903
1920
  });
1904
- (0, import_editor_v1_adapters11.blockCommand)({
1921
+ (0, import_editor_v1_adapters12.blockCommand)({
1905
1922
  command: "document/elements/paste",
1906
1923
  condition: blockFormFieldPaste
1907
1924
  });
@@ -1951,7 +1968,7 @@ function handleBlockedFormField() {
1951
1968
 
1952
1969
  // src/form-structure/form-atom-added-hints.ts
1953
1970
  var import_editor_notifications2 = require("@elementor/editor-notifications");
1954
- var import_editor_v1_adapters12 = require("@elementor/editor-v1-adapters");
1971
+ var import_editor_v1_adapters13 = require("@elementor/editor-v1-adapters");
1955
1972
  var import_i18n2 = require("@wordpress/i18n");
1956
1973
  var MOVE_COMMAND = "document/elements/move";
1957
1974
  var FORM_ATOM_HINTS = {
@@ -1966,7 +1983,7 @@ var FORM_ATOM_HINTS = {
1966
1983
  };
1967
1984
  var notificationCounter = 0;
1968
1985
  function initFormAtomAddedHints() {
1969
- (0, import_editor_v1_adapters12.registerDataHook)("after", "document/elements/create", (args, _result, options) => {
1986
+ (0, import_editor_v1_adapters13.registerDataHook)("after", "document/elements/create", (args, _result, options) => {
1970
1987
  if (options?.commandsCurrentTrace?.includes(MOVE_COMMAND)) {
1971
1988
  return;
1972
1989
  }
@@ -1985,7 +2002,7 @@ function initFormAtomAddedHints() {
1985
2002
 
1986
2003
  // src/form-structure/hidden-field-hint.ts
1987
2004
  var import_editor_notifications3 = require("@elementor/editor-notifications");
1988
- var import_editor_v1_adapters13 = require("@elementor/editor-v1-adapters");
2005
+ var import_editor_v1_adapters14 = require("@elementor/editor-v1-adapters");
1989
2006
  var import_i18n3 = require("@wordpress/i18n");
1990
2007
  var MOVE_COMMAND2 = "document/elements/move";
1991
2008
  var notificationCounter2 = 0;
@@ -1997,7 +2014,7 @@ function createHiddenFieldNotification() {
1997
2014
  };
1998
2015
  }
1999
2016
  function initHiddenFieldHint() {
2000
- (0, import_editor_v1_adapters13.registerDataHook)("after", "document/elements/create", (args, _result, options) => {
2017
+ (0, import_editor_v1_adapters14.registerDataHook)("after", "document/elements/create", (args, _result, options) => {
2001
2018
  if (options?.commandsCurrentTrace?.includes(MOVE_COMMAND2)) {
2002
2019
  return;
2003
2020
  }
@@ -2010,7 +2027,7 @@ function initHiddenFieldHint() {
2010
2027
  // src/form-structure/prevent-duplicate-form-atoms-commands.ts
2011
2028
  var import_editor_elements5 = require("@elementor/editor-elements");
2012
2029
  var import_editor_notifications4 = require("@elementor/editor-notifications");
2013
- var import_editor_v1_adapters14 = require("@elementor/editor-v1-adapters");
2030
+ var import_editor_v1_adapters15 = require("@elementor/editor-v1-adapters");
2014
2031
  var import_i18n4 = require("@wordpress/i18n");
2015
2032
  var MOVE_COMMAND3 = "document/elements/move";
2016
2033
  var SINGLE_INSTANCE_FORM_ATOM_ALERTS = {
@@ -2027,10 +2044,10 @@ var SINGLE_INSTANCE_FORM_ATOM_ALERTS = {
2027
2044
  };
2028
2045
  var SINGLE_INSTANCE_FORM_ATOM_TYPES = Object.keys(SINGLE_INSTANCE_FORM_ATOM_ALERTS);
2029
2046
  function initDuplicateFormAtomsPrevention() {
2030
- (0, import_editor_v1_adapters14.registerDataHook)("dependency", "document/elements/create", (args, options) => {
2047
+ (0, import_editor_v1_adapters15.registerDataHook)("dependency", "document/elements/create", (args, options) => {
2031
2048
  return !blockDuplicateCreate(args, options);
2032
2049
  });
2033
- (0, import_editor_v1_adapters14.blockCommand)({
2050
+ (0, import_editor_v1_adapters15.blockCommand)({
2034
2051
  command: "document/elements/move",
2035
2052
  condition: blockDuplicateMove
2036
2053
  });
@@ -2074,7 +2091,7 @@ function formHasElementType(form, type, excluded = /* @__PURE__ */ new Set()) {
2074
2091
 
2075
2092
  // src/form-structure/prevent-form-nesting-commands.ts
2076
2093
  var import_editor_notifications5 = require("@elementor/editor-notifications");
2077
- var import_editor_v1_adapters15 = require("@elementor/editor-v1-adapters");
2094
+ var import_editor_v1_adapters16 = require("@elementor/editor-v1-adapters");
2078
2095
  var import_i18n5 = require("@wordpress/i18n");
2079
2096
  var FORM_NESTING_ALERT = {
2080
2097
  type: "default",
@@ -2082,15 +2099,15 @@ var FORM_NESTING_ALERT = {
2082
2099
  id: "form-nesting-blocked"
2083
2100
  };
2084
2101
  function initFormNestingPrevention() {
2085
- (0, import_editor_v1_adapters15.blockCommand)({
2102
+ (0, import_editor_v1_adapters16.blockCommand)({
2086
2103
  command: "document/elements/create",
2087
2104
  condition: blockFormCreate
2088
2105
  });
2089
- (0, import_editor_v1_adapters15.blockCommand)({
2106
+ (0, import_editor_v1_adapters16.blockCommand)({
2090
2107
  command: "document/elements/move",
2091
2108
  condition: blockFormMove
2092
2109
  });
2093
- (0, import_editor_v1_adapters15.blockCommand)({
2110
+ (0, import_editor_v1_adapters16.blockCommand)({
2094
2111
  command: "document/elements/paste",
2095
2112
  condition: blockFormPaste
2096
2113
  });
@@ -2828,7 +2845,7 @@ function initStyleTransformers() {
2828
2845
 
2829
2846
  // src/legacy/init-legacy-views.ts
2830
2847
  var import_editor_elements9 = require("@elementor/editor-elements");
2831
- var import_editor_v1_adapters17 = require("@elementor/editor-v1-adapters");
2848
+ var import_editor_v1_adapters18 = require("@elementor/editor-v1-adapters");
2832
2849
 
2833
2850
  // src/renderers/create-dom-renderer.ts
2834
2851
  var import_twing = require("@elementor/twing");
@@ -3579,7 +3596,7 @@ var import_client = require("react-dom/client");
3579
3596
  var React11 = __toESM(require("react"));
3580
3597
  var import_editor_elements8 = require("@elementor/editor-elements");
3581
3598
  var import_editor_props4 = require("@elementor/editor-props");
3582
- var import_editor_v1_adapters16 = require("@elementor/editor-v1-adapters");
3599
+ var import_editor_v1_adapters17 = require("@elementor/editor-v1-adapters");
3583
3600
  var import_i18n6 = require("@wordpress/i18n");
3584
3601
 
3585
3602
  // src/legacy/replacements/base.ts
@@ -3626,14 +3643,14 @@ var ReplacementBase = class {
3626
3643
 
3627
3644
  // src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
3628
3645
  var React10 = __toESM(require("react"));
3629
- var import_react18 = require("react");
3646
+ var import_react19 = require("react");
3630
3647
  var import_editor_controls3 = require("@elementor/editor-controls");
3631
3648
  var import_editor_ui = require("@elementor/editor-ui");
3632
3649
  var import_ui5 = require("@elementor/ui");
3633
- var import_react19 = require("@floating-ui/react");
3650
+ var import_react20 = require("@floating-ui/react");
3634
3651
 
3635
3652
  // src/legacy/replacements/inline-editing/inline-editing-utils.ts
3636
- var import_react17 = require("react");
3653
+ var import_react18 = require("react");
3637
3654
  var TOP_BAR_SELECTOR = "#elementor-editor-wrapper-v2";
3638
3655
  var NAVIGATOR_SELECTOR = "#elementor-navigator";
3639
3656
  var EDITING_PANEL = "#elementor-panel";
@@ -3664,8 +3681,8 @@ var getInlineEditorElement = (elementWrapper, expectedTag) => {
3664
3681
  return !expectedTag ? null : elementWrapper.querySelector(expectedTag);
3665
3682
  };
3666
3683
  var useOnClickOutsideIframe = (handleUnmount) => {
3667
- const asyncUnmountInlineEditor = (0, import_react17.useCallback)(() => queueMicrotask(handleUnmount), [handleUnmount]);
3668
- (0, import_react17.useEffect)(() => {
3684
+ const asyncUnmountInlineEditor = (0, import_react18.useCallback)(() => queueMicrotask(handleUnmount), [handleUnmount]);
3685
+ (0, import_react18.useEffect)(() => {
3669
3686
  EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
3670
3687
  (selector) => document?.querySelector(selector)?.addEventListener("mousedown", asyncUnmountInlineEditor)
3671
3688
  );
@@ -3675,8 +3692,8 @@ var useOnClickOutsideIframe = (handleUnmount) => {
3675
3692
  }, []);
3676
3693
  };
3677
3694
  var useRenderToolbar = (ownerDocument, id) => {
3678
- const [anchor, setAnchor] = (0, import_react17.useState)(null);
3679
- (0, import_react17.useEffect)(() => {
3695
+ const [anchor, setAnchor] = (0, import_react18.useState)(null);
3696
+ (0, import_react18.useEffect)(() => {
3680
3697
  if (!anchor) {
3681
3698
  removeToolbarAnchor(ownerDocument, id);
3682
3699
  }
@@ -3690,7 +3707,7 @@ var useRenderToolbar = (ownerDocument, id) => {
3690
3707
  setAnchor(null);
3691
3708
  }
3692
3709
  };
3693
- const clearAnchor = (0, import_react17.useCallback)(() => {
3710
+ const clearAnchor = (0, import_react18.useCallback)(() => {
3694
3711
  setAnchor(null);
3695
3712
  }, []);
3696
3713
  return { onSelectionEnd, anchor, clearAnchor };
@@ -3770,21 +3787,21 @@ var CanvasInlineEditor = ({
3770
3787
  setValue,
3771
3788
  requestDestroy
3772
3789
  }) => {
3773
- const [active, setActive] = (0, import_react18.useState)(true);
3774
- const [editor, setEditor] = (0, import_react18.useState)(null);
3790
+ const [active, setActive] = (0, import_react19.useState)(true);
3791
+ const [editor, setEditor] = (0, import_react19.useState)(null);
3775
3792
  const { onSelectionEnd, anchor: toolbarAnchor, clearAnchor } = useRenderToolbar(rootElement.ownerDocument, id);
3776
- (0, import_react18.useEffect)(() => {
3793
+ (0, import_react19.useEffect)(() => {
3777
3794
  if (!active) {
3778
3795
  clearAnchor();
3779
3796
  requestDestroy();
3780
3797
  }
3781
3798
  }, [active, clearAnchor, requestDestroy]);
3782
- const dismiss = (0, import_react18.useCallback)(() => {
3799
+ const dismiss = (0, import_react19.useCallback)(() => {
3783
3800
  setEditor(null);
3784
3801
  setActive(false);
3785
3802
  }, []);
3786
3803
  useOnClickOutsideIframe(dismiss);
3787
- (0, import_react18.useEffect)(() => {
3804
+ (0, import_react19.useEffect)(() => {
3788
3805
  const ownerDocument = contentElement.ownerDocument;
3789
3806
  const handleClickAway = (event) => {
3790
3807
  if (contentElement.contains(event.target)) {
@@ -3823,25 +3840,25 @@ var InlineEditingOverlay = ({
3823
3840
  id
3824
3841
  }) => {
3825
3842
  const inlineEditedElement = getInlineEditorElement(rootElement, expectedTag);
3826
- const [overlayRefElement, setOverlayElement] = (0, import_react18.useState)(inlineEditedElement);
3827
- (0, import_react18.useEffect)(() => {
3843
+ const [overlayRefElement, setOverlayElement] = (0, import_react19.useState)(inlineEditedElement);
3844
+ (0, import_react19.useEffect)(() => {
3828
3845
  setOverlayElement(getInlineEditorElement(rootElement, expectedTag));
3829
3846
  }, [expectedTag, rootElement]);
3830
3847
  return overlayRefElement ? /* @__PURE__ */ React10.createElement(OutlineOverlay, { element: overlayRefElement, id, isSelected: true }) : null;
3831
3848
  };
3832
3849
  var InlineEditingToolbar = ({ anchor, editor, id }) => {
3833
- const { refs, floatingStyles } = (0, import_react19.useFloating)({
3850
+ const { refs, floatingStyles } = (0, import_react20.useFloating)({
3834
3851
  placement: "top",
3835
3852
  strategy: "fixed",
3836
3853
  transform: false,
3837
- whileElementsMounted: import_react19.autoUpdate,
3838
- middleware: [horizontalShifterMiddleware, (0, import_react19.flip)()]
3854
+ whileElementsMounted: import_react20.autoUpdate,
3855
+ middleware: [horizontalShifterMiddleware, (0, import_react20.flip)()]
3839
3856
  });
3840
- (0, import_react18.useLayoutEffect)(() => {
3857
+ (0, import_react19.useLayoutEffect)(() => {
3841
3858
  refs.setReference(anchor);
3842
3859
  return () => refs.setReference(null);
3843
3860
  }, [anchor, refs]);
3844
- return /* @__PURE__ */ React10.createElement(import_react19.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React10.createElement(
3861
+ return /* @__PURE__ */ React10.createElement(import_react20.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React10.createElement(
3845
3862
  import_ui5.Box,
3846
3863
  {
3847
3864
  ref: refs.setFloating,
@@ -3898,7 +3915,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
3898
3915
  return this.editing;
3899
3916
  }
3900
3917
  shouldRenderReplacement() {
3901
- return this.isInlineEditingEligible() && (0, import_editor_v1_adapters16.getCurrentEditMode)() === "edit";
3918
+ return this.isInlineEditingEligible() && (0, import_editor_v1_adapters17.getCurrentEditMode)() === "edit";
3902
3919
  }
3903
3920
  handleRenderInlineEditor = () => {
3904
3921
  if (this.isEditingModeActive() || !this.isInlineEditingEligible()) {
@@ -3985,7 +4002,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
3985
4002
  setContentValue(value) {
3986
4003
  const settingKey = this.getInlineEditablePropertyName();
3987
4004
  const valueToSave = this.createContentPropValue(value);
3988
- (0, import_editor_v1_adapters16.undoable)(
4005
+ (0, import_editor_v1_adapters17.undoable)(
3989
4006
  {
3990
4007
  do: () => {
3991
4008
  const prevValue = this.getInlineEditablePropValue();
@@ -4027,7 +4044,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
4027
4044
  return null;
4028
4045
  }
4029
4046
  runCommand(key, value) {
4030
- (0, import_editor_v1_adapters16.__privateRunCommandSync)(
4047
+ (0, import_editor_v1_adapters17.__privateRunCommandSync)(
4031
4048
  "document/elements/set-settings",
4032
4049
  {
4033
4050
  container: (0, import_editor_elements8.getContainer)(this.id),
@@ -4037,7 +4054,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
4037
4054
  },
4038
4055
  { internal: true }
4039
4056
  );
4040
- (0, import_editor_v1_adapters16.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
4057
+ (0, import_editor_v1_adapters17.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
4041
4058
  }
4042
4059
  getExpectedTag() {
4043
4060
  const tagPropType = this.getTagPropType();
@@ -4202,12 +4219,12 @@ function registerModelExtensions(type, extensions) {
4202
4219
  }
4203
4220
  function registerElementType(type, elementTypeGenerator) {
4204
4221
  elementsLegacyTypes[type] = elementTypeGenerator;
4205
- if ((0, import_editor_v1_adapters17.__privateIsReady)()) {
4222
+ if ((0, import_editor_v1_adapters18.__privateIsReady)()) {
4206
4223
  registerElementInLegacyManager(type, createDomRenderer());
4207
4224
  }
4208
4225
  }
4209
4226
  function initLegacyViews() {
4210
- (0, import_editor_v1_adapters17.__privateListenTo)((0, import_editor_v1_adapters17.v1ReadyEvent)(), () => {
4227
+ (0, import_editor_v1_adapters18.__privateListenTo)((0, import_editor_v1_adapters18.v1ReadyEvent)(), () => {
4211
4228
  const widgetsCache = (0, import_editor_elements9.getWidgetsCache)() ?? {};
4212
4229
  const renderer = createDomRenderer();
4213
4230
  registerProPromotionTypes(widgetsCache);
@@ -4420,7 +4437,7 @@ var initBestPracticesResource = (reg) => {
4420
4437
 
4421
4438
  // src/mcp/resources/document-structure-resource.ts
4422
4439
  var import_editor_elements10 = require("@elementor/editor-elements");
4423
- var import_editor_v1_adapters18 = require("@elementor/editor-v1-adapters");
4440
+ var import_editor_v1_adapters19 = require("@elementor/editor-v1-adapters");
4424
4441
  var DOCUMENT_STRUCTURE_URI = "elementor://document/structure";
4425
4442
  var initDocumentStructureResource = (reg) => {
4426
4443
  const { resource, sendResourceUpdated } = reg;
@@ -4433,15 +4450,15 @@ var initDocumentStructureResource = (reg) => {
4433
4450
  sendResourceUpdated({ uri: DOCUMENT_STRUCTURE_URI });
4434
4451
  }
4435
4452
  };
4436
- (0, import_editor_v1_adapters18.__privateListenTo)(
4453
+ (0, import_editor_v1_adapters19.__privateListenTo)(
4437
4454
  [
4438
- (0, import_editor_v1_adapters18.commandEndEvent)("document/elements/create"),
4439
- (0, import_editor_v1_adapters18.commandEndEvent)("document/elements/delete"),
4440
- (0, import_editor_v1_adapters18.commandEndEvent)("document/elements/move"),
4441
- (0, import_editor_v1_adapters18.commandEndEvent)("document/elements/copy"),
4442
- (0, import_editor_v1_adapters18.commandEndEvent)("document/elements/paste"),
4443
- (0, import_editor_v1_adapters18.commandEndEvent)("editor/documents/attach-preview"),
4444
- (0, import_editor_v1_adapters18.commandEndEvent)("editor/documents/switch")
4455
+ (0, import_editor_v1_adapters19.commandEndEvent)("document/elements/create"),
4456
+ (0, import_editor_v1_adapters19.commandEndEvent)("document/elements/delete"),
4457
+ (0, import_editor_v1_adapters19.commandEndEvent)("document/elements/move"),
4458
+ (0, import_editor_v1_adapters19.commandEndEvent)("document/elements/copy"),
4459
+ (0, import_editor_v1_adapters19.commandEndEvent)("document/elements/paste"),
4460
+ (0, import_editor_v1_adapters19.commandEndEvent)("editor/documents/attach-preview"),
4461
+ (0, import_editor_v1_adapters19.commandEndEvent)("editor/documents/switch")
4445
4462
  ],
4446
4463
  updateDocumentStructure
4447
4464
  );
@@ -4544,7 +4561,7 @@ var initDynamicTagsResource = (reg) => {
4544
4561
  };
4545
4562
 
4546
4563
  // src/mcp/resources/editor-state-resource.ts
4547
- var import_editor_v1_adapters19 = require("@elementor/editor-v1-adapters");
4564
+ var import_editor_v1_adapters20 = require("@elementor/editor-v1-adapters");
4548
4565
  var CURRENTLY_VIEWED_SCREEN = "The user is currently viewing the Elementor editor";
4549
4566
  var PAGE_CONTENT_CHARACTER_LIMIT = 500;
4550
4567
  var PREVIEW_TEXT_NODE_MIN_LENGTH = 2;
@@ -4565,8 +4582,8 @@ var initEditorStateResource = (reg) => {
4565
4582
  lastSerializedState = serialized;
4566
4583
  sendResourceUpdated({ uri: EDITOR_STATE_URI });
4567
4584
  };
4568
- (0, import_editor_v1_adapters19.__privateListenTo)(
4569
- [(0, import_editor_v1_adapters19.commandEndEvent)("editor/documents/switch"), (0, import_editor_v1_adapters19.commandEndEvent)("editor/documents/attach-preview")],
4585
+ (0, import_editor_v1_adapters20.__privateListenTo)(
4586
+ [(0, import_editor_v1_adapters20.commandEndEvent)("editor/documents/switch"), (0, import_editor_v1_adapters20.commandEndEvent)("editor/documents/attach-preview")],
4570
4587
  notifyIfChanged
4571
4588
  );
4572
4589
  lastSerializedState = JSON.stringify(buildState());
@@ -4640,7 +4657,7 @@ function getPageTitle() {
4640
4657
  }
4641
4658
 
4642
4659
  // src/mcp/resources/general-context-resource.ts
4643
- var import_editor_v1_adapters20 = require("@elementor/editor-v1-adapters");
4660
+ var import_editor_v1_adapters21 = require("@elementor/editor-v1-adapters");
4644
4661
  var GENERAL_CONTEXT_URI = "elementor://context/general";
4645
4662
  var initGeneralContextResource = (reg) => {
4646
4663
  const { resource, sendResourceUpdated } = reg;
@@ -4701,11 +4718,11 @@ var initGeneralContextResource = (reg) => {
4701
4718
  };
4702
4719
  }
4703
4720
  );
4704
- (0, import_editor_v1_adapters20.__privateListenTo)(
4721
+ (0, import_editor_v1_adapters21.__privateListenTo)(
4705
4722
  [
4706
- (0, import_editor_v1_adapters20.commandEndEvent)("editor/documents/switch"),
4707
- (0, import_editor_v1_adapters20.commandEndEvent)("editor/documents/attach-preview"),
4708
- (0, import_editor_v1_adapters20.commandEndEvent)("document/elements/settings")
4723
+ (0, import_editor_v1_adapters21.commandEndEvent)("editor/documents/switch"),
4724
+ (0, import_editor_v1_adapters21.commandEndEvent)("editor/documents/attach-preview"),
4725
+ (0, import_editor_v1_adapters21.commandEndEvent)("document/elements/settings")
4709
4726
  ],
4710
4727
  pushUpdateIfChanged
4711
4728
  );
@@ -4715,7 +4732,7 @@ var initGeneralContextResource = (reg) => {
4715
4732
  // src/mcp/resources/selected-element-resource.ts
4716
4733
  var import_editor_elements11 = require("@elementor/editor-elements");
4717
4734
  var import_editor_props6 = require("@elementor/editor-props");
4718
- var import_editor_v1_adapters21 = require("@elementor/editor-v1-adapters");
4735
+ var import_editor_v1_adapters22 = require("@elementor/editor-v1-adapters");
4719
4736
  var SELECTED_ELEMENT_URI = "elementor://context/selected-element";
4720
4737
  var initSelectedElementResource = (reg) => {
4721
4738
  const { resource, sendResourceUpdated } = reg;
@@ -4746,11 +4763,11 @@ var initSelectedElementResource = (reg) => {
4746
4763
  }
4747
4764
  publishIfChanged(readSelectionFromEditor());
4748
4765
  };
4749
- (0, import_editor_v1_adapters21.__privateListenTo)(
4766
+ (0, import_editor_v1_adapters22.__privateListenTo)(
4750
4767
  [
4751
- (0, import_editor_v1_adapters21.commandEndEvent)("document/elements/select"),
4752
- (0, import_editor_v1_adapters21.commandEndEvent)("document/elements/deselect-all"),
4753
- (0, import_editor_v1_adapters21.commandEndEvent)("document/elements/settings")
4768
+ (0, import_editor_v1_adapters22.commandEndEvent)("document/elements/select"),
4769
+ (0, import_editor_v1_adapters22.commandEndEvent)("document/elements/deselect-all"),
4770
+ (0, import_editor_v1_adapters22.commandEndEvent)("document/elements/settings")
4754
4771
  ],
4755
4772
  onCommand
4756
4773
  );
@@ -4874,7 +4891,7 @@ var import_editor_props8 = require("@elementor/editor-props");
4874
4891
  var import_editor_elements13 = require("@elementor/editor-elements");
4875
4892
  var import_editor_props7 = require("@elementor/editor-props");
4876
4893
  var import_editor_styles4 = require("@elementor/editor-styles");
4877
- var import_editor_v1_adapters23 = require("@elementor/editor-v1-adapters");
4894
+ var import_editor_v1_adapters24 = require("@elementor/editor-v1-adapters");
4878
4895
 
4879
4896
  // src/mcp/utils/merge-custom-css.ts
4880
4897
  var CUSTOM_CSS_SEPARATOR = "\n";
@@ -4943,11 +4960,11 @@ function resolveCanonicalPropKeys(elementType, props) {
4943
4960
  }
4944
4961
 
4945
4962
  // src/mcp/utils/resolve-dynamic-tag.ts
4946
- var import_editor_v1_adapters22 = require("@elementor/editor-v1-adapters");
4963
+ var import_editor_v1_adapters23 = require("@elementor/editor-v1-adapters");
4947
4964
  var DYNAMIC_PROP_TYPE_KEY = "dynamic";
4948
4965
  var OMITTED_DYNAMIC_SETTING_KEYS = ["fallback"];
4949
4966
  var getAtomicDynamicTags = () => {
4950
- const config = (0, import_editor_v1_adapters22.getElementorConfig)();
4967
+ const config = (0, import_editor_v1_adapters23.getElementorConfig)();
4951
4968
  return config.atomicDynamicTags?.tags ?? {};
4952
4969
  };
4953
4970
  var getDynamicTagNamesByCategories = (categories) => {
@@ -5148,7 +5165,7 @@ Expected Schema: ${jsonSchema}`
5148
5165
  },
5149
5166
  withHistory: false
5150
5167
  });
5151
- (0, import_editor_v1_adapters23.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
5168
+ (0, import_editor_v1_adapters24.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
5152
5169
  };
5153
5170
 
5154
5171
  // src/mcp/tools/configure-element/prompt.ts
@@ -5754,14 +5771,14 @@ Note: The "size" property controls image resolution/loading, not visual size. Se
5754
5771
  // src/prevent-link-in-link-commands.ts
5755
5772
  var import_editor_elements15 = require("@elementor/editor-elements");
5756
5773
  var import_editor_notifications6 = require("@elementor/editor-notifications");
5757
- var import_editor_v1_adapters24 = require("@elementor/editor-v1-adapters");
5774
+ var import_editor_v1_adapters25 = require("@elementor/editor-v1-adapters");
5758
5775
  var import_i18n7 = require("@wordpress/i18n");
5759
5776
  function initLinkInLinkPrevention() {
5760
- (0, import_editor_v1_adapters24.blockCommand)({
5777
+ (0, import_editor_v1_adapters25.blockCommand)({
5761
5778
  command: "document/elements/paste",
5762
5779
  condition: blockLinkInLinkPaste
5763
5780
  });
5764
- (0, import_editor_v1_adapters24.blockCommand)({
5781
+ (0, import_editor_v1_adapters25.blockCommand)({
5765
5782
  command: "document/elements/move",
5766
5783
  condition: blockLinkInLinkMove
5767
5784
  });
@@ -5837,7 +5854,7 @@ function shouldBlock(sourceElements, targetElements) {
5837
5854
  // src/style-commands/paste-style.ts
5838
5855
  var import_editor_elements18 = require("@elementor/editor-elements");
5839
5856
  var import_editor_props11 = require("@elementor/editor-props");
5840
- var import_editor_v1_adapters26 = require("@elementor/editor-v1-adapters");
5857
+ var import_editor_v1_adapters27 = require("@elementor/editor-v1-adapters");
5841
5858
 
5842
5859
  // src/utils/command-utils.ts
5843
5860
  var import_editor_elements16 = require("@elementor/editor-elements");
@@ -5884,9 +5901,9 @@ function getTitleForContainers(containers) {
5884
5901
  // src/style-commands/undoable-actions/paste-element-style.ts
5885
5902
  var import_editor_elements17 = require("@elementor/editor-elements");
5886
5903
  var import_editor_styles_repository4 = require("@elementor/editor-styles-repository");
5887
- var import_editor_v1_adapters25 = require("@elementor/editor-v1-adapters");
5904
+ var import_editor_v1_adapters26 = require("@elementor/editor-v1-adapters");
5888
5905
  var import_i18n9 = require("@wordpress/i18n");
5889
- var undoablePasteElementStyle = () => (0, import_editor_v1_adapters25.undoable)(
5906
+ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters26.undoable)(
5890
5907
  {
5891
5908
  do: ({ containers, newStyle }) => {
5892
5909
  return containers.map((container) => {
@@ -5962,12 +5979,12 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters25.undoable)(
5962
5979
  // src/style-commands/paste-style.ts
5963
5980
  function initPasteStyleCommand() {
5964
5981
  const pasteElementStyleCommand = undoablePasteElementStyle();
5965
- (0, import_editor_v1_adapters26.blockCommand)({
5982
+ (0, import_editor_v1_adapters27.blockCommand)({
5966
5983
  command: "document/elements/paste-style",
5967
5984
  condition: hasAtomicWidgets
5968
5985
  });
5969
- (0, import_editor_v1_adapters26.__privateListenTo)(
5970
- (0, import_editor_v1_adapters26.commandStartEvent)("document/elements/paste-style"),
5986
+ (0, import_editor_v1_adapters27.__privateListenTo)(
5987
+ (0, import_editor_v1_adapters27.commandStartEvent)("document/elements/paste-style"),
5971
5988
  (e) => pasteStyles(e.args, pasteElementStyleCommand)
5972
5989
  );
5973
5990
  }
@@ -6018,14 +6035,14 @@ function pasteClasses(containers, classes) {
6018
6035
  }
6019
6036
 
6020
6037
  // src/style-commands/reset-style.ts
6021
- var import_editor_v1_adapters28 = require("@elementor/editor-v1-adapters");
6038
+ var import_editor_v1_adapters29 = require("@elementor/editor-v1-adapters");
6022
6039
 
6023
6040
  // src/style-commands/undoable-actions/reset-element-style.ts
6024
6041
  var import_editor_elements19 = require("@elementor/editor-elements");
6025
6042
  var import_editor_styles_repository5 = require("@elementor/editor-styles-repository");
6026
- var import_editor_v1_adapters27 = require("@elementor/editor-v1-adapters");
6043
+ var import_editor_v1_adapters28 = require("@elementor/editor-v1-adapters");
6027
6044
  var import_i18n10 = require("@wordpress/i18n");
6028
- var undoableResetElementStyle = () => (0, import_editor_v1_adapters27.undoable)(
6045
+ var undoableResetElementStyle = () => (0, import_editor_v1_adapters28.undoable)(
6029
6046
  {
6030
6047
  do: ({ containers }) => {
6031
6048
  return containers.map((container) => {
@@ -6069,12 +6086,12 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters27.undoable)(
6069
6086
  // src/style-commands/reset-style.ts
6070
6087
  function initResetStyleCommand() {
6071
6088
  const resetElementStyles = undoableResetElementStyle();
6072
- (0, import_editor_v1_adapters28.blockCommand)({
6089
+ (0, import_editor_v1_adapters29.blockCommand)({
6073
6090
  command: "document/elements/reset-style",
6074
6091
  condition: hasAtomicWidgets
6075
6092
  });
6076
- (0, import_editor_v1_adapters28.__privateListenTo)(
6077
- (0, import_editor_v1_adapters28.commandStartEvent)("document/elements/reset-style"),
6093
+ (0, import_editor_v1_adapters29.__privateListenTo)(
6094
+ (0, import_editor_v1_adapters29.commandStartEvent)("document/elements/reset-style"),
6078
6095
  (e) => resetStyles(e.args, resetElementStyles)
6079
6096
  );
6080
6097
  }
@@ -6226,15 +6243,15 @@ function getRectClipPath(rect, viewport) {
6226
6243
  }
6227
6244
 
6228
6245
  // src/hooks/use-canvas-document.ts
6229
- var import_editor_v1_adapters29 = require("@elementor/editor-v1-adapters");
6246
+ var import_editor_v1_adapters30 = require("@elementor/editor-v1-adapters");
6230
6247
  function useCanvasDocument() {
6231
- return (0, import_editor_v1_adapters29.__privateUseListenTo)((0, import_editor_v1_adapters29.commandEndEvent)("editor/documents/attach-preview"), () => (0, import_editor_v1_adapters29.getCanvasIframeDocument)());
6248
+ return (0, import_editor_v1_adapters30.__privateUseListenTo)((0, import_editor_v1_adapters30.commandEndEvent)("editor/documents/attach-preview"), () => (0, import_editor_v1_adapters30.getCanvasIframeDocument)());
6232
6249
  }
6233
6250
 
6234
6251
  // src/hooks/use-escape-on-canvas.ts
6235
- var import_react20 = require("react");
6252
+ var import_react21 = require("react");
6236
6253
  function useEscapeOnCanvas(canvasDocument, onEscape) {
6237
- (0, import_react20.useEffect)(() => {
6254
+ (0, import_react21.useEffect)(() => {
6238
6255
  if (!canvasDocument) {
6239
6256
  return;
6240
6257
  }
package/dist/index.mjs CHANGED
@@ -1122,7 +1122,7 @@ import * as React9 from "react";
1122
1122
  import {
1123
1123
  __privateUseListenTo as useListenTo5,
1124
1124
  commandEndEvent as commandEndEvent3,
1125
- getCanvasIframeDocument as getCanvasIframeDocument4
1125
+ getCanvasIframeDocument as getCanvasIframeDocument5
1126
1126
  } from "@elementor/editor-v1-adapters";
1127
1127
  import { Portal as Portal2 } from "@elementor/ui";
1128
1128
 
@@ -1239,6 +1239,25 @@ function signalizedProcess(signal, steps = []) {
1239
1239
  };
1240
1240
  }
1241
1241
 
1242
+ // src/hooks/use-pregenerated-links-handoff.ts
1243
+ import { useLayoutEffect } from "react";
1244
+ import { getCanvasIframeDocument as getCanvasIframeDocument4 } from "@elementor/editor-v1-adapters";
1245
+ function usePregeneratedLinksHandoff(canvasHead, renderedProviders) {
1246
+ useLayoutEffect(() => {
1247
+ if (!isCurrentCanvasHead(canvasHead)) {
1248
+ return;
1249
+ }
1250
+ Object.entries(renderedProviders).forEach(([providerKey, { provider, items }]) => {
1251
+ if (items.length > 0 && provider.isPregeneratedLink) {
1252
+ removeProviderPregeneratedLinks(providerKey, provider.isPregeneratedLink);
1253
+ }
1254
+ });
1255
+ }, [canvasHead, renderedProviders]);
1256
+ }
1257
+ function isCurrentCanvasHead(canvasHead) {
1258
+ return !!canvasHead && canvasHead === getCanvasIframeDocument4()?.head;
1259
+ }
1260
+
1242
1261
  // src/hooks/use-style-prop-resolver.ts
1243
1262
  import { useMemo as useMemo3 } from "react";
1244
1263
  import { getStylesSchema } from "@elementor/editor-styles";
@@ -1524,7 +1543,7 @@ function useStyleRenderer(resolve) {
1524
1543
  }
1525
1544
 
1526
1545
  // src/hooks/use-style-items.ts
1527
- function useStyleItems() {
1546
+ function useStyleItems(canvasHead) {
1528
1547
  const resolve = useStylePropResolver();
1529
1548
  const renderStyles = useStyleRenderer(resolve);
1530
1549
  const breakpoints = useBreakpoints();
@@ -1571,6 +1590,7 @@ function useStyleItems() {
1571
1590
  await Promise.all(promises);
1572
1591
  });
1573
1592
  });
1593
+ usePregeneratedLinksHandoff(canvasHead, styleItems);
1574
1594
  const breakpointSorter = useMemo5(
1575
1595
  () => createBreakpointSorter(breakpoints.map((breakpoint) => breakpoint.id)),
1576
1596
  [breakpoints]
@@ -1608,9 +1628,6 @@ function createProviderSubscriber2({ provider, renderStyles, setStyleItems, getC
1608
1628
  const cache = getCache();
1609
1629
  const hasDiffInfo = current !== void 0 && previous !== void 0;
1610
1630
  const hasCache = cache.orderedIds.length > 0;
1611
- if (hasCache && provider.isPregeneratedLink) {
1612
- removeProviderPregeneratedLinks(provider.getKey(), provider.isPregeneratedLink);
1613
- }
1614
1631
  if (hasDiffInfo && hasCache) {
1615
1632
  return updateItems(cache, previous, current, signal);
1616
1633
  }
@@ -1712,7 +1729,7 @@ function rebuildCache(cache, allStyles, items) {
1712
1729
  // src/components/style-renderer.tsx
1713
1730
  function StyleRenderer() {
1714
1731
  const container = usePortalContainer2();
1715
- const styleItems = useStyleItems();
1732
+ const styleItems = useStyleItems(container);
1716
1733
  const linksAttrs = useDocumentsCssLinks();
1717
1734
  if (!container) {
1718
1735
  return null;
@@ -1720,7 +1737,7 @@ function StyleRenderer() {
1720
1737
  return /* @__PURE__ */ React9.createElement(Portal2, { container }, filterUniqueStyleDefinitions(styleItems).map((item) => /* @__PURE__ */ React9.createElement("style", { key: `${item.id}-${item.breakpoint}-${item.state ?? "normal"}` }, item.value)), linksAttrs.map((attrs) => /* @__PURE__ */ React9.createElement("link", { ...attrs, key: attrs.id })));
1721
1738
  }
1722
1739
  function usePortalContainer2() {
1723
- return useListenTo5(commandEndEvent3("editor/documents/attach-preview"), () => getCanvasIframeDocument4()?.head);
1740
+ return useListenTo5(commandEndEvent3("editor/documents/attach-preview"), () => getCanvasIframeDocument5()?.head);
1724
1741
  }
1725
1742
  function filterUniqueStyleDefinitions(styleItems) {
1726
1743
  const seen = /* @__PURE__ */ new Map();
@@ -3592,7 +3609,7 @@ var ReplacementBase = class {
3592
3609
 
3593
3610
  // src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
3594
3611
  import * as React10 from "react";
3595
- import { useCallback as useCallback2, useEffect as useEffect12, useLayoutEffect, useState as useState8 } from "react";
3612
+ import { useCallback as useCallback2, useEffect as useEffect12, useLayoutEffect as useLayoutEffect2, useState as useState8 } from "react";
3596
3613
  import { InlineEditor, InlineEditorToolbar } from "@elementor/editor-controls";
3597
3614
  import { ThemeProvider } from "@elementor/editor-ui";
3598
3615
  import { Box as Box3 } from "@elementor/ui";
@@ -3803,7 +3820,7 @@ var InlineEditingToolbar = ({ anchor, editor, id }) => {
3803
3820
  whileElementsMounted: autoUpdate2,
3804
3821
  middleware: [horizontalShifterMiddleware, flip()]
3805
3822
  });
3806
- useLayoutEffect(() => {
3823
+ useLayoutEffect2(() => {
3807
3824
  refs.setReference(anchor);
3808
3825
  return () => refs.setReference(null);
3809
3826
  }, [anchor, refs]);
@@ -6227,10 +6244,10 @@ function getRectClipPath(rect, viewport) {
6227
6244
  import {
6228
6245
  __privateUseListenTo as useListenTo6,
6229
6246
  commandEndEvent as commandEndEvent8,
6230
- getCanvasIframeDocument as getCanvasIframeDocument5
6247
+ getCanvasIframeDocument as getCanvasIframeDocument6
6231
6248
  } from "@elementor/editor-v1-adapters";
6232
6249
  function useCanvasDocument() {
6233
- return useListenTo6(commandEndEvent8("editor/documents/attach-preview"), () => getCanvasIframeDocument5());
6250
+ return useListenTo6(commandEndEvent8("editor/documents/attach-preview"), () => getCanvasIframeDocument6());
6234
6251
  }
6235
6252
 
6236
6253
  // src/hooks/use-escape-on-canvas.ts
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elementor/editor-canvas",
3
3
  "description": "Elementor Editor Canvas",
4
- "version": "4.5.0-1155",
4
+ "version": "4.5.0-1156",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -37,26 +37,26 @@
37
37
  "react-dom": "^18.3.1"
38
38
  },
39
39
  "dependencies": {
40
- "@elementor/editor": "4.5.0-1155",
41
- "@elementor/editor-controls": "4.5.0-1155",
42
- "@elementor/editor-documents": "4.5.0-1155",
43
- "@elementor/editor-elements": "4.5.0-1155",
44
- "@elementor/editor-interactions": "4.5.0-1155",
45
- "@elementor/editor-mcp": "4.5.0-1155",
46
- "@elementor/editor-notifications": "4.5.0-1155",
47
- "@elementor/editor-props": "4.5.0-1155",
48
- "@elementor/editor-responsive": "4.5.0-1155",
49
- "@elementor/editor-styles": "4.5.0-1155",
50
- "@elementor/editor-styles-repository": "4.5.0-1155",
51
- "@elementor/editor-ui": "4.5.0-1155",
52
- "@elementor/editor-v1-adapters": "4.5.0-1155",
53
- "@elementor/events": "4.5.0-1155",
54
- "@elementor/http-client": "4.5.0-1155",
55
- "@elementor/schema": "4.5.0-1155",
56
- "@elementor/twing": "4.5.0-1155",
40
+ "@elementor/editor": "4.5.0-1156",
41
+ "@elementor/editor-controls": "4.5.0-1156",
42
+ "@elementor/editor-documents": "4.5.0-1156",
43
+ "@elementor/editor-elements": "4.5.0-1156",
44
+ "@elementor/editor-interactions": "4.5.0-1156",
45
+ "@elementor/editor-mcp": "4.5.0-1156",
46
+ "@elementor/editor-notifications": "4.5.0-1156",
47
+ "@elementor/editor-props": "4.5.0-1156",
48
+ "@elementor/editor-responsive": "4.5.0-1156",
49
+ "@elementor/editor-styles": "4.5.0-1156",
50
+ "@elementor/editor-styles-repository": "4.5.0-1156",
51
+ "@elementor/editor-ui": "4.5.0-1156",
52
+ "@elementor/editor-v1-adapters": "4.5.0-1156",
53
+ "@elementor/events": "4.5.0-1156",
54
+ "@elementor/http-client": "4.5.0-1156",
55
+ "@elementor/schema": "4.5.0-1156",
56
+ "@elementor/twing": "4.5.0-1156",
57
57
  "@elementor/ui": "1.41.4",
58
- "@elementor/utils": "4.5.0-1155",
59
- "@elementor/wp-media": "4.5.0-1155",
58
+ "@elementor/utils": "4.5.0-1156",
59
+ "@elementor/wp-media": "4.5.0-1156",
60
60
  "@floating-ui/react": "^0.27.5",
61
61
  "@wordpress/i18n": "^5.13.0",
62
62
  "dompurify": "^3.2.6"
@@ -64,6 +64,7 @@ describe( '<StyleRenderer />', () => {
64
64
  render( <StyleRenderer /> );
65
65
 
66
66
  // Assert.
67
+ expect( useStyleItems ).toHaveBeenCalledWith( mockContainer );
67
68
  // eslint-disable-next-line testing-library/no-test-id-queries
68
69
  expect( screen.getByTestId( 'portal' ) ).toMatchSnapshot();
69
70
  } );
@@ -13,7 +13,7 @@ import { type StyleItem } from '../renderers/create-styles-renderer';
13
13
  export function StyleRenderer() {
14
14
  const container = usePortalContainer();
15
15
 
16
- const styleItems = useStyleItems();
16
+ const styleItems = useStyleItems( container );
17
17
  const linksAttrs = useDocumentsCssLinks();
18
18
 
19
19
  if ( ! container ) {
@@ -1,12 +1,18 @@
1
1
  import { createMockStyleDefinition, createMockStyleDefinitionWithVariants, createMockStylesProvider } from 'test-utils';
2
2
  import { type StyleDefinition } from '@elementor/editor-styles';
3
3
  import { stylesRepository } from '@elementor/editor-styles-repository';
4
- import { registerDataHook } from '@elementor/editor-v1-adapters';
4
+ import { getCanvasIframeDocument, registerDataHook } from '@elementor/editor-v1-adapters';
5
5
  import { act, renderHook } from '@testing-library/react';
6
6
 
7
+ import { removeProviderPregeneratedLinks } from '../../utils/pregenerated-links-removal';
7
8
  import { useStyleItems } from '../use-style-items';
8
9
  import { useStyleRenderer } from '../use-style-renderer';
9
10
 
11
+ jest.mock( '../../utils/pregenerated-links-removal', () => ( {
12
+ removeProviderPregeneratedLinks: jest.fn(),
13
+ resetRemovedProviders: jest.fn(),
14
+ } ) );
15
+
10
16
  jest.mock( '@elementor/editor-styles-repository', () => ( {
11
17
  ...jest.requireActual( '@elementor/editor-styles-repository' ),
12
18
  stylesRepository: {
@@ -17,6 +23,7 @@ jest.mock( '@elementor/editor-styles-repository', () => ( {
17
23
  jest.mock( '@elementor/editor-v1-adapters', () => ( {
18
24
  ...jest.requireActual( '@elementor/editor-v1-adapters' ),
19
25
  registerDataHook: jest.fn(),
26
+ getCanvasIframeDocument: jest.fn(),
20
27
  } ) );
21
28
 
22
29
  jest.mock( '../use-style-prop-resolver', () => ( {
@@ -513,4 +520,158 @@ describe( 'useStyleItems', () => {
513
520
  expect( renderStylesMock.mock.calls[ 0 ][ 0 ].styles[ 0 ].id ).toBe( 'style2' );
514
521
  expect( result.current ).toHaveLength( 3 );
515
522
  } );
523
+
524
+ describe( 'pregenerated links removal', () => {
525
+ let attachPreviewCallback: () => Promise< void >;
526
+ let canvasDocument: Document;
527
+
528
+ beforeEach( () => {
529
+ jest.mocked( removeProviderPregeneratedLinks ).mockClear();
530
+
531
+ canvasDocument = document.implementation.createHTMLDocument();
532
+ jest.mocked( getCanvasIframeDocument ).mockReturnValue( canvasDocument );
533
+
534
+ jest.mocked( registerDataHook ).mockImplementation( ( position, command, callback ) => {
535
+ if ( command === 'editor/documents/attach-preview' && position === 'after' ) {
536
+ attachPreviewCallback = callback as never;
537
+ }
538
+
539
+ return null as never;
540
+ } );
541
+ } );
542
+
543
+ const createProviderWithPregeneratedLinks = ( key: string, styles: StyleDefinition[] ) => ( {
544
+ ...createMockStylesProvider( { key }, styles ),
545
+ isPregeneratedLink: jest.fn(),
546
+ } );
547
+
548
+ it( 'should not remove pregenerated links before the canvas head is available', async () => {
549
+ // Arrange.
550
+ const provider = createProviderWithPregeneratedLinks( 'global-classes', [
551
+ createMockStyleDefinition( { id: 'style1' } ),
552
+ ] );
553
+
554
+ jest.mocked( stylesRepository ).getProviders.mockReturnValue( [ provider ] );
555
+
556
+ const { result } = renderHook( () => useStyleItems( null ) );
557
+
558
+ // Act.
559
+ await act( async () => {
560
+ await attachPreviewCallback?.();
561
+ } );
562
+
563
+ await act( async () => {
564
+ await attachPreviewCallback?.();
565
+ } );
566
+
567
+ // Assert.
568
+ expect( result.current ).toHaveLength( 1 );
569
+ expect( removeProviderPregeneratedLinks ).not.toHaveBeenCalled();
570
+ } );
571
+
572
+ it( 'should remove pregenerated links once rendered items are committed into the canvas head', async () => {
573
+ // Arrange.
574
+ const provider = createProviderWithPregeneratedLinks( 'global-classes', [
575
+ createMockStyleDefinition( { id: 'style1' } ),
576
+ ] );
577
+
578
+ jest.mocked( stylesRepository ).getProviders.mockReturnValue( [ provider ] );
579
+
580
+ const { rerender } = renderHook( ( { head } ) => useStyleItems( head ), {
581
+ initialProps: { head: null as HTMLElement | null },
582
+ } );
583
+
584
+ await act( async () => {
585
+ await attachPreviewCallback?.();
586
+ } );
587
+
588
+ // Act.
589
+ rerender( { head: canvasDocument.head } );
590
+
591
+ // Assert.
592
+ expect( removeProviderPregeneratedLinks ).toHaveBeenCalledTimes( 1 );
593
+ expect( removeProviderPregeneratedLinks ).toHaveBeenCalledWith(
594
+ 'global-classes',
595
+ provider.isPregeneratedLink
596
+ );
597
+ } );
598
+
599
+ it( 'should not remove pregenerated links while the portal targets a stale document head', async () => {
600
+ // Arrange.
601
+ const provider = createProviderWithPregeneratedLinks( 'global-classes', [
602
+ createMockStyleDefinition( { id: 'style1' } ),
603
+ ] );
604
+
605
+ jest.mocked( stylesRepository ).getProviders.mockReturnValue( [ provider ] );
606
+
607
+ const staleDocument = document.implementation.createHTMLDocument();
608
+
609
+ const { rerender } = renderHook( ( { head } ) => useStyleItems( head ), {
610
+ initialProps: { head: staleDocument.head },
611
+ } );
612
+
613
+ // Act.
614
+ await act( async () => {
615
+ await attachPreviewCallback?.();
616
+ } );
617
+
618
+ // Assert.
619
+ expect( removeProviderPregeneratedLinks ).not.toHaveBeenCalled();
620
+
621
+ // Act.
622
+ rerender( { head: canvasDocument.head } );
623
+
624
+ // Assert.
625
+ expect( removeProviderPregeneratedLinks ).toHaveBeenCalledTimes( 1 );
626
+ } );
627
+
628
+ it( 'should keep pregenerated links while the provider has no rendered items', async () => {
629
+ // Arrange.
630
+ const placeholderStyle: StyleDefinition = {
631
+ id: 'g-placeholder',
632
+ type: 'class',
633
+ label: 'placeholder',
634
+ variants: [],
635
+ };
636
+
637
+ const provider = createProviderWithPregeneratedLinks( 'global-classes', [ placeholderStyle ] );
638
+
639
+ jest.mocked( stylesRepository ).getProviders.mockReturnValue( [ provider ] );
640
+
641
+ const { result } = renderHook( () => useStyleItems( canvasDocument.head ) );
642
+
643
+ // Act.
644
+ await act( async () => {
645
+ await attachPreviewCallback?.();
646
+ } );
647
+
648
+ await act( async () => {
649
+ await attachPreviewCallback?.();
650
+ } );
651
+
652
+ // Assert.
653
+ expect( result.current ).toEqual( [] );
654
+ expect( removeProviderPregeneratedLinks ).not.toHaveBeenCalled();
655
+ } );
656
+
657
+ it( 'should not remove links for providers without pregenerated links', async () => {
658
+ // Arrange.
659
+ const provider = createMockStylesProvider( { key: 'provider1' }, [
660
+ createMockStyleDefinition( { id: 'style1' } ),
661
+ ] );
662
+
663
+ jest.mocked( stylesRepository ).getProviders.mockReturnValue( [ provider ] );
664
+
665
+ const { result } = renderHook( () => useStyleItems( canvasDocument.head ) );
666
+
667
+ // Act.
668
+ await act( async () => {
669
+ await attachPreviewCallback?.();
670
+ } );
671
+
672
+ // Assert.
673
+ expect( result.current ).toHaveLength( 1 );
674
+ expect( removeProviderPregeneratedLinks ).not.toHaveBeenCalled();
675
+ } );
676
+ } );
516
677
  } );
@@ -0,0 +1,33 @@
1
+ import { useLayoutEffect } from 'react';
2
+ import { type StylesProvider } from '@elementor/editor-styles-repository';
3
+ import { getCanvasIframeDocument } from '@elementor/editor-v1-adapters';
4
+
5
+ import { type StyleItem } from '../renderers/create-styles-renderer';
6
+ import { removeProviderPregeneratedLinks } from '../utils/pregenerated-links-removal';
7
+
8
+ type RenderedProviders = Record< string, { provider: StylesProvider; items: StyleItem[] } >;
9
+
10
+ // The pregenerated <link /> css can only be dropped once the client-side <style /> tags replacing it are committed
11
+ // into the canvas, otherwise the canvas is painted without any of the provider's styles.
12
+ export function usePregeneratedLinksHandoff(
13
+ canvasHead: HTMLElement | null | undefined,
14
+ renderedProviders: RenderedProviders
15
+ ) {
16
+ useLayoutEffect( () => {
17
+ if ( ! isCurrentCanvasHead( canvasHead ) ) {
18
+ return;
19
+ }
20
+
21
+ Object.entries( renderedProviders ).forEach( ( [ providerKey, { provider, items } ] ) => {
22
+ if ( items.length > 0 && provider.isPregeneratedLink ) {
23
+ removeProviderPregeneratedLinks( providerKey, provider.isPregeneratedLink );
24
+ }
25
+ } );
26
+ }, [ canvasHead, renderedProviders ] );
27
+ }
28
+
29
+ // The portal container is resolved before the preview document replaces the iframe's initial document,
30
+ // so a stale head would let the live canvas lose its pregenerated links while the styles render elsewhere.
31
+ function isCurrentCanvasHead( canvasHead?: HTMLElement | null ): canvasHead is HTMLElement {
32
+ return !! canvasHead && canvasHead === getCanvasIframeDocument()?.head;
33
+ }
@@ -6,9 +6,10 @@ import { registerDataHook } from '@elementor/editor-v1-adapters';
6
6
 
7
7
  import { type RendererStyleDefinition, type StyleItem, type StyleRenderer } from '../renderers/create-styles-renderer';
8
8
  import { abortPreviousRuns } from '../utils/abort-previous-runs';
9
- import { removeProviderPregeneratedLinks, resetRemovedProviders } from '../utils/pregenerated-links-removal';
9
+ import { resetRemovedProviders } from '../utils/pregenerated-links-removal';
10
10
  import { signalizedProcess } from '../utils/signalized-process';
11
11
  import { useOnMount } from './use-on-mount';
12
+ import { usePregeneratedLinksHandoff } from './use-pregenerated-links-handoff';
12
13
  import { useStylePropResolver } from './use-style-prop-resolver';
13
14
  import { useStyleRenderer } from './use-style-renderer';
14
15
 
@@ -28,7 +29,7 @@ type ProviderAndSubscriber = {
28
29
 
29
30
  type ProviderAndStyleItemsMap = Record< string, ProviderAndStyleItems >;
30
31
 
31
- export function useStyleItems() {
32
+ export function useStyleItems( canvasHead?: HTMLElement | null ) {
32
33
  const resolve = useStylePropResolver();
33
34
  const renderStyles = useStyleRenderer( resolve );
34
35
  const breakpoints = useBreakpoints();
@@ -88,6 +89,8 @@ export function useStyleItems() {
88
89
  } );
89
90
  } );
90
91
 
92
+ usePregeneratedLinksHandoff( canvasHead, styleItems );
93
+
91
94
  const breakpointSorter = useMemo(
92
95
  () => createBreakpointSorter( breakpoints.map( ( breakpoint ) => breakpoint.id ) ),
93
96
  [ breakpoints ]
@@ -158,11 +161,6 @@ function createProviderSubscriber( { provider, renderStyles, setStyleItems, getC
158
161
  const hasDiffInfo = current !== undefined && previous !== undefined;
159
162
  const hasCache = cache.orderedIds.length > 0;
160
163
 
161
- if ( hasCache && provider.isPregeneratedLink ) {
162
- // if styles were rendered already (i.e. hasCache = true), we can safely remove the pregenerated css rules imported via <link /> tags
163
- removeProviderPregeneratedLinks( provider.getKey(), provider.isPregeneratedLink );
164
- }
165
-
166
164
  if ( hasDiffInfo && hasCache ) {
167
165
  return updateItems( cache, previous, current, signal );
168
166
  }