From 61cc83f9f8783e00b525a3777dfcf540dfda87d8 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Thu, 28 Sep 2023 16:44:40 +0800 Subject: [PATCH 01/23] Make editor.getBlocks to return only testing-related properties (#54901) --- .../src/editor/get-blocks.ts | 48 ++++++++++++++----- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/packages/e2e-test-utils-playwright/src/editor/get-blocks.ts b/packages/e2e-test-utils-playwright/src/editor/get-blocks.ts index 70a5a03628ee0..f5adb295a00a5 100644 --- a/packages/e2e-test-utils-playwright/src/editor/get-blocks.ts +++ b/packages/e2e-test-utils-playwright/src/editor/get-blocks.ts @@ -3,25 +3,49 @@ */ import type { Editor } from './index'; +type Block = { + name: string; + attributes: Record< string, unknown >; + innerBlocks: Block[]; +}; + /** * Returns the edited blocks. * * @param this + * @param options + * @param options.full Whether to return the full block data or just the name and attributes. * * @return The blocks. */ -export async function getBlocks( this: Editor ) { - return await this.page.evaluate( () => { - const blocks = window.wp.data.select( 'core/block-editor' ).getBlocks(); +export async function getBlocks( this: Editor, { full = false } = {} ) { + return await this.page.evaluate( + ( [ _full ] ) => { + // Remove other unpredictable properties like clientId from blocks for testing purposes. + function recursivelyTransformBlocks( blocks: Block[] ): Block[] { + return blocks.map( ( block ) => ( { + name: block.name, + attributes: block.attributes, + innerBlocks: recursivelyTransformBlocks( + block.innerBlocks + ), + } ) ); + } + + const blocks = window.wp.data + .select( 'core/block-editor' ) + .getBlocks(); - // The editor might still contain an unmodified empty block even when it's technically "empty". - if ( - blocks.length === 1 && - window.wp.blocks.isUnmodifiedDefaultBlock( blocks[ 0 ] ) - ) { - return []; - } + // The editor might still contain an unmodified empty block even when it's technically "empty". + if ( + blocks.length === 1 && + window.wp.blocks.isUnmodifiedDefaultBlock( blocks[ 0 ] ) + ) { + return []; + } - return blocks; - } ); + return _full ? blocks : recursivelyTransformBlocks( blocks ); + }, + [ full ] + ); } From 46995a21f1249d4e9e63eca30b2cfed025aacf97 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 28 Sep 2023 09:54:22 +0100 Subject: [PATCH 02/23] Add a documentation page about the block editor settings (#54870) --- platform-docs/docs/basic-concepts/settings.md | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) diff --git a/platform-docs/docs/basic-concepts/settings.md b/platform-docs/docs/basic-concepts/settings.md index 66d0691aef5f7..11e25996b2ec1 100644 --- a/platform-docs/docs/basic-concepts/settings.md +++ b/platform-docs/docs/basic-concepts/settings.md @@ -3,3 +3,161 @@ sidebar_position: 4 --- # Block Editor Settings + +You can customize the block editor by providing a `settings` prop to the `BlockEditorProvider` component. This prop accepts an object with the following properties: + +## styles + +The styles setting is an array of editor styles to enqueue in the iframe/canvas of the block editor. Each style is an object with a `css` property. Example: + +```jsx +import { BlockEditorProvider, BlockCanvas } from '@wordpress/block-editor'; + +export const editorStyles = [ + { + css: ` + body { + font-family: Arial; + font-size: 16px; + } + + p { + font-size: inherit; + line-height: inherit; + } + + ul { + list-style-type: disc; + } + + ol { + list-style-type: decimal; + } + `, + }, +]; + +export default function App() { + return ( + + + + ); +} +``` + +## mediaUpload + +Some core blocks, like the image or video blocks, allow users to render media within the block editor. By default, you can use external URLs but if you want to allow users to upload media from their computer, you need to provide a `mediaUpload` function. Here's a quick example of such function: + +```jsx +async function mediaUpload( { + additionalData = {}, + filesList, + onError = noop, + onFileChange, +} ) { + const uploadedMedia = []; + for ( const file of filesList ) { + try { + const data = await someApiCallToUploadTheFile( file ); + const mediaObject = { + alt: data.alt, + caption: data.caption, + title: data.title, + url: data.url, + }; + uploadedMedia.push( mediaObject ); + } catch ( error ) { + onError( { + code: 'SOME_ERROR_CODE', + message: + mediaFile.name + + ' : Sorry, an error happened while uploading this file.', + file: mediaFile, + } ); + } + if ( uploadedMedia.length ) { + onFileChange( uploadedMedia ); + } + } +} +``` + +Providing a `mediaUpload` function also enables drag and dropping files into the editor to upload them. + +## inserterMediaCategories + +The inserter media categories setting is an array of media categories to display in the inserter. Each category is an object with `name` and `labels` values, a `fetch` function and a few extra keys. Example: + +```jsx +{ + name: 'openverse', + labels: { + name: 'Openverse', + search_items: 'Search Openverse', + }, + mediaType: 'image', + async fetch( query = {} ) { + const defaultArgs = { + mature: false, + excluded_source: 'flickr,inaturalist,wikimedia', + license: 'pdm,cc0', + }; + const finalQuery = { ...query, ...defaultArgs }; + // Sometimes you might need to map the supported request params according to the `InserterMediaRequest` + // interface. In this example the `search` query param is named `q`. + const mapFromInserterMediaRequest = { + per_page: 'page_size', + search: 'q', + }; + const url = new URL( 'https://api.openverse.engineering/v1/images/' ); + Object.entries( finalQuery ).forEach( ( [ key, value ] ) => { + const queryKey = mapFromInserterMediaRequest[ key ] || key; + url.searchParams.set( queryKey, value ); + } ); + const response = await window.fetch( url, { + headers: { + 'User-Agent': 'WordPress/inserter-media-fetch', + }, + } ); + const jsonResponse = await response.json(); + const results = jsonResponse.results; + return results.map( ( result ) => ( { + ...result, + // If your response result includes an `id` prop that you want to access later, it should + // be mapped to `InserterMediaItem`'s `sourceId` prop. This can be useful if you provide + // a report URL getter. + // Additionally you should always clear the `id` value of your response results because + // it is used to identify WordPress media items. + sourceId: result.id, + id: undefined, + caption: result.caption, + previewUrl: result.thumbnail, + } ) ); + }, + getReportUrl: ( { sourceId } ) => + `https://wordpress.org/openverse/image/${ sourceId }/report/`, + isExternalResource: true, +} +``` + +## hasFixedToolbar + +Whether the `BlockTools` component renders the toolbar in a fixed position or if follows the position of the selected block. Defaults to `false`. + +## focusMode + +The focus mode is a special mode where any block that is not selected is shown with a reduced opacity, giving more prominence to the selected block. Defaults to `false`. + +## keepCaretInsideBlock + +By default, arrow keys can be used to navigate across blocks. You can turn off that behavior and keep the caret inside the currently selected block using this setting. Defaults to `false`. + +## codeEditingEnabled + +Allows the user to edit the currently selected block using an HTML code editor. Note that using the code editor is not supported by all blocks and that it has the potential to create invalid blocks depending on the markup the user provides. Defaults to `true`. + +## canLockBlocks + +Whether the user can lock blocks. Defaults to `true`. From 429e6451a70270bf2cf1ba033ca376200a4dad61 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 28 Sep 2023 10:46:18 +0100 Subject: [PATCH 03/23] Update the default JSX pragma to React instead of @wordpress/element (#54494) --- package-lock.json | 8 ++++---- packages/babel-plugin-import-jsx-pragma/README.md | 4 ++-- packages/babel-preset-default/CHANGELOG.md | 4 ++++ packages/babel-preset-default/index.js | 2 +- packages/babel-preset-default/package.json | 4 ++-- packages/react-native-editor/babel.config.js | 4 ++-- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5895a051a0741..13613ee74c9ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55891,10 +55891,10 @@ "@babel/runtime": "^7.16.0", "@wordpress/babel-plugin-import-jsx-pragma": "file:../babel-plugin-import-jsx-pragma", "@wordpress/browserslist-config": "file:../browserslist-config", - "@wordpress/element": "file:../element", "@wordpress/warning": "file:../warning", "browserslist": "^4.21.10", - "core-js": "^3.31.0" + "core-js": "^3.31.0", + "react": "^18.2.0" }, "engines": { "node": ">=14" @@ -69255,10 +69255,10 @@ "@babel/runtime": "^7.16.0", "@wordpress/babel-plugin-import-jsx-pragma": "file:../babel-plugin-import-jsx-pragma", "@wordpress/browserslist-config": "file:../browserslist-config", - "@wordpress/element": "file:../element", "@wordpress/warning": "file:../warning", "browserslist": "^4.21.10", - "core-js": "^3.31.0" + "core-js": "^3.31.0", + "react": "^18.2.0" } }, "@wordpress/base-styles": { diff --git a/packages/babel-plugin-import-jsx-pragma/README.md b/packages/babel-plugin-import-jsx-pragma/README.md index 5edb4d357ae27..eb252d501290b 100644 --- a/packages/babel-plugin-import-jsx-pragma/README.md +++ b/packages/babel-plugin-import-jsx-pragma/README.md @@ -38,7 +38,7 @@ _Note:_ `@wordpress/babel-plugin-import-jsx-pragma` is included in `@wordpress/b As the `@babel/plugin-transform-react-jsx` plugin offers options to customize the `pragma` to which the transform references, there are equivalent options to assign for customizing the imports generated. -For example, if you are using the `@wordpress/element` package, you may want to use the following configuration: +For example, if you are using the `react` package, you may want to use the following configuration: ```js // .babelrc.js @@ -49,7 +49,7 @@ module.exports = { { scopeVariable: 'createElement', scopeVariableFrag: 'Fragment', - source: '@wordpress/element', + source: 'react', isDefault: false, }, ], diff --git a/packages/babel-preset-default/CHANGELOG.md b/packages/babel-preset-default/CHANGELOG.md index 586702f5857a8..1dd52099e25f4 100644 --- a/packages/babel-preset-default/CHANGELOG.md +++ b/packages/babel-preset-default/CHANGELOG.md @@ -6,6 +6,10 @@ - The bundled `browserslist` dependency has been updated from requiring `^4.21.9` to requiring `^4.21.10` ([#54657](https://github.com/WordPress/gutenberg/pull/54657)). +## Enhancements + +- Use `react` as the default scope variable for JSX pragma instead of `@wordpress/element`. + ## 7.26.0 (2023-09-20) ## 7.25.0 (2023-08-31) diff --git a/packages/babel-preset-default/index.js b/packages/babel-preset-default/index.js index cb5ed0ccac3b1..40f7c31bb3c25 100644 --- a/packages/babel-preset-default/index.js +++ b/packages/babel-preset-default/index.js @@ -80,7 +80,7 @@ module.exports = ( api ) => { { scopeVariable: 'createElement', scopeVariableFrag: 'Fragment', - source: '@wordpress/element', + source: 'react', isDefault: false, }, ], diff --git a/packages/babel-preset-default/package.json b/packages/babel-preset-default/package.json index 5f26247faa6c0..d443fda5c060c 100644 --- a/packages/babel-preset-default/package.json +++ b/packages/babel-preset-default/package.json @@ -37,10 +37,10 @@ "@babel/runtime": "^7.16.0", "@wordpress/babel-plugin-import-jsx-pragma": "file:../babel-plugin-import-jsx-pragma", "@wordpress/browserslist-config": "file:../browserslist-config", - "@wordpress/element": "file:../element", "@wordpress/warning": "file:../warning", "browserslist": "^4.21.10", - "core-js": "^3.31.0" + "core-js": "^3.31.0", + "react": "^18.2.0" }, "publishConfig": { "access": "public" diff --git a/packages/react-native-editor/babel.config.js b/packages/react-native-editor/babel.config.js index 62a9959bcf45a..4f7138636e23a 100644 --- a/packages/react-native-editor/babel.config.js +++ b/packages/react-native-editor/babel.config.js @@ -41,14 +41,14 @@ module.exports = function ( api ) { /node_modules\/(react-native|@react-native-community|@react-navigation|react-native-reanimated)/, }, { - // Auto-add `import { createElement } from '@wordpress/element';` when JSX is found. + // Auto-add `import { createElement } from 'react';` when JSX is found. plugins: [ [ '@wordpress/babel-plugin-import-jsx-pragma', { scopeVariable: 'createElement', scopeVariableFrag: 'Fragment', - source: '@wordpress/element', + source: 'react', isDefault: false, }, ], From 15c2dd9ca1fda5760761eaf6b1d624fce1bf343c Mon Sep 17 00:00:00 2001 From: Andrew Hayward Date: Thu, 28 Sep 2023 10:55:22 +0100 Subject: [PATCH 04/23] Adding label/description to `BlockEditor/DuotoneControl` (#54473) Adding label/description to `BlockEditor/DuotoneControl` --- .../src/components/duotone-control/index.js | 16 ++++++++++++++-- packages/components/CHANGELOG.md | 3 ++- .../src/duotone-picker/duotone-picker.tsx | 6 +++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/duotone-control/index.js b/packages/block-editor/src/components/duotone-control/index.js index 7682e7ee157e8..e110286976b1a 100644 --- a/packages/block-editor/src/components/duotone-control/index.js +++ b/packages/block-editor/src/components/duotone-control/index.js @@ -12,8 +12,10 @@ import { import { __ } from '@wordpress/i18n'; import { DOWN } from '@wordpress/keycodes'; import { Icon, filter } from '@wordpress/icons'; +import { useInstanceId } from '@wordpress/compose'; function DuotoneControl( { + id: idProp, colorPalette, duotonePalette, disableCustomColors, @@ -31,6 +33,11 @@ function DuotoneControl( { } else { toolbarIcon = ; } + + const actionLabel = __( 'Apply duotone filter' ); + const id = useInstanceId( DuotoneControl, 'duotone-control', idProp ); + const descriptionId = `${ id }__description`; + return ( ); } } renderContent={ () => ( -
+
{ __( 'Create a two-tone color effect without losing your original image.' ) }
getDefaultColors( colorPalette ), @@ -74,13 +75,15 @@ function DuotonePicker( { ); const isUnset = value === 'unset'; + const unsetOptionLabel = __( 'Unset' ); const unsetOption = ( { onChange( isUnset ? undefined : 'unset' ); @@ -154,6 +157,7 @@ function DuotonePicker( { return ( Date: Thu, 28 Sep 2023 12:46:55 +0200 Subject: [PATCH 05/23] =?UTF-8?q?[Mobile]=C2=A0-=20GutenbergDemo=20app:=20?= =?UTF-8?q?Enable=20Hermes=20(#54151)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove Reanimated patch * Update Podfile and project to use Hermes * Update bundle scripts to generate bytecode bundle * Update React Native URL Polyfill to minor 1.3.0 version. This also will help to trigger the npm cache --- package-lock.json | 107 ++++++- .../GutenbergDemo.xcodeproj/project.pbxproj | 270 ++++++------------ packages/react-native-editor/ios/Podfile | 26 +- packages/react-native-editor/ios/Podfile.lock | 112 +++++--- packages/react-native-editor/package.json | 8 +- patches/react-native-reanimated+2.17.0.patch | 14 - 6 files changed, 280 insertions(+), 257 deletions(-) delete mode 100644 patches/react-native-reanimated+2.17.0.patch diff --git a/package-lock.json b/package-lock.json index 13613ee74c9ec..56d80e9f75776 100644 --- a/package-lock.json +++ b/package-lock.json @@ -46765,7 +46765,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, "engines": { "node": ">=6" } @@ -47606,6 +47605,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/react-native-url-polyfill/-/react-native-url-polyfill-1.1.2.tgz", "integrity": "sha512-RPYwjW+4udnAf26xUCQP2dn4t2tnRFo3Ii4s/hy7Ivpe7xYtXp7CMVX505CR8X3p0f8NKmOJ4MQEFMMnbd/Y/Q==", + "dev": true, "dependencies": { "buffer": "^5.4.3", "whatwg-url-without-unicode": "8.0.0-1" @@ -47618,6 +47618,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, "funding": [ { "type": "github", @@ -55118,6 +55119,7 @@ "version": "8.0.0-1", "resolved": "https://registry.npmjs.org/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-1.tgz", "integrity": "sha512-0Uy8mjsG5O8Y53327XL+ZqsrMdxO1CL/6m840SmW5iyRWFvU2zlxS2RzpD3pFFVKYOKCmsKn5JKzWxQ+bImnWA==", + "dev": true, "dependencies": { "webidl-conversions": "^5.0.0" }, @@ -55129,6 +55131,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, "engines": { "node": ">=8" } @@ -57655,7 +57658,7 @@ "react-native-sass-transformer": "^1.1.1", "react-native-screens": "3.22.0", "react-native-svg": "13.9.0", - "react-native-url-polyfill": "^1.1.2", + "react-native-url-polyfill": "1.3.0", "react-native-video": "https://raw.githubusercontent.com/wordpress-mobile/react-native-video/5.2.0-wp-6/react-native-video-5.2.0-wp-6.tgz", "react-native-webview": "11.26.1" }, @@ -57664,6 +57667,61 @@ "npm": ">=6.9" } }, + "packages/react-native-editor/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "packages/react-native-editor/node_modules/react-native-url-polyfill": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-native-url-polyfill/-/react-native-url-polyfill-1.3.0.tgz", + "integrity": "sha512-w9JfSkvpqqlix9UjDvJjm1EjSt652zVQ6iwCIj1cVVkwXf4jQhQgTNXY6EVTwuAmUjg6BC6k9RHCBynoLFo3IQ==", + "dependencies": { + "whatwg-url-without-unicode": "8.0.0-3" + }, + "peerDependencies": { + "react-native": "*" + } + }, + "packages/react-native-editor/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "engines": { + "node": ">=8" + } + }, + "packages/react-native-editor/node_modules/whatwg-url-without-unicode": { + "version": "8.0.0-3", + "resolved": "https://registry.npmjs.org/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-3.tgz", + "integrity": "sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig==", + "dependencies": { + "buffer": "^5.4.3", + "punycode": "^2.1.1", + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, "packages/readable-js-assets-webpack-plugin": { "name": "@wordpress/readable-js-assets-webpack-plugin", "version": "2.25.0", @@ -70451,9 +70509,43 @@ "react-native-sass-transformer": "^1.1.1", "react-native-screens": "3.22.0", "react-native-svg": "13.9.0", - "react-native-url-polyfill": "^1.1.2", + "react-native-url-polyfill": "1.3.0", "react-native-video": "https://raw.githubusercontent.com/wordpress-mobile/react-native-video/5.2.0-wp-6/react-native-video-5.2.0-wp-6.tgz", "react-native-webview": "11.26.1" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "react-native-url-polyfill": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-native-url-polyfill/-/react-native-url-polyfill-1.3.0.tgz", + "integrity": "sha512-w9JfSkvpqqlix9UjDvJjm1EjSt652zVQ6iwCIj1cVVkwXf4jQhQgTNXY6EVTwuAmUjg6BC6k9RHCBynoLFo3IQ==", + "requires": { + "whatwg-url-without-unicode": "8.0.0-3" + } + }, + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + }, + "whatwg-url-without-unicode": { + "version": "8.0.0-3", + "resolved": "https://registry.npmjs.org/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-3.tgz", + "integrity": "sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig==", + "requires": { + "buffer": "^5.4.3", + "punycode": "^2.1.1", + "webidl-conversions": "^5.0.0" + } + } } }, "@wordpress/readable-js-assets-webpack-plugin": { @@ -95889,8 +95981,7 @@ "punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" }, "puppeteer-core": { "version": "13.7.0", @@ -96729,6 +96820,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/react-native-url-polyfill/-/react-native-url-polyfill-1.1.2.tgz", "integrity": "sha512-RPYwjW+4udnAf26xUCQP2dn4t2tnRFo3Ii4s/hy7Ivpe7xYtXp7CMVX505CR8X3p0f8NKmOJ4MQEFMMnbd/Y/Q==", + "dev": true, "requires": { "buffer": "^5.4.3", "whatwg-url-without-unicode": "8.0.0-1" @@ -96738,6 +96830,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -102230,6 +102323,7 @@ "version": "8.0.0-1", "resolved": "https://registry.npmjs.org/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-1.tgz", "integrity": "sha512-0Uy8mjsG5O8Y53327XL+ZqsrMdxO1CL/6m840SmW5iyRWFvU2zlxS2RzpD3pFFVKYOKCmsKn5JKzWxQ+bImnWA==", + "dev": true, "requires": { "webidl-conversions": "^5.0.0" }, @@ -102237,7 +102331,8 @@ "webidl-conversions": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true } } }, diff --git a/packages/react-native-editor/ios/GutenbergDemo.xcodeproj/project.pbxproj b/packages/react-native-editor/ios/GutenbergDemo.xcodeproj/project.pbxproj index a4e179d3baa74..5cbe46243ff4e 100644 --- a/packages/react-native-editor/ios/GutenbergDemo.xcodeproj/project.pbxproj +++ b/packages/react-native-editor/ios/GutenbergDemo.xcodeproj/project.pbxproj @@ -216,6 +216,7 @@ 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, 71C0B5FDA891DD4D469D2DFB /* [CP] Embed Pods Frameworks */, + 6C6876BA82C8AB734B9EB348 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -237,6 +238,7 @@ 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 06CE89E9A162D62B604C3B6C /* [CP] Embed Pods Frameworks */, + BD87D2B56A91E91E3DFD2CBA /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -333,107 +335,55 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-GutenbergDemo/Pods-GutenbergDemo-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/BVLinearGradient/BVLinearGradient.framework", - "${BUILT_PRODUCTS_DIR}/DoubleConversion/DoubleConversion.framework", - "${BUILT_PRODUCTS_DIR}/Gutenberg/Gutenberg.framework", - "${BUILT_PRODUCTS_DIR}/RCT-Folly/folly.framework", - "${BUILT_PRODUCTS_DIR}/RCTTypeSafety/RCTTypeSafety.framework", - "${BUILT_PRODUCTS_DIR}/RNCClipboard/RNCClipboard.framework", - "${BUILT_PRODUCTS_DIR}/RNCMaskedView/RNCMaskedView.framework", - "${BUILT_PRODUCTS_DIR}/RNFastImage/RNFastImage.framework", - "${BUILT_PRODUCTS_DIR}/RNGestureHandler/RNGestureHandler.framework", - "${BUILT_PRODUCTS_DIR}/RNReanimated/RNReanimated.framework", - "${BUILT_PRODUCTS_DIR}/RNSVG/RNSVG.framework", - "${BUILT_PRODUCTS_DIR}/RNScreens/RNScreens.framework", - "${BUILT_PRODUCTS_DIR}/RNTAztecView/RNTAztecView.framework", - "${BUILT_PRODUCTS_DIR}/React-Codegen/React_Codegen.framework", - "${BUILT_PRODUCTS_DIR}/React-Core/React.framework", - "${BUILT_PRODUCTS_DIR}/React-CoreModules/CoreModules.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTAnimation/RCTAnimation.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTAppDelegate/React_RCTAppDelegate.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTBlob/RCTBlob.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTImage/RCTImage.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTLinking/RCTLinking.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTNetwork/RCTNetwork.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTSettings/RCTSettings.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTText/RCTText.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTVibration/RCTVibration.framework", - "${BUILT_PRODUCTS_DIR}/React-cxxreact/cxxreact.framework", - "${BUILT_PRODUCTS_DIR}/React-jsc/React_jsc.framework", - "${BUILT_PRODUCTS_DIR}/React-jsi/jsi.framework", - "${BUILT_PRODUCTS_DIR}/React-jsiexecutor/jsireact.framework", - "${BUILT_PRODUCTS_DIR}/React-jsinspector/jsinspector.framework", - "${BUILT_PRODUCTS_DIR}/React-logger/logger.framework", - "${BUILT_PRODUCTS_DIR}/React-perflogger/reactperflogger.framework", - "${BUILT_PRODUCTS_DIR}/ReactCommon/ReactCommon.framework", - "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", - "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework", - "${BUILT_PRODUCTS_DIR}/WordPress-Aztec-iOS/Aztec.framework", - "${BUILT_PRODUCTS_DIR}/Yoga/yoga.framework", - "${BUILT_PRODUCTS_DIR}/fmt/fmt.framework", - "${BUILT_PRODUCTS_DIR}/glog/glog.framework", - "${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework", - "${BUILT_PRODUCTS_DIR}/react-native-blur/react_native_blur.framework", - "${BUILT_PRODUCTS_DIR}/react-native-get-random-values/react_native_get_random_values.framework", - "${BUILT_PRODUCTS_DIR}/react-native-safe-area/react_native_safe_area.framework", - "${BUILT_PRODUCTS_DIR}/react-native-safe-area-context/react_native_safe_area_context.framework", - "${BUILT_PRODUCTS_DIR}/react-native-slider/react_native_slider.framework", - "${BUILT_PRODUCTS_DIR}/react-native-webview/react_native_webview.framework", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BVLinearGradient.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DoubleConversion.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Gutenberg.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/folly.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTTypeSafety.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNCClipboard.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNCMaskedView.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNFastImage.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNGestureHandler.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNReanimated.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNSVG.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNScreens.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNTAztecView.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/React_Codegen.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/React.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CoreModules.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTAnimation.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/React_RCTAppDelegate.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTBlob.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTImage.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTLinking.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTNetwork.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTSettings.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTText.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTVibration.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/cxxreact.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/React_jsc.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/jsi.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/jsireact.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/jsinspector.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/logger.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/reactperflogger.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactCommon.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Aztec.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/yoga.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/fmt.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/glog.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_blur.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_get_random_values.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_safe_area.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_safe_area_context.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_slider.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_webview.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-GutenbergDemo/Pods-GutenbergDemo-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + 6C6876BA82C8AB734B9EB348 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-GutenbergDemo-GutenbergDemoTests/Pods-GutenbergDemo-GutenbergDemoTests-resources.sh", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/content-functions.js", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/editor-behavior-overrides.js", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/editor-style-overrides.css", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/gutenberg-observer.js", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/inject-css.js", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/insert-block.js", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/local-storage-overrides.json", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/prevent-autosaves.js", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/wp-bar-override.css", + "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/WordPress-Aztec-iOS/WordPress-Aztec-iOS.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/content-functions.js", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/editor-behavior-overrides.js", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/editor-style-overrides.css", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gutenberg-observer.js", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/inject-css.js", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/insert-block.js", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/local-storage-overrides.json", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/prevent-autosaves.js", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/wp-bar-override.css", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/WordPress-Aztec-iOS.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-GutenbergDemo-GutenbergDemoTests/Pods-GutenbergDemo-GutenbergDemoTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 70B839CE7B6A174DC4DE8FB6 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -463,101 +413,11 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-GutenbergDemo-GutenbergDemoTests/Pods-GutenbergDemo-GutenbergDemoTests-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/BVLinearGradient/BVLinearGradient.framework", - "${BUILT_PRODUCTS_DIR}/DoubleConversion/DoubleConversion.framework", - "${BUILT_PRODUCTS_DIR}/Gutenberg/Gutenberg.framework", - "${BUILT_PRODUCTS_DIR}/RCT-Folly/folly.framework", - "${BUILT_PRODUCTS_DIR}/RCTTypeSafety/RCTTypeSafety.framework", - "${BUILT_PRODUCTS_DIR}/RNCClipboard/RNCClipboard.framework", - "${BUILT_PRODUCTS_DIR}/RNCMaskedView/RNCMaskedView.framework", - "${BUILT_PRODUCTS_DIR}/RNFastImage/RNFastImage.framework", - "${BUILT_PRODUCTS_DIR}/RNGestureHandler/RNGestureHandler.framework", - "${BUILT_PRODUCTS_DIR}/RNReanimated/RNReanimated.framework", - "${BUILT_PRODUCTS_DIR}/RNSVG/RNSVG.framework", - "${BUILT_PRODUCTS_DIR}/RNScreens/RNScreens.framework", - "${BUILT_PRODUCTS_DIR}/RNTAztecView/RNTAztecView.framework", - "${BUILT_PRODUCTS_DIR}/React-Codegen/React_Codegen.framework", - "${BUILT_PRODUCTS_DIR}/React-Core/React.framework", - "${BUILT_PRODUCTS_DIR}/React-CoreModules/CoreModules.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTAnimation/RCTAnimation.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTAppDelegate/React_RCTAppDelegate.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTBlob/RCTBlob.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTImage/RCTImage.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTLinking/RCTLinking.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTNetwork/RCTNetwork.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTSettings/RCTSettings.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTText/RCTText.framework", - "${BUILT_PRODUCTS_DIR}/React-RCTVibration/RCTVibration.framework", - "${BUILT_PRODUCTS_DIR}/React-cxxreact/cxxreact.framework", - "${BUILT_PRODUCTS_DIR}/React-jsc/React_jsc.framework", - "${BUILT_PRODUCTS_DIR}/React-jsi/jsi.framework", - "${BUILT_PRODUCTS_DIR}/React-jsiexecutor/jsireact.framework", - "${BUILT_PRODUCTS_DIR}/React-jsinspector/jsinspector.framework", - "${BUILT_PRODUCTS_DIR}/React-logger/logger.framework", - "${BUILT_PRODUCTS_DIR}/React-perflogger/reactperflogger.framework", - "${BUILT_PRODUCTS_DIR}/ReactCommon/ReactCommon.framework", - "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", - "${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder/SDWebImageWebPCoder.framework", - "${BUILT_PRODUCTS_DIR}/WordPress-Aztec-iOS/Aztec.framework", - "${BUILT_PRODUCTS_DIR}/Yoga/yoga.framework", - "${BUILT_PRODUCTS_DIR}/fmt/fmt.framework", - "${BUILT_PRODUCTS_DIR}/glog/glog.framework", - "${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework", - "${BUILT_PRODUCTS_DIR}/react-native-blur/react_native_blur.framework", - "${BUILT_PRODUCTS_DIR}/react-native-get-random-values/react_native_get_random_values.framework", - "${BUILT_PRODUCTS_DIR}/react-native-safe-area/react_native_safe_area.framework", - "${BUILT_PRODUCTS_DIR}/react-native-safe-area-context/react_native_safe_area_context.framework", - "${BUILT_PRODUCTS_DIR}/react-native-slider/react_native_slider.framework", - "${BUILT_PRODUCTS_DIR}/react-native-webview/react_native_webview.framework", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BVLinearGradient.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DoubleConversion.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Gutenberg.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/folly.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTTypeSafety.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNCClipboard.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNCMaskedView.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNFastImage.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNGestureHandler.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNReanimated.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNSVG.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNScreens.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNTAztecView.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/React_Codegen.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/React.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CoreModules.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTAnimation.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/React_RCTAppDelegate.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTBlob.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTImage.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTLinking.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTNetwork.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTSettings.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTText.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTVibration.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/cxxreact.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/React_jsc.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/jsi.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/jsireact.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/jsinspector.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/logger.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/reactperflogger.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactCommon.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Aztec.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/yoga.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/fmt.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/glog.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_blur.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_get_random_values.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_safe_area.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_safe_area_context.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_slider.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_webview.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -586,6 +446,44 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + BD87D2B56A91E91E3DFD2CBA /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-GutenbergDemo/Pods-GutenbergDemo-resources.sh", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/content-functions.js", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/editor-behavior-overrides.js", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/editor-style-overrides.css", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/gutenberg-observer.js", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/inject-css.js", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/insert-block.js", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/local-storage-overrides.json", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/prevent-autosaves.js", + "${PODS_ROOT}/../../../react-native-bridge/common/gutenberg-web-single-block/wp-bar-override.css", + "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/WordPress-Aztec-iOS/WordPress-Aztec-iOS.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/content-functions.js", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/editor-behavior-overrides.js", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/editor-style-overrides.css", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gutenberg-observer.js", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/inject-css.js", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/insert-block.js", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/local-storage-overrides.json", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/prevent-autosaves.js", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/wp-bar-override.css", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/WordPress-Aztec-iOS.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-GutenbergDemo/Pods-GutenbergDemo-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -789,7 +687,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -833,7 +731,7 @@ COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; diff --git a/packages/react-native-editor/ios/Podfile b/packages/react-native-editor/ios/Podfile index a6100a7827265..cc7cda4894b0b 100644 --- a/packages/react-native-editor/ios/Podfile +++ b/packages/react-native-editor/ios/Podfile @@ -28,7 +28,7 @@ end target 'GutenbergDemo' do # Comment the next line if you don't want to use dynamic frameworks - use_frameworks! + use_frameworks! linkage: :static config = use_native_modules! @@ -37,7 +37,7 @@ target 'GutenbergDemo' do # Hermes is now enabled by default. Disable by setting this flag to false. # Upcoming versions of React Native may rely on get_default_flags(), but # we make it explicit here to aid in the React Native upgrade process. - :hermes_enabled => false, + :hermes_enabled => true, :fabric_enabled => false, # Enables Flipper. # @@ -93,16 +93,16 @@ target 'GutenbergDemo' do end end end - ### End workaround for https://github.com/facebook/react-native/issues/31034 + ### End workaround for https://github.com/facebook/react-native/issues/31034 - ### Begin workaround: https://github.com/CocoaPods/CocoaPods/issues/8891#issuecomment-1201465446 - installer.pods_project.targets.each do |target| - if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle" - target.build_configurations.each do |config| - config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO' - end - end - end - ### End workaround: https://github.com/CocoaPods/CocoaPods/issues/8891#issuecomment-1201465446 + ### Begin workaround: https://github.com/CocoaPods/CocoaPods/issues/8891#issuecomment-1201465446 + installer.pods_project.targets.each do |target| + if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle" + target.build_configurations.each do |config| + config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO' + end + end + end + ### End workaround: https://github.com/CocoaPods/CocoaPods/issues/8891#issuecomment-1201465446 end -end +end \ No newline at end of file diff --git a/packages/react-native-editor/ios/Podfile.lock b/packages/react-native-editor/ios/Podfile.lock index 73a7e20c622f9..324c80709386c 100644 --- a/packages/react-native-editor/ios/Podfile.lock +++ b/packages/react-native-editor/ios/Podfile.lock @@ -18,6 +18,10 @@ PODS: - React-CoreModules (= 0.71.11) - React-RCTImage (= 0.71.11) - RNTAztecView + - hermes-engine (0.71.11): + - hermes-engine/Pre-built (= 0.71.11) + - hermes-engine/Pre-built (0.71.11) + - libevent (2.1.12) - libwebp (1.2.3): - libwebp/demux (= 1.2.3) - libwebp/mux (= 1.2.3) @@ -38,6 +42,12 @@ PODS: - DoubleConversion - fmt (~> 6.2.1) - glog + - RCT-Folly/Futures (2021.07.22.00): + - boost + - DoubleConversion + - fmt (~> 6.2.1) + - glog + - libevent - RCTRequired (0.71.11) - RCTTypeSafety (0.71.11): - FBLazyVector (= 0.71.11) @@ -59,51 +69,55 @@ PODS: - React-callinvoker (0.71.11) - React-Codegen (0.71.11): - FBReactNativeSpec + - hermes-engine - RCT-Folly - RCTRequired - RCTTypeSafety - React-Core - - React-jsc - React-jsi - React-jsiexecutor - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - React-Core (0.71.11): - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default (= 0.71.11) - React-cxxreact (= 0.71.11) - - React-jsc + - React-hermes - React-jsi (= 0.71.11) - React-jsiexecutor (= 0.71.11) - React-perflogger (= 0.71.11) - Yoga - React-Core/CoreModulesHeaders (0.71.11): - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - React-cxxreact (= 0.71.11) - - React-jsc + - React-hermes - React-jsi (= 0.71.11) - React-jsiexecutor (= 0.71.11) - React-perflogger (= 0.71.11) - Yoga - React-Core/Default (0.71.11): - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-cxxreact (= 0.71.11) - - React-jsc + - React-hermes - React-jsi (= 0.71.11) - React-jsiexecutor (= 0.71.11) - React-perflogger (= 0.71.11) - Yoga - React-Core/DevSupport (0.71.11): - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default (= 0.71.11) - React-Core/RCTWebSocket (= 0.71.11) - React-cxxreact (= 0.71.11) - - React-jsc + - React-hermes - React-jsi (= 0.71.11) - React-jsiexecutor (= 0.71.11) - React-jsinspector (= 0.71.11) @@ -111,100 +125,110 @@ PODS: - Yoga - React-Core/RCTActionSheetHeaders (0.71.11): - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - React-cxxreact (= 0.71.11) - - React-jsc + - React-hermes - React-jsi (= 0.71.11) - React-jsiexecutor (= 0.71.11) - React-perflogger (= 0.71.11) - Yoga - React-Core/RCTAnimationHeaders (0.71.11): - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - React-cxxreact (= 0.71.11) - - React-jsc + - React-hermes - React-jsi (= 0.71.11) - React-jsiexecutor (= 0.71.11) - React-perflogger (= 0.71.11) - Yoga - React-Core/RCTBlobHeaders (0.71.11): - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - React-cxxreact (= 0.71.11) - - React-jsc + - React-hermes - React-jsi (= 0.71.11) - React-jsiexecutor (= 0.71.11) - React-perflogger (= 0.71.11) - Yoga - React-Core/RCTImageHeaders (0.71.11): - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - React-cxxreact (= 0.71.11) - - React-jsc + - React-hermes - React-jsi (= 0.71.11) - React-jsiexecutor (= 0.71.11) - React-perflogger (= 0.71.11) - Yoga - React-Core/RCTLinkingHeaders (0.71.11): - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - React-cxxreact (= 0.71.11) - - React-jsc + - React-hermes - React-jsi (= 0.71.11) - React-jsiexecutor (= 0.71.11) - React-perflogger (= 0.71.11) - Yoga - React-Core/RCTNetworkHeaders (0.71.11): - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - React-cxxreact (= 0.71.11) - - React-jsc + - React-hermes - React-jsi (= 0.71.11) - React-jsiexecutor (= 0.71.11) - React-perflogger (= 0.71.11) - Yoga - React-Core/RCTSettingsHeaders (0.71.11): - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - React-cxxreact (= 0.71.11) - - React-jsc + - React-hermes - React-jsi (= 0.71.11) - React-jsiexecutor (= 0.71.11) - React-perflogger (= 0.71.11) - Yoga - React-Core/RCTTextHeaders (0.71.11): - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - React-cxxreact (= 0.71.11) - - React-jsc + - React-hermes - React-jsi (= 0.71.11) - React-jsiexecutor (= 0.71.11) - React-perflogger (= 0.71.11) - Yoga - React-Core/RCTVibrationHeaders (0.71.11): - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default - React-cxxreact (= 0.71.11) - - React-jsc + - React-hermes - React-jsi (= 0.71.11) - React-jsiexecutor (= 0.71.11) - React-perflogger (= 0.71.11) - Yoga - React-Core/RCTWebSocket (0.71.11): - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Core/Default (= 0.71.11) - React-cxxreact (= 0.71.11) - - React-jsc + - React-hermes - React-jsi (= 0.71.11) - React-jsiexecutor (= 0.71.11) - React-perflogger (= 0.71.11) @@ -222,6 +246,7 @@ PODS: - boost (= 1.76.0) - DoubleConversion - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-callinvoker (= 0.71.11) - React-jsi (= 0.71.11) @@ -229,19 +254,27 @@ PODS: - React-logger (= 0.71.11) - React-perflogger (= 0.71.11) - React-runtimeexecutor (= 0.71.11) - - React-jsc (0.71.11): - - React-jsc/Fabric (= 0.71.11) - - React-jsi (= 0.71.11) - - React-jsc/Fabric (0.71.11): - - React-jsi (= 0.71.11) + - React-hermes (0.71.11): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2021.07.22.00) + - RCT-Folly/Futures (= 2021.07.22.00) + - React-cxxreact (= 0.71.11) + - React-jsi + - React-jsiexecutor (= 0.71.11) + - React-jsinspector (= 0.71.11) + - React-perflogger (= 0.71.11) - React-jsi (0.71.11): - boost (= 1.76.0) - DoubleConversion - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-jsiexecutor (0.71.11): - DoubleConversion - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-cxxreact (= 0.71.11) - React-jsi (= 0.71.11) @@ -287,6 +320,7 @@ PODS: - React-Core - ReactCommon/turbomodule/core - React-RCTBlob (0.71.11): + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-Codegen (= 0.71.11) - React-Core/RCTBlobHeaders (= 0.71.11) @@ -334,6 +368,7 @@ PODS: - ReactCommon/turbomodule/bridging (0.71.11): - DoubleConversion - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-callinvoker (= 0.71.11) - React-Core (= 0.71.11) @@ -344,6 +379,7 @@ PODS: - ReactCommon/turbomodule/core (0.71.11): - DoubleConversion - glog + - hermes-engine - RCT-Folly (= 2021.07.22.00) - React-callinvoker (= 0.71.11) - React-Core (= 0.71.11) @@ -375,7 +411,6 @@ PODS: - React-Core/RCTWebSocket - React-CoreModules - React-cxxreact - - React-jsc - React-jsi - React-jsiexecutor - React-jsinspector @@ -414,6 +449,8 @@ DEPENDENCIES: - FBReactNativeSpec (from `../../../node_modules/react-native/React/FBReactNativeSpec`) - glog (from `../../../node_modules/react-native/third-party-podspecs/glog.podspec`) - Gutenberg (from `../../react-native-bridge`) + - hermes-engine (from `../../../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) + - libevent (~> 2.1.12) - RCT-Folly (from `../../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) - RCTRequired (from `../../../node_modules/react-native/Libraries/RCTRequired`) - RCTTypeSafety (from `../../../node_modules/react-native/Libraries/TypeSafety`) @@ -424,7 +461,7 @@ DEPENDENCIES: - React-Core/RCTWebSocket (from `../../../node_modules/react-native/`) - React-CoreModules (from `../../../node_modules/react-native/React/CoreModules`) - React-cxxreact (from `../../../node_modules/react-native/ReactCommon/cxxreact`) - - React-jsc (from `../../../node_modules/react-native/ReactCommon/jsc`) + - React-hermes (from `../../../node_modules/react-native/ReactCommon/hermes`) - React-jsi (from `../../../node_modules/react-native/ReactCommon/jsi`) - React-jsiexecutor (from `../../../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsinspector (from `../../../node_modules/react-native/ReactCommon/jsinspector`) @@ -462,6 +499,7 @@ DEPENDENCIES: SPEC REPOS: trunk: - fmt + - libevent - libwebp - SDWebImage - SDWebImageWebPCoder @@ -482,6 +520,8 @@ EXTERNAL SOURCES: :podspec: "../../../node_modules/react-native/third-party-podspecs/glog.podspec" Gutenberg: :path: "../../react-native-bridge" + hermes-engine: + :podspec: "../../../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" RCT-Folly: :podspec: "../../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTRequired: @@ -500,8 +540,8 @@ EXTERNAL SOURCES: :path: "../../../node_modules/react-native/React/CoreModules" React-cxxreact: :path: "../../../node_modules/react-native/ReactCommon/cxxreact" - React-jsc: - :path: "../../../node_modules/react-native/ReactCommon/jsc" + React-hermes: + :path: "../../../node_modules/react-native/ReactCommon/hermes" React-jsi: :path: "../../../node_modules/react-native/ReactCommon/jsi" React-jsiexecutor: @@ -578,19 +618,21 @@ SPEC CHECKSUMS: fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b Gutenberg: a79dedde03484f2766429558a85f6ff6c90e2513 + hermes-engine: 34c863b446d0135b85a6536fa5fd89f48196f848 + libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 libwebp: 60305b2e989864154bd9be3d772730f08fc6a59c RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 RCTRequired: f6187ec763637e6a57f5728dd9a3bdabc6d6b4e0 RCTTypeSafety: a01aca2dd3b27fa422d5239252ad38e54e958750 React: 741b4f5187e7a2137b69c88e65f940ba40600b4b React-callinvoker: 72ba74b2d5d690c497631191ae6eeca0c043d9cf - React-Codegen: 6a3870e906e80066a9b707389846c692a02415d9 - React-Core: 9cf97a2d0830a024deffebe873407f6717bbcc19 + React-Codegen: 8a7cda1633e4940de8a710f6bf5cae5dd673546e + React-Core: 72bb19702c465b6451a40501a2879532bec9acee React-CoreModules: ffd19b082fc36b9b463fedf30955138b5426c053 - React-cxxreact: f88c74ac51e59c294fbf825974d377fcf9641eba - React-jsc: 75bfda40ea4032b5018875355ab5ee089ac748bf - React-jsi: 71ae5726d2b0fd6b0aaa0845a9294739cf4c95c6 - React-jsiexecutor: 089cd07c76ecf498960a64ba8ae0f2dddd382f44 + React-cxxreact: 8b3dd87e3b8ea96dd4ad5c7bac8f31f1cc3da97f + React-hermes: be95942c3f47fc032da1387360413f00dae0ea68 + React-jsi: 9978e2a64c2a4371b40e109f4ef30a33deaa9bcb + React-jsiexecutor: 18b5b33c5f2687a784a61bc8176611b73524ae77 React-jsinspector: b6ed4cb3ffa27a041cd440300503dc512b761450 React-logger: 186dd536128ae5924bc38ed70932c00aa740cd5b react-native-blur: 3e9c8e8e9f7d17fa1b94e1a0ae9fd816675f5382 @@ -603,8 +645,8 @@ SPEC CHECKSUMS: React-perflogger: e706562ab7eb8eb590aa83a224d26fa13963d7f2 React-RCTActionSheet: 57d4bd98122f557479a3359ad5dad8e109e20c5a React-RCTAnimation: ccf3ef00101ea74bda73a045d79a658b36728a60 - React-RCTAppDelegate: de78bc79e1a469ffa275fbe3948356cea061c4bb - React-RCTBlob: 519c8ecb8ef83ce461a5670bdaf2fef882af3393 + React-RCTAppDelegate: d0c28a35c65e9a0aef287ac0dafe1b71b1ac180c + React-RCTBlob: 1700b92ece4357af0a49719c9638185ad2902e95 React-RCTImage: f2e4904566ccccaa4b704170fcc5ae144ca347bf React-RCTLinking: 52a3740e3651e30aa11dff5a6debed7395dd8169 React-RCTNetwork: ea0976f2b3ffc7877cd7784e351dc460adf87b12 @@ -612,12 +654,12 @@ SPEC CHECKSUMS: React-RCTText: c9dfc6722621d56332b4f3a19ac38105e7504145 React-RCTVibration: f09f08de63e4122deb32506e20ca4cae6e4e14c1 React-runtimeexecutor: 4817d63dbc9d658f8dc0ec56bd9b83ce531129f0 - ReactCommon: e2d70ebcd90a2eaab343fb0cc23bbdb5ac321f5c + ReactCommon: 864169d79e7fb2e846ad1257a2afd7ed846d6375 RNCClipboard: 3f0451a8100393908bea5c5c5b16f96d45f30bfc RNCMaskedView: 949696f25ec596bfc697fc88e6f95cf0c79669b6 RNFastImage: 1f2cab428712a4baaf78d6169eaec7f622556dd7 RNGestureHandler: f75d81410b40aaa99e71ae8f8bb7a88620c95042 - RNReanimated: df2567658c01135f9ff4709d372675bcb9fd1d83 + RNReanimated: d4f363f4987ae0ade3e36ff81c94e68261bf4b8d RNScreens: 68fd1060f57dd1023880bf4c05d74784b5392789 RNSVG: 53c661b76829783cdaf9b7a57258f3d3b4c28315 RNTAztecView: dfbe69cb1448f08b29846616fbb79d79f21968b3 @@ -626,6 +668,6 @@ SPEC CHECKSUMS: WordPress-Aztec-iOS: fbebd569c61baa252b3f5058c0a2a9a6ada686bb Yoga: f7decafdc5e8c125e6fa0da38a687e35238420fa -PODFILE CHECKSUM: 13786fe1bd037b8f06258137c3f1269a82608b59 +PODFILE CHECKSUM: 0965b30267e411f56545967f14da09df5daa07f4 COCOAPODS: 1.11.3 diff --git a/packages/react-native-editor/package.json b/packages/react-native-editor/package.json index 2d5235e41df9f..627cae16b549c 100644 --- a/packages/react-native-editor/package.json +++ b/packages/react-native-editor/package.json @@ -69,7 +69,7 @@ "react-native-sass-transformer": "^1.1.1", "react-native-screens": "3.22.0", "react-native-svg": "13.9.0", - "react-native-url-polyfill": "^1.1.2", + "react-native-url-polyfill": "1.3.0", "react-native-video": "https://raw.githubusercontent.com/wordpress-mobile/react-native-video/5.2.0-wp-6/react-native-video-5.2.0-wp-6.tgz", "react-native-webview": "11.26.1" }, @@ -87,7 +87,9 @@ "prebundle": "npm run i18n-cache:force", "bundle": "npm run bundle:android && npm run bundle:ios", "bundle:android": "mkdir -p bundle/android && npm run rn-bundle -- --platform android --dev false --entry-file index.js --assets-dest bundle/android --bundle-output bundle/android/App.text.js --sourcemap-output bundle/android/App.text.js.map && ./../../node_modules/react-native/sdks/hermesc/`node -e \"const platform=require('os').platform();console.log(platform === 'darwin' ? 'osx-bin' : (platform === 'linux' ? 'linux64-bin' : (platform === 'win32' ? 'win64-bin' : 'unsupported-os')));\"`/hermesc -emit-binary -O -out bundle/android/App.js bundle/android/App.text.js -output-source-map", - "bundle:ios": "mkdir -p bundle/ios && npm run rn-bundle -- --platform ios --dev false --entry-file index.js --assets-dest bundle/ios --bundle-output bundle/ios/App.js --sourcemap-output bundle/ios/App.js.map", + "bundle:ios": "npm run bundle:ios:text && npm run bundle:ios:bytecode", + "bundle:ios:text": "mkdir -p bundle/ios && npm run rn-bundle -- --platform ios --dev false --minify false --entry-file ./index.js --assets-dest bundle/ios --bundle-output ./bundle/ios/App.text.js --sourcemap-output ./bundle/ios/App.text.js.map", + "bundle:ios:bytecode": "./../../node_modules/react-native/sdks/hermesc/`node -e \"const platform=require('os').platform();console.log(platform === 'darwin' ? 'osx-bin' : (platform === 'linux' ? 'linux64-bin' : (platform === 'win32' ? 'win64-bin' : 'unsupported-os')));\"`/hermesc -emit-binary -O -out bundle/ios/App.js bundle/ios/App.text.js -output-source-map", "i18n-cache": "node i18n-cache/index.js", "i18n-cache:force": "cross-env REFRESH_I18N_CACHE=1 node i18n-cache/index.js", "i18n:extract-used-strings": "node bin/extract-used-strings", @@ -110,7 +112,7 @@ "test:e2e:bundle:android": "mkdir -p android/app/src/main/assets && npm run rn-bundle -- --reset-cache --platform android --dev false --minify false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res", "test:e2e:build-app:android": "cd android && ./gradlew clean && ./gradlew assembleDebug", "test:e2e:android:local": "npm run test:e2e:bundle:android && npm run test:e2e:build-app:android && TEST_RN_PLATFORM=android npm run device-tests:local", - "test:e2e:bundle:ios": "mkdir -p ios/build/GutenbergDemo/Build/Products/Release-iphonesimulator/GutenbergDemo.app && npm run rn-bundle -- --reset-cache --platform=ios --dev=false --minify false --entry-file=index.js --bundle-output=./ios/build/GutenbergDemo/Build/Products/Release-iphonesimulator/GutenbergDemo.app/main.jsbundle --assets-dest=./ios/build/GutenbergDemo/Build/Products/Release-iphonesimulator/GutenbergDemo.app", + "test:e2e:bundle:ios": "mkdir -p ios/build/GutenbergDemo/Build/Products/Release-iphonesimulator/GutenbergDemo.app && npm run bundle:ios && cp bundle/ios/App.js ./ios/build/GutenbergDemo/Build/Products/Release-iphonesimulator/GutenbergDemo.app/main.jsbundle && cp -r bundle/ios/assets ./ios/build/GutenbergDemo/Build/Products/Release-iphonesimulator/GutenbergDemo.app/", "test:e2e:build-app:ios": "npm run preios && ./bin/build_e2e_ios_app", "test:e2e:build-wda": "xcodebuild -project ../../node_modules/appium/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ios/build/WDA", "test:e2e:ios:local": "npm run test:e2e:bundle:ios && npm run test:e2e:build-app:ios && npm run test:e2e:build-wda && TEST_RN_PLATFORM=ios npm run device-tests:local", diff --git a/patches/react-native-reanimated+2.17.0.patch b/patches/react-native-reanimated+2.17.0.patch deleted file mode 100644 index 8d4d634ea1374..0000000000000 --- a/patches/react-native-reanimated+2.17.0.patch +++ /dev/null @@ -1,14 +0,0 @@ -This patch will be removed when the Gutenberg demo app uses Hermes. - -diff --git a/node_modules/react-native-reanimated/RNReanimated.podspec b/node_modules/react-native-reanimated/RNReanimated.podspec -index 1cbeafc..34f49db 100644 ---- a/node_modules/react-native-reanimated/RNReanimated.podspec -+++ b/node_modules/react-native-reanimated/RNReanimated.podspec -@@ -80,6 +80,7 @@ Pod::Spec.new do |s| - s.dependency 'Yoga' - s.dependency 'DoubleConversion' - s.dependency 'glog' -+ s.dependency 'React-jsc' - - if config[:react_native_minor_version] == 62 - s.dependency 'ReactCommon/callinvoker' From 20843c09aef884e2b8a92b7121e4e03d6ed7d19f Mon Sep 17 00:00:00 2001 From: Marin Atanasov <8436925+tyxla@users.noreply.github.com> Date: Thu, 28 Sep 2023 15:46:05 +0300 Subject: [PATCH 06/23] Block Editor: Expose getDuotoneFilter() as private API (#54905) --- packages/block-editor/src/private-apis.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/block-editor/src/private-apis.js b/packages/block-editor/src/private-apis.js index e6c80a731e180..fe16d791dc7c5 100644 --- a/packages/block-editor/src/private-apis.js +++ b/packages/block-editor/src/private-apis.js @@ -24,6 +24,7 @@ import { } from './components/inserter/reusable-block-rename-hint'; import { usesContextKey } from './components/rich-text/format-edit'; import { ExperimentalBlockCanvas } from './components/block-canvas'; +import { getDuotoneFilter } from './components/duotone/utils'; /** * Private @wordpress/block-editor APIs. @@ -33,6 +34,7 @@ lock( privateApis, { ...globalStyles, ExperimentalBlockCanvas, ExperimentalBlockEditorProvider, + getDuotoneFilter, getRichTextValues, kebabCase, PrivateInserter, From 744a23048340c119a27476999501cbe042faae73 Mon Sep 17 00:00:00 2001 From: Marin Atanasov <8436925+tyxla@users.noreply.github.com> Date: Thu, 28 Sep 2023 16:35:29 +0300 Subject: [PATCH 07/23] ESLint: Update eslint-plugin-testing-library to v6 (#54910) --- package-lock.json | 18 +++++++++--------- package.json | 2 +- packages/block-library/src/cover/test/edit.js | 2 +- .../src/combobox-control/test/index.tsx | 13 ++++++------- .../src/external-link/test/index.tsx | 10 ++++------ .../components/src/input-control/test/index.js | 12 +++++------- .../src/select-control/test/select-control.tsx | 6 ++---- .../plugins/src/components/test/plugin-area.js | 1 + 8 files changed, 29 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index 56d80e9f75776..f40f805940461 100644 --- a/package-lock.json +++ b/package-lock.json @@ -186,7 +186,7 @@ "eslint-plugin-prettier": "5.0.0", "eslint-plugin-ssr-friendly": "1.0.6", "eslint-plugin-storybook": "0.6.13", - "eslint-plugin-testing-library": "5.7.2", + "eslint-plugin-testing-library": "6.0.2", "execa": "4.0.2", "fast-glob": "3.2.7", "filenamify": "4.2.0", @@ -29940,12 +29940,12 @@ } }, "node_modules/eslint-plugin-testing-library": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.7.2.tgz", - "integrity": "sha512-0ZmHeR/DUUgEzW8rwUBRWxuqntipDtpvxK0hymdHnLlABryJkzd+CAHr+XnISaVsTisZ5MLHp6nQF+8COHLLTA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-6.0.2.tgz", + "integrity": "sha512-3BV6FWtLbpKFb4Y1obSdt8PC9xSqz6T+7EHB/6pSCXqVjKPoS67ck903feKMKQphd5VhrX+N51yHuVaPa7elsw==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^5.13.0" + "@typescript-eslint/utils": "^5.58.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0", @@ -83265,12 +83265,12 @@ } }, "eslint-plugin-testing-library": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.7.2.tgz", - "integrity": "sha512-0ZmHeR/DUUgEzW8rwUBRWxuqntipDtpvxK0hymdHnLlABryJkzd+CAHr+XnISaVsTisZ5MLHp6nQF+8COHLLTA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-6.0.2.tgz", + "integrity": "sha512-3BV6FWtLbpKFb4Y1obSdt8PC9xSqz6T+7EHB/6pSCXqVjKPoS67ck903feKMKQphd5VhrX+N51yHuVaPa7elsw==", "dev": true, "requires": { - "@typescript-eslint/utils": "^5.13.0" + "@typescript-eslint/utils": "^5.58.0" } }, "eslint-scope": { diff --git a/package.json b/package.json index 02fe8c3843ba4..b5eee1c26704c 100644 --- a/package.json +++ b/package.json @@ -198,7 +198,7 @@ "eslint-plugin-prettier": "5.0.0", "eslint-plugin-ssr-friendly": "1.0.6", "eslint-plugin-storybook": "0.6.13", - "eslint-plugin-testing-library": "5.7.2", + "eslint-plugin-testing-library": "6.0.2", "execa": "4.0.2", "fast-glob": "3.2.7", "filenamify": "4.2.0", diff --git a/packages/block-library/src/cover/test/edit.js b/packages/block-library/src/cover/test/edit.js index 8a391baa5f01d..d1febe3c6fa11 100644 --- a/packages/block-library/src/cover/test/edit.js +++ b/packages/block-library/src/cover/test/edit.js @@ -260,7 +260,7 @@ describe( 'Cover block', () => { } ) ); expect( - within( screen.queryByLabelText( 'Block: Cover' ) ).queryByRole( + within( screen.getByLabelText( 'Block: Cover' ) ).queryByRole( 'img' ) ).not.toBeInTheDocument(); diff --git a/packages/components/src/combobox-control/test/index.tsx b/packages/components/src/combobox-control/test/index.tsx index 0f1a25c251366..c26d8ab5afeb9 100644 --- a/packages/components/src/combobox-control/test/index.tsx +++ b/packages/components/src/combobox-control/test/index.tsx @@ -56,7 +56,6 @@ const getOption = ( name: string ) => screen.getByRole( 'option', { name } ); const getAllOptions = () => screen.getAllByRole( 'option' ); const getOptionSearchString = ( option: ComboboxControlOption ) => option.label.substring( 0, 11 ); -const setupUser = () => userEvent.setup(); const ControlledComboboxControl = ( { value: valueProp, @@ -112,7 +111,7 @@ describe.each( [ } ); it( 'should render with the correct options', async () => { - const user = setupUser(); + const user = await userEvent.setup(); render( ); @@ -133,7 +132,7 @@ describe.each( [ } ); it( 'should select the correct option via click events', async () => { - const user = setupUser(); + const user = await userEvent.setup(); const targetOption = timezones[ 2 ]; const onChangeSpy = jest.fn(); render( @@ -157,7 +156,7 @@ describe.each( [ } ); it( 'should select the correct option via keypress events', async () => { - const user = setupUser(); + const user = await userEvent.setup(); const targetIndex = 4; const targetOption = timezones[ targetIndex ]; const onChangeSpy = jest.fn(); @@ -187,7 +186,7 @@ describe.each( [ } ); it( 'should select the correct option from a search', async () => { - const user = setupUser(); + const user = await userEvent.setup(); const targetOption = timezones[ 13 ]; const onChangeSpy = jest.fn(); render( @@ -214,7 +213,7 @@ describe.each( [ } ); it( 'should render aria-live announcement upon selection', async () => { - const user = setupUser(); + const user = await userEvent.setup(); const targetOption = timezones[ 9 ]; const onChangeSpy = jest.fn(); render( @@ -242,7 +241,7 @@ describe.each( [ } ); it( 'should process multiple entries in a single session', async () => { - const user = setupUser(); + const user = await userEvent.setup(); const unmatchedString = 'Mordor'; const targetOption = timezones[ 6 ]; const onChangeSpy = jest.fn(); diff --git a/packages/components/src/external-link/test/index.tsx b/packages/components/src/external-link/test/index.tsx index 810874577231d..18fc0104270b0 100644 --- a/packages/components/src/external-link/test/index.tsx +++ b/packages/components/src/external-link/test/index.tsx @@ -9,11 +9,9 @@ import userEvent from '@testing-library/user-event'; */ import { ExternalLink } from '..'; -const setupUser = () => userEvent.setup(); - describe( 'ExternalLink', () => { test( 'should call function passed in onClick handler when clicking the link', async () => { - const user = setupUser(); + const user = await userEvent.setup(); const onClickMock = jest.fn(); render( @@ -32,7 +30,7 @@ describe( 'ExternalLink', () => { } ); test( 'should prevent default action when clicking an internal anchor link without passing onClick prop', async () => { - const user = setupUser(); + const user = await userEvent.setup(); render( I'm an anchor link! @@ -55,7 +53,7 @@ describe( 'ExternalLink', () => { } ); test( 'should call function passed in onClick handler and prevent default action when clicking an internal anchor link', async () => { - const user = setupUser(); + const user = await userEvent.setup(); const onClickMock = jest.fn(); render( @@ -76,7 +74,7 @@ describe( 'ExternalLink', () => { } ); test( 'should not prevent default action when clicking a non anchor link without passing onClick prop', async () => { - const user = setupUser(); + const user = await userEvent.setup(); render( diff --git a/packages/components/src/input-control/test/index.js b/packages/components/src/input-control/test/index.js index f93fe9f091528..1ca2860442bd9 100644 --- a/packages/components/src/input-control/test/index.js +++ b/packages/components/src/input-control/test/index.js @@ -14,8 +14,6 @@ import { useState } from '@wordpress/element'; */ import BaseInputControl from '../'; -const setupUser = () => userEvent.setup(); - const getInput = () => screen.getByTestId( 'input' ); describe( 'InputControl', () => { @@ -70,7 +68,7 @@ describe( 'InputControl', () => { describe( 'Ensurance of focus for number inputs', () => { it( 'should focus its input on mousedown events', async () => { - const user = setupUser(); + const user = await userEvent.setup(); const spy = jest.fn(); render( ); const target = getInput(); @@ -87,7 +85,7 @@ describe( 'InputControl', () => { describe( 'Value', () => { it( 'should update value onChange', async () => { - const user = setupUser(); + const user = await userEvent.setup(); const spy = jest.fn(); render( spy( v ) } /> @@ -102,7 +100,7 @@ describe( 'InputControl', () => { } ); it( 'should work as a controlled component given normal, falsy or nullish values', async () => { - const user = setupUser(); + const user = await userEvent.setup(); const spy = jest.fn(); const heldKeySet = new Set(); const Example = () => { @@ -173,7 +171,7 @@ describe( 'InputControl', () => { } ); it( 'should not commit value until blurred when isPressEnterToChange is true', async () => { - const user = setupUser(); + const user = await userEvent.setup(); const spy = jest.fn(); render( { } ); it( 'should commit value when blurred if value is invalid', async () => { - const user = setupUser(); + const user = await userEvent.setup(); const spyChange = jest.fn(); render( userEvent.setup(); - describe( 'SelectControl', () => { it( 'should not render when no options or children are provided', () => { render( ); @@ -20,7 +18,7 @@ describe( 'SelectControl', () => { } ); it( 'should not render its children', async () => { - const user = setupUser(); + const user = await userEvent.setup(); const handleChangeMock = jest.fn(); render( @@ -49,7 +47,7 @@ describe( 'SelectControl', () => { } ); it( 'should not render its options', async () => { - const user = setupUser(); + const user = await userEvent.setup(); const handleChangeMock = jest.fn(); render( diff --git a/packages/plugins/src/components/test/plugin-area.js b/packages/plugins/src/components/test/plugin-area.js index 42ea556081ae2..b566b48795887 100644 --- a/packages/plugins/src/components/test/plugin-area.js +++ b/packages/plugins/src/components/test/plugin-area.js @@ -1,6 +1,7 @@ /** * External dependencies */ +// eslint-disable-next-line testing-library/no-manual-cleanup import { act, render, cleanup } from '@testing-library/react'; /** From 1ae60e757a6f8160de0b83490bcca023eb9a307b Mon Sep 17 00:00:00 2001 From: Hiroshi Urabe Date: Thu, 28 Sep 2023 22:40:29 +0900 Subject: [PATCH 08/23] SlotFill: Migrate to Typescript. (#51350) * convert typescript slot-fill-context.ts and slot-fill-provider.tsx * fix portalContainer type. * convert hooks to ts. * fix types * fix fillProps * convert slot.tsx * update Fill * fix typename. * fix dropdown v2 portal container type. * fix ref type * refactor * refactor SlotFillProvider * migrate SlotComponent to TS * convert useSlot * add update * fix ProviderProps * refactor type * refactor type * allow symbol to name prop. * refactor SlotComponentProps * refactor stroies and README * fix typo * remove comments. remove children from Slot. * refactor SlotComponentProps * Apply suggestions from code review Co-authored-by: Lena Morita * Apply suggestions from code review Co-authored-by: Lena Morita * refactor: newChildren to inline. * Remove unnecessary type variables. * fix type comments * Remove unnecessary Type Guards. Remove unnecessary Type Guards. And use `React.Key`. * remove type from jsdoc * refactor types * refactor types * Simplify the type of `slot`. * Remove the type specification and leave it to type inference. * fix types * remove story.js * update changelog * remove ts-nocheck * fix story filename. remove override bubblesVirtually attribute * replace useState to useMemo * switch to ts-expect-error in story. * fix mssing changelog https://github.com/WordPress/gutenberg/pull/53272/files/362b6d4405edd476df1f6479bb264dc9f51d6789#r1319926144 * add `children?: never` https://github.com/WordPress/gutenberg/pull/51350#discussion_r1320548263 * use Record * use Record / Enable className only when bubblesVirtually: true. * Update packages/components/src/slot-fill/types.ts Co-authored-by: Marco Ciampini * update changelog * use optional chain * fix WordPressComponentProps import --------- Co-authored-by: Lena Morita Co-authored-by: Marco Ciampini --- packages/components/CHANGELOG.md | 3 + .../components/src/dropdown-menu-v2/types.ts | 2 +- packages/components/src/popover/index.tsx | 1 - .../bubbles-virtually/{fill.js => fill.tsx} | 13 +- ...t-fill-context.js => slot-fill-context.ts} | 11 +- .../bubbles-virtually/slot-fill-provider.js | 95 ----------- .../bubbles-virtually/slot-fill-provider.tsx | 115 +++++++++++++ .../bubbles-virtually/{slot.js => slot.tsx} | 19 ++- .../{use-slot-fills.js => use-slot-fills.ts} | 4 +- .../{use-slot.js => use-slot.ts} | 21 ++- packages/components/src/slot-fill/context.js | 17 -- packages/components/src/slot-fill/context.ts | 21 +++ .../src/slot-fill/{fill.js => fill.ts} | 5 +- .../src/slot-fill/{index.js => index.tsx} | 50 ++++-- packages/components/src/slot-fill/provider.js | 119 -------------- .../components/src/slot-fill/provider.tsx | 129 +++++++++++++++ .../src/slot-fill/{slot.js => slot.tsx} | 42 +++-- .../src/slot-fill/stories/index.story.js | 89 ---------- .../src/slot-fill/stories/index.story.tsx | 140 ++++++++++++++++ packages/components/src/slot-fill/types.ts | 155 ++++++++++++++++++ .../slot-fill/{use-slot.js => use-slot.ts} | 8 +- 21 files changed, 682 insertions(+), 377 deletions(-) rename packages/components/src/slot-fill/bubbles-virtually/{fill.js => fill.tsx} (86%) rename packages/components/src/slot-fill/bubbles-virtually/{slot-fill-context.js => slot-fill-context.ts} (74%) delete mode 100644 packages/components/src/slot-fill/bubbles-virtually/slot-fill-provider.js create mode 100644 packages/components/src/slot-fill/bubbles-virtually/slot-fill-provider.tsx rename packages/components/src/slot-fill/bubbles-virtually/{slot.js => slot.tsx} (78%) rename packages/components/src/slot-fill/bubbles-virtually/{use-slot-fills.js => use-slot-fills.ts} (84%) rename packages/components/src/slot-fill/bubbles-virtually/{use-slot.js => use-slot.ts} (54%) delete mode 100644 packages/components/src/slot-fill/context.js create mode 100644 packages/components/src/slot-fill/context.ts rename packages/components/src/slot-fill/{fill.js => fill.ts} (93%) rename packages/components/src/slot-fill/{index.js => index.tsx} (58%) delete mode 100644 packages/components/src/slot-fill/provider.js create mode 100644 packages/components/src/slot-fill/provider.tsx rename packages/components/src/slot-fill/{slot.js => slot.tsx} (66%) delete mode 100644 packages/components/src/slot-fill/stories/index.story.js create mode 100644 packages/components/src/slot-fill/stories/index.story.tsx create mode 100644 packages/components/src/slot-fill/types.ts rename packages/components/src/slot-fill/{use-slot.js => use-slot.ts} (77%) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 39c6c6afc42d5..5f9f5de9327cd 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -22,6 +22,8 @@ - Refactor ariakit usages to use the `render` prop instead of `as` and to use the namespace import ([#54696](https://github.com/WordPress/gutenberg/pull/54696)). - Update `uuid` package to 9.0.1 ([#54725](https://github.com/WordPress/gutenberg/pull/54725)). - `ContextSystemProvider`: Move out of `ui/` ([#54847](https://github.com/WordPress/gutenberg/pull/54847)). +- `SlotFill`: Migrate to TypeScript and Convert to Functional Component ``. ([#51350](https://github.com/WordPress/gutenberg/pull/51350)). + ## 25.8.0 (2023-09-20) @@ -135,6 +137,7 @@ - `ColorPalette`, `BorderControl`: Don't hyphenate hex value in `aria-label` ([#52932](https://github.com/WordPress/gutenberg/pull/52932)). - `MenuItemsChoice`, `MenuItem`: Support a `disabled` prop on a menu item ([#52737](https://github.com/WordPress/gutenberg/pull/52737)). +- `TabPanel`: Introduce a new version of `TabPanel` with updated internals and improved adherence to ARIA guidance on `tabpanel` focus behavior while maintaining the same functionality and API surface.([#52133](https://github.com/WordPress/gutenberg/pull/52133)). ### Bug Fix diff --git a/packages/components/src/dropdown-menu-v2/types.ts b/packages/components/src/dropdown-menu-v2/types.ts index 5c7d6469b656c..c06bb5aac626a 100644 --- a/packages/components/src/dropdown-menu-v2/types.ts +++ b/packages/components/src/dropdown-menu-v2/types.ts @@ -261,5 +261,5 @@ export type DropdownMenuPrivateContext = Pick< DropdownMenuInternalContext, 'variant' > & { - portalContainer: HTMLElement | null; + portalContainer?: HTMLElement | null; }; diff --git a/packages/components/src/popover/index.tsx b/packages/components/src/popover/index.tsx index 3dc450e9bcb14..19e0daeb79d12 100644 --- a/packages/components/src/popover/index.tsx +++ b/packages/components/src/popover/index.tsx @@ -493,7 +493,6 @@ function PopoverSlot( ) { return ( - { children } + { typeof children === 'function' + ? children( slot.fillProps ?? {} ) + : children } ); diff --git a/packages/components/src/slot-fill/bubbles-virtually/slot-fill-context.js b/packages/components/src/slot-fill/bubbles-virtually/slot-fill-context.ts similarity index 74% rename from packages/components/src/slot-fill/bubbles-virtually/slot-fill-context.js rename to packages/components/src/slot-fill/bubbles-virtually/slot-fill-context.ts index e3c6652f22e94..7c0ef340e53fe 100644 --- a/packages/components/src/slot-fill/bubbles-virtually/slot-fill-context.js +++ b/packages/components/src/slot-fill/bubbles-virtually/slot-fill-context.ts @@ -1,4 +1,3 @@ -// @ts-nocheck /** * External dependencies */ @@ -8,8 +7,12 @@ import { proxyMap } from 'valtio/utils'; */ import { createContext } from '@wordpress/element'; import warning from '@wordpress/warning'; +/** + * Internal dependencies + */ +import type { SlotFillBubblesVirtuallyContext } from '../types'; -const SlotFillContext = createContext( { +const initialContextValue: SlotFillBubblesVirtuallyContext = { slots: proxyMap(), fills: proxyMap(), registerSlot: () => { @@ -25,6 +28,8 @@ const SlotFillContext = createContext( { // This helps the provider know if it's using the default context value or not. isDefault: true, -} ); +}; + +const SlotFillContext = createContext( initialContextValue ); export default SlotFillContext; diff --git a/packages/components/src/slot-fill/bubbles-virtually/slot-fill-provider.js b/packages/components/src/slot-fill/bubbles-virtually/slot-fill-provider.js deleted file mode 100644 index 9a00a90a7c835..0000000000000 --- a/packages/components/src/slot-fill/bubbles-virtually/slot-fill-provider.js +++ /dev/null @@ -1,95 +0,0 @@ -// @ts-nocheck -/** - * External dependencies - */ -import { ref as valRef } from 'valtio'; -import { proxyMap } from 'valtio/utils'; - -/** - * WordPress dependencies - */ -import { useState } from '@wordpress/element'; -import isShallowEqual from '@wordpress/is-shallow-equal'; - -/** - * Internal dependencies - */ -import SlotFillContext from './slot-fill-context'; - -function createSlotRegistry() { - const slots = proxyMap(); - const fills = proxyMap(); - - function registerSlot( name, ref, fillProps ) { - const slot = slots.get( name ) || {}; - slots.set( - name, - valRef( { - ...slot, - ref: ref || slot.ref, - fillProps: fillProps || slot.fillProps || {}, - } ) - ); - } - - function unregisterSlot( name, ref ) { - // Make sure we're not unregistering a slot registered by another element - // See https://github.com/WordPress/gutenberg/pull/19242#issuecomment-590295412 - if ( slots.get( name )?.ref === ref ) { - slots.delete( name ); - } - } - - function updateSlot( name, fillProps ) { - const slot = slots.get( name ); - if ( ! slot ) { - return; - } - - if ( isShallowEqual( slot.fillProps, fillProps ) ) { - return; - } - - slot.fillProps = fillProps; - const slotFills = fills.get( name ); - if ( slotFills ) { - // Force update fills. - slotFills.map( ( fill ) => fill.current.rerender() ); - } - } - - function registerFill( name, ref ) { - fills.set( name, valRef( [ ...( fills.get( name ) || [] ), ref ] ) ); - } - - function unregisterFill( name, ref ) { - const fillsForName = fills.get( name ); - if ( ! fillsForName ) { - return; - } - - fills.set( - name, - valRef( fillsForName.filter( ( fillRef ) => fillRef !== ref ) ) - ); - } - - return { - slots, - fills, - registerSlot, - updateSlot, - unregisterSlot, - registerFill, - unregisterFill, - }; -} - -export default function SlotFillProvider( { children } ) { - const [ registry ] = useState( createSlotRegistry ); - return ( - - { children } - - ); -} diff --git a/packages/components/src/slot-fill/bubbles-virtually/slot-fill-provider.tsx b/packages/components/src/slot-fill/bubbles-virtually/slot-fill-provider.tsx new file mode 100644 index 0000000000000..f98ac36c4a2bd --- /dev/null +++ b/packages/components/src/slot-fill/bubbles-virtually/slot-fill-provider.tsx @@ -0,0 +1,115 @@ +/** + * External dependencies + */ +import { ref as valRef } from 'valtio'; +import { proxyMap } from 'valtio/utils'; + +/** + * WordPress dependencies + */ +import { useMemo } from '@wordpress/element'; +import isShallowEqual from '@wordpress/is-shallow-equal'; + +/** + * Internal dependencies + */ +import SlotFillContext from './slot-fill-context'; +import type { + SlotFillProviderProps, + SlotFillBubblesVirtuallyContext, +} from '../types'; + +function createSlotRegistry(): SlotFillBubblesVirtuallyContext { + const slots: SlotFillBubblesVirtuallyContext[ 'slots' ] = proxyMap(); + const fills: SlotFillBubblesVirtuallyContext[ 'fills' ] = proxyMap(); + + const registerSlot: SlotFillBubblesVirtuallyContext[ 'registerSlot' ] = ( + name, + ref, + fillProps + ) => { + const slot = slots.get( name ); + + slots.set( + name, + valRef( { + ...slot, + ref: ref || slot?.ref, + fillProps: fillProps || slot?.fillProps || {}, + } ) + ); + }; + + const unregisterSlot: SlotFillBubblesVirtuallyContext[ 'unregisterSlot' ] = + ( name, ref ) => { + // Make sure we're not unregistering a slot registered by another element + // See https://github.com/WordPress/gutenberg/pull/19242#issuecomment-590295412 + if ( slots.get( name )?.ref === ref ) { + slots.delete( name ); + } + }; + + const updateSlot: SlotFillBubblesVirtuallyContext[ 'updateSlot' ] = ( + name, + fillProps + ) => { + const slot = slots.get( name ); + if ( ! slot ) { + return; + } + + if ( isShallowEqual( slot.fillProps, fillProps ) ) { + return; + } + + slot.fillProps = fillProps; + const slotFills = fills.get( name ); + if ( slotFills ) { + // Force update fills. + slotFills.map( ( fill ) => fill.current.rerender() ); + } + }; + + const registerFill: SlotFillBubblesVirtuallyContext[ 'registerFill' ] = ( + name, + ref + ) => { + fills.set( name, valRef( [ ...( fills.get( name ) || [] ), ref ] ) ); + }; + + const unregisterFill: SlotFillBubblesVirtuallyContext[ 'registerFill' ] = ( + name, + ref + ) => { + const fillsForName = fills.get( name ); + if ( ! fillsForName ) { + return; + } + + fills.set( + name, + valRef( fillsForName.filter( ( fillRef ) => fillRef !== ref ) ) + ); + }; + + return { + slots, + fills, + registerSlot, + updateSlot, + unregisterSlot, + registerFill, + unregisterFill, + }; +} + +export default function SlotFillProvider( { + children, +}: SlotFillProviderProps ) { + const registry = useMemo( createSlotRegistry, [] ); + return ( + + { children } + + ); +} diff --git a/packages/components/src/slot-fill/bubbles-virtually/slot.js b/packages/components/src/slot-fill/bubbles-virtually/slot.tsx similarity index 78% rename from packages/components/src/slot-fill/bubbles-virtually/slot.js rename to packages/components/src/slot-fill/bubbles-virtually/slot.tsx index be6fde0c8e6b7..e836782c90615 100644 --- a/packages/components/src/slot-fill/bubbles-virtually/slot.js +++ b/packages/components/src/slot-fill/bubbles-virtually/slot.tsx @@ -1,4 +1,8 @@ -// @ts-nocheck +/** + * External dependencies + */ +import type { ForwardedRef } from 'react'; + /** * WordPress dependencies */ @@ -15,21 +19,30 @@ import { useMergeRefs } from '@wordpress/compose'; */ import { View } from '../../view'; import SlotFillContext from './slot-fill-context'; +import type { WordPressComponentProps } from '../../context'; +import type { SlotComponentProps } from '../types'; -function Slot( props, forwardedRef ) { +function Slot( + props: WordPressComponentProps< + Omit< SlotComponentProps, 'bubblesVirtually' >, + 'div' + >, + forwardedRef: ForwardedRef< any > +) { const { name, fillProps = {}, as, // `children` is not allowed. However, if it is passed, // it will be displayed as is, so remove `children`. + // @ts-ignore children, ...restProps } = props; const { registerSlot, unregisterSlot, ...registry } = useContext( SlotFillContext ); - const ref = useRef(); + const ref = useRef< HTMLElement >( null ); useLayoutEffect( () => { registerSlot( name, ref, fillProps ); diff --git a/packages/components/src/slot-fill/bubbles-virtually/use-slot-fills.js b/packages/components/src/slot-fill/bubbles-virtually/use-slot-fills.ts similarity index 84% rename from packages/components/src/slot-fill/bubbles-virtually/use-slot-fills.js rename to packages/components/src/slot-fill/bubbles-virtually/use-slot-fills.ts index 29e4380ed3d43..599f0bc566771 100644 --- a/packages/components/src/slot-fill/bubbles-virtually/use-slot-fills.js +++ b/packages/components/src/slot-fill/bubbles-virtually/use-slot-fills.ts @@ -1,4 +1,3 @@ -// @ts-nocheck /** * External dependencies */ @@ -13,8 +12,9 @@ import { useContext } from '@wordpress/element'; * Internal dependencies */ import SlotFillContext from './slot-fill-context'; +import type { SlotKey } from '../types'; -export default function useSlotFills( name ) { +export default function useSlotFills( name: SlotKey ) { const registry = useContext( SlotFillContext ); const fills = useSnapshot( registry.fills, { sync: true } ); // The important bit here is that this call ensures that the hook diff --git a/packages/components/src/slot-fill/bubbles-virtually/use-slot.js b/packages/components/src/slot-fill/bubbles-virtually/use-slot.ts similarity index 54% rename from packages/components/src/slot-fill/bubbles-virtually/use-slot.js rename to packages/components/src/slot-fill/bubbles-virtually/use-slot.ts index 20b00c2cdf264..c039a36946991 100644 --- a/packages/components/src/slot-fill/bubbles-virtually/use-slot.js +++ b/packages/components/src/slot-fill/bubbles-virtually/use-slot.ts @@ -1,4 +1,3 @@ -// @ts-nocheck /** * External dependencies */ @@ -13,8 +12,14 @@ import { useMemo, useContext } from '@wordpress/element'; * Internal dependencies */ import SlotFillContext from './slot-fill-context'; +import type { + SlotFillBubblesVirtuallyFillRef, + SlotFillBubblesVirtuallySlotRef, + FillProps, + SlotKey, +} from '../types'; -export default function useSlot( name ) { +export default function useSlot( name: SlotKey ) { const registry = useContext( SlotFillContext ); const slots = useSnapshot( registry.slots, { sync: true } ); // The important bit here is that the `useSnapshot` call ensures that the @@ -24,10 +29,14 @@ export default function useSlot( name ) { const api = useMemo( () => ( { - updateSlot: ( fillProps ) => registry.updateSlot( name, fillProps ), - unregisterSlot: ( ref ) => registry.unregisterSlot( name, ref ), - registerFill: ( ref ) => registry.registerFill( name, ref ), - unregisterFill: ( ref ) => registry.unregisterFill( name, ref ), + updateSlot: ( fillProps: FillProps ) => + registry.updateSlot( name, fillProps ), + unregisterSlot: ( ref: SlotFillBubblesVirtuallySlotRef ) => + registry.unregisterSlot( name, ref ), + registerFill: ( ref: SlotFillBubblesVirtuallyFillRef ) => + registry.registerFill( name, ref ), + unregisterFill: ( ref: SlotFillBubblesVirtuallyFillRef ) => + registry.unregisterFill( name, ref ), } ), [ name, registry ] ); diff --git a/packages/components/src/slot-fill/context.js b/packages/components/src/slot-fill/context.js deleted file mode 100644 index 0f7961a8ffd3b..0000000000000 --- a/packages/components/src/slot-fill/context.js +++ /dev/null @@ -1,17 +0,0 @@ -// @ts-nocheck -/** - * WordPress dependencies - */ -import { createContext } from '@wordpress/element'; - -export const SlotFillContext = createContext( { - registerSlot: () => {}, - unregisterSlot: () => {}, - registerFill: () => {}, - unregisterFill: () => {}, - getSlot: () => {}, - getFills: () => {}, - subscribe: () => {}, -} ); - -export default SlotFillContext; diff --git a/packages/components/src/slot-fill/context.ts b/packages/components/src/slot-fill/context.ts new file mode 100644 index 0000000000000..c4839462fbce0 --- /dev/null +++ b/packages/components/src/slot-fill/context.ts @@ -0,0 +1,21 @@ +/** + * WordPress dependencies + */ +import { createContext } from '@wordpress/element'; +/** + * Internal dependencies + */ +import type { BaseSlotFillContext } from './types'; + +const initialValue: BaseSlotFillContext = { + registerSlot: () => {}, + unregisterSlot: () => {}, + registerFill: () => {}, + unregisterFill: () => {}, + getSlot: () => undefined, + getFills: () => [], + subscribe: () => () => {}, +}; +export const SlotFillContext = createContext( initialValue ); + +export default SlotFillContext; diff --git a/packages/components/src/slot-fill/fill.js b/packages/components/src/slot-fill/fill.ts similarity index 93% rename from packages/components/src/slot-fill/fill.js rename to packages/components/src/slot-fill/fill.ts index e7ff943df07bf..6aefacc4ff6f1 100644 --- a/packages/components/src/slot-fill/fill.js +++ b/packages/components/src/slot-fill/fill.ts @@ -1,5 +1,3 @@ -// @ts-nocheck - /** * WordPress dependencies */ @@ -10,8 +8,9 @@ import { useContext, useLayoutEffect, useRef } from '@wordpress/element'; */ import SlotFillContext from './context'; import useSlot from './use-slot'; +import type { FillComponentProps } from './types'; -export default function Fill( { name, children } ) { +export default function Fill( { name, children }: FillComponentProps ) { const { registerFill, unregisterFill } = useContext( SlotFillContext ); const slot = useSlot( name ); diff --git a/packages/components/src/slot-fill/index.js b/packages/components/src/slot-fill/index.tsx similarity index 58% rename from packages/components/src/slot-fill/index.js rename to packages/components/src/slot-fill/index.tsx index 34216fd347c05..fb1a08bc2207f 100644 --- a/packages/components/src/slot-fill/index.js +++ b/packages/components/src/slot-fill/index.tsx @@ -1,4 +1,8 @@ -// @ts-nocheck +/** + * External dependencies + */ +import type { ForwardedRef } from 'react'; + /** * WordPress dependencies */ @@ -14,10 +18,19 @@ import BubblesVirtuallySlot from './bubbles-virtually/slot'; import BubblesVirtuallySlotFillProvider from './bubbles-virtually/slot-fill-provider'; import SlotFillProvider from './provider'; import SlotFillContext from './bubbles-virtually/slot-fill-context'; +import type { WordPressComponentProps } from '../context'; + export { default as useSlot } from './bubbles-virtually/use-slot'; export { default as useSlotFills } from './bubbles-virtually/use-slot-fills'; +import type { + DistributiveOmit, + FillComponentProps, + SlotComponentProps, + SlotFillProviderProps, + SlotKey, +} from './types'; -export function Fill( props ) { +export function Fill( props: FillComponentProps ) { // We're adding both Fills here so they can register themselves before // their respective slot has been registered. Only the Fill that has a slot // will render. The other one will return null. @@ -28,20 +41,27 @@ export function Fill( props ) { ); } -export const Slot = forwardRef( ( { bubblesVirtually, ...props }, ref ) => { + +export function UnforwardedSlot( + props: SlotComponentProps & + Omit< WordPressComponentProps< {}, 'div' >, 'className' >, + ref: ForwardedRef< any > +) { + const { bubblesVirtually, ...restProps } = props; if ( bubblesVirtually ) { - return ; + return ; } - return ; -} ); + return ; +} +export const Slot = forwardRef( UnforwardedSlot ); -export function Provider( { children, ...props } ) { +export function Provider( { children }: SlotFillProviderProps ) { const parent = useContext( SlotFillContext ); if ( ! parent.isDefault ) { - return children; + return <>{ children }; } return ( - + { children } @@ -49,12 +69,16 @@ export function Provider( { children, ...props } ) { ); } -export function createSlotFill( key ) { +export function createSlotFill( key: SlotKey ) { const baseName = typeof key === 'symbol' ? key.description : key; - const FillComponent = ( props ) => ; + const FillComponent = ( props: Omit< FillComponentProps, 'name' > ) => ( + + ); FillComponent.displayName = `${ baseName }Fill`; - const SlotComponent = ( props ) => ; + const SlotComponent = ( + props: DistributiveOmit< SlotComponentProps, 'name' > + ) => ; SlotComponent.displayName = `${ baseName }Slot`; SlotComponent.__unstableName = key; @@ -64,7 +88,7 @@ export function createSlotFill( key ) { }; } -export const createPrivateSlotFill = ( name ) => { +export const createPrivateSlotFill = ( name: string ) => { const privateKey = Symbol( name ); const privateSlotFill = createSlotFill( privateKey ); diff --git a/packages/components/src/slot-fill/provider.js b/packages/components/src/slot-fill/provider.js deleted file mode 100644 index 94c83c3c35011..0000000000000 --- a/packages/components/src/slot-fill/provider.js +++ /dev/null @@ -1,119 +0,0 @@ -// @ts-nocheck -/** - * WordPress dependencies - */ -import { Component } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import SlotFillContext from './context'; - -export default class SlotFillProvider extends Component { - constructor() { - super( ...arguments ); - - this.registerSlot = this.registerSlot.bind( this ); - this.registerFill = this.registerFill.bind( this ); - this.unregisterSlot = this.unregisterSlot.bind( this ); - this.unregisterFill = this.unregisterFill.bind( this ); - this.getSlot = this.getSlot.bind( this ); - this.getFills = this.getFills.bind( this ); - this.subscribe = this.subscribe.bind( this ); - - this.slots = {}; - this.fills = {}; - this.listeners = []; - this.contextValue = { - registerSlot: this.registerSlot, - unregisterSlot: this.unregisterSlot, - registerFill: this.registerFill, - unregisterFill: this.unregisterFill, - getSlot: this.getSlot, - getFills: this.getFills, - subscribe: this.subscribe, - }; - } - - registerSlot( name, slot ) { - const previousSlot = this.slots[ name ]; - this.slots[ name ] = slot; - this.triggerListeners(); - - // Sometimes the fills are registered after the initial render of slot - // But before the registerSlot call, we need to rerender the slot. - this.forceUpdateSlot( name ); - - // If a new instance of a slot is being mounted while another with the - // same name exists, force its update _after_ the new slot has been - // assigned into the instance, such that its own rendering of children - // will be empty (the new Slot will subsume all fills for this name). - if ( previousSlot ) { - previousSlot.forceUpdate(); - } - } - - registerFill( name, instance ) { - this.fills[ name ] = [ ...( this.fills[ name ] || [] ), instance ]; - this.forceUpdateSlot( name ); - } - - unregisterSlot( name, instance ) { - // If a previous instance of a Slot by this name unmounts, do nothing, - // as the slot and its fills should only be removed for the current - // known instance. - if ( this.slots[ name ] !== instance ) { - return; - } - - delete this.slots[ name ]; - this.triggerListeners(); - } - - unregisterFill( name, instance ) { - this.fills[ name ] = - this.fills[ name ]?.filter( ( fill ) => fill !== instance ) ?? []; - this.forceUpdateSlot( name ); - } - - getSlot( name ) { - return this.slots[ name ]; - } - - getFills( name, slotInstance ) { - // Fills should only be returned for the current instance of the slot - // in which they occupy. - if ( this.slots[ name ] !== slotInstance ) { - return []; - } - return this.fills[ name ]; - } - - forceUpdateSlot( name ) { - const slot = this.getSlot( name ); - - if ( slot ) { - slot.forceUpdate(); - } - } - - triggerListeners() { - this.listeners.forEach( ( listener ) => listener() ); - } - - subscribe( listener ) { - this.listeners.push( listener ); - - return () => { - this.listeners = this.listeners.filter( ( l ) => l !== listener ); - }; - } - - render() { - return ( - - { this.props.children } - - ); - } -} diff --git a/packages/components/src/slot-fill/provider.tsx b/packages/components/src/slot-fill/provider.tsx new file mode 100644 index 0000000000000..ea32d7104b498 --- /dev/null +++ b/packages/components/src/slot-fill/provider.tsx @@ -0,0 +1,129 @@ +/** + * WordPress dependencies + */ +import type { Component } from '@wordpress/element'; +import { useMemo } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import SlotFillContext from './context'; +import type { + FillComponentProps, + BaseSlotFillContext, + BaseSlotComponentProps, + SlotFillProviderProps, + SlotKey, +} from './types'; + +function createSlotRegistry(): BaseSlotFillContext { + const slots: Record< SlotKey, Component< BaseSlotComponentProps > > = {}; + const fills: Record< SlotKey, FillComponentProps[] > = {}; + let listeners: Array< () => void > = []; + + function registerSlot( + name: SlotKey, + slot: Component< BaseSlotComponentProps > + ) { + const previousSlot = slots[ name ]; + slots[ name ] = slot; + triggerListeners(); + + // Sometimes the fills are registered after the initial render of slot + // But before the registerSlot call, we need to rerender the slot. + forceUpdateSlot( name ); + + // If a new instance of a slot is being mounted while another with the + // same name exists, force its update _after_ the new slot has been + // assigned into the instance, such that its own rendering of children + // will be empty (the new Slot will subsume all fills for this name). + if ( previousSlot ) { + previousSlot.forceUpdate(); + } + } + + function registerFill( name: SlotKey, instance: FillComponentProps ) { + fills[ name ] = [ ...( fills[ name ] || [] ), instance ]; + forceUpdateSlot( name ); + } + + function unregisterSlot( + name: SlotKey, + instance: Component< BaseSlotComponentProps > + ) { + // If a previous instance of a Slot by this name unmounts, do nothing, + // as the slot and its fills should only be removed for the current + // known instance. + if ( slots[ name ] !== instance ) { + return; + } + + delete slots[ name ]; + triggerListeners(); + } + + function unregisterFill( name: SlotKey, instance: FillComponentProps ) { + fills[ name ] = + fills[ name ]?.filter( ( fill ) => fill !== instance ) ?? []; + forceUpdateSlot( name ); + } + + function getSlot( + name: SlotKey + ): Component< BaseSlotComponentProps > | undefined { + return slots[ name ]; + } + + function getFills( + name: SlotKey, + slotInstance: Component< BaseSlotComponentProps > + ): FillComponentProps[] { + // Fills should only be returned for the current instance of the slot + // in which they occupy. + if ( slots[ name ] !== slotInstance ) { + return []; + } + return fills[ name ]; + } + + function forceUpdateSlot( name: SlotKey ) { + const slot = getSlot( name ); + + if ( slot ) { + slot.forceUpdate(); + } + } + + function triggerListeners() { + listeners.forEach( ( listener ) => listener() ); + } + + function subscribe( listener: () => void ) { + listeners.push( listener ); + + return () => { + listeners = listeners.filter( ( l ) => l !== listener ); + }; + } + + return { + registerSlot, + unregisterSlot, + registerFill, + unregisterFill, + getSlot, + getFills, + subscribe, + }; +} + +export function SlotFillProvider( { children }: SlotFillProviderProps ) { + const contextValue = useMemo( createSlotRegistry, [] ); + return ( + + { children } + + ); +} + +export default SlotFillProvider; diff --git a/packages/components/src/slot-fill/slot.js b/packages/components/src/slot-fill/slot.tsx similarity index 66% rename from packages/components/src/slot-fill/slot.js rename to packages/components/src/slot-fill/slot.tsx index f03192de95263..3fe2a54935926 100644 --- a/packages/components/src/slot-fill/slot.js +++ b/packages/components/src/slot-fill/slot.tsx @@ -1,4 +1,8 @@ -// @ts-nocheck +/** + * External dependencies + */ +import type { ReactElement, ReactNode, Key } from 'react'; + /** * WordPress dependencies */ @@ -13,20 +17,23 @@ import { * Internal dependencies */ import SlotFillContext from './context'; +import type { BaseSlotComponentProps, SlotComponentProps } from './types'; /** * Whether the argument is a function. * - * @param {*} maybeFunc The argument to check. - * @return {boolean} True if the argument is a function, false otherwise. + * @param maybeFunc The argument to check. + * @return True if the argument is a function, false otherwise. */ -function isFunction( maybeFunc ) { +function isFunction( maybeFunc: any ): maybeFunc is Function { return typeof maybeFunc === 'function'; } -class SlotComponent extends Component { - constructor() { - super( ...arguments ); +class SlotComponent extends Component< BaseSlotComponentProps > { + private isUnmounted: boolean; + + constructor( props: BaseSlotComponentProps ) { + super( props ); this.isUnmounted = false; } @@ -43,7 +50,7 @@ class SlotComponent extends Component { unregisterSlot( this.props.name, this ); } - componentDidUpdate( prevProps ) { + componentDidUpdate( prevProps: BaseSlotComponentProps ) { const { name, unregisterSlot, registerSlot } = this.props; if ( prevProps.name !== name ) { @@ -61,20 +68,27 @@ class SlotComponent extends Component { render() { const { children, name, fillProps = {}, getFills } = this.props; - - const fills = ( getFills( name, this ) ?? [] ) + const fills: ReactNode[] = ( getFills( name, this ) ?? [] ) .map( ( fill ) => { const fillChildren = isFunction( fill.children ) ? fill.children( fillProps ) : fill.children; - return Children.map( fillChildren, ( child, childIndex ) => { if ( ! child || typeof child === 'string' ) { return child; } + let childKey: Key = childIndex; + if ( + typeof child === 'object' && + 'key' in child && + child?.key + ) { + childKey = child.key; + } - const childKey = child.key || childIndex; - return cloneElement( child, { key: childKey } ); + return cloneElement( child as ReactElement, { + key: childKey, + } ); } ); } ) .filter( @@ -88,7 +102,7 @@ class SlotComponent extends Component { } } -const Slot = ( props ) => ( +const Slot = ( props: Omit< SlotComponentProps, 'bubblesVirtually' > ) => ( { ( { registerSlot, unregisterSlot, getFills } ) => ( { - return ( - -

Profile

-

- Name: -

-

- Age: -

- Grace - 33 -
- ); -}; - -export const WithFillProps = () => { - return ( - -

Profile

-

- Name:{ ' ' } - -

-

- Age:{ ' ' } - -

- { ( fillProps ) => fillProps.name } - { ( fillProps ) => fillProps.age } -
- ); -}; - -export const WithContext = () => { - const Context = createContext(); - const ContextFill = ( { name } ) => { - const value = useContext( Context ); - return { value }; - }; - return ( - -

Profile

-

- Name: -

-

- Age: -

- - - - - - -
- ); -}; diff --git a/packages/components/src/slot-fill/stories/index.story.tsx b/packages/components/src/slot-fill/stories/index.story.tsx new file mode 100644 index 0000000000000..ee00a12d69895 --- /dev/null +++ b/packages/components/src/slot-fill/stories/index.story.tsx @@ -0,0 +1,140 @@ +/** + * External dependencies + */ +import type { Meta, StoryFn } from '@storybook/react'; + +/** + * WordPress dependencies + */ +import { createContext, useContext } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { Slot, Fill, Provider as SlotFillProvider } from '../'; + +const meta: Meta< typeof Slot > = { + component: Slot, + title: 'Components/SlotFill', + // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170 + subcomponents: { Fill, SlotFillProvider }, + argTypes: { + name: { control: { type: null } }, + as: { control: { type: 'text' } }, + fillProps: { control: { type: null } }, + }, + parameters: { + controls: { expanded: true }, + docs: { source: { state: 'open' } }, + }, +}; + +export default meta; + +export const Default: StoryFn< typeof Slot > = ( props ) => { + return ( + +

Profile

+

+ Name: +

+

+ Age: +

+ Grace + 33 +
+ ); +}; +Default.args = { + bubblesVirtually: true, + as: 'span', +}; + +export const WithFillProps: StoryFn< typeof Slot > = ( props ) => { + return ( + +

Profile

+

+ Name:{ ' ' } + +

+

+ Age: +

+ + { ( fillProps ) => fillProps.name } + { ( fillProps ) => fillProps.age } +
+ ); +}; +WithFillProps.args = { + ...Default.args, +}; + +export const WithSlotChildren: StoryFn< typeof Slot > = ( props ) => { + return ( + +

Profile

+

+ Name: + { /* @ts-expect-error Not supported children for `` when `bubblesVirtually` is true. */ } + + { ( fills ) => { + return ( + { fills } + ); + } } + +

+

+ Age: + { /* @ts-expect-error Not support children for `` when `bubblesVirtually` is true. */ } + + { ( fills ) => { + return ( + { fills } + ); + } } + +

+ Alice + 18 +
+ ); +}; +WithSlotChildren.args = { + ...Default.args, +}; + +export const WithContext: StoryFn< typeof Slot > = ( props ) => { + const Context = createContext< string | number >( '' ); + const ContextFill = ( { name }: { name: string } ) => { + const value = useContext( Context ); + return { value }; + }; + return ( + +

Profile

+

+ Name: +

+

+ Age: +

+ + + + + + +
+ ); +}; +WithContext.args = { + ...Default.args, +}; diff --git a/packages/components/src/slot-fill/types.ts b/packages/components/src/slot-fill/types.ts new file mode 100644 index 0000000000000..763fa799c8d86 --- /dev/null +++ b/packages/components/src/slot-fill/types.ts @@ -0,0 +1,155 @@ +/** + * External dependencies + */ +import type { Component, MutableRefObject, ReactNode, RefObject } from 'react'; + +export type DistributiveOmit< T, K extends keyof any > = T extends any + ? Omit< T, K > + : never; + +export type SlotKey = string | symbol; + +export type FillProps = Record< string, any >; + +type SlotPropBase = { + /** + * Slot name. + */ + name: SlotKey; + + /** + * props to pass from `Slot` to `Fill`. + * + * @default {} + */ + fillProps?: FillProps; +}; + +export type SlotComponentProps = + | ( SlotPropBase & { + /** + * By default, events will bubble to their parents on the DOM hierarchy (native event bubbling). + * If set to true, events will bubble to their virtual parent in the React elements hierarchy instead, + * also accept an optional `className`, `id`, etc. to add to the slot container. + */ + bubblesVirtually: true; + + /** + * A function that returns nodes to be rendered. + * Not supported when `bubblesVirtually` is true. + */ + children?: never; + + /** + * className. + * Not supported when `bubblesVirtually` is true. + */ + className?: string; + } ) + | ( SlotPropBase & { + /** + * By default, events will bubble to their parents on the DOM hierarchy (native event bubbling). + * If set to true, events will bubble to their virtual parent in the React elements hierarchy instead, + * also accept an optional `className`, `id`, etc. to add to the slot container. + */ + bubblesVirtually?: false; + + /** + * A function that returns nodes to be rendered. + * Not supported when `bubblesVirtually` is true. + */ + children?: ( fills: ReactNode ) => ReactNode; + + /** + * className. + * Not supported when `bubblesVirtually` is false. + */ + className?: never; + } ); + +export type FillComponentProps = { + /** + * The name of the slot to fill into. + */ + name: SlotKey; + + /** + * Children elements or render function. + */ + children?: ReactNode | ( ( fillProps: FillProps ) => ReactNode ); +}; + +export type SlotFillProviderProps = { + /** + * The children elements. + */ + children: ReactNode; +}; + +export type SlotFillBubblesVirtuallySlotRef = RefObject< HTMLElement >; +export type SlotFillBubblesVirtuallyFillRef = MutableRefObject< { + rerender: () => void; +} >; + +export type SlotFillBubblesVirtuallyContext = { + slots: Map< + SlotKey, + { + ref: SlotFillBubblesVirtuallySlotRef; + fillProps: FillProps; + } + >; + fills: Map< SlotKey, SlotFillBubblesVirtuallyFillRef[] >; + registerSlot: ( + name: SlotKey, + ref: SlotFillBubblesVirtuallySlotRef, + fillProps: FillProps + ) => void; + unregisterSlot: ( + name: SlotKey, + ref: SlotFillBubblesVirtuallySlotRef + ) => void; + updateSlot: ( name: SlotKey, fillProps: FillProps ) => void; + registerFill: ( + name: SlotKey, + ref: SlotFillBubblesVirtuallyFillRef + ) => void; + unregisterFill: ( + name: SlotKey, + ref: SlotFillBubblesVirtuallyFillRef + ) => void; + + /** + * This helps the provider know if it's using the default context value or not. + */ + isDefault?: boolean; +}; + +export type BaseSlotFillContext = { + registerSlot: ( + name: SlotKey, + slot: Component< BaseSlotComponentProps > + ) => void; + unregisterSlot: ( + name: SlotKey, + slot: Component< BaseSlotComponentProps > + ) => void; + registerFill: ( name: SlotKey, instance: FillComponentProps ) => void; + unregisterFill: ( name: SlotKey, instance: FillComponentProps ) => void; + getSlot: ( + name: SlotKey + ) => Component< BaseSlotComponentProps > | undefined; + getFills: ( + name: SlotKey, + slotInstance: Component< BaseSlotComponentProps > + ) => FillComponentProps[]; + subscribe: ( listener: () => void ) => () => void; +}; + +export type BaseSlotComponentProps = Pick< + BaseSlotFillContext, + 'registerSlot' | 'unregisterSlot' | 'getFills' +> & + Omit< SlotComponentProps, 'bubblesVirtually' > & { + children?: ( fills: ReactNode ) => ReactNode; + }; diff --git a/packages/components/src/slot-fill/use-slot.js b/packages/components/src/slot-fill/use-slot.ts similarity index 77% rename from packages/components/src/slot-fill/use-slot.js rename to packages/components/src/slot-fill/use-slot.ts index fce7c651495d5..4ab419be1ad2b 100644 --- a/packages/components/src/slot-fill/use-slot.js +++ b/packages/components/src/slot-fill/use-slot.ts @@ -1,4 +1,3 @@ -// @ts-nocheck /** * WordPress dependencies */ @@ -8,14 +7,15 @@ import { useContext, useSyncExternalStore } from '@wordpress/element'; * Internal dependencies */ import SlotFillContext from './context'; +import type { SlotKey } from './types'; /** * React hook returning the active slot given a name. * - * @param {string} name Slot name. - * @return {Object} Slot object. + * @param name Slot name. + * @return Slot object. */ -const useSlot = ( name ) => { +const useSlot = ( name: SlotKey ) => { const { getSlot, subscribe } = useContext( SlotFillContext ); return useSyncExternalStore( subscribe, From 47eff011d716a8efef831c8c399dd171dcb31c79 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Sep 2023 09:58:35 -0400 Subject: [PATCH 09/23] Bump gradle/gradle-build-action from 2.8.0 to 2.8.1 (#54827) Bumps [gradle/gradle-build-action](https://github.com/gradle/gradle-build-action) from 2.8.0 to 2.8.1. - [Release notes](https://github.com/gradle/gradle-build-action/releases) - [Commits](https://github.com/gradle/gradle-build-action/compare/ef76a971e2fa3f867b617efd72f2fbd72cf6f8bc...b5126f31dbc19dd434c3269bf8c28c315e121da2) --- updated-dependencies: - dependency-name: gradle/gradle-build-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/rnmobile-android-runner.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rnmobile-android-runner.yml b/.github/workflows/rnmobile-android-runner.yml index 375e7e22fe760..18b51db7d8db0 100644 --- a/.github/workflows/rnmobile-android-runner.yml +++ b/.github/workflows/rnmobile-android-runner.yml @@ -37,7 +37,7 @@ jobs: uses: ./.github/setup-node - name: Gradle cache - uses: gradle/gradle-build-action@ef76a971e2fa3f867b617efd72f2fbd72cf6f8bc # v2.8.0 + uses: gradle/gradle-build-action@b5126f31dbc19dd434c3269bf8c28c315e121da2 # v2.8.1 - name: AVD cache uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 From d78304bf66c54fb9c19221493dfda53739199adc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Sep 2023 10:01:55 -0400 Subject: [PATCH 10/23] Bump tj-actions/changed-files from 39.1.2 to 39.2.0 (#54789) Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 39.1.2 to 39.2.0. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/41960309398d165631f08c5df47a11147e14712b...8238a4103220c636f2dad328ead8a7c8dbe316a3) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/php-changes-detection.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/php-changes-detection.yml b/.github/workflows/php-changes-detection.yml index b78a787f3a4b8..69ed704392056 100644 --- a/.github/workflows/php-changes-detection.yml +++ b/.github/workflows/php-changes-detection.yml @@ -17,7 +17,7 @@ jobs: - name: Get changed PHP files id: changed-files-php - uses: tj-actions/changed-files@41960309398d165631f08c5df47a11147e14712b # v39.1.2 + uses: tj-actions/changed-files@8238a4103220c636f2dad328ead8a7c8dbe316a3 # v39.2.0 with: files: | *.{php} From b2d37cc5a8b9106e493b594429828bf04aa4c561 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Sep 2023 10:02:18 -0400 Subject: [PATCH 11/23] Bump actions/checkout from 4.0.0 to 4.1.0 (#54788) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/3df4ab11eba7bda6032a0b82a6bb43b11571feac...8ade135a41bc03ea155e62e844d188df1ea18608) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-plugin-zip.yml | 10 +++++----- .github/workflows/bundle-size.yml | 2 +- .github/workflows/check-components-changelog.yml | 2 +- .github/workflows/create-block.yml | 2 +- .github/workflows/end2end-test.yml | 6 +++--- .github/workflows/gradle-wrapper-validation.yml | 2 +- .github/workflows/performance.yml | 2 +- .github/workflows/php-changes-detection.yml | 2 +- .github/workflows/publish-npm-packages.yml | 6 +++--- .github/workflows/pull-request-automation.yml | 2 +- .github/workflows/rnmobile-android-runner.yml | 2 +- .github/workflows/rnmobile-ios-runner.yml | 2 +- .github/workflows/static-checks.yml | 2 +- .github/workflows/storybook-pages.yml | 2 +- .github/workflows/unit-test.yml | 8 ++++---- .github/workflows/upload-release-to-plugin-repo.yml | 2 +- 16 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.github/workflows/build-plugin-zip.yml b/.github/workflows/build-plugin-zip.yml index 5c06393ec3c01..0921d1f9fc79c 100644 --- a/.github/workflows/build-plugin-zip.yml +++ b/.github/workflows/build-plugin-zip.yml @@ -69,7 +69,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: token: ${{ secrets.GUTENBERG_TOKEN }} show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -165,7 +165,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: ref: ${{ needs.bump-version.outputs.release_branch || github.ref }} show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -221,7 +221,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: fetch-depth: 2 ref: ${{ needs.bump-version.outputs.release_branch }} @@ -310,14 +310,14 @@ jobs: if: ${{ endsWith( needs.bump-version.outputs.new_version, '-rc.1' ) }} steps: - name: Checkout (for CLI) - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: path: main ref: trunk show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - name: Checkout (for publishing) - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: path: publish # Later, we switch this branch in the script that publishes packages. diff --git a/.github/workflows/bundle-size.yml b/.github/workflows/bundle-size.yml index f5a28f7859097..d6a9ca83bf360 100644 --- a/.github/workflows/bundle-size.yml +++ b/.github/workflows/bundle-size.yml @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: fetch-depth: 1 show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/check-components-changelog.yml b/.github/workflows/check-components-changelog.yml index 5271b3883c141..5ab89671c1cf6 100644 --- a/.github/workflows/check-components-changelog.yml +++ b/.github/workflows/check-components-changelog.yml @@ -20,7 +20,7 @@ jobs: - name: 'Get PR commit count' run: echo "PR_COMMIT_COUNT=$(( ${{ github.event.pull_request.commits }} + 1 ))" >> "${GITHUB_ENV}" - name: Checkout code - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: ref: ${{ github.event.pull_request.head.ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} diff --git a/.github/workflows/create-block.yml b/.github/workflows/create-block.yml index f3c9f64b97072..d46a3077ee7c9 100644 --- a/.github/workflows/create-block.yml +++ b/.github/workflows/create-block.yml @@ -24,7 +24,7 @@ jobs: os: [macos-latest, ubuntu-latest, windows-latest] steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/end2end-test.yml b/.github/workflows/end2end-test.yml index 61cb39612fa55..9bf85a1ac5363 100644 --- a/.github/workflows/end2end-test.yml +++ b/.github/workflows/end2end-test.yml @@ -27,7 +27,7 @@ jobs: totalParts: [3] steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -73,7 +73,7 @@ jobs: totalParts: [4] steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -119,7 +119,7 @@ jobs: steps: # Checkout defaults to using the branch which triggered the event, which # isn't necessarily `trunk` (e.g. in the case of a merge). - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: ref: trunk show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 5e417c27bc82f..b4012ffc19fd4 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -6,7 +6,7 @@ jobs: name: 'Validation' runs-on: ubuntu-latest steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - uses: gradle/wrapper-validation-action@v1 diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 7813f04874bc2..875ed28c743aa 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -32,7 +32,7 @@ jobs: WP_ARTIFACTS_PATH: ${{ github.workspace }}/artifacts steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/php-changes-detection.yml b/.github/workflows/php-changes-detection.yml index 69ed704392056..2078bb4a1ddfe 100644 --- a/.github/workflows/php-changes-detection.yml +++ b/.github/workflows/php-changes-detection.yml @@ -10,7 +10,7 @@ jobs: if: ${{ github.repository == 'WordPress/gutenberg' || github.event_name == 'pull_request' }} steps: - name: Check out code - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: fetch-depth: 0 show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/publish-npm-packages.yml b/.github/workflows/publish-npm-packages.yml index 7c2e9412cc1de..3698441458ce0 100644 --- a/.github/workflows/publish-npm-packages.yml +++ b/.github/workflows/publish-npm-packages.yml @@ -31,7 +31,7 @@ jobs: steps: - name: Checkout (for CLI) if: ${{ github.event.inputs.release_type != 'wp' }} - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: path: cli ref: trunk @@ -39,7 +39,7 @@ jobs: - name: Checkout (for publishing) if: ${{ github.event.inputs.release_type != 'wp' }} - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: path: publish # Later, we switch this branch in the script that publishes packages. @@ -49,7 +49,7 @@ jobs: - name: Checkout (for publishing WP major version) if: ${{ github.event.inputs.release_type == 'wp' && github.event.inputs.wp_version }} - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: path: publish ref: wp/${{ github.event.inputs.wp_version }} diff --git a/.github/workflows/pull-request-automation.yml b/.github/workflows/pull-request-automation.yml index a34df5282d6d8..38cf4c66a503f 100644 --- a/.github/workflows/pull-request-automation.yml +++ b/.github/workflows/pull-request-automation.yml @@ -15,7 +15,7 @@ jobs: steps: # Checkout defaults to using the branch which triggered the event, which # isn't necessarily `trunk` (e.g. in the case of a merge). - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: ref: trunk show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/rnmobile-android-runner.yml b/.github/workflows/rnmobile-android-runner.yml index 18b51db7d8db0..8a51df3faade2 100644 --- a/.github/workflows/rnmobile-android-runner.yml +++ b/.github/workflows/rnmobile-android-runner.yml @@ -23,7 +23,7 @@ jobs: steps: - name: checkout - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/rnmobile-ios-runner.yml b/.github/workflows/rnmobile-ios-runner.yml index 6a03547966fe1..60eb439d1e1c2 100644 --- a/.github/workflows/rnmobile-ios-runner.yml +++ b/.github/workflows/rnmobile-ios-runner.yml @@ -23,7 +23,7 @@ jobs: native-test-name: [gutenberg-editor-rendering] steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml index 87e936757814e..7fe07bb2ae7bf 100644 --- a/.github/workflows/static-checks.yml +++ b/.github/workflows/static-checks.yml @@ -22,7 +22,7 @@ jobs: if: ${{ github.repository == 'WordPress/gutenberg' || github.event_name == 'pull_request' }} steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/storybook-pages.yml b/.github/workflows/storybook-pages.yml index d8932b4a4e277..32683fac2178c 100644 --- a/.github/workflows/storybook-pages.yml +++ b/.github/workflows/storybook-pages.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: ref: trunk show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 31d2497417272..7ce44a6931d9e 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -31,7 +31,7 @@ jobs: node: ['16'] steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -111,7 +111,7 @@ jobs: WP_ENV_CORE: ${{ matrix.wordpress == '' && 'WordPress/WordPress' || format( 'https://wordpress.org/wordpress-{0}.zip', matrix.wordpress ) }} steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -221,7 +221,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} @@ -290,7 +290,7 @@ jobs: if: ${{ github.repository == 'WordPress/gutenberg' || github.event_name == 'pull_request' }} steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} diff --git a/.github/workflows/upload-release-to-plugin-repo.yml b/.github/workflows/upload-release-to-plugin-repo.yml index d7fdb9b3fe379..2b5ca0e5a8593 100644 --- a/.github/workflows/upload-release-to-plugin-repo.yml +++ b/.github/workflows/upload-release-to-plugin-repo.yml @@ -96,7 +96,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: ref: ${{ matrix.branch }} token: ${{ secrets.GUTENBERG_TOKEN }} From d626ade5d07441dda84fb77fbfd6aa30fff57a91 Mon Sep 17 00:00:00 2001 From: Derek Blank Date: Thu, 28 Sep 2023 16:44:14 +0200 Subject: [PATCH 12/23] Mobile Release v1.105.0 (#54898) * Release script: Update react-native-editor version to 1.105.0 * Release script: Update with changes from 'npm run core preios' * Update Gutenberg Mobile CHANGELOG * Update package-lock.json with 1.105.0 version number --------- Co-authored-by: Carlos Garcia --- package-lock.json | 6 +++--- packages/react-native-aztec/package.json | 2 +- packages/react-native-bridge/package.json | 2 +- packages/react-native-editor/CHANGELOG.md | 2 ++ packages/react-native-editor/ios/Podfile.lock | 8 ++++---- packages/react-native-editor/package.json | 2 +- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index f40f805940461..f500f14520bdd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57590,7 +57590,7 @@ }, "packages/react-native-aztec": { "name": "@wordpress/react-native-aztec", - "version": "1.104.0", + "version": "1.105.0", "license": "GPL-2.0-or-later", "dependencies": { "@wordpress/element": "file:../element", @@ -57603,7 +57603,7 @@ }, "packages/react-native-bridge": { "name": "@wordpress/react-native-bridge", - "version": "1.104.0", + "version": "1.105.0", "license": "GPL-2.0-or-later", "dependencies": { "@wordpress/react-native-aztec": "file:../react-native-aztec" @@ -57614,7 +57614,7 @@ }, "packages/react-native-editor": { "name": "@wordpress/react-native-editor", - "version": "1.104.0", + "version": "1.105.0", "hasInstallScript": true, "license": "GPL-2.0-or-later", "dependencies": { diff --git a/packages/react-native-aztec/package.json b/packages/react-native-aztec/package.json index 4f1715b9656c5..87ebdf194696b 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.104.0", + "version": "1.105.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 1beb86e3791fa..b6de1b5c53fff 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.104.0", + "version": "1.105.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/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index df489757dd6bd..86161840ea148 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -10,6 +10,8 @@ For each user feature we should also add a importance categorization label to i --> ## Unreleased + +## 1.105.0 - [*] Limit inner blocks nesting depth to avoid call stack size exceeded crash [#54382] - [*] Prevent crashes when setting an invalid media URL for Video or Audio blocks [#54834] - [**] Fallback to Twitter provider when embedding X URLs [#54876] diff --git a/packages/react-native-editor/ios/Podfile.lock b/packages/react-native-editor/ios/Podfile.lock index 324c80709386c..26a891a240251 100644 --- a/packages/react-native-editor/ios/Podfile.lock +++ b/packages/react-native-editor/ios/Podfile.lock @@ -13,7 +13,7 @@ PODS: - ReactCommon/turbomodule/core (= 0.71.11) - fmt (6.2.1) - glog (0.3.5) - - Gutenberg (1.104.0): + - Gutenberg (1.105.0): - React-Core (= 0.71.11) - React-CoreModules (= 0.71.11) - React-RCTImage (= 0.71.11) @@ -429,7 +429,7 @@ PODS: - React-RCTImage - RNSVG (13.9.0): - React-Core - - RNTAztecView (1.104.0): + - RNTAztecView (1.105.0): - React-Core - WordPress-Aztec-iOS (= 1.19.9) - SDWebImage (5.11.1): @@ -617,7 +617,7 @@ SPEC CHECKSUMS: FBReactNativeSpec: f07662560742d82a5b73cee116c70b0b49bcc220 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b - Gutenberg: a79dedde03484f2766429558a85f6ff6c90e2513 + Gutenberg: eb59e13cd7ef341f9ef92857009d960b0831f21a hermes-engine: 34c863b446d0135b85a6536fa5fd89f48196f848 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 libwebp: 60305b2e989864154bd9be3d772730f08fc6a59c @@ -662,7 +662,7 @@ SPEC CHECKSUMS: RNReanimated: d4f363f4987ae0ade3e36ff81c94e68261bf4b8d RNScreens: 68fd1060f57dd1023880bf4c05d74784b5392789 RNSVG: 53c661b76829783cdaf9b7a57258f3d3b4c28315 - RNTAztecView: dfbe69cb1448f08b29846616fbb79d79f21968b3 + RNTAztecView: 4b0ffdbaa58dcbf73b63403a888a2334fc4465dd SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d WordPress-Aztec-iOS: fbebd569c61baa252b3f5058c0a2a9a6ada686bb diff --git a/packages/react-native-editor/package.json b/packages/react-native-editor/package.json index 627cae16b549c..0c6ff58c7184d 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.104.0", + "version": "1.105.0", "description": "Mobile WordPress gutenberg editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From f637b3735300894e9698a3a5246a086c4454d4bd Mon Sep 17 00:00:00 2001 From: Maggie Date: Thu, 28 Sep 2023 17:25:23 +0200 Subject: [PATCH 13/23] Fix warning when a template calls a template area twice (#54861) * ensure no duplicated template areas * give the variable a meaningful name --------- Co-authored-by: scruffian --- packages/edit-site/src/store/utils.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/edit-site/src/store/utils.js b/packages/edit-site/src/store/utils.js index af24684ace615..2a8840c7104d8 100644 --- a/packages/edit-site/src/store/utils.js +++ b/packages/edit-site/src/store/utils.js @@ -49,8 +49,13 @@ function getFilteredTemplatePartBlocks( blocks = EMPTY_ARRAY, templateParts ) { const templatePartId = `${ theme }//${ slug }`; const templatePart = templatePartsById[ templatePartId ]; + // Make sure we don't duplicate template parts. + const existingTemplatePart = result.find( + ( oneResult ) => oneResult.templatePart.id === templatePartId + ); + // Only add to output if the found template part block is in the list of available template parts. - if ( templatePart ) { + if ( templatePart && ! existingTemplatePart ) { result.push( { templatePart, block, From d667d809a0c90c3874fe1422b99a667ed0120453 Mon Sep 17 00:00:00 2001 From: Jason Crist Date: Thu, 28 Sep 2023 12:13:47 -0400 Subject: [PATCH 14/23] Font Library: Changed the OTF mime type expected value to be what PHP returns (#54886) * Changed the OTF mime type expected value to be what PHP returns * add unit test for otf file installation --------- Co-authored-by: madhusudhand --- .../font-library/class-wp-font-library.php | 2 +- phpunit/tests/data/fonts/gilbert-color.otf | Bin 0 -> 626352 bytes .../font-library/wpFontFamily/install.php | 28 ++++++++++++++++++ .../wpFontLibrary/getMimeTypes.php | 12 ++++---- 4 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 phpunit/tests/data/fonts/gilbert-color.otf diff --git a/lib/experimental/fonts/font-library/class-wp-font-library.php b/lib/experimental/fonts/font-library/class-wp-font-library.php index 6d2ad5de43a35..e77a79244569b 100644 --- a/lib/experimental/fonts/font-library/class-wp-font-library.php +++ b/lib/experimental/fonts/font-library/class-wp-font-library.php @@ -36,7 +36,7 @@ public static function get_expected_font_mime_types_per_php_version( $php_versio $php_7_ttf_mime_type = $php_version_id >= 70300 ? 'application/font-sfnt' : 'application/x-font-ttf'; return array( - 'otf' => 'font/otf', + 'otf' => 'application/vnd.ms-opentype', 'ttf' => $php_version_id >= 70400 ? 'font/sfnt' : $php_7_ttf_mime_type, 'woff' => $php_version_id >= 80100 ? 'font/woff' : 'application/font-woff', 'woff2' => $php_version_id >= 80100 ? 'font/woff2' : 'application/font-woff2', diff --git a/phpunit/tests/data/fonts/gilbert-color.otf b/phpunit/tests/data/fonts/gilbert-color.otf new file mode 100644 index 0000000000000000000000000000000000000000..f21f9a173f2fe0b53a02723ce7fae62fca7cb897 GIT binary patch literal 626352 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 array( 'dm-sans_regular_500.woff2' ), ), + // otf font type. + 'otf local font' => array( + 'font_data' => array( + 'name' => 'Gilbert Color', + 'slug' => 'gilbert-color', + 'fontFamily' => 'Gilbert Color', + 'fontFace' => array( + array( + 'fontFamily' => 'Gilbert Color', + 'fontStyle' => 'regular', + 'fontWeight' => '500', + 'uploadedFile' => 'files0', + ), + ), + ), + 'files_data' => array( + 'files0' => array( + 'name' => 'gilbert-color.otf', + 'type' => 'application/vnd.ms-opentype', + 'tmp_name' => wp_tempnam( 'Gilbert-' ), + 'error' => 0, + 'size' => 123, + ), + ), + 'expected' => array( 'gilbert-color_regular_500.otf' ), + ), ); } diff --git a/phpunit/tests/fonts/font-library/wpFontLibrary/getMimeTypes.php b/phpunit/tests/fonts/font-library/wpFontLibrary/getMimeTypes.php index 720695d8fe5ef..708134af69e92 100644 --- a/phpunit/tests/fonts/font-library/wpFontLibrary/getMimeTypes.php +++ b/phpunit/tests/fonts/font-library/wpFontLibrary/getMimeTypes.php @@ -34,7 +34,7 @@ public function data_should_supply_correct_mime_type_for_php_version() { 'version 7.2' => array( 'php_version_id' => 70200, 'expected' => array( - 'otf' => 'font/otf', + 'otf' => 'application/vnd.ms-opentype', 'ttf' => 'application/x-font-ttf', 'woff' => 'application/font-woff', 'woff2' => 'application/font-woff2', @@ -43,7 +43,7 @@ public function data_should_supply_correct_mime_type_for_php_version() { 'version 7.3' => array( 'php_version_id' => 70300, 'expected' => array( - 'otf' => 'font/otf', + 'otf' => 'application/vnd.ms-opentype', 'ttf' => 'application/font-sfnt', 'woff' => 'application/font-woff', 'woff2' => 'application/font-woff2', @@ -52,7 +52,7 @@ public function data_should_supply_correct_mime_type_for_php_version() { 'version 7.4' => array( 'php_version_id' => 70400, 'expected' => array( - 'otf' => 'font/otf', + 'otf' => 'application/vnd.ms-opentype', 'ttf' => 'font/sfnt', 'woff' => 'application/font-woff', 'woff2' => 'application/font-woff2', @@ -61,7 +61,7 @@ public function data_should_supply_correct_mime_type_for_php_version() { 'version 8.0' => array( 'php_version_id' => 80000, 'expected' => array( - 'otf' => 'font/otf', + 'otf' => 'application/vnd.ms-opentype', 'ttf' => 'font/sfnt', 'woff' => 'application/font-woff', 'woff2' => 'application/font-woff2', @@ -70,7 +70,7 @@ public function data_should_supply_correct_mime_type_for_php_version() { 'version 8.1' => array( 'php_version_id' => 80100, 'expected' => array( - 'otf' => 'font/otf', + 'otf' => 'application/vnd.ms-opentype', 'ttf' => 'font/sfnt', 'woff' => 'font/woff', 'woff2' => 'font/woff2', @@ -79,7 +79,7 @@ public function data_should_supply_correct_mime_type_for_php_version() { 'version 8.2' => array( 'php_version_id' => 80200, 'expected' => array( - 'otf' => 'font/otf', + 'otf' => 'application/vnd.ms-opentype', 'ttf' => 'font/sfnt', 'woff' => 'font/woff', 'woff2' => 'font/woff2', From 25d7b32024576513848b6486ee161b705db60825 Mon Sep 17 00:00:00 2001 From: Mitchell Austin Date: Thu, 28 Sep 2023 09:21:58 -0700 Subject: [PATCH 15/23] `Modal`: Accessibly hide/show outer modal when nested (#54743) --- packages/components/CHANGELOG.md | 1 + packages/components/src/modal/aria-helper.ts | 42 ++++++++------------ packages/components/src/modal/index.tsx | 7 +++- packages/components/src/modal/test/index.tsx | 3 +- 4 files changed, 24 insertions(+), 29 deletions(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 5f9f5de9327cd..986c7fa19b9ea 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -7,6 +7,7 @@ - `SearchControl`: polish metrics for `compact` size variant ([#54663](https://github.com/WordPress/gutenberg/pull/54663)). - `Button`: deprecating `isPressed` prop in favour of `aria-pressed` ([#54740](https://github.com/WordPress/gutenberg/pull/54740)). - `DuotonePicker/ColorListPicker`: Adds appropriate label and description to 'Duotone Filter' picker ([#54473](https://github.com/WordPress/gutenberg/pull/54473)). +- `Modal`: Accessibly hide/show outer modal when nested ([#54743](https://github.com/WordPress/gutenberg/pull/54743)). ### Bug Fix diff --git a/packages/components/src/modal/aria-helper.ts b/packages/components/src/modal/aria-helper.ts index 25ef449a30d3d..6d4427ddea948 100644 --- a/packages/components/src/modal/aria-helper.ts +++ b/packages/components/src/modal/aria-helper.ts @@ -6,8 +6,7 @@ const LIVE_REGION_ARIA_ROLES = new Set( [ 'timer', ] ); -let hiddenElements: Element[] = [], - isHidden = false; +const hiddenElementsByDepth: Element[][] = []; /** * Hides all elements in the body element from screen-readers except @@ -19,31 +18,28 @@ let hiddenElements: Element[] = [], * we should consider removing these helper functions in favor of * `aria-modal="true"`. * - * @param {HTMLDivElement} unhiddenElement The element that should not be hidden. + * @param modalElement The element that should not be hidden. */ -export function hideApp( unhiddenElement?: HTMLDivElement ) { - if ( isHidden ) { - return; - } +export function modalize( modalElement?: HTMLDivElement ) { const elements = Array.from( document.body.children ); - elements.forEach( ( element ) => { - if ( element === unhiddenElement ) { - return; - } + const hiddenElements: Element[] = []; + hiddenElementsByDepth.push( hiddenElements ); + for ( const element of elements ) { + if ( element === modalElement ) continue; + if ( elementShouldBeHidden( element ) ) { element.setAttribute( 'aria-hidden', 'true' ); hiddenElements.push( element ); } - } ); - isHidden = true; + } } /** * Determines if the passed element should not be hidden from screen readers. * - * @param {HTMLElement} element The element that should be checked. + * @param element The element that should be checked. * - * @return {boolean} Whether the element should not be hidden from screen-readers. + * @return Whether the element should not be hidden from screen-readers. */ export function elementShouldBeHidden( element: Element ) { const role = element.getAttribute( 'role' ); @@ -56,16 +52,12 @@ export function elementShouldBeHidden( element: Element ) { } /** - * Makes all elements in the body that have been hidden by `hideApp` - * visible again to screen-readers. + * Accessibly reveals the elements hidden by the latest modal. */ -export function showApp() { - if ( ! isHidden ) { - return; - } - hiddenElements.forEach( ( element ) => { +export function unmodalize() { + const hiddenElements = hiddenElementsByDepth.pop(); + if ( ! hiddenElements ) return; + + for ( const element of hiddenElements ) element.removeAttribute( 'aria-hidden' ); - } ); - hiddenElements = []; - isHidden = false; } diff --git a/packages/components/src/modal/index.tsx b/packages/components/src/modal/index.tsx index 139b0805a04db..13d352f46058b 100644 --- a/packages/components/src/modal/index.tsx +++ b/packages/components/src/modal/index.tsx @@ -112,11 +112,15 @@ function UnforwardedModal( } }, [ contentRef ] ); + useEffect( () => { + ariaHelper.modalize( ref.current ); + return () => ariaHelper.unmodalize(); + }, [] ); + useEffect( () => { openModalCount++; if ( openModalCount === 1 ) { - ariaHelper.hideApp( ref.current ); document.body.classList.add( bodyOpenClassName ); } @@ -125,7 +129,6 @@ function UnforwardedModal( if ( openModalCount === 0 ) { document.body.classList.remove( bodyOpenClassName ); - ariaHelper.showApp(); } }; }, [ bodyOpenClassName ] ); diff --git a/packages/components/src/modal/test/index.tsx b/packages/components/src/modal/test/index.tsx index ae606bb831513..69f28508c1405 100644 --- a/packages/components/src/modal/test/index.tsx +++ b/packages/components/src/modal/test/index.tsx @@ -167,8 +167,7 @@ describe( 'Modal', () => { expect( onRequestClose ).not.toHaveBeenCalled(); } ); - // TODO enable once nested modals hide outer modals. - it.skip( 'should accessibly hide and show siblings including outer modals', async () => { + it( 'should accessibly hide and show siblings including outer modals', async () => { const user = userEvent.setup(); const AriaDemo = () => { From 9b2f4bf769154bf8a4f831a4614f9fef5a4d25b6 Mon Sep 17 00:00:00 2001 From: Carlos Bravo <37012961+c4rl0sbr4v0@users.noreply.github.com> Date: Thu, 28 Sep 2023 19:12:41 +0200 Subject: [PATCH 16/23] Image: Fix layout shift when lightbox is opened and closed (#53026) * Replace overflow: hidden with JavaScript callback to prevent scrolling * Disable scroll callback on mobile; add comments; fix scrim styles The page jumps around when trying to override the scroll behavior on mobile, so I disabled it altogether. I've also added comments to clarify this and other decisions made around the scroll handling. While testing, I realized that the scrim was completely opaque during the zoom animation, which does not match the design, so I added a new animation specifically for the scrim to fix that. * Add handling for horizontally oriented pages * Move close button so that it's further from scrollbar on desktop * Fix call to handleScroll() and add touch callback to new render method * Improve lightbox experience on mobile To ensure pinch to zoom works as expected when the lightbox is open on mobile, I added logic to disable the scroll override when touch is detected. Without this, the scroll override kicks in whenever one tries to pinch to zoom, and it breaks the experience. I also revised the styles for the scrim to make it opaque, as having content visible outside of the lightbox is distracting when pinching to zoom on a mobile device, and I think having a consistent lightbox across devices will make for the best user experience. * Fix spacing * Add touch directives to block supports * Fix spacing in block supports * Rename attribute for clarity * Update comment * Update comments * Fix spacing --------- Co-authored-by: Ricardo Artemio Morales --- lib/block-supports/behaviors.php | 4 +- packages/block-library/src/image/index.php | 4 +- packages/block-library/src/image/style.scss | 8 +- packages/block-library/src/image/view.js | 181 +++++++++++++++----- 4 files changed, 145 insertions(+), 52 deletions(-) diff --git a/lib/block-supports/behaviors.php b/lib/block-supports/behaviors.php index cf668ed22d887..6f442d7b0d2d7 100644 --- a/lib/block-supports/behaviors.php +++ b/lib/block-supports/behaviors.php @@ -233,7 +233,9 @@ function gutenberg_render_behaviors_support_lightbox( $block_content, $block ) { data-wp-bind--aria-modal="context.core.image.lightboxEnabled" data-wp-effect="effects.core.image.initLightbox" data-wp-on--keydown="actions.core.image.handleKeydown" - data-wp-on--mousewheel="actions.core.image.hideLightbox" + data-wp-on--touchstart="actions.core.image.handleTouchStart" + data-wp-on--touchmove="actions.core.image.handleTouchMove" + data-wp-on--touchend="actions.core.image.handleTouchEnd" data-wp-on--click="actions.core.image.hideLightbox" > + + `.${ ext }` + ).join( ',' ) } + multiple={ true } + onChange={ onFilesUpload } + render={ ( { openFileDialog } ) => ( + + ) } + /> + { notice && ( + + + + { notice.message } + + ) } - /> + + + { sprintf( + /* translators: %s: supported font formats: ex: .ttf, .woff and .woff2 */ + __( + 'Uploaded fonts appear in your library and can be used in your theme. Supported formats: %s.' + ), + supportedFormats + ) } + + ); } diff --git a/packages/edit-site/src/components/global-styles/font-library-modal/style.scss b/packages/edit-site/src/components/global-styles/font-library-modal/style.scss index 663aef94ab7e6..cd11cc7b57ebd 100644 --- a/packages/edit-site/src/components/global-styles/font-library-modal/style.scss +++ b/packages/edit-site/src/components/global-styles/font-library-modal/style.scss @@ -92,11 +92,24 @@ align-items: center; display: flex; justify-content: center; - height: 100px; + height: 250px; width: 100%; background-color: #f0f0f0; } +.font-library-modal__local-fonts { + margin: 0 auto; + width: 80%; + + .font-library-modal__upload-area__text { + color: #6e6e6e; + } + + .font-library-modal__upload-area__notice { + margin: 0; + } +} + .font-library-modal__font-name { font-weight: bold; } diff --git a/packages/edit-site/src/components/global-styles/font-library-modal/upload-fonts.js b/packages/edit-site/src/components/global-styles/font-library-modal/upload-fonts.js new file mode 100644 index 0000000000000..effc4a2a5227c --- /dev/null +++ b/packages/edit-site/src/components/global-styles/font-library-modal/upload-fonts.js @@ -0,0 +1,20 @@ +/** + * WordPress dependencies + */ +import { __experimentalSpacer as Spacer } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import LocalFonts from './local-fonts'; + +function UploadFonts() { + return ( + <> + + + + ); +} + +export default UploadFonts; diff --git a/packages/edit-site/src/components/global-styles/font-library-modal/utils/index.js b/packages/edit-site/src/components/global-styles/font-library-modal/utils/index.js index 49e7e7e4684ee..7afa0f7aee17a 100644 --- a/packages/edit-site/src/components/global-styles/font-library-modal/utils/index.js +++ b/packages/edit-site/src/components/global-styles/font-library-modal/utils/index.js @@ -109,6 +109,10 @@ export async function loadFontFaceInBrowser( fontFace, source, addTo = 'all' ) { } export function getDisplaySrcFromFontFace( input, urlPrefix ) { + if ( ! input ) { + return; + } + let src; if ( Array.isArray( input ) ) { src = input[ 0 ]; From 1fb1343c42a59d5062660a7da20a4bff4d06e369 Mon Sep 17 00:00:00 2001 From: Andrew Hayward Date: Thu, 28 Sep 2023 20:54:39 +0100 Subject: [PATCH 18/23] Tidying `CircularOptionPicker.Option` (#54903) Tidying `CircularOptionPicker.Option` --- .../test/__snapshots__/control.js.snap | 2 +- packages/components/src/button/style.scss | 3 ++- .../circular-option-picker-option.tsx | 20 +++++++++---------- .../src/circular-option-picker/style.scss | 3 ++- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/block-editor/src/components/color-palette/test/__snapshots__/control.js.snap b/packages/block-editor/src/components/color-palette/test/__snapshots__/control.js.snap index 94dc53f7da187..516fa70a321e9 100644 --- a/packages/block-editor/src/components/color-palette/test/__snapshots__/control.js.snap +++ b/packages/block-editor/src/components/color-palette/test/__snapshots__/control.js.snap @@ -218,7 +218,7 @@ exports[`ColorPaletteControl matches the snapshot 1`] = ` ; + const { isPressed, ...additionalProps } = props; + return ( + + ); } const OptionAsButton = forwardRef( UnforwardedOptionAsButton ); @@ -48,7 +55,7 @@ function UnforwardedOptionAsOption( }, forwardedRef: ForwardedRef< any > ) { - const { id, className, isSelected, context, ...additionalProps } = props; + const { id, isSelected, context, ...additionalProps } = props; const { isComposite, ..._compositeState } = context; const compositeState = _compositeState as CircularOptionPickerCompositeState; @@ -73,15 +80,6 @@ function UnforwardedOptionAsOption( { ...compositeState } as={ Button } id={ id } - // Ideally we'd let the underlying `Button` component - // handle this by passing `isPressed` as a prop. - // Unfortunately doing so also sets `aria-pressed` as - // an attribute on the element, which is incompatible - // with `role="option"`, and there is no way at this - // point to override that behaviour. - className={ classnames( className, { - 'is-pressed': isSelected, - } ) } role="option" aria-selected={ !! isSelected } ref={ forwardedRef } diff --git a/packages/components/src/circular-option-picker/style.scss b/packages/components/src/circular-option-picker/style.scss index e0e4f3e81d419..a705bf62fdb11 100644 --- a/packages/components/src/circular-option-picker/style.scss +++ b/packages/components/src/circular-option-picker/style.scss @@ -83,7 +83,8 @@ $color-palette-circle-spacing: 12px; box-shadow: inset 0 0 0 ($color-palette-circle-size * 0.5) !important; } - &.is-pressed { + &[aria-pressed="true"], + &[aria-selected="true"] { box-shadow: inset 0 0 0 4px; position: relative; z-index: z-index(".components-circular-option-picker__option.is-pressed"); From ad530e9cd21a93c006a81094329d506b36523654 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Fri, 29 Sep 2023 12:51:37 +0200 Subject: [PATCH 19/23] [RNMobile] HTML mode: Add dark mode color to post title (#54927) * Add dark mode color to `HTMLTextInput` title * Update test snapshot --- .../components/src/mobile/html-text-input/index.native.js | 5 ++++- packages/components/src/mobile/html-text-input/style.scss | 4 ++++ .../html-text-input/test/__snapshots__/index.native.js.snap | 4 +++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/components/src/mobile/html-text-input/index.native.js b/packages/components/src/mobile/html-text-input/index.native.js index 18bdc2caa3ac0..16604bbc4e3eb 100644 --- a/packages/components/src/mobile/html-text-input/index.native.js +++ b/packages/components/src/mobile/html-text-input/index.native.js @@ -81,7 +81,10 @@ export class HTMLTextInput extends Component { title, } = this.props; const titleStyle = [ - styles.htmlViewTitle, + getStylesFromColorScheme( + styles.htmlViewTitle, + styles.htmlViewTitleDark + ), style?.text && { color: style.text }, ]; const htmlStyle = [ diff --git a/packages/components/src/mobile/html-text-input/style.scss b/packages/components/src/mobile/html-text-input/style.scss index 89b81e898ad4b..47102aca75504 100644 --- a/packages/components/src/mobile/html-text-input/style.scss +++ b/packages/components/src/mobile/html-text-input/style.scss @@ -37,3 +37,7 @@ $textColorDark: $white; .scrollView { flex: 1; } + +.htmlViewTitleDark { + color: $textColorDark; +} diff --git a/packages/components/src/mobile/html-text-input/test/__snapshots__/index.native.js.snap b/packages/components/src/mobile/html-text-input/test/__snapshots__/index.native.js.snap index ace4108a9968a..dd3272bef4d71 100644 --- a/packages/components/src/mobile/html-text-input/test/__snapshots__/index.native.js.snap +++ b/packages/components/src/mobile/html-text-input/test/__snapshots__/index.native.js.snap @@ -14,7 +14,9 @@ exports[`HTMLTextInput HTMLTextInput renders and matches snapshot 1`] = ` placeholderTextColor="white" style={ [ - undefined, + { + "color": "white", + }, undefined, ] } From b7dc65c429633f18adc2aef8f6224e5b068220a1 Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Fri, 29 Sep 2023 11:52:57 +0100 Subject: [PATCH 20/23] Revert "Fix warning when a template calls a template area twice (#54861)" (#54926) This reverts commit f637b3735300894e9698a3a5246a086c4454d4bd. --- packages/edit-site/src/store/utils.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/edit-site/src/store/utils.js b/packages/edit-site/src/store/utils.js index 2a8840c7104d8..af24684ace615 100644 --- a/packages/edit-site/src/store/utils.js +++ b/packages/edit-site/src/store/utils.js @@ -49,13 +49,8 @@ function getFilteredTemplatePartBlocks( blocks = EMPTY_ARRAY, templateParts ) { const templatePartId = `${ theme }//${ slug }`; const templatePart = templatePartsById[ templatePartId ]; - // Make sure we don't duplicate template parts. - const existingTemplatePart = result.find( - ( oneResult ) => oneResult.templatePart.id === templatePartId - ); - // Only add to output if the found template part block is in the list of available template parts. - if ( templatePart && ! existingTemplatePart ) { + if ( templatePart ) { result.push( { templatePart, block, From 9eaf30c97ada390273f0d12e49b968344dc919c1 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 29 Sep 2023 12:02:42 +0100 Subject: [PATCH 21/23] Remove word-wrap property (#54866) --- packages/block-library/src/navigation-link/style.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/block-library/src/navigation-link/style.scss b/packages/block-library/src/navigation-link/style.scss index 19080c8d38482..2a45c3c545d30 100644 --- a/packages/block-library/src/navigation-link/style.scss +++ b/packages/block-library/src/navigation-link/style.scss @@ -5,7 +5,6 @@ .wp-block-navigation { // This wraps just the innermost text for custom menu items. .wp-block-navigation-item__label { - word-break: normal; overflow-wrap: break-word; } From 5dec32e31ceaf8d87f527a348533ad7a0c7f5f8c Mon Sep 17 00:00:00 2001 From: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Date: Fri, 29 Sep 2023 20:31:05 +0900 Subject: [PATCH 22/23] Block custom CSS: Fix incorrect CSS when multiple root selectors (#53602) * Block custom CSS: Fix incorrect CSS when multiple root selectors * Fix PHP lint error * Use `scope_selector` and `append_to_selector` method and update unit test * Use `scopeSelector` and `appendToSelector` function and update JS unit test * Update packages/block-editor/src/components/global-styles/test/use-global-styles-output.js Co-authored-by: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> * Update packages/block-editor/src/components/global-styles/test/use-global-styles-output.js Co-authored-by: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> * Update packages/block-editor/src/components/global-styles/test/use-global-styles-output.js Co-authored-by: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> * Update packages/block-editor/src/components/global-styles/test/use-global-styles-output.js Co-authored-by: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> * Update packages/block-editor/src/components/global-styles/utils.js Co-authored-by: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> * re-trigger CI --------- Co-authored-by: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> --- lib/class-wp-theme-json-gutenberg.php | 20 ++++++++-- .../test/use-global-styles-output.js | 39 +++++++++++++++++++ .../global-styles/use-global-styles-output.js | 32 ++++++++++++--- .../src/components/global-styles/utils.js | 21 ++++++++++ phpunit/class-wp-theme-json-test.php | 28 ++++++++----- 5 files changed, 121 insertions(+), 19 deletions(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 59a3bbc3eb2ef..3aa07158df853 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -1145,9 +1145,23 @@ protected function process_blocks_custom_css( $css, $selector ) { // Split CSS nested rules. $parts = explode( '&', $css ); foreach ( $parts as $part ) { - $processed_css .= ( ! str_contains( $part, '{' ) ) - ? trim( $selector ) . '{' . trim( $part ) . '}' // If the part doesn't contain braces, it applies to the root level. - : trim( $selector . $part ); // Prepend the selector, which effectively replaces the "&" character. + $is_root_css = ( ! str_contains( $part, '{' ) ); + if ( $is_root_css ) { + // If the part doesn't contain braces, it applies to the root level. + $processed_css .= trim( $selector ) . '{' . trim( $part ) . '}'; + } else { + // If the part contains braces, it's a nested CSS rule. + $part = explode( '{', str_replace( '}', '', $part ) ); + if ( count( $part ) !== 2 ) { + continue; + } + $nested_selector = $part[0]; + $css_value = $part[1]; + $part_selector = str_starts_with( $nested_selector, ' ' ) + ? static::scope_selector( $selector, $nested_selector ) + : static::append_to_selector( $selector, $nested_selector ); + $processed_css .= $part_selector . '{' . trim( $css_value ) . '}'; + } } return $processed_css; } diff --git a/packages/block-editor/src/components/global-styles/test/use-global-styles-output.js b/packages/block-editor/src/components/global-styles/test/use-global-styles-output.js index 1aead846e95cd..b05381a8325b0 100644 --- a/packages/block-editor/src/components/global-styles/test/use-global-styles-output.js +++ b/packages/block-editor/src/components/global-styles/test/use-global-styles-output.js @@ -14,6 +14,7 @@ import { toCustomProperties, toStyles, getStylesDeclarations, + processCSSNesting, } from '../use-global-styles-output'; import { ROOT_BLOCK_SELECTOR } from '../utils'; @@ -967,4 +968,42 @@ describe( 'global styles renderer', () => { ] ); } ); } ); + + describe( 'processCSSNesting', () => { + it( 'should return processed CSS without any nested selectors', () => { + expect( + processCSSNesting( 'color: red; margin: auto;', '.foo' ) + ).toEqual( '.foo{color: red; margin: auto;}' ); + } ); + it( 'should return processed CSS with nested selectors', () => { + expect( + processCSSNesting( + 'color: red; margin: auto; &.one{color: blue;} & .two{color: green;}', + '.foo' + ) + ).toEqual( + '.foo{color: red; margin: auto;}.foo.one{color: blue;}.foo .two{color: green;}' + ); + } ); + it( 'should return processed CSS with pseudo elements', () => { + expect( + processCSSNesting( + 'color: red; margin: auto; &::before{color: blue;} & ::before{color: green;} &.one::before{color: yellow;} & .two::before{color: purple;}', + '.foo' + ) + ).toEqual( + '.foo{color: red; margin: auto;}.foo::before{color: blue;}.foo ::before{color: green;}.foo.one::before{color: yellow;}.foo .two::before{color: purple;}' + ); + } ); + it( 'should return processed CSS with multiple root selectors', () => { + expect( + processCSSNesting( + 'color: red; margin: auto; &.one{color: blue;} & .two{color: green;} &::before{color: yellow;} & ::before{color: purple;} &.three::before{color: orange;} & .four::before{color: skyblue;}', + '.foo, .bar' + ) + ).toEqual( + '.foo, .bar{color: red; margin: auto;}.foo.one, .bar.one{color: blue;}.foo .two, .bar .two{color: green;}.foo::before, .bar::before{color: yellow;}.foo ::before, .bar ::before{color: purple;}.foo.three::before, .bar.three::before{color: orange;}.foo .four::before, .bar .four::before{color: skyblue;}' + ); + } ); + } ); } ); diff --git a/packages/block-editor/src/components/global-styles/use-global-styles-output.js b/packages/block-editor/src/components/global-styles/use-global-styles-output.js index e32df90695b35..7e99eca355b52 100644 --- a/packages/block-editor/src/components/global-styles/use-global-styles-output.js +++ b/packages/block-editor/src/components/global-styles/use-global-styles-output.js @@ -15,7 +15,12 @@ import { getCSSRules } from '@wordpress/style-engine'; /** * Internal dependencies */ -import { PRESET_METADATA, ROOT_BLOCK_SELECTOR, scopeSelector } from './utils'; +import { + PRESET_METADATA, + ROOT_BLOCK_SELECTOR, + scopeSelector, + appendToSelector, +} from './utils'; import { getBlockCSSSelector } from './get-block-css-selector'; import { getTypographyFontSizeValue, @@ -1124,18 +1129,33 @@ function updateConfigWithSeparator( config ) { return config; } -const processCSSNesting = ( css, blockSelector ) => { +export function processCSSNesting( css, blockSelector ) { let processedCSS = ''; // Split CSS nested rules. const parts = css.split( '&' ); parts.forEach( ( part ) => { - processedCSS += ! part.includes( '{' ) - ? blockSelector + '{' + part + '}' // If the part doesn't contain braces, it applies to the root level. - : blockSelector + part; // Prepend the selector, which effectively replaces the "&" character. + const isRootCss = ! part.includes( '{' ); + if ( isRootCss ) { + // If the part doesn't contain braces, it applies to the root level. + processedCSS += `${ blockSelector }{${ part.trim() }}`; + } else { + // If the part contains braces, it's a nested CSS rule. + const splittedPart = part.replace( '}', '' ).split( '{' ); + if ( splittedPart.length !== 2 ) { + return; + } + + const [ nestedSelector, cssValue ] = splittedPart; + const combinedSelector = nestedSelector.startsWith( ' ' ) + ? scopeSelector( blockSelector, nestedSelector ) + : appendToSelector( blockSelector, nestedSelector ); + + processedCSS += `${ combinedSelector }{${ cssValue.trim() }}`; + } } ); return processedCSS; -}; +} /** * Returns the global styles output using a global styles configuration. diff --git a/packages/block-editor/src/components/global-styles/utils.js b/packages/block-editor/src/components/global-styles/utils.js index d4f2d959a3365..f4adb7a790312 100644 --- a/packages/block-editor/src/components/global-styles/utils.js +++ b/packages/block-editor/src/components/global-styles/utils.js @@ -393,6 +393,27 @@ export function scopeSelector( scope, selector ) { return selectorsScoped.join( ', ' ); } +/** + * Appends a sub-selector to an existing one. + * + * Given the compounded `selector` "h1, h2, h3" + * and the `toAppend` selector ".some-class" the result will be + * "h1.some-class, h2.some-class, h3.some-class". + * + * @param {string} selector Original selector. + * @param {string} toAppend Selector to append. + * + * @return {string} The new selector. + */ +export function appendToSelector( selector, toAppend ) { + if ( ! selector.includes( ',' ) ) { + return selector + toAppend; + } + const selectors = selector.split( ',' ); + const newSelectors = selectors.map( ( sel ) => sel + toAppend ); + return newSelectors.join( ',' ); +} + /** * Compares global style variations according to their styles and settings properties. * diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 39f308a5791f6..0e212983d9080 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -2007,29 +2007,37 @@ public function test_process_blocks_custom_css( $input, $expected ) { */ public function data_process_blocks_custom_css() { return array( - // Simple CSS without any child selectors. - 'no child selectors' => array( + // Simple CSS without any nested selectors. + 'no nested selectors' => array( 'input' => array( 'selector' => '.foo', 'css' => 'color: red; margin: auto;', ), 'expected' => '.foo{color: red; margin: auto;}', ), - // CSS with child selectors. - 'with children' => array( + // CSS with nested selectors. + 'with nested selector' => array( 'input' => array( 'selector' => '.foo', - 'css' => 'color: red; margin: auto; & .bar{color: blue;}', + 'css' => 'color: red; margin: auto; &.one{color: blue;} & .two{color: green;}', ), - 'expected' => '.foo{color: red; margin: auto;}.foo .bar{color: blue;}', + 'expected' => '.foo{color: red; margin: auto;}.foo.one{color: blue;}.foo .two{color: green;}', ), - // CSS with child selectors and pseudo elements. - 'with children and pseudo elements' => array( + // CSS with pseudo elements. + 'with pseudo elements' => array( 'input' => array( 'selector' => '.foo', - 'css' => 'color: red; margin: auto; & .bar{color: blue;} &::before{color: green;}', + 'css' => 'color: red; margin: auto; &::before{color: blue;} & ::before{color: green;} &.one::before{color: yellow;} & .two::before{color: purple;}', ), - 'expected' => '.foo{color: red; margin: auto;}.foo .bar{color: blue;}.foo::before{color: green;}', + 'expected' => '.foo{color: red; margin: auto;}.foo::before{color: blue;}.foo ::before{color: green;}.foo.one::before{color: yellow;}.foo .two::before{color: purple;}', + ), + // CSS with multiple root selectors. + 'with multiple root selectors' => array( + 'input' => array( + 'selector' => '.foo, .bar', + 'css' => 'color: red; margin: auto; &.one{color: blue;} & .two{color: green;} &::before{color: yellow;} & ::before{color: purple;} &.three::before{color: orange;} & .four::before{color: skyblue;}', + ), + 'expected' => '.foo, .bar{color: red; margin: auto;}.foo.one, .bar.one{color: blue;}.foo .two, .bar .two{color: green;}.foo::before, .bar::before{color: yellow;}.foo ::before, .bar ::before{color: purple;}.foo.three::before, .bar.three::before{color: orange;}.foo .four::before, .bar .four::before{color: skyblue;}', ), ); } From e58fc36ce9952ab3eaf55b9ee4659bafc903553a Mon Sep 17 00:00:00 2001 From: Andrew Hayward Date: Fri, 29 Sep 2023 12:32:14 +0100 Subject: [PATCH 23/23] Reverting addition of `aria-selected` style hook in `Button` (#54931) Reverting addition of `aria-selected` style hook in `Button` --- packages/components/CHANGELOG.md | 1 + packages/components/src/button/style.scss | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 986c7fa19b9ea..6f9291d27e1cd 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -15,6 +15,7 @@ - `DateTimePicker`: fix onChange callback check so that it also works inside iframes ([#54669](https://github.com/WordPress/gutenberg/pull/54669)). - `FormTokenField`: Add `box-sizing` reset style and reset default padding ([#54734](https://github.com/WordPress/gutenberg/pull/54734)). - `SlotFill`: Pass `Component` instance to unregisterSlot ([#54765](https://github.com/WordPress/gutenberg/pull/54765)). +- `Button`: Remove `aria-selected` CSS selector from styling 'active' buttons ([#54931](https://github.com/WordPress/gutenberg/pull/54931)). ### Internal diff --git a/packages/components/src/button/style.scss b/packages/components/src/button/style.scss index 2d212ed992621..0487d19db99df 100644 --- a/packages/components/src/button/style.scss +++ b/packages/components/src/button/style.scss @@ -309,8 +309,7 @@ // Toggled style. &[aria-pressed="true"], - &[aria-pressed="mixed"], - &[aria-selected="true"] { + &[aria-pressed="mixed"] { color: $components-color-foreground-inverted; background: $components-color-foreground;