diff --git a/.github/workflows/php-changes-detection.yml b/.github/workflows/php-changes-detection.yml deleted file mode 100644 index 2eeaea561eb7ed..00000000000000 --- a/.github/workflows/php-changes-detection.yml +++ /dev/null @@ -1,101 +0,0 @@ -name: OPTIONAL - Confirm if PHP changes require backporting to WordPress Core - -on: - pull_request: - types: [opened, synchronize] -jobs: - detect_php_changes: - name: Detect PHP changes - runs-on: ubuntu-latest - if: ${{ github.repository == 'WordPress/gutenberg' || github.event_name == 'pull_request' }} - steps: - - name: Check out code - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - with: - fetch-depth: 0 - show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - - - name: Get changed PHP files - id: changed-files-php - uses: tj-actions/changed-files@d6babd6899969df1a11d14c368283ea4436bca78 # v44.5.2 - with: - files: | - lib/** - packages/**/*.php - phpunit/** - - - name: List all changed files - if: steps.changed-files-php.outputs.any_changed == 'true' - id: list-changed-php-files - run: | - echo "Changed files:" - formatted_change_list="" - for file in ${{ steps.changed-files-php.outputs.all_changed_files }}; do - echo "$file was changed" - formatted_change_list+="
:grey_question: $file" - done - formatted_change_list+="
" - echo "formatted_change_list=$formatted_change_list" >> $GITHUB_OUTPUT - - - name: Find Comment - uses: peter-evans/find-comment@v3 - id: find-comment - with: - issue-number: ${{ github.event.pull_request.number }} - comment-author: 'github-actions[bot]' - body-includes: '' - - - name: Create comment - if: steps.find-comment.outputs.comment-id == '' && steps.changed-files-php.outputs.any_changed == 'true' - uses: peter-evans/create-or-update-comment@v4 - with: - issue-number: ${{ github.event.pull_request.number }} - body: | - - This pull request has changed or added PHP files. Please confirm whether these changes need to be synced to WordPress Core, and therefore featured in the next release of WordPress. - - If so, it is recommended to create a [new Trac ticket](https://core.trac.wordpress.org/newticket) and submit a pull request to the [WordPress Core Github repository](https://github.com/WordPress/wordpress-develop) soon after this pull request is merged. - - If you're unsure, you can always ask for help in the #core-editor channel in [WordPress Slack](https://make.wordpress.org/chat/). - - Thank you! :heart: - -
- View changed files - ${{ steps.list-changed-php-files.outputs.formatted_change_list }} -
- - - name: Update comment - if: steps.find-comment.outputs.comment-id != '' && steps.changed-files-php.outputs.any_changed == 'true' - uses: peter-evans/create-or-update-comment@v4 - with: - comment-id: ${{ steps.find-comment.outputs.comment-id }} - issue-number: ${{ github.event.pull_request.number }} - edit-mode: replace - body: | - - This pull request has changed or added PHP files. Please confirm whether these changes need to be synced to WordPress Core, and therefore featured in the next release of WordPress. - - If so, it is recommended to create a [new Trac ticket](https://core.trac.wordpress.org/newticket) and submit a pull request to the [WordPress Core Github repository](https://github.com/WordPress/wordpress-develop) soon after this pull request is merged. - - If you're unsure, you can always ask for help in the #core-editor channel in [WordPress Slack](https://make.wordpress.org/chat/). - - Thank you! :heart: - -
- View changed files - ${{ steps.list-changed-php-files.outputs.formatted_change_list }} -
- - - name: Update comment - if: steps.find-comment.outputs.comment-id != '' && steps.changed-files-php.outputs.any_changed != 'true' - uses: peter-evans/create-or-update-comment@v4 - with: - comment-id: ${{ steps.find-comment.outputs.comment-id }} - issue-number: ${{ github.event.pull_request.number }} - edit-mode: replace - body: | - - This pull request changed or added PHP files in previous commits, but none have been detected in the latest commit. - - Thank you! :heart: diff --git a/.github/workflows/upload-release-to-plugin-repo.yml b/.github/workflows/upload-release-to-plugin-repo.yml index 60ecacb2a8d705..9bb40a3f06cbc0 100644 --- a/.github/workflows/upload-release-to-plugin-repo.yml +++ b/.github/workflows/upload-release-to-plugin-repo.yml @@ -51,7 +51,7 @@ jobs: return $? } - # Only update trunk *if* the published release's version in Github is GREATER + # Only update trunk *if* the published release's version in GitHub is GREATER # than the version currently published in the WP plugins repo. If not, then it # will upload it as a new tag. shouldUpdateTrunk=false diff --git a/.prettierignore b/.prettierignore index 0b73d70681dbb0..642f7273d61043 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,7 +3,6 @@ build build-module build-types packages/block-serialization-spec-parser/parser.js -packages/e2e-tests/plugins packages/react-native-editor/bundle packages/url/src/test/fixtures vendor diff --git a/backport-changelog/6.6/6785.md b/backport-changelog/6.6/6785.md new file mode 100644 index 00000000000000..ad26227bf12565 --- /dev/null +++ b/backport-changelog/6.6/6785.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/6785 + +* https://github.com/WordPress/gutenberg/pull/62459 diff --git a/backport-changelog/6.6/6797.md b/backport-changelog/6.6/6797.md new file mode 100644 index 00000000000000..630b677655ddce --- /dev/null +++ b/backport-changelog/6.6/6797.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/6797 + +* https://github.com/WordPress/gutenberg/pull/62526 \ No newline at end of file diff --git a/backport-changelog/6.6/6824.md b/backport-changelog/6.6/6824.md new file mode 100644 index 00000000000000..7dc6e090f01498 --- /dev/null +++ b/backport-changelog/6.6/6824.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/6824 + +* https://github.com/WordPress/gutenberg/pull/62550 diff --git a/backport-changelog/6.6/6825.md b/backport-changelog/6.6/6825.md new file mode 100644 index 00000000000000..73e5f46600d892 --- /dev/null +++ b/backport-changelog/6.6/6825.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/6825 + +* https://github.com/WordPress/gutenberg/pull/62552 diff --git a/backport-changelog/6.6/6827.md b/backport-changelog/6.6/6827.md new file mode 100644 index 00000000000000..bfe177c4cac0e5 --- /dev/null +++ b/backport-changelog/6.6/6827.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/6827 + +* https://github.com/WordPress/gutenberg/pull/62465 diff --git a/backport-changelog/6.6/6837.md b/backport-changelog/6.6/6837.md new file mode 100644 index 00000000000000..2fffba68b53a10 --- /dev/null +++ b/backport-changelog/6.6/6837.md @@ -0,0 +1,4 @@ +https://github.com/WordPress/wordpress-develop/pull/6837 + +* https://github.com/WordPress/gutenberg/pull/62529 +* https://github.com/WordPress/gutenberg/pull/62610 diff --git a/backport-changelog/6.7/6750.md b/backport-changelog/6.7/6750.md new file mode 100644 index 00000000000000..257ebe3a5aa698 --- /dev/null +++ b/backport-changelog/6.7/6750.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/6750 + +* https://github.com/WordPress/gutenberg/pull/62357 \ No newline at end of file diff --git a/bin/cherry-pick.mjs b/bin/cherry-pick.mjs index d81bc017fc0be6..e6b2b6f0692a56 100644 --- a/bin/cherry-pick.mjs +++ b/bin/cherry-pick.mjs @@ -466,7 +466,7 @@ function getCurrentBranch() { */ async function reportGhUnavailable() { console.log( - 'Github CLI is not setup. This script will not be able to automatically' + 'GitHub CLI is not setup. This script will not be able to automatically' ); console.log( 'comment on the processed PRs and remove the backport label from them.' diff --git a/bin/packages/build-worker.js b/bin/packages/build-worker.js index 3f1512ef0feb78..06e30efc6c6dc9 100644 --- a/bin/packages/build-worker.js +++ b/bin/packages/build-worker.js @@ -13,6 +13,8 @@ const postcss = require( 'postcss' ); */ const getBabelConfig = require( './get-babel-config' ); +const isDev = process.env.NODE_ENV === 'development'; + /** * Path to packages directory. * @@ -27,10 +29,12 @@ const PACKAGES_DIR = path * * @type {Object} */ -const JS_ENVIRONMENTS = { - main: 'build', - module: 'build-module', -}; +const JS_ENVIRONMENTS = isDev + ? { module: 'build-module' } + : { + main: 'build', + module: 'build-module', + }; /** * Promisified fs.readFile. @@ -122,9 +126,10 @@ async function buildCSS( file ) { data: ''.concat( '@use "sass:math";', importLists, contents ), } ); - const result = await postcss( - require( '@wordpress/postcss-plugins-preset' ) - ).process( builtSass.css, { + const result = await postcss( [ + require( 'postcss-local-keyframes' ), + ...require( '@wordpress/postcss-plugins-preset' ), + ] ).process( builtSass.css, { from: 'src/app.css', to: 'dest/app.css', } ); diff --git a/bin/packages/check-build-type-declaration-files.js b/bin/packages/check-build-type-declaration-files.js index 3d70145ceb588e..ffc68c83b8da8e 100644 --- a/bin/packages/check-build-type-declaration-files.js +++ b/bin/packages/check-build-type-declaration-files.js @@ -70,7 +70,7 @@ async function getDecFile( packagePath ) { async function typecheckDeclarations( file ) { return new Promise( ( resolve, reject ) => { exec( - `npx tsc --target esnext --moduleResolution node --noEmit "${ file }"`, + `npx tsc --target esnext --moduleResolution node --noEmit --skipLibCheck "${ file }"`, ( error, stdout, stderr ) => { if ( error ) { reject( { file, error, stderr, stdout } ); diff --git a/bin/plugin/commands/changelog.js b/bin/plugin/commands/changelog.js index 652c6e97a6c0a2..43164a80ab24a4 100644 --- a/bin/plugin/commands/changelog.js +++ b/bin/plugin/commands/changelog.js @@ -606,11 +606,11 @@ function getEntry( issue ) { /** * Builds a formatted string of the Issue/PR title with a link - * to the Github URL for that item. + * to the GitHub URL for that item. * * @param {string} title the title of the Issue/PR. * @param {number} number the ID/number of the Issue/PR. - * @param {string} url the URL of the Github Issue/PR. + * @param {string} url the URL of the GitHub Issue/PR. * @return {string} the formatted item */ function getFormattedItemDescription( title, number, url ) { @@ -856,7 +856,7 @@ function sortFeatureGroups( featureGroups ) { } /** - * Returns a list of PRs created by first time contributors based on the Github + * Returns a list of PRs created by first time contributors based on the GitHub * label associated with the PR. Also filters out any "bots". * * @param {IssuesListForRepoResponseItem[]} pullRequests List of pull requests. diff --git a/bin/plugin/commands/test/changelog.js b/bin/plugin/commands/test/changelog.js index 12420fd1e4b6f9..9c9d423d18d1cb 100644 --- a/bin/plugin/commands/test/changelog.js +++ b/bin/plugin/commands/test/changelog.js @@ -25,7 +25,7 @@ import _pullRequests from './fixtures/pull-requests.json'; import botPullRequestFixture from './fixtures/bot-pull-requests.json'; /** - * pull-requests.json is a static snapshot of real data from the Github API. + * pull-requests.json is a static snapshot of real data from the GitHub API. * We merge this with dummy fixture data for a "bot" pull request so as to * ensure future updates to the pull-requests.json doesn't reduce test coverage * of filtering out of bot PRs. diff --git a/changelog.txt b/changelog.txt index decdb88ea9a7a4..8679f4a40ba9ec 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1378,7 +1378,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@tellthemachines @arthur791004 +@tellthemachines @arthur791004 = 18.1.1 = @@ -1392,7 +1392,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@okmttdhr @ntsekouras +@okmttdhr @ntsekouras = 18.1.0 = @@ -2423,7 +2423,7 @@ The following contributors merged PRs in this release: - Rich text: Fix typing into empty flex element. ([59473](https://github.com/WordPress/gutenberg/pull/59473)) - URLPopover: Fix a problem with the layout of link settings. ([58906](https://github.com/WordPress/gutenberg/pull/58906)) - Fix issue with appender jumping when creating a new pattern. ([59582](https://github.com/WordPress/gutenberg/pull/59582)) -- Allow event bubbling even if keydown is passed. ([59474](https://github.com/WordPress/gutenberg/pull/59474)) +- Allow event bubbling even if keydown is passed. ([59474](https://github.com/WordPress/gutenberg/pull/59474)) #### Custom Fields - Block Bindings: Fix console error when selecting a bound block. ([59598](https://github.com/WordPress/gutenberg/pull/59598)) @@ -3344,7 +3344,7 @@ The following contributors merged PRs in this release: - Docs: Copy and formatting edits for the "Static or Dynamic rendering" guide. ([58681](https://github.com/WordPress/gutenberg/pull/58681)) - Docs: Copy and formatting edits for the "The block in the Editor" guide. ([58697](https://github.com/WordPress/gutenberg/pull/58697)) - Docs: Copy and formatting edits for the "The block wrapper" guide. ([58704](https://github.com/WordPress/gutenberg/pull/58704)) -- Docs: Copy and formatting edits for the "Working with Javascript for the Block Editor" guide. ([58651](https://github.com/WordPress/gutenberg/pull/58651)) +- Docs: Copy and formatting edits for the "Working with JavaScript for the Block Editor" guide. ([58651](https://github.com/WordPress/gutenberg/pull/58651)) - Docs: Copy and formatting edits for the "block.json" guide. ([58732](https://github.com/WordPress/gutenberg/pull/58732)) - Docs: Copy edits and list formatting for main Block Editor Handbook readme. ([58652](https://github.com/WordPress/gutenberg/pull/58652)) - Docs: Fix list formatting and some grammar in the Entities explanation doc. ([58655](https://github.com/WordPress/gutenberg/pull/58655)) @@ -3563,7 +3563,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@ramonjd +@ramonjd = 17.7.0-rc.1 = @@ -3918,7 +3918,7 @@ The following contributors merged PRs in this release: - Docs: Copy and formatting edits for the "Static or Dynamic rendering" guide. ([58681](https://github.com/WordPress/gutenberg/pull/58681)) - Docs: Copy and formatting edits for the "The block in the Editor" guide. ([58697](https://github.com/WordPress/gutenberg/pull/58697)) - Docs: Copy and formatting edits for the "The block wrapper" guide. ([58704](https://github.com/WordPress/gutenberg/pull/58704)) -- Docs: Copy and formatting edits for the "Working with Javascript for the Block Editor" guide. ([58651](https://github.com/WordPress/gutenberg/pull/58651)) +- Docs: Copy and formatting edits for the "Working with JavaScript for the Block Editor" guide. ([58651](https://github.com/WordPress/gutenberg/pull/58651)) - Docs: Copy and formatting edits for the "block.json" guide. ([58732](https://github.com/WordPress/gutenberg/pull/58732)) - Docs: Copy edits and list formatting for main Block Editor Handbook readme. ([58652](https://github.com/WordPress/gutenberg/pull/58652)) - Docs: Fix list formatting and some grammar in the Entities explanation doc. ([58655](https://github.com/WordPress/gutenberg/pull/58655)) @@ -4145,7 +4145,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@dd32 +@dd32 = 17.6.2 = @@ -4663,7 +4663,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@andrewserong @t-hamano @luisherranz @pbking +@andrewserong @t-hamano @luisherranz @pbking = 17.6.0-rc.1 = @@ -5090,7 +5090,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@fullofcaffeine +@fullofcaffeine @@ -5107,7 +5107,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@youknowriad @fullofcaffeine +@youknowriad @fullofcaffeine @@ -5380,7 +5380,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@glendaviesnz +@glendaviesnz @@ -5412,7 +5412,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@ellatrix +@ellatrix @@ -5487,7 +5487,7 @@ The following contributors merged PRs in this release: - Gallery: Hide some controls when multi-editing blocks. ([57378](https://github.com/WordPress/gutenberg/pull/57378)) - Image Block: Get lightbox trigger button ref via data-wp-init. ([57089](https://github.com/WordPress/gutenberg/pull/57089)) - Image: Hide caption control when multi-editing images. ([57357](https://github.com/WordPress/gutenberg/pull/57357)) -- Video: Hide some controls when multi-editing blocks. ([57375](https://github.com/WordPress/gutenberg/pull/57375)) +- Video: Hide some controls when multi-editing blocks. ([57375](https://github.com/WordPress/gutenberg/pull/57375)) - Image Block: Fix deprecation when width/height attribute is number. ([57063](https://github.com/WordPress/gutenberg/pull/57063)) #### Patterns @@ -5500,7 +5500,7 @@ The following contributors merged PRs in this release: - Fix image upload bug. ([57040](https://github.com/WordPress/gutenberg/pull/57040)) - Reduce clearance around the Frame in the site editor. ([57023](https://github.com/WordPress/gutenberg/pull/57023)) - Swap Template: Show the right templates for the right post type. ([57149](https://github.com/WordPress/gutenberg/pull/57149)) -- Save Button: Fix the translation of the Activate button. ([57147](https://github.com/WordPress/gutenberg/pull/57147)) +- Save Button: Fix the translation of the Activate button. ([57147](https://github.com/WordPress/gutenberg/pull/57147)) - SlotFill: Allow contextual SlotFillProviders. ([56779](https://github.com/WordPress/gutenberg/pull/56779)) #### Post Editor @@ -5729,7 +5729,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@glendaviesnz +@glendaviesnz @@ -6418,7 +6418,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@jorgefilipecosta +@jorgefilipecosta = 17.2.0 = @@ -6662,7 +6662,7 @@ The following contributors merged PRs in this release: - Docs: Fundamentals of Block Development - File structure of a block. ([56551](https://github.com/WordPress/gutenberg/pull/56551)) - Docs: Fundamentals of Block Development - Registration of a block. ([56334](https://github.com/WordPress/gutenberg/pull/56334)) - Docs: Fundamentals of Block Development - The block wrapper. ([56596](https://github.com/WordPress/gutenberg/pull/56596)) -- Docs: Fundamentals of Block Development - Working with Javascript in the Block Editor. ([56553](https://github.com/WordPress/gutenberg/pull/56553)) +- Docs: Fundamentals of Block Development - Working with JavaScript in the Block Editor. ([56553](https://github.com/WordPress/gutenberg/pull/56553)) - Docs: Fundamentals of Block Development - block.json. ([56435](https://github.com/WordPress/gutenberg/pull/56435)) - Docs: Improve downloadBlob example. ([56225](https://github.com/WordPress/gutenberg/pull/56225)) - Documentation - Block Editor Handbook - Add end user documentation about Block Editor as a resource on the Landing Page of the Block Editor Handbook. ([49854](https://github.com/WordPress/gutenberg/pull/49854)) @@ -6991,7 +6991,7 @@ The following contributors merged PRs in this release: - Docs: Fundamentals of Block Development - File structure of a block. ([56551](https://github.com/WordPress/gutenberg/pull/56551)) - Docs: Fundamentals of Block Development - Registration of a block. ([56334](https://github.com/WordPress/gutenberg/pull/56334)) - Docs: Fundamentals of Block Development - The block wrapper. ([56596](https://github.com/WordPress/gutenberg/pull/56596)) -- Docs: Fundamentals of Block Development - Working with Javascript in the Block Editor. ([56553](https://github.com/WordPress/gutenberg/pull/56553)) +- Docs: Fundamentals of Block Development - Working with JavaScript in the Block Editor. ([56553](https://github.com/WordPress/gutenberg/pull/56553)) - Docs: Fundamentals of Block Development - block.json. ([56435](https://github.com/WordPress/gutenberg/pull/56435)) - Docs: Improve downloadBlob example. ([56225](https://github.com/WordPress/gutenberg/pull/56225)) - Documentation - Block Editor Handbook - Add end user documentation about Block Editor as a resource on the Landing Page of the Block Editor Handbook. ([49854](https://github.com/WordPress/gutenberg/pull/49854)) @@ -8077,7 +8077,7 @@ The following contributors merged PRs in this release: ## Changelog This copies the commits from the 16.7.1 patch release into the 16.8.0 main release. - + ### Tools #### Build Tooling @@ -9536,7 +9536,7 @@ The following contributors merged PRs in this release: - Button: Remove default border from the destructive button. ([53607](https://github.com/WordPress/gutenberg/pull/53607)) - LineHeightControl: Allow for more granular control of decimal places. ([52902](https://github.com/WordPress/gutenberg/pull/52902)) - Snackbar: Design and motion improvements. ([53248](https://github.com/WordPress/gutenberg/pull/53248)) -- Modal: +- Modal: - Add `headerActions` prop to enable buttons or other elements to be injected in the header. ([53328](https://github.com/WordPress/gutenberg/pull/53328)) - Enhance overlay interactions, enabling outside interactions without dismissal. ([52994](https://github.com/WordPress/gutenberg/pull/52994)) - ProgressBar: Update colors, including gray 300 for track color ([53349](https://github.com/WordPress/gutenberg/pull/53349)), theme system accent for indicator color ([53347](https://github.com/WordPress/gutenberg/pull/53347)), and the theme accent color variable. ([53632](https://github.com/WordPress/gutenberg/pull/53632)). @@ -9546,7 +9546,7 @@ The following contributors merged PRs in this release: - Add a `stretch` option to block's vertical alignment options. ([53325](https://github.com/WordPress/gutenberg/pull/53325)) - Exit upon pressing enter in an empty paragraph at the end of the block. ([53311](https://github.com/WordPress/gutenberg/pull/53311)) - Classic block: Increase dimensions of modal and allow toggling fullscreen. ([53449](https://github.com/WordPress/gutenberg/pull/53449)) -- Details block: +- Details block: - Add `accordion` and `toggle` keywords to improve block's discoverability. ([53501](https://github.com/WordPress/gutenberg/pull/53501)) - Add layout and block spacing options. ([53282](https://github.com/WordPress/gutenberg/pull/53282)) - File block: Add block spacing options. ([45107](https://github.com/WordPress/gutenberg/pull/45107)) @@ -9586,7 +9586,7 @@ The following contributors merged PRs in this release: ### Bug Fixes -#### Commands +#### Commands - Style tweaks to fix metrics for resting and no results view in command palette. ([53497](https://github.com/WordPress/gutenberg/pull/53497)) - Order template results in Site Editor, to fix some templates not displaying. ([53286](https://github.com/WordPress/gutenberg/pull/53286)) - Don't allow access to Styles-related pages via the command palette in the hybrid theme. ([53123](https://github.com/WordPress/gutenberg/pull/53123)) @@ -9594,12 +9594,12 @@ The following contributors merged PRs in this release: #### Block Library - Button block: Avoid losing user changes when the `ButtonEdit` component re-renders. ([53507](https://github.com/WordPress/gutenberg/pull/53507)) - Cover block: Fix flickering when inserted in templates and also fix `isDark` calculation bugs. ([53253](https://github.com/WordPress/gutenberg/pull/53253)) -- Footnotes block: +- Footnotes block: - Ensure autosave works and escapes quotes as expected. ([53664](https://github.com/WordPress/gutenberg/pull/53664)) - Fix accidental override. ([53663](https://github.com/WordPress/gutenberg/pull/53663)) - Fix recursion into updating attributes when attributes is not an object. ([53257](https://github.com/WordPress/gutenberg/pull/53257)) - Remove Footnotes when interactive formatting is disabled. ([53474](https://github.com/WordPress/gutenberg/pull/53474)) -- Image block: +- Image block: - Fix image stretching with only height. ([53443](https://github.com/WordPress/gutenberg/pull/53443)) - Don't render `DimensionsTool` if it is not resizable. ([53181](https://github.com/WordPress/gutenberg/pull/53181)) - Fix stretched images constrained by max-width. ([53274](https://github.com/WordPress/gutenberg/pull/53274)) @@ -9715,7 +9715,7 @@ The following contributors merged PRs in this release: - Fix outdated specification in the "Anatomy of a Block". ([53581](https://github.com/WordPress/gutenberg/pull/53581)) #### How To Guides -- Block Tutorial: +- Block Tutorial: - Adds import from `@wordpress/i18n` in code example. ([53504](https://github.com/WordPress/gutenberg/pull/53504)) - Adds package.json configuration instructions to tutorial. ([53689](https://github.com/WordPress/gutenberg/pull/53689)) - Building a Custom Block Editor: Consolidate and update the guide. ([53159](https://github.com/WordPress/gutenberg/pull/53159)) @@ -9731,7 +9731,7 @@ The following contributors merged PRs in this release: - Edit Post: Update "PluginDocumentSettingPanel" documentation. ([53393](https://github.com/WordPress/gutenberg/pull/53393)) - Interface: Fix "complimentary" typo with "complementary". ([53413](https://github.com/WordPress/gutenberg/pull/53413)) -#### Interactivity API +#### Interactivity API - Revamp of README to include API Reference among other indications. ([53385](https://github.com/WordPress/gutenberg/pull/53385)) - Add missing section in ToC and minor improvements to Getting Started Guide. ([53362](https://github.com/WordPress/gutenberg/pull/53362)) - Update Interactivity API package README with clear references to documentation. ([53388](https://github.com/WordPress/gutenberg/pull/53388)) @@ -9753,7 +9753,7 @@ The following contributors merged PRs in this release: #### Block Library - Button block: Replace the `isSmall` deprecated prop in the `WidthPanel`. ([53472](https://github.com/WordPress/gutenberg/pull/53472)) - Details block: Remove unnecessary comment attributes. ([51610](https://github.com/WordPress/gutenberg/pull/51610)) -- Footnotes block: +- Footnotes block: - Add some test coverage for footnotes logic in useEntityBlockEditor. ([53376](https://github.com/WordPress/gutenberg/pull/53376)) - Checking type before using count(). ([53660](https://github.com/WordPress/gutenberg/pull/53660)) - LinkControl/LinkUI: Remove unused `className` prop. ([53348](https://github.com/WordPress/gutenberg/pull/53348)) @@ -10121,7 +10121,7 @@ The following contributors merged PRs in this release: ### Tools - Add GH action to enforce PR labels. ([52760](https://github.com/WordPress/gutenberg/pull/52760)) -- Changelog automation: +- Changelog automation: - Make Accessibility a top-level section. ([52900](https://github.com/WordPress/gutenberg/pull/52900)) - Update to work with consolidated a11y labels. ([52896](https://github.com/WordPress/gutenberg/pull/52896)) - Use the correct label to filter Mobile app PRs. ([53024](https://github.com/WordPress/gutenberg/pull/53024)) @@ -10420,7 +10420,7 @@ The following contributors merged PRs in this release: #### Project Management - Update issue gardening automation with new label. ([52173](https://github.com/WordPress/gutenberg/pull/52173)) - Revert "Update Changelog for 16.1.2". ([52433](https://github.com/WordPress/gutenberg/pull/52433)) -- Github workflow: Add a PHP backport changes action. ([52096](https://github.com/WordPress/gutenberg/pull/52096)) +- GitHub workflow: Add a PHP backport changes action. ([52096](https://github.com/WordPress/gutenberg/pull/52096)) ## First time contributors @@ -10459,7 +10459,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@getdave @mcsf +@getdave @mcsf = 16.2.0 = @@ -10523,13 +10523,13 @@ The following contributors merged PRs in this release: - Footnotes: save numbering through the entity provider (https://github.com/WordPress/gutenberg/pull/52423) #### Code Quality / Performance -- Iframe: avoid asset parsing & fix script localisation +- Iframe: avoid asset parsing & fix script localisation ## Contributors The following contributors merged PRs in this release: -@ellatrix @ockham @t-hamano +@ellatrix @ockham @t-hamano = 16.2.0-rc.1 = @@ -10782,7 +10782,7 @@ The following contributors merged PRs in this release: - Update delete page button label. ([51812](https://github.com/WordPress/gutenberg/pull/51812)) - Update versions in WP for 6.3. ([51984](https://github.com/WordPress/gutenberg/pull/51984)) - Wrap "Move to trash" and "Switch to draft" buttons when labels are too long to fit on a single row. ([52249](https://github.com/WordPress/gutenberg/pull/52249)) -- [Github-Actions-Workflows][Plugin-Release] Allow shipping a point-release for an older stable release. ([49082](https://github.com/WordPress/gutenberg/pull/49082)) +- [GitHub-Actions-Workflows][Plugin-Release] Allow shipping a point-release for an older stable release. ([49082](https://github.com/WordPress/gutenberg/pull/49082)) #### Block Library - Block Editor: Unify texts for Create pattern modal. ([52151](https://github.com/WordPress/gutenberg/pull/52151)) @@ -11097,7 +11097,7 @@ The following contributors merged PRs in this release: - Update delete page button label. ([51812](https://github.com/WordPress/gutenberg/pull/51812)) - Update versions in WP for 6.3. ([51984](https://github.com/WordPress/gutenberg/pull/51984)) - Wrap "Move to trash" and "Switch to draft" buttons when labels are too long to fit on a single row. ([52249](https://github.com/WordPress/gutenberg/pull/52249)) -- [Github-Actions-Workflows][Plugin-Release] Allow shipping a point-release for an older stable release. ([49082](https://github.com/WordPress/gutenberg/pull/49082)) +- [GitHub-Actions-Workflows][Plugin-Release] Allow shipping a point-release for an older stable release. ([49082](https://github.com/WordPress/gutenberg/pull/49082)) #### Block Library - Block Editor: Unify texts for Create pattern modal. ([52151](https://github.com/WordPress/gutenberg/pull/52151)) @@ -11423,7 +11423,7 @@ The following contributors merged PRs in this release: #### Block Variations - [Block Library - Post Terms]: Custom taxonomies do not show icons when transforming from the toolbar. ([51476](https://github.com/WordPress/gutenberg/pull/51476)) -#### Page Content Focus +#### Page Content Focus - Switch to Page panel when deselecting a block [51881](https://github.com/WordPress/gutenberg/pull/51881) - Don't show 'Back to page' notification when navigating away from page [51880](https://github.com/WordPress/gutenberg/pull/51880) - useBlockSync(): Reset inner blocks when component unmounts [51783](https://github.com/WordPress/gutenberg/pull/51783) @@ -11563,7 +11563,7 @@ The following contributors merged PRs in this release: - Babel config: Enable useSpread option for JSX transform to reduce transpilation. ([51574](https://github.com/WordPress/gutenberg/pull/51574)) - Lodash: Remove from lint staged type check. ([51698](https://github.com/WordPress/gutenberg/pull/51698)) - Performance Tests: Update the base point to compare against. ([51689](https://github.com/WordPress/gutenberg/pull/51689)) -- wp-env: Try to fix failing PHP Github actions. ([51513](https://github.com/WordPress/gutenberg/pull/51513)) +- wp-env: Try to fix failing PHP GitHub actions. ([51513](https://github.com/WordPress/gutenberg/pull/51513)) - npm lockfile: Hoist reakit and date-fns packages to the top. ([51500](https://github.com/WordPress/gutenberg/pull/51500)) #### Plugin @@ -11582,7 +11582,7 @@ The following PRs were merged by first time contributors: The following contributors merged PRs in this release: -@aaronrobertshaw @afercia @alexstine @andrewserong @aristath @artemiomorales @aurooba @bangank36 @c4rl0sbr4v0 @carolinan @ciampo @dcalhoun @derekblank @diegohaz @draganescu @ellatrix @fabiankaegy @fluiddot @geriux @getdave @glendaviesnz @jameskoster @jasmussen @jeryj @jhnstn @jsnajdr @juanfra @kozer @luisherranz @MaggieCabrera @Mamaduka @matiasbenedetto @mcliwanow @mcsf @mikachan @n2erjo00 @noahtallen @noisysocks @ntsekouras @oandregal @okmttdhr @paulopmt1 @pbking @peterwilsoncc @pooja-muchandikar @ramonjd @richtabor @samnajian @SantosGuillamot @SavPhill @SaxonF @scruffian @shimotmk @Sidsector9 @SiobhyB @spacedmonkey @stokesman @sunyatasattva @t-hamano @talldan @tellthemachines @tyxla @walbo @WunderBart @xerpa43 @youknowriad @priethor @ajlende @mirka +@aaronrobertshaw @afercia @alexstine @andrewserong @aristath @artemiomorales @aurooba @bangank36 @c4rl0sbr4v0 @carolinan @ciampo @dcalhoun @derekblank @diegohaz @draganescu @ellatrix @fabiankaegy @fluiddot @geriux @getdave @glendaviesnz @jameskoster @jasmussen @jeryj @jhnstn @jsnajdr @juanfra @kozer @luisherranz @MaggieCabrera @Mamaduka @matiasbenedetto @mcliwanow @mcsf @mikachan @n2erjo00 @noahtallen @noisysocks @ntsekouras @oandregal @okmttdhr @paulopmt1 @pbking @peterwilsoncc @pooja-muchandikar @ramonjd @richtabor @samnajian @SantosGuillamot @SavPhill @SaxonF @scruffian @shimotmk @Sidsector9 @SiobhyB @spacedmonkey @stokesman @sunyatasattva @t-hamano @talldan @tellthemachines @tyxla @walbo @WunderBart @xerpa43 @youknowriad @priethor @ajlende @mirka @@ -11840,7 +11840,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@hellofromtonya @ndiego +@hellofromtonya @ndiego = 15.9.0 = @@ -11900,7 +11900,7 @@ The following contributors merged PRs in this release: - Remove `unwrap` from transforms and add `ungroup` to more blocks. ([50385](https://github.com/WordPress/gutenberg/pull/50385)) - Add new API to allow inserter items to be prioritised. ([50510](https://github.com/WordPress/gutenberg/pull/50510)) - Integrate `prioritizedInserterBlocks` API to slash inserter. ([50658](https://github.com/WordPress/gutenberg/pull/50658)) - + #### Global Styles - Custom CSS: Force display of in custom css input boxes to LTR. ([50768](https://github.com/WordPress/gutenberg/pull/50768)) - Styles Navigation Screen: Add Style Book. ([50566](https://github.com/WordPress/gutenberg/pull/50566)) @@ -11919,7 +11919,7 @@ The following contributors merged PRs in this release: #### Accessibility - Modals: Update the Cancel action's button design. ([50544](https://github.com/WordPress/gutenberg/pull/50544)) - Writing flow: Improve keyboard navigation on certain input types. ([43667](https://github.com/WordPress/gutenberg/pull/43667)) - + #### Icons - Add new `HeadingLevel` icons. ([50856](https://github.com/WordPress/gutenberg/pull/50856)) - Smaller external link icon. ([50728](https://github.com/WordPress/gutenberg/pull/50728)) @@ -12631,7 +12631,7 @@ Continued the work refactor away from Lodash usages to reduce the build size - Re-write of the landing page. ([49643](https://github.com/WordPress/gutenberg/pull/49643)) - Improve insertBlock(s) documentation. ([50078](https://github.com/WordPress/gutenberg/pull/50078)) - Small Typo: Remove dots. ([49853](https://github.com/WordPress/gutenberg/pull/49853)) - + ### Code Quality - Fix PrivateInserter import. ([50038](https://github.com/WordPress/gutenberg/pull/50038)) @@ -12649,7 +12649,7 @@ Continued the work refactor away from Lodash usages to reduce the build size - Migrate CPT end-to-end tests to Playwright. ([50031](https://github.com/WordPress/gutenberg/pull/50031)) - Fonts API: Add tests for gutenberg_add_registered_fonts_to_theme_json(). ([50049](https://github.com/WordPress/gutenberg/pull/50049)) - Expand multi-line block tests. ([49732](https://github.com/WordPress/gutenberg/pull/49732)) -- Rich text test helpers mimic user events. ([49804](https://github.com/WordPress/gutenberg/pull/49804)) +- Rich text test helpers mimic user events. ([49804](https://github.com/WordPress/gutenberg/pull/49804)) - Fix editor canvas detaching error in end-to-end tests. ([49374](https://github.com/WordPress/gutenberg/pull/49374)) #### Build Tooling @@ -12819,7 +12819,7 @@ The following contributors merged PRs in this release: ### Performance -- Continued the work refactor away from Lodash usages to reduce the build size +- Continued the work refactor away from Lodash usages to reduce the build size ([49725](https://github.com/WordPress/gutenberg/pull/49725), [49724](https://github.com/WordPress/gutenberg/pull/49724), [49638](https://github.com/WordPress/gutenberg/pull/49638), [49654](https://github.com/WordPress/gutenberg/pull/49654), [49639](https://github.com/WordPress/gutenberg/pull/49639), [49637](https://github.com/WordPress/gutenberg/pull/49637), [49727](https://github.com/WordPress/gutenberg/pull/49727)) ### Documentation @@ -13515,7 +13515,7 @@ The following contributors merged PRs in this release: - Create automatic change higher order reducer. ([48312](https://github.com/WordPress/gutenberg/pull/48312)) - [Inserter]: Preload media categories empty check - client side. ([47503](https://github.com/WordPress/gutenberg/pull/47503)) -#### Post Editor +#### Post Editor - Revert iframed editor for WP core only. ([48076](https://github.com/WordPress/gutenberg/pull/48076)) - PageAttributesCheck: Return boolean value directly from the selector. ([48336](https://github.com/WordPress/gutenberg/pull/48336)) - Apply busy status to the publish button in progress and unify button width. ([48444](https://github.com/WordPress/gutenberg/pull/48444)) @@ -13633,7 +13633,7 @@ The following contributors merged PRs in this release: ### Performance -#### Block Editor +#### Block Editor - Block Editor: Improve empty `getBlockParents()` perf. ([48242](https://github.com/WordPress/gutenberg/pull/48242)) - Fix perf regression in duotone hooks. ([48401](https://github.com/WordPress/gutenberg/pull/48401)) - Writing flow: Avoid recalc style on every selection change. ([48409](https://github.com/WordPress/gutenberg/pull/48409)) @@ -13664,7 +13664,7 @@ The following contributors merged PRs in this release: - Lodash: Remove some `_.get()` from Image block. ([48489](https://github.com/WordPress/gutenberg/pull/48489)) - Playwright: Fix request utils for non Docker envs. ([48206](https://github.com/WordPress/gutenberg/pull/48206)) - [Private APIs] Only prevent module re-registration if IS_WORDPRESS_CORE. ([48352](https://github.com/WordPress/gutenberg/pull/48352)) -- Add a manual performance job that we can trigger from Github UI. ([48302](https://github.com/WordPress/gutenberg/pull/48302)) +- Add a manual performance job that we can trigger from GitHub UI. ([48302](https://github.com/WordPress/gutenberg/pull/48302)) - Track new front-end metric: LCP-TTFB. ([48288](https://github.com/WordPress/gutenberg/pull/48288)) ### Documentation @@ -13678,7 +13678,7 @@ The following contributors merged PRs in this release: - Updates to the curating the editor experience to include 6.1 & 6.2 items. ([48294](https://github.com/WordPress/gutenberg/pull/48294)) ### Tools -#### Testing +#### Testing - Migrate `switch-to-draft` to Playwright. ([48120](https://github.com/WordPress/gutenberg/pull/48120)) - VizReg end-to-end tests: Programmatically test all combinations of a given list of props/values. ([48260](https://github.com/WordPress/gutenberg/pull/48260)) - Update end-to-end test snapshots to Jest 29 default. ([48626](https://github.com/WordPress/gutenberg/pull/48626)) @@ -13740,7 +13740,7 @@ The following contributors merged PRs in this release: - Create automatic change higher order reducer. ([48312](https://github.com/WordPress/gutenberg/pull/48312)) - [Inserter]: Preload media categories empty check - client side. ([47503](https://github.com/WordPress/gutenberg/pull/47503)) -#### Post Editor +#### Post Editor - Revert iframed editor for WP core only. ([48076](https://github.com/WordPress/gutenberg/pull/48076)) - PageAttributesCheck: Return boolean value directly from the selector. ([48336](https://github.com/WordPress/gutenberg/pull/48336)) - Apply busy status to the publish button in progress and unify button width. ([48444](https://github.com/WordPress/gutenberg/pull/48444)) @@ -13858,7 +13858,7 @@ The following contributors merged PRs in this release: ### Performance -#### Block Editor +#### Block Editor - Block Editor: Improve empty `getBlockParents()` perf. ([48242](https://github.com/WordPress/gutenberg/pull/48242)) - Fix perf regression in duotone hooks. ([48401](https://github.com/WordPress/gutenberg/pull/48401)) - Writing flow: Avoid recalc style on every selection change. ([48409](https://github.com/WordPress/gutenberg/pull/48409)) @@ -13889,7 +13889,7 @@ The following contributors merged PRs in this release: - Lodash: Remove some `_.get()` from Image block. ([48489](https://github.com/WordPress/gutenberg/pull/48489)) - Playwright: Fix request utils for non Docker envs. ([48206](https://github.com/WordPress/gutenberg/pull/48206)) - [Private APIs] Only prevent module re-registration if IS_WORDPRESS_CORE. ([48352](https://github.com/WordPress/gutenberg/pull/48352)) -- Add a manual performance job that we can trigger from Github UI. ([48302](https://github.com/WordPress/gutenberg/pull/48302)) +- Add a manual performance job that we can trigger from GitHub UI. ([48302](https://github.com/WordPress/gutenberg/pull/48302)) - Track new front-end metric: LCP-TTFB. ([48288](https://github.com/WordPress/gutenberg/pull/48288)) ### Documentation @@ -13903,7 +13903,7 @@ The following contributors merged PRs in this release: - Updates to the curating the editor experience to include 6.1 & 6.2 items. ([48294](https://github.com/WordPress/gutenberg/pull/48294)) ### Tools -#### Testing +#### Testing - Migrate `switch-to-draft` to Playwright. ([48120](https://github.com/WordPress/gutenberg/pull/48120)) - VizReg end-to-end tests: Programmatically test all combinations of a given list of props/values. ([48260](https://github.com/WordPress/gutenberg/pull/48260)) - Update end-to-end test snapshots to Jest 29 default. ([48626](https://github.com/WordPress/gutenberg/pull/48626)) @@ -14162,7 +14162,7 @@ The following contributors merged PRs in this release: - [Automated Testing]: Fix wrong button fixture. ([48305](https://github.com/WordPress/gutenberg/pull/48305)) #### Build Tooling -- Add a manual performance job that we can trigger from Github UI. ([48302](https://github.com/WordPress/gutenberg/pull/48302)) +- Add a manual performance job that we can trigger from GitHub UI. ([48302](https://github.com/WordPress/gutenberg/pull/48302)) - Add command to run performance tests in debug mode. ([48614](https://github.com/WordPress/gutenberg/pull/48614)) - Make the performance tests more stable. ([48094](https://github.com/WordPress/gutenberg/pull/48094)) - SpacingSizesControl: Fix white dot on thumb. ([48574](https://github.com/WordPress/gutenberg/pull/48574)) @@ -14257,7 +14257,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@jsnajdr +@jsnajdr = 15.2.2 = @@ -15342,7 +15342,7 @@ The following contributors merged PRs in this release: ### Bug Fixes #### Block Editor -- Move block variation picker styles in the iframe ([47109](https://github.com/WordPress/gutenberg/pull/47109)) +- Move block variation picker styles in the iframe ([47109](https://github.com/WordPress/gutenberg/pull/47109)) - Add useBlockPreview styles in iframe ([47110](https://github.com/WordPress/gutenberg/pull/47110)) #### Block Library @@ -15897,7 +15897,7 @@ Fixes compatibility with WordPress 6.0.x. This includes the following PRs: - #46809 Broadly, this needed to include the two refactors of the Theme_JSON compatibility files, along with two fixes switching `wp_*` and `gutenberg_*` function variants as needed. - + ## Contributors The following contributors were involved with this release: @@ -16204,7 +16204,7 @@ The following contributors merged PRs in this release: ### Tools #### Build Tooling -- Adds Github Action to validate Gradle Wrapper. ([46247](https://github.com/WordPress/gutenberg/pull/46247)) +- Adds GitHub Action to validate Gradle Wrapper. ([46247](https://github.com/WordPress/gutenberg/pull/46247)) - Prevent api-fetch and core-data from being imported in the block editor package. ([46302](https://github.com/WordPress/gutenberg/pull/46302)) - Serialize the map objects properly in the Redux dev tools. ([46282](https://github.com/WordPress/gutenberg/pull/46282)) @@ -16482,7 +16482,7 @@ The following contributors merged PRs in this release: ### Tools #### Build Tooling -- Adds Github Action to validate Gradle Wrapper. ([46247](https://github.com/WordPress/gutenberg/pull/46247)) +- Adds GitHub Action to validate Gradle Wrapper. ([46247](https://github.com/WordPress/gutenberg/pull/46247)) - Prevent api-fetch and core-data from being imported in the block editor package. ([46302](https://github.com/WordPress/gutenberg/pull/46302)) - Serialize the map objects properly in the Redux dev tools. ([46282](https://github.com/WordPress/gutenberg/pull/46282)) @@ -16519,7 +16519,7 @@ The following contributors merged PRs in this release: The following contributors merged PRs in this release: -@youknowriad +@youknowriad = 14.7.2 = @@ -17880,7 +17880,7 @@ The following contributors merged PRs in this release: - Query Loop: Hide instructions for FormTokenField. ([44641](https://github.com/WordPress/gutenberg/pull/44641)) - Tag Cloud: Remove `strtolower` around taxonomy name. ([16112](https://github.com/WordPress/gutenberg/pull/16112)) - Video: Update placeholder style. ([44215](https://github.com/WordPress/gutenberg/pull/44215)) - + #### Components - FontSizePicker: Make control take up full width. ([44559](https://github.com/WordPress/gutenberg/pull/44559)) - Placeholder: Remove unnecessary background color. ([44497](https://github.com/WordPress/gutenberg/pull/44497)) @@ -18313,7 +18313,7 @@ The following PRs were merged by first time contributors: The following contributors merged PRs in this release: -@aaronrobertshaw @ajlende @annezazu @apmatthews @aristath @c4rl0sbr4v0 @carolinan @chad1008 @ciampo @dcalhoun @draganescu @ellatrix @geriux @glendaviesnz @gziolo @jasmussen @jorgefilipecosta @kebbet @kkoppenhaver @Mamaduka @matiasbenedetto @mcsf @michalczaplinski @mirka @mtias @noisysocks @ntsekouras @pagelab @ramonjd @t-hamano @talldan @tellthemachines @tyxla @walbo @youknowriad +@aaronrobertshaw @ajlende @annezazu @apmatthews @aristath @c4rl0sbr4v0 @carolinan @chad1008 @ciampo @dcalhoun @draganescu @ellatrix @geriux @glendaviesnz @gziolo @jasmussen @jorgefilipecosta @kebbet @kkoppenhaver @Mamaduka @matiasbenedetto @mcsf @michalczaplinski @mirka @mtias @noisysocks @ntsekouras @pagelab @ramonjd @t-hamano @talldan @tellthemachines @tyxla @walbo @youknowriad @@ -20690,7 +20690,7 @@ The following contributors merged PRs in this release: - JS Error Tracking: Allow custom error reporting logic to be called in Error Boundaries via a WP action hook. ([42024](https://github.com/WordPress/gutenberg/pull/42024)) -### Accessibility +### Accessibility - Add aria-checked to the selected heading level menu item. ([42273](https://github.com/WordPress/gutenberg/pull/42273)) - Fix tabbing from first or last block in site editor. ([42036](https://github.com/WordPress/gutenberg/pull/42036)) @@ -20799,7 +20799,7 @@ The following contributors merged PRs in this release: - Tip: Covert component to TypeScript. ([42262](https://github.com/WordPress/gutenberg/pull/42262)) - VisuallyHidden: Convert component to TypeScript. ([42220](https://github.com/WordPress/gutenberg/pull/42220)) - Spacer: Complete TypeScript migration of component. ([42013](https://github.com/WordPress/gutenberg/pull/42013)) -- +- #### Components - Add eslint to prevent SSR breakage. ([42248](https://github.com/WordPress/gutenberg/pull/42248)) - Fix typos in components changelog. ([42244](https://github.com/WordPress/gutenberg/pull/42244)) @@ -20889,7 +20889,7 @@ The following contributors merged PRs in this release: ### Enhancements -#### UI +#### UI - Increase fade intensity during spotlight mode. ([40454](https://github.com/WordPress/gutenberg/pull/40454)) - Improvements to "inherit default layout" toggle. ([41893](https://github.com/WordPress/gutenberg/pull/41893)) - Make it easier to select "Edit visually" when in "Edit as HTML. ([41516](https://github.com/WordPress/gutenberg/pull/41516)) @@ -20949,7 +20949,7 @@ The following contributors merged PRs in this release: - [Block Editor]: Fix content loss from `replaceInnerBlocks` with controlled blocks. ([41948](https://github.com/WordPress/gutenberg/pull/41948)) - Fix action button spacing on the widget editor. ([41915](https://github.com/WordPress/gutenberg/pull/41915)) - Render duotone presets in pattern preview. ([41249](https://github.com/WordPress/gutenberg/pull/41249)) - + #### Block Library - List v2: - Fix impossible to outdent multiple list items. ([41713](https://github.com/WordPress/gutenberg/pull/41713)) @@ -22265,7 +22265,7 @@ The following contributors merged PRs in this release: ### Bug Fixes -- Fix the position of the block inserter in between blocks ([40919](https://github.com/WordPress/gutenberg/pull/40919)) +- Fix the position of the block inserter in between blocks ([40919](https://github.com/WordPress/gutenberg/pull/40919)) = 13.2.0 = @@ -22635,7 +22635,7 @@ The following PRs were merged by first time contributors: - Fixed focus loss when navigating the guide component. ([40324](https://github.com/WordPress/gutenberg/pull/40324)) - Navigation block: After choosing an option from Select Menu, focus after block rerender. ([40390](https://github.com/WordPress/gutenberg/pull/40390)) - Block Styles: Remove unnecessary button role and 'onKeyDown' handler. ([40427](https://github.com/WordPress/gutenberg/pull/40427)) - + ### Performance - Added a context param to sidebar entity request. ([40148](https://github.com/WordPress/gutenberg/pull/40148)) @@ -22673,12 +22673,12 @@ The following PRs were merged by first time contributors: - Stop exporting individual color objects from color values file. ([40387](https://github.com/WordPress/gutenberg/pull/40387)) - Added reusable BlockPopover and BlockPopoverInbetween components. ([40441](https://github.com/WordPress/gutenberg/pull/40441)) - Cleaned BlockMover component and styles. ([40379](https://github.com/WordPress/gutenberg/pull/40379)) - + #### Packages - Block Editor: Remove unused sub-components in list view. ([40448](https://github.com/WordPress/gutenberg/pull/40448)) - Data: Cancel render queue in a more straightforward way. ([40433](https://github.com/WordPress/gutenberg/pull/40433)) - + #### Plugin - Added `edit` context to patterns REST controllers. ([40259](https://github.com/WordPress/gutenberg/pull/40259)) @@ -39722,7 +39722,7 @@ Add knobs to the [ColorIndicator Story](https://github.com/WordPress/gutenberg/p * `is_gutenberg_page` incorrectly assumes `get_current_screen` exists, add check. * Brings code inline with CSS standards by switching font weight to numeric values. * Wrapped component would not the most up-to-date store values if it incurred a store state change during its own mount (e.g. dispatching during its own constructor), resolved by rerunning selection. -* Display an error message if Javascript is disabled. +* Display an error message if JavaScript is disabled. * Update to React 16.6.3. * Adds missing components dependency for RichText. * Refactors list block to remove previously exposed RichText/TinyMCE logic. diff --git a/docs/contributors/code/release.md b/docs/contributors/code/release.md index 4c8950eb5e7cd6..f304ec9cd3a487 100644 --- a/docs/contributors/code/release.md +++ b/docs/contributors/code/release.md @@ -320,13 +320,13 @@ If an RC already exists for a new version, you _need_ to cherry-pick the same co The cherry-picking process can be automated with the [`npm run cherry-pick`](/docs/contributors/code/auto-cherry-picking.md) script, but be sure to use the `Backport to Gutenberg Minor Release` label when running the script. -You must also ensure that all PRs being included are assigned to the Github Milestone on which the minor release is based. Bear in mind, that when PRs are _merged_ they are automatically assigned a milestone for the next _stable_ release. Therefore you will need to go back through each PR in Github and re-assign the Milestone. +You must also ensure that all PRs being included are assigned to the GitHub Milestone on which the minor release is based. Bear in mind, that when PRs are _merged_ they are automatically assigned a milestone for the next _stable_ release. Therefore you will need to go back through each PR in GitHub and re-assign the Milestone. For example, if you are releasing version `12.5.4`, then all PRs picked for that release must be unassigned from the `12.6` Milestone and instead assigned to the `12.5` Milestone. Once cherry picking is complete, you can also remove the `Backport to Gutenberg Minor Release` label from the PRs. -Once you have the stable release branch in order and the correct Milestone assigned to your PRs you can _push the branch to Github_ and continue with the release process using the Github website GUI. +Once you have the stable release branch in order and the correct Milestone assigned to your PRs you can _push the branch to GitHub_ and continue with the release process using the GitHub website GUI. #### Running the minor release diff --git a/docs/explanations/README.md b/docs/explanations/README.md index 04d9f8e9e15b52..2d0da6cabdf67c 100644 --- a/docs/explanations/README.md +++ b/docs/explanations/README.md @@ -8,5 +8,5 @@ - [Block Editor Performance](/docs/explanations/architecture/performance.md). - What are the decision decisions behind the Data Module? - [Why is Puppeteer the tool of choice for end-to-end tests?](/docs/explanations/architecture/automated-testing.md) -- [What’s the difference between the different editor packages? What’s the purpose of each package?](/docs/explanations/architecture/modularity.md/#whats-the-difference-between-the-different-editor-packages-whats-the-purpose-of-each-package) +- [What’s the difference between the different editor packages? What’s the purpose of each package?](/docs/explanations/architecture/modularity.md#whats-the-difference-between-the-different-editor-packages-whats-the-purpose-of-each-package) - [Template and template parts flows](/docs/explanations/architecture/full-site-editing-templates.md) diff --git a/docs/explanations/architecture/performance.md b/docs/explanations/architecture/performance.md index de3b7b5dcdbd5b..4c8b6386b9263b 100644 --- a/docs/explanations/architecture/performance.md +++ b/docs/explanations/architecture/performance.md @@ -69,7 +69,7 @@ The performance results for each commit are pushed to codevitals and can be seen It's thus very important to ensure that the metric being computed is stable. Meaning, if you run the same test twice with the same code and environment, you'll get results that are close. -Our performance job runs Github CI which means that we can't trust the consistency of the numbers that we get between two similar job runs. Github CI may allocate different CPU and memory resources for us over time for instance. To alleviate this problem, each time we run the performance job on the trunk branch, we compare the current commit's performance to a fixed reference commit hash, which allows us to track the relative difference between the current commit and the reference commit consistently regardless of environment changes. +Our performance job runs GitHub CI which means that we can't trust the consistency of the numbers that we get between two similar job runs. GitHub CI may allocate different CPU and memory resources for us over time for instance. To alleviate this problem, each time we run the performance job on the trunk branch, we compare the current commit's performance to a fixed reference commit hash, which allows us to track the relative difference between the current commit and the reference commit consistently regardless of environment changes. ### Update the reference commit @@ -77,7 +77,7 @@ Gutenberg supports only two WP versions, this impacts the performance job in two - The base WP version used to run the performance job needs to be updated, when the minimum version supported by Gutenberg changes. In order to do that, we rely on the `Tested up to` flag of the plugin's `readme.txt` file. So each time that flag is changed, the version used for the performance job is changed as well. - - Updating the WP version used for performance jobs means that there's a high chance that the reference commit used for performance test stability becomes incompatible with the WP version that is used. So every time, the `Tested up to` flag is updated in the `readme.txt` is changed, we also have to update the reference commit that is used in `.github/workflows/performance.yml`. + - Updating the WP version used for performance jobs means that there's a high chance that the reference commit used for performance test stability becomes incompatible with the WP version that is used. So every time, the `Tested up to` flag is updated in the `readme.txt` is changed, we also have to update the reference commit that is used in `.github/workflows/performance.yml`. The new reference commit hash that is chosen needs to meet the following requirements: diff --git a/docs/getting-started/fundamentals/README.md b/docs/getting-started/fundamentals/README.md index fd2941711dd01b..42dbace9d7ba3f 100644 --- a/docs/getting-started/fundamentals/README.md +++ b/docs/getting-started/fundamentals/README.md @@ -9,4 +9,4 @@ This section provides an introduction to the most relevant concepts in block dev 1. **[The block in the Editor](https://developer.wordpress.org/block-editor/getting-started/fundamentals/block-in-the-editor):** How a block, as a React component, is loaded in the Block Editor and an overview of its structure. 1. **[Markup representation of a block](https://developer.wordpress.org/block-editor/getting-started/fundamentals/markup-representation-block):** How blocks are represented in the database, theme templates, and patterns. 1. **[Static or Dynamic rendering of a block](https://developer.wordpress.org/block-editor/getting-started/fundamentals/static-dynamic-rendering):** How blocks generate their front-end output either dynamically or statically. -1. **[Javascript in the Block Editor](https://developer.wordpress.org/block-editor/getting-started/fundamentals/javascript-in-the-block-editor):** How to work with modern Javascript when developing for the Block Editor. +1. **[JavaScript in the Block Editor](https://developer.wordpress.org/block-editor/getting-started/fundamentals/javascript-in-the-block-editor):** How to work with modern JavaScript when developing for the Block Editor. diff --git a/docs/getting-started/fundamentals/javascript-in-the-block-editor.md b/docs/getting-started/fundamentals/javascript-in-the-block-editor.md index 42d7363b6aa4df..348b95ba88da3c 100644 --- a/docs/getting-started/fundamentals/javascript-in-the-block-editor.md +++ b/docs/getting-started/fundamentals/javascript-in-the-block-editor.md @@ -1,20 +1,20 @@ -# Working with Javascript for the Block Editor +# Working with JavaScript for the Block Editor Developing blocks for the Block Editor often involves using modern JavaScript (ESNext and JSX), and most examples here in the Block Editor Handbook are written in these syntaxes. -However, this form of JavaScript must be transformed into a browser-compatible format, necessitating a build step. This process transforms, bundles, and optimizes JavaScript source code and related assets into a format suitable for production environments. +However, this form of JavaScript must be transformed into a browser-compatible format, necessitating a build step. This process transforms, bundles, and optimizes JavaScript source code and related assets into a format suitable for production environments. ## JavaScript with a build process Using a build process for block development unlocks the full potential of modern JavaScript, facilitating the use of ESNext and JSX. -[ESNext](https://developer.mozilla.org/en-US/docs/Web/JavaScript/JavaScript_technologies_overview#standardization_process) refers to Javascript's most recent syntax and features. [JSX](https://react.dev/learn/writing-markup-with-jsx) is a syntax extension developed by the React project that enables you to write JavaScript that resembles HTML. +[ESNext](https://developer.mozilla.org/en-US/docs/Web/JavaScript/JavaScript_technologies_overview#standardization_process) refers to JavaScript's most recent syntax and features. [JSX](https://react.dev/learn/writing-markup-with-jsx) is a syntax extension developed by the React project that enables you to write JavaScript that resembles HTML. Since browsers cannot directly execute ESNext and JSX, these syntaxes must be transformed into browser-compatible JavaScript. [webpack](https://webpack.js.org/concepts/why-webpack/) is a pluggable tool that processes and bundles JavaScript for browser compatibility. [Babel](https://babeljs.io/), a plugin for webpack, converts ESNext and JSX into standard JavaScript. -Configuring webpack and Babel can be challenging, so it's recommended that you use the [`@wordpress/scripts`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-scripts/) package. This tool simplifies development by preconfiguring both, so you rarely need to write custom webpack or Babel configurations. +Configuring webpack and Babel can be challenging, so it's recommended that you use the [`@wordpress/scripts`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-scripts/) package. This tool simplifies development by preconfiguring both, so you rarely need to write custom webpack or Babel configurations. For an introduction, refer to the [Get started with wp-scripts](/docs/getting-started/devenv/get-started-with-wp-scripts.md) guide. @@ -28,21 +28,21 @@ The diagram below provides an overview of the build process when using the `wp-s - **Development Mode (`npm run start`):** This mode is tailored for active development. It skips minification for easier debugging, generates source maps for better error tracking, and watches your source files for changes. When a change is detected, it automatically rebuilds the affected files, allowing you to see updates in real-time. -The `wp-scripts` package also facilitates the use of JavaScript modules, allowing code distribution across multiple files and resulting in a streamlined bundle after the build process. The [block-development-example](https://github.com/WordPress/block-development-examples/tree/trunk/plugins/data-basics-59c8f8) GitHub repository provides some good examples. +The `wp-scripts` package also facilitates the use of JavaScript modules, allowing code distribution across multiple files and resulting in a streamlined bundle after the build process. The [block-development-example](https://github.com/WordPress/block-development-examples/tree/trunk/plugins/data-basics-59c8f8) GitHub repository provides some good examples.
In most situations, no customization will be needed, but you can provide a webpack.config.js when using wp-scripts to modify the build process to suit your needs.
-## Javascript without a build process +## JavaScript without a build process Integrating JavaScript into your WordPress projects without a build process can be the most straightforward approach in specific scenarios. This is particularly true for projects that don't leverage JSX or other advanced JavaScript features requiring compilation. -When you opt out of a build process, you interact directly with WordPress's [Javascript APIs](/docs/reference-guides/packages/) through the global `wp` object. This means that all the methods and packages provided by WordPress are readily available, but with one caveat: you must manually manage script dependencies. This is done by adding [the handle](/docs/contributors/code/scripts.md) of each corresponding package to the dependency array of your enqueued JavaScript file. +When you opt out of a build process, you interact directly with WordPress's [JavaScript APIs](/docs/reference-guides/packages/) through the global `wp` object. This means that all the methods and packages provided by WordPress are readily available, but with one caveat: you must manually manage script dependencies. This is done by adding [the handle](/docs/contributors/code/scripts.md) of each corresponding package to the dependency array of your enqueued JavaScript file. For example, suppose you're creating a script that registers a new block [variation](/docs/reference-guides/block-api/block-variations.md) using the `registerBlockVariation` function from the [`blocks`](/docs/reference-guides/packages/packages-blocks.md) package. You must include `wp-blocks` in your script's dependency array. This guarantees that the `wp.blocks.registerBlockVariation` method is available and defined by the time your script executes. -In the following example, the `wp-blocks` dependency is defined when enqueuing the `variations.js` file. +In the following example, the `wp-blocks` dependency is defined when enqueuing the `variations.js` file. ```php function example_enqueue_block_variations() { @@ -84,10 +84,10 @@ Refer to [Enqueueing assets in the Editor](/docs/how-to-guides/enqueueing-assets ## Additional resources - [Package reference](/docs/reference-guides/packages.md) -- [Get started with wp-scripts](/docs/getting-started/devenv/get-started-with-wp-scripts.md) -- [Enqueueing assets in the Editor](/docs/how-to-guides/enqueueing-assets-in-the-editor.md) -- [WordPress package handles](/docs/contributors/code/scripts.md) -- [Javascript reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript) | MDN Web Docs +- [Get started with wp-scripts](/docs/getting-started/devenv/get-started-with-wp-scripts.md) +- [Enqueueing assets in the Editor](/docs/how-to-guides/enqueueing-assets-in-the-editor.md) +- [WordPress package handles](/docs/contributors/code/scripts.md) +- [JavaScript reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript) | MDN Web Docs - [block-development-examples](https://github.com/WordPress/block-development-examples) | GitHub repository - [block-theme-examples](https://github.com/wptrainingteam/block-theme-examples) | GitHub repository - [How webpack and WordPress packages interact](https://developer.wordpress.org/news/2023/04/how-webpack-and-wordpress-packages-interact/) | Developer Blog diff --git a/docs/getting-started/tutorial.md b/docs/getting-started/tutorial.md index b57391a806cf6a..641ecad07ab9bc 100644 --- a/docs/getting-started/tutorial.md +++ b/docs/getting-started/tutorial.md @@ -156,7 +156,7 @@ Save the file and select the block in the Editor. You will now see both Color an #### Removing unnecessary code -For simplicity, the styling for the Copyright Date Block will be controlled entirely by the color and typography block supports. This block also does not have any front-end Javascript. Therefore, you don't need to specify stylesheets or a `viewScript` in the `block.json` file. +For simplicity, the styling for the Copyright Date Block will be controlled entirely by the color and typography block supports. This block also does not have any front-end JavaScript. Therefore, you don't need to specify stylesheets or a `viewScript` in the `block.json` file. 1. Remove the line for `editorStyle` 2. Remove the line for `style` diff --git a/docs/how-to-guides/data-basics/3-building-an-edit-form.md b/docs/how-to-guides/data-basics/3-building-an-edit-form.md index 34136ff4080800..65c4d0a5486a0d 100644 --- a/docs/how-to-guides/data-basics/3-building-an-edit-form.md +++ b/docs/how-to-guides/data-basics/3-building-an-edit-form.md @@ -215,7 +215,7 @@ As you can see, the `title` of an Entity Record is an object, but the `title` of This is no accident. Fields like `title`, `excerpt`, and `content` may contain [shortcodes](https://developer.wordpress.org/apis/handbook/shortcode/) or [dynamic blocks](/docs/how-to-guides/block-tutorial/creating-dynamic-blocks.md), which means they can only be rendered on the server. For such fields, the REST API exposes both the `raw` markup _and_ the `rendered` string. For example, in the block editor, `content.rendered` could used as a visual preview, and `content.raw` could be used to populate the code editor. -So why is the `content` of an Edited Entity Record a string? Since Javascript is not be able to properly render arbitrary block markup, it stores only the `raw` markup without the `rendered` part. And since that's a string, the entire field becomes a string. +So why is the `content` of an Edited Entity Record a string? Since JavaScript is not be able to properly render arbitrary block markup, it stores only the `raw` markup without the `rendered` part. And since that's a string, the entire field becomes a string. We can now update `EditPageForm` accordingly. We can access the actions using the [`useDispatch`](/packages/data/README.md#usedispatch) hook similarly to how we use `useSelect` to access selectors: diff --git a/docs/how-to-guides/enqueueing-assets-in-the-editor.md b/docs/how-to-guides/enqueueing-assets-in-the-editor.md index 02d9020d351e38..fb0efb88e67967 100644 --- a/docs/how-to-guides/enqueueing-assets-in-the-editor.md +++ b/docs/how-to-guides/enqueueing-assets-in-the-editor.md @@ -18,7 +18,7 @@ There are different hooks to use depending on the answers to these questions, an Whenever you need to enqueue assets for the Editor itself (i.e. not the user-generated content), you should use the [`enqueue_block_editor_assets`](https://developer.wordpress.org/reference/hooks/enqueue_block_editor_assets/) hook coupled with the standard [`wp_enqueue_script`](https://developer.wordpress.org/reference/functions/wp_enqueue_script/) and [`wp_enqueue_style`](https://developer.wordpress.org/reference/functions/wp_enqueue_style/) functions. -Examples might be adding custom inspector or toolbar controls, registering block styles and variations in Javascript, registering Editor plugins, etc. +Examples might be adding custom inspector or toolbar controls, registering block styles and variations in JavaScript, registering Editor plugins, etc. ```php /** @@ -31,7 +31,7 @@ function example_enqueue_editor_assets() { ); wp_enqueue_style( 'example-editor-styles', - plugins_url( 'editor-styles.css', __FILE__ ) + plugins_url( 'editor-styles.css', __FILE__ ) ); } add_action( 'enqueue_block_editor_assets', 'example_enqueue_editor_assets' ); diff --git a/docs/manifest.json b/docs/manifest.json index ac269e47846333..1704e6d711510f 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -102,7 +102,7 @@ "parent": "fundamentals" }, { - "title": "Working with Javascript for the Block Editor", + "title": "Working with JavaScript for the Block Editor", "slug": "javascript-in-the-block-editor", "markdown_source": "../docs/getting-started/fundamentals/javascript-in-the-block-editor.md", "parent": "fundamentals" diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 21bb576f12a1ce..93ab0a031800f0 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -616,7 +616,7 @@ Displays the contents of a post or page. ([Source](https://github.com/WordPress/ - **Name:** core/post-content - **Category:** theme -- **Supports:** align (full, wide), color (background, gradients, link, text), dimensions (minHeight), layout, spacing (blockGap), typography (fontSize, lineHeight), ~~html~~ +- **Supports:** align (full, wide), background (backgroundImage, backgroundSize), color (background, gradients, link, text), dimensions (minHeight), layout, spacing (blockGap, padding), typography (fontSize, lineHeight), ~~html~~ ## Date diff --git a/docs/reference-guides/data/data-core-block-editor.md b/docs/reference-guides/data/data-core-block-editor.md index f687eb79732b5a..4b66ad9eb6cb40 100644 --- a/docs/reference-guides/data/data-core-block-editor.md +++ b/docs/reference-guides/data/data-core-block-editor.md @@ -81,7 +81,6 @@ _Parameters_ - _state_ `Object`: Editor state. - _clientId_ `string`: The block client Id. -- _rootClientId_ `?string`: Optional root client ID of block list. _Returns_ @@ -95,7 +94,6 @@ _Parameters_ - _state_ `Object`: Editor state. - _clientIds_ `string`: The block client IDs to be moved. -- _rootClientId_ `?string`: Optional root client ID of block list. _Returns_ @@ -109,7 +107,6 @@ _Parameters_ - _state_ `Object`: Editor state. - _clientId_ `string`: The block client Id. -- _rootClientId_ `?string`: Optional root client ID of block list. _Returns_ @@ -123,7 +120,6 @@ _Parameters_ - _state_ `Object`: Editor state. - _clientIds_ `string`: The block client IDs to be removed. -- _rootClientId_ `?string`: Optional root client ID of block list. _Returns_ diff --git a/docs/reference-guides/interactivity-api/README.md b/docs/reference-guides/interactivity-api/README.md index b6e0d639c3fc8b..85255af785cbb5 100644 --- a/docs/reference-guides/interactivity-api/README.md +++ b/docs/reference-guides/interactivity-api/README.md @@ -1,6 +1,6 @@ # Interactivity API Reference -The Interactivity API, [introduced in WordPress 6.5](https://make.wordpress.org/core/2024/02/19/merge-announcement-interactivity-api/), provides a standard way for developers to add interactions to the front end of their blocks. The API is also used in many Core WordPress blocks, including Search, Query, Navigation, and File. +The Interactivity API, [introduced in WordPress 6.5](https://make.wordpress.org/core/2024/02/19/merge-announcement-interactivity-api/), provides a standard way for developers to add interactions to the front end of their blocks. The API is also used in many Core WordPress blocks, including Search, Query, Navigation, and File. This standard makes it easier for developers to create rich, interactive user experiences, from simple counters or pop-ups to more complex features like instant page navigation, instant search, shopping carts, or checkouts. @@ -32,7 +32,7 @@ To get a deeper understanding of what the Interactivity API is or find answers t Interactivity API is included in Core in WordPress 6.5. For versions below, you'll need Gutenberg 17.5 or higher installed and activated in your WordPress installation. -It’s also important to highlight that the block creation workflow doesn’t change, and all the [prerequisites](https://developer.wordpress.org/block-editor/getting-started/devenv/) remain the same. These include: +It’s also important to highlight that the block creation workflow doesn’t change, and all the [prerequisites](https://developer.wordpress.org/block-editor/getting-started/devenv/) remain the same. These include: - [Code Editor](https://developer.wordpress.org/block-editor/getting-started/devenv/#code-editor) - [Node.js development tools](https://developer.wordpress.org/block-editor/getting-started/devenv/#node-js-development-tools) @@ -55,7 +55,7 @@ To indicate that the block [supports](https://developer.wordpress.org/block-edit Refer to the [`interactivity` support property docs](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#interactivity) to get a more detailed description of this property. -#### Load Interactivity API Javascript code with `viewScriptModule` +#### Load Interactivity API JavaScript code with `viewScriptModule` The Interactivity API provides the `@wordpress/interactivity` Script Module. JavaScript using the Interactivity API should be implemented as Script Modules so they can depend on `@wordpress/interactivity`. [Script Modules have been available since WordPress 6.5](https://make.wordpress.org/core/2024/03/04/script-modules-in-6-5/). Blocks can use [`viewScriptModule` block metadata](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#view-script-module) to enqueue their Script Modules easily: @@ -82,7 +82,7 @@ The use of `viewScriptModule` also requires the `--experimental-modules` flag fo #### Add `wp-interactive` directive to a DOM element -To "activate" the Interactivity API in a DOM element (and its children), add the [`wp-interactive`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-interactive) directive to the DOM element in the block's `render.php` or `save.js` files. +To "activate" the Interactivity API in a DOM element (and its children), add the [`wp-interactive`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-interactive) directive to the DOM element in the block's `render.php` or `save.js` files. diff --git a/lib/README.md b/lib/README.md index cbc86d67a18f7e..8e22f676a153d2 100644 --- a/lib/README.md +++ b/lib/README.md @@ -6,7 +6,7 @@ The Gutenberg plugin is continuously enhancing existing features and creating ne During a WordPress release, new features, bugfixes and other changes are "synced" between the Gutenberg plugin and WordPress Core. Consistent naming and directory structures make this process easier by preventing naming conflicts and compartmentalizing release-specific code. -The following documentation is intended to act as a guide only. If you're unsure about naming or where to place new PHP files, please don't hesitate to ping other contributors on Github or ask in the #core-editor channel on [WordPress Slack](https://make.wordpress.org/chat/). +The following documentation is intended to act as a guide only. If you're unsure about naming or where to place new PHP files, please don't hesitate to ping other contributors on GitHub or ask in the #core-editor channel on [WordPress Slack](https://make.wordpress.org/chat/). ## File structure @@ -194,10 +194,10 @@ Existing comments in `lib/load.php` should act as a guide. If you've changed or added PHP files to the Gutenberg plugin, you'll need to confirm whether the changes are to be synced to WordPress Core, and therefore featured in the next release of WordPress. -The Gutenberg Github pull request in question should be labeled with the `Needs PHP backport` label if the changes are to be synced to Core. +The Gutenberg GitHub pull request in question should be labeled with the `Needs PHP backport` label if the changes are to be synced to Core. -If so, it is recommended to create a [new Trac ticket](https://core.trac.wordpress.org/newticket) and submit a pull request to the [WordPress Core Github repository](https://github.com/WordPress/wordpress-develop) soon after your pull request is merged. +If so, it is recommended to create a [new Trac ticket](https://core.trac.wordpress.org/newticket) and submit a pull request to the [WordPress Core GitHub repository](https://github.com/WordPress/wordpress-develop) soon after your pull request is merged. -So too, if you've made changes in WordPress Core to code that also lives in the Gutenberg plugin, these changes will need to be synced (often called "backporting") to Gutenberg. The relevant Gutenberg Github pull request should be labeled with the `Backport from WordPress Core` label. +So too, if you've made changes in WordPress Core to code that also lives in the Gutenberg plugin, these changes will need to be synced (often called "backporting") to Gutenberg. The relevant Gutenberg GitHub pull request should be labeled with the `Backport from WordPress Core` label. If you're unsure, you can always ask for help in the #core-editor channel in [WordPress Slack](https://make.wordpress.org/chat/). diff --git a/lib/block-editor-settings.php b/lib/block-editor-settings.php index 53668e114e04cb..defd7cd391b16b 100644 --- a/lib/block-editor-settings.php +++ b/lib/block-editor-settings.php @@ -58,7 +58,7 @@ function gutenberg_get_block_editor_settings( $settings ) { * entered by users does not break other global styles. */ $global_styles[] = array( - 'css' => gutenberg_get_global_styles_custom_css(), + 'css' => gutenberg_get_global_stylesheet( array( 'custom-css' ) ), '__unstableType' => 'user', 'isGlobalStyles' => true, ); diff --git a/lib/block-supports/block-style-variations.php b/lib/block-supports/block-style-variations.php index f2bc6af92e9dec..13a7d4dce18c3d 100644 --- a/lib/block-supports/block-style-variations.php +++ b/lib/block-supports/block-style-variations.php @@ -133,8 +133,9 @@ function gutenberg_render_block_style_variation_support_styles( $parsed_block ) array( 'styles' ), array( 'custom' ), array( - 'skip_root_layout_styles' => true, - 'scope' => ".$class_name", + 'include_block_style_variations' => true, + 'skip_root_layout_styles' => true, + 'scope' => ".$class_name", ) ); @@ -244,7 +245,7 @@ function gutenberg_resolve_block_style_variations( $variations ) { * Block style variations read in via standalone theme.json partials * need to have their name set to the kebab case version of their title. */ - $variation_name = $have_named_variations ? $key : _wp_to_kebab_case( $variation['title'] ); + $variation_name = $have_named_variations ? $key : ( $variation['slug'] ?? _wp_to_kebab_case( $variation['title'] ) ); foreach ( $supported_blocks as $block_type ) { // Add block style variation data under current block type. @@ -455,7 +456,7 @@ function gutenberg_register_block_style_variations_from_theme_json_data( $variat * Block style variations read in via standalone theme.json partials * need to have their name set to the kebab case version of their title. */ - $variation_name = $have_named_variations ? $key : _wp_to_kebab_case( $variation['title'] ); + $variation_name = $have_named_variations ? $key : ( $variation['slug'] ?? _wp_to_kebab_case( $variation['title'] ) ); $variation_label = $variation['title'] ?? $variation_name; foreach ( $supported_blocks as $block_type ) { @@ -486,6 +487,23 @@ function gutenberg_register_block_style_variations_from_theme_json_data( $variat * @access private */ function gutenberg_register_block_style_variations_from_theme() { + /* + * Skip any registration of styles if no theme.json or variation partials are present. + * + * Given the possibility of hybrid themes, this check can't rely on if the theme + * is a block theme or not. Instead: + * - If there is a primary theme.json, continue. + * - If there is a partials directory, continue. + * - The only variations to be registered from the global styles user origin, + * are those that have been copied in from the selected theme style variation. + * For a theme style variation to be selected it would have to have a partial + * theme.json file covered by the previous check. + */ + $has_partials_directory = is_dir( get_stylesheet_directory() . '/styles' ) || is_dir( get_template_directory() . '/styles' ); + if ( ! wp_theme_has_theme_json() && ! $has_partials_directory ) { + return; + } + // Partials from `/styles`. $variations_partials = WP_Theme_JSON_Resolver_Gutenberg::get_style_variations( 'block' ); gutenberg_register_block_style_variations_from_theme_json_data( $variations_partials ); diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index a1e79a56a683bf..e3a3d1b1f256c3 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -357,6 +357,7 @@ class WP_Theme_JSON_Gutenberg { 'styles', 'templateParts', 'title', + 'slug', 'version', ); @@ -1247,7 +1248,7 @@ public function get_settings() { * * @since 5.8.0 * @since 5.9.0 Removed the `$type` parameter`, added the `$types` and `$origins` parameters. - * @since 6.6.0 Added option to skip root layout styles. + * @since 6.6.0 Added option to skip root layout or block style variation styles. * * @param array $types Types of styles to load. Will load all by default. It accepts: * - `variables`: only the CSS Custom Properties for presets & custom ones. @@ -1259,6 +1260,7 @@ public function get_settings() { * - 'scope' that makes sure all style are scoped to a given selector * - `root_selector` which overwrites and forces a given selector to be used on the root node * - `skip_root_layout_styles` which omits root layout styles from the generated stylesheet. + * - `include_block_style_variations` which includes CSS for block style variations. * @return string The resulting stylesheet. */ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' ), $origins = null, $options = array() ) { @@ -1279,7 +1281,7 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' } $blocks_metadata = static::get_blocks_metadata(); - $style_nodes = static::get_style_nodes( $this->theme_json, $blocks_metadata ); + $style_nodes = static::get_style_nodes( $this->theme_json, $blocks_metadata, $options ); $setting_nodes = static::get_setting_nodes( $this->theme_json, $blocks_metadata ); $root_style_key = array_search( static::ROOT_BLOCK_SELECTOR, array_column( $style_nodes, 'selector' ), true ); @@ -1355,6 +1357,12 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' $stylesheet .= $this->get_preset_classes( $setting_nodes, $origins ); } + // Load the custom CSS last so it has the highest specificity. + if ( in_array( 'custom-css', $types, true ) ) { + // Add the global styles root CSS. + $stylesheet .= _wp_array_get( $this->theme_json, array( 'styles', 'css' ) ); + } + return $stylesheet; } @@ -1399,10 +1407,12 @@ protected function process_blocks_custom_css( $css, $selector ) { * Returns the global styles custom css. * * @since 6.2.0 + * @deprecated 6.7.0 Use {@see 'get_stylesheet'} instead. * * @return string The global styles custom CSS. */ public function get_custom_css() { + _deprecated_function( __METHOD__, '6.7.0', 'get_stylesheet' ); $block_custom_css = ''; $block_nodes = $this->get_block_custom_css_nodes(); foreach ( $block_nodes as $node ) { @@ -1415,23 +1425,23 @@ public function get_custom_css() { /** * Returns the global styles base custom CSS. - * - * @since 6.6.0 + * This function is deprecated; please do not sync to core. * * @return string The global styles base custom CSS. */ public function get_base_custom_css() { + _deprecated_function( __METHOD__, 'Gutenberg 18.6.0', 'get_stylesheet' ); return isset( $this->theme_json['styles']['css'] ) ? $this->theme_json['styles']['css'] : ''; } /** * Returns the block nodes with custom CSS. - * - * @since 6.6.0 + * This function is deprecated; please do not sync to core. * * @return array The block nodes. */ public function get_block_custom_css_nodes() { + _deprecated_function( __METHOD__, 'Gutenberg 18.6.0', 'get_block_nodes' ); $block_nodes = array(); // Add the global styles block CSS. @@ -1455,8 +1465,7 @@ public function get_block_custom_css_nodes() { /** * Returns the global styles custom CSS for a single block. - * - * @since 6.6.0 + * This function is deprecated; please do not sync to core. * * @param array $css The block css node. * @param string $selector The block selector. @@ -1464,6 +1473,7 @@ public function get_block_custom_css_nodes() { * @return string The global styles custom CSS for the block. */ public function get_block_custom_css( $css, $selector ) { + _deprecated_function( __METHOD__, 'Gutenberg 18.6.0', 'get_styles_for_block' ); return $this->process_blocks_custom_css( $css, $selector ); } @@ -2478,9 +2488,12 @@ protected static function get_setting_nodes( $theme_json, $selectors = array() ) * * @param array $theme_json The tree to extract style nodes from. * @param array $selectors List of selectors per block. + * @param array $options An array of options to facilitate filtering style node generation + * The options currently supported are: + * - `include_block_style_variations` which includes CSS for block style variations. * @return array An array of style nodes metadata. */ - protected static function get_style_nodes( $theme_json, $selectors = array() ) { + protected static function get_style_nodes( $theme_json, $selectors = array(), $options = array() ) { $nodes = array(); if ( ! isset( $theme_json['styles'] ) ) { return $nodes; @@ -2524,7 +2537,7 @@ protected static function get_style_nodes( $theme_json, $selectors = array() ) { return $nodes; } - $block_nodes = static::get_block_nodes( $theme_json, $selectors ); + $block_nodes = static::get_block_nodes( $theme_json, $selectors, $options ); foreach ( $block_nodes as $block_node ) { $nodes[] = $block_node; } @@ -2599,9 +2612,12 @@ private static function update_separator_declarations( $declarations ) { * * @param array $theme_json The theme.json converted to an array. * @param array $selectors Optional list of selectors per block. + * @param array $options An array of options to facilitate filtering node generation + * The options currently supported are: + * - `include_block_style_variations` which includes CSS for block style variations. * @return array The block nodes in theme.json. */ - private static function get_block_nodes( $theme_json, $selectors = array() ) { + private static function get_block_nodes( $theme_json, $selectors = array(), $options = array() ) { $selectors = empty( $selectors ) ? static::get_blocks_metadata() : $selectors; $nodes = array(); if ( ! isset( $theme_json['styles'] ) ) { @@ -2630,7 +2646,8 @@ private static function get_block_nodes( $theme_json, $selectors = array() ) { } $variation_selectors = array(); - if ( isset( $node['variations'] ) ) { + $include_variations = $options['include_block_style_variations'] ?? false; + if ( $include_variations && isset( $node['variations'] ) ) { foreach ( $node['variations'] as $variation => $node ) { $variation_selectors[] = array( 'path' => array( 'styles', 'blocks', $name, 'variations', $variation ), @@ -2646,6 +2663,7 @@ private static function get_block_nodes( $theme_json, $selectors = array() ) { 'selectors' => $feature_selectors, 'duotone' => $duotone_selector, 'variations' => $variation_selectors, + 'css' => $selector, ); if ( isset( $theme_json['styles']['blocks'][ $name ]['elements'] ) ) { @@ -2694,6 +2712,7 @@ public function get_styles_for_block( $block_metadata ) { // If there are style variations, generate the declarations for them, including any feature selectors the block may have. $style_variation_declarations = array(); + $style_variation_custom_css = array(); if ( ! empty( $block_metadata['variations'] ) ) { foreach ( $block_metadata['variations'] as $style_variation ) { $style_variation_node = _wp_array_get( $this->theme_json, $style_variation['path'], array() ); @@ -2720,9 +2739,12 @@ static function ( $split_selector ) use ( $clean_style_variation_selector ) { // Add the new declarations to the overall results under the modified selector. $style_variation_declarations[ $combined_selectors ] = $new_declarations; } - // Compute declarations for remaining styles not covered by feature level selectors. $style_variation_declarations[ $style_variation['selector'] ] = static::compute_style_properties( $style_variation_node, $settings, null, $this->theme_json ); + // Store custom CSS for the style variation. + if ( isset( $style_variation_node['css'] ) ) { + $style_variation_custom_css[ $style_variation['selector'] ] = $this->process_blocks_custom_css( $style_variation_node['css'], $style_variation['selector'] ); + } } } @@ -2853,6 +2875,14 @@ static function ( $pseudo_selector ) use ( $selector ) { // 6. Generate and append the style variation rulesets. foreach ( $style_variation_declarations as $style_variation_selector => $individual_style_variation_declarations ) { $block_rules .= static::to_ruleset( ":root :where($style_variation_selector)", $individual_style_variation_declarations ); + if ( isset( $style_variation_custom_css[ $style_variation_selector ] ) ) { + $block_rules .= $style_variation_custom_css[ $style_variation_selector ]; + } + } + + // 7. Generate and append any custom CSS rules. + if ( isset( $node['css'] ) && ! $is_root_selector ) { + $block_rules .= $this->process_blocks_custom_css( $node['css'], $selector ); } return $block_rules; @@ -3301,7 +3331,8 @@ public static function remove_insecure_properties( $theme_json, $origin = 'theme $theme_json = static::sanitize( $theme_json, $valid_block_names, $valid_element_names, $valid_variations ); $blocks_metadata = static::get_blocks_metadata(); - $style_nodes = static::get_style_nodes( $theme_json, $blocks_metadata ); + $style_options = array( 'include_block_style_variations' => true ); // Allow variations data. + $style_nodes = static::get_style_nodes( $theme_json, $blocks_metadata, $style_options ); foreach ( $style_nodes as $metadata ) { $input = _wp_array_get( $theme_json, $metadata['path'], array() ); diff --git a/lib/compat/wordpress-6.5/html-api/class-gutenberg-html-tag-processor-6-5.php b/lib/compat/wordpress-6.5/html-api/class-gutenberg-html-tag-processor-6-5.php index 5c371f4bf6569d..f93a48515d93b6 100644 --- a/lib/compat/wordpress-6.5/html-api/class-gutenberg-html-tag-processor-6-5.php +++ b/lib/compat/wordpress-6.5/html-api/class-gutenberg-html-tag-processor-6-5.php @@ -298,8 +298,8 @@ * * The special elements are: * - `SCRIPT` whose contents are treated as raw plaintext but supports a legacy - * style of including Javascript inside of HTML comments to avoid accidentally - * closing the SCRIPT from inside a Javascript string. E.g. `console.log( '' )`. + * style of including JavaScript inside of HTML comments to avoid accidentally + * closing the SCRIPT from inside a JavaScript string. E.g. `console.log( '' )`. * - `TITLE` and `TEXTAREA` whose contents are treated as plaintext and then any * character references are decoded. E.g. `1 < 2 < 3` becomes `1 < 2 < 3`. * - `IFRAME`, `NOSCRIPT`, `NOEMBED`, `NOFRAME`, `STYLE` whose contents are treated as diff --git a/lib/compat/wordpress-6.6/admin-bar.php b/lib/compat/wordpress-6.6/admin-bar.php index 8892559cd7f62a..b7a77faebea72a 100644 --- a/lib/compat/wordpress-6.6/admin-bar.php +++ b/lib/compat/wordpress-6.6/admin-bar.php @@ -25,14 +25,14 @@ function gutenberg_admin_bar_edit_site_menu( $wp_admin_bar ) { } // Don't show for users who can't edit theme options or when in the admin. - if ( ! current_user_can( 'edit_theme_options' ) || is_admin() ) { + if ( ! current_user_can( 'edit_theme_options' ) || is_admin() || ( is_blog_admin() && is_multisite() && current_user_can( 'manage_sites' ) ) ) { return; } $wp_admin_bar->add_node( array( 'id' => 'site-editor', - 'title' => __( 'Site Editor' ), + 'title' => __( 'Edit site' ), 'href' => add_query_arg( array( 'postType' => 'wp_template', diff --git a/lib/global-styles-and-settings.php b/lib/global-styles-and-settings.php index 4ceade6c7125b1..79c7028e32543e 100644 --- a/lib/global-styles-and-settings.php +++ b/lib/global-styles-and-settings.php @@ -144,6 +144,7 @@ function gutenberg_get_global_settings( $path = array(), $context = array() ) { * @return string */ function gutenberg_get_global_styles_custom_css() { + _deprecated_function( __FUNCTION__, 'Gutenberg 18.6.0', 'gutenberg_get_global_stylesheet' ); // Ignore cache when `WP_DEBUG` is enabled, so it doesn't interfere with the theme developers workflow. $can_use_cached = ! WP_DEBUG; $cache_key = 'gutenberg_get_global_custom_css'; @@ -177,6 +178,7 @@ function gutenberg_get_global_styles_custom_css() { * @return string The global base custom CSS. */ function gutenberg_get_global_styles_base_custom_css() { + _deprecated_function( __FUNCTION__, 'Gutenberg 18.6.0', 'gutenberg_get_global_stylesheet' ); if ( ! wp_theme_has_theme_json() ) { return ''; } @@ -211,6 +213,7 @@ function gutenberg_get_global_styles_base_custom_css() { * @global WP_Styles $wp_styles */ function gutenberg_add_global_styles_block_custom_css() { + _deprecated_function( __FUNCTION__, 'Gutenberg 18.6.0', 'gutenberg_add_global_styles_for_blocks' ); global $wp_styles; if ( ! wp_theme_has_theme_json() || ! wp_should_load_separate_core_block_assets() ) { diff --git a/lib/script-loader.php b/lib/script-loader.php index 01008a0da8967e..59df13556e9cfc 100644 --- a/lib/script-loader.php +++ b/lib/script-loader.php @@ -43,45 +43,29 @@ function gutenberg_enqueue_global_styles() { add_filter( 'wp_theme_json_get_style_nodes', 'wp_filter_out_block_nodes' ); $stylesheet = gutenberg_get_global_stylesheet(); - if ( empty( $stylesheet ) ) { - return; - } - - wp_register_style( 'global-styles', false ); - wp_add_inline_style( 'global-styles', $stylesheet ); - wp_enqueue_style( 'global-styles' ); - - // Add each block as an inline css. - gutenberg_add_global_styles_for_blocks(); /* - * Add the custom CSS for the global styles. - * Before that, dequeue the Customizer's custom CSS + * Dequeue the Customizer's custom CSS * and add it before the global styles custom CSS. - * Don't enqueue Customizer's custom CSS separately. */ remove_action( 'wp_head', 'wp_custom_css_cb', 101 ); + // Get the custom CSS from the Customizer and add it to the global stylesheet. + $custom_css = wp_get_custom_css(); + $stylesheet .= $custom_css; - $custom_css = wp_get_custom_css(); + // Add the global styles custom CSS at the end. + $stylesheet .= gutenberg_get_global_stylesheet( array( 'custom-css' ) ); - if ( ! wp_should_load_separate_core_block_assets() ) { - /* - * If loading all block assets together, add both - * the base and block custom CSS at once. Else load - * the base custom CSS only, and the block custom CSS - * will be added to the inline CSS for each block in - * gutenberg_add_global_styles_block_custom_css(). - */ - $custom_css .= gutenberg_get_global_styles_custom_css(); - } else { - $custom_css .= gutenberg_get_global_styles_base_custom_css(); + if ( empty( $stylesheet ) ) { + return; } - if ( ! empty( $custom_css ) ) { - wp_add_inline_style( 'global-styles', $custom_css ); - } + wp_register_style( 'global-styles', false ); + wp_add_inline_style( 'global-styles', $stylesheet ); + wp_enqueue_style( 'global-styles' ); - gutenberg_add_global_styles_block_custom_css(); + // Add each block as an inline css. + gutenberg_add_global_styles_for_blocks(); } add_action( 'wp_enqueue_scripts', 'gutenberg_enqueue_global_styles' ); add_action( 'wp_footer', 'gutenberg_enqueue_global_styles', 1 ); diff --git a/lib/theme-i18n.json b/lib/theme-i18n.json index e4d14502132cbe..fe541e65c676ba 100644 --- a/lib/theme-i18n.json +++ b/lib/theme-i18n.json @@ -81,6 +81,15 @@ } } }, + "styles": { + "blocks": { + "variations": { + "*": { + "title": "Style variation name" + } + } + } + }, "customTemplates": [ { "title": "Custom template name" diff --git a/package-lock.json b/package-lock.json index 4f2901c8fe8bd5..9fceaac246b7ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gutenberg", - "version": "18.5.0", + "version": "18.6.0-rc.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gutenberg", - "version": "18.5.0", + "version": "18.6.0-rc.1", "hasInstallScript": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -80,7 +80,8 @@ "@wordpress/warning": "file:packages/warning", "@wordpress/widgets": "file:packages/widgets", "@wordpress/wordcount": "file:packages/wordcount", - "es-module-shims": "^1.8.2" + "es-module-shims": "^1.8.2", + "postcss-local-keyframes": "^0.0.2" }, "devDependencies": { "@actions/core": "1.9.1", @@ -169,7 +170,7 @@ "babel-plugin-transform-remove-console": "6.9.4", "benchmark": "2.1.4", "browserslist": "4.22.2", - "caniuse-lite": "1.0.30001579", + "caniuse-lite": "1.0.30001636", "chalk": "4.1.1", "change-case": "4.1.2", "client-zip": "^2.4.5", @@ -21439,9 +21440,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001579", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz", - "integrity": "sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==", + "version": "1.0.30001636", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", + "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", "funding": [ { "type": "opencollective", @@ -21455,7 +21456,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/capital-case": { "version": "1.0.4", @@ -42422,6 +42424,17 @@ "webpack": "^5.0.0" } }, + "node_modules/postcss-local-keyframes": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/postcss-local-keyframes/-/postcss-local-keyframes-0.0.2.tgz", + "integrity": "sha512-nRN01llvxnqLw1TZu4kBknHwpxPPK3DLLJClQ3eTGhS+jBNyoIAMx0hw+fdiDOy7TXjfnojamPwUm/UxBEZDTw==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.2.8" + } + }, "node_modules/postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", @@ -53064,7 +53077,7 @@ }, "packages/a11y": { "name": "@wordpress/a11y", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53078,7 +53091,7 @@ }, "packages/annotations": { "name": "@wordpress/annotations", - "version": "3.0.0", + "version": "3.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53106,7 +53119,7 @@ }, "packages/api-fetch": { "name": "@wordpress/api-fetch", - "version": "7.0.0", + "version": "7.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53120,7 +53133,7 @@ }, "packages/autop": { "name": "@wordpress/autop", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -53132,7 +53145,7 @@ }, "packages/babel-plugin-import-jsx-pragma": { "name": "@wordpress/babel-plugin-import-jsx-pragma", - "version": "5.0.0", + "version": "5.1.0", "dev": true, "license": "GPL-2.0-or-later", "engines": { @@ -53145,7 +53158,7 @@ }, "packages/babel-plugin-makepot": { "name": "@wordpress/babel-plugin-makepot", - "version": "6.0.0", + "version": "6.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -53163,7 +53176,7 @@ }, "packages/babel-preset-default": { "name": "@wordpress/babel-preset-default", - "version": "8.0.0", + "version": "8.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -53186,7 +53199,7 @@ }, "packages/base-styles": { "name": "@wordpress/base-styles", - "version": "5.0.0", + "version": "5.1.0", "dev": true, "license": "GPL-2.0-or-later", "engines": { @@ -53196,7 +53209,7 @@ }, "packages/blob": { "name": "@wordpress/blob", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -53208,7 +53221,7 @@ }, "packages/block-directory": { "name": "@wordpress/block-directory", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53244,7 +53257,7 @@ }, "packages/block-editor": { "name": "@wordpress/block-editor", - "version": "13.0.0", + "version": "13.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53358,7 +53371,7 @@ }, "packages/block-library": { "name": "@wordpress/block-library", - "version": "9.0.0", + "version": "9.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53424,7 +53437,7 @@ }, "packages/block-serialization-default-parser": { "name": "@wordpress/block-serialization-default-parser", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -53436,7 +53449,7 @@ }, "packages/block-serialization-spec-parser": { "name": "@wordpress/block-serialization-spec-parser", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "pegjs": "^0.10.0", @@ -53449,7 +53462,7 @@ }, "packages/blocks": { "name": "@wordpress/blocks", - "version": "13.0.0", + "version": "13.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53502,7 +53515,7 @@ }, "packages/browserslist-config": { "name": "@wordpress/browserslist-config", - "version": "6.0.0", + "version": "6.1.0", "dev": true, "license": "GPL-2.0-or-later", "engines": { @@ -53512,7 +53525,7 @@ }, "packages/commands": { "name": "@wordpress/commands", - "version": "1.0.0", + "version": "1.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53537,7 +53550,7 @@ }, "packages/components": { "name": "@wordpress/components", - "version": "28.0.0", + "version": "28.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@ariakit/react": "^0.3.12", @@ -53629,7 +53642,7 @@ }, "packages/compose": { "name": "@wordpress/compose", - "version": "7.0.0", + "version": "7.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53666,7 +53679,7 @@ }, "packages/core-commands": { "name": "@wordpress/core-commands", - "version": "1.0.0", + "version": "1.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53693,7 +53706,7 @@ }, "packages/core-data": { "name": "@wordpress/core-data", - "version": "7.0.0", + "version": "7.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53737,7 +53750,7 @@ }, "packages/create-block": { "name": "@wordpress/create-block", - "version": "4.43.0", + "version": "4.44.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -53765,7 +53778,7 @@ }, "packages/create-block-tutorial-template": { "name": "@wordpress/create-block-tutorial-template", - "version": "4.0.0", + "version": "4.1.0", "dev": true, "license": "GPL-2.0-or-later", "engines": { @@ -53775,7 +53788,7 @@ }, "packages/customize-widgets": { "name": "@wordpress/customize-widgets", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53813,7 +53826,7 @@ }, "packages/data": { "name": "@wordpress/data", - "version": "10.0.0", + "version": "10.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53842,7 +53855,7 @@ }, "packages/data-controls": { "name": "@wordpress/data-controls", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53860,7 +53873,7 @@ }, "packages/dataviews": { "name": "@wordpress/dataviews", - "version": "2.0.0", + "version": "2.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@ariakit/react": "^0.3.12", @@ -53920,7 +53933,7 @@ }, "packages/date": { "name": "@wordpress/date", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53935,7 +53948,7 @@ }, "packages/dependency-extraction-webpack-plugin": { "name": "@wordpress/dependency-extraction-webpack-plugin", - "version": "6.0.0", + "version": "6.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -53951,7 +53964,7 @@ }, "packages/deprecated": { "name": "@wordpress/deprecated", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53964,7 +53977,7 @@ }, "packages/docgen": { "name": "@wordpress/docgen", - "version": "2.0.0", + "version": "2.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -53986,7 +53999,7 @@ }, "packages/dom": { "name": "@wordpress/dom", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -53999,7 +54012,7 @@ }, "packages/dom-ready": { "name": "@wordpress/dom-ready", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -54011,7 +54024,7 @@ }, "packages/e2e-test-utils": { "name": "@wordpress/e2e-test-utils", - "version": "11.0.0", + "version": "11.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54034,7 +54047,7 @@ }, "packages/e2e-test-utils-playwright": { "name": "@wordpress/e2e-test-utils-playwright", - "version": "1.0.0", + "version": "1.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54058,7 +54071,7 @@ }, "packages/e2e-tests": { "name": "@wordpress/e2e-tests", - "version": "8.0.0", + "version": "8.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54098,7 +54111,7 @@ }, "packages/edit-post": { "name": "@wordpress/edit-post", - "version": "8.0.0", + "version": "8.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54145,7 +54158,7 @@ }, "packages/edit-site": { "name": "@wordpress/edit-site", - "version": "6.0.0", + "version": "6.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54207,7 +54220,7 @@ }, "packages/edit-widgets": { "name": "@wordpress/edit-widgets", - "version": "6.0.0", + "version": "6.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54250,7 +54263,7 @@ }, "packages/editor": { "name": "@wordpress/editor", - "version": "14.0.0", + "version": "14.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54309,7 +54322,7 @@ }, "packages/element": { "name": "@wordpress/element", - "version": "6.0.0", + "version": "6.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54328,7 +54341,7 @@ }, "packages/env": { "name": "@wordpress/env", - "version": "10.0.0", + "version": "10.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54469,7 +54482,7 @@ }, "packages/escape-html": { "name": "@wordpress/escape-html", - "version": "3.0.0", + "version": "3.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -54481,7 +54494,7 @@ }, "packages/eslint-plugin": { "name": "@wordpress/eslint-plugin", - "version": "19.0.0", + "version": "19.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54524,7 +54537,7 @@ }, "packages/format-library": { "name": "@wordpress/format-library", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54552,7 +54565,7 @@ }, "packages/hooks": { "name": "@wordpress/hooks", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -54564,7 +54577,7 @@ }, "packages/html-entities": { "name": "@wordpress/html-entities", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -54576,7 +54589,7 @@ }, "packages/i18n": { "name": "@wordpress/i18n", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54596,7 +54609,7 @@ }, "packages/icons": { "name": "@wordpress/icons", - "version": "10.0.0", + "version": "10.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54610,7 +54623,7 @@ }, "packages/interactivity": { "name": "@wordpress/interactivity", - "version": "6.0.0", + "version": "6.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@preact/signals": "^1.2.2", @@ -54624,7 +54637,7 @@ }, "packages/interactivity-router": { "name": "@wordpress/interactivity-router", - "version": "2.0.0", + "version": "2.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@wordpress/interactivity": "file:../interactivity" @@ -54685,7 +54698,7 @@ }, "packages/interface": { "name": "@wordpress/interface", - "version": "6.0.0", + "version": "6.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54714,7 +54727,7 @@ }, "packages/is-shallow-equal": { "name": "@wordpress/is-shallow-equal", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -54726,7 +54739,7 @@ }, "packages/jest-console": { "name": "@wordpress/jest-console", - "version": "8.0.0", + "version": "8.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54743,7 +54756,7 @@ }, "packages/jest-preset-default": { "name": "@wordpress/jest-preset-default", - "version": "12.0.0", + "version": "12.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54761,7 +54774,7 @@ }, "packages/jest-puppeteer-axe": { "name": "@wordpress/jest-puppeteer-axe", - "version": "7.0.0", + "version": "7.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54784,7 +54797,7 @@ }, "packages/keyboard-shortcuts": { "name": "@wordpress/keyboard-shortcuts", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54802,7 +54815,7 @@ }, "packages/keycodes": { "name": "@wordpress/keycodes", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54815,7 +54828,7 @@ }, "packages/lazy-import": { "name": "@wordpress/lazy-import", - "version": "2.0.0", + "version": "2.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54830,7 +54843,7 @@ }, "packages/list-reusable-blocks": { "name": "@wordpress/list-reusable-blocks", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54853,7 +54866,7 @@ }, "packages/media-utils": { "name": "@wordpress/media-utils", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54869,7 +54882,7 @@ }, "packages/notices": { "name": "@wordpress/notices", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54886,7 +54899,7 @@ }, "packages/npm-package-json-lint-config": { "name": "@wordpress/npm-package-json-lint-config", - "version": "5.0.0", + "version": "5.1.0", "dev": true, "license": "GPL-2.0-or-later", "engines": { @@ -54899,7 +54912,7 @@ }, "packages/nux": { "name": "@wordpress/nux", - "version": "9.0.0", + "version": "9.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54922,7 +54935,7 @@ }, "packages/patterns": { "name": "@wordpress/patterns", - "version": "2.0.0", + "version": "2.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54952,7 +54965,7 @@ }, "packages/plugins": { "name": "@wordpress/plugins", - "version": "7.0.0", + "version": "7.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -54975,7 +54988,7 @@ }, "packages/postcss-plugins-preset": { "name": "@wordpress/postcss-plugins-preset", - "version": "5.0.0", + "version": "5.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -54992,7 +55005,7 @@ }, "packages/postcss-themes": { "name": "@wordpress/postcss-themes", - "version": "6.0.0", + "version": "6.1.0", "dev": true, "license": "GPL-2.0-or-later", "engines": { @@ -55005,7 +55018,7 @@ }, "packages/preferences": { "name": "@wordpress/preferences", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55031,7 +55044,7 @@ }, "packages/preferences-persistence": { "name": "@wordpress/preferences-persistence", - "version": "2.0.0", + "version": "2.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55044,7 +55057,7 @@ }, "packages/prettier-config": { "name": "@wordpress/prettier-config", - "version": "4.0.0", + "version": "4.1.0", "dev": true, "license": "GPL-2.0-or-later", "engines": { @@ -55057,7 +55070,7 @@ }, "packages/primitives": { "name": "@wordpress/primitives", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55071,7 +55084,7 @@ }, "packages/priority-queue": { "name": "@wordpress/priority-queue", - "version": "3.0.0", + "version": "3.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55084,7 +55097,7 @@ }, "packages/private-apis": { "name": "@wordpress/private-apis", - "version": "1.0.0", + "version": "1.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -55096,7 +55109,7 @@ }, "packages/project-management-automation": { "name": "@wordpress/project-management-automation", - "version": "2.0.0", + "version": "2.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -55113,7 +55126,7 @@ }, "packages/react-i18n": { "name": "@wordpress/react-i18n", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55269,7 +55282,7 @@ }, "packages/readable-js-assets-webpack-plugin": { "name": "@wordpress/readable-js-assets-webpack-plugin", - "version": "3.0.0", + "version": "3.1.0", "dev": true, "license": "GPL-2.0-or-later", "engines": { @@ -55282,7 +55295,7 @@ }, "packages/redux-routine": { "name": "@wordpress/redux-routine", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55327,7 +55340,7 @@ }, "packages/reusable-blocks": { "name": "@wordpress/reusable-blocks", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55354,7 +55367,7 @@ }, "packages/rich-text": { "name": "@wordpress/rich-text", - "version": "7.0.0", + "version": "7.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55378,7 +55391,7 @@ }, "packages/router": { "name": "@wordpress/router", - "version": "1.0.0", + "version": "1.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55397,7 +55410,7 @@ }, "packages/scripts": { "name": "@wordpress/scripts", - "version": "28.0.0", + "version": "28.1.0", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -55783,7 +55796,7 @@ }, "packages/server-side-render": { "name": "@wordpress/server-side-render", - "version": "5.0.0", + "version": "5.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55809,7 +55822,7 @@ }, "packages/shortcode": { "name": "@wordpress/shortcode", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55822,7 +55835,7 @@ }, "packages/style-engine": { "name": "@wordpress/style-engine", - "version": "2.0.0", + "version": "2.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55835,7 +55848,7 @@ }, "packages/stylelint-config": { "name": "@wordpress/stylelint-config", - "version": "22.0.0", + "version": "22.1.0", "dev": true, "license": "MIT", "dependencies": { @@ -55852,7 +55865,7 @@ }, "packages/sync": { "name": "@wordpress/sync", - "version": "1.0.0", + "version": "1.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55873,7 +55886,7 @@ }, "packages/token-list": { "name": "@wordpress/token-list", - "version": "3.0.0", + "version": "3.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -55885,7 +55898,7 @@ }, "packages/undo-manager": { "name": "@wordpress/undo-manager", - "version": "1.0.0", + "version": "1.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55898,7 +55911,7 @@ }, "packages/url": { "name": "@wordpress/url", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55911,7 +55924,7 @@ }, "packages/viewport": { "name": "@wordpress/viewport", - "version": "6.0.0", + "version": "6.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55929,7 +55942,7 @@ }, "packages/warning": { "name": "@wordpress/warning", - "version": "3.0.0", + "version": "3.1.0", "license": "GPL-2.0-or-later", "engines": { "node": ">=18.12.0", @@ -55938,7 +55951,7 @@ }, "packages/widgets": { "name": "@wordpress/widgets", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", @@ -55966,7 +55979,7 @@ }, "packages/wordcount": { "name": "@wordpress/wordcount", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0" @@ -72832,9 +72845,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001579", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz", - "integrity": "sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==" + "version": "1.0.30001636", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", + "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==" }, "capital-case": { "version": "1.0.4", @@ -88797,6 +88810,11 @@ "semver": "^7.3.5" } }, + "postcss-local-keyframes": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/postcss-local-keyframes/-/postcss-local-keyframes-0.0.2.tgz", + "integrity": "sha512-nRN01llvxnqLw1TZu4kBknHwpxPPK3DLLJClQ3eTGhS+jBNyoIAMx0hw+fdiDOy7TXjfnojamPwUm/UxBEZDTw==" + }, "postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", diff --git a/package.json b/package.json index ca8ebb89876a60..42f796f442a262 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "18.5.0", + "version": "18.6.0-rc.1", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", @@ -92,7 +92,8 @@ "@wordpress/warning": "file:packages/warning", "@wordpress/widgets": "file:packages/widgets", "@wordpress/wordcount": "file:packages/wordcount", - "es-module-shims": "^1.8.2" + "es-module-shims": "^1.8.2", + "postcss-local-keyframes": "^0.0.2" }, "devDependencies": { "@actions/core": "1.9.1", @@ -181,7 +182,7 @@ "babel-plugin-transform-remove-console": "6.9.4", "benchmark": "2.1.4", "browserslist": "4.22.2", - "caniuse-lite": "1.0.30001579", + "caniuse-lite": "1.0.30001636", "chalk": "4.1.1", "change-case": "4.1.2", "client-zip": "^2.4.5", @@ -274,8 +275,8 @@ "build:plugin-zip": "bash ./bin/build-plugin-zip.sh", "clean:package-types": "tsc --build --clean && rimraf \"./packages/*/build-types\"", "clean:packages": "rimraf \"./packages/*/@(build|build-module|build-style)\"", - "dev": "npm run build:packages && concurrently \"wp-scripts start\" \"npm run dev:packages\"", - "dev:packages": "concurrently \"node ./bin/packages/watch.js\" \"tsc --build --watch\"", + "dev": "cross-env NODE_ENV=development npm run build:packages && concurrently \"wp-scripts start\" \"npm run dev:packages\"", + "dev:packages": "cross-env NODE_ENV=development concurrently \"node ./bin/packages/watch.js\" \"tsc --build --watch\"", "distclean": "git clean --force -d -X", "docs:api-ref": "node ./bin/api-docs/update-api-docs.js", "docs:blocks": "node ./bin/api-docs/gen-block-lib-list.js", diff --git a/packages/a11y/CHANGELOG.md b/packages/a11y/CHANGELOG.md index 6505d2b35579ab..14f0d5ee2cc3dd 100644 --- a/packages/a11y/CHANGELOG.md +++ b/packages/a11y/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.1.0 (2024-06-15) + ## 4.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/a11y/package.json b/packages/a11y/package.json index 7ab67fe4c16233..a3c205af4905bb 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "4.0.0", + "version": "4.1.0", "description": "Accessibility (a11y) utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/annotations/CHANGELOG.md b/packages/annotations/CHANGELOG.md index eb85e84d604f5d..50dfcc8e55e227 100644 --- a/packages/annotations/CHANGELOG.md +++ b/packages/annotations/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.1.0 (2024-06-15) + ## 3.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/annotations/package.json b/packages/annotations/package.json index cba00c1591e13a..8b2013129ba062 100644 --- a/packages/annotations/package.json +++ b/packages/annotations/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/annotations", - "version": "3.0.0", + "version": "3.1.0", "description": "Annotate content in the Gutenberg editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/api-fetch/CHANGELOG.md b/packages/api-fetch/CHANGELOG.md index 6b2495368ee24f..290b08572547ce 100644 --- a/packages/api-fetch/CHANGELOG.md +++ b/packages/api-fetch/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 7.1.0 (2024-06-15) + ## 7.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/api-fetch/package.json b/packages/api-fetch/package.json index d200edd4d81e41..a245dcd9e9e236 100644 --- a/packages/api-fetch/package.json +++ b/packages/api-fetch/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/api-fetch", - "version": "7.0.0", + "version": "7.1.0", "description": "Utility to make WordPress REST API requests.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/autop/CHANGELOG.md b/packages/autop/CHANGELOG.md index a1af20c63ba0b1..70d766f623a342 100644 --- a/packages/autop/CHANGELOG.md +++ b/packages/autop/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +## 4.1.0 (2024-06-15) + +### Internal + +- Refactor to TypeScript ([#62583](https://github.com/WordPress/gutenberg/pull/62583)). + ## 4.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/autop/package.json b/packages/autop/package.json index 7946a728ea22db..dc2850c225b9a9 100644 --- a/packages/autop/package.json +++ b/packages/autop/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/autop", - "version": "4.0.0", + "version": "4.1.0", "description": "WordPress's automatic paragraph functions `autop` and `removep`.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/autop/src/index.js b/packages/autop/src/index.ts similarity index 92% rename from packages/autop/src/index.js rename to packages/autop/src/index.ts index 596a028f461643..e4a4b7ff27cb2a 100644 --- a/packages/autop/src/index.js +++ b/packages/autop/src/index.ts @@ -1,9 +1,7 @@ /** * The regular expression for an HTML element. - * - * @type {RegExp} */ -const htmlSplitRegex = ( () => { +const htmlSplitRegex: RegExp = ( () => { /* eslint-disable no-multi-spaces */ const comments = '!' + // Start of comment, after the <. @@ -51,11 +49,11 @@ const htmlSplitRegex = ( () => { /** * Separate HTML elements and comments from the text. * - * @param {string} input The text which has to be formatted. + * @param input The text which has to be formatted. * - * @return {string[]} The formatted text. + * @return The formatted text. */ -function htmlSplit( input ) { +function htmlSplit( input: string ): string[] { const parts = []; let workingInput = input; @@ -65,7 +63,7 @@ function htmlSplit( input ) { // If the `g` flag is omitted, `index` is included. // `htmlSplitRegex` does not have the `g` flag so we can assert it will have an index number. // Assert `match.index` is a number. - const index = /** @type {number} */ ( match.index ); + const index = match.index as number; parts.push( workingInput.slice( 0, index ) ); parts.push( match[ 0 ] ); @@ -82,12 +80,15 @@ function htmlSplit( input ) { /** * Replace characters or phrases within HTML elements only. * - * @param {string} haystack The text which has to be formatted. - * @param {Record} replacePairs In the form {from: 'to', …}. + * @param haystack The text which has to be formatted. + * @param replacePairs In the form {from: 'to', …}. * - * @return {string} The formatted text. + * @return The formatted text. */ -function replaceInHtmlTags( haystack, replacePairs ) { +function replaceInHtmlTags( + haystack: string, + replacePairs: Record< string, string > +): string { // Find all elements. const textArr = htmlSplit( haystack ); let changed = false; @@ -125,9 +126,9 @@ function replaceInHtmlTags( haystack, replacePairs ) { * replace double line-breaks with HTML paragraph tags. The remaining line- * breaks after conversion become `
` tags, unless br is set to 'false'. * - * @param {string} text The text which has to be formatted. - * @param {boolean} br Optional. If set, will convert all remaining line- - * breaks after paragraphing. Default true. + * @param text The text which has to be formatted. + * @param br Optional. If set, will convert all remaining line- + * breaks after paragraphing. Default true. * * @example *```js @@ -135,10 +136,10 @@ function replaceInHtmlTags( haystack, replacePairs ) { * autop( 'my text' ); // "

my text

" * ``` * - * @return {string} Text which has been converted into paragraph tags. + * @return Text which has been converted into paragraph tags. */ -export function autop( text, br = true ) { - const preTags = []; +export function autop( text: string, br: boolean = true ): string { + const preTags: Array< [ string, string ] > = []; if ( text.trim() === '' ) { return ''; @@ -330,7 +331,7 @@ export function autop( text, br = true ) { * Replaces `

` tags with two line breaks except where the `

` has attributes. * Unifies whitespace. Indents `

  • `, `
    ` and `
    ` for better readability. * - * @param {string} html The content from the editor. + * @param html The content from the editor. * * @example * ```js @@ -338,15 +339,14 @@ export function autop( text, br = true ) { * removep( '

    my text

    ' ); // "my text" * ``` * - * @return {string} The content with stripped paragraph tags. + * @return The content with stripped paragraph tags. */ -export function removep( html ) { +export function removep( html: string ): string { const blocklist = 'blockquote|ul|ol|li|dl|dt|dd|table|thead|tbody|tfoot|tr|th|td|h[1-6]|fieldset|figure'; const blocklist1 = blocklist + '|div|p'; const blocklist2 = blocklist + '|pre'; - /** @type {string[]} */ - const preserve = []; + const preserve: string[] = []; let preserveLinebreaks = false; let preserveBr = false; @@ -480,7 +480,7 @@ export function removep( html ) { // Restore preserved tags. if ( preserve.length ) { html = html.replace( //g, () => { - return /** @type {string} */ ( preserve.shift() ); + return preserve.shift() as string; } ); } diff --git a/packages/autop/src/test/index.test.js b/packages/autop/src/test/index.test.ts similarity index 98% rename from packages/autop/src/test/index.test.js rename to packages/autop/src/test/index.test.ts index 734a20ff37be2b..466aade0f25f10 100644 --- a/packages/autop/src/test/index.test.js +++ b/packages/autop/src/test/index.test.ts @@ -311,7 +311,7 @@ test( 'that_autop_treats_block_level_elements_as_blocks', () => { ]; // Check whitespace normalization. - let content = []; + let content: string[] = []; blocks.forEach( ( block ) => { content.push( `<${ block }>foo` ); @@ -388,18 +388,18 @@ test( 'that autop treats inline elements as inline', () => { 'select', ]; - let content = []; - let expected = []; + const content: string[] = []; + const expected: string[] = []; inlines.forEach( ( inline ) => { content.push( `<${ inline }>foo` ); expected.push( `

    <${ inline }>foo

    ` ); } ); - content = content.join( '\n\n' ); - expected = expected.join( '\n' ); + const contentString = content.join( '\n\n' ); + const expectedString = expected.join( '\n' ); - expect( autop( content ).trim() ).toBe( expected ); + expect( autop( contentString ).trim() ).toBe( expectedString ); } ); test( 'element sanity', () => { diff --git a/packages/babel-plugin-import-jsx-pragma/CHANGELOG.md b/packages/babel-plugin-import-jsx-pragma/CHANGELOG.md index 53ced4dd01d2bb..e2d28f989be2c8 100644 --- a/packages/babel-plugin-import-jsx-pragma/CHANGELOG.md +++ b/packages/babel-plugin-import-jsx-pragma/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/babel-plugin-import-jsx-pragma/package.json b/packages/babel-plugin-import-jsx-pragma/package.json index fc7c1294339083..4069427e2266f0 100644 --- a/packages/babel-plugin-import-jsx-pragma/package.json +++ b/packages/babel-plugin-import-jsx-pragma/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/babel-plugin-import-jsx-pragma", - "version": "5.0.0", + "version": "5.1.0", "description": "Babel transform plugin for automatically injecting an import to be used as the pragma for the React JSX Transform plugin.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/babel-plugin-makepot/CHANGELOG.md b/packages/babel-plugin-makepot/CHANGELOG.md index 62a625ec2beeb7..fb97b5a036f414 100644 --- a/packages/babel-plugin-makepot/CHANGELOG.md +++ b/packages/babel-plugin-makepot/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 6.1.0 (2024-06-15) + ## 6.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/babel-plugin-makepot/package.json b/packages/babel-plugin-makepot/package.json index c6f74686e56af2..6e0f58ed11f21f 100644 --- a/packages/babel-plugin-makepot/package.json +++ b/packages/babel-plugin-makepot/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/babel-plugin-makepot", - "version": "6.0.0", + "version": "6.1.0", "description": "WordPress Babel internationalization (i18n) plugin.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/babel-preset-default/CHANGELOG.md b/packages/babel-preset-default/CHANGELOG.md index a59bd0bd795e16..94ca9ee37c6a39 100644 --- a/packages/babel-preset-default/CHANGELOG.md +++ b/packages/babel-preset-default/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 8.1.0 (2024-06-15) + ## 8.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/babel-preset-default/README.md b/packages/babel-preset-default/README.md index 945e1137a328f4..fb853a73ea3c8b 100644 --- a/packages/babel-preset-default/README.md +++ b/packages/babel-preset-default/README.md @@ -2,7 +2,7 @@ Default [Babel](https://babeljs.io/) preset for WordPress development. -The preset includes configuration which enable language features and syntax extensions targeted for support by WordPress. This includes [ECMAScript proposals](https://github.com/tc39/proposals) which have reached [Stage 4 ("Finished")](https://tc39.es/process-document/), as well as the [JSX syntax extension](https://reactjs.org/docs/introducing-jsx.html). For more information, refer to the [JavaScript Coding Guidelines](https://github.com/WordPress/gutenberg/blob/HEAD/docs/contributors/coding-guidelines.md#javascript). +The preset includes configuration which enable language features and syntax extensions targeted for support by WordPress. This includes [ECMAScript proposals](https://github.com/tc39/proposals) which have reached [Stage 4 ("Finished")](https://tc39.es/process-document/), as well as the [JSX syntax extension](https://react.dev/learn/writing-markup-with-jsx). For more information, refer to the [JavaScript Coding Guidelines](https://github.com/WordPress/gutenberg/blob/HEAD/docs/contributors/code/coding-guidelines.md#javascript). ## Installation diff --git a/packages/babel-preset-default/package.json b/packages/babel-preset-default/package.json index e6d8f163b253fe..6e7f46a6480eb1 100644 --- a/packages/babel-preset-default/package.json +++ b/packages/babel-preset-default/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/babel-preset-default", - "version": "8.0.0", + "version": "8.1.0", "description": "Default Babel preset for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/base-styles/CHANGELOG.md b/packages/base-styles/CHANGELOG.md index 51e71a7555b8b9..81eaa88f226805 100644 --- a/packages/base-styles/CHANGELOG.md +++ b/packages/base-styles/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/base-styles/package.json b/packages/base-styles/package.json index 690cd2ea76551e..7d0f3abb46f421 100644 --- a/packages/base-styles/package.json +++ b/packages/base-styles/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/base-styles", - "version": "5.0.0", + "version": "5.1.0", "description": "Base SCSS utilities and variables for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blob/CHANGELOG.md b/packages/blob/CHANGELOG.md index 50b6143dfb3e6c..940db196eede93 100644 --- a/packages/blob/CHANGELOG.md +++ b/packages/blob/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +## 4.1.0 (2024-06-15) + +### Internal + +- Refactor to TypeScript ([#62569](https://github.com/WordPress/gutenberg/pull/62569)). + ## 4.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/blob/README.md b/packages/blob/README.md index 64520a98bd6a79..d315cdab5e4a48 100644 --- a/packages/blob/README.md +++ b/packages/blob/README.md @@ -61,7 +61,7 @@ _Parameters_ _Returns_ -- `File|undefined`: The file for the blob URL. +- `File | undefined`: The file for the blob URL. ### getBlobTypeByURL @@ -73,7 +73,7 @@ _Parameters_ _Returns_ -- `string|undefined`: The blob type. +- `string | undefined`: The blob type. ### isBlobURL @@ -81,7 +81,7 @@ Check whether a url is a blob url. _Parameters_ -- _url_ `string|undefined`: The URL. +- _url_ `string | undefined`: The URL. _Returns_ diff --git a/packages/blob/package.json b/packages/blob/package.json index a6ea4525b3d376..335bf6cba82989 100644 --- a/packages/blob/package.json +++ b/packages/blob/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blob", - "version": "4.0.0", + "version": "4.1.0", "description": "Blob utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blob/src/index.js b/packages/blob/src/index.ts similarity index 66% rename from packages/blob/src/index.js rename to packages/blob/src/index.ts index 2493f81fc4c65b..62a6671db61544 100644 --- a/packages/blob/src/index.js +++ b/packages/blob/src/index.ts @@ -1,16 +1,13 @@ -/** - * @type {Record} - */ -const cache = {}; +const cache: Record< string, File > = {}; /** * Create a blob URL from a file. * - * @param {File} file The file to create a blob URL for. + * @param file The file to create a blob URL for. * - * @return {string} The blob URL. + * @return The blob URL. */ -export function createBlobURL( file ) { +export function createBlobURL( file: File ): string { const url = window.URL.createObjectURL( file ); cache[ url ] = file; @@ -23,11 +20,11 @@ export function createBlobURL( file ) { * `createBlobURL` and not removed by `revokeBlobURL`, otherwise it will return * `undefined`. * - * @param {string} url The blob URL. + * @param url The blob URL. * - * @return {File|undefined} The file for the blob URL. + * @return The file for the blob URL. */ -export function getBlobByURL( url ) { +export function getBlobByURL( url: string ): File | undefined { return cache[ url ]; } @@ -36,20 +33,20 @@ export function getBlobByURL( url ) { * `createBlobURL` and not removed by `revokeBlobURL`, otherwise it will return * `undefined`. * - * @param {string} url The blob URL. + * @param url The blob URL. * - * @return {string|undefined} The blob type. + * @return The blob type. */ -export function getBlobTypeByURL( url ) { +export function getBlobTypeByURL( url: string ): string | undefined { return getBlobByURL( url )?.type.split( '/' )[ 0 ]; // 0: media type , 1: file extension eg ( type: 'image/jpeg' ). } /** * Remove the resource and file cache from memory. * - * @param {string} url The blob URL. + * @param url The blob URL. */ -export function revokeBlobURL( url ) { +export function revokeBlobURL( url: string ): void { if ( cache[ url ] ) { window.URL.revokeObjectURL( url ); } @@ -60,11 +57,11 @@ export function revokeBlobURL( url ) { /** * Check whether a url is a blob url. * - * @param {string|undefined} url The URL. + * @param url The URL. * - * @return {boolean} Is the url a blob url? + * @return Is the url a blob url? */ -export function isBlobURL( url ) { +export function isBlobURL( url: string | undefined ): boolean { if ( ! url || ! url.indexOf ) { return false; } @@ -90,11 +87,15 @@ export function isBlobURL( url ) { * downloadBlob( filename, fileContent, 'application/json' ); * ``` * - * @param {string} filename File name. - * @param {BlobPart} content File content (BufferSource | Blob | string). - * @param {string} contentType (Optional) File mime type. Default is `''`. + * @param filename File name. + * @param content File content (BufferSource | Blob | string). + * @param contentType (Optional) File mime type. Default is `''`. */ -export function downloadBlob( filename, content, contentType = '' ) { +export function downloadBlob( + filename: string, + content: BlobPart, + contentType: string = '' +): void { if ( ! filename || ! content ) { return; } diff --git a/packages/blob/src/test/index.js b/packages/blob/src/test/index.ts similarity index 83% rename from packages/blob/src/test/index.js rename to packages/blob/src/test/index.ts index 47dcb5019ee25e..381b04fd817a6b 100644 --- a/packages/blob/src/test/index.js +++ b/packages/blob/src/test/index.ts @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import { isBlobURL, getBlobTypeByURL, downloadBlob } from '../'; +import { isBlobURL, getBlobTypeByURL, downloadBlob } from '..'; describe( 'isBlobURL', () => { it( 'returns true if the url starts with "blob:"', () => { @@ -13,17 +13,23 @@ describe( 'isBlobURL', () => { } ); it( 'returns false if the url is not defined', () => { - expect( isBlobURL() ).toBe( false ); + expect( + // @ts-expect-error This is not a valid call according to types. + isBlobURL() + ).toBe( false ); } ); } ); describe( 'getBlobTypeByURL', () => { it( 'returns undefined if the blob is not found', () => { - expect( getBlobTypeByURL( 'blob:notexisting' ) ).toBe( undefined ); + expect( getBlobTypeByURL( 'blob:notexisting' ) ).toBeUndefined(); } ); it( 'returns undefined if the url is not defined', () => { - expect( getBlobTypeByURL() ).toBe( undefined ); + expect( + // @ts-expect-error This is not a valid call according to types. + getBlobTypeByURL() + ).toBeUndefined(); } ); } ); @@ -36,13 +42,17 @@ describe( 'downloadBlob', () => { const createElementSpy = jest .spyOn( global.document, 'createElement' ) .mockReturnValue( mockAnchorElement ); + const mockBlob = jest.fn(); - const blobSpy = jest.spyOn( window, 'Blob' ).mockReturnValue( mockBlob ); + const blobSpy = jest + .spyOn( window, 'Blob' ) + .mockReturnValue( mockBlob as unknown as Blob ); jest.spyOn( document.body, 'appendChild' ); jest.spyOn( document.body, 'removeChild' ); beforeEach( () => { // Can't seem to spy on these static methods. They are `undefined`. // Possibly overwritten: https://github.com/WordPress/gutenberg/blob/trunk/packages/jest-preset-default/scripts/setup-globals.js#L5 + // @ts-expect-error This is not a valid URL object. window.URL = { createObjectURL, revokeObjectURL, diff --git a/packages/block-directory/CHANGELOG.md b/packages/block-directory/CHANGELOG.md index eca5759aba1f1e..447942c81773a7 100644 --- a/packages/block-directory/CHANGELOG.md +++ b/packages/block-directory/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index adefc0e827edad..2aea90812b7b7a 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-directory", - "version": "5.0.0", + "version": "5.1.0", "description": "Extend editor with block directory features to search, download and install blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-editor/CHANGELOG.md b/packages/block-editor/CHANGELOG.md index 7127bddacb8289..33317bb8c436db 100644 --- a/packages/block-editor/CHANGELOG.md +++ b/packages/block-editor/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 13.1.0 (2024-06-15) + ## 13.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index bcbe777cedaa9b..22bca4dc5c310a 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-editor", - "version": "13.0.0", + "version": "13.1.0", "description": "Generic block editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-editor/src/components/block-actions/index.js b/packages/block-editor/src/components/block-actions/index.js index b34f8eea936155..5e12165c679424 100644 --- a/packages/block-editor/src/components/block-actions/index.js +++ b/packages/block-editor/src/components/block-actions/index.js @@ -31,12 +31,10 @@ export default function BlockActions( { getDirectInsertBlock, canMoveBlocks, canRemoveBlocks, - getBlockEditingMode, } = select( blockEditorStore ); const blocks = getBlocksByClientId( clientIds ); const rootClientId = getBlockRootClientId( clientIds[ 0 ] ); - const rootBlockEditingMode = getBlockEditingMode( rootClientId ); const canInsertDefaultBlock = canInsertBlockType( getDefaultBlockName(), rootClientId @@ -46,11 +44,9 @@ export default function BlockActions( { : null; return { - canMove: canMoveBlocks( clientIds, rootClientId ), - canRemove: canRemoveBlocks( clientIds, rootClientId ), - canInsertBlock: - ( canInsertDefaultBlock || !! directInsertBlock ) && - rootBlockEditingMode === 'default', + canMove: canMoveBlocks( clientIds ), + canRemove: canRemoveBlocks( clientIds ), + canInsertBlock: canInsertDefaultBlock || !! directInsertBlock, canCopyStyles: blocks.every( ( block ) => { return ( !! block && diff --git a/packages/block-editor/src/components/block-draggable/index.js b/packages/block-editor/src/components/block-draggable/index.js index c86bc55e8ed079..0ba2b857bc693e 100644 --- a/packages/block-editor/src/components/block-draggable/index.js +++ b/packages/block-editor/src/components/block-draggable/index.js @@ -53,7 +53,7 @@ const BlockDraggable = ( { return { srcRootClientId: rootClientId, - isDraggable: canMoveBlocks( clientIds, rootClientId ), + isDraggable: canMoveBlocks( clientIds ), icon: variation?.icon || _getBlockType( blockName )?.icon, visibleInserter: isBlockInsertionPointVisible(), getBlockType: _getBlockType, diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index 030d08b42ce4dd..bdf33c944deb13 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -623,8 +623,8 @@ function BlockListBlockProvider( props ) { } const _isSelected = isBlockSelected( clientId ); - const canRemove = canRemoveBlock( clientId, rootClientId ); - const canMove = canMoveBlock( clientId, rootClientId ); + const canRemove = canRemoveBlock( clientId ); + const canMove = canMoveBlock( clientId ); const match = getActiveBlockVariation( blockName, attributes ); const isMultiSelected = isBlockMultiSelected( clientId ); const checkDeep = true; diff --git a/packages/block-editor/src/components/block-list/block.native.js b/packages/block-editor/src/components/block-list/block.native.js index f76021b50fc4b2..4112d614da35fc 100644 --- a/packages/block-editor/src/components/block-list/block.native.js +++ b/packages/block-editor/src/components/block-list/block.native.js @@ -432,8 +432,8 @@ const applyWithSelect = withSelect( ( select, { clientId, rootClientId } ) => { const attributes = getBlockAttributes( clientId ); const isSelected = isBlockSelected( clientId ); const templateLock = getTemplateLock( rootClientId ); - const canRemove = canRemoveBlock( clientId, rootClientId ); - const canMove = canMoveBlock( clientId, rootClientId ); + const canRemove = canRemoveBlock( clientId ); + const canMove = canMoveBlock( clientId ); // The fallback to `{}` is a temporary fix. // This function should never be called when a block is not present in diff --git a/packages/block-editor/src/components/block-list/use-in-between-inserter.js b/packages/block-editor/src/components/block-list/use-in-between-inserter.js index 044e5b185a2244..68fa8628c54c72 100644 --- a/packages/block-editor/src/components/block-list/use-in-between-inserter.js +++ b/packages/block-editor/src/components/block-list/use-in-between-inserter.js @@ -40,7 +40,9 @@ export function useInBetweenInserter() { } function onMouseMove( event ) { - if ( openRef.current ) { + // openRef is the reference to the insertion point between blocks. + // If the reference is not set or the insertion point is already open, return. + if ( openRef === undefined || openRef.current ) { return; } diff --git a/packages/block-editor/src/components/block-lock/use-block-lock.js b/packages/block-editor/src/components/block-lock/use-block-lock.js index da6ccc4092096d..9917a739eacd83 100644 --- a/packages/block-editor/src/components/block-lock/use-block-lock.js +++ b/packages/block-editor/src/components/block-lock/use-block-lock.js @@ -24,14 +24,12 @@ export default function useBlockLock( clientId ) { canRemoveBlock, canLockBlockType, getBlockName, - getBlockRootClientId, getTemplateLock, } = select( blockEditorStore ); - const rootClientId = getBlockRootClientId( clientId ); const canEdit = canEditBlock( clientId ); - const canMove = canMoveBlock( clientId, rootClientId ); - const canRemove = canRemoveBlock( clientId, rootClientId ); + const canMove = canMoveBlock( clientId ); + const canRemove = canRemoveBlock( clientId ); return { canEdit, diff --git a/packages/block-editor/src/components/block-mover/index.js b/packages/block-editor/src/components/block-mover/index.js index a143ab391a43fd..24f259613351d2 100644 --- a/packages/block-editor/src/components/block-mover/index.js +++ b/packages/block-editor/src/components/block-mover/index.js @@ -46,7 +46,7 @@ function BlockMover( { const blockOrder = getBlockOrder( _rootClientId ); return { - canMove: canMoveBlocks( clientIds, _rootClientId ), + canMove: canMoveBlocks( clientIds ), rootClientId: _rootClientId, isFirst: firstIndex === 0, isLast: lastIndex === blockOrder.length - 1, diff --git a/packages/block-editor/src/components/block-mover/index.native.js b/packages/block-editor/src/components/block-mover/index.native.js index 326479cd3bc6e5..74a72aec01dbef 100644 --- a/packages/block-editor/src/components/block-mover/index.native.js +++ b/packages/block-editor/src/components/block-mover/index.native.js @@ -166,7 +166,7 @@ export default compose( numberOfBlocks: blockOrder.length - 1, isFirst: firstIndex === 0, isLast: lastIndex === blockOrder.length - 1, - canMove: canMoveBlocks( clientIds, rootClientId ), + canMove: canMoveBlocks( clientIds ), rootClientId, }; } ), diff --git a/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js b/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js index 62c5ff4a5f158c..069bd2c9ff1ee4 100644 --- a/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js +++ b/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js @@ -256,7 +256,7 @@ export function BlockSettingsDropdown( { { __( 'Duplicate' ) } ) } - { canInsertBlock && ( + { canInsertBlock && ! isContentOnly && ( <> { - const { - getBlockRootClientId, - getBlockAttributes, - canRemoveBlocks, - } = select( blockEditorStore ); + const { getBlockAttributes, canRemoveBlocks } = + select( blockEditorStore ); const { getActiveBlockVariation, getBlockVariations } = select( blocksStore ); - const rootClientId = getBlockRootClientId( - Array.isArray( clientIds ) ? clientIds[ 0 ] : clientIds - ); - const canRemove = canRemoveBlocks( clientIds, rootClientId ); + + const canRemove = canRemoveBlocks( clientIds ); // Only handle single selected blocks for now. if ( blocks.length !== 1 || ! canRemove ) { return EMPTY_OBJECT; diff --git a/packages/block-editor/src/components/block-switcher/index.js b/packages/block-editor/src/components/block-switcher/index.js index 87970d53c19f42..f7f75dd8fa2ccb 100644 --- a/packages/block-editor/src/components/block-switcher/index.js +++ b/packages/block-editor/src/components/block-switcher/index.js @@ -191,21 +191,14 @@ export const BlockSwitcher = ( { clientIds, disabled, isUsingBindings } ) => { isTemplate, } = useSelect( ( select ) => { - const { - getBlockRootClientId, - getBlocksByClientId, - getBlockAttributes, - canRemoveBlocks, - } = select( blockEditorStore ); + const { getBlocksByClientId, getBlockAttributes, canRemoveBlocks } = + select( blockEditorStore ); const { getBlockStyles, getBlockType, getActiveBlockVariation } = select( blocksStore ); const _blocks = getBlocksByClientId( clientIds ); if ( ! _blocks.length || _blocks.some( ( block ) => ! block ) ) { return { invalidBlocks: true }; } - const rootClientId = getBlockRootClientId( - Array.isArray( clientIds ) ? clientIds[ 0 ] : clientIds - ); const [ { name: firstBlockName } ] = _blocks; const _isSingleBlockSelected = _blocks.length === 1; const blockType = getBlockType( firstBlockName ); @@ -227,7 +220,7 @@ export const BlockSwitcher = ( { clientIds, disabled, isUsingBindings } ) => { } return { - canRemove: canRemoveBlocks( clientIds, rootClientId ), + canRemove: canRemoveBlocks( clientIds ), hasBlockStyles: _isSingleBlockSelected && !! getBlockStyles( firstBlockName )?.length, diff --git a/packages/block-editor/src/components/block-toolbar/index.js b/packages/block-editor/src/components/block-toolbar/index.js index cffb46413c5bbb..6c6acd662ed962 100644 --- a/packages/block-editor/src/components/block-toolbar/index.js +++ b/packages/block-editor/src/components/block-toolbar/index.js @@ -35,9 +35,8 @@ import { store as blockEditorStore } from '../../store'; import __unstableBlockNameContext from './block-name-context'; import NavigableToolbar from '../navigable-toolbar'; import Shuffle from './shuffle'; -import PatternOverridesToolbarIndicator from '../pattern-overrides-toolbar-indicator'; import { useHasBlockToolbar } from './use-has-block-toolbar'; -import { canBindBlock } from '../../hooks/use-bindings-attributes'; + /** * Renders the block toolbar. * @@ -62,18 +61,15 @@ export function PrivateBlockToolbar( { blockClientIds, isDefaultEditingMode, blockType, - blockName, toolbarKey, shouldShowVisualToolbar, showParentSelector, isUsingBindings, - hasParentPattern, } = useSelect( ( select ) => { const { getBlockName, getBlockMode, getBlockParents, - getBlockParentsByBlockName, getSelectedBlockClientIds, isBlockValid, getBlockRootClientId, @@ -96,18 +92,14 @@ export function PrivateBlockToolbar( { const isVisual = selectedBlockClientIds.every( ( id ) => getBlockMode( id ) === 'visual' ); - const bindings = getBlockAttributes( selectedBlockClientId )?.metadata - ?.bindings; - const parentPatternClientId = getBlockParentsByBlockName( - selectedBlockClientId, - 'core/block', - true - )[ 0 ]; + const _isUsingBindings = selectedBlockClientIds.every( + ( clientId ) => + !! getBlockAttributes( clientId )?.metadata?.bindings + ); return { blockClientId: selectedBlockClientId, blockClientIds: selectedBlockClientIds, isDefaultEditingMode: _isDefaultEditingMode, - blockName: _blockName, blockType: selectedBlockClientId && getBlockType( _blockName ), shouldShowVisualToolbar: isValid && isVisual, rootClientId: blockRootClientId, @@ -122,8 +114,7 @@ export function PrivateBlockToolbar( { ) && selectedBlockClientIds.length === 1 && _isDefaultEditingMode, - isUsingBindings: !! bindings, - hasParentPattern: !! parentPatternClientId, + isUsingBindings: _isUsingBindings, }; }, [] ); @@ -176,13 +167,6 @@ export function PrivateBlockToolbar( { { ! isMultiToolbar && isLargeViewport && isDefaultEditingMode && } - { isUsingBindings && - hasParentPattern && - canBindBlock( blockName ) && ( - - ) } { ( shouldShowVisualToolbar || isMultiToolbar ) && ( isDefaultEditingMode || isSynced ) && (
    { const canReset = !! config && ! fastDeepEqual( config, EMPTY_CONFIG ); return [ canReset, - useCallback( - () => setUserConfig( () => EMPTY_CONFIG ), - [ setUserConfig ] - ), + useCallback( () => setUserConfig( EMPTY_CONFIG ), [ setUserConfig ] ), ]; }; 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 b858a2e4140ea9..d3a22335e88433 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 @@ -565,9 +565,44 @@ describe( 'global styles renderer', () => { }, }; - expect( toStyles( Object.freeze( tree ), blockSelectors ) ).toEqual( - ':where(body) {margin: 0;}.is-layout-flow > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }.is-layout-flow > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }.is-layout-flow > .aligncenter { margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }.is-layout-constrained > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }.is-layout-constrained > .aligncenter { margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) { max-width: var(--wp--style--global--content-size); margin-left: auto !important; margin-right: auto !important; }.is-layout-constrained > .alignwide { max-width: var(--wp--style--global--wide-size); }body .is-layout-flex { display:flex; }.is-layout-flex { flex-wrap: wrap; align-items: center; }.is-layout-flex > :is(*, div) { margin: 0; }body .is-layout-grid { display:grid; }.is-layout-grid > :is(*, div) { margin: 0; }' + - ':root :where(.is-style-foo.wp-image.wp-image-spacing){padding-top: 2px;}:root :where(.is-style-foo.wp-image.wp-image-border-color){border-color: blue;}:root :where(.is-style-foo.wp-image){color: blue;}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }' + const hasBlockGapSupport = false; + const hasFallbackGapSupport = true; + const disableLayoutStyles = true; + const disableRootPadding = true; + const styleOptions = { + blockGap: false, + blockStyles: true, + layoutStyles: false, + marginReset: false, + presets: false, + rootPadding: false, + }; + + // Confirm no variation styles by default. + const withoutVariations = toStyles( + Object.freeze( tree ), + blockSelectors, + hasBlockGapSupport, + hasFallbackGapSupport, + disableLayoutStyles, + disableRootPadding, + styleOptions + ); + expect( withoutVariations ).toEqual( '' ); + + // Includes variation styles when requested. + styleOptions.variationStyles = true; + const withVariations = toStyles( + Object.freeze( tree ), + blockSelectors, + hasBlockGapSupport, + hasFallbackGapSupport, + disableLayoutStyles, + disableRootPadding, + styleOptions + ); + expect( withVariations ).toEqual( + ':root :where(.is-style-foo.wp-image.wp-image-spacing){padding-top: 2px;}:root :where(.is-style-foo.wp-image.wp-image-border-color){border-color: blue;}:root :where(.is-style-foo.wp-image){color: blue;}' ); } ); 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 28e1ddac9ab1d6..adeb021c078c59 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 @@ -651,7 +651,9 @@ export const getNodesWithStyles = ( tree, blockSelectors ) => { ( [ variationName, variation ] ) => { variations[ variationName ] = pickStyleKeys( variation ); - + if ( variation?.css ) { + variations[ variationName ].css = variation.css; + } const variationSelector = blockSelectors[ blockName ] .styleVariationSelectors?.[ variationName ]; @@ -697,6 +699,14 @@ export const getNodesWithStyles = ( tree, blockSelectors ) => { .featureSelectors ); + const variationBlockStyleNodes = + pickStyleKeys( variationBlockStyles ); + + if ( variationBlockStyles?.css ) { + variationBlockStyleNodes.css = + variationBlockStyles.css; + } + nodes.push( { selector: variationBlockSelector, duotoneSelector: variationDuotoneSelector, @@ -707,9 +717,7 @@ export const getNodesWithStyles = ( tree, blockSelectors ) => { hasLayoutSupport: blockSelectors[ variationBlockName ] .hasLayoutSupport, - styles: pickStyleKeys( - variationBlockStyles - ), + styles: variationBlockStyleNodes, } ); // Process element styles for the inner blocks @@ -873,6 +881,7 @@ export const toStyles = ( marginReset: true, presets: true, rootPadding: true, + variationStyles: false, ...styleOptions, }; const nodesWithStyles = getNodesWithStyles( tree, blockSelectors ); @@ -995,8 +1004,14 @@ export const toStyles = ( ';' ) };}`; } + if ( styles?.css ) { + ruleset += processCSSNesting( + styles.css, + `:root :where(${ selector })` + ); + } - if ( styleVariationSelectors ) { + if ( options.variationStyles && styleVariationSelectors ) { Object.entries( styleVariationSelectors ).forEach( ( [ styleVariationName, styleVariationSelector ] ) => { const styleVariations = @@ -1041,6 +1056,12 @@ export const toStyles = ( ';' ) };}`; } + if ( styleVariations?.css ) { + ruleset += processCSSNesting( + styleVariations.css, + `:root :where(${ styleVariationSelector })` + ); + } } } ); diff --git a/packages/block-editor/src/components/inserter/block-types-tab.native.js b/packages/block-editor/src/components/inserter/block-types-tab.native.js index e6108b95d60c37..e92efde21b1388 100644 --- a/packages/block-editor/src/components/inserter/block-types-tab.native.js +++ b/packages/block-editor/src/components/inserter/block-types-tab.native.js @@ -18,7 +18,8 @@ const getBlockNamespace = ( item ) => item.name.split( '/' )[ 0 ]; function BlockTypesTab( { onSelect, rootClientId, listProps } ) { const [ rawBlockTypes, , collections ] = useBlockTypesState( rootClientId, - onSelect + onSelect, + true ); const clipboardBlock = useClipboardBlock( rootClientId ); const filteredBlockTypes = filterInserterItems( rawBlockTypes ); diff --git a/packages/block-editor/src/components/list-view/block.js b/packages/block-editor/src/components/list-view/block.js index 4db12c4d8b77c2..0f6541f9f5b3b9 100644 --- a/packages/block-editor/src/components/list-view/block.js +++ b/packages/block-editor/src/components/list-view/block.js @@ -210,7 +210,7 @@ function ListViewBlock( { } = getBlocksToUpdate(); // Don't update the selection if the blocks cannot be deleted. - if ( ! canRemoveBlocks( blocksToDelete, firstBlockRootClientId ) ) { + if ( ! canRemoveBlocks( blocksToDelete ) ) { return; } diff --git a/packages/block-editor/src/components/list-view/use-clipboard-handler.js b/packages/block-editor/src/components/list-view/use-clipboard-handler.js index dd3ac65ac79d24..e7c3026e70f090 100644 --- a/packages/block-editor/src/components/list-view/use-clipboard-handler.js +++ b/packages/block-editor/src/components/list-view/use-clipboard-handler.js @@ -112,12 +112,7 @@ export default function useClipboardHandler( { selectBlock } ) { if ( event.type === 'cut' ) { // Don't update the selection if the blocks cannot be deleted. - if ( - ! canRemoveBlocks( - selectedBlockClientIds, - firstBlockRootClientId - ) - ) { + if ( ! canRemoveBlocks( selectedBlockClientIds ) ) { return; } diff --git a/packages/block-editor/src/components/pattern-overrides-toolbar-indicator/index.js b/packages/block-editor/src/components/pattern-overrides-toolbar-indicator/index.js deleted file mode 100644 index af359da542d37a..00000000000000 --- a/packages/block-editor/src/components/pattern-overrides-toolbar-indicator/index.js +++ /dev/null @@ -1,120 +0,0 @@ -/** - * WordPress dependencies - */ -import { useId } from '@wordpress/element'; -import { __, sprintf } from '@wordpress/i18n'; -import { - DropdownMenu, - ToolbarGroup, - ToolbarItem, - __experimentalText as Text, -} from '@wordpress/components'; -import { store as blocksStore } from '@wordpress/blocks'; -import { useSelect } from '@wordpress/data'; -import { copy } from '@wordpress/icons'; - -/** - * Internal dependencies - */ -import { store as blockEditorStore } from '../../store'; -import BlockIcon from '../block-icon'; -import useBlockDisplayTitle from '../block-title/use-block-display-title'; - -/** - * This component is currently only for pattern overrides, which is a WP-only feature. - * Ideally, this should be moved to the `patterns` package once ready. - * @param {Object} props The component props. - * @param {Array} props.clientIds The client IDs of the selected blocks. - */ -export default function PatternOverridesToolbarIndicator( { clientIds } ) { - const isSingleBlockSelected = clientIds.length === 1; - const { icon, firstBlockName } = useSelect( - ( select ) => { - const { getBlockAttributes, getBlockNamesByClientId } = - select( blockEditorStore ); - const { getBlockType, getActiveBlockVariation } = - select( blocksStore ); - const blockTypeNames = getBlockNamesByClientId( clientIds ); - const _firstBlockTypeName = blockTypeNames[ 0 ]; - const firstBlockType = getBlockType( _firstBlockTypeName ); - let _icon; - if ( isSingleBlockSelected ) { - const match = getActiveBlockVariation( - _firstBlockTypeName, - getBlockAttributes( clientIds[ 0 ] ) - ); - // Take into account active block variations. - _icon = match?.icon || firstBlockType.icon; - } else { - const isSelectionOfSameType = - new Set( blockTypeNames ).size === 1; - // When selection consists of blocks of multiple types, display an - // appropriate icon to communicate the non-uniformity. - _icon = isSelectionOfSameType ? firstBlockType.icon : copy; - } - - return { - icon: _icon, - firstBlockName: getBlockAttributes( clientIds[ 0 ] ).metadata - .name, - }; - }, - [ clientIds, isSingleBlockSelected ] - ); - const firstBlockTitle = useBlockDisplayTitle( { - clientId: clientIds[ 0 ], - maximumLength: 35, - } ); - - const blockDescription = isSingleBlockSelected - ? sprintf( - /* translators: %1s: The block type's name; %2s: The block's user-provided name (the same as the override name). */ - __( 'This %1$s is editable using the "%2$s" override.' ), - firstBlockTitle.toLowerCase(), - firstBlockName - ) - : __( 'These blocks are editable using overrides.' ); - - const descriptionId = useId(); - - return ( - - - { ( toggleProps ) => ( - - - - } - toggleProps={ { - describedBy: blockDescription, - ...toggleProps, - } } - menuProps={ { - orientation: 'both', - 'aria-describedby': descriptionId, - } } - > - { () => ( - - { blockDescription } - - ) } - - ) } - - - ); -} diff --git a/packages/block-editor/src/components/pattern-overrides-toolbar-indicator/style.scss b/packages/block-editor/src/components/pattern-overrides-toolbar-indicator/style.scss deleted file mode 100644 index 90b2c1cdd79a5e..00000000000000 --- a/packages/block-editor/src/components/pattern-overrides-toolbar-indicator/style.scss +++ /dev/null @@ -1,12 +0,0 @@ -.block-editor-pattern-overrides-toolbar-indicator__popover .components-popover__content { - min-width: 260px; - padding: $grid-unit-20; -} - -.block-editor-pattern-overrides-toolbar-indicator .block-editor-pattern-overrides-toolbar-indicator-icon.has-colors svg { - fill: var(--wp-block-synced-color); -} - -.editor-collapsible-block-toolbar .block-editor-pattern-overrides-toolbar-indicator { - height: 32px; -} diff --git a/packages/block-editor/src/components/rich-text/index.native.js b/packages/block-editor/src/components/rich-text/index.native.js index 2697f5fdf154b6..9390c71bdcf0b5 100644 --- a/packages/block-editor/src/components/rich-text/index.native.js +++ b/packages/block-editor/src/components/rich-text/index.native.js @@ -80,6 +80,7 @@ export function RichTextWrapper( unstableOnFocus, __unstableAllowPrefixTransformations, // Native props. + __unstableUseSplitSelection, __unstableMobileNoFocusOnMount, deleteEnter, placeholderTextColor, @@ -178,6 +179,7 @@ export function RichTextWrapper( exitFormattedText, selectionChange, __unstableMarkAutomaticChange, + __unstableSplitSelection, clearSelectedBlock, } = useDispatch( blockEditorStore ); const adjustedAllowedFormats = getAllowedFormats( { @@ -345,6 +347,8 @@ export function RichTextWrapper( } } else if ( canSplit ) { splitValue( value ); + } else if ( __unstableUseSplitSelection ) { + __unstableSplitSelection(); } else if ( canSplitAtEnd ) { onSplitAtEnd(); } else if ( diff --git a/packages/block-editor/src/components/rich-text/native/index.native.js b/packages/block-editor/src/components/rich-text/native/index.native.js index aa06c4dd1e8926..4eeaabe6d790aa 100644 --- a/packages/block-editor/src/components/rich-text/native/index.native.js +++ b/packages/block-editor/src/components/rich-text/native/index.native.js @@ -424,7 +424,9 @@ export class RichText extends Component { return; } - onDelete( { isReverse, value } ); + if ( onDelete ) { + onDelete( { isReverse, value } ); + } event.preventDefault(); this.lastAztecEventType = 'input'; diff --git a/packages/block-editor/src/components/spacing-sizes-control/hooks/use-spacing-sizes.js b/packages/block-editor/src/components/spacing-sizes-control/hooks/use-spacing-sizes.js index 9943978c15af18..d822dd200b626d 100644 --- a/packages/block-editor/src/components/spacing-sizes-control/hooks/use-spacing-sizes.js +++ b/packages/block-editor/src/components/spacing-sizes-control/hooks/use-spacing-sizes.js @@ -44,15 +44,8 @@ export default function useSpacingSizes() { ...defaultSizes, ]; - // Only sort if more than one origin has presets defined in order to - // preserve order for themes that don't include default presets and - // want a custom order. - if ( - ( customSizes.length && 1 ) + - ( themeSizes.length && 1 ) + - ( defaultSizes.length && 1 ) > - 1 - ) { + // Using numeric slugs opts-in to sorting by slug. + if ( sizes.every( ( { slug } ) => /^[0-9]/.test( slug ) ) ) { sizes.sort( ( a, b ) => compare( a.slug, b.slug ) ); } diff --git a/packages/block-editor/src/components/use-block-commands/index.js b/packages/block-editor/src/components/use-block-commands/index.js index 1b3a1d2215f818..8a09999ecdff3c 100644 --- a/packages/block-editor/src/components/use-block-commands/index.js +++ b/packages/block-editor/src/components/use-block-commands/index.js @@ -65,7 +65,7 @@ export const useTransformCommands = () => { selectedBlocks, rootClientId ), - canRemove: canRemoveBlocks( selectedBlockClientIds, rootClientId ), + canRemove: canRemoveBlocks( selectedBlockClientIds ), invalidSelection: false, }; }, [] ); @@ -150,8 +150,7 @@ const useActionsCommands = () => { const rootClientId = getBlockRootClientId( clientIds[ 0 ] ); const canMove = - canMoveBlocks( clientIds, rootClientId ) && - getBlockCount( rootClientId ) !== 1; + canMoveBlocks( clientIds ) && getBlockCount( rootClientId ) !== 1; const commands = []; @@ -260,7 +259,7 @@ const useQuickActionsCommands = () => { canInsertBlockType( block.name, rootClientId ) ); } ); - const canRemove = canRemoveBlocks( clientIds, rootClientId ); + const canRemove = canRemoveBlocks( clientIds ); const commands = []; diff --git a/packages/block-editor/src/hooks/block-bindings.js b/packages/block-editor/src/hooks/block-bindings.js index ab12d5d73f0b6d..c61f586575a530 100644 --- a/packages/block-editor/src/hooks/block-bindings.js +++ b/packages/block-editor/src/hooks/block-bindings.js @@ -4,6 +4,7 @@ import { __ } from '@wordpress/i18n'; import { store as blocksStore } from '@wordpress/blocks'; import { + BaseControl, PanelBody, __experimentalHStack as HStack, __experimentalItemGroup as ItemGroup, @@ -54,30 +55,35 @@ export const BlockBindingsPanel = ( { name, metadata } ) => { return ( - - { Object.keys( filteredBindings ).map( ( key ) => { - return ( - - - { key } - - { sources[ - filteredBindings[ key ].source - ] - ? sources[ - filteredBindings[ key ] - .source - ].label - : filteredBindings[ key ].source } - - - - ); - } ) } - + + + { Object.keys( filteredBindings ).map( ( key ) => { + return ( + + + { key } + + { sources[ + filteredBindings[ key ].source + ] + ? sources[ + filteredBindings[ key ] + .source + ].label + : filteredBindings[ key ] + .source } + + + + ); + } ) } + + ); diff --git a/packages/block-editor/src/hooks/block-style-variation.js b/packages/block-editor/src/hooks/block-style-variation.js index 311997d46f0ada..3ad8896e735616 100644 --- a/packages/block-editor/src/hooks/block-style-variation.js +++ b/packages/block-editor/src/hooks/block-style-variation.js @@ -116,7 +116,7 @@ function useBlockProps( { name, className, clientId } ) { const hasBlockGapSupport = false; const hasFallbackGapSupport = true; const disableLayoutStyles = true; - const isTemplate = true; + const disableRootPadding = true; return toStyles( variationConfig, @@ -124,7 +124,7 @@ function useBlockProps( { name, className, clientId } ) { hasBlockGapSupport, hasFallbackGapSupport, disableLayoutStyles, - isTemplate, + disableRootPadding, { blockGap: false, blockStyles: true, @@ -132,6 +132,7 @@ function useBlockProps( { name, className, clientId } ) { marginReset: false, presets: false, rootPadding: false, + variationStyles: true, } ); }, [ variation, settings, styles, getBlockStyles, clientId ] ); diff --git a/packages/block-editor/src/hooks/use-bindings-attributes.js b/packages/block-editor/src/hooks/use-bindings-attributes.js index 334c751bc01b0b..7bd5df05d31eb4 100644 --- a/packages/block-editor/src/hooks/use-bindings-attributes.js +++ b/packages/block-editor/src/hooks/use-bindings-attributes.js @@ -97,6 +97,9 @@ export const withBlockBindingSupport = createHigherOrderComponent( unlock( select( blocksStore ) ).getAllBlockBindingsSources() ); const { name, clientId, context } = props; + const hasPatternOverridesDefaultBinding = + props.attributes.metadata?.bindings?.[ DEFAULT_ATTRIBUTE ] + ?.source === 'core/pattern-overrides'; const bindings = useMemo( () => replacePatternOverrideDefaultBindings( @@ -213,7 +216,13 @@ export const withBlockBindingSupport = createHigherOrderComponent( } } - if ( Object.keys( keptAttributes ).length ) { + // Only apply normal attribute updates to blocks + // that have partial bindings. Currently this is + // only skipped for pattern overrides sources. + if ( + ! hasPatternOverridesDefaultBinding && + Object.keys( keptAttributes ).length + ) { setAttributes( keptAttributes ); } } ); @@ -226,6 +235,7 @@ export const withBlockBindingSupport = createHigherOrderComponent( context, setAttributes, sources, + hasPatternOverridesDefaultBinding, ] ); diff --git a/packages/block-editor/src/private-apis.js b/packages/block-editor/src/private-apis.js index 848a3ee49251bd..e6f3fc4cc39d6a 100644 --- a/packages/block-editor/src/private-apis.js +++ b/packages/block-editor/src/private-apis.js @@ -43,6 +43,7 @@ import { PrivateBlockPopover } from './components/block-popover'; import { PrivateInserterLibrary } from './components/inserter/library'; import { PrivatePublishDateTimePicker } from './components/publish-date-time-picker'; import useSpacingSizes from './components/spacing-sizes-control/hooks/use-spacing-sizes'; +import useBlockDisplayTitle from './components/block-title/use-block-display-title'; /** * Private @wordpress/block-editor APIs. @@ -86,4 +87,5 @@ lock( privateApis, { PrivateBlockPopover, PrivatePublishDateTimePicker, useSpacingSizes, + useBlockDisplayTitle, } ); diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index d44fa3e69f86ad..170c5192f3bee9 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -409,7 +409,7 @@ const createOnMove = ( clientIds, rootClientId ) => ( { select, dispatch } ) => { // If one of the blocks is locked or the parent is locked, we cannot move any block. - const canMoveBlocks = select.canMoveBlocks( clientIds, rootClientId ); + const canMoveBlocks = select.canMoveBlocks( clientIds ); if ( ! canMoveBlocks ) { return; } @@ -431,10 +431,7 @@ export const moveBlocksUp = createOnMove( 'MOVE_BLOCKS_UP' ); export const moveBlocksToPosition = ( clientIds, fromRootClientId = '', toRootClientId = '', index ) => ( { select, dispatch } ) => { - const canMoveBlocks = select.canMoveBlocks( - clientIds, - fromRootClientId - ); + const canMoveBlocks = select.canMoveBlocks( clientIds ); // If one of the blocks is locked or the parent is locked, we cannot move any block. if ( ! canMoveBlocks ) { @@ -443,10 +440,7 @@ export const moveBlocksToPosition = // If moving inside the same root block the move is always possible. if ( fromRootClientId !== toRootClientId ) { - const canRemoveBlocks = select.canRemoveBlocks( - clientIds, - fromRootClientId - ); + const canRemoveBlocks = select.canRemoveBlocks( clientIds ); // If we're moving to another block, it means we're deleting blocks from // the original block, so we need to check if removing is possible. @@ -988,7 +982,7 @@ export const __unstableSplitSelection = }, }; - const tail = { + let tail = { ...blockB, // Only preserve the original client ID if the end is different. clientId: @@ -1001,6 +995,26 @@ export const __unstableSplitSelection = }, }; + // When splitting a block, attempt to convert the tail block to the + // default block type. For example, when splitting a heading block, the + // tail block will be converted to a paragraph block. Note that for + // blocks such as a list item and button, this will be skipped because + // the default block type cannot be inserted. + const defaultBlockName = getDefaultBlockName(); + if ( + // A block is only split when the selection is within the same + // block. + blockA.clientId === blockB.clientId && + defaultBlockName && + tail.name !== defaultBlockName && + select.canInsertBlockType( defaultBlockName, anchorRootClientId ) + ) { + const switched = switchToBlockType( tail, defaultBlockName ); + if ( switched?.length === 1 ) { + tail = switched[ 0 ]; + } + } + if ( ! blocks.length ) { dispatch.replaceBlocks( select.getSelectedBlockClientIds(), [ head, diff --git a/packages/block-editor/src/store/private-actions.js b/packages/block-editor/src/store/private-actions.js index 5e4e0c7a222b0b..74aec3c49d1e89 100644 --- a/packages/block-editor/src/store/private-actions.js +++ b/packages/block-editor/src/store/private-actions.js @@ -104,11 +104,7 @@ export const privateRemoveBlocks = } clientIds = castArray( clientIds ); - const rootClientId = select.getBlockRootClientId( clientIds[ 0 ] ); - const canRemoveBlocks = select.canRemoveBlocks( - clientIds, - rootClientId - ); + const canRemoveBlocks = select.canRemoveBlocks( clientIds ); if ( ! canRemoveBlocks ) { return; diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index bf98521dfe9b65..d78d75e4210c8e 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1712,13 +1712,12 @@ export function canInsertBlocks( state, clientIds, rootClientId = null ) { /** * Determines if the given block is allowed to be deleted. * - * @param {Object} state Editor state. - * @param {string} clientId The block client Id. - * @param {?string} rootClientId Optional root client ID of block list. + * @param {Object} state Editor state. + * @param {string} clientId The block client Id. * * @return {boolean} Whether the given block is allowed to be removed. */ -export function canRemoveBlock( state, clientId, rootClientId = null ) { +export function canRemoveBlock( state, clientId ) { const attributes = getBlockAttributes( state, clientId ); if ( attributes === null ) { return true; @@ -1726,6 +1725,8 @@ export function canRemoveBlock( state, clientId, rootClientId = null ) { if ( attributes.lock?.remove !== undefined ) { return ! attributes.lock.remove; } + + const rootClientId = getBlockRootClientId( state, clientId ); if ( getTemplateLock( state, rootClientId ) ) { return false; } @@ -1736,28 +1737,24 @@ export function canRemoveBlock( state, clientId, rootClientId = null ) { /** * Determines if the given blocks are allowed to be removed. * - * @param {Object} state Editor state. - * @param {string} clientIds The block client IDs to be removed. - * @param {?string} rootClientId Optional root client ID of block list. + * @param {Object} state Editor state. + * @param {string} clientIds The block client IDs to be removed. * * @return {boolean} Whether the given blocks are allowed to be removed. */ -export function canRemoveBlocks( state, clientIds, rootClientId = null ) { - return clientIds.every( ( clientId ) => - canRemoveBlock( state, clientId, rootClientId ) - ); +export function canRemoveBlocks( state, clientIds ) { + return clientIds.every( ( clientId ) => canRemoveBlock( state, clientId ) ); } /** * Determines if the given block is allowed to be moved. * - * @param {Object} state Editor state. - * @param {string} clientId The block client Id. - * @param {?string} rootClientId Optional root client ID of block list. + * @param {Object} state Editor state. + * @param {string} clientId The block client Id. * * @return {boolean | undefined} Whether the given block is allowed to be moved. */ -export function canMoveBlock( state, clientId, rootClientId = null ) { +export function canMoveBlock( state, clientId ) { const attributes = getBlockAttributes( state, clientId ); if ( attributes === null ) { return true; @@ -1765,6 +1762,8 @@ export function canMoveBlock( state, clientId, rootClientId = null ) { if ( attributes.lock?.move !== undefined ) { return ! attributes.lock.move; } + + const rootClientId = getBlockRootClientId( state, clientId ); if ( getTemplateLock( state, rootClientId ) === 'all' ) { return false; } @@ -1774,16 +1773,13 @@ export function canMoveBlock( state, clientId, rootClientId = null ) { /** * Determines if the given blocks are allowed to be moved. * - * @param {Object} state Editor state. - * @param {string} clientIds The block client IDs to be moved. - * @param {?string} rootClientId Optional root client ID of block list. + * @param {Object} state Editor state. + * @param {string} clientIds The block client IDs to be moved. * * @return {boolean} Whether the given blocks are allowed to be moved. */ -export function canMoveBlocks( state, clientIds, rootClientId = null ) { - return clientIds.every( ( clientId ) => - canMoveBlock( state, clientId, rootClientId ) - ); +export function canMoveBlocks( state, clientIds ) { + return clientIds.every( ( clientId ) => canMoveBlock( state, clientId ) ); } /** @@ -3041,10 +3037,7 @@ export const isGroupable = createRegistrySelector( rootClientId ); const _isGroupable = groupingBlockAvailable && _clientIds.length; - return ( - _isGroupable && - canRemoveBlocks( state, _clientIds, rootClientId ) - ); + return _isGroupable && canRemoveBlocks( state, _clientIds ); } ); diff --git a/packages/block-editor/src/style.scss b/packages/block-editor/src/style.scss index d22ea9b3d0a283..cf4683b02c707d 100644 --- a/packages/block-editor/src/style.scss +++ b/packages/block-editor/src/style.scss @@ -1,6 +1,5 @@ @import "./autocompleters/style.scss"; @import "./components/block-alignment-control/style.scss"; -@import "./components/pattern-overrides-toolbar-indicator/style.scss"; @import "./components/block-canvas/style.scss"; @import "./components/block-icon/style.scss"; @import "./components/block-inspector/style.scss"; diff --git a/packages/block-library/CHANGELOG.md b/packages/block-library/CHANGELOG.md index 1ef1ad977e9770..b8a1f41dabd892 100644 --- a/packages/block-library/CHANGELOG.md +++ b/packages/block-library/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 9.1.0 (2024-06-15) + ## 9.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 3615ec396d976c..909fc9a53ee679 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "9.0.0", + "version": "9.1.0", "description": "Block library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-library/src/buttons/test/edit.native.js b/packages/block-library/src/buttons/test/edit.native.js index be1762d520e818..fabee59bc5bc6b 100644 --- a/packages/block-library/src/buttons/test/edit.native.js +++ b/packages/block-library/src/buttons/test/edit.native.js @@ -10,6 +10,7 @@ import { initializeEditor, triggerBlockListLayout, typeInRichText, + screen, openBlockSettings, waitFor, } from 'test/helpers'; @@ -92,7 +93,7 @@ describe( 'Buttons block', () => { } ); it( 'adds another button using the inline appender', async () => { - const screen = await initializeEditor( { + await initializeEditor( { initialHtml: BUTTONS_HTML, } ); @@ -143,7 +144,7 @@ describe( 'Buttons block', () => { } ); it( 'adds another button using the inserter', async () => { - const screen = await initializeEditor( { + await initializeEditor( { initialHtml: BUTTONS_HTML, } ); @@ -202,9 +203,48 @@ describe( 'Buttons block', () => { expect( getEditorHtml() ).toMatchSnapshot(); } ); + it( 'shows only the button block when using the inserter', async () => { + await initializeEditor(); + + // Add block + await addBlock( screen, 'Buttons' ); + + // Get block + const buttonsBlock = await getBlock( screen, 'Buttons' ); + fireEvent.press( buttonsBlock ); + await triggerBlockListLayout( buttonsBlock ); + + // Get inner button block + const buttonBlock = await getBlock( screen, 'Button' ); + fireEvent.press( buttonBlock ); + + // Open the block inserter + fireEvent.press( screen.getByLabelText( 'Add block' ) ); + + const inserterList = screen.getByTestId( 'InserterUI-Blocks' ); + // onScroll event used to force the FlatList to render all items + fireEvent.scroll( inserterList, { + nativeEvent: { + contentOffset: { y: 0, x: 0 }, + contentSize: { width: 100, height: 100 }, + layoutMeasurement: { width: 100, height: 100 }, + }, + } ); + + // Check the Button block is in the list + const buttonInserterBlock = + await within( inserterList ).findByText( 'Button' ); + expect( buttonInserterBlock ).toBeVisible(); + + // Check the Paragraph core block is not in the list + expect( + within( inserterList ).queryByLabelText( 'Paragraph block' ) + ).toBeNull(); + } ); + describe( 'removing button along with buttons block', () => { it( 'removes the button and buttons block when deleting the block using the block delete action', async () => { - const screen = await initializeEditor( { + await initializeEditor( { initialHtml: BUTTONS_HTML, } ); @@ -250,7 +290,7 @@ describe( 'Buttons block', () => { 'Justify items right', ].forEach( ( justificationOption ) => it( `sets ${ justificationOption } option`, async () => { - const screen = await initializeEditor( { + await initializeEditor( { initialHtml: BUTTONS_HTML, } ); @@ -276,7 +316,7 @@ describe( 'Buttons block', () => { describe( 'color customization', () => { it( 'sets a text color', async () => { // Arrange - const screen = await initializeEditor(); + await initializeEditor(); await addBlock( screen, 'Buttons' ); // Act @@ -317,7 +357,7 @@ describe( 'Buttons block', () => { it( 'sets a background color', async () => { // Arrange - const screen = await initializeEditor(); + await initializeEditor(); await addBlock( screen, 'Buttons' ); // Act @@ -354,7 +394,7 @@ describe( 'Buttons block', () => { it( 'sets a gradient background color', async () => { // Arrange - const screen = await initializeEditor(); + await initializeEditor(); await addBlock( screen, 'Buttons' ); // Act @@ -396,7 +436,7 @@ describe( 'Buttons block', () => { it( 'sets a custom gradient background color', async () => { // Arrange - const screen = await initializeEditor(); + await initializeEditor(); await addBlock( screen, 'Buttons' ); // Act diff --git a/packages/block-library/src/list-item/edit.native.js b/packages/block-library/src/list-item/edit.native.js index 89f7bd0ace0b7b..2367529242ded1 100644 --- a/packages/block-library/src/list-item/edit.native.js +++ b/packages/block-library/src/list-item/edit.native.js @@ -21,8 +21,7 @@ import { useState, useCallback, useRef } from '@wordpress/element'; /** * Internal dependencies */ -import { useSplit, useMerge, useEnter } from './hooks'; -import { convertToListItems } from './utils'; +import { useMerge, useEnter } from './hooks'; import { IndentUI } from './edit.js'; import styles from './style.scss'; import ListStyleType from './list-style-type'; @@ -32,7 +31,6 @@ const OPACITY = '9e'; export default function ListItemEdit( { attributes, setAttributes, - onReplace, clientId, style, mergeBlocks, @@ -118,24 +116,7 @@ export default function ListItemEdit( { const preventDefault = useRef( false ); const { onEnter } = useEnter( { content, clientId }, preventDefault ); - const onSplit = useSplit( clientId ); const onMerge = useMerge( clientId, mergeBlocks ); - const onSplitList = useCallback( - ( value ) => { - if ( ! preventDefault.current ) { - return onSplit( value ); - } - }, - [ clientId, onSplit ] - ); - const onReplaceList = useCallback( - ( blocks, ...args ) => { - if ( ! preventDefault.current ) { - onReplace( convertToListItems( blocks ), ...args ); - } - }, - [ clientId, onReplace, convertToListItems ] - ); const onLayout = useCallback( ( { nativeEvent } ) => { setContentWidth( ( prevState ) => { const { width } = nativeEvent.layout; @@ -166,6 +147,7 @@ export default function ListItemEdit( { onLayout={ onLayout } > @@ -176,9 +158,7 @@ export default function ListItemEdit( { placeholderTextColor={ defaultPlaceholderTextColorWithOpacity } - onSplit={ onSplitList } onMerge={ onMerge } - onReplace={ onReplaceList } onEnter={ onEnter } style={ styleWithPlaceholderOpacity } deleteEnter diff --git a/packages/block-library/src/post-content/block.json b/packages/block-library/src/post-content/block.json index b0e0487a0b8249..a2d3094137545a 100644 --- a/packages/block-library/src/post-content/block.json +++ b/packages/block-library/src/post-content/block.json @@ -11,11 +11,23 @@ "align": [ "wide", "full" ], "html": false, "layout": true, + "background": { + "backgroundImage": true, + "backgroundSize": true, + "__experimentalDefaultControls": { + "backgroundImage": true + } + }, "dimensions": { "minHeight": true }, "spacing": { - "blockGap": true + "blockGap": true, + "padding": true, + "__experimentalDefaultControls": { + "margin": false, + "padding": false + } }, "color": { "gradients": true, diff --git a/packages/block-library/src/quote/edit.js b/packages/block-library/src/quote/edit.js index d712f9691ee54b..66f8f9d66c85ae 100644 --- a/packages/block-library/src/quote/edit.js +++ b/packages/block-library/src/quote/edit.js @@ -121,6 +121,7 @@ export default function QuoteEdit( { } addLabel={ __( 'Add citation' ) } removeLabel={ __( 'Remove citation' ) } + excludeElementClassName className="wp-block-quote__citation" insertBlocksAfter={ insertBlocksAfter } { ...( ! isWebPlatform ? { textAlign } : {} ) } diff --git a/packages/block-library/src/social-links/test/edit.native.js b/packages/block-library/src/social-links/test/edit.native.js index a4ac5246979aa3..1ff2c89768b03a 100644 --- a/packages/block-library/src/social-links/test/edit.native.js +++ b/packages/block-library/src/social-links/test/edit.native.js @@ -9,6 +9,8 @@ import { initializeEditor, within, getBlock, + screen, + triggerBlockListLayout, waitFor, waitForModalVisible, } from 'test/helpers'; @@ -33,7 +35,7 @@ afterAll( () => { describe( 'Social links block', () => { it( 'inserts block with the default icons and the WordPress link set as active', async () => { - const screen = await initializeEditor(); + await initializeEditor(); // Add block await addBlock( screen, 'Social Icons' ); @@ -65,7 +67,7 @@ describe( 'Social links block', () => { } ); it( 'shows active links correctly when not selected', async () => { - const screen = await initializeEditor(); + await initializeEditor(); // Add Social Icons block await addBlock( screen, 'Social Icons' ); @@ -105,7 +107,7 @@ describe( 'Social links block', () => { } ); it( 'shows the social links bottom sheet when tapping on the inline appender', async () => { - const screen = await initializeEditor(); + await initializeEditor(); // Add block await addBlock( screen, 'Social Icons' ); @@ -154,8 +156,42 @@ describe( 'Social links block', () => { expect( getEditorHtml() ).toMatchSnapshot(); } ); + it( 'shows only the social link blocks when tapping on the inline appender', async () => { + await initializeEditor(); + + // Add block + await addBlock( screen, 'Social Icons' ); + + // Get block + const socialLinksBlock = await getBlock( screen, 'Social Icons' ); + fireEvent.press( socialLinksBlock ); + await triggerBlockListLayout( socialLinksBlock ); + + // Open the links bottom sheet + const appenderButton = + within( socialLinksBlock ).getByTestId( 'appender-button' ); + fireEvent.press( appenderButton ); + + // Find a social link in the inserter + const inserterList = screen.getByTestId( 'InserterUI-Blocks' ); + + // onScroll event used to force the FlatList to render all items + fireEvent.scroll( inserterList, { + nativeEvent: { + contentOffset: { y: 0, x: 0 }, + contentSize: { width: 100, height: 100 }, + layoutMeasurement: { width: 100, height: 100 }, + }, + } ); + + // Check the Paragraph core block is not in the list + expect( + within( inserterList ).queryByLabelText( 'Paragraph block' ) + ).toBeNull(); + } ); + it( 'shows the ghost placeholder when no icon is active', async () => { - const screen = await initializeEditor(); + await initializeEditor(); const { getByLabelText } = screen; // Add block @@ -201,7 +237,7 @@ describe( 'Social links block', () => { } ); it( "should set a icon's URL", async () => { - const screen = await initializeEditor(); + await initializeEditor(); await addBlock( screen, 'Social Icons' ); fireEvent.press( screen.getByLabelText( 'Facebook social icon' ) ); fireEvent.press( screen.getByLabelText( 'Add link to Facebook' ) ); diff --git a/packages/block-library/src/utils/caption.js b/packages/block-library/src/utils/caption.js index 2c653a9cc7fb8c..82e951d4813eb1 100644 --- a/packages/block-library/src/utils/caption.js +++ b/packages/block-library/src/utils/caption.js @@ -32,6 +32,7 @@ export function Caption( { placeholder = __( 'Add caption' ), label = __( 'Caption text' ), showToolbarButton = true, + excludeElementClassName, className, readOnly, tagName = 'figcaption', @@ -70,6 +71,7 @@ export function Caption( { }, [ isCaptionEmpty ] ); + return ( <> { showToolbarButton && ( @@ -96,7 +98,9 @@ export function Caption( { tagName={ tagName } className={ clsx( className, - __experimentalGetElementClassName( 'caption' ) + excludeElementClassName + ? '' + : __experimentalGetElementClassName( 'caption' ) ) } ref={ ref } aria-label={ label } diff --git a/packages/block-serialization-default-parser/CHANGELOG.md b/packages/block-serialization-default-parser/CHANGELOG.md index 199849d08ce2ce..64e20788b79d77 100644 --- a/packages/block-serialization-default-parser/CHANGELOG.md +++ b/packages/block-serialization-default-parser/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/block-serialization-default-parser/package.json b/packages/block-serialization-default-parser/package.json index fba002addabba6..6a8bdb94fa9356 100644 --- a/packages/block-serialization-default-parser/package.json +++ b/packages/block-serialization-default-parser/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-serialization-default-parser", - "version": "5.0.0", + "version": "5.1.0", "description": "Block serialization specification parser for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-serialization-spec-parser/CHANGELOG.md b/packages/block-serialization-spec-parser/CHANGELOG.md index 2048ba7631ee0c..a0d79d05b7a9a0 100644 --- a/packages/block-serialization-spec-parser/CHANGELOG.md +++ b/packages/block-serialization-spec-parser/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/block-serialization-spec-parser/package.json b/packages/block-serialization-spec-parser/package.json index b83b8ebb4b38d4..c9cb21ee361483 100644 --- a/packages/block-serialization-spec-parser/package.json +++ b/packages/block-serialization-spec-parser/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-serialization-spec-parser", - "version": "5.0.0", + "version": "5.1.0", "description": "Block serialization specification parser for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blocks/CHANGELOG.md b/packages/blocks/CHANGELOG.md index de9f9180822d4c..eb1a5db27cc3cf 100644 --- a/packages/blocks/CHANGELOG.md +++ b/packages/blocks/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 13.1.0 (2024-06-15) + ## 13.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/blocks/package.json b/packages/blocks/package.json index 8250de1fac564c..54a434eb0b5406 100644 --- a/packages/blocks/package.json +++ b/packages/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blocks", - "version": "13.0.0", + "version": "13.1.0", "description": "Block API for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blocks/src/api/raw-handling/index.js b/packages/blocks/src/api/raw-handling/index.js index 475453ca61aabf..2d1094023ada1d 100644 --- a/packages/blocks/src/api/raw-handling/index.js +++ b/packages/blocks/src/api/raw-handling/index.js @@ -38,7 +38,13 @@ export function deprecatedGetPhrasingContentSchema( context ) { export function rawHandler( { HTML = '' } ) { // If we detect block delimiters, parse entirely as blocks. if ( HTML.indexOf( ' diff --git a/packages/element/package.json b/packages/element/package.json index fe9a68695b159c..066476f4429f25 100644 --- a/packages/element/package.json +++ b/packages/element/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/element", - "version": "6.0.0", + "version": "6.1.0", "description": "Element React module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/element/src/react.js b/packages/element/src/react.js index 14bd4a66d2e0de..c51f3f16b7fb10 100644 --- a/packages/element/src/react.js +++ b/packages/element/src/react.js @@ -140,7 +140,7 @@ export { Fragment }; export { isValidElement }; /** - * @see https://reactjs.org/docs/react-api.html#reactmemo + * @see https://react.dev/reference/react/memo */ export { memo }; @@ -150,22 +150,22 @@ export { memo }; export { StrictMode }; /** - * @see https://reactjs.org/docs/hooks-reference.html#usecallback + * @see https://react.dev/reference/react/useCallback */ export { useCallback }; /** - * @see https://reactjs.org/docs/hooks-reference.html#usecontext + * @see https://react.dev/reference/react/useContext */ export { useContext }; /** - * @see https://reactjs.org/docs/hooks-reference.html#usedebugvalue + * @see https://react.dev/reference/react/useDebugValue */ export { useDebugValue }; /** - * @see https://reactjs.org/docs/hooks-reference.html#usedeferredvalue + * @see https://react.dev/reference/react/useDeferredValue */ export { useDeferredValue }; @@ -175,72 +175,72 @@ export { useDeferredValue }; export { useEffect }; /** - * @see https://reactjs.org/docs/hooks-reference.html#useid + * @see https://react.dev/reference/react/useId */ export { useId }; /** - * @see https://reactjs.org/docs/hooks-reference.html#useimperativehandle + * @see https://react.dev/reference/react/useImperativeHandle */ export { useImperativeHandle }; /** - * @see https://reactjs.org/docs/hooks-reference.html#useinsertioneffect + * @see https://react.dev/reference/react/useInsertionEffect */ export { useInsertionEffect }; /** - * @see https://reactjs.org/docs/hooks-reference.html#uselayouteffect + * @see https://react.dev/reference/react/useLayoutEffect */ export { useLayoutEffect }; /** - * @see https://reactjs.org/docs/hooks-reference.html#usememo + * @see https://react.dev/reference/react/useMemo */ export { useMemo }; /** - * @see https://reactjs.org/docs/hooks-reference.html#usereducer + * @see https://react.dev/reference/react/useReducer */ export { useReducer }; /** - * @see https://reactjs.org/docs/hooks-reference.html#useref + * @see https://react.dev/reference/react/useRef */ export { useRef }; /** - * @see https://reactjs.org/docs/hooks-reference.html#usestate + * @see https://react.dev/reference/react/useState */ export { useState }; /** - * @see https://reactjs.org/docs/hooks-reference.html#usesyncexternalstore + * @see https://react.dev/reference/react/useSyncExternalStore */ export { useSyncExternalStore }; /** - * @see https://reactjs.org/docs/hooks-reference.html#usetransition + * @see https://react.dev/reference/react/useTransition */ export { useTransition }; /** - * @see https://reactjs.org/docs/react-api.html#starttransition + * @see https://react.dev/reference/react/startTransition */ export { startTransition }; /** - * @see https://reactjs.org/docs/react-api.html#reactlazy + * @see https://react.dev/reference/react/lazy */ export { lazy }; /** - * @see https://reactjs.org/docs/react-api.html#reactsuspense + * @see https://react.dev/reference/react/Suspense */ export { Suspense }; /** - * @see https://reactjs.org/docs/react-api.html#reactpurecomponent + * @see https://react.dev/reference/react/PureComponent */ export { PureComponent }; diff --git a/packages/env/CHANGELOG.md b/packages/env/CHANGELOG.md index 7669cf755943ea..06e5d513f1c784 100644 --- a/packages/env/CHANGELOG.md +++ b/packages/env/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 10.1.0 (2024-06-15) + ## 10.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/env/package.json b/packages/env/package.json index 165ff57790fba2..1b60a44e5676d2 100644 --- a/packages/env/package.json +++ b/packages/env/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/env", - "version": "10.0.0", + "version": "10.1.0", "description": "A zero-config, self contained local WordPress environment for development and testing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/escape-html/CHANGELOG.md b/packages/escape-html/CHANGELOG.md index 2562662aa2ce91..82a4f159f0b8a4 100644 --- a/packages/escape-html/CHANGELOG.md +++ b/packages/escape-html/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +## 3.1.0 (2024-06-15) + +### Internal + +- Refactor to TypeScript ([#62586](https://github.com/WordPress/gutenberg/pull/62586)). + ## 3.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/escape-html/package.json b/packages/escape-html/package.json index 35cf1e8c286957..12238b3036e320 100644 --- a/packages/escape-html/package.json +++ b/packages/escape-html/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/escape-html", - "version": "3.0.0", + "version": "3.1.0", "description": "Escape HTML utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/escape-html/src/escape-greater.js b/packages/escape-html/src/escape-greater.ts similarity index 68% rename from packages/escape-html/src/escape-greater.js rename to packages/escape-html/src/escape-greater.ts index f761a81e16ae61..6e5956dc47e8f3 100644 --- a/packages/escape-html/src/escape-greater.js +++ b/packages/escape-html/src/escape-greater.ts @@ -6,10 +6,10 @@ * * See: https://core.trac.wordpress.org/ticket/45387 * - * @param {string} value Original string. + * @param value Original string. * - * @return {string} Escaped string. + * @return Escaped string. */ -export default function __unstableEscapeGreaterThan( value ) { +export default function __unstableEscapeGreaterThan( value: string ): string { return value.replace( />/g, '>' ); } diff --git a/packages/escape-html/src/index.js b/packages/escape-html/src/index.ts similarity index 72% rename from packages/escape-html/src/index.js rename to packages/escape-html/src/index.ts index 8ddce62c443257..71206695bb7d3b 100644 --- a/packages/escape-html/src/index.js +++ b/packages/escape-html/src/index.ts @@ -11,10 +11,9 @@ import __unstableEscapeGreaterThan from './escape-greater'; * and noncharacters." * * @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 - * - * @type {RegExp} */ -const REGEXP_INVALID_ATTRIBUTE_NAME = /[\u007F-\u009F "'>/="\uFDD0-\uFDEF]/; +const REGEXP_INVALID_ATTRIBUTE_NAME: RegExp = + /[\u007F-\u009F "'>/="\uFDD0-\uFDEF]/; /** * Returns a string with ampersands escaped. Note that this is an imperfect @@ -26,33 +25,33 @@ const REGEXP_INVALID_ATTRIBUTE_NAME = /[\u007F-\u009F "'>/="\uFDD0-\uFDEF]/; * @see https://w3c.github.io/html/syntax.html#ambiguous-ampersand * @see https://w3c.github.io/html/syntax.html#named-character-references * - * @param {string} value Original string. + * @param value Original string. * - * @return {string} Escaped string. + * @return Escaped string. */ -export function escapeAmpersand( value ) { +export function escapeAmpersand( value: string ): string { return value.replace( /&(?!([a-z0-9]+|#[0-9]+|#x[a-f0-9]+);)/gi, '&' ); } /** * Returns a string with quotation marks replaced. * - * @param {string} value Original string. + * @param value Original string. * - * @return {string} Escaped string. + * @return Escaped string. */ -export function escapeQuotationMark( value ) { +export function escapeQuotationMark( value: string ): string { return value.replace( /"/g, '"' ); } /** * Returns a string with less-than sign replaced. * - * @param {string} value Original string. + * @param value Original string. * - * @return {string} Escaped string. + * @return Escaped string. */ -export function escapeLessThan( value ) { +export function escapeLessThan( value: string ): string { return value.replace( / string; + +function testUnstableEscapeGreaterThan( implementation: Implementation ) { it( 'should escape greater than', () => { const result = implementation( 'Chicken > Ribs' ); expect( result ).toBe( 'Chicken > Ribs' ); } ); } -function testEscapeAmpersand( implementation ) { +function testEscapeAmpersand( implementation: Implementation ) { it( 'should escape ampersand', () => { const result = implementation( 'foo & bar & & baz Σ &#bad; Σ Σ vil;' @@ -31,7 +33,7 @@ function testEscapeAmpersand( implementation ) { } ); } -function testEscapeQuotationMark( implementation ) { +function testEscapeQuotationMark( implementation: Implementation ) { it( 'should escape quotation mark', () => { const result = implementation( '"Be gone!"' ); @@ -39,7 +41,7 @@ function testEscapeQuotationMark( implementation ) { } ); } -function testEscapeLessThan( implementation ) { +function testEscapeLessThan( implementation: Implementation ) { it( 'should escape less than', () => { const result = implementation( 'Chicken < Ribs' ); diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 816140ed76900b..7a1c7fba6bc08d 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 19.1.0 (2024-06-15) + ## 19.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 8cf48275fbe884..bb10b13063b705 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/eslint-plugin", - "version": "19.0.0", + "version": "19.1.0", "description": "ESLint plugin for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/format-library/CHANGELOG.md b/packages/format-library/CHANGELOG.md index 8f73bad3fcad36..78683f978421a1 100644 --- a/packages/format-library/CHANGELOG.md +++ b/packages/format-library/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/format-library/package.json b/packages/format-library/package.json index 5582be09668464..054e12970d401d 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/format-library", - "version": "5.0.0", + "version": "5.1.0", "description": "Format library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/hooks/CHANGELOG.md b/packages/hooks/CHANGELOG.md index c92c344893f368..65bca0287d45e7 100644 --- a/packages/hooks/CHANGELOG.md +++ b/packages/hooks/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.1.0 (2024-06-15) + ## 4.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 06779db3d042de..86aa8aca76ca29 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/hooks", - "version": "4.0.0", + "version": "4.1.0", "description": "WordPress hooks library.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/html-entities/CHANGELOG.md b/packages/html-entities/CHANGELOG.md index b970e05f95faa7..8a2e69e403c285 100644 --- a/packages/html-entities/CHANGELOG.md +++ b/packages/html-entities/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.1.0 (2024-06-15) + ## 4.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/html-entities/package.json b/packages/html-entities/package.json index 2cb96e17a6270c..b3cc8bd8944e9f 100644 --- a/packages/html-entities/package.json +++ b/packages/html-entities/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/html-entities", - "version": "4.0.0", + "version": "4.1.0", "description": "HTML entity utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/i18n/CHANGELOG.md b/packages/i18n/CHANGELOG.md index 55a6a848950dfc..b006c64bc71ec9 100644 --- a/packages/i18n/CHANGELOG.md +++ b/packages/i18n/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/i18n/package.json b/packages/i18n/package.json index b6ec0f47c1f9b0..8c62b68ee2aef2 100644 --- a/packages/i18n/package.json +++ b/packages/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/i18n", - "version": "5.0.0", + "version": "5.1.0", "description": "WordPress internationalization (i18n) library.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/icons/CHANGELOG.md b/packages/icons/CHANGELOG.md index 485fdaed579965..5e0e30cb9a9747 100644 --- a/packages/icons/CHANGELOG.md +++ b/packages/icons/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 10.1.0 (2024-06-15) + ## 10.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/icons/package.json b/packages/icons/package.json index f3912559bb7101..84cc88af2cc81b 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/icons", - "version": "10.0.0", + "version": "10.1.0", "description": "WordPress Icons package, based on dashicon.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/interactivity-router/CHANGELOG.md b/packages/interactivity-router/CHANGELOG.md index a7e6f5060b6023..c58f4eec699c0b 100644 --- a/packages/interactivity-router/CHANGELOG.md +++ b/packages/interactivity-router/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.1.0 (2024-06-15) + ## 2.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/interactivity-router/package.json b/packages/interactivity-router/package.json index a2ed315c7d1856..9c323d7775872b 100644 --- a/packages/interactivity-router/package.json +++ b/packages/interactivity-router/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/interactivity-router", - "version": "2.0.0", + "version": "2.1.0", "description": "Package that exposes state and actions from the `core/router` store, part of the Interactivity API.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/interactivity/CHANGELOG.md b/packages/interactivity/CHANGELOG.md index 6154841c1db2c4..f46f0a0d3a7c09 100644 --- a/packages/interactivity/CHANGELOG.md +++ b/packages/interactivity/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 6.1.0 (2024-06-15) + ## 6.0.0 (2024-05-31) ### New Features diff --git a/packages/interactivity/package.json b/packages/interactivity/package.json index 0b18d2ced29197..c5f67a336346ed 100644 --- a/packages/interactivity/package.json +++ b/packages/interactivity/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/interactivity", - "version": "6.0.0", + "version": "6.1.0", "description": "Package that provides a standard and simple way to handle the frontend interactivity of Gutenberg blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/interface/CHANGELOG.md b/packages/interface/CHANGELOG.md index 108bac3e369670..0314d848019c18 100644 --- a/packages/interface/CHANGELOG.md +++ b/packages/interface/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 6.1.0 (2024-06-15) + ## 6.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/interface/package.json b/packages/interface/package.json index a8ad016a5dc21f..a9e3c5826a9d14 100644 --- a/packages/interface/package.json +++ b/packages/interface/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/interface", - "version": "6.0.0", + "version": "6.1.0", "description": "Interface module for WordPress. The package contains shared functionality across the modern JavaScript-based WordPress screens.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/is-shallow-equal/CHANGELOG.md b/packages/is-shallow-equal/CHANGELOG.md index 19b2bc958b3cb2..c8040b74d47ad1 100644 --- a/packages/is-shallow-equal/CHANGELOG.md +++ b/packages/is-shallow-equal/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/is-shallow-equal/package.json b/packages/is-shallow-equal/package.json index 5ee5ce57fc304f..f99f677c31ae7c 100644 --- a/packages/is-shallow-equal/package.json +++ b/packages/is-shallow-equal/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/is-shallow-equal", - "version": "5.0.0", + "version": "5.1.0", "description": "Test for shallow equality between two objects or arrays.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/jest-console/CHANGELOG.md b/packages/jest-console/CHANGELOG.md index 7473e8e4467088..af1b0fb2fb6dec 100644 --- a/packages/jest-console/CHANGELOG.md +++ b/packages/jest-console/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 8.1.0 (2024-06-15) + ## 8.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/jest-console/package.json b/packages/jest-console/package.json index 2f0ea47a9c52cc..837e0334eef670 100644 --- a/packages/jest-console/package.json +++ b/packages/jest-console/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/jest-console", - "version": "8.0.0", + "version": "8.1.0", "description": "Custom Jest matchers for the Console object.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/jest-preset-default/CHANGELOG.md b/packages/jest-preset-default/CHANGELOG.md index 461bd5cb30256e..9b77a3883b9cc2 100644 --- a/packages/jest-preset-default/CHANGELOG.md +++ b/packages/jest-preset-default/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 12.1.0 (2024-06-15) + ## 12.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/jest-preset-default/package.json b/packages/jest-preset-default/package.json index 14ff5a6364d799..9581fd2aa0b20c 100644 --- a/packages/jest-preset-default/package.json +++ b/packages/jest-preset-default/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/jest-preset-default", - "version": "12.0.0", + "version": "12.1.0", "description": "Default Jest preset for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/jest-puppeteer-axe/CHANGELOG.md b/packages/jest-puppeteer-axe/CHANGELOG.md index 97d0efc9ddb247..803845ce73bfe1 100644 --- a/packages/jest-puppeteer-axe/CHANGELOG.md +++ b/packages/jest-puppeteer-axe/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 7.1.0 (2024-06-15) + ## 7.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/jest-puppeteer-axe/package.json b/packages/jest-puppeteer-axe/package.json index a6f162cf219954..44ec042ed3d528 100644 --- a/packages/jest-puppeteer-axe/package.json +++ b/packages/jest-puppeteer-axe/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/jest-puppeteer-axe", - "version": "7.0.0", + "version": "7.1.0", "description": "Axe API integration with Jest and Puppeteer.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/keyboard-shortcuts/CHANGELOG.md b/packages/keyboard-shortcuts/CHANGELOG.md index 9ab27b46d52739..da9c4578a2ad2e 100644 --- a/packages/keyboard-shortcuts/CHANGELOG.md +++ b/packages/keyboard-shortcuts/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/keyboard-shortcuts/package.json b/packages/keyboard-shortcuts/package.json index 76381f56991057..25f044dd9b2884 100644 --- a/packages/keyboard-shortcuts/package.json +++ b/packages/keyboard-shortcuts/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/keyboard-shortcuts", - "version": "5.0.0", + "version": "5.1.0", "description": "Handling keyboard shortcuts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/keycodes/CHANGELOG.md b/packages/keycodes/CHANGELOG.md index 9d3a14f65666bb..ef19ac07424f05 100644 --- a/packages/keycodes/CHANGELOG.md +++ b/packages/keycodes/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.1.0 (2024-06-15) + ## 4.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/keycodes/package.json b/packages/keycodes/package.json index 266b898d704a11..435f9d0931ea18 100644 --- a/packages/keycodes/package.json +++ b/packages/keycodes/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/keycodes", - "version": "4.0.0", + "version": "4.1.0", "description": "Keycodes utilities for WordPress. Used to check for keyboard events across browsers/operating systems.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/lazy-import/CHANGELOG.md b/packages/lazy-import/CHANGELOG.md index 864736a68f008a..843ad006093a0e 100644 --- a/packages/lazy-import/CHANGELOG.md +++ b/packages/lazy-import/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.1.0 (2024-06-15) + ## 2.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/lazy-import/package.json b/packages/lazy-import/package.json index 20825ef2bb5611..6c21a408471c47 100644 --- a/packages/lazy-import/package.json +++ b/packages/lazy-import/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/lazy-import", - "version": "2.0.0", + "version": "2.1.0", "description": "Lazily import a module, installing it automatically if missing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/list-reusable-blocks/CHANGELOG.md b/packages/list-reusable-blocks/CHANGELOG.md index 954509404024ab..4658dc79943a4e 100644 --- a/packages/list-reusable-blocks/CHANGELOG.md +++ b/packages/list-reusable-blocks/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/list-reusable-blocks/package.json b/packages/list-reusable-blocks/package.json index e6f95acab19c17..9cfe85281d0db2 100644 --- a/packages/list-reusable-blocks/package.json +++ b/packages/list-reusable-blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/list-reusable-blocks", - "version": "5.0.0", + "version": "5.1.0", "description": "Adding Export/Import support to the reusable blocks listing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/media-utils/CHANGELOG.md b/packages/media-utils/CHANGELOG.md index f9ad3a6b77b42a..a2cdb1cfd85b3f 100644 --- a/packages/media-utils/CHANGELOG.md +++ b/packages/media-utils/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/media-utils/package.json b/packages/media-utils/package.json index 1ca36aa6fd1a82..8203bfbea69ffe 100644 --- a/packages/media-utils/package.json +++ b/packages/media-utils/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/media-utils", - "version": "5.0.0", + "version": "5.1.0", "description": "WordPress Media Upload Utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/notices/CHANGELOG.md b/packages/notices/CHANGELOG.md index 3a847355bd0a82..cc112c81f42837 100644 --- a/packages/notices/CHANGELOG.md +++ b/packages/notices/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/notices/package.json b/packages/notices/package.json index abcbb6ecfba2d5..525e739f669ce1 100644 --- a/packages/notices/package.json +++ b/packages/notices/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/notices", - "version": "5.0.0", + "version": "5.1.0", "description": "State management for notices.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/npm-package-json-lint-config/CHANGELOG.md b/packages/npm-package-json-lint-config/CHANGELOG.md index 09ee8912592a09..1cbaa7ee592086 100644 --- a/packages/npm-package-json-lint-config/CHANGELOG.md +++ b/packages/npm-package-json-lint-config/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/npm-package-json-lint-config/package.json b/packages/npm-package-json-lint-config/package.json index 71e584477d5cb2..70db6bbb3cc6b7 100644 --- a/packages/npm-package-json-lint-config/package.json +++ b/packages/npm-package-json-lint-config/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/npm-package-json-lint-config", - "version": "5.0.0", + "version": "5.1.0", "description": "WordPress npm-package-json-lint shareable configuration.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/nux/CHANGELOG.md b/packages/nux/CHANGELOG.md index 9141ca8ee3b278..4aec520b7565ac 100644 --- a/packages/nux/CHANGELOG.md +++ b/packages/nux/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 9.1.0 (2024-06-15) + ## 9.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/nux/package.json b/packages/nux/package.json index d2c760a6cf1aae..c5d06804ea5833 100644 --- a/packages/nux/package.json +++ b/packages/nux/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/nux", - "version": "9.0.0", + "version": "9.1.0", "description": "NUX (New User eXperience) module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/patterns/CHANGELOG.md b/packages/patterns/CHANGELOG.md index 1519a8164fe29a..d7e44b37667870 100644 --- a/packages/patterns/CHANGELOG.md +++ b/packages/patterns/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.1.0 (2024-06-15) + ## 2.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/patterns/package.json b/packages/patterns/package.json index b14c3739e31751..9c8559284363ab 100644 --- a/packages/patterns/package.json +++ b/packages/patterns/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/patterns", - "version": "2.0.0", + "version": "2.1.0", "description": "Management of user pattern editing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/patterns/src/components/pattern-overrides-block-controls.js b/packages/patterns/src/components/pattern-overrides-block-controls.js new file mode 100644 index 00000000000000..ae8ef5e1bb7da9 --- /dev/null +++ b/packages/patterns/src/components/pattern-overrides-block-controls.js @@ -0,0 +1,155 @@ +/** + * WordPress dependencies + */ +import { useId } from '@wordpress/element'; +import { __, sprintf } from '@wordpress/i18n'; +import { + DropdownMenu, + ToolbarItem, + __experimentalText as Text, +} from '@wordpress/components'; +import { store as blocksStore } from '@wordpress/blocks'; +import { useSelect } from '@wordpress/data'; +import { copy } from '@wordpress/icons'; +import { + store as blockEditorStore, + BlockIcon, + privateApis as blockEditorPrivateApis, + BlockControls, +} from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import { unlock } from '../lock-unlock'; +import { PATTERN_OVERRIDES_BINDING_SOURCE } from '../constants'; + +const { useBlockDisplayTitle } = unlock( blockEditorPrivateApis ); + +function PatternOverridesToolbarIndicator( { clientIds } ) { + const isSingleBlockSelected = clientIds.length === 1; + const { icon, firstBlockName } = useSelect( + ( select ) => { + const { getBlockAttributes, getBlockNamesByClientId } = + select( blockEditorStore ); + const { getBlockType, getActiveBlockVariation } = + select( blocksStore ); + const blockTypeNames = getBlockNamesByClientId( clientIds ); + const _firstBlockTypeName = blockTypeNames[ 0 ]; + const firstBlockType = getBlockType( _firstBlockTypeName ); + let _icon; + if ( isSingleBlockSelected ) { + const match = getActiveBlockVariation( + _firstBlockTypeName, + getBlockAttributes( clientIds[ 0 ] ) + ); + // Take into account active block variations. + _icon = match?.icon || firstBlockType.icon; + } else { + const isSelectionOfSameType = + new Set( blockTypeNames ).size === 1; + // When selection consists of blocks of multiple types, display an + // appropriate icon to communicate the non-uniformity. + _icon = isSelectionOfSameType ? firstBlockType.icon : copy; + } + + return { + icon: _icon, + firstBlockName: getBlockAttributes( clientIds[ 0 ] ).metadata + .name, + }; + }, + [ clientIds, isSingleBlockSelected ] + ); + const firstBlockTitle = useBlockDisplayTitle( { + clientId: clientIds[ 0 ], + maximumLength: 35, + } ); + + const blockDescription = isSingleBlockSelected + ? sprintf( + /* translators: %1s: The block type's name; %2s: The block's user-provided name (the same as the override name). */ + __( 'This %1$s is editable using the "%2$s" override.' ), + firstBlockTitle.toLowerCase(), + firstBlockName + ) + : __( 'These blocks are editable using overrides.' ); + + const descriptionId = useId(); + + return ( + + { ( toggleProps ) => ( + + + + } + toggleProps={ { + describedBy: blockDescription, + ...toggleProps, + } } + menuProps={ { + orientation: 'both', + 'aria-describedby': descriptionId, + } } + > + { () => ( + { blockDescription } + ) } + + ) } + + ); +} + +export default function PatternOverridesBlockControls() { + const { clientIds, hasPatternOverrides, hasParentPattern } = useSelect( + ( select ) => { + const { + getBlockAttributes, + getSelectedBlockClientIds, + getBlockParentsByBlockName, + } = select( blockEditorStore ); + const selectedClientIds = getSelectedBlockClientIds(); + const _hasPatternOverrides = selectedClientIds.every( + ( clientId ) => + Object.values( + getBlockAttributes( clientId )?.metadata?.bindings ?? {} + ).some( + ( binding ) => + binding?.source === PATTERN_OVERRIDES_BINDING_SOURCE + ) + ); + const _hasParentPattern = selectedClientIds.every( + ( clientId ) => + getBlockParentsByBlockName( clientId, 'core/block', true ) + .length > 0 + ); + return { + clientIds: selectedClientIds, + hasPatternOverrides: _hasPatternOverrides, + hasParentPattern: _hasParentPattern, + }; + }, + [] + ); + + return hasPatternOverrides && hasParentPattern ? ( + + + + ) : null; +} diff --git a/packages/patterns/src/components/style.scss b/packages/patterns/src/components/style.scss index 86af3df7ff3b90..30fe0300503c48 100644 --- a/packages/patterns/src/components/style.scss +++ b/packages/patterns/src/components/style.scss @@ -44,3 +44,16 @@ justify-content: center; } + +.patterns-pattern-overrides-toolbar-indicator__popover .components-popover__content { + min-width: 260px; + padding: $grid-unit-20; +} + +.patterns-pattern-overrides-toolbar-indicator .patterns-pattern-overrides-toolbar-indicator-icon.has-colors svg { + fill: var(--wp-block-synced-color); +} + +.editor-collapsible-block-toolbar .patterns-pattern-overrides-toolbar-indicator { + height: 32px; +} diff --git a/packages/patterns/src/private-apis.js b/packages/patterns/src/private-apis.js index 0553378cb56043..8893b3c57d7360 100644 --- a/packages/patterns/src/private-apis.js +++ b/packages/patterns/src/private-apis.js @@ -17,6 +17,7 @@ import PatternsMenuItems from './components'; import RenamePatternCategoryModal from './components/rename-pattern-category-modal'; import PatternOverridesControls from './components/pattern-overrides-controls'; import ResetOverridesControl from './components/reset-overrides-control'; +import PatternOverridesBlockControls from './components/pattern-overrides-block-controls'; import { useAddPatternCategory } from './private-hooks'; import { PATTERN_TYPES, @@ -41,6 +42,7 @@ lock( privateApis, { RenamePatternCategoryModal, PatternOverridesControls, ResetOverridesControl, + PatternOverridesBlockControls, useAddPatternCategory, PATTERN_TYPES, PATTERN_DEFAULT_CATEGORY, diff --git a/packages/plugins/CHANGELOG.md b/packages/plugins/CHANGELOG.md index 5ba4ad33c6a745..d6131dd1316610 100644 --- a/packages/plugins/CHANGELOG.md +++ b/packages/plugins/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 7.1.0 (2024-06-15) + ## 7.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/plugins/package.json b/packages/plugins/package.json index 5747c0d6d889cf..4efe766c5f1670 100644 --- a/packages/plugins/package.json +++ b/packages/plugins/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/plugins", - "version": "7.0.0", + "version": "7.1.0", "description": "Plugins module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/postcss-plugins-preset/CHANGELOG.md b/packages/postcss-plugins-preset/CHANGELOG.md index 35fa13f05ab1df..305cf4cfffd956 100644 --- a/packages/postcss-plugins-preset/CHANGELOG.md +++ b/packages/postcss-plugins-preset/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/postcss-plugins-preset/package.json b/packages/postcss-plugins-preset/package.json index a8954e0ec9cbc1..f7876cf44cf7a9 100644 --- a/packages/postcss-plugins-preset/package.json +++ b/packages/postcss-plugins-preset/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/postcss-plugins-preset", - "version": "5.0.0", + "version": "5.1.0", "description": "PostCSS sharable plugins preset for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/postcss-themes/CHANGELOG.md b/packages/postcss-themes/CHANGELOG.md index cf32c7f744931c..0c454e48a54693 100644 --- a/packages/postcss-themes/CHANGELOG.md +++ b/packages/postcss-themes/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 6.1.0 (2024-06-15) + ## 6.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/postcss-themes/package.json b/packages/postcss-themes/package.json index eddfdecb3d0522..8ba9357397990f 100644 --- a/packages/postcss-themes/package.json +++ b/packages/postcss-themes/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/postcss-themes", - "version": "6.0.0", + "version": "6.1.0", "description": "PostCSS plugin to generate theme colors.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/preferences-persistence/CHANGELOG.md b/packages/preferences-persistence/CHANGELOG.md index 6c7af3085d8378..c406b533623b47 100644 --- a/packages/preferences-persistence/CHANGELOG.md +++ b/packages/preferences-persistence/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.1.0 (2024-06-15) + ## 2.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/preferences-persistence/package.json b/packages/preferences-persistence/package.json index a250930699aec4..a7c6bd72b5131e 100644 --- a/packages/preferences-persistence/package.json +++ b/packages/preferences-persistence/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/preferences-persistence", - "version": "2.0.0", + "version": "2.1.0", "description": "Persistence utilities for `wordpress/preferences`.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/preferences/CHANGELOG.md b/packages/preferences/CHANGELOG.md index 54778a68a2ce1b..b2315defb18b69 100644 --- a/packages/preferences/CHANGELOG.md +++ b/packages/preferences/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.1.0 (2024-06-15) + ## 4.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/preferences/package.json b/packages/preferences/package.json index 5b3e520ea96e8c..a13f00eb6abcd4 100644 --- a/packages/preferences/package.json +++ b/packages/preferences/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/preferences", - "version": "4.0.0", + "version": "4.1.0", "description": "Utilities for managing WordPress preferences.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/prettier-config/CHANGELOG.md b/packages/prettier-config/CHANGELOG.md index a3e735502062d2..795cd1bb5c1f38 100644 --- a/packages/prettier-config/CHANGELOG.md +++ b/packages/prettier-config/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.1.0 (2024-06-15) + ## 4.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/prettier-config/package.json b/packages/prettier-config/package.json index 56e4a530ec2767..d846963e30e13d 100644 --- a/packages/prettier-config/package.json +++ b/packages/prettier-config/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/prettier-config", - "version": "4.0.0", + "version": "4.1.0", "description": "WordPress Prettier shared configuration.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/primitives/CHANGELOG.md b/packages/primitives/CHANGELOG.md index 95093af2921921..96aa384d1b3150 100644 --- a/packages/primitives/CHANGELOG.md +++ b/packages/primitives/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.1.0 (2024-06-15) + ## 4.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/primitives/package.json b/packages/primitives/package.json index f47b368097470d..13b9814e572af6 100644 --- a/packages/primitives/package.json +++ b/packages/primitives/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/primitives", - "version": "4.0.0", + "version": "4.1.0", "description": "WordPress cross-platform primitives.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/priority-queue/CHANGELOG.md b/packages/priority-queue/CHANGELOG.md index ebc0c6501bcdb8..6e872f430c8d26 100644 --- a/packages/priority-queue/CHANGELOG.md +++ b/packages/priority-queue/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.1.0 (2024-06-15) + ## 3.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/priority-queue/package.json b/packages/priority-queue/package.json index a544c61f217d6b..e1dd5720fb1ae5 100644 --- a/packages/priority-queue/package.json +++ b/packages/priority-queue/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/priority-queue", - "version": "3.0.0", + "version": "3.1.0", "description": "Generic browser priority queue.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/private-apis/CHANGELOG.md b/packages/private-apis/CHANGELOG.md index d10d7d73cd78f9..f9ff4f1f743b4c 100644 --- a/packages/private-apis/CHANGELOG.md +++ b/packages/private-apis/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.1.0 (2024-06-15) + ## 1.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/private-apis/package.json b/packages/private-apis/package.json index 307c4f021e7612..72d2a446913ffe 100644 --- a/packages/private-apis/package.json +++ b/packages/private-apis/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/private-apis", - "version": "1.0.0", + "version": "1.1.0", "description": "Internal experimental APIs for WordPress core.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/project-management-automation/CHANGELOG.md b/packages/project-management-automation/CHANGELOG.md index 6794a20720a5cb..d3df30b940b124 100644 --- a/packages/project-management-automation/CHANGELOG.md +++ b/packages/project-management-automation/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.1.0 (2024-06-15) + ## 2.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/project-management-automation/package.json b/packages/project-management-automation/package.json index d0741b4c4e094d..0757c11558a582 100644 --- a/packages/project-management-automation/package.json +++ b/packages/project-management-automation/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/project-management-automation", - "version": "2.0.0", + "version": "2.1.0", "description": "GitHub Action that implements various automation to assist with managing the Gutenberg GitHub repository.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/react-i18n/CHANGELOG.md b/packages/react-i18n/CHANGELOG.md index 2d547d0335f644..289c5353213335 100644 --- a/packages/react-i18n/CHANGELOG.md +++ b/packages/react-i18n/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.1.0 (2024-06-15) + ## 4.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/react-i18n/package.json b/packages/react-i18n/package.json index 89f7a763b4b8df..b7adfdba6bfd85 100644 --- a/packages/react-i18n/package.json +++ b/packages/react-i18n/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-i18n", - "version": "4.0.0", + "version": "4.1.0", "description": "React bindings for @wordpress/i18n.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/react-native-aztec/ios/RNTAztecView/RCTAztecView.swift b/packages/react-native-aztec/ios/RNTAztecView/RCTAztecView.swift index 6304939b768a50..03362c3a371fb2 100644 --- a/packages/react-native-aztec/ios/RNTAztecView/RCTAztecView.swift +++ b/packages/react-native-aztec/ios/RNTAztecView/RCTAztecView.swift @@ -245,12 +245,8 @@ class RCTAztecView: Aztec.TextView { } private func readHTML(from pasteboard: UIPasteboard) -> String? { - if let data = pasteboard.data(forPasteboardType: kUTTypeHTML as String), let html = String(data: data, encoding: .utf8) { - // Make sure we are not getting a full HTML DOC. We only want inner content - if !html.hasPrefix(" ## Unreleased +- [internal] Fix Inserter items list filtering [#62334] +- [*] Prevent hiding the keyboard when creating new list items [#62446] +- [*] RichText - Fix undefined onDelete callback [#62486] +- [*] Fix issue when pasting HTML content [#62588] ## 1.120.0 - [*] Prevent deleting content when backspacing in the first Paragraph block [#62069] diff --git a/packages/readable-js-assets-webpack-plugin/CHANGELOG.md b/packages/readable-js-assets-webpack-plugin/CHANGELOG.md index 121831aa851bf6..1703977ce4f6c0 100644 --- a/packages/readable-js-assets-webpack-plugin/CHANGELOG.md +++ b/packages/readable-js-assets-webpack-plugin/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.1.0 (2024-06-15) + ## 3.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/readable-js-assets-webpack-plugin/package.json b/packages/readable-js-assets-webpack-plugin/package.json index 29e3ce5562847d..d9dc135a1f95d8 100644 --- a/packages/readable-js-assets-webpack-plugin/package.json +++ b/packages/readable-js-assets-webpack-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/readable-js-assets-webpack-plugin", - "version": "3.0.0", + "version": "3.1.0", "description": "Generate a readable JS file for each JS asset.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/redux-routine/CHANGELOG.md b/packages/redux-routine/CHANGELOG.md index 2fc48dbef19025..38f9365de891b9 100644 --- a/packages/redux-routine/CHANGELOG.md +++ b/packages/redux-routine/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/redux-routine/package.json b/packages/redux-routine/package.json index b423accef8f0a8..eda47226c9b98e 100644 --- a/packages/redux-routine/package.json +++ b/packages/redux-routine/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/redux-routine", - "version": "5.0.0", + "version": "5.1.0", "description": "Redux middleware for generator coroutines.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/reusable-blocks/CHANGELOG.md b/packages/reusable-blocks/CHANGELOG.md index 5a89e64ba8c46e..a1d2c1d29f4650 100644 --- a/packages/reusable-blocks/CHANGELOG.md +++ b/packages/reusable-blocks/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/reusable-blocks/package.json b/packages/reusable-blocks/package.json index d496eded1a7537..57d26bac79c8b4 100644 --- a/packages/reusable-blocks/package.json +++ b/packages/reusable-blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/reusable-blocks", - "version": "5.0.0", + "version": "5.1.0", "description": "Reusable blocks utilities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/rich-text/CHANGELOG.md b/packages/rich-text/CHANGELOG.md index 1fae202db5fc0d..6cad58596caa68 100644 --- a/packages/rich-text/CHANGELOG.md +++ b/packages/rich-text/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 7.1.0 (2024-06-15) + ## 7.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/rich-text/package.json b/packages/rich-text/package.json index c823d1018009fd..613b8353e54d44 100644 --- a/packages/rich-text/package.json +++ b/packages/rich-text/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/rich-text", - "version": "7.0.0", + "version": "7.1.0", "description": "Rich text value and manipulation API.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/router/CHANGELOG.md b/packages/router/CHANGELOG.md index b05dda0cca2b23..e320955adcfd19 100644 --- a/packages/router/CHANGELOG.md +++ b/packages/router/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.1.0 (2024-06-15) + ## 1.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/router/package.json b/packages/router/package.json index 2b0f84aac06cc1..1350ff461cdc1d 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/router", - "version": "1.0.0", + "version": "1.1.0", "description": "Router API for WordPress pages.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index 470929fd0628a2..09e8a98f8d04cd 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 28.1.0 (2024-06-15) + ## 28.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 6fe707ec9571c9..de70a76cabf83d 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/scripts", - "version": "28.0.0", + "version": "28.1.0", "description": "Collection of reusable scripts for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/server-side-render/CHANGELOG.md b/packages/server-side-render/CHANGELOG.md index 23d8b8aa75353b..0c007674e5f35a 100644 --- a/packages/server-side-render/CHANGELOG.md +++ b/packages/server-side-render/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.1.0 (2024-06-15) + ## 5.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/server-side-render/package.json b/packages/server-side-render/package.json index e1d3d95e39a23a..76685756bccda9 100644 --- a/packages/server-side-render/package.json +++ b/packages/server-side-render/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/server-side-render", - "version": "5.0.0", + "version": "5.1.0", "description": "The component used with WordPress to server-side render a preview of dynamic blocks to display in the editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/shortcode/CHANGELOG.md b/packages/shortcode/CHANGELOG.md index bcb92c69a7ef4a..75557775325dbd 100644 --- a/packages/shortcode/CHANGELOG.md +++ b/packages/shortcode/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.1.0 (2024-06-15) + ## 4.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/shortcode/package.json b/packages/shortcode/package.json index baeb4000c0420c..08c1f775bf1104 100644 --- a/packages/shortcode/package.json +++ b/packages/shortcode/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/shortcode", - "version": "4.0.0", + "version": "4.1.0", "description": "Shortcode module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/style-engine/CHANGELOG.md b/packages/style-engine/CHANGELOG.md index 006fc960398b6a..f9acb3eeca4a14 100644 --- a/packages/style-engine/CHANGELOG.md +++ b/packages/style-engine/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.1.0 (2024-06-15) + ## 2.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/style-engine/CONTRIBUTING.md b/packages/style-engine/CONTRIBUTING.md index 70bfddb8eb5011..ab65920229b607 100644 --- a/packages/style-engine/CONTRIBUTING.md +++ b/packages/style-engine/CONTRIBUTING.md @@ -4,7 +4,7 @@ This document contains information you might need to know when extending or debu ## Workflow and build tooling -The Style Engine PHP and Javascript (JS) files exist inside the `style-engine` package. +The Style Engine PHP and JavaScript (JS) files exist inside the `style-engine` package. In order to use the Style Engine in the Block Editor, these files must be compiled (in the case of JS) and copied to the build folder. @@ -29,9 +29,9 @@ To start the JS unit tests, run: `npm run test:unit packages/style-engine/src/test/` -[PHP unit tests](https://github.com/WordPress/gutenberg/tree/HEAD/phpunit/style-engine) are located in the root `phpunit` directory. +[PHP unit tests](https://github.com/WordPress/gutenberg/tree/HEAD/phpunit/style-engine) are located in the root `phpunit` directory. -In order to test the latest version of the Style Engine and avoid conflicts with existing Core equivalents, all PHP unit tests call the `gutenberg_` functions and `_Gutenberg` classes. +In order to test the latest version of the Style Engine and avoid conflicts with existing Core equivalents, all PHP unit tests call the `gutenberg_` functions and `_Gutenberg` classes. Therefore, Style Engine PHP source files should be parsed and copied to the build folder before running tests. During development, this will happen as part of the `npm run dev` script. You can also trigger a build by executing `npm run build`. diff --git a/packages/style-engine/README.md b/packages/style-engine/README.md index f26f8ff7e779b0..44b78eed8a81a6 100644 --- a/packages/style-engine/README.md +++ b/packages/style-engine/README.md @@ -17,7 +17,7 @@ Upcoming tasks on the roadmap include, but are not limited to, the following: - Propose a way to control hierarchy and specificity, and make the style hierarchy cascade accessible and predictable. This might include preparing for CSS cascade layers until they become more widely supported, and allowing for opt-in support in Gutenberg via theme.json. - Refactor all blocks to consistently use the "style" attribute for all customizations, that is, deprecate preset-specific attributes such as `attributes.fontSize`. -For more information about the roadmap, please refer to [Block editor styles: initiatives and goals](https://make.wordpress.org/core/2022/06/24/block-editor-styles-initiatives-and-goals/) and the [Github project board](https://github.com/orgs/WordPress/projects/19). +For more information about the roadmap, please refer to [Block editor styles: initiatives and goals](https://make.wordpress.org/core/2022/06/24/block-editor-styles-initiatives-and-goals/) and the [GitHub project board](https://github.com/orgs/WordPress/projects/19). If you're making changes or additions to the Style Engine, please take a moment to read the [notes on contributing](https://github.com/WordPress/gutenberg/tree/HEAD/packages/style-engine/CONTRIBUTING.md). diff --git a/packages/style-engine/package.json b/packages/style-engine/package.json index 9ebe2800e1b411..029b43ad3384ce 100644 --- a/packages/style-engine/package.json +++ b/packages/style-engine/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/style-engine", - "version": "2.0.0", + "version": "2.1.0", "description": "A suite of parsers and compilers for WordPress styles.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/stylelint-config/CHANGELOG.md b/packages/stylelint-config/CHANGELOG.md index 9c26f9efa6e03e..4186933cec42a8 100644 --- a/packages/stylelint-config/CHANGELOG.md +++ b/packages/stylelint-config/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 22.1.0 (2024-06-15) + ## 22.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/stylelint-config/package.json b/packages/stylelint-config/package.json index dbb0a0899b726b..57aa1eb9c2564f 100644 --- a/packages/stylelint-config/package.json +++ b/packages/stylelint-config/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/stylelint-config", - "version": "22.0.0", + "version": "22.1.0", "description": "stylelint config for WordPress development.", "author": "The WordPress Contributors", "license": "MIT", diff --git a/packages/sync/CHANGELOG.md b/packages/sync/CHANGELOG.md index b4c3d770142183..83b651222361e1 100644 --- a/packages/sync/CHANGELOG.md +++ b/packages/sync/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.1.0 (2024-06-15) + ## 1.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/sync/package.json b/packages/sync/package.json index 3bda7acb0e1187..5112e568aa9d7a 100644 --- a/packages/sync/package.json +++ b/packages/sync/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/sync", - "version": "1.0.0", + "version": "1.1.0", "description": "Sync Data.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/token-list/CHANGELOG.md b/packages/token-list/CHANGELOG.md index 3cd9c7e7aa5925..b53163519cd1b5 100644 --- a/packages/token-list/CHANGELOG.md +++ b/packages/token-list/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +## 3.1.0 (2024-06-15) + +### Internal + +- Refactor to TypeScript ([#62584](https://github.com/WordPress/gutenberg/pull/62584)). + ## 3.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/token-list/package.json b/packages/token-list/package.json index ee46c9f269c47e..4c080f2d0ddf83 100644 --- a/packages/token-list/package.json +++ b/packages/token-list/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/token-list", - "version": "3.0.0", + "version": "3.1.0", "description": "Constructable, plain JavaScript DOMTokenList implementation, supporting non-browser runtimes.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/token-list/src/index.js b/packages/token-list/src/index.ts similarity index 65% rename from packages/token-list/src/index.js rename to packages/token-list/src/index.ts index efd4ab68c478e5..f4da3d23293eda 100644 --- a/packages/token-list/src/index.js +++ b/packages/token-list/src/index.ts @@ -4,49 +4,33 @@ * @see https://dom.spec.whatwg.org/#domtokenlist */ export default class TokenList { + private _currentValue: string; + private _valueAsArray: string[]; + /** * Constructs a new instance of TokenList. * - * @param {string} initialValue Initial value to assign. + * @param initialValue Initial value to assign. */ - constructor( initialValue = '' ) { + constructor( initialValue: string = '' ) { + this._currentValue = ''; + this._valueAsArray = []; this.value = initialValue; - - // Disable reason: These are type hints on the class. - /* eslint-disable no-unused-expressions */ - /** @type {string} */ - this._currentValue; - - /** @type {string[]} */ - this._valueAsArray; - /* eslint-enable no-unused-expressions */ } - /** - * @param {Parameters['entries']>} args - */ - entries( ...args ) { + entries( ...args: Parameters< Array< string >[ 'entries' ] > ) { return this._valueAsArray.entries( ...args ); } - /** - * @param {Parameters['forEach']>} args - */ - forEach( ...args ) { + forEach( ...args: Parameters< Array< string >[ 'forEach' ] > ) { return this._valueAsArray.forEach( ...args ); } - /** - * @param {Parameters['keys']>} args - */ - keys( ...args ) { + keys( ...args: Parameters< Array< string >[ 'keys' ] > ) { return this._valueAsArray.keys( ...args ); } - /** - * @param {Parameters['values']>} args - */ - values( ...args ) { + values( ...args: Parameters< Array< string >[ 'values' ] > ) { return this._valueAsArray.values( ...args ); } @@ -55,9 +39,9 @@ export default class TokenList { * * @see https://dom.spec.whatwg.org/#dom-domtokenlist-value * - * @return {string} Token set as string. + * @return Token set as string. */ - get value() { + get value(): string { return this._currentValue; } @@ -66,9 +50,9 @@ export default class TokenList { * * @see https://dom.spec.whatwg.org/#dom-domtokenlist-value * - * @param {string} value New token set as string. + * @param value New token set as string. */ - set value( value ) { + set value( value: string ) { value = String( value ); this._valueAsArray = [ ...new Set( value.split( /\s+/g ).filter( Boolean ) ), @@ -81,9 +65,9 @@ export default class TokenList { * * @see https://dom.spec.whatwg.org/#dom-domtokenlist-length * - * @return {number} Number of tokens. + * @return Number of tokens. */ - get length() { + get length(): number { return this._valueAsArray.length; } @@ -93,9 +77,9 @@ export default class TokenList { * @see https://dom.spec.whatwg.org/#DOMTokenList-stringification-behavior * @see https://www.ecma-international.org/ecma-262/9.0/index.html#sec-tostring * - * @return {string} Token set as string. + * @return Token set as string. */ - toString() { + toString(): string { return this.value; } @@ -104,9 +88,9 @@ export default class TokenList { * * @see https://dom.spec.whatwg.org/#domtokenlist * - * @return {IterableIterator} TokenList iterator. + * @return TokenList iterator. */ - *[ Symbol.iterator ]() { + *[ Symbol.iterator ](): IterableIterator< string > { return yield* this._valueAsArray; } @@ -115,11 +99,11 @@ export default class TokenList { * * @see https://dom.spec.whatwg.org/#dom-domtokenlist-item * - * @param {number} index Index at which to return token. + * @param index Index at which to return token. * - * @return {string|undefined} Token at index. + * @return Token at index. */ - item( index ) { + item( index: number ): string | undefined { return this._valueAsArray[ index ]; } @@ -128,11 +112,11 @@ export default class TokenList { * * @see https://dom.spec.whatwg.org/#dom-domtokenlist-contains * - * @param {string} item Token to test. + * @param item Token to test. * - * @return {boolean} Whether token is present. + * @return Whether token is present. */ - contains( item ) { + contains( item: string ): boolean { return this._valueAsArray.indexOf( item ) !== -1; } @@ -141,9 +125,9 @@ export default class TokenList { * * @see https://dom.spec.whatwg.org/#dom-domtokenlist-add * - * @param {...string} items Items to add. + * @param items Items to add. */ - add( ...items ) { + add( ...items: string[] ): void { this.value += ' ' + items.join( ' ' ); } @@ -152,9 +136,9 @@ export default class TokenList { * * @see https://dom.spec.whatwg.org/#dom-domtokenlist-remove * - * @param {...string} items Items to remove. + * @param items Items to remove. */ - remove( ...items ) { + remove( ...items: string[] ): void { this.value = this._valueAsArray .filter( ( val ) => ! items.includes( val ) ) .join( ' ' ); @@ -168,12 +152,12 @@ export default class TokenList { * * @see https://dom.spec.whatwg.org/#dom-domtokenlist-toggle * - * @param {string} token Token to toggle. - * @param {boolean} [force] Presence to force. + * @param token Token to toggle. + * @param [force] Presence to force. * - * @return {boolean} Whether token is present after toggle. + * @return Whether token is present after toggle. */ - toggle( token, force ) { + toggle( token: string, force?: boolean ): boolean { if ( undefined === force ) { force = ! this.contains( token ); } @@ -193,12 +177,12 @@ export default class TokenList { * * @see https://dom.spec.whatwg.org/#dom-domtokenlist-replace * - * @param {string} token Token to replace with `newToken`. - * @param {string} newToken Token to use in place of `token`. + * @param token Token to replace with `newToken`. + * @param newToken Token to use in place of `token`. * - * @return {boolean} Whether replacement occurred. + * @return Whether replacement occurred. */ - replace( token, newToken ) { + replace( token: string, newToken: string ): boolean { if ( ! this.contains( token ) ) { return false; } @@ -215,11 +199,12 @@ export default class TokenList { * * Always returns `true` in this implementation. * + * @param _token * @see https://dom.spec.whatwg.org/#dom-domtokenlist-supports * - * @return {boolean} Whether token is supported. + * @return Whether token is supported. */ - supports() { + supports( _token: string ): boolean { return true; } } diff --git a/packages/token-list/src/test/index.js b/packages/token-list/src/test/index.ts similarity index 98% rename from packages/token-list/src/test/index.js rename to packages/token-list/src/test/index.ts index e208742d0fc6cc..fda0de0c53e489 100644 --- a/packages/token-list/src/test/index.js +++ b/packages/token-list/src/test/index.ts @@ -64,6 +64,7 @@ describe( 'token-list', () => { it( 'sets to stringified value', () => { const list = new TokenList(); + // @ts-expect-error The value should be a string, for testing we pass a "bad" value. list.value = undefined; expect( list.value ).toBe( 'undefined' ); diff --git a/packages/undo-manager/CHANGELOG.md b/packages/undo-manager/CHANGELOG.md index 36e815bbe8e2ba..53eea442c05221 100644 --- a/packages/undo-manager/CHANGELOG.md +++ b/packages/undo-manager/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.1.0 (2024-06-15) + ## 1.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/undo-manager/package.json b/packages/undo-manager/package.json index ed4f4a8e6b9204..7ff682f391ed01 100644 --- a/packages/undo-manager/package.json +++ b/packages/undo-manager/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/undo-manager", - "version": "1.0.0", + "version": "1.1.0", "description": "A small package to manage undo/redo.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/url/CHANGELOG.md b/packages/url/CHANGELOG.md index 172f881f369223..d3731414723bde 100644 --- a/packages/url/CHANGELOG.md +++ b/packages/url/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.1.0 (2024-06-15) + ## 4.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/url/package.json b/packages/url/package.json index 89d3e673254894..f12b30c8777aa5 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "4.0.0", + "version": "4.1.0", "description": "WordPress URL utilities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/viewport/CHANGELOG.md b/packages/viewport/CHANGELOG.md index 7f3e15b09fc542..ded2ad6be36b81 100644 --- a/packages/viewport/CHANGELOG.md +++ b/packages/viewport/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 6.1.0 (2024-06-15) + ## 6.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/viewport/package.json b/packages/viewport/package.json index fe54fccb2ca496..c50eecd6c35316 100644 --- a/packages/viewport/package.json +++ b/packages/viewport/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/viewport", - "version": "6.0.0", + "version": "6.1.0", "description": "Viewport module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/warning/CHANGELOG.md b/packages/warning/CHANGELOG.md index cfc8338f86c597..c08d177984c55f 100644 --- a/packages/warning/CHANGELOG.md +++ b/packages/warning/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +## 3.1.0 (2024-06-15) + +### Internal + +- Refactor to TypeScript ([#62557](https://github.com/WordPress/gutenberg/pull/62557)). + ## 3.0.0 (2024-05-31) ### Breaking Changes @@ -147,3 +153,4 @@ ## 1.0.0 (2020-02-04) Initial release. + diff --git a/packages/warning/package.json b/packages/warning/package.json index 6052f207b0d3f9..ef19454cb0b775 100644 --- a/packages/warning/package.json +++ b/packages/warning/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/warning", - "version": "3.0.0", + "version": "3.1.0", "description": "Warning utility for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/warning/src/index.js b/packages/warning/src/index.ts similarity index 86% rename from packages/warning/src/index.js rename to packages/warning/src/index.ts index 5744e99d94fd27..a5a092abbd2121 100644 --- a/packages/warning/src/index.js +++ b/packages/warning/src/index.ts @@ -3,7 +3,7 @@ */ import { logged } from './utils'; -function isDev() { +function isDev(): boolean { // eslint-disable-next-line @wordpress/wp-global-usage return globalThis.SCRIPT_DEBUG === true; } @@ -11,7 +11,7 @@ function isDev() { /** * Shows a warning with `message` if environment is not `production`. * - * @param {string} message Message to show in the warning. + * @param message Message to show in the warning. * * @example * ```js @@ -25,7 +25,7 @@ function isDev() { * } * ``` */ -export default function warning( message ) { +export default function warning( message: string ): void { if ( ! isDev() ) { return; } @@ -46,6 +46,5 @@ export default function warning( message ) { } catch ( x ) { // Do nothing. } - logged.add( message ); } diff --git a/packages/warning/src/utils.js b/packages/warning/src/utils.ts similarity index 66% rename from packages/warning/src/utils.js rename to packages/warning/src/utils.ts index fb087255f6bf6b..4f4b5d3e1f7976 100644 --- a/packages/warning/src/utils.js +++ b/packages/warning/src/utils.ts @@ -1,7 +1,5 @@ /** * Object map tracking messages which have been logged, for use in ensuring a * message is only logged once. - * - * @type {Set} */ -export const logged = new Set(); +export const logged: Set< string > = new Set(); diff --git a/packages/widgets/CHANGELOG.md b/packages/widgets/CHANGELOG.md index 3b318660859eb4..1e824ea0e07715 100644 --- a/packages/widgets/CHANGELOG.md +++ b/packages/widgets/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.1.0 (2024-06-15) + ## 4.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/widgets/package.json b/packages/widgets/package.json index cbbc3a928b9b4e..49d7c2e29fead4 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/widgets", - "version": "4.0.0", + "version": "4.1.0", "description": "Functionality used by the widgets block editor in the Widgets screen and the Customizer.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/wordcount/CHANGELOG.md b/packages/wordcount/CHANGELOG.md index 73042aef093a31..a718e90acb59ef 100644 --- a/packages/wordcount/CHANGELOG.md +++ b/packages/wordcount/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.1.0 (2024-06-15) + ## 4.0.0 (2024-05-31) ### Breaking Changes diff --git a/packages/wordcount/package.json b/packages/wordcount/package.json index 4bbda336f2eb75..8210b0328a46be 100644 --- a/packages/wordcount/package.json +++ b/packages/wordcount/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/wordcount", - "version": "4.0.0", + "version": "4.1.0", "description": "WordPress word count utility.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/phpunit/bootstrap.php b/phpunit/bootstrap.php index acc7cfde89dbd4..295d02978f120f 100644 --- a/phpunit/bootstrap.php +++ b/phpunit/bootstrap.php @@ -101,91 +101,6 @@ function fail_if_died( $message ) { // Enable the widget block editor. tests_add_filter( 'gutenberg_use_widgets_block_editor', '__return_true' ); -/** - * Register test block prior to theme.json generating metadata. - * - * This new block is used to test experimental selectors. It is registered - * via `tests_add_filter()` here during bootstrapping so that it occurs prior - * to theme.json generating block metadata. Once a core block, such as Image, - * uses feature level selectors we could remove this in favour of testing via - * the core block. - */ -function gutenberg_register_test_block_for_feature_selectors() { - WP_Block_Type_Registry::get_instance()->register( - 'test/test', - array( - 'api_version' => 3, - 'attributes' => array( - 'textColor' => array( - 'type' => 'string', - ), - 'style' => array( - 'type' => 'object', - ), - ), - 'supports' => array( - '__experimentalBorder' => array( - 'radius' => true, - '__experimentalSelector' => '.inner', - ), - 'color' => array( - 'text' => true, - ), - 'spacing' => array( - 'padding' => true, - '__experimentalSelector' => '.inner', - ), - 'typography' => array( - 'fontSize' => true, - '__experimentalSelector' => '.sub-heading', - ), - '__experimentalSelector' => '.wp-block-test, .wp-block-test__wrapper', - ), - ) - ); - - WP_Block_Type_Registry::get_instance()->register( - 'my/block-with-selectors', - array( - 'api_version' => 2, - 'attributes' => array( - 'textColor' => array( - 'type' => 'string', - ), - 'style' => array( - 'type' => 'object', - ), - ), - 'supports' => array( - '__experimentalBorder' => array( - 'radius' => true, - ), - 'color' => array( - 'background' => true, - 'text' => true, - ), - 'spacing' => array( - 'padding' => true, - ), - 'typography' => array( - 'fontSize' => true, - ), - ), - 'selectors' => array( - 'root' => '.custom-root-selector', - 'border' => array( - 'root' => '.custom-root-selector img', - ), - 'color' => array( - 'text' => '.custom-root-selector > figcaption', - ), - 'typography' => '.custom-root-selector > figcaption', - ), - ) - ); -} -tests_add_filter( 'init', 'gutenberg_register_test_block_for_feature_selectors' ); - // Start up the WP testing environment. require $_tests_dir . '/includes/bootstrap.php'; diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index bcf0d238400a08..ebfaeeb3d188fd 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -562,7 +562,7 @@ public function test_get_stylesheet() { $this->assertSame( $all, $theme_json->get_stylesheet() ); } - public function test_get_stylesheet_support_for_shorthand_and_longhand_values() { + public function test_get_styles_for_block_support_for_shorthand_and_longhand_values() { $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -598,9 +598,28 @@ public function test_get_stylesheet_support_for_shorthand_and_longhand_values() ) ); - $styles = static::$base_styles . ':root :where(.wp-block-group){border-radius: 10px;margin: 1em;padding: 24px;}:root :where(.wp-block-image){margin-bottom: 30px;padding-top: 15px;}:root :where(.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder){border-top-left-radius: 10px;border-bottom-right-radius: 1em;}'; - $this->assertSame( $styles, $theme_json->get_stylesheet() ); - $this->assertSame( $styles, $theme_json->get_stylesheet( array( 'styles' ) ) ); + $group_node = array( + 'name' => 'core/group', + 'path' => array( 'styles', 'blocks', 'core/group' ), + 'selector' => '.wp-block-group', + 'selectors' => array( + 'root' => '.wp-block-group', + ), + ); + $image_node = array( + 'name' => 'core/image', + 'path' => array( 'styles', 'blocks', 'core/image' ), + 'selector' => '.wp-block-image', + 'selectors' => array( + 'root' => '.wp-block-image', + 'border' => '.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder', + ), + ); + + $group_styles = ':root :where(.wp-block-group){border-radius: 10px;margin: 1em;padding: 24px;}'; + $image_styles = ':root :where(.wp-block-image){margin-bottom: 30px;padding-top: 15px;}:root :where(.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder){border-top-left-radius: 10px;border-bottom-right-radius: 1em;}'; + $this->assertSame( $group_styles, $theme_json->get_styles_for_block( $group_node ) ); + $this->assertSame( $image_styles, $theme_json->get_styles_for_block( $image_node ) ); } public function test_get_stylesheet_skips_disabled_protected_properties() { @@ -711,14 +730,14 @@ public function test_get_stylesheet_preset_rules_come_after_block_rules() { ) ); - $styles = static::$base_styles . ':root :where(.wp-block-group){color: red;}'; + $styles = ':root :where(.wp-block-group){color: red;}'; $presets = '.wp-block-group.has-grey-color{color: var(--wp--preset--color--grey) !important;}.wp-block-group.has-grey-background-color{background-color: var(--wp--preset--color--grey) !important;}.wp-block-group.has-grey-border-color{border-color: var(--wp--preset--color--grey) !important;}'; $variables = '.wp-block-group{--wp--preset--color--grey: grey;}'; $all = $variables . $styles . $presets; - $this->assertSame( $all, $theme_json->get_stylesheet() ); - $this->assertSame( $styles, $theme_json->get_stylesheet( array( 'styles' ) ) ); + $this->assertSame( $all, $theme_json->get_stylesheet( array( 'styles', 'presets', 'variables' ), null, array( 'skip_root_layout_styles' => true ) ) ); + $this->assertSame( $styles, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) ); $this->assertSame( $presets, $theme_json->get_stylesheet( array( 'presets' ) ) ); $this->assertSame( $variables, $theme_json->get_stylesheet( array( 'variables' ) ) ); } @@ -765,45 +784,7 @@ public function test_get_stylesheet_generates_proper_classes_and_css_vars_from_s ); } - public function test_get_stylesheet_preset_values_are_marked_as_important() { - $theme_json = new WP_Theme_JSON_Gutenberg( - array( - 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, - 'settings' => array( - 'color' => array( - 'palette' => array( - array( - 'slug' => 'grey', - 'color' => 'grey', - ), - ), - ), - ), - 'styles' => array( - 'blocks' => array( - 'core/paragraph' => array( - 'color' => array( - 'text' => 'red', - 'background' => 'blue', - ), - 'typography' => array( - 'fontSize' => '12px', - 'lineHeight' => '1.3', - ), - ), - ), - ), - ), - 'default' - ); - - $this->assertSame( - ':root{--wp--preset--color--grey: grey;}' . static::$base_styles . ':root :where(p){background-color: blue;color: red;font-size: 12px;line-height: 1.3;}.has-grey-color{color: var(--wp--preset--color--grey) !important;}.has-grey-background-color{background-color: var(--wp--preset--color--grey) !important;}.has-grey-border-color{border-color: var(--wp--preset--color--grey) !important;}', - $theme_json->get_stylesheet() - ); - } - - public function test_get_stylesheet_handles_whitelisted_element_pseudo_selectors() { + public function test_get_styles_for_block_handles_whitelisted_element_pseudo_selectors() { $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -836,14 +817,31 @@ public function test_get_stylesheet_handles_whitelisted_element_pseudo_selectors ) ); - $element_styles = ':root :where(a:where(:not(.wp-element-button))){background-color: red;color: green;}:root :where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;font-size: 10em;text-transform: uppercase;}:root :where(a:where(:not(.wp-element-button)):focus){background-color: black;color: yellow;}'; + $link_node = array( + 'path' => array( 'styles', 'elements', 'link' ), + 'selector' => 'a:where(:not(.wp-element-button))', + ); + $hover_node = array( + 'path' => array( 'styles', 'elements', 'link' ), + 'selector' => 'a:where(:not(.wp-element-button)):hover', + ); + $focus_node = array( + 'path' => array( 'styles', 'elements', 'link' ), + 'selector' => 'a:where(:not(.wp-element-button)):focus', + ); - $expected = static::$base_styles . $element_styles; + $link_style = ':root :where(a:where(:not(.wp-element-button))){background-color: red;color: green;}'; + $hover_style = ':root :where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;font-size: 10em;text-transform: uppercase;}'; + $focus_style = ':root :where(a:where(:not(.wp-element-button)):focus){background-color: black;color: yellow;}'; - $this->assertSame( $expected, $theme_json->get_stylesheet() ); - $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ) ) ); + $this->assertSame( $link_style, $theme_json->get_styles_for_block( $link_node ) ); + $this->assertSame( $hover_style, $theme_json->get_styles_for_block( $hover_node ) ); + $this->assertSame( $focus_style, $theme_json->get_styles_for_block( $focus_node ) ); } + /** + * Tests that if an element has nothing but pseudo selector styles, they are still output by get_stylesheet. + */ public function test_get_stylesheet_handles_only_pseudo_selector_rules_for_given_property() { $theme_json = new WP_Theme_JSON_Gutenberg( array( @@ -873,12 +871,9 @@ public function test_get_stylesheet_handles_only_pseudo_selector_rules_for_given ) ); - $element_styles = ':root :where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;font-size: 10em;text-transform: uppercase;}:root :where(a:where(:not(.wp-element-button)):focus){background-color: black;color: yellow;}'; + $expected = ':root :where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;font-size: 10em;text-transform: uppercase;}:root :where(a:where(:not(.wp-element-button)):focus){background-color: black;color: yellow;}'; - $expected = static::$base_styles . $element_styles; - - $this->assertSame( $expected, $theme_json->get_stylesheet() ); - $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ) ) ); + $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) ); } public function test_get_stylesheet_ignores_pseudo_selectors_on_non_whitelisted_elements() { @@ -910,12 +905,9 @@ public function test_get_stylesheet_ignores_pseudo_selectors_on_non_whitelisted_ ) ); - $element_styles = ':root :where(h4){background-color: red;color: green;}'; - - $expected = static::$base_styles . $element_styles; + $expected = ':root :where(h4){background-color: red;color: green;}'; - $this->assertSame( $expected, $theme_json->get_stylesheet() ); - $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ) ) ); + $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) ); } public function test_get_stylesheet_ignores_non_whitelisted_pseudo_selectors() { @@ -947,15 +939,16 @@ public function test_get_stylesheet_ignores_non_whitelisted_pseudo_selectors() { ) ); - $element_styles = ':root :where(a:where(:not(.wp-element-button))){background-color: red;color: green;}:root :where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;}'; + $expected = ':root :where(a:where(:not(.wp-element-button))){background-color: red;color: green;}:root :where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;}'; - $expected = static::$base_styles . $element_styles; - - $this->assertSame( $expected, $theme_json->get_stylesheet() ); - $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ) ) ); + $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) ); $this->assertStringNotContainsString( 'a:levitate{', $theme_json->get_stylesheet( array( 'styles' ) ) ); } + /** + * Tests that element pseudo selectors are output before block element pseudo selectors, and that whitelisted + * block element pseudo selectors are output correctly. + */ public function test_get_stylesheet_handles_priority_of_elements_vs_block_elements_pseudo_selectors() { $theme_json = new WP_Theme_JSON_Gutenberg( array( @@ -993,75 +986,20 @@ public function test_get_stylesheet_handles_priority_of_elements_vs_block_elemen ) ); - $element_styles = ':root :where(.wp-block-group a:where(:not(.wp-element-button))){background-color: red;color: green;}:root :where(.wp-block-group a:where(:not(.wp-element-button)):hover){background-color: green;color: red;font-size: 10em;text-transform: uppercase;}:root :where(.wp-block-group a:where(:not(.wp-element-button)):focus){background-color: black;color: yellow;}'; + $expected = ':root :where(.wp-block-group a:where(:not(.wp-element-button))){background-color: red;color: green;}:root :where(.wp-block-group a:where(:not(.wp-element-button)):hover){background-color: green;color: red;font-size: 10em;text-transform: uppercase;}:root :where(.wp-block-group a:where(:not(.wp-element-button)):focus){background-color: black;color: yellow;}'; - $expected = static::$base_styles . $element_styles; - - $this->assertSame( $expected, $theme_json->get_stylesheet() ); - $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ) ) ); - } - - public function test_get_stylesheet_handles_whitelisted_block_level_element_pseudo_selectors() { - $theme_json = new WP_Theme_JSON_Gutenberg( - array( - 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, - 'styles' => array( - 'elements' => array( - 'link' => array( - 'color' => array( - 'text' => 'green', - 'background' => 'red', - ), - ':hover' => array( - 'color' => array( - 'text' => 'red', - 'background' => 'green', - ), - ), - ), - ), - 'blocks' => array( - 'core/group' => array( - 'elements' => array( - 'link' => array( - ':hover' => array( - 'color' => array( - 'text' => 'yellow', - 'background' => 'black', - ), - ), - ), - ), - ), - ), - ), - ) - ); - - $element_styles = ':root :where(a:where(:not(.wp-element-button))){background-color: red;color: green;}:root :where(a:where(:not(.wp-element-button)):hover){background-color: green;color: red;}:root :where(.wp-block-group a:where(:not(.wp-element-button)):hover){background-color: black;color: yellow;}'; - - $expected = static::$base_styles . $element_styles; - - $this->assertSame( $expected, $theme_json->get_stylesheet() ); - $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ) ) ); + $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) ); } /** - * This test relies on a block having already been registered prior to - * theme.json generating block metadata. Until a core block, such as Image, - * opts into feature level selectors, we need to register a test block. - * This is achieved via `tests_add_filter()` in Gutenberg's phpunit - * bootstrap. After a core block adopts feature level selectors we could - * remove that filter and instead use the core block for the following test. + * This test checks that feature selectors defined as `__experimentalSelector` inside + * the `supports` property are correctly output in the stylesheet. */ public function test_get_stylesheet_with_deprecated_feature_level_selectors() { $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( - 'border' => array( - 'radius' => true, - ), 'color' => array( 'custom' => false, 'palette' => array( @@ -1071,25 +1009,16 @@ public function test_get_stylesheet_with_deprecated_feature_level_selectors() { ), ), ), - 'spacing' => array( - 'padding' => true, - ), 'typography' => array( 'fontSize' => true, ), ), 'styles' => array( 'blocks' => array( - 'test/test' => array( - 'border' => array( - 'radius' => '9999px', - ), + 'core/calendar' => array( 'color' => array( 'text' => 'green', ), - 'spacing' => array( - 'padding' => '20px', - ), 'typography' => array( 'fontSize' => '3em', ), @@ -1099,61 +1028,33 @@ public function test_get_stylesheet_with_deprecated_feature_level_selectors() { ) ); - $base_styles = ':root{--wp--preset--color--green: green;}' . static::$base_styles; - $block_styles = ':root :where(.wp-block-test, .wp-block-test__wrapper){color: green;}:root :where(.wp-block-test .inner, .wp-block-test__wrapper .inner){border-radius: 9999px;padding: 20px;}:root :where(.wp-block-test .sub-heading, .wp-block-test__wrapper .sub-heading){font-size: 3em;}'; + $base_styles = ':root{--wp--preset--color--green: green;}'; + $block_styles = ':root :where(.wp-block-calendar){font-size: 3em;}:root :where(.wp-block-calendar table, .wp-block-calendar th){color: green;}'; $preset_styles = '.has-green-color{color: var(--wp--preset--color--green) !important;}.has-green-background-color{background-color: var(--wp--preset--color--green) !important;}.has-green-border-color{border-color: var(--wp--preset--color--green) !important;}'; $expected = $base_styles . $block_styles . $preset_styles; - $this->assertEquals( $expected, $theme_json->get_stylesheet() ); + $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles', 'presets', 'variables' ), null, array( 'skip_root_layout_styles' => true ) ) ); } + /** - * This test relies on a block having already been registered prior to - * theme.json generating block metadata. Until a core block adopts the - * new selectors API, we need to register a test block. - * This is achieved via `tests_add_filter()` in Gutenberg's phpunit - * bootstrap. After a core block adopts feature level selectors we could - * remove that filter and instead use the core block for the following test. + * This test checks that feature selectors defined in the stable `selectors` + * property are correctly output in the stylesheet. */ public function test_get_stylesheet_with_block_json_selectors() { $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( - 'border' => array( + 'border' => array( 'radius' => true, ), - 'color' => array( - 'custom' => false, - 'palette' => array( - array( - 'slug' => 'green', - 'color' => 'green', - ), - ), - ), - 'spacing' => array( - 'padding' => true, - ), - 'typography' => array( - 'fontSize' => true, - ), ), 'styles' => array( 'blocks' => array( - 'my/block-with-selectors' => array( - 'border' => array( - 'radius' => '9999px', - ), - 'color' => array( - 'background' => 'grey', - 'text' => 'navy', - ), - 'spacing' => array( - 'padding' => '20px', - ), - 'typography' => array( - 'fontSize' => '3em', + 'core/image' => array( + 'border' => array( + 'radius' => '374px', ), ), ), @@ -1161,12 +1062,9 @@ public function test_get_stylesheet_with_block_json_selectors() { ) ); - $base_styles = ':root{--wp--preset--color--green: green;}' . static::$base_styles; - $block_styles = ':root :where(.custom-root-selector){background-color: grey;padding: 20px;}:root :where(.custom-root-selector img){border-radius: 9999px;}:root :where(.custom-root-selector > figcaption){color: navy;font-size: 3em;}'; - $preset_styles = '.has-green-color{color: var(--wp--preset--color--green) !important;}.has-green-background-color{background-color: var(--wp--preset--color--green) !important;}.has-green-border-color{border-color: var(--wp--preset--color--green) !important;}'; - $expected = $base_styles . $block_styles . $preset_styles; + $expected = ':root :where(.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder){border-radius: 374px;}'; - $this->assertEquals( $expected, $theme_json->get_stylesheet() ); + $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles', 'presets', 'variables' ), null, array( 'skip_root_layout_styles' => true ) ) ); } public function test_get_stylesheet_generates_layout_styles() { @@ -1262,10 +1160,6 @@ public function test_get_stylesheet_generates_base_fallback_gap_layout_styles() array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( - 'layout' => array( - 'contentSize' => '640px', - 'wideSize' => '1200px', - ), 'spacing' => array( 'blockGap' => null, ), @@ -1383,10 +1277,9 @@ public function test_get_stylesheet_returns_outline_styles() { ) ); - $element_styles = ':root :where(.wp-element-button, .wp-block-button__link){outline-color: red;outline-offset: 3px;outline-style: dashed;outline-width: 3px;}:root :where(.wp-element-button:hover, .wp-block-button__link:hover){outline-color: blue;outline-offset: 3px;outline-style: solid;outline-width: 3px;}'; + $expected = ':root :where(.wp-element-button, .wp-block-button__link){outline-color: red;outline-offset: 3px;outline-style: dashed;outline-width: 3px;}:root :where(.wp-element-button:hover, .wp-block-button__link:hover){outline-color: blue;outline-offset: 3px;outline-style: solid;outline-width: 3px;}'; - $expected = static::$base_styles . $element_styles; - $this->assertSame( $expected, $theme_json->get_stylesheet() ); + $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) ); } public function test_get_stylesheet_custom_root_selector() { @@ -1402,13 +1295,15 @@ public function test_get_stylesheet_custom_root_selector() { 'default' ); - $options = array( 'root_selector' => '.custom' ); + // Custom root selector is unrelated to root layout styles so they don't need to be output for this test. + $options = array( + 'root_selector' => '.custom', + 'skip_root_layout_styles' => true, + ); $actual = $theme_json->get_stylesheet( array( 'styles' ), null, $options ); - // Results also include root site blocks styles which hard code - // `:where(body) { margin: 0; }`. $this->assertSame( - ':where(body) { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:root :where(.custom){color: teal;}', + ':root :where(.custom){color: teal;}', $actual ); } @@ -1465,10 +1360,9 @@ public function test_get_stylesheet_generates_fluid_typography_values() { unregister_block_type( 'test/clamp-me' ); - // Results also include root site blocks styles. $this->assertSame( - ':root{--wp--preset--font-size--pickles: clamp(14px, 0.875rem + ((1vw - 3.2px) * 0.156), 16px);--wp--preset--font-size--toast: clamp(14.642px, 0.915rem + ((1vw - 3.2px) * 0.575), 22px);}:where(body) { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}:root :where(body){font-size: clamp(0.875em, 0.875rem + ((1vw - 0.2em) * 0.156), 1em);}:root :where(h1){font-size: clamp(50.171px, 3.136rem + ((1vw - 3.2px) * 3.893), 100px);}:root :where(.wp-block-test-clamp-me){font-size: clamp(27.894px, 1.743rem + ((1vw - 3.2px) * 1.571), 48px);}.has-pickles-font-size{font-size: var(--wp--preset--font-size--pickles) !important;}.has-toast-font-size{font-size: var(--wp--preset--font-size--toast) !important;}', - $theme_json->get_stylesheet() + ':root{--wp--preset--font-size--pickles: clamp(14px, 0.875rem + ((1vw - 3.2px) * 0.156), 16px);--wp--preset--font-size--toast: clamp(14.642px, 0.915rem + ((1vw - 3.2px) * 0.575), 22px);}:root :where(body){font-size: clamp(0.875em, 0.875rem + ((1vw - 0.2em) * 0.156), 1em);}:root :where(h1){font-size: clamp(50.171px, 3.136rem + ((1vw - 3.2px) * 3.893), 100px);}:root :where(.wp-block-test-clamp-me){font-size: clamp(27.894px, 1.743rem + ((1vw - 3.2px) * 1.571), 48px);}.has-pickles-font-size{font-size: var(--wp--preset--font-size--pickles) !important;}.has-toast-font-size{font-size: var(--wp--preset--font-size--toast) !important;}', + $theme_json->get_stylesheet( array( 'styles', 'variables', 'presets' ), null, array( 'skip_root_layout_styles' => true ) ) ); } @@ -3524,9 +3418,8 @@ public function test_get_property_value_valid() { ) ); - $color_styles = ':root :where(body){background-color: #ffffff;color: #000000;}:root :where(.wp-element-button, .wp-block-button__link){background-color: #000000;color: #ffffff;}'; - $expected = static::$base_styles . $color_styles; - $this->assertSame( $expected, $theme_json->get_stylesheet() ); + $expected = ':root :where(body){background-color: #ffffff;color: #000000;}:root :where(.wp-element-button, .wp-block-button__link){background-color: #000000;color: #ffffff;}'; + $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) ); } /** @@ -3602,9 +3495,8 @@ public function test_get_property_value_loop() { ) ); - $color_styles = ':root :where(body){background-color: #ffffff;}:root :where(.wp-element-button, .wp-block-button__link){color: #ffffff;}'; - $expected = static::$base_styles . $color_styles; - $this->assertSame( $expected, $theme_json->get_stylesheet() ); + $expected = ':root :where(body){background-color: #ffffff;}:root :where(.wp-element-button, .wp-block-button__link){color: #ffffff;}'; + $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) ); } /** @@ -3635,9 +3527,8 @@ public function test_get_property_value_recursion() { ) ); - $color_styles = ':root :where(body){background-color: #ffffff;color: #ffffff;}:root :where(.wp-element-button, .wp-block-button__link){color: #ffffff;}'; - $expected = static::$base_styles . $color_styles; - $this->assertSame( $expected, $theme_json->get_stylesheet() ); + $expected = ':root :where(body){background-color: #ffffff;color: #ffffff;}:root :where(.wp-element-button, .wp-block-button__link){color: #ffffff;}'; + $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) ); } /** @@ -3659,9 +3550,8 @@ public function test_get_property_value_self() { ) ); - $color_styles = ':root :where(body){background-color: #ffffff;}'; - $expected = static::$base_styles . $color_styles; - $this->assertSame( $expected, $theme_json->get_stylesheet() ); + $expected = ':root :where(body){background-color: #ffffff;}'; + $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ), null, array( 'skip_root_layout_styles' => true ) ) ); } public function test_get_styles_for_block_with_padding_aware_alignments() { @@ -3723,7 +3613,7 @@ public function test_get_styles_for_block_without_padding_aware_alignments() { $this->assertSame( $expected, $root_rules . $style_rules ); } - public function test_get_styles_for_block_with_content_width() { + public function test_get_styles_with_content_width() { $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -3741,10 +3631,8 @@ public function test_get_styles_for_block_with_content_width() { 'selector' => 'body', ); - $expected = ':root { --wp--style--global--content-size: 800px;--wp--style--global--wide-size: 1000px; }:where(body) { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}'; - $root_rules = $theme_json->get_root_layout_rules( WP_Theme_JSON_Gutenberg::ROOT_BLOCK_SELECTOR, $metadata ); - $style_rules = $theme_json->get_styles_for_block( $metadata ); - $this->assertSame( $expected, $root_rules . $style_rules ); + $expected = ':root { --wp--style--global--content-size: 800px;--wp--style--global--wide-size: 1000px; }:where(body) { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}'; + $this->assertSame( $expected, $theme_json->get_root_layout_rules( WP_Theme_JSON::ROOT_BLOCK_SELECTOR, $metadata ) ); } public function test_get_styles_with_appearance_tools() { @@ -3762,9 +3650,8 @@ public function test_get_styles_with_appearance_tools() { 'selector' => 'body', ); - $expected = ':where(body) { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.wp-site-blocks) > * { margin-block-start: ; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child { margin-block-end: 0; }:root { --wp--style--block-gap: ; }.is-layout-flow > :first-child{margin-block-start: 0;}.is-layout-flow > :last-child{margin-block-end: 0;}.is-layout-flow > *{margin-block-start: 1;margin-block-end: 0;}.is-layout-constrained > :first-child{margin-block-start: 0;}.is-layout-constrained > :last-child{margin-block-end: 0;}.is-layout-constrained > *{margin-block-start: 1;margin-block-end: 0;}.is-layout-flex {gap: 1;}.is-layout-grid {gap: 1;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}'; - $root_rules = $theme_json->get_root_layout_rules( WP_Theme_JSON_Gutenberg::ROOT_BLOCK_SELECTOR, $metadata ); - $this->assertSame( $expected, $root_rules ); + $expected = ':where(body) { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.wp-site-blocks) > * { margin-block-start: ; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child { margin-block-end: 0; }:root { --wp--style--block-gap: ; }.is-layout-flow > :first-child{margin-block-start: 0;}.is-layout-flow > :last-child{margin-block-end: 0;}.is-layout-flow > *{margin-block-start: 1;margin-block-end: 0;}.is-layout-constrained > :first-child{margin-block-start: 0;}.is-layout-constrained > :last-child{margin-block-end: 0;}.is-layout-constrained > *{margin-block-start: 1;margin-block-end: 0;}.is-layout-flex {gap: 1;}.is-layout-grid {gap: 1;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}'; + $this->assertSame( $expected, $theme_json->get_root_layout_rules( WP_Theme_JSON_Gutenberg::ROOT_BLOCK_SELECTOR, $metadata ) ); } public function test_sanitization() { @@ -4643,7 +4530,6 @@ public function data_set_spacing_sizes_when_invalid() { * @param array $expected_output Expected output from data provider. */ public function test_update_separator_declarations( $separator_block_settings, $expected_output ) { - // If only background is defined, test that includes border-color to the style so it is applied on the front end. $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -4656,9 +4542,11 @@ public function test_update_separator_declarations( $separator_block_settings, $ 'default' ); - $stylesheet = $theme_json->get_stylesheet( array( 'styles' ) ); - - $this->assertSame( $expected_output, $stylesheet ); + $separator_node = array( + 'path' => array( 'styles', 'blocks', 'core/separator' ), + 'selector' => '.wp-block-separator', + ); + $this->assertSame( $expected_output, $theme_json->get_styles_for_block( $separator_node ) ); } /** @@ -4675,7 +4563,7 @@ public function data_update_separator_declarations() { 'background' => 'blue', ), ), - 'expected_output' => static::$base_styles . ':root :where(.wp-block-separator){background-color: blue;color: blue;}', + 'expected_output' => ':root :where(.wp-block-separator){background-color: blue;color: blue;}', ), // If background and text are defined, do not include border-color, as text color is enough. 'background and text, no border-color' => array( @@ -4685,7 +4573,7 @@ public function data_update_separator_declarations() { 'text' => 'red', ), ), - 'expected_output' => static::$base_styles . ':root :where(.wp-block-separator){background-color: blue;color: red;}', + 'expected_output' => ':root :where(.wp-block-separator){background-color: blue;color: red;}', ), // If only text is defined, do not include border-color, as by itself is enough. 'only text' => array( @@ -4694,7 +4582,7 @@ public function data_update_separator_declarations() { 'text' => 'red', ), ), - 'expected_output' => static::$base_styles . ':root :where(.wp-block-separator){color: red;}', + 'expected_output' => ':root :where(.wp-block-separator){color: red;}', ), // If background, text, and border-color are defined, include everything, CSS specificity will decide which to apply. 'background, text, and border-color' => array( @@ -4707,7 +4595,7 @@ public function data_update_separator_declarations() { 'color' => 'pink', ), ), - 'expected_output' => static::$base_styles . ':root :where(.wp-block-separator){background-color: blue;border-color: pink;color: red;}', + 'expected_output' => ':root :where(.wp-block-separator){background-color: blue;border-color: pink;color: red;}', ), // If background and border color are defined, include everything, CSS specificity will decide which to apply. 'background, and border-color' => array( @@ -4719,7 +4607,7 @@ public function data_update_separator_declarations() { 'color' => 'pink', ), ), - 'expected_output' => static::$base_styles . ':root :where(.wp-block-separator){background-color: blue;border-color: pink;}', + 'expected_output' => ':root :where(.wp-block-separator){background-color: blue;border-color: pink;}', ), ); } @@ -4782,10 +4670,10 @@ public function test_get_shadow_styles_for_blocks() { ) ); - $global_styles = ':root{--wp--preset--shadow--natural: 5px 5px 0 0 black;}' . static::$base_styles; + $variable_styles = ':root{--wp--preset--shadow--natural: 5px 5px 0 0 black;}'; $element_styles = ':root :where(a:where(:not(.wp-element-button))){box-shadow: var(--wp--preset--shadow--natural);}:root :where(.wp-element-button, .wp-block-button__link){box-shadow: var(--wp--preset--shadow--natural);}:root :where(p){box-shadow: var(--wp--preset--shadow--natural);}'; - $expected_styles = $global_styles . $element_styles; - $this->assertSame( $expected_styles, $theme_json->get_stylesheet() ); + $expected_styles = $variable_styles . $element_styles; + $this->assertSame( $expected_styles, $theme_json->get_stylesheet( array( 'styles', 'presets', 'variables' ), null, array( 'skip_root_layout_styles' => true ) ) ); } public function test_get_top_level_background_image_styles() { @@ -4801,36 +4689,17 @@ public function test_get_top_level_background_image_styles() { 'backgroundRepeat' => 'no-repeat', 'backgroundPosition' => 'center center', ), - 'blocks' => array( - 'core/paragraph' => array( - 'background' => array( - 'backgroundImage' => array( - 'url' => 'http://example.org/image.png', - ), - 'backgroundSize' => 'cover', - 'backgroundRepeat' => 'no-repeat', - 'backgroundPosition' => 'center center', - ), - ), - ), - 'elements' => array( - 'button' => array( - 'background' => array( - 'backgroundImage' => array( - 'url' => 'http://example.org/image.png', - ), - 'backgroundSize' => 'cover', - 'backgroundRepeat' => 'no-repeat', - 'backgroundPosition' => 'center center', - ), - ), - ), ), ) ); - $expected_styles = ":where(body) { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;}"; - $this->assertSame( $expected_styles, $theme_json->get_stylesheet(), 'Styles returned from "::get_stylesheet()" with top-level background styles type does not match expectations' ); + $body_node = array( + 'path' => array( 'styles' ), + 'selector' => 'body', + ); + + $expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;}"; + $this->assertSame( $expected_styles, $theme_json->get_styles_for_block( $body_node ), 'Styles returned from "::get_styles_for_block()" with top-level background styles type does not match expectations' ); $theme_json = new WP_Theme_JSON_Gutenberg( array( @@ -4846,16 +4715,35 @@ public function test_get_top_level_background_image_styles() { ) ); - $expected_styles = ":where(body) { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;}"; - $this->assertSame( $expected_styles, $theme_json->get_stylesheet(), 'Styles returned from "::get_stylesheet()" with top-level background image as string type does not match expectations' ); + $expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;}"; + $this->assertSame( $expected_styles, $theme_json->get_styles_for_block( $body_node ), 'Styles returned from "::get_styles_for_block()" with top-level background image as string type does not match expectations' ); + } + + /** + * Tests that base custom CSS is generated correctly. + */ + public function test_get_stylesheet_handles_base_custom_css() { + $theme_json = new WP_Theme_JSON_Gutenberg( + array( + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, + 'styles' => array( + 'css' => 'body {color:purple;}', + ), + ) + ); + + $custom_css = 'body {color:purple;}'; + $this->assertSame( $custom_css, $theme_json->get_stylesheet( array( 'custom-css' ) ) ); } - public function test_get_custom_css_handles_global_custom_css() { + /** + * Tests that block custom CSS is generated correctly. + */ + public function test_get_styles_for_block_handles_block_custom_css() { $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( - 'css' => 'body {color:purple;}', 'blocks' => array( 'core/paragraph' => array( 'css' => 'color:red;', @@ -4865,8 +4753,17 @@ public function test_get_custom_css_handles_global_custom_css() { ) ); - $custom_css = 'body {color:purple;}:root :where(p){color:red;}'; - $this->assertSame( $custom_css, $theme_json->get_custom_css() ); + $paragraph_node = array( + 'name' => 'core/paragraph', + 'path' => array( 'styles', 'blocks', 'core/paragraph' ), + 'selector' => 'p', + 'selectors' => array( + 'root' => 'p', + ), + ); + + $custom_css = ':root :where(p){color:red;}'; + $this->assertSame( $custom_css, $theme_json->get_styles_for_block( $paragraph_node ) ); } /** @@ -5382,4 +5279,81 @@ public function test_scope_style_node_selectors() { $this->assertEquals( $expected, $actual ); } + + /** + * Block style variations styles aren't generated by default. This test covers + * the `get_block_nodes` does not include variations by default, preventing + * the inclusion of their styles. + */ + public function test_opt_out_of_block_style_variations_by_default() { + $theme_json = new ReflectionClass( 'WP_Theme_JSON_Gutenberg' ); + + $func = $theme_json->getMethod( 'get_block_nodes' ); + $func->setAccessible( true ); + + $theme_json = array( + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, + 'styles' => array( + 'blocks' => array( + 'core/button' => array( + 'variations' => array( + 'outline' => array( + 'color' => array( + 'background' => 'red', + ), + ), + ), + ), + ), + ), + ); + $selectors = array(); + + $block_nodes = $func->invoke( null, $theme_json, $selectors ); + $button_variations = $block_nodes[0]['variations'] ?? array(); + + $this->assertEquals( array(), $button_variations ); + } + + /** + * Block style variations styles aren't generated by default. This test ensures + * variations are included by `get_block_nodes` when requested. + */ + public function test_opt_in_to_block_style_variations() { + $theme_json = new ReflectionClass( 'WP_Theme_JSON_Gutenberg' ); + + $func = $theme_json->getMethod( 'get_block_nodes' ); + $func->setAccessible( true ); + + $theme_json = array( + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, + 'styles' => array( + 'blocks' => array( + 'core/button' => array( + 'variations' => array( + 'outline' => array( + 'color' => array( + 'background' => 'red', + ), + ), + ), + ), + ), + ), + ); + $selectors = array(); + $options = array( 'include_block_style_variations' => true ); + + $block_nodes = $func->invoke( null, $theme_json, $selectors, $options ); + $button_variations = $block_nodes[0]['variations'] ?? array(); + + $expected = array( + array( + 'path' => array( 'styles', 'blocks', 'core/button', 'variations', 'outline' ), + 'selector' => '.wp-block-button.is-style-outline .wp-block-button__link', + ), + ); + + $this->assertEquals( $expected, $button_variations ); + } } diff --git a/platform-docs/src/components/HomepageThanks/index.js b/platform-docs/src/components/HomepageThanks/index.js index f543e3aaee5d2b..61cfddf2a8fb96 100644 --- a/platform-docs/src/components/HomepageThanks/index.js +++ b/platform-docs/src/components/HomepageThanks/index.js @@ -31,7 +31,7 @@ export default function HomepageThanks() {
    diff --git a/schemas/json/.wp-env.json b/schemas/json/.wp-env.json new file mode 100644 index 00000000000000..b559cb9d8a5021 --- /dev/null +++ b/schemas/json/.wp-env.json @@ -0,0 +1,107 @@ +{ + "title": "JSON schema for WordPress wp-env configuration files", + "$schema": "http://json-schema.org/draft-04/schema#", + "definitions": { + "//": { + "reference": "https://developer.wordpress.org/block-editor/reference-guides/packages/packages-env/" + }, + "wpEnvProperties": { + "properties": { + "core": { + "description": "The WordPress installation to use. If null is specified, wp-env will use the latest production release of WordPress.", + "default": null, + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "phpVersion": { + "description": "The PHP version to use. If null is specified, wp-env will use the default version used with production release of WordPress.", + "default": null, + "oneOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "plugins": { + "description": "A list of plugins to install and activate in the environment.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "themes": { + "description": "A list of themes to install in the environment.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "port": { + "description": "The primary port number to use for the installation. You'll access the instance through the port: 'http://localhost:8888'.", + "default": 8888, + "type": "integer" + }, + "config": { + "description": "Mapping of wp-config.php constants to their desired values.", + "default": {}, + "type": "object" + }, + "mappings": { + "description": "Mapping of WordPress directories to local directories to be mounted in the WordPress instance.", + "default": {}, + "type": "object" + } + } + } + }, + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/wpEnvProperties" + }, + { + "properties": { + "$schema": { + "type": "string" + }, + "env": { + "description": "The key env is available to override any of the above options on an individual-environment basis.", + "type": "object", + "default": {}, + "patternProperties": { + "[a-zA-Z]": { + "type": "object", + "$ref": "#/definitions/wpEnvProperties", + "additionalProperties": false + } + } + } + } + }, + { + "properties": { + "$schema": {}, + "core": {}, + "phpVersion": {}, + "plugins": {}, + "themes": {}, + "port": {}, + "config": {}, + "mappings": {}, + "env": {} + }, + "additionalProperties": false + } + ] +} diff --git a/schemas/json/theme.json b/schemas/json/theme.json index bdfea7279f67ac..5b9e37ef7378a6 100644 --- a/schemas/json/theme.json +++ b/schemas/json/theme.json @@ -444,9 +444,8 @@ "type": "string" }, "slug": { - "description": "Unique identifier for the space size preset. Will be sorted numerically. For best cross theme compatibility these should be in the form '10','20','30','40','50','60', etc. with '50' representing the 'Medium' size step.", - "type": "string", - "pattern": "^[0-9].*$" + "description": "Unique identifier for the space size preset. For best cross theme compatibility these should be in the form '10','20','30','40','50','60', etc. with '50' representing the 'Medium' size step. If all slugs begin with a number they will be merged with default and user slugs and sorted numerically.", + "type": "string" }, "size": { "description": "CSS space-size value, including units.", @@ -2288,6 +2287,10 @@ }, { "properties": { + "title": { + "type": "string", + "description": "Style variation name." + }, "blockTypes": { "type": "array", "items": { @@ -2696,6 +2699,10 @@ "type": "string", "description": "Title of the global styles variation. If not defined, the file name will be used." }, + "slug": { + "type": "string", + "description": "Slug of the global styles variation. If not defined, the kebab-case title will be used." + }, "description": { "type": "string", "description": "Description of the global styles variation." diff --git a/test/e2e/specs/editor/various/block-bindings.spec.js b/test/e2e/specs/editor/various/block-bindings.spec.js index cb25afc416eaaf..222004c7c1bccc 100644 --- a/test/e2e/specs/editor/various/block-bindings.spec.js +++ b/test/e2e/specs/editor/various/block-bindings.spec.js @@ -1975,6 +1975,41 @@ test.describe( 'Block bindings', () => { ).toHaveText( 'new value' ); } ); + // Related issue: https://github.com/WordPress/gutenberg/issues/62347 + test( 'should be possible to use symbols and numbers as the custom field value', async ( { + editor, + } ) => { + await editor.insertBlock( { + name: 'core/paragraph', + attributes: { + anchor: 'paragraph-binding', + content: 'paragraph default content', + metadata: { + bindings: { + content: { + source: 'core/post-meta', + args: { key: 'text_custom_field' }, + }, + }, + }, + }, + } ); + const paragraphBlock = editor.canvas.getByRole( 'document', { + name: 'Block: Paragraph', + } ); + + await expect( paragraphBlock ).toHaveAttribute( + 'contenteditable', + 'true' + ); + await paragraphBlock.fill( '$10.00' ); + // Check the value of the custom field is being updated by visiting the frontend. + const previewPage = await editor.openPreviewPage(); + await expect( + previewPage.locator( '#paragraph-binding' ) + ).toHaveText( '$10.00' ); + } ); + test( 'should be possible to edit the value of the url custom field from the button', async ( { editor, page, diff --git a/test/e2e/specs/editor/various/copy-cut-paste.spec.js b/test/e2e/specs/editor/various/copy-cut-paste.spec.js index 4951f99fb6b5b2..33a65e6f5a1195 100644 --- a/test/e2e/specs/editor/various/copy-cut-paste.spec.js +++ b/test/e2e/specs/editor/various/copy-cut-paste.spec.js @@ -695,10 +695,9 @@ test.describe( 'Copy/cut/paste', () => { }, }, { - name: 'core/heading', + name: 'core/paragraph', attributes: { content: 'bB', - level: 2, }, }, ] ); diff --git a/test/e2e/specs/editor/various/pattern-overrides.spec.js b/test/e2e/specs/editor/various/pattern-overrides.spec.js index f4648a03efe956..3587296a6b2a08 100644 --- a/test/e2e/specs/editor/various/pattern-overrides.spec.js +++ b/test/e2e/specs/editor/various/pattern-overrides.spec.js @@ -742,6 +742,59 @@ test.describe( 'Pattern Overrides', () => { ).toBeHidden(); } ); + test( 'overridden images should not have unsupported attributes set', async ( { + admin, + requestUtils, + editor, + } ) => { + const imageName = 'Editable image'; + const TEST_IMAGE_FILE_PATH = path.resolve( + __dirname, + '../../../assets/10x10_e2e_test_image_z9T8jK.png' + ); + const { id } = await requestUtils.createBlock( { + title: 'Pattern', + content: ` +
    +`, + status: 'publish', + } ); + + await admin.createNewPost(); + + await editor.insertBlock( { + name: 'core/block', + attributes: { ref: id }, + } ); + + const imageBlock = editor.canvas.getByRole( 'document', { + name: 'Block: Image', + } ); + await editor.selectBlocks( imageBlock ); + await imageBlock + .getByTestId( 'form-file-upload-input' ) + .setInputFiles( TEST_IMAGE_FILE_PATH ); + await expect( imageBlock.getByRole( 'img' ) ).toHaveCount( 1 ); + await expect( imageBlock.getByRole( 'img' ) ).toHaveAttribute( + 'src', + /\/wp-content\/uploads\// + ); + + // Because the image is an inner block of a controlled pattern block, + // `getBlocks` has to be called using the pattern block's client id. + const patternBlock = editor.canvas.getByRole( 'document', { + name: 'Block: Pattern', + } ); + const patternClientId = await patternBlock.getAttribute( 'data-block' ); + const patternInnerBlocks = await editor.getBlocks( { + clientId: patternClientId, + } ); + + // Link is an unsupported attribute, so should be undefined, even though + // the image block tries to set its attribute. + expect( patternInnerBlocks[ 0 ].attributes.link ).toBe( undefined ); + } ); + test( 'blocks with the same name should be synced', async ( { page, admin, diff --git a/test/e2e/specs/editor/various/publish-panel.spec.js b/test/e2e/specs/editor/various/publish-panel.spec.js index c70a7b85cd70fe..02a7bfa60eea45 100644 --- a/test/e2e/specs/editor/various/publish-panel.spec.js +++ b/test/e2e/specs/editor/various/publish-panel.spec.js @@ -164,7 +164,7 @@ test.describe( 'Post publish panel', () => { await expect( publishPanel ).toBeVisible(); const postMetaPanel = publishPanel.locator( - '.entities-saved-states__post-meta' + '.entities-saved-states__changes' ); await expect( postMetaPanel ).toBeVisible(); diff --git a/test/e2e/specs/interactivity/deferred-store.spec.ts b/test/e2e/specs/interactivity/deferred-store.spec.ts index 4521322e61dfc9..b6a7853c40dcd4 100644 --- a/test/e2e/specs/interactivity/deferred-store.spec.ts +++ b/test/e2e/specs/interactivity/deferred-store.spec.ts @@ -21,6 +21,9 @@ test.describe( 'deferred store', () => { } ) => { const resultInput = page.getByTestId( 'result' ); await expect( resultInput ).toHaveText( '' ); + await page.evaluate( () => { + window.dispatchEvent( new Event( '_test_proceed_' ) ); + } ); await expect( resultInput ).toHaveText( 'Hello, world!' ); } ); @@ -31,6 +34,9 @@ test.describe( 'deferred store', () => { } ) => { const resultInput = page.getByTestId( 'result-getter' ); await expect( resultInput ).toHaveText( '' ); + await page.evaluate( () => { + window.dispatchEvent( new Event( '_test_proceed_' ) ); + } ); await expect( resultInput ).toHaveText( 'Hello, world!' ); } ); } ); diff --git a/test/integration/__snapshots__/blocks-raw-handling.test.js.snap b/test/integration/__snapshots__/blocks-raw-handling.test.js.snap index 589eef78f34e21..2ceadd67d4d1f4 100644 --- a/test/integration/__snapshots__/blocks-raw-handling.test.js.snap +++ b/test/integration/__snapshots__/blocks-raw-handling.test.js.snap @@ -26,6 +26,8 @@ exports[`Blocks raw handling pasteHandler iframe-embed 1`] = `""`; exports[`Blocks raw handling pasteHandler markdown 1`] = `"This is a heading with italic
    This is a paragraph with a link, bold, and strikethrough.
    Preserve
    line breaks please.
    Lists
    A
    Bulleted Indented
    List
    One
    Two
    Three
    Table
    First Header
    Second Header
    Content from cell 1
    Content from cell 2
    Content in the first column
    Content in the second column



    Table with empty cells.
    Quote
    First
    Second
    Code
    Inline code tags should work.
    This is a code block."`; +exports[`Blocks raw handling pasteHandler mixed-content 1`] = `"Some heading

    Content we need to preserve"`; + exports[`Blocks raw handling pasteHandler ms-word 1`] = `"This is a title
     
    This is a subtitle
     
    This is a heading level 1
     
    This is a heading level 2
     
    This is a paragraph with a link.
     
    A
    Bulleted
    Indented
    List
     
    One
    Two
    Three
     
    One
    Two
    Three
    1
    2
    3
    I
    II
    III
     
    An image:
     

    This is an anchor link that leads to the next paragraph.
    This is the paragraph with the anchor.
    This is an anchor link that leads nowhere.
    This is a paragraph with an anchor with no link pointing to it.
    This is a reference to a footnote[1].
    This is a reference to an endnote[i].


    [1] This is a footnote.


    [i] This is an endnote."`; exports[`Blocks raw handling pasteHandler ms-word-list 1`] = `"This is a headline?
    This is a text:
    One
    Two
    Three
    Lorem Ipsum.
     "`; diff --git a/test/integration/blocks-raw-handling.test.js b/test/integration/blocks-raw-handling.test.js index 81d3b7053468be..70af14f3290460 100644 --- a/test/integration/blocks-raw-handling.test.js +++ b/test/integration/blocks-raw-handling.test.js @@ -424,6 +424,7 @@ describe( 'Blocks raw handling', () => { 'shortcode-matching', 'slack-quote', 'slack-paragraphs', + 'mixed-content', ].forEach( ( type ) => { // eslint-disable-next-line jest/valid-title it( type, () => { diff --git a/test/integration/fixtures/documents/mixed-content-in.html b/test/integration/fixtures/documents/mixed-content-in.html new file mode 100644 index 00000000000000..a190f8523cd6c7 --- /dev/null +++ b/test/integration/fixtures/documents/mixed-content-in.html @@ -0,0 +1,7 @@ +

    Some heading

    +
      +
    • +
      +
    • +
    • Content we need to preserve
    • +
    diff --git a/test/integration/fixtures/documents/mixed-content-out.html b/test/integration/fixtures/documents/mixed-content-out.html new file mode 100644 index 00000000000000..9c317a3b8edbf2 --- /dev/null +++ b/test/integration/fixtures/documents/mixed-content-out.html @@ -0,0 +1,3 @@ + +

    Some heading

    + \ No newline at end of file