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

Editor: Fix block highlight rendering after block is moved #23425

Merged
merged 13 commits into from
Jul 20, 2020

Conversation

ItsJonQ
Copy link

@ItsJonQ ItsJonQ commented Jun 24, 2020

Screen Capture on 2020-06-24 at 11-04-51

This update resolves the highlight rendering for blocks after they've been dragged and moved. The GIF demo above shows the highlight correctly disappearing after a block is moved, and another block is selected.

The solution involved removing the requestAnimationFrame wrapper that controlled the highlight state. It seemed like this was previously added to help with Toolbar rendering. I've done a bunch on my end. There does not appear to be any behavioural issues (or console errors) from removing this rAF wrapper.

How has this been tested?

  • Run npm run dev
  • Add a block
  • Add another block
  • Drag the first block to re-order it. Highlight should appear.
  • Drop the block
  • Click on another block
  • The highlight should disappear.

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • 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.

Resolves: #23413

@ItsJonQ ItsJonQ added [Type] Bug An existing feature does not function as intended [Package] Block editor /packages/block-editor labels Jun 24, 2020
@ItsJonQ ItsJonQ requested a review from ellatrix June 24, 2020 17:06
@ItsJonQ ItsJonQ self-assigned this Jun 24, 2020
@github-actions
Copy link

github-actions bot commented Jun 24, 2020

Size Change: +728 B (0%)

Total Size: 1.15 MB

Filename Size Change
build/block-editor/index.min.js 125 kB +611 B (0%)
build/block-library/index.min.js 132 kB -78 B (0%)
build/components/index.min.js 200 kB +8 B (0%)
build/edit-site/index.min.js 16.8 kB +9 B (0%)
build/edit-site/style-rtl.css 3.06 kB +21 B (0%)
build/edit-site/style.css 3.06 kB +22 B (0%)
build/editor/index.min.js 45.3 kB +135 B (0%)
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.min.js 1.14 kB 0 B
build/annotations/index.min.js 3.67 kB 0 B
build/api-fetch/index.min.js 3.43 kB 0 B
build/autop/index.min.js 2.82 kB 0 B
build/blob/index.min.js 620 B 0 B
build/block-directory/index.min.js 7.63 kB 0 B
build/block-directory/style-rtl.css 944 B 0 B
build/block-directory/style.css 945 B 0 B
build/block-editor/style-rtl.css 10.8 kB 0 B
build/block-editor/style.css 10.8 kB 0 B
build/block-library/editor-rtl.css 7.58 kB 0 B
build/block-library/editor.css 7.57 kB 0 B
build/block-library/style-rtl.css 7.77 kB 0 B
build/block-library/style.css 7.77 kB 0 B
build/block-library/theme-rtl.css 728 B 0 B
build/block-library/theme.css 729 B 0 B
build/block-serialization-default-parser/index.min.js 1.88 kB 0 B
build/block-serialization-spec-parser/index.min.js 3.1 kB 0 B
build/blocks/index.min.js 48.3 kB 0 B
build/components/style-rtl.css 15.6 kB 0 B
build/components/style.css 15.6 kB 0 B
build/compose/index.min.js 9.67 kB 0 B
build/core-data/index.min.js 11.5 kB 0 B
build/data-controls/index.min.js 1.29 kB 0 B
build/data/index.min.js 8.45 kB 0 B
build/date/index.min.js 5.38 kB 0 B
build/deprecated/index.min.js 772 B 0 B
build/dom-ready/index.min.js 568 B 0 B
build/dom/index.min.js 3.23 kB 0 B
build/edit-navigation/index.min.js 10.8 kB 0 B
build/edit-navigation/style-rtl.css 1.08 kB 0 B
build/edit-navigation/style.css 1.08 kB 0 B
build/edit-post/index.min.js 304 kB 0 B
build/edit-post/style-rtl.css 5.61 kB 0 B
build/edit-post/style.css 5.61 kB 0 B
build/edit-widgets/index.min.js 9.35 kB 0 B
build/edit-widgets/style-rtl.css 2.45 kB 0 B
build/edit-widgets/style.css 2.45 kB 0 B
build/editor/editor-styles-rtl.css 537 B 0 B
build/editor/editor-styles.css 539 B 0 B
build/editor/style-rtl.css 3.78 kB 0 B
build/editor/style.css 3.78 kB 0 B
build/element/index.min.js 4.65 kB 0 B
build/escape-html/index.min.js 733 B 0 B
build/format-library/index.min.js 7.72 kB 0 B
build/format-library/style-rtl.css 547 B 0 B
build/format-library/style.css 548 B 0 B
build/hooks/index.min.js 2.13 kB 0 B
build/html-entities/index.min.js 621 B 0 B
build/i18n/index.min.js 3.56 kB 0 B
build/is-shallow-equal/index.min.js 711 B 0 B
build/keyboard-shortcuts/index.min.js 2.51 kB 0 B
build/keycodes/index.min.js 1.94 kB 0 B
build/list-reusable-blocks/index.min.js 3.12 kB 0 B
build/list-reusable-blocks/style-rtl.css 476 B 0 B
build/list-reusable-blocks/style.css 476 B 0 B
build/media-utils/index.min.js 5.32 kB 0 B
build/notices/index.min.js 1.79 kB 0 B
build/nux/index.min.js 3.4 kB 0 B
build/nux/style-rtl.css 671 B 0 B
build/nux/style.css 668 B 0 B
build/plugins/index.min.js 2.56 kB 0 B
build/primitives/index.min.js 1.4 kB 0 B
build/priority-queue/index.min.js 789 B 0 B
build/redux-routine/index.min.js 2.85 kB 0 B
build/rich-text/index.min.js 13.9 kB 0 B
build/server-side-render/index.min.js 2.71 kB 0 B
build/shortcode/index.min.js 1.7 kB 0 B
build/token-list/index.min.js 1.27 kB 0 B
build/url/index.min.js 4.06 kB 0 B
build/viewport/index.min.js 1.85 kB 0 B
build/warning/index.min.js 1.14 kB 0 B
build/wordcount/index.min.js 1.17 kB 0 B

