@elementor/editor-canvas 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/CHANGELOG.md +17 -0
  3. package/dist/index.js +275 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +275 -0
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +10 -5
  8. package/src/__tests__/init-styles-renderer.test.ts +69 -0
  9. package/src/init-styles-renderer.ts +43 -0
  10. package/src/init.tsx +3 -0
  11. package/src/styles-renderer/__tests__/__mocks__/style-definitions.ts +171 -0
  12. package/src/styles-renderer/__tests__/enqueue-used-fonts.test.ts +54 -0
  13. package/src/styles-renderer/__tests__/index.test.ts +132 -0
  14. package/src/styles-renderer/enqueue-used-fonts.ts +21 -0
  15. package/src/styles-renderer/index.ts +2 -0
  16. package/src/styles-renderer/render.ts +112 -0
  17. package/src/styles-renderer/transform.ts +34 -0
  18. package/src/styles-renderer/transformers/__tests__/background-overlay-transformer.test.ts +46 -0
  19. package/src/styles-renderer/transformers/__tests__/create-combine-array-transformer.test.ts +61 -0
  20. package/src/styles-renderer/transformers/__tests__/linked-dimensions-transformer.test.ts +34 -0
  21. package/src/styles-renderer/transformers/__tests__/shadow-transformer.test.ts +127 -0
  22. package/src/styles-renderer/transformers/__tests__/size-transformer.test.ts +37 -0
  23. package/src/styles-renderer/transformers/__tests__/stroke-transformer.test.ts +59 -0
  24. package/src/styles-renderer/transformers/background-overlay-transformer.ts +13 -0
  25. package/src/styles-renderer/transformers/border-radius-transformer.ts +20 -0
  26. package/src/styles-renderer/transformers/border-width-transformer.ts +15 -0
  27. package/src/styles-renderer/transformers/color-transformer.ts +11 -0
  28. package/src/styles-renderer/transformers/create-combine-array-transformer.ts +20 -0
  29. package/src/styles-renderer/transformers/index.ts +22 -0
  30. package/src/styles-renderer/transformers/linked-dimensions-transformer.ts +15 -0
  31. package/src/styles-renderer/transformers/shadow-transformer.ts +22 -0
  32. package/src/styles-renderer/transformers/size-transformer.ts +11 -0
  33. package/src/styles-renderer/transformers/stroke-transformer.ts +11 -0
  34. package/src/styles-renderer/types.ts +9 -0
  35. package/src/sync/enqueue-font.ts +7 -0
  36. package/src/sync/get-canvas-iframe-body.ts +7 -0
  37. package/src/sync/types.ts +10 -0
package/dist/index.mjs CHANGED
@@ -127,8 +127,283 @@ function ElementsOverlays() {
127
127
  ));
128
128
  }
129
129
 
