@elementor/editor-canvas 4.4.0-1109 → 4.4.0-1111

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
@@ -2131,32 +2131,101 @@ function processSvgContent(svgText) {
2131
2131
  return svgElement.outerHTML;
2132
2132
  }
2133
2133
 
2134
+ // src/transformers/shared/svg-src-transformer.ts
2135
+ var import_wp_media = require("@elementor/wp-media");
2136
+ async function fetchSvgContent(url, signal) {
2137
+ try {
2138
+ const response = await fetch(url, { signal });
2139
+ if (!response.ok) {
2140
+ return null;
2141
+ }
2142
+ const contentType = response.headers.get("content-type") ?? "";
2143
+ const isSvg = contentType.includes("svg") || contentType.includes("xml") || url.endsWith(".svg");
2144
+ if (!isSvg) {
2145
+ return null;
2146
+ }
2147
+ return await response.text();
2148
+ } catch {
2149
+ return null;
2150
+ }
2151
+ }
2152
+ function resolveSvgSrcId(id) {
2153
+ if (typeof id !== "number" || id <= 0) {
2154
+ return null;
2155
+ }
2156
+ return id;
2157
+ }
2158
+ var svgSrcTransformer = createTransformer(async (value, { signal }) => {
2159
+ const id = resolveSvgSrcId(value.id);
2160
+ const urlFromValue = typeof value.url === "string" ? value.url : null;
2161
+ let url = urlFromValue;
2162
+ if (id && !urlFromValue) {
2163
+ const attachment = await (0, import_wp_media.getMediaAttachment)({ id });
2164
+ url = attachment?.url ?? null;
2165
+ }
2166
+ const resolvedUrl = typeof url === "string" ? url : null;
2167
+ if (!resolvedUrl) {
2168
+ return { html: null, url: null };
2169
+ }
2170
+ const svgText = await fetchSvgContent(resolvedUrl, signal);
2171
+ const html = svgText ? processSvgContent(svgText) : null;
2172
+ return { html, url: resolvedUrl };
2173
+ });
2174
+
2134
2175
  // src/transformers/shared/icon-transformer.ts
2135
2176
  var EMPTY_ICON_RESULT = { html: null, url: null };
2136
2177
  var ICON_SVG_SIZE = "100%";
2137
2178
  var ICON_SVG_OVERFLOW = "visible";
