diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 89c4cd3dd515bd..f8c8a77ff5214a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -132,12 +132,12 @@ # PHP /lib @timothybjacobs @spacedmonkey -/lib/global-styles.php @timothybjacobs @spacedmonkey @oandregal -/lib/class-wp-rest-block-editor-settings-controller.php @timothybjacobs @spacedmonkey @geriux +/lib/compat/wordpress-5.9/kses.php @timothybjacobs @spacedmonkey @oandregal /lib/compat/wordpress-5.9/theme.json @timothybjacobs @spacedmonkey @oandregal /lib/compat/wordpress-6.0/theme-i18n.json @timothybjacobs @spacedmonkey @oandregal /lib/compat/wordpress-5.9/class-wp-theme-json-gutenberg.php @timothybjacobs @spacedmonkey @oandregal /lib/compat/wordpress-5.9/class-wp-theme-json-resolver-gutenberg.php @timothybjacobs @spacedmonkey @oandregal +/lib/experimental/class-wp-rest-block-editor-settings-controller.php @timothybjacobs @spacedmonkey @geriux /phpunit/class-wp-theme-json-test.php @oandregal # Web App diff --git a/lib/client-assets.php b/lib/client-assets.php index d83ef13b65a4e0..a30cae47dc3dd6 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -182,36 +182,6 @@ function gutenberg_override_style( $styles, $handle, $src, $deps = array(), $ver $styles->add( $handle, $src, $deps, $ver, $media ); } -/** - * Registers vendor JavaScript files to be used as dependencies of the editor - * and plugins. - * - * This function is called from a script during the plugin build process, so it - * should not call any WordPress PHP functions. - * - * @since 0.1.0 - * - * @param WP_Scripts $scripts WP_Scripts instance. - */ -function gutenberg_register_vendor_scripts( $scripts ) { - $extension = SCRIPT_DEBUG ? '.js' : '.min.js'; - - gutenberg_override_script( - $scripts, - 'react', - gutenberg_url( 'build/vendors/react' . $extension ), - // See https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/TROUBLESHOOTING.md#externalising-react. - SCRIPT_DEBUG ? array( 'wp-react-refresh-entry', 'wp-polyfill' ) : array( 'wp-polyfill' ) - ); - gutenberg_override_script( - $scripts, - 'react-dom', - gutenberg_url( 'build/vendors/react-dom' . $extension ), - array( 'react' ) - ); -} -add_action( 'wp_default_scripts', 'gutenberg_register_vendor_scripts' ); - /** * Registers all the WordPress packages scripts that are in the standardized * `build/` location. diff --git a/lib/compat.php b/lib/compat/wordpress-5.9/block-gallery.php similarity index 71% rename from lib/compat.php rename to lib/compat/wordpress-5.9/block-gallery.php index c164eed2b32cab..3c46c03d520c41 100644 --- a/lib/compat.php +++ b/lib/compat/wordpress-5.9/block-gallery.php @@ -1,33 +1,10 @@ = 5.9. - * - * @param string[] $attrs Array of allowed CSS attributes. - * @return string[] CSS attributes. - */ -function gutenberg_safe_style_attrs( $attrs ) { - $attrs[] = 'object-position'; - $attrs[] = 'border-top-left-radius'; - $attrs[] = 'border-top-right-radius'; - $attrs[] = 'border-bottom-right-radius'; - $attrs[] = 'border-bottom-left-radius'; - $attrs[] = 'filter'; - - return $attrs; -} -add_filter( 'safe_style_css', 'gutenberg_safe_style_attrs' ); - /** * The new gallery block format is not compatible with the use_BalanceTags option * in WP versions <= 5.8 https://core.trac.wordpress.org/ticket/54130. diff --git a/lib/compat/wordpress-5.9/blocks.php b/lib/compat/wordpress-5.9/blocks.php index 22012e77914baa..4d0bea00a2b0a6 100644 --- a/lib/compat/wordpress-5.9/blocks.php +++ b/lib/compat/wordpress-5.9/blocks.php @@ -42,3 +42,23 @@ function get_query_pagination_arrow( $block, $is_next ) { return null; } } + +/** + * Update allowed inline style attributes list. + * + * Note: This should be removed when the minimum required WP version is >= 5.9. + * + * @param string[] $attrs Array of allowed CSS attributes. + * @return string[] CSS attributes. + */ +function gutenberg_safe_style_attrs( $attrs ) { + $attrs[] = 'object-position'; + $attrs[] = 'border-top-left-radius'; + $attrs[] = 'border-top-right-radius'; + $attrs[] = 'border-bottom-right-radius'; + $attrs[] = 'border-bottom-left-radius'; + $attrs[] = 'filter'; + + return $attrs; +} +add_filter( 'safe_style_css', 'gutenberg_safe_style_attrs' ); diff --git a/lib/full-site-editing/edit-site-page.php b/lib/compat/wordpress-5.9/edit-site-page.php similarity index 100% rename from lib/full-site-editing/edit-site-page.php rename to lib/compat/wordpress-5.9/edit-site-page.php diff --git a/lib/global-styles.php b/lib/compat/wordpress-5.9/kses.php similarity index 98% rename from lib/global-styles.php rename to lib/compat/wordpress-5.9/kses.php index 7e1b9b4a231bdb..648718d6facd21 100644 --- a/lib/global-styles.php +++ b/lib/compat/wordpress-5.9/kses.php @@ -1,6 +1,6 @@ register_routes(); +} +add_action( 'rest_api_init', 'gutenberg_register_url_details_routes' ); + +/** + * Registers the menu locations REST API routes. + */ +function gutenberg_register_rest_menu_location() { + $nav_menu_location = new WP_REST_Menu_Locations_Controller(); + $nav_menu_location->register_routes(); +} +add_action( 'rest_api_init', 'gutenberg_register_rest_menu_location' ); + +/** + * Hook in to the nav menu item post type and enable a post type rest endpoint. + * + * @param array $args Current registered post type args. + * @param string $post_type Name of post type. + * + * @return array + */ +function wp_api_nav_menus_post_type_args( $args, $post_type ) { + if ( 'nav_menu_item' === $post_type ) { + $args['show_in_rest'] = true; + $args['rest_base'] = 'menu-items'; + $args['rest_controller_class'] = 'WP_REST_Menu_Items_Controller'; + } + + return $args; +} +add_filter( 'register_post_type_args', 'wp_api_nav_menus_post_type_args', 10, 2 ); + +/** + * Hook in to the nav_menu taxonomy and enable a taxonomy rest endpoint. + * + * @param array $args Current registered taxonomy args. + * @param string $taxonomy Name of taxonomy. + * + * @return array + */ +function wp_api_nav_menus_taxonomy_args( $args, $taxonomy ) { + if ( 'nav_menu' === $taxonomy ) { + $args['show_in_rest'] = true; + $args['rest_base'] = 'menus'; + $args['rest_controller_class'] = 'WP_REST_Menus_Controller'; + } + + return $args; +} +add_filter( 'register_taxonomy_args', 'wp_api_nav_menus_taxonomy_args', 10, 2 ); + +/** + * Exposes the site logo to the Gutenberg editor through the WordPress REST + * API. This is used for fetching this information when user has no rights + * to update settings. + * + * @param WP_REST_Response $response Response data served by the WordPress REST index endpoint. + * @return WP_REST_Response + */ +function gutenberg_register_site_logo_to_rest_index( $response ) { + $site_logo_id = get_theme_mod( 'custom_logo' ); + $response->data['site_logo'] = $site_logo_id; + if ( $site_logo_id ) { + $response->add_link( + 'https://api.w.org/featuredmedia', + rest_url( 'wp/v2/media/' . $site_logo_id ), + array( + 'embeddable' => true, + ) + ); + } + return $response; +} + +add_filter( 'rest_index', 'gutenberg_register_site_logo_to_rest_index' ); + +/** + * Filters WP_User_Query arguments when querying users via the REST API. + * + * Allow using the has_published_post argument. + * + * @param array $prepared_args Array of arguments for WP_User_Query. + * @param WP_REST_Request $request The REST API request. + * + * @return array Returns modified $prepared_args. + */ +function gutenberg_rest_user_query_has_published_posts( $prepared_args, $request ) { + if ( ! empty( $request['has_published_posts'] ) ) { + $prepared_args['has_published_posts'] = ( true === $request['has_published_posts'] ) + ? get_post_types( array( 'show_in_rest' => true ), 'names' ) + : (array) $request['has_published_posts']; + } + return $prepared_args; +} +add_filter( 'rest_user_query', 'gutenberg_rest_user_query_has_published_posts', 10, 2 ); + +/** + * Filters REST API collection parameters for the users controller. + * + * @param array $query_params JSON Schema-formatted collection parameters. + * + * @return array Returns the $query_params with "has_published_posts". + */ +function gutenberg_rest_user_collection_params_has_published_posts( $query_params ) { + $query_params['has_published_posts'] = array( + 'description' => __( 'Limit result set to users who have published posts.', 'gutenberg' ), + 'type' => array( 'boolean', 'array' ), + 'items' => array( + 'type' => 'string', + 'enum' => get_post_types( array( 'show_in_rest' => true ), 'names' ), + ), + ); + return $query_params; +} +add_filter( 'rest_user_collection_params', 'gutenberg_rest_user_collection_params_has_published_posts' ); diff --git a/lib/compat/wordpress-6.0/client-assets.php b/lib/compat/wordpress-6.0/client-assets.php new file mode 100644 index 00000000000000..1d2f76ee342733 --- /dev/null +++ b/lib/compat/wordpress-6.0/client-assets.php @@ -0,0 +1,36 @@ +register_routes(); -} -add_action( 'rest_api_init', 'gutenberg_register_url_details_routes' ); - -/** - * Registers the menu locations REST API routes. - */ -function gutenberg_register_rest_menu_location() { - $nav_menu_location = new WP_REST_Menu_Locations_Controller(); - $nav_menu_location->register_routes(); -} -add_action( 'rest_api_init', 'gutenberg_register_rest_menu_location' ); - /** * Registers the navigation areas REST API routes. */ @@ -58,44 +37,6 @@ function gutenberg_register_block_editor_settings() { } add_action( 'rest_api_init', 'gutenberg_register_block_editor_settings' ); -/** - * Hook in to the nav menu item post type and enable a post type rest endpoint. - * - * @param array $args Current registered post type args. - * @param string $post_type Name of post type. - * - * @return array - */ -function wp_api_nav_menus_post_type_args( $args, $post_type ) { - if ( 'nav_menu_item' === $post_type ) { - $args['show_in_rest'] = true; - $args['rest_base'] = 'menu-items'; - $args['rest_controller_class'] = 'WP_REST_Menu_Items_Controller'; - } - - return $args; -} -add_filter( 'register_post_type_args', 'wp_api_nav_menus_post_type_args', 10, 2 ); - -/** - * Hook in to the nav_menu taxonomy and enable a taxonomy rest endpoint. - * - * @param array $args Current registered taxonomy args. - * @param string $taxonomy Name of taxonomy. - * - * @return array - */ -function wp_api_nav_menus_taxonomy_args( $args, $taxonomy ) { - if ( 'nav_menu' === $taxonomy ) { - $args['show_in_rest'] = true; - $args['rest_base'] = 'menus'; - $args['rest_controller_class'] = 'WP_REST_Menus_Controller'; - } - - return $args; -} -add_filter( 'register_taxonomy_args', 'wp_api_nav_menus_taxonomy_args', 10, 2 ); - /** * Shim for get_sample_permalink() to add support for auto-draft status. * @@ -168,44 +109,3 @@ function gutenberg_auto_draft_get_sample_permalink( $permalink, $id, $title, $na return $permalink; } add_filter( 'get_sample_permalink', 'gutenberg_auto_draft_get_sample_permalink', 10, 5 ); - -/** - * Filters WP_User_Query arguments when querying users via the REST API. - * - * Allow using the has_published_post argument. - * - * @param array $prepared_args Array of arguments for WP_User_Query. - * @param WP_REST_Request $request The REST API request. - * - * @return array Returns modified $prepared_args. - */ -function gutenberg_rest_user_query_has_published_posts( $prepared_args, $request ) { - if ( ! empty( $request['has_published_posts'] ) ) { - $prepared_args['has_published_posts'] = ( true === $request['has_published_posts'] ) - ? get_post_types( array( 'show_in_rest' => true ), 'names' ) - : (array) $request['has_published_posts']; - } - return $prepared_args; -} -add_filter( 'rest_user_query', 'gutenberg_rest_user_query_has_published_posts', 10, 2 ); - - -/** - * Filters REST API collection parameters for the users controller. - * - * @param array $query_params JSON Schema-formatted collection parameters. - * - * @return array Returns the $query_params with "has_published_posts". - */ -function gutenberg_rest_user_collection_params_has_published_posts( $query_params ) { - $query_params['has_published_posts'] = array( - 'description' => __( 'Limit result set to users who have published posts.', 'gutenberg' ), - 'type' => array( 'boolean', 'array' ), - 'items' => array( - 'type' => 'string', - 'enum' => get_post_types( array( 'show_in_rest' => true ), 'names' ), - ), - ); - return $query_params; -} -add_filter( 'rest_user_collection_params', 'gutenberg_rest_user_collection_params_has_published_posts' ); diff --git a/lib/style-engine/class-wp-style-engine-gutenberg.php b/lib/experimental/style-engine/class-wp-style-engine-gutenberg.php similarity index 100% rename from lib/style-engine/class-wp-style-engine-gutenberg.php rename to lib/experimental/style-engine/class-wp-style-engine-gutenberg.php diff --git a/lib/init.php b/lib/init.php index c84bb91155cc2e..92f52e8292dfc8 100644 --- a/lib/init.php +++ b/lib/init.php @@ -101,50 +101,3 @@ function gutenberg_rest_nonce() { exit( wp_create_nonce( 'wp_rest' ) ); } add_action( 'wp_ajax_gutenberg_rest_nonce', 'gutenberg_rest_nonce' ); - - -/** - * Exposes the site icon url to the Gutenberg editor through the WordPress REST - * API. The site icon url should instead be fetched from the wp/v2/settings - * endpoint when https://github.com/WordPress/gutenberg/pull/19967 is complete. - * - * @since 8.2.1 - * - * @param WP_REST_Response $response Response data served by the WordPress REST index endpoint. - * @return WP_REST_Response - */ -function register_site_icon_url( $response ) { - $data = $response->data; - $data['site_icon_url'] = get_site_icon_url(); - $response->set_data( $data ); - return $response; -} - -add_filter( 'rest_index', 'register_site_icon_url' ); - -/** - * Exposes the site logo to the Gutenberg editor through the WordPress REST - * API. This is used for fetching this information when user has no rights - * to update settings. - * - * @since 10.9 - * - * @param WP_REST_Response $response Response data served by the WordPress REST index endpoint. - * @return WP_REST_Response - */ -function register_site_logo_to_rest_index( $response ) { - $site_logo_id = get_theme_mod( 'custom_logo' ); - $response->data['site_logo'] = $site_logo_id; - if ( $site_logo_id ) { - $response->add_link( - 'https://api.w.org/featuredmedia', - rest_url( 'wp/v2/media/' . $site_logo_id ), - array( - 'embeddable' => true, - ) - ); - } - return $response; -} - -add_filter( 'rest_index', 'register_site_logo_to_rest_index' ); diff --git a/lib/load.php b/lib/load.php index 2b059a7f9dc5da..56d633964a96fc 100644 --- a/lib/load.php +++ b/lib/load.php @@ -55,10 +55,11 @@ function gutenberg_is_experiment_enabled( $name ) { require_once __DIR__ . '/compat/wordpress-5.9/class-wp-rest-url-details-controller.php'; } - require __DIR__ . '/rest-api.php'; + require __DIR__ . '/experimental/rest-api.php'; + require __DIR__ . '/compat/wordpress-5.9/rest-api.php'; } -require __DIR__ . '/compat.php'; +require __DIR__ . '/compat/wordpress-5.9/block-gallery.php'; require __DIR__ . '/compat/wordpress-5.9/widget-render-api-endpoint/index.php'; require __DIR__ . '/compat/wordpress-5.9/blocks.php'; require __DIR__ . '/compat/wordpress-5.9/block-editor-settings.php'; @@ -78,13 +79,13 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/compat/wordpress-5.9/templates.php'; require __DIR__ . '/compat/wordpress-5.9/template-parts.php'; require __DIR__ . '/compat/wordpress-5.9/theme-templates.php'; -require __DIR__ . '/editor-settings.php'; +require __DIR__ . '/experimental/editor-settings.php'; require __DIR__ . '/compat/wordpress-5.9/class-wp-theme-json-schema-gutenberg.php'; require __DIR__ . '/compat/wordpress-5.9/class-wp-theme-json-5-9.php'; require __DIR__ . '/compat/wordpress-5.9/class-wp-theme-json-resolver-5-9.php'; require __DIR__ . '/compat/wordpress-5.9/theme.php'; require __DIR__ . '/compat/wordpress-5.9/admin-menu.php'; -require __DIR__ . '/full-site-editing/edit-site-page.php'; +require __DIR__ . '/compat/wordpress-5.9/edit-site-page.php'; require __DIR__ . '/compat/wordpress-5.9/block-template.php'; require __DIR__ . '/compat/wordpress-5.9/wp-theme-get-post-templates.php'; require __DIR__ . '/compat/wordpress-5.9/default-theme-supports.php'; @@ -99,7 +100,7 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/compat/wordpress-6.0/class-gutenberg-rest-edit-site-export-controller.php'; require __DIR__ . '/compat/wordpress-6.0/class-wp-rest-block-patterns-controller.php'; require __DIR__ . '/compat/wordpress-6.0/class-wp-rest-block-pattern-categories-controller.php'; -require __DIR__ . '/compat/wordpress-6.0/utils.php'; +require __DIR__ . '/compat/wordpress-6.0/functions.php'; require __DIR__ . '/compat/wordpress-6.0/class-wp-theme-json-gutenberg.php'; require __DIR__ . '/compat/wordpress-6.0/rest-api.php'; require __DIR__ . '/compat/wordpress-6.0/block-patterns.php'; @@ -116,18 +117,19 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/blocks.php'; require __DIR__ . '/compat/wordpress-6.0/block-patterns-update.php'; require __DIR__ . '/client-assets.php'; +require __DIR__ . '/compat/wordpress-6.0/client-assets.php'; require __DIR__ . '/demo.php'; -require __DIR__ . '/navigation.php'; -require __DIR__ . '/navigation-theme-opt-in.php'; -require __DIR__ . '/navigation-page.php'; -require __DIR__ . '/experiments-page.php'; -require __DIR__ . '/global-styles.php'; +require __DIR__ . '/compat/wordpress-5.9/navigation.php'; +require __DIR__ . '/experimental/navigation-theme-opt-in.php'; +require __DIR__ . '/experimental/navigation-page.php'; +require __DIR__ . '/experimental/experiments-page.php'; +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__ . '/style-engine/class-wp-style-engine-gutenberg.php'; +require __DIR__ . '/experimental/style-engine/class-wp-style-engine-gutenberg.php'; require __DIR__ . '/block-supports/utils.php'; require __DIR__ . '/block-supports/elements.php';