From 5c1914ed7ccd50ef8de916589002174c6a574910 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 31 Jan 2019 15:52:26 -0500 Subject: [PATCH 1/3] Plugin: Extract block editor styles replacement as filter --- lib/client-assets.php | 44 +++++++++++++- phpunit/class-extend-styles-test.php | 88 ++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 phpunit/class-extend-styles-test.php diff --git a/lib/client-assets.php b/lib/client-assets.php index 96986825e9bc27..e98220ddd864a1 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -840,6 +840,48 @@ function gutenberg_get_available_image_sizes() { return $all_sizes; } +/** + * Extends block editor settings to include Gutenberg's `editor-styles.css` as + * taking precedent those styles shipped with core. + * + * @param array $settings Default editor settings. + * + * @return array Filtered editor settings. + */ +function gutenberg_extend_block_editor_styles( $settings ) { + if ( empty( $settings['styles'] ) ) { + $settings['styles'] = array(); + } else { + /* + * By handling this filter at an earlier-than-default priority and with + * an understanding that plugins should concatenate (not unshift) their + * own custom styles, it's assumed that the first entry of the styles + * setting should be the default (core) stylesheet. + */ + array_shift( $settings['styles'] ); + } + + /* + * The default styles array would include the core `editor-styles.css` and + * a separate style for the locale font family. To avoid overriding the + * localized value, ensure that Gutenberg's editor styles assume the same + * order as core styles (earlier than the font style assignment). + * + * See: https://github.com/WordPress/wordpress-develop/blob/5.0.3/src/wp-admin/edit-form-blocks.php#L168-L181 + */ + array_unshift( + $settings['styles'], + array( + 'css' => file_get_contents( + gutenberg_dir_path() . 'build/editor/editor-styles.css' + ), + ) + ); + + return $settings; +} +add_filter( 'block_editor_settings', 'gutenberg_extend_block_editor_styles', 9 ); + /** * Scripts & Styles. * @@ -1037,7 +1079,7 @@ function gutenberg_editor_scripts_and_styles( $hook ) { $styles = array( array( 'css' => file_get_contents( - gutenberg_dir_path() . 'build/editor/editor-styles.css' + ABSPATH . WPINC . '/css/dist/editor/editor-styles.css' ), ), ); diff --git a/phpunit/class-extend-styles-test.php b/phpunit/class-extend-styles-test.php new file mode 100644 index 00000000000000..2d29bcf355df3b --- /dev/null +++ b/phpunit/class-extend-styles-test.php @@ -0,0 +1,88 @@ +assertEquals( + array( array( 'css' => self::$style_contents ) ), + $settings['styles'] + ); + } + + /** + * Tests a default `styles` setting. + */ + function test_default_editor_settings_style() { + $settings = array( + 'styles' => array( + array( 'css' => 'original' ), + array( 'css' => 'someother' ), + ), + ); + + $settings = gutenberg_extend_block_editor_styles( $settings ); + + $this->assertEquals( + array( + array( 'css' => self::$style_contents ), + array( 'css' => 'someother' ), + ), + $settings['styles'] + ); + } + +} From d4be401f7deb900c2e27b5cbaa229000fbd2966e Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 14 Feb 2019 12:23:03 -0500 Subject: [PATCH 2/3] Plugin: Override default styles by exact file contents match --- lib/client-assets.php | 57 +++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/lib/client-assets.php b/lib/client-assets.php index e98220ddd864a1..183360e0605cdd 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -849,38 +849,53 @@ function gutenberg_get_available_image_sizes() { * @return array Filtered editor settings. */ function gutenberg_extend_block_editor_styles( $settings ) { + $editor_styles_file = gutenberg_dir_path() . 'build/editor/editor-styles.css'; + + /* + * If, for whatever reason, the built editor styles do not exist, avoid + * override and fall back to the default. + */ + if ( ! file_exists( $editor_styles_file ) ) { + return $settings; + } + + $i = 0; if ( empty( $settings['styles'] ) ) { $settings['styles'] = array(); } else { /* - * By handling this filter at an earlier-than-default priority and with - * an understanding that plugins should concatenate (not unshift) their - * own custom styles, it's assumed that the first entry of the styles - * setting should be the default (core) stylesheet. + * The styles setting is an array of CSS strings, so there is no direct + * way to find the default styles. To maximize stability, load (again) + * the default styles from disk and find its place in the array. + * + * See: https://github.com/WordPress/wordpress-develop/blob/5.0.3/src/wp-admin/edit-form-blocks.php#L168-L175 + */ + + $default_styles = file_get_contents( + ABSPATH . WPINC . '/css/dist/editor/editor-styles.css' + ); + + /* + * Iterate backwards from the end of the array since the preferred + * insertion point in case not found is as the first entry. */ - array_shift( $settings['styles'] ); + + $i = count( $settings['styles'] ); + while ( --$i >= 0 ) { + if ( isset( $settings['styles'][ $i ]['css'] ) && + $settings['styles'][ $i ]['css'] === $default_styles ) { + break; + } + } } - /* - * The default styles array would include the core `editor-styles.css` and - * a separate style for the locale font family. To avoid overriding the - * localized value, ensure that Gutenberg's editor styles assume the same - * order as core styles (earlier than the font style assignment). - * - * See: https://github.com/WordPress/wordpress-develop/blob/5.0.3/src/wp-admin/edit-form-blocks.php#L168-L181 - */ - array_unshift( - $settings['styles'], - array( - 'css' => file_get_contents( - gutenberg_dir_path() . 'build/editor/editor-styles.css' - ), - ) + $settings['styles'][ $i ] = array( + 'css' => file_get_contents( $editor_styles_file ), ); return $settings; } -add_filter( 'block_editor_settings', 'gutenberg_extend_block_editor_styles', 9 ); +add_filter( 'block_editor_settings', 'gutenberg_extend_block_editor_styles' ); /** * Scripts & Styles. From 2681cf83bc7e98d5e73fc592372acce17ecb320f Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 14 Feb 2019 16:33:06 -0500 Subject: [PATCH 3/3] Plugin: Fix editor styles prepend behavior --- lib/client-assets.php | 18 ++-- phpunit/class-extend-styles-test.php | 143 ++++++++++++++++++++++----- 2 files changed, 131 insertions(+), 30 deletions(-) diff --git a/lib/client-assets.php b/lib/client-assets.php index 183360e0605cdd..87ecea4f69dd25 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -859,7 +859,6 @@ function gutenberg_extend_block_editor_styles( $settings ) { return $settings; } - $i = 0; if ( empty( $settings['styles'] ) ) { $settings['styles'] = array(); } else { @@ -877,22 +876,27 @@ function gutenberg_extend_block_editor_styles( $settings ) { /* * Iterate backwards from the end of the array since the preferred - * insertion point in case not found is as the first entry. + * insertion point in case not found is prepended as first entry. */ - - $i = count( $settings['styles'] ); - while ( --$i >= 0 ) { + for ( $i = count( $settings['styles'] ) - 1; $i >= 0; $i-- ) { if ( isset( $settings['styles'][ $i ]['css'] ) && - $settings['styles'][ $i ]['css'] === $default_styles ) { + $default_styles === $settings['styles'][ $i ]['css'] ) { break; } } } - $settings['styles'][ $i ] = array( + $editor_styles = array( 'css' => file_get_contents( $editor_styles_file ), ); + // Substitute default styles if found. Otherwise, prepend to setting array. + if ( isset( $i ) && $i >= 0 ) { + $settings['styles'][ $i ] = $editor_styles; + } else { + array_unshift( $settings['styles'], $editor_styles ); + } + return $settings; } add_filter( 'block_editor_settings', 'gutenberg_extend_block_editor_styles' ); diff --git a/phpunit/class-extend-styles-test.php b/phpunit/class-extend-styles-test.php index 2d29bcf355df3b..6ae12ada227973 100644 --- a/phpunit/class-extend-styles-test.php +++ b/phpunit/class-extend-styles-test.php @@ -8,68 +8,165 @@ class Extend_Styles_Test extends WP_UnitTestCase { /** - * Path of the `editor-styles.css` stub file created, or null if one had - * already existed on the filesystem. + * Path of the original `editor-styles.css` file. * * @var string|null */ - protected static $stub_file; + protected $orignal_file = null; /** * Contents of the `editor-styles.css` file. * * @var string */ - protected static $style_contents; + protected $style_contents = null; - public static function wpSetUpBeforeClass() { - self::ensure_editor_styles(); + public function wpTearDown() { + parent::wpTearDown(); + + $this->restore_editor_styles(); } - public static function wpTearDownAfterClass() { - if ( self::$stub_file ) { - unlink( self::$stub_file ); + /** + * Restores the existence of `editor-styles.css` to its original state. + */ + protected function restore_editor_styles() { + $path = gutenberg_dir_path() . 'build/editor/editor-styles.css'; + + if ( $this->original_file ) { + if ( $this->original_file !== $path ) { + rename( $this->original_file, $path ); + } + } elseif ( file_exists( $path ) ) { + unlink( $path ); } + + $this->style_contents = null; + $this->original_file = null; } /** - * Verifies that an `editor-styles.css` file exists, creating it otherwise, - * and assigning the `style_contents` and `stub_file` class properties. + * Guarantees that an `editor-styles.css` file exists, if and only if it + * should exist. Assigns `style_contents` according to the contents of the + * file if it should exist. Renames the existing file temporarily if it + * exists but should not. + * + * @param bool $should_exist Whether the editor styles file should exist. */ - protected static function ensure_editor_styles() { + protected function ensure_editor_styles( $should_exist = true ) { $path = gutenberg_dir_path() . 'build/editor/editor-styles.css'; if ( file_exists( $path ) ) { - self::$style_contents = file_get_contents( $path ); - self::$stub_file = null; - } else { - self::$style_contents = ''; - file_put_contents( $path, self::$style_contents ); - self::$stub_file = $path; + if ( $should_exist ) { + $this->style_contents = file_get_contents( $path ); + $this->original_file = $path; + } else { + rename( $path, $path . '.bak' ); + $this->original_file = $path . '.bak'; + } + } elseif ( $should_exist ) { + $this->style_contents = ''; + file_put_contents( $path, $this->style_contents ); + $this->original_file = null; } } + /** + * Tests a non-existent build `styles`. + */ + function test_without_built_styles() { + $this->ensure_editor_styles( false ); + + $settings = array( + 'styles' => array( + array( 'css' => 'original' ), + array( 'css' => 'someother' ), + ), + ); + + $result = gutenberg_extend_block_editor_styles( $settings ); + + $this->assertEquals( $settings, $result ); + } + /** * Tests an unset `styles` setting. */ function test_unset_editor_settings_style() { + $this->ensure_editor_styles(); + $settings = array(); $settings = gutenberg_extend_block_editor_styles( $settings ); $this->assertEquals( - array( array( 'css' => self::$style_contents ) ), + array( array( 'css' => $this->style_contents ) ), $settings['styles'] ); } /** - * Tests a default `styles` setting. + * Tests replacing the default styles. */ - function test_default_editor_settings_style() { + function test_replace_default_editor_styles() { + $this->ensure_editor_styles(); + $default_styles = file_get_contents( + ABSPATH . WPINC . '/css/dist/editor/editor-styles.css' + ); + + $settings = array( + 'styles' => array( + array( 'css' => $default_styles ), + array( 'css' => 'someother' ), + ), + ); + + $settings = gutenberg_extend_block_editor_styles( $settings ); + + $this->assertEquals( + array( + array( 'css' => $this->style_contents ), + array( 'css' => 'someother' ), + ), + $settings['styles'] + ); + } + + /** + * Tests replacing the rearranged default styles. + */ + function test_replace_rearranged_default_editor_styles() { + $this->ensure_editor_styles(); + $default_styles = file_get_contents( + ABSPATH . WPINC . '/css/dist/editor/editor-styles.css' + ); + + $settings = array( + 'styles' => array( + array( 'css' => 'someother' ), + array( 'css' => $default_styles ), + ), + ); + + $settings = gutenberg_extend_block_editor_styles( $settings ); + + $this->assertEquals( + array( + array( 'css' => 'someother' ), + array( 'css' => $this->style_contents ), + ), + $settings['styles'] + ); + } + + /** + * Tests when the default styles aren't in the styles setting. + */ + function test_without_default_editor_styles() { + $this->ensure_editor_styles(); + $settings = array( 'styles' => array( - array( 'css' => 'original' ), array( 'css' => 'someother' ), ), ); @@ -78,7 +175,7 @@ function test_default_editor_settings_style() { $this->assertEquals( array( - array( 'css' => self::$style_contents ), + array( 'css' => $this->style_contents ), array( 'css' => 'someother' ), ), $settings['styles']