compressed-size-action

@youknowriad
Copy link
Contributor

youknowriad commented Jun 24, 2020

Is it intended that the block stays highlighted after I drop it? Seems a bit weird to me personally, I thought the block highlighting was only needed when we "hover" the switcher.

Copy link
Contributor

@youknowriad youknowriad left a comment

Choose a reason for hiding this comment

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

this is better than master, but the fadeout animation when I select another block after move feels a bit long. I'd personally prefer to not highlight the block entirely after drag and drop but maybe that's intended.

@ItsJonQ
Copy link
Author

ItsJonQ commented Jun 24, 2020

Is it intended that the block stays highlighted after I drop it

@youknowriad It's highlight as long as the BlockSwitcher / Move arrows are hovered or focused. At least, that's how the logic works right now :)

@youknowriad
Copy link
Contributor

It's highlight as long as the BlockSwitcher / Move arrows are hovered or focused

Makes sense I guess after drag and drop the switcher/movers are focused. maybe there are better heuristics but definitely not the PR for it.

@ItsJonQ
Copy link
Author

ItsJonQ commented Jun 24, 2020

Travis was complaining about snapshots 🤔 . I'm not sure what command I need to run to regenerate these (correctly).

I tried npm run fixtures:regenerate. It didn't seem to do anything

@ItsJonQ
Copy link
Author

ItsJonQ commented Jun 30, 2020

Hmm! Not sure how to fix these E2E snapshot test failures 🤔

@ItsJonQ
Copy link
Author

ItsJonQ commented Jun 30, 2020

👋 I think I need some help with these E2E tests.

For example, the Admin 1 test:

GH actions is saying:

