PluginProbe
Extendify / 3.1.6
Extendify v3.1.6
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / src / Agent / hooks / useVariationOverride.js

useVariationOverride.js in Extendify 3.1.6, at src/Agent/hooks/useVariationOverride.js

112 lines 3.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { refreshBlockHighlight } from '@agent/lib/block-highlight';
2 import { getDynamicDuotoneMap } from '@agent/lib/svg-blocks-scanner';
3 import { replaceDuotoneSVG } from '@agent/lib/svg-helpers';
4 import { parse } from '@wordpress/blocks';
5 import { useSelect } from '@wordpress/data';
6 import { useCallback, useEffect, useRef, useState } from '@wordpress/element';
7
8 const id = 'global-styles-inline-css';
9 const path = window.location.pathname;
10 const s = new URLSearchParams(window.location.search);
11 const onEditor =
12 path.includes('/wp-admin/post.php') && s.get('action') === 'edit';
13
14 export const useVariationOverride = ({ css, duotoneTheme }) => {
15 const frontStyles = useRef(null);
16 const duotoneCleanup = useRef(null);
17 const [theDocument, setDocument] = useState(null);
18
19 useEffect(() => {
20 if (!css || onEditor) return;
21 const style = document.getElementById(id);
22 if (!style) return;
23 if (!frontStyles.current) {
24 frontStyles.current = style.innerHTML;
25 }
26 style.innerHTML = css;
27 refreshBlockHighlight();
28 }, [css]);
29
30 // Handle the editor
31 useEffect(() => {
32 if (!css || !theDocument || !onEditor) return;
33 const style = theDocument.getElementById(id);
34 const hasIframe = document.querySelector('iframe[name="editor-canvas"]');
35 style.innerHTML = css.replaceAll(
36 ':root',
37 // If the iframe was removed, target the editor the old way
38 hasIframe ? ':root' : '.editor-styles-wrapper',
39 );
40 }, [css, theDocument]);
41
42 useEffect(() => {
43 if (theDocument) return;
44 const timer = setTimeout(() => {
45 if (theDocument) return;
46 const frame = document.querySelector('iframe[name="editor-canvas"]');
47 const doc = frame?.contentDocument || document;
48 if (!doc || !doc.body) return;
49 // Add a tag to the body
50 const newStyle = doc.createElement('style');
51 newStyle.id = id;
52 doc.body.appendChild(newStyle);
53 setDocument(doc);
54 }, 300); // wait for iframe
55 return () => clearTimeout(timer);
56 }, [theDocument]);
57
58 const dynamicDuotone = useSelect((select) => {
59 let blocks = select('core/block-editor')?.getBlocks?.() ?? [];
60
61 const hasShowTemplateOn = blocks.find(
62 (block) => block.name === 'core/template-part',
63 );
64
65 if (hasShowTemplateOn) {
66 const { getEditedPostContent } = select('core/editor');
67 blocks = parse(getEditedPostContent(), {});
68 }
69
70 return getDynamicDuotoneMap(blocks);
71 }, []);
72
73 // Handle duotone changes
74 useEffect(() => {
75 if (!duotoneTheme) return;
76
77 // Clean up previous duotone changes
78 if (duotoneCleanup.current) {
79 duotoneCleanup.current();
80 duotoneCleanup.current = null;
81 }
82
83 // Apply new duotone changes and store cleanup
84 duotoneCleanup.current = replaceDuotoneSVG({
85 duotoneTheme,
86 dynamicDuotone,
87 });
88 }, [css, duotoneTheme, dynamicDuotone]);
89
90 const undoChange = useCallback(() => {
91 // Revert duotone changes
92 if (duotoneCleanup.current) {
93 duotoneCleanup.current();
94 duotoneCleanup.current = null;
95 }
96
97 // Revert CSS changes
98 const style = document.getElementById(id);
99 if (style && frontStyles.current) {
100 style.innerHTML = frontStyles.current;
101 }
102
103 // Remove editor CSS
104 if (!onEditor) return;
105 const iframe = document.querySelector('iframe[name="editor-canvas"]');
106 const doc = iframe?.contentDocument || document;
107 doc?.getElementById(id)?.remove();
108 }, []);
109
110 return { undoChange };
111 };
112