From d4b769211862cf946b29ad8ad29f46ffd7a11efb Mon Sep 17 00:00:00 2001 From: Enrique Piqueras Date: Mon, 20 Jan 2020 14:31:17 -0500 Subject: [PATCH 01/58] Use Select: Fix render queue. (#19286) * Use Select: Fix render queue issues. * Use Select: Make `isMounted` more informative. * Framework: Reset lockfile changes to dependencies Co-authored-by: Andrew Duthie --- package-lock.json | 8 ++++- packages/data/package.json | 3 +- .../data/src/components/use-select/index.js | 32 ++++++++++++------- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 27a092565cfea..2654a57aca02c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9692,7 +9692,8 @@ "lodash": "^4.17.15", "memize": "^1.0.5", "redux": "^4.0.0", - "turbo-combine-reducers": "^1.0.2" + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" } }, "@wordpress/data-controls": { @@ -36580,6 +36581,11 @@ "integrity": "sha512-C3nvxh0ZpaOxs9RCnWwAJ+7bJPwQI8LHF71LzbQ3BvzH5XkdtlkMadqElGevg5bYBDFip4sAnD4m06zAKebg1w==", "dev": true }, + "use-memo-one": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.1.tgz", + "integrity": "sha512-oFfsyun+bP7RX8X2AskHNTxu+R3QdE/RC5IefMbqptmACAA/gfol1KDD5KRzPsGMa62sWxGZw+Ui43u6x4ddoQ==" + }, "use-sidecar": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.0.2.tgz", diff --git a/packages/data/package.json b/packages/data/package.json index b246b0cf500b3..375c98db1d086 100644 --- a/packages/data/package.json +++ b/packages/data/package.json @@ -34,7 +34,8 @@ "lodash": "^4.17.15", "memize": "^1.0.5", "redux": "^4.0.0", - "turbo-combine-reducers": "^1.0.2" + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" }, "publishConfig": { "access": "public" diff --git a/packages/data/src/components/use-select/index.js b/packages/data/src/components/use-select/index.js index 1ea5619477b7b..97b8e207dd11d 100644 --- a/packages/data/src/components/use-select/index.js +++ b/packages/data/src/components/use-select/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { useMemoOne } from 'use-memo-one'; + /** * WordPress dependencies */ @@ -5,7 +10,6 @@ import { createQueue } from '@wordpress/priority-queue'; import { useLayoutEffect, useRef, - useMemo, useCallback, useEffect, useReducer, @@ -78,14 +82,17 @@ export default function useSelect( _mapSelect, deps ) { const mapSelect = useCallback( _mapSelect, deps ); const registry = useRegistry(); const isAsync = useAsyncMode(); - const queueContext = useMemo( () => ( { queue: true } ), [ registry ] ); + // React can sometimes clear the `useMemo` cache. + // We use the cache-stable `useMemoOne` to avoid + // losing queues. + const queueContext = useMemoOne( () => ( { queue: true } ), [ registry ] ); const [ , forceRender ] = useReducer( ( s ) => s + 1, 0 ); const latestMapSelect = useRef(); const latestIsAsync = useRef( isAsync ); const latestMapOutput = useRef(); const latestMapOutputError = useRef(); - const isMounted = useRef(); + const isMountedAndNotUnsubscribing = useRef(); let mapOutput; @@ -96,9 +103,7 @@ export default function useSelect( _mapSelect, deps ) { mapOutput = latestMapOutput.current; } } catch ( error ) { - let errorMessage = `An error occurred while running 'mapSelect': ${ - error.message - }`; + let errorMessage = `An error occurred while running 'mapSelect': ${ error.message }`; if ( latestMapOutputError.current ) { errorMessage += `\nThe error may be correlated with this previous error:\n`; @@ -111,18 +116,23 @@ export default function useSelect( _mapSelect, deps ) { useIsomorphicLayoutEffect( () => { latestMapSelect.current = mapSelect; + latestMapOutput.current = mapOutput; + latestMapOutputError.current = undefined; + isMountedAndNotUnsubscribing.current = true; + + // This has to run after the other ref updates + // to avoid using stale values in the flushed + // callbacks or potentially overwriting a + // changed `latestMapOutput.current`. if ( latestIsAsync.current !== isAsync ) { latestIsAsync.current = isAsync; renderQueue.flush( queueContext ); } - latestMapOutput.current = mapOutput; - latestMapOutputError.current = undefined; - isMounted.current = true; } ); useIsomorphicLayoutEffect( () => { const onStoreChange = () => { - if ( isMounted.current ) { + if ( isMountedAndNotUnsubscribing.current ) { try { const newMapOutput = latestMapSelect.current( registry.select, @@ -156,7 +166,7 @@ export default function useSelect( _mapSelect, deps ) { } ); return () => { - isMounted.current = false; + isMountedAndNotUnsubscribing.current = false; unsubscribe(); renderQueue.flush( queueContext ); }; From e654dce82f575b3f5971b22be8e34874d8ba2a9c Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Mon, 20 Jan 2020 15:09:16 -0500 Subject: [PATCH 02/58] Project Management: Run pull request automation on closed (#19742) --- .github/workflows/pull-request-automation.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pull-request-automation.yml b/.github/workflows/pull-request-automation.yml index 10277d5a3b45e..cb6bcb8f104c1 100644 --- a/.github/workflows/pull-request-automation.yml +++ b/.github/workflows/pull-request-automation.yml @@ -1,4 +1,6 @@ -on: pull_request +on: + pull_request: + types: [opened, closed] name: Pull request automation jobs: From 5ba397636d04ee3c0735475c4ce6ff50df882577 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 21 Jan 2020 10:04:31 +1300 Subject: [PATCH 03/58] Try/group block custom text color (#19181) * Add text color selector to group block to allow setting a text colour that applies to all children of the group to avoid having to set text colour on every individual child --- packages/block-library/src/group/block.json | 6 ++ packages/block-library/src/group/edit.js | 68 +++++++++------------ packages/block-library/src/group/index.js | 1 + packages/block-library/src/group/save.js | 5 +- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/packages/block-library/src/group/block.json b/packages/block-library/src/group/block.json index d8b417099f8fd..8883720bbc2aa 100644 --- a/packages/block-library/src/group/block.json +++ b/packages/block-library/src/group/block.json @@ -7,6 +7,12 @@ }, "customBackgroundColor": { "type": "string" + }, + "textColor": { + "type": "string" + }, + "customTextColor": { + "type": "string" } } } diff --git a/packages/block-library/src/group/edit.js b/packages/block-library/src/group/edit.js index 1e7445a20cc95..0a5ddae01ad05 100644 --- a/packages/block-library/src/group/edit.js +++ b/packages/block-library/src/group/edit.js @@ -1,62 +1,52 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - /** * WordPress dependencies */ import { withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; -import { __ } from '@wordpress/i18n'; import { - InspectorControls, InnerBlocks, - PanelColorSettings, - withColors, + __experimentalUseColors, } from '@wordpress/block-editor'; +import { useRef } from '@wordpress/element'; function GroupEdit( { - className, - setBackgroundColor, - backgroundColor, hasInnerBlocks, } ) { - const styles = { - backgroundColor: backgroundColor.color, - }; - - const classes = classnames( className, backgroundColor.class, { - 'has-background': !! backgroundColor.color, - } ); + const ref = useRef(); + const { + TextColor, + BackgroundColor, + InspectorControlsColorPanel, + } = __experimentalUseColors( + [ + { name: 'textColor', property: 'color' }, + { name: 'backgroundColor', className: 'has-background' }, + ], + { + contrastCheckers: { backgroundColor: true, textColor: true }, + colorDetector: { targetRef: ref }, + } + ); return ( <> - - - -
-
- -
-
+ { InspectorControlsColorPanel } + + +
+
+ +
+
+
+
); } export default compose( [ - withColors( 'backgroundColor' ), withSelect( ( select, { clientId } ) => { const { getBlock, diff --git a/packages/block-library/src/group/index.js b/packages/block-library/src/group/index.js index 956ded85aa22a..987b8d8235ade 100644 --- a/packages/block-library/src/group/index.js +++ b/packages/block-library/src/group/index.js @@ -25,6 +25,7 @@ export const settings = { example: { attributes: { customBackgroundColor: '#ffffff', + customTextColor: '#000000', }, innerBlocks: [ { diff --git a/packages/block-library/src/group/save.js b/packages/block-library/src/group/save.js index c2c56221766b1..f37cb085659f3 100644 --- a/packages/block-library/src/group/save.js +++ b/packages/block-library/src/group/save.js @@ -9,15 +9,18 @@ import classnames from 'classnames'; import { InnerBlocks, getColorClassName } from '@wordpress/block-editor'; export default function save( { attributes } ) { - const { backgroundColor, customBackgroundColor } = attributes; + const { backgroundColor, customBackgroundColor, textColor, customTextColor } = attributes; const backgroundClass = getColorClassName( 'background-color', backgroundColor ); + const textClass = getColorClassName( 'color', textColor ); const className = classnames( backgroundClass, { + 'has-text-color': textColor || customTextColor, 'has-background': backgroundColor || customBackgroundColor, } ); const styles = { backgroundColor: backgroundClass ? undefined : customBackgroundColor, + color: textClass ? undefined : customTextColor, }; return ( From 80824d7a131493ff867fac7d9cf2260b7611c9ef Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Mon, 20 Jan 2020 16:21:01 -0500 Subject: [PATCH 04/58] Block Editor: Handle LinkControl submission via form handler (#19651) * Block Editor: Handle LinkControl submission via form handler * E2E Tests: Unskip intermittent buttons test failure --- .../components/link-control/search-input.js | 21 +++++++++++-------- .../components/link-control/search-item.js | 1 - .../src/components/link-control/test/index.js | 4 ++++ .../blocks/__snapshots__/buttons.test.js.snap | 2 +- .../specs/editor/blocks/buttons.test.js | 4 +--- .../specs/editor/blocks/navigation.test.js | 10 +++------ 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/block-editor/src/components/link-control/search-input.js b/packages/block-editor/src/components/link-control/search-input.js index 0d72bc0444fad..4bda15f1f1eb7 100644 --- a/packages/block-editor/src/components/link-control/search-input.js +++ b/packages/block-editor/src/components/link-control/search-input.js @@ -1,7 +1,7 @@ - /** * WordPress dependencies */ +import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { Button } from '@wordpress/components'; import { LEFT, @@ -45,21 +45,24 @@ const LinkControlSearchInput = ( { onReset, showInitialSuggestions, } ) => { + const [ selectedSuggestion, setSelectedSuggestion ] = useState(); + const selectItemHandler = ( selection, suggestion ) => { onChange( selection ); - - if ( suggestion ) { - onSelect( suggestion ); - } + setSelectedSuggestion( suggestion ); }; - const stopFormEventsPropagation = ( event ) => { + function selectSuggestionOrCurrentInputValue( event ) { + // Avoid default forms behavior, since it's being handled custom here. event.preventDefault(); - event.stopPropagation(); - }; + + // Interpret the selected value as either the selected suggestion, if + // exists, or otherwise the current input value as entered. + onSelect( selectedSuggestion || { url: value } ); + } return ( -
+ { return (