From 1799c03dc0d0ffb2ab7a825e2a5cfe499affbbc9 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Fri, 1 Mar 2019 16:34:35 -0500 Subject: [PATCH 1/3] Plugin: Remove replace_editor filter, extend core editor --- .../backward-compatibility/deprecations.md | 11 + gutenberg.php | 132 +---- lib/client-assets.php | 477 +----------------- lib/load.php | 1 + lib/widgets.php | 123 +++++ 5 files changed, 164 insertions(+), 580 deletions(-) create mode 100644 lib/widgets.php diff --git a/docs/designers-developers/developers/backward-compatibility/deprecations.md b/docs/designers-developers/developers/backward-compatibility/deprecations.md index 8e8f8ee2d3c372..496a8b3e5d571a 100644 --- a/docs/designers-developers/developers/backward-compatibility/deprecations.md +++ b/docs/designers-developers/developers/backward-compatibility/deprecations.md @@ -2,6 +2,17 @@ The Gutenberg project's deprecation policy is intended to support backward compatibility for releases, when possible. The current deprecations are listed below and are grouped by _the version at which they will be removed completely_. If your plugin depends on these behaviors, you must update to the recommended alternative before the noted version. +## 5.5.0 + +- The PHP function `gutenberg_init` has been removed. +- The PHP function `is_gutenberg_page` has been removed. Use [`WP_Screen::is_block_editor`](https://developer.wordpress.org/reference/classes/wp_screen/is_block_editor/) instead. +- The PHP function `the_gutenberg_project` has been removed. +- The PHP function `gutenberg_default_post_format_template` has been removed. +- The PHP function `gutenberg_get_available_image_sizes` has been removed. +- The PHP function `gutenberg_get_autosave_newer_than_post_save` has been removed. +- The PHP function `gutenberg_default_post_format_template` has been removed. +- The PHP function `gutenberg_editor_scripts_and_styles` has been removed. + ## 5.4.0 - The PHP function `gutenberg_load_plugin_textdomain` has been removed. diff --git a/gutenberg.php b/gutenberg.php index cbb0375d2a7605..5676c589b7d070 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -22,47 +22,11 @@ * The main entry point for the Gutenberg editor. Renders the editor on the * wp-admin page for the plugin. * - * The gutenberg and gutenberg__editor classNames are left for backward compatibility. - * * @since 0.1.0 + * @deprecated 5.3.0 */ function the_gutenberg_project() { - global $post_type_object; - ?> - -
-

labels->edit_item ); ?>