FAIL packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js (19.371s)
  ● Navigating the block hierarchy › should navigate using the block hierarchy dropdown menu

    expect(received).toMatchSnapshot()

    Snapshot name: `Navigating the block hierarchy should navigate using the block hierarchy dropdown menu 1`

    - Snapshot  - 3
    + Received  + 1

    @@ -8,10 +8,8 @@
      <!-- wp:column -->
      <div class="wp-block-column"></div>
      <!-- /wp:column -->

      <!-- wp:column -->
    - <div class="wp-block-column"><!-- wp:paragraph -->
    - <p>Third column</p>
    - <!-- /wp:paragraph --></div>
    + <div class="wp-block-column"></div>
      <!-- /wp:column --></div>
      <!-- /wp:columns -->


      71 | 		await page.keyboard.type( 'Third column' );
      72 | 
    > 73 | 		expect( await getEditedPostContent() ).toMatchSnapshot();
         | 		                                       ^
      74 | 	} );
      75 | 
      76 | 	it( 'should navigate block hierarchy using only the keyboard', async () => {

      at Object.<anonymous> (specs/editor/various/block-hierarchy-navigation.test.js:73:42)
          at runMicrotasks (<anonymous>)

 › 1 snapshot failed.

However, then I run it locally:

npm run test-e2e -- packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js

It seems okay:

 PASS  packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js (44.841s)
  Navigating the block hierarchy
    ✓ should navigate using the block hierarchy dropdown menu (11585ms)
    ✓ should navigate block hierarchy using only the keyboard (9260ms)
    ✓ should appear and function even without nested blocks (8007ms)
    ✓ should select the wrapper div for a group  (8129ms)

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   4 passed, 4 total
Time:        44.969s

@ItsJonQ
Copy link
Author

ItsJonQ commented Jun 30, 2020

Hmm. I'm a bit stuck on this E2E test.

	it( 'should undo asterisk transform with backspace after mouse move', async () => {
		await clickBlockAppender();
		await page.keyboard.type( '* ' );
		await page.mouse.move( 0, 0, { steps: 10 } );
		await page.keyboard.press( 'Backspace' );

		expect( await getEditedPostContent() ).toMatchSnapshot();
	} );

It says that the snapshot doesn't match.

In doing the interaction in real life (and also observing Chromium), it seems to work okay.
The test seems to not like this part, specifically, the return of the useEffect hook:

	useEffect( () => {
		// On mount, we make sure to cancel any pending animation frame request
		// that hasn't been completed yet. Components like NavigableToolbar may
		// mount and unmount quickly.
		if ( requestAnimationFrameId ) {
			cancelAnimationFrame( requestAnimationFrameId );
		}

		return () => {
			// Sequences state change to enable editor updates (e.g. cursor
			// position) to render correctly.
			requestAnimationFrameId = requestAnimationFrame( () => {
				updateBlockHighlight( false );
			} );
		};
	}, [ updateBlockHighlight ] );

I've tried a bunch of things, including moving the functionality to the useShowMoversGestures instead. Doing various this with the requestAnimationFrameId. No luck so far.

@youknowriad youknowriad force-pushed the fix/toolbar-block-highlight-rendering branch 3 times, most recently from e07f460 to 239e07a Compare July 1, 2020 10:18
@youknowriad
Copy link
Contributor

I tried playing with the tests, added some timeouts... but unfortunately, I didn't learn a lot.
Since the snapshot suggests that there's no content, I think maybe the issue is that the "backspace" remove the block entirely.

I think it's a race condition between the "backspace to remove empty lists" and "backspace to work as undo after a transform". cc @ellatrix

I noticed other bugs (on master too) that could be related: If you have "two empty lists" and click backspace when the last one is focused, both are removed.

@ellatrix
Copy link
Member

ellatrix commented Jul 2, 2020

@ItsJonQ This doesn't fix the issue for me. If I select a block, press up/down, then select another block, and you'll see that the highlight is still on the previous block.

@ItsJonQ
Copy link
Author

ItsJonQ commented Jul 6, 2020

@youknowriad Thank you so much for looking into the E2E for me 🙏

@ellatrix Thank you for extra context. Lemme see what I can do. Maybe it'll fix the E2E complaints 🤷‍♀️

@ItsJonQ
Copy link
Author

ItsJonQ commented Jul 6, 2020

@ellatrix Hmm! I'm not noticing the bug on my end - I'd love to reproduce it though!

I recorded a screencast of me walking through the steps:
https://d.pr/v/xzLOgx

  • Click up
  • Click Down
  • Click another block
  • (Highlight disappears)

Let me know if I'm missing something! 🙏

@ItsJonQ
Copy link
Author

ItsJonQ commented Jul 6, 2020

Still figuring out what's happening with this test. I tried something that may point to regarding the delete action - something that @youknowriad touched upon.

If I remove my custom toggleBlockHighlight hook and add a basic useEffect to the BlockToolbar, it still breaks in E2E:

// packages/block-editor/src/components/block-toolbar/index.js

const { toggleBlockHighlight } = useDispatch( 'core/block-editor' );
useEffect( () => {
    return () => {
        toggleBlockHighlight( blockClientId, false );
    };
}, [ blockClientId ] );

// const toggleBlockHighlight = useToggleBlockHighlight( blockClientId );

Test Failure:

  ● List › should undo asterisk transform with backspace after mouse move

    expect(received).toMatchSnapshot()

    Snapshot name: `List should undo asterisk transform with backspace after mouse move 1`

    - Snapshot  - 3
    + Received  + 0

    - <!-- wp:paragraph -->
    - <p>* </p>
    - <!-- /wp:paragraph -->

@ItsJonQ
Copy link
Author

ItsJonQ commented Jul 7, 2020

Revisited this one. Still unsure what's up 🤔

@ellatrix
Copy link
Member

@ItsJonQ You're right it does fix the issue.

@@ -195,14 +195,15 @@ export function useToggleBlockHighlight( clientId ) {
if ( requestAnimationFrameId ) {
cancelAnimationFrame( requestAnimationFrameId );
}

return () => {
// Sequences state change to enable editor updates (e.g. cursor
// position) to render correctly.
requestAnimationFrameId = requestAnimationFrame( () => {
Copy link
Member

Choose a reason for hiding this comment

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

Where is this cancelled?

Copy link
Author

@ItsJonQ ItsJonQ Jul 16, 2020

Choose a reason for hiding this comment

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

@ellatrix I paused on this for now, as regardless of whether I use RAF or not, a couple of particular E2E tests keep failing. They fail when they attempt to use the toggleBlockHighlight action in a useCallback return.

Edit: Nevermind. I think we may need RAF

@ellatrix ellatrix 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 Jul 16, 2020
@ItsJonQ
Copy link
Author

ItsJonQ commented Jul 16, 2020

@ellatrix Haii! @youknowriad and I hopped on a call to debug this. I think we discovered the issue.

The useIsAccessibleToolbar hook within packages/block-editor/src/components/navigable-toolbar/index.js appears to be causing the inner <Toolbar /> to be mounting twice on render. The side-effect of this is that it causes the highlight useEffect to be unreliable.

The reason why it's double mounting is because it starts with an accessibility state of false, which is flipped to true after a useLayoutEffect check.

To make the tests happy, we opted to use a default accessibility state of true, to avoid to double render. This appears to make the (previously failing) E2E test happy. There is no different we can see or feel when using the editor in real life.

cc'ing @diegohaz . Haii! It would be great to get your quick thoughts on the solution we went with. I know you've done extensive and wonderful work on the Toolbar 🙏

Thank you all ❤️

youknowriad referenced this pull request Jul 16, 2020
* Block Editor: Simplify Selection Reducer

* Test selectionStart and selectionEnd reducers instead of internal selection reducer

* Add comment when reducer resets state by default
@diegohaz
Copy link
Member

@ItsJonQ I agree with defaulting the accessible state of the navigable toolbar to true. It was set to false just because, when it was implemented, most of the toolbars were using the old behavior. 👍

* is true, as it seems to be the most common case.
*
* Transitioning from an (initial) false to true state causes the
* <Toolbar /> component to mount twice, which is causing undesired
Copy link
Member

Choose a reason for hiding this comment

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

Mount or render?

Copy link
Contributor

Choose a reason for hiding this comment

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

mount :)

Copy link
Member

Choose a reason for hiding this comment

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

I wonder if this is still needed after the adjustments I made?

Copy link
Author

Choose a reason for hiding this comment

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

I think so. From our debugging, the Toolbar was double mounting regardless of the toggleBlockHighlight dispatch action.

} );
};
}, [] );
return () => toggleBlockHighlight( clientId, false );
Copy link
Member

