From 090171de32704bb8b8777bc9339b052fa3a5aec1 Mon Sep 17 00:00:00 2001 From: Ramon Date: Wed, 10 Aug 2022 08:16:46 +1000 Subject: [PATCH] Style engine: enqueue block supports styles in Gutenberg (#42880) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Enqueuing block supports styles in gutenberg Updating README.md * get_instance() and constructor no longer needed * remove $instance declaration * Rename hook callback to `gutenberg_enqueue_stored_styles` Hard code a list of core styles that we want to fetch from the store and the order in which we fetch them. * Removing layout-block-supports store Chaining store ids for the style tag id attribute so it's clear what's being included. Also adding a comment for debugging for the same purpose. * Removing layout-block-supports store Chaining store ids for the style tag id attribute so it's clear what's being included. Also adding a comment for debugging for the same purpose. Adding tests for enqueuing styles Updated README.md * Assign $duplicate_selectors var to avoid duplicate implodes * Update packages/style-engine/README.md Co-authored-by: Andrew Serong <14988353+andrewserong@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Andrew Serong <14988353+andrewserong@users.noreply.github.com> * Remove unnecessary conditional * Remove deprecation notice for now until we can deal with other usages, e.g., gallery/index.php * For block themes, print stored styles in the header. For classic themes, in the footer. * Update packages/style-engine/README.md Co-authored-by: Sören Wrede Co-authored-by: Ari Stathopoulos Co-authored-by: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Co-authored-by: Sören Wrede --- lib/compat/wordpress-6.1/script-loader.php | 58 ++++++ packages/style-engine/README.md | 166 +++++++++++++++++- .../class-wp-style-engine-processor.php | 3 +- .../style-engine/class-wp-style-engine.php | 137 ++++----------- .../phpunit/class-wp-style-engine-test.php | 7 +- phpunit/script-loader.php | 71 ++++++++ 6 files changed, 333 insertions(+), 109 deletions(-) create mode 100644 phpunit/script-loader.php diff --git a/lib/compat/wordpress-6.1/script-loader.php b/lib/compat/wordpress-6.1/script-loader.php index 399d7e30270b67..330e6b2614e1f2 100644 --- a/lib/compat/wordpress-6.1/script-loader.php +++ b/lib/compat/wordpress-6.1/script-loader.php @@ -36,6 +36,61 @@ static function () use ( $style ) { ); } +/** + * Fetches, processes and compiles stored core styles, then combines and renders them to the page. + * Styles are stored via the style engine API. See: packages/style-engine/README.md + */ +function gutenberg_enqueue_stored_styles() { + $is_block_theme = wp_is_block_theme(); + $is_classic_theme = ! $is_block_theme; + + /* + * For block themes, print stored styles in the header. + * For classic themes, in the footer. + */ + if ( + ( $is_block_theme && doing_action( 'wp_footer' ) ) || + ( $is_classic_theme && doing_action( 'wp_enqueue_scripts' ) ) + ) { + return; + } + + $core_styles_keys = array( 'block-supports' ); + $compiled_core_stylesheet = ''; + $style_tag_id = 'core'; + foreach ( $core_styles_keys as $style_key ) { + // Add comment to identify core styles sections in debugging. + if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) { + $compiled_core_stylesheet .= "/**\n * Core styles: $style_key\n */\n"; + } + // Chain core store ids to signify what the styles contain. + $style_tag_id .= '-' . $style_key; + $compiled_core_stylesheet .= gutenberg_style_engine_get_stylesheet_from_store( $style_key ); + } + + // Combine Core styles. + if ( ! empty( $compiled_core_stylesheet ) ) { + wp_register_style( $style_tag_id, false, array(), true, true ); + wp_add_inline_style( $style_tag_id, $compiled_core_stylesheet ); + wp_enqueue_style( $style_tag_id ); + } + + // If there are any other stores registered by themes etc, print them out. + $additional_stores = WP_Style_Engine_CSS_Rules_Store_Gutenberg::get_stores(); + foreach ( array_keys( $additional_stores ) as $store_name ) { + if ( in_array( $store_name, $core_styles_keys, true ) ) { + continue; + } + $styles = gutenberg_style_engine_get_stylesheet_from_store( $store_name ); + if ( ! empty( $styles ) ) { + $key = "wp-style-engine-$store_name"; + wp_register_style( $key, false, array(), true, true ); + wp_add_inline_style( $key, $styles ); + wp_enqueue_style( $key ); + } + } +} + /** * This applies a filter to the list of style nodes that comes from `get_style_nodes` in WP_Theme_JSON. * This particular filter removes all of the blocks from the array. @@ -109,5 +164,8 @@ function gutenberg_enqueue_global_styles() { remove_action( 'wp_enqueue_scripts', 'gutenberg_enqueue_global_styles_assets' ); remove_action( 'wp_footer', 'gutenberg_enqueue_global_styles_assets' ); +// Enqueue global styles, and then block supports styles. add_action( 'wp_enqueue_scripts', 'gutenberg_enqueue_global_styles' ); add_action( 'wp_footer', 'gutenberg_enqueue_global_styles', 1 ); +add_action( 'wp_enqueue_scripts', 'gutenberg_enqueue_stored_styles' ); +add_action( 'wp_footer', 'gutenberg_enqueue_stored_styles', 1 ); diff --git a/packages/style-engine/README.md b/packages/style-engine/README.md index 4a2990c6b5f669..03ae933f24c909 100644 --- a/packages/style-engine/README.md +++ b/packages/style-engine/README.md @@ -2,6 +2,158 @@ The Style Engine powering global styles and block customizations. +## Backend API + +### wp_style_engine_get_styles() + +Global public function to generate styles from a single style object, e.g., the value of +a [block's attributes.style object](https://developer.wordpress.org/block-editor/reference-guides/theme-json-reference/theme-json-living/#styles) +or +the [top level styles in theme.json](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/) +. + +_Parameters_ + +- _$block_styles_ `array` A block's `attributes.style` object or the top level styles in theme.json +- _$options_ `array` An array of options to determine the output. + - _context_ `string` An identifier describing the origin of the style object, e.g., 'block-supports' or ' + global-styles'. Default is 'block-supports'. + - _enqueue_ `boolean` When `true` will attempt to store and enqueue for rendering in a `style` tag on the site frontend. + - _convert_vars_to_classnames_ `boolean` Whether to skip converting CSS var:? values to var( --wp--preset--\* ) + values. Default is `false`. + - _selector_ `string` When a selector is passed, `generate()` will return a full CSS rule `$selector { ...rules }`, + otherwise a concatenated string of properties and values. + +_Returns_ +`array|null` + +```php +array( + 'css' => (string) A CSS ruleset or declarations block formatted to be placed in an HTML `style` attribute or tag. + 'declarations' => (array) An array of property/value pairs representing parsed CSS declarations. + 'classnames' => (string) Classnames separated by a space. +); +``` + +It will return compiled CSS declarations for inline styles, or, where a selector is provided, a complete CSS rule. + +To enqueue a style for rendering in the site's frontend, the `$options` array requires the following: + +1. **selector (string)** - this is the CSS selector for your block style CSS declarations. +2. **context (string)** - this tells the style engine where to store the styles. Styles in the same context will be + batched together and printed in the same HTML style tag. The default is `'block-supports'`. +3. **enqueue (boolean)** - tells the style engine to store the styles. + +`wp_style_engine_get_styles` will return the compiled CSS and CSS declarations array. + +#### Usage + +```php +$block_styles = array( + 'spacing' => array( 'padding' => '100px' ) +); +$styles = wp_style_engine_get_styles( + $block_styles, + array( + 'selector' => '.a-selector', + 'context' => 'block-supports', + 'enqueue' => true, + ) +); +print_r( $styles ); + +/* +array( + 'css' => '.a-selector{padding:10px}' + 'declarations' => array( 'padding' => '100px' ) +) +*/ +``` + +### wp_style_engine_get_stylesheet_from_css_rules() + +Use this function to compile and return a stylesheet for any CSS rules. The style engine will automatically merge declarations and combine selectors. + +This function acts as a CSS compiler, but will also enqueue styles for rendering where `enqueue` and `context` strings are passed in the options. + +_Parameters_ + +- _$css_rules_ `array` +- _$options_ `array` An array of options to determine the output. + - _context_ `string` An identifier describing the origin of the style object, e.g., 'block-supports' or ' + global-styles'. Default is 'block-supports'. + - _enqueue_ `boolean` When `true` will store using the `context` value as a key. + +_Returns_ +`string` A compiled CSS string based on `$css_rules`. + +#### Usage + +```php +$styles = array( + array( + 'selector'. => '.wp-pumpkin', + 'declarations' => array( 'color' => 'orange' ) + ), + array( + 'selector'. => '.wp-tomato', + 'declarations' => array( 'color' => 'red' ) + ), + array( + 'selector'. => '.wp-tomato', + 'declarations' => array( 'padding' => '100px' ) + ), + array( + 'selector'. => '.wp-kumquat', + 'declarations' => array( 'color' => 'orange' ) + ), +); + +$stylesheet = wp_style_engine_get_stylesheet_from_css_rules( + $styles, + array( + 'context' => 'block-supports', // Indicates that these styles should be stored with block supports CSS. + 'enqueue' => true, // Render the styles for output. + ) +); +print_r( $stylesheet ); // .wp-pumpkin, .wp-kumquat {color:orange}.wp-tomato{color:red;padding:100px} +``` + +### wp_style_engine_get_stylesheet_from_store() + +Returns compiled CSS from a store, if found. + +_Parameters_ + +- _$store_key_ `string` An identifier describing the origin of the style object, e.g., 'block-supports' or ' global-styles'. Default is 'block-supports'. + +_Returns_ +`string` A compiled CSS string from the stored CSS rules. + +#### Usage + +```php +// First register some styles. +$styles = array( + array( + 'selector'. => '.wp-apple', + 'declarations' => array( 'color' => 'green' ) + ), +); + +$stylesheet = wp_style_engine_get_stylesheet_from_css_rules( + $styles, + array( + 'context' => 'fruit-styles', + 'enqueue' => true, + ) +); + +// Later, fetch compiled rules from store. +$stylesheet = gutenberg_style_engine_get_stylesheet_from_store( 'fruit-styles' ); +print_r( $stylesheet ); // .wp-apple{color:green;} +``` + ## Installation (JS only) Install the module @@ -10,13 +162,18 @@ Install the module npm install @wordpress/style-engine --save ``` -_This package assumes that your code will run in an **ES2015+** environment. If you're using an environment that has limited or no support for such language features and APIs, you should include [the polyfill shipped in `@wordpress/babel-preset-default`](https://github.com/WordPress/gutenberg/tree/HEAD/packages/babel-preset-default#polyfill) in your code._ +_This package assumes that your code will run in an **ES2015+** environment. If you're using an environment that has +limited or no support for such language features and APIs, you should +include [the polyfill shipped in `@wordpress/babel-preset-default`](https://github.com/WordPress/gutenberg/tree/HEAD/packages/babel-preset-default#polyfill) +in your code._ ## Important -This Package is considered experimental at the moment. The idea is to have a package used to generate styles based on a style object that is consistent between: backend, frontend, block style object and theme.json. +This Package is considered experimental at the moment. The idea is to have a package used to generate styles based on a +style object that is consistent between: backend, frontend, block style object and theme.json. -Because this package is experimental and still in development it does not yet generate a `wp.styleEngine` global. To get there, the following tasks need to be completed: +Because this package is experimental and still in development it does not yet generate a `wp.styleEngine` global. To get +there, the following tasks need to be completed: **TODO List:** @@ -26,7 +183,8 @@ Because this package is experimental and still in development it does not yet ge - Support generating styles in the backend (block supports and theme.json stylesheet). (Ongoing) - Refactor all block styles to use the style engine server side. (Ongoing) - Consolidate global and block style rendering and enqueuing -- Refactor all blocks to consistently use the "style" attribute for all customizations (get rid of the preset specific attributes). +- Refactor all blocks to consistently use the "style" attribute for all customizations (get rid of the preset specific + attributes). See [Tracking: Add a Style Engine to manage rendering block styles #38167](https://github.com/WordPress/gutenberg/issues/38167) diff --git a/packages/style-engine/class-wp-style-engine-processor.php b/packages/style-engine/class-wp-style-engine-processor.php index 84c33b9520486c..91948a360242f4 100644 --- a/packages/style-engine/class-wp-style-engine-processor.php +++ b/packages/style-engine/class-wp-style-engine-processor.php @@ -128,7 +128,8 @@ private function combine_rules_selectors() { unset( $this->css_rules[ $key ] ); } // Create a new rule with the combined selectors. - $this->css_rules[ implode( ',', $duplicates ) ] = new WP_Style_Engine_CSS_Rule( implode( ',', $duplicates ), $declarations ); + $duplicate_selectors = implode( ',', $duplicates ); + $this->css_rules[ $duplicate_selectors ] = new WP_Style_Engine_CSS_Rule( $duplicate_selectors, $declarations ); } } } diff --git a/packages/style-engine/class-wp-style-engine.php b/packages/style-engine/class-wp-style-engine.php index a63ef7f2215a3e..b991265f62294f 100644 --- a/packages/style-engine/class-wp-style-engine.php +++ b/packages/style-engine/class-wp-style-engine.php @@ -23,13 +23,6 @@ * @access private */ class WP_Style_Engine { - /** - * Container for the main instance of the class. - * - * @var WP_Style_Engine|null - */ - private static $instance = null; - /** * Style definitions that contain the instructions to * parse/output valid Gutenberg styles from a block's attributes. @@ -278,29 +271,6 @@ protected static function is_valid_style_value( $style_value ) { return true; } - /** - * Private constructor to prevent instantiation. - */ - private function __construct() { - // Register the hook callback to render stored styles to the page. - static::register_actions( array( __CLASS__, 'process_and_enqueue_stored_styles' ) ); - } - - /** - * Utility method to retrieve the main instance of the class. - * - * The instance will be created if it does not exist yet. - * - * @return WP_Style_Engine The main instance. - */ - public static function get_instance() { - if ( null === static::$instance ) { - static::$instance = new static(); - } - - return static::$instance; - } - /** * Stores a CSS rule using the provide CSS selector and CSS declarations. * @@ -328,58 +298,6 @@ public static function get_store( $store_key ) { return WP_Style_Engine_CSS_Rules_Store::get_store( $store_key ); } - /** - * Taken from gutenberg_enqueue_block_support_styles() - * - * This function takes care of registering hooks to add inline styles - * in the proper place, depending on the theme in use. - * - * For block themes, it's loaded in the head. - * For classic ones, it's loaded in the body - * because the wp_head action happens before - * the render_block. - * - * @param callable $callable A user-defined callback function for a WordPress hook. - * @param int $priority To set the priority for the add_action. - * - * @see gutenberg_enqueue_block_support_styles() - */ - protected static function register_actions( $callable, $priority = 10 ) { - if ( ! $callable ) { - return; - } - add_action( 'wp_enqueue_scripts', $callable ); - add_action( - wp_is_block_theme() ? 'wp_head' : 'wp_footer', - $callable, - $priority - ); - } - - /** - * Fetches, processes and compiles stored styles, then renders them to the page. - */ - public static function process_and_enqueue_stored_styles() { - $stores = WP_Style_Engine_CSS_Rules_Store::get_stores(); - - foreach ( $stores as $key => $store ) { - $processor = new WP_Style_Engine_Processor(); - $processor->add_store( $store ); - $styles = $processor->get_css( - array( - 'optimize' => false, - 'prettify' => defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG, - ) - ); - - if ( ! empty( $styles ) ) { - wp_register_style( $key, false, array(), true, true ); - wp_add_inline_style( $key, $styles ); - wp_enqueue_style( $key ); - } - } - } - /** * Returns classnames and CSS based on the values in a styles object. * Return values are parsed based on the instructions in BLOCK_STYLE_DEFINITIONS_METADATA. @@ -580,6 +498,7 @@ public static function compile_css( $css_declarations, $css_selector ) { return $css_rule->get_css(); } $css_declarations = new WP_Style_Engine_CSS_Declarations( $css_declarations ); + return $css_declarations->get_declarations_string(); } @@ -593,7 +512,7 @@ public static function compile_css( $css_declarations, $css_selector ) { public static function compile_stylesheet_from_css_rules( $css_rules ) { $processor = new WP_Style_Engine_Processor(); $processor->add_rules( $css_rules ); - return $processor->get_css(); + return $processor->get_css( array( 'prettify' => defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ); } } @@ -610,37 +529,37 @@ public static function compile_stylesheet_from_css_rules( $css_rules ) { * * @access public * - * @param array $block_styles The style object. - * @param array $options array( + * @param array $block_styles The style object. + * @param array $options array( * 'context' => (string) An identifier describing the origin of the style object, e.g., 'block-supports' or 'global-styles'. Default is 'block-supports'. * 'enqueue' => (boolean) When `true` will attempt to store and enqueue for rendering on the frontend. * 'convert_vars_to_classnames' => (boolean) Whether to skip converting CSS var:? values to var( --wp--preset--* ) values. Default is `false`. * 'selector' => (string) When a selector is passed, `generate()` will return a full CSS rule `$selector { ...rules }`, otherwise a concatenated string of properties and values. * );. * - * @return array|null array( - * 'css' => (string) A CSS ruleset or declarations block formatted to be placed in an HTML `style` attribute or tag. - * 'declarations' => (array) An array of property/value pairs representing parsed CSS declarations. - * 'classnames' => (string) Classnames separated by a space. + * @return array|null array( + * 'css' => (string) A CSS ruleset or declarations block formatted to be placed in an HTML `style` attribute or tag. + * 'declarations' => (array) An array of property/value pairs representing parsed CSS declarations. + * 'classnames' => (string) Classnames separated by a space. * ); */ function wp_style_engine_get_styles( $block_styles, $options = array() ) { if ( ! class_exists( 'WP_Style_Engine' ) ) { return array(); } - $defaults = array( + $defaults = array( 'selector' => null, 'context' => 'block-supports', 'convert_vars_to_classnames' => false, 'enqueue' => false, ); + $options = wp_parse_args( $options, $defaults ); - $style_engine = WP_Style_Engine::get_instance(); $parsed_styles = null; // Block supports styles. if ( 'block-supports' === $options['context'] ) { - $parsed_styles = $style_engine::parse_block_styles( $block_styles, $options ); + $parsed_styles = WP_Style_Engine::parse_block_styles( $block_styles, $options ); } // Output. @@ -651,10 +570,10 @@ function wp_style_engine_get_styles( $block_styles, $options = array() ) { } if ( ! empty( $parsed_styles['declarations'] ) ) { - $styles_output['css'] = $style_engine::compile_css( $parsed_styles['declarations'], $options['selector'] ); + $styles_output['css'] = WP_Style_Engine::compile_css( $parsed_styles['declarations'], $options['selector'] ); $styles_output['declarations'] = $parsed_styles['declarations']; if ( true === $options['enqueue'] ) { - $style_engine::store_css_rule( $options['context'], $options['selector'], $parsed_styles['declarations'] ); + WP_Style_Engine::store_css_rule( $options['context'], $options['selector'], $parsed_styles['declarations'] ); } } @@ -673,13 +592,13 @@ function wp_style_engine_get_styles( $block_styles, $options = array() ) { * * @param array $css_rules array( * array( - * 'selector' => (string) A CSS selector. + * 'selector' => (string) A CSS selector. * declarations' => (boolean) An array of CSS definitions, e.g., array( "$property" => "$value" ). * ) * );. * @param array $options array( - * 'context' => (string) An identifier describing the origin of the style object, e.g., 'block-supports' or 'global-styles'. Default is 'block-supports'. - * 'enqueue' => (boolean) When `true` will attempt to store and enqueue for rendering on the frontend. + * 'context' => (string) An identifier describing the origin of the style object, e.g., 'block-supports' or 'global-styles'. Default is 'block-supports'. + * 'enqueue' => (boolean) When `true` will attempt to store and enqueue for rendering on the frontend. * );. * * @return string A compiled CSS string. @@ -694,7 +613,6 @@ function wp_style_engine_get_stylesheet_from_css_rules( $css_rules, $options = a 'enqueue' => false, ); $options = wp_parse_args( $options, $defaults ); - $style_engine = WP_Style_Engine::get_instance(); $css_rule_objects = array(); foreach ( $css_rules as $css_rule ) { @@ -703,7 +621,7 @@ function wp_style_engine_get_stylesheet_from_css_rules( $css_rules, $options = a } if ( true === $options['enqueue'] ) { - $style_engine::store_css_rule( $options['context'], $css_rule['selector'], $css_rule['declarations'] ); + WP_Style_Engine::store_css_rule( $options['context'], $css_rule['selector'], $css_rule['declarations'] ); } $css_rule_objects[] = new WP_Style_Engine_CSS_Rule( $css_rule['selector'], $css_rule['declarations'] ); @@ -713,5 +631,24 @@ function wp_style_engine_get_stylesheet_from_css_rules( $css_rules, $options = a return ''; } - return $style_engine::compile_stylesheet_from_css_rules( $css_rule_objects ); + return WP_Style_Engine::compile_stylesheet_from_css_rules( $css_rule_objects ); +} + +/** + * Returns compiled CSS from a store, if found. + * + * @access public + * + * @param string $store_key A valid store key. + * + * @return string A compiled CSS string. + */ +function wp_style_engine_get_stylesheet_from_store( $store_key ) { + if ( ! class_exists( 'WP_Style_Engine' ) || empty( $store_key ) ) { + return ''; + } + + $store = WP_Style_Engine::get_store( $store_key ); + + return WP_Style_Engine::compile_stylesheet_from_css_rules( $store->get_all_rules() ); } diff --git a/packages/style-engine/phpunit/class-wp-style-engine-test.php b/packages/style-engine/phpunit/class-wp-style-engine-test.php index db9e231f808c66..62c9d0a9189165 100644 --- a/packages/style-engine/phpunit/class-wp-style-engine-test.php +++ b/packages/style-engine/phpunit/class-wp-style-engine-test.php @@ -531,7 +531,7 @@ public function test_enqueue_block_styles_store() { 'selector' => 'article', ) ); - $store = WP_Style_Engine::get_instance()::get_store( 'block-supports' ); + $store = WP_Style_Engine::get_store( 'block-supports' ); $rule = $store->get_all_rules()['article']; $this->assertSame( $generated_styles['css'], $rule->get_css() ); } @@ -569,10 +569,9 @@ public function test_add_to_store() { ); // Check that the style engine knows about the store. - $style_engine = WP_Style_Engine::get_instance(); - $stored_store = $style_engine::get_store( 'test-store' ); + $stored_store = WP_Style_Engine::get_store( 'test-store' ); $this->assertInstanceOf( 'WP_Style_Engine_CSS_Rules_Store', $stored_store ); - $this->assertSame( $compiled_stylesheet, $style_engine::compile_stylesheet_from_css_rules( $stored_store->get_all_rules() ) ); + $this->assertSame( $compiled_stylesheet, WP_Style_Engine::compile_stylesheet_from_css_rules( $stored_store->get_all_rules() ) ); } /** diff --git a/phpunit/script-loader.php b/phpunit/script-loader.php new file mode 100644 index 00000000000000..b8dfa970b1762e --- /dev/null +++ b/phpunit/script-loader.php @@ -0,0 +1,71 @@ + '.saruman', + 'declarations' => array( + 'color' => 'white', + 'height' => '100px', + 'border-style' => 'solid', + ), + ), + ); + + // Enqueue a block supports (core styles). + gutenberg_style_engine_get_stylesheet_from_css_rules( + $core_styles_to_enqueue, + array( + 'context' => 'block-supports', + 'enqueue' => true, + ) + ); + + $my_styles_to_enqueue = array( + array( + 'selector' => '.gandalf', + 'declarations' => array( + 'color' => 'grey', + 'height' => '90px', + 'border-style' => 'dotted', + ), + ), + ); + + // Enqueue some other styles. + gutenberg_style_engine_get_stylesheet_from_css_rules( + $my_styles_to_enqueue, + array( + 'context' => 'my-styles', + 'enqueue' => true, + ) + ); + + gutenberg_enqueue_stored_styles(); + + $this->assertEquals( array( '.saruman{color:white;height:100px;border-style:solid;}' ), $wp_styles->get_data( 'core-block-supports', 'after' ) ); + $this->assertEquals( array( '.gandalf{color:grey;height:90px;border-style:dotted;}' ), $wp_styles->get_data( 'wp-style-engine-my-styles', 'after' ) ); + } +}