@elementor/editor-canvas 4.0.0-607 → 4.0.0-619

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -61,6 +61,9 @@ type LegacyWindow = Window & {
61
61
  }
62
62
  ];
63
63
  $previewWrapper: JQueryElement;
64
+ helpers: {
65
+ hasPro: () => boolean;
66
+ };
64
67
  };
65
68
  };
66
69
  type JQueryStatic = (html: string) => JQueryElement;
@@ -82,6 +85,7 @@ declare class ElementView {
82
85
  length: number;
83
86
  findByIndex: (index: number) => ElementView;
84
87
  each: (callback: (view: ElementView) => void) => void;
88
+ map: <T>(callback: (view: ElementView) => T) => T[];
85
89
  };
86
90
  constructor(...args: unknown[]);
87
91
  onRender(...args: unknown[]): void;
@@ -177,7 +181,15 @@ type ToJSON<T> = {
177
181
  };
178
182
  type ContextMenuGroup = {
179
183
  name: string;
180
- actions: unknown[];
184
+ actions: ContextMenuAction[];
185
+ };
186
+ type ContextMenuAction = {
187
+ name: string;
188
+ icon: string;
189
+ title: string | (() => string);
190
+ shortcut?: string;
191
+ isEnabled: () => boolean;
192
+ callback: (_: unknown, eventData: unknown) => void;
181
193
  };
182
194
  type ReplacementSettings = {
183
195
  getSetting: (key: string) => unknown;
@@ -324,4 +336,4 @@ declare const UnknownStyleStateError: {
324
336
  isError(error: unknown): error is Error;
325
337
  };
326
338
 
327
- export { type AnyTransformer, BREAKPOINTS_SCHEMA_URI, type BackboneModel, type BackboneModelConstructor, type CreateNestedTemplatedElementTypeOptions, type CreateTemplatedElementTypeOptions, DOCUMENT_STRUCTURE_URI, type ElementModel, ElementType, ElementView, type LegacyWindow, type NamespacedRenderContext, type NestedTemplatedElementConfig, type PropsResolver, type RenderContext, type ReplacementSettings, STYLE_SCHEMA_URI, type TransformerOptions, UnknownStyleStateError, UnknownStyleTypeError, WIDGET_SCHEMA_URI, canBeNestedTemplated, createNestedTemplatedElementType, createNestedTemplatedElementView, createPropsResolver, createTemplatedElementView, createTransformer, createTransformersRegistry, endDragElementFromPanel, init, isAtomicWidget, registerElementType, registerModelExtensions, settingsTransformersRegistry, startDragElementFromPanel, styleTransformersRegistry, stylesInheritanceTransformersRegistry };
339
+ export { type AnyTransformer, BREAKPOINTS_SCHEMA_URI, type BackboneModel, type BackboneModelConstructor, type ContextMenuAction, type CreateNestedTemplatedElementTypeOptions, type CreateTemplatedElementTypeOptions, DOCUMENT_STRUCTURE_URI, type ElementModel, ElementType, ElementView, type LegacyWindow, type NamespacedRenderContext, type NestedTemplatedElementConfig, type PropsResolver, type RenderContext, type ReplacementSettings, STYLE_SCHEMA_URI, type TransformerOptions, UnknownStyleStateError, UnknownStyleTypeError, WIDGET_SCHEMA_URI, canBeNestedTemplated, createNestedTemplatedElementType, createNestedTemplatedElementView, createPropsResolver, createTemplatedElementView, createTransformer, createTransformersRegistry, endDragElementFromPanel, init, isAtomicWidget, registerElementType, registerModelExtensions, settingsTransformersRegistry, startDragElementFromPanel, styleTransformersRegistry, stylesInheritanceTransformersRegistry };
package/dist/index.d.ts CHANGED
@@ -61,6 +61,9 @@ type LegacyWindow = Window & {
61
61
  }
62
62
  ];
63
63
  $previewWrapper: JQueryElement;
64
+ helpers: {
65
+ hasPro: () => boolean;
66
+ };
64
67
  };
65
68
  };
66
69
  type JQueryStatic = (html: string) => JQueryElement;
@@ -82,6 +85,7 @@ declare class ElementView {
82
85
  length: number;
83
86
  findByIndex: (index: number) => ElementView;
84
87
  each: (callback: (view: ElementView) => void) => void;
88
+ map: <T>(callback: (view: ElementView) => T) => T[];
85
89
  };
86
90
  constructor(...args: unknown[]);
87
91
  onRender(...args: unknown[]): void;
@@ -177,7 +181,15 @@ type ToJSON<T> = {
177
181
  };