-
- - -
- base !== 'post' ) { - return false; - } + _deprecated_function( __FUNCTION__, '5.3.0', 'WP_Screen::is_block_editor' ); - if ( ! use_block_editor_for_post( $post ) ) { - return false; - } - - return true; + require_once ABSPATH . 'wp-admin/includes/screen.php'; + return get_current_screen()->is_block_editor(); } /** @@ -198,8 +144,6 @@ function gutenberg_pre_init() { } require_once dirname( __FILE__ ) . '/lib/load.php'; - - add_filter( 'replace_editor', 'gutenberg_init', 10, 2 ); } /** @@ -207,57 +151,13 @@ function gutenberg_pre_init() { * * Load API functions, register scripts and actions, etc. * - * @param bool $return Whether to replace the editor. Used in the `replace_editor` filter. - * @param object $post The post to edit or an auto-draft. - * @return bool Whether Gutenberg was initialized. + * @deprecated 5.3.0 + * + * @return bool Whether Gutenberg was initialized. */ -function gutenberg_init( $return, $post ) { - if ( true === $return && current_filter() === 'replace_editor' ) { - return $return; - } - - if ( ! is_gutenberg_page() ) { - return false; - } - - // Instruct WordPress that this is the block editor. Without this, a call - // to `is_block_editor()` would yield `false` while editing a post with - // Gutenberg. - // - // [TODO]: This is temporary so long as Gutenberg is implemented to use - // `replace_editor`, rather than allow `edit-form-blocks.php` from core to - // take effect, where this would otherwise be assigned. - get_current_screen()->is_block_editor( true ); - - add_action( 'admin_enqueue_scripts', 'gutenberg_editor_scripts_and_styles' ); - add_filter( 'screen_options_show_screen', '__return_false' ); - - /* - * Remove the emoji script as it is incompatible with both React and any - * contenteditable fields. - */ - remove_action( 'admin_print_scripts', 'print_emoji_detection_script' ); - - /** - * Start: Include for phase 2 - */ - // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores - do_action( 'admin_print_styles-widgets.php' ); - // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores - do_action( 'admin_print_scripts-widgets.php' ); - /** - * End: Include for phase 2 - */ - - /* - * Ensure meta box functions are available to third-party code; - * includes/meta-boxes is typically loaded from edit-form-advanced.php. - */ - require_once ABSPATH . 'wp-admin/includes/meta-boxes.php'; - register_and_do_post_meta_boxes( $post ); - - require_once ABSPATH . 'wp-admin/admin-header.php'; - the_gutenberg_project(); +function gutenberg_init() { + _deprecated_function( __FUNCTION__, '5.3.0' ); - return true; + require_once ABSPATH . 'wp-admin/includes/screen.php'; + return get_current_screen()->is_block_editor(); } diff --git a/lib/client-assets.php b/lib/client-assets.php index 801aefe8c91773..787c4c52458ef5 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -489,67 +489,29 @@ function gutenberg_register_vendor_script( $handle, $src, $deps = array() ) { * Assigns a default editor template with a default block by post format, if * not otherwise assigned for a new post of type "post". * - * @param array $settings Default editor settings. - * @param WP_Post $post Post being edited. + * @deprecated 5.3.0 + * + * @param array $settings Default editor settings. * * @return array Filtered block editor settings. */ -function gutenberg_default_post_format_template( $settings, $post ) { - // Only assign template for new posts without explicitly assigned template. - $is_new_post = 'auto-draft' === $post->post_status; - if ( $is_new_post && ! isset( $settings['template'] ) && 'post' === $post->post_type ) { - switch ( get_post_format() ) { - case 'audio': - $default_block_name = 'core/audio'; - break; - case 'gallery': - $default_block_name = 'core/gallery'; - break; - case 'image': - $default_block_name = 'core/image'; - break; - case 'quote': - $default_block_name = 'core/quote'; - break; - case 'video': - $default_block_name = 'core/video'; - break; - } - - if ( isset( $default_block_name ) ) { - $settings['template'] = array( array( $default_block_name ) ); - } - } +function gutenberg_default_post_format_template( $settings ) { + _deprecated_function( __FUNCTION__, '5.3.0' ); return $settings; } -add_filter( 'block_editor_settings', 'gutenberg_default_post_format_template', 10, 2 ); /** * Retrieve a stored autosave that is newer than the post save. * * Deletes autosaves that are older than the post save. * - * @param WP_Post $post Post object. + * @deprecated 5.3.0 + * * @return WP_Post|boolean The post autosave. False if none found. */ -function gutenberg_get_autosave_newer_than_post_save( $post ) { - // Add autosave data if it is newer and changed. - $autosave = wp_get_post_autosave( $post->ID ); - - if ( ! $autosave ) { - return false; - } - - // Check if the autosave is newer than the current post. - if ( - mysql2date( 'U', $autosave->post_modified_gmt, false ) > mysql2date( 'U', $post->post_modified_gmt, false ) - ) { - return $autosave; - } - - // If the autosave isn't newer, remove it. - wp_delete_post_revision( $autosave->ID ); +function gutenberg_get_autosave_newer_than_post_save() { + _deprecated_function( __FUNCTION__, '5.3.0' ); return false; } @@ -566,28 +528,14 @@ function gutenberg_load_locale_data() { /** * Retrieve The available image sizes for a post * + * @deprecated 5.3.0 + * * @return array */ function gutenberg_get_available_image_sizes() { - $size_names = apply_filters( - 'image_size_names_choose', - array( - 'thumbnail' => __( 'Thumbnail', 'gutenberg' ), - 'medium' => __( 'Medium', 'gutenberg' ), - 'large' => __( 'Large', 'gutenberg' ), - 'full' => __( 'Full Size', 'gutenberg' ), - ) - ); - - $all_sizes = array(); - foreach ( $size_names as $size_slug => $size_name ) { - $all_sizes[] = array( - 'slug' => $size_slug, - 'name' => $size_name, - ); - } + _deprecated_function( __FUNCTION__, '5.3.0' ); - return $all_sizes; + return array(); } /** @@ -650,402 +598,3 @@ function gutenberg_extend_block_editor_styles( $settings ) { return $settings; } add_filter( 'block_editor_settings', 'gutenberg_extend_block_editor_styles' ); - -/** - * Scripts & Styles. - * - * Enqueues the needed scripts and styles when visiting the top-level page of - * the Gutenberg editor. - * - * @since 0.1.0 - * - * @param string $hook Screen name. - */ -function gutenberg_editor_scripts_and_styles( $hook ) { - global $wp_meta_boxes; - - // Enqueue heartbeat separately as an "optional" dependency of the editor. - // Heartbeat is used for automatic nonce refreshing, but some hosts choose - // to disable it outright. - wp_enqueue_script( 'heartbeat' ); - - wp_enqueue_script( 'wp-edit-post' ); - wp_enqueue_script( 'wp-format-library' ); - wp_enqueue_style( 'wp-format-library' ); - - global $post; - - // Set initial title to empty string for auto draft for duration of edit. - // Otherwise, title defaults to and displays as "Auto Draft". - $is_new_post = 'auto-draft' === $post->post_status; - - // Set the post type name. - $post_type = get_post_type( $post ); - $post_type_object = get_post_type_object( $post_type ); - $rest_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; - - $preload_paths = array( - '/', - '/wp/v2/types?context=edit', - '/wp/v2/taxonomies?per_page=-1&context=edit', - '/wp/v2/themes?status=active', - sprintf( '/wp/v2/%s/%s?context=edit', $rest_base, $post->ID ), - sprintf( '/wp/v2/types/%s?context=edit', $post_type ), - sprintf( '/wp/v2/users/me?post_type=%s&context=edit', $post_type ), - array( '/wp/v2/media', 'OPTIONS' ), - array( '/wp/v2/blocks', 'OPTIONS' ), - ); - - /** - * Preload common data by specifying an array of REST API paths that will be preloaded. - * - * Filters the array of paths that will be preloaded. - * - * @param array $preload_paths Array of paths to preload - * @param object $post The post resource data. - */ - $preload_paths = apply_filters( 'block_editor_preload_paths', $preload_paths, $post ); - - // Ensure the global $post remains the same after - // API data is preloaded. Because API preloading - // can call the_content and other filters, callbacks - // can unexpectedly modify $post resulting in issues - // like https://github.com/WordPress/gutenberg/issues/7468. - $backup_global_post = $post; - - $preload_data = array_reduce( - $preload_paths, - 'rest_preload_api_request', - array() - ); - - // Restore the global $post as it was before API preloading. - $post = $backup_global_post; - - wp_add_inline_script( - 'wp-api-fetch', - sprintf( 'wp.apiFetch.use( wp.apiFetch.createPreloadingMiddleware( %s ) );', wp_json_encode( $preload_data ) ), - 'after' - ); - - wp_add_inline_script( - 'wp-blocks', - sprintf( 'wp.blocks.setCategories( %s );', wp_json_encode( get_block_categories( $post ) ) ), - 'after' - ); - - // Assign initial edits, if applicable. These are not initially assigned - // to the persisted post, but should be included in its save payload. - if ( $is_new_post ) { - // Override "(Auto Draft)" new post default title with empty string, - // or filtered value. - $initial_edits = array( - 'title' => $post->post_title, - 'content' => $post->post_content, - 'excerpt' => $post->post_excerpt, - ); - } else { - $initial_edits = null; - } - - // Preload server-registered block schemas. - wp_add_inline_script( - 'wp-blocks', - 'wp.blocks.unstable__bootstrapServerSideBlockDefinitions(' . json_encode( get_block_editor_server_block_settings() ) . ');' - ); - - // Get admin url for handling meta boxes. - $meta_box_url = admin_url( 'post.php' ); - $meta_box_url = add_query_arg( - array( - 'post' => $post->ID, - 'action' => 'edit', - 'meta-box-loader' => true, - '_wpnonce' => wp_create_nonce( 'meta-box-loader' ), - ), - $meta_box_url - ); - wp_localize_script( 'wp-editor', '_wpMetaBoxUrl', $meta_box_url ); - - // Initialize the editor. - $align_wide = get_theme_support( 'align-wide' ); - $color_palette = current( (array) get_theme_support( 'editor-color-palette' ) ); - $font_sizes = current( (array) get_theme_support( 'editor-font-sizes' ) ); - - /** - * Filters the allowed block types for the editor, defaulting to true (all - * block types supported). - * - * @param bool|array $allowed_block_types Array of block type slugs, or - * boolean to enable/disable all. - * @param object $post The post resource data. - */ - $allowed_block_types = apply_filters( 'allowed_block_types', true, $post ); - - // Get all available templates for the post/page attributes meta-box. - // The "Default template" array element should only be added if the array is - // not empty so we do not trigger the template select element without any options - // besides the default value. - $available_templates = wp_get_theme()->get_page_templates( get_post( $post->ID ) ); - $available_templates = ! empty( $available_templates ) ? array_merge( - array( - '' => apply_filters( 'default_page_template_title', __( 'Default template', 'gutenberg' ), 'rest-api' ), - ), - $available_templates - ) : $available_templates; - - // Media settings. - $max_upload_size = wp_max_upload_size(); - if ( ! $max_upload_size ) { - $max_upload_size = 0; - } - - // Editor Styles. - global $editor_styles; - $styles = array( - array( - 'css' => file_get_contents( - ABSPATH . WPINC . '/css/dist/editor/editor-styles.css' - ), - ), - ); - - /* Translators: Use this to specify the CSS font family for the default font */ - $locale_font_family = esc_html_x( 'Noto Serif', 'CSS Font Family for Editor Font', 'gutenberg' ); - $styles[] = array( - 'css' => "body { font-family: '$locale_font_family' }", - ); - - if ( $editor_styles && current_theme_supports( 'editor-styles' ) ) { - foreach ( $editor_styles as $style ) { - if ( filter_var( $style, FILTER_VALIDATE_URL ) ) { - $styles[] = array( - 'css' => file_get_contents( $style ), - ); - } else { - $file = get_theme_file_path( $style ); - if ( file_exists( $file ) ) { - $styles[] = array( - 'css' => file_get_contents( $file ), - 'baseURL' => get_theme_file_uri( $style ), - ); - } - } - } - } - - // Lock settings. - $user_id = wp_check_post_lock( $post->ID ); - if ( $user_id ) { - /** - * Filters whether to show the post locked dialog. - * - * Returning a falsey value to the filter will short-circuit displaying the dialog. - * - * @since 3.6.0 - * - * @param bool $display Whether to display the dialog. Default true. - * @param WP_Post $post Post object. - * @param WP_User|bool $user The user id currently editing the post. - */ - if ( apply_filters( 'show_post_locked_dialog', true, $post, $user_id ) ) { - $locked = true; - } - - $user_details = null; - if ( $locked ) { - $user = get_userdata( $user_id ); - $user_details = array( - 'name' => $user->display_name, - ); - $avatar = get_avatar( $user_id, 64 ); - if ( $avatar ) { - if ( preg_match( "|src='([^']+)'|", $avatar, $matches ) ) { - $user_details['avatar'] = $matches[1]; - } - } - } - - $lock_details = array( - 'isLocked' => $locked, - 'user' => $user_details, - ); - } else { - - // Lock the post. - $active_post_lock = wp_set_post_lock( $post->ID ); - $lock_details = array( - 'isLocked' => false, - 'activePostLock' => esc_attr( implode( ':', $active_post_lock ) ), - ); - } - - /** - * Start: Include for phase 2 - */ - - /** - * Todo: The hardcoded array should be replaced with a mechanisms that allows core blocks - * and third party blocks to specify they already have equivalent blocks, and maybe even allow them - * to have a migration function. - */ - $core_widgets = array( 'WP_Widget_Pages', 'WP_Widget_Calendar', 'WP_Widget_Archives', 'WP_Widget_Media_Audio', 'WP_Widget_Media_Image', 'WP_Widget_Media_Gallery', 'WP_Widget_Media_Video', 'WP_Widget_Meta', 'WP_Widget_Search', 'WP_Widget_Text', 'WP_Widget_Categories', 'WP_Widget_Recent_Posts', 'WP_Widget_Recent_Comments', 'WP_Widget_RSS', 'WP_Widget_Tag_Cloud', 'WP_Nav_Menu_Widget', 'WP_Widget_Custom_HTML' ); - - $has_permissions_to_manage_widgets = current_user_can( 'edit_theme_options' ); - $available_legacy_widgets = array(); - global $wp_widget_factory, $wp_registered_widgets; - foreach ( $wp_widget_factory->widgets as $class => $widget_obj ) { - if ( ! in_array( $class, $core_widgets ) ) { - $available_legacy_widgets[ $class ] = array( - 'name' => html_entity_decode( $widget_obj->name ), - 'description' => html_entity_decode( $widget_obj->widget_options['description'] ), - 'isCallbackWidget' => false, - ); - } - } - foreach ( $wp_registered_widgets as $widget_id => $widget_obj ) { - if ( - is_array( $widget_obj['callback'] ) && - isset( $widget_obj['callback'][0] ) && - ( $widget_obj['callback'][0] instanceof WP_Widget ) - ) { - continue; - } - $available_legacy_widgets[ $widget_id ] = array( - 'name' => html_entity_decode( $widget_obj['name'] ), - 'description' => null, - 'isCallbackWidget' => true, - ); - } - /** - * End: Include for phase 2 - */ - - $editor_settings = array( - 'alignWide' => $align_wide, - 'availableTemplates' => $available_templates, - /** - * Start: Include for phase 2 - */ - 'hasPermissionsToManageWidgets' => $has_permissions_to_manage_widgets, - 'availableLegacyWidgets' => $available_legacy_widgets, - /** - * End: Include for phase 2 - */ - 'allowedBlockTypes' => $allowed_block_types, - 'disableCustomColors' => get_theme_support( 'disable-custom-colors' ), - 'disableCustomFontSizes' => get_theme_support( 'disable-custom-font-sizes' ), - 'disablePostFormats' => ! current_theme_supports( 'post-formats' ), - 'titlePlaceholder' => apply_filters( 'enter_title_here', __( 'Add title', 'gutenberg' ), $post ), - 'bodyPlaceholder' => apply_filters( 'write_your_story', __( 'Start writing or type / to choose a block', 'gutenberg' ), $post ), - 'isRTL' => is_rtl(), - 'autosaveInterval' => 10, - 'maxUploadFileSize' => $max_upload_size, - 'allowedMimeTypes' => get_allowed_mime_types(), - 'styles' => $styles, - 'imageSizes' => gutenberg_get_available_image_sizes(), - 'richEditingEnabled' => user_can_richedit(), - - // Ideally, we'd remove this and rely on a REST API endpoint. - 'postLock' => $lock_details, - 'postLockUtils' => array( - 'nonce' => wp_create_nonce( 'lock-post_' . $post->ID ), - 'unlockNonce' => wp_create_nonce( 'update-post_' . $post->ID ), - 'ajaxUrl' => admin_url( 'admin-ajax.php' ), - ), - - // Whether or not to load the 'postcustom' meta box is stored as a user meta - // field so that we're not always loading its assets. - 'enableCustomFields' => (bool) get_user_meta( get_current_user_id(), 'enable_custom_fields', true ), - ); - - $post_autosave = gutenberg_get_autosave_newer_than_post_save( $post ); - if ( $post_autosave ) { - $editor_settings['autosave'] = array( - 'editLink' => get_edit_post_link( $post_autosave->ID ), - ); - } - - if ( false !== $color_palette ) { - $editor_settings['colors'] = $color_palette; - } - - if ( false !== $font_sizes ) { - $editor_settings['fontSizes'] = $font_sizes; - } - - if ( ! empty( $post_type_object->template ) ) { - $editor_settings['template'] = $post_type_object->template; - $editor_settings['templateLock'] = ! empty( $post_type_object->template_lock ) ? $post_type_object->template_lock : false; - } - - $current_screen = get_current_screen(); - $core_meta_boxes = array(); - - // Make sure the current screen is set as well as the normal core metaboxes. - if ( isset( $current_screen->id ) && isset( $wp_meta_boxes[ $current_screen->id ]['normal']['core'] ) ) { - $core_meta_boxes = $wp_meta_boxes[ $current_screen->id ]['normal']['core']; - } - - // Check if the Custom Fields meta box has been removed at some point. - if ( ! isset( $core_meta_boxes['postcustom'] ) || ! $core_meta_boxes['postcustom'] ) { - unset( $editor_settings['enableCustomFields'] ); - } - - /** - * Filters the settings to pass to the block editor. - * - * @since 3.7.0 - * - * @param array $editor_settings Default editor settings. - * @param WP_Post $post Post being edited. - */ - $editor_settings = apply_filters( 'block_editor_settings', $editor_settings, $post ); - - $init_script = <<post_type, - $post->ID, - wp_json_encode( $editor_settings ), - wp_json_encode( $initial_edits ) - ); - wp_add_inline_script( 'wp-edit-post', $script ); - - /** - * Scripts - */ - wp_enqueue_media( - array( - 'post' => $post->ID, - ) - ); - wp_tinymce_inline_scripts(); - wp_enqueue_editor(); - - /** - * Styles - */ - wp_enqueue_style( 'wp-edit-post' ); - - /** - * Fires after block assets have been enqueued for the editing interface. - * - * Call `add_action` on any hook before 'admin_enqueue_scripts'. - * - * In the function call you supply, simply use `wp_enqueue_script` and - * `wp_enqueue_style` to add your functionality to the Gutenberg editor. - * - * @since 0.4.0 - */ - do_action( 'enqueue_block_editor_assets' ); -} diff --git a/lib/load.php b/lib/load.php index 6e8f9a6e101c86..f469513fd83a91 100644 --- a/lib/load.php +++ b/lib/load.php @@ -27,6 +27,7 @@ require dirname( __FILE__ ) . '/client-assets.php'; require dirname( __FILE__ ) . '/i18n.php'; require dirname( __FILE__ ) . '/demo.php'; +require dirname( __FILE__ ) . '/widgets.php'; require dirname( __FILE__ ) . '/widgets-page.php'; // Register server-side code for individual blocks. diff --git a/lib/widgets.php b/lib/widgets.php new file mode 100644 index 00000000000000..b756cce99d5222 --- /dev/null +++ b/lib/widgets.php @@ -0,0 +1,123 @@ +is_block_editor() ) { + /** This action is documented in wp-admin/admin-footer.php */ + // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores + do_action( 'admin_print_styles-widgets.php' ); + } +} +add_action( 'admin_print_styles', 'gutenberg_block_editor_admin_print_styles' ); + +/** + * Emulates the Widgets screen `admin_print_scripts` when at the block editor + * screen. + */ +function gutenberg_block_editor_admin_print_scripts() { + if ( get_current_screen()->is_block_editor() ) { + // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores + do_action( 'admin_print_scripts-widgets.php' ); + } +} +add_action( 'admin_print_scripts', 'gutenberg_block_editor_admin_print_scripts' ); + +/** + * Emulates the Widgets screen `admin_print_footer_scripts` when at the block + * editor screen. + */ +function gutenberg_block_editor_admin_print_footer_scripts() { + if ( get_current_screen()->is_block_editor() ) { + /** This action is documented in wp-admin/admin-footer.php */ + // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores + do_action( 'admin_print_footer_scripts-widgets.php' ); + } +} +add_action( 'admin_print_footer_scripts', 'gutenberg_block_editor_admin_print_footer_scripts' ); + +/** + * Emulates the Widgets screen `admin_footer` when at the block editor screen. + */ +function gutenberg_block_editor_admin_footer() { + if ( get_current_screen()->is_block_editor() ) { + /** This action is documented in wp-admin/admin-footer.php */ + // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores + do_action( 'admin_footer-widgets.php' ); + } +} +add_action( 'admin_footer', 'gutenberg_block_editor_admin_footer' ); + +/** + * Extends default editor settings with values supporting legacy widgets. + * + * @param array $settings Default editor settings. + * + * @return array Filtered editor settings. + */ +function gutenberg_legacy_widget_settings( $settings ) { + /** + * TODO: The hardcoded array should be replaced with a mechanism to allow + * core and third party blocks to specify they already have equivalent + * blocks, and maybe even allow them to have a migration function. + */ + $core_widgets = array( + 'WP_Widget_Pages', + 'WP_Widget_Calendar', + 'WP_Widget_Archives', + 'WP_Widget_Media_Audio', + 'WP_Widget_Media_Image', + 'WP_Widget_Media_Gallery', + 'WP_Widget_Media_Video', + 'WP_Widget_Meta', + 'WP_Widget_Search', + 'WP_Widget_Text', + 'WP_Widget_Categories', + 'WP_Widget_Recent_Posts', + 'WP_Widget_Recent_Comments', + 'WP_Widget_RSS', + 'WP_Widget_Tag_Cloud', + 'WP_Nav_Menu_Widget', + 'WP_Widget_Custom_HTML', + ); + + $has_permissions_to_manage_widgets = current_user_can( 'edit_theme_options' ); + $available_legacy_widgets = array(); + global $wp_widget_factory, $wp_registered_widgets; + foreach ( $wp_widget_factory->widgets as $class => $widget_obj ) { + if ( ! in_array( $class, $core_widgets ) ) { + $available_legacy_widgets[ $class ] = array( + 'name' => html_entity_decode( $widget_obj->name ), + 'description' => html_entity_decode( $widget_obj->widget_options['description'] ), + 'isCallbackWidget' => false, + ); + } + } + foreach ( $wp_registered_widgets as $widget_id => $widget_obj ) { + if ( + is_array( $widget_obj['callback'] ) && + isset( $widget_obj['callback'][0] ) && + ( $widget_obj['callback'][0] instanceof WP_Widget ) + ) { + continue; + } + $available_legacy_widgets[ $widget_id ] = array( + 'name' => html_entity_decode( $widget_obj['name'] ), + 'description' => null, + 'isCallbackWidget' => true, + ); + } + + $settings['hasPermissionsToManageWidgets'] = $has_permissions_to_manage_widgets; + $settings['availableLegacyWidgets'] = $available_legacy_widgets; + + return $settings; +} +add_filter( 'block_editor_settings', 'gutenberg_legacy_widget_settings' ); From 1dcef89cdccf535594fe861fc50b10e385ffd76a Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Fri, 1 Mar 2019 16:50:38 -0500 Subject: [PATCH 2/3] Plugin: Avoid dynamic dependencies for wp-block-library style This is handled by core in common blocks style enqueues behavior https://github.com/WordPress/wordpress-develop/blob/e421f26/src/wp-includes/script-loader.php#L2626-L2630 --- lib/client-assets.php | 2 +- phpunit/class-core-block-theme-test.php | 106 ------------------------ 2 files changed, 1 insertion(+), 107 deletions(-) delete mode 100644 phpunit/class-core-block-theme-test.php diff --git a/lib/client-assets.php b/lib/client-assets.php index 787c4c52458ef5..a99e0a64292ac4 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -299,7 +299,7 @@ function gutenberg_register_scripts_and_styles() { gutenberg_override_style( 'wp-block-library', gutenberg_url( 'build/block-library/style.css' ), - current_theme_supports( 'wp-block-styles' ) ? array( 'wp-block-library-theme' ) : array(), + array(), filemtime( gutenberg_dir_path() . 'build/block-library/style.css' ) ); wp_style_add_data( 'wp-block-library', 'rtl', 'replace' ); diff --git a/phpunit/class-core-block-theme-test.php b/phpunit/class-core-block-theme-test.php deleted file mode 100644 index dc378dd85a4eaa..00000000000000 --- a/phpunit/class-core-block-theme-test.php +++ /dev/null @@ -1,106 +0,0 @@ -old_wp_scripts = isset( $GLOBALS['wp_scripts'] ) ? $GLOBALS['wp_scripts'] : null; - remove_action( 'wp_default_scripts', 'wp_default_scripts' ); - - $GLOBALS['wp_scripts'] = new WP_Scripts(); - $GLOBALS['wp_scripts']->default_version = get_bloginfo( 'version' ); - - $this->old_wp_styles = isset( $GLOBALS['wp_styles'] ) ? $GLOBALS['wp_styles'] : null; - remove_action( 'wp_default_styles', 'wp_default_styles' ); - - $GLOBALS['wp_styles'] = new WP_Styles(); - $GLOBALS['wp_styles']->default_version = get_bloginfo( 'version' ); - } - - function tearDown() { - $GLOBALS['wp_scripts'] = $this->old_wp_scripts; - add_action( 'wp_default_scripts', 'wp_default_scripts' ); - - $GLOBALS['wp_styles'] = $this->old_wp_styles; - add_action( 'wp_default_styles', 'wp_default_styles' ); - - if ( current_theme_supports( 'wp-block-styles' ) ) { - remove_theme_support( 'wp-block-styles' ); - } - - parent::tearDown(); - } - - /** - * Tests that visual block styles are enqueued in the editor even when there is not theme support for 'wp-block-styles'. - * - * Visual block styles should always be enqueued when editing to avoid the appearance of a broken editor. - */ - function test_block_styles_for_editing_without_theme_support() { - // Confirm we are without theme support by default. - $this->assertFalse( current_theme_supports( 'wp-block-styles' ) ); - - gutenberg_register_scripts_and_styles(); - - $this->assertFalse( wp_style_is( 'wp-block-library-theme' ) ); - wp_enqueue_style( 'wp-edit-blocks' ); - $this->assertTrue( wp_style_is( 'wp-block-library-theme' ) ); - } - - /** - * Tests that visual block styles are enqueued when there is theme support for 'wp-block-styles'. - * - * Visual block styles should always be enqueued when editing to avoid the appearance of a broken editor. - */ - function test_block_styles_for_editing_with_theme_support() { - add_theme_support( 'wp-block-styles' ); - gutenberg_register_scripts_and_styles(); - - $this->assertFalse( wp_style_is( 'wp-block-library-theme' ) ); - wp_enqueue_style( 'wp-edit-blocks' ); - $this->assertTrue( wp_style_is( 'wp-block-library-theme' ) ); - } - - /** - * Tests that visual block styles are not enqueued for viewing when there is no theme support for 'wp-block-styles'. - * - * Visual block styles should not be enqueued unless a theme opts in. - * This way we avoid style conflicts with existing themes. - */ - function test_no_block_styles_for_viewing_without_theme_support() { - // Confirm we are without theme support by default. - $this->assertFalse( current_theme_supports( 'wp-block-styles' ) ); - - gutenberg_register_scripts_and_styles(); - - $this->assertFalse( wp_style_is( 'wp-block-library-theme' ) ); - wp_enqueue_style( 'wp-block-library' ); - $this->assertFalse( wp_style_is( 'wp-block-library-theme' ) ); - } - - /** - * Tests that visual block styles are enqueued for viewing when there is theme support for 'wp-block-styles'. - * - * Visual block styles should be enqueued when a theme opts in. - */ - function test_block_styles_for_viewing_with_theme_support() { - add_theme_support( 'wp-block-styles' ); - - gutenberg_register_scripts_and_styles(); - - $this->assertFalse( wp_style_is( 'wp-block-library-theme' ) ); - wp_enqueue_style( 'wp-block-library' ); - $this->assertTrue( wp_style_is( 'wp-block-library-theme' ) ); - } -} From c31f85dabf942930f6e39bedc24857a17622765c Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 5 Mar 2019 14:12:25 -0500 Subject: [PATCH 3/3] Testing: Leverage saveDraft for meta boxes save --- .../specs/plugins/meta-boxes.test.js | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/packages/e2e-tests/specs/plugins/meta-boxes.test.js b/packages/e2e-tests/specs/plugins/meta-boxes.test.js index b2e7649f53b57b..0a21dfe20d9d72 100644 --- a/packages/e2e-tests/specs/plugins/meta-boxes.test.js +++ b/packages/e2e-tests/specs/plugins/meta-boxes.test.js @@ -9,11 +9,15 @@ import { insertBlock, openDocumentSettingsSidebar, publishPost, + saveDraft, } from '@wordpress/e2e-test-utils'; describe( 'Meta boxes', () => { beforeAll( async () => { await activatePlugin( 'gutenberg-test-plugin-meta-box' ); + } ); + + beforeEach( async () => { await createNewPost(); } ); @@ -29,23 +33,14 @@ describe( 'Meta boxes', () => { await page.type( '.editor-post-title__input', 'Hello Meta' ); expect( await page.$( '.editor-post-save-draft' ) ).not.toBe( null ); - await Promise.all( [ - // Transitions between three states "Saving..." -> "Saved" -> "Save - // Draft" (the button is always visible while meta are present). - page.waitForSelector( '.editor-post-saved-state.is-saving' ), - page.waitForSelector( '.editor-post-saved-state.is-saved' ), - page.waitForSelector( '.editor-post-save-draft' ), - - // Keyboard shortcut Ctrl+S save. - page.keyboard.down( 'Meta' ), - page.keyboard.press( 'S' ), - page.keyboard.up( 'Meta' ), - ] ); + await saveDraft(); + + // After saving, affirm that the button returns to Save Draft. + await page.waitForSelector( '.editor-post-save-draft' ); } ); it( 'Should render dynamic blocks when the meta box uses the excerpt for front end rendering', async () => { // Publish a post so there's something for the latest posts dynamic block to render. - await createNewPost(); await page.type( '.editor-post-title__input', 'A published post' ); await insertBlock( 'Paragraph' ); await page.keyboard.type( 'Hello there!' ); @@ -67,7 +62,6 @@ describe( 'Meta boxes', () => { } ); it( 'Should render the excerpt in meta based on post content if no explicit excerpt exists', async () => { - await createNewPost(); await insertBlock( 'Paragraph' ); await page.keyboard.type( 'Excerpt from content.' ); await page.type( '.editor-post-title__input', 'A published post' ); @@ -91,7 +85,6 @@ describe( 'Meta boxes', () => { } ); it( 'Should render the explicitly set excerpt in meta instead of the content based one', async () => { - await createNewPost(); await insertBlock( 'Paragraph' ); await page.keyboard.type( 'Excerpt from content.' ); await page.type( '.editor-post-title__input', 'A published post' );