130
+ // src/init-styles-renderer.ts
131
+ import { getBreakpointsMap } from "@elementor/editor-responsive";
132
+ import { stylesRepository } from "@elementor/editor-styles-repository";
133
+
134
+ // src/styles-renderer/transformers/background-overlay-transformer.ts
135
+ import { colorGradientPropTypeUtil } from "@elementor/editor-props";
136
+ var backgroundOverlayTransformer = (propValue, { transform }) => {
137
+ if (colorGradientPropTypeUtil.isValid(propValue)) {
138
+ return `linear-gradient( ${[transform(propValue.value.color)]}, ${[
139
+ transform(propValue.value.color)
140
+ ]} )`;
141
+ }
142
+ };
143
+ var background_overlay_transformer_default = backgroundOverlayTransformer;
144
+
145
+ // src/styles-renderer/transformers/border-radius-transformer.ts
146
+ import { borderRadiusPropTypeUtil } from "@elementor/editor-props";
147
+ var borderRadiusTransformer = (propValue, { transform }) => {
148
+ if (borderRadiusPropTypeUtil.isValid(propValue)) {
149
+ const {
150
+ "top-left": topLeft,
151
+ "top-right": topRight,
152
+ "bottom-right": bottomRight,
153
+ "bottom-left": bottomLeft
154
+ } = propValue.value || {};
155
+ return `${transform(topLeft) || "unset"} ${transform(topRight) || "unset"} ${transform(bottomRight) || "unset"} ${transform(bottomLeft) || "unset"}`;
156
+ }
157
+ };
158
+ var border_radius_transformer_default = borderRadiusTransformer;
159
+
160
+ // src/styles-renderer/transformers/border-width-transformer.ts
161
+ import { borderWidthPropTypeUtil } from "@elementor/editor-props";
162
+ var borderWidthTransformer = (propValue, { transform }) => {
163
+ if (borderWidthPropTypeUtil.isValid(propValue)) {
164
+ const { top, right, bottom, left } = propValue.value || {};
165
+ return `${transform(top) || "unset"} ${transform(right) || "unset"} ${transform(bottom) || "unset"} ${transform(left) || "unset"}`;
166
+ }
167
+ };
168
+ var border_width_transformer_default = borderWidthTransformer;
169
+
170
+ // src/styles-renderer/transformers/color-transformer.ts
171
+ import { colorPropTypeUtil } from "@elementor/editor-props";
172
+ var colorTransformer = (propValue) => {
173
+ if (colorPropTypeUtil.isValid(propValue)) {
174
+ return propValue.value;
175
+ }
176
+ };
177
+ var color_transformer_default = colorTransformer;
178
+
179
+ // src/styles-renderer/transformers/create-combine-array-transformer.ts
180
+ import { z } from "@elementor/schema";
181
+ var schema = z.object({
182
+ $$type: z.string(),
183
+ value: z.array(z.any())
184
+ });
185
+ var createCombineArrayTransformer = (delimiter) => (propValue, { transform }) => {
186
+ const { success, data } = schema.safeParse(propValue);
187
+ if (success) {
188
+ return data.value.map((item) => transform(item)).join(delimiter);
189
+ }
190
+ };
191
+ var create_combine_array_transformer_default = createCombineArrayTransformer;
192
+
193
+ // src/styles-renderer/transformers/linked-dimensions-transformer.ts
194
+ import { linkedDimensionsPropTypeUtil } from "@elementor/editor-props";
195
+ var linkedDimensionsTransformer = (propValue, { transform }) => {
196
+ if (linkedDimensionsPropTypeUtil.isValid(propValue)) {
197
+ const { top, right, bottom, left } = propValue.value || {};
198
+ return `${transform(top) || "unset"} ${transform(right) || "unset"} ${transform(bottom) || "unset"} ${transform(left) || "unset"}`;
199
+ }
200
+ };
201
+ var linked_dimensions_transformer_default = linkedDimensionsTransformer;
202
+
203
+ // src/styles-renderer/transformers/shadow-transformer.ts
204
+ import { shadowPropTypeUtil } from "@elementor/editor-props";
205
+ var shadowTransformer = (propValue, { transform }) => {
206
+ if (shadowPropTypeUtil.isValid(propValue)) {
207
+ const { position, hOffset, vOffset, blur, spread, color } = propValue.value || {};
208
+ return [
209
+ transform(hOffset),
210
+ transform(vOffset),
211
+ transform(blur),
212
+ transform(spread),
213
+ transform(color),
214
+ position
215
+ ].filter(Boolean).join(" ");
216
+ }
217
+ };
218
+ var shadow_transformer_default = shadowTransformer;
219
+
220
+ // src/styles-renderer/transformers/size-transformer.ts
221
+ import { sizePropTypeUtil } from "@elementor/editor-props";
222
+ var sizeTransformer = (propValue) => {
223
+ if (sizePropTypeUtil.isValid(propValue)) {
224
+ return propValue.value && propValue.value.size + propValue.value.unit;
225
+ }
226
+ };
227
+ var size_transformer_default = sizeTransformer;
228
+
229
+ // src/styles-renderer/transformers/stroke-transformer.ts
230
+ import { strokePropTypeUtil } from "@elementor/editor-props";
231
+ var strokeTransformer = (propValue, { transform }) => {
232
+ if (strokePropTypeUtil.isValid(propValue)) {
233
+ return `${transform(propValue.value?.width)} ${transform(propValue.value?.color)}`;
234
+ }
235
+ };
236
+ var stroke_transformer_default = strokeTransformer;
237
+
238
+ // src/styles-renderer/transformers/index.ts
239
+ var transformers_default = {
240
+ color: color_transformer_default,
241
+ size: size_transformer_default,
242
+ shadow: shadow_transformer_default,
243
+ "border-radius": border_radius_transformer_default,
244
+ "border-width": border_width_transformer_default,
245
+ "box-shadow": create_combine_array_transformer_default(", "),
246
+ "background-image": create_combine_array_transformer_default(", "),
247
+ "linked-dimensions": linked_dimensions_transformer_default,
248
+ stroke: stroke_transformer_default,
249
+ "background-overlay": background_overlay_transformer_default
250
+ };
251
+
252
+ // src/styles-renderer/render.ts
253
+ import { ensureError } from "@elementor/utils";
254
+
255
+ // src/styles-renderer/transform.ts
256
+ import { isTransformable } from "@elementor/editor-props";
257
+ var FALLBACK_VALUE = "unset";
258
+ function transformValue(value, transformers) {
259
+ if (!isTransformable(value)) {
260
+ return value;
261
+ }
262
+ const transformer = transformers[value.$$type];
263
+ if (!transformer) {
264
+ console.error(`Transformer not found for prop type '${value.$$type}'`);
265
+ return FALLBACK_VALUE;
266
+ }
267
+ const transformedValue = transformer(value, {
268
+ transform: (v) => transformValue(v, transformers)
269
+ });
270
+ if (transformedValue === void 0) {
271
+ console.error(`Transformer '${value.$$type}' received unsupported value`);
272
+ return FALLBACK_VALUE;
273
+ }
274
+ return transformValue(transformedValue, transformers);
275
+ }
276
+
277
+ // src/styles-renderer/render.ts
278
+ function render({ transformers, styles, breakpoints }) {
279
+ const cssStyle = [];
280
+ try {
281
+ styles.forEach((styleDef) => {
282
+ const style = renderStyle(styleDef, transformers, breakpoints);
283
+ cssStyle.push(wrapWithStyleElement(styleDef.id, style));
284
+ });
285
+ } catch (error) {
286
+ console.error(`Cannot render style': ${ensureError(error).message}`);
287
+ }
288
+ return cssStyle.join("");
289
+ }
290
+ function renderStyle(style, transformers, breakpoints) {
291
+ const baseSelector = getBaseSelector(style);
292
+ if (!baseSelector) {
293
+ return "";
294
+ }
295
+ const stylesheet = [];
296
+ Object.values(style.variants).forEach((variant) => {
297
+ const styleDeclaration = variantToStyleDeclaration(baseSelector, variant, transformers, breakpoints);
298
+ if (styleDeclaration) {
299
+ stylesheet.push(styleDeclaration);
300
+ }
301
+ });
302
+ return stylesheet.join("");
303
+ }
304
+ function getBaseSelector(styleDef) {
305
+ const map = {
306
+ class: "."
307
+ };
308
+ return `${map[styleDef.type]}${styleDef.id}`;
309
+ }
310
+ function variantToStyleDeclaration(baseSelector, variant, transformers, breakpoints) {
311
+ const css = propsToCss(variant.props, transformers);
312
+ if (!css) {
313
+ return "";
314
+ }
315
+ const state = variant.meta.state ? `:${variant.meta.state}` : "";
316
+ const selector = `${baseSelector}${state}`;
317
+ let styleDeclaration = `${selector}{${css}}`;
318
+ if (variant.meta.breakpoint) {
319
+ styleDeclaration = wrapWithMediaQuery(breakpoints, variant.meta.breakpoint, styleDeclaration);
320
+ }
321
+ return styleDeclaration;
322
+ }
323
+ function propsToCss(props, transformers) {
324
+ return Object.entries(props).reduce((acc, [cssProp, cssValue]) => {
325
+ const prop = camelCaseToDash(cssProp);
326
+ const value = transformValue(cssValue, transformers);
327
+ acc.push(prop + ":" + value);
328
+ return acc;
329
+ }, []).join(";");
330
+ }
331
+ function camelCaseToDash(str) {
332
+ return str.replace(/([a-zA-Z])(?=[A-Z])/g, "$1-").toLowerCase();
333
+ }
334
+ function wrapWithMediaQuery(breakpoints, breakpoint, css) {
335
+ const size2 = getBreakpointSize(breakpoints[breakpoint]);
336
+ return size2 ? `@media(${size2}){${css}}` : css;
337
+ }
338
+ function getBreakpointSize(breakpoint) {
339
+ return breakpoint.type ? `${breakpoint.type}:${breakpoint.width}px` : null;
340
+ }
341
+ function wrapWithStyleElement(id, content) {
342
+ return `<style data-style-id="${id}">${content}</style>`;
343
+ }
344
+
345
+ // src/styles-renderer/enqueue-used-fonts.ts
346
+ import { ensureError as ensureError2 } from "@elementor/utils";
347
+
348
+ // src/sync/enqueue-font.ts
349
+ var enqueueFont = (fontFamily, context = "preview") => {
350
+ const extendedWindow = window;
351
+ return extendedWindow.elementor?.helpers?.enqueueFont?.(fontFamily, context) ?? null;
352
+ };
353
+
354
+ // src/styles-renderer/enqueue-used-fonts.ts
355
+ function enqueueUsedFonts(styles) {
356
+ try {
357
+ styles.forEach((styleDef) => {
358
+ Object.values(styleDef.variants).forEach((variant) => {
359
+ const fontFamily = variant.props["font-family"] ?? null;
360
+ if (fontFamily && typeof fontFamily === "string") {
361
+ enqueueFont(fontFamily);
362
+ }
363
+ });
364
+ });
365
+ } catch (error) {
366
+ console.error(`Cannot enqueue font': ${ensureError2(error).message}`);
367
+ }
368
+ }
369
+
370
+ // src/sync/get-canvas-iframe-body.ts
371
+ function getCanvasIframeBody() {
372
+ const extendedWindow = window;
373
+ return extendedWindow.elementor?.$preview?.[0]?.contentDocument?.body;
374
+ }
375
+
376
+ // src/init-styles-renderer.ts
377
+ var WRAPPER_DATA_ATTR = "data-styles-container";
378
+ function initStylesRenderer() {
379
+ stylesRepository.subscribe(() => {
380
+ const styleContainer = getStylesContainer();
381
+ const styles = Object.values(stylesRepository.all());
382
+ const breakpoints = getBreakpointsMap();
383
+ styleContainer.innerHTML = render({ transformers: transformers_default, styles, breakpoints });
384
+ enqueueUsedFonts(styles);
385
+ });
386
+ }
387
+ function getStylesContainer() {
388
+ const preview = getCanvasIframeBody();
389
+ const stylesContainer = preview?.querySelector(`[${WRAPPER_DATA_ATTR}]`);
390
+ if (stylesContainer) {
391
+ return stylesContainer;
392
+ }
393
+ const el = createStylesContainer();
394
+ preview?.prepend(el);
395
+ return el;
396
+ }
397
+ function createStylesContainer() {
398
+ const el = document.createElement("div");
399
+ el.style.display = "none";
400
+ el.setAttribute(WRAPPER_DATA_ATTR, "");
401
+ return el;
402
+ }
403
+
130
404
  // src/init.tsx
