From 0aa898ae6ea87e20dcb8086890fd9bc15a988219 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Thu, 25 May 2023 09:30:08 +0200 Subject: [PATCH 01/42] Remove experimental flag --- lib/experiments-page.php | 12 ------------ lib/load.php | 6 ++---- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/lib/experiments-page.php b/lib/experiments-page.php index 9e31815f3f50ff..725aa1efcf0e28 100644 --- a/lib/experiments-page.php +++ b/lib/experiments-page.php @@ -101,18 +101,6 @@ function gutenberg_initialize_experiments_settings() { ) ); - add_settings_field( - 'gutenberg-interactivity-api-core-blocks', - __( 'Core blocks', 'gutenberg' ), - 'gutenberg_display_experiment_field', - 'gutenberg-experiments', - 'gutenberg_experiments_section', - array( - 'label' => __( 'Test the core blocks using the Interactivity API', 'gutenberg' ), - 'id' => 'gutenberg-interactivity-api-core-blocks', - ) - ); - add_settings_field( 'gutenberg-pattern-enhancements', __( 'Pattern enhancements', 'gutenberg' ), diff --git a/lib/load.php b/lib/load.php index f66fe7f474b961..1cfb13c54f2146 100644 --- a/lib/load.php +++ b/lib/load.php @@ -104,10 +104,8 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/experimental/kses.php'; require __DIR__ . '/experimental/l10n.php'; require __DIR__ . '/experimental/navigation-fallback.php'; -if ( gutenberg_is_experiment_enabled( 'gutenberg-interactivity-api-core-blocks' ) ) { - require __DIR__ . '/experimental/interactivity-api/script-loader.php'; - require __DIR__ . '/experimental/interactivity-api/blocks.php'; -} +require __DIR__ . '/experimental/interactivity-api/script-loader.php'; +require __DIR__ . '/experimental/interactivity-api/blocks.php'; // Fonts API. if ( ! class_exists( 'WP_Fonts' ) ) { From 1e5faae7060a35c7d0b40b14f6f12de768b78b8b Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Thu, 25 May 2023 09:34:00 +0200 Subject: [PATCH 02/42] Move interactive scripts to `block.json` --- lib/experimental/interactivity-api/blocks.php | 18 ----- packages/block-library/src/file/block.json | 2 +- packages/block-library/src/file/view.js | 9 --- packages/block-library/src/image/block.json | 1 + .../block-library/src/navigation/block.json | 2 +- .../src/navigation/view-modal.js | 78 ------------------- packages/block-library/src/navigation/view.js | 74 ------------------ 7 files changed, 3 insertions(+), 181 deletions(-) delete mode 100644 packages/block-library/src/file/view.js delete mode 100644 packages/block-library/src/navigation/view-modal.js delete mode 100644 packages/block-library/src/navigation/view.js diff --git a/lib/experimental/interactivity-api/blocks.php b/lib/experimental/interactivity-api/blocks.php index 3ad6d13d660fb1..fc8318cf6a2909 100644 --- a/lib/experimental/interactivity-api/blocks.php +++ b/lib/experimental/interactivity-api/blocks.php @@ -214,21 +214,3 @@ function gutenberg_block_core_navigation_add_directives_to_submenu( $w ) { }; add_filter( 'render_block_core/navigation', 'gutenberg_block_core_navigation_add_directives_to_markup', 10, 1 ); - -/** - * Replaces view script for the File, Navigation, and Image blocks with version using Interactivity API. - * - * @param array $metadata Block metadata as read in via block.json. - * - * @return array Filtered block type metadata. - */ -function gutenberg_block_update_interactive_view_script( $metadata ) { - if ( - in_array( $metadata['name'], array( 'core/file', 'core/navigation', 'core/image' ), true ) && - str_contains( $metadata['file'], 'build/block-library/blocks' ) - ) { - $metadata['viewScript'] = array( 'file:./interactivity.min.js' ); - } - return $metadata; -} -add_filter( 'block_type_metadata', 'gutenberg_block_update_interactive_view_script', 10, 1 ); diff --git a/packages/block-library/src/file/block.json b/packages/block-library/src/file/block.json index 08a78f3a94ce42..6b7da0a5ab1651 100644 --- a/packages/block-library/src/file/block.json +++ b/packages/block-library/src/file/block.json @@ -67,7 +67,7 @@ } } }, - "viewScript": "file:./view.min.js", + "viewScript": "file:./interactivity.min.js", "editorStyle": "wp-block-file-editor", "style": "wp-block-file" } diff --git a/packages/block-library/src/file/view.js b/packages/block-library/src/file/view.js deleted file mode 100644 index 6d0b61fa51cb7c..00000000000000 --- a/packages/block-library/src/file/view.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Internal dependencies - */ -import { hidePdfEmbedsOnUnsupportedBrowsers } from './utils'; - -document.addEventListener( - 'DOMContentLoaded', - hidePdfEmbedsOnUnsupportedBrowsers -); diff --git a/packages/block-library/src/image/block.json b/packages/block-library/src/image/block.json index 791e09f73c8009..ac22cf68ce22cd 100644 --- a/packages/block-library/src/image/block.json +++ b/packages/block-library/src/image/block.json @@ -120,6 +120,7 @@ }, { "name": "rounded", "label": "Rounded" } ], + "viewScript": "file:./interactivity.min.js", "editorStyle": "wp-block-image-editor", "style": "wp-block-image" } diff --git a/packages/block-library/src/navigation/block.json b/packages/block-library/src/navigation/block.json index ce2bed0d8837f6..d964c236bd15a7 100644 --- a/packages/block-library/src/navigation/block.json +++ b/packages/block-library/src/navigation/block.json @@ -134,7 +134,7 @@ } } }, - "viewScript": [ "file:./view.min.js", "file:./view-modal.min.js" ], + "viewScript": "file:./interactivity.min.js", "editorStyle": "wp-block-navigation-editor", "style": "wp-block-navigation" } diff --git a/packages/block-library/src/navigation/view-modal.js b/packages/block-library/src/navigation/view-modal.js deleted file mode 100644 index 9477d262816d93..00000000000000 --- a/packages/block-library/src/navigation/view-modal.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * External dependencies - */ -import MicroModal from 'micromodal'; - -// Responsive navigation toggle. -function navigationToggleModal( modal ) { - const dialogContainer = modal.querySelector( - `.wp-block-navigation__responsive-dialog` - ); - - const isHidden = 'true' === modal.getAttribute( 'aria-hidden' ); - - modal.classList.toggle( 'has-modal-open', ! isHidden ); - dialogContainer.toggleAttribute( 'aria-modal', ! isHidden ); - - if ( isHidden ) { - dialogContainer.removeAttribute( 'role' ); - dialogContainer.removeAttribute( 'aria-modal' ); - } else { - dialogContainer.setAttribute( 'role', 'dialog' ); - dialogContainer.setAttribute( 'aria-modal', 'true' ); - } - - // Add a class to indicate the modal is open. - const htmlElement = document.documentElement; - htmlElement.classList.toggle( 'has-modal-open' ); -} - -function isLinkToAnchorOnCurrentPage( node ) { - return ( - node.hash && - node.protocol === window.location.protocol && - node.host === window.location.host && - node.pathname === window.location.pathname && - node.search === window.location.search - ); -} - -window.addEventListener( 'load', () => { - MicroModal.init( { - onShow: navigationToggleModal, - onClose: navigationToggleModal, - openClass: 'is-menu-open', - } ); - - // Close modal automatically on clicking anchor links inside modal. - const navigationLinks = document.querySelectorAll( - '.wp-block-navigation-item__content' - ); - - navigationLinks.forEach( function ( link ) { - // Ignore non-anchor links and anchor links which open on a new tab. - if ( - ! isLinkToAnchorOnCurrentPage( link ) || - link.attributes?.target === '_blank' - ) { - return; - } - - // Find the specific parent modal for this link - // since .close() won't work without an ID if there are - // multiple navigation menus in a post/page. - const modal = link.closest( - '.wp-block-navigation__responsive-container' - ); - const modalId = modal?.getAttribute( 'id' ); - - link.addEventListener( 'click', () => { - // check if modal exists and is open before trying to close it - // otherwise Micromodal will toggle the `has-modal-open` class - // on the html tag which prevents scrolling - if ( modalId && modal.classList.contains( 'has-modal-open' ) ) { - MicroModal.close( modalId ); - } - } ); - } ); -} ); diff --git a/packages/block-library/src/navigation/view.js b/packages/block-library/src/navigation/view.js deleted file mode 100644 index 19805a44ae4ae2..00000000000000 --- a/packages/block-library/src/navigation/view.js +++ /dev/null @@ -1,74 +0,0 @@ -// Open on click functionality. -function closeSubmenus( element ) { - element - .querySelectorAll( '[aria-expanded="true"]' ) - .forEach( function ( toggle ) { - toggle.setAttribute( 'aria-expanded', 'false' ); - } ); -} - -function toggleSubmenuOnClick( event ) { - const buttonToggle = event.target.closest( '[aria-expanded]' ); - const isSubmenuOpen = buttonToggle.getAttribute( 'aria-expanded' ); - - if ( isSubmenuOpen === 'true' ) { - closeSubmenus( buttonToggle.closest( '.wp-block-navigation-item' ) ); - } else { - // Close all sibling submenus. - const parentElement = buttonToggle.closest( - '.wp-block-navigation-item' - ); - const navigationParent = buttonToggle.closest( - '.wp-block-navigation__submenu-container, .wp-block-navigation__container, .wp-block-page-list' - ); - navigationParent - .querySelectorAll( '.wp-block-navigation-item' ) - .forEach( function ( child ) { - if ( child !== parentElement ) { - closeSubmenus( child ); - } - } ); - // Open submenu. - buttonToggle.setAttribute( 'aria-expanded', 'true' ); - } -} - -// Necessary for some themes such as TT1 Blocks, where -// scripts could be loaded before the body. -window.addEventListener( 'load', () => { - const submenuButtons = document.querySelectorAll( - '.wp-block-navigation-submenu__toggle' - ); - - submenuButtons.forEach( function ( button ) { - button.addEventListener( 'click', toggleSubmenuOnClick ); - } ); - - // Close on click outside. - document.addEventListener( 'click', function ( event ) { - const navigationBlocks = document.querySelectorAll( - '.wp-block-navigation' - ); - navigationBlocks.forEach( function ( block ) { - if ( ! block.contains( event.target ) ) { - closeSubmenus( block ); - } - } ); - } ); - // Close on focus outside or escape key. - document.addEventListener( 'keyup', function ( event ) { - const submenuBlocks = document.querySelectorAll( - '.wp-block-navigation-item.has-child' - ); - submenuBlocks.forEach( function ( block ) { - if ( ! block.contains( event.target ) ) { - closeSubmenus( block ); - } else if ( event.key === 'Escape' ) { - const toggle = block.querySelector( '[aria-expanded="true"]' ); - closeSubmenus( block ); - // Focus the submenu trigger so focus does not get trapped in the closed submenu. - toggle?.focus(); - } - } ); - } ); -} ); From 499397387a871af79471f36e7d3d894768a2a2fe Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Thu, 25 May 2023 09:50:44 +0200 Subject: [PATCH 03/42] Add scripts conditionally --- packages/block-library/src/file/index.php | 19 ++++++++++++---- packages/block-library/src/image/index.php | 19 +++++++++++++--- .../block-library/src/navigation/index.php | 22 ++++++++++++------- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/packages/block-library/src/file/index.php b/packages/block-library/src/file/index.php index 9081b63a5e76b4..b0dc41655406ec 100644 --- a/packages/block-library/src/file/index.php +++ b/packages/block-library/src/file/index.php @@ -13,10 +13,21 @@ * * @return string Returns the block content. */ -function render_block_core_file( $attributes, $content ) { - $should_load_view_script = ! empty( $attributes['displayPreview'] ) && ! wp_script_is( 'wp-block-file-view' ); - if ( $should_load_view_script ) { - wp_enqueue_script( 'wp-block-file-view' ); +function render_block_core_file( $attributes, $content, $block ) { + $should_load_view_script = ! empty( $attributes['displayPreview'] ); + $view_js_file = 'wp-block-file-view'; + // If the script already exists, there is no point in removing it from viewScript. + if ( ! wp_script_is( $view_js_file ) ) { + $script_handles = $block->block_type->view_script_handles; + + // If the script is not needed, and it is still in the `view_script_handles`, remove it. + if ( ! $should_load_view_script && in_array( $view_js_file, $script_handles ) ) { + $block->block_type->view_script_handles = array_diff( $script_handles, array( $view_js_file ) ); + } + // If the script is needed, but it was previously removed, add it again. + if ( $should_load_view_script && ! in_array( $view_js_file, $script_handles ) ) { + $block->block_type->view_script_handles = array_merge( $script_handles, array( $view_js_file ) ); + } } // Update object's aria-label attribute if present in block HTML. diff --git a/packages/block-library/src/image/index.php b/packages/block-library/src/image/index.php index 828211f4f135d6..720103a8a879cf 100644 --- a/packages/block-library/src/image/index.php +++ b/packages/block-library/src/image/index.php @@ -13,7 +13,7 @@ * @param string $content The block content. * @return string Returns the block content with the data-id attribute added. */ -function render_block_core_image( $attributes, $content ) { +function render_block_core_image( $attributes, $content, $block ) { $processor = new WP_HTML_Tag_Processor( $content ); $processor->next_tag( 'img' ); @@ -45,10 +45,23 @@ function render_block_core_image( $attributes, $content ) { } } - $experiments = get_option( 'gutenberg-experiments' ); + $should_load_view_script = 'none' === $link_destination && $lightbox; + $view_js_file = 'wp-block-image-view'; + // If the script already exists, there is no point in removing it from viewScript. + if ( ! wp_script_is( $view_js_file ) ) { + $script_handles = $block->block_type->view_script_handles; - if ( ! empty( $experiments['gutenberg-interactivity-api-core-blocks'] ) && 'none' === $link_destination && $lightbox ) { + // If the script is not needed, and it is still in the `view_script_handles`, remove it. + if ( ! $should_load_view_script && in_array( $view_js_file, $script_handles ) ) { + $block->block_type->view_script_handles = array_diff( $script_handles, array( $view_js_file ) ); + } + // If the script is needed, but it was previously removed, add it again. + if ( $should_load_view_script && ! in_array( $view_js_file, $script_handles ) ) { + $block->block_type->view_script_handles = array_merge( $script_handles, array( $view_js_file ) ); + } + } + if ( $should_load_view_script ) { $aria_label = 'Open image lightbox'; if ( $processor->get_attribute( 'alt' ) ) { $aria_label .= ' : ' . $processor->get_attribute( 'alt' ); diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php index 5756724bfa7182..8787f4cb895f0a 100644 --- a/packages/block-library/src/navigation/index.php +++ b/packages/block-library/src/navigation/index.php @@ -364,14 +364,20 @@ function render_block_core_navigation( $attributes, $content, $block ) { */ $has_old_responsive_attribute = ! empty( $attributes['isResponsive'] ) && $attributes['isResponsive']; $is_responsive_menu = isset( $attributes['overlayMenu'] ) && 'never' !== $attributes['overlayMenu'] || $has_old_responsive_attribute; - $should_load_view_script = ! wp_script_is( 'wp-block-navigation-view' ) && ( $is_responsive_menu || $attributes['openSubmenusOnClick'] || $attributes['showSubmenuIcon'] ); - if ( $should_load_view_script ) { - wp_enqueue_script( 'wp-block-navigation-view' ); - } - - $should_load_modal_view_script = isset( $attributes['overlayMenu'] ) && 'never' !== $attributes['overlayMenu']; - if ( $should_load_modal_view_script ) { - wp_enqueue_script( 'wp-block-navigation-view-modal' ); + $should_load_view_script = ( $is_responsive_menu || $attributes['openSubmenusOnClick'] || $attributes['showSubmenuIcon'] ); + $view_js_file = 'wp-block-navigation-view'; + // If the script already exists, there is no point in removing it from viewScript. + if ( ! wp_script_is( $view_js_file ) ) { + $script_handles = $block->block_type->view_script_handles; + + // If the script is not needed, and it is still in the `view_script_handles`, remove it. + if ( ! $should_load_view_script && in_array( $view_js_file, $script_handles ) ) { + $block->block_type->view_script_handles = array_diff( $script_handles, array( $view_js_file ) ); + } + // If the script is needed, but it was previously removed, add it again. + if ( $should_load_view_script && ! in_array( $view_js_file, $script_handles ) ) { + $block->block_type->view_script_handles = array_merge( $script_handles, array( $view_js_file ) ); + } } $inner_blocks = $block->inner_blocks; From 203428c44fc5e287fe1ea3a62af0d582c36287a1 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Thu, 25 May 2023 10:01:54 +0200 Subject: [PATCH 04/42] Move directives to `index.php` files --- lib/experimental/interactivity-api/blocks.php | 216 ------------------ lib/load.php | 1 - packages/block-library/src/file/index.php | 11 + .../block-library/src/navigation/index.php | 186 +++++++++++++++ 4 files changed, 197 insertions(+), 217 deletions(-) delete mode 100644 lib/experimental/interactivity-api/blocks.php diff --git a/lib/experimental/interactivity-api/blocks.php b/lib/experimental/interactivity-api/blocks.php deleted file mode 100644 index fc8318cf6a2909..00000000000000 --- a/lib/experimental/interactivity-api/blocks.php +++ /dev/null @@ -1,216 +0,0 @@ -attributes['displayPreview'] ) ) { - return $block_content; - } - $processor = new WP_HTML_Tag_Processor( $block_content ); - $processor->next_tag(); - $processor->set_attribute( 'data-wp-island', '' ); - $processor->next_tag( 'object' ); - $processor->set_attribute( 'data-wp-bind.hidden', '!selectors.core.file.hasPdfPreview' ); - $processor->set_attribute( 'hidden', true ); - return $processor->get_updated_html(); -} -add_filter( 'render_block_core/file', 'gutenberg_block_core_file_add_directives_to_content', 10, 3 ); - -/** - * Add Interactivity API directives to the navigation block markup using the Tag Processor - * The final HTML of the navigation block will look similar to this: - * - * - * - * @param string $block_content Markup of the navigation block. - * - * @return string Navigation block markup with the proper directives - */ -function gutenberg_block_core_navigation_add_directives_to_markup( $block_content ) { - $w = new WP_HTML_Tag_Processor( $block_content ); - // Add directives to the `