-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Elements: Add styles to the footer before the block is rendered #37728
Changes from all commits
d43a3ce
2d50ea2
e34c716
9b22cad
46e5e40
4c65449
4b8f820
653aede
92cc1ab
e524d1d
f67438c
6aca09e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,14 +6,23 @@ | |
*/ | ||
|
||
/** | ||
* Render the elements stylesheet. | ||
* Get the elements class names. | ||
* | ||
* @param array $block Block object. | ||
* @return string The unique class name. | ||
*/ | ||
function gutenberg_get_elements_class_name( $block ) { | ||
return 'wp-elements-' . md5( serialize( $block ) ); | ||
} | ||
|
||
/** | ||
* Update the block content with elements class names. | ||
* | ||
* @param string $block_content Rendered block content. | ||
* @param array $block Block object. | ||
* @return string Filtered block content. | ||
*/ | ||
function gutenberg_render_elements_support( $block_content, $block ) { | ||
|
||
if ( ! $block_content ) { | ||
return $block_content; | ||
} | ||
|
@@ -40,17 +49,7 @@ function gutenberg_render_elements_support( $block_content, $block ) { | |
return $block_content; | ||
} | ||
|
||
$class_name = wp_unique_id( 'wp-elements-' ); | ||
|
||
if ( strpos( $link_color, 'var:preset|color|' ) !== false ) { | ||
// Get the name from the string and add proper styles. | ||
$index_to_splice = strrpos( $link_color, '|' ) + 1; | ||
$link_color_name = substr( $link_color, $index_to_splice ); | ||
$link_color = "var(--wp--preset--color--$link_color_name)"; | ||
} | ||
$link_color_declaration = esc_html( safecss_filter_attr( "color: $link_color" ) ); | ||
|
||
$style = ".$class_name a{" . $link_color_declaration . ';}'; | ||
$class_name = gutenberg_get_elements_class_name( $block ); | ||
|
||
// Like the layout hook this assumes the hook only applies to blocks with a single wrapper. | ||
// Retrieve the opening tag of the first HTML element. | ||
|
@@ -72,11 +71,61 @@ function gutenberg_render_elements_support( $block_content, $block ) { | |
$content = substr_replace( $block_content, ' class="' . $class_name . '"', $first_element_offset + strlen( $first_element ) - 1, 0 ); | ||
} | ||
|
||
return $content; | ||
} | ||
|
||
/** | ||
* Render the elements stylesheet. | ||
* | ||
* In the case of nested blocks we want the parent element styles to be rendered before their descendants. | ||
* This solves the issue of an element (e.g.: link color) being styled in both the parent and a descendant: | ||
* we want the descendant style to take priority, and this is done by loading it after, in DOM order. | ||
* | ||
* @param string|null $pre_render The pre-rendered content. Default null. | ||
* @param array $block The block being rendered. | ||
* | ||
* @return null | ||
*/ | ||
function gutenberg_render_elements_support_styles( $pre_render, $block ) { | ||
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); | ||
$skip_link_color_serialization = gutenberg_should_skip_block_supports_serialization( $block_type, 'color', 'link' ); | ||
if ( $skip_link_color_serialization ) { | ||
return null; | ||
} | ||
|
||
$link_color = null; | ||
if ( ! empty( $block['attrs'] ) ) { | ||
$link_color = _wp_array_get( $block['attrs'], array( 'style', 'elements', 'link', 'color', 'text' ), null ); | ||
} | ||
|
||
/* | ||
* For now we only care about link color. | ||
* This code in the future when we have a public API | ||
* should take advantage of WP_Theme_JSON_Gutenberg::compute_style_properties | ||
* and work for any element and style. | ||
*/ | ||
if ( null === $link_color ) { | ||
return null; | ||
} | ||
|
||
$class_name = gutenberg_get_elements_class_name( $block ); | ||
|
||
if ( strpos( $link_color, 'var:preset|color|' ) !== false ) { | ||
// Get the name from the string and add proper styles. | ||
$index_to_splice = strrpos( $link_color, '|' ) + 1; | ||
$link_color_name = substr( $link_color, $index_to_splice ); | ||
$link_color = "var(--wp--preset--color--$link_color_name)"; | ||
} | ||
$link_color_declaration = esc_html( safecss_filter_attr( "color: $link_color" ) ); | ||
|
||
$style = ".$class_name a{" . $link_color_declaration . ';}'; | ||
|
||
gutenberg_enqueue_block_support_styles( $style ); | ||
|
||
return $content; | ||
return null; | ||
} | ||
|
||
// Remove WordPress core filter to avoid rendering duplicate elements stylesheet. | ||
remove_filter( 'render_block', 'wp_render_elements_support', 10, 2 ); | ||
add_filter( 'render_block', 'gutenberg_render_elements_support', 10, 2 ); | ||
add_filter( 'pre_render_block', 'gutenberg_render_elements_support_styles', 10, 2 ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For me this PR raises an interesting question about the styles order. Is there any place where we want the block styles to be generated "child" first then "parent" later? In other words, this PR does invert the order for the "elements" styles but why not invert it for all kind of styles. It seems it's something worth thinking about for the future in regards of the style engine work. cc @andrewserong @ramonjd There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Thanks for the ping. I suppose depending on how we output styles we might want to look at a mix of specificity and style rendering order. Anyway, I've added a note to look at a complete inheritance modal over at the style engine tracking issue. 🙇 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe it should be like this for all styles, to follow the pattern of CSS inheritance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did that for the sake of the test...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed the test I suggested we should have. As you said, in this case, the value would lie in a e2e test. It'd be great to have it :)