131
405
  function init() {
406
+ initStylesRenderer();
132
407
  injectIntoTop({
133
408
  id: "elements-overlays",
134
409
  component: ElementsOverlays
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/init.tsx","../src/components/elements-overlays.tsx","../src/components/element-overlay.tsx","../src/hooks/use-bind-react-props-to-element.ts","../src/hooks/use-floating-on-element.ts","../src/index.ts"],"sourcesContent":["import { injectIntoTop } from '@elementor/editor';\n\nimport { ElementsOverlays } from './components/elements-overlays';\n\nexport function init() {\n\tinjectIntoTop( {\n\t\tid: 'elements-overlays',\n\t\tcomponent: ElementsOverlays,\n\t} );\n}\n","import * as React from 'react';\nimport { useElementsDomRef, useSelectedElement } from '@elementor/editor-elements';\nimport {\n\t__privateUseIsPreviewMode as useIsPreviewMode,\n\t__privateUseIsRouteActive as useIsRouteActive,\n} from '@elementor/editor-v1-adapters';\n\nimport { ElementOverlay } from './element-overlay';\n\nexport function ElementsOverlays() {\n\tconst selected = useSelectedElement();\n\tconst domElements = useElementsDomRef();\n\n\tconst isPreviewMode = useIsPreviewMode();\n\tconst isKitRouteActive = useIsRouteActive( 'panel/global' );\n\n\tconst isActive = ! isPreviewMode && ! isKitRouteActive;\n\n\treturn (\n\t\tisActive &&\n\t\tdomElements.map( ( el ) => (\n\t\t\t<ElementOverlay\n\t\t\t\telement={ el }\n\t\t\t\tkey={ el.dataset.id }\n\t\t\t\tisSelected={ selected.element?.id === el.dataset.id }\n\t\t\t/>\n\t\t) )\n\t);\n}\n","import * as React from 'react';\nimport { Box, styled } from '@elementor/ui';\nimport { FloatingPortal, useHover, useInteractions } from '@floating-ui/react';\n\nimport { useBindReactPropsToElement } from '../hooks/use-bind-react-props-to-element';\nimport { useFloatingOnElement } from '../hooks/use-floating-on-element';\n\nexport const CANVAS_WRAPPER_ID = 'elementor-preview-responsive-wrapper';\n\ntype Props = {\n\telement: HTMLElement;\n\tisSelected: boolean;\n};\n\nconst OverlayBox = styled( Box, { shouldForwardProp: ( prop ) => prop !== 'isSelected' } )<\n\tPick< Props, 'isSelected' >\n>( ( { theme, isSelected } ) => ( {\n\toutline: `${ isSelected ? '2px' : '1px' } solid ${ theme.palette.primary.light }`,\n\toutlineOffset: isSelected ? '-2px' : '-1px',\n\tpointerEvents: 'none',\n} ) );\n\nexport function ElementOverlay( { element, isSelected }: Props ) {\n\tconst { context, floating, isVisible } = useFloatingOnElement( { element, isSelected } );\n\tconst { getFloatingProps, getReferenceProps } = useInteractions( [ useHover( context ) ] );\n\n\tuseBindReactPropsToElement( element, getReferenceProps );\n\n\treturn (\n\t\tisVisible && (\n\t\t\t<FloatingPortal id={ CANVAS_WRAPPER_ID }>\n\t\t\t\t<OverlayBox\n\t\t\t\t\tref={ floating.setRef }\n\t\t\t\t\tisSelected={ isSelected }\n\t\t\t\t\tstyle={ floating.styles }\n\t\t\t\t\tdata-element-overlay={ element.dataset.id }\n\t\t\t\t\trole=\"presentation\"\n\t\t\t\t\t{ ...getFloatingProps() }\n\t\t\t\t/>\n\t\t\t</FloatingPortal>\n\t\t)\n\t);\n}\n","import { useEffect } from 'react';\n\ntype Props = Record< string, unknown >;\n\nexport function useBindReactPropsToElement( element: HTMLElement, getProps: () => Props ) {\n\tuseEffect( () => {\n\t\tconst el = element;\n\n\t\tconst { events, attrs } = groupProps( getProps() );\n\n\t\tevents.forEach( ( [ eventName, listener ] ) => el.addEventListener( eventName, listener ) );\n\t\tattrs.forEach( ( [ attrName, attrValue ] ) => el.setAttribute( attrName, attrValue ) );\n\n\t\treturn () => {\n\t\t\tevents.forEach( ( [ eventName, listener ] ) => el.removeEventListener( eventName, listener ) );\n\t\t\tattrs.forEach( ( [ attrName ] ) => el.removeAttribute( attrName ) );\n\t\t};\n\t}, [ getProps, element ] );\n}\n\ntype GroupedProps = {\n\tevents: Array< [ string, () => void ] >;\n\tattrs: Array< [ string, string ] >;\n};\n\nfunction groupProps( props: Props ) {\n\tconst eventRegex = /^on(?=[A-Z])/;\n\n\treturn Object.entries( props ).reduce< GroupedProps >(\n\t\t( acc, [ propName, propValue ] ) => {\n\t\t\tif ( ! eventRegex.test( propName ) ) {\n\t\t\t\tacc.attrs.push( [ propName, propValue as string ] );\n\n\t\t\t\treturn acc;\n\t\t\t}\n\n\t\t\tconst eventName = propName.replace( eventRegex, '' ).toLowerCase();\n\t\t\tconst listener = propValue as () => void;\n\n\t\t\tacc.events.push( [ eventName, listener ] );\n\n\t\t\treturn acc;\n\t\t},\n\t\t{\n\t\t\tevents: [],\n\t\t\tattrs: [],\n\t\t}\n\t);\n}\n","import { useState } from 'react';\nimport { autoUpdate, offset, size, useFloating } from '@floating-ui/react';\n\ntype Options = {\n\telement: HTMLElement;\n\tisSelected: boolean;\n};\n\nexport function useFloatingOnElement( { element, isSelected }: Options ) {\n\tconst [ isOpen, setIsOpen ] = useState( false );\n\n\tconst { refs, floatingStyles, context } = useFloating( {\n\t\t// Must be controlled for interactions (like hover) to work.\n\t\topen: isOpen || isSelected,\n\t\tonOpenChange: setIsOpen,\n\n\t\t// Add an animation frame to support scroll events (without it the floating element will stay in the same position).\n\t\twhileElementsMounted: ( ...args ) => autoUpdate( ...args, { animationFrame: true } ),\n\n\t\t// The first element in the canvas is `display: contents` so we need to use the first child.\n\t\telements: { reference: element.firstElementChild },\n\n\t\tmiddleware: [\n\t\t\t// Match the floating element's size to the reference element.\n\t\t\tsize( {\n\t\t\t\tapply( { elements, rects } ) {\n\t\t\t\t\tObject.assign( elements.floating.style, {\n\t\t\t\t\t\twidth: `${ rects.reference.width }px`,\n\t\t\t\t\t\theight: `${ rects.reference.height }px`,\n\t\t\t\t\t} );\n\t\t\t\t},\n\t\t\t} ),\n\n\t\t\t// Center the floating element on the reference element.\n\t\t\toffset( ( { rects } ) => -rects.reference.height / 2 - rects.floating.height / 2 ),\n\t\t],\n\t} );\n\n\treturn {\n\t\tisVisible: isOpen || isSelected,\n\t\tcontext,\n\t\tfloating: {\n\t\t\tsetRef: refs.setFloating,\n\t\t\tref: refs.floating,\n\t\t\tstyles: floatingStyles,\n\t\t},\n\t};\n}\n","import { init } from './init';\n\ninit();\n"],"mappings":"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","names":["React"]}
1
+ {"version":3,"sources":["../src/init.tsx","../src/components/elements-overlays.tsx","../src/components/element-overlay.tsx","../src/hooks/use-bind-react-props-to-element.ts","../src/hooks/use-floating-on-element.ts","../src/init-styles-renderer.ts","../src/styles-renderer/transformers/background-overlay-transformer.ts","../src/styles-renderer/transformers/border-radius-transformer.ts","../src/styles-renderer/transformers/border-width-transformer.ts","../src/styles-renderer/transformers/color-transformer.ts","../src/styles-renderer/transformers/create-combine-array-transformer.ts","../src/styles-renderer/transformers/linked-dimensions-transformer.ts","../src/styles-renderer/transformers/shadow-transformer.ts","../src/styles-renderer/transformers/size-transformer.ts","../src/styles-renderer/transformers/stroke-transformer.ts","../src/styles-renderer/transformers/index.ts","../src/styles-renderer/render.ts","../src/styles-renderer/transform.ts","../src/styles-renderer/enqueue-used-fonts.ts","../src/sync/enqueue-font.ts","../src/sync/get-canvas-iframe-body.ts","../src/index.ts"],"sourcesContent":["import { injectIntoTop } from '@elementor/editor';\n\nimport { ElementsOverlays } from './components/elements-overlays';\nimport { initStylesRenderer } from './init-styles-renderer';\n\nexport function init() {\n\tinitStylesRenderer();\n\n\tinjectIntoTop( {\n\t\tid: 'elements-overlays',\n\t\tcomponent: ElementsOverlays,\n\t} );\n}\n","import * as React from 'react';\nimport { useElementsDomRef, useSelectedElement } from '@elementor/editor-elements';\nimport {\n\t__privateUseIsPreviewMode as useIsPreviewMode,\n\t__privateUseIsRouteActive as useIsRouteActive,\n} from '@elementor/editor-v1-adapters';\n\nimport { ElementOverlay } from './element-overlay';\n\nexport function ElementsOverlays() {\n\tconst selected = useSelectedElement();\n\tconst domElements = useElementsDomRef();\n\n\tconst isPreviewMode = useIsPreviewMode();\n\tconst isKitRouteActive = useIsRouteActive( 'panel/global' );\n\n\tconst isActive = ! isPreviewMode && ! isKitRouteActive;\n\n\treturn (\n\t\tisActive &&\n\t\tdomElements.map( ( el ) => (\n\t\t\t<ElementOverlay\n\t\t\t\telement={ el }\n\t\t\t\tkey={ el.dataset.id }\n\t\t\t\tisSelected={ selected.element?.id === el.dataset.id }\n\t\t\t/>\n\t\t) )\n\t);\n}\n","import * as React from 'react';\nimport { Box, styled } from '@elementor/ui';\nimport { FloatingPortal, useHover, useInteractions } from '@floating-ui/react';\n\nimport { useBindReactPropsToElement } from '../hooks/use-bind-react-props-to-element';\nimport { useFloatingOnElement } from '../hooks/use-floating-on-element';\n\nexport const CANVAS_WRAPPER_ID = 'elementor-preview-responsive-wrapper';\n\ntype Props = {\n\telement: HTMLElement;\n\tisSelected: boolean;\n};\n\nconst OverlayBox = styled( Box, { shouldForwardProp: ( prop ) => prop !== 'isSelected' } )<\n\tPick< Props, 'isSelected' >\n>( ( { theme, isSelected } ) => ( {\n\toutline: `${ isSelected ? '2px' : '1px' } solid ${ theme.palette.primary.light }`,\n\toutlineOffset: isSelected ? '-2px' : '-1px',\n\tpointerEvents: 'none',\n} ) );\n\nexport function ElementOverlay( { element, isSelected }: Props ) {\n\tconst { context, floating, isVisible } = useFloatingOnElement( { element, isSelected } );\n\tconst { getFloatingProps, getReferenceProps } = useInteractions( [ useHover( context ) ] );\n\n\tuseBindReactPropsToElement( element, getReferenceProps );\n\n\treturn (\n\t\tisVisible && (\n\t\t\t<FloatingPortal id={ CANVAS_WRAPPER_ID }>\n\t\t\t\t<OverlayBox\n\t\t\t\t\tref={ floating.setRef }\n\t\t\t\t\tisSelected={ isSelected }\n\t\t\t\t\tstyle={ floating.styles }\n\t\t\t\t\tdata-element-overlay={ element.dataset.id }\n\t\t\t\t\trole=\"presentation\"\n\t\t\t\t\t{ ...getFloatingProps() }\n\t\t\t\t/>\n\t\t\t</FloatingPortal>\n\t\t)\n\t);\n}\n","import { useEffect } from 'react';\n\ntype Props = Record< string, unknown >;\n\nexport function useBindReactPropsToElement( element: HTMLElement, getProps: () => Props ) {\n\tuseEffect( () => {\n\t\tconst el = element;\n\n\t\tconst { events, attrs } = groupProps( getProps() );\n\n\t\tevents.forEach( ( [ eventName, listener ] ) => el.addEventListener( eventName, listener ) );\n\t\tattrs.forEach( ( [ attrName, attrValue ] ) => el.setAttribute( attrName, attrValue ) );\n\n\t\treturn () => {\n\t\t\tevents.forEach( ( [ eventName, listener ] ) => el.removeEventListener( eventName, listener ) );\n\t\t\tattrs.forEach( ( [ attrName ] ) => el.removeAttribute( attrName ) );\n\t\t};\n\t}, [ getProps, element ] );\n}\n\ntype GroupedProps = {\n\tevents: Array< [ string, () => void ] >;\n\tattrs: Array< [ string, string ] >;\n};\n\nfunction groupProps( props: Props ) {\n\tconst eventRegex = /^on(?=[A-Z])/;\n\n\treturn Object.entries( props ).reduce< GroupedProps >(\n\t\t( acc, [ propName, propValue ] ) => {\n\t\t\tif ( ! eventRegex.test( propName ) ) {\n\t\t\t\tacc.attrs.push( [ propName, propValue as string ] );\n\n\t\t\t\treturn acc;\n\t\t\t}\n\n\t\t\tconst eventName = propName.replace( eventRegex, '' ).toLowerCase();\n\t\t\tconst listener = propValue as () => void;\n\n\t\t\tacc.events.push( [ eventName, listener ] );\n\n\t\t\treturn acc;\n\t\t},\n\t\t{\n\t\t\tevents: [],\n\t\t\tattrs: [],\n\t\t}\n\t);\n}\n","import { useState } from 'react';\nimport { autoUpdate, offset, size, useFloating } from '@floating-ui/react';\n\ntype Options = {\n\telement: HTMLElement;\n\tisSelected: boolean;\n};\n\nexport function useFloatingOnElement( { element, isSelected }: Options ) {\n\tconst [ isOpen, setIsOpen ] = useState( false );\n\n\tconst { refs, floatingStyles, context } = useFloating( {\n\t\t// Must be controlled for interactions (like hover) to work.\n\t\topen: isOpen || isSelected,\n\t\tonOpenChange: setIsOpen,\n\n\t\t// Add an animation frame to support scroll events (without it the floating element will stay in the same position).\n\t\twhileElementsMounted: ( ...args ) => autoUpdate( ...args, { animationFrame: true } ),\n\n\t\t// The first element in the canvas is `display: contents` so we need to use the first child.\n\t\telements: { reference: element.firstElementChild },\n\n\t\tmiddleware: [\n\t\t\t// Match the floating element's size to the reference element.\n\t\t\tsize( {\n\t\t\t\tapply( { elements, rects } ) {\n\t\t\t\t\tObject.assign( elements.floating.style, {\n\t\t\t\t\t\twidth: `${ rects.reference.width }px`,\n\t\t\t\t\t\theight: `${ rects.reference.height }px`,\n\t\t\t\t\t} );\n\t\t\t\t},\n\t\t\t} ),\n\n\t\t\t// Center the floating element on the reference element.\n\t\t\toffset( ( { rects } ) => -rects.reference.height / 2 - rects.floating.height / 2 ),\n\t\t],\n\t} );\n\n\treturn {\n\t\tisVisible: isOpen || isSelected,\n\t\tcontext,\n\t\tfloating: {\n\t\t\tsetRef: refs.setFloating,\n\t\t\tref: refs.floating,\n\t\t\tstyles: floatingStyles,\n\t\t},\n\t};\n}\n","import { getBreakpointsMap } from '@elementor/editor-responsive';\nimport { stylesRepository } from '@elementor/editor-styles-repository';\n\nimport { render, transformers } from './styles-renderer';\nimport enqueueUsedFonts from './styles-renderer/enqueue-used-fonts';\nimport { getCanvasIframeBody } from './sync/get-canvas-iframe-body';\n\nconst WRAPPER_DATA_ATTR = 'data-styles-container';\n\nexport function initStylesRenderer() {\n\tstylesRepository.subscribe( () => {\n\t\tconst styleContainer = getStylesContainer();\n\t\tconst styles = Object.values( stylesRepository.all() );\n\t\tconst breakpoints = getBreakpointsMap();\n\n\t\tstyleContainer.innerHTML = render( { transformers, styles, breakpoints } );\n\n\t\tenqueueUsedFonts( styles );\n\t} );\n}\n\nfunction getStylesContainer() {\n\tconst preview = getCanvasIframeBody();\n\tconst stylesContainer = preview?.querySelector( `[${ WRAPPER_DATA_ATTR }]` );\n\n\tif ( stylesContainer ) {\n\t\treturn stylesContainer;\n\t}\n\n\tconst el = createStylesContainer();\n\n\tpreview?.prepend( el );\n\n\treturn el;\n}\n\nfunction createStylesContainer() {\n\tconst el = document.createElement( 'div' );\n\tel.style.display = 'none';\n\tel.setAttribute( WRAPPER_DATA_ATTR, '' );\n\n\treturn el;\n}\n","import { colorGradientPropTypeUtil } from '@elementor/editor-props';\n\nimport { type Transformer } from '../types';\n\nconst backgroundOverlayTransformer: Transformer = ( propValue, { transform } ) => {\n\tif ( colorGradientPropTypeUtil.isValid( propValue ) ) {\n\t\treturn `linear-gradient( ${ [ transform( propValue.value.color ) ] }, ${ [\n\t\t\ttransform( propValue.value.color ),\n\t\t] } )`;\n\t}\n};\n\nexport default backgroundOverlayTransformer;\n","import { borderRadiusPropTypeUtil } from '@elementor/editor-props';\n\nimport { type Transformer } from '../types';\n\nconst borderRadiusTransformer: Transformer = ( propValue, { transform } ) => {\n\tif ( borderRadiusPropTypeUtil.isValid( propValue ) ) {\n\t\tconst {\n\t\t\t'top-left': topLeft,\n\t\t\t'top-right': topRight,\n\t\t\t'bottom-right': bottomRight,\n\t\t\t'bottom-left': bottomLeft,\n\t\t} = propValue.value || {};\n\n\t\treturn `${ transform( topLeft ) || 'unset' } ${ transform( topRight ) || 'unset' } ${\n\t\t\ttransform( bottomRight ) || 'unset'\n\t\t} ${ transform( bottomLeft ) || 'unset' }`;\n\t}\n};\n\nexport default borderRadiusTransformer;\n","import { borderWidthPropTypeUtil } from '@elementor/editor-props';\n\nimport { type Transformer } from '../types';\n\nconst borderWidthTransformer: Transformer = ( propValue, { transform } ) => {\n\tif ( borderWidthPropTypeUtil.isValid( propValue ) ) {\n\t\tconst { top, right, bottom, left } = propValue.value || {};\n\n\t\treturn `${ transform( top ) || 'unset' } ${ transform( right ) || 'unset' } ${\n\t\t\ttransform( bottom ) || 'unset'\n\t\t} ${ transform( left ) || 'unset' }`;\n\t}\n};\n\nexport default borderWidthTransformer;\n","import { colorPropTypeUtil } from '@elementor/editor-props';\n\nimport { type Transformer } from '../types';\n\nconst colorTransformer: Transformer = ( propValue ) => {\n\tif ( colorPropTypeUtil.isValid( propValue ) ) {\n\t\treturn propValue.value;\n\t}\n};\n\nexport default colorTransformer;\n","import { z } from '@elementor/schema';\n\nimport { type Transformer } from '../types';\n\nexport const schema = z.object( {\n\t$$type: z.string(),\n\tvalue: z.array( z.any() ),\n} );\n\nconst createCombineArrayTransformer =\n\t( delimiter: string ): Transformer =>\n\t( propValue, { transform } ) => {\n\t\tconst { success, data } = schema.safeParse( propValue );\n\n\t\tif ( success ) {\n\t\t\treturn data.value.map( ( item ) => transform( item ) ).join( delimiter );\n\t\t}\n\t};\n\nexport default createCombineArrayTransformer;\n","import { linkedDimensionsPropTypeUtil } from '@elementor/editor-props';\n\nimport { type Transformer } from '../types';\n\nconst linkedDimensionsTransformer: Transformer = ( propValue, { transform } ) => {\n\tif ( linkedDimensionsPropTypeUtil.isValid( propValue ) ) {\n\t\tconst { top, right, bottom, left } = propValue.value || {};\n\n\t\treturn `${ transform( top ) || 'unset' } ${ transform( right ) || 'unset' } ${\n\t\t\ttransform( bottom ) || 'unset'\n\t\t} ${ transform( left ) || 'unset' }`;\n\t}\n};\n\nexport default linkedDimensionsTransformer;\n","import { shadowPropTypeUtil } from '@elementor/editor-props';\n\nimport { type Transformer } from '../types';\n\nconst shadowTransformer: Transformer = ( propValue, { transform } ) => {\n\tif ( shadowPropTypeUtil.isValid( propValue ) ) {\n\t\tconst { position, hOffset, vOffset, blur, spread, color } = propValue.value || {};\n\n\t\treturn [\n\t\t\ttransform( hOffset ),\n\t\t\ttransform( vOffset ),\n\t\t\ttransform( blur ),\n\t\t\ttransform( spread ),\n\t\t\ttransform( color ),\n\t\t\tposition,\n\t\t]\n\t\t\t.filter( Boolean )\n\t\t\t.join( ' ' );\n\t}\n};\n\nexport default shadowTransformer;\n","import { sizePropTypeUtil } from '@elementor/editor-props';\n\nimport { type Transformer } from '../types';\n\nconst sizeTransformer: Transformer = ( propValue ) => {\n\tif ( sizePropTypeUtil.isValid( propValue ) ) {\n\t\treturn propValue.value && propValue.value.size + propValue.value.unit;\n\t}\n};\n\nexport default sizeTransformer;\n","import { strokePropTypeUtil } from '@elementor/editor-props';\n\nimport { type Transformer } from '../types';\n\nconst strokeTransformer: Transformer = ( propValue, { transform } ) => {\n\tif ( strokePropTypeUtil.isValid( propValue ) ) {\n\t\treturn `${ transform( propValue.value?.width ) } ${ transform( propValue.value?.color ) }`;\n\t}\n};\n\nexport default strokeTransformer;\n","import { default as backgroundOverlay } from './background-overlay-transformer';\nimport { default as borderRadius } from './border-radius-transformer';\nimport { default as borderWidth } from './border-width-transformer';\nimport { default as color } from './color-transformer';\nimport { default as createCombineArrayTransformer } from './create-combine-array-transformer';\nimport { default as linkedDimensions } from './linked-dimensions-transformer';\nimport { default as shadow } from './shadow-transformer';\nimport { default as size } from './size-transformer';\nimport { default as stroke } from './stroke-transformer';\n\nexport default {\n\tcolor,\n\tsize,\n\tshadow,\n\t'border-radius': borderRadius,\n\t'border-width': borderWidth,\n\t'box-shadow': createCombineArrayTransformer( ', ' ),\n\t'background-image': createCombineArrayTransformer( ', ' ),\n\t'linked-dimensions': linkedDimensions,\n\tstroke,\n\t'background-overlay': backgroundOverlay,\n};\n","import { type Props } from '@elementor/editor-props';\nimport { type Breakpoint, type BreakpointId, type BreakpointsMap } from '@elementor/editor-responsive';\nimport { type StyleDefinition, type StyleVariant } from '@elementor/editor-styles';\nimport { ensureError } from '@elementor/utils';\n\nimport { transformValue } from './transform';\nimport { type TransformersMap } from './types';\n\ntype RenderParams = {\n\ttransformers: TransformersMap;\n\tstyles: StyleDefinition[];\n\tbreakpoints: BreakpointsMap;\n};\n\nexport default function render( { transformers, styles, breakpoints }: RenderParams ) {\n\tconst cssStyle: string[] = [];\n\n\ttry {\n\t\tstyles.forEach( ( styleDef ) => {\n\t\t\tconst style = renderStyle( styleDef, transformers, breakpoints );\n\n\t\t\tcssStyle.push( wrapWithStyleElement( styleDef.id, style ) );\n\t\t} );\n\t} catch ( error: unknown ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( `Cannot render style': ${ ensureError( error ).message }` );\n\t}\n\n\treturn cssStyle.join( '' );\n}\n\nfunction renderStyle( style: StyleDefinition, transformers: TransformersMap, breakpoints: BreakpointsMap ) {\n\tconst baseSelector = getBaseSelector( style );\n\n\tif ( ! baseSelector ) {\n\t\treturn '';\n\t}\n\n\tconst stylesheet: string[] = [];\n\n\tObject.values( style.variants ).forEach( ( variant ) => {\n\t\tconst styleDeclaration = variantToStyleDeclaration( baseSelector, variant, transformers, breakpoints );\n\n\t\tif ( styleDeclaration ) {\n\t\t\tstylesheet.push( styleDeclaration );\n\t\t}\n\t} );\n\n\treturn stylesheet.join( '' );\n}\n\nfunction getBaseSelector( styleDef: StyleDefinition ) {\n\tconst map = {\n\t\tclass: '.',\n\t};\n\n\treturn `${ map[ styleDef.type ] }${ styleDef.id }`;\n}\n\nfunction variantToStyleDeclaration(\n\tbaseSelector: string,\n\tvariant: StyleVariant,\n\ttransformers: TransformersMap,\n\tbreakpoints: BreakpointsMap\n) {\n\tconst css = propsToCss( variant.props, transformers );\n\n\tif ( ! css ) {\n\t\treturn '';\n\t}\n\n\tconst state = variant.meta.state ? `:${ variant.meta.state }` : '';\n\tconst selector = `${ baseSelector }${ state }`;\n\n\tlet styleDeclaration = `${ selector }{${ css }}`;\n\n\tif ( variant.meta.breakpoint ) {\n\t\tstyleDeclaration = wrapWithMediaQuery( breakpoints, variant.meta.breakpoint, styleDeclaration );\n\t}\n\n\treturn styleDeclaration;\n}\n\nfunction propsToCss( props: Props, transformers: TransformersMap ) {\n\treturn Object.entries( props )\n\t\t.reduce< string[] >( ( acc, [ cssProp, cssValue ] ) => {\n\t\t\tconst prop = camelCaseToDash( cssProp );\n\t\t\tconst value = transformValue( cssValue, transformers );\n\n\t\t\tacc.push( prop + ':' + value );\n\n\t\t\treturn acc;\n\t\t}, [] )\n\t\t.join( ';' );\n}\n\nfunction camelCaseToDash( str: string ) {\n\treturn str.replace( /([a-zA-Z])(?=[A-Z])/g, '$1-' ).toLowerCase();\n}\n\nfunction wrapWithMediaQuery( breakpoints: BreakpointsMap, breakpoint: BreakpointId, css: string ) {\n\tconst size = getBreakpointSize( breakpoints[ breakpoint ] );\n\treturn size ? `@media(${ size }){${ css }}` : css;\n}\n\nfunction getBreakpointSize( breakpoint: Breakpoint ) {\n\treturn breakpoint.type ? `${ breakpoint.type }:${ breakpoint.width }px` : null;\n}\n\nfunction wrapWithStyleElement( id: string, content: string ) {\n\treturn `<style data-style-id=\"${ id }\">${ content }</style>`;\n}\n","import { isTransformable, type PropValue } from '@elementor/editor-props';\n\nimport { type TransformersMap } from './types';\n\nconst FALLBACK_VALUE = 'unset';\n\nexport function transformValue( value: PropValue | undefined, transformers: TransformersMap ): PropValue {\n\tif ( ! isTransformable( value ) ) {\n\t\treturn value;\n\t}\n\n\tconst transformer = transformers[ value.$$type ];\n\n\tif ( ! transformer ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( `Transformer not found for prop type '${ value.$$type }'` );\n\n\t\treturn FALLBACK_VALUE;\n\t}\n\n\tconst transformedValue = transformer( value, {\n\t\ttransform: ( v ) => transformValue( v, transformers ),\n\t} );\n\n\tif ( transformedValue === undefined ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( `Transformer '${ value.$$type }' received unsupported value` );\n\n\t\treturn FALLBACK_VALUE;\n\t}\n\n\t// Transform recursively to support transformers that return transformable values.\n\treturn transformValue( transformedValue, transformers );\n}\n","import { type StyleDefinition } from '@elementor/editor-styles';\nimport { ensureError } from '@elementor/utils';\n\nimport { enqueueFont } from '../sync/enqueue-font';\n\nexport default function enqueueUsedFonts( styles: StyleDefinition[] ) {\n\ttry {\n\t\tstyles.forEach( ( styleDef ) => {\n\t\t\tObject.values( styleDef.variants ).forEach( ( variant ) => {\n\t\t\t\tconst fontFamily = variant.props[ 'font-family' ] ?? null;\n\n\t\t\t\tif ( fontFamily && typeof fontFamily === 'string' ) {\n\t\t\t\t\tenqueueFont( fontFamily );\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t} catch ( error: unknown ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( `Cannot enqueue font': ${ ensureError( error ).message }` );\n\t}\n}\n","import { type CanvasExtendedWindow, type EnqueueFont } from './types';\n\nexport const enqueueFont: EnqueueFont = ( fontFamily, context = 'preview' ) => {\n\tconst extendedWindow = window as unknown as CanvasExtendedWindow;\n\n\treturn extendedWindow.elementor?.helpers?.enqueueFont?.( fontFamily, context ) ?? null;\n};\n","import type { CanvasExtendedWindow } from './types';\n\nexport function getCanvasIframeBody() {\n\tconst extendedWindow = window as unknown as CanvasExtendedWindow;\n\n\treturn extendedWindow.elementor?.$preview?.[ 0 ]?.contentDocument?.body;\n}\n","import { init } from './init';\n\ninit();\n"],"mappings":"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","names":["React","size","ensureError","ensureError"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elementor/editor-canvas",
3
3
  "description": "Elementor Editor Canvas",
4
- "version": "0.1.0",
4
+ "version": "0.2.0",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -36,10 +36,15 @@
36
36
  "react": "^18.3.1"
37
37
  },
38
38
  "dependencies": {
39
- "@elementor/editor": "^0.17.0",
40
- "@elementor/ui": "^1.21.9",
39
+ "@elementor/editor": "^0.17.1",
40
+ "@elementor/ui": "^1.22.0",
41
41
  "@floating-ui/react": "^0.26.28",
42
- "@elementor/editor-elements": "^0.3.0",
43
- "@elementor/editor-v1-adapters": "^0.8.4"
42
+ "@elementor/editor-elements": "^0.3.1",
43
+ "@elementor/editor-v1-adapters": "^0.8.4",
44
+ "@elementor/editor-props": "^0.3.0",
45
+ "@elementor/schema": "^0.1.2",
46
+ "@elementor/utils": "^0.3.0",
47
+ "@elementor/editor-styles-repository": "^0.1.0",
48
+ "@elementor/editor-responsive": "^0.12.3"
44
49
  }
45
50
  }
@@ -0,0 +1,69 @@
1
+ import { createDOMElement, createMockStyleDefinition } from 'test-utils';
2
+ import { type BreakpointsMap, getBreakpointsMap } from '@elementor/editor-responsive';
3
+ import { stylesRepository } from '@elementor/editor-styles-repository';
4
+
5
+ import { initStylesRenderer } from '../init-styles-renderer';
6
+ import { render, transformers } from '../styles-renderer';
7
+ import { getCanvasIframeBody } from '../sync/get-canvas-iframe-body';
8
+
9
+ jest.mock( '@elementor/editor-styles-repository' );
10
+ jest.mock( '@elementor/editor-responsive' );
11
+ jest.mock( '../styles-renderer/index' );
12
+ jest.mock( '../sync/get-canvas-iframe-body' );
13
+
14
+ describe( 'initStylesRenderer', () => {
15
+ it( 'should trigger styles render on each change in the styles repo', () => {
16
+ // Arrange.
17
+ let triggerStylesChange = () => {};
18
+ const mockStyleDef = createMockStyleDefinition();
19
+
20
+ jest.mocked( stylesRepository.subscribe ).mockImplementation( ( cb ) => ( triggerStylesChange = cb ) );
21
+ jest.mocked( stylesRepository.all ).mockReturnValue( { [ mockStyleDef.id ]: mockStyleDef } );
22
+ jest.mocked( getBreakpointsMap ).mockReturnValue( {
23
+ mobile: { id: 'mobile', label: 'Mobile' },
24
+ } as BreakpointsMap );
25
+
26
+ // Act.
27
+ initStylesRenderer();
28
+
29
+ triggerStylesChange();
30
+
31
+ // Assert.
32
+ expect( render ).toHaveBeenCalledTimes( 1 );
33
+ expect( render ).toHaveBeenCalledWith( {
34
+ transformers,
35
+ styles: [ mockStyleDef ],
36
+ breakpoints: { mobile: { id: 'mobile', label: 'Mobile' } },
37
+ } );
38
+ } );
39
+
40
+ it( 'should create a style container and fill it with render result', () => {
41
+ // Arrange.
42
+ const wrapperEl = createDOMElement( { tag: 'div' } );
43
+ let triggerStylesChange = () => {};
44
+
45
+ jest.mocked( stylesRepository.subscribe ).mockImplementation( ( cb ) => ( triggerStylesChange = cb ) );
46
+ jest.mocked( getCanvasIframeBody ).mockReturnValue( wrapperEl );
47
+ jest.mocked( render ).mockReturnValue( '.a { color: red; }' );
48
+
49
+ // Act.
50
+ initStylesRenderer();
51
+
52
+ triggerStylesChange();
53
+
54
+ // Assert.
55
+ expect( wrapperEl.innerHTML ).toEqual(
56
+ '<div style="display: none;" data-styles-container="">.a { color: red; }</div>'
57
+ );
58
+
59
+ // Act.
60
+ jest.mocked( render ).mockImplementation( () => '.a { color: red; display: block; }' );
61
+
62
+ triggerStylesChange();
63
+
64
+ // Assert.
65
+ expect( wrapperEl.innerHTML ).toEqual(
66
+ '<div style="display: none;" data-styles-container="">.a { color: red; display: block; }</div>'
67
+ );
68
+ } );
69
+ } );
@@ -0,0 +1,43 @@
1
+ import { getBreakpointsMap } from '@elementor/editor-responsive';
2
+ import { stylesRepository } from '@elementor/editor-styles-repository';
3
+
4
+ import { render, transformers } from './styles-renderer';
5
+ import enqueueUsedFonts from './styles-renderer/enqueue-used-fonts';
6
+ import { getCanvasIframeBody } from './sync/get-canvas-iframe-body';
7
+
8
+ const WRAPPER_DATA_ATTR = 'data-styles-container';
9
+
10
+ export function initStylesRenderer() {
11
+ stylesRepository.subscribe( () => {
12
+ const styleContainer = getStylesContainer();
13
+ const styles = Object.values( stylesRepository.all() );
14
+ const breakpoints = getBreakpointsMap();
15
+
16
+ styleContainer.innerHTML = render( { transformers, styles, breakpoints } );
17
+
18
+ enqueueUsedFonts( styles );
19
+ } );
20
+ }
21
+
22
+ function getStylesContainer() {
23
+ const preview = getCanvasIframeBody();
24
+ const stylesContainer = preview?.querySelector( `[${ WRAPPER_DATA_ATTR }]` );
25
+
26
+ if ( stylesContainer ) {
27
+ return stylesContainer;
28
+ }
29
+
30
+ const el = createStylesContainer();
31
+
32
+ preview?.prepend( el );
33
+
34
+ return el;
35
+ }
36
+
37
+ function createStylesContainer() {
38
+ const el = document.createElement( 'div' );
39
+ el.style.display = 'none';
40
+ el.setAttribute( WRAPPER_DATA_ATTR, '' );
41
+
42
+ return el;
43
+ }
package/src/init.tsx CHANGED
@@ -1,8 +1,11 @@
1
1
  import { injectIntoTop } from '@elementor/editor';
2
2
 
3
3
  import { ElementsOverlays } from './components/elements-overlays';
4
+ import { initStylesRenderer } from './init-styles-renderer';
4
5
 
5
6
  export function init() {
7
+ initStylesRenderer();
8
+
6
9
  injectIntoTop( {
7
10
  id: 'elements-overlays',
8
11
  component: ElementsOverlays,