PluginProbe
Gutenberg / 12.8.1
Gutenberg v12.8.1
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.8.1, at lib/client-assets.php

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