From 61d742e39b0f066e63c9e796aa8901ded949753a Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Fri, 25 Jun 2021 16:31:47 +0300 Subject: [PATCH 01/64] [Block Library - Post Terms]: Fix handling for low privileged users (#32947) * [Block Library - Post Terms]: Fix handling for low privileged users * use `apiFetch` * revert changes that have been applied to trunk * revert to use context 'view' --- packages/block-library/src/post-terms/edit.js | 50 +++++++---------- .../src/post-terms/use-post-terms.js | 38 +++++++++++++ .../src/post-terms/use-term-links.js | 55 ------------------- 3 files changed, 59 insertions(+), 84 deletions(-) create mode 100644 packages/block-library/src/post-terms/use-post-terms.js delete mode 100644 packages/block-library/src/post-terms/use-term-links.js diff --git a/packages/block-library/src/post-terms/edit.js b/packages/block-library/src/post-terms/edit.js index 2e950479a9bcf3..da8b2004aa23e2 100644 --- a/packages/block-library/src/post-terms/edit.js +++ b/packages/block-library/src/post-terms/edit.js @@ -2,7 +2,6 @@ * External dependencies */ import classnames from 'classnames'; -import { find } from 'lodash'; /** * WordPress dependencies @@ -21,7 +20,7 @@ import { store as coreStore } from '@wordpress/core-data'; /** * Internal dependencies */ -import useTermLinks from './use-term-links'; +import usePostTerms from './use-post-terms'; export default function PostTermsEdit( { attributes, @@ -34,28 +33,18 @@ export default function PostTermsEdit( { const selectedTerm = useSelect( ( select ) => { if ( ! term ) return {}; - const taxonomies = select( coreStore ).getTaxonomies( { - per_page: -1, - } ); - return ( - find( - taxonomies, - ( taxonomy ) => - taxonomy.slug === term && taxonomy.visibility.show_ui - ) || {} - ); + const { getTaxonomy } = select( coreStore ); + const taxonomy = getTaxonomy( term ); + return taxonomy?.visibility?.show_ui ? taxonomy : {}; }, [ term ] ); - - const { termLinks, isLoadingTermLinks } = useTermLinks( { + const { postTerms, hasPostTerms, isLoading } = usePostTerms( { postId, postType, term: selectedTerm, } ); - const hasPost = postId && postType; - const hasTermLinks = termLinks && termLinks.length > 0; const blockProps = useBlockProps( { className: classnames( { [ `has-text-align-${ textAlign }` ]: textAlign, @@ -90,19 +79,22 @@ export default function PostTermsEdit( { />
- { isLoadingTermLinks && } - - { hasTermLinks && - ! isLoadingTermLinks && - termLinks.reduce( ( prev, curr ) => [ - prev, - ' | ', - curr, - ] ) } - - { ! isLoadingTermLinks && - ! hasTermLinks && - // eslint-disable-next-line camelcase + { isLoading && } + { ! isLoading && + hasPostTerms && + postTerms + .map( ( postTerm ) => ( + event.preventDefault() } + > + { postTerm.name } + + ) ) + .reduce( ( prev, curr ) => [ prev, ' | ', curr ] ) } + { ! isLoading && + ! hasPostTerms && ( selectedTerm?.labels?.no_terms || __( 'Term items not found.' ) ) }
diff --git a/packages/block-library/src/post-terms/use-post-terms.js b/packages/block-library/src/post-terms/use-post-terms.js new file mode 100644 index 00000000000000..facfffa21117f8 --- /dev/null +++ b/packages/block-library/src/post-terms/use-post-terms.js @@ -0,0 +1,38 @@ +/** + * WordPress dependencies + */ +import { useEntityProp, store as coreStore } from '@wordpress/core-data'; +import { useSelect } from '@wordpress/data'; + +export default function usePostTerms( { postId, postType, term } ) { + const { rest_base: restBase, slug } = term; + const [ termIds ] = useEntityProp( 'postType', postType, restBase, postId ); + return useSelect( + ( select ) => { + if ( ! termIds ) { + // Waiting for post terms to be fetched. + return { isLoading: true }; + } + if ( ! termIds.length ) { + return { isLoading: false }; + } + const { getEntityRecords, isResolving } = select( coreStore ); + const taxonomyArgs = [ + 'taxonomy', + slug, + { + include: termIds, + context: 'view', + }, + ]; + const terms = getEntityRecords( ...taxonomyArgs ); + const _isLoading = isResolving( 'getEntityRecords', taxonomyArgs ); + return { + postTerms: terms, + isLoading: _isLoading, + hasPostTerms: !! terms?.length, + }; + }, + [ termIds ] + ); +} diff --git a/packages/block-library/src/post-terms/use-term-links.js b/packages/block-library/src/post-terms/use-term-links.js deleted file mode 100644 index 387e8cf92d3c4d..00000000000000 --- a/packages/block-library/src/post-terms/use-term-links.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * External dependencies - */ -import { map } from 'lodash'; - -/** - * WordPress dependencies - */ -import { useEntityProp, store as coreStore } from '@wordpress/core-data'; -import { useSelect } from '@wordpress/data'; - -export default function useTermLinks( { postId, postType, term } ) { - const { rest_base: restBase, slug } = term; - - const [ termItems ] = useEntityProp( - 'postType', - postType, - restBase, - postId - ); - - const { termLinks, isLoadingTermLinks } = useSelect( - ( select ) => { - const { getEntityRecord } = select( coreStore ); - - let loaded = true; - - const links = map( termItems, ( itemId ) => { - const item = getEntityRecord( 'taxonomy', slug, itemId ); - - if ( ! item ) { - return ( loaded = false ); - } - - return ( - event.preventDefault() } - > - { item.name } - - ); - } ); - - return { - termLinks: links, - isLoadingTermLinks: ! loaded, - }; - }, - [ termItems ] - ); - - return { termLinks, isLoadingTermLinks }; -} From 152fa0df3f7ea23d912bb89a25997d62614f2573 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Fri, 25 Jun 2021 16:53:15 +0300 Subject: [PATCH 02/64] [Block Library - Categories]: Fix crash when trying to access categories on insertion (#32989) --- packages/block-library/src/categories/edit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/categories/edit.js b/packages/block-library/src/categories/edit.js index 08be1b3a7053aa..5c8aad58698cd8 100644 --- a/packages/block-library/src/categories/edit.js +++ b/packages/block-library/src/categories/edit.js @@ -150,7 +150,7 @@ export default function CategoriesEdit( { ) } - { ! isRequesting && categories.length === 0 && ( + { ! isRequesting && categories?.length === 0 && (

{ __( 'Your site does not have any posts, so there is nothing to display here at the moment.' @@ -158,7 +158,7 @@ export default function CategoriesEdit( {

) } { ! isRequesting && - categories.length > 0 && + categories?.length > 0 && ( displayAsDropdown ? renderCategoryDropdown() : renderCategoryList() ) } From 571588dc119725e708bd93cbb71b2a161b51a003 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Fri, 25 Jun 2021 16:56:38 +0300 Subject: [PATCH 03/64] [Block Library - Site Logo]: Add permissions handling (#32919) * [Block Library - Site Logo]: Add permissions handling * Add only logo id to rest index * add link to logo in rest index * use context 'view' only * fallback to logo id from rest index --- lib/init.php | 27 ++++ packages/block-library/src/site-logo/edit.js | 118 ++++++++++-------- .../block-library/src/site-logo/editor.scss | 20 +++ 3 files changed, 112 insertions(+), 53 deletions(-) diff --git a/lib/init.php b/lib/init.php index a79550fa6e012e..744e9395015b7a 100644 --- a/lib/init.php +++ b/lib/init.php @@ -188,6 +188,33 @@ function register_site_icon_url( $response ) { add_filter( 'rest_index', 'register_site_icon_url' ); +/** + * Exposes the site logo to the Gutenberg editor through the WordPress REST + * API. This is used for fetching this information when user has no rights + * to update settings. + * + * @since 10.9 + * + * @param WP_REST_Response $response Response data served by the WordPress REST index endpoint. + * @return WP_REST_Response + */ +function register_site_logo_to_rest_index( $response ) { + $site_logo_id = get_theme_mod( 'custom_logo' ); + $response->data['site_logo'] = $site_logo_id; + if ( $site_logo_id ) { + $response->add_link( + 'https://api.w.org/featuredmedia', + rest_url( 'wp/v2/media/' . $site_logo_id ), + array( + 'embeddable' => true, + ) + ); + } + return $response; +} + +add_filter( 'rest_index', 'register_site_logo_to_rest_index' ); + add_theme_support( 'widgets-block-editor' ); /** diff --git a/packages/block-library/src/site-logo/edit.js b/packages/block-library/src/site-logo/edit.js index 05e225513392d1..aecda3ec75d2b3 100644 --- a/packages/block-library/src/site-logo/edit.js +++ b/packages/block-library/src/site-logo/edit.js @@ -17,6 +17,7 @@ import { ResizableBox, Spinner, ToggleControl, + Icon, } from '@wordpress/components'; import { useViewportMatch } from '@wordpress/compose'; import { @@ -73,7 +74,7 @@ const SiteLogo = ( { title: siteEntities.title, ...pick( getSettings(), [ 'imageSizes', 'maxWidth' ] ), }; - } ); + }, [] ); function onResizeStart() { toggleSelection( false ); @@ -255,27 +256,38 @@ export default function LogoEdit( { const [ logoUrl, setLogoUrl ] = useState(); const [ error, setError ] = useState(); const ref = useRef(); - const { mediaItemData, siteLogo, url } = useSelect( ( select ) => { - const siteSettings = select( coreStore ).getEditedEntityRecord( - 'root', - 'site' - ); - const mediaItem = siteSettings.site_logo - ? select( coreStore ).getEntityRecord( + + const { siteLogoId, canUserEdit, url, mediaItemData } = useSelect( + ( select ) => { + const { canUser, getEntityRecord, getEditedEntityRecord } = select( + coreStore + ); + const siteSettings = getEditedEntityRecord( 'root', 'site' ); + const siteData = getEntityRecord( 'root', '__unstableBase' ); + const _siteLogo = siteSettings?.site_logo; + const _readOnlyLogo = siteData?.site_logo; + const _canUserEdit = canUser( 'update', 'settings' ); + const _siteLogoId = _siteLogo || _readOnlyLogo; + const mediaItem = + _siteLogoId && + select( coreStore ).getEntityRecord( 'root', 'media', - siteSettings.site_logo - ) - : null; - return { - mediaItemData: mediaItem && { - url: mediaItem.source_url, - alt: mediaItem.alt_text, - }, - siteLogo: siteSettings.site_logo, - url: siteSettings.url, - }; - }, [] ); + _siteLogoId, + { context: 'view' } + ); + return { + siteLogoId: _siteLogoId, + canUserEdit: _canUserEdit, + url: siteData?.url, + mediaItemData: mediaItem && { + url: mediaItem.source_url, + alt: mediaItem.alt_text, + }, + }; + }, + [] + ); const { editEntityRecord } = useDispatch( coreStore ); const setLogo = ( newValue ) => @@ -290,7 +302,6 @@ export default function LogoEdit( { setLogoUrl( mediaItemData.url ); } } - const onSelectLogo = ( media ) => { if ( ! media ) { return; @@ -311,7 +322,7 @@ export default function LogoEdit( { setError( message[ 2 ] ? message[ 2 ] : null ); }; - const controls = logoUrl && ( + const controls = canUserEdit && logoUrl && ( ; } - if ( !! logoUrl ) { logoImage = ( ); } - - const mediaPlaceholder = ( - } - labels={ { - title: label, - instructions: __( - 'Upload an image, or pick one from your media library, to be your site logo' - ), - } } - onSelect={ onSelectLogo } - accept={ ACCEPT_MEDIA_STRING } - allowedTypes={ ALLOWED_MEDIA_TYPES } - mediaPreview={ logoImage } - notices={ - error && ( - - { error } - - ) - } - onError={ onUploadError } - /> - ); - const classes = classnames( className, { 'is-default-size': ! width, } ); - const blockProps = useBlockProps( { ref, className: classes, } ); - return (
{ controls } - { logoUrl && logoImage } - { ! logoUrl && mediaPlaceholder } + { !! logoUrl && logoImage } + { ! logoUrl && ! canUserEdit && ( +
+ +

{ __( 'Site Logo' ) }

+
+ ) } + { ! logoUrl && canUserEdit && ( + } + labels={ { + title: label, + instructions: __( + 'Upload an image, or pick one from your media library, to be your site logo' + ), + } } + onSelect={ onSelectLogo } + accept={ ACCEPT_MEDIA_STRING } + allowedTypes={ ALLOWED_MEDIA_TYPES } + mediaPreview={ logoImage } + notices={ + error && ( + + { error } + + ) + } + onError={ onUploadError } + /> + ) }
); } diff --git a/packages/block-library/src/site-logo/editor.scss b/packages/block-library/src/site-logo/editor.scss index 694cc980312839..de72e08f7cbff7 100644 --- a/packages/block-library/src/site-logo/editor.scss +++ b/packages/block-library/src/site-logo/editor.scss @@ -80,3 +80,23 @@ } } } +.editor-styles-wrapper { + .site-logo_placeholder { + display: flex; + flex-direction: row; + align-items: flex-start; + border-radius: $radius-block-ui; + background-color: $white; + box-shadow: inset 0 0 0 $border-width $gray-900; + padding: $grid-unit-15; + svg { + margin-right: $grid-unit-15; + } + p { + font-family: $default-font; + font-size: $default-font-size; + margin: 0; + line-height: initial; + } + } +} From 408170a9b4007857166b41041aceedb1cef012c8 Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Fri, 25 Jun 2021 15:01:23 +0100 Subject: [PATCH 04/64] Fix: template editor header area is difficult to navigate with screen readers (#32938) --- .../components/header/header-toolbar/index.js | 3 - .../edit-post/src/components/header/index.js | 2 + .../components/header/template-title/index.js | 97 +++++++++---------- 3 files changed, 46 insertions(+), 56 deletions(-) diff --git a/packages/edit-post/src/components/header/header-toolbar/index.js b/packages/edit-post/src/components/header/header-toolbar/index.js index f3e16a6f2b398d..6334791036c255 100644 --- a/packages/edit-post/src/components/header/header-toolbar/index.js +++ b/packages/edit-post/src/components/header/header-toolbar/index.js @@ -23,7 +23,6 @@ import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; /** * Internal dependencies */ -import TemplateTitle from '../template-title'; import { store as editPostStore } from '../../../store'; const preventDefault = ( event ) => { @@ -164,8 +163,6 @@ function HeaderToolbar() { ) } - - ); } diff --git a/packages/edit-post/src/components/header/index.js b/packages/edit-post/src/components/header/index.js index c24e41ec59b411..40e5fa91239e0b 100644 --- a/packages/edit-post/src/components/header/index.js +++ b/packages/edit-post/src/components/header/index.js @@ -21,6 +21,7 @@ import PostPublishButtonOrToggle from './post-publish-button-or-toggle'; import { default as DevicePreview } from '../device-preview'; import MainDashboardButton from './main-dashboard-button'; import { store as editPostStore } from '../../store'; +import TemplateTitle from './template-title'; function Header( { setEntitiesSavedStatesCallback } ) { const { @@ -59,6 +60,7 @@ function Header( { setEntitiesSavedStatesCallback } ) {
+
{ ! isPublishSidebarOpened && ( diff --git a/packages/edit-post/src/components/header/template-title/index.js b/packages/edit-post/src/components/header/template-title/index.js index a2cd8b0ca07f78..21431ee1e319c0 100644 --- a/packages/edit-post/src/components/header/template-title/index.js +++ b/packages/edit-post/src/components/header/template-title/index.js @@ -3,7 +3,7 @@ */ import { __, sprintf } from '@wordpress/i18n'; import { useSelect, useDispatch } from '@wordpress/data'; -import { Dropdown, ToolbarItem, Button } from '@wordpress/components'; +import { Dropdown, Button } from '@wordpress/components'; import { chevronDown } from '@wordpress/icons'; /** @@ -47,59 +47,50 @@ function TemplateTitle() { } return ( - - { ( toolbarItemHTMLProps ) => { - return ( - ( - <> - - - +
+ + ( + + ) } + renderContent={ () => ( + <> + { template.has_theme_file ? ( + + ) : ( + ) } - renderContent={ () => ( - <> - { template.has_theme_file ? ( - - ) : ( - - ) } - - - ) } - /> - ); - } } - + + + ) } + /> +
); } From d3ae58589fbb3c53351a4cfaf4bc5da0a36cbb4d Mon Sep 17 00:00:00 2001 From: Gerardo Pacheco Date: Fri, 25 Jun 2021 16:23:10 +0200 Subject: [PATCH 05/64] Mobile Release v1.56.0 (#32982) * Release script: Update react-native-editor version to 1.56.0 * Release script: Update with changes from 'npm run core preios' --- packages/react-native-aztec/package.json | 2 +- packages/react-native-bridge/package.json | 2 +- packages/react-native-editor/ios/Podfile.lock | 16 ++++++++-------- packages/react-native-editor/package.json | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/react-native-aztec/package.json b/packages/react-native-aztec/package.json index 94cd9b18ac9c9d..0b0fcc20e5514d 100644 --- a/packages/react-native-aztec/package.json +++ b/packages/react-native-aztec/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-aztec", - "version": "1.55.2", + "version": "1.56.0", "description": "Aztec view for react-native.", "private": true, "author": "The WordPress Contributors", diff --git a/packages/react-native-bridge/package.json b/packages/react-native-bridge/package.json index fe2a4436570e8e..7b946159f0d851 100644 --- a/packages/react-native-bridge/package.json +++ b/packages/react-native-bridge/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-bridge", - "version": "1.55.2", + "version": "1.56.0", "description": "Native bridge library used to integrate the block editor into a native App.", "private": true, "author": "The WordPress Contributors", diff --git a/packages/react-native-editor/ios/Podfile.lock b/packages/react-native-editor/ios/Podfile.lock index ad5ba78005c622..135e8c97bfa777 100644 --- a/packages/react-native-editor/ios/Podfile.lock +++ b/packages/react-native-editor/ios/Podfile.lock @@ -12,7 +12,7 @@ PODS: - React-jsi (= 0.64.0) - ReactCommon/turbomodule/core (= 0.64.0) - glog (0.3.5) - - Gutenberg (1.55.2): + - Gutenberg (1.56.0): - React-Core (= 0.64.0) - React-CoreModules (= 0.64.0) - React-RCTImage (= 0.64.0) @@ -303,7 +303,7 @@ PODS: - React-Core - RNSVG (9.13.6-gb): - React-Core - - RNTAztecView (1.55.2): + - RNTAztecView (1.56.0): - React-Core - WordPress-Aztec-iOS (~> 1.19.4) - WordPress-Aztec-iOS (1.19.4) @@ -457,9 +457,9 @@ SPEC CHECKSUMS: BVLinearGradient: b2d297a15cf094d1947df4f0519779bb3a7f2392 DoubleConversion: cf9b38bf0b2d048436d9a82ad2abe1404f11e7de FBLazyVector: 49cbe4b43e445b06bf29199b6ad2057649e4c8f5 - FBReactNativeSpec: 805a3c2471c7458fc66bafc5b635e3ecf80f99c9 + FBReactNativeSpec: 80e9cf1155002ee4720084d8813326d913815e2f glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62 - Gutenberg: 370764154bd1acf878f58985e3d75d15f7cc0666 + Gutenberg: 92bec6d8f160c51fd16b7538ff750e1136e8a134 RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c RCTRequired: 2f8cb5b7533219bf4218a045f92768129cf7050a RCTTypeSafety: 512728b73549e72ad7330b92f3d42936f2a4de5b @@ -475,9 +475,9 @@ SPEC CHECKSUMS: react-native-get-random-values: 03edb8dcc2d3f43e55aa67ea13b61b6723bbf047 react-native-keyboard-aware-scroll-view: 6cb84879bf07e4cc1caed18b11fb928e142adac6 react-native-safe-area: c9cf765aa2dd96159476a99633e7d462ce5bb94f - react-native-safe-area-context: e471852c5ed67eea4b10c5d9d43c1cebae3b231d + react-native-safe-area-context: f0906bf8bc9835ac9a9d3f97e8bde2a997d8da79 react-native-slider: 2e42dc91e7ab8b35a9c7f2eb3532729a41d0dbe2 - react-native-video: e5dd0649534076cd6d09a0db51c617fa668d534a + react-native-video: b8767f54061e475ddd38c22375f46f4d93e5fdfd React-perflogger: 9c547d8f06b9bf00cb447f2b75e8d7f19b7e02af React-RCTActionSheet: 3080b6e12e0e1a5b313c8c0050699b5c794a1b11 React-RCTAnimation: 3f96f21a497ae7dabf4d2f150ee43f906aaf516f @@ -491,12 +491,12 @@ SPEC CHECKSUMS: React-runtimeexecutor: cad74a1eaa53ee6e7a3620231939d8fe2c6afcf0 ReactCommon: cfe2b7fd20e0dbd2d1185cd7d8f99633fbc5ff05 ReactNativeDarkMode: 6d807bc8373b872472c8541fc3341817d979a6fb - RNCMaskedView: dfeba59697c44d36abec79c062aeb1ea343d610d + RNCMaskedView: 66caacf33c86eaa7d22b43178dd998257d5c2e4d RNGestureHandler: 5e58135436aacc1c5d29b75547d3d2b9430d052c RNReanimated: f05baf4cd76b6eab2e4d7e2b244424960b968918 RNScreens: 953633729a42e23ad0c93574d676b361e3335e8b RNSVG: 46c4b680fe18237fa01eb7d7b311d77618fde31f - RNTAztecView: 4a25067d531ba62f2e0595b513d34477a538988f + RNTAztecView: 2d4d506e2e203ad07ff911adf7eeb9a36a87512b WordPress-Aztec-iOS: 870c93297849072aadfc2223e284094e73023e82 Yoga: 8c8436d4171c87504c648ae23b1d81242bdf3bbf diff --git a/packages/react-native-editor/package.json b/packages/react-native-editor/package.json index dc08e028c41ece..d3c5b7d53a1154 100644 --- a/packages/react-native-editor/package.json +++ b/packages/react-native-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-editor", - "version": "1.55.2", + "version": "1.56.0", "description": "Mobile WordPress gutenberg editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From 09428b5234014a9f0e068a3c28457ad5fd2272ea Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Fri, 25 Jun 2021 17:30:05 +0300 Subject: [PATCH 06/64] Only reset edits for requests on the default context (#32991) Co-authored-by: Riad Benguella --- packages/core-data/src/reducer.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/core-data/src/reducer.js b/packages/core-data/src/reducer.js index 6ce70d6a1b4659..4b975e9a47efd4 100644 --- a/packages/core-data/src/reducer.js +++ b/packages/core-data/src/reducer.js @@ -197,6 +197,11 @@ function entity( entityConfig ) { edits: ( state = {}, action ) => { switch ( action.type ) { case 'RECEIVE_ITEMS': + const context = action?.query?.context ?? 'default'; + if ( context !== 'default' ) { + return state; + } + const nextState = { ...state }; for ( const record of action.items ) { From b78b615b59ded086d947140dcfb65806f610001c Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Fri, 25 Jun 2021 17:35:30 +0300 Subject: [PATCH 07/64] [Block Library - Categories]: Fix handling for low privileged users (#32994) --- packages/block-library/src/categories/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/categories/edit.js b/packages/block-library/src/categories/edit.js index 5c8aad58698cd8..475ca9a25954d9 100644 --- a/packages/block-library/src/categories/edit.js +++ b/packages/block-library/src/categories/edit.js @@ -27,7 +27,7 @@ export default function CategoriesEdit( { const selectId = useInstanceId( CategoriesEdit, 'blocks-category-select' ); const { categories, isRequesting } = useSelect( ( select ) => { const { getEntityRecords, isResolving } = select( coreStore ); - const query = { per_page: -1, hide_empty: true }; + const query = { per_page: -1, hide_empty: true, context: 'view' }; return { categories: getEntityRecords( 'taxonomy', 'category', query ), isRequesting: isResolving( 'getEntityRecords', [ From 700b85f6d7752a9184d5723ec1117dcb07a9f41a Mon Sep 17 00:00:00 2001 From: Stefanos Togoulidis Date: Fri, 25 Jun 2021 17:37:31 +0300 Subject: [PATCH 08/64] Bump version of caniuse-lite (#32881) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9413b978ebdb95..916a75bcccb228 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25731,9 +25731,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001228", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", - "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==" + "version": "1.0.30001237", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001237.tgz", + "integrity": "sha512-pDHgRndit6p1NR2GhzMbQ6CkRrp4VKuSsqbcLeOQppYPKOYkKT/6ZvZDvKJUqcmtyWIAHuZq3SVS2vc1egCZzw==" }, "capture-exit": { "version": "2.0.0", From b58fbb3c4456967ff4d8d8df184ef98ce83f3efb Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Fri, 25 Jun 2021 07:58:18 -0700 Subject: [PATCH 09/64] data: Type `promise-middleware` (#32967) --- packages/data/src/promise-middleware.js | 2 +- packages/data/tsconfig.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/data/src/promise-middleware.js b/packages/data/src/promise-middleware.js index 16cd4ccf097443..1721efa6b58259 100644 --- a/packages/data/src/promise-middleware.js +++ b/packages/data/src/promise-middleware.js @@ -6,7 +6,7 @@ import isPromise from 'is-promise'; /** * Simplest possible promise redux middleware. * - * @return {Function} middleware. + * @type {import('redux').Middleware} */ const promiseMiddleware = () => ( next ) => ( action ) => { if ( isPromise( action ) ) { diff --git a/packages/data/tsconfig.json b/packages/data/tsconfig.json index 288fbf3474f993..ff86e7b3df6328 100644 --- a/packages/data/tsconfig.json +++ b/packages/data/tsconfig.json @@ -15,5 +15,6 @@ ], "include": [ "src/redux-store/metadata/**/*", + "src/promise-middleware.js", ] } From 0d0dc1e49b915b95c09ba88c65326c8c9732891c Mon Sep 17 00:00:00 2001 From: Matt Chowning Date: Fri, 25 Jun 2021 11:15:21 -0400 Subject: [PATCH 10/64] Remove ReactAztecTextInputShadowNodeFork (#32940) The changes that required that forked class are now included in the `ReactTextInputShadowNode` class. --- .../ReactAztecTextShadowNode.java | 8 +- .../ReactTextInputShadowNodeFork.java | 240 ------------------ 2 files changed, 4 insertions(+), 244 deletions(-) delete mode 100644 packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactTextInputShadowNodeFork.java diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecTextShadowNode.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecTextShadowNode.java index c2e217363a2fad..464b4874c7c996 100644 --- a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecTextShadowNode.java +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecTextShadowNode.java @@ -5,14 +5,14 @@ import androidx.annotation.Nullable; import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.annotations.ReactProp; +import com.facebook.react.views.textinput.ReactTextInputShadowNode; -public class ReactAztecTextShadowNode extends ReactTextInputShadowNodeFork { +public class ReactAztecTextShadowNode extends ReactTextInputShadowNode { @Override - protected EditText createDummyEditText(ThemedReactContext themedContext) { - return new EditText(themedContext, null, 0); + protected EditText createInternalEditText() { + return new EditText(getThemedContext(), null, 0); } @ReactProp(name = PROP_TEXT) diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactTextInputShadowNodeFork.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactTextInputShadowNodeFork.java deleted file mode 100644 index 4ec32e6beded04..00000000000000 --- a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactTextInputShadowNodeFork.java +++ /dev/null @@ -1,240 +0,0 @@ -package org.wordpress.mobile.ReactNativeAztec; - -import android.os.Build; -import android.text.Layout; -import android.util.TypedValue; -import android.view.ViewGroup; -import android.widget.EditText; - -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; -import androidx.core.view.ViewCompat; - -import com.facebook.infer.annotation.Assertions; -import com.facebook.react.bridge.JSApplicationIllegalArgumentException; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.uimanager.Spacing; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.UIViewOperationQueue; -import com.facebook.react.uimanager.annotations.ReactProp; -import com.facebook.react.views.text.ReactBaseTextShadowNode; -import com.facebook.react.views.text.ReactTextUpdate; -import com.facebook.react.views.textinput.ReactTextInputLocalData; -import com.facebook.react.views.view.MeasureUtil; -import com.facebook.yoga.YogaMeasureFunction; -import com.facebook.yoga.YogaMeasureMode; -import com.facebook.yoga.YogaMeasureOutput; -import com.facebook.yoga.YogaNode; - -/** - * This is a fork from {@link com.facebook.react.views.textinput.ReactTextInputShadowNode} for the purpose - * of customizing that class so that the construction of the dummy {@link EditText} instance - * can be overridden (see {@link ReactTextInputShadowNodeFork#createDummyEditText(ThemedReactContext)}). - */ -public class ReactTextInputShadowNodeFork extends ReactBaseTextShadowNode - implements YogaMeasureFunction { - - private int mMostRecentEventCount = UNSET; - private @Nullable EditText mDummyEditText; - private @Nullable ReactTextInputLocalData mLocalData; - - @VisibleForTesting public static final String PROP_TEXT = "text"; - @VisibleForTesting public static final String PROP_PLACEHOLDER = "placeholder"; - @VisibleForTesting public static final String PROP_SELECTION = "selection"; - - // Represents the {@code text} property only, not possible nested content. - private @Nullable String mText = null; - private @Nullable String mPlaceholder = null; - private int mSelectionStart = UNSET; - private int mSelectionEnd = UNSET; - - public ReactTextInputShadowNodeFork() { - mTextBreakStrategy = (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) ? - Layout.BREAK_STRATEGY_SIMPLE : Layout.BREAK_STRATEGY_HIGH_QUALITY; - - initMeasureFunction(); - } - - private void initMeasureFunction() { - setMeasureFunction(this); - } - - @Override - public void setThemedContext(ThemedReactContext themedContext) { - super.setThemedContext(themedContext); - - // {@code EditText} has by default a border at the bottom of its view - // called "underline". To have a native look and feel of the TextEdit - // we have to preserve it at least by default. - // The border (underline) has its padding set by the background image - // provided by the system (which vary a lot among versions and vendors - // of Android), and it cannot be changed. - // So, we have to enforce it as a default padding. - // TODO #7120264: Cache this stuff better. - EditText editText = createDummyEditText(getThemedContext()); - setDefaultPadding(Spacing.START, ViewCompat.getPaddingStart(editText)); - setDefaultPadding(Spacing.TOP, editText.getPaddingTop()); - setDefaultPadding(Spacing.END, ViewCompat.getPaddingEnd(editText)); - setDefaultPadding(Spacing.BOTTOM, editText.getPaddingBottom()); - - mDummyEditText = editText; - - // We must measure the EditText without paddings, so we have to reset them. - mDummyEditText.setPadding(0, 0, 0, 0); - - // This is needed to fix an android bug since 4.4.3 which will throw an NPE in measure, - // setting the layoutParams fixes it: https://code.google.com/p/android/issues/detail?id=75877 - mDummyEditText.setLayoutParams( - new ViewGroup.LayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); - } - - protected EditText createDummyEditText(ThemedReactContext themedContext) { - return new EditText(themedContext); - } - - @Override - public long measure( - YogaNode node, - float width, - YogaMeasureMode widthMode, - float height, - YogaMeasureMode heightMode) { - // measure() should never be called before setThemedContext() - EditText editText = Assertions.assertNotNull(mDummyEditText); - - if (mLocalData != null) { - mLocalData.apply(editText); - } else { - editText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextAttributes.getEffectiveFontSize()); - - if (mNumberOfLines != UNSET) { - editText.setLines(mNumberOfLines); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && - editText.getBreakStrategy() != mTextBreakStrategy) { - editText.setBreakStrategy(mTextBreakStrategy); - } - } - - // make sure the placeholder content is also being measured - editText.setHint(getPlaceholder()); - editText.measure( - MeasureUtil.getMeasureSpec(width, widthMode), - MeasureUtil.getMeasureSpec(height, heightMode)); - - return YogaMeasureOutput.make(editText.getMeasuredWidth(), editText.getMeasuredHeight()); - } - - @Override - public boolean isVirtualAnchor() { - return true; - } - - @Override - public boolean isYogaLeafNode() { - return true; - } - - @Override - public void setLocalData(Object data) { - Assertions.assertCondition(data instanceof ReactTextInputLocalData); - mLocalData = (ReactTextInputLocalData) data; - - // Telling to Yoga that the node should be remeasured on next layout pass. - dirty(); - - // Note: We should NOT mark the node updated (by calling {@code markUpdated}) here - // because the state remains the same. - } - - @ReactProp(name = "mostRecentEventCount") - public void setMostRecentEventCount(int mostRecentEventCount) { - mMostRecentEventCount = mostRecentEventCount; - } - - @ReactProp(name = PROP_TEXT) - public void setText(@Nullable String text) { - mText = text; - markUpdated(); - } - - public @Nullable String getText() { - return mText; - } - - @ReactProp(name = PROP_PLACEHOLDER) - public void setPlaceholder(@Nullable String placeholder) { - mPlaceholder = placeholder; - markUpdated(); - } - - public @Nullable String getPlaceholder() { - return mPlaceholder; - } - - @ReactProp(name = PROP_SELECTION) - public void setSelection(@Nullable ReadableMap selection) { - mSelectionStart = mSelectionEnd = UNSET; - if (selection == null) - return; - - if (selection.hasKey("start") && selection.hasKey("end")) { - mSelectionStart = selection.getInt("start"); - mSelectionEnd = selection.getInt("end"); - markUpdated(); - } - } - - @Override - public void setTextBreakStrategy(@Nullable String textBreakStrategy) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - return; - } - - if (textBreakStrategy == null || "simple".equals(textBreakStrategy)) { - mTextBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE; - } else if ("highQuality".equals(textBreakStrategy)) { - mTextBreakStrategy = Layout.BREAK_STRATEGY_HIGH_QUALITY; - } else if ("balanced".equals(textBreakStrategy)) { - mTextBreakStrategy = Layout.BREAK_STRATEGY_BALANCED; - } else { - throw new JSApplicationIllegalArgumentException("Invalid textBreakStrategy: " + textBreakStrategy); - } - } - - @Override - public void onCollectExtraUpdates(UIViewOperationQueue uiViewOperationQueue) { - super.onCollectExtraUpdates(uiViewOperationQueue); - - if (mMostRecentEventCount != UNSET) { - ReactTextUpdate reactTextUpdate = - new ReactTextUpdate( - spannedFromShadowNode( - this, - getText(), - /* supportsInlineViews: */ false, - /* nativeViewHierarchyOptimizer: */ null // only needed to support inline views - ), - mMostRecentEventCount, - mContainsImages, - getPadding(Spacing.LEFT), - getPadding(Spacing.TOP), - getPadding(Spacing.RIGHT), - getPadding(Spacing.BOTTOM), - mTextAlign, - mTextBreakStrategy, - mJustificationMode, - mSelectionStart, - mSelectionEnd); - uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), reactTextUpdate); - } - } - - @Override - public void setPadding(int spacingType, float padding) { - super.setPadding(spacingType, padding); - markUpdated(); - } -} From 21499dcf1841f3ee6f1dfa5d5cc23aea6c952267 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 25 Jun 2021 16:30:09 +0100 Subject: [PATCH 11/64] Fix to remove default indent from Latest Posts and Latest Comments block in various editors (#32983) * Remove default left spacing on Latest Posts in all Editors * Remove spacing consistently across Post/Site, Widgets and Widgets Customizer editors * Fix indentation of Comments block in Site Editor --- packages/block-library/src/latest-comments/style.scss | 11 +++++++++++ packages/block-library/src/latest-posts/style.scss | 2 ++ 2 files changed, 13 insertions(+) diff --git a/packages/block-library/src/latest-comments/style.scss b/packages/block-library/src/latest-comments/style.scss index 61c6aea843a742..14d3d67eae5edb 100644 --- a/packages/block-library/src/latest-comments/style.scss +++ b/packages/block-library/src/latest-comments/style.scss @@ -1,4 +1,15 @@ +// Lower specificity - target list element. ol.wp-block-latest-comments { + // Removes left spacing in Customizer Widgets screen. + // Due to low specificity this will be safely overriden + // by default wp-block layout styles in the Post/Site editor + margin-left: 0; +} + +// Higher specificity - target list via wrapper. +.wp-block-latest-comments .wp-block-latest-comments { + // Remove left spacing. Higher specificity required to + // override default wp-block layout styles in the Post/Site editor. padding-left: 0; } diff --git a/packages/block-library/src/latest-posts/style.scss b/packages/block-library/src/latest-posts/style.scss index b52fb34cb26f48..2df097b3fc9907 100644 --- a/packages/block-library/src/latest-posts/style.scss +++ b/packages/block-library/src/latest-posts/style.scss @@ -9,11 +9,13 @@ } &.wp-block-latest-posts__list { list-style: none; + padding-left: 0; li { clear: both; } } + &.is-grid { display: flex; flex-wrap: wrap; From 6a3c3b72895162158870e3e000c5529d56135c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= <4710635+ellatrix@users.noreply.github.com> Date: Fri, 25 Jun 2021 18:53:57 +0300 Subject: [PATCH 12/64] Autocomplete: fix double popover (#32988) The popover is rendered twice, once inside the rich text tag and once outside. One of the popovers is removed when rich text is deselected, but the other is not. --- packages/block-editor/src/components/rich-text/index.js | 1 - packages/components/src/autocomplete/index.js | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index 34e5a3f963aaab..807a9014850155 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -289,7 +289,6 @@ function RichTextWrapper( { isSelected && children && children( { value, onChange, onFocus } ) } - { isSelected && autocompleteProps.children } { isSelected && ( Date: Fri, 25 Jun 2021 16:10:31 +0000 Subject: [PATCH 13/64] Bump plugin version to 10.9.1 --- gutenberg.php | 2 +- package-lock.json | 2 +- package.json | 2 +- readme.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index 547f5f25170ddd..6ab88b1ddad4e2 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the new block editor in core. * Requires at least: 5.6 * Requires PHP: 5.6 - * Version: 10.9.0 + * Version: 10.9.1 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index 916a75bcccb228..be1d33fd063859 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "10.9.0", + "version": "10.9.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index fbb44d37f747e4..5c6f2ce818d575 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "10.9.0", + "version": "10.9.1", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", diff --git a/readme.txt b/readme.txt index 07a4c4f03c8677..ed14a644cb815c 100644 --- a/readme.txt +++ b/readme.txt @@ -55,4 +55,4 @@ View release page. +To read the changelog for Gutenberg 10.9.1, please navigate to the release page. From 1be105906f30dc623d9f7e1f4d192744d41cff71 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Fri, 25 Jun 2021 16:29:13 +0000 Subject: [PATCH 14/64] Update Changelog for 10.9.1 --- changelog.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/changelog.txt b/changelog.txt index d7e4d83bd38030..7dd4097cad1aee 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,14 @@ == Changelog == += 10.9.1 = + +### Bug Fixes + +- Autocomplete: Fix double popover. ([32988](https://github.com/WordPress/gutenberg/pull/32988)) + + + + = 10.9.0 = ### Enhancements From afee31ee020b8965e811f5d68a5ca8001780af9d Mon Sep 17 00:00:00 2001 From: Addison Stavlo Date: Fri, 25 Jun 2021 13:13:53 -0400 Subject: [PATCH 15/64] Template Parts & Reusable Blocks - try overlay element for clickthrough to edit pattern. (#31109) * clickthrough for template part * make store names more consistent and accurate * remove unnecessary selector change * move color from hover to selected, add opacity value * Add hover overlay * bleh resizing issues * kind of working... * remove unnecessary popover goo * fix for nested template parts and selection bleeding out of boundary * remove unnecessary effect/state * fix resizing issue * try only selected color when focused * cleanup css * try overlay for initial selection only * enable drag and drop * only show borders on drag and drop * ensure background color not on drag and drop * apply to reusable blocks * fix e2e tests * try add basic test * try fix test * only use the afterEach where needed * use css vars * fix border color * fix block toolbar issue * fix width on classic themes * fix width by moving overlay inside block wrapper * fix bug with selection from list view * add condition to dismissing * show overlay when highlighting list view * use selector for highlight style * refactor and comments * position overlay above resize containers * fix nested entity test * fix template part test * fix intermittent errors on conversion tests * remove box shadow on hover - block hover style will already be present * add border back to overlay * use blockProps in innerBlockProps as well * cleanup which blockProps are passed to innerBlockProps * use component as wrapper * remove unnecessary layout selectors on TP e2es * fix reusable blocks test xpath Co-authored-by: James Koster --- packages/base-styles/_functions.scss | 9 ++ packages/base-styles/_mixins.scss | 8 +- packages/base-styles/_z-index.scss | 3 + .../components/block-content-overlay/index.js | 101 ++++++++++++++++++ .../block-content-overlay/style.scss | 41 +++++++ packages/block-editor/src/components/index.js | 1 + packages/block-editor/src/style.scss | 1 + packages/block-library/src/block/edit.js | 13 ++- .../src/template-part/edit/index.js | 1 + .../src/template-part/edit/inner-blocks.js | 14 ++- packages/e2e-test-utils/src/inserter.js | 2 +- .../experiments/multi-entity-editing.test.js | 30 +++++- .../experiments/multi-entity-saving.test.js | 5 +- .../specs/experiments/template-part.test.js | 17 +-- 14 files changed, 227 insertions(+), 19 deletions(-) create mode 100644 packages/base-styles/_functions.scss create mode 100644 packages/block-editor/src/components/block-content-overlay/index.js create mode 100644 packages/block-editor/src/components/block-content-overlay/style.scss diff --git a/packages/base-styles/_functions.scss b/packages/base-styles/_functions.scss new file mode 100644 index 00000000000000..734506d456d974 --- /dev/null +++ b/packages/base-styles/_functions.scss @@ -0,0 +1,9 @@ +/** +* Converts a hex value into the rgb equivalent. +* +* @param {string} hex - the hexadecimal value to convert +* @return {string} comma separated rgb values +*/ +@function hex-to-rgb($hex) { + @return red($hex), green($hex), blue($hex); +} diff --git a/packages/base-styles/_mixins.scss b/packages/base-styles/_mixins.scss index c1c4215c4f48f4..d01d312014b879 100644 --- a/packages/base-styles/_mixins.scss +++ b/packages/base-styles/_mixins.scss @@ -1,3 +1,5 @@ +@import "./functions"; + /** * Breakpoint mixins */ @@ -440,11 +442,15 @@ } @mixin admin-scheme($color-primary) { + // Define RGB equivalents for use in rgba function. + // Hexadecimal css vars do not work in the rgba function. --wp-admin-theme-color: #{$color-primary}; - + --wp-admin-theme-color--rgb: #{hex-to-rgb($color-primary)}; // Darker shades. --wp-admin-theme-color-darker-10: #{darken($color-primary, 5%)}; + --wp-admin-theme-color-darker-10--rgb: #{hex-to-rgb(darken($color-primary, 5%))}; --wp-admin-theme-color-darker-20: #{darken($color-primary, 10%)}; + --wp-admin-theme-color-darker-20--rgb: #{hex-to-rgb(darken($color-primary, 10%))}; // Focus style width. // Avoid rounding issues by showing a whole 2px for 1x screens, and 1.5px on high resolution screens. diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index dda6e438edf4af..c7bc54004e1d49 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -74,6 +74,9 @@ $z-layers: ( // The toolbar, when contextual, should be above any adjacent nested block click overlays. ".block-editor-block-contextual-toolbar": 61, + // Ensures content overlay appears higher than resize containers used for image/video/etc. + ".block-editor-block-content-overlay__overlay": 10, + // The block mover, particularly in nested contexts, // should overlap most block content. ".block-editor-block-list__block.is-{selected,hovered} .block-editor-block-mover": 61, diff --git a/packages/block-editor/src/components/block-content-overlay/index.js b/packages/block-editor/src/components/block-content-overlay/index.js new file mode 100644 index 00000000000000..d75d2716c9eb5c --- /dev/null +++ b/packages/block-editor/src/components/block-content-overlay/index.js @@ -0,0 +1,101 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { useState, useEffect } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../../store'; + +/** + * External dependencies + */ +import classnames from 'classnames'; + +export default function BlockContentOverlay( { + clientId, + tagName: TagName = 'div', + wrapperProps, + className, +} ) { + const baseClassName = 'block-editor-block-content-overlay'; + const [ isOverlayActive, setIsOverlayActive ] = useState( true ); + const [ isHovered, setIsHovered ] = useState( false ); + + const { + isParentSelected, + hasChildSelected, + isDraggingBlocks, + isParentHighlighted, + } = useSelect( + ( select ) => { + const { + isBlockSelected, + hasSelectedInnerBlock, + isDraggingBlocks: _isDraggingBlocks, + isBlockHighlighted, + } = select( blockEditorStore ); + return { + isParentSelected: isBlockSelected( clientId ), + hasChildSelected: hasSelectedInnerBlock( clientId, true ), + isDraggingBlocks: _isDraggingBlocks(), + isParentHighlighted: isBlockHighlighted( clientId ), + }; + }, + [ clientId ] + ); + + const classes = classnames( + baseClassName, + wrapperProps?.className, + className, + { + 'overlay-active': isOverlayActive, + 'parent-highlighted': isParentHighlighted, + 'is-dragging-blocks': isDraggingBlocks, + } + ); + + useEffect( () => { + // Reenable when blocks are not in use. + if ( ! isParentSelected && ! hasChildSelected && ! isOverlayActive ) { + setIsOverlayActive( true ); + } + // Disable if parent selected by another means (such as list view). + // We check hover to ensure the overlay click interaction is not taking place. + // Trying to click the overlay will select the parent block via its 'focusin' + // listener on the wrapper, so if the block is selected while hovered we will + // let the mouseup disable the overlay instead. + if ( isParentSelected && ! isHovered && isOverlayActive ) { + setIsOverlayActive( false ); + } + // Ensure overlay is disabled if a child block is selected. + if ( hasChildSelected && isOverlayActive ) { + setIsOverlayActive( false ); + } + }, [ isParentSelected, hasChildSelected, isOverlayActive, isHovered ] ); + + // Disabled because the overlay div doesn't actually have a role or functionality + // as far as the a11y is concerned. We're just catching the first click so that + // the block can be selected without interacting with its contents. + /* eslint-disable jsx-a11y/no-static-element-interactions */ + return ( + setIsHovered( true ) } + onMouseLeave={ () => setIsHovered( false ) } + > + { isOverlayActive && ( +
setIsOverlayActive( false ) } + /> + ) } + { wrapperProps?.children } + + ); +} +/* eslint-enable jsx-a11y/no-static-element-interactions */ diff --git a/packages/block-editor/src/components/block-content-overlay/style.scss b/packages/block-editor/src/components/block-content-overlay/style.scss new file mode 100644 index 00000000000000..35cd3afcd8a897 --- /dev/null +++ b/packages/block-editor/src/components/block-content-overlay/style.scss @@ -0,0 +1,41 @@ +// Specificity required to ensure overlay width is not restricted to that +// of standard block content. The overlay's width should be as wide as +// its children require. +.editor-styles-wrapper .wp-block .block-editor-block-content-overlay__overlay { + max-width: none; +} + +.block-editor-block-content-overlay { + .block-editor-block-content-overlay__overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: transparent; + border: none; + border-radius: $radius-block-ui; + z-index: z-index(".block-editor-block-content-overlay__overlay"); + } + + &:hover:not(.is-dragging-blocks), + &.parent-highlighted { + > .block-editor-block-content-overlay__overlay { + background: rgba(var(--wp-admin-theme-color--rgb), 0.1); + box-shadow: 0 0 0 $border-width var(--wp-admin-theme-color) inset; + } + } + + &.overlay-active:not(.is-dragging-blocks) { + *:not(.block-editor-block-content-overlay__overlay) { + pointer-events: none; + } + } + + &.is-dragging-blocks { + box-shadow: 0 0 0 $border-width var(--wp-admin-theme-color); + .block-editor-block-content-overlay__overlay { + pointer-events: none; + } + } +} diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index f8752a39f8fde7..ef4095a17a1d3a 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -14,6 +14,7 @@ export { export { default as __experimentalBlockFullHeightAligmentControl } from './block-full-height-alignment-control'; export { default as __experimentalBlockAlignmentMatrixControl } from './block-alignment-matrix-control'; export { default as BlockBreadcrumb } from './block-breadcrumb'; +export { default as __experimentalBlockContentOverlay } from './block-content-overlay'; export { BlockContextProvider } from './block-context'; export { default as BlockControls, diff --git a/packages/block-editor/src/style.scss b/packages/block-editor/src/style.scss index 92fc673e65ccf5..a3c9a9f055b342 100644 --- a/packages/block-editor/src/style.scss +++ b/packages/block-editor/src/style.scss @@ -15,6 +15,7 @@ @import "./components/block-breadcrumb/style.scss"; @import "./components/block-card/style.scss"; @import "./components/block-compare/style.scss"; +@import "./components/block-content-overlay/style.scss"; @import "./components/block-draggable/style.scss"; @import "./components/block-mobile-toolbar/style.scss"; @import "./components/block-mover/style.scss"; diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 966654c87a3dc8..bf4f933773d6bf 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -19,6 +19,7 @@ import { __ } from '@wordpress/i18n'; import { __experimentalUseInnerBlocksProps as useInnerBlocksProps, __experimentalUseNoRecursiveRenders as useNoRecursiveRenders, + __experimentalBlockContentOverlay as BlockContentOverlay, InnerBlocks, BlockControls, InspectorControls, @@ -70,6 +71,8 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { ref ); + const blockProps = useBlockProps(); + const innerBlocksProps = useInnerBlocksProps( {}, { @@ -82,8 +85,6 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { } ); - const blockProps = useBlockProps(); - if ( hasAlreadyRendered ) { return (
@@ -136,9 +137,11 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { /> -
- {
} -
+
); diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index e8ed05baa9b1f4..a6f6078bd09251 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -194,6 +194,7 @@ export default function TemplatePartEdit( { ) } { isEntityAvailable && ( { const { getSettings } = select( blockEditorStore ); @@ -45,6 +47,7 @@ export default function TemplatePartInnerBlocks( { 'wp_template_part', { id } ); + const innerBlocksProps = useInnerBlocksProps( blockProps, { value: blocks, onInput, @@ -54,5 +57,12 @@ export default function TemplatePartInnerBlocks( { : InnerBlocks.ButtonBlockAppender, __experimentalLayout: _layout, } ); - return ; + + return ( + + ); } diff --git a/packages/e2e-test-utils/src/inserter.js b/packages/e2e-test-utils/src/inserter.js index b5041992f2bbc4..48a4985bfe62fe 100644 --- a/packages/e2e-test-utils/src/inserter.js +++ b/packages/e2e-test-utils/src/inserter.js @@ -196,7 +196,7 @@ export async function insertReusableBlock( searchTerm ) { await waitForInserterCloseAndContentFocus(); // We should wait until the block is loaded await page.waitForXPath( - '//*[@class="block-library-block__reusable-block-container"]' + '//*[contains(@class,"block-library-block__reusable-block-container")]' ); } diff --git a/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js b/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js index 0538e5e4b54a5e..e23c5180828d27 100644 --- a/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js +++ b/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js @@ -10,6 +10,7 @@ import { canvas, openDocumentSettingsSidebar, pressKeyWithModifier, + selectBlockByClientId, } from '@wordpress/e2e-test-utils'; /** @@ -218,7 +219,7 @@ describe( 'Multi-entity editor states', () => { removeErrorMocks(); } ); - afterEach( async () => { + const saveAndWaitResponse = async () => { await Promise.all( [ saveAllEntities(), @@ -241,7 +242,7 @@ describe( 'Multi-entity editor states', () => { } ), ] ); removeErrorMocks(); - } ); + }; it( 'should only dirty the parent entity when editing the parent', async () => { // Clear selection so that the block is not added to the template part. @@ -253,9 +254,12 @@ describe( 'Multi-entity editor states', () => { expect( await isEntityDirty( templateName ) ).toBe( true ); expect( await isEntityDirty( templatePartName ) ).toBe( false ); expect( await isEntityDirty( nestedTPName ) ).toBe( false ); + await saveAndWaitResponse(); } ); it( 'should only dirty the child when editing the child', async () => { + // Select parent TP to unlock selecting content. + await canvas().click( '.wp-block-template-part' ); await canvas().click( '.wp-block-template-part .wp-block[data-type="core/paragraph"]' ); @@ -264,9 +268,16 @@ describe( 'Multi-entity editor states', () => { expect( await isEntityDirty( templateName ) ).toBe( false ); expect( await isEntityDirty( templatePartName ) ).toBe( true ); expect( await isEntityDirty( nestedTPName ) ).toBe( false ); + await saveAndWaitResponse(); } ); it( 'should only dirty the nested entity when editing the nested entity', async () => { + // Select parent TP to unlock selecting child. + await canvas().click( '.wp-block-template-part' ); + // Select child TP to unlock selecting content. + await canvas().click( + '.wp-block-template-part .wp-block-template-part' + ); await canvas().click( '.wp-block-template-part .wp-block-template-part .wp-block[data-type="core/paragraph"]' ); @@ -275,6 +286,21 @@ describe( 'Multi-entity editor states', () => { expect( await isEntityDirty( templateName ) ).toBe( false ); expect( await isEntityDirty( templatePartName ) ).toBe( false ); expect( await isEntityDirty( nestedTPName ) ).toBe( true ); + await saveAndWaitResponse(); + } ); + + it( 'should not allow selecting template part content without parent selected', async () => { + // Unselect blocks. + await selectBlockByClientId(); + // Try to select a child block of a template part. + await canvas().click( + '.wp-block-template-part .wp-block-template-part .wp-block[data-type="core/paragraph"]' + ); + + const selectedBlock = await page.evaluate( () => { + return wp.data.select( 'core/block-editor' ).getSelectedBlock(); + } ); + expect( selectedBlock?.name ).toBe( 'core/template-part' ); } ); } ); } ); diff --git a/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js b/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js index 357b0967197c96..dc640faf32cf26 100644 --- a/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js +++ b/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js @@ -105,8 +105,6 @@ describe( 'Multi-entity save flow', () => { ); await createNewButton.click(); await page.waitForSelector( activatedTemplatePartSelector ); - await page.keyboard.press( 'Tab' ); - await page.keyboard.type( 'test-template-part' ); await page.click( '.block-editor-button-block-appender' ); await page.click( '.editor-block-list-item-paragraph' ); await page.keyboard.type( 'some words...' ); @@ -163,6 +161,9 @@ describe( 'Multi-entity save flow', () => { // Update template part. await page.click( templatePartSelector ); + await page.click( + `${ templatePartSelector } .wp-block[data-type="core/paragraph"]` + ); await page.keyboard.type( '...some more words...' ); await page.keyboard.press( 'Enter' ); diff --git a/packages/e2e-tests/specs/experiments/template-part.test.js b/packages/e2e-tests/specs/experiments/template-part.test.js index 4f86248fd79b5e..4e16c07c4e88c1 100644 --- a/packages/e2e-tests/specs/experiments/template-part.test.js +++ b/packages/e2e-tests/specs/experiments/template-part.test.js @@ -94,6 +94,15 @@ describe( 'Template Part', () => { expect( paragraphInTemplatePart ).not.toBeNull(); } + async function awaitHeaderAndFooterLoad() { + await canvas().waitForSelector( + '.wp-block-template-part.site-header.block-editor-block-list__layout' + ); + await canvas().waitForSelector( + '.wp-block-template-part.site-footer.block-editor-block-list__layout' + ); + } + it( 'Should load customizations when in a template even if only the slug and theme attributes are set.', async () => { await updateHeader( 'Header Template Part 123' ); @@ -164,9 +173,7 @@ describe( 'Template Part', () => { } ); it( 'Should convert selected block to template part', async () => { - await canvas().waitForSelector( - '.wp-block-template-part.block-editor-block-list__layout' - ); + await awaitHeaderAndFooterLoad(); const initialTemplateParts = await canvas().$$( '.wp-block-template-part' ); @@ -204,9 +211,7 @@ describe( 'Template Part', () => { } ); it( 'Should convert multiple selected blocks to template part', async () => { - await canvas().waitForSelector( - '.wp-block-template-part.block-editor-block-list__layout' - ); + await awaitHeaderAndFooterLoad(); const initialTemplateParts = await canvas().$$( '.wp-block-template-part' ); From 0ad973b3aab844f25fa2d22945106293c6bdbc33 Mon Sep 17 00:00:00 2001 From: Marcelo Serpa <81248+fullofcaffeine@users.noreply.github.com> Date: Fri, 25 Jun 2021 21:00:47 -0500 Subject: [PATCH 16/64] Add regression E2E test for the bug that caused some wp_options to get corrupted data (#32797) * Manually revert the relevant portions of https://github.com/WordPress/gutenberg/pull/32229 in order to reproduce the wp_option data corruption bug * Test regression for settings update corrupting some wp_options * Cleanup * Revert "Manually revert the relevant portions of https://github.com/WordPress/gutenberg/pull/32229 in order to reproduce the wp_option data corruption bug" This reverts commit 17eb33b3c1ea543cc6646479765b2a20047ce773. * Add comment to remind us that to eventually add a similar test to core --- .../e2e-tests/specs/misc/settings.test.js | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 packages/e2e-tests/specs/misc/settings.test.js diff --git a/packages/e2e-tests/specs/misc/settings.test.js b/packages/e2e-tests/specs/misc/settings.test.js new file mode 100644 index 00000000000000..0eb98a2de050b4 --- /dev/null +++ b/packages/e2e-tests/specs/misc/settings.test.js @@ -0,0 +1,42 @@ +/** + * WordPress dependencies + */ +import { visitAdminPage } from '@wordpress/e2e-test-utils'; + +async function getOptionsValues( selector ) { + await visitAdminPage( 'options.php' ); + return page.evaluate( ( theSelector ) => { + const inputs = Array.from( document.querySelectorAll( theSelector ) ); + return inputs.reduce( ( memo, input ) => { + memo[ input.id ] = input.value; + return memo; + }, {} ); + }, selector ); +} + +// It might make sense to include a similar test in WP core (or move this one over). +// See discussion here: https://github.com/WordPress/gutenberg/pull/32797#issuecomment-864192088. +describe( 'Settings', () => { + test( 'Regression: updating a specific option will only change its value and will not corrupt others', async () => { + // We won't select the option that we updated and will also remove some + // _transient options that seem to change at every update. + const optionsInputsSelector = + 'form#all-options table.form-table input:not([id*="_transient"]):not([id="blogdescription"])'; + const optionsBefore = await getOptionsValues( optionsInputsSelector ); + + await visitAdminPage( 'options-general.php' ); + await page.type( + 'input#blogdescription', + 'Just another Gutenberg site' + ); + await page.click( 'input#submit' ); + + const optionsAfter = await getOptionsValues( optionsInputsSelector ); + + Object.entries( optionsBefore ).forEach( ( optionBefore ) => { + const [ id ] = optionBefore; + const optionAfter = [ id, optionsAfter[ id ] ]; + expect( optionAfter ).toStrictEqual( optionBefore ); + } ); + } ); +} ); From b422e35fbf0451201667b072ab53527cf460f8f4 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Sat, 26 Jun 2021 12:46:02 +0800 Subject: [PATCH 17/64] Unregister default block in customizer to be able to empty widget areas (#32979) --- packages/block-editor/src/store/actions.js | 12 +++++++ .../src/components/block-appender/index.js | 33 +++++++++++++++++++ .../components/sidebar-block-editor/index.js | 7 ++-- 3 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 packages/customize-widgets/src/components/block-appender/index.js diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index f72b7a942d31ad..23ef155e31aff3 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -44,6 +44,18 @@ function* ensureDefaultBlock() { // To avoid a focus loss when removing the last block, assure there is // always a default block if the last of the blocks have been removed. if ( count === 0 ) { + const { __unstableHasCustomAppender } = yield controls.select( + blockEditorStoreName, + 'getSettings' + ); + + // If there's an custom appender, don't insert default block. + // We have to remember to manually move the focus elsewhere to + // prevent it from being lost though. + if ( __unstableHasCustomAppender ) { + return; + } + return yield insertDefaultBlock(); } } diff --git a/packages/customize-widgets/src/components/block-appender/index.js b/packages/customize-widgets/src/components/block-appender/index.js new file mode 100644 index 00000000000000..b8a068f4f697e9 --- /dev/null +++ b/packages/customize-widgets/src/components/block-appender/index.js @@ -0,0 +1,33 @@ +/** + * WordPress dependencies + */ +import { useRef, useEffect } from '@wordpress/element'; +import { + ButtonBlockAppender, + store as blockEditorStore, +} from '@wordpress/block-editor'; +import { useSelect } from '@wordpress/data'; + +export default function BlockAppender( props ) { + const ref = useRef(); + const isBlocksListEmpty = useSelect( + ( select ) => select( blockEditorStore ).getBlockCount() === 0 + ); + + // Move the focus to the block appender to prevent focus from + // being lost when emptying the widget area. + useEffect( () => { + if ( isBlocksListEmpty && ref.current ) { + const { ownerDocument } = ref.current; + + if ( + ! ownerDocument.activeElement || + ownerDocument.activeElement === ownerDocument.body + ) { + ref.current.focus(); + } + } + }, [ isBlocksListEmpty ] ); + + return ; +} diff --git a/packages/customize-widgets/src/components/sidebar-block-editor/index.js b/packages/customize-widgets/src/components/sidebar-block-editor/index.js index 40592021000aff..3ba3fa0b1799a2 100644 --- a/packages/customize-widgets/src/components/sidebar-block-editor/index.js +++ b/packages/customize-widgets/src/components/sidebar-block-editor/index.js @@ -18,7 +18,6 @@ import { WritingFlow, BlockEditorKeyboardShortcuts, __unstableBlockSettingsMenuFirstItem, - ButtonBlockAppender, } from '@wordpress/block-editor'; import { uploadMedia } from '@wordpress/media-utils'; @@ -32,6 +31,7 @@ import SidebarEditorProvider from './sidebar-editor-provider'; import { store as customizeWidgetsStore } from '../../store'; import WelcomeGuide from '../welcome-guide'; import KeyboardShortcuts from '../keyboard-shortcuts'; +import BlockAppender from '../block-appender'; export default function SidebarBlockEditor( { blockEditorSettings, @@ -80,6 +80,7 @@ export default function SidebarBlockEditor( { mediaUpload: mediaUploadBlockEditor, hasFixedToolbar: isFixedToolbarActive, keepCaretInsideBlock, + __unstableHasCustomAppender: true, }; }, [ hasUploadPermissions, @@ -117,9 +118,7 @@ export default function SidebarBlockEditor( { - + From 69c689ac07df3f70cc7d02c31b5830b2e46c0347 Mon Sep 17 00:00:00 2001 From: Jorge Date: Sat, 26 Jun 2021 14:32:25 +0100 Subject: [PATCH 18/64] chore(release): publish - @wordpress/block-directory@2.1.11 - @wordpress/block-editor@6.1.6 - @wordpress/block-library@3.2.9 - @wordpress/customize-widgets@1.0.10 - @wordpress/e2e-tests@2.2.9 - @wordpress/edit-navigation@1.9.9 - @wordpress/edit-post@4.1.11 - @wordpress/edit-site@2.1.11 - @wordpress/edit-widgets@2.1.11 - @wordpress/editor@10.1.9 - @wordpress/format-library@2.1.6 - @wordpress/react-native-editor@1.53.10 - @wordpress/reusable-blocks@2.1.9 - @wordpress/widgets@1.1.10 --- packages/block-directory/package.json | 2 +- packages/block-editor/package.json | 2 +- packages/block-library/package.json | 2 +- packages/customize-widgets/package.json | 2 +- packages/e2e-tests/package.json | 2 +- packages/edit-navigation/package.json | 2 +- packages/edit-post/package.json | 2 +- packages/edit-site/package.json | 2 +- packages/edit-widgets/package.json | 2 +- packages/editor/package.json | 2 +- packages/format-library/package.json | 2 +- packages/reusable-blocks/package.json | 2 +- packages/widgets/package.json | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index 08ea4fc906f099..6c5f4dd6d61d6d 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-directory", - "version": "2.1.10", + "version": "2.1.11", "description": "Extend editor with block directory features to search, download and install blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index abb91a79a345c5..da04ab4d91fd45 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-editor", - "version": "6.1.5", + "version": "6.1.6", "description": "Generic block editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 70ba354f0fa2c9..d162caa53882d2 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "3.2.8", + "version": "3.2.9", "description": "Block library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/customize-widgets/package.json b/packages/customize-widgets/package.json index 99aef1da9c06b4..2bb82278059daf 100644 --- a/packages/customize-widgets/package.json +++ b/packages/customize-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/customize-widgets", - "version": "1.0.9", + "version": "1.0.10", "description": "Widgets blocks in Customizer Module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-tests/package.json b/packages/e2e-tests/package.json index faa1059d4c7a82..8f09145bd32549 100644 --- a/packages/e2e-tests/package.json +++ b/packages/e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-tests", - "version": "2.2.8", + "version": "2.2.9", "description": "End-To-End (E2E) tests for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-navigation/package.json b/packages/edit-navigation/package.json index b879d4b4e39258..57f3f8fb667ded 100644 --- a/packages/edit-navigation/package.json +++ b/packages/edit-navigation/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-navigation", - "version": "1.9.8", + "version": "1.9.9", "private": true, "description": "Module for the Navigation page in WordPress.", "author": "The WordPress Contributors", diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index bd88ff14f1882b..23a2e3b7c985d3 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-post", - "version": "4.1.10", + "version": "4.1.11", "description": "Edit Post module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index 56f7d31ec6907c..14e9ae57e3feab 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-site", - "version": "2.1.10", + "version": "2.1.11", "description": "Edit Site Page module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-widgets/package.json b/packages/edit-widgets/package.json index b8e102fd81e0f9..03c1f77be927f3 100644 --- a/packages/edit-widgets/package.json +++ b/packages/edit-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-widgets", - "version": "2.1.10", + "version": "2.1.11", "description": "Widgets Page module for WordPress..", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/editor/package.json b/packages/editor/package.json index b02b17d279c6c1..06f80bdab60439 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/editor", - "version": "10.1.8", + "version": "10.1.9", "description": "Enhanced block editor for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/format-library/package.json b/packages/format-library/package.json index ed6aa65c20b5a2..756b059cfc1e10 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/format-library", - "version": "2.1.5", + "version": "2.1.6", "description": "Format library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/reusable-blocks/package.json b/packages/reusable-blocks/package.json index bcddbb9fc1b30d..701d932237df4d 100644 --- a/packages/reusable-blocks/package.json +++ b/packages/reusable-blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/reusable-blocks", - "version": "2.1.8", + "version": "2.1.9", "description": "Reusable blocks utilities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/widgets/package.json b/packages/widgets/package.json index fb9d0352547453..3bfe799ec13c66 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/widgets", - "version": "1.1.9", + "version": "1.1.10", "description": "Functionality used by the widgets block editor in the Widgets screen and the Customizer.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From 52d49b65bc3a0bee4e022b566835471170cd4ab0 Mon Sep 17 00:00:00 2001 From: Jorge Date: Fri, 25 Jun 2021 16:06:14 +0100 Subject: [PATCH 19/64] chore(release): publish - @wordpress/block-directory@2.1.12 - @wordpress/block-editor@6.1.7 - @wordpress/block-library@3.2.10 - @wordpress/core-data@3.1.8 - @wordpress/customize-widgets@1.0.11 - @wordpress/edit-navigation@1.9.10 - @wordpress/edit-post@4.1.12 - @wordpress/edit-site@2.1.12 - @wordpress/edit-widgets@2.1.12 - @wordpress/editor@10.1.10 - @wordpress/format-library@2.1.7 - @wordpress/react-native-editor@1.53.11 - @wordpress/reusable-blocks@2.1.10 - @wordpress/widgets@1.1.11 --- packages/block-directory/package.json | 2 +- packages/block-editor/package.json | 2 +- packages/block-library/package.json | 2 +- packages/core-data/package.json | 2 +- packages/customize-widgets/package.json | 2 +- packages/edit-navigation/package.json | 2 +- packages/edit-post/package.json | 2 +- packages/edit-site/package.json | 2 +- packages/edit-widgets/package.json | 2 +- packages/editor/package.json | 2 +- packages/format-library/package.json | 2 +- packages/reusable-blocks/package.json | 2 +- packages/widgets/package.json | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index 6c5f4dd6d61d6d..eb7490310bf41d 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-directory", - "version": "2.1.11", + "version": "2.1.12", "description": "Extend editor with block directory features to search, download and install blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index da04ab4d91fd45..616249c2feed60 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-editor", - "version": "6.1.6", + "version": "6.1.7", "description": "Generic block editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-library/package.json b/packages/block-library/package.json index d162caa53882d2..2a7855fa1d5a87 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "3.2.9", + "version": "3.2.10", "description": "Block library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/core-data/package.json b/packages/core-data/package.json index 5282d06d7af5b7..c774e0927971d0 100644 --- a/packages/core-data/package.json +++ b/packages/core-data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/core-data", - "version": "3.1.7", + "version": "3.1.8", "description": "Access to and manipulation of core WordPress entities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/customize-widgets/package.json b/packages/customize-widgets/package.json index 2bb82278059daf..d3542e120e15f4 100644 --- a/packages/customize-widgets/package.json +++ b/packages/customize-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/customize-widgets", - "version": "1.0.10", + "version": "1.0.11", "description": "Widgets blocks in Customizer Module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-navigation/package.json b/packages/edit-navigation/package.json index 57f3f8fb667ded..22c281185675e1 100644 --- a/packages/edit-navigation/package.json +++ b/packages/edit-navigation/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-navigation", - "version": "1.9.9", + "version": "1.9.10", "private": true, "description": "Module for the Navigation page in WordPress.", "author": "The WordPress Contributors", diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index 23a2e3b7c985d3..1faa6d09fb5d01 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-post", - "version": "4.1.11", + "version": "4.1.12", "description": "Edit Post module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index 14e9ae57e3feab..5e8927afeab710 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-site", - "version": "2.1.11", + "version": "2.1.12", "description": "Edit Site Page module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-widgets/package.json b/packages/edit-widgets/package.json index 03c1f77be927f3..65418504de58c3 100644 --- a/packages/edit-widgets/package.json +++ b/packages/edit-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-widgets", - "version": "2.1.11", + "version": "2.1.12", "description": "Widgets Page module for WordPress..", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/editor/package.json b/packages/editor/package.json index 06f80bdab60439..c7404158e8e9b3 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/editor", - "version": "10.1.9", + "version": "10.1.10", "description": "Enhanced block editor for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/format-library/package.json b/packages/format-library/package.json index 756b059cfc1e10..1a9d38039fc826 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/format-library", - "version": "2.1.6", + "version": "2.1.7", "description": "Format library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/reusable-blocks/package.json b/packages/reusable-blocks/package.json index 701d932237df4d..7386949eb33e5f 100644 --- a/packages/reusable-blocks/package.json +++ b/packages/reusable-blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/reusable-blocks", - "version": "2.1.9", + "version": "2.1.10", "description": "Reusable blocks utilities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/widgets/package.json b/packages/widgets/package.json index 3bfe799ec13c66..48e2a2e6933751 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/widgets", - "version": "1.1.10", + "version": "1.1.11", "description": "Functionality used by the widgets block editor in the Widgets screen and the Customizer.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From 98d1fd7684a42ba61b03280dae287c2a4be61783 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Mon, 28 Jun 2021 13:19:41 +1000 Subject: [PATCH 20/64] Set display only when form not hidden (#33015) --- packages/widgets/src/blocks/legacy-widget/editor.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/widgets/src/blocks/legacy-widget/editor.scss b/packages/widgets/src/blocks/legacy-widget/editor.scss index 72c15ff32a6b16..5ad552605f9971 100644 --- a/packages/widgets/src/blocks/legacy-widget/editor.scss +++ b/packages/widgets/src/blocks/legacy-widget/editor.scss @@ -1,5 +1,7 @@ .wp-block-legacy-widget__edit-form { - display: flow-root; + &:not([hidden]) { + display: flow-root; + } background: $white; border-radius: $radius-block-ui; border: 1px solid $gray-900; From 96a87816f9dad9ac87f9be279d31e019685a44e2 Mon Sep 17 00:00:00 2001 From: Tom Cafferkey Date: Mon, 28 Jun 2021 04:42:01 +0100 Subject: [PATCH 21/64] Use isValidHref in addLink function to check validity of selected text (#32663) * Use isValidHref in addLink function to check validity of selected text * Add isValidHref to React Native occurrence of file. * Add E2E test coverage for Links when selected text is not a valid URL * Update E2E test --- .../specs/editor/various/links.test.js | 21 +++++++++++++++++++ packages/format-library/src/link/index.js | 3 ++- .../format-library/src/link/index.native.js | 3 ++- .../format-library/src/link/test/utils.js | 1 + 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/e2e-tests/specs/editor/various/links.test.js b/packages/e2e-tests/specs/editor/various/links.test.js index 2b422916562753..1be82dab150345 100644 --- a/packages/e2e-tests/specs/editor/various/links.test.js +++ b/packages/e2e-tests/specs/editor/various/links.test.js @@ -81,6 +81,27 @@ describe( 'Links', () => { expect( await getEditedPostContent() ).toMatchSnapshot(); } ); + it( 'will not automatically create a link if selected text is not a valid HTTP based URL', async () => { + // Create a block with some text + await clickBlockAppender(); + await page.keyboard.type( 'This: is not a link' ); + + // Select some text + await pressKeyWithModifier( 'shiftAlt', 'ArrowLeft' ); + + // Click on the Link button + await page.click( 'button[aria-label="Link"]' ); + + // Wait for the URL field to auto-focus + await waitForAutoFocus(); + + const urlInputValue = await page.evaluate( + () => document.querySelector( '[aria-label="URL"]' ).value + ); + + expect( urlInputValue ).toBe( '' ); + } ); + it( 'can be created by selecting text and using keyboard shortcuts', async () => { // Create a block with some text await clickBlockAppender(); diff --git a/packages/format-library/src/link/index.js b/packages/format-library/src/link/index.js index e56e93f1743c45..5fe0067087dbd0 100644 --- a/packages/format-library/src/link/index.js +++ b/packages/format-library/src/link/index.js @@ -23,6 +23,7 @@ import { speak } from '@wordpress/a11y'; * Internal dependencies */ import InlineLinkUI from './inline'; +import { isValidHref } from './utils'; const name = 'core/link'; const title = __( 'Link' ); @@ -40,7 +41,7 @@ function Edit( { function addLink() { const text = getTextContent( slice( value ) ); - if ( text && isURL( text ) ) { + if ( text && isURL( text ) && isValidHref( text ) ) { onChange( applyFormat( value, { type: name, diff --git a/packages/format-library/src/link/index.native.js b/packages/format-library/src/link/index.native.js index 2c49c4a98a5775..e79ed696aea37d 100644 --- a/packages/format-library/src/link/index.native.js +++ b/packages/format-library/src/link/index.native.js @@ -26,6 +26,7 @@ import { link as linkIcon } from '@wordpress/icons'; * Internal dependencies */ import ModalLinkUI from './modal'; +import { isValidHref } from './utils'; const name = 'core/link'; @@ -58,7 +59,7 @@ export const link = { const { value, onChange } = this.props; const text = getTextContent( slice( value ) ); - if ( text && isURL( text ) ) { + if ( text && isURL( text ) && isValidHref( text ) ) { const newValue = applyFormat( value, { type: name, attributes: { url: text }, diff --git a/packages/format-library/src/link/test/utils.js b/packages/format-library/src/link/test/utils.js index 7ae7c1b3ad10c6..0cad99eed3245a 100644 --- a/packages/format-library/src/link/test/utils.js +++ b/packages/format-library/src/link/test/utils.js @@ -74,6 +74,7 @@ describe( 'isValidHref', () => { expect( isValidHref( 'http://test.com/eeee#qwd qwdw' ) ).toBe( false ); + expect( isValidHref( 'this: is invalid' ) ).toBe( false ); } ); } ); From a6314ffd2d87e55ac8bafa6be668027da4d894d3 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Mon, 28 Jun 2021 16:57:58 +1000 Subject: [PATCH 22/64] Disable flakey multi-entity-editing tests --- .../specs/experiments/multi-entity-editing.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js b/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js index e23c5180828d27..e239d9a5cffba0 100644 --- a/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js +++ b/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js @@ -244,7 +244,7 @@ describe( 'Multi-entity editor states', () => { removeErrorMocks(); }; - it( 'should only dirty the parent entity when editing the parent', async () => { + it.skip( 'should only dirty the parent entity when editing the parent', async () => { // Clear selection so that the block is not added to the template part. await insertBlock( 'Paragraph' ); @@ -257,7 +257,7 @@ describe( 'Multi-entity editor states', () => { await saveAndWaitResponse(); } ); - it( 'should only dirty the child when editing the child', async () => { + it.skip( 'should only dirty the child when editing the child', async () => { // Select parent TP to unlock selecting content. await canvas().click( '.wp-block-template-part' ); await canvas().click( @@ -271,7 +271,7 @@ describe( 'Multi-entity editor states', () => { await saveAndWaitResponse(); } ); - it( 'should only dirty the nested entity when editing the nested entity', async () => { + it.skip( 'should only dirty the nested entity when editing the nested entity', async () => { // Select parent TP to unlock selecting child. await canvas().click( '.wp-block-template-part' ); // Select child TP to unlock selecting content. @@ -289,7 +289,7 @@ describe( 'Multi-entity editor states', () => { await saveAndWaitResponse(); } ); - it( 'should not allow selecting template part content without parent selected', async () => { + it.skip( 'should not allow selecting template part content without parent selected', async () => { // Unselect blocks. await selectBlockByClientId(); // Try to select a child block of a template part. From 8d3db371b033d4e331702a7a837978fac79e82ca Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Mon, 28 Jun 2021 10:32:26 +0200 Subject: [PATCH 23/64] Polish block manager search. (#32922) --- .../edit-post/src/components/block-manager/index.js | 13 +++++++++++-- .../src/components/preferences-modal/index.js | 5 +++-- .../test/__snapshots__/index.js.snap | 3 ++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/edit-post/src/components/block-manager/index.js b/packages/edit-post/src/components/block-manager/index.js index 9daddf3eae7808..8dc3aea8ec91dc 100644 --- a/packages/edit-post/src/components/block-manager/index.js +++ b/packages/edit-post/src/components/block-manager/index.js @@ -8,9 +8,10 @@ import { filter, includes, isArray } from 'lodash'; */ import { store as blocksStore } from '@wordpress/blocks'; import { withSelect } from '@wordpress/data'; -import { TextControl } from '@wordpress/components'; +import { VisuallyHidden, TextControl } from '@wordpress/components'; import { __, _n, sprintf } from '@wordpress/i18n'; import { useState } from '@wordpress/element'; +import { useInstanceId } from '@wordpress/compose'; /** * Internal dependencies @@ -26,6 +27,7 @@ function BlockManager( { numberOfHiddenBlocks, } ) { const [ search, setSearch ] = useState( '' ); + const instanceId = useInstanceId( BlockManager ); // Filtering occurs here (as opposed to `withSelect`) to avoid // wasted renders by consequence of `Array#filter` producing @@ -53,9 +55,16 @@ function BlockManager( { ) }
) } + + { __( 'Search for a block' ) } + setSearch( nextSearch ) } className="edit-post-block-manager__search" diff --git a/packages/edit-post/src/components/preferences-modal/index.js b/packages/edit-post/src/components/preferences-modal/index.js index 5b79d6f2cec743..eec907a073ed62 100644 --- a/packages/edit-post/src/components/preferences-modal/index.js +++ b/packages/edit-post/src/components/preferences-modal/index.js @@ -172,8 +172,9 @@ export default function PreferencesModal() { />
diff --git a/packages/edit-post/src/components/preferences-modal/test/__snapshots__/index.js.snap b/packages/edit-post/src/components/preferences-modal/test/__snapshots__/index.js.snap index ccf0feb5585742..93b38fe63759ae 100644 --- a/packages/edit-post/src/components/preferences-modal/test/__snapshots__/index.js.snap +++ b/packages/edit-post/src/components/preferences-modal/test/__snapshots__/index.js.snap @@ -145,7 +145,8 @@ exports[`PreferencesModal should match snapshot when the modal is active small v />
From d2111e0d6aa57fa0129cee7f3cb19a9ef9c35bc3 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Mon, 28 Jun 2021 12:02:05 +0100 Subject: [PATCH 24/64] Implement basic in memory cache for rich link previews data (#32741) * Implement closer to API layer using Map * Only cache successful responses. * Adds automated test coverage * Directly return promise chain Co-authored-by: Kai Hao * Rename default import for clarity Co-authored-by: Kai Hao --- .../__experimental-fetch-remote-url-data.js | 14 ++ .../__experimental-fetch-remote-url-data.js | 121 ++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 packages/core-data/src/fetch/test/__experimental-fetch-remote-url-data.js diff --git a/packages/core-data/src/fetch/__experimental-fetch-remote-url-data.js b/packages/core-data/src/fetch/__experimental-fetch-remote-url-data.js index c9210c009bc74d..656c41a6a0d07a 100644 --- a/packages/core-data/src/fetch/__experimental-fetch-remote-url-data.js +++ b/packages/core-data/src/fetch/__experimental-fetch-remote-url-data.js @@ -4,6 +4,13 @@ import apiFetch from '@wordpress/api-fetch'; import { addQueryArgs, prependHTTP } from '@wordpress/url'; +/** + * A simple in-memory cache for requests. + * This avoids repeat HTTP requests which may be beneficial + * for those wishing to preserve low-bandwidth. + */ +const CACHE = new Map(); + /** * @typedef WPRemoteUrlData * @@ -38,9 +45,16 @@ const fetchRemoteUrlData = async ( url, options = {} ) => { url: prependHTTP( url ), }; + if ( CACHE.has( url ) ) { + return CACHE.get( url ); + } + return apiFetch( { path: addQueryArgs( endpoint, args ), ...options, + } ).then( ( res ) => { + CACHE.set( url, res ); + return res; } ); }; diff --git a/packages/core-data/src/fetch/test/__experimental-fetch-remote-url-data.js b/packages/core-data/src/fetch/test/__experimental-fetch-remote-url-data.js new file mode 100644 index 00000000000000..0ea3ec4c39a557 --- /dev/null +++ b/packages/core-data/src/fetch/test/__experimental-fetch-remote-url-data.js @@ -0,0 +1,121 @@ +/** + * Internal dependencies + */ +import fetchRemoteUrlData from '../__experimental-fetch-remote-url-data'; +/** + * WordPress dependencies + */ +import apiFetch from '@wordpress/api-fetch'; + +jest.mock( '@wordpress/api-fetch' ); + +describe( 'fetchRemoteUrlData', () => { + afterEach( () => { + apiFetch.mockReset(); + } ); + + describe( 'return value settles as expected', () => { + it( 'resolves with response data upon fetch success', async () => { + const data = { + title: 'Lorem ipsum dolor', + icon: '', + image: '', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + }; + apiFetch.mockReturnValueOnce( Promise.resolve( data ) ); + + await expect( + fetchRemoteUrlData( 'https://www.wordpress.org' ) + ).resolves.toEqual( data ); + + expect( apiFetch ).toBeCalledTimes( 1 ); + } ); + + it( 'rejects with error upon fetch failure', async () => { + apiFetch.mockReturnValueOnce( Promise.reject( 'fetch failed' ) ); + + await expect( + fetchRemoteUrlData( 'https://www.wordpress.org/1' ) + ).rejects.toEqual( 'fetch failed' ); + } ); + } ); + + describe( 'interaction with underlying fetch API', () => { + it( 'passes options argument through to fetch API', async () => { + apiFetch.mockReturnValueOnce( Promise.resolve() ); + + await fetchRemoteUrlData( 'https://www.wordpress.org/2', { + method: 'POST', + } ); + + expect( apiFetch ).toBeCalledTimes( 1 ); + + const argsPassedToFetchApi = apiFetch.mock.calls[ 0 ][ 0 ]; + + expect( argsPassedToFetchApi ).toEqual( + expect.objectContaining( { + method: 'POST', + } ) + ); + } ); + } ); + + describe( 'client side caching', () => { + it( 'caches repeat requests to same url', async () => { + const targetUrl = 'https://www.wordpress.org/3'; + const data = { + title: 'Lorem ipsum dolor', + icon: '', + image: '', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + }; + apiFetch.mockReturnValueOnce( Promise.resolve( data ) ); + + await expect( fetchRemoteUrlData( targetUrl ) ).resolves.toEqual( + data + ); + expect( apiFetch ).toBeCalledTimes( 1 ); + + // Allow us to reassert on calls without it being polluted by first fetch + // but retains the mock implementation from earlier. + apiFetch.mockClear(); + + // Fetch the same URL again...should be cached. + await expect( fetchRemoteUrlData( targetUrl ) ).resolves.toEqual( + data + ); + + // Should now be in cache so no need to refetch from API. + expect( apiFetch ).toBeCalledTimes( 0 ); + } ); + + it( 'does not cache failed requests', async () => { + const targetUrl = 'https://www.wordpress.org/4'; + const data = { + title: 'Lorem ipsum dolor', + icon: '', + image: '', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + }; + + apiFetch + .mockReturnValueOnce( Promise.reject( 'fetch failed' ) ) + .mockReturnValueOnce( Promise.resolve( data ) ); + + await expect( fetchRemoteUrlData( targetUrl ) ).rejects.toEqual( + 'fetch failed' + ); + + // Cache should not store the previous failed fetch and should retry + // with a new fetch. + await expect( fetchRemoteUrlData( targetUrl ) ).resolves.toEqual( + data + ); + + expect( apiFetch ).toBeCalledTimes( 2 ); + } ); + } ); +} ); From 962e084b91762058706e64c8b01271e795f17f6f Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 28 Jun 2021 19:40:12 +0800 Subject: [PATCH 25/64] Fix drag and drop indicator above first block and RTL drop indicators (#33024) * Update logic * RTL and block appender fixes * Fix RTL positioning calculations * Avoid adding wp-block to the appender --- .../components/block-list-appender/index.js | 6 +- .../components/block-tools/insertion-point.js | 73 +++++++++++-------- .../components/use-block-drop-zone/index.js | 10 ++- 3 files changed, 54 insertions(+), 35 deletions(-) diff --git a/packages/block-editor/src/components/block-list-appender/index.js b/packages/block-editor/src/components/block-list-appender/index.js index 9ad8ff2ee624e0..28b96308abd781 100644 --- a/packages/block-editor/src/components/block-list-appender/index.js +++ b/packages/block-editor/src/components/block-list-appender/index.js @@ -94,11 +94,7 @@ function BlockListAppender( { // Prevent the block from being selected when the appender is // clicked. onFocus={ stopPropagation } - className={ classnames( - 'block-list-appender', - 'wp-block', - className - ) } + className={ classnames( 'block-list-appender', className ) } > { appender } diff --git a/packages/block-editor/src/components/block-tools/insertion-point.js b/packages/block-editor/src/components/block-tools/insertion-point.js index b836beba7d3ae0..3739e81ff9ad0c 100644 --- a/packages/block-editor/src/components/block-tools/insertion-point.js +++ b/packages/block-editor/src/components/block-tools/insertion-point.js @@ -79,24 +79,33 @@ function InsertionPointPopover( { }, [] ); const previousElement = useBlockElement( previousClientId ); const nextElement = useBlockElement( nextClientId ); + const style = useMemo( () => { - if ( ! previousElement ) { + if ( ! previousElement && ! nextElement ) { return {}; } - const previousRect = previousElement.getBoundingClientRect(); + + const previousRect = previousElement + ? previousElement.getBoundingClientRect() + : null; const nextRect = nextElement ? nextElement.getBoundingClientRect() : null; if ( orientation === 'vertical' ) { return { - width: previousElement.offsetWidth, - height: nextRect ? nextRect.top - previousRect.bottom : 0, + width: previousElement + ? previousElement.offsetWidth + : nextElement.offsetWidth, + height: + nextRect && previousRect + ? nextRect.top - previousRect.bottom + : 0, }; } let width = 0; - if ( nextElement ) { + if ( previousRect && nextRect ) { width = isRTL() ? previousRect.left - nextRect.right : nextRect.left - previousRect.right; @@ -104,31 +113,41 @@ function InsertionPointPopover( { return { width, - height: previousElement.offsetHeight, + height: previousElement + ? previousElement.offsetHeight + : nextElement.offsetHeight, }; }, [ previousElement, nextElement ] ); const getAnchorRect = useCallback( () => { - const { ownerDocument } = previousElement; - const previousRect = previousElement.getBoundingClientRect(); + if ( ! previousElement && ! nextElement ) { + return {}; + } + + const { ownerDocument } = previousElement || nextElement; + + const previousRect = previousElement + ? previousElement.getBoundingClientRect() + : null; const nextRect = nextElement ? nextElement.getBoundingClientRect() : null; + if ( orientation === 'vertical' ) { if ( isRTL() ) { return { - top: previousRect.bottom, - left: previousRect.right, - right: previousRect.left, + top: previousRect ? previousRect.bottom : nextRect.top, + left: previousRect ? previousRect.right : nextRect.right, + right: previousRect ? previousRect.left : nextRect.left, bottom: nextRect ? nextRect.top : previousRect.bottom, ownerDocument, }; } return { - top: previousRect.bottom, - left: previousRect.left, - right: previousRect.right, + top: previousRect ? previousRect.bottom : nextRect.top, + left: previousRect ? previousRect.left : nextRect.left, + right: previousRect ? previousRect.right : nextRect.right, bottom: nextRect ? nextRect.top : previousRect.bottom, ownerDocument, }; @@ -136,29 +155,25 @@ function InsertionPointPopover( { if ( isRTL() ) { return { - top: previousRect.top, - left: nextRect ? nextRect.right : previousRect.left, - right: previousRect.left, - bottom: previousRect.bottom, + top: previousRect ? previousRect.top : nextRect.top, + left: previousRect ? previousRect.left : nextRect.right, + right: nextRect ? nextRect.right : previousRect.left, + bottom: previousRect ? previousRect.bottom : nextRect.bottom, ownerDocument, }; } return { - top: previousRect.top, - left: previousRect.right, + top: previousRect ? previousRect.top : nextRect.top, + left: previousRect ? previousRect.right : nextRect.left, right: nextRect ? nextRect.left : previousRect.right, - bottom: previousRect.bottom, + bottom: previousRect ? previousRect.bottom : nextRect.bottom, ownerDocument, }; }, [ previousElement, nextElement ] ); const popoverScrollRef = usePopoverScroll( __unstableContentRef ); - if ( ! previousElement ) { - return null; - } - const className = classnames( 'block-editor-block-list__insertion-point', 'is-' + orientation @@ -178,10 +193,10 @@ function InsertionPointPopover( { } } - // Only show the inserter when there's a `nextElement` (a block after the - // insertion point). At the end of the block list the trailing appender - // should serve the purpose of inserting blocks. - const showInsertionPointInserter = nextElement && isInserterShown; + // Only show the in-between inserter between blocks, so when there's a + // previous and a next element. + const showInsertionPointInserter = + previousElement && nextElement && isInserterShown; /* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */ // While ideally it would be enough to capture the diff --git a/packages/block-editor/src/components/use-block-drop-zone/index.js b/packages/block-editor/src/components/use-block-drop-zone/index.js index a034f1af2d7e7b..f9edab72733537 100644 --- a/packages/block-editor/src/components/use-block-drop-zone/index.js +++ b/packages/block-editor/src/components/use-block-drop-zone/index.js @@ -7,6 +7,7 @@ import { useThrottle, __experimentalUseDropZone as useDropZone, } from '@wordpress/compose'; +import { isRTL } from '@wordpress/i18n'; /** * Internal dependencies @@ -39,6 +40,8 @@ export function getNearestBlockIndex( elements, position, orientation ) { ? [ 'left', 'right' ] : [ 'top', 'bottom' ]; + const isRightToLeft = isRTL(); + let candidateIndex; let candidateDistance; @@ -53,7 +56,12 @@ export function getNearestBlockIndex( elements, position, orientation ) { if ( candidateDistance === undefined || distance < candidateDistance ) { // If the user is dropping to the trailing edge of the block // add 1 to the index to represent dragging after. - const isTrailingEdge = edge === 'bottom' || edge === 'right'; + // Take RTL languages into account where the left edge is + // the trailing edge. + const isTrailingEdge = + edge === 'bottom' || + ( ! isRightToLeft && edge === 'right' ) || + ( isRightToLeft && edge === 'left' ); const offset = isTrailingEdge ? 1 : 0; // Update the currently known best candidate. From 70bc14e9604e7f528de168d87b953a1f83ffd836 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Mon, 28 Jun 2021 14:21:12 +0200 Subject: [PATCH 26/64] RNMobile] Fix wp.data.select deprecation warning (#32957) Some selectors are deprecated in the editor store and now require to use the block editor store. --- .../src/components/header/header-toolbar/index.native.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/edit-post/src/components/header/header-toolbar/index.native.js b/packages/edit-post/src/components/header/header-toolbar/index.native.js index ad741f320a9ecf..ca22da5ecfc28c 100644 --- a/packages/edit-post/src/components/header/header-toolbar/index.native.js +++ b/packages/edit-post/src/components/header/header-toolbar/index.native.js @@ -115,8 +115,8 @@ export default compose( [ getBlockRootClientId, getBlockSelectionEnd, hasInserterItems, - getEditorSettings, - } = select( editorStore ); + } = select( blockEditorStore ); + const { getEditorSettings } = select( editorStore ); return { hasRedo: select( editorStore ).hasEditorRedo(), hasUndo: select( editorStore ).hasEditorUndo(), From 7e0689e8d6e96ba5524827d7a3af6fc540e5a9bb Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Mon, 28 Jun 2021 22:57:54 +1000 Subject: [PATCH 27/64] Widgets: Fix creating and editing non-multi widgets (#32978) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Widgets: Fix creating and editing non-multi widgets * Add regression e2e tests * Lint * Lint * Deactivate gutenberg-test-marquee-widget after test runs Co-authored-by: Adam Zieliński --- .../plugins/marquee-function-widget.php | 51 ++++++++ .../specs/widgets/editing-widgets.test.js | 109 +++++++++++++++++- packages/edit-widgets/src/store/actions.js | 9 +- .../src/blocks/legacy-widget/edit/control.js | 17 ++- .../src/blocks/legacy-widget/edit/index.js | 3 +- 5 files changed, 183 insertions(+), 6 deletions(-) create mode 100644 packages/e2e-tests/plugins/marquee-function-widget.php diff --git a/packages/e2e-tests/plugins/marquee-function-widget.php b/packages/e2e-tests/plugins/marquee-function-widget.php new file mode 100644 index 00000000000000..43b4f15661772f --- /dev/null +++ b/packages/e2e-tests/plugins/marquee-function-widget.php @@ -0,0 +1,51 @@ +%s', esc_html( $greeting ) ); + } + ); + + wp_register_widget_control( + 'marquee_greeting', + 'Marquee Greeting', + function() { + if ( isset( $_POST['marquee-greeting'] ) ) { + update_option( + 'marquee_greeting', + sanitize_text_field( $_POST['marquee-greeting'] ) + ); + } + + $greeting = get_option( 'marquee_greeting' ); + ?> +

+ + +

+ { @@ -394,6 +394,111 @@ describe( 'Widgets screen', () => { ` ); } ); + async function addMarquee() { + // There will be 2 matches here. + // One is the in-between inserter, + // and the other one is the button block appender. + const [ inlineInserterButton ] = await findAll( { + role: 'combobox', + name: 'Add block', + } ); + await inlineInserterButton.click(); + + // TODO: Convert to find() API from puppeteer-testing-library. + const inserterSearchBox = await page.waitForSelector( + 'aria/Search for blocks and patterns[role="searchbox"]' + ); + await expect( inserterSearchBox ).toHaveFocus(); + + await page.keyboard.type( 'Marquee' ); + + const inlineQuickInserter = await find( { + role: 'listbox', + name: 'Blocks', + } ); + const marqueeBlockOption = await find( + { + role: 'option', + }, + { + root: inlineQuickInserter, + } + ); + await marqueeBlockOption.click(); + } + + it( 'Should add and save the marquee widget', async () => { + await activatePlugin( 'gutenberg-test-marquee-widget' ); + await visitAdminPage( 'widgets.php' ); + + await addMarquee(); + + await find( { + selector: '[data-block][data-type="core/legacy-widget"]', + } ); + + const greetingsInput = await find( { + selector: '#marquee-greeting', + } ); + await greetingsInput.click(); + await page.keyboard.type( 'Howdy' ); + + await saveWidgets(); + + let editedSerializedWidgetAreas = await getSerializedWidgetAreas(); + await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( ` + Object { + "sidebar-1": "Hello!", + } + ` ); + + await page.reload(); + + editedSerializedWidgetAreas = await getSerializedWidgetAreas(); + await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( ` + Object { + "sidebar-1": "Hello!", + } + ` ); + + // Add another marquee, it shouldn't be saved + await addMarquee(); + + // It takes a moment to load the form, let's wait for it. + await waitFor( async () => { + const marquees = await findAll( { + selector: '[id=marquee-greeting]', + } ); + if ( marquees.length === 1 ) { + throw new Error(); + } + } ); + + const marquees = await findAll( { + selector: '[id=marquee-greeting]', + } ); + + expect( marquees ).toHaveLength( 2 ); + await marquees[ 1 ].click(); + await page.keyboard.type( 'Second howdy' ); + + await saveWidgets(); + editedSerializedWidgetAreas = await getSerializedWidgetAreas(); + await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( ` + Object { + "sidebar-1": "Hello!", + } + ` ); + + await page.reload(); + const marqueesAfter = await findAll( { + selector: '[id=marquee-greeting]', + } ); + expect( marqueesAfter ).toHaveLength( 1 ); + + await deactivatePlugin( 'gutenberg-test-marquee-widget' ); + } ); + // Disable reason: We temporary skip this test until we can figure out why it fails sometimes. // eslint-disable-next-line jest/no-disabled-tests it.skip( 'Should duplicate the widgets', async () => { @@ -423,6 +528,7 @@ describe( 'Widgets screen', () => { "sidebar-1": "

First Paragraph

", + "wp_inactive_widgets": "", } ` ); const initialWidgets = await getWidgetAreaWidgets(); @@ -493,6 +599,7 @@ describe( 'Widgets screen', () => {

First Paragraph

", + "wp_inactive_widgets": "", } ` ); const editedWidgets = await getWidgetAreaWidgets(); diff --git a/packages/edit-widgets/src/store/actions.js b/packages/edit-widgets/src/store/actions.js index 520a0cee7355a7..bd0a994f10af14 100644 --- a/packages/edit-widgets/src/store/actions.js +++ b/packages/edit-widgets/src/store/actions.js @@ -148,13 +148,15 @@ export function* saveWidgetArea( widgetAreaId ) { const widgetId = getWidgetIdFromBlock( block ); const oldWidget = widgets[ widgetId ]; const widget = transformBlockToWidget( block, oldWidget ); + // We'll replace the null widgetId after save, but we track it here // since order is important. sidebarWidgetsIds.push( widgetId ); - // We need to check for the id in the widget object here, because a deleted - // and restored widget won't have this id. - if ( widget.id ) { + // Check oldWidget as widgetId might refer to an ID which has been + // deleted, e.g. if a deleted block is restored via undo after saving. + if ( oldWidget ) { + // Update an existing widget. yield dispatch( 'core', 'editEntityRecord', @@ -184,6 +186,7 @@ export function* saveWidgetArea( widgetAreaId ) { saveEditedEntityRecord( 'root', 'widget', widgetId ) ); } else { + // Create a new widget. batchTasks.push( ( { saveEntityRecord } ) => saveEntityRecord( 'root', 'widget', { ...widget, diff --git a/packages/widgets/src/blocks/legacy-widget/edit/control.js b/packages/widgets/src/blocks/legacy-widget/edit/control.js index 04e80673528f43..3f63d272b27a1b 100644 --- a/packages/widgets/src/blocks/legacy-widget/edit/control.js +++ b/packages/widgets/src/blocks/legacy-widget/edit/control.js @@ -52,7 +52,10 @@ export default class Control { // a fake but unique number. this.number = ++lastNumber; - this.handleFormChange = debounce( this.saveForm.bind( this ), 200 ); + this.handleFormChange = debounce( + this.handleFormChange.bind( this ), + 200 + ); this.handleFormSubmit = this.handleFormSubmit.bind( this ); this.initDOM(); @@ -214,6 +217,18 @@ export default class Control { } } + /** + * Perform a save when a multi widget's form is changed. Non-multi widgets + * are saved manually. + * + * @access private + */ + handleFormChange() { + if ( this.idBase ) { + this.saveForm(); + } + } + /** * Perform a save when the control's form is manually submitted. * diff --git a/packages/widgets/src/blocks/legacy-widget/edit/index.js b/packages/widgets/src/blocks/legacy-widget/edit/index.js index eea3405d835fff..f456c0e4e66dba 100644 --- a/packages/widgets/src/blocks/legacy-widget/edit/index.js +++ b/packages/widgets/src/blocks/legacy-widget/edit/index.js @@ -131,7 +131,8 @@ function NotEmpty( { ); } - const mode = isNavigationMode || ! isSelected ? 'preview' : 'edit'; + const mode = + idBase && ( isNavigationMode || ! isSelected ) ? 'preview' : 'edit'; return ( <> From 53d145aa2b08f626a0555c1cb4894ce077405620 Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Mon, 28 Jun 2021 16:12:57 +0200 Subject: [PATCH 28/64] Fix switcher focus style. (#33031) * Fix switcher focus style. * Polish RBs. --- .../block-editor/src/components/block-toolbar/style.scss | 8 -------- packages/components/src/toolbar/style.scss | 8 ++++---- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/packages/block-editor/src/components/block-toolbar/style.scss b/packages/block-editor/src/components/block-toolbar/style.scss index 4a8bfc6f307316..6a747fa59cd8af 100644 --- a/packages/block-editor/src/components/block-toolbar/style.scss +++ b/packages/block-editor/src/components/block-toolbar/style.scss @@ -82,10 +82,6 @@ width: $button-size-small !important; margin: 0 !important; } - - &:focus::before { - right: $grid-unit-05 !important; - } } // Match the parent selector button. @@ -158,10 +154,6 @@ width: 0 !important; height: 0 !important; } - - &:focus::before { - right: $grid-unit-05 !important; - } } // Parent selector overrides diff --git a/packages/components/src/toolbar/style.scss b/packages/components/src/toolbar/style.scss index a0b7815d356b5c..d24a3317328d64 100644 --- a/packages/components/src/toolbar/style.scss +++ b/packages/components/src/toolbar/style.scss @@ -72,12 +72,12 @@ } // Ensure the icon buttons remain square. - &.has-icon { + // This needs specificity. + &.has-icon.has-icon { // Reduce the default padding when a button only has an icon. - padding-left: $grid-unit-10; - padding-right: $grid-unit-10; + padding-left: $grid-unit-15; + padding-right: $grid-unit-15; min-width: $block-toolbar-height; - justify-content: center; } // @todo: We should extract the tabs styles to the tabs component itself From be0dcb02237f3c342256ce9d6399abdde4735011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= <4710635+ellatrix@users.noreply.github.com> Date: Mon, 28 Jun 2021 18:05:48 +0300 Subject: [PATCH 29/64] Iframed editor: add Masonry integration e2e test (#33008) --- .../src/components/iframe/index.js | 20 +++++-- .../plugins/iframed-masonry-block.php | 40 +++++++++++++ .../plugins/iframed-masonry-block/block.json | 16 +++++ .../plugins/iframed-masonry-block/editor.css | 6 ++ .../plugins/iframed-masonry-block/editor.js | 57 ++++++++++++++++++ .../plugins/iframed-masonry-block/script.js | 13 +++++ .../plugins/iframed-masonry-block/style.css | 23 ++++++++ .../iframed-masonry-block.test.js.snap | 7 +++ .../plugins/iframed-masonry-block.test.js | 58 +++++++++++++++++++ 9 files changed, 235 insertions(+), 5 deletions(-) create mode 100644 packages/e2e-tests/plugins/iframed-masonry-block.php create mode 100644 packages/e2e-tests/plugins/iframed-masonry-block/block.json create mode 100644 packages/e2e-tests/plugins/iframed-masonry-block/editor.css create mode 100644 packages/e2e-tests/plugins/iframed-masonry-block/editor.js create mode 100644 packages/e2e-tests/plugins/iframed-masonry-block/script.js create mode 100644 packages/e2e-tests/plugins/iframed-masonry-block/style.css create mode 100644 packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap create mode 100644 packages/e2e-tests/specs/editor/plugins/iframed-masonry-block.test.js diff --git a/packages/block-editor/src/components/iframe/index.js b/packages/block-editor/src/components/iframe/index.js index 4c8c94bbf53e48..d089925b3846aa 100644 --- a/packages/block-editor/src/components/iframe/index.js +++ b/packages/block-editor/src/components/iframe/index.js @@ -8,6 +8,7 @@ import { forwardRef, useEffect, useMemo, + useReducer, } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { useMergeRefs } from '@wordpress/compose'; @@ -164,6 +165,7 @@ async function loadScript( doc, { id, src } ) { } function Iframe( { contentRef, children, head, ...props }, ref ) { + const [ , forceRender ] = useReducer( () => ( {} ) ); const [ iframeDocument, setIframeDocument ] = useState(); const styles = useParsedAssets( window.__editorAssets.styles ); const scripts = useParsedAssets( window.__editorAssets.scripts ); @@ -194,11 +196,19 @@ function Iframe( { contentRef, children, head, ...props }, ref ) { clearerRef( documentElement ); clearerRef( body ); - scripts.reduce( - ( promise, script ) => - promise.then( () => loadScript( contentDocument, script ) ), - Promise.resolve() - ); + scripts + .reduce( + ( promise, script ) => + promise.then( () => + loadScript( contentDocument, script ) + ), + Promise.resolve() + ) + .finally( () => { + // When script are loaded, re-render blocks to allow them + // to initialise. + forceRender(); + } ); return true; } diff --git a/packages/e2e-tests/plugins/iframed-masonry-block.php b/packages/e2e-tests/plugins/iframed-masonry-block.php new file mode 100644 index 00000000000000..d8d6ea14120f85 --- /dev/null +++ b/packages/e2e-tests/plugins/iframed-masonry-block.php @@ -0,0 +1,40 @@ + { + const { createElement: el } = element; + const { registerBlockType } = blocks; + const { useBlockProps } = blockEditor; + const { useRefEffect } = compose; + + const content = [ + el( 'div', { className: 'grid-item' } ), + el( 'div', { className: 'grid-item grid-item--width2 grid-item--height2' } ), + el( 'div', { className: 'grid-item grid-item--height3' } ), + el( 'div', { className: 'grid-item grid-item--height2' } ), + el( 'div', { className: 'grid-item grid-item--width3' } ), + el( 'div', { className: 'grid-item' } ), + el( 'div', { className: 'grid-item' } ), + el( 'div', { className: 'grid-item grid-item--height2' } ), + el( 'div', { className: 'grid-item grid-item--width2 grid-item--height3' } ), + el( 'div', { className: 'grid-item' } ), + el( 'div', { className: 'grid-item grid-item--height2' } ), + el( 'div', { className: 'grid-item' } ), + el( 'div', { className: 'grid-item grid-item--width2 grid-item--height2' } ), + el( 'div', { className: 'grid-item grid-item--width2' } ), + el( 'div', { className: 'grid-item' } ), + el( 'div', { className: 'grid-item grid-item--height2' } ), + el( 'div', { className: 'grid-item' } ), + el( 'div', { className: 'grid-item' } ), + el( 'div', { className: 'grid-item grid-item--height3' } ), + el( 'div', { className: 'grid-item grid-item--height2' } ), + el( 'div', { className: 'grid-item' } ), + el( 'div', { className: 'grid-item' } ), + el( 'div', { className: 'grid-item grid-item--height2' } ), + ] + + registerBlockType( 'test/iframed-masonry-block', { + edit: function Edit() { + const ref = useRefEffect( ( node ) => { + const { ownerDocument } = node; + const { defaultView } = ownerDocument; + + if ( ! defaultView.Masonry ) { + return; + } + + const masonry = new defaultView.Masonry( node, { + itemSelector: '.grid-item', + } ); + + return () => { + masonry.destroy(); + }; + } ); + return el( 'div', useBlockProps( { ref } ), ...content ); + }, + save: function Save() { + return el( 'div', useBlockProps.save(), ...content ); + }, + } ); +} )( window ); diff --git a/packages/e2e-tests/plugins/iframed-masonry-block/script.js b/packages/e2e-tests/plugins/iframed-masonry-block/script.js new file mode 100644 index 00000000000000..e287e6ec2e9745 --- /dev/null +++ b/packages/e2e-tests/plugins/iframed-masonry-block/script.js @@ -0,0 +1,13 @@ +( ( win ) => { + const { Masonry, document } = win; + win.addEventListener( 'DOMContentLoaded', () => { + document + .querySelectorAll( '.wp-block-test-iframed-masonry-block' ) + .forEach( ( element ) => { + new Masonry( element, { + itemSelector: '.grid-item', + } ); + } ); + } ); +} )( window ); + diff --git a/packages/e2e-tests/plugins/iframed-masonry-block/style.css b/packages/e2e-tests/plugins/iframed-masonry-block/style.css new file mode 100644 index 00000000000000..321f2347b02328 --- /dev/null +++ b/packages/e2e-tests/plugins/iframed-masonry-block/style.css @@ -0,0 +1,23 @@ +/** + * The following styles get applied both on the front of your site + * and in the editor. + */ +.wp-block-test-iframed-masonry-block { + background-color: #21759b; + color: #fff; + padding: 2px; +} + +.grid-item { + float: left; + width: 80px; + height: 60px; + background: #D26; + border: 2px solid #333; + border-color: hsla(0, 0%, 0%, 0.5); + border-radius: 5px; + box-sizing: border-box; +} + +.grid-item--width2 { width: 160px; } +.grid-item--height2 { height: 140px; } diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap new file mode 100644 index 00000000000000..1c0d56386164f5 --- /dev/null +++ b/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`changing image size should load script and dependencies in iframe 1`] = ` +" +
+" +`; diff --git a/packages/e2e-tests/specs/editor/plugins/iframed-masonry-block.test.js b/packages/e2e-tests/specs/editor/plugins/iframed-masonry-block.test.js new file mode 100644 index 00000000000000..5c12f2abb1b6aa --- /dev/null +++ b/packages/e2e-tests/specs/editor/plugins/iframed-masonry-block.test.js @@ -0,0 +1,58 @@ +/** + * WordPress dependencies + */ +import { + activatePlugin, + createNewPost, + deactivatePlugin, + insertBlock, + getEditedPostContent, + openDocumentSettingsSidebar, + clickButton, + canvas, +} from '@wordpress/e2e-test-utils'; + +async function didMasonryLoadCorrectly( context ) { + return await context.evaluate( () => { + const container = document.querySelector( + '.wp-block-test-iframed-masonry-block' + ); + return ( + // Expect Masonry to set a non-zero height. + parseInt( container.style.height, 10 ) > 0 && + // Expect Masonry to absolute position items. + container.firstElementChild.style.position === 'absolute' + ); + } ); +} + +describe( 'changing image size', () => { + beforeEach( async () => { + await activatePlugin( 'gutenberg-test-iframed-masonry-block' ); + await createNewPost( { postType: 'page' } ); + } ); + + afterEach( async () => { + await deactivatePlugin( 'gutenberg-test-iframed-masonry-block' ); + } ); + + it( 'should load script and dependencies in iframe', async () => { + await insertBlock( 'Iframed Masonry Block' ); + + expect( await getEditedPostContent() ).toMatchSnapshot(); + expect( await didMasonryLoadCorrectly( page ) ).toBe( true ); + + await openDocumentSettingsSidebar(); + await clickButton( 'Page' ); + await clickButton( 'Template' ); + await clickButton( 'New' ); + await page.keyboard.press( 'Tab' ); + await page.keyboard.press( 'Tab' ); + await page.keyboard.type( 'Iframed Test' ); + await clickButton( 'Create' ); + await page.waitForSelector( 'iframe[name="editor-canvas"]' ); + await canvas().waitForSelector( '.grid-item[style]' ); + + expect( await didMasonryLoadCorrectly( canvas() ) ).toBe( true ); + } ); +} ); From 056990d8598cdcbdfa9db96396a557d14e19ff0e Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Mon, 28 Jun 2021 18:12:27 +0300 Subject: [PATCH 30/64] [Block Library - Query Loop] Fix race condition for making Post blocks inside uneditable (#33037) --- packages/block-library/src/post-template/edit.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/block-library/src/post-template/edit.js b/packages/block-library/src/post-template/edit.js index 40e565e3525d9d..2c8c142c2f4a0a 100644 --- a/packages/block-library/src/post-template/edit.js +++ b/packages/block-library/src/post-template/edit.js @@ -41,7 +41,6 @@ export default function PostTemplateEdit( { sticky, inherit, } = {}, - queryId, queryContext = [ { page: 1 } ], templateSlug, displayLayout: { type: layoutType = 'flex', columns = 1 } = {}, @@ -116,7 +115,6 @@ export default function PostTemplateEdit( { posts?.map( ( post ) => ( { postType: post.type, postId: post.id, - queryId, } ) ), [ posts ] ); From 779fdaa94263611a3ccb5f7fdd5f312b43e5cbea Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 28 Jun 2021 16:42:16 +0100 Subject: [PATCH 31/64] chore(release): publish - @wordpress/block-directory@2.1.13 - @wordpress/block-editor@6.1.8 - @wordpress/block-library@3.2.11 - @wordpress/components@14.1.5 - @wordpress/customize-widgets@1.0.12 - @wordpress/e2e-tests@2.2.10 - @wordpress/edit-navigation@1.9.11 - @wordpress/edit-post@4.1.13 - @wordpress/edit-site@2.1.13 - @wordpress/edit-widgets@2.1.13 - @wordpress/editor@10.1.11 - @wordpress/format-library@2.1.8 - @wordpress/interface@3.1.6 - @wordpress/list-reusable-blocks@2.1.5 - @wordpress/nux@4.1.5 - @wordpress/react-native-editor@1.53.12 - @wordpress/reusable-blocks@2.1.11 - @wordpress/server-side-render@2.1.6 - @wordpress/widgets@1.1.12 --- packages/block-directory/package.json | 2 +- packages/block-editor/package.json | 2 +- packages/block-library/package.json | 2 +- packages/components/package.json | 2 +- packages/customize-widgets/package.json | 2 +- packages/e2e-tests/package.json | 2 +- packages/edit-navigation/package.json | 2 +- packages/edit-post/package.json | 2 +- packages/edit-site/package.json | 2 +- packages/edit-widgets/package.json | 2 +- packages/editor/package.json | 2 +- packages/format-library/package.json | 2 +- packages/interface/package.json | 2 +- packages/list-reusable-blocks/package.json | 2 +- packages/nux/package.json | 2 +- packages/reusable-blocks/package.json | 2 +- packages/server-side-render/package.json | 2 +- packages/widgets/package.json | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index eb7490310bf41d..c78b5bacaa9cc1 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-directory", - "version": "2.1.12", + "version": "2.1.13", "description": "Extend editor with block directory features to search, download and install blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index 616249c2feed60..24e94fdfde1472 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-editor", - "version": "6.1.7", + "version": "6.1.8", "description": "Generic block editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 2a7855fa1d5a87..087d623110e78f 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "3.2.10", + "version": "3.2.11", "description": "Block library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/components/package.json b/packages/components/package.json index d18e1318e0ecea..d96ff912be264d 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/components", - "version": "14.1.4", + "version": "14.1.5", "description": "UI components for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/customize-widgets/package.json b/packages/customize-widgets/package.json index d3542e120e15f4..e7b1801f78248c 100644 --- a/packages/customize-widgets/package.json +++ b/packages/customize-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/customize-widgets", - "version": "1.0.11", + "version": "1.0.12", "description": "Widgets blocks in Customizer Module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-tests/package.json b/packages/e2e-tests/package.json index 8f09145bd32549..252f704e72ac7e 100644 --- a/packages/e2e-tests/package.json +++ b/packages/e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-tests", - "version": "2.2.9", + "version": "2.2.10", "description": "End-To-End (E2E) tests for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-navigation/package.json b/packages/edit-navigation/package.json index 22c281185675e1..d9876dbe033f4c 100644 --- a/packages/edit-navigation/package.json +++ b/packages/edit-navigation/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-navigation", - "version": "1.9.10", + "version": "1.9.11", "private": true, "description": "Module for the Navigation page in WordPress.", "author": "The WordPress Contributors", diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index 1faa6d09fb5d01..e7566243c2224e 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-post", - "version": "4.1.12", + "version": "4.1.13", "description": "Edit Post module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index 5e8927afeab710..055d8924ab1cab 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-site", - "version": "2.1.12", + "version": "2.1.13", "description": "Edit Site Page module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-widgets/package.json b/packages/edit-widgets/package.json index 65418504de58c3..1710b43c66fbc6 100644 --- a/packages/edit-widgets/package.json +++ b/packages/edit-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-widgets", - "version": "2.1.12", + "version": "2.1.13", "description": "Widgets Page module for WordPress..", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/editor/package.json b/packages/editor/package.json index c7404158e8e9b3..102c38d2f2d96d 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/editor", - "version": "10.1.10", + "version": "10.1.11", "description": "Enhanced block editor for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/format-library/package.json b/packages/format-library/package.json index 1a9d38039fc826..b1dfec6ba955c2 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/format-library", - "version": "2.1.7", + "version": "2.1.8", "description": "Format library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/interface/package.json b/packages/interface/package.json index 7d42adbfe5ca22..943c15c29556f9 100644 --- a/packages/interface/package.json +++ b/packages/interface/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/interface", - "version": "3.1.5", + "version": "3.1.6", "description": "Interface module for WordPress. The package contains shared functionality across the modern JavaScript-based WordPress screens.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/list-reusable-blocks/package.json b/packages/list-reusable-blocks/package.json index b1b44353b687ff..ad2531e7e29779 100644 --- a/packages/list-reusable-blocks/package.json +++ b/packages/list-reusable-blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/list-reusable-blocks", - "version": "2.1.4", + "version": "2.1.5", "description": "Adding Export/Import support to the reusable blocks listing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/nux/package.json b/packages/nux/package.json index 9378b50a3f9367..5cb82913411485 100644 --- a/packages/nux/package.json +++ b/packages/nux/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/nux", - "version": "4.1.4", + "version": "4.1.5", "description": "NUX (New User eXperience) module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/reusable-blocks/package.json b/packages/reusable-blocks/package.json index 7386949eb33e5f..ee0226129e0ab5 100644 --- a/packages/reusable-blocks/package.json +++ b/packages/reusable-blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/reusable-blocks", - "version": "2.1.10", + "version": "2.1.11", "description": "Reusable blocks utilities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/server-side-render/package.json b/packages/server-side-render/package.json index fd8fb1bab6e83b..1efa273a5c8afb 100644 --- a/packages/server-side-render/package.json +++ b/packages/server-side-render/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/server-side-render", - "version": "2.1.5", + "version": "2.1.6", "description": "The component used with WordPress to server-side render a preview of dynamic blocks to display in the editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/widgets/package.json b/packages/widgets/package.json index 48e2a2e6933751..ac55f282312a22 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/widgets", - "version": "1.1.11", + "version": "1.1.12", "description": "Functionality used by the widgets block editor in the Widgets screen and the Customizer.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From 37d6024ed0993615d1af6f5af78494a98602710b Mon Sep 17 00:00:00 2001 From: Adam Zielinski Date: Mon, 28 Jun 2021 18:33:32 +0200 Subject: [PATCH 32/64] Adjust widget form margins in the new widget editor (#33040) * Adjust widget form margins in the new widget editor * Adjust the selector to cover more input types, change background to background-color --- .../src/blocks/legacy-widget/editor.scss | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/widgets/src/blocks/legacy-widget/editor.scss b/packages/widgets/src/blocks/legacy-widget/editor.scss index 5ad552605f9971..69f8f577702255 100644 --- a/packages/widgets/src/blocks/legacy-widget/editor.scss +++ b/packages/widgets/src/blocks/legacy-widget/editor.scss @@ -21,8 +21,13 @@ display: block; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; + p { + margin: $grid-unit-10 0; + } + label { font-size: $default-font-size; + line-height: $default-line-height * 1.5; } // Override theme style bleed. @@ -34,9 +39,21 @@ color: $black; } input[type="text"], + input[type="password"], + input[type="date"], + input[type="datetime"], + input[type="datetime-local"], + input[type="email"], + input[type="month"], + input[type="number"], + input[type="search"], + input[type="tel"], + input[type="time"], + input[type="url"], + input[type="week"], select { font-family: system-ui; - background: transparent; + background-color: transparent; box-sizing: border-box; border: 1px solid $gray-700; border-radius: 3px; @@ -47,9 +64,11 @@ width: 100%; font-size: $default-font-size; font-weight: normal; - height: 30px; line-height: 1; min-height: 30px; + padding-left: $grid-unit-10; + } + select { padding-left: $grid-unit-05; } } From f1e2f3b6c75a18568d5626b573c142b67117bc42 Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Tue, 29 Jun 2021 11:59:12 +1000 Subject: [PATCH 33/64] Button: Update to use border support provided styles and classes (#33017) --- packages/block-library/src/button/deprecated.js | 2 +- packages/block-library/src/button/edit.js | 10 +++++++--- packages/block-library/src/button/save.js | 10 +++++++--- .../core__button__border_radius__deprecated.json | 2 +- ...__button__border_radius__deprecated.serialized.html | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/block-library/src/button/deprecated.js b/packages/block-library/src/button/deprecated.js index 367e5050df6edb..2d22972f5d1165 100644 --- a/packages/block-library/src/button/deprecated.js +++ b/packages/block-library/src/button/deprecated.js @@ -27,7 +27,7 @@ const migrateBorderRadius = ( attributes ) => { ...newAttributes, style: { ...newAttributes.style, - border: { radius: borderRadius }, + border: { radius: `${ borderRadius }px` }, }, }; }; diff --git a/packages/block-library/src/button/edit.js b/packages/block-library/src/button/edit.js index 15235369b2ee05..079185d8e2e39e 100644 --- a/packages/block-library/src/button/edit.js +++ b/packages/block-library/src/button/edit.js @@ -23,6 +23,7 @@ import { InspectorAdvancedControls, RichText, useBlockProps, + __experimentalUseBorderProps as useBorderProps, __experimentalUseColorProps as useColorProps, __experimentalLinkControl as LinkControl, } from '@wordpress/block-editor'; @@ -196,7 +197,7 @@ function ButtonEdit( props ) { setAttributes( { text: newText.replace( /<\/?a[^>]*>/g, '' ) } ); }; - const borderRadius = style?.border?.radius; + const borderProps = useBorderProps( attributes ); const colorProps = useColorProps( attributes ); const ref = useRef(); const blockProps = useBlockProps( { ref } ); @@ -220,12 +221,15 @@ function ButtonEdit( props ) { className, 'wp-block-button__link', colorProps.className, + borderProps.className, { - 'no-border-radius': borderRadius === 0, + // For backwards compatibility add style that isn't + // provided via block support. + 'no-border-radius': style?.border?.radius === 0, } ) } style={ { - borderRadius: borderRadius ? borderRadius : undefined, + ...borderProps.style, ...colorProps.style, } } onSplit={ ( value ) => diff --git a/packages/block-library/src/button/save.js b/packages/block-library/src/button/save.js index af4f4e6f566f35..d462cf52e6dd7b 100644 --- a/packages/block-library/src/button/save.js +++ b/packages/block-library/src/button/save.js @@ -9,6 +9,7 @@ import classnames from 'classnames'; import { RichText, useBlockProps, + __experimentalGetBorderClassesAndStyles as getBorderClassesAndStyles, __experimentalGetColorClassesAndStyles as getColorClassesAndStyles, } from '@wordpress/block-editor'; @@ -28,17 +29,20 @@ export default function save( { attributes, className } ) { return null; } - const borderRadius = style?.border?.radius; + const borderProps = getBorderClassesAndStyles( attributes ); const colorProps = getColorClassesAndStyles( attributes ); const buttonClasses = classnames( 'wp-block-button__link', colorProps.className, + borderProps.className, { - 'no-border-radius': borderRadius === 0, + // For backwards compatibility add style that isn't provided via + // block support. + 'no-border-radius': style?.border?.radius === 0, } ); const buttonStyle = { - borderRadius: borderRadius ? borderRadius : undefined, + ...borderProps.style, ...colorProps.style, }; diff --git a/packages/e2e-tests/fixtures/blocks/core__button__border_radius__deprecated.json b/packages/e2e-tests/fixtures/blocks/core__button__border_radius__deprecated.json index 00f2d0ab540744..47c67a944a2062 100644 --- a/packages/e2e-tests/fixtures/blocks/core__button__border_radius__deprecated.json +++ b/packages/e2e-tests/fixtures/blocks/core__button__border_radius__deprecated.json @@ -7,7 +7,7 @@ "text": "My button", "style": { "border": { - "radius": 25 + "radius": "25px" } } }, diff --git a/packages/e2e-tests/fixtures/blocks/core__button__border_radius__deprecated.serialized.html b/packages/e2e-tests/fixtures/blocks/core__button__border_radius__deprecated.serialized.html index 4cc048a9c2e7eb..2f0b0fe6f6e77b 100644 --- a/packages/e2e-tests/fixtures/blocks/core__button__border_radius__deprecated.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__button__border_radius__deprecated.serialized.html @@ -1,4 +1,4 @@ - + From 39ca11a84d1560dc45275af26e678be6f2f71227 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Tue, 29 Jun 2021 14:13:25 +0800 Subject: [PATCH 34/64] Add some technical implementation details for Widgets Customizer (#33026) Co-authored-by: Dave Smith --- packages/customize-widgets/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/customize-widgets/README.md b/packages/customize-widgets/README.md index 771e81f7a8bcc7..f99d5b945cd179 100644 --- a/packages/customize-widgets/README.md +++ b/packages/customize-widgets/README.md @@ -14,4 +14,20 @@ npm install @wordpress/customize-widgets _This package assumes that your code will run in an **ES2015+** environment. If you're using an environment that has limited or no support for ES2015+ such as IE browsers then using [core-js](https://github.com/zloirock/core-js) will add polyfills for these methods._ +## Technical implementation details + +The new Widgets Customizer replaces `Appearance > Customize > Widgets` with block-based editors. The original Customizer is a Backbone app, but the new editor is a React app. One of the challenges is to integrate them together but make sure features from both sides still work. + +We extend the Customizer's sections and controls in the `/controls` directory and inject some custom logic for the editor. We use React portal to render each editor in its section to reuse most of the styles and scripts provided by the Customizer. + +`components/sidebar-block-editor` is the entry point for each widget area's block editor. `component/sidebar-block-editor/sidebar-adapter.js` is an adapter to talk to [the Customize API](https://developer.wordpress.org/themes/customize-api/) and transform widget objects into widget instances. + +`components/sidebar-block-editor/use-sidebar-block-editor.js` is a custom React Hook to integrate the adapter into React and handle most of the translations between blocks and widgets. These allow us to implement basic editing features as well as real-time preview in a backwards-compatible way. + +Whenever the blocks change, we run through each block to determine if there are created, edited, or deleted blocks. We then convert them to their widget counterparts and call the Customize API to update them. + +For React developers, this can be thought of as a custom reconciler or a custom renderer for the Customizer. But instead of targeting DOM as the render target, we are targeting WordPress widgets using the Customize API. + +This is not the typical way the block editor is intended to be used. As a result, we have to also implement some missing features such as undo/redo and custom focus control. It is still a goal to make the block editor as easy to integrate into different systems as possible, so the integration in the Widgets Customizer can be a good experience for us to reflect some drawbacks in our current API and potentially improve them in the future. +

Code is Poetry.

From bcb96d8477ca3357da5be44fe1cd45e4edb798e9 Mon Sep 17 00:00:00 2001 From: Herb Miller Date: Tue, 29 Jun 2021 07:58:08 +0100 Subject: [PATCH 35/64] Typo correction (#33013) from Guterberg to Gutenberg --- docs/how-to-guides/block-tutorial/creating-dynamic-blocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/how-to-guides/block-tutorial/creating-dynamic-blocks.md b/docs/how-to-guides/block-tutorial/creating-dynamic-blocks.md index a82bb3c6058118..bf86d303fc643e 100644 --- a/docs/how-to-guides/block-tutorial/creating-dynamic-blocks.md +++ b/docs/how-to-guides/block-tutorial/creating-dynamic-blocks.md @@ -5,7 +5,7 @@ Dynamic blocks are blocks that build their structure and content on the fly when There are two primary uses for dynamic blocks: 1. Blocks where content should change even if a post has not been updated. One example from WordPress itself is the Latest Posts block. This block will update everywhere it is used when a new post is published. -2. Blocks where updates to the code (HTML, CSS, JS) should be immediately shown on the front end of the website. For example, if you update the structure of a block by adding a new class, adding an HTML element, or changing the layout in any other way, using a dynamic block ensures those changes are applied immediately on all occurrences of that block across the site. (If a dynamic block is not used then when block code is updated Guterberg's [validation process](/docs/reference-guides/block-api/block-edit-save.md#validation) generally applies, causing users to see the validation message, "This block appears to have been modified externally"). +2. Blocks where updates to the code (HTML, CSS, JS) should be immediately shown on the front end of the website. For example, if you update the structure of a block by adding a new class, adding an HTML element, or changing the layout in any other way, using a dynamic block ensures those changes are applied immediately on all occurrences of that block across the site. (If a dynamic block is not used then when block code is updated Gutenberg's [validation process](/docs/reference-guides/block-api/block-edit-save.md#validation) generally applies, causing users to see the validation message, "This block appears to have been modified externally"). For many dynamic blocks, the `save` callback function should be returned as `null`, which tells the editor to save only the [block attributes](/docs/reference-guides/block-api/block-attributes.md) to the database. These attributes are then passed into the server-side rendering callback, so you can decide how to display the block on the front end of your site. When you return `null`, the editor will skip the block markup validation process, avoiding issues with frequently-changing markup. From 290f3b76ec7d94f50abdd47a82fe20791cd90770 Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Tue, 29 Jun 2021 10:35:49 +0200 Subject: [PATCH 36/64] Remove "is-dark-theme" rules from mixins. (#33058) --- packages/base-styles/_mixins.scss | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/packages/base-styles/_mixins.scss b/packages/base-styles/_mixins.scss index d01d312014b879..fed727e4e4a6e1 100644 --- a/packages/base-styles/_mixins.scss +++ b/packages/base-styles/_mixins.scss @@ -266,21 +266,6 @@ &:-ms-input-placeholder { color: $dark-gray-placeholder; } - - .is-dark-theme & { - &::-webkit-input-placeholder { - color: $light-gray-placeholder; - } - - &::-moz-placeholder { - opacity: 1; // Necessary because Firefox reduces this from 1. - color: $light-gray-placeholder; - } - - &:-ms-input-placeholder { - color: $light-gray-placeholder; - } - } } @mixin checkbox-control { From 9a6fdb0de8d327cc62b3eb18686e0930b534b397 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Tue, 29 Jun 2021 13:11:56 +0400 Subject: [PATCH 37/64] Group Block: Avoid rendering the layout config twice (#33045) * Update snapshot --- lib/block-supports/layout.php | 24 ++++++++++++------- .../post-editor-template-mode.test.js.snap | 2 +- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index 1b1eec679c80a0..6d09ffa6d4e751 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -89,14 +89,17 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { return $content . ''; } -// Register the block support. -WP_Block_Supports::get_instance()->register( - 'layout', - array( - 'register_attribute' => 'gutenberg_register_layout_support', - ) -); -add_filter( 'render_block', 'gutenberg_render_layout_support_flag', 10, 2 ); +// This can be removed when plugin support requires WordPress 5.8.0+. +if ( ! function_exists( 'wp_render_layout_support_flag' ) ) { + // Register the block support. + WP_Block_Supports::get_instance()->register( + 'layout', + array( + 'register_attribute' => 'gutenberg_register_layout_support', + ) + ); + add_filter( 'render_block', 'gutenberg_render_layout_support_flag', 10, 2 ); +} /** * For themes without theme.json file, make sure @@ -129,4 +132,7 @@ function( $matches ) { return $updated_content; } -add_filter( 'render_block', 'gutenberg_restore_group_inner_container', 10, 2 ); +// This can be removed when plugin support requires WordPress 5.8.0+. +if ( ! function_exists( 'wp_restore_group_inner_container' ) ) { + add_filter( 'render_block', 'gutenberg_restore_group_inner_container', 10, 2 ); +} diff --git a/packages/e2e-tests/specs/experiments/__snapshots__/post-editor-template-mode.test.js.snap b/packages/e2e-tests/specs/experiments/__snapshots__/post-editor-template-mode.test.js.snap index 469047fa627266..b4d29c714824d7 100644 --- a/packages/e2e-tests/specs/experiments/__snapshots__/post-editor-template-mode.test.js.snap +++ b/packages/e2e-tests/specs/experiments/__snapshots__/post-editor-template-mode.test.js.snap @@ -13,7 +13,7 @@ exports[`Post Editor Template mode Allow creating custom block templates in clas
-

Another FSE Post

+

Another FSE Post

From 8a138c45b2fa21bf92d032ff011a5977fc72b47a Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Tue, 29 Jun 2021 11:30:37 +0200 Subject: [PATCH 38/64] Focus style followup. (#33022) --- packages/block-editor/src/components/block-list/style.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/block-editor/src/components/block-list/style.scss b/packages/block-editor/src/components/block-list/style.scss index a0cd8651776ba4..2e150322c17623 100644 --- a/packages/block-editor/src/components/block-list/style.scss +++ b/packages/block-editor/src/components/block-list/style.scss @@ -172,6 +172,7 @@ // 2px outside. box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); border-radius: $radius-block-ui - $border-width; // Border is outset, so subtract the width to achieve correct radius. + outline: 2px solid transparent; // This shows up in Windows High Contrast Mode. // Show a light color for dark themes. .is-dark-theme & { From 8adb5be4e51673763921463b0c4663e6987e4623 Mon Sep 17 00:00:00 2001 From: Hug0-Drelon <69580439+Hug0-Drelon@users.noreply.github.com> Date: Tue, 29 Jun 2021 11:59:24 +0200 Subject: [PATCH 39/64] add a label for screen reader in categories block (#33060) --- packages/block-library/src/categories/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/categories/index.php b/packages/block-library/src/categories/index.php index c820b7bd76b578..3cffff955183c8 100644 --- a/packages/block-library/src/categories/index.php +++ b/packages/block-library/src/categories/index.php @@ -28,7 +28,7 @@ function render_block_core_categories( $attributes ) { $id = 'wp-block-categories-' . $block_id; $args['id'] = $id; $args['show_option_none'] = __( 'Select Category' ); - $wrapper_markup = '
%2$s
'; + $wrapper_markup = '
%2$s
'; $items_markup = wp_dropdown_categories( $args ); $type = 'dropdown'; From fa3bfd5e960fb6d9901edc05530a27454ecb912a Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Tue, 29 Jun 2021 13:47:27 +0300 Subject: [PATCH 40/64] [RN Mobile][Global Styles] Adds new Prop for Global Styles Settings (#30544) * Adds new Prop for Global Styles Settings * Rename updateTheme to be more generic for update settings include GSS (#31566) * Fix wrong naming of subscribeUpdateEditorSettings * Update Gutenberg demo * Updates new props to rawStyles and rawFeatures * Update iOS Bridge for new values * Mobile - Global styles: Pass settings and set color palette and gradients (#30684) * Mobile - Read global styles and set color palette and gradients * Parse all color variables * Fix gradients * Update global styles mocked data * Move color settings * Removed added spaces * Add tests * Update experimental features path and prepare for rawGlobalStylesBaseStyles * Remove mock data and update code to use latest API changes * Removes Android rawFeatures prop * Mobile - Remove usage of rawFeatures * Remove rawFeatures * Adds raw Styles in React Native Bridge * Mobile - Pass rawStyles on initial props and fix colors and gradients * Add Raw Features back * Revert "Removes Android rawFeatures prop" This reverts commit 32a2b3aff85ed83d2a3c953f94d4f37685b4f2ca. * Add rawFeatures in the mobile editor * Mobile - Global styles: Set theme's background and text color (#30810) * Mobile - Read global styles and set color palette and gradients * Mobile - Enable colors for blocks that support it * Parse all color variables * Mobile - Set background, title, text and link colors * Fix gradients * Add placeholder color * Update global styles mocked data * Move color settings * Removed added spaces * Add tests * Update experimental features path and prepare for rawGlobalStylesBaseStyles * Add missing provider * Get the right color attribute * Remove mock data * Mobile - Fix base global colors Co-authored-by: Chip Co-authored-by: Gerardo Pacheco --- .../src/components/block-list/block.native.js | 7 + .../block-settings/container.native.js | 9 +- .../src/components/provider/index.native.js | 3 +- packages/block-editor/src/hooks/color.js | 2 +- .../src/paragraph/edit.native.js | 5 + packages/components/src/index.native.js | 1 + .../global-styles-context/index.native.js | 5 + .../test/utils.native.js | 189 +++++++++++++++++- .../global-styles-context/utils.native.js | 40 ++++ .../src/components/layout/index.native.js | 30 ++- .../src/components/post-title/index.native.js | 30 ++- .../src/components/provider/index.native.js | 43 ++-- .../RNReactNativeGutenbergBridgeModule.java | 10 +- .../mobile/WPAndroidGlue/GutenbergProps.kt | 6 + packages/react-native-bridge/index.js | 7 +- .../react-native-bridge/ios/Gutenberg.swift | 38 ++-- .../ios/GutenbergBridgeDataSource.swift | 7 +- .../ios/RNReactNativeGutenbergBridge.swift | 2 +- .../GutenbergViewController.swift | 2 +- packages/react-native-editor/src/index.js | 4 + .../rich-text/src/component/index.native.js | 15 +- test/native/setup.js | 2 +- 22 files changed, 384 insertions(+), 73 deletions(-) diff --git a/packages/block-editor/src/components/block-list/block.native.js b/packages/block-editor/src/components/block-list/block.native.js index 018cf4760a07eb..c81a2d5469ecc1 100644 --- a/packages/block-editor/src/components/block-list/block.native.js +++ b/packages/block-editor/src/components/block-list/block.native.js @@ -48,11 +48,13 @@ function BlockForType( { parentWidth, wrapperProps, blockWidth, + baseGlobalStyles, } ) { const defaultColors = useSetting( 'color.palette' ) || emptyArray; const globalStyle = useGlobalStyles(); const mergedStyle = useMemo( () => { return getMergedGlobalStyles( + baseGlobalStyles, globalStyle, wrapperProps.style, attributes, @@ -300,6 +302,7 @@ export default compose( [ withSelect( ( select, { clientId, rootClientId } ) => { const { getBlockIndex, + getSettings, isBlockSelected, __unstableGetBlockWithoutInnerBlocks, getSelectedBlockClientId, @@ -347,6 +350,9 @@ export default compose( [ isDescendantOfParentSelected || isParentSelected || parentId === ''; + const baseGlobalStyles = getSettings() + ?.__experimentalGlobalStylesBaseStyles; + return { icon, name: name || 'core/missing', @@ -360,6 +366,7 @@ export default compose( [ isParentSelected, firstToSelectId, isTouchable, + baseGlobalStyles, wrapperProps: getWrapperProps( attributes, blockType.getEditWrapperProps diff --git a/packages/block-editor/src/components/block-settings/container.native.js b/packages/block-editor/src/components/block-settings/container.native.js index e9f16b185a5564..7f9d8a9073d398 100644 --- a/packages/block-editor/src/components/block-settings/container.native.js +++ b/packages/block-editor/src/components/block-settings/container.native.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { InspectorControls } from '@wordpress/block-editor'; +import { InspectorControls, useSetting } from '@wordpress/block-editor'; import { BottomSheet, ColorSettings, @@ -29,6 +29,11 @@ function BottomSheetSettings( { settings, ...props } ) { + const colorSettings = { + colors: useSetting( 'color.palette' ) || settings.colors, + gradients: useSetting( 'color.gradients' ) || settings.gradients, + }; + return ( - + { children }; } export default withRegistryProvider( BlockEditorProvider ); diff --git a/packages/block-editor/src/hooks/color.js b/packages/block-editor/src/hooks/color.js index 554781d057b5fd..2da9875c07584f 100644 --- a/packages/block-editor/src/hooks/color.js +++ b/packages/block-editor/src/hooks/color.js @@ -234,7 +234,7 @@ export function ColorEdit( props ) { localAttributes.current = attributes; }, [ attributes ] ); - if ( ! hasColorSupport( blockName ) || Platform.OS !== 'web' ) { + if ( ! hasColorSupport( blockName ) ) { return null; } diff --git a/packages/block-library/src/paragraph/edit.native.js b/packages/block-library/src/paragraph/edit.native.js index a51a708a222767..1cd75758543006 100644 --- a/packages/block-library/src/paragraph/edit.native.js +++ b/packages/block-library/src/paragraph/edit.native.js @@ -30,6 +30,11 @@ function ParagraphBlock( { const { align, content, placeholder } = attributes; const styles = { + ...( mergedStyle?.baseColors && { + color: mergedStyle.baseColors?.color?.text, + placeholderColor: mergedStyle.baseColors?.color?.text, + linkColor: mergedStyle.baseColors?.elements?.link?.color?.text, + } ), ...mergedStyle, ...style, }; diff --git a/packages/components/src/index.native.js b/packages/components/src/index.native.js index ac8f5b0a237f22..e7e1deea5f7523 100644 --- a/packages/components/src/index.native.js +++ b/packages/components/src/index.native.js @@ -124,3 +124,4 @@ export { withGlobalStyles, getMergedGlobalStyles, } from './mobile/global-styles-context'; +export { getGlobalStyles } from './mobile/global-styles-context/utils'; diff --git a/packages/components/src/mobile/global-styles-context/index.native.js b/packages/components/src/mobile/global-styles-context/index.native.js index 81a60ccc8eb56e..1d4d0d45be6761 100644 --- a/packages/components/src/mobile/global-styles-context/index.native.js +++ b/packages/components/src/mobile/global-styles-context/index.native.js @@ -22,16 +22,21 @@ const GlobalStylesContext = createContext( { style: {} } ); GlobalStylesContext.BLOCK_STYLE_ATTRIBUTES = BLOCK_STYLE_ATTRIBUTES; export const getMergedGlobalStyles = ( + baseGlobalStyles, globalStyle, wrapperPropsStyle, blockAttributes, defaultColors ) => { + const baseGlobalColors = { + baseColors: baseGlobalStyles || {}, + }; const blockStyleAttributes = pick( blockAttributes, BLOCK_STYLE_ATTRIBUTES ); const mergedStyle = { + ...baseGlobalColors, ...globalStyle, ...wrapperPropsStyle, }; diff --git a/packages/components/src/mobile/global-styles-context/test/utils.native.js b/packages/components/src/mobile/global-styles-context/test/utils.native.js index 396dee85b215f6..e29dc8bbed7fa8 100644 --- a/packages/components/src/mobile/global-styles-context/test/utils.native.js +++ b/packages/components/src/mobile/global-styles-context/test/utils.native.js @@ -1,7 +1,12 @@ /** * Internal dependencies */ -import { getBlockPaddings, getBlockColors } from '../utils'; +import { + getBlockPaddings, + getBlockColors, + parseColorVariables, + getGlobalStyles, +} from '../utils'; const DEFAULT_COLORS = [ { color: '#cd2653', name: 'Accent Color', slug: 'accent' }, @@ -9,6 +14,142 @@ const DEFAULT_COLORS = [ { color: '#6d6d6d', name: 'Secondary', slug: 'secondary' }, ]; +const GLOBAL_STYLES_PALETTE = [ + { + slug: 'green', + color: '#D1E4DD', + name: 'Green', + }, + { + slug: 'blue', + color: '#D1DFE4', + name: 'Blue', + }, + { + slug: 'purple', + color: '#D1D1E4', + name: 'Purple', + }, +]; + +const GLOBAL_STYLES_GRADIENTS = [ + { + slug: 'purple-to-blue', + gradient: + 'linear-gradient(160deg, var(--wp--preset--color--purple), var(--wp--preset--color--blue))', + name: 'Purple to Blue', + }, + { + slug: 'green-to-purple', + gradient: + 'linear-gradient(160deg, var(--wp--preset--color--green), var(--wp--preset--color--purple))', + name: 'Green to Purple', + }, +]; + +const DEFAULT_GLOBAL_STYLES = { + styles: { + color: { + background: 'var(--wp--preset--color--green)', + text: 'var(--wp--preset--color--blue)', + }, + elements: { + link: { + color: { + text: 'var(--wp--preset--color--purple)', + }, + }, + }, + }, +}; + +const PARSED_GLOBAL_STYLES = { + styles: { + color: { + background: '#D1E4DD', + text: '#D1DFE4', + }, + elements: { + link: { + color: { + text: '#D1D1E4', + }, + }, + }, + }, +}; + +const RAW_FEATURES = { + color: { + palette: { + core: [ + { + name: 'Black', + slug: 'black', + color: '#000000', + }, + { + name: 'Cyan bluish gray', + slug: 'cyan-bluish-gray', + color: '#abb8c3', + }, + { + name: 'White', + slug: 'white', + color: '#ffffff', + }, + ], + theme: [ + { + slug: 'green', + color: '#D1E4DD', + name: 'Green', + }, + { + slug: 'blue', + color: '#D1DFE4', + name: 'Blue', + }, + { + slug: 'purple', + color: '#D1D1E4', + name: 'Purple', + }, + ], + }, + gradients: { + core: [ + { + name: 'Vivid cyan blue to vivid purple', + gradient: + 'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)', + slug: 'vivid-cyan-blue-to-vivid-purple', + }, + { + name: 'Light green cyan to vivid green cyan', + gradient: + 'linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)', + slug: 'light-green-cyan-to-vivid-green-cyan', + }, + ], + theme: [ + { + slug: 'purple-to-blue', + gradient: + 'linear-gradient(160deg, var(--wp--preset--color--purple), var(--wp--preset--color--blue))', + name: 'Purple to Blue', + }, + { + slug: 'green-to-purple', + gradient: + 'linear-gradient(160deg, var(--wp--preset--color--green), var(--wp--preset--color--purple))', + name: 'Green to Purple', + }, + ], + }, + }, +}; + describe( 'getBlockPaddings', () => { const PADDING = 12; @@ -84,3 +225,49 @@ describe( 'getBlockColors', () => { ); } ); } ); + +describe( 'parseColorVariables', () => { + it( 'returns the parsed colors values correctly', () => { + const blockColors = parseColorVariables( + JSON.stringify( DEFAULT_GLOBAL_STYLES ), + GLOBAL_STYLES_PALETTE + ); + expect( blockColors ).toEqual( + expect.objectContaining( PARSED_GLOBAL_STYLES ) + ); + } ); +} ); + +describe( 'getGlobalStyles', () => { + it( 'returns the global styles data correctly', () => { + const rawFeatures = JSON.stringify( RAW_FEATURES ); + const globalStyles = getGlobalStyles( + JSON.stringify( DEFAULT_GLOBAL_STYLES ), + rawFeatures, + GLOBAL_STYLES_PALETTE, + GLOBAL_STYLES_GRADIENTS + ); + const gradients = parseColorVariables( + JSON.stringify( GLOBAL_STYLES_GRADIENTS ), + GLOBAL_STYLES_PALETTE + ); + const parsedExperimentalFeatures = parseColorVariables( + rawFeatures, + GLOBAL_STYLES_PALETTE + ); + + expect( globalStyles ).toEqual( + expect.objectContaining( { + colors: GLOBAL_STYLES_PALETTE, + gradients, + __experimentalFeatures: { + color: { + palette: parsedExperimentalFeatures?.color?.palette, + gradients: parsedExperimentalFeatures?.color?.gradients, + }, + }, + __experimentalGlobalStylesBaseStyles: PARSED_GLOBAL_STYLES, + } ) + ); + } ); +} ); diff --git a/packages/components/src/mobile/global-styles-context/utils.native.js b/packages/components/src/mobile/global-styles-context/utils.native.js index c8e2bce0c91f8a..0cf5bee75c4c75 100644 --- a/packages/components/src/mobile/global-styles-context/utils.native.js +++ b/packages/components/src/mobile/global-styles-context/utils.native.js @@ -66,3 +66,43 @@ export function getBlockColors( blockStyleAttributes, defaultColors ) { return blockStyles; } + +export function parseColorVariables( styles, colorPalette ) { + const stylesBase = styles; + const colorPrefixRegex = /var\(--wp--preset--color--(.*?)\)/g; + + return stylesBase + ? JSON.parse( + stylesBase?.replace( colorPrefixRegex, ( _$1, $2 ) => { + const mappedColor = find( colorPalette, { + slug: $2, + } ); + return mappedColor?.color; + } ) + ) + : styles; +} + +export function getGlobalStyles( rawStyles, rawFeatures, colors, gradients ) { + const parsedGradients = parseColorVariables( + JSON.stringify( gradients ), + colors + ); + const globalStyles = parseColorVariables( rawStyles, colors ); + const parsedExperimentalFeatures = parseColorVariables( + rawFeatures, + colors + ); + + return { + colors, + gradients: parsedGradients, + __experimentalFeatures: { + color: { + palette: parsedExperimentalFeatures?.color?.palette, + gradients: parsedExperimentalFeatures?.color?.gradients, + }, + }, + __experimentalGlobalStylesBaseStyles: globalStyles, + }; +} diff --git a/packages/edit-post/src/components/layout/index.native.js b/packages/edit-post/src/components/layout/index.native.js index f0abe54cfc9e97..d98bae6739ef59 100644 --- a/packages/edit-post/src/components/layout/index.native.js +++ b/packages/edit-post/src/components/layout/index.native.js @@ -9,7 +9,11 @@ import SafeArea from 'react-native-safe-area'; */ import { Component } from '@wordpress/element'; import { withSelect } from '@wordpress/data'; -import { BottomSheetSettings, FloatingToolbar } from '@wordpress/block-editor'; +import { + BottomSheetSettings, + FloatingToolbar, + store as blockEditorStore, +} from '@wordpress/block-editor'; import { compose, withPreferredColorScheme } from '@wordpress/compose'; import { HTMLTextInput, @@ -101,7 +105,7 @@ class Layout extends Component { } render() { - const { getStylesFromColorScheme, mode } = this.props; + const { getStylesFromColorScheme, mode, globalStyles } = this.props; const isHtmlView = mode === 'text'; @@ -118,6 +122,16 @@ class Layout extends Component { bottom: this.state.safeAreaInsets.bottom, }; + const editorStyles = [ + getStylesFromColorScheme( + styles.background, + styles.backgroundDark + ), + globalStyles?.background && { + backgroundColor: globalStyles.background, + }, + ]; + return ( - + { isHtmlView ? this.renderHTML() : this.renderVisual() } { ! isHtmlView && Platform.OS === 'android' && ( @@ -176,9 +185,14 @@ export default compose( [ editorStore ); const { getEditorMode } = select( editPostStore ); + const { getSettings } = select( blockEditorStore ); + const globalStyles = getSettings()?.__experimentalGlobalStylesBaseStyles + ?.color; + return { isReady: isEditorReady(), mode: getEditorMode(), + globalStyles, }; } ), withPreferredColorScheme, diff --git a/packages/editor/src/components/post-title/index.native.js b/packages/editor/src/components/post-title/index.native.js index 0587f26227ec83..4e117f73fb315b 100644 --- a/packages/editor/src/components/post-title/index.native.js +++ b/packages/editor/src/components/post-title/index.native.js @@ -19,6 +19,8 @@ import { withFocusOutside } from '@wordpress/components'; import { withInstanceId, compose } from '@wordpress/compose'; import { __, sprintf } from '@wordpress/i18n'; import { pasteHandler } from '@wordpress/blocks'; +import { store as blockEditorStore } from '@wordpress/block-editor'; +import { store as editorStore } from '@wordpress/editor'; /** * Internal dependencies @@ -107,12 +109,20 @@ class PostTitle extends Component { borderStyle, isDimmed, postType, + globalStyles, } = this.props; const decodedPlaceholder = decodeEntities( placeholder ); const borderColor = this.props.isSelected ? focusedBorderColor : 'transparent'; + const titleStyles = { + ...style, + ...( globalStyles?.text && { + color: globalStyles.text, + placeholderColor: globalStyles.text, + } ), + }; return ( { const { isPostTitleSelected, getEditedPostAttribute } = select( - 'core/editor' - ); - - const { getSelectedBlockClientId, getBlockRootClientId } = select( - 'core/block-editor' + editorStore ); + const { + getSelectedBlockClientId, + getBlockRootClientId, + getSettings, + } = select( blockEditorStore ); const selectedId = getSelectedBlockClientId(); const selectionIsNested = !! getBlockRootClientId( selectedId ); + const globalStyles = getSettings()?.__experimentalGlobalStylesBaseStyles + ?.color; return { postType: getEditedPostAttribute( 'type' ), isAnyBlockSelected: !! selectedId, isSelected: isPostTitleSelected(), isDimmed: selectionIsNested, + globalStyles, }; } ), withDispatch( ( dispatch ) => { const { undo, redo, togglePostTitleSelection } = dispatch( - 'core/editor' + editorStore ); const { clearSelectedBlock, insertDefaultBlock } = dispatch( - 'core/block-editor' + blockEditorStore ); return { diff --git a/packages/editor/src/components/provider/index.native.js b/packages/editor/src/components/provider/index.native.js index df425e279fc05c..8440c998856622 100644 --- a/packages/editor/src/components/provider/index.native.js +++ b/packages/editor/src/components/provider/index.native.js @@ -13,14 +13,10 @@ import RNReactNativeGutenbergBridge, { subscribeSetTitle, subscribeMediaAppend, subscribeReplaceBlock, - subscribeUpdateTheme, + subscribeUpdateEditorSettings, subscribeUpdateCapabilities, subscribeShowNotice, } from '@wordpress/react-native-bridge'; - -/** - * WordPress dependencies - */ import { Component } from '@wordpress/element'; import { count as wordCount } from '@wordpress/wordcount'; import { @@ -37,6 +33,7 @@ import { validateThemeGradients, store as blockEditorStore, } from '@wordpress/block-editor'; +import { getGlobalStyles } from '@wordpress/components'; const postTypeEntities = [ { name: 'post', baseURL: '/wp/v2/posts' }, @@ -84,13 +81,11 @@ class NativeEditorProvider extends Component { } componentDidMount() { - const { capabilities, colors, gradients } = this.props; + const { capabilities, updateSettings } = this.props; - this.props.updateSettings( { + updateSettings( { ...capabilities, - // Set theme colors for the editor - ...( colors ? { colors } : {} ), - ...( gradients ? { gradients } : {} ), + ...this.getThemeColors( this.props ), } ); this.subscriptionParentGetHtml = subscribeParentGetHtml( () => { @@ -137,15 +132,10 @@ class NativeEditorProvider extends Component { } ); - this.subscriptionParentUpdateTheme = subscribeUpdateTheme( - ( theme ) => { - // Reset the colors and gradients in case one theme was set with custom items and then updated to a theme without custom elements. - - theme.colors = validateThemeColors( theme.colors ); - - theme.gradients = validateThemeGradients( theme.gradients ); - - this.props.updateSettings( theme ); + this.subscriptionParentUpdateEditorSettings = subscribeUpdateEditorSettings( + ( editorSettings ) => { + const themeColors = this.getThemeColors( editorSettings ); + updateSettings( themeColors ); } ); @@ -187,8 +177,8 @@ class NativeEditorProvider extends Component { this.subscriptionParentMediaAppend.remove(); } - if ( this.subscriptionParentUpdateTheme ) { - this.subscriptionParentUpdateTheme.remove(); + if ( this.subscriptionParentUpdateEditorSettings ) { + this.subscriptionParentUpdateEditorSettings.remove(); } if ( this.subscriptionParentUpdateCapabilities ) { @@ -200,6 +190,17 @@ class NativeEditorProvider extends Component { } } + getThemeColors( { colors, gradients, rawStyles, rawFeatures } ) { + return { + ...( rawStyles + ? getGlobalStyles( rawStyles, rawFeatures, colors, gradients ) + : { + colors: validateThemeColors( colors ), + gradients: validateThemeGradients( gradients ), + } ), + }; + } + componentDidUpdate( prevProps ) { if ( ! prevProps.isReady && this.props.isReady ) { const blocks = this.props.blocks; diff --git a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java index 4f7c04bd8b3ca0..896748b541559e 100644 --- a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java +++ b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java @@ -44,7 +44,7 @@ public class RNReactNativeGutenbergBridgeModule extends ReactContextBaseJavaModu private static final String EVENT_NAME_NOTIFY_MODAL_CLOSED = "notifyModalClosed"; private static final String EVENT_NAME_PREFERRED_COLOR_SCHEME = "preferredColorScheme"; private static final String EVENT_NAME_MEDIA_REPLACE_BLOCK = "replaceBlock"; - private static final String EVENT_NAME_UPDATE_THEME = "updateTheme"; + private static final String EVENT_NAME_UPDATE_EDITOR_SETTINGS = "updateEditorSettings"; private static final String EVENT_NAME_SHOW_NOTICE = "showNotice"; private static final String MAP_KEY_UPDATE_HTML = "html"; @@ -57,6 +57,7 @@ public class RNReactNativeGutenbergBridgeModule extends ReactContextBaseJavaModu public static final String MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_TYPE = "mediaType"; private static final String MAP_KEY_THEME_UPDATE_COLORS = "colors"; private static final String MAP_KEY_THEME_UPDATE_GRADIENTS = "gradients"; + private static final String MAP_KEY_THEME_UPDATE_RAW_STYLES = "rawStyles"; public static final String MAP_KEY_MEDIA_FINAL_SAVE_RESULT_SUCCESS_VALUE = "success"; private static final String MAP_KEY_IS_PREFERRED_COLOR_SCHEME_DARK = "isPreferredColorSchemeDark"; @@ -144,6 +145,7 @@ public void updateTheme(@Nullable Bundle editorTheme) { WritableMap writableMap = new WritableNativeMap(); Serializable colors = editorTheme.getSerializable(MAP_KEY_THEME_UPDATE_COLORS); Serializable gradients = editorTheme.getSerializable(MAP_KEY_THEME_UPDATE_GRADIENTS); + Serializable rawStyles = editorTheme.getSerializable(MAP_KEY_THEME_UPDATE_RAW_STYLES); if (colors != null) { writableMap.putArray(MAP_KEY_THEME_UPDATE_COLORS, Arguments.fromList((ArrayList)colors)); @@ -153,7 +155,11 @@ public void updateTheme(@Nullable Bundle editorTheme) { writableMap.putArray(MAP_KEY_THEME_UPDATE_GRADIENTS, Arguments.fromList((ArrayList)gradients)); } - emitToJS(EVENT_NAME_UPDATE_THEME, writableMap); + if (rawStyles != null) { + writableMap.putString(MAP_KEY_THEME_UPDATE_RAW_STYLES, rawStyles.toString()); + } + + emitToJS(EVENT_NAME_UPDATE_EDITOR_SETTINGS, writableMap); } @ReactMethod diff --git a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/GutenbergProps.kt b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/GutenbergProps.kt index 4425769cfe8b87..aa49f177f3c235 100644 --- a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/GutenbergProps.kt +++ b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/WPAndroidGlue/GutenbergProps.kt @@ -36,6 +36,10 @@ data class GutenbergProps @JvmOverloads constructor( editorTheme?.also { theme -> theme.getSerializable(PROP_COLORS)?.let { putSerializable(PROP_COLORS, it) } theme.getSerializable(PROP_GRADIENTS)?.let { putSerializable(PROP_GRADIENTS, it) } + theme.getSerializable(PROP_STYLES) + ?.let { putSerializable(PROP_STYLES, it) } + theme.getSerializable(PROP_FEATURES) + ?.let { putSerializable(PROP_FEATURES, it) } } } @@ -69,6 +73,8 @@ data class GutenbergProps @JvmOverloads constructor( private const val PROP_TRANSLATIONS = "translations" private const val PROP_COLORS = "colors" private const val PROP_GRADIENTS = "gradients" + private const val PROP_STYLES = "rawStyles" + private const val PROP_FEATURES = "rawFeatures" const val PROP_CAPABILITIES = "capabilities" const val PROP_CAPABILITIES_CONTACT_INFO_BLOCK = "contactInfoBlock" diff --git a/packages/react-native-bridge/index.js b/packages/react-native-bridge/index.js index fde2f098563465..7d781095749b0d 100644 --- a/packages/react-native-bridge/index.js +++ b/packages/react-native-bridge/index.js @@ -125,8 +125,11 @@ export function subscribeAndroidModalClosed( callback ) { : undefined; } -export function subscribeUpdateTheme( callback ) { - return gutenbergBridgeEvents.addListener( 'updateTheme', callback ); +export function subscribeUpdateEditorSettings( callback ) { + return gutenbergBridgeEvents.addListener( + 'updateEditorSettings', + callback + ); } export function subscribePreferredColorScheme( callback ) { diff --git a/packages/react-native-bridge/ios/Gutenberg.swift b/packages/react-native-bridge/ios/Gutenberg.swift index d6cc7605385125..cd143ae0d831f4 100644 --- a/packages/react-native-bridge/ios/Gutenberg.swift +++ b/packages/react-native-bridge/ios/Gutenberg.swift @@ -79,13 +79,10 @@ public class Gutenberg: NSObject { initialProps["capabilities"] = capabilities.toJSPayload() } - let editorTheme = dataSource.gutenbergEditorTheme() - if let colors = editorTheme?.colors { - initialProps["colors"] = colors - } - - if let gradients = editorTheme?.gradients { - initialProps["gradients"] = gradients + let editorSettings = dataSource.gutenbergEditorSettings() + let settingsUpdates = properties(from: editorSettings) + initialProps.merge(settingsUpdates) { (intialProp, settingsUpdates) -> Any in + settingsUpdates } return initialProps @@ -184,19 +181,32 @@ public class Gutenberg: NSObject { bridgeModule.sendEventIfNeeded(.setFocusOnTitle, body: nil) } - public func updateTheme(_ editorTheme: GutenbergEditorTheme?) { + public func updateEditorSettings(_ editorSettings: GutenbergEditorSettings?) { + let settingsUpdates = properties(from: editorSettings) + sendEvent(.updateEditorSettings, body: settingsUpdates) + } + + private func properties(from editorSettings: GutenbergEditorSettings?) -> [String : Any] { + var settingsUpdates = [String : Any]() + settingsUpdates["isFSETheme"] = editorSettings?.isFSETheme ?? false - var themeUpdates = [String : Any]() + if let rawStyles = editorSettings?.rawStyles { + settingsUpdates["rawStyles"] = rawStyles + } + + if let rawFeatures = editorSettings?.rawFeatures { + settingsUpdates["rawFeatures"] = rawFeatures + } - if let colors = editorTheme?.colors { - themeUpdates["colors"] = colors + if let colors = editorSettings?.colors { + settingsUpdates["colors"] = colors } - if let gradients = editorTheme?.gradients { - themeUpdates["gradients"] = gradients + if let gradients = editorSettings?.gradients { + settingsUpdates["gradients"] = gradients } - sendEvent(.updateTheme, body:themeUpdates) + return settingsUpdates } public func showNotice(_ message: String) { diff --git a/packages/react-native-bridge/ios/GutenbergBridgeDataSource.swift b/packages/react-native-bridge/ios/GutenbergBridgeDataSource.swift index d6023f4d1508d7..b082cbd60682df 100644 --- a/packages/react-native-bridge/ios/GutenbergBridgeDataSource.swift +++ b/packages/react-native-bridge/ios/GutenbergBridgeDataSource.swift @@ -46,7 +46,7 @@ public protocol GutenbergBridgeDataSource: class { func gutenbergCapabilities() -> [Capabilities: Bool] /// Asks the data source for a list of theme colors. - func gutenbergEditorTheme() -> GutenbergEditorTheme? + func gutenbergEditorSettings() -> GutenbergEditorSettings? /// Asks the data source for a view to show while the Editor is loading. var loadingView: UIView? { get } @@ -70,7 +70,10 @@ public extension GutenbergBridgeDataSource { } } -public protocol GutenbergEditorTheme { +public protocol GutenbergEditorSettings { + var isFSETheme: Bool { get } + var rawStyles: String? { get } + var rawFeatures: String? { get } var colors: [[String: String]]? { get } var gradients: [[String: String]]? { get } } diff --git a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift index 82f19d50a5a154..2b57384df96109 100644 --- a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift +++ b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift @@ -369,7 +369,7 @@ extension RNReactNativeGutenbergBridge { case mediaUpload case setFocusOnTitle case mediaAppend - case updateTheme + case updateEditorSettings case replaceBlock case updateCapabilities case showNotice diff --git a/packages/react-native-editor/ios/GutenbergDemo/GutenbergViewController.swift b/packages/react-native-editor/ios/GutenbergDemo/GutenbergViewController.swift index 4e24a4dc1f75d9..ae3cb177d7ccb0 100644 --- a/packages/react-native-editor/ios/GutenbergDemo/GutenbergViewController.swift +++ b/packages/react-native-editor/ios/GutenbergDemo/GutenbergViewController.swift @@ -296,7 +296,7 @@ extension GutenbergViewController: GutenbergBridgeDataSource { return ExampleAttachmentDelegate() } - func gutenbergEditorTheme() -> GutenbergEditorTheme? { + func gutenbergEditorSettings() -> GutenbergEditorSettings? { return nil } diff --git a/packages/react-native-editor/src/index.js b/packages/react-native-editor/src/index.js index 2d9cd3ed6c79ac..c8b8fd8b152ab2 100644 --- a/packages/react-native-editor/src/index.js +++ b/packages/react-native-editor/src/index.js @@ -81,6 +81,8 @@ const setupInitHooks = () => { featuredImageId, colors, gradients, + rawStyles, + rawFeatures, } = props; if ( initialData === undefined && __DEV__ ) { @@ -106,6 +108,8 @@ const setupInitHooks = () => { capabilities, colors, gradients, + rawStyles, + rawFeatures, }; } ); diff --git a/packages/rich-text/src/component/index.native.js b/packages/rich-text/src/component/index.native.js index 195de53e802fed..8f5afcc4857168 100644 --- a/packages/rich-text/src/component/index.native.js +++ b/packages/rich-text/src/component/index.native.js @@ -3,21 +3,18 @@ /** * External dependencies */ +import { View, Platform } from 'react-native'; +import { get, pickBy, debounce, isString } from 'lodash'; +import memize from 'memize'; + /** * WordPress dependencies */ import RCTAztecView from '@wordpress/react-native-aztec'; -import { View, Platform } from 'react-native'; import { showUserSuggestions, showXpostSuggestions, } from '@wordpress/react-native-bridge'; -import { get, pickBy, debounce, isString } from 'lodash'; -import memize from 'memize'; - -/** - * WordPress dependencies - */ import { BlockFormatControls } from '@wordpress/block-editor'; import { Component } from '@wordpress/element'; import { compose, withPreferredColorScheme } from '@wordpress/compose'; @@ -982,10 +979,12 @@ export class RichText extends Component { text: html, eventCount: this.lastEventCount, selection, - linkTextColor: defaultTextDecorationColor, + linkTextColor: + style?.linkColor || defaultTextDecorationColor, } } placeholder={ this.props.placeholder } placeholderTextColor={ + style?.placeholderColor || this.props.placeholderTextColor || defaultPlaceholderTextColor } diff --git a/test/native/setup.js b/test/native/setup.js index 2df7fb1889b293..6fd0a13c873371 100644 --- a/test/native/setup.js +++ b/test/native/setup.js @@ -48,7 +48,7 @@ jest.mock( '@wordpress/react-native-bridge', () => { subscribeFeaturedImageIdNativeUpdated: jest.fn(), subscribeMediaAppend: jest.fn(), subscribeAndroidModalClosed: jest.fn(), - subscribeUpdateTheme: jest.fn(), + subscribeUpdateEditorSettings: jest.fn(), subscribePreferredColorScheme: () => 'light', subscribeUpdateCapabilities: jest.fn(), subscribeShowNotice: jest.fn(), From 8ed827d91d078bffd602755a0449ade569dd1d22 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 29 Jun 2021 14:46:33 +0200 Subject: [PATCH 41/64] E2E Test Utils: Add getCurrentUser(), and use it for user switching (#33050) --- packages/e2e-test-utils/CHANGELOG.md | 1 + packages/e2e-test-utils/src/get-current-user.js | 16 ++++++++++++++++ .../e2e-test-utils/src/switch-user-to-admin.js | 5 +++-- .../e2e-test-utils/src/switch-user-to-test.js | 5 +++-- 4 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 packages/e2e-test-utils/src/get-current-user.js diff --git a/packages/e2e-test-utils/CHANGELOG.md b/packages/e2e-test-utils/CHANGELOG.md index 890f6040afa72b..4fea6127682e5e 100644 --- a/packages/e2e-test-utils/CHANGELOG.md +++ b/packages/e2e-test-utils/CHANGELOG.md @@ -5,6 +5,7 @@ ### New Features - Added `createUser` and `deleteUser` - Create and delete a user account, respectively. +- Added `getCurrentUser` - Determine the currently logged in user. Changed `switchUserToAdmin` and `switchUserToTest` to use it. ## 5.3.0 (2021-05-31) diff --git a/packages/e2e-test-utils/src/get-current-user.js b/packages/e2e-test-utils/src/get-current-user.js new file mode 100644 index 00000000000000..d59ec0da2dd5da --- /dev/null +++ b/packages/e2e-test-utils/src/get-current-user.js @@ -0,0 +1,16 @@ +/** + * Get the username of the user that's currently logged into WordPress (if any). + * + * @return {string?} username The user that's currently logged into WordPress (if any). + */ +export async function getCurrentUser() { + const cookies = await page.cookies(); + const cookie = cookies.find( + ( c ) => !! c?.name?.startsWith( 'wordpress_logged_in_' ) + ); + + if ( ! cookie?.value ) { + return; + } + return decodeURIComponent( cookie.value ).split( '|' )[ 0 ]; +} diff --git a/packages/e2e-test-utils/src/switch-user-to-admin.js b/packages/e2e-test-utils/src/switch-user-to-admin.js index f36cab835297bc..d1e51322149c0d 100644 --- a/packages/e2e-test-utils/src/switch-user-to-admin.js +++ b/packages/e2e-test-utils/src/switch-user-to-admin.js @@ -1,15 +1,16 @@ /** * Internal dependencies */ +import { getCurrentUser } from './get-current-user'; import { loginUser } from './login-user'; -import { WP_USERNAME, WP_ADMIN_USER } from './shared/config'; +import { WP_ADMIN_USER } from './shared/config'; /** * Switches the current user to the admin user (if the user * running the test is not already the admin user). */ export async function switchUserToAdmin() { - if ( WP_USERNAME === WP_ADMIN_USER.username ) { + if ( ( await getCurrentUser() ) === WP_ADMIN_USER.username ) { return; } await loginUser( WP_ADMIN_USER.username, WP_ADMIN_USER.password ); diff --git a/packages/e2e-test-utils/src/switch-user-to-test.js b/packages/e2e-test-utils/src/switch-user-to-test.js index c726de258fb577..b0a2d009cb0b0e 100644 --- a/packages/e2e-test-utils/src/switch-user-to-test.js +++ b/packages/e2e-test-utils/src/switch-user-to-test.js @@ -1,15 +1,16 @@ /** * Internal dependencies */ +import { getCurrentUser } from './get-current-user'; import { loginUser } from './login-user'; -import { WP_USERNAME, WP_ADMIN_USER } from './shared/config'; +import { WP_USERNAME } from './shared/config'; /** * Switches the current user to whichever user we should be * running the tests as (if we're not already that user). */ export async function switchUserToTest() { - if ( WP_USERNAME === WP_ADMIN_USER.username ) { + if ( ( await getCurrentUser() ) === WP_USERNAME ) { return; } await loginUser(); From 24bf3628818e96d7f5def53351fa95383715471d Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 29 Jun 2021 15:29:58 +0200 Subject: [PATCH 42/64] Prepublish Panel: Disable the Publish and Cancel buttons while saving (#32889) Currently, when editing a post in such a way that a "multi-entity save" is required (i.e. updates to things that aren't just limited to the post content (and other post attributes), but e.g. site title and the like), the user is prompted with a panel to save those changes prior to publishing the post. Once they're done saving, they're presented with the regular pre-publish panel, including the familiar 'Publish' and 'Cancel' buttons. Actually, those buttons are visible even before the rest of the pre-publish panel is: The panel might still show a spinner that indicates that entities are being saved, but the buttons are already present -- and clickable. This has turned out to be a problem in e2e tests, where the headless browser is quick enough to press one of those buttons, even though entities haven't been saved yet. However, it's of course possible that a user might also be quick enough (e.g. if behind a slow network connection). This commit changes the behavior to disable the buttons while entities are still being saved. --- .../components/post-publish-button/index.js | 2 +- .../post-publish-button/test/index.js | 30 +++++++++++++++++++ .../components/post-publish-panel/index.js | 6 +++- .../test/__snapshots__/index.js.snap | 2 ++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/packages/editor/src/components/post-publish-button/index.js b/packages/editor/src/components/post-publish-button/index.js index 36b67b9756d455..58029c2789faae 100644 --- a/packages/editor/src/components/post-publish-button/index.js +++ b/packages/editor/src/components/post-publish-button/index.js @@ -147,7 +147,7 @@ export class PostPublishButton extends Component { }; const buttonProps = { - 'aria-disabled': isButtonDisabled && ! hasNonPostEntityChanges, + 'aria-disabled': isButtonDisabled, className: 'editor-post-publish-button', isBusy: ! isAutoSaving && isSaving && isPublished, variant: 'primary', diff --git a/packages/editor/src/components/post-publish-button/test/index.js b/packages/editor/src/components/post-publish-button/test/index.js index 7dbcc34036c02a..b816b0477149fb 100644 --- a/packages/editor/src/components/post-publish-button/test/index.js +++ b/packages/editor/src/components/post-publish-button/test/index.js @@ -25,6 +25,22 @@ describe( 'PostPublishButton', () => { ); } ); + it( 'should be true if post is currently saving, even if there are non-post entity changes', () => { + // This normally means that we're still saving those changes. + const wrapper = shallow( + + ); + + expect( wrapper.find( Button ).prop( 'aria-disabled' ) ).toBe( + true + ); + } ); + it( 'should be true if forceIsSaving is true', () => { const wrapper = shallow( @@ -96,6 +112,20 @@ describe( 'PostPublishButton', () => { false ); } ); + + it( 'should be false if there are non-post entity changes', () => { + const wrapper = shallow( + + ); + + expect( wrapper.find( Button ).prop( 'aria-disabled' ) ).toBe( + false + ); + } ); } ); describe( 'publish status', () => { diff --git a/packages/editor/src/components/post-publish-panel/index.js b/packages/editor/src/components/post-publish-panel/index.js index c2092bd70e3398..5b58fba2f1810c 100644 --- a/packages/editor/src/components/post-publish-panel/index.js +++ b/packages/editor/src/components/post-publish-panel/index.js @@ -97,7 +97,11 @@ export class PostPublishPanel extends Component { />
-
diff --git a/packages/editor/src/components/post-publish-panel/test/__snapshots__/index.js.snap b/packages/editor/src/components/post-publish-panel/test/__snapshots__/index.js.snap index 7bd560d187275c..e7507902cb5fea 100644 --- a/packages/editor/src/components/post-publish-panel/test/__snapshots__/index.js.snap +++ b/packages/editor/src/components/post-publish-panel/test/__snapshots__/index.js.snap @@ -135,6 +135,7 @@ exports[`PostPublishPanel should render the pre-publish panel if the post is not className="editor-post-publish-panel__header-cancel-button" > Cancel @@ -175,6 +176,7 @@ exports[`PostPublishPanel should render the spinner if the post is being saved 1 className="editor-post-publish-panel__header-cancel-button" > Cancel From b6a8a288852019f5a809cc5f3ad1c268905f739d Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Tue, 29 Jun 2021 07:04:08 -0700 Subject: [PATCH 43/64] components: Restrict imports of @emotion/css (#33051) * Add @emotion/css to restricted imports list * Temporarily disable no-restricted-imports for @emotion/css --- .eslintrc.js | 5 +++++ packages/components/src/base-field/hook.js | 3 +++ packages/components/src/base-field/styles.js | 3 +++ packages/components/src/card/card-body/hook.js | 3 +++ packages/components/src/card/card-divider/hook.js | 3 +++ packages/components/src/card/card-footer/hook.js | 3 +++ packages/components/src/card/card-header/hook.js | 3 +++ packages/components/src/card/card-media/hook.js | 3 +++ packages/components/src/card/card/component.js | 3 +++ packages/components/src/card/card/hook.js | 3 +++ packages/components/src/card/styles.js | 3 +++ packages/components/src/divider/component.tsx | 3 +++ packages/components/src/divider/styles.ts | 3 +++ packages/components/src/elevation/hook.js | 3 +++ packages/components/src/elevation/styles.js | 3 +++ packages/components/src/flex/flex-item/hook.js | 3 +++ packages/components/src/flex/flex/hook.js | 3 +++ packages/components/src/flex/styles.js | 3 +++ packages/components/src/grid/hook.js | 3 +++ packages/components/src/scrollable/hook.js | 3 +++ packages/components/src/scrollable/styles.js | 4 ++++ packages/components/src/spacer/hook.ts | 3 +++ packages/components/src/surface/hook.js | 3 +++ packages/components/src/surface/styles.js | 3 +++ packages/components/src/text/hook.js | 3 +++ packages/components/src/text/styles.js | 3 +++ packages/components/src/truncate/hook.js | 3 +++ packages/components/src/truncate/styles.js | 3 +++ packages/components/src/ui/context/use-context-system.js | 3 +++ packages/components/src/ui/control-group/hook.js | 3 +++ packages/components/src/ui/control-group/styles.js | 3 +++ packages/components/src/ui/control-label/hook.js | 3 +++ packages/components/src/ui/control-label/styles.js | 3 +++ packages/components/src/ui/form-group/form-group-styles.js | 3 +++ packages/components/src/ui/form-group/use-form-group.js | 3 +++ packages/components/src/ui/item-group/styles.ts | 3 +++ packages/components/src/ui/item-group/use-item-group.ts | 3 +++ packages/components/src/ui/item-group/use-item.ts | 3 +++ packages/components/src/ui/popover/content.js | 3 +++ packages/components/src/ui/popover/styles.js | 3 +++ packages/components/src/ui/tooltip/content.js | 3 +++ packages/components/src/ui/tooltip/styles.js | 3 +++ packages/components/src/ui/utils/get-high-dpi.ts | 3 +++ packages/components/src/ui/visually-hidden/hook.js | 3 +++ packages/components/src/ui/visually-hidden/styles.js | 3 +++ packages/components/src/utils/browsers.js | 7 +++++-- packages/components/src/z-stack/component.tsx | 3 +++ packages/components/src/z-stack/styles.ts | 3 +++ 48 files changed, 149 insertions(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 5ad25a66edaff4..b24c3129f1134e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -96,6 +96,11 @@ module.exports = { message: '`puppeteer-testing-library` is still experimental.', }, + { + name: '@emotion/css', + message: + 'Please use `@emotion/react` and `@emotion/styled` in order to maintain iframe support', + }, ], }, ], diff --git a/packages/components/src/base-field/hook.js b/packages/components/src/base-field/hook.js index f11a7169a3f5f1..28f7a3b5e6aae0 100644 --- a/packages/components/src/base-field/hook.js +++ b/packages/components/src/base-field/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/base-field/styles.js b/packages/components/src/base-field/styles.js index 20e12fee0e57f2..9c9946b85caa21 100644 --- a/packages/components/src/base-field/styles.js +++ b/packages/components/src/base-field/styles.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; /** diff --git a/packages/components/src/card/card-body/hook.js b/packages/components/src/card/card-body/hook.js index 1f27df7ec47a19..3de530b38017b0 100644 --- a/packages/components/src/card/card-body/hook.js +++ b/packages/components/src/card/card-body/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/card/card-divider/hook.js b/packages/components/src/card/card-divider/hook.js index 9095e1497881ea..3f05de00abc04e 100644 --- a/packages/components/src/card/card-divider/hook.js +++ b/packages/components/src/card/card-divider/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/card/card-footer/hook.js b/packages/components/src/card/card-footer/hook.js index c52d4530c5d0f9..bc1345ddff1105 100644 --- a/packages/components/src/card/card-footer/hook.js +++ b/packages/components/src/card/card-footer/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/card/card-header/hook.js b/packages/components/src/card/card-header/hook.js index 5d272495ea348e..fa046ec316142b 100644 --- a/packages/components/src/card/card-header/hook.js +++ b/packages/components/src/card/card-header/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/card/card-media/hook.js b/packages/components/src/card/card-media/hook.js index fd2fba826b6e46..c0ade5fa2ffc26 100644 --- a/packages/components/src/card/card-media/hook.js +++ b/packages/components/src/card/card-media/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/card/card/component.js b/packages/components/src/card/card/component.js index 0f266f33841ac6..f49f67128883b5 100644 --- a/packages/components/src/card/card/component.js +++ b/packages/components/src/card/card/component.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; /** diff --git a/packages/components/src/card/card/hook.js b/packages/components/src/card/card/hook.js index e90d51ec669c3e..ee3e66a22e98fb 100644 --- a/packages/components/src/card/card/hook.js +++ b/packages/components/src/card/card/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/card/styles.js b/packages/components/src/card/styles.js index 6d874a49fcceab..d4ecdd89db176c 100644 --- a/packages/components/src/card/styles.js +++ b/packages/components/src/card/styles.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; /** diff --git a/packages/components/src/divider/component.tsx b/packages/components/src/divider/component.tsx index 0bf253d1b03791..3e296464554e72 100644 --- a/packages/components/src/divider/component.tsx +++ b/packages/components/src/divider/component.tsx @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css, cx } from '@emotion/css'; // eslint-disable-next-line no-restricted-imports import { Separator } from 'reakit'; diff --git a/packages/components/src/divider/styles.ts b/packages/components/src/divider/styles.ts index 3a6b1e20ca9861..b13218ab657fe8 100644 --- a/packages/components/src/divider/styles.ts +++ b/packages/components/src/divider/styles.ts @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; /** diff --git a/packages/components/src/elevation/hook.js b/packages/components/src/elevation/hook.js index 173c331597f34b..3f4d6c88dbedee 100644 --- a/packages/components/src/elevation/hook.js +++ b/packages/components/src/elevation/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css, cx } from '@emotion/css'; import { isNil } from 'lodash'; diff --git a/packages/components/src/elevation/styles.js b/packages/components/src/elevation/styles.js index 23c29f01d85bcf..8199f1264023d2 100644 --- a/packages/components/src/elevation/styles.js +++ b/packages/components/src/elevation/styles.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; export const Elevation = css` diff --git a/packages/components/src/flex/flex-item/hook.js b/packages/components/src/flex/flex-item/hook.js index 4ab2ff3beeee0b..9ea9c077e7889c 100644 --- a/packages/components/src/flex/flex-item/hook.js +++ b/packages/components/src/flex/flex-item/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css, cx } from '@emotion/css'; /** diff --git a/packages/components/src/flex/flex/hook.js b/packages/components/src/flex/flex/hook.js index 044644e3c55a44..1af2602a38255d 100644 --- a/packages/components/src/flex/flex/hook.js +++ b/packages/components/src/flex/flex/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css, cx } from '@emotion/css'; /** diff --git a/packages/components/src/flex/styles.js b/packages/components/src/flex/styles.js index 9fdeade2335fca..a1ca92db3afee6 100644 --- a/packages/components/src/flex/styles.js +++ b/packages/components/src/flex/styles.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; export const Flex = css` diff --git a/packages/components/src/grid/hook.js b/packages/components/src/grid/hook.js index 9de54c0e0a7a27..69c1e74b4954d8 100644 --- a/packages/components/src/grid/hook.js +++ b/packages/components/src/grid/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css, cx } from '@emotion/css'; /** diff --git a/packages/components/src/scrollable/hook.js b/packages/components/src/scrollable/hook.js index 1451d46161275e..db71d3dc158f9b 100644 --- a/packages/components/src/scrollable/hook.js +++ b/packages/components/src/scrollable/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/scrollable/styles.js b/packages/components/src/scrollable/styles.js index 0bff9cf580bcd2..d9ae60f8f0396e 100644 --- a/packages/components/src/scrollable/styles.js +++ b/packages/components/src/scrollable/styles.js @@ -1,7 +1,11 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; + /** * Internal dependencies */ diff --git a/packages/components/src/spacer/hook.ts b/packages/components/src/spacer/hook.ts index 17215d0dfebfb8..2bca326ed584f4 100644 --- a/packages/components/src/spacer/hook.ts +++ b/packages/components/src/spacer/hook.ts @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css, cx } from '@emotion/css'; /** diff --git a/packages/components/src/surface/hook.js b/packages/components/src/surface/hook.js index 1269bc06c7cae1..10b46a20aeb060 100644 --- a/packages/components/src/surface/hook.js +++ b/packages/components/src/surface/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/surface/styles.js b/packages/components/src/surface/styles.js index 2df015ef303c7c..093f96d68e8a63 100644 --- a/packages/components/src/surface/styles.js +++ b/packages/components/src/surface/styles.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; /** diff --git a/packages/components/src/text/hook.js b/packages/components/src/text/hook.js index 10016bf53fc90e..601f8139a9859e 100644 --- a/packages/components/src/text/hook.js +++ b/packages/components/src/text/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css, cx } from '@emotion/css'; import { isPlainObject } from 'lodash'; diff --git a/packages/components/src/text/styles.js b/packages/components/src/text/styles.js index 6323d6aedc5124..3f8dc4dd3e2070 100644 --- a/packages/components/src/text/styles.js +++ b/packages/components/src/text/styles.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; /** diff --git a/packages/components/src/truncate/hook.js b/packages/components/src/truncate/hook.js index 1598074718270c..be990dd4fcc77f 100644 --- a/packages/components/src/truncate/hook.js +++ b/packages/components/src/truncate/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css, cx } from '@emotion/css'; /** diff --git a/packages/components/src/truncate/styles.js b/packages/components/src/truncate/styles.js index b70e64fa76828e..d49a3e3294630f 100644 --- a/packages/components/src/truncate/styles.js +++ b/packages/components/src/truncate/styles.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; export const Truncate = css` diff --git a/packages/components/src/ui/context/use-context-system.js b/packages/components/src/ui/context/use-context-system.js index 48926b32c8e83f..5abbe63ef24457 100644 --- a/packages/components/src/ui/context/use-context-system.js +++ b/packages/components/src/ui/context/use-context-system.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/ui/control-group/hook.js b/packages/components/src/ui/control-group/hook.js index 3dd09bc997afaf..1a94aced2f835d 100644 --- a/packages/components/src/ui/control-group/hook.js +++ b/packages/components/src/ui/control-group/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/ui/control-group/styles.js b/packages/components/src/ui/control-group/styles.js index ef811dec1c51c4..2163aac28175c5 100644 --- a/packages/components/src/ui/control-group/styles.js +++ b/packages/components/src/ui/control-group/styles.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; export const first = css` diff --git a/packages/components/src/ui/control-label/hook.js b/packages/components/src/ui/control-label/hook.js index 54d4b940f4515e..66e0d7612ea769 100644 --- a/packages/components/src/ui/control-label/hook.js +++ b/packages/components/src/ui/control-label/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/ui/control-label/styles.js b/packages/components/src/ui/control-label/styles.js index 209b9fee06adfd..1a1afde87719b7 100644 --- a/packages/components/src/ui/control-label/styles.js +++ b/packages/components/src/ui/control-label/styles.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; /** diff --git a/packages/components/src/ui/form-group/form-group-styles.js b/packages/components/src/ui/form-group/form-group-styles.js index d1c4766658159a..c69bd8b1e43def 100644 --- a/packages/components/src/ui/form-group/form-group-styles.js +++ b/packages/components/src/ui/form-group/form-group-styles.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; export const FormGroup = css` diff --git a/packages/components/src/ui/form-group/use-form-group.js b/packages/components/src/ui/form-group/use-form-group.js index 102a5efa634b36..b107b5cb95f988 100644 --- a/packages/components/src/ui/form-group/use-form-group.js +++ b/packages/components/src/ui/form-group/use-form-group.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/ui/item-group/styles.ts b/packages/components/src/ui/item-group/styles.ts index 8ada7b89237793..a5efb4afa9cc3e 100644 --- a/packages/components/src/ui/item-group/styles.ts +++ b/packages/components/src/ui/item-group/styles.ts @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; /** diff --git a/packages/components/src/ui/item-group/use-item-group.ts b/packages/components/src/ui/item-group/use-item-group.ts index 0942a743cd9385..a30dfdc2d9ce4f 100644 --- a/packages/components/src/ui/item-group/use-item-group.ts +++ b/packages/components/src/ui/item-group/use-item-group.ts @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/ui/item-group/use-item.ts b/packages/components/src/ui/item-group/use-item.ts index 9f1f5736562c30..f654a886d70a31 100644 --- a/packages/components/src/ui/item-group/use-item.ts +++ b/packages/components/src/ui/item-group/use-item.ts @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/ui/popover/content.js b/packages/components/src/ui/popover/content.js index fbf48792b96489..cdb29e8c5bd582 100644 --- a/packages/components/src/ui/popover/content.js +++ b/packages/components/src/ui/popover/content.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css, cx } from '@emotion/css'; // eslint-disable-next-line no-restricted-imports import { Popover as ReakitPopover } from 'reakit'; diff --git a/packages/components/src/ui/popover/styles.js b/packages/components/src/ui/popover/styles.js index 9fc4dbc91352d7..b3bb67def80ab9 100644 --- a/packages/components/src/ui/popover/styles.js +++ b/packages/components/src/ui/popover/styles.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; /** diff --git a/packages/components/src/ui/tooltip/content.js b/packages/components/src/ui/tooltip/content.js index 9a05ec7bbaaefe..4861941aa0552b 100644 --- a/packages/components/src/ui/tooltip/content.js +++ b/packages/components/src/ui/tooltip/content.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; // eslint-disable-next-line no-restricted-imports import { Tooltip as ReakitTooltip } from 'reakit'; diff --git a/packages/components/src/ui/tooltip/styles.js b/packages/components/src/ui/tooltip/styles.js index e50a89aab24099..8e3d0fabb69d4a 100644 --- a/packages/components/src/ui/tooltip/styles.js +++ b/packages/components/src/ui/tooltip/styles.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; import styled from '@emotion/styled'; diff --git a/packages/components/src/ui/utils/get-high-dpi.ts b/packages/components/src/ui/utils/get-high-dpi.ts index b38e953511ddad..15b0e2f0aae001 100644 --- a/packages/components/src/ui/utils/get-high-dpi.ts +++ b/packages/components/src/ui/utils/get-high-dpi.ts @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css, CSSInterpolation } from '@emotion/css'; export function getHighDpi( diff --git a/packages/components/src/ui/visually-hidden/hook.js b/packages/components/src/ui/visually-hidden/hook.js index 26f3ced9797d54..a0d67887f10d72 100644 --- a/packages/components/src/ui/visually-hidden/hook.js +++ b/packages/components/src/ui/visually-hidden/hook.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { cx } from '@emotion/css'; /** diff --git a/packages/components/src/ui/visually-hidden/styles.js b/packages/components/src/ui/visually-hidden/styles.js index 87f650b610d596..972c5a65f6e4ba 100644 --- a/packages/components/src/ui/visually-hidden/styles.js +++ b/packages/components/src/ui/visually-hidden/styles.js @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; /** diff --git a/packages/components/src/utils/browsers.js b/packages/components/src/utils/browsers.js index 4e71dd75954cb5..96008a62ac6a64 100644 --- a/packages/components/src/utils/browsers.js +++ b/packages/components/src/utils/browsers.js @@ -1,11 +1,14 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; /* eslint-disable jsdoc/no-undefined-types */ /** - * @param {TemplateStringsArray} strings + * @param {TemplateStringsArray} strings * @param {import('@emotion/css/create-instance').CSSInterpolation[]} interpolations */ export function firefoxOnly( strings, ...interpolations ) { @@ -19,7 +22,7 @@ export function firefoxOnly( strings, ...interpolations ) { } /** - * @param {TemplateStringsArray} strings + * @param {TemplateStringsArray} strings * @param {import('@emotion/css/create-instance').CSSInterpolation[]} interpolations */ export function safariOnly( strings, ...interpolations ) { diff --git a/packages/components/src/z-stack/component.tsx b/packages/components/src/z-stack/component.tsx index 8b4d0b6d107d20..b3357e881d262b 100644 --- a/packages/components/src/z-stack/component.tsx +++ b/packages/components/src/z-stack/component.tsx @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css, cx } from '@emotion/css'; // eslint-disable-next-line no-restricted-imports import type { Ref, ReactNode } from 'react'; diff --git a/packages/components/src/z-stack/styles.ts b/packages/components/src/z-stack/styles.ts index 60ae05a2a897e4..e74a60de0c705f 100644 --- a/packages/components/src/z-stack/styles.ts +++ b/packages/components/src/z-stack/styles.ts @@ -1,6 +1,9 @@ /** * External dependencies */ +// Disable reason: Temporarily disable for existing usages +// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css +// eslint-disable-next-line no-restricted-imports import { css } from '@emotion/css'; import styled from '@emotion/styled'; From 82d3e4afed5e5f32cb04b45183c129f62f53fb5b Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Tue, 29 Jun 2021 15:17:06 +0000 Subject: [PATCH 44/64] Bump plugin version to 10.9.2 --- gutenberg.php | 2 +- package-lock.json | 2 +- package.json | 2 +- readme.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index 6ab88b1ddad4e2..67eaf6c630c4c9 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the new block editor in core. * Requires at least: 5.6 * Requires PHP: 5.6 - * Version: 10.9.1 + * Version: 10.9.2 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index be1d33fd063859..143e4ed03fbe7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "10.9.1", + "version": "10.9.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5c6f2ce818d575..c97eab3386806f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "10.9.1", + "version": "10.9.2", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", diff --git a/readme.txt b/readme.txt index ed14a644cb815c..be70c005bbceac 100644 --- a/readme.txt +++ b/readme.txt @@ -55,4 +55,4 @@ View release page. +To read the changelog for Gutenberg 10.9.2, please navigate to the release page. From 9305d979fb9a806019e29f0299deaf494db7a843 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 29 Jun 2021 16:33:56 +0100 Subject: [PATCH 45/64] chore(release): publish - @wordpress/base-styles@3.5.4 - @wordpress/block-directory@2.1.14 - @wordpress/block-library@3.2.12 - @wordpress/customize-widgets@1.0.13 - @wordpress/e2e-tests@2.2.11 - @wordpress/edit-navigation@1.9.12 - @wordpress/edit-post@4.1.14 - @wordpress/edit-site@2.1.14 - @wordpress/edit-widgets@2.1.14 - @wordpress/postcss-plugins-preset@3.1.4 - @wordpress/react-native-editor@1.53.13 - @wordpress/scripts@16.1.4 - @wordpress/widgets@1.1.13 --- packages/base-styles/package.json | 2 +- packages/block-directory/package.json | 2 +- packages/block-library/package.json | 2 +- packages/customize-widgets/package.json | 2 +- packages/e2e-tests/package.json | 2 +- packages/edit-navigation/package.json | 2 +- packages/edit-post/package.json | 2 +- packages/edit-site/package.json | 2 +- packages/edit-widgets/package.json | 2 +- packages/postcss-plugins-preset/package.json | 2 +- packages/scripts/package.json | 2 +- packages/widgets/package.json | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/base-styles/package.json b/packages/base-styles/package.json index 8f0837fbb6790e..7f273c2d732eb8 100644 --- a/packages/base-styles/package.json +++ b/packages/base-styles/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/base-styles", - "version": "3.5.3", + "version": "3.5.4", "description": "Base SCSS utilities and variables for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index c78b5bacaa9cc1..4fc2962878bc6c 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-directory", - "version": "2.1.13", + "version": "2.1.14", "description": "Extend editor with block directory features to search, download and install blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 087d623110e78f..ebb79ef5673ddd 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "3.2.11", + "version": "3.2.12", "description": "Block library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/customize-widgets/package.json b/packages/customize-widgets/package.json index e7b1801f78248c..e8973fa74d0ee5 100644 --- a/packages/customize-widgets/package.json +++ b/packages/customize-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/customize-widgets", - "version": "1.0.12", + "version": "1.0.13", "description": "Widgets blocks in Customizer Module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-tests/package.json b/packages/e2e-tests/package.json index 252f704e72ac7e..03ac6c0fb8bc1d 100644 --- a/packages/e2e-tests/package.json +++ b/packages/e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-tests", - "version": "2.2.10", + "version": "2.2.11", "description": "End-To-End (E2E) tests for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-navigation/package.json b/packages/edit-navigation/package.json index d9876dbe033f4c..66247f0bcf7889 100644 --- a/packages/edit-navigation/package.json +++ b/packages/edit-navigation/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-navigation", - "version": "1.9.11", + "version": "1.9.12", "private": true, "description": "Module for the Navigation page in WordPress.", "author": "The WordPress Contributors", diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index e7566243c2224e..fe2c1e49392cbe 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-post", - "version": "4.1.13", + "version": "4.1.14", "description": "Edit Post module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index 055d8924ab1cab..c0302861b16dd3 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-site", - "version": "2.1.13", + "version": "2.1.14", "description": "Edit Site Page module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-widgets/package.json b/packages/edit-widgets/package.json index 1710b43c66fbc6..2a7ce2a3459ad6 100644 --- a/packages/edit-widgets/package.json +++ b/packages/edit-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-widgets", - "version": "2.1.13", + "version": "2.1.14", "description": "Widgets Page module for WordPress..", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/postcss-plugins-preset/package.json b/packages/postcss-plugins-preset/package.json index 0dcbf34b6acce5..4b9657671b6cbb 100644 --- a/packages/postcss-plugins-preset/package.json +++ b/packages/postcss-plugins-preset/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/postcss-plugins-preset", - "version": "3.1.3", + "version": "3.1.4", "description": "PostCSS sharable plugins preset for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/scripts/package.json b/packages/scripts/package.json index f62bf4c8da1814..dfaf4fddadebce 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/scripts", - "version": "16.1.3", + "version": "16.1.4", "description": "Collection of reusable scripts for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/widgets/package.json b/packages/widgets/package.json index ac55f282312a22..b0c7065eca6a3a 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/widgets", - "version": "1.1.12", + "version": "1.1.13", "description": "Functionality used by the widgets block editor in the Widgets screen and the Customizer.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From 07406cdd30edcb19ed5dc903e859d4d7c0e60bdb Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Tue, 29 Jun 2021 22:50:58 +0400 Subject: [PATCH 46/64] ServerSideRender: Update documentation for placeholder props (#33030) --- packages/server-side-render/README.md | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/server-side-render/README.md b/packages/server-side-render/README.md index 50743c8281370e..8c0a782fed3b16 100644 --- a/packages/server-side-render/README.md +++ b/packages/server-side-render/README.md @@ -67,25 +67,35 @@ E.g: `{ post_id: 12 }`. ### EmptyResponsePlaceholder -This is a [render prop](https://reactjs.org/docs/render-props.html). When the api response is empty, the value of this prop is rendered. The render prop will receive the value of the api response as well as all props passed into `ServerSideRenderer`. +The component is rendered when the API response is empty. The component will receive the value of the API response, and all props passed into `ServerSideRenderer`. -- Type: `WPElement` +- Type: `Component` - Required: No ### ErrorResponsePlaceholder -This is a [render prop](https://reactjs.org/docs/render-props.html). When the api response is an error, the value of this prop is rendered. The render prop will receive the value of the api response as well as all props passed into `ServerSideRenderer`. +The component is rendered when the API response is an error. The component will receive the value of the API response, and all props passed into `ServerSideRenderer`. -- Type: `WPElement` +- Type: `Component` - Required: No ### LoadingResponsePlaceholder -This is a [render prop](https://reactjs.org/docs/render-props.html). While the request is being processed (loading state), the value of this prop is rendered. The render prop will receive the value of the api response as well as all props passed into `ServerSideRenderer`. +The component is rendered while the API request is being processed (loading state). The component will receive the value of the API response, and all props passed into `ServerSideRenderer`. -- Type: `WPElement` +- Type: `Component` - Required: No +#### Example usage + +```jsx +const MyServerSideRender = () => ( + +); +``` + ## Usage Render core/archives preview. From 4d0959e2dc956a9e40a4e04db3029f26832c4d70 Mon Sep 17 00:00:00 2001 From: Kerry Liu Date: Tue, 29 Jun 2021 12:44:37 -0700 Subject: [PATCH 47/64] Navigation: skip flakey tests (#33074) --- .../e2e-tests/specs/experiments/blocks/navigation.test.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/e2e-tests/specs/experiments/blocks/navigation.test.js b/packages/e2e-tests/specs/experiments/blocks/navigation.test.js index 9212d6ee436e8e..4c389d1076970f 100644 --- a/packages/e2e-tests/specs/experiments/blocks/navigation.test.js +++ b/packages/e2e-tests/specs/experiments/blocks/navigation.test.js @@ -592,7 +592,9 @@ describe( 'Navigation', () => { expect( await getEditedPostContent() ).toMatchSnapshot(); } ); - it( 'loads frontend code only if the block is present', async () => { + // The following tests are unstable, roughly around when https://github.com/WordPress/wordpress-develop/pull/1412 + // landed. The block manually tests well, so let's skip to unblock other PRs and immediately follow up. cc @vcanales + it.skip( 'loads frontend code only if the block is present', async () => { // Mock the response from the Pages endpoint. This is done so that the pages returned are always // consistent and to test the feature more rigorously than the single default sample page. await mockPagesResponse( [ @@ -650,7 +652,7 @@ describe( 'Navigation', () => { expect( tagCount ).toBe( 1 ); } ); - it( 'loads frontend code only if responsiveness is turned on', async () => { + it.skip( 'loads frontend code only if responsiveness is turned on', async () => { await mockPagesResponse( [ { title: 'Home', From 012461b161b915496ad4aef3b5fd0727abedf583 Mon Sep 17 00:00:00 2001 From: Kerry Liu Date: Tue, 29 Jun 2021 13:19:09 -0700 Subject: [PATCH 48/64] Safari: see if compositing layer size is more reasonable when position fixed divs are not inserted into content (#32824) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Safari: remove position:fixed div in scrollable content so compositing layers are of more reasonable size * Prevent scroll after focusing focus capture element * Prevent scrolling when tabbing back to a focus capture div Co-authored-by: Ella van Durpe --- .../components/writing-flow/use-tab-nav.js | 56 ++++++++++++++++--- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/packages/block-editor/src/components/writing-flow/use-tab-nav.js b/packages/block-editor/src/components/writing-flow/use-tab-nav.js index b94a6cfb86fb9d..04456706a6bb4e 100644 --- a/packages/block-editor/src/components/writing-flow/use-tab-nav.js +++ b/packages/block-editor/src/components/writing-flow/use-tab-nav.js @@ -12,12 +12,6 @@ import { useRef } from '@wordpress/element'; */ import { store as blockEditorStore } from '../../store'; -/** - * Useful for positioning an element within the viewport so focussing the - * element does not scroll the page. - */ -const PREVENT_SCROLL_ON_FOCUS = { position: 'fixed' }; - function isFormElement( element ) { const { tagName } = element; return ( @@ -75,7 +69,6 @@ export default function useTabNav() { ref={ focusCaptureBeforeRef } tabIndex={ focusCaptureTabIndex } onFocus={ onFocusCapture } - style={ PREVENT_SCROLL_ON_FOCUS } /> ); @@ -84,7 +77,6 @@ export default function useTabNav() { ref={ focusCaptureAfterRef } tabIndex={ focusCaptureTabIndex } onFocus={ onFocusCapture } - style={ PREVENT_SCROLL_ON_FOCUS } /> ); @@ -131,16 +123,62 @@ export default function useTabNav() { // doesn't refocus this block and so it allows default behaviour // (moving focus to the next tabbable element). noCapture.current = true; - next.current.focus(); + + // Focusing the focus capture element, which is located above and + // below the editor, should not scroll the page all the way up or + // down. + next.current.focus( { preventScroll: true } ); } function onFocusOut( event ) { lastFocus.current = event.target; } + // When tabbing back to an element in block list, this event handler prevents scrolling if the + // focus capture divs (before/after) are outside of the viewport. (For example shift+tab back to a paragraph + // when focus is on a sidebar element. This prevents the scrollable writing area from jumping either to the + // top or bottom of the document. + // + // Note that it isn't possible to disable scrolling in the onFocus event. We need to intercept this + // earlier in the keypress handler, and call focus( { preventScroll: true } ) instead. + // https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/focus#parameters + function preventScrollOnTab( event ) { + if ( event.keyCode !== TAB ) { + return; + } + + if ( event.target?.getAttribute( 'role' ) === 'region' ) { + return; + } + + if ( container.current === event.target ) { + return; + } + + const isShift = event.shiftKey; + const direction = isShift ? 'findPrevious' : 'findNext'; + const target = focus.tabbable[ direction ]( event.target ); + // only do something when the next tabbable is a focus capture div (before/after) + if ( + target === focusCaptureBeforeRef.current || + target === focusCaptureAfterRef.current + ) { + event.preventDefault(); + target.focus( { preventScroll: true } ); + } + } + + node.ownerDocument.defaultView.addEventListener( + 'keydown', + preventScrollOnTab + ); node.addEventListener( 'keydown', onKeyDown ); node.addEventListener( 'focusout', onFocusOut ); return () => { + node.ownerDocument.defaultView.removeEventListener( + 'keydown', + preventScrollOnTab + ); node.removeEventListener( 'keydown', onKeyDown ); node.removeEventListener( 'focusout', onFocusOut ); }; From a125447b6383e0a186e3614fdd886c61f2651a1c Mon Sep 17 00:00:00 2001 From: Siobhan Bamber Date: Tue, 29 Jun 2021 22:09:20 +0100 Subject: [PATCH 49/64] [RNMobile] Update Loading and Failed Screens for Unsupported Block Editor (#32395) * Add strings for use in updated layout These strings will be referenced in an updated layout, which seeks to provide more details to users when the UBE is loading or fails to load. * Add dimensions for use in updated layout These dimension will be used in an update to the "foreground_view" layout, which will display when the UBE is either loading or has failed to load. * Add 'ube_failed' image for use in new screen This image will be used on a new screen, which will be displayed to users when the UBE fails to load. * Add image and text to 'foreground_view' The 'foreground_view' screen is displayed to users when the UBE is loading. With this commit, an image and text (both a title and subtitle) are added to the screen. The image is invisible by default, as it'll only be visible if the UBE fails to load. Future commits will make the image visible in cases where the UBE doesn't load, and also change the text used for the title and subtitle. * Declare and retrieve new views The new views (added to 'foreground_view' in the last commit) are declared and retrieved (via 'findViewById') in this commit. Any updates to the old 'View' have also been updated to represent the fact that 'foreground_view' is now a 'LinearLayout'. * Introduce function that fires when UBE fails With this commit, a 'showTroubleshootingInstructions' is introduced. This function will fire after 10 seconds, if Gutenberg still hasn't loaded after that time. * Make changes to progress screen when UBE fails If the 'showTroubleshootingInstructions' function fires, this commit includes changes that will update the progress screen's title, text, and image accordingly. * Add reference to color used in image The "ube.failed.xml" is currently an image of a cloud, which was copied/pasted from the WordPress Android app. See: https://github.com/wordpress-mobile/WordPress-Android/blob/develop/WordPress/src/main/res/drawable/img_illustration_cloud_off_152dp.xml The image references a "neutral_20" color and this commit adds that color to the JS side, so that it can be called correctly. * Update CHANGELOG * Correct typo in CHANGELOG.md This commit corrects the reference to an "in-progress" screen to "failed". * Optimize conditionals around "mIsGutenbergReady" At the moment, the code that loads the failed screen in cases where "mIsGutenbergReady" is false loads in a separate if statement to code that loads if "mIsGutenbergReady" is true. This isn't optimal. If "mIsGutenbergReady" resolves as true, then the code that loads the failed screen doesn't need to be processed at all. This commit optimises the code by combining the current two separate if statements into an if/else statement. * Remove unecessary text alignment The centered text alignment was unecessary, as the text remains centered without it. * Update CHANGELOG.md This commit moves the description of these changes from the '1.55.2' section of the notes to the 'unreleased' section. --- .../GutenbergWebViewActivity.java | 26 ++++++++++++- .../src/main/res/drawable/ube_failed.xml | 25 +++++++++++++ .../layout/activity_gutenberg_web_view.xml | 37 ++++++++++++++++++- .../src/main/res/values/colors.xml | 2 + .../src/main/res/values/dimens.xml | 7 ++++ .../src/main/res/values/strings.xml | 6 +++ packages/react-native-editor/CHANGELOG.md | 1 + 7 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 packages/react-native-bridge/android/react-native-bridge/src/main/res/drawable/ube_failed.xml diff --git a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergWebViewActivity.java b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergWebViewActivity.java index cd8ffb69b7dbb0..b67cae08e932eb 100644 --- a/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergWebViewActivity.java +++ b/packages/react-native-bridge/android/react-native-bridge/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergWebViewActivity.java @@ -14,7 +14,10 @@ import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; +import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.ProgressBar; +import android.widget.TextView; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; @@ -41,7 +44,10 @@ public class GutenbergWebViewActivity extends AppCompatActivity { private static final String JAVA_SCRIPT_INTERFACE_NAME = "wpwebkit"; protected WebView mWebView; - protected View mForegroundView; + protected LinearLayout mForegroundView; + protected ImageView mForegroundViewImage; + protected TextView mForegroundViewTitle; + protected TextView mForegroundViewSubtitle; protected boolean mIsRedirected; private ProgressBar mProgressBar; @@ -61,11 +67,24 @@ public class GutenbergWebViewActivity extends AppCompatActivity { // Insert block content insertBlockScript(); }, 200); + } else { + final Handler handler = new Handler(); + handler.postDelayed(() -> { + if (!mIsGutenbergReady) { + showTroubleshootingInstructions(); + } + }, 10000); } } } }; + private void showTroubleshootingInstructions() { + mForegroundViewTitle.setText(R.string.block_editor_failed_title); + mForegroundViewSubtitle.setText(R.string.block_editor_failed_subtitle); + mForegroundViewImage.setVisibility(ImageView.VISIBLE); + } + @SuppressLint("SetJavaScriptEnabled") protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -75,6 +94,9 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { mWebView = findViewById(R.id.gutenberg_web_view); mForegroundView = findViewById(R.id.foreground_view); + mForegroundViewImage = findViewById(R.id.foreground_view_image); + mForegroundViewTitle = findViewById(R.id.foreground_view_title); + mForegroundViewSubtitle = findViewById(R.id.foreground_view_subtitle); mProgressBar = findViewById(R.id.progress_bar); // Set settings @@ -271,7 +293,7 @@ private void onGutenbergReady() { } // We need some extra time to hide all unwanted html elements // like NUX (new user experience) modal is. - mForegroundView.postDelayed(() -> mForegroundView.setVisibility(View.INVISIBLE), 1500); + mForegroundView.postDelayed(() -> mForegroundView.setVisibility(LinearLayout.INVISIBLE), 1500); }, 2000); } diff --git a/packages/react-native-bridge/android/react-native-bridge/src/main/res/drawable/ube_failed.xml b/packages/react-native-bridge/android/react-native-bridge/src/main/res/drawable/ube_failed.xml new file mode 100644 index 00000000000000..ed681ac99a1ea8 --- /dev/null +++ b/packages/react-native-bridge/android/react-native-bridge/src/main/res/drawable/ube_failed.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + diff --git a/packages/react-native-bridge/android/react-native-bridge/src/main/res/layout/activity_gutenberg_web_view.xml b/packages/react-native-bridge/android/react-native-bridge/src/main/res/layout/activity_gutenberg_web_view.xml index 26024f79f21b5a..2dcf133412d64e 100644 --- a/packages/react-native-bridge/android/react-native-bridge/src/main/res/layout/activity_gutenberg_web_view.xml +++ b/packages/react-native-bridge/android/react-native-bridge/src/main/res/layout/activity_gutenberg_web_view.xml @@ -32,11 +32,44 @@ android:layout_height="match_parent" android:visibility="visible"/> - + android:background="@color/white" + android:gravity="center" + android:paddingStart="@dimen/foreground_view_padding_large" + android:paddingEnd="@dimen/foreground_view_padding_large" + android:orientation="vertical"> + + + + + + + #006088 + #a7aaad + diff --git a/packages/react-native-bridge/android/react-native-bridge/src/main/res/values/dimens.xml b/packages/react-native-bridge/android/react-native-bridge/src/main/res/values/dimens.xml index 55b8f63169a804..cd6054d65b6401 100644 --- a/packages/react-native-bridge/android/react-native-bridge/src/main/res/values/dimens.xml +++ b/packages/react-native-bridge/android/react-native-bridge/src/main/res/values/dimens.xml @@ -7,4 +7,11 @@ 72dp 0dp + 30dp + 16dp + 8dp + + 20sp + 16sp + \ No newline at end of file diff --git a/packages/react-native-bridge/android/react-native-bridge/src/main/res/values/strings.xml b/packages/react-native-bridge/android/react-native-bridge/src/main/res/values/strings.xml index 36c2e8cf1f93ec..5e7bc7a1012e8c 100644 --- a/packages/react-native-bridge/android/react-native-bridge/src/main/res/values/strings.xml +++ b/packages/react-native-bridge/android/react-native-bridge/src/main/res/values/strings.xml @@ -3,4 +3,10 @@ Save + Loading the block editor... + Please ensure the block editor is enabled on your site. If it is not enabled, it will not load. + + Unable to load the block editor right now. + Please ensure the block editor is enabled on your site and try again. + \ No newline at end of file diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index bd5b9b569b6936..c66a5df07edd37 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -11,6 +11,7 @@ For each user feature we should also add a importance categorization label to i ## Unreleased +- [*] Update loading and failed screens for web version of the editor [#32395] ## 1.55.2 - [**] Fix incorrect block insertion point after blurring the post title field. [#32831] From 79e02a2684abb53a6235818abcad5c045653fc7b Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Wed, 30 Jun 2021 11:38:17 +0300 Subject: [PATCH 50/64] add post-classes in the loop (#30497) * add post-classes in the loop * Add wp-block-post class --- packages/block-library/src/post-template/index.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/post-template/index.php b/packages/block-library/src/post-template/index.php index dd69fda45fe7f3..c7f52c905577e9 100644 --- a/packages/block-library/src/post-template/index.php +++ b/packages/block-library/src/post-template/index.php @@ -61,7 +61,8 @@ function render_block_core_post_template( $attributes, $content, $block ) { ) ) )->render( array( 'dynamic' => false ) ); - $content .= "
  • {$block_content}
  • "; + $post_classes = esc_attr( implode( ' ', get_post_class( 'wp-block-post' ) ) ); + $content .= '
  • ' . $block_content . '
  • '; } wp_reset_postdata(); From 2f7989197ea2b70595a043b499a4b091fa98986c Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Wed, 30 Jun 2021 11:38:44 +0000 Subject: [PATCH 51/64] Bump plugin version to 11.0.0-rc.1 --- gutenberg.php | 2 +- package-lock.json | 2 +- package.json | 2 +- readme.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index 67eaf6c630c4c9..ab7049ffb7bf9e 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the new block editor in core. * Requires at least: 5.6 * Requires PHP: 5.6 - * Version: 10.9.2 + * Version: 11.0.0-rc.1 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index 143e4ed03fbe7a..ca2d654ff162ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "10.9.2", + "version": "11.0.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index c97eab3386806f..4546293f5555aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "10.9.2", + "version": "11.0.0-rc.1", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", diff --git a/readme.txt b/readme.txt index be70c005bbceac..94bfddb91a1420 100644 --- a/readme.txt +++ b/readme.txt @@ -55,4 +55,4 @@ View release page. +To read the changelog for Gutenberg 11.0.0-rc.1, please navigate to the release page. From 6eac4a26f143c7378c3b39b5a83271538f36dfa9 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 30 Jun 2021 13:43:46 +0100 Subject: [PATCH 52/64] Add Unlink button to LinkControl popover (#32541) * Adds initial Unlink button * Add dedicated opt in prop for removing links * Add tests * Update docs * Focus PR by removing unneeded onChange handler change * Use more accessible query for button Resolves https://github.com/WordPress/gutenberg/pull/32541#discussion_r660516876 * Remove checking if onRemove is a function. --- .../src/components/link-control/README.md | 8 ++++ .../src/components/link-control/index.js | 23 +++++++--- .../src/components/link-control/style.scss | 15 ++++++- .../src/components/link-control/test/index.js | 43 +++++++++++++++++++ packages/format-library/src/link/inline.js | 9 ++++ 5 files changed, 92 insertions(+), 6 deletions(-) diff --git a/packages/block-editor/src/components/link-control/README.md b/packages/block-editor/src/components/link-control/README.md index d143b7b5fcb3ed..45da4a723c07c2 100644 --- a/packages/block-editor/src/components/link-control/README.md +++ b/packages/block-editor/src/components/link-control/README.md @@ -127,6 +127,14 @@ This `suggestion` will then be _automatically_ passed to the `onChange` handler As a result of the above, this prop is often used to allow on the fly creation of new entities (eg: `Posts`, `Pages`) based on the text the user has entered into the link search UI. As an example, the Navigation Block uses `createSuggestion` to create Pages on the fly from within the Block itself. +### onRemove + +- Type: `Function` +- Required: No +- Default: null + +An optional handler, which when passed will trigger the display of an `Unlink` UI within the control. This handler is expected to remove the current `value` of the control thus resetting it back to a default state. The key use case for this is allowing users to remove a link from the control without relying on there being an "unlink" control in the block toolbar. + #### Search `suggestion` values A `suggestion` should have the following shape: diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js index b9a63ceb71da3c..db6b005ac79fab 100644 --- a/packages/block-editor/src/components/link-control/index.js +++ b/packages/block-editor/src/components/link-control/index.js @@ -106,6 +106,7 @@ function LinkControl( { value, settings, onChange = noop, + onRemove, noDirectEntry = false, showSuggestions = true, showInitialSuggestions, @@ -260,11 +261,23 @@ function LinkControl( { /> ) } - +
    + + { onRemove && value && ! isEditingLink && ! isCreatingPage && ( + + ) } +
    ); } diff --git a/packages/block-editor/src/components/link-control/style.scss b/packages/block-editor/src/components/link-control/style.scss index b1b6958dbe5f8c..3d5d5941bb7749 100644 --- a/packages/block-editor/src/components/link-control/style.scss +++ b/packages/block-editor/src/components/link-control/style.scss @@ -380,10 +380,23 @@ $preview-image-height: 140px; padding: 10px; } -.block-editor-link-control__settings { +.block-editor-link-control__tools { + display: flex; + align-items: center; border-top: $border-width solid $gray-300; margin: 0; padding: $grid-unit-20 $grid-unit-30; +} + +.block-editor-link-control__unlink { + padding-left: $grid-unit-20; + padding-right: $grid-unit-20; +} + +.block-editor-link-control__settings { + flex: 1; + margin: 0; + :last-child { margin-bottom: 0; diff --git a/packages/block-editor/src/components/link-control/test/index.js b/packages/block-editor/src/components/link-control/test/index.js index 27e1665d869ff2..250e4656d3708d 100644 --- a/packages/block-editor/src/components/link-control/test/index.js +++ b/packages/block-editor/src/components/link-control/test/index.js @@ -227,6 +227,49 @@ describe( 'Basic rendering', () => { expect( isEditing() ).toBe( false ); } ); } ); + + describe( 'Unlinking', () => { + it( 'should not show "Unlink" button if no onRemove handler is provided', () => { + act( () => { + render( + , + container + ); + } ); + + const unLinkButton = queryByRole( container, 'button', { + name: 'Unlink', + } ); + + expect( unLinkButton ).toBeNull(); + expect( unLinkButton ).not.toBeInTheDocument(); + } ); + + it( 'should show "Unlink" button if a onRemove handler is provided', () => { + const mockOnRemove = jest.fn(); + act( () => { + render( + , + container + ); + } ); + + const unLinkButton = queryByRole( container, 'button', { + name: 'Unlink', + } ); + expect( unLinkButton ).toBeTruthy(); + expect( unLinkButton ).toBeInTheDocument(); + + act( () => { + Simulate.click( unLinkButton ); + } ); + + expect( mockOnRemove ).toHaveBeenCalled(); + } ); + } ); } ); describe( 'Searching for a link', () => { diff --git a/packages/format-library/src/link/inline.js b/packages/format-library/src/link/inline.js index d015267a8e38f7..8a9e7efae2fa1e 100644 --- a/packages/format-library/src/link/inline.js +++ b/packages/format-library/src/link/inline.js @@ -11,6 +11,7 @@ import { isCollapsed, applyFormat, useAnchorRef, + removeFormat, } from '@wordpress/rich-text'; import { __experimentalLinkControl as LinkControl } from '@wordpress/block-editor'; @@ -48,6 +49,13 @@ function InlineLinkUI( { ...nextLinkValue, }; + function removeLink() { + const newValue = removeFormat( value, 'core/link' ); + onChange( newValue ); + stopAddingLink(); + speak( __( 'Link removed.' ), 'assertive' ); + } + function onChangeLink( nextValue ) { // Merge with values from state, both for the purpose of assigning the // next state value, and for use in constructing the new link format if @@ -139,6 +147,7 @@ function InlineLinkUI( { From fba27725d146cc9aa8801950c16223becceef081 Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Wed, 30 Jun 2021 23:48:29 +1000 Subject: [PATCH 53/64] Box Control: Rename VerticalHorizontalInputControls to AxialInputControls (#33016) --- ...horizontal-input-controls.js => axial-input-controls.js} | 2 +- packages/components/src/box-control/index.js | 6 ++---- packages/components/src/box-control/stories/index.js | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) rename packages/components/src/box-control/{vertical-horizontal-input-controls.js => axial-input-controls.js} (97%) diff --git a/packages/components/src/box-control/vertical-horizontal-input-controls.js b/packages/components/src/box-control/axial-input-controls.js similarity index 97% rename from packages/components/src/box-control/vertical-horizontal-input-controls.js rename to packages/components/src/box-control/axial-input-controls.js index 6c7b5a9ad396ee..f4b014e8f5e804 100644 --- a/packages/components/src/box-control/vertical-horizontal-input-controls.js +++ b/packages/components/src/box-control/axial-input-controls.js @@ -7,7 +7,7 @@ import { Layout } from './styles/box-control-styles'; const groupedSides = [ 'vertical', 'horizontal' ]; -export default function VerticalHorizontalInputControls( { +export default function AxialInputControls( { onChange, onFocus, onHoverOn, diff --git a/packages/components/src/box-control/index.js b/packages/components/src/box-control/index.js index e651020069bbde..3f23a17d7ea47b 100644 --- a/packages/components/src/box-control/index.js +++ b/packages/components/src/box-control/index.js @@ -17,7 +17,7 @@ import Button from '../button'; import { FlexItem, FlexBlock } from '../flex'; import AllInputControl from './all-input-control'; import InputControls from './input-controls'; -import VerticalHorizontalInputControls from './vertical-horizontal-input-controls'; +import AxialInputControls from './axial-input-controls'; import BoxControlIcon from './icon'; import { Text } from '../text'; import LinkedButton from './linked-button'; @@ -157,9 +157,7 @@ export default function BoxControl( { ) } { ! isLinked && splitOnAxis && ( - + ) } { ! hasOneSide && ( diff --git a/packages/components/src/box-control/stories/index.js b/packages/components/src/box-control/stories/index.js index f5ba9ee7bcbecf..03f71885edb535 100644 --- a/packages/components/src/box-control/stories/index.js +++ b/packages/components/src/box-control/stories/index.js @@ -87,11 +87,11 @@ export const singleSide = () => { ); }; -export const verticalHorizontalControls = () => { +export const axialControls = () => { return ; }; -export const verticalHorizontalControlsWithSingleSide = () => { +export const axialControlsWithSingleSide = () => { return ( Date: Wed, 30 Jun 2021 16:22:45 +0200 Subject: [PATCH 54/64] Revert "Bump plugin version to 11.0.0-rc.1" This reverts commit 2f7989197ea2b70595a043b499a4b091fa98986c. --- gutenberg.php | 2 +- package-lock.json | 2 +- package.json | 2 +- readme.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index ab7049ffb7bf9e..67eaf6c630c4c9 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the new block editor in core. * Requires at least: 5.6 * Requires PHP: 5.6 - * Version: 11.0.0-rc.1 + * Version: 10.9.2 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index ca2d654ff162ae..143e4ed03fbe7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "11.0.0-rc.1", + "version": "10.9.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 4546293f5555aa..c97eab3386806f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "11.0.0-rc.1", + "version": "10.9.2", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", diff --git a/readme.txt b/readme.txt index 94bfddb91a1420..be70c005bbceac 100644 --- a/readme.txt +++ b/readme.txt @@ -55,4 +55,4 @@ View release page. +To read the changelog for Gutenberg 10.9.2, please navigate to the release page. From 5cafe02e25f9a42d4abd7bf05857c006683ef023 Mon Sep 17 00:00:00 2001 From: Adam Zielinski Date: Wed, 30 Jun 2021 16:25:57 +0200 Subject: [PATCH 55/64] Fix flaky widgets-related E2E tests (#33066) * Remove empty keys from the compared object * Revert dev artifacts * Disable the gutenberg-test-marquee-widget plugin * Wrap marquee tests in their own describe statement * Lint * Update snapshots * Replace hello with howdy * Move plugin activation to beforeEach * Move deleteAllWidgets to beforeEach * Update tests * use data-testid rather than name attribute selectors * Remove any existing marquees before running the tests, use the "save" form button * Remove dev artifact Co-authored-by: Kai Hao --- .../plugins/marquee-function-widget.php | 20 +- .../specs/widgets/editing-widgets.test.js | 190 ++++++++++-------- 2 files changed, 115 insertions(+), 95 deletions(-) diff --git a/packages/e2e-tests/plugins/marquee-function-widget.php b/packages/e2e-tests/plugins/marquee-function-widget.php index 43b4f15661772f..dda0c3f9a6e273 100644 --- a/packages/e2e-tests/plugins/marquee-function-widget.php +++ b/packages/e2e-tests/plugins/marquee-function-widget.php @@ -34,15 +34,17 @@ function() { $greeting = get_option( 'marquee_greeting' ); ?>

    - - +

    { @@ -89,6 +89,12 @@ describe( 'Widgets screen', () => { ); expect( categoryHeaders.length > 0 ).toBe( true ); + const searchBox = await find( { + role: 'searchbox', + name: 'Search for blocks and patterns', + } ); + await searchBox.type( blockName ); + const addBlock = await find( { role: 'option', @@ -394,109 +400,123 @@ describe( 'Widgets screen', () => { ` ); } ); - async function addMarquee() { - // There will be 2 matches here. - // One is the in-between inserter, - // and the other one is the button block appender. - const [ inlineInserterButton ] = await findAll( { - role: 'combobox', - name: 'Add block', - } ); - await inlineInserterButton.click(); - - // TODO: Convert to find() API from puppeteer-testing-library. - const inserterSearchBox = await page.waitForSelector( - 'aria/Search for blocks and patterns[role="searchbox"]' - ); - await expect( inserterSearchBox ).toHaveFocus(); + describe( 'Function widgets', () => { + async function addMarquee( nbExpectedMarquees ) { + const marqueeBlock = await getBlockInGlobalInserter( + 'Marquee Greeting' + ); + await marqueeBlock.click(); + await page.waitForFunction( + ( expectedMarquees ) => { + return ( + document.querySelectorAll( + '[data-testid="marquee-greeting"]' + ).length === expectedMarquees + ); + }, + {}, + nbExpectedMarquees + ); + } - await page.keyboard.type( 'Marquee' ); + async function deleteExistingMarquees() { + const widgetAreasHoldingMarqueeWidgets = await page.$x( + '//input[@data-testid="marquee-greeting"]/ancestor::div[@aria-label="Block: Widget Area"]' + ); + for ( const widgetArea of widgetAreasHoldingMarqueeWidgets ) { + const closedPanelBody = await widgetArea.$( + '.components-panel__body:not(.is-opened)' + ); + if ( closedPanelBody ) { + await closedPanelBody.focus(); + await closedPanelBody.click(); + } - const inlineQuickInserter = await find( { - role: 'listbox', - name: 'Blocks', - } ); - const marqueeBlockOption = await find( - { - role: 'option', - }, - { - root: inlineQuickInserter, + const [ existingMarqueeWidgets ] = await widgetArea.$x( + '//input[@data-testid="marquee-greeting"]/ancestor::div[@data-block][contains(@class, "wp-block-legacy-widget")]' + ); + if ( existingMarqueeWidgets ) { + await existingMarqueeWidgets.focus(); + await pressKeyWithModifier( 'access', 'z' ); + } } - ); - await marqueeBlockOption.click(); - } - - it( 'Should add and save the marquee widget', async () => { - await activatePlugin( 'gutenberg-test-marquee-widget' ); - await visitAdminPage( 'widgets.php' ); + } - await addMarquee(); + beforeAll( async () => { + await activatePlugin( 'gutenberg-test-marquee-widget' ); + } ); - await find( { - selector: '[data-block][data-type="core/legacy-widget"]', + beforeEach( async () => { + await deleteExistingMarquees(); } ); - const greetingsInput = await find( { - selector: '#marquee-greeting', + afterAll( async () => { + await deactivatePlugin( 'gutenberg-test-marquee-widget' ); } ); - await greetingsInput.click(); - await page.keyboard.type( 'Howdy' ); - await saveWidgets(); + it( 'Should add and save the marquee widget', async () => { + await addMarquee( 1 ); - let editedSerializedWidgetAreas = await getSerializedWidgetAreas(); - await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( ` - Object { - "sidebar-1": "Hello!", - } - ` ); + const [ marqueeInput ] = await page.$x( + '//input[@data-testid="marquee-greeting"]' + ); + await marqueeInput.focus(); + await marqueeInput.type( 'Howdy' ); - await page.reload(); + // The first marquee is saved after clicking the form save button. + const [ marqueeSaveButton ] = await marqueeInput.$x( + '//input/ancestor::div[@data-block][contains(@class, "wp-block-legacy-widget")]//button[@type="submit"]' + ); + await marqueeSaveButton.click(); - editedSerializedWidgetAreas = await getSerializedWidgetAreas(); - await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( ` - Object { - "sidebar-1": "Hello!", - } - ` ); + await saveWidgets(); - // Add another marquee, it shouldn't be saved - await addMarquee(); + let editedSerializedWidgetAreas = await getSerializedWidgetAreas(); + await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( ` + Object { + "sidebar-1": "Howdy", + } + ` ); - // It takes a moment to load the form, let's wait for it. - await waitFor( async () => { - const marquees = await findAll( { - selector: '[id=marquee-greeting]', - } ); - if ( marquees.length === 1 ) { - throw new Error(); + await page.reload(); + + editedSerializedWidgetAreas = await getSerializedWidgetAreas(); + await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( ` + Object { + "sidebar-1": "Howdy", } - } ); + ` ); - const marquees = await findAll( { - selector: '[id=marquee-greeting]', - } ); + await addMarquee( 2 ); - expect( marquees ).toHaveLength( 2 ); - await marquees[ 1 ].click(); - await page.keyboard.type( 'Second howdy' ); + const marqueeInputs = await page.$$( + '[data-testid="marquee-greeting"]' + ); - await saveWidgets(); - editedSerializedWidgetAreas = await getSerializedWidgetAreas(); - await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( ` - Object { - "sidebar-1": "Hello!", - } - ` ); + expect( marqueeInputs ).toHaveLength( 2 ); + await marqueeInputs[ 0 ].focus(); + await marqueeInputs[ 0 ].type( 'first howdy' ); + + await marqueeInputs[ 1 ].focus(); + await marqueeInputs[ 1 ].type( 'Second howdy' ); + + // No marquee should be changed without clicking on their "save" button. + // The second marquee shouldn't be stored as a widget. + // See #32978 for more info. + await saveWidgets(); + editedSerializedWidgetAreas = await getSerializedWidgetAreas(); + await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( ` + Object { + "sidebar-1": "Howdy", + } + ` ); - await page.reload(); - const marqueesAfter = await findAll( { - selector: '[id=marquee-greeting]', + await page.reload(); + const marqueesAfter = await findAll( { + selector: '[data-testid="marquee-greeting"]', + } ); + expect( marqueesAfter ).toHaveLength( 1 ); } ); - expect( marqueesAfter ).toHaveLength( 1 ); - - await deactivatePlugin( 'gutenberg-test-marquee-widget' ); } ); // Disable reason: We temporary skip this test until we can figure out why it fails sometimes. @@ -528,7 +548,6 @@ describe( 'Widgets screen', () => { "sidebar-1": "

    First Paragraph

    ", - "wp_inactive_widgets": "", } ` ); const initialWidgets = await getWidgetAreaWidgets(); @@ -599,7 +618,6 @@ describe( 'Widgets screen', () => {

    First Paragraph

    ", - "wp_inactive_widgets": "", } ` ); const editedWidgets = await getWidgetAreaWidgets(); From da5355f9c93c7f42794e94f018ef6bb4c2434c84 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Wed, 30 Jun 2021 14:29:02 +0000 Subject: [PATCH 56/64] Bump plugin version to 11.0.0-rc.1 --- gutenberg.php | 2 +- package-lock.json | 2 +- package.json | 2 +- readme.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index 67eaf6c630c4c9..ab7049ffb7bf9e 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the new block editor in core. * Requires at least: 5.6 * Requires PHP: 5.6 - * Version: 10.9.2 + * Version: 11.0.0-rc.1 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index 143e4ed03fbe7a..ca2d654ff162ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "10.9.2", + "version": "11.0.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index c97eab3386806f..4546293f5555aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "10.9.2", + "version": "11.0.0-rc.1", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", diff --git a/readme.txt b/readme.txt index be70c005bbceac..94bfddb91a1420 100644 --- a/readme.txt +++ b/readme.txt @@ -55,4 +55,4 @@ View release page. +To read the changelog for Gutenberg 11.0.0-rc.1, please navigate to the release page. From 014d837e85989208434b33918bfe0a200b5b64e7 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Wed, 30 Jun 2021 14:43:52 +0000 Subject: [PATCH 57/64] Update Changelog for 11.0.0-rc.1 --- changelog.txt | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/changelog.txt b/changelog.txt index 7dd4097cad1aee..a8e1c97339697f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,177 @@ == Changelog == += 11.0.0-rc.1 = + + + +### Enhancements + +- Polish block manager search. ([32922](https://github.com/WordPress/gutenberg/pull/32922)) +- Allow left/right/center alignments when a layout is defined. ([32810](https://github.com/WordPress/gutenberg/pull/32810)) +- [Block Library - Query Loop]: Select first Query Loop found from pattern selection. ([32737](https://github.com/WordPress/gutenberg/pull/32737)) +- Remove the widget switcher block toolbar button. ([32733](https://github.com/WordPress/gutenberg/pull/32733)) +- Block categories: Clean these up by moving several blocks from Design to Theme. ([32568](https://github.com/WordPress/gutenberg/pull/32568)) +- Allow longhand and shorthand properties in `theme.json` and block attributes. ([31641](https://github.com/WordPress/gutenberg/pull/31641)) +- Media & Text: Allow drag n drop media replacement. ([29710](https://github.com/WordPress/gutenberg/pull/29710)) + +### New APIs + +- Allow making context specific requests using the data module. ([32961](https://github.com/WordPress/gutenberg/pull/32961)) +- Add an API to define the default template used for the template mode. ([32771](https://github.com/WordPress/gutenberg/pull/32771)) + +### Bug Fixes + +- Fix flaky widgets-related end-to-end tests. ([33066](https://github.com/WordPress/gutenberg/pull/33066)) +- Remove "is-dark-theme" rules from mixins. ([33058](https://github.com/WordPress/gutenberg/pull/33058)) +- Group Block: Avoid rendering the layout configuration twice. ([33045](https://github.com/WordPress/gutenberg/pull/33045)) +- [Block Library - Query Loop] Fix race condition for making Post blocks inside uneditable. ([33037](https://github.com/WordPress/gutenberg/pull/33037)) +- Fix switcher focus style. ([33031](https://github.com/WordPress/gutenberg/pull/33031)) +- Fix drag and drop indicator above first block and RTL drop indicators. ([33024](https://github.com/WordPress/gutenberg/pull/33024)) +- Button: Update to use border support provided styles and classes. ([33017](https://github.com/WordPress/gutenberg/pull/33017)) +- [Block Library - Categories]: Fix handling for low privileged users. ([32994](https://github.com/WordPress/gutenberg/pull/32994)) +- [Block Library - Categories]: Fix crash when trying to access categories on insertion. ([32989](https://github.com/WordPress/gutenberg/pull/32989)) +- Fix to remove default indent from Latest Posts and Latest Comments block in various editors. ([32983](https://github.com/WordPress/gutenberg/pull/32983)) +- Avoid adding default block to empty widget areas in customizer. ([32979](https://github.com/WordPress/gutenberg/pull/32979)) +- Add custom classes to archive dropdown. ([32971](https://github.com/WordPress/gutenberg/pull/32971)) +- [Block Library - Post Terms]: Fix handling for low privileged users. ([32947](https://github.com/WordPress/gutenberg/pull/32947)) +- Fix: Template editor header area is difficult to navigate with screenreaders. ([32938](https://github.com/WordPress/gutenberg/pull/32938)) +- Fix glitchy block focus style when multiselecting blocks. ([32927](https://github.com/WordPress/gutenberg/pull/32927)) +- Fix a regression where `custom-units` are forced as an array. ([32898](https://github.com/WordPress/gutenberg/pull/32898)) +- Fix collapsing appender when paragraph disabled. ([32894](https://github.com/WordPress/gutenberg/pull/32894)) +- Fix unintended search http request in . ([32857](https://github.com/WordPress/gutenberg/pull/32857)) +- CI: Recursively clear node modules when building for ci. ([32856](https://github.com/WordPress/gutenberg/pull/32856)) +- Fixed a problem with double encoding of URLs. ([32840](https://github.com/WordPress/gutenberg/pull/32840)) +- Fix incorrect block insertion point after blurring post title. ([32831](https://github.com/WordPress/gutenberg/pull/32831)) +- RNMobile: Fix column wrapping. ([32830](https://github.com/WordPress/gutenberg/pull/32830)) +- [Block Library - Site Title, Site Tagline] - Readonly view when user has no the right permissions. ([32817](https://github.com/WordPress/gutenberg/pull/32817)) +- useNavigateRegions: Don't remove click event if there's no element. ([32816](https://github.com/WordPress/gutenberg/pull/32816)) +- Block Library: Unify handling for block view scripts. ([32814](https://github.com/WordPress/gutenberg/pull/32814)) +- Do not allow users to create templates with blank titles. ([32809](https://github.com/WordPress/gutenberg/pull/32809)) +- Remove @wordpress/editor as a dependency from @wordpress/block-library. ([32801](https://github.com/WordPress/gutenberg/pull/32801)) +- Fix drag and drop indices when block list contains a style element. ([32776](https://github.com/WordPress/gutenberg/pull/32776)) +- Customize Widgets: Fix block toolbar deselection when clicking scrollbar. ([32762](https://github.com/WordPress/gutenberg/pull/32762)) +- Fix apparent overflow in Customizer caused by widgets editor. ([32749](https://github.com/WordPress/gutenberg/pull/32749)) +- components: Stop modifying the parent context and correctly memoize it. ([32745](https://github.com/WordPress/gutenberg/pull/32745)) +- TemplatePanel: Fixed a problem that when a new template is created, the template is not displayed in the select box. ([32744](https://github.com/WordPress/gutenberg/pull/32744)) +- Clear event listeners on unmount in Tooltip component. ([32729](https://github.com/WordPress/gutenberg/pull/32729)) +- Fix: Allow decimals in spacing controls. ([32692](https://github.com/WordPress/gutenberg/pull/32692)) +- Ensure only valid URLs or anchors within text are automatically created as links. ([32663](https://github.com/WordPress/gutenberg/pull/32663)) +- [Image Block]: Fix block validation errors when clearing height/width. ([32524](https://github.com/WordPress/gutenberg/pull/32524)) +- Fix scroll jitter in Customize Widgets. ([32479](https://github.com/WordPress/gutenberg/pull/32479)) +- Image Block: Correctly set image size slug. ([32364](https://github.com/WordPress/gutenberg/pull/32364)) +- Fix: Adding buttons should respect the preferred style. ([31089](https://github.com/WordPress/gutenberg/pull/31089)) + +### Experiments + +- Navigation: Skip flakey tests. ([33074](https://github.com/WordPress/gutenberg/pull/33074)) +- Adjust widget form margins in the new widget editor. ([33040](https://github.com/WordPress/gutenberg/pull/33040)) +- Set display only when form not hidden. ([33015](https://github.com/WordPress/gutenberg/pull/33015)) +- Widgets: Fix creating and editing non-multi widgets. ([32978](https://github.com/WordPress/gutenberg/pull/32978)) +- Fix wide widget styles to allow floated contents. ([32976](https://github.com/WordPress/gutenberg/pull/32976)) +- Adjust legacy widget form styles to match editor. ([32974](https://github.com/WordPress/gutenberg/pull/32974)) +- Improve insertion point and drag-n-drop in the widgets screen. ([32953](https://github.com/WordPress/gutenberg/pull/32953)) +- Widget Editor: Fix allow adding same image twice. ([32951](https://github.com/WordPress/gutenberg/pull/32951)) +- [Block Library - Site Logo]: Add permissions handling. ([32919](https://github.com/WordPress/gutenberg/pull/32919)) +- Navigation: Update the function name and correct the comment. ([32918](https://github.com/WordPress/gutenberg/pull/32918)) +- Stretch Widgets editor layout to full height. ([32905](https://github.com/WordPress/gutenberg/pull/32905)) +- Don't display admin notices on widgets screen. ([32877](https://github.com/WordPress/gutenberg/pull/32877)) +- Fix legacy widget edit style bleed. ([32871](https://github.com/WordPress/gutenberg/pull/32871)) +- Rename .interface-interface-skeleton__body z-index to .interface-interface-skeleton__content. ([32869](https://github.com/WordPress/gutenberg/pull/32869)) +- Legacy custom html widget should have option to transform to custom html block. ([32862](https://github.com/WordPress/gutenberg/pull/32862)) +- Wire handle_legacy_widget_preview_iframe to admin_init_hook. ([32854](https://github.com/WordPress/gutenberg/pull/32854)) +- Remove classic block in widgets editor. ([32800](https://github.com/WordPress/gutenberg/pull/32800)) +- Fix: Logic error on site editor useSetting. ([32793](https://github.com/WordPress/gutenberg/pull/32793)) +- Widget preivew not working if widget registered via a instance. ([32781](https://github.com/WordPress/gutenberg/pull/32781)) +- Disable "FSE" blocks in Widgets Editor. ([32761](https://github.com/WordPress/gutenberg/pull/32761)) +- Update filter in Widget Block Editor documentation. ([32759](https://github.com/WordPress/gutenberg/pull/32759)) +- Widgets editor: Display shortcuts for navigating regions. ([32757](https://github.com/WordPress/gutenberg/pull/32757)) +- Set explicit z-index on interface body to ensure it’s pinned under interface header. ([32732](https://github.com/WordPress/gutenberg/pull/32732)) +- Fix widgets background when loading theme styles. ([32683](https://github.com/WordPress/gutenberg/pull/32683)) +- Navigation block: Add an unstable location attribute. ([32491](https://github.com/WordPress/gutenberg/pull/32491)) +- Fix oembeds not working in block template parts. ([32331](https://github.com/WordPress/gutenberg/pull/32331)) +- Global Styles: Allow custom properties to merge. ([31840](https://github.com/WordPress/gutenberg/pull/31840)) +- Add post-classes in the loop. ([30497](https://github.com/WordPress/gutenberg/pull/30497)) + +### Documentation + +- ServerSideRender: Update documentation for placeholder props. ([33030](https://github.com/WordPress/gutenberg/pull/33030)) +- Add some technical implementation details for Widgets Customizer. ([33026](https://github.com/WordPress/gutenberg/pull/33026)) +- Docs: Add link color suppots to Block API documentation. ([32936](https://github.com/WordPress/gutenberg/pull/32936)) +- Add a schema explaining the relationship between the packages that make the post editor. ([32921](https://github.com/WordPress/gutenberg/pull/32921)) +- Handbook: Polish the Gutenberg release docs, performance audit section. ([32770](https://github.com/WordPress/gutenberg/pull/32770)) +- Fix abort error thrown by `api-fetch` and add documentation. ([32530](https://github.com/WordPress/gutenberg/pull/32530)) +- Update the block toolbar ESnext code. ([32422](https://github.com/WordPress/gutenberg/pull/32422)) +- Unify Block Editor readme language and example. ([31850](https://github.com/WordPress/gutenberg/pull/31850)) + +### Code Quality + +- data: Type `promise-middleware`. ([32967](https://github.com/WordPress/gutenberg/pull/32967)) +- data: Add types to redux-store/metadata/selectors. ([32965](https://github.com/WordPress/gutenberg/pull/32965)) +- data: Add types to redux-store metadata reducer. ([32942](https://github.com/WordPress/gutenberg/pull/32942)) +- Block Library: Ensure there is no direct import from core/editor store. ([32866](https://github.com/WordPress/gutenberg/pull/32866)) +- data: Begin adding types, starting with redus-store/meta/actions. ([32855](https://github.com/WordPress/gutenberg/pull/32855)) +- components: Remove duplicated space utilities. ([32852](https://github.com/WordPress/gutenberg/pull/32852)) +- Correct the case of navigation __unstableLocation. ([32783](https://github.com/WordPress/gutenberg/pull/32783)) +- Unit control Utils: Update JS documentation and add basic test coverage. ([32774](https://github.com/WordPress/gutenberg/pull/32774)) +- Quality: Promote lint rule to error when validating store string literals. ([32537](https://github.com/WordPress/gutenberg/pull/32537)) +- Cleanup PHP Codesniffer warnings and enable fail. ([26516](https://github.com/WordPress/gutenberg/pull/26516)) +- Redux routine: Add types. ([21313](https://github.com/WordPress/gutenberg/pull/21313)) + +### Tools + +- components: Restrict imports of @emotion/css. ([33051](https://github.com/WordPress/gutenberg/pull/33051)) +- end-to-end Test Utils: Add getCurrentUser(), and use it for user switching. ([33050](https://github.com/WordPress/gutenberg/pull/33050)) +- Disable Android end-to-end tests while we investigate foundational breakage. ([32934](https://github.com/WordPress/gutenberg/pull/32934)) +- [E2E Tests]: Fix WP editor metabox test. ([32915](https://github.com/WordPress/gutenberg/pull/32915)) +- Fix eslint-import resolver with extraneous dependencies. ([32906](https://github.com/WordPress/gutenberg/pull/32906)) +- Fix broken the post-template-editor test. ([32904](https://github.com/WordPress/gutenberg/pull/32904)) +- Testing: Fix failing PHPUnit test caused by changes in WP core. ([32888](https://github.com/WordPress/gutenberg/pull/32888)) +- Skip failing image caption caret test. ([32847](https://github.com/WordPress/gutenberg/pull/32847)) +- @wordpress/scripts: Support path-based chunk names in FixStyleWebpackPlugin. ([32834](https://github.com/WordPress/gutenberg/pull/32834)) +- Improve image caret e2e-test. ([32832](https://github.com/WordPress/gutenberg/pull/32832)) +- Docs: Update testing overview documentation. ([32829](https://github.com/WordPress/gutenberg/pull/32829)) +- Scripts: Update `lint-md-docs` script to use ignore-path. ([32633](https://github.com/WordPress/gutenberg/pull/32633)) +- Workflows: Allow point releases after a new RC is out. ([32560](https://github.com/WordPress/gutenberg/pull/32560)) + +### Various + +- Add a label for screen reader in categories block. ([33060](https://github.com/WordPress/gutenberg/pull/33060)) +- Focus style followup. ([33022](https://github.com/WordPress/gutenberg/pull/33022)) +- Typo correction. ([33013](https://github.com/WordPress/gutenberg/pull/33013)) +- Iframed editor: Add Masonry integration end-to-end test. ([33008](https://github.com/WordPress/gutenberg/pull/33008)) +- Handle context on `edits`. ([32991](https://github.com/WordPress/gutenberg/pull/32991)) +- Block Library: Improve view script integration to account for WordPress Core. ([32977](https://github.com/WordPress/gutenberg/pull/32977)) +- Revert mistaken push to trunk. ([32948](https://github.com/WordPress/gutenberg/pull/32948)) +- Upgrade to Emotion 11. ([32930](https://github.com/WordPress/gutenberg/pull/32930)) +- Replace FullscreenMode from Class components to functional components. ([32925](https://github.com/WordPress/gutenberg/pull/32925)) +- Query block: Fix full width children from scrolling horizontally only in the editor. ([32892](https://github.com/WordPress/gutenberg/pull/32892)) +- Prepublish Panel: Disable the Publish and Cancel buttons while saving. ([32889](https://github.com/WordPress/gutenberg/pull/32889)) +- Update pre-publish setting copy. ([32874](https://github.com/WordPress/gutenberg/pull/32874)) +- Query Loop Patterns: Use plain `div` for wrapper element. ([32867](https://github.com/WordPress/gutenberg/pull/32867)) +- Properly handle 404 errors while publishing Android artifacts. ([32860](https://github.com/WordPress/gutenberg/pull/32860)) +- Auto-enable the template editor for themes with theme.json only. ([32858](https://github.com/WordPress/gutenberg/pull/32858)) +- Safari: See if compositing layer size is more reasonable when position fixed divs are not inserted into content. ([32824](https://github.com/WordPress/gutenberg/pull/32824)) +- Remove `gutenberg` domain from Post Template block. ([32804](https://github.com/WordPress/gutenberg/pull/32804)) +- Add regression end-to-end test for the bug that caused some wp_options to get corrupted data. ([32797](https://github.com/WordPress/gutenberg/pull/32797)) +- components: Allow for non-polymorphic components. ([32796](https://github.com/WordPress/gutenberg/pull/32796)) +- Revert accidental commit. ([32777](https://github.com/WordPress/gutenberg/pull/32777)) +- Card: Delete old version of the g2 implementation. ([32764](https://github.com/WordPress/gutenberg/pull/32764)) +- Card: Update Storybook story. ([32763](https://github.com/WordPress/gutenberg/pull/32763)) +- Avoid flash of background color when scrolling in safari. ([32747](https://github.com/WordPress/gutenberg/pull/32747)) +- Add 'area' key to function doc for `gutenberg_get_block_templates`. ([32746](https://github.com/WordPress/gutenberg/pull/32746)) +- Components: Update components provider story. ([32743](https://github.com/WordPress/gutenberg/pull/32743)) +- Implement basic in memory cache for rich link previews data. ([32741](https://github.com/WordPress/gutenberg/pull/32741)) +- Rename native editor onboarding properties for clarity. ([32739](https://github.com/WordPress/gutenberg/pull/32739)) +- Try: Align widget sidebar button. ([32738](https://github.com/WordPress/gutenberg/pull/32738)) +- Card: Update to g2 implementation. ([32566](https://github.com/WordPress/gutenberg/pull/32566)) +- Rnmobile/fix/disable controls when template lock is set. ([32495](https://github.com/WordPress/gutenberg/pull/32495)) +- Added filters to get block templates functions. ([31806](https://github.com/WordPress/gutenberg/pull/31806)) +- Template Parts & Reusable Blocks - try overlay element for clickthrough to edit pattern. ([31109](https://github.com/WordPress/gutenberg/pull/31109)) +- [RN Mobile][Global Styles] Adds new Prop for Global Styles Settings. ([30544](https://github.com/WordPress/gutenberg/pull/30544)) + + + + = 10.9.1 = ### Bug Fixes From 8533ca10dac2c2aa1831fb65bc2cf5768b9615e5 Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Wed, 30 Jun 2021 17:18:12 +0200 Subject: [PATCH 58/64] Improve high contrast mode rendering of icon buttons. (#33062) --- packages/block-editor/src/components/block-icon/style.scss | 6 ++++++ packages/components/src/button/style.scss | 6 ++++++ packages/components/src/placeholder/style.scss | 7 ++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-icon/style.scss b/packages/block-editor/src/components/block-icon/style.scss index 7c81a32be891cf..033e0d3129d741 100644 --- a/packages/block-editor/src/components/block-icon/style.scss +++ b/packages/block-editor/src/components/block-icon/style.scss @@ -8,6 +8,12 @@ &.has-colors { svg { fill: currentColor; + + // Optimizate for high contrast modes. + // See also https://blogs.windows.com/msedgedev/2020/09/17/styling-for-windows-high-contrast-with-new-standards-for-forced-colors/. + @media (forced-colors: active) { + fill: CanvasText; + } } } diff --git a/packages/components/src/button/style.scss b/packages/components/src/button/style.scss index 0dd565c3725874..8a00e365cd38f6 100644 --- a/packages/components/src/button/style.scss +++ b/packages/components/src/button/style.scss @@ -332,6 +332,12 @@ svg { fill: currentColor; outline: none; + + // Optimizate for high contrast modes. + // See also https://blogs.windows.com/msedgedev/2020/09/17/styling-for-windows-high-contrast-with-new-standards-for-forced-colors/. + @media (forced-colors: active) { + fill: CanvasText; + } } // Fixes a Safari+VoiceOver bug, where the screen reader text is announced not respecting the source order. diff --git a/packages/components/src/placeholder/style.scss b/packages/components/src/placeholder/style.scss index 0958bb5a0b16c1..53df5294e497fd 100644 --- a/packages/components/src/placeholder/style.scss +++ b/packages/components/src/placeholder/style.scss @@ -49,8 +49,13 @@ > svg, .dashicon, .block-editor-block-icon { - fill: currentColor; margin-right: 1ch; + fill: currentColor; + // Optimizate for high contrast modes. + // See also https://blogs.windows.com/msedgedev/2020/09/17/styling-for-windows-high-contrast-with-new-standards-for-forced-colors/. + @media (forced-colors: active) { + fill: CanvasText; + } } // Don't take up space if the label is empty. From 6b6ac7bc6eb3d90515588d500cb8f4da4f820dac Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Wed, 30 Jun 2021 08:19:46 -0700 Subject: [PATCH 59/64] components: Remove `@emotion/css` from ZStack (#33053) * Remove `@emotion/css` from ZStack * Use a better name --- packages/components/src/z-stack/component.tsx | 28 ++++--------------- packages/components/src/z-stack/styles.ts | 25 +++++++++++++---- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/packages/components/src/z-stack/component.tsx b/packages/components/src/z-stack/component.tsx index b3357e881d262b..e3003f0897774a 100644 --- a/packages/components/src/z-stack/component.tsx +++ b/packages/components/src/z-stack/component.tsx @@ -1,10 +1,6 @@ /** * External dependencies */ -// Disable reason: Temporarily disable for existing usages -// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css -// eslint-disable-next-line no-restricted-imports -import { css, cx } from '@emotion/css'; // eslint-disable-next-line no-restricted-imports import type { Ref, ReactNode } from 'react'; @@ -20,9 +16,7 @@ import { getValidChildren } from '../ui/utils/get-valid-children'; import { contextConnect, useContextSystem } from '../ui/context'; // eslint-disable-next-line no-duplicate-imports import type { PolymorphicComponentProps } from '../ui/context'; -import { View } from '../view'; -import * as styles from './styles'; -const { ZStackView } = styles; +import { ZStackView, ZStackChildView } from './styles'; export interface ZStackProps { /** @@ -69,27 +63,17 @@ function ZStack( const zIndex = isReversed ? childrenLastIndex - index : index; const offsetAmount = offset * index; - const classes = cx( - isLayered ? styles.positionAbsolute : styles.positionRelative, - css( { - ...( isLayered - ? { marginLeft: offsetAmount } - : { right: offsetAmount * -1 } ), - } ) - ); - const key = isValidElement( child ) ? child.key : index; return ( - { child } - + ); } ); diff --git a/packages/components/src/z-stack/styles.ts b/packages/components/src/z-stack/styles.ts index e74a60de0c705f..141ab50191d744 100644 --- a/packages/components/src/z-stack/styles.ts +++ b/packages/components/src/z-stack/styles.ts @@ -1,10 +1,7 @@ /** * External dependencies */ -// Disable reason: Temporarily disable for existing usages -// until we remove them as part of https://github.com/WordPress/gutenberg/issues/30503#deprecating-emotion-css -// eslint-disable-next-line no-restricted-imports -import { css } from '@emotion/css'; +import { css } from '@emotion/react'; import styled from '@emotion/styled'; export const ZStackView = styled.div` @@ -12,10 +9,26 @@ export const ZStackView = styled.div` position: relative; `; -export const positionAbsolute = css` +export const ZStackChildView = styled.div< { + isLayered: boolean; + offsetAmount: number; + zIndex: number; +} >` + ${ ( { isLayered, offsetAmount } ) => + isLayered + ? css( { marginLeft: offsetAmount } ) + : css( { right: offsetAmount * -1 } ) } + + ${ ( { isLayered } ) => + isLayered ? positionAbsolute : positionRelative } + + ${ ( { zIndex } ) => css( { zIndex } ) } +`; + +const positionAbsolute = css` position: absolute; `; -export const positionRelative = css` +const positionRelative = css` position: relative; `; From bdb8410547f277a2b111739a70123985ce1e1aef Mon Sep 17 00:00:00 2001 From: Joen A <1204802+jasmussen@users.noreply.github.com> Date: Wed, 30 Jun 2021 17:59:24 +0200 Subject: [PATCH 60/64] Fix slash command focus style. (#33084) --- packages/components/src/autocomplete/style.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/autocomplete/style.scss b/packages/components/src/autocomplete/style.scss index 3bef5a13a47b6e..b7060e4a469189 100644 --- a/packages/components/src/autocomplete/style.scss +++ b/packages/components/src/autocomplete/style.scss @@ -11,6 +11,6 @@ width: 100%; &.is-selected { - box-shadow: 0 0 0 2px var(--wp-admin-theme-color); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } } From 5fb8d4be9df11f87cca948bd29ce327ec02053ca Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Mon, 28 Jun 2021 06:37:56 -0700 Subject: [PATCH 61/64] Add useControlledValue --- packages/components/src/utils/hooks/index.js | 1 + .../src/utils/hooks/use-controlled-value.ts | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 packages/components/src/utils/hooks/use-controlled-value.ts diff --git a/packages/components/src/utils/hooks/index.js b/packages/components/src/utils/hooks/index.js index 3eeca7881e2563..187718e5e70a9a 100644 --- a/packages/components/src/utils/hooks/index.js +++ b/packages/components/src/utils/hooks/index.js @@ -1,3 +1,4 @@ export { default as useControlledState } from './use-controlled-state'; export { default as useJumpStep } from './use-jump-step'; export { default as useUpdateEffect } from './use-update-effect'; +export { useControlledValue } from './use-controlled-value'; diff --git a/packages/components/src/utils/hooks/use-controlled-value.ts b/packages/components/src/utils/hooks/use-controlled-value.ts new file mode 100644 index 00000000000000..b29c93d1fb6a6a --- /dev/null +++ b/packages/components/src/utils/hooks/use-controlled-value.ts @@ -0,0 +1,38 @@ +/** + * External dependencies + */ +import { isNil } from 'lodash'; + +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + +type Props< T > = { + defaultValue?: T; + value?: T; + onChange?: ( value: T ) => void; +}; + +/** + * Simplified and improved implementation of useControlledState. + * + * @param props + * @param props.defaultValue + * @param props.value + * @param props.onChange + * @return The controlled value and the value setter. + */ +export function useControlledValue< T >( { + defaultValue, + onChange, + value: valueProp, +}: Props< T > ): [ T | undefined, ( value: T ) => void ] { + const hasValue = ! isNil( valueProp ); + const initialValue = hasValue ? valueProp : defaultValue; + const [ state, setState ] = useState( initialValue ); + const value = hasValue ? valueProp : state; + const setValue = hasValue && ! isNil( onChange ) ? onChange : setState; + + return [ value, setValue ]; +} From 5af2b964e39e427fd85a1f4c3d27e6eae57ab5fc Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Mon, 28 Jun 2021 12:19:26 -0700 Subject: [PATCH 62/64] Add unit tests --- package-lock.json | 31 +++++ package.json | 1 + .../utils/hooks/test/use-controlled-value.js | 107 ++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 packages/components/src/utils/hooks/test/use-controlled-value.js diff --git a/package-lock.json b/package-lock.json index ca2d654ff162ae..42638c56cb1fb3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12100,6 +12100,19 @@ "@testing-library/dom": "^7.28.1" } }, + "@testing-library/react-hooks": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-7.0.0.tgz", + "integrity": "sha512-WFBGH8DWdIGGBHt6PBtQPe2v4Kbj9vQ1sQ9qLBTmwn1PNggngint4MTE/IiWCYhPbyTW3oc/7X62DObMn/AjQQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5", + "@types/react": ">=16.9.0", + "@types/react-dom": ">=16.9.0", + "@types/react-test-renderer": ">=16.9.0", + "react-error-boundary": "^3.1.0" + } + }, "@testing-library/react-native": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@testing-library/react-native/-/react-native-7.1.0.tgz", @@ -12624,6 +12637,15 @@ "@types/react": "*" } }, + "@types/react-test-renderer": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz", + "integrity": "sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/requestidlecallback": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@types/requestidlecallback/-/requestidlecallback-0.3.1.tgz", @@ -50252,6 +50274,15 @@ } } }, + "react-error-boundary": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.3.tgz", + "integrity": "sha512-A+F9HHy9fvt9t8SNDlonq01prnU8AmkjvGKV4kk8seB9kU3xMEO8J/PQlLVmoOIDODl5U2kufSBs4vrWIqhsAA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5" + } + }, "react-error-overlay": { "version": "6.0.9", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", diff --git a/package.json b/package.json index 4546293f5555aa..7f3ee6214c10d1 100644 --- a/package.json +++ b/package.json @@ -103,6 +103,7 @@ "@testing-library/jest-dom": "5.11.9", "@testing-library/react": "11.2.2", "@testing-library/react-native": "7.1.0", + "@testing-library/react-hooks": "7.0.0", "@types/classnames": "2.2.10", "@types/clipboard": "2.0.1", "@types/eslint": "6.8.0", diff --git a/packages/components/src/utils/hooks/test/use-controlled-value.js b/packages/components/src/utils/hooks/test/use-controlled-value.js new file mode 100644 index 00000000000000..d7b77f0b8f99c7 --- /dev/null +++ b/packages/components/src/utils/hooks/test/use-controlled-value.js @@ -0,0 +1,107 @@ +/** + * External dependencies + */ +import { renderHook, act } from '@testing-library/react-hooks'; + +/** + * Internal dependencies + */ +import { useControlledValue } from '../use-controlled-value'; + +describe( 'useControlledValue', () => { + it( 'should use the default value', () => { + const { result } = renderHook( () => + useControlledValue( { defaultValue: 'WordPress.org' } ) + ); + + expect( result.current[ 0 ] ).toEqual( 'WordPress.org' ); + } ); + + it( 'should use the default value then switch to the controlled value', () => { + const { result, rerender } = renderHook( + ( { value } ) => + useControlledValue( { defaultValue: 'WordPress.org', value } ), + { initialProps: { value: undefined } } + ); + expect( result.current[ 0 ] ).toEqual( 'WordPress.org' ); + + rerender( { value: 'Code is Poetry' } ); + + expect( result.current[ 0 ] ).toEqual( 'Code is Poetry' ); + } ); + + it( 'should not call onChange only when there is no value being passed in', () => { + const onChange = jest.fn(); + const { result } = renderHook( () => + useControlledValue( { defaultValue: 'WordPress.org', onChange } ) + ); + + expect( result.current[ 0 ] ).toEqual( 'WordPress.org' ); + + act( () => { + result.current[ 1 ]( 'Code is Poetry' ); + } ); + + expect( result.current[ 0 ] ).toEqual( 'Code is Poetry' ); + expect( onChange ).not.toHaveBeenCalled(); + } ); + + it( 'should call onChange when there is a value passed in', () => { + const onChange = jest.fn(); + const { result, rerender } = renderHook( + ( { value } ) => + useControlledValue( { + defaultValue: 'WordPress.org', + value, + onChange, + } ), + { initialProps: { value: 'Code is Poetry' } } + ); + + expect( result.current[ 0 ] ).toEqual( 'Code is Poetry' ); + + act( () => { + // simulate `setValue` getting called by an input + result.current[ 1 ]( 'WordPress rocks!' ); + } ); + + // simulate the parent re-rendering and passing a new value down + rerender( { value: 'WordPress rocks!' } ); + + expect( result.current[ 0 ] ).toEqual( 'WordPress rocks!' ); + expect( onChange ).toHaveBeenCalledWith( 'WordPress rocks!' ); + } ); + + it( 'should not maintain internal state if no onChange is passed but a value is passed', () => { + const { result, rerender } = renderHook( + ( { value } ) => useControlledValue( { value } ), + { initialProps: { value: undefined } } + ); + + expect( result.current[ 0 ] ).toBe( undefined ); + + rerender( { value: 'Code is Poetry' } ); + + expect( result.current[ 0 ] ).toEqual( 'Code is Poetry' ); + + act( () => { + // call setState which will be the internal state rather than + // the onChange prop (as no onChange was passed in) + + // primarily this proves that the hook doesn't break if no onChange is passed but + // value turns into a controlled state, for example if the value needs to be set + // to a constant in certain conditions but no change listening needs to happen + result.current[ 1 ]( 'WordPress.org' ); + } ); + + // If `value` is passed then we expect the value to be fully controlled + // meaning that the value passed in will always be used even though + // we're managing internal state. + expect( result.current[ 0 ] ).toEqual( 'Code is Poetry' ); + + // Next we un-set the value to uncover the internal state which was still maintained + rerender( { value: undefined } ); + + expect( result.current[ 0 ] ).toEqual( 'WordPress.org' ); + } ); +} ); From 133b262a566a5799b82f71c06708f0920ee09cd7 Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Mon, 28 Jun 2021 13:19:35 -0700 Subject: [PATCH 63/64] Remove usage of renderHook --- package-lock.json | 31 ----- package.json | 1 - .../utils/hooks/test/use-controlled-value.js | 112 +++++++++--------- 3 files changed, 53 insertions(+), 91 deletions(-) diff --git a/package-lock.json b/package-lock.json index 42638c56cb1fb3..ca2d654ff162ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12100,19 +12100,6 @@ "@testing-library/dom": "^7.28.1" } }, - "@testing-library/react-hooks": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-7.0.0.tgz", - "integrity": "sha512-WFBGH8DWdIGGBHt6PBtQPe2v4Kbj9vQ1sQ9qLBTmwn1PNggngint4MTE/IiWCYhPbyTW3oc/7X62DObMn/AjQQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5", - "@types/react": ">=16.9.0", - "@types/react-dom": ">=16.9.0", - "@types/react-test-renderer": ">=16.9.0", - "react-error-boundary": "^3.1.0" - } - }, "@testing-library/react-native": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@testing-library/react-native/-/react-native-7.1.0.tgz", @@ -12637,15 +12624,6 @@ "@types/react": "*" } }, - "@types/react-test-renderer": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz", - "integrity": "sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, "@types/requestidlecallback": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@types/requestidlecallback/-/requestidlecallback-0.3.1.tgz", @@ -50274,15 +50252,6 @@ } } }, - "react-error-boundary": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.3.tgz", - "integrity": "sha512-A+F9HHy9fvt9t8SNDlonq01prnU8AmkjvGKV4kk8seB9kU3xMEO8J/PQlLVmoOIDODl5U2kufSBs4vrWIqhsAA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5" - } - }, "react-error-overlay": { "version": "6.0.9", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", diff --git a/package.json b/package.json index 7f3ee6214c10d1..4546293f5555aa 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,6 @@ "@testing-library/jest-dom": "5.11.9", "@testing-library/react": "11.2.2", "@testing-library/react-native": "7.1.0", - "@testing-library/react-hooks": "7.0.0", "@types/classnames": "2.2.10", "@types/clipboard": "2.0.1", "@types/eslint": "6.8.0", diff --git a/packages/components/src/utils/hooks/test/use-controlled-value.js b/packages/components/src/utils/hooks/test/use-controlled-value.js index d7b77f0b8f99c7..1d63d9248021ea 100644 --- a/packages/components/src/utils/hooks/test/use-controlled-value.js +++ b/packages/components/src/utils/hooks/test/use-controlled-value.js @@ -1,107 +1,101 @@ /** * External dependencies */ -import { renderHook, act } from '@testing-library/react-hooks'; +import { fireEvent, render, screen } from '@testing-library/react'; /** * Internal dependencies */ import { useControlledValue } from '../use-controlled-value'; +function Input( props ) { + const [ value, setValue ] = useControlledValue( props ); + return ( + setValue( event.target.value ) } + /> + ); +} + +function getInput() { + return screen.getByRole( 'textbox' ); +} + describe( 'useControlledValue', () => { it( 'should use the default value', () => { - const { result } = renderHook( () => - useControlledValue( { defaultValue: 'WordPress.org' } ) - ); - - expect( result.current[ 0 ] ).toEqual( 'WordPress.org' ); + render( ); + expect( getInput() ).toHaveValue( 'WordPress.org' ); } ); it( 'should use the default value then switch to the controlled value', () => { - const { result, rerender } = renderHook( - ( { value } ) => - useControlledValue( { defaultValue: 'WordPress.org', value } ), - { initialProps: { value: undefined } } - ); - expect( result.current[ 0 ] ).toEqual( 'WordPress.org' ); - - rerender( { value: 'Code is Poetry' } ); + const { rerender } = render( ); + expect( getInput() ).toHaveValue( 'WordPress.org' ); - expect( result.current[ 0 ] ).toEqual( 'Code is Poetry' ); + rerender( + + ); + expect( getInput() ).toHaveValue( 'Code is Poetry' ); } ); it( 'should not call onChange only when there is no value being passed in', () => { const onChange = jest.fn(); - const { result } = renderHook( () => - useControlledValue( { defaultValue: 'WordPress.org', onChange } ) - ); + render( ); - expect( result.current[ 0 ] ).toEqual( 'WordPress.org' ); + expect( getInput() ).toHaveValue( 'WordPress.org' ); - act( () => { - result.current[ 1 ]( 'Code is Poetry' ); - } ); + fireEvent.change( getInput(), { target: { value: 'Code is Poetry' } } ); - expect( result.current[ 0 ] ).toEqual( 'Code is Poetry' ); + expect( getInput() ).toHaveValue( 'Code is Poetry' ); expect( onChange ).not.toHaveBeenCalled(); } ); it( 'should call onChange when there is a value passed in', () => { const onChange = jest.fn(); - const { result, rerender } = renderHook( - ( { value } ) => - useControlledValue( { - defaultValue: 'WordPress.org', - value, - onChange, - } ), - { initialProps: { value: 'Code is Poetry' } } + const { rerender } = render( + ); - expect( result.current[ 0 ] ).toEqual( 'Code is Poetry' ); + expect( getInput() ).toHaveValue( 'Code is Poetry' ); - act( () => { - // simulate `setValue` getting called by an input - result.current[ 1 ]( 'WordPress rocks!' ); + fireEvent.change( getInput(), { + target: { value: 'WordPress rocks!' }, } ); - // simulate the parent re-rendering and passing a new value down - rerender( { value: 'WordPress rocks!' } ); + rerender( + + ); - expect( result.current[ 0 ] ).toEqual( 'WordPress rocks!' ); + expect( getInput() ).toHaveValue( 'WordPress rocks!' ); expect( onChange ).toHaveBeenCalledWith( 'WordPress rocks!' ); } ); it( 'should not maintain internal state if no onChange is passed but a value is passed', () => { - const { result, rerender } = renderHook( - ( { value } ) => useControlledValue( { value } ), - { initialProps: { value: undefined } } - ); - - expect( result.current[ 0 ] ).toBe( undefined ); + const { rerender } = render( ); - rerender( { value: 'Code is Poetry' } ); + expect( getInput() ).toHaveValue( 'Code is Poetry' ); - expect( result.current[ 0 ] ).toEqual( 'Code is Poetry' ); - - act( () => { - // call setState which will be the internal state rather than - // the onChange prop (as no onChange was passed in) - - // primarily this proves that the hook doesn't break if no onChange is passed but - // value turns into a controlled state, for example if the value needs to be set - // to a constant in certain conditions but no change listening needs to happen - result.current[ 1 ]( 'WordPress.org' ); - } ); + // primarily this proves that the hook doesn't break if no onChange is passed but + // value turns into a controlled state, for example if the value needs to be set + // to a constant in certain conditions but no change listening needs to happen + fireEvent.change( getInput(), { target: { value: 'WordPress.org' } } ); // If `value` is passed then we expect the value to be fully controlled // meaning that the value passed in will always be used even though // we're managing internal state. - expect( result.current[ 0 ] ).toEqual( 'Code is Poetry' ); + expect( getInput() ).toHaveValue( 'Code is Poetry' ); // Next we un-set the value to uncover the internal state which was still maintained - rerender( { value: undefined } ); + rerender( ); - expect( result.current[ 0 ] ).toEqual( 'WordPress.org' ); + expect( getInput() ).toHaveValue( 'WordPress.org' ); } ); } ); From 0e6ce0b4cce7cfe4630d9cbe156fdaf79f4575d0 Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Tue, 29 Jun 2021 08:34:46 -0700 Subject: [PATCH 64/64] Allow null as a value --- .../components/src/utils/hooks/use-controlled-value.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/components/src/utils/hooks/use-controlled-value.ts b/packages/components/src/utils/hooks/use-controlled-value.ts index b29c93d1fb6a6a..c0878e75f191cf 100644 --- a/packages/components/src/utils/hooks/use-controlled-value.ts +++ b/packages/components/src/utils/hooks/use-controlled-value.ts @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import { isNil } from 'lodash'; - /** * WordPress dependencies */ @@ -28,11 +23,12 @@ export function useControlledValue< T >( { onChange, value: valueProp, }: Props< T > ): [ T | undefined, ( value: T ) => void ] { - const hasValue = ! isNil( valueProp ); + const hasValue = typeof valueProp !== 'undefined'; const initialValue = hasValue ? valueProp : defaultValue; const [ state, setState ] = useState( initialValue ); const value = hasValue ? valueProp : state; - const setValue = hasValue && ! isNil( onChange ) ? onChange : setState; + const setValue = + hasValue && typeof onChange === 'function' ? onChange : setState; return [ value, setValue ]; }