Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image: Fix resizer controls being hidden in Safari when switching between alignments #37210

Conversation

andrewserong
Copy link
Contributor

@andrewserong andrewserong commented Dec 8, 2021

Description

Fixes #24587

In Safari, when switching the Image block between not aligned and an alignment, the component appears to re-render however the img element's onload callback is never fired, resulting in naturalWidth and naturalHeight being undefined. This means that the conditional on this line is reached, which means that the resizer isn't rendered.

The fix is to update naturalWidth and naturalHeight to pull from an image ref (so that the values are always available) and fall back to local component state when not available. This should 🤞 give us the best of both worlds — the real current value is available for Safari, and the fallback local component state value is available when cropping and editing images so that the saving state doesn't unexpectedly fail due to undefined natural width/height.

How has this been tested?

  1. In Safari, before applying this PR, insert an image block.
  2. Switch the image block from no alignment to any alignment (e.g. Left alignment)
  3. Observe that the resizer controls are no longer visible.
  4. Apply this PR.
  5. Repeat the above steps, and the resizer should always be available.

Test in other browsers, and also test cropping / image editing to be sure this doesn't introduce any regressions.

Screenshots

Before After
Kapture 2021-12-08 at 12 31 31 Kapture 2021-12-08 at 12 29 20

Types of changes

Bug fix (non-breaking change which fixes an issue)

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • I've tested my changes with keyboard and screen readers.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR (please manually search all *.native.js files for terms that need renaming or removal).

@andrewserong andrewserong added [Type] Bug An existing feature does not function as intended [Block] Image Affects the Image Block labels Dec 8, 2021
@andrewserong andrewserong self-assigned this Dec 8, 2021
@github-actions
Copy link

github-actions bot commented Dec 8, 2021

Size Change: +128 B (0%)

Total Size: 1.11 MB

