From b1e8c2c7f9c7a42fb381a47e01bcbc1338cd1c67 Mon Sep 17 00:00:00 2001 From: madhusudhand Date: Wed, 10 Jul 2024 16:05:27 +0530 Subject: [PATCH 1/8] move the image context data to state --- packages/block-library/src/image/index.php | 34 +++++++++++++++------- packages/block-library/src/image/view.js | 15 +++++++--- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/packages/block-library/src/image/index.php b/packages/block-library/src/image/index.php index 584318b51d196..ec9bf673f5037 100644 --- a/packages/block-library/src/image/index.php +++ b/packages/block-library/src/image/index.php @@ -185,22 +185,36 @@ function block_core_image_render_lightbox( $block_content, $block ) { $p->seek( 'figure' ); $figure_class_names = $p->get_attribute( 'class' ); $figure_styles = $p->get_attribute( 'style' ); + + // Create unique id and set the image metadata in the state. + $unique_image_id = wp_unique_id( 'image-' ); + wp_interactivity_state( + 'core/image', + array( + 'metadata' => array( + $unique_image_id => array( + 'uploadedSrc' => $img_uploaded_src, + 'figureClassNames' => $figure_class_names, + 'figureStyles' => $figure_styles, + 'imgClassNames' => $img_class_names, + 'imgStyles' => $img_styles, + 'targetWidth' => $img_width, + 'targetHeight' => $img_height, + 'scaleAttr' => $block['attrs']['scale'] ?? false, + 'ariaLabel' => $aria_label, + 'alt' => $alt, + ), + ), + ) + ); + $p->add_class( 'wp-lightbox-container' ); $p->set_attribute( 'data-wp-interactive', 'core/image' ); $p->set_attribute( 'data-wp-context', wp_json_encode( array( - 'uploadedSrc' => $img_uploaded_src, - 'figureClassNames' => $figure_class_names, - 'figureStyles' => $figure_styles, - 'imgClassNames' => $img_class_names, - 'imgStyles' => $img_styles, - 'targetWidth' => $img_width, - 'targetHeight' => $img_height, - 'scaleAttr' => $block['attrs']['scale'] ?? false, - 'ariaLabel' => $aria_label, - 'alt' => $alt, + 'imageId' => $unique_image_id, ), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP ) diff --git a/packages/block-library/src/image/view.js b/packages/block-library/src/image/view.js index 4feb45dc9a399..827f28d90df21 100644 --- a/packages/block-library/src/image/view.js +++ b/packages/block-library/src/image/view.js @@ -23,6 +23,7 @@ const { state, actions, callbacks } = store( 'core/image', { state: { + metadata: {}, currentImage: {}, get overlayOpened() { return state.currentImage.currentSrc; @@ -58,14 +59,20 @@ const { state, actions, callbacks } = store( return; } - // Stores the positons of the scroll to fix it until the overlay is + // Stores the positions of the scroll to fix it until the overlay is // closed. state.scrollTopReset = document.documentElement.scrollTop; state.scrollLeftReset = document.documentElement.scrollLeft; - // Moves the information of the expaned image to the state. - ctx.currentSrc = ctx.imageRef.currentSrc; - state.currentImage = ctx; + // Sets the information of the expanded image in the state. + state.currentImage = { + ...state.metadata[ ctx.imageId ], + imageRef: ctx.imageRef, + buttonRef: ctx.buttonRef, + currentSrc: ctx.imageRef.currentSrc, + imageButtonTop: ctx.imageButtonTop, + imageButtonRight: ctx.imageButtonRight, + }; state.overlayEnabled = true; // Computes the styles of the overlay for the animation. From a24fa6207246a30204524618bed8cc9b15424e38 Mon Sep 17 00:00:00 2001 From: madhusudhand Date: Thu, 11 Jul 2024 15:03:30 +0530 Subject: [PATCH 2/8] move image and button refs from context to state --- packages/block-library/src/image/view.js | 45 ++++++++++++++---------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/packages/block-library/src/image/view.js b/packages/block-library/src/image/view.js index 827f28d90df21..497f7dc94de0a 100644 --- a/packages/block-library/src/image/view.js +++ b/packages/block-library/src/image/view.js @@ -55,25 +55,19 @@ const { state, actions, callbacks } = store( const ctx = getContext(); // Bails out if the image has not loaded yet. - if ( ! ctx.imageRef?.complete ) { + if ( ! state.metadata[ ctx.imageId ].imageRef?.complete ) { return; } + state.overlayEnabled = true; + // Stores the positions of the scroll to fix it until the overlay is // closed. state.scrollTopReset = document.documentElement.scrollTop; state.scrollLeftReset = document.documentElement.scrollLeft; // Sets the information of the expanded image in the state. - state.currentImage = { - ...state.metadata[ ctx.imageId ], - imageRef: ctx.imageRef, - buttonRef: ctx.buttonRef, - currentSrc: ctx.imageRef.currentSrc, - imageButtonTop: ctx.imageButtonTop, - imageButtonRight: ctx.imageButtonRight, - }; - state.overlayEnabled = true; + state.currentImage = state.metadata[ ctx.imageId ]; // Computes the styles of the overlay for the animation. callbacks.setOverlayStyles(); @@ -332,7 +326,11 @@ const { state, actions, callbacks } = store( setButtonStyles() { const ctx = getContext(); const { ref } = getElement(); - ctx.imageRef = ref; + state.metadata[ ctx.imageId ] = { + ...state.metadata[ ctx.imageId ], + imageRef: ref, + currentSrc: ref.currentSrc, + }; const { naturalWidth, @@ -375,6 +373,9 @@ const { state, actions, callbacks } = store( const buttonOffsetTop = figureHeight - offsetHeight; const buttonOffsetRight = figureWidth - offsetWidth; + let imageButtonTop = buttonOffsetTop + 16; + let imageButtonRight = buttonOffsetRight + 16; + // In the case of an image with object-fit: contain, the size of the // element can be larger than the image itself, so it needs to // calculate where to place the button. @@ -388,25 +389,28 @@ const { state, actions, callbacks } = store( // If it reaches the width first, it keeps the width and compute the // height. const referenceHeight = offsetWidth / naturalRatio; - ctx.imageButtonTop = + imageButtonTop = ( offsetHeight - referenceHeight ) / 2 + buttonOffsetTop + 16; - ctx.imageButtonRight = buttonOffsetRight + 16; + imageButtonRight = buttonOffsetRight + 16; } else { // If it reaches the height first, it keeps the height and compute // the width. const referenceWidth = offsetHeight * naturalRatio; - ctx.imageButtonTop = buttonOffsetTop + 16; - ctx.imageButtonRight = + imageButtonTop = buttonOffsetTop + 16; + imageButtonRight = ( offsetWidth - referenceWidth ) / 2 + buttonOffsetRight + 16; } - } else { - ctx.imageButtonTop = buttonOffsetTop + 16; - ctx.imageButtonRight = buttonOffsetRight + 16; } + + state.metadata[ ctx.imageId ] = { + ...state.metadata[ ctx.imageId ], + imageButtonTop, + imageButtonRight, + }; }, setOverlayFocus() { if ( state.overlayEnabled ) { @@ -418,7 +422,10 @@ const { state, actions, callbacks } = store( initTriggerButton() { const ctx = getContext(); const { ref } = getElement(); - ctx.buttonRef = ref; + state.metadata[ ctx.imageId ] = { + ...state.metadata[ ctx.imageId ], + buttonRef: ref, + }; }, }, }, From 189c7f51dc2bd395ca80c3a1435ecf4b0f76a9a4 Mon Sep 17 00:00:00 2001 From: Luis Herranz Date: Fri, 12 Jul 2024 13:30:40 +0200 Subject: [PATCH 3/8] Use hash instead of counter for the unique id --- packages/block-library/src/image/index.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/image/index.php b/packages/block-library/src/image/index.php index ec9bf673f5037..035c671260f87 100644 --- a/packages/block-library/src/image/index.php +++ b/packages/block-library/src/image/index.php @@ -187,7 +187,8 @@ function block_core_image_render_lightbox( $block_content, $block ) { $figure_styles = $p->get_attribute( 'style' ); // Create unique id and set the image metadata in the state. - $unique_image_id = wp_unique_id( 'image-' ); + $unique_image_id = substr( md5( $img_uploaded_src ), 0, 10 ); + wp_interactivity_state( 'core/image', array( From 3c3c3f27ea50e8c8749b8bd2e41a47afdc598142 Mon Sep 17 00:00:00 2001 From: Luis Herranz Date: Fri, 12 Jul 2024 13:32:49 +0200 Subject: [PATCH 4/8] Don't use immutability --- packages/block-library/src/image/view.js | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/packages/block-library/src/image/view.js b/packages/block-library/src/image/view.js index 497f7dc94de0a..c66cdbc8ed1f0 100644 --- a/packages/block-library/src/image/view.js +++ b/packages/block-library/src/image/view.js @@ -324,13 +324,11 @@ const { state, actions, callbacks } = store( `; }, setButtonStyles() { - const ctx = getContext(); + const { imageId } = getContext(); const { ref } = getElement(); - state.metadata[ ctx.imageId ] = { - ...state.metadata[ ctx.imageId ], - imageRef: ref, - currentSrc: ref.currentSrc, - }; + + state.metadata[ imageId ].imageRef = ref; + state.metadata[ imageId ].currentSrc = ref.currentSrc; const { naturalWidth, @@ -406,11 +404,8 @@ const { state, actions, callbacks } = store( } } - state.metadata[ ctx.imageId ] = { - ...state.metadata[ ctx.imageId ], - imageButtonTop, - imageButtonRight, - }; + state.metadata[ imageId ].imageButtonTop = imageButtonTop; + state.metadata[ imageId ].imageButtonRight = imageButtonRight; }, setOverlayFocus() { if ( state.overlayEnabled ) { @@ -420,12 +415,9 @@ const { state, actions, callbacks } = store( } }, initTriggerButton() { - const ctx = getContext(); + const { imageId } = getContext(); const { ref } = getElement(); - state.metadata[ ctx.imageId ] = { - ...state.metadata[ ctx.imageId ], - buttonRef: ref, - }; + state.metadata[ imageId ].buttonRef = ref; }, }, }, From 64ad89e6a87723fa657ecdd13885e7c9d63d8cb6 Mon Sep 17 00:00:00 2001 From: Luis Herranz Date: Fri, 12 Jul 2024 13:33:47 +0200 Subject: [PATCH 5/8] Fix reading prop from old context --- packages/block-library/src/image/view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/image/view.js b/packages/block-library/src/image/view.js index c66cdbc8ed1f0..9c3d81e3a64f3 100644 --- a/packages/block-library/src/image/view.js +++ b/packages/block-library/src/image/view.js @@ -377,7 +377,7 @@ const { state, actions, callbacks } = store( // In the case of an image with object-fit: contain, the size of the // element can be larger than the image itself, so it needs to // calculate where to place the button. - if ( ctx.scaleAttr === 'contain' ) { + if ( state.metadata[ imageId ].scaleAttr === 'contain' ) { // Natural ratio of the image. const naturalRatio = naturalWidth / naturalHeight; // Offset ratio of the image. From 56d94872c41e57fcbb47652359d3acdedf1bbe63 Mon Sep 17 00:00:00 2001 From: Luis Herranz Date: Fri, 12 Jul 2024 13:34:24 +0200 Subject: [PATCH 6/8] Only store the current image ID in the state --- packages/block-library/src/image/view.js | 34 +++++++++++++----------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/block-library/src/image/view.js b/packages/block-library/src/image/view.js index 9c3d81e3a64f3..9e54b916206e1 100644 --- a/packages/block-library/src/image/view.js +++ b/packages/block-library/src/image/view.js @@ -23,10 +23,12 @@ const { state, actions, callbacks } = store( 'core/image', { state: { - metadata: {}, - currentImage: {}, + currentImageId: null, + get currentImage() { + return state.metadata[ state.currentImageId ]; + }, get overlayOpened() { - return state.currentImage.currentSrc; + return state.currentImageId !== null; }, get roleAttribute() { return state.overlayOpened ? 'dialog' : null; @@ -52,28 +54,32 @@ const { state, actions, callbacks } = store( }, actions: { showLightbox() { - const ctx = getContext(); + const { imageId } = getContext(); // Bails out if the image has not loaded yet. - if ( ! state.metadata[ ctx.imageId ].imageRef?.complete ) { + if ( ! state.metadata[ imageId ].imageRef?.complete ) { return; } - state.overlayEnabled = true; - // Stores the positions of the scroll to fix it until the overlay is // closed. state.scrollTopReset = document.documentElement.scrollTop; state.scrollLeftReset = document.documentElement.scrollLeft; - // Sets the information of the expanded image in the state. - state.currentImage = state.metadata[ ctx.imageId ]; + // Sets the current expanded image in the state and enables the overlay. + state.currentImageId = imageId; + state.overlayEnabled = true; // Computes the styles of the overlay for the animation. callbacks.setOverlayStyles(); }, hideLightbox() { if ( state.overlayEnabled ) { + // Starts the overlay closing animation. The showClosingAnimation + // class is used to avoid showing it on page load. + state.showClosingAnimation = true; + state.overlayEnabled = false; + // Waits until the close animation has completed before allowing a // user to scroll again. The duration of this animation is defined in // the `styles.scss` file, but in any case we should wait a few @@ -87,14 +93,9 @@ const { state, actions, callbacks } = store( preventScroll: true, } ); - // Resets the current image to mark the overlay as closed. - state.currentImage = {}; + // Resets the current image id to mark the overlay as closed. + state.currentImageId = null; }, 450 ); - - // Starts the overlay closing animation. The showClosingAnimation - // class is used to avoid showing it on page load. - state.showClosingAnimation = true; - state.overlayEnabled = false; } }, handleKeydown( event ) { @@ -214,6 +215,7 @@ const { state, actions, callbacks } = store( let containerMaxHeight = imgMaxHeight; let containerWidth = imgMaxWidth; let containerHeight = imgMaxHeight; + // Checks if the target image has a different ratio than the original // one (thumbnail). Recalculates the width and height. if ( naturalRatio.toFixed( 2 ) !== imgRatio.toFixed( 2 ) ) { From d0d8a85c896fa85e3a2f6a723dc7e04a6d00410d Mon Sep 17 00:00:00 2001 From: Luis Herranz Date: Mon, 15 Jul 2024 11:02:47 +0200 Subject: [PATCH 7/8] Replace hash based on url with PHP's uniqid() --- packages/block-library/src/image/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/image/index.php b/packages/block-library/src/image/index.php index 035c671260f87..65f480c141f13 100644 --- a/packages/block-library/src/image/index.php +++ b/packages/block-library/src/image/index.php @@ -187,7 +187,7 @@ function block_core_image_render_lightbox( $block_content, $block ) { $figure_styles = $p->get_attribute( 'style' ); // Create unique id and set the image metadata in the state. - $unique_image_id = substr( md5( $img_uploaded_src ), 0, 10 ); + $unique_image_id = uniqid(); wp_interactivity_state( 'core/image', From 86e188708a399d8adef50465dadabd9ca31c103a Mon Sep 17 00:00:00 2001 From: madhusudhand Date: Mon, 15 Jul 2024 15:08:31 +0530 Subject: [PATCH 8/8] fix lightbox trigger image position --- packages/block-library/src/image/index.php | 4 ++-- packages/block-library/src/image/view.js | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/image/index.php b/packages/block-library/src/image/index.php index 65f480c141f13..886843d83ba72 100644 --- a/packages/block-library/src/image/index.php +++ b/packages/block-library/src/image/index.php @@ -246,8 +246,8 @@ class="lightbox-trigger" aria-label="' . esc_attr( $aria_label ) . '" data-wp-init="callbacks.initTriggerButton" data-wp-on-async--click="actions.showLightbox" - data-wp-style--right="context.imageButtonRight" - data-wp-style--top="context.imageButtonTop" + data-wp-style--right="state.imageButtonRight" + data-wp-style--top="state.imageButtonTop" > diff --git a/packages/block-library/src/image/view.js b/packages/block-library/src/image/view.js index 9e54b916206e1..99cc84d79f0f4 100644 --- a/packages/block-library/src/image/view.js +++ b/packages/block-library/src/image/view.js @@ -51,6 +51,14 @@ const { state, actions, callbacks } = store( ) }; object-fit:cover;` ); }, + get imageButtonRight() { + const { imageId } = getContext(); + return state.metadata[ imageId ].imageButtonRight; + }, + get imageButtonTop() { + const { imageId } = getContext(); + return state.metadata[ imageId ].imageButtonTop; + }, }, actions: { showLightbox() {