2179
+ var DEFAULT_SVG_RELATIVE_PATH = "images/default-svg.svg";
2138
2180
  var iconTransformer = createTransformer(async (value, { signal }) => {
2139
2181
  const iconValue = typeof value.value === "string" ? value.value : null;
2140
2182
  const library = typeof value.library === "string" ? value.library : null;
2141
2183
  if (!iconValue || !library) {
2142
2184
  return EMPTY_ICON_RESULT;
2143
2185
  }
2186
+ const fontAwesomeHtml = await resolveFontAwesomeSvg(library, iconValue, signal);
2187
+ if (fontAwesomeHtml) {
2188
+ return { html: fontAwesomeHtml, url: null };
2189
+ }
2190
+ if ((0, import_editor_controls.isDeletedCustomIconLibrary)(library, iconValue)) {
2191
+ return resolveDefaultSvg(signal);
2192
+ }
2193
+ const customHtml = await resolveCustomSvg(library, iconValue, signal);
2194
+ if (customHtml) {
2195
+ return { html: customHtml, url: null };
2196
+ }
2197
+ return EMPTY_ICON_RESULT;
2198
+ });
2199
+ async function resolveDefaultSvg(signal) {
2200
+ const assetsUrl = window.elementorCommon?.config?.urls?.assets;
2201
+ if (typeof assetsUrl !== "string" || assetsUrl === "") {
2202
+ return EMPTY_ICON_RESULT;
2203
+ }
2204
+ return svgSrcTransformer(
2205
+ {
2206
+ id: null,
2207
+ url: `${assetsUrl}${DEFAULT_SVG_RELATIVE_PATH}`
2208
+ },
2209
+ { key: "svg", signal }
2210
+ );
2211
+ }
2212
+ async function resolveCustomSvg(library, iconValue, signal) {
2213
+ const markup = await (0, import_editor_controls.resolveCustomIconSvg)(library, iconValue, signal);
2214
+ return markup ? processIconSvgContent(markup) : null;
2215
+ }
2216
+ async function resolveFontAwesomeSvg(library, iconValue, signal) {
2144
2217
  const iconName = (0, import_editor_controls.getFontAwesome7IconName)(iconValue);
2145
2218
  if (!iconName) {
2146
- return EMPTY_ICON_RESULT;
2219
+ return null;
2147
2220
  }
2148
2221
  const iconData = await (0, import_editor_controls.resolveFontAwesome7Icon)(library, iconName, signal);
2149
2222
  if (!iconData) {
2150
- return EMPTY_ICON_RESULT;
2151
- }
2152
- const svgText = buildFontAwesomeSvg(iconData);
2153
- if (!svgText) {
2154
- return EMPTY_ICON_RESULT;
2223
+ return null;
2155
2224
  }
2156
- const html = processIconSvgContent(svgText);
2157
- return { html, url: null };
2158
- });
2159
- function buildFontAwesomeSvg(iconData) {
2225
+ const svgText = buildPathSvg(iconData);
2226
+ return svgText ? processIconSvgContent(svgText) : null;
2227
+ }
2228
+ function buildPathSvg(iconData) {
2160
2229
  if (iconData.paths.length === 0) {
2161
2230
  return null;
2162
2231
  }
@@ -2192,13 +2261,13 @@ var imageSrcTransformer = createTransformer((value) => ({
2192
2261
  }));
2193
2262
 
2194
2263
  // src/transformers/shared/image-transformer.ts
2195
- var import_wp_media = require("@elementor/wp-media");
2264
+ var import_wp_media2 = require("@elementor/wp-media");
2196
2265
  var imageTransformer = createTransformer(async (value) => {
2197
2266
  const { src, size: size2 } = value;
2198
2267
  if (!src?.id) {
2199
2268
  return src?.url ? { src: src.url, alt: src.alt ?? "" } : null;
2200
2269
  }
2201
- const attachment = await (0, import_wp_media.getMediaAttachment)({ id: src.id });
2270
+ const attachment = await (0, import_wp_media2.getMediaAttachment)({ id: src.id });
2202
2271
  const sizedAttachment = attachment?.sizes?.[size2 ?? ""];
2203
2272
  if (sizedAttachment) {
2204
2273
  return {
@@ -2224,47 +2293,6 @@ var plainTransformer = createTransformer((value) => {
2224
2293
  return value;
2225
2294
  });
2226
2295
 
2227
- // src/transformers/shared/svg-src-transformer.ts
2228
- var import_wp_media2 = require("@elementor/wp-media");
2229
- async function fetchSvgContent(url, signal) {
2230
- try {
2231
- const response = await fetch(url, { signal });
2232
- if (!response.ok) {
2233
- return null;
2234
- }
2235
- const contentType = response.headers.get("content-type") ?? "";
2236
- const isSvg = contentType.includes("svg") || contentType.includes("xml") || url.endsWith(".svg");
2237
- if (!isSvg) {
2238
- return null;
2239
- }
2240
- return await response.text();
2241
- } catch {
2242
- return null;
2243
- }
2244
- }
2245
- function resolveSvgSrcId(id) {
2246
- if (typeof id !== "number" || id <= 0) {
2247
- return null;
2248
- }
2249
- return id;
2250
- }
2251
- var svgSrcTransformer = createTransformer(async (value, { signal }) => {
2252
- const id = resolveSvgSrcId(value.id);
2253
- const urlFromValue = typeof value.url === "string" ? value.url : null;
2254
- let url = urlFromValue;
2255
- if (id && !urlFromValue) {
2256
- const attachment = await (0, import_wp_media2.getMediaAttachment)({ id });
2257
- url = attachment?.url ?? null;
2258
- }
2259
- const resolvedUrl = typeof url === "string" ? url : null;
2260
- if (!resolvedUrl) {
2261
- return { html: null, url: null };
2262
- }
2263
- const svgText = await fetchSvgContent(resolvedUrl, signal);
2264
- const html = svgText ? processSvgContent(svgText) : null;
2265
- return { html, url: resolvedUrl };
2266
- });
2267
-
2268
2296
  // src/transformers/shared/video-src-transformer.ts
2269
2297
  var import_wp_media3 = require("@elementor/wp-media");
2270
2298
  var videoSrcTransformer = createTransformer(async (value) => {
package/dist/index.mjs CHANGED
@@ -2062,6 +2062,8 @@ var timeRangeTransformer = createTransformer((value) => {
2062
2062
  // src/transformers/shared/icon-transformer.ts
2063
2063
  import {
2064
2064
  getFontAwesome7IconName,
2065
+ isDeletedCustomIconLibrary,
2066
+ resolveCustomIconSvg,
2065
2067
  resolveFontAwesome7Icon
2066
2068
  } from "@elementor/editor-controls";
2067
2069
 
@@ -2086,32 +2088,101 @@ function processSvgContent(svgText) {
2086
2088
  return svgElement.outerHTML;
2087
2089
  }
2088
2090
 
2091
+ // src/transformers/shared/svg-src-transformer.ts
2092
+ import { getMediaAttachment } from "@elementor/wp-media";
2093
+ async function fetchSvgContent(url, signal) {
2094
+ try {
2095
+ const response = await fetch(url, { signal });
2096
+ if (!response.ok) {
2097
+ return null;
2098
+ }
2099
+ const contentType = response.headers.get("content-type") ?? "";
2100
+ const isSvg = contentType.includes("svg") || contentType.includes("xml") || url.endsWith(".svg");
2101
+ if (!isSvg) {
2102
+ return null;
2103
+ }
2104
+ return await response.text();
2105
+ } catch {
2106
+ return null;
2107
+ }
2108
+ }
2109
+ function resolveSvgSrcId(id) {
2110
+ if (typeof id !== "number" || id <= 0) {
2111
+ return null;
2112
+ }
2113
+ return id;
2114
+ }
2115
+ var svgSrcTransformer = createTransformer(async (value, { signal }) => {
2116
+ const id = resolveSvgSrcId(value.id);
2117
+ const urlFromValue = typeof value.url === "string" ? value.url : null;
2118
+ let url = urlFromValue;
2119
+ if (id && !urlFromValue) {
2120
+ const attachment = await getMediaAttachment({ id });
2121
+ url = attachment?.url ?? null;
2122
+ }
2123
+ const resolvedUrl = typeof url === "string" ? url : null;
2124
+ if (!resolvedUrl) {
2125
+ return { html: null, url: null };
2126
+ }
2127
+ const svgText = await fetchSvgContent(resolvedUrl, signal);
2128
+ const html = svgText ? processSvgContent(svgText) : null;
2129
+ return { html, url: resolvedUrl };
2130
+ });
2131
+
2089
2132
  // src/transformers/shared/icon-transformer.ts
2090
2133
  var EMPTY_ICON_RESULT = { html: null, url: null };
2091
2134
  var ICON_SVG_SIZE = "100%";
2092
2135
  var ICON_SVG_OVERFLOW = "visible";
2136
+ var DEFAULT_SVG_RELATIVE_PATH = "images/default-svg.svg";
2093
2137
  var iconTransformer = createTransformer(async (value, { signal }) => {
2094
2138
  const iconValue = typeof value.value === "string" ? value.value : null;
2095
2139
  const library = typeof value.library === "string" ? value.library : null;
2096
2140
  if (!iconValue || !library) {
2097
2141
  return EMPTY_ICON_RESULT;
2098
2142
  }
2143
+ const fontAwesomeHtml = await resolveFontAwesomeSvg(library, iconValue, signal);
2144
+ if (fontAwesomeHtml) {
2145
+ return { html: fontAwesomeHtml, url: null };
2146
+ }
2147
+ if (isDeletedCustomIconLibrary(library, iconValue)) {
2148
+ return resolveDefaultSvg(signal);
2149
+ }
2150
+ const customHtml = await resolveCustomSvg(library, iconValue, signal);
2151
+ if (customHtml) {
2152
+ return { html: customHtml, url: null };
2153
+ }
2154
+ return EMPTY_ICON_RESULT;
2155
+ });
2156
+ async function resolveDefaultSvg(signal) {
2157
+ const assetsUrl = window.elementorCommon?.config?.urls?.assets;
2158
+ if (typeof assetsUrl !== "string" || assetsUrl === "") {
2159
+ return EMPTY_ICON_RESULT;
2160
+ }
2161
+ return svgSrcTransformer(
2162
+ {
2163
+ id: null,
2164
+ url: `${assetsUrl}${DEFAULT_SVG_RELATIVE_PATH}`
2165
+ },
2166
+ { key: "svg", signal }
2167
+ );
2168
+ }
2169
+ async function resolveCustomSvg(library, iconValue, signal) {
2170
+ const markup = await resolveCustomIconSvg(library, iconValue, signal);
2171
+ return markup ? processIconSvgContent(markup) : null;
2172
+ }
2173
+ async function resolveFontAwesomeSvg(library, iconValue, signal) {
2099
2174
  const iconName = getFontAwesome7IconName(iconValue);
2100
2175
  if (!iconName) {
2101
- return EMPTY_ICON_RESULT;
2176
+ return null;
2102
2177
  }
2103
2178
  const iconData = await resolveFontAwesome7Icon(library, iconName, signal);
2104
2179
  if (!iconData) {
2105
- return EMPTY_ICON_RESULT;
2106
- }
2107
- const svgText = buildFontAwesomeSvg(iconData);
2108
- if (!svgText) {
2109
- return EMPTY_ICON_RESULT;
2180
+ return null;
2110
2181
  }
2111
- const html = processIconSvgContent(svgText);
2112
- return { html, url: null };
2113
- });
2114
- function buildFontAwesomeSvg(iconData) {
2182
+ const svgText = buildPathSvg(iconData);
2183
+ return svgText ? processIconSvgContent(svgText) : null;
2184
+ }
2185
+ function buildPathSvg(iconData) {
2115
2186
  if (iconData.paths.length === 0) {
2116
2187
  return null;
2117
2188
  }
@@ -2147,13 +2218,13 @@ var imageSrcTransformer = createTransformer((value) => ({
2147
2218
  }));
2148
2219
 
2149
2220
  // src/transformers/shared/image-transformer.ts
2150
- import { getMediaAttachment } from "@elementor/wp-media";
2221
+ import { getMediaAttachment as getMediaAttachment2 } from "@elementor/wp-media";
2151
2222
  var imageTransformer = createTransformer(async (value) => {
2152
2223
  const { src, size: size2 } = value;
2153
2224
  if (!src?.id) {
2154
2225
  return src?.url ? { src: src.url, alt: src.alt ?? "" } : null;
2155
2226
  }
2156
- const attachment = await getMediaAttachment({ id: src.id });
2227
+ const attachment = await getMediaAttachment2({ id: src.id });
2157
2228
  const sizedAttachment = attachment?.sizes?.[size2 ?? ""];
2158
2229
  if (sizedAttachment) {
2159
2230
  return {
@@ -2179,47 +2250,6 @@ var plainTransformer = createTransformer((value) => {
2179
2250
  return value;
2180
2251
  });
2181
2252
 
2182
- // src/transformers/shared/svg-src-transformer.ts
2183
- import { getMediaAttachment as getMediaAttachment2 } from "@elementor/wp-media";
2184
- async function fetchSvgContent(url, signal) {
2185
- try {
2186
- const response = await fetch(url, { signal });
2187
- if (!response.ok) {
2188
- return null;
2189
- }
2190
- const contentType = response.headers.get("content-type") ?? "";
2191
- const isSvg = contentType.includes("svg") || contentType.includes("xml") || url.endsWith(".svg");
2192
- if (!isSvg) {
2193
- return null;
2194
- }
2195
- return await response.text();
2196
- } catch {
2197
- return null;
2198
- }
2199
- }
2200
- function resolveSvgSrcId(id) {
2201
- if (typeof id !== "number" || id <= 0) {
2202
- return null;
2203
- }
2204
- return id;
2205
- }
2206
- var svgSrcTransformer = createTransformer(async (value, { signal }) => {
2207
- const id = resolveSvgSrcId(value.id);
2208
- const urlFromValue = typeof value.url === "string" ? value.url : null;
2209
- let url = urlFromValue;
2210
- if (id && !urlFromValue) {
2211
- const attachment = await getMediaAttachment2({ id });
2212
- url = attachment?.url ?? null;
2213
- }
2214
- const resolvedUrl = typeof url === "string" ? url : null;
2215
- if (!resolvedUrl) {
2216
- return { html: null, url: null };
2217
- }
2218
- const svgText = await fetchSvgContent(resolvedUrl, signal);
2219
- const html = svgText ? processSvgContent(svgText) : null;
2220
- return { html, url: resolvedUrl };
2221
- });
2222
-
2223
2253
  // src/transformers/shared/video-src-transformer.ts
2224
2254
  import { getMediaAttachment as getMediaAttachment3 } from "@elementor/wp-media";
2225
2255
  var videoSrcTransformer = createTransformer(async (value) => {
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-1109",
4
+ "version": "4.4.0-1111",
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-1109",
41
- "@elementor/editor-controls": "4.4.0-1109",
42
- "@elementor/editor-documents": "4.4.0-1109",
43
- "@elementor/editor-elements": "4.4.0-1109",
44
- "@elementor/editor-interactions": "4.4.0-1109",
45
- "@elementor/editor-mcp": "4.4.0-1109",
46
- "@elementor/editor-notifications": "4.4.0-1109",
47
- "@elementor/editor-props": "4.4.0-1109",
48
- "@elementor/editor-responsive": "4.4.0-1109",
49
- "@elementor/editor-styles": "4.4.0-1109",
50
- "@elementor/editor-styles-repository": "4.4.0-1109",
51
- "@elementor/editor-ui": "4.4.0-1109",
52
- "@elementor/editor-v1-adapters": "4.4.0-1109",
53
- "@elementor/events": "4.4.0-1109",
54
- "@elementor/http-client": "4.4.0-1109",
55
- "@elementor/schema": "4.4.0-1109",
56
- "@elementor/twing": "4.4.0-1109",
40
+ "@elementor/editor": "4.4.0-1111",
41
+ "@elementor/editor-controls": "4.4.0-1111",
42
+ "@elementor/editor-documents": "4.4.0-1111",
43
+ "@elementor/editor-elements": "4.4.0-1111",
44
+ "@elementor/editor-interactions": "4.4.0-1111",
45
+ "@elementor/editor-mcp": "4.4.0-1111",
46
+ "@elementor/editor-notifications": "4.4.0-1111",
47
+ "@elementor/editor-props": "4.4.0-1111",
48
+ "@elementor/editor-responsive": "4.4.0-1111",
49
+ "@elementor/editor-styles": "4.4.0-1111",
50
+ "@elementor/editor-styles-repository": "4.4.0-1111",
51
+ "@elementor/editor-ui": "4.4.0-1111",
52
+ "@elementor/editor-v1-adapters": "4.4.0-1111",
53
+ "@elementor/events": "4.4.0-1111",
54
+ "@elementor/http-client": "4.4.0-1111",
55
+ "@elementor/schema": "4.4.0-1111",
56
+ "@elementor/twing": "4.4.0-1111",
57
57
  "@elementor/ui": "1.37.5",
58
- "@elementor/utils": "4.4.0-1109",
59
- "@elementor/wp-media": "4.4.0-1109",
58
+ "@elementor/utils": "4.4.0-1111",
59
+ "@elementor/wp-media": "4.4.0-1111",
60
60
  "@floating-ui/react": "^0.27.5",
61
61
  "@wordpress/i18n": "^5.13.0",
62
62
  "dompurify": "^3.2.6"
@@ -1,3 +1,9 @@
1
+ jest.mock( '@elementor/http-client', () => ( {
2
+ httpService: () => ( {
3
+ get: jest.fn().mockRejectedValue( new Error( 'no custom svg' ) ),
4
+ } ),
5
+ } ) );
6
+
1
7
  import { resetFontAwesome7IconsCache } from '@elementor/editor-controls';
2
8
  import { iconPropTypeUtil, stringPropTypeUtil } from '@elementor/editor-props';
3
9
 
@@ -41,6 +47,7 @@ async function resolveSavedIcon( iconClass: string, library: string ) {
41
47
 
42
48
  describe( 'iconTransformer', () => {
43
49
  const originalElementorCommon = window.elementorCommon;
50
+ const originalElementor = window.elementor;
44
51
 
45
52
  beforeEach( () => {
46
53
  jest.clearAllMocks();
@@ -63,6 +70,7 @@ describe( 'iconTransformer', () => {
63
70
 
64
71
  afterEach( () => {
65
72
  window.elementorCommon = originalElementorCommon;
73
+ window.elementor = originalElementor;
66
74
  jest.restoreAllMocks();
67
75
  } );
68
76
 
@@ -178,6 +186,37 @@ describe( 'iconTransformer', () => {
178
186
  expect( result ).toEqual( { html: null, url: null } );
179
187
  } );
180
188
 
189
+ it( 'falls back to the default svg when a custom library has been deleted', async () => {
190
+ // Arrange.
191
+ window.elementor = {
192
+ config: {
193
+ icons: {
194
+ libraries: [ { name: 'fa-solid', prefix: 'fa-', native: true } ],
195
+ },
196
+ },
197
+ } as typeof window.elementor;
198
+ const defaultSvg =
199
+ '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"><path d="M24.9999 4.31543"></path></svg>';
200
+ global.fetch = jest.fn().mockResolvedValue( {
201
+ ok: true,
202
+ headers: new Headers( { 'content-type': 'image/svg+xml' } ),
203
+ text: () => Promise.resolve( defaultSvg ),
204
+ } );
205
+
206
+ // Act.
207
+ const result = await resolveSavedIcon( 'missing-set missing-set-ghost', 'missing-set' );
208
+
209
+ // Assert.
210
+ expect( global.fetch ).toHaveBeenCalledWith(
211
+ 'https://example.com/assets/images/default-svg.svg',
212
+ expect.anything()
213
+ );
214
+ expect( result ).toEqual( {
215
+ html: expect.stringContaining( 'M24.9999 4.31543' ),
216
+ url: 'https://example.com/assets/images/default-svg.svg',
217
+ } );
218
+ } );
219
+
181
220
  it( 'returns null html when value or library is missing', async () => {
182
221
  // Act.
183
222
  const resolve = createPropsResolver( {
@@ -1,16 +1,20 @@
1
1
  import {
2
2
  type FontAwesome7IconDefinition,
3
3
  getFontAwesome7IconName,
4
+ isDeletedCustomIconLibrary,
5
+ resolveCustomIconSvg,
4
6
  resolveFontAwesome7Icon,
5
7
  } from '@elementor/editor-controls';
6
8
 
7
9
  import { createTransformer } from '../create-transformer';
8
10
  import type { TransformerOptions } from '../types';
9
11
  import { processSvgContent } from './process-svg-content';
12
+ import { svgSrcTransformer } from './svg-src-transformer';
10
13
 
11
14
  const EMPTY_ICON_RESULT = { html: null, url: null };
12
15
  const ICON_SVG_SIZE = '100%';
13
16
  const ICON_SVG_OVERFLOW = 'visible';
17
+ const DEFAULT_SVG_RELATIVE_PATH = 'images/default-svg.svg';
14
18
 
15
19
  type IconValue = {
16
20
  value?: unknown;
@@ -25,30 +29,70 @@ export const iconTransformer = createTransformer( async ( value: IconValue, { si
25
29
  return EMPTY_ICON_RESULT;
26
30
  }
27
31
 
28
- const iconName = getFontAwesome7IconName( iconValue );
32
+ const fontAwesomeHtml = await resolveFontAwesomeSvg( library, iconValue, signal );
29
33
 
30
- if ( ! iconName ) {
31
- return EMPTY_ICON_RESULT;
34
+ if ( fontAwesomeHtml ) {
35
+ return { html: fontAwesomeHtml, url: null };
32
36
  }
33
37
 
34
- const iconData = await resolveFontAwesome7Icon( library, iconName, signal );
38
+ if ( isDeletedCustomIconLibrary( library, iconValue ) ) {
39
+ return resolveDefaultSvg( signal );
40
+ }
35
41
 
36
- if ( ! iconData ) {
37
- return EMPTY_ICON_RESULT;
42
+ const customHtml = await resolveCustomSvg( library, iconValue, signal );
43
+
44
+ if ( customHtml ) {
45
+ return { html: customHtml, url: null };
38
46
  }
39
47
 
40
- const svgText = buildFontAwesomeSvg( iconData );
48
+ return EMPTY_ICON_RESULT;
49
+ } );
50
+
51
+ async function resolveDefaultSvg( signal?: AbortSignal ) {
52
+ const assetsUrl = window.elementorCommon?.config?.urls?.assets;
41
53
 
42
- if ( ! svgText ) {
54
+ if ( typeof assetsUrl !== 'string' || assetsUrl === '' ) {
43
55
  return EMPTY_ICON_RESULT;
44
56
  }
45
57
 
46
- const html = processIconSvgContent( svgText );
58
+ return svgSrcTransformer(
59
+ {
60
+ id: null,
61
+ url: `${ assetsUrl }${ DEFAULT_SVG_RELATIVE_PATH }`,
62
+ },
63
+ { key: 'svg', signal }
64
+ );
65
+ }
47
66
 
48
- return { html, url: null };
49
- } );
67
+ async function resolveCustomSvg( library: string, iconValue: string, signal?: AbortSignal ): Promise< string | null > {
68
+ const markup = await resolveCustomIconSvg( library, iconValue, signal );
69
+
70
+ return markup ? processIconSvgContent( markup ) : null;
71
+ }
72
+
73
+ async function resolveFontAwesomeSvg(
74
+ library: string,
75
+ iconValue: string,
76
+ signal?: AbortSignal
77
+ ): Promise< string | null > {
78
+ const iconName = getFontAwesome7IconName( iconValue );
79
+
80
+ if ( ! iconName ) {
81
+ return null;
82
+ }
83
+
84
+ const iconData = await resolveFontAwesome7Icon( library, iconName, signal );
85
+
86
+ if ( ! iconData ) {
87
+ return null;
88
+ }
89
+
90
+ const svgText = buildPathSvg( iconData );
91
+
92
+ return svgText ? processIconSvgContent( svgText ) : null;
93
+ }
50
94
 
51
- function buildFontAwesomeSvg( iconData: FontAwesome7IconDefinition ): string | null {
95
+ function buildPathSvg( iconData: FontAwesome7IconDefinition ): string | null {
52
96
  if ( iconData.paths.length === 0 ) {
53
97
  return null;
54
98
  }