PluginProbe ʕ •ᴥ•ʔ
Widget Options – Advanced Conditional Visibility for Gutenberg Blocks & Classic Widgets / 4.0.5
Widget Options – Advanced Conditional Visibility for Gutenberg Blocks & Classic Widgets v4.0.5
4.2.5 4.2.4 trunk 3.7.10 3.7.11 3.7.12 3.7.13 3.7.14 3.7.2 3.7.5 3.7.6 3.7.7 3.7.8 3.7.9 3.8 3.8.1 3.8.10 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.8.8 3.8.9 3.8.9.1 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.5.1 4.0.6 4.0.6.1 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.2 4.1.3 4.2.0 4.2.1 4.2.2 4.2.3
widget-options / includes / widgets / gutenberg / lib / client-assets.php
widget-options / includes / widgets / gutenberg / lib Last commit date
block-supports 2 years ago compat 2 years ago experimental 2 years ago README.md 2 years ago block-editor-settings.php 2 years ago blocks.php 2 years ago class-wp-duotone-gutenberg.php 2 years ago class-wp-theme-json-data-gutenberg.php 2 years ago class-wp-theme-json-gutenberg.php 2 years ago class-wp-theme-json-resolver-gutenberg.php 2 years ago client-assets.php 2 years ago demo.php 2 years ago experiments-page.php 2 years ago global-styles-and-settings.php 2 years ago init.php 2 years ago load.php 2 years ago script-loader.php 2 years ago theme-i18n.json 2 years ago theme.json 2 years ago upgrade.php 2 years ago
client-assets.php
572 lines
1 <?php
2 /**
3 * Functions to register client-side assets (scripts and stylesheets) specific
4 * for the Gutenberg editor plugin.
5 *
6 * @package gutenberg
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 die( 'Silence is golden.' );
11 }
12
13 /**
14 * Retrieves the root plugin path.
15 *
16 * @return string Root path to the gutenberg plugin.
17 *
18 * @since 0.1.0
19 */
20 function gutenberg_dir_path() {
21 return plugin_dir_path( __DIR__ );
22 }
23
24 /**
25 * Retrieves a URL to a file in the gutenberg plugin.
26 *
27 * @param string $path Relative path of the desired file.
28 *
29 * @return string Fully qualified URL pointing to the desired file.
30 *
31 * @since 0.1.0
32 */
33 function gutenberg_url( $path ) {
34 return plugins_url( $path, __DIR__ );
35 }
36
37 /**
38 * Registers a script according to `wp_register_script`. Honors this request by
39 * reassigning internal dependency properties of any script handle already
40 * registered by that name. It does not deregister the original script, to
41 * avoid losing inline scripts which may have been attached.
42 *
43 * @since 4.1.0
44 *
45 * @param WP_Scripts $scripts WP_Scripts instance.
46 * @param string $handle Name of the script. Should be unique.
47 * @param string $src Full URL of the script, or path of the script relative to the WordPress root directory.
48 * @param array $deps Optional. An array of registered script handles this script depends on. Default empty array.
49 * @param string|bool|null $ver Optional. String specifying script version number, if it has one, which is added to the URL
50 * as a query string for cache busting purposes. If version is set to false, a version
51 * number is automatically added equal to current installed WordPress version.
52 * If set to null, no version is added.
53 * @param bool $in_footer Optional. Whether to enqueue the script before </body> instead of in the <head>.
54 * Default 'false'.
55 */
56 function gutenberg_override_script( $scripts, $handle, $src, $deps = array(), $ver = false, $in_footer = false ) {
57 /*
58 * Force `wp-i18n` script to be registered in the <head> as a
59 * temporary workaround for https://meta.trac.wordpress.org/ticket/6195.
60 */
61 $in_footer = 'wp-i18n' === $handle ? false : $in_footer;
62
63 $script = $scripts->query( $handle, 'registered' );
64 if ( $script ) {
65 /*
66 * In many ways, this is a reimplementation of `wp_register_script` but
67 * bypassing consideration of whether a script by the given handle had
68 * already been registered.
69 */
70
71 // See: `_WP_Dependency::__construct` .
72 $script->src = $src;
73 $script->deps = $deps;
74 $script->ver = $ver;
75 $script->args = $in_footer ? 1 : null;
76 } else {
77 $scripts->add( $handle, $src, $deps, $ver, ( $in_footer ? 1 : null ) );
78 }
79
80 if ( in_array( 'wp-i18n', $deps, true ) ) {
81 $scripts->set_translations( $handle );
82 }
83
84 /*
85 * Wp-editor module is exposed as window.wp.editor.
86 * Problem: there is quite some code expecting window.wp.oldEditor object available under window.wp.editor.
87 * Solution: fuse the two objects together to maintain backward compatibility.
88 * For more context, see https://github.com/WordPress/gutenberg/issues/33203
89 */
90 if ( 'wp-editor' === $handle ) {
91 $scripts->add_inline_script(
92 'wp-editor',
93 'Object.assign( window.wp.editor, window.wp.oldEditor );',
94 'after'
95 );
96 }
97 }
98
99 /**
100 * Filters the default translation file load behavior to load the Gutenberg
101 * plugin translation file, if available.
102 *
103 * @param string|false $file Path to the translation file to load. False if
104 * there isn't one.
105 * @param string $handle Name of the script to register a translation
106 * domain to.
107 *
108 * @return string|false Filtered path to the Gutenberg translation file, if
109 * available.
110 */
111 function gutenberg_override_translation_file( $file, $handle ) {
112 if ( ! $file ) {
113 return $file;
114 }
115
116 // Ignore scripts whose handle does not have the "wp-" prefix.
117 if ( ! str_starts_with( $handle, 'wp-' ) ) {
118 return $file;
119 }
120
121 // Ignore scripts that are not found in the expected `build/` location.
122 $script_path = gutenberg_dir_path() . 'build/' . substr( $handle, 3 ) . '/index.min.js';
123 if ( ! file_exists( $script_path ) ) {
124 return $file;
125 }
126
127 /*
128 * The default file will be in the plugins language directory, omitting the
129 * domain since Gutenberg assigns the script translations as the default.
130 *
131 * Example: /www/wp-content/languages/plugins/de_DE-07d88e6a803e01276b9bfcc1203e862e.json
132 *
133 * The logic of `load_script_textdomain` is such that it will assume to
134 * search in the plugins language directory, since the assigned source of
135 * the overridden Gutenberg script originates in the plugins directory.
136 *
137 * The plugin translation files each begin with the slug of the plugin, so
138 * it's a simple matter of prepending the Gutenberg plugin slug.
139 */
140 $path_parts = pathinfo( $file );
141 $plugin_translation_file = (
142 $path_parts['dirname'] .
143 '/gutenberg-' .
144 $path_parts['basename']
145 );
146
147 return $plugin_translation_file;
148 }
149 add_filter( 'load_script_translation_file', 'gutenberg_override_translation_file', 10, 2 );
150
151 /**
152 * Registers a style according to `wp_register_style`. Honors this request by
153 * deregistering any style by the same handler before registration.
154 *
155 * @since 4.1.0
156 *
157 * @param WP_Styles $styles WP_Styles instance.
158 * @param string $handle Name of the stylesheet. Should be unique.
159 * @param string $src Full URL of the stylesheet, or path of the stylesheet relative to the WordPress root directory.
160 * @param array $deps Optional. An array of registered stylesheet handles this stylesheet depends on. Default empty array.
161 * @param string|bool|null $ver Optional. String specifying stylesheet version number, if it has one, which is added to the URL
162 * as a query string for cache busting purposes. If version is set to false, a version
163 * number is automatically added equal to current installed WordPress version.
164 * If set to null, no version is added.
165 * @param string $media Optional. The media for which this stylesheet has been defined.
166 * Default 'all'. Accepts media types like 'all', 'print' and 'screen', or media queries like
167 * '(orientation: portrait)' and '(max-width: 640px)'.
168 */
169 function gutenberg_override_style( $styles, $handle, $src, $deps = array(), $ver = false, $media = 'all' ) {
170 $style = $styles->query( $handle, 'registered' );
171 if ( $style ) {
172 $styles->remove( $handle );
173 }
174 $styles->add( $handle, $src, $deps, $ver, $media );
175 }
176
177 /**
178 * Registers all the WordPress packages scripts that are in the standardized
179 * `build/` location.
180 *
181 * @since 4.5.0
182 *
183 * @param WP_Scripts $scripts WP_Scripts instance.
184 */
185 function gutenberg_register_packages_scripts( $scripts ) {
186 // When in production, use the plugin's version as the default asset version;
187 // else (for development or test) default to use the current time.
188 $default_version = defined( 'GUTENBERG_VERSION' ) && ! SCRIPT_DEBUG ? GUTENBERG_VERSION : time();
189
190 foreach ( glob( gutenberg_dir_path() . 'build/*/index.min.js' ) as $path ) {
191 // Prefix `wp-` to package directory to get script handle.
192 // For example, `…/build/a11y/index.min.js` becomes `wp-a11y`.
193 $handle = 'wp-' . basename( dirname( $path ) );
194
195 // Replace extension with `.asset.php` to find the generated dependencies file.
196 $asset_file = substr( $path, 0, -( strlen( '.js' ) ) ) . '.asset.php';
197 $asset = file_exists( $asset_file )
198 ? require $asset_file
199 : null;
200 $dependencies = isset( $asset['dependencies'] ) ? $asset['dependencies'] : array();
201 $version = isset( $asset['version'] ) ? $asset['version'] : $default_version;
202
203 // Add dependencies that cannot be detected and generated by build tools.
204 switch ( $handle ) {
205 case 'wp-block-library':
206 array_push( $dependencies, 'editor' );
207 break;
208
209 case 'wp-edit-post':
210 array_push( $dependencies, 'media-models', 'media-views', 'postbox' );
211 break;
212
213 case 'wp-edit-site':
214 array_push( $dependencies, 'wp-dom-ready' );
215 break;
216 case 'wp-preferences':
217 array_push( $dependencies, 'wp-preferences-persistence' );
218 break;
219 }
220
221 // Get the path from Gutenberg directory as expected by `gutenberg_url`.
222 $gutenberg_path = substr( $path, strlen( gutenberg_dir_path() ) );
223
224 gutenberg_override_script(
225 $scripts,
226 $handle,
227 gutenberg_url( $gutenberg_path ),
228 $dependencies,
229 $version,
230 true
231 );
232 }
233 }
234 add_action( 'wp_default_scripts', 'gutenberg_register_packages_scripts' );
235
236 /**
237 * Registers all the WordPress packages styles that are in the standardized
238 * `build/` location.
239 *
240 * @since 6.7.0
241
242 * @param WP_Styles $styles WP_Styles instance.
243 */
244 function gutenberg_register_packages_styles( $styles ) {
245 // When in production, use the plugin's version as the asset version;
246 // else (for development or test) default to use the current time.
247 $version = defined( 'GUTENBERG_VERSION' ) && ! SCRIPT_DEBUG ? GUTENBERG_VERSION : time();
248
249 gutenberg_override_style(
250 $styles,
251 'wp-block-editor-content',
252 gutenberg_url( 'build/block-editor/content.css' ),
253 array( 'wp-components' ),
254 $version
255 );
256 $styles->add_data( 'wp-block-editor-content', 'rtl', 'replace' );
257
258 // Editor Styles.
259 gutenberg_override_style(
260 $styles,
261 'wp-block-editor',
262 gutenberg_url( 'build/block-editor/style.css' ),
263 array( 'wp-components' ),
264 $version
265 );
266 $styles->add_data( 'wp-block-editor', 'rtl', 'replace' );
267
268 gutenberg_override_style(
269 $styles,
270 'wp-editor',
271 gutenberg_url( 'build/editor/style.css' ),
272 array( 'wp-components', 'wp-block-editor', 'wp-reusable-blocks' ),
273 $version
274 );
275 $styles->add_data( 'wp-editor', 'rtl', 'replace' );
276
277 gutenberg_override_style(
278 $styles,
279 'wp-edit-post',
280 gutenberg_url( 'build/edit-post/style.css' ),
281 array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-block-library', 'wp-commands' ),
282 $version
283 );
284 $styles->add_data( 'wp-edit-post', 'rtl', 'replace' );
285
286 gutenberg_override_style(
287 $styles,
288 'wp-components',
289 gutenberg_url( 'build/components/style.css' ),
290 array( 'dashicons' ),
291 $version
292 );
293 $styles->add_data( 'wp-components', 'rtl', 'replace' );
294
295 $block_library_filename = wp_should_load_separate_core_block_assets() ? 'common' : 'style';
296 gutenberg_override_style(
297 $styles,
298 'wp-block-library',
299 gutenberg_url( 'build/block-library/' . $block_library_filename . '.css' ),
300 array(),
301 $version
302 );
303 $styles->add_data( 'wp-block-library', 'rtl', 'replace' );
304 $styles->add_data( 'wp-block-library', 'path', gutenberg_dir_path() . 'build/block-library/' . $block_library_filename . '.css' );
305
306 gutenberg_override_style(
307 $styles,
308 'wp-format-library',
309 gutenberg_url( 'build/format-library/style.css' ),
310 array( 'wp-block-editor', 'wp-components' ),
311 $version
312 );
313 $styles->add_data( 'wp-format-library', 'rtl', 'replace' );
314
315 $wp_edit_blocks_dependencies = array(
316 'wp-components',
317 // This need to be added before the block library styles,
318 // The block library styles override the "reset" styles.
319 'wp-reset-editor-styles',
320 'wp-block-library',
321 'wp-reusable-blocks',
322 // Until #37466, we can't specifically add them as editor styles yet,
323 // so we must hard-code it here as a dependency.
324 'wp-block-editor-content',
325 );
326
327 // Only load the default layout and margin styles for themes without theme.json file.
328 if ( ! wp_theme_has_theme_json() ) {
329 $wp_edit_blocks_dependencies[] = 'wp-editor-classic-layout-styles';
330 }
331
332 global $editor_styles;
333 if ( current_theme_supports( 'wp-block-styles' ) && ( ! is_array( $editor_styles ) || count( $editor_styles ) === 0 ) ) {
334 // Include opinionated block styles if the theme supports block styles and no $editor_styles are declared, so the editor never appears broken.
335 $wp_edit_blocks_dependencies[] = 'wp-block-library-theme';
336 }
337
338 gutenberg_override_style(
339 $styles,
340 'wp-reset-editor-styles',
341 gutenberg_url( 'build/block-library/reset.css' ),
342 array( 'common', 'forms' ), // Make sure the reset is loaded after the default WP Admin styles.
343 $version
344 );
345 $styles->add_data( 'wp-reset-editor-styles', 'rtl', 'replace' );
346
347 gutenberg_override_style(
348 $styles,
349 'wp-editor-classic-layout-styles',
350 gutenberg_url( 'build/edit-post/classic.css' ),
351 array(),
352 $version
353 );
354 $styles->add_data( 'wp-editor-classic-layout-styles', 'rtl', 'replace' );
355
356 gutenberg_override_style(
357 $styles,
358 'wp-edit-blocks',
359 gutenberg_url( 'build/block-library/editor.css' ),
360 $wp_edit_blocks_dependencies,
361 $version
362 );
363 $styles->add_data( 'wp-edit-blocks', 'rtl', 'replace' );
364
365 gutenberg_override_style(
366 $styles,
367 'wp-block-library-theme',
368 gutenberg_url( 'build/block-library/theme.css' ),
369 array(),
370 $version
371 );
372 $styles->add_data( 'wp-block-library-theme', 'rtl', 'replace' );
373
374 gutenberg_override_style(
375 $styles,
376 'wp-list-reusable-blocks',
377 gutenberg_url( 'build/list-reusable-blocks/style.css' ),
378 array( 'wp-components' ),
379 $version
380 );
381 $styles->add_data( 'wp-list-reusable-block', 'rtl', 'replace' );
382
383 gutenberg_override_style(
384 $styles,
385 'wp-commands',
386 gutenberg_url( 'build/commands/style.css' ),
387 array( 'wp-components' ),
388 $version
389 );
390 $styles->add_data( 'wp-commands', 'rtl', 'replace' );
391
392 gutenberg_override_style(
393 $styles,
394 'wp-edit-site',
395 gutenberg_url( 'build/edit-site/style.css' ),
396 array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-commands' ),
397 $version
398 );
399 $styles->add_data( 'wp-edit-site', 'rtl', 'replace' );
400
401 gutenberg_override_style(
402 $styles,
403 'wp-edit-widgets',
404 gutenberg_url( 'build/edit-widgets/style.css' ),
405 array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-reusable-blocks', 'wp-widgets' ),
406 $version
407 );
408 $styles->add_data( 'wp-edit-widgets', 'rtl', 'replace' );
409
410 gutenberg_override_style(
411 $styles,
412 'wp-block-directory',
413 gutenberg_url( 'build/block-directory/style.css' ),
414 array( 'wp-block-editor', 'wp-components' ),
415 $version
416 );
417 $styles->add_data( 'wp-block-directory', 'rtl', 'replace' );
418
419 gutenberg_override_style(
420 $styles,
421 'wp-customize-widgets',
422 gutenberg_url( 'build/customize-widgets/style.css' ),
423 array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-widgets' ),
424 $version
425 );
426 $styles->add_data( 'wp-customize-widgets', 'rtl', 'replace' );
427
428 gutenberg_override_style(
429 $styles,
430 'wp-reusable-blocks',
431 gutenberg_url( 'build/reusable-blocks/style.css' ),
432 array( 'wp-components' ),
433 $version
434 );
435 $styles->add_data( 'wp-reusable-blocks', 'rtl', 'replace' );
436
437 gutenberg_override_style(
438 $styles,
439 'wp-widgets',
440 gutenberg_url( 'build/widgets/style.css' ),
441 array( 'wp-components' )
442 );
443 $styles->add_data( 'wp-widgets', 'rtl', 'replace' );
444 }
445 add_action( 'wp_default_styles', 'gutenberg_register_packages_styles' );
446
447 /**
448 * Fetches, processes and compiles stored core styles, then combines and renders them to the page.
449 * Styles are stored via the Style Engine API.
450 *
451 * This hook also exists, and should be backported to Core in future versions.
452 * However, it is envisaged that Gutenberg will continue to use the Style Engine's `gutenberg_*` functions and `_Gutenberg` classes to aid continuous development.
453 *
454 * See: https://developer.wordpress.org/block-editor/reference-guides/packages/packages-style-engine/
455 *
456 * @param array $options {
457 * Optional. An array of options to pass to gutenberg_style_engine_get_stylesheet_from_context(). Default empty array.
458 *
459 * @type bool $optimize Whether to optimize the CSS output, e.g., combine rules. Default is `false`.
460 * @type bool $prettify Whether to add new lines and indents to output. Default is the test of whether the global constant `SCRIPT_DEBUG` is defined.
461 * }
462 *
463 * @since 6.1
464 *
465 * @return void
466 */
467 function gutenberg_enqueue_stored_styles( $options = array() ) {
468 $is_block_theme = wp_is_block_theme();
469 $is_classic_theme = ! $is_block_theme;
470
471 /*
472 * For block themes, print stored styles in the header.
473 * For classic themes, in the footer.
474 */
475 if (
476 ( $is_block_theme && doing_action( 'wp_footer' ) ) ||
477 ( $is_classic_theme && doing_action( 'wp_enqueue_scripts' ) )
478 ) {
479 return;
480 }
481
482 $core_styles_keys = array( 'block-supports' );
483 $compiled_core_stylesheet = '';
484 $style_tag_id = 'core';
485 foreach ( $core_styles_keys as $style_key ) {
486 // Adds comment if code is prettified to identify core styles sections in debugging.
487 $should_prettify = isset( $options['prettify'] ) ? true === $options['prettify'] : SCRIPT_DEBUG;
488 if ( $should_prettify ) {
489 $compiled_core_stylesheet .= "/**\n * Core styles: $style_key\n */\n";
490 }
491 // Chains core store ids to signify what the styles contain.
492 $style_tag_id .= '-' . $style_key;
493 $compiled_core_stylesheet .= gutenberg_style_engine_get_stylesheet_from_context( $style_key, $options );
494 }
495
496 // Combines Core styles.
497 if ( ! empty( $compiled_core_stylesheet ) ) {
498 wp_register_style( $style_tag_id, false, array(), true, true );
499 wp_add_inline_style( $style_tag_id, $compiled_core_stylesheet );
500 wp_enqueue_style( $style_tag_id );
501 }
502
503 // If there are any other stores registered by themes etc., print them out.
504 $additional_stores = WP_Style_Engine_CSS_Rules_Store_Gutenberg::get_stores();
505
506 /*
507 * Since the corresponding action hook in Core is removed below,
508 * this function should still honour any styles stored using the Core Style Engine store.
509 */
510 if ( class_exists( 'WP_Style_Engine_CSS_Rules_Store' ) ) {
511 $additional_stores = array_merge( $additional_stores, WP_Style_Engine_CSS_Rules_Store::get_stores() );
512 }
513
514 foreach ( array_keys( $additional_stores ) as $store_name ) {
515 if ( in_array( $store_name, $core_styles_keys, true ) ) {
516 continue;
517 }
518 $styles = gutenberg_style_engine_get_stylesheet_from_context( $store_name, $options );
519 if ( ! empty( $styles ) ) {
520 $key = "wp-style-engine-$store_name";
521 wp_register_style( $key, false, array(), true, true );
522 wp_add_inline_style( $key, $styles );
523 wp_enqueue_style( $key );
524 }
525 }
526 }
527
528 /**
529 * Registers vendor JavaScript files to be used as dependencies of the editor
530 * and plugins.
531 *
532 * This function is called from a script during the plugin build process, so it
533 * should not call any WordPress PHP functions.
534 *
535 * @since 13.0
536 *
537 * @param WP_Scripts $scripts WP_Scripts instance.
538 */
539 function gutenberg_register_vendor_scripts( $scripts ) {
540 $extension = SCRIPT_DEBUG ? '.js' : '.min.js';
541
542 gutenberg_override_script(
543 $scripts,
544 'react',
545 gutenberg_url( 'build/vendors/react' . $extension ),
546 // See https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/TROUBLESHOOTING.md#externalising-react.
547 SCRIPT_DEBUG ? array( 'wp-react-refresh-entry', 'wp-polyfill' ) : array( 'wp-polyfill' ),
548 '18'
549 );
550 gutenberg_override_script(
551 $scripts,
552 'react-dom',
553 gutenberg_url( 'build/vendors/react-dom' . $extension ),
554 array( 'react' ),
555 '18'
556 );
557 }
558 add_action( 'wp_default_scripts', 'gutenberg_register_vendor_scripts' );
559
560
561 /*
562 * Always remove the Core action hook while gutenberg_enqueue_stored_styles() exists to avoid styles being printed twice.
563 * This is also because gutenberg_enqueue_stored_styles uses the Style Engine's `gutenberg_*` functions and `_Gutenberg` classes,
564 * which are in continuous development and generally ahead of Core.
565 */
566 remove_action( 'wp_enqueue_scripts', 'wp_enqueue_stored_styles' );
567 remove_action( 'wp_footer', 'wp_enqueue_stored_styles', 1 );
568
569 // Enqueue stored styles.
570 add_action( 'wp_enqueue_scripts', 'gutenberg_enqueue_stored_styles' );
571 add_action( 'wp_footer', 'gutenberg_enqueue_stored_styles', 1 );
572