Filename Size Change
build/block-library/index.min.js 163 kB +128 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 960 B
build/admin-manifest/index.min.js 1.1 kB
build/annotations/index.min.js 2.75 kB
build/api-fetch/index.min.js 2.21 kB
build/autop/index.min.js 2.12 kB
build/blob/index.min.js 459 B
build/block-directory/index.min.js 6.28 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-editor/index.min.js 139 kB
build/block-editor/style-rtl.css 14.4 kB
build/block-editor/style.css 14.4 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 58 B
build/block-library/blocks/audio/editor.css 58 B
build/block-library/blocks/audio/style-rtl.css 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 470 B
build/block-library/blocks/button/editor.css 470 B
build/block-library/blocks/button/style-rtl.css 560 B
build/block-library/blocks/button/style.css 560 B
build/block-library/blocks/buttons/editor-rtl.css 291 B
build/block-library/blocks/buttons/editor.css 291 B
build/block-library/blocks/buttons/style-rtl.css 275 B
build/block-library/blocks/buttons/style.css 275 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 90 B
build/block-library/blocks/code/style.css 90 B
build/block-library/blocks/code/theme-rtl.css 134 B
build/block-library/blocks/code/theme.css 134 B
build/block-library/blocks/columns/editor-rtl.css 210 B
build/block-library/blocks/columns/editor.css 208 B
build/block-library/blocks/columns/style-rtl.css 503 B
build/block-library/blocks/columns/style.css 502 B
build/block-library/blocks/comment-template/style-rtl.css 127 B
build/block-library/blocks/comment-template/style.css 127 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/cover/editor-rtl.css 546 B
build/block-library/blocks/cover/editor.css 547 B
build/block-library/blocks/cover/style-rtl.css 1.22 kB
build/block-library/blocks/cover/style.css 1.22 kB
build/block-library/blocks/embed/editor-rtl.css 488 B
build/block-library/blocks/embed/editor.css 488 B
build/block-library/blocks/embed/style-rtl.css 417 B
build/block-library/blocks/embed/style.css 417 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 322 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 966 B
build/block-library/blocks/gallery/editor.css 970 B
build/block-library/blocks/gallery/style-rtl.css 1.63 kB
build/block-library/blocks/gallery/style.css 1.62 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 159 B
build/block-library/blocks/group/editor.css 159 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 114 B
build/block-library/blocks/heading/style.css 114 B
build/block-library/blocks/html/editor-rtl.css 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/editor-rtl.css 810 B
build/block-library/blocks/image/editor.css 809 B
build/block-library/blocks/image/style-rtl.css 507 B
build/block-library/blocks/image/style.css 511 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 137 B
build/block-library/blocks/latest-posts/editor.css 137 B
build/block-library/blocks/latest-posts/style-rtl.css 528 B
build/block-library/blocks/latest-posts/style.css 527 B
build/block-library/blocks/list/style-rtl.css 94 B
build/block-library/blocks/list/style.css 94 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 493 B
build/block-library/blocks/media-text/style.css 490 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 649 B
build/block-library/blocks/navigation-link/editor.css 650 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B
build/block-library/blocks/navigation-link/style.css 94 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation-submenu/view.min.js 343 B
build/block-library/blocks/navigation/editor-rtl.css 1.91 kB
build/block-library/blocks/navigation/editor.css 1.91 kB
build/block-library/blocks/navigation/style-rtl.css 1.68 kB
build/block-library/blocks/navigation/style.css 1.67 kB
build/block-library/blocks/navigation/view.min.js 2.79 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 377 B
build/block-library/blocks/page-list/editor.css 377 B
build/block-library/blocks/page-list/style-rtl.css 172 B
build/block-library/blocks/page-list/style.css 172 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 273 B
build/block-library/blocks/paragraph/style.css 273 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/style-rtl.css 444 B
build/block-library/blocks/post-comments-form/style.css 444 B
build/block-library/blocks/post-comments/style-rtl.css 492 B
build/block-library/blocks/post-comments/style.css 493 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 721 B
build/block-library/blocks/post-featured-image/editor.css 721 B
build/block-library/blocks/post-featured-image/style-rtl.css 153 B
build/block-library/blocks/post-featured-image/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 391 B
build/block-library/blocks/post-template/style.css 392 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 80 B
build/block-library/blocks/post-title/style.css 80 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 389 B
build/block-library/blocks/pullquote/style.css 388 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 273 B
build/block-library/blocks/query-pagination/style.css 269 B
build/block-library/blocks/query/editor-rtl.css 131 B
build/block-library/blocks/query/editor.css 132 B
build/block-library/blocks/quote/style-rtl.css 187 B
build/block-library/blocks/quote/style.css 187 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 397 B
build/block-library/blocks/search/style.css 398 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 99 B
build/block-library/blocks/separator/editor.css 99 B
build/block-library/blocks/separator/style-rtl.css 245 B
build/block-library/blocks/separator/style.css 245 B
build/block-library/blocks/separator/theme-rtl.css 172 B
build/block-library/blocks/separator/theme.css 172 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 772 B
build/block-library/blocks/site-logo/editor.css 772 B
build/block-library/blocks/site-logo/style-rtl.css 165 B
build/block-library/blocks/site-logo/style.css 165 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 177 B
build/block-library/blocks/social-link/editor.css 177 B
build/block-library/blocks/social-links/editor-rtl.css 670 B
build/block-library/blocks/social-links/editor.css 669 B
build/block-library/blocks/social-links/style-rtl.css 1.32 kB
build/block-library/blocks/social-links/style.css 1.32 kB
build/block-library/blocks/spacer/editor-rtl.css 307 B
build/block-library/blocks/spacer/editor.css 307 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 471 B
build/block-library/blocks/table/editor.css 472 B
build/block-library/blocks/table/style-rtl.css 481 B
build/block-library/blocks/table/style.css 481 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 146 B
build/block-library/blocks/tag-cloud/style.css 146 B
build/block-library/blocks/template-part/editor-rtl.css 560 B
build/block-library/blocks/template-part/editor.css 559 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 569 B
build/block-library/blocks/video/editor.css 570 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 857 B
build/block-library/common.css 856 B
build/block-library/editor-rtl.css 10 kB
build/block-library/editor.css 10 kB
build/block-library/reset-rtl.css 474 B
build/block-library/reset.css 474 B
build/block-library/style-rtl.css 10.7 kB
build/block-library/style.css 10.7 kB
build/block-library/theme-rtl.css 672 B
build/block-library/theme.css 677 B
build/block-serialization-default-parser/index.min.js 1.09 kB
build/block-serialization-spec-parser/index.min.js 2.79 kB
build/blocks/index.min.js 46.3 kB
build/components/index.min.js 215 kB
build/components/style-rtl.css 15.5 kB
build/components/style.css 15.5 kB
build/compose/index.min.js 10.9 kB
build/core-data/index.min.js 13.2 kB
build/customize-widgets/index.min.js 11.4 kB
build/customize-widgets/style-rtl.css 1.5 kB
build/customize-widgets/style.css 1.49 kB
build/data-controls/index.min.js 631 B
build/data/index.min.js 7.49 kB
build/date/index.min.js 31.5 kB
build/deprecated/index.min.js 485 B
build/dom-ready/index.min.js 304 B
build/dom/index.min.js 4.5 kB
build/edit-navigation/index.min.js 16 kB
build/edit-navigation/style-rtl.css 3.76 kB
build/edit-navigation/style.css 3.76 kB
build/edit-post/classic-rtl.css 492 B
build/edit-post/classic.css 494 B
build/edit-post/index.min.js 29.7 kB
build/edit-post/style-rtl.css 7.1 kB
build/edit-post/style.css 7.09 kB
build/edit-site/index.min.js 35.5 kB
build/edit-site/style-rtl.css 6.57 kB
build/edit-site/style.css 6.57 kB
build/edit-widgets/index.min.js 16.5 kB
build/edit-widgets/style-rtl.css 4.18 kB
build/edit-widgets/style.css 4.18 kB
build/editor/index.min.js 37.8 kB
build/editor/style-rtl.css 3.78 kB
build/editor/style.css 3.77 kB
build/element/index.min.js 3.29 kB
build/escape-html/index.min.js 517 B
build/format-library/index.min.js 6.58 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.63 kB
build/html-entities/index.min.js 424 B
build/i18n/index.min.js 3.71 kB
build/is-shallow-equal/index.min.js 501 B
build/keyboard-shortcuts/index.min.js 1.8 kB
build/keycodes/index.min.js 1.39 kB
build/list-reusable-blocks/index.min.js 1.72 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.92 kB
build/notices/index.min.js 925 B
build/nux/index.min.js 2.08 kB
build/nux/style-rtl.css 747 B
build/nux/style.css 743 B
build/plugins/index.min.js 1.84 kB
build/primitives/index.min.js 924 B
build/priority-queue/index.min.js 582 B
build/react-i18n/index.min.js 671 B
build/redux-routine/index.min.js 2.65 kB
build/reusable-blocks/index.min.js 2.22 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 11 kB
build/server-side-render/index.min.js 1.57 kB
build/shortcode/index.min.js 1.49 kB
build/token-list/index.min.js 639 B
build/url/index.min.js 1.9 kB
build/viewport/index.min.js 1.05 kB
build/warning/index.min.js 248 B
build/widgets/index.min.js 7.15 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.04 kB

