PluginProbe
Gutenberg / 12.1.0
Gutenberg v12.1.0
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / lib / client-assets.php

client-assets.php in Gutenberg 12.1.0, at lib/client-assets.php

781 lines 25.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Functions to register client-side assets (scripts and stylesheets) for the
4 * 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 $script = $scripts->query( $handle, 'registered' );
58 if ( $script ) {
59 /*
60 * In many ways, this is a reimplementation of `wp_register_script` but
61 * bypassing consideration of whether a script by the given handle had
62 * already been registered.
63 */
64
65 // See: `_WP_Dependency::__construct` .
66 $script->src = $src;
67 $script->deps = $deps;
68 $script->ver = $ver;
69 $script->args = $in_footer;
70
71 /*
72 * The script's `group` designation is an indication of whether it is
73 * to be printed in the header or footer. The behavior here defers to
74 * the arguments as passed. Specifically, group data is not assigned
75 * for a script unless it is designated to be printed in the footer.
76 */
77
78 // See: `wp_register_script` .
79 unset( $script->extra['group'] );
80 if ( $in_footer ) {
81 $script->add_data( 'group', 1 );
82 }
83 } else {
84 $scripts->add( $handle, $src, $deps, $ver, $in_footer );
85 }
86
87 /*
88 * `WP_Dependencies::set_translations` will fall over on itself if setting
89 * translations on the `wp-i18n` handle, since it internally adds `wp-i18n`
90 * as a dependency of itself, exhausting memory. The same applies for the
91 * polyfill and hooks scripts, which are dependencies _of_ `wp-i18n`.
92 *
93 * See: https://core.trac.wordpress.org/ticket/46089
94 */
95 if ( ! in_array( $handle, array( 'wp-i18n', 'wp-polyfill', 'wp-hooks' ), true ) ) {
96 $scripts->set_translations( $handle, 'default' );
97 }
98
99 /*
100 * Wp-editor module is exposed as window.wp.editor.
101 * Problem: there is quite some code expecting window.wp.oldEditor object available under window.wp.editor.
102 * Solution: fuse the two objects together to maintain backward compatibility.
103 * For more context, see https://github.com/WordPress/gutenberg/issues/33203
104 */
105 if ( 'wp-editor' === $handle ) {
106 $scripts->add_inline_script(
107 'wp-editor',
108 'Object.assign( window.wp.editor, window.wp.oldEditor );',
109 'after'
110 );
111 }
112 }
113
114 /**
115 * Filters the default translation file load behavior to load the Gutenberg
116 * plugin translation file, if available.
117 *
118 * @param string|false $file Path to the translation file to load. False if
119 * there isn't one.
120 * @param string $handle Name of the script to register a translation
121 * domain to.
122 *
123 * @return string|false Filtered path to the Gutenberg translation file, if
124 * available.
125 */
126 function gutenberg_override_translation_file( $file, $handle ) {
127 if ( ! $file ) {
128 return $file;
129 }
130
131 // Ignore scripts whose handle does not have the "wp-" prefix.
132 if ( 'wp-' !== substr( $handle, 0, 3 ) ) {
133 return $file;
134 }
135
136 // Ignore scripts that are not found in the expected `build/` location.
137 $script_path = gutenberg_dir_path() . 'build/' . substr( $handle, 3 ) . '/index.min.js';
138 if ( ! file_exists( $script_path ) ) {
139 return $file;
140 }
141
142 /*
143 * The default file will be in the plugins language directory, omitting the
144 * domain since Gutenberg assigns the script translations as the default.
145 *
146 * Example: /www/wp-content/languages/plugins/de_DE-07d88e6a803e01276b9bfcc1203e862e.json
147 *
148 * The logic of `load_script_textdomain` is such that it will assume to
149 * search in the plugins language directory, since the assigned source of
150 * the overridden Gutenberg script originates in the plugins directory.
151 *
152 * The plugin translation files each begin with the slug of the plugin, so
153 * it's a simple matter of prepending the Gutenberg plugin slug.
154 */
155 $path_parts = pathinfo( $file );
156 $plugin_translation_file = (
157 $path_parts['dirname'] .
158 '/gutenberg-' .
159 $path_parts['basename']
160 );
161
162 return $plugin_translation_file;
163 }
164 add_filter( 'load_script_translation_file', 'gutenberg_override_translation_file', 10, 2 );
165
166 /**
167 * Registers a style according to `wp_register_style`. Honors this request by
168 * deregistering any style by the same handler before registration.
169 *
170 * @since 4.1.0
171 *
172 * @param WP_Styles $styles WP_Styles instance.
173 * @param string $handle Name of the stylesheet. Should be unique.
174 * @param string $src Full URL of the stylesheet, or path of the stylesheet relative to the WordPress root directory.
175 * @param array $deps Optional. An array of registered stylesheet handles this stylesheet depends on. Default empty array.
176 * @param string|bool|null $ver Optional. String specifying stylesheet version number, if it has one, which is added to the URL
177 * as a query string for cache busting purposes. If version is set to false, a version
178 * number is automatically added equal to current installed WordPress version.
179 * If set to null, no version is added.
180 * @param string $media Optional. The media for which this stylesheet has been defined.
181 * Default 'all'. Accepts media types like 'all', 'print' and 'screen', or media queries like
182 * '(orientation: portrait)' and '(max-width: 640px)'.
183 */
184 function gutenberg_override_style( $styles, $handle, $src, $deps = array(), $ver = false, $media = 'all' ) {
185 $style = $styles->query( $handle, 'registered' );
186 if ( $style ) {
187 $styles->remove( $handle );
188 }
189 $styles->add( $handle, $src, $deps, $ver, $media );
190 }
191
192 /**
193 * Registers vendor JavaScript files to be used as dependencies of the editor
194 * and plugins.
195 *
196 * This function is called from a script during the plugin build process, so it
197 * should not call any WordPress PHP functions.
198 *
199 * @since 0.1.0
200 *
201 * @param WP_Scripts $scripts WP_Scripts instance.
202 */
203 function gutenberg_register_vendor_scripts( $scripts ) {
204 $suffix = SCRIPT_DEBUG ? '' : '.min';
205
206 $react_suffix = ( SCRIPT_DEBUG ? '.development' : '.production' ) . $suffix;
207 gutenberg_register_vendor_script(
208 $scripts,
209 'react',
210 'https://unpkg.com/react@17.0.1/umd/react' . $react_suffix . '.js',
211 array( 'wp-polyfill' )
212 );
213 gutenberg_register_vendor_script(
214 $scripts,
215 'react-dom',
216 'https://unpkg.com/react-dom@17.0.1/umd/react-dom' . $react_suffix . '.js',
217 array( 'react' )
218 );
219 }
220 add_action( 'wp_default_scripts', 'gutenberg_register_vendor_scripts' );
221
222 /**
223 * Registers all the WordPress packages scripts that are in the standardized
224 * `build/` location.
225 *
226 * @since 4.5.0
227 *
228 * @param WP_Scripts $scripts WP_Scripts instance.
229 */
230 function gutenberg_register_packages_scripts( $scripts ) {
231 // When in production, use the plugin's version as the default asset version;
232 // else (for development or test) default to use the current time.
233 $default_version = defined( 'GUTENBERG_VERSION' ) && ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? GUTENBERG_VERSION : time();
234
235 foreach ( glob( gutenberg_dir_path() . 'build/*/index.min.js' ) as $path ) {
236 // Prefix `wp-` to package directory to get script handle.
237 // For example, `…/build/a11y/index.min.js` becomes `wp-a11y`.
238 $handle = 'wp-' . basename( dirname( $path ) );
239
240 // Replace extension with `.asset.php` to find the generated dependencies file.
241 $asset_file = substr( $path, 0, -( strlen( '.js' ) ) ) . '.asset.php';
242 $asset = file_exists( $asset_file )
243 ? require( $asset_file )
244 : null;
245 $dependencies = isset( $asset['dependencies'] ) ? $asset['dependencies'] : array();
246 $version = isset( $asset['version'] ) ? $asset['version'] : $default_version;
247
248 // Add dependencies that cannot be detected and generated by build tools.
249 switch ( $handle ) {
250 case 'wp-block-library':
251 array_push( $dependencies, 'editor' );
252 break;
253
254 case 'wp-edit-post':
255 array_push( $dependencies, 'media-models', 'media-views', 'postbox' );
256 break;
257
258 case 'wp-edit-site':
259 array_push( $dependencies, 'wp-dom-ready' );
260 break;
261 }
262
263 // Get the path from Gutenberg directory as expected by `gutenberg_url`.
264 $gutenberg_path = substr( $path, strlen( gutenberg_dir_path() ) );
265
266 gutenberg_override_script(
267 $scripts,
268 $handle,
269 gutenberg_url( $gutenberg_path ),
270 $dependencies,
271 $version,
272 true
273 );
274 }
275 }
276 add_action( 'wp_default_scripts', 'gutenberg_register_packages_scripts' );
277
278 /**
279 * Registers all the WordPress packages styles that are in the standardized
280 * `build/` location.
281 *
282 * @since 6.7.0
283
284 * @param WP_Styles $styles WP_Styles instance.
285 */
286 function gutenberg_register_packages_styles( $styles ) {
287 // When in production, use the plugin's version as the asset version;
288 // else (for development or test) default to use the current time.
289 $version = defined( 'GUTENBERG_VERSION' ) && ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? GUTENBERG_VERSION : time();
290
291 // Editor Styles.
292 gutenberg_override_style(
293 $styles,
294 'wp-block-editor',
295 gutenberg_url( 'build/block-editor/style.css' ),
296 array( 'wp-components' ),
297 $version
298 );
299 $styles->add_data( 'wp-block-editor', 'rtl', 'replace' );
300
301 gutenberg_override_style(
302 $styles,
303 'wp-editor',
304 gutenberg_url( 'build/editor/style.css' ),
305 array( 'wp-components', 'wp-block-editor', 'wp-nux', 'wp-reusable-blocks' ),
306 $version
307 );
308 $styles->add_data( 'wp-editor', 'rtl', 'replace' );
309
310 gutenberg_override_style(
311 $styles,
312 'wp-edit-post',
313 gutenberg_url( 'build/edit-post/style.css' ),
314 array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-block-library', 'wp-nux' ),
315 $version
316 );
317 $styles->add_data( 'wp-edit-post', 'rtl', 'replace' );
318
319 gutenberg_override_style(
320 $styles,
321 'wp-components',
322 gutenberg_url( 'build/components/style.css' ),
323 array( 'dashicons' ),
324 $version
325 );
326 $styles->add_data( 'wp-components', 'rtl', 'replace' );
327
328 $block_library_filename = wp_should_load_separate_core_block_assets() ? 'common' : 'style';
329 gutenberg_override_style(
330 $styles,
331 'wp-block-library',
332 gutenberg_url( 'build/block-library/' . $block_library_filename . '.css' ),
333 array(),
334 $version
335 );
336 $styles->add_data( 'wp-block-library', 'rtl', 'replace' );
337 $styles->add_data( 'wp-block-library', 'path', gutenberg_dir_path() . 'build/block-library/' . $block_library_filename . '.css' );
338
339 gutenberg_override_style(
340 $styles,
341 'wp-format-library',
342 gutenberg_url( 'build/format-library/style.css' ),
343 array( 'wp-block-editor', 'wp-components' ),
344 $version
345 );
346 $styles->add_data( 'wp-format-library', 'rtl', 'replace' );
347
348 $wp_edit_blocks_dependencies = array(
349 'wp-components',
350 'wp-editor',
351 // This need to be added before the block library styles,
352 // The block library styles override the "reset" styles.
353 'wp-reset-editor-styles',
354 'wp-block-library',
355 'wp-reusable-blocks',
356 );
357
358 // Only load the default layout and margin styles for themes without theme.json file.
359 if ( ! WP_Theme_JSON_Resolver_Gutenberg::theme_has_support() ) {
360 $wp_edit_blocks_dependencies[] = 'wp-editor-classic-layout-styles';
361 }
362
363 global $editor_styles;
364 if ( ! is_array( $editor_styles ) || count( $editor_styles ) === 0 ) {
365 // Include opinionated block styles if no $editor_styles are declared, so the editor never appears broken.
366 $wp_edit_blocks_dependencies[] = 'wp-block-library-theme';
367 }
368
369 gutenberg_override_style(
370 $styles,
371 'wp-reset-editor-styles',
372 gutenberg_url( 'build/block-library/reset.css' ),
373 array( 'common', 'forms' ), // Make sure the reset is loaded after the default WP Adminn styles.
374 $version
375 );
376 $styles->add_data( 'wp-reset-editor-styles', 'rtl', 'replace' );
377
378 gutenberg_override_style(
379 $styles,
380 'wp-editor-classic-layout-styles',
381 gutenberg_url( 'build/edit-post/classic.css' ),
382 array(),
383 $version
384 );
385 $styles->add_data( 'wp-editor-classic-layout-styles', 'rtl', 'replace' );
386
387 gutenberg_override_style(
388 $styles,
389 'wp-edit-blocks',
390 gutenberg_url( 'build/block-library/editor.css' ),
391 $wp_edit_blocks_dependencies,
392 $version
393 );
394 $styles->add_data( 'wp-edit-blocks', 'rtl', 'replace' );
395
396 gutenberg_override_style(
397 $styles,
398 'wp-nux',
399 gutenberg_url( 'build/nux/style.css' ),
400 array( 'wp-components' ),
401 $version
402 );
403 $styles->add_data( 'wp-nux', 'rtl', 'replace' );
404
405 gutenberg_override_style(
406 $styles,
407 'wp-block-library-theme',
408 gutenberg_url( 'build/block-library/theme.css' ),
409 array(),
410 $version
411 );
412 $styles->add_data( 'wp-block-library-theme', 'rtl', 'replace' );
413
414 gutenberg_override_style(
415 $styles,
416 'wp-list-reusable-blocks',
417 gutenberg_url( 'build/list-reusable-blocks/style.css' ),
418 array( 'wp-components' ),
419 $version
420 );
421 $styles->add_data( 'wp-list-reusable-block', 'rtl', 'replace' );
422
423 gutenberg_override_style(
424 $styles,
425 'wp-edit-navigation',
426 gutenberg_url( 'build/edit-navigation/style.css' ),
427 array( 'wp-components', 'wp-block-editor', 'wp-edit-blocks' ),
428 $version
429 );
430 $styles->add_data( 'wp-edit-navigation', 'rtl', 'replace' );
431
432 gutenberg_override_style(
433 $styles,
434 'wp-edit-site',
435 gutenberg_url( 'build/edit-site/style.css' ),
436 array( 'wp-components', 'wp-block-editor', 'wp-edit-blocks' ),
437 $version
438 );
439 $styles->add_data( 'wp-edit-site', 'rtl', 'replace' );
440
441 gutenberg_override_style(
442 $styles,
443 'wp-edit-widgets',
444 gutenberg_url( 'build/edit-widgets/style.css' ),
445 array( 'wp-components', 'wp-block-editor', 'wp-edit-blocks', 'wp-reusable-blocks', 'wp-widgets' ),
446 $version
447 );
448 $styles->add_data( 'wp-edit-widgets', 'rtl', 'replace' );
449
450 gutenberg_override_style(
451 $styles,
452 'wp-block-directory',
453 gutenberg_url( 'build/block-directory/style.css' ),
454 array( 'wp-block-editor', 'wp-components' ),
455 $version
456 );
457 $styles->add_data( 'wp-block-directory', 'rtl', 'replace' );
458
459 gutenberg_override_style(
460 $styles,
461 'wp-customize-widgets',
462 gutenberg_url( 'build/customize-widgets/style.css' ),
463 array( 'wp-components', 'wp-block-editor', 'wp-edit-blocks', 'wp-widgets' ),
464 $version
465 );
466 $styles->add_data( 'wp-customize-widgets', 'rtl', 'replace' );
467
468 gutenberg_override_style(
469 $styles,
470 'wp-reusable-blocks',
471 gutenberg_url( 'build/reusable-blocks/style.css' ),
472 array( 'wp-components' ),
473 $version
474 );
475 $styles->add_data( 'wp-reusable-block', 'rtl', 'replace' );
476
477 gutenberg_override_style(
478 $styles,
479 'wp-widgets',
480 gutenberg_url( 'build/widgets/style.css' ),
481 array( 'wp-components' )
482 );
483 $styles->add_data( 'wp-widgets', 'rtl', 'replace' );
484 }
485 add_action( 'wp_default_styles', 'gutenberg_register_packages_styles' );
486
487 /**
488 * Registers common scripts and styles to be used as dependencies of the editor
489 * and plugins.
490 *
491 * @since 0.1.0
492 */
493 function gutenberg_enqueue_block_editor_assets() {
494 if ( defined( 'GUTENBERG_LIVE_RELOAD' ) && GUTENBERG_LIVE_RELOAD ) {
495 $live_reload_url = ( GUTENBERG_LIVE_RELOAD === true ) ? 'http://localhost:35729/livereload.js' : GUTENBERG_LIVE_RELOAD;
496
497 wp_enqueue_script(
498 'gutenberg-live-reload',
499 $live_reload_url
500 );
501 }
502 }
503 add_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets' );
504
505 /**
506 * Retrieves a unique and reasonably short and human-friendly filename for a
507 * vendor script based on a URL and the script handle.
508 *
509 * @param string $handle The name of the script.
510 * @param string $src Full URL of the external script.
511 *
512 * @return string Script filename suitable for local caching.
513 *
514 * @since 0.1.0
515 */
516 function gutenberg_vendor_script_filename( $handle, $src ) {
517 $filename = basename( $src );
518 $match = preg_match(
519 '/^'
520 . '(?P<ignore>.*?)'
521 . '(?P<suffix>\.min)?'
522 . '(?P<extension>\.js)'
523 . '(?P<extra>.*)'
524 . '$/',
525 $filename,
526 $filename_pieces
527 );
528
529 $prefix = $handle;
530 $suffix = $match ? $filename_pieces['suffix'] : '';
531 $hash = substr( md5( $src ), 0, 8 );
532
533 return "${prefix}${suffix}.${hash}.js";
534 }
535
536 /**
537 * Registers a vendor script from a URL, preferring a locally cached version if
538 * possible, or downloading it if the cached version is unavailable or
539 * outdated.
540 *
541 * @param WP_Scripts $scripts WP_Scripts instance.
542 * @param string $handle Name of the script.
543 * @param string $src Full URL of the external script.
544 * @param array $deps Optional. An array of registered script handles this
545 * script depends on.
546 * @param string|bool|null $ver Optional. String specifying script version number, if it has one, which is added to the URL
547 * as a query string for cache busting purposes. If version is set to false, a version
548 * number is automatically added equal to current installed WordPress version.
549 * If set to null, no version is added.
550 * @param bool $in_footer Optional. Whether to enqueue the script before </body> instead of in the <head>.
551 * Default 'false'.
552 *
553 * @since 0.1.0
554 */
555 function gutenberg_register_vendor_script( $scripts, $handle, $src, $deps = array(), $ver = null, $in_footer = false ) {
556 if ( defined( 'GUTENBERG_LOAD_VENDOR_SCRIPTS' ) && ! GUTENBERG_LOAD_VENDOR_SCRIPTS ) {
557 return;
558 }
559
560 $filename = gutenberg_vendor_script_filename( $handle, $src );
561
562 if ( defined( 'GUTENBERG_LIST_VENDOR_ASSETS' ) && GUTENBERG_LIST_VENDOR_ASSETS ) {
563 echo "$src|$filename\n";
564 return;
565 }
566
567 $full_path = gutenberg_dir_path() . 'vendor/' . $filename;
568
569 $needs_fetch = (
570 defined( 'GUTENBERG_DEVELOPMENT_MODE' ) && GUTENBERG_DEVELOPMENT_MODE && (
571 ! file_exists( $full_path ) ||
572 time() - filemtime( $full_path ) >= DAY_IN_SECONDS
573 )
574 );
575
576 if ( $needs_fetch ) {
577 // Determine whether we can write to this file. If not, don't waste
578 // time doing a network request.
579 // @codingStandardsIgnoreStart
580
581 $is_writable = is_writable( $full_path );
582 if ( $is_writable ) {
583 $f = @fopen( $full_path, 'a' );
584 if ( ! $f ) {
585 $is_writable = false;
586 } else {
587 fclose( $f );
588 }
589 }
590
591 // @codingStandardsIgnoreEnd
592 if ( ! $is_writable ) {
593 // Failed to open the file for writing, probably due to server
594 // permissions. Enqueue the script directly from the URL instead.
595 gutenberg_override_script( $scripts, $handle, $src, $deps, $ver, $in_footer );
596 return;
597 }
598
599 $response = wp_remote_get( $src );
600 if ( wp_remote_retrieve_response_code( $response ) === 200 ) {
601 $f = fopen( $full_path, 'w' );
602 fwrite( $f, wp_remote_retrieve_body( $response ) );
603 fclose( $f );
604 } elseif ( ! filesize( $full_path ) ) {
605 // The request failed. If the file is already cached, continue to
606 // use this file. If not, then unlink the 0 byte file, and enqueue
607 // the script directly from the URL.
608 gutenberg_override_script( $scripts, $handle, $src, $deps, $ver, $in_footer );
609 unlink( $full_path );
610 return;
611 }
612 }
613 gutenberg_override_script(
614 $scripts,
615 $handle,
616 gutenberg_url( 'vendor/' . $filename ),
617 $deps,
618 $ver,
619 $in_footer
620 );
621 }
622
623 /**
624 * Extends block editor settings to remove the Gutenberg's `editor-styles.css`;
625 *
626 * This can be removed when plugin support requires WordPress 5.8.0+.
627 *
628 * @param array $settings Default editor settings.
629 *
630 * @return array Filtered editor settings.
631 */
632 function gutenberg_extend_block_editor_styles( $settings ) {
633 if ( empty( $settings['styles'] ) ) {
634 $settings['styles'] = array();
635 } else {
636 /*
637 * WordPress versions prior to 5.8 include a legacy editor styles file
638 * that need to be removed.
639 * This code can be removed from the Gutenberg plugin when the supported WP
640 * version is 5.8
641 */
642 $default_styles_file = is_rtl() ?
643 ABSPATH . WPINC . '/css/dist/editor/editor-styles-rtl.css' :
644 ABSPATH . WPINC . '/css/dist/editor/editor-styles.css';
645
646 if ( file_exists( $default_styles_file ) ) {
647 $default_styles = file_get_contents(
648 $default_styles_file
649 );
650
651 /*
652 * Iterate backwards from the end of the array since the preferred
653 * insertion point in case not found is prepended as first entry.
654 */
655 for ( $i = count( $settings['styles'] ) - 1; $i >= 0; $i-- ) {
656 if ( isset( $settings['styles'][ $i ]['css'] ) &&
657 $default_styles === $settings['styles'][ $i ]['css'] ) {
658 break;
659 }
660 }
661
662 if ( isset( $i ) && $i >= 0 ) {
663 unset( $settings['styles'][ $i ] );
664 }
665 }
666 }
667
668 // Remove the default font editor styles for FSE themes.
669 if ( WP_Theme_JSON_Resolver_Gutenberg::theme_has_support() ) {
670 foreach ( $settings['styles'] as $j => $style ) {
671 if ( 0 === strpos( $style['css'], 'body { font-family:' ) ) {
672 unset( $settings['styles'][ $j ] );
673 }
674 }
675 }
676
677 return $settings;
678 }
679 // This can be removed when plugin support requires WordPress 5.8.0+.
680 if ( function_exists( 'get_block_editor_settings' ) ) {
681 add_filter( 'block_editor_settings_all', 'gutenberg_extend_block_editor_styles' );
682 } else {
683 add_filter( 'block_editor_settings', 'gutenberg_extend_block_editor_styles' );
684 }
685
686 /**
687 * Adds a flag to the editor settings to know whether we're in FSE theme or not.
688 *
689 * This can be removed when plugin support requires WordPress 5.8.0+.
690 *
691 * @param array $settings Default editor settings.
692 *
693 * @return array Filtered editor settings.
694 */
695 function gutenberg_extend_block_editor_settings_with_fse_theme_flag( $settings ) {
696 $settings['supportsTemplateMode'] = gutenberg_supports_block_templates();
697
698 // Enable the new layout options for themes with a theme.json file.
699 $settings['supportsLayout'] = WP_Theme_JSON_Resolver_Gutenberg::theme_has_support();
700
701 return $settings;
702 }
703 // This can be removed when plugin support requires WordPress 5.8.0+.
704 if ( function_exists( 'get_block_editor_settings' ) ) {
705 add_filter( 'block_editor_settings_all', 'gutenberg_extend_block_editor_settings_with_fse_theme_flag' );
706 } else {
707 add_filter( 'block_editor_settings', 'gutenberg_extend_block_editor_settings_with_fse_theme_flag' );
708 }
709
710 /**
711 * Sets the editor styles to be consumed by JS.
712 */
713 function gutenberg_extend_block_editor_styles_html() {
714 global $pagenow;
715
716 $script_handles = array();
717 $style_handles = array(
718 'wp-block-editor',
719 'wp-block-library',
720 'wp-block-library-theme',
721 'wp-edit-blocks',
722 );
723
724 if ( 'widgets.php' === $pagenow || 'customize.php' === $pagenow ) {
725 $style_handles[] = 'wp-widgets';
726 $style_handles[] = 'wp-edit-widgets';
727 }
728
729 $block_registry = WP_Block_Type_Registry::get_instance();
730
731 foreach ( $block_registry->get_all_registered() as $block_type ) {
732 if ( ! empty( $block_type->style ) ) {
733 $style_handles[] = $block_type->style;
734 }
735
736 if ( ! empty( $block_type->editor_style ) ) {
737 $style_handles[] = $block_type->editor_style;
738 }
739
740 if ( ! empty( $block_type->script ) ) {
741 $script_handles[] = $block_type->script;
742 }
743 }
744
745 $style_handles = array_unique( $style_handles );
746 $done = wp_styles()->done;
747
748 ob_start();
749
750 // We do not need reset styles for the iframed editor.
751 wp_styles()->done = array( 'wp-reset-editor-styles' );
752 wp_styles()->do_items( $style_handles );
753 wp_styles()->done = $done;
754
755 $styles = ob_get_clean();
756
757 $script_handles = array_unique( $script_handles );
758 $done = wp_scripts()->done;
759
760 ob_start();
761
762 wp_scripts()->done = array();
763 wp_scripts()->do_items( $script_handles );
764 wp_scripts()->done = $done;
765
766 $scripts = ob_get_clean();
767
768 $editor_assets = wp_json_encode(
769 array(
770 'styles' => $styles,
771 'scripts' => $scripts,
772 )
773 );
774
775 echo "<script>window.__editorAssets = $editor_assets</script>";
776 }
777 add_action( 'admin_footer-appearance_page_gutenberg-edit-site', 'gutenberg_extend_block_editor_styles_html' );
778 add_action( 'admin_footer-post.php', 'gutenberg_extend_block_editor_styles_html' );
779 add_action( 'admin_footer-post-new.php', 'gutenberg_extend_block_editor_styles_html' );
780 add_action( 'admin_footer-widgets.php', 'gutenberg_extend_block_editor_styles_html' );
781