Choose a reason for hiding this comment

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

Why are we toggling block highlight in an effect rather than at the reducer level? For a SELECT_BLOCK action etc., the highlight state should change immediately. Cc @youknowriad.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that if we can do it automatically on the reducer, it's better and avoid an extra rerenders for all components.

@ItsJonQ
Copy link
Author

ItsJonQ commented Jul 20, 2020

OMG @ellatrix ! That did it! You are amazing 🙏 . Thank you so much!!!

@ItsJonQ
Copy link
Author

ItsJonQ commented Jul 20, 2020

I retested it locally, and it looks like it's working for me!

With things working and E2E happy, I'll merge this up!

Thank you @ellatrix , @youknowriad , and @diegohaz for all of your help!!!! <3

@ItsJonQ ItsJonQ merged commit f2c5268 into master Jul 20, 2020
@ItsJonQ ItsJonQ deleted the fix/toolbar-block-highlight-rendering branch July 20, 2020 14:16
@github-actions github-actions bot added this to the Gutenberg 8.6 milestone Jul 20, 2020
@ellatrix ellatrix mentioned this pull request Jul 20, 2020
6 tasks
ellatrix added a commit that referenced this pull request Jul 20, 2020
* Editor: Fix block outline rendering after block is moved

* Fix rendering for tests. Reduce Timeout from 250 -> 200 to improve UX.

* Fix rAF call with toggling highlight

* Resolve the E2E test issue, which appears to be caused by a double-mounting Toolbar

* Use reducer

Co-authored-by: Ella van Durpe <ella@vandurpe.com>
@youknowriad youknowriad 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 Jul 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Block editor /packages/block-editor [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Highlight remains after selecting other block
4 participants