PluginProbe ʕ •ᴥ•ʔ
VK Blocks / trunk
VK Blocks vtrunk
1.123.0 1.122.0 1.121.0 1.120.0 1.119.2 1.119.1 1.119.0 1.118.7 1.82.0.0 1.82.0.1 1.83.0.0 1.83.0.1 1.84.0.0 1.84.0.1 1.85.0.2 1.85.0.3 1.85.1.0 1.85.1.1 1.86.0.0 1.86.0.1 1.86.1.0 1.87.0.0 1.87.0.1 1.88.0.1 1.88.0.2 1.89.0.0 1.9.2 1.90.0.0 1.90.0.1 1.90.1.1 1.91.0.0 1.91.1.1 1.92.0.0 1.92.0.1 1.92.1.0 1.92.1.1 1.93.0.0 trunk 1.93.0.1 0.1.1 1.93.1.0 0.10.3 1.93.1.1 0.11.0 1.94.0.0 0.12.6 1.94.0.1 0.15.1 1.94.1.0 0.16.2 1.94.2.1 0.17.6 1.94.2.2 0.2.2 1.95.0.3 0.22.4 1.95.0.4 0.26.7 1.96.2.0 0.3.2 1.96.2.1 0.31.0 1.97.0.1 0.35.5 1.97.0.2 0.37.5 1.99.0.0 0.38.8 1.99.0.1 0.39.4 0.4.7 0.41.0 0.42.0 0.44.13 0.45.2 0.46.1 0.47.0 0.48.0 0.49.8 0.5.2 0.50.3 0.51.0 0.52.2 0.53.2 0.54.0 0.55.0 0.56.2 0.56.3 0.57.6 0.58.10 0.59.0 0.6.0 0.60.1 0.61.2 0.7.1 0.8.2 1.0.16 1.10.0 1.100.0.0 1.100.0.1 1.102.0.0 1.102.0.1 1.103.0.0 1.104.0.0 1.104.0.1 1.105.1.0 1.105.1.1 1.106.0.0 1.106.0.1 1.107.0.0 1.107.0.1 1.107.0.2 1.108.0.0 1.108.0.1 1.109.0.0 1.109.0.1 1.11.4 1.110.0.0 1.110.0.1 1.111.0.0 1.111.0.1 1.111.0.2 1.112.0.0 1.112.0.1 1.113.0.0 1.113.0.1 1.114.0.0 1.114.0.1 1.114.2.0 1.114.2.1 1.115.0.0 1.115.0.1 1.115.1.0 1.115.1.1 1.115.2.0 1.115.2.1 1.116.0.0 1.116.0.1 1.116.1.0 1.116.1.1 1.116.2.0 1.117.0.0 1.117.0.1 1.117.1.0 1.118.2 1.118.5 1.12.0 1.13.2 1.14.1 1.15.1 1.16.11 1.17.0 1.18.6 1.19.0 1.19.1 1.2.3 1.20.7 1.21.0 1.22.4 1.23.0 1.24.5 1.25.1 1.26.2 1.27.7.2 1.28.0.1 1.29.2.0 1.3.9 1.30.0.1 1.31.0.1 1.32.0.2 1.33.2.1 1.36.1.5 1.37.0.0 1.39.2.1 1.4.6 1.40.0.1 1.40.1.0 1.40.1.1 1.41.0.0 1.41.0.1 1.41.2.2 1.41.2.3 1.43.0.0 1.43.0.1 1.43.0.2 1.44.0.0 1.44.0.1 1.45.0.0 1.45.0.1 1.46.0.0 1.46.0.1 1.47.0.0 1.47.0.1 1.47.1.0 1.48.0.0 1.48.0.1 1.48.0.2 1.48.1.0 1.48.1.1 1.5.0 1.50.0.0 1.50.0.1 1.51.0.0 1.51.0.1 1.52.0.0 1.52.0.1 1.53.0.0 1.53.0.1 1.54.0.0 1.54.0.1 1.55.0.0 1.55.0.1 1.56.0.0 1.56.0.1 1.57.0.0 1.57.0.2 1.57.0.3 1.57.0.4 1.57.0.5 1.57.1.0 1.57.1.1 1.57.1.2 1.58.0.0 1.58.0.1 1.59.0.0 1.59.0.1 1.6.0 1.60.0.0 1.60.0.1 1.63.0.0 1.63.0.1 1.64.0.0 1.64.0.1 1.64.1.0 1.64.1.2 1.67.0.0 1.67.0.1 1.68.0.0 1.68.0.1 1.69.0.0 1.69.0.1 1.69.1.1 1.69.1.2 1.7.1 1.70.0.0 1.70.0.1 1.71.0.0 1.71.0.1 1.72.0.0 1.72.1.0 1.72.1.1 1.73.0.0 1.73.0.1 1.74.0.0 1.74.0.1 1.75.0.0 1.75.1.0 1.75.1.1 1.76.0.0 1.76.0.1 1.76.1.0 1.76.1.1 1.76.2.0 1.76.2.1 1.77.0.0 1.77.0.1 1.78.0.0 1.78.0.1 1.79.0.0 1.79.0.1 1.79.0.2 1.79.0.3 1.79.1.0 1.79.1.1 1.8.2 1.80.1.0 1.80.1.1 1.80.1.2 1.81.0.1 1.81.0.2
vk-blocks / src / extensions / common / custom-css-extension / index.js
vk-blocks / src / extensions / common / custom-css-extension Last commit date
index.js 3 weeks ago
index.js
324 lines
1 /**
2 * WordPress dependencies
3 */
4 import { __, getLocaleData } from '@wordpress/i18n';
5 import { addFilter } from '@wordpress/hooks';
6 import { PanelBody, Button, ExternalLink } from '@wordpress/components';
7 import { InspectorControls, transformStyles } from '@wordpress/block-editor';
8 import { createHigherOrderComponent, useInstanceId } from '@wordpress/compose';
9 import { hasBlockSupport } from '@wordpress/blocks';
10 import { useEffect } from '@wordpress/element';
11 import { select } from '@wordpress/data';
12 /**
13 * External dependencies
14 */
15 import classnames from 'classnames';
16
17 /**
18 * Internal dependencies
19 */
20 import { CodeMirrorCss } from '@vkblocks/components/code-mirror-css';
21 import { emptyStringToUndefined } from '@vkblocks/utils/empty-string-to-undefined';
22 import { getSettingsPageUrl } from '@vkblocks/utils/settings-page-url';
23 import { VkPanelIcon } from '@vkblocks/components/vk-icon';
24 /*globals vk_blocks_params */
25
26 export const inString = (str, keyword) => {
27 return str.indexOf(keyword) !== -1;
28 };
29
30 export const hasCustomCssSupport = (blockName) => {
31 // 追加CSSクラスを許可していない場合はfalse
32 if (!hasBlockSupport(blockName, 'customClassName', true)) {
33 return false;
34 }
35
36 const allowed = ['core', 'vk-blocks'];
37 let returnBool =
38 allowed.find((item) => inString(blockName, item)) !== undefined;
39
40 const excludeBlocks = [
41 // ExUnitに�
42 �っているvk blocksブロック
43 'vk-blocks/share-button',
44 'vk-blocks/child-page-index',
45 'vk-blocks/contact-section',
46 'vk-blocks/page-list-ancestor',
47 'vk-blocks/sitemap',
48 'vk-blocks/cta',
49 ];
50 const excludeBlock =
51 excludeBlocks.find((excludeName) =>
52 inString(blockName, excludeName)
53 ) !== undefined;
54 if (excludeBlock) {
55 returnBool = false;
56 }
57 return returnBool;
58 };
59
60 export const existsCss = (css) => {
61 // cssが存在するかつ空白文字のみではない
62 return css && css.match(/\S/g);
63 };
64
65 export const customCssSelectorRegex = /selector/g;
66
67 /**
68 * Filters registered block settings.
69 *
70 * @param {Object} settings
71 */
72 export function addAttribute(settings) {
73 if (!hasCustomCssSupport(settings.name)) {
74 return settings;
75 }
76 settings.attributes = {
77 ...settings.attributes,
78 vkbCustomCss: {
79 type: 'string',
80 },
81 };
82 return settings;
83 }
84
85 /**
86 * Determine if the editor context is a widget screen
87 */
88 const isWidgetsEditor = () => {
89 try {
90 // `core/edit-widgets` store が存在するか確認し、そこから�
91 報を取得
92 const widgetsStore = select('core/edit-widgets');
93 return !!widgetsStore;
94 } catch (e) {
95 return false;
96 }
97 };
98
99 /**
100 * On the widget screen, only the blocks included in the allowList are true
101 * @param {string} blockName -Name of the block to check
102 */
103 const shouldApplyOnThisScreenAndBlock = (blockName) => {
104 if (!isWidgetsEditor()) {
105 return false;
106 }
107 const allowList = new Set(['core/legacy-widget', 'core/widget-group']);
108 return allowList.has(blockName);
109 };
110
111 /**
112 * Override the default edit UI to include layout controls
113 */
114 export const withInspectorControls = createHigherOrderComponent(
115 (BlockEdit) => (props) => {
116 const { name, attributes, setAttributes } = props;
117 if (
118 !hasCustomCssSupport(name) ||
119 shouldApplyOnThisScreenAndBlock(name)
120 ) {
121 return <BlockEdit {...props} />;
122 }
123
124 const { vkbCustomCss, className } = attributes;
125 // 追加CSSを半角文字列で分けて�
126 �列化
127 const nowClassArray = className ? className.split(' ') : [];
128
129 // 追加 CSS クラスにvk_custom_cssがあるか
130 const existsCustomCssClass = (_nowClassArray) => {
131 return _nowClassArray.indexOf('vk_custom_css') !== -1
132 ? true
133 : false;
134 };
135
136 // カスタムCSSにselectorがあるか
137 const existsCustomCssSelector = (_vkbCustomCss) => {
138 return customCssSelectorRegex.test(_vkbCustomCss);
139 };
140
141 // vkbCustomCssが変更されたとき
142 useEffect(() => {
143 if (
144 !existsCustomCssClass(nowClassArray) &&
145 existsCustomCssSelector(vkbCustomCss)
146 ) {
147 // カスタムCSS用クラスを追加
148 setAttributes({
149 className: emptyStringToUndefined(
150 classnames(nowClassArray, `vk_custom_css`)
151 ),
152 });
153 }
154
155 if (
156 existsCustomCssClass(nowClassArray) &&
157 !existsCustomCssSelector(vkbCustomCss)
158 ) {
159 // カスタムCSS用クラスを削除
160 const deleteClass = nowClassArray.indexOf('vk_custom_css');
161 nowClassArray.splice(deleteClass, 1);
162 setAttributes({
163 className: emptyStringToUndefined(
164 classnames(nowClassArray)
165 ),
166 });
167 }
168 }, [vkbCustomCss]);
169
170 // classNameが変更されたときに
171 useEffect(() => {
172 if (
173 !existsCustomCssClass(nowClassArray) &&
174 existsCustomCssSelector(vkbCustomCss)
175 ) {
176 // カスタムCSS用クラスを追加
177 setAttributes({
178 className: emptyStringToUndefined(
179 classnames(`vk_custom_css`, nowClassArray)
180 ),
181 });
182 }
183 }, [className]);
184
185 return (
186 <>
187 <BlockEdit {...props} />
188 <InspectorControls>
189 <PanelBody
190 className={'vk_custom_css_panel'}
191 icon={
192 <VkPanelIcon isActive={existsCss(vkbCustomCss)} />
193 }
194 title={__('Custom CSS', 'vk-blocks')}
195 initialOpen={false}
196 >
197 <CodeMirrorCss
198 className="vk-codemirror-block-editor"
199 value={vkbCustomCss ? vkbCustomCss : ''}
200 onChange={(value) => {
201 setAttributes({
202 vkbCustomCss: emptyStringToUndefined(value),
203 });
204 }}
205 />
206 <p>
207 {__(
208 'If selector is specified, it is replaced by a block-specific CSS class. If selector is set to "selector", it will be replaced with a block-specific CSS class. CSS selectors other than "selector" may affect the entire page.',
209 'vk-blocks'
210 )}
211 {(() => {
212 const lang = getLocaleData()[''].lang;
213 if (lang === 'ja_JP') {
214 return (
215 <ExternalLink
216 href="https://www.vektor-inc.co.jp/service/wordpress-plugins/vk-blocks/vk-custom-css/"
217 target="_blank"
218 rel="noreferrer"
219 >
220 詳しくはこちら
221 </ExternalLink>
222 );
223 }
224 })()}
225 </p>
226 <p>{__('Example:', 'vk-blocks')}</p>
227 <pre className="vk-custom-css-sample-code">
228 {'selector {\n background: #f5f5f5;\n}'}
229 </pre>
230 <p>
231 {__(
232 'If you want the edit screen to be as close to the public screen as possible, or if your own CSS interferes with the CSS for the identification display and does not display as intended on the edit screen, please hide it.',
233 'vk-blocks'
234 )}
235 </p>
236 <Button
237 href={getSettingsPageUrl('custom-css-setting')}
238 target="_blank"
239 rel="noreferrer"
240 variant="secondary"
241 isSmall
242 >
243 {__('Custom CSS Setting', 'vk-blocks')}
244 </Button>
245 </PanelBody>
246 </InspectorControls>
247 </>
248 );
249 },
250 'withInspectorControls'
251 );
252
253 /**
254 * Override the default block element to include elements styles.
255 */
256 const withElementsStyles = createHigherOrderComponent(
257 (BlockListBlock) => (props) => {
258 const { name, attributes } = props;
259 if (
260 !hasCustomCssSupport(name) ||
261 shouldApplyOnThisScreenAndBlock(name)
262 ) {
263 return <BlockListBlock {...props} />;
264 }
265 // 編集画面で使用出来る Unique id
266 // @see https://github.com/WordPress/gutenberg/blob/086b77ed409a70a6c6a6e74dee704851eff812f2/packages/compose/src/hooks/use-instance-id/README.md
267 const id = useInstanceId(BlockListBlock);
268 const uniqueClass = `vk_custom_css_${id}`;
269
270 const { vkbCustomCss } = attributes;
271 // editor用のクラス名を追加
272 const customCssClass = classnames(props.className, {
273 [uniqueClass]: existsCss(vkbCustomCss),
274 [`vk_edit_custom_css`]:
275 vk_blocks_params.show_custom_css_editor_flag === 'show' &&
276 existsCss(vkbCustomCss),
277 });
278
279 // selectorをUniqueクラスに変換する
280 let cssTag = vkbCustomCss ? vkbCustomCss : '';
281 if (cssTag && uniqueClass) {
282 cssTag = vkbCustomCss.replace(
283 customCssSelectorRegex,
284 '.' + uniqueClass
285 );
286 }
287
288 // cssに.editor-styles-wrapperをwrapする
289 if (cssTag !== '') {
290 cssTag = transformStyles(
291 [{ css: cssTag }],
292 '.editor-styles-wrapper'
293 );
294 }
295
296 return (
297 <>
298 {(() => {
299 if (cssTag) {
300 return <style>{cssTag}</style>;
301 }
302 })()}
303 <BlockListBlock {...props} className={customCssClass} />
304 </>
305 );
306 }
307 );
308
309 addFilter(
310 'blocks.registerBlockType',
311 'vk-blocks/custom-css/addAttribute',
312 addAttribute
313 );
314 addFilter(
315 'editor.BlockEdit',
316 'vk-blocks/editor/custom-css/with-inspector-controls',
317 withInspectorControls
318 );
319 addFilter(
320 'editor.BlockListBlock',
321 'vk-blocks/style/with-block-controls',
322 withElementsStyles
323 );
324