PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 2.2.2
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v2.2.2
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
betterdocs / public / js / style-handler.js

style-handler.js in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 2.2.2, at public/js/style-handler.js

225 lines 6.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 //Generate Styles
2 (() => {
3 /**
4 * WordPress Dependencies
5 */
6 const { select, subscribe } = wp.data;
7 const { isFunction } = lodash;
8 const { parse, isReusableBlock, isTemplatePart } = wp.blocks;
9
10 const { editor_type } = betterdocs_style_handler;
11
12 const makeIdOfTemplatePart = (theme, slug) =>
13 theme && slug ? theme + "//" + slug : null;
14 const emptyFuns = () => {};
15
16 let ebEditGetPreviewDeviceType = false;
17
18 if (editor_type === "edit-site") {
19 //
20 ebEditGetPreviewDeviceType =
21 select("core/edit-site").__experimentalGetPreviewDeviceType;
22 } else if (editor_type === "edit-post") {
23 //
24 ebEditGetPreviewDeviceType =
25 select("core/edit-post").__experimentalGetPreviewDeviceType;
26 }
27
28 window.ebEditCurrentPreviewOption = ebEditGetPreviewDeviceType();
29
30 const {
31 isSavingPost = emptyFuns,
32 isAutosavingPost = emptyFuns,
33 isSavingNonPostEntityChanges = emptyFuns,
34 } = select("core/editor");
35
36 const regexForBlockNameTest = /^betterdocs\//g;
37
38 //
39 const generateAndSendStyleToBackend = () => {
40 const { getEditedEntityRecord = emptyFuns } = select("core");
41 const { getBlocks = emptyFuns } = select("core/block-editor");
42 const { getCurrentPostId = emptyFuns } = select("core/editor");
43 const post_id = getCurrentPostId();
44 const all_blocks = getBlocks();
45
46 const styles = {};
47 const cssObjectMaker = (blocks) => {
48 for (const item of blocks) {
49 const {
50 attributes: { blockMeta, blockRoot, blockId },
51 innerBlocks,
52 } = item;
53 if (isFunction(isReusableBlock) && isReusableBlock(item)) {
54 const reusableBlock = getEditedEntityRecord(
55 "postType",
56 "wp_block",
57 item.attributes.ref
58 );
59 const parsedBlocks = !isEmpty(reusableBlock)
60 ? parse(
61 isFunction(reusableBlock.content)
62 ? reusableBlock.content(reusableBlock)
63 : reusableBlock.content
64 )
65 : false;
66
67 if (parsedBlocks) {
68 for (const blockItem of parsedBlocks) {
69 const {
70 attributes: { blockMeta, blockRoot, blockId },
71 innerBlocks,
72 } = blockItem;
73 if (blockMeta && blockRoot === "better_docs") {
74 styles[blockId] = blockMeta;
75 }
76 if (innerBlocks.length > 0) {
77 cssObjectMaker(innerBlocks);
78 }
79 }
80 }
81 } else if (isFunction(isTemplatePart) && isTemplatePart(item)) {
82 const { theme, slug } = item.attributes;
83
84 const templatePartEntity = getEditedEntityRecord(
85 "postType",
86 "wp_template_part",
87 makeIdOfTemplatePart(theme, slug)
88 );
89
90 const { blocks = [], innerBlocks = [] } = templatePartEntity;
91 cssObjectMaker(blocks);
92 cssObjectMaker(innerBlocks);
93 } else if (blockMeta && blockRoot === "better_docs") {
94 styles[blockId] = blockMeta;
95 }
96 if (innerBlocks.length > 0) {
97 cssObjectMaker(innerBlocks);
98 }
99 }
100 };
101
102 cssObjectMaker(all_blocks); // Call function
103
104 const stringStyles = JSON.stringify(styles);
105
106 jQuery.ajax({
107 type: "POST",
108 url: ajaxurl,
109 data: {
110 data: stringStyles,
111 id: post_id,
112 editorType: editor_type,
113 action: "betterdocs_write_block_css",
114 nonce: betterdocs_style_handler.sth_nonce,
115 },
116 error: function (msg) {
117 console.log(msg);
118 },
119 });
120 };
121
122 const callBackFuncOnPreviewChange = () => {
123 if (window.ebEditCurrentPreviewOption !== ebEditGetPreviewDeviceType()) {
124 const newDeviceType = ebEditGetPreviewDeviceType();
125
126 // the following line of code should be at the top of this if statement
127 window.ebEditCurrentPreviewOption = newDeviceType;
128
129 //
130 const { isFunction } = lodash;
131 const {
132 parse = emptyFuns,
133 isReusableBlock = emptyFuns,
134 isTemplatePart = emptyFuns,
135 } = wp.blocks;
136 const { getEditedEntityRecord = emptyFuns } = select("core");
137 const { getBlocks = emptyFuns, updateBlockAttributes = emptyFuns } =
138 select("core/block-editor");
139
140 const all_blocks = getBlocks();
141
142 const resOptionChanger = (blocks) => {
143 for (const item of blocks) {
144 const { name, clientId, innerBlocks } = item;
145
146 if (isFunction(isReusableBlock) && isReusableBlock(item)) {
147 const reusableBlock = getEditedEntityRecord(
148 "postType",
149 "wp_block",
150 item.attributes.ref
151 );
152
153 const parsedBlocks = parse(
154 isFunction(reusableBlock.content)
155 ? reusableBlock.content(reusableBlock)
156 : reusableBlock.content
157 );
158
159 for (const blockItem of parsedBlocks) {
160 const { innerBlocks, clientId, name } = blockItem;
161 if (regexForBlockNameTest.test(name)) {
162 updateBlockAttributes(clientId, {
163 resOption: newDeviceType,
164 });
165 }
166 if (innerBlocks.length > 0) {
167 resOptionChanger(innerBlocks);
168 }
169 }
170 } else if (isFunction(isTemplatePart) && isTemplatePart(item)) {
171 const { theme, slug } = item.attributes;
172
173 const templatePartEntity = getEditedEntityRecord(
174 "postType",
175 "wp_template_part",
176 makeIdOfTemplatePart(theme, slug)
177 );
178
179 const { blocks = [], innerBlocks = [] } = templatePartEntity;
180 resOptionChanger(blocks);
181 resOptionChanger(innerBlocks);
182 } else if (regexForBlockNameTest.test(name)) {
183 updateBlockAttributes(clientId, {
184 resOption: newDeviceType,
185 });
186 }
187 if (innerBlocks.length > 0) {
188 resOptionChanger(innerBlocks);
189 }
190 }
191 };
192
193 resOptionChanger(all_blocks); // Call function
194 }
195 };
196
197 //
198 const callBackFuncForSubsCribeForEditPost = () => {
199 if (isSavingPost() && !isAutosavingPost()) {
200 generateAndSendStyleToBackend();
201 }
202 callBackFuncOnPreviewChange();
203 };
204
205 const callBackFuncForSubsCribeForEditSite = () => {
206 if (isSavingNonPostEntityChanges()) {
207 generateAndSendStyleToBackend();
208 }
209 callBackFuncOnPreviewChange();
210 };
211
212 if (editor_type === "edit-site") {
213 //
214 subscribe(callBackFuncForSubsCribeForEditSite);
215 } else if (editor_type === "edit-post") {
216 //
217 subscribe(callBackFuncForSubsCribeForEditPost);
218 }
219 })();
220
221 //Helper Functions
222 function isEmpty(obj) {
223 return Object.keys(obj).length === 0;
224 }
225