@elementor/editor-canvas 4.4.0-1145 → 4.4.0-1147

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
@@ -2330,7 +2330,6 @@ var svgSrcTransformer = createTransformer(async (value, { signal }) => {
2330
2330
  var EMPTY_ICON_RESULT = { html: null, url: null };
2331
2331
  var ICON_SVG_SIZE = "100%";
2332
2332
  var ICON_SVG_OVERFLOW = "visible";
2333
- var FONT_AWESOME_LIBRARY_PREFIX = "fa-";
2334
2333
  var EICONS_LIBRARY = "eicons";
2335
2334
  var DEFAULT_SVG_RELATIVE_PATH = "images/default-svg.svg";
2336
2335
  var iconTransformer = createTransformer(async (value, { signal }) => {
@@ -2343,7 +2342,7 @@ var iconTransformer = createTransformer(async (value, { signal }) => {
2343
2342
  if (fontAwesomeHtml) {
2344
2343
  return { html: fontAwesomeHtml, url: null };
2345
2344
  }
2346
- if (library.startsWith(FONT_AWESOME_LIBRARY_PREFIX) || EICONS_LIBRARY === library) {
2345
+ if (EICONS_LIBRARY === library) {
2347
2346
  return EMPTY_ICON_RESULT;
2348
2347
  }
2349
2348
  const providerHtml = await resolveProviderSvg(library, iconValue, signal);
@@ -4345,11 +4344,6 @@ function initTabsModelExtensions() {
4345
4344
  // src/mcp/canvas-mcp.ts
4346
4345
  var import_editor_props8 = require("@elementor/editor-props");
4347
4346
 
4348
- // src/mcp/icon-library-experiment.ts
4349
- var import_editor_v1_adapters18 = require("@elementor/editor-v1-adapters");
4350
- var ICON_LIBRARY_EXPERIMENT = "e_svg_library";
4351
- var isIconLibraryActive = () => (0, import_editor_v1_adapters18.isExperimentActive)(ICON_LIBRARY_EXPERIMENT);
4352
-
4353
4347
  // src/mcp/resources/available-widgets-resource.ts
4354
4348
  var import_http_client3 = require("@elementor/http-client");
4355
4349
  var MCP_PROXY_URL2 = "elementor/v1/mcp-proxy";
@@ -4426,7 +4420,7 @@ var initBestPracticesResource = (reg) => {
4426
4420
 
4427
4421
  // src/mcp/resources/document-structure-resource.ts
4428
4422
  var import_editor_elements10 = require("@elementor/editor-elements");
4429
- var import_editor_v1_adapters19 = require("@elementor/editor-v1-adapters");
4423
+ var import_editor_v1_adapters18 = require("@elementor/editor-v1-adapters");
4430
4424
  var DOCUMENT_STRUCTURE_URI = "elementor://document/structure";
4431
4425
  var initDocumentStructureResource = (reg) => {
4432
4426
  const { resource, sendResourceUpdated } = reg;
@@ -4439,15 +4433,15 @@ var initDocumentStructureResource = (reg) => {
4439
4433
  sendResourceUpdated({ uri: DOCUMENT_STRUCTURE_URI });
4440
4434
  }
4441
4435
  };
4442
- (0, import_editor_v1_adapters19.__privateListenTo)(
4436
+ (0, import_editor_v1_adapters18.__privateListenTo)(
4443
4437
  [
4444
- (0, import_editor_v1_adapters19.commandEndEvent)("document/elements/create"),
4445
- (0, import_editor_v1_adapters19.commandEndEvent)("document/elements/delete"),
4446
- (0, import_editor_v1_adapters19.commandEndEvent)("document/elements/move"),
4447
- (0, import_editor_v1_adapters19.commandEndEvent)("document/elements/copy"),
4448
- (0, import_editor_v1_adapters19.commandEndEvent)("document/elements/paste"),
4449
- (0, import_editor_v1_adapters19.commandEndEvent)("editor/documents/attach-preview"),
4450
- (0, import_editor_v1_adapters19.commandEndEvent)("editor/documents/switch")
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")
4451
4445
  ],
4452
4446
  updateDocumentStructure
4453
4447
  );
@@ -4550,7 +4544,7 @@ var initDynamicTagsResource = (reg) => {
4550
4544
  };
4551
4545
 
4552
4546
  // src/mcp/resources/editor-state-resource.ts
4553
- var import_editor_v1_adapters20 = require("@elementor/editor-v1-adapters");
4547
+ var import_editor_v1_adapters19 = require("@elementor/editor-v1-adapters");
4554
4548
  var CURRENTLY_VIEWED_SCREEN = "The user is currently viewing the Elementor editor";
4555
4549
  var PAGE_CONTENT_CHARACTER_LIMIT = 500;
4556
4550
  var PREVIEW_TEXT_NODE_MIN_LENGTH = 2;
@@ -4571,8 +4565,8 @@ var initEditorStateResource = (reg) => {
4571
4565
  lastSerializedState = serialized;
4572
4566
  sendResourceUpdated({ uri: EDITOR_STATE_URI });
4573
4567
  };
4574
- (0, import_editor_v1_adapters20.__privateListenTo)(
4575
- [(0, import_editor_v1_adapters20.commandEndEvent)("editor/documents/switch"), (0, import_editor_v1_adapters20.commandEndEvent)("editor/documents/attach-preview")],
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")],
4576
4570
  notifyIfChanged
4577
4571
  );
4578
4572
  lastSerializedState = JSON.stringify(buildState());
@@ -4646,7 +4640,7 @@ function getPageTitle() {
4646
4640
  }
4647
4641
 
4648
4642
  // src/mcp/resources/general-context-resource.ts
4649
- var import_editor_v1_adapters21 = require("@elementor/editor-v1-adapters");
4643
+ var import_editor_v1_adapters20 = require("@elementor/editor-v1-adapters");
4650
4644
  var GENERAL_CONTEXT_URI = "elementor://context/general";
4651
4645
  var initGeneralContextResource = (reg) => {
4652
4646
  const { resource, sendResourceUpdated } = reg;
@@ -4707,11 +4701,11 @@ var initGeneralContextResource = (reg) => {
4707
4701
  };
4708
4702
  }
4709
4703
  );
4710
- (0, import_editor_v1_adapters21.__privateListenTo)(
4704
+ (0, import_editor_v1_adapters20.__privateListenTo)(
4711
4705
  [
4712
- (0, import_editor_v1_adapters21.commandEndEvent)("editor/documents/switch"),
4713
- (0, import_editor_v1_adapters21.commandEndEvent)("editor/documents/attach-preview"),
4714
- (0, import_editor_v1_adapters21.commandEndEvent)("document/elements/settings")
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")
4715
4709
  ],
4716
4710
  pushUpdateIfChanged
4717
4711
  );
@@ -4720,7 +4714,7 @@ var initGeneralContextResource = (reg) => {
4720
4714
 
4721
4715
  // src/mcp/resources/selected-element-resource.ts
4722
4716
  var import_editor_elements11 = require("@elementor/editor-elements");
4723
- var import_editor_v1_adapters22 = require("@elementor/editor-v1-adapters");
4717
+ var import_editor_v1_adapters21 = require("@elementor/editor-v1-adapters");
4724
4718
  var SELECTED_ELEMENT_URI = "elementor://context/selected-element";
4725
4719
  var initSelectedElementResource = (reg) => {
4726
4720
  const { resource, sendResourceUpdated } = reg;
@@ -4751,11 +4745,11 @@ var initSelectedElementResource = (reg) => {
4751
4745
  }
4752
4746
  publishIfChanged(readSelectionFromEditor());
4753
4747
  };
4754
- (0, import_editor_v1_adapters22.__privateListenTo)(
4748
+ (0, import_editor_v1_adapters21.__privateListenTo)(
4755
4749
  [
4756
- (0, import_editor_v1_adapters22.commandEndEvent)("document/elements/select"),
4757
- (0, import_editor_v1_adapters22.commandEndEvent)("document/elements/deselect-all"),
4758
- (0, import_editor_v1_adapters22.commandEndEvent)("document/elements/settings")
4750
+ (0, import_editor_v1_adapters21.commandEndEvent)("document/elements/select"),
4751
+ (0, import_editor_v1_adapters21.commandEndEvent)("document/elements/deselect-all"),
4752
+ (0, import_editor_v1_adapters21.commandEndEvent)("document/elements/settings")
4759
4753
  ],
4760
4754
  onCommand
4761
4755
  );
@@ -4873,7 +4867,7 @@ var import_editor_props7 = require("@elementor/editor-props");
4873
4867
  var import_editor_elements13 = require("@elementor/editor-elements");
4874
4868
  var import_editor_props6 = require("@elementor/editor-props");
4875
4869
  var import_editor_styles4 = require("@elementor/editor-styles");
4876
- var import_editor_v1_adapters24 = require("@elementor/editor-v1-adapters");
4870
+ var import_editor_v1_adapters23 = require("@elementor/editor-v1-adapters");
4877
4871
 
4878
4872
  // src/mcp/utils/merge-custom-css.ts
4879
4873
  var CUSTOM_CSS_SEPARATOR = "\n";
@@ -4942,11 +4936,11 @@ function resolveCanonicalPropKeys(elementType, props) {
4942
4936
  }
4943
4937
 
4944
4938
  // src/mcp/utils/resolve-dynamic-tag.ts
4945
- var import_editor_v1_adapters23 = require("@elementor/editor-v1-adapters");
4939
+ var import_editor_v1_adapters22 = require("@elementor/editor-v1-adapters");
4946
4940
  var DYNAMIC_PROP_TYPE_KEY = "dynamic";
4947
4941
  var OMITTED_DYNAMIC_SETTING_KEYS = ["fallback"];
4948
4942
  var getAtomicDynamicTags = () => {
4949
- const config = (0, import_editor_v1_adapters23.getElementorConfig)();
4943
+ const config = (0, import_editor_v1_adapters22.getElementorConfig)();
4950
4944
  return config.atomicDynamicTags?.tags ?? {};
4951
4945
  };
4952
4946
  var getDynamicTagNamesByCategories = (categories) => {
@@ -5147,7 +5141,7 @@ Expected Schema: ${jsonSchema}`
5147
5141
  },
5148
5142
  withHistory: false
5149
5143
  });
5150
- (0, import_editor_v1_adapters24.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
5144
+ (0, import_editor_v1_adapters23.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
5151
5145
  };
5152
5146
 
5153
5147
  // src/mcp/tools/configure-element/prompt.ts
@@ -5191,7 +5185,6 @@ Setting a Font Awesome icon on an e-svg, after resolving it with \`find-icons\`:
5191
5185
  `;
5192
5186
  var CONFIGURE_ELEMENT_GUIDE_URI = "elementor://canvas/tools/configure-element-guide";
5193
5187
  var generatePrompt = () => {
5194
- const iconLibraryActive = isIconLibraryActive();
5195
5188
  const configureElementToolPrompt = (0, import_editor_mcp2.toolPrompts)("configure-element");
5196
5189
  configureElementToolPrompt.description(`
5197
5190
  Configure an existing element on the page.
@@ -5250,7 +5243,7 @@ Put the dynamic object EXACTLY at the node whose schema offers the "dynamic" var
5250
5243
  Image example: { "$$type": "image", "value": { "src": { "$$type": "dynamic", "value": { "name": "<image tag>", "settings": { ... } } } } }
5251
5244
  Do NOT send "group" (it is resolved automatically). Use { "settings": {} } only when the tag has no settings.
5252
5245
 
5253
- ${iconLibraryActive ? ICONS_SECTION : ""}`);
5246
+ ${ICONS_SECTION}`);
5254
5247
  configureElementToolPrompt.parameter("elementId", "The ID of the element to configure. MANDATORY.");
5255
5248
  configureElementToolPrompt.parameter(
5256
5249
  "elementType",
@@ -5287,9 +5280,7 @@ ${iconLibraryActive ? ICONS_SECTION : ""}`);
5287
5280
  };
5288
5281
  \`\`\`
5289
5282
  `);
5290
- if (iconLibraryActive) {
5291
- configureElementToolPrompt.example(ICON_EXAMPLE);
5292
- }
5283
+ configureElementToolPrompt.example(ICON_EXAMPLE);
5293
5284
  configureElementToolPrompt.instruction(
5294
5285
  "The $$type property is MANDATORY for every value in propertiesToChange; it is not used in the style parameter (raw CSS only)."
5295
5286
  );
@@ -5652,9 +5643,7 @@ var initCanvasMcp = (reg) => {
5652
5643
  initGeneralContextResource(reg);
5653
5644
  initBestPracticesResource(reg);
5654
5645
  initConfigureElementTool(reg);
5655
- if (isIconLibraryActive()) {
5656
- initFindIconsTool(reg);
5657
- }
5646
+ initFindIconsTool(reg);
5658
5647
  initGetPageStructureTool(reg);
5659
5648
  initBreakpointsResource(reg);
5660
5649
  };
@@ -5758,14 +5747,14 @@ Note: The "size" property controls image resolution/loading, not visual size. Se
5758
5747
  // src/prevent-link-in-link-commands.ts
5759
5748
  var import_editor_elements15 = require("@elementor/editor-elements");
5760
5749
  var import_editor_notifications6 = require("@elementor/editor-notifications");
5761
- var import_editor_v1_adapters25 = require("@elementor/editor-v1-adapters");
5750
+ var import_editor_v1_adapters24 = require("@elementor/editor-v1-adapters");
5762
5751
  var import_i18n7 = require("@wordpress/i18n");
5763
5752
  function initLinkInLinkPrevention() {
5764
- (0, import_editor_v1_adapters25.blockCommand)({
5753
+ (0, import_editor_v1_adapters24.blockCommand)({
5765
5754
  command: "document/elements/paste",
5766
5755
  condition: blockLinkInLinkPaste
5767
5756
  });
5768
- (0, import_editor_v1_adapters25.blockCommand)({
5757
+ (0, import_editor_v1_adapters24.blockCommand)({
5769
5758
  command: "document/elements/move",
5770
5759
  condition: blockLinkInLinkMove
5771
5760
  });
@@ -5841,7 +5830,7 @@ function shouldBlock(sourceElements, targetElements) {
5841
5830
  // src/style-commands/paste-style.ts
5842
5831
  var import_editor_elements18 = require("@elementor/editor-elements");
5843
5832
  var import_editor_props10 = require("@elementor/editor-props");
5844
- var import_editor_v1_adapters27 = require("@elementor/editor-v1-adapters");
5833
+ var import_editor_v1_adapters26 = require("@elementor/editor-v1-adapters");
5845
5834
 
5846
5835
  // src/utils/command-utils.ts
5847
5836
  var import_editor_elements16 = require("@elementor/editor-elements");
@@ -5888,9 +5877,9 @@ function getTitleForContainers(containers) {
5888
5877
  // src/style-commands/undoable-actions/paste-element-style.ts
5889
5878
  var import_editor_elements17 = require("@elementor/editor-elements");
5890
5879
  var import_editor_styles_repository4 = require("@elementor/editor-styles-repository");
5891
- var import_editor_v1_adapters26 = require("@elementor/editor-v1-adapters");
5880
+ var import_editor_v1_adapters25 = require("@elementor/editor-v1-adapters");
5892
5881
  var import_i18n9 = require("@wordpress/i18n");
5893
- var undoablePasteElementStyle = () => (0, import_editor_v1_adapters26.undoable)(
5882
+ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters25.undoable)(
5894
5883
  {
5895
5884
  do: ({ containers, newStyle }) => {
5896
5885
  return containers.map((container) => {
@@ -5966,12 +5955,12 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters26.undoable)(
5966
5955
  // src/style-commands/paste-style.ts
5967
5956
  function initPasteStyleCommand() {
5968
5957
  const pasteElementStyleCommand = undoablePasteElementStyle();
5969
- (0, import_editor_v1_adapters27.blockCommand)({
5958
+ (0, import_editor_v1_adapters26.blockCommand)({
5970
5959
  command: "document/elements/paste-style",
5971
5960
  condition: hasAtomicWidgets
5972
5961
  });
5973
- (0, import_editor_v1_adapters27.__privateListenTo)(
5974
- (0, import_editor_v1_adapters27.commandStartEvent)("document/elements/paste-style"),
5962
+ (0, import_editor_v1_adapters26.__privateListenTo)(
5963
+ (0, import_editor_v1_adapters26.commandStartEvent)("document/elements/paste-style"),
5975
5964
  (e) => pasteStyles(e.args, pasteElementStyleCommand)
5976
5965
  );
5977
5966
  }
@@ -6022,14 +6011,14 @@ function pasteClasses(containers, classes) {
6022
6011
  }
6023
6012
 
6024
6013
  // src/style-commands/reset-style.ts
6025
- var import_editor_v1_adapters29 = require("@elementor/editor-v1-adapters");
6014
+ var import_editor_v1_adapters28 = require("@elementor/editor-v1-adapters");
6026
6015
 
6027
6016
  // src/style-commands/undoable-actions/reset-element-style.ts
6028
6017
  var import_editor_elements19 = require("@elementor/editor-elements");
6029
6018
  var import_editor_styles_repository5 = require("@elementor/editor-styles-repository");
6030
- var import_editor_v1_adapters28 = require("@elementor/editor-v1-adapters");
6019
+ var import_editor_v1_adapters27 = require("@elementor/editor-v1-adapters");
6031
6020
  var import_i18n10 = require("@wordpress/i18n");
6032
- var undoableResetElementStyle = () => (0, import_editor_v1_adapters28.undoable)(
6021
+ var undoableResetElementStyle = () => (0, import_editor_v1_adapters27.undoable)(
6033
6022
  {
6034
6023
  do: ({ containers }) => {
6035
6024
  return containers.map((container) => {
@@ -6073,12 +6062,12 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters28.undoable)(
6073
6062
  // src/style-commands/reset-style.ts
6074
6063
  function initResetStyleCommand() {
6075
6064
  const resetElementStyles = undoableResetElementStyle();
6076
- (0, import_editor_v1_adapters29.blockCommand)({
6065
+ (0, import_editor_v1_adapters28.blockCommand)({
6077
6066
  command: "document/elements/reset-style",
6078
6067
  condition: hasAtomicWidgets
6079
6068
  });
6080
- (0, import_editor_v1_adapters29.__privateListenTo)(
6081
- (0, import_editor_v1_adapters29.commandStartEvent)("document/elements/reset-style"),
6069
+ (0, import_editor_v1_adapters28.__privateListenTo)(
6070
+ (0, import_editor_v1_adapters28.commandStartEvent)("document/elements/reset-style"),
6082
6071
  (e) => resetStyles(e.args, resetElementStyles)
6083
6072
  );
6084
6073
  }
@@ -6230,9 +6219,9 @@ function getRectClipPath(rect, viewport) {
6230
6219
  }
6231
6220
 
6232
6221
  // src/hooks/use-canvas-document.ts
6233
- var import_editor_v1_adapters30 = require("@elementor/editor-v1-adapters");
6222
+ var import_editor_v1_adapters29 = require("@elementor/editor-v1-adapters");
6234
6223
  function useCanvasDocument() {
6235
- return (0, import_editor_v1_adapters30.__privateUseListenTo)((0, import_editor_v1_adapters30.commandEndEvent)("editor/documents/attach-preview"), () => (0, import_editor_v1_adapters30.getCanvasIframeDocument)());
6224
+ return (0, import_editor_v1_adapters29.__privateUseListenTo)((0, import_editor_v1_adapters29.commandEndEvent)("editor/documents/attach-preview"), () => (0, import_editor_v1_adapters29.getCanvasIframeDocument)());
6236
6225
  }
6237
6226
 
6238
6227
  // src/hooks/use-escape-on-canvas.ts
package/dist/index.mjs CHANGED
@@ -2286,7 +2286,6 @@ var svgSrcTransformer = createTransformer(async (value, { signal }) => {
2286
2286
  var EMPTY_ICON_RESULT = { html: null, url: null };
2287
2287
  var ICON_SVG_SIZE = "100%";
2288
2288
  var ICON_SVG_OVERFLOW = "visible";
2289
- var FONT_AWESOME_LIBRARY_PREFIX = "fa-";
2290
2289
  var EICONS_LIBRARY = "eicons";
2291
2290
  var DEFAULT_SVG_RELATIVE_PATH = "images/default-svg.svg";
2292
2291
  var iconTransformer = createTransformer(async (value, { signal }) => {
@@ -2299,7 +2298,7 @@ var iconTransformer = createTransformer(async (value, { signal }) => {
2299
2298
  if (fontAwesomeHtml) {
2300
2299
  return { html: fontAwesomeHtml, url: null };
2301
2300
  }
2302
- if (library.startsWith(FONT_AWESOME_LIBRARY_PREFIX) || EICONS_LIBRARY === library) {
2301
+ if (EICONS_LIBRARY === library) {
2303
2302
  return EMPTY_ICON_RESULT;
2304
2303
  }
2305
2304
  const providerHtml = await resolveProviderSvg(library, iconValue, signal);
@@ -4315,11 +4314,6 @@ function initTabsModelExtensions() {
4315
4314
  // src/mcp/canvas-mcp.ts
4316
4315
  import { Schema as Schema3 } from "@elementor/editor-props";
4317
4316
 
4318
- // src/mcp/icon-library-experiment.ts
4319
- import { isExperimentActive } from "@elementor/editor-v1-adapters";
4320
- var ICON_LIBRARY_EXPERIMENT = "e_svg_library";
4321
- var isIconLibraryActive = () => isExperimentActive(ICON_LIBRARY_EXPERIMENT);
4322
-
4323
4317
  // src/mcp/resources/available-widgets-resource.ts
4324
4318
  import { httpService as httpService3 } from "@elementor/http-client";
4325
4319
  var MCP_PROXY_URL2 = "elementor/v1/mcp-proxy";
@@ -5172,7 +5166,6 @@ Setting a Font Awesome icon on an e-svg, after resolving it with \`find-icons\`:
5172
5166
  `;
5173
5167
  var CONFIGURE_ELEMENT_GUIDE_URI = "elementor://canvas/tools/configure-element-guide";
5174
5168
  var generatePrompt = () => {
5175
- const iconLibraryActive = isIconLibraryActive();
5176
5169
  const configureElementToolPrompt = toolPrompts("configure-element");
5177
5170
  configureElementToolPrompt.description(`
5178
5171
  Configure an existing element on the page.
@@ -5231,7 +5224,7 @@ Put the dynamic object EXACTLY at the node whose schema offers the "dynamic" var
5231
5224
  Image example: { "$$type": "image", "value": { "src": { "$$type": "dynamic", "value": { "name": "<image tag>", "settings": { ... } } } } }
5232
5225
  Do NOT send "group" (it is resolved automatically). Use { "settings": {} } only when the tag has no settings.
5233
5226
 
5234
- ${iconLibraryActive ? ICONS_SECTION : ""}`);
5227
+ ${ICONS_SECTION}`);
5235
5228
  configureElementToolPrompt.parameter("elementId", "The ID of the element to configure. MANDATORY.");
5236
5229
  configureElementToolPrompt.parameter(
5237
5230
  "elementType",
@@ -5268,9 +5261,7 @@ ${iconLibraryActive ? ICONS_SECTION : ""}`);
5268
5261
  };
5269
5262
  \`\`\`
5270
5263
  `);
5271
- if (iconLibraryActive) {
5272
- configureElementToolPrompt.example(ICON_EXAMPLE);
5273
- }
5264
+ configureElementToolPrompt.example(ICON_EXAMPLE);
5274
5265
  configureElementToolPrompt.instruction(
5275
5266
  "The $$type property is MANDATORY for every value in propertiesToChange; it is not used in the style parameter (raw CSS only)."
5276
5267
  );
@@ -5633,9 +5624,7 @@ var initCanvasMcp = (reg) => {
5633
5624
  initGeneralContextResource(reg);
5634
5625
  initBestPracticesResource(reg);
5635
5626
  initConfigureElementTool(reg);
5636
- if (isIconLibraryActive()) {
5637
- initFindIconsTool(reg);
5638
- }
5627
+ initFindIconsTool(reg);
5639
5628
  initGetPageStructureTool(reg);
5640
5629
  initBreakpointsResource(reg);
5641
5630
  };
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.4.0-1145",
4
+ "version": "4.4.0-1147",
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.4.0-1145",
41
- "@elementor/editor-controls": "4.4.0-1145",
42
- "@elementor/editor-documents": "4.4.0-1145",
43
- "@elementor/editor-elements": "4.4.0-1145",
44
- "@elementor/editor-interactions": "4.4.0-1145",
45
- "@elementor/editor-mcp": "4.4.0-1145",
46
- "@elementor/editor-notifications": "4.4.0-1145",
47
- "@elementor/editor-props": "4.4.0-1145",
48
- "@elementor/editor-responsive": "4.4.0-1145",
49
- "@elementor/editor-styles": "4.4.0-1145",
50
- "@elementor/editor-styles-repository": "4.4.0-1145",
51
- "@elementor/editor-ui": "4.4.0-1145",
52
- "@elementor/editor-v1-adapters": "4.4.0-1145",
53
- "@elementor/events": "4.4.0-1145",
54
- "@elementor/http-client": "4.4.0-1145",
55
- "@elementor/schema": "4.4.0-1145",
56
- "@elementor/twing": "4.4.0-1145",
40
+ "@elementor/editor": "4.4.0-1147",
41
+ "@elementor/editor-controls": "4.4.0-1147",
42
+ "@elementor/editor-documents": "4.4.0-1147",
43
+ "@elementor/editor-elements": "4.4.0-1147",
44
+ "@elementor/editor-interactions": "4.4.0-1147",
45
+ "@elementor/editor-mcp": "4.4.0-1147",
46
+ "@elementor/editor-notifications": "4.4.0-1147",
47
+ "@elementor/editor-props": "4.4.0-1147",
48
+ "@elementor/editor-responsive": "4.4.0-1147",
49
+ "@elementor/editor-styles": "4.4.0-1147",
50
+ "@elementor/editor-styles-repository": "4.4.0-1147",
51
+ "@elementor/editor-ui": "4.4.0-1147",
52
+ "@elementor/editor-v1-adapters": "4.4.0-1147",
53
+ "@elementor/events": "4.4.0-1147",
54
+ "@elementor/http-client": "4.4.0-1147",
55
+ "@elementor/schema": "4.4.0-1147",
56
+ "@elementor/twing": "4.4.0-1147",
57
57
  "@elementor/ui": "1.41.4",
58
- "@elementor/utils": "4.4.0-1145",
59
- "@elementor/wp-media": "4.4.0-1145",
58
+ "@elementor/utils": "4.4.0-1147",
59
+ "@elementor/wp-media": "4.4.0-1147",
60
60
  "@floating-ui/react": "^0.27.5",
61
61
  "@wordpress/i18n": "^5.13.0",
62
62
  "dompurify": "^3.2.6"
@@ -0,0 +1,33 @@
1
+ import { initCanvasMcp } from '../canvas-mcp';
2
+ import { initFindIconsTool } from '../tools/find-icons/tool';
3
+
4
+ jest.mock( '@elementor/editor-props', () => ( {
5
+ Schema: { setDynamicTagNamesResolver: jest.fn() },
6
+ } ) );
7
+
8
+ jest.mock( '../resources/available-widgets-resource', () => ( { initAvailableWidgetsResource: jest.fn() } ) );
9
+ jest.mock( '../resources/best-practices-resource', () => ( { initBestPracticesResource: jest.fn() } ) );
10
+ jest.mock( '../resources/breakpoints-resource', () => ( { initBreakpointsResource: jest.fn() } ) );
11
+ jest.mock( '../resources/document-structure-resource', () => ( { initDocumentStructureResource: jest.fn() } ) );
12
+ jest.mock( '../resources/dynamic-tags-resource', () => ( { initDynamicTagsResource: jest.fn() } ) );
13
+ jest.mock( '../resources/editor-state-resource', () => ( { initEditorStateResource: jest.fn() } ) );
14
+ jest.mock( '../resources/general-context-resource', () => ( { initGeneralContextResource: jest.fn() } ) );
15
+ jest.mock( '../resources/selected-element-resource', () => ( { initSelectedElementResource: jest.fn() } ) );
16
+ jest.mock( '../resources/widgets-schema-resource', () => ( { initWidgetsSchemaResource: jest.fn() } ) );
17
+ jest.mock( '../tools/configure-element/tool', () => ( { initConfigureElementTool: jest.fn() } ) );
18
+ jest.mock( '../tools/find-icons/tool', () => ( { initFindIconsTool: jest.fn() } ) );
19
+ jest.mock( '../tools/get-page-structure/tool', () => ( { initGetPageStructureTool: jest.fn() } ) );
20
+ jest.mock( '../utils/resolve-dynamic-tag', () => ( { getDynamicTagNamesByCategories: jest.fn() } ) );
21
+
22
+ describe( 'initCanvasMcp', () => {
23
+ it( 'should always register the find-icons tool', () => {
24
+ // Arrange.
25
+ const reg = { addTool: jest.fn() } as never;
26
+
27
+ // Act.
28
+ initCanvasMcp( reg );
29
+
30
+ // Assert.
31
+ expect( initFindIconsTool ).toHaveBeenCalledWith( reg );
32
+ } );
33
+ } );
@@ -1,7 +1,6 @@
1
1
  import { type MCPRegistryEntry } from '@elementor/editor-mcp';
2
2
  import { Schema } from '@elementor/editor-props';
3
3
 
4
- import { isIconLibraryActive } from './icon-library-experiment';
5
4
  import { initAvailableWidgetsResource } from './resources/available-widgets-resource';
6
5
  import { initBestPracticesResource } from './resources/best-practices-resource';
7
6
  import { initBreakpointsResource } from './resources/breakpoints-resource';
@@ -30,9 +29,7 @@ export const initCanvasMcp = ( reg: MCPRegistryEntry ) => {
30
29
  initGeneralContextResource( reg );
31
30
  initBestPracticesResource( reg );
32
31
  initConfigureElementTool( reg );
33
- if ( isIconLibraryActive() ) {
34
- initFindIconsTool( reg );
35
- }
32
+ initFindIconsTool( reg );
36
33
  initGetPageStructureTool( reg );
37
34
  initBreakpointsResource( reg );
38
35
  };
@@ -0,0 +1,34 @@
1
+ import { generatePrompt } from '../prompt';
2
+
3
+ const mockPromptParts: string[] = [];
4
+
5
+ jest.mock( '@elementor/editor-mcp', () => ( {
6
+ toolPrompts: () => {
7
+ const record = ( ...args: unknown[] ) => {
8
+ mockPromptParts.push( ...args.filter( ( arg ): arg is string => 'string' === typeof arg ) );
9
+ };
10
+
11
+ return {
12
+ description: record,
13
+ parameter: record,
14
+ example: record,
15
+ instruction: record,
16
+ prompt: () => mockPromptParts.join( '\n' ),
17
+ };
18
+ },
19
+ } ) );
20
+
21
+ describe( 'configure-element prompt', () => {
22
+ beforeEach( () => {
23
+ mockPromptParts.length = 0;
24
+ } );
25
+
26
+ it( 'should always point agents at the find-icons tool for the svg property', () => {
27
+ // Act.
28
+ const prompt = generatePrompt();
29
+
30
+ // Assert.
31
+ expect( prompt ).toContain( '# Icons (the `svg` property on e-svg)' );
32
+ expect( prompt ).toContain( 'find-icons' );
33
+ } );
34
+ } );
@@ -1,6 +1,5 @@
1
1
  import { toolPrompts } from '@elementor/editor-mcp';
2
2
 
3
- import { isIconLibraryActive } from '../../icon-library-experiment';
4
3
  import { DYNAMIC_TAGS_URI } from '../../resources/dynamic-tags-resource';
5
4
  import { WIDGET_SCHEMA_URI } from '../../resources/widgets-schema-resource';
6
5
 
@@ -46,7 +45,6 @@ Setting a Font Awesome icon on an e-svg, after resolving it with \`find-icons\`:
46
45
  export const CONFIGURE_ELEMENT_GUIDE_URI = 'elementor://canvas/tools/configure-element-guide';
47
46
 
48
47
  export const generatePrompt = () => {
49
- const iconLibraryActive = isIconLibraryActive();
50
48
  const configureElementToolPrompt = toolPrompts( 'configure-element' );
51
49
 
52
50
  configureElementToolPrompt.description( `
@@ -106,7 +104,7 @@ Put the dynamic object EXACTLY at the node whose schema offers the "dynamic" var
106
104
  Image example: { "$$type": "image", "value": { "src": { "$$type": "dynamic", "value": { "name": "<image tag>", "settings": { ... } } } } }
107
105
  Do NOT send "group" (it is resolved automatically). Use { "settings": {} } only when the tag has no settings.
108
106
 
109
- ${ iconLibraryActive ? ICONS_SECTION : '' }` );
107
+ ${ ICONS_SECTION }` );
110
108
 
111
109
  configureElementToolPrompt.parameter( 'elementId', 'The ID of the element to configure. MANDATORY.' );
112
110
 
@@ -149,9 +147,7 @@ ${ iconLibraryActive ? ICONS_SECTION : '' }` );
149
147
  \`\`\`
150
148
  ` );
151
149
 
152
- if ( iconLibraryActive ) {
153
- configureElementToolPrompt.example( ICON_EXAMPLE );
154
- }
150
+ configureElementToolPrompt.example( ICON_EXAMPLE );
155
151
 
156
152
  configureElementToolPrompt.instruction(
157
153
  'The $$type property is MANDATORY for every value in propertiesToChange; it is not used in the style parameter (raw CSS only).'
@@ -133,7 +133,7 @@ describe( 'iconTransformer', () => {
133
133
  expect( html ).toContain( 'M10 10' );
134
134
  } );
135
135
 
136
- it( 'returns null html when the icon cannot be resolved', async () => {
136
+ it( 'falls back to the default svg when the icon cannot be resolved', async () => {
137
137
  // Arrange.
138
138
  mockFetch( { icons: {} } );
139
139
 
@@ -141,7 +141,7 @@ describe( 'iconTransformer', () => {
141
141
  const result = await resolveSavedIcon( 'fas fa-missing', 'fa-solid' );
142
142
 
143
143
  // Assert.
144
- expect( result ).toEqual( { html: null, url: null } );
144
+ expect( result ).toEqual( { html: null, url: 'https://example.com/assets/images/default-svg.svg' } );
145
145
  } );
146
146
 
147
147
  it( 'fetches json from the localized font awesome 7 base url', async () => {
@@ -180,8 +180,70 @@ describe( 'iconTransformer', () => {
180
180
  const result = await resolveSavedIcon( 'fas fa-star', 'fa-../../wp-config' );
181
181
 
182
182
  // Assert.
183
- expect( global.fetch ).not.toHaveBeenCalled();
184
- expect( result ).toEqual( { html: null, url: null } );
183
+ expect( ( global.fetch as jest.Mock ).mock.calls.map( ( [ url ] ) => String( url ) ) ).toEqual( [
184
+ 'https://example.com/assets/images/default-svg.svg',
185
+ ] );
186
+ expect( result ).toEqual(
187
+ expect.objectContaining( { url: 'https://example.com/assets/images/default-svg.svg' } )
188
+ );
189
+ } );
190
+
191
+ it( 'asks providers for a font awesome icon missing from the free data', async () => {
192
+ // Arrange.
193
+ mockFetch( { icons: {} } );
194
+ const resolveSvg = jest
195
+ .fn()
196
+ .mockResolvedValue(
197
+ '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10"><path d="M2 2h6v6H2z"></path></svg>'
198
+ );
199
+ registerIconLibraryProvider( {
200
+ id: 'test-provider',
201
+ useIcons: () => ( { data: [], isLoading: false } ),
202
+ resolveSvg,
203
+ } );
204
+
205
+ // Act.
206
+ const result = ( await resolveSavedIcon( 'fal fa-star', 'fa-light' ) ) as { html: string; url: string | null };
207
+
208
+ unregisterIconLibraryProvider( 'test-provider' );
209
+
210
+ // Assert.
211
+ expect( resolveSvg ).toHaveBeenCalledWith( 'fa-light', 'fal fa-star', undefined );
212
+ expect( result.html ).toContain( 'M2 2h6v6H2z' );
213
+ expect( result.url ).toBeNull();
214
+ } );
215
+
216
+ it( 'falls back to the default svg for a font awesome icon when no provider resolves it', async () => {
217
+ // Arrange.
218
+ registerIconLibraryProvider( {
219
+ id: 'test-provider',
220
+ useIcons: () => ( { data: [], isLoading: false } ),
221
+ resolveSvg: async () => null,
222
+ } );
223
+ const defaultSvg =
224
+ '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"><path d="M24.9999 4.31543"></path></svg>';
225
+ global.fetch = jest.fn( ( url: string ) =>
226
+ Promise.resolve(
227
+ String( url ).endsWith( '.svg' )
228
+ ? {
229
+ ok: true,
230
+ headers: new Headers( { 'content-type': 'image/svg+xml' } ),
231
+ text: () => Promise.resolve( defaultSvg ),
232
+ }
233
+ : { ok: true, json: () => Promise.resolve( { icons: {} } ) }
234
+ )
235
+ ) as never;
236
+
237
+ // Act.
238
+ const result = await resolveSavedIcon( 'fa-light fa-star', 'fa-light' );
239
+
240
+ unregisterIconLibraryProvider( 'test-provider' );
241
+
242
+ // Assert.
243
+ expect( result ).toEqual( {
244
+ html: expect.stringContaining( 'M24.9999 4.31543' ),
245
+ url: 'https://example.com/assets/images/default-svg.svg',
246
+ } );
185
247
  } );
186
248
 
187
249
  it( 'falls back to the default svg when no provider resolves a non-native library', async () => {
@@ -13,7 +13,6 @@ import { svgSrcTransformer } from './svg-src-transformer';
13
13
  const EMPTY_ICON_RESULT = { html: null, url: null };
14
14
  const ICON_SVG_SIZE = '100%';
15
15
  const ICON_SVG_OVERFLOW = 'visible';
16
- const FONT_AWESOME_LIBRARY_PREFIX = 'fa-';
17
16
  const EICONS_LIBRARY = 'eicons';
18
17
  const DEFAULT_SVG_RELATIVE_PATH = 'images/default-svg.svg';
19
18
 
@@ -36,7 +35,7 @@ export const iconTransformer = createTransformer( async ( value: IconValue, { si
36
35
  return { html: fontAwesomeHtml, url: null };
37
36
  }
38
37
 
39
- if ( library.startsWith( FONT_AWESOME_LIBRARY_PREFIX ) || EICONS_LIBRARY === library ) {
38
+ if ( EICONS_LIBRARY === library ) {
40
39
  return EMPTY_ICON_RESULT;
41
40
  }
42
41
 
@@ -1,5 +0,0 @@
1
- import { isExperimentActive } from '@elementor/editor-v1-adapters';
2
-
3
- const ICON_LIBRARY_EXPERIMENT = 'e_svg_library';
4
-
5
- export const isIconLibraryActive = () => isExperimentActive( ICON_LIBRARY_EXPERIMENT );