From 6b878d7dcd3f6b7b8401fd2a89b4ee2b3025031e Mon Sep 17 00:00:00 2001
From: Ella van Durpe <ella@vandurpe.com>
Date: Thu, 2 Jan 2020 19:04:01 +0100
Subject: [PATCH 1/2] Remove unused is-hovered class

---
 .../src/components/block-list/block.js        | 69 +------------------
 1 file changed, 1 insertion(+), 68 deletions(-)

diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js
index 54c224771cab4..ebe849dddc313 100644
--- a/packages/block-editor/src/components/block-list/block.js
+++ b/packages/block-editor/src/components/block-list/block.js
@@ -125,59 +125,6 @@ function BlockListBlock( {
 
 	const breadcrumb = useRef();
 
-	// Keep track of touchstart to disable hover on iOS
-	const hadTouchStart = useRef( false );
-	const onTouchStart = () => {
-		hadTouchStart.current = true;
-	};
-	const onTouchStop = () => {
-		// Clear touchstart detection
-		// Browser will try to emulate mouse events also see https://www.html5rocks.com/en/mobile/touchandmouse/
-		hadTouchStart.current = false;
-	};
-
-	// Handling isHovered
-	const [ isBlockHovered, setBlockHoveredState ] = useState( false );
-
-	/**
-	 * Sets the block state as unhovered if currently hovering. There are cases
-	 * where mouseleave may occur but the block is not hovered (multi-select),
-	 * so to avoid unnecesary renders, the state is only set if hovered.
-	 */
-	const hideHoverEffects = () => {
-		if ( isBlockHovered ) {
-			setBlockHoveredState( false );
-		}
-	};
-	/**
-	 * A mouseover event handler to apply hover effect when a pointer device is
-	 * placed within the bounds of the block. The mouseover event is preferred
-	 * over mouseenter because it may be the case that a previous mouseenter
-	 * event was blocked from being handled by a IgnoreNestedEvents component,
-	 * therefore transitioning out of a nested block to the bounds of the block
-	 * would otherwise not trigger a hover effect.
-	 *
-	 * @see https://developer.mozilla.org/en-US/docs/Web/Events/mouseenter
-	 */
-	const maybeHover = () => {
-		if (
-			isBlockHovered ||
-			isPartOfMultiSelection ||
-			isSelected ||
-			hadTouchStart.current
-		) {
-			return;
-		}
-		setBlockHoveredState( true );
-	};
-
-	// Set hover to false once we start typing or select the block.
-	useEffect( () => {
-		if ( isTypingWithinBlock || isSelected ) {
-			hideHoverEffects();
-		}
-	} );
-
 	// Handling the error state
 	const [ hasError, setErrorState ] = useState( false );
 	const onBlockError = () => setErrorState( true );
@@ -389,8 +336,6 @@ function BlockListBlock( {
 		if ( isSelected && ( buttons || which ) === 1 ) {
 			onSelectionStart( clientId );
 		}
-
-		hideHoverEffects();
 	};
 
 	const selectOnOpen = ( open ) => {
@@ -413,7 +358,6 @@ function BlockListBlock( {
 	);
 
 	// Rendering the output
-	const isHovered = isBlockHovered && ! isPartOfMultiSelection;
 	const blockType = getBlockType( name );
 	// translators: %s: Type of block (i.e. Text, Image etc)
 	const blockLabel = sprintf( __( 'Block: %s' ), blockType.title );
@@ -424,17 +368,12 @@ function BlockListBlock( {
 
 	// If the block is selected and we're typing the block should not appear.
 	// Empty paragraph blocks should always show up as unselected.
-	const showEmptyBlockSideInserter = ! isNavigationMode && ( isSelected || isHovered || isLast ) && isEmptyDefaultBlock && isValid;
+	const showEmptyBlockSideInserter = ! isNavigationMode && ( isSelected || isLast ) && isEmptyDefaultBlock && isValid;
 	const shouldAppearSelected =
 		! isFocusMode &&
 		! showEmptyBlockSideInserter &&
 		isSelected &&
 		! isTypingWithinBlock;
-	const shouldAppearHovered =
-		! isFocusMode &&
-		! hasFixedToolbar &&
-		isHovered &&
-		! isEmptyDefaultBlock;
 	const shouldShowBreadcrumb = isNavigationMode && isSelected;
 	const shouldShowContextualToolbar =
 		! isNavigationMode &&
@@ -467,7 +406,6 @@ function BlockListBlock( {
 			'is-selected': shouldAppearSelected && hasSelectedUI,
 			'is-navigate-mode': isNavigationMode,
 			'is-multi-selected': isMultiSelected,
-			'is-hovered': shouldAppearHovered,
 			'is-reusable': isReusableBlock( blockType ),
 			'is-dragging': isDragging,
 			'is-typing': isTypingWithinBlock,
@@ -534,14 +472,9 @@ function BlockListBlock( {
 		<IgnoreNestedEvents
 			id={ blockElementId }
 			ref={ wrapper }
-			onMouseOver={ maybeHover }
-			onMouseOverHandled={ hideHoverEffects }
-			onMouseLeave={ hideHoverEffects }
 			className={ wrapperClassName }
 			data-type={ name }
-			onTouchStart={ onTouchStart }
 			onFocus={ onFocus }
-			onClick={ onTouchStop }
 			onKeyDown={ onKeyDown }
 			tabIndex="0"
 			aria-label={ blockLabel }

From 94cbec6ce0d06a3bbf8dbc855a99e6f60c3fa5c1 Mon Sep 17 00:00:00 2001
From: Ella van Durpe <ella@vandurpe.com>
Date: Thu, 2 Jan 2020 23:27:32 +0100
Subject: [PATCH 2/2] Revert 0d0c8e0d55849529227df3540ad35ff3edf5be5b

---
 .../components/ignore-nested-events/index.js  | 27 +++++-----------
 .../ignore-nested-events/test/index.js        | 31 ++++---------------
 2 files changed, 14 insertions(+), 44 deletions(-)

diff --git a/packages/block-editor/src/components/ignore-nested-events/index.js b/packages/block-editor/src/components/ignore-nested-events/index.js
index 92bbe5ed44c63..c419d282a7602 100644
--- a/packages/block-editor/src/components/ignore-nested-events/index.js
+++ b/packages/block-editor/src/components/ignore-nested-events/index.js
@@ -41,7 +41,10 @@ export class IgnoreNestedEvents extends Component {
 	 * @param {Event} event Event object.
 	 */
 	proxyEvent( event ) {
-		const isHandled = !! event.nativeEvent._blockHandled;
+		// Skip if already handled (i.e. assume nested block)
+		if ( event.nativeEvent._blockHandled ) {
+			return;
+		}
 
 		// Assign into the native event, since React will reuse their synthetic
 		// event objects and this property assignment could otherwise leak.
@@ -50,13 +53,7 @@ export class IgnoreNestedEvents extends Component {
 		event.nativeEvent._blockHandled = true;
 
 		// Invoke original prop handler
-		let propKey = this.eventMap[ event.type ];
-
-		// If already handled (i.e. assume nested block), only invoke a
-		// corresponding "Handled"-suffixed prop callback.
-		if ( isHandled ) {
-			propKey += 'Handled';
-		}
+		const propKey = this.eventMap[ event.type ];
 
 		if ( this.props[ propKey ] ) {
 			this.props[ propKey ]( event );
@@ -71,24 +68,16 @@ export class IgnoreNestedEvents extends Component {
 			...Object.keys( props ),
 		], ( result, key ) => {
 			// Try to match prop key as event handler
-			const match = key.match( /^on([A-Z][a-zA-Z]+?)(Handled)?$/ );
+			const match = key.match( /^on([A-Z][a-zA-Z]+)$/ );
 			if ( match ) {
-				const isHandledProp = !! match[ 2 ];
-				if ( isHandledProp ) {
-					// Avoid assigning through the invalid prop key. This
-					// assumes mutation of shallow clone by above spread.
-					delete props[ key ];
-				}
-
 				// Re-map the prop to the local proxy handler to check whether
 				// the event has already been handled.
-				const proxiedPropName = 'on' + match[ 1 ];
-				result[ proxiedPropName ] = this.proxyEvent;
+				result[ key ] = this.proxyEvent;
 
 				// Assign event -> propName into an instance variable, so as to
 				// avoid re-renders which could be incurred either by setState
 				// or in mapping values to a newly created function.
-				this.eventMap[ match[ 1 ].toLowerCase() ] = proxiedPropName;
+				this.eventMap[ match[ 1 ].toLowerCase() ] = key;
 			}
 
 			return result;
diff --git a/packages/block-editor/src/components/ignore-nested-events/test/index.js b/packages/block-editor/src/components/ignore-nested-events/test/index.js
index 56ded3e4df340..367570c89646e 100644
--- a/packages/block-editor/src/components/ignore-nested-events/test/index.js
+++ b/packages/block-editor/src/components/ignore-nested-events/test/index.js
@@ -1,7 +1,7 @@
 /**
  * External dependencies
  */
-import { mount } from 'enzyme';
+import { shallow } from 'enzyme';
 
 /**
  * Internal dependencies
@@ -10,24 +10,24 @@ import { IgnoreNestedEvents } from '../';
 
 describe( 'IgnoreNestedEvents', () => {
 	it( 'passes props to its rendered div', () => {
-		const wrapper = mount(
+		const wrapper = shallow(
 			<IgnoreNestedEvents className="foo" />
 		);
 
-		expect( wrapper.find( 'div' ) ).toHaveLength( 1 );
+		expect( wrapper.type() ).toBe( 'div' );
 		expect( wrapper.prop( 'className' ) ).toBe( 'foo' );
 	} );
 
 	it( 'stops propagation of events to ancestor IgnoreNestedEvents', () => {
 		const spyOuter = jest.fn();
 		const spyInner = jest.fn();
-		const wrapper = mount(
+		const wrapper = shallow(
 			<IgnoreNestedEvents onClick={ spyOuter }>
 				<IgnoreNestedEvents onClick={ spyInner } />
 			</IgnoreNestedEvents>
 		);
 
-		wrapper.find( 'div' ).last().simulate( 'click' );
+		wrapper.childAt( 0 ).simulate( 'click' );
 
 		expect( spyInner ).toHaveBeenCalled();
 		expect( spyOuter ).not.toHaveBeenCalled();
@@ -36,7 +36,7 @@ describe( 'IgnoreNestedEvents', () => {
 	it( 'stops propagation of child handled events', () => {
 		const spyOuter = jest.fn();
 		const spyInner = jest.fn();
-		const wrapper = mount(
+		const wrapper = shallow(
 			<IgnoreNestedEvents onClick={ spyOuter }>
 				<IgnoreNestedEvents childHandledEvents={ [ 'onClick' ] }>
 					<div />
@@ -51,23 +51,4 @@ describe( 'IgnoreNestedEvents', () => {
 		expect( spyInner ).not.toHaveBeenCalled();
 		expect( spyOuter ).not.toHaveBeenCalled();
 	} );
-
-	it( 'invokes callback of Handled-suffixed prop if handled', () => {
-		const spyOuter = jest.fn();
-		const spyInner = jest.fn();
-		const wrapper = mount(
-			<IgnoreNestedEvents onClickHandled={ spyOuter }>
-				<IgnoreNestedEvents childHandledEvents={ [ 'onClick' ] }>
-					<div />
-					<IgnoreNestedEvents onClick={ spyInner } />
-				</IgnoreNestedEvents>
-			</IgnoreNestedEvents>
-		);
-
-		const div = wrapper.childAt( 0 ).childAt( 0 );
-		div.simulate( 'click' );
-
-		expect( spyInner ).not.toHaveBeenCalled();
-		expect( spyOuter ).toHaveBeenCalled();
-	} );
 } );