From d4927f00addde925896c934d15cea23d9af58247 Mon Sep 17 00:00:00 2001 From: Ramon Date: Thu, 7 Apr 2022 09:40:21 +1000 Subject: [PATCH] Style engine: move backend scripts to package (#39736) * Initial commit: - moving Style Engine class and tests to packages - updating build script to copy package PHP into the build folder - rename methods and classes * Removing style engine from Gutenberg's phpunit suite since it's based in the package now. --- lib/load.php | 8 ++-- .../style-engine/class-wp-style-engine.php | 21 ++++++--- .../phpunit/class-wp-style-engine-test.php | 6 ++- phpunit.xml.dist | 3 ++ tools/webpack/packages.js | 44 +++++++++++++++++++ 5 files changed, 71 insertions(+), 11 deletions(-) rename lib/experimental/style-engine/class-wp-style-engine-gutenberg.php => packages/style-engine/class-wp-style-engine.php (93%) rename phpunit/style-engine/class-wp-style-engine-gutenberg-test.php => packages/style-engine/phpunit/class-wp-style-engine-test.php (95%) diff --git a/lib/load.php b/lib/load.php index 36397318b9d9d..a7a8988dc027b 100644 --- a/lib/load.php +++ b/lib/load.php @@ -127,10 +127,10 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/compat/wordpress-5.9/kses.php'; require __DIR__ . '/pwa.php'; -// TODO: Move this to be loaded from the style engine package, via the build directory. -// Part of the build process should be to copy the PHP file to the correct location, -// similar to the loading behaviour in `blocks.php`. -require __DIR__ . '/experimental/style-engine/class-wp-style-engine-gutenberg.php'; +// Copied package PHP files. +if ( file_exists( __DIR__ . '/../build/style-engine/class-wp-style-engine-gutenberg.php' ) ) { + require_once __DIR__ . '/../build/style-engine/class-wp-style-engine-gutenberg.php'; +} require __DIR__ . '/block-supports/utils.php'; require __DIR__ . '/block-supports/elements.php'; diff --git a/lib/experimental/style-engine/class-wp-style-engine-gutenberg.php b/packages/style-engine/class-wp-style-engine.php similarity index 93% rename from lib/experimental/style-engine/class-wp-style-engine-gutenberg.php rename to packages/style-engine/class-wp-style-engine.php index 7abb3315c79be..c07075184c41b 100644 --- a/lib/experimental/style-engine/class-wp-style-engine-gutenberg.php +++ b/packages/style-engine/class-wp-style-engine.php @@ -1,13 +1,13 @@ generate( $block_styles, $options diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 75b7e4bfeb52e..220581708552d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -10,6 +10,9 @@ ./phpunit/ + + ./packages/**/phpunit/ + diff --git a/tools/webpack/packages.js b/tools/webpack/packages.js index 4d02b4b6e2f81..dc161ab4dd75f 100644 --- a/tools/webpack/packages.js +++ b/tools/webpack/packages.js @@ -20,12 +20,55 @@ const { dependencies } = require( '../../package' ); const { baseConfig, plugins, stylesTransform } = require( './shared' ); const WORDPRESS_NAMESPACE = '@wordpress/'; + +// Experimental or other packages that should be private are bundled when used. +// That way, we can iterate on these package without making them part of the public API. +// See: https://github.com/WordPress/gutenberg/pull/19809 const BUNDLED_PACKAGES = [ '@wordpress/icons', '@wordpress/interface', '@wordpress/style-engine', ]; +// PHP files in packages that have to be copied during build. +const bundledPackagesPhpConfig = [ + { + from: './packages/style-engine/', + to: 'build/style-engine/', + replaceClasses: [ 'WP_Style_Engine' ], + }, +].map( ( { from, to, replaceClasses } ) => ( { + from: `${ from }/*.php`, + to( { absoluteFilename } ) { + const [ , filename ] = absoluteFilename.match( + /([\w-]+)(\.php){1,1}$/ + ); + return join( to, `${ filename }-gutenberg.php` ); + }, + transform: ( content ) => { + const classSuffix = '_Gutenberg'; + const functionPrefix = 'gutenberg_'; + content = content.toString(); + // Replace class names. + content = content.replace( + new RegExp( replaceClasses.join( '|' ), 'g' ), + ( match ) => `${ match }${ classSuffix }` + ); + // Replace function names. + content = Array.from( + content.matchAll( /^\s*function ([^\(]+)/gm ) + ).reduce( ( result, [ , functionName ] ) => { + // Prepend the Gutenberg prefix, substituting any + // other core prefix (e.g. "wp_"). + return result.replace( + new RegExp( functionName, 'g' ), + ( match ) => functionPrefix + match.replace( /^wp_/, '' ) + ); + }, content ); + return content; + }, +} ) ); + const gutenbergPackages = Object.keys( dependencies ) .filter( ( packageName ) => @@ -107,6 +150,7 @@ module.exports = { transform: stylesTransform, noErrorOnMissing: true, } ) ) + .concat( bundledPackagesPhpConfig ) .concat( vendorsCopyConfig ), } ), ].filter( Boolean ),