178
182
  type ContextMenuGroup = {
179
183
  name: string;
180
- actions: unknown[];
184
+ actions: ContextMenuAction[];
185
+ };
186
+ type ContextMenuAction = {
187
+ name: string;
188
+ icon: string;
189
+ title: string | (() => string);
190
+ shortcut?: string;
191
+ isEnabled: () => boolean;
192
+ callback: (_: unknown, eventData: unknown) => void;
181
193
  };
182
194
  type ReplacementSettings = {
183
195
  getSetting: (key: string) => unknown;
@@ -324,4 +336,4 @@ declare const UnknownStyleStateError: {
324
336
  isError(error: unknown): error is Error;
325
337
  };
326
338
 
327
- export { type AnyTransformer, BREAKPOINTS_SCHEMA_URI, type BackboneModel, type BackboneModelConstructor, type CreateNestedTemplatedElementTypeOptions, type CreateTemplatedElementTypeOptions, DOCUMENT_STRUCTURE_URI, type ElementModel, ElementType, ElementView, type LegacyWindow, type NamespacedRenderContext, type NestedTemplatedElementConfig, type PropsResolver, type RenderContext, type ReplacementSettings, STYLE_SCHEMA_URI, type TransformerOptions, UnknownStyleStateError, UnknownStyleTypeError, WIDGET_SCHEMA_URI, canBeNestedTemplated, createNestedTemplatedElementType, createNestedTemplatedElementView, createPropsResolver, createTemplatedElementView, createTransformer, createTransformersRegistry, endDragElementFromPanel, init, isAtomicWidget, registerElementType, registerModelExtensions, settingsTransformersRegistry, startDragElementFromPanel, styleTransformersRegistry, stylesInheritanceTransformersRegistry };
339
+ export { type AnyTransformer, BREAKPOINTS_SCHEMA_URI, type BackboneModel, type BackboneModelConstructor, type ContextMenuAction, type CreateNestedTemplatedElementTypeOptions, type CreateTemplatedElementTypeOptions, DOCUMENT_STRUCTURE_URI, type ElementModel, ElementType, ElementView, type LegacyWindow, type NamespacedRenderContext, type NestedTemplatedElementConfig, type PropsResolver, type RenderContext, type ReplacementSettings, STYLE_SCHEMA_URI, type TransformerOptions, UnknownStyleStateError, UnknownStyleTypeError, WIDGET_SCHEMA_URI, canBeNestedTemplated, createNestedTemplatedElementType, createNestedTemplatedElementView, createPropsResolver, createTemplatedElementView, createTransformer, createTransformersRegistry, endDragElementFromPanel, init, isAtomicWidget, registerElementType, registerModelExtensions, settingsTransformersRegistry, startDragElementFromPanel, styleTransformersRegistry, stylesInheritanceTransformersRegistry };
package/dist/index.js CHANGED
@@ -228,7 +228,6 @@ The css string must follow standard CSS syntax, with properties and values separ
228
228
 
229
229
  // src/init.tsx
230
230
  var import_editor = require("@elementor/editor");
231
- var import_editor_interactions2 = require("@elementor/editor-interactions");
232
231
  var import_editor_mcp3 = require("@elementor/editor-mcp");
233
232
 
234
233
  // src/components/classes-rename.tsx
@@ -830,7 +829,15 @@ var SELECTORS_MAP = {
830
829
  };
831
830
  function createStylesRenderer({ resolve, breakpoints, selectorPrefix = "" }) {
832
831
  return async ({ styles, signal }) => {
833
- const stylesCssPromises = styles.map(async (style) => {
832
+ const seenIds = /* @__PURE__ */ new Set();
833
+ const uniqueStyles = styles.filter((style) => {
834
+ if (seenIds.has(style.id)) {
835
+ return false;
836
+ }
837
+ seenIds.add(style.id);
838
+ return true;
839
+ });
840
+ const stylesCssPromises = uniqueStyles.map(async (style) => {
834
841
  const variantCssPromises = Object.values(style.variants).map(async (variant) => {
835
842
  const css = await propsToCss({ props: variant.props, resolve, signal });
836
843
  const customCss = customCssToString(variant.custom_css);
@@ -912,15 +919,23 @@ function useStyleRenderer(resolve) {
912
919
  function useStyleItems() {
913
920
  const resolve = useStylePropResolver();
914
921
  const renderStyles = useStyleRenderer(resolve);
922
+ const breakpoints = (0, import_editor_responsive2.useBreakpoints)();
915
923
  const [styleItems, setStyleItems] = (0, import_react10.useState)({});
924
+ const styleItemsCacheRef = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
916
925
  const providerAndSubscribers = (0, import_react10.useMemo)(() => {
917
926
  return import_editor_styles_repository2.stylesRepository.getProviders().map((provider) => {
927
+ const providerKey = provider.getKey();
928
+ if (!styleItemsCacheRef.current.has(providerKey)) {
929
+ styleItemsCacheRef.current.set(providerKey, { orderedIds: [], itemsById: /* @__PURE__ */ new Map() });
930
+ }
931
+ const cache = styleItemsCacheRef.current.get(providerKey);
918
932
  return {
919
933
  provider,
920
934
  subscriber: createProviderSubscriber2({
921
935
  provider,
922
936
  renderStyles,
923
- setStyleItems
937
+ setStyleItems,
938
+ cache
924
939
  })
925
940
  };
926
941
  });
@@ -939,20 +954,19 @@ function useStyleItems() {
939
954
  await Promise.all(promises);
940
955
  });
941
956
  });
942
- const breakpointsOrder = (0, import_editor_responsive2.getBreakpoints)().map((breakpoint) => breakpoint.id);
957
+ const breakpointSorter = (0, import_react10.useMemo)(
958
+ () => createBreakpointSorter(breakpoints.map((breakpoint) => breakpoint.id)),
959
+ [breakpoints]
960
+ );
943
961
  return (0, import_react10.useMemo)(
944
- () => Object.values(styleItems).sort(sortByProviderPriority2).flatMap(({ items }) => items).sort(sortByStateType).sort(sortByBreakpoint(breakpointsOrder)),
945
- // eslint-disable-next-line react-hooks/exhaustive-deps
946
- [styleItems, breakpointsOrder.join("-")]
962
+ () => Object.values(styleItems).sort(prioritySorter).flatMap(({ items }) => items).sort(stateSorter).sort(breakpointSorter),
963
+ [styleItems, breakpointSorter]
947
964
  );
948
965
  }
949
- function sortByProviderPriority2({ provider: providerA }, { provider: providerB }) {
966
+ function prioritySorter({ provider: providerA }, { provider: providerB }) {
950
967
  return providerA.priority - providerB.priority;
951
968
  }
952
- function sortByBreakpoint(breakpointsOrder) {
953
- return ({ breakpoint: breakpointA }, { breakpoint: breakpointB }) => breakpointsOrder.indexOf(breakpointA) - breakpointsOrder.indexOf(breakpointB);
954
- }
955
- function sortByStateType({ state: stateA }, { state: stateB }) {
969
+ function stateSorter({ state: stateA }, { state: stateB }) {
956
970
  if ((0, import_editor_styles4.isClassState)(stateA) && !(0, import_editor_styles4.isClassState)(stateB)) {
957
971
  return -1;
958
972
  }
@@ -961,18 +975,18 @@ function sortByStateType({ state: stateA }, { state: stateB }) {
961
975
  }
962
976
  return 0;
963
977
  }
964
- function createProviderSubscriber2({ provider, renderStyles, setStyleItems }) {
978
+ function createBreakpointSorter(breakpointsOrder) {
979
+ return ({ breakpoint: breakpointA }, { breakpoint: breakpointB }) => breakpointsOrder.indexOf(breakpointA) - breakpointsOrder.indexOf(breakpointB);
980
+ }
981
+ function createProviderSubscriber2({ provider, renderStyles, setStyleItems, cache }) {
965
982
  return abortPreviousRuns(
966
- (abortController) => signalizedProcess(abortController.signal).then((_, signal) => {
967
- const styles = provider.actions.all().map((__8, index, items) => {
968
- const lastPosition = items.length - 1;
969
- const style = items[lastPosition - index];
970
- return {
971
- ...style,
972
- cssName: provider.actions.resolveCssName(style.id)
973
- };
974
- });
975
- return renderStyles({ styles: breakToBreakpoints(styles), signal });
983
+ (abortController, previous, current) => signalizedProcess(abortController.signal).then((_, signal) => {
984
+ const hasDiffInfo = current !== void 0 && previous !== void 0;
985
+ const hasCache = cache.orderedIds.length > 0;
986
+ if (hasDiffInfo && hasCache) {
987
+ return updateItems(previous, current, signal);
988
+ }
989
+ return createItems(signal);
976
990
  }).then((items) => {
977
991
  setStyleItems((prev) => ({
978
992
  ...prev,
@@ -980,6 +994,34 @@ function createProviderSubscriber2({ provider, renderStyles, setStyleItems }) {
980
994
  }));
981
995
  }).execute()
982
996
  );
997
+ async function updateItems(previous, current, signal) {
998
+ const changedIds = getChangedStyleIds(previous, current);
999
+ cache.orderedIds = provider.actions.all().map((style) => style.id).reverse();
1000
+ if (changedIds.length > 0) {
1001
+ const changedStyles = changedIds.map((id) => provider.actions.get(id)).filter((style) => !!style).map((style) => ({
1002
+ ...style,
1003
+ cssName: provider.actions.resolveCssName(style.id)
1004
+ }));
1005
+ return renderStyles({ styles: breakToBreakpoints(changedStyles), signal }).then((rendered) => {
1006
+ updateCacheItems(cache, rendered);
1007
+ return getOrderedItems(cache);
1008
+ });
1009
+ }
1010
+ return getOrderedItems(cache);
1011
+ }
1012
+ async function createItems(signal) {
1013
+ const allStyles = provider.actions.all();
1014
+ const styles = allStyles.reverse().map((style) => {
1015
+ return {
1016
+ ...style,
1017
+ cssName: provider.actions.resolveCssName(style.id)
1018
+ };
1019
+ });
1020
+ return renderStyles({ styles: breakToBreakpoints(styles), signal }).then((rendered) => {
1021
+ rebuildCache(cache, allStyles, rendered);
1022
+ return rendered;
1023
+ });
1024
+ }
983
1025
  function breakToBreakpoints(styles) {
984
1026
  return Object.values(
985
1027
  styles.reduce(
@@ -1004,6 +1046,44 @@ function createProviderSubscriber2({ provider, renderStyles, setStyleItems }) {
1004
1046
  ).flatMap((breakpointMap) => Object.values(breakpointMap));
1005
1047
  }
1006
1048
  }
1049
+ function getChangedStyleIds(previous, current) {
1050
+ const changedIds = [];
1051
+ for (const id of Object.keys(current)) {
1052
+ const currentStyle = current[id];
1053
+ const previousStyle = previous[id];
1054
+ if (!previousStyle || currentStyle !== previousStyle) {
1055
+ changedIds.push(id);
1056
+ }
1057
+ }
1058
+ return changedIds;
1059
+ }
1060
+ function getOrderedItems(cache) {
1061
+ return cache.orderedIds.map((id) => cache.itemsById.get(id)).filter((items) => items !== void 0).flat();
1062
+ }
1063
+ function updateCacheItems(cache, changedItems) {
1064
+ for (const item of changedItems) {
1065
+ const existing = cache.itemsById.get(item.id);
1066
+ if (existing) {
1067
+ const idx = existing.findIndex((e) => e.breakpoint === item.breakpoint && e.state === item.state);
1068
+ if (idx >= 0) {
1069
+ existing[idx] = item;
1070
+ } else {
1071
+ existing.push(item);
1072
+ }
1073
+ } else {
1074
+ cache.itemsById.set(item.id, [item]);
1075
+ }
1076
+ }
1077
+ }
1078
+ function rebuildCache(cache, allStyles, items) {
1079
+ cache.orderedIds = allStyles.map((style) => style.id).reverse();
1080
+ cache.itemsById.clear();
1081
+ for (const item of items) {
1082
+ const existing = cache.itemsById.get(item.id) || [];
1083
+ existing.push(item);
1084
+ cache.itemsById.set(item.id, existing);
1085
+ }
1086
+ }
1007
1087
 
1008
1088
  // src/components/style-renderer.tsx
1009
1089
  function StyleRenderer() {
@@ -1013,11 +1093,29 @@ function StyleRenderer() {
1013
1093
  if (!container) {
1014
1094
  return null;
1015
1095
  }
1016
- return /* @__PURE__ */ React4.createElement(import_ui3.Portal, { container }, styleItems.map((item, i) => /* @__PURE__ */ React4.createElement("style", { key: `${item.id}-${i}-${item.breakpoint}` }, item.value)), linksAttrs.map((attrs) => /* @__PURE__ */ React4.createElement("link", { ...attrs, key: attrs.id })));
1096
+ return /* @__PURE__ */ React4.createElement(import_ui3.Portal, { container }, filterUniqueStyleDefinitions(styleItems).map((item) => /* @__PURE__ */ React4.createElement("style", { key: `${item.id}-${item.breakpoint}-${item.state ?? "normal"}` }, item.value)), linksAttrs.map((attrs) => /* @__PURE__ */ React4.createElement("link", { ...attrs, key: attrs.id })));
1017
1097
  }
1018
1098
  function usePortalContainer2() {
1019
1099
  return (0, import_editor_v1_adapters8.__privateUseListenTo)((0, import_editor_v1_adapters8.commandEndEvent)("editor/documents/attach-preview"), () => (0, import_editor_v1_adapters8.getCanvasIframeDocument)()?.head);
1020
1100
  }
1101
+ function filterUniqueStyleDefinitions(styleItems) {
1102
+ const seen = /* @__PURE__ */ new Map();
1103
+ return styleItems.filter((style) => {
1104
+ const existingStyle = seen.get(style.id);
1105
+ if (existingStyle) {
1106
+ const existingStyleVariant = existingStyle.find(
1107
+ (s) => s.breakpoint === style.breakpoint && s.state === style.state
1108
+ );
1109
+ if (existingStyleVariant) {
1110
+ return false;
1111
+ }
1112
+ existingStyle.push(style);
1113
+ return true;
1114
+ }
1115
+ seen.set(style.id, [style]);
1116
+ return true;
1117
+ });
1118
+ }
1021
1119
 
1022
1120
  // src/form-structure/enforce-form-ancestor-commands.ts
1023
1121
  var import_editor_notifications = require("@elementor/editor-notifications");
@@ -1306,9 +1404,23 @@ var plainTransformer = createTransformer((value) => {
1306
1404
  return value;
1307
1405
  });
1308
1406
 
1407
+ // src/transformers/shared/video-src-transformer.ts
1408
+ var import_wp_media2 = require("@elementor/wp-media");
1409
+ var videoSrcTransformer = createTransformer(async (value) => {
1410
+ const { id, url } = value;
1411
+ if (!id) {
1412
+ return { id: null, url };
1413
+ }
1414
+ const attachment = await (0, import_wp_media2.getMediaAttachment)({ id });
1415
+ return {
1416
+ id,
1417
+ url: attachment?.url ?? url
1418
+ };
1419
+ });
1420
+
1309
1421
  // src/init-settings-transformers.ts
1310
1422
  function initSettingsTransformers() {
1311
- settingsTransformersRegistry.register("classes", createClassesTransformer()).register("link", linkTransformer).register("query", queryTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).register("attributes", attributesTransformer).register("date-time", dateTimeTransformer).register("html-v2", htmlV2Transformer).register("html-v3", htmlV3Transformer).registerFallback(plainTransformer);
1423
+ settingsTransformersRegistry.register("classes", createClassesTransformer()).register("link", linkTransformer).register("query", queryTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).register("video-src", videoSrcTransformer).register("attributes", attributesTransformer).register("date-time", dateTimeTransformer).register("html-v2", htmlV2Transformer).register("html-v3", htmlV3Transformer).registerFallback(plainTransformer);
1312
1424
  }
1313
1425
 
1314
1426
  // src/transformers/styles/background-color-overlay-transformer.ts
@@ -4364,7 +4476,6 @@ function init() {
4364
4476
  initViewReplacements();
4365
4477
  initLegacyViews();
4366
4478
  initSettingsTransformers();
4367
- (0, import_editor_interactions2.init)();
4368
4479
  (0, import_editor.injectIntoTop)({
4369
4480
  id: "elements-overlays",
4370
4481
  component: ElementsOverlays
package/dist/index.mjs CHANGED
@@ -173,7 +173,6 @@ The css string must follow standard CSS syntax, with properties and values separ
173
173
 
174
174
  // src/init.tsx
175
175
  import { injectIntoLogic, injectIntoTop } from "@elementor/editor";
176
- import { init as initInteractionsRepository } from "@elementor/editor-interactions";
177
176
  import { getMCPByDomain } from "@elementor/editor-mcp";
178
177
 
179
178
  // src/components/classes-rename.tsx
@@ -587,8 +586,8 @@ function getLinkAttrs(el) {
587
586
  }
588
587
 
589
588
  // src/hooks/use-style-items.ts
590
- import { useEffect as useEffect6, useMemo as useMemo4, useState as useState3 } from "react";
591
- import { getBreakpoints } from "@elementor/editor-responsive";
589
+ import { useEffect as useEffect6, useMemo as useMemo4, useRef as useRef2, useState as useState3 } from "react";
590
+ import { useBreakpoints } from "@elementor/editor-responsive";
592
591
  import { isClassState } from "@elementor/editor-styles";
593
592
  import { stylesRepository as stylesRepository2 } from "@elementor/editor-styles-repository";
594
593
  import { registerDataHook as registerDataHook2 } from "@elementor/editor-v1-adapters";
@@ -796,7 +795,15 @@ var SELECTORS_MAP = {
796
795
  };
797
796
  function createStylesRenderer({ resolve, breakpoints, selectorPrefix = "" }) {
798
797
  return async ({ styles, signal }) => {
799
- const stylesCssPromises = styles.map(async (style) => {
798
+ const seenIds = /* @__PURE__ */ new Set();
799
+ const uniqueStyles = styles.filter((style) => {
800
+ if (seenIds.has(style.id)) {
801
+ return false;
802
+ }
803
+ seenIds.add(style.id);
804
+ return true;
805
+ });
806
+ const stylesCssPromises = uniqueStyles.map(async (style) => {
800
807
  const variantCssPromises = Object.values(style.variants).map(async (variant) => {
801
808
  const css = await propsToCss({ props: variant.props, resolve, signal });
802
809
  const customCss = customCssToString(variant.custom_css);
@@ -878,15 +885,23 @@ function useStyleRenderer(resolve) {
878
885
  function useStyleItems() {
879
886
  const resolve = useStylePropResolver();
880
887
  const renderStyles = useStyleRenderer(resolve);
888
+ const breakpoints = useBreakpoints();
881
889
  const [styleItems, setStyleItems] = useState3({});
890
+ const styleItemsCacheRef = useRef2(/* @__PURE__ */ new Map());
882
891
  const providerAndSubscribers = useMemo4(() => {
883
892
  return stylesRepository2.getProviders().map((provider) => {
893
+ const providerKey = provider.getKey();
894
+ if (!styleItemsCacheRef.current.has(providerKey)) {
895
+ styleItemsCacheRef.current.set(providerKey, { orderedIds: [], itemsById: /* @__PURE__ */ new Map() });
896
+ }
897
+ const cache = styleItemsCacheRef.current.get(providerKey);
884
898
  return {
885
899
  provider,
886
900
  subscriber: createProviderSubscriber2({
887
901
  provider,
888
902
  renderStyles,
889
- setStyleItems
903
+ setStyleItems,
904
+ cache
890
905
  })
891
906
  };
892
907
  });
@@ -905,20 +920,19 @@ function useStyleItems() {
905
920
  await Promise.all(promises);
906
921
  });
907
922
  });
908
- const breakpointsOrder = getBreakpoints().map((breakpoint) => breakpoint.id);
923
+ const breakpointSorter = useMemo4(
924
+ () => createBreakpointSorter(breakpoints.map((breakpoint) => breakpoint.id)),
925
+ [breakpoints]
926
+ );
909
927
  return useMemo4(
910
- () => Object.values(styleItems).sort(sortByProviderPriority2).flatMap(({ items }) => items).sort(sortByStateType).sort(sortByBreakpoint(breakpointsOrder)),
911
- // eslint-disable-next-line react-hooks/exhaustive-deps
912
- [styleItems, breakpointsOrder.join("-")]
928
+ () => Object.values(styleItems).sort(prioritySorter).flatMap(({ items }) => items).sort(stateSorter).sort(breakpointSorter),
929
+ [styleItems, breakpointSorter]
913
930
  );
914
931
  }
915
- function sortByProviderPriority2({ provider: providerA }, { provider: providerB }) {
932
+ function prioritySorter({ provider: providerA }, { provider: providerB }) {
916
933
  return providerA.priority - providerB.priority;
917
934
  }
918
- function sortByBreakpoint(breakpointsOrder) {
919
- return ({ breakpoint: breakpointA }, { breakpoint: breakpointB }) => breakpointsOrder.indexOf(breakpointA) - breakpointsOrder.indexOf(breakpointB);
920
- }
921
- function sortByStateType({ state: stateA }, { state: stateB }) {
935
+ function stateSorter({ state: stateA }, { state: stateB }) {
922
936
  if (isClassState(stateA) && !isClassState(stateB)) {
923
937
  return -1;
924
938
  }
@@ -927,18 +941,18 @@ function sortByStateType({ state: stateA }, { state: stateB }) {
927
941
  }
928
942
  return 0;
929
943
  }
930
- function createProviderSubscriber2({ provider, renderStyles, setStyleItems }) {
944
+ function createBreakpointSorter(breakpointsOrder) {
945
+ return ({ breakpoint: breakpointA }, { breakpoint: breakpointB }) => breakpointsOrder.indexOf(breakpointA) - breakpointsOrder.indexOf(breakpointB);
946
+ }
947
+ function createProviderSubscriber2({ provider, renderStyles, setStyleItems, cache }) {
931
948
  return abortPreviousRuns(
932
- (abortController) => signalizedProcess(abortController.signal).then((_, signal) => {
933
- const styles = provider.actions.all().map((__8, index, items) => {
934
- const lastPosition = items.length - 1;
935
- const style = items[lastPosition - index];
936
- return {
937
- ...style,
938
- cssName: provider.actions.resolveCssName(style.id)
939
- };
940
- });
941
- return renderStyles({ styles: breakToBreakpoints(styles), signal });
949
+ (abortController, previous, current) => signalizedProcess(abortController.signal).then((_, signal) => {
950
+ const hasDiffInfo = current !== void 0 && previous !== void 0;
951
+ const hasCache = cache.orderedIds.length > 0;
952
+ if (hasDiffInfo && hasCache) {
953
+ return updateItems(previous, current, signal);
954
+ }
955
+ return createItems(signal);
942
956
  }).then((items) => {
943
957
  setStyleItems((prev) => ({
944
958
  ...prev,
@@ -946,6 +960,34 @@ function createProviderSubscriber2({ provider, renderStyles, setStyleItems }) {
946
960
  }));
947
961
  }).execute()
948
962
  );
963
+ async function updateItems(previous, current, signal) {
964
+ const changedIds = getChangedStyleIds(previous, current);
965
+ cache.orderedIds = provider.actions.all().map((style) => style.id).reverse();
966
+ if (changedIds.length > 0) {
967
+ const changedStyles = changedIds.map((id) => provider.actions.get(id)).filter((style) => !!style).map((style) => ({
968
+ ...style,
969
+ cssName: provider.actions.resolveCssName(style.id)
970
+ }));
971
+ return renderStyles({ styles: breakToBreakpoints(changedStyles), signal }).then((rendered) => {
972
+ updateCacheItems(cache, rendered);
973
+ return getOrderedItems(cache);
974
+ });
975
+ }
976
+ return getOrderedItems(cache);
977
+ }
978
+ async function createItems(signal) {
979
+ const allStyles = provider.actions.all();
980
+ const styles = allStyles.reverse().map((style) => {
981
+ return {
982
+ ...style,
983
+ cssName: provider.actions.resolveCssName(style.id)
984
+ };
985
+ });
986
+ return renderStyles({ styles: breakToBreakpoints(styles), signal }).then((rendered) => {
987
+ rebuildCache(cache, allStyles, rendered);
988
+ return rendered;
989
+ });
990
+ }
949
991
  function breakToBreakpoints(styles) {
950
992
  return Object.values(
951
993
  styles.reduce(
@@ -970,6 +1012,44 @@ function createProviderSubscriber2({ provider, renderStyles, setStyleItems }) {
970
1012
  ).flatMap((breakpointMap) => Object.values(breakpointMap));
971
1013
  }
972
1014
  }
1015
+ function getChangedStyleIds(previous, current) {
1016
+ const changedIds = [];
1017
+ for (const id of Object.keys(current)) {
1018
+ const currentStyle = current[id];
1019
+ const previousStyle = previous[id];
1020
+ if (!previousStyle || currentStyle !== previousStyle) {
1021
+ changedIds.push(id);
1022
+ }
1023
+ }
1024
+ return changedIds;
1025
+ }
1026
+ function getOrderedItems(cache) {
1027
+ return cache.orderedIds.map((id) => cache.itemsById.get(id)).filter((items) => items !== void 0).flat();
1028
+ }
1029
+ function updateCacheItems(cache, changedItems) {
1030
+ for (const item of changedItems) {
1031
+ const existing = cache.itemsById.get(item.id);
1032
+ if (existing) {
1033
+ const idx = existing.findIndex((e) => e.breakpoint === item.breakpoint && e.state === item.state);
1034
+ if (idx >= 0) {
1035
+ existing[idx] = item;
1036
+ } else {
1037
+ existing.push(item);
1038
+ }
1039
+ } else {
1040
+ cache.itemsById.set(item.id, [item]);
1041
+ }
1042
+ }
1043
+ }
1044
+ function rebuildCache(cache, allStyles, items) {
1045
+ cache.orderedIds = allStyles.map((style) => style.id).reverse();
1046
+ cache.itemsById.clear();
1047
+ for (const item of items) {
1048
+ const existing = cache.itemsById.get(item.id) || [];
1049
+ existing.push(item);
1050
+ cache.itemsById.set(item.id, existing);
1051
+ }
1052
+ }
973
1053
 
974
1054
  // src/components/style-renderer.tsx
975
1055
  function StyleRenderer() {
@@ -979,11 +1059,29 @@ function StyleRenderer() {
979
1059
  if (!container) {
980
1060
  return null;
981
1061
  }
982
- return /* @__PURE__ */ React4.createElement(Portal2, { container }, styleItems.map((item, i) => /* @__PURE__ */ React4.createElement("style", { key: `${item.id}-${i}-${item.breakpoint}` }, item.value)), linksAttrs.map((attrs) => /* @__PURE__ */ React4.createElement("link", { ...attrs, key: attrs.id })));
1062
+ return /* @__PURE__ */ React4.createElement(Portal2, { container }, filterUniqueStyleDefinitions(styleItems).map((item) => /* @__PURE__ */ React4.createElement("style", { key: `${item.id}-${item.breakpoint}-${item.state ?? "normal"}` }, item.value)), linksAttrs.map((attrs) => /* @__PURE__ */ React4.createElement("link", { ...attrs, key: attrs.id })));
983
1063
  }
984
1064
  function usePortalContainer2() {
985
1065
  return useListenTo4(commandEndEvent3("editor/documents/attach-preview"), () => getCanvasIframeDocument3()?.head);
986
1066
  }
1067
+ function filterUniqueStyleDefinitions(styleItems) {
1068
+ const seen = /* @__PURE__ */ new Map();
1069
+ return styleItems.filter((style) => {
1070
+ const existingStyle = seen.get(style.id);
1071
+ if (existingStyle) {
1072
+ const existingStyleVariant = existingStyle.find(
1073
+ (s) => s.breakpoint === style.breakpoint && s.state === style.state
1074
+ );
1075
+ if (existingStyleVariant) {
1076
+ return false;
1077
+ }
1078
+ existingStyle.push(style);
1079
+ return true;
1080
+ }
1081
+ seen.set(style.id, [style]);
1082
+ return true;
1083
+ });
1084
+ }
987
1085
 
988
1086
  // src/form-structure/enforce-form-ancestor-commands.ts
989
1087
  import { notify } from "@elementor/editor-notifications";
@@ -1272,9 +1370,23 @@ var plainTransformer = createTransformer((value) => {
1272
1370
  return value;
1273
1371
  });
1274
1372
 
1373
+ // src/transformers/shared/video-src-transformer.ts
1374
+ import { getMediaAttachment as getMediaAttachment2 } from "@elementor/wp-media";
1375
+ var videoSrcTransformer = createTransformer(async (value) => {
1376
+ const { id, url } = value;
1377
+ if (!id) {
1378
+ return { id: null, url };
1379
+ }
1380
+ const attachment = await getMediaAttachment2({ id });
1381
+ return {
1382
+ id,
1383
+ url: attachment?.url ?? url
1384
+ };
1385
+ });
1386
+
1275
1387
  // src/init-settings-transformers.ts
1276
1388
  function initSettingsTransformers() {
1277
- settingsTransformersRegistry.register("classes", createClassesTransformer()).register("link", linkTransformer).register("query", queryTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).register("attributes", attributesTransformer).register("date-time", dateTimeTransformer).register("html-v2", htmlV2Transformer).register("html-v3", htmlV3Transformer).registerFallback(plainTransformer);
1389
+ settingsTransformersRegistry.register("classes", createClassesTransformer()).register("link", linkTransformer).register("query", queryTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).register("video-src", videoSrcTransformer).register("attributes", attributesTransformer).register("date-time", dateTimeTransformer).register("html-v2", htmlV2Transformer).register("html-v3", htmlV3Transformer).registerFallback(plainTransformer);
1278
1390
  }
1279
1391
 
1280
1392
  // src/transformers/styles/background-color-overlay-transformer.ts
@@ -4367,7 +4479,6 @@ function init() {
4367
4479
  initViewReplacements();
4368
4480
  initLegacyViews();
4369
4481
  initSettingsTransformers();
4370
- initInteractionsRepository();
4371
4482
  injectIntoTop({
4372
4483
  id: "elements-overlays",
4373
4484
  component: ElementsOverlays
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.0.0-607",
4
+ "version": "4.0.0-619",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -37,24 +37,24 @@
37
37
  "react-dom": "^18.3.1"
38
38
  },
39
39
  "dependencies": {
40
- "@elementor/editor": "4.0.0-607",
41
- "@elementor/editor-controls": "4.0.0-607",
42
- "@elementor/editor-documents": "4.0.0-607",
43
- "@elementor/editor-elements": "4.0.0-607",
44
- "@elementor/editor-interactions": "4.0.0-607",
45
- "@elementor/editor-mcp": "4.0.0-607",
46
- "@elementor/editor-notifications": "4.0.0-607",
47
- "@elementor/editor-props": "4.0.0-607",
48
- "@elementor/editor-responsive": "4.0.0-607",
49
- "@elementor/editor-styles": "4.0.0-607",
50
- "@elementor/editor-styles-repository": "4.0.0-607",
51
- "@elementor/editor-ui": "4.0.0-607",
52
- "@elementor/editor-v1-adapters": "4.0.0-607",
53
- "@elementor/schema": "4.0.0-607",
54
- "@elementor/twing": "4.0.0-607",
40
+ "@elementor/editor": "4.0.0-619",
41
+ "@elementor/editor-controls": "4.0.0-619",
42
+ "@elementor/editor-documents": "4.0.0-619",
43
+ "@elementor/editor-elements": "4.0.0-619",
44
+ "@elementor/editor-interactions": "4.0.0-619",
45
+ "@elementor/editor-mcp": "4.0.0-619",
46
+ "@elementor/editor-notifications": "4.0.0-619",
47
+ "@elementor/editor-props": "4.0.0-619",
48
+ "@elementor/editor-responsive": "4.0.0-619",
49
+ "@elementor/editor-styles": "4.0.0-619",
50
+ "@elementor/editor-styles-repository": "4.0.0-619",
51
+ "@elementor/editor-ui": "4.0.0-619",
52
+ "@elementor/editor-v1-adapters": "4.0.0-619",
53
+ "@elementor/schema": "4.0.0-619",
54
+ "@elementor/twing": "4.0.0-619",
55
55
  "@elementor/ui": "1.36.17",
56
- "@elementor/utils": "4.0.0-607",
57
- "@elementor/wp-media": "4.0.0-607",
56
+ "@elementor/utils": "4.0.0-619",
57
+ "@elementor/wp-media": "4.0.0-619",
58
58
  "@floating-ui/react": "^0.27.5",
59
59
  "@wordpress/i18n": "^5.13.0"
60
60
  },