Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block editor: iframe: add enqueue_block_assets #49655

Merged
merged 12 commits into from
Apr 26, 2023
2 changes: 1 addition & 1 deletion lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ function gutenberg_register_packages_styles( $styles ) {
$styles,
'wp-block-editor-content',
gutenberg_url( 'build/block-editor/content.css' ),
array(),
array( 'wp-components' ),
ellatrix marked this conversation as resolved.
Show resolved Hide resolved
$version
);
$styles->add_data( 'wp-block-editor-content', 'rtl', 'replace' );
Expand Down
70 changes: 70 additions & 0 deletions lib/compat/wordpress-6.3/script-loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,73 @@
remove_action( 'wp_body_open', 'wp_global_styles_render_svg_filters' );
remove_action( 'in_admin_header', 'wp_global_styles_render_svg_filters' );

/**
* Collect the block editor assets that need to be loaded into the editor's iframe.
*
* @since 6.0.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be 6.3.0?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be replacing the core function, which was introduced in 6.0.0?

* @access private
*
* @return array {
* The block editor assets.
*
* @type string|false $styles String containing the HTML for styles.
* @type string|false $scripts String containing the HTML for scripts.
* }
*/
function _gutenberg_get_iframed_editor_assets() {
global $wp_styles, $wp_scripts;

// Keep track of the styles and scripts instance to restore later.
$current_wp_styles = $wp_styles;
$current_wp_scripts = $wp_scripts;

// Create new instances to collect the assets.
$wp_styles = new WP_Styles();
$wp_scripts = new WP_Scripts();

// Register all currently registered styles and scripts. The actions that
// follow enqueue assets, but don't necessarily register them.
$wp_styles->registered = $current_wp_styles->registered;
$wp_scripts->registered = $current_wp_scripts->registered;

wp_enqueue_style( 'wp-block-editor-content' );
ellatrix marked this conversation as resolved.
Show resolved Hide resolved
// To do: investigate why this is not enqueued through enqueue_block_assets,
// as styles for non-core blocks are.
wp_enqueue_style( 'wp-block-library' );
wp_enqueue_script( 'wp-polyfill' );

// We don't want to load EDITOR scripts and styles in the iframe, only
// assets for the content.
add_filter( 'should_load_block_editor_scripts_and_styles', '__return_false' );
do_action( 'enqueue_block_assets' );
remove_filter( 'should_load_block_editor_scripts_and_styles', '__return_false' );

ob_start();
wp_print_styles();
wp_print_fonts();
Copy link
Contributor

@arthur791004 arthur791004 May 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an issue using wp_print_fonts since it will do nothing if the handles are empty.

Before, Gutenberg assigned the registered fonts to the queue so $wp_fonts can fallback to the handles in the queue. However, this function doesn't implement that mechanism and it leads to the font styles won't be printed

For example,

  1. Activate TT3 on your site
  2. Go to the site editor
  3. Select Styles > Typography > Text
  4. Try different fonts, e.g. Arvo, Bodoni Moda
  5. The selected font is not affected

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this fixed now since #49655 (comment)? Thanks for looking into it!

@ellatrix Yes, it is fixed via PR #49655. That change was cherry-picked for 15.7.1, which will be released today.

$styles = ob_get_clean();

ob_start();
wp_print_head_scripts();
wp_print_footer_scripts();
$scripts = ob_get_clean();

// Restore the original instances.
$wp_styles = $current_wp_styles;
$wp_scripts = $current_wp_scripts;

return array(
'styles' => $styles,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documenting how we fill this array in core:

  • styles
    • wp-polyfill
    • for all registered blocks: the $script_handles (script asset from block.json as well as any other registered by other means)
    • all the dependencies of the previous two items (automatically resolved by wp_scripts->do_items)
  • scripts
    • wp-edit-blocks
    • wp-block-library-theme if theme supports wp-block-styles but hasn't provided any
    • wp-widgets and wp-edit-widgets for the widgets editor
    • for all registered blocks: the $style_handles and $editor_style_handles (style and editorStyles assets from block.json respectively, as well as any other registered by other means)
    • all the dependencies of the previous items (automatically resolved by wp_styles->do_items
    • wp-reset-editor-styles: avoid enqueuing it in the iframe by adding it to the done queue, so it's ignored

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this should be covered, except the widgets stuff as the iframe is not being used there right now. wp-reset-editor-styles is not added.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've looked at the assets loaded in the iframe for the post editor using the TwentyTwentyThree theme.

Extra things this PR has that are not present in trunk:

  • The assets added via enqueue_block_assets. This is correct. I've used this test plugin:
    • enqueue_block_assets_style_body is for styles without a .wp-block class
    • enqueue_block_assets_style_wp_block is for styles with .wp-block class
  • The inline styles for emojis, which are not present in trunk. Are these necessary?

Things this PR misses that are present in trunk:

  • wp-reusable-blocks. I'm a bit surprised about this. It should have been present because it's a dependency of wp-edit-blocks, which is enqueued. The same issue happens with wp-components and we had to declare it as a dependency of wp-block-editor-content for it to be enqueued. It sounds like all dependencies of wp-edit-blocks are missing. Any ideas why would this happen? 🤔
  • wp-fonts-local. It sounds like these are fonts defined by the theme.
Post Editor Assets Trunk This PR
html.height.auto, body.margin.0 (inline) x x
img.wp-smiley, img.emoji (inline) x
dashicons-css x x
wp-components-css x x
wp-block-editor-content-css x x
wp-block-library-css x x
wp-edit-blocks-css x x
wp-reusable-blocks-css x
wp-fonts-local (inline) x
enqueue_block_assets_style_body-css x
enqueue_block_assets_style_wp_block-css x x
enqueue_block_editor_assets_style_wp_block-css x x
wp-inert-polyfill-js x x
enqueue_block_assets_script_console-js x
enqueue_block_assets_wp_api-js x
wp-polyfill-inert-js x x
regenerator-runtime-js x x
wp-polyfill-js x x

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wp-reusable-blocks is not there because wp-edit-blocks is added through the compat layer. We need to change wp-edit-blocks in a follow up PR so it's not added anymore. wp-reusable-blocks does not contain any styles relevant to the editor content.

wp-fonts-local this is not present in core either. Looks like these are added in the 6.2, but not added to WP core. I don't know why. Since they are not present in core I don't think it's a big deal (see lib/compat/wordpress-6.2/script-loader.php)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wp-reusable-blocks is not there because wp-edit-blocks is added through the compat layer.

I just checked and that's correct! It can be iterated in a follow-up.

img.wp-smiley, img.emoji (inline)

This is also enqueued in the front, so it's expected.

enqueue_block_assets_style_body-css, enqueue_block_assets_script_console-js, enqueue_block_assets_wp_api-js

What we aimed to get with this PR.

'scripts' => $scripts,
);
}

add_filter(
'block_editor_settings_all',
function( $settings ) {
// We must override what core is passing now.
$settings['__unstableResolvedAssets'] = _gutenberg_get_iframed_editor_assets();
return $settings;
},
100
);
21 changes: 21 additions & 0 deletions packages/e2e-tests/plugins/iframed-enqueue-block-assets.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
/**
* Plugin Name: Gutenberg Test Iframed enqueue_block_assets
* Plugin URI: https://github.com/WordPress/gutenberg
* Author: Gutenberg Team
*
* @package gutenberg-test-iframed-iframed-enqueue-block-assets
*/

add_action(
'enqueue_block_assets',
function() {
wp_enqueue_style(
'iframed-enqueue-block-assets',
plugin_dir_url( __FILE__ ) . 'iframed-enqueue-block-assets/style.css',
array(),
filemtime( plugin_dir_path( __FILE__ ) . 'iframed-enqueue-block-assets/style.css' )
);
wp_add_inline_style( 'iframed-enqueue-block-assets', 'body{padding:20px!important}' );
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* The following styles get applied both on the front of your site and in the
* editor.
*/
body {
background-color: rgb(33, 117, 155) !important;
color: #fff !important;
padding: 2px !important;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* WordPress dependencies
*/
import {
activatePlugin,
createNewPost,
deactivatePlugin,
canvas,
activateTheme,
} from '@wordpress/e2e-test-utils';

async function getComputedStyle( context, selector, property ) {
return await context.evaluate(
( sel, prop ) =>
window.getComputedStyle( document.querySelector( sel ) )[ prop ],
selector,
property
);
}

describe( 'iframed inline styles', () => {
beforeEach( async () => {
// Activate the empty theme (block based theme), which is iframed.
await activateTheme( 'emptytheme' );
await activatePlugin( 'gutenberg-test-iframed-enqueue_block_assets' );
await createNewPost();
} );

afterEach( async () => {
await deactivatePlugin( 'gutenberg-test-iframed-enqueue_block_assets' );
await activateTheme( 'twentytwentyone' );
} );

it( 'should load styles added through enqueue_block_assets', async () => {
// Check stylesheet.
expect(
await getComputedStyle( canvas(), 'body', 'background-color' )
).toBe( 'rgb(33, 117, 155)' );
// Check inline style.
expect( await getComputedStyle( canvas(), 'body', 'padding' ) ).toBe(
'20px'
);
} );
} );