compressed-size-action

@andrewserong
Copy link
Contributor Author

andrewserong commented Dec 8, 2021

Update: this fix will need some adjustment, I just noticed it introduces a regression when dealing with external images when the external image is initially added to the block (the resizer is not visible).

We might wind up needing to retain the onload and use the imageRef as a fallback if available. I'll have a play around.

@andrewserong andrewserong added [Status] In Progress Tracking issues with work in progress and removed [Status] In Progress Tracking issues with work in progress labels Dec 8, 2021
@andrewserong
Copy link
Contributor Author

I just noticed it introduces a regression when dealing with external images when the external image is initially added to the block (the resizer is not visible).

Another update: I think I've fixed up the issue by preserving the local component state for the loaded image's natural width / height. We then use that as a fallback value, and prioritise the real img element's natural width/height when available, so that the fix for Safari still works.

@paaljoachim
Copy link
Contributor

Hey @andrewserong
I assume we also need the backtrack label here as well?
As the various fixes can easier be picked up to be added to the next beta.

@andrewserong andrewserong added the Backport to WP 6.7 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Dec 8, 2021
@andrewserong
Copy link
Contributor Author

I assume we also need the backtrack label here as well?

@paaljoachim yes, we sure do! I've added the label. 👍

@andrewserong andrewserong force-pushed the fix/image-block-resizer-controls-availability-in-safari-after-switching-alignments branch from 7cbb1b5 to 573e521 Compare December 9, 2021 00:39
@glendaviesnz
Copy link
Contributor

glendaviesnz commented Dec 9, 2021

This tests well for me. An alternative, rather than using image onload method at all for this, would be to use ref.current.complete. A quick test of just adding the following to the existing image.js code seems to work for chrome and safari:

	const imgRef = useRef();
	const imageOnload = () => {
		setNaturalSize(
			pick( imgRef.current, [ 'naturalWidth', 'naturalHeight' ] )
		);
	};

	useEffect( () => {
		if ( imgRef.current?.complete ) {
			imageOnload();
		}
	}, [ imgRef.current?.complete ] );

	let img = (
		// Disable reason: Image itself is not meant to be interactive, but
		// should direct focus to block.
		/* eslint-disable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events */
		<>
			<img
				ref={ imgRef }
				src={ temporaryURL || url }
				alt={ defaultedAlt }
				onError={ () => onImageError() }
			/>
			{ temporaryURL && <Spinner /> }
		</>
		/* eslint-enable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events */
	);

@glendaviesnz
Copy link
Contributor

A quick test of just adding the following to the existing image.js code seems to work for chrome and safari:

Actually it only works for existing images - ref.current.complete stays as false for new images for some reason.

@glendaviesnz
Copy link
Contributor

glendaviesnz commented Dec 9, 2021

Actually it only works for existing images - ref.current.complete stays as false for new images for some reason.

My bad, the useEffect in above should be:

	useEffect( () => {
		if ( imgRef.current?.complete ) {
			imageOnload();
		}
	}, [ imgRef.current?.complete ] );

have updated the full example above, and now seems to test well for me for existing images on page load and new images added.

@andrewserong
Copy link
Contributor Author

Thanks for reviewing @glendaviesnz! Nice, I hadn't thought of using imgRef?.current?.complete. With the other approaches I tried for removing the onload handler, I wound up introducing bugs when using the cropping tool, or with external images that don't have CORS access. I'll give imgRef?.current?.complete a try! 🤞

loadedNaturalHeight ||
undefined,
};
}, [ loadedNaturalWidth, loadedNaturalHeight, imageRef.current ] );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to include imageRef.current in the dependency, at least based on exhaustive-deps 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I've removed the useMemo call, since I think setting the naturalWidth and naturalHeight isn't quite worth it (because there's no real calculation going on). Let me know if you think it's better to leave it in, and I can add it back 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: I actually just added it back in, as removing it caused the resizer to intermittently fail to display in Safari. I've included imageRef.current?.complete in the dependency array — here I think we want the useMemo to recalculate slightly more frequently than with just the loadedNaturalWidth and loadedNaturalHeight values, but happy to remove it if it winds up not being needed.

I've found the behaviour in Safari to be a bit unreliable in testing, so working out what is and isn't needed has been a bit more challenging than usual 😅

@andrewserong andrewserong force-pushed the fix/image-block-resizer-controls-availability-in-safari-after-switching-alignments branch from 573e521 to 832d1c5 Compare December 10, 2021 06:03
@andrewserong
Copy link
Contributor Author

Thanks for the suggestion to move away from the onLoad callback and to use imageRef.current?.complete in a useEffect instead, @glendaviesnz! Unfortunately doing that introduced a regression:

Kapture 2021-12-10 at 17 09 47

In this screengrab, I've added an external image, and once it's loaded, the resizer controls aren't available. I think this is due to:

When inserting an image from an external URL, the useEffect at this line attempts to async fetch the image so that it can be uploaded if need be. When the fetch fails for images without an appropriate CORS policy, the imageRef.current?.complete value is set to false, even though the image itself has loaded within the editor. This appears to be because fetching the asset resets .complete? And then the CORS failure means that it remains false. I found a tiny bit more context in this MDN article, but I wasn't too sure of what I was observing. It looks like the cases where the value changes are a fair bit more broad than the onLoad handler.

To resolve that issue, adding an onLoad handler back in on the img element worked, however we then have multiple state updates and additional renders occurring from having both the useEffect and onLoad methods updating the natural width/height. So, if we need to have the onLoad handler there, I think I prefer the idea of reducing the number of state updates and avoiding the useEffect? The imageRef.current?.complete is still a good idea, though, so I've added it to the useMemo dependency array. I've also moved things around a little bit to reduce the diff.

Let me know if you can think of a better way to handle all this, though, or if I missed something in your approach. Very happy to try alternatives!

@glendaviesnz
Copy link
Contributor

@andrewserong I didn't try the remote url scenario - I can't see a way around the CORs failure with my approach. The current change of your's seems to work well in both cases - although I did have one failure still in Safari, so just trying to see if I can replicate that

@glendaviesnz
Copy link
Contributor

glendaviesnz commented Dec 12, 2021

I couldn't replicate the issue with Safari not showing the resize handles with this patch applied, so not sure what caused that.

The only other thought I had was that maybe this extra code isn't needed if the allowResize context is set to false by a parent gallery, but I can't see an easy way of making it dependent on allowResize=true as hooks can't be used conditionally - but it doesn't seem like it would cause any performance issues on a large gallery, what do you think?

@andrewserong
Copy link
Contributor Author

Thanks for re-testing @glendaviesnz!

The only other thought I had was that maybe this extra code isn't needed if the allowResize context is set to false by a parent gallery, but I can't see an easy way of making it dependent on allowResize=true as hooks can't be used conditionally - but it doesn't seem like it would cause any performance issues on a large gallery, what do you think?

That's a good point. I can't think of a clean way to exclude it, either, but 🤞 the useMemo means that the logic only fires when an image is loaded or changes are made to it, so I don't think it should have much of an effect on larger galleries. I just had a go at inserting a gallery with 50 images and performance switching between image blocks appears to be unaffected in my manual testing:

Kapture 2021-12-13 at 10 46 24

Let me know if you can think of any other edges cases I should test, though!

@glendaviesnz
Copy link
Contributor

Let me know if you can think of any other edges cases I should test, though!

I can't think of any additional edge cases that we would need to check.

Copy link
Contributor

@glendaviesnz glendaviesnz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tested well for me on chrome, firefox and safari.

@ramonjd
Copy link
Member

ramonjd commented Dec 13, 2021

Also LGTM! 🙇

@noisysocks noisysocks merged commit 2201507 into trunk Dec 13, 2021
@noisysocks noisysocks deleted the fix/image-block-resizer-controls-availability-in-safari-after-switching-alignments branch December 13, 2021 00:35
@github-actions github-actions bot added this to the Gutenberg 12.2 milestone Dec 13, 2021
@noisysocks noisysocks removed the Backport to WP 6.7 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Dec 13, 2021
noisysocks pushed a commit that referenced this pull request Dec 13, 2021
…ween alignments (#37210)

* Image: Update naturalWidth and naturalHeight to pull from image ref instead of local component state

* Re-introduce onLoad setState behaviour to allow fallback while cropping images

* Remove useMemo

* Re-instate useMemo as removing it caused the resizer to disappear intermittently
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Image Affects the Image Block [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Image block resizer controls hidden in Safari after setting block alignment
6 participants