diff --git a/.eslintrc.js b/.eslintrc.js
index 6626a55a762d1..402c16ec5c80f 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -116,9 +116,15 @@ const restrictedSyntax = [
},
{
selector:
- 'CallExpression[callee.name=/^(__|_x|_n|_nx)$/] > Literal[value=/^toggle\\b/i]',
+ 'CallExpression[callee.name=/^(__|_x|_n|_nx)$/] > Literal[value=/toggle\\b/i]',
message: "Avoid using the verb 'Toggle' in translatable strings",
},
+ {
+ selector:
+ 'CallExpression[callee.name=/^(__|_x|_n|_nx)$/] > Literal[value=/(?
## What?
+
+Closes
+
## Why?
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 76d1e45e3c6ce..c469ccfd74b55 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -4,23 +4,21 @@ version: 2
updates:
# Check for updates to GitHub Actions.
- package-ecosystem: 'github-actions'
- directory: '/'
+ directories:
+ - '.github/workflows'
+ - '.github/setup-node'
schedule:
interval: 'daily'
open-pull-requests-limit: 10
labels:
- 'GitHub Actions'
- '[Type] Build Tooling'
+ ignore:
+ - dependency-name: 'actions/setup-java'
+ - dependency-name: 'gradle/*'
+ - dependency-name: 'reactivecircus/*'
+ - dependency-name: 'ruby/setup-ruby'
groups:
github-actions:
patterns:
- '*'
- exclude-patterns:
- - 'actions/setup-java'
- - 'gradle/*'
- - 'reactivecircus/*'
- react-native:
- patterns:
- - 'actions/setup-java'
- - 'gradle/*'
- - 'reactivecircus/*'
diff --git a/.github/setup-node/action.yml b/.github/setup-node/action.yml
index a17adfe5f5007..83c4123fbab93 100644
--- a/.github/setup-node/action.yml
+++ b/.github/setup-node/action.yml
@@ -10,7 +10,7 @@ runs:
using: 'composite'
steps:
- name: Use desired version of Node.js
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
+ uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with:
node-version-file: '.nvmrc'
node-version: ${{ inputs.node-version }}
@@ -25,7 +25,7 @@ runs:
- name: Cache node_modules
id: cache-node_modules
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
+ uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: '**/node_modules'
key: node_modules-${{ runner.os }}-${{ runner.arch }}-${{ steps.node-version.outputs.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}
@@ -36,7 +36,7 @@ runs:
npm ci
shell: bash
- name: Upload npm logs as an artifact on failure
- uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
+ uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
if: failure()
with:
name: npm-logs
diff --git a/.github/workflows/build-plugin-zip.yml b/.github/workflows/build-plugin-zip.yml
index 7ed57c5c5865a..281146b63f290 100644
--- a/.github/workflows/build-plugin-zip.yml
+++ b/.github/workflows/build-plugin-zip.yml
@@ -174,7 +174,7 @@ jobs:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
- name: Use desired version of Node.js
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
+ uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with:
node-version-file: '.nvmrc'
check-latest: true
@@ -336,7 +336,7 @@ jobs:
git config user.email gutenberg@wordpress.org
- name: Setup Node.js
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
+ uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with:
node-version-file: 'main/.nvmrc'
registry-url: 'https://registry.npmjs.org'
diff --git a/.github/workflows/bundle-size.yml b/.github/workflows/bundle-size.yml
index 3d95e7aa92bc1..b967157836a4d 100644
--- a/.github/workflows/bundle-size.yml
+++ b/.github/workflows/bundle-size.yml
@@ -43,7 +43,7 @@ jobs:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
- name: Use desired version of Node.js
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
+ uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with:
node-version-file: '.nvmrc'
check-latest: true
diff --git a/.github/workflows/publish-npm-packages.yml b/.github/workflows/publish-npm-packages.yml
index 11cff85f4717a..7a354ed819dfc 100644
--- a/.github/workflows/publish-npm-packages.yml
+++ b/.github/workflows/publish-npm-packages.yml
@@ -67,7 +67,7 @@ jobs:
- name: Setup Node.js
if: ${{ github.event.inputs.release_type != 'wp' }}
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
+ uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with:
node-version-file: 'cli/.nvmrc'
registry-url: 'https://registry.npmjs.org'
@@ -75,7 +75,7 @@ jobs:
- name: Setup Node.js (for WP major version)
if: ${{ github.event.inputs.release_type == 'wp' && github.event.inputs.wp_version }}
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
+ uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with:
node-version-file: 'publish/.nvmrc'
registry-url: 'https://registry.npmjs.org'
diff --git a/.github/workflows/rnmobile-ios-runner.yml b/.github/workflows/rnmobile-ios-runner.yml
index b6d796b1108ff..4d6b310e60f97 100644
--- a/.github/workflows/rnmobile-ios-runner.yml
+++ b/.github/workflows/rnmobile-ios-runner.yml
@@ -28,7 +28,7 @@ jobs:
with:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
- - uses: ruby/setup-ruby@7a6302104fbeea3c6aaa43b1b91e08f7d6623279 # v1.209.0
+ - uses: ruby/setup-ruby@1287d2b408066abada82d5ad1c63652e758428d9 # v1.214.0
with:
# `.ruby-version` file location
working-directory: packages/react-native-editor/ios
diff --git a/.github/workflows/stale-issue-gardening.yml b/.github/workflows/stale-issue-gardening.yml
index c73fe7a19b24b..6b8c7e82d1ca7 100644
--- a/.github/workflows/stale-issue-gardening.yml
+++ b/.github/workflows/stale-issue-gardening.yml
@@ -36,7 +36,7 @@ jobs:
steps:
- name: Update issues
- uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
+ uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: ${{ matrix.message }}
diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml
index baf97e8d390e9..9281158aab833 100644
--- a/.github/workflows/static-checks.yml
+++ b/.github/workflows/static-checks.yml
@@ -27,7 +27,7 @@ jobs:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
- name: Use desired version of Node.js
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
+ uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with:
node-version-file: '.nvmrc'
check-latest: true
diff --git a/.github/workflows/upload-release-to-plugin-repo.yml b/.github/workflows/upload-release-to-plugin-repo.yml
index 4d2b0a66a7e7d..7d2c780599cdd 100644
--- a/.github/workflows/upload-release-to-plugin-repo.yml
+++ b/.github/workflows/upload-release-to-plugin-repo.yml
@@ -167,6 +167,10 @@ jobs:
VERSION: ${{ github.event.release.name }}
steps:
+ - name: Install Subversion
+ run: |
+ sudo apt-get update -y && sudo apt-get install -y subversion
+
- name: Check out Gutenberg trunk from WP.org plugin repo
run: |
svn checkout "$PLUGIN_REPO_URL/trunk" --username "$SVN_USERNAME" --password "$SVN_PASSWORD"
@@ -222,6 +226,10 @@ jobs:
VERSION: ${{ github.event.release.name }}
steps:
+ - name: Install Subversion
+ run: |
+ sudo apt-get update -y && sudo apt-get install -y subversion
+
- name: Download and unzip Gutenberg plugin asset into tags folder
env:
PLUGIN_URL: ${{ github.event.release.assets[0].browser_download_url }}
diff --git a/backport-changelog/6.8/7488.md b/backport-changelog/6.8/7488.md
deleted file mode 100644
index a588bef0e0179..0000000000000
--- a/backport-changelog/6.8/7488.md
+++ /dev/null
@@ -1,3 +0,0 @@
-https://github.com/WordPress/wordpress-develop/pull/7488
-
-* https://github.com/WordPress/gutenberg/pull/60622
\ No newline at end of file
diff --git a/backport-changelog/6.8/7498.md b/backport-changelog/6.8/7498.md
deleted file mode 100644
index 6c903246166b6..0000000000000
--- a/backport-changelog/6.8/7498.md
+++ /dev/null
@@ -1,3 +0,0 @@
-https://github.com/WordPress/wordpress-develop/pull/7498
-
-* https://github.com/WordPress/gutenberg/pull/60622
\ No newline at end of file
diff --git a/backport-changelog/6.8/7903.md b/backport-changelog/6.8/7903.md
index cb20d8d2dd2b1..60703831a8e39 100644
--- a/backport-changelog/6.8/7903.md
+++ b/backport-changelog/6.8/7903.md
@@ -1,3 +1,5 @@
https://github.com/WordPress/wordpress-develop/pull/7903
* https://github.com/WordPress/gutenberg/pull/67199
+* https://github.com/WordPress/gutenberg/pull/68971
+
diff --git a/backport-changelog/6.8/8123.md b/backport-changelog/6.8/8123.md
index 7955ec7741685..bef3b35833001 100644
--- a/backport-changelog/6.8/8123.md
+++ b/backport-changelog/6.8/8123.md
@@ -2,3 +2,5 @@ https://github.com/WordPress/wordpress-develop/pull/8123
* https://github.com/WordPress/gutenberg/pull/68549
* https://github.com/WordPress/gutenberg/pull/68745
+* https://github.com/WordPress/gutenberg/pull/69160
+* https://github.com/WordPress/gutenberg/pull/69209
diff --git a/backport-changelog/6.8/8212.md b/backport-changelog/6.8/8212.md
new file mode 100644
index 0000000000000..30483af9e7b71
--- /dev/null
+++ b/backport-changelog/6.8/8212.md
@@ -0,0 +1,4 @@
+https://github.com/WordPress/wordpress-develop/pull/8212
+
+* https://github.com/WordPress/gutenberg/pull/68926
+* https://github.com/WordPress/gutenberg/pull/69142
diff --git a/backport-changelog/6.8/8228.md b/backport-changelog/6.8/8228.md
new file mode 100644
index 0000000000000..0b3774ffffa5b
--- /dev/null
+++ b/backport-changelog/6.8/8228.md
@@ -0,0 +1,3 @@
+https://github.com/WordPress/wordpress-develop/pull/8228
+
+* https://github.com/WordPress/gutenberg/pull/68970
diff --git a/backport-changelog/6.8/8245.md b/backport-changelog/6.8/8245.md
new file mode 100644
index 0000000000000..ca9bc3588c5ce
--- /dev/null
+++ b/backport-changelog/6.8/8245.md
@@ -0,0 +1,3 @@
+https://github.com/WordPress/wordpress-develop/pull/8245
+
+* https://github.com/WordPress/gutenberg/pull/68983
diff --git a/backport-changelog/6.8/8265.md b/backport-changelog/6.8/8265.md
new file mode 100644
index 0000000000000..46fa3f0181051
--- /dev/null
+++ b/backport-changelog/6.8/8265.md
@@ -0,0 +1,3 @@
+https://github.com/WordPress/wordpress-develop/pull/8265
+
+* https://github.com/WordPress/gutenberg/pull/69057
diff --git a/backport-changelog/6.8/6910.md b/backport-changelog/6.9/6910.md
similarity index 100%
rename from backport-changelog/6.8/6910.md
rename to backport-changelog/6.9/6910.md
diff --git a/bin/generate-php-sync-issue.mjs b/bin/generate-php-sync-issue.mjs
index bd627aeb65107..9ea79c4f165e9 100644
--- a/bin/generate-php-sync-issue.mjs
+++ b/bin/generate-php-sync-issue.mjs
@@ -156,17 +156,6 @@ async function main() {
fs.writeFileSync( nodePath.join( __dirname, 'issueContent.md' ), content );
}
-/**
- * Checks if the first date is after the second date.
- *
- * @param {string} date1 - The first date.
- * @param {string} date2 - The second date.
- * @return {boolean} - Returns true if the first date is after the second date, false otherwise.
- */
-function isAfter( date1, date2 ) {
- return new Date( date1 ) > new Date( date2 );
-}
-
function validateDate( sinceArg ) {
const sinceDate = new Date( sinceArg );
const maxPreviousDate = new Date();
diff --git a/changelog.txt b/changelog.txt
index fa1e1cdcb6a0c..2a1e7d62ed656 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,8 +1,344 @@
== Changelog ==
-= 20.1.0-rc.1 =
+= 20.3.0-rc.1 =
+## Changelog
+
+### Enhancements
+
+- Disable hover animation on preview frame for classic themes. ([68976](https://github.com/WordPress/gutenberg/pull/68976))
+
+#### Block Library
+- Added discord in social links. ([68848](https://github.com/WordPress/gutenberg/pull/68848))
+- Featured Image block: Use resolution tool component. ([68471](https://github.com/WordPress/gutenberg/pull/68471))
+- Query block: Add option to ignore sticky posts behavior. ([69057](https://github.com/WordPress/gutenberg/pull/69057))
+- RSS: Border & Spacing support. ([66411](https://github.com/WordPress/gutenberg/pull/66411))
+
+#### Global Styles
+- Disable Clear button if there's no shadow. ([69092](https://github.com/WordPress/gutenberg/pull/69092))
+- Duotone Settings: Add `reset` button and improve toggle rendering in FiltersPanel. ([68672](https://github.com/WordPress/gutenberg/pull/68672))
+- Shadow Panel: Add reset button. ([68981](https://github.com/WordPress/gutenberg/pull/68981))
+
+#### Post Editor
+- Editor: Add loading state to the 'PageAttributesParent' component. ([69062](https://github.com/WordPress/gutenberg/pull/69062))
+- Editor: Add loading state to the 'PostAuthorCombobox' component. ([68991](https://github.com/WordPress/gutenberg/pull/68991))
+- Editor: Display error message when loading current post fails. ([68999](https://github.com/WordPress/gutenberg/pull/68999))
+
+#### Block Editor
+- Quick Inserter: Restore pattern search and insertion. ([69028](https://github.com/WordPress/gutenberg/pull/69028))
+- Update keyboard shortcuts to use `primaryShift+backspace` for block deletion. ([69074](https://github.com/WordPress/gutenberg/pull/69074))
+
+#### Design Tools
+- Archives: Add Color Support. ([68685](https://github.com/WordPress/gutenberg/pull/68685))
+- Categories: Add Color Support. ([68686](https://github.com/WordPress/gutenberg/pull/68686))
+
+#### Components
+- ComboboxControl: Add an `isLoading` prop to show a loading spinner. ([68990](https://github.com/WordPress/gutenberg/pull/68990))
+
+
+### Bug Fixes
+
+- Exclude Iterator helpers from polyfills. ([69070](https://github.com/WordPress/gutenberg/pull/69070))
+- Fix Dependabot ignore statements. ([69144](https://github.com/WordPress/gutenberg/pull/69144))
+
+#### Block Editor
+- Block popover: Fix scrolling over. ([68075](https://github.com/WordPress/gutenberg/pull/68075))
+- Display root appender when default block is disabled. ([68951](https://github.com/WordPress/gutenberg/pull/68951))
+- Fix regression for root appender logic. ([68994](https://github.com/WordPress/gutenberg/pull/68994))
+- Inserter: Remove block default icon from no results message. ([68693](https://github.com/WordPress/gutenberg/pull/68693))
+- Rename `aspect` property to `ratio` to carry the `defaultAspect` in `AspectRatioDropdown`. ([69085](https://github.com/WordPress/gutenberg/pull/69085))
+- Writing Flow: Restore early return for no block selection in tab nav hook. ([69079](https://github.com/WordPress/gutenberg/pull/69079))
+
+#### Site Editor
+- Edit Site: Fix Fields package private APIs error. ([68964](https://github.com/WordPress/gutenberg/pull/68964))
+- Fix: Site Editor should display a 404 message. ([69009](https://github.com/WordPress/gutenberg/pull/69009))
+- Use the same editor component for all routes. ([69093](https://github.com/WordPress/gutenberg/pull/69093))
+
+#### Global Styles
+- Fix: Additional CSS button not working after back navigation. ([68954](https://github.com/WordPress/gutenberg/pull/68954))
+- Fix: Missing 'No blocks found.' message for block search in editor. ([69036](https://github.com/WordPress/gutenberg/pull/69036))
+
+#### Block Library
+- Query Block: Fix 'parents' argument validation. ([68983](https://github.com/WordPress/gutenberg/pull/68983))
+- Social Links: Fix appender size in non-iframe editor. ([68215](https://github.com/WordPress/gutenberg/pull/68215))
+
+#### REST API
+- Add support for the 'ignore_sticky_posts' argument. ([68970](https://github.com/WordPress/gutenberg/pull/68970))
+- Fix: Prevent Errors in Header Processing and Encode URLs Properly. ([67780](https://github.com/WordPress/gutenberg/pull/67780))
+
+#### Icons
+- Fix the background, arrowUpLeft, keyboardReturn and square icons. ([69076](https://github.com/WordPress/gutenberg/pull/69076))
+
+#### Font Library
+- Refactor font variant components to use useId for checkbox IDs. ([69050](https://github.com/WordPress/gutenberg/pull/69050))
+
+#### Block Directory
+- Remove block icon from InstalledBlocksPrePublishPanel. ([69046](https://github.com/WordPress/gutenberg/pull/69046))
+
+#### DataViews
+- Fixed: Empty Pattern Overlap in Pattern Title in Dataviews Table Layout. ([68997](https://github.com/WordPress/gutenberg/pull/68997))
+
+#### Media
+- Add optional chain to sizes indexing of media details in edit-site. ([68995](https://github.com/WordPress/gutenberg/pull/68995))
+
+#### CSS & Styling
+- Enabled Full height in Additional CSS. ([68993](https://github.com/WordPress/gutenberg/pull/68993))
+
+#### Block hooks
+- Fix truncation of post content. ([68926](https://github.com/WordPress/gutenberg/pull/68926))
+
+#### Interactivity API
+- iAPI Router: Fix CSS rule order in some constructed style sheets. ([68923](https://github.com/WordPress/gutenberg/pull/68923))
+
+
+### Accessibility
+
+#### Components
+- Font Size Picker: Remove Custom option from FontSizePickerSelect dropdown. ([69038](https://github.com/WordPress/gutenberg/pull/69038))
+
+#### Global Styles
+- Add missing list role to the list of blocks in the global Styles. ([69027](https://github.com/WordPress/gutenberg/pull/69027))
+
+#### Block API
+- Block support: Preserve aria-label value in comment delimiter. ([69002](https://github.com/WordPress/gutenberg/pull/69002))
+
+#### Block Editor
+- [Block Editor]: A11y - Add and Update missing reduce-motion mixing. ([68417](https://github.com/WordPress/gutenberg/pull/68417))
+
+
+### Performance
+
+#### Post Editor
+- Editor: Don't use selector shortcuts for the taxonomy queries. ([68998](https://github.com/WordPress/gutenberg/pull/68998))
+- Editor: Optimize 'PostAuthorCheck' component data selection. ([69105](https://github.com/WordPress/gutenberg/pull/69105))
+
+#### Style Book
+- Improve StyleBook resize responsiveness for Classic Theme. ([68980](https://github.com/WordPress/gutenberg/pull/68980))
+
+
+### Documentation
+
+- Added Missing Global Documentation. ([69104](https://github.com/WordPress/gutenberg/pull/69104))
+- Changed Inline Document Order. ([68992](https://github.com/WordPress/gutenberg/pull/68992))
+- wp-env: Add lifecycleScripts to the schema. ([68724](https://github.com/WordPress/gutenberg/pull/68724))
+
+
+### Code Quality
+
+- Core Data: Add type for term entity. ([69151](https://github.com/WordPress/gutenberg/pull/69151))
+- iAPI Router: Add missing changelog entry for #68923. ([68945](https://github.com/WordPress/gutenberg/pull/68945))
+
+#### Block Library
+- E2E: Add regression test for spacer block in themes without spacing units. ([68913](https://github.com/WordPress/gutenberg/pull/68913))
+- Navigation Link Block: Use stable variable for underline color styling. ([68953](https://github.com/WordPress/gutenberg/pull/68953))
+- Regenerate block fixtures. ([68982](https://github.com/WordPress/gutenberg/pull/68982))
+- Social Links: Remove redundant reduce-motion mixin. ([69000](https://github.com/WordPress/gutenberg/pull/69000))
+
+#### Site Editor
+- Fast follow: Redirections of deprecated site editor URLs. ([68971](https://github.com/WordPress/gutenberg/pull/68971))
+- Quality: Remove unused props and styles from SidebarNavigationScreen. ([68972](https://github.com/WordPress/gutenberg/pull/68972))
+
+#### Block Editor
+- Inserter: Remove unused no-results-icon styles. ([69018](https://github.com/WordPress/gutenberg/pull/69018))
+
+
+### Tools
+
+- PR Template: Suggest linking the issue. ([68924](https://github.com/WordPress/gutenberg/pull/68924))
+- Relocate changelog file for WP#6910 to 6.9 backports. ([69068](https://github.com/WordPress/gutenberg/pull/69068))
+
+#### Build Tooling
+- Fix installing svn during deploys. ([69047](https://github.com/WordPress/gutenberg/pull/69047))
+- Remove `react-native` dependabot group. ([69118](https://github.com/WordPress/gutenberg/pull/69118))
+
+#### Testing
+- e2e: Fix "add new" selector. ([69111](https://github.com/WordPress/gutenberg/pull/69111))
+
+
+### Various
+
+- Remove react-native dependabot group - Take 2. ([69122](https://github.com/WordPress/gutenberg/pull/69122))
+
+#### Plugin
+- Code Quality: Delete unused function from PHP Sync Issue generation script. ([68947](https://github.com/WordPress/gutenberg/pull/68947))
+- npm scripts: Use `node -p` instead of `echo`. ([68946](https://github.com/WordPress/gutenberg/pull/68946))
+
+
+## First-time contributors
+
+The following PRs were merged by first-time contributors:
+
+- @benazeer-ben: RSS: Border & Spacing support. ([66411](https://github.com/WordPress/gutenberg/pull/66411))
+- @grgar: Add optional chain to sizes indexing of media details in edit-site. ([68995](https://github.com/WordPress/gutenberg/pull/68995))
+- @Gulamdastgir-Momin: Added discord in social links. ([68848](https://github.com/WordPress/gutenberg/pull/68848))
+- @Juzar10: Fix: Prevent Errors in Header Processing and Encode URLs Properly. ([67780](https://github.com/WordPress/gutenberg/pull/67780))
+- @singhakanshu00: Disable hover animation on preview frame for classic themes. ([68976](https://github.com/WordPress/gutenberg/pull/68976))
+- @srtfisher: wp-env: Add lifecycleScripts to the schema. ([68724](https://github.com/WordPress/gutenberg/pull/68724))
+
+
+## Contributors
+
+The following contributors merged PRs in this release:
+
+@adamsilverstein @afercia @akasunil @benazeer-ben @carolinan @DAreRodz @desrosj @ellatrix @grgar @Gulamdastgir-Momin @himanshupathak95 @Infinite-Null @joemcgill @Juzar10 @Mamaduka @Mayank-Tripathi32 @ockham @peterwilsoncc @Rishit30G @SainathPoojary @shail-mehta @shimotmk @singhakanshu00 @srtfisher @swissspidy @t-hamano @torounit @yogeshbhutkar
+
+
+= 20.0.1 =
+
+## Changelog
+
+### Bug Fixes
+
+- iAPI Router: add missing changelog entry for [#68923](https://github.com/WordPress/gutenberg/pull/68945)
+
+
+= 20.2.0 =
+
+## Changelog
+
+### Enhancements
+
+#### Block Library
+- Details block: Add name attribute for exclusive accordion. ([56971](https://github.com/WordPress/gutenberg/pull/56971))
+- Details block: Add placeholder attribute. ([68917](https://github.com/WordPress/gutenberg/pull/68917))
+- Home Link: Enable all non-interactive formats. ([68737](https://github.com/WordPress/gutenberg/pull/68737))
+- Latest Comments: Refactor settings panel to use ToolsPanel. ([67951](https://github.com/WordPress/gutenberg/pull/67951))
+- Latest Post Block: Refactor settings panel to use ToolsPanel. ([67956](https://github.com/WordPress/gutenberg/pull/67956))
+- Read More: Refactor settings panel to use ToolsPanel. ([67925](https://github.com/WordPress/gutenberg/pull/67925))
+- Search Block: Refactoring settings panel. ([67907](https://github.com/WordPress/gutenberg/pull/67907))
+- Search Results Title Block: Add dropdown menu props to Tools Panel component. ([68763](https://github.com/WordPress/gutenberg/pull/68763))
+- Spacer: Add dropdown menu props to Tools Panel component. ([68761](https://github.com/WordPress/gutenberg/pull/68761))
+- Term List Block: Refactor settings panel to use ToolsPanel. ([67955](https://github.com/WordPress/gutenberg/pull/67955))
+
+#### Design Tools
+- Position: Refactor "Position" controls panel to use `ToolsPanel` instead of `PanelBody`. ([67967](https://github.com/WordPress/gutenberg/pull/67967))
+- Post-content block header color support. ([67783](https://github.com/WordPress/gutenberg/pull/67783))
+
+#### Block Editor
+- Improve grid visualizer resize observation. ([68842](https://github.com/WordPress/gutenberg/pull/68842))
+
+#### Style Book
+- Navigation Submenu Block: Add example preview. ([68378](https://github.com/WordPress/gutenberg/pull/68378))
+
+
+### Bug Fixes
+
+- Fix: Invalid `_doing_it_wrong()` for `experimental-link-color`. ([68408](https://github.com/WordPress/gutenberg/pull/68408))
+
+#### Block Library
+- Archives Block: Fix reset button display state. ([68757](https://github.com/WordPress/gutenberg/pull/68757))
+- Fix: Add `rel="tag"` to individual anchor links in editor markup of the post terms block. ([68722](https://github.com/WordPress/gutenberg/pull/68722))
+- Fix: Linked featured image block cannot be selected correctly. ([68775](https://github.com/WordPress/gutenberg/pull/68775))
+- Page List Block: Fix empty settings panel. ([68756](https://github.com/WordPress/gutenberg/pull/68756))
+- Post Date Block: Fix reset button display state. ([68758](https://github.com/WordPress/gutenberg/pull/68758))
+- Query Page Numbers Block: Fix reset button display state. ([68759](https://github.com/WordPress/gutenberg/pull/68759))
+- Spacer block: Fix dimension control when no spacing presets are available. ([68818](https://github.com/WordPress/gutenberg/pull/68818))
+- Spacer: Fix flex layout unit reset. ([68815](https://github.com/WordPress/gutenberg/pull/68815))
+- `Spacer`: Fix changes being marked as persistent to `undo`. ([68869](https://github.com/WordPress/gutenberg/pull/68869))
+
+#### Patterns
+- Editor: Improve conditions for displaying new page assembler. ([68852](https://github.com/WordPress/gutenberg/pull/68852))
+
+#### Style Book
+- Disable the device preview button in the header. ([68841](https://github.com/WordPress/gutenberg/pull/68841))
+
+#### Block Editor
+- Fix block color contrast checker. ([68799](https://github.com/WordPress/gutenberg/pull/68799))
+
+#### DataViews
+- Fixed Incorrect Text Position issue in Dataviews. ([68767](https://github.com/WordPress/gutenberg/pull/68767))
+
+#### Block Transforms
+- Embed: Remove aspect ratio classes when transforming into Paragraph. ([68721](https://github.com/WordPress/gutenberg/pull/68721))
+
+#### Media
+- Upload Media: Fix package dependencies. ([68718](https://github.com/WordPress/gutenberg/pull/68718))
+
+
+### Accessibility
+
+#### Block Library
+- Navigation Link: Improve accessibility by removing non-interactive tooltips. ([68628](https://github.com/WordPress/gutenberg/pull/68628))
+- Use the term menu instead of navigation in nav elements labels. ([68683](https://github.com/WordPress/gutenberg/pull/68683))
+
+#### Post Editor
+- Update text description of the "Contain text cursor inside block" preference. ([68132](https://github.com/WordPress/gutenberg/pull/68132))
+
+
+### Performance
+
+#### Block Editor
+- Fix 'isBlockVisibleInTheInserter' selector helper performance. ([68898](https://github.com/WordPress/gutenberg/pull/68898))
+
+#### Block Library
+- Paragraph: Use CSS to hide placeholders in Zoom out mode. ([68690](https://github.com/WordPress/gutenberg/pull/68690))
+
+
+### Documentation
+
+- Block Editor: Add documentation for SpacingSizesControl component. ([68581](https://github.com/WordPress/gutenberg/pull/68581))
+- Changed Inline Documentation Order. ([68879](https://github.com/WordPress/gutenberg/pull/68879))
+- Docs: Update links to HTTPS. ([68888](https://github.com/WordPress/gutenberg/pull/68888))
+- Lint: Fix broken URL reference for `stylelint` user guide configuration. ([68706](https://github.com/WordPress/gutenberg/pull/68706))
+- Updated Typo in Constants.js. ([68765](https://github.com/WordPress/gutenberg/pull/68765))
+- Used https in main-dashboard-button.md file. ([68883](https://github.com/WordPress/gutenberg/pull/68883))
+- wp-env: Add phpMyAdmin and multisite support to the documentation. ([68125](https://github.com/WordPress/gutenberg/pull/68125))
+
+
+### Code Quality
+
+- Inline Commenting: Change the PHP compat directory. ([68846](https://github.com/WordPress/gutenberg/pull/68846))
+- Fix: Remove invalid param from wp_register_style() in gutenberg_enqueue_stored_styles(). ([68409](https://github.com/WordPress/gutenberg/pull/68409))
+- Fix: setcookie() $value must be string in Gutenberg_HTTP_Signaling_Server::Handle_read_pending_messages(). ([68411](https://github.com/WordPress/gutenberg/pull/68411))
+
+#### Block Library
+- Gallery: Remove unused inline menu styles. ([68776](https://github.com/WordPress/gutenberg/pull/68776))
+- Move HTML element help messages to the block library utils. ([68708](https://github.com/WordPress/gutenberg/pull/68708))
+- Navigation Submenu: Classname trailing spaces. ([68880](https://github.com/WordPress/gutenberg/pull/68880))
+- Unify block title with a strict title case. ([51912](https://github.com/WordPress/gutenberg/pull/51912))
+- Video: Fix react component warning error. ([68762](https://github.com/WordPress/gutenberg/pull/68762))
+
+#### Post Editor
+- Editor: Children prop to accept `ReactNode`. ([68839](https://github.com/WordPress/gutenberg/pull/68839))
+- Editor: Combine selectors in the 'Header' component. ([68697](https://github.com/WordPress/gutenberg/pull/68697))
+- Editor: Standardize reduced motion handling using media queries. ([68424](https://github.com/WordPress/gutenberg/pull/68424))
+
+#### Components
+- Box Control: Add Runtime Check & Conditional Types for `presets` and `presetKey` Props. ([68385](https://github.com/WordPress/gutenberg/pull/68385))
+- Remove unnecessary `Tooltip` component from linked `button`. ([68498](https://github.com/WordPress/gutenberg/pull/68498))
+
+#### Block Editor
+- Clean up unused utils of spacing size control. ([68794](https://github.com/WordPress/gutenberg/pull/68794))
+
+#### Template Editor
+- Editor: Update post-type support key for new default rendering mode. ([68745](https://github.com/WordPress/gutenberg/pull/68745))
+
+
+### Tools
+
+#### Build Tooling
+- Fix Duplicate Entries for 19.7.0 in changelog.txt. ([68836](https://github.com/WordPress/gutenberg/pull/68836))
+- Release Workflow: Install Subversion. ([68837](https://github.com/WordPress/gutenberg/pull/68837))
+
+#### Testing
+- E2E: Fix WP Editor Meta Boxes test. ([68872](https://github.com/WordPress/gutenberg/pull/68872))
+
+#### Env
+- Add WP_ENV_MULTISITE envoriment variable. ([68792](https://github.com/WordPress/gutenberg/pull/68792))
+
+
+## Contributors
+
+The following contributors merged PRs in this release:
+
+@afercia @benazeer-ben @fabiankaegy @himanshupathak95 @im3dabasia @Infinite-Null @justlevine @karthick-murugan @Mamaduka @Mayank-Tripathi32 @SainathPoojary @shail-mehta @shimotmk @Soean @spacedmonkey @stokesman @Sukhendu2002 @t-hamano @yogeshbhutkar
+
+
+
+
+= 20.1.0 =
+
## Changelog
### Enhancements
@@ -205,6 +541,8 @@ The following contributors merged PRs in this release:
@afercia @AhmarZaidi @atachibana @benazeer-ben @carolinan @ciampo @dhananjaykuber @ellatrix @geriux @himanipanchal @himanshupathak95 @im3dabasia @Infinite-Null @jeryj @jorgefilipecosta @juanfra @justlevine @karthick-murugan @luisherranz @Mamaduka @manzoorwanijk @mirka @ramonjd @SainathPoojary @shail-mehta @shimotmk @sirreal @stokesman @Sukhendu2002 @szepeviktor @t-hamano @vipul0425 @Vrishabhsk @yogeshbhutkar
+
+
= 20.0.0 =
## Changelog
@@ -1833,298 +2171,6 @@ The following contributors merged PRs in this release:
@aaronrobertshaw @afercia @ajlende @akasunil @AKSHAT2802 @benazeer-ben @benniledl @carolinan @cbravobernal @desrosj @dhruvang21 @dougwollison @ellatrix @getdave @gigitux @gziolo @hbhalodia @himanshupathak95 @Infinite-Null @jeryj @jsnajdr @juanfra @louwie17 @Mamaduka @manzoorwanijk @matiasbenedetto @mcsf @michalczaplinski @miminari @mirka @ndiego @ntsekouras @oandregal @ockham @PARTHVATALIYA @ramonjd @SainathPoojary @SantosGuillamot @sarthaknagoshe2002 @snehapatil2001 @Soean @Sukhendu2002 @t-hamano @talldan @tellthemachines @TylerB24890 @tyxla @up1512001 @vipul0425 @yogeshbhutkar @youknowriad
-
-= 19.7.0 =
-
-## Changelog
-
-### Enhancements
-
-- Add "show template" to preview dropdown. ([66514](https://github.com/WordPress/gutenberg/pull/66514))
-- Iframe: Always enable for block themes, in core too. ([66800](https://github.com/WordPress/gutenberg/pull/66800))
-- Media Utils: Add experimental `sideloadMedia`. ([66378](https://github.com/WordPress/gutenberg/pull/66378))
-- Post fields: Clean up. ([66941](https://github.com/WordPress/gutenberg/pull/66941))
-- Post fields: Extract `title` from `edit-site` to `fields` package. ([66940](https://github.com/WordPress/gutenberg/pull/66940))
-- Post fields: Move `comment_status` from edit-site to fields package. ([66934](https://github.com/WordPress/gutenberg/pull/66934))
-- Post fields: Move `date` fields from `edit-site` to `fields` package. ([66938](https://github.com/WordPress/gutenberg/pull/66938))
-- Post fields: Move `status` from `edit-site` to `fields`. ([66937](https://github.com/WordPress/gutenberg/pull/66937))
-- Relocate “View” external link to end of editor header controls. ([66785](https://github.com/WordPress/gutenberg/pull/66785))
-
-#### Block Library
-- Added toggle control to set any image as feature image if no feature image is set for post. ([65896](https://github.com/WordPress/gutenberg/pull/65896))
-- Improve cover z-index solution. ([66249](https://github.com/WordPress/gutenberg/pull/66249))
-- Post Content: Add border and spacing support. ([66366](https://github.com/WordPress/gutenberg/pull/66366))
-- Query Loop: Use templateSlug and postType for more context. ([65820](https://github.com/WordPress/gutenberg/pull/65820))
-- Update text case of "Starter Content". ([66954](https://github.com/WordPress/gutenberg/pull/66954))
-- [Details Block]: Adds anchor support in details block. ([66734](https://github.com/WordPress/gutenberg/pull/66734))
-
-#### Components
-- Guide: Use small size button for page controls. ([66607](https://github.com/WordPress/gutenberg/pull/66607))
-- MenuItem: Add 40px size prop on Button. ([66596](https://github.com/WordPress/gutenberg/pull/66596))
-- Notice: Add appropriate size props to Buttons. ([66593](https://github.com/WordPress/gutenberg/pull/66593))
-- PaletteEdit: Add appropriate size props to Buttons. ([66590](https://github.com/WordPress/gutenberg/pull/66590))
-- Popover: Add small size prop to close button. ([66587](https://github.com/WordPress/gutenberg/pull/66587))
-
-#### Global Styles
-- Global styles revisions: Move focus and active state to list item. ([66780](https://github.com/WordPress/gutenberg/pull/66780))
-- Site editor: Integrate global styles controls and style book preview into the styles panel. ([65619](https://github.com/WordPress/gutenberg/pull/65619))
-
-#### DataViews
-- DataViews Fields API: Default getValueFromId supports nested objects. ([66890](https://github.com/WordPress/gutenberg/pull/66890))
-
-#### Block Editor
-- Inserter: Add 'Starter Content' category to the inserter. ([66819](https://github.com/WordPress/gutenberg/pull/66819))
-
-#### Zoom Out
-- Enable zoom out mode for non-iframe editor. ([66789](https://github.com/WordPress/gutenberg/pull/66789))
-
-#### Themes
-- Theme JSON Resolver: Remove theme json merge in resolve_theme_file_uris. ([66662](https://github.com/WordPress/gutenberg/pull/66662))
-
-#### Edit Mode
-- Image block: Add support for "more" dropdown for additional tools in Write mode. ([66605](https://github.com/WordPress/gutenberg/pull/66605))
-
-#### Style Book
-- Add a landing section to stylebook tabs. ([66545](https://github.com/WordPress/gutenberg/pull/66545))
-
-#### Media
-- Media Library: Expose filters dropdown for individual images, such as with the Image block. ([65965](https://github.com/WordPress/gutenberg/pull/65965))
-
-
-### Bug Fixes
-
-- Block toolbar: Restrict visible child calculation to known blocks. ([66702](https://github.com/WordPress/gutenberg/pull/66702))
-- ComplementaryArea: Fix button position. ([66677](https://github.com/WordPress/gutenberg/pull/66677))
-- Fix Paragraph appender layout shift (building on 66061). ([66779](https://github.com/WordPress/gutenberg/pull/66779))
-- Fix: Set the `fit-content` width for images that are not `.svg`. ([66643](https://github.com/WordPress/gutenberg/pull/66643))
-- Preference modal: Avoid fetching all reusable blocks when the site editor loads. ([66621](https://github.com/WordPress/gutenberg/pull/66621))
-- Revert "Set image width to `fit-content` to solve aspect ratio problems in Firefox. (#66217)". ([66804](https://github.com/WordPress/gutenberg/pull/66804))
-- Safari: Fix site editor template error. ([66647](https://github.com/WordPress/gutenberg/pull/66647))
-- Safari: Prevent focus capturing caused by flex display. ([66402](https://github.com/WordPress/gutenberg/pull/66402))
-- Select Mode: Hide tool selector in the post editor and force design mode. ([66784](https://github.com/WordPress/gutenberg/pull/66784))
-- Shadow panel: Make the delete modal text translatable. ([66712](https://github.com/WordPress/gutenberg/pull/66712))
-- Site Editor: Fix template for page-on-front option. ([66739](https://github.com/WordPress/gutenberg/pull/66739))
-- WP Scripts: Make watch mode more resilient for developer errors. ([66752](https://github.com/WordPress/gutenberg/pull/66752))
-- getDefaultTemplateId: Ensure entity configuration is loaded. ([66650](https://github.com/WordPress/gutenberg/pull/66650))
-- Comments controller: fix issue where comments are allowed when closed (https://github.com/WordPress/gutenberg/pull/66976)
-
-#### Block Library
-- Cover: Fix media library image selection. ([66782](https://github.com/WordPress/gutenberg/pull/66782))
-- Cover: Show DropZone only when dragging withing the block. ([66912](https://github.com/WordPress/gutenberg/pull/66912))
-- Media & Text: Set `.wp-block-media-text__media a` display to block. ([66915](https://github.com/WordPress/gutenberg/pull/66915))
-- Prevent duplicate post format taxonomy queries. ([66627](https://github.com/WordPress/gutenberg/pull/66627))
-- Query Loop: Check for postTypeFromContext before using it. ([66655](https://github.com/WordPress/gutenberg/pull/66655))
-- Query Loop: Remove postTypeFromContext. ([66681](https://github.com/WordPress/gutenberg/pull/66681))
-
-#### Block Editor
-- Appender: Fix initial position. ([66711](https://github.com/WordPress/gutenberg/pull/66711))
-- Appender: Fix outside canvas styles. ([66630](https://github.com/WordPress/gutenberg/pull/66630))
-- Block Inspector: Restore bottom margin for RadioControl. ([66688](https://github.com/WordPress/gutenberg/pull/66688))
-- Iframed editor: Fix relative wp-content URLs. ([66751](https://github.com/WordPress/gutenberg/pull/66751))
-
-#### Global Styles
-- Section Styles: Fix insecure properties removal for inner block types and elements. ([66896](https://github.com/WordPress/gutenberg/pull/66896))
-- Style book: Reduce margin selector specificity so that it doesn't override global block styles. ([66895](https://github.com/WordPress/gutenberg/pull/66895))
-- Theme JSON: Replace top-level background style objects on merge. ([66656](https://github.com/WordPress/gutenberg/pull/66656))
-
-#### Components
-- FormTokenField: Fix token styles. ([66640](https://github.com/WordPress/gutenberg/pull/66640))
-- Storybook: Fix DataViews action modals. ([66727](https://github.com/WordPress/gutenberg/pull/66727))
-- ToggleGroupControl: Fix active background for `zero` value. ([66855](https://github.com/WordPress/gutenberg/pull/66855))
-
-#### Post Editor
-- Disable device preview button in pattern/template part/navitation editor. ([65970](https://github.com/WordPress/gutenberg/pull/65970))
-- PostTaxonomiesFlatTermSelector: Abstract wrapper component. ([66625](https://github.com/WordPress/gutenberg/pull/66625))
-- VisualEditor: Always output has-global-padding classname when in post only mode. ([66626](https://github.com/WordPress/gutenberg/pull/66626))
-
-#### DataViews
-- Fix TypeError when duplicating uncategorized theme patterns. ([66889](https://github.com/WordPress/gutenberg/pull/66889))
-- Tweak primary field in patterns grid layout. ([66733](https://github.com/WordPress/gutenberg/pull/66733))
-
-#### Meta Boxes
-- Fix: Show Meta Boxes at the bottom of the screen regardless of the current rendering mode. ([66508](https://github.com/WordPress/gutenberg/pull/66508))
-- Hide metaboxes in Zoom Out. ([66886](https://github.com/WordPress/gutenberg/pull/66886))
-
-#### Site Editor
-- DataViews: Fix 'aria-label' for pattern preview element. ([66601](https://github.com/WordPress/gutenberg/pull/66601))
-- Site Hub: Fixed navigation redirect on mobile devices for classic themes. ([66867](https://github.com/WordPress/gutenberg/pull/66867))
-
-#### Media
-- Add `x-wav` mime type for wav files in Firefox. ([66850](https://github.com/WordPress/gutenberg/pull/66850))
-- Ensure HEIC files selectable from “Upload” button. ([66292](https://github.com/WordPress/gutenberg/pull/66292))
-
-#### Patterns
-- Fix uncategorized pattern browsing when pattern has no categories. ([66945](https://github.com/WordPress/gutenberg/pull/66945))
-
-#### Interactivity API
-- Fix property modification from inherited context two or more levels above. ([66872](https://github.com/WordPress/gutenberg/pull/66872))
-
-#### Block API
-- Process Block Type: Copy deprecation to a new object instead of mutating when stabilizing supports. ([66849](https://github.com/WordPress/gutenberg/pull/66849))
-
-#### Design Tools
-- Block Gap: Fix block spacing control for axial gap supported blocks. ([66783](https://github.com/WordPress/gutenberg/pull/66783))
-
-#### Document Settings
-- Editor: Restore the 'PluginPostStatusInfo' slot position. ([66665](https://github.com/WordPress/gutenberg/pull/66665))
-
-#### Templates API
-- Fix flash when clicking template name in the editor when a plugin registered template matches a default WP theme template. ([66359](https://github.com/WordPress/gutenberg/pull/66359))
-
-#### Block bindings
-- Fix unset array key warning in block-bindings.php. ([66337](https://github.com/WordPress/gutenberg/pull/66337))
-
-
-### Accessibility
-
-- Fix : Snackbar Notice Inconsistency. ([66405](https://github.com/WordPress/gutenberg/pull/66405))
-- Image: Add `aria-haspopup` prop write mode `more` tools menu items. ([66815](https://github.com/WordPress/gutenberg/pull/66815))
-- Site Icon Focus fix. ([66952](https://github.com/WordPress/gutenberg/pull/66952))
-
-#### Components
-- Popover: Fix missing label of the headerTitle Close button. ([66813](https://github.com/WordPress/gutenberg/pull/66813))
-
-#### Post Editor
-- Fix inconsistent sidebars close buttons sizes. ([66756](https://github.com/WordPress/gutenberg/pull/66756))
-
-#### Block Library
-- Remove unnecessary tooltip from Video block Text tracks button. ([66716](https://github.com/WordPress/gutenberg/pull/66716))
-
-#### Block Editor
-- Speak 'Block moved up/down' after using keyboard actions to move up/down. ([64966](https://github.com/WordPress/gutenberg/pull/64966))
-
-#### Patterns
-- Block Patterns List: Fix visual title and tooltip inconsistencies. ([64815](https://github.com/WordPress/gutenberg/pull/64815))
-
-
-### Performance
-
-- Inline Commenting: Avoid querying comments on editor load. ([66670](https://github.com/WordPress/gutenberg/pull/66670))
-- Patterns: Receive intermediate responses while unbound request is resolving. ([66713](https://github.com/WordPress/gutenberg/pull/66713))
-- Perf metrics: Update select and other metrics to use non-empty paragraphs. ([66762](https://github.com/WordPress/gutenberg/pull/66762))
-- Site Editor: Preload settings requests. ([66488](https://github.com/WordPress/gutenberg/pull/66488))
-- Site Editor: Speed up load by preloading home and front-page templates. ([66579](https://github.com/WordPress/gutenberg/pull/66579))
-- Site editor: Preload post if needed. ([66631](https://github.com/WordPress/gutenberg/pull/66631))
-
-#### Global Styles
-- Preload user global styles based on user caps. ([66541](https://github.com/WordPress/gutenberg/pull/66541))
-
-
-### Experiments
-
-- Add `isVisible` option to fields within DataForm. ([65826](https://github.com/WordPress/gutenberg/pull/65826))
-- DataViews: Implement `isItemClickable` and `onClickItem` props. ([66365](https://github.com/WordPress/gutenberg/pull/66365))
-
-#### DataViews
-- Quick Edit - Slug Field: Improve slug preview. ([66559](https://github.com/WordPress/gutenberg/pull/66559))
-- QuickEdit: Add password field data to the pages quick edit. ([66567](https://github.com/WordPress/gutenberg/pull/66567))
-
-
-### Documentation
-
-- Add 6.6.2 to Version in WordPress. ([66870](https://github.com/WordPress/gutenberg/pull/66870))
-- Add missing properties for DataViews/DataForm components. ([66749](https://github.com/WordPress/gutenberg/pull/66749))
-- Add section about the Fields API. ([66761](https://github.com/WordPress/gutenberg/pull/66761))
-- Block Bindings: Documentation API reference. ([66251](https://github.com/WordPress/gutenberg/pull/66251))
-- Docs: Include a note about supported licenses in WordPress packages. ([66562](https://github.com/WordPress/gutenberg/pull/66562))
-- Document `filterSortAndPaginate` & `isItemValid` utilities. ([66738](https://github.com/WordPress/gutenberg/pull/66738))
-- Feat: Storybook: Improve component organisation - Navigation Category - Issue #66275. ([66658](https://github.com/WordPress/gutenberg/pull/66658))
-- Feat: Storybook: Improve component organisation - Overlays Category - Issue #66275. ([66657](https://github.com/WordPress/gutenberg/pull/66657))
-- Feat: Storybook: Improve component organisation - Selection & Input Category - Issue #66275. ([66660](https://github.com/WordPress/gutenberg/pull/66660))
-- Feat: Storybook: Improve component organisation - Typography - Issue #66275. ([66633](https://github.com/WordPress/gutenberg/pull/66633))
-- Improve readability of DataViews documentation. ([66766](https://github.com/WordPress/gutenberg/pull/66766))
-- Move documentation for filter operators to proper place. ([66743](https://github.com/WordPress/gutenberg/pull/66743))
-- Reorganize to bootstrap DataForm API section. ([66729](https://github.com/WordPress/gutenberg/pull/66729))
-- Storybook: Improve component organisation - Actions. ([66680](https://github.com/WordPress/gutenberg/pull/66680))
-- Storybook: Log `warning()` when in dev mode. ([66568](https://github.com/WordPress/gutenberg/pull/66568))
-- Update Commands documentation with the existing contexts. ([66860](https://github.com/WordPress/gutenberg/pull/66860))
-
-
-### Code Quality
-
-- BlockPatternsList: Use the Async component. ([66744](https://github.com/WordPress/gutenberg/pull/66744))
-- Core Commands: Fix add new post URL assignment. ([66830](https://github.com/WordPress/gutenberg/pull/66830))
-- Inline Commenting: Optimize store selector and misc changes. ([66592](https://github.com/WordPress/gutenberg/pull/66592))
-- Remove unnecessary boolean assignments. ([66857](https://github.com/WordPress/gutenberg/pull/66857))
-- TypeScript: Fix and improve types for private-apis. ([66667](https://github.com/WordPress/gutenberg/pull/66667))
-
-#### Block Editor
-- Fix 'useSelect' dependencies for the 'RichText' component. ([66964](https://github.com/WordPress/gutenberg/pull/66964))
-- Fix ESLint warning for 'useBlockTypesState' hook. ([66757](https://github.com/WordPress/gutenberg/pull/66757))
-- Fix React Compiler error for 'BlockProps' util component. ([66809](https://github.com/WordPress/gutenberg/pull/66809))
-- Optimize `getVisibleElementBounds` in scrollable cases. ([66546](https://github.com/WordPress/gutenberg/pull/66546))
-- Revert: Fix unable to remove empty blocks on merge (#65262) + alternative. ([66564](https://github.com/WordPress/gutenberg/pull/66564))
-- URLInput: Fix incorrect classname for suggestions. ([66714](https://github.com/WordPress/gutenberg/pull/66714))
-
-#### Site Editor
-- Avoid using edited entity state in site editor loading hook. ([66924](https://github.com/WordPress/gutenberg/pull/66924))
-- Avoid using edited post selectors in welcome guide. ([66926](https://github.com/WordPress/gutenberg/pull/66926))
-- Edit Site: Refactor to remove usage of edited entity state. ([66922](https://github.com/WordPress/gutenberg/pull/66922))
-- Edit Site: Remove leftover 'priority-queue' dependency. ([66773](https://github.com/WordPress/gutenberg/pull/66773))
-- Remove useEditedEntityRecord hook. ([66955](https://github.com/WordPress/gutenberg/pull/66955))
-
-#### Components
-- Fix React Compiler error for 'useScrollRectIntoView'. ([66498](https://github.com/WordPress/gutenberg/pull/66498))
-- Panel: Add 40px size prop to Button. ([66589](https://github.com/WordPress/gutenberg/pull/66589))
-- Radio: Deprecate 36px default size. ([66572](https://github.com/WordPress/gutenberg/pull/66572))
-- Snackbar: Use `link` variant for action Button. ([66560](https://github.com/WordPress/gutenberg/pull/66560))
-
-#### Data Layer
-- Convert the emitter module in data package to TS. ([66669](https://github.com/WordPress/gutenberg/pull/66669))
-- Data: Rename useSelect internals to fix React Compiler violations. ([66807](https://github.com/WordPress/gutenberg/pull/66807))
-- Data: Upgrade Redux to v5.0.1. ([66966](https://github.com/WordPress/gutenberg/pull/66966))
-
-#### Post Editor
-- ESLint: Fix React Compiler violations in various commands. ([66787](https://github.com/WordPress/gutenberg/pull/66787))
-- Fix TS types for editor package. ([66754](https://github.com/WordPress/gutenberg/pull/66754))
-
-#### Zoom Out
-- Zoom-out: Move default background to the iframe component. ([66284](https://github.com/WordPress/gutenberg/pull/66284))
-
-#### Design Tools
-- Typography: Stabilize typography block supports within block processing. ([63401](https://github.com/WordPress/gutenberg/pull/63401))
-
-
-### Tools
-
-#### Testing
-- Media: Check for `wav` mime type using isset. ([66947](https://github.com/WordPress/gutenberg/pull/66947))
-
-#### Build Tooling
-- Enforce the same order of fields in `package.json` files. ([66239](https://github.com/WordPress/gutenberg/pull/66239))
-- Introduce React Scanner for component usage stats. ([65463](https://github.com/WordPress/gutenberg/pull/65463))
-
-
-### Various
-
-- Style engine: Wrap array_merge in conditionals to prevent unnecessary merging. ([66661](https://github.com/WordPress/gutenberg/pull/66661))
-
-#### Block Library
-- Update placeholder text for blocks that support drag and drop. ([66842](https://github.com/WordPress/gutenberg/pull/66842))
-- update: Add Media to Add media in cover block. ([66835](https://github.com/WordPress/gutenberg/pull/66835))
-
-
-## First-time contributors
-
-The following PRs were merged by first-time contributors:
-
-- @benharri: Fix unset array key warning in block-bindings.php. ([66337](https://github.com/WordPress/gutenberg/pull/66337))
-- @benniledl: Add 6.6.2 to Version in WordPress. ([66870](https://github.com/WordPress/gutenberg/pull/66870))
-- @Infinite-Null: Media & Text: Set `.wp-block-media-text__media a` display to block. ([66915](https://github.com/WordPress/gutenberg/pull/66915))
-- @karthick-murugan: Site Icon Focus fix. ([66952](https://github.com/WordPress/gutenberg/pull/66952))
-- @rinkalpagdar: Post Content: Add border and spacing support. ([66366](https://github.com/WordPress/gutenberg/pull/66366))
-- @yogeshbhutkar: Site Hub: Fixed navigation redirect on mobile devices for classic themes. ([66867](https://github.com/WordPress/gutenberg/pull/66867))
-
-
-## Contributors
-
-The following contributors merged PRs in this release:
-
-@aaronrobertshaw @adamsilverstein @afercia @Aljullu @amitraj2203 @andrewserong @benharri @benniledl @carolinan @cbravobernal @DAreRodz @dcalhoun @ellatrix @fabiankaegy @gigitux @gziolo @hbhalodia @Infinite-Null @jasmussen @jorgefilipecosta @jsnajdr @juanfra @karthick-murugan @kevin940726 @louwie17 @Mamaduka @manzoorwanijk @matiasbenedetto @mikachan @mirka @n2erjo00 @ntsekouras @oandregal @ramonjd @renatho @rinkalpagdar @Soean @stokesman @swissspidy @t-hamano @tellthemachines @tyxla @up1512001 @Vrishabhsk @yogeshbhutkar @youknowriad
-
-
-
-
= 19.6.4 =
- PostTaxonomiesFlatTermSelector: abstract wrapper component (#66625)
@@ -5481,7 +5527,7 @@ The following contributors merged PRs in this release:
- Fix: DataViews: Layout resets for patterns each time a new pattern category is selected. ([63711](https://github.com/WordPress/gutenberg/pull/63711))
- Fix: Inconsistent field spacing in Grid layout. ([63363](https://github.com/WordPress/gutenberg/pull/63363))
- Templates DataViews: Set the right context for the preview field. ([63488](https://github.com/WordPress/gutenberg/pull/63488))
--
+-
#### Block Editor
- Fix user patterns disabling sync filter. ([63828](https://github.com/WordPress/gutenberg/pull/63828))
- ImageURLInputUI: Make onSetLightbox and resetLightbox optional. ([63573](https://github.com/WordPress/gutenberg/pull/63573))
@@ -6364,7 +6410,7 @@ The following contributors merged PRs in this release:
The following contributors merged PRs in this release:
-@luisherranz @aaronjorbin @gziolo @westonruter @cbravobernal
+@luisherranz @aaronjorbin @gziolo @westonruter @cbravobernal
= 18.6.0 =
diff --git a/docs/contributors/code/coding-guidelines.md b/docs/contributors/code/coding-guidelines.md
index d8a5220c70ca2..e8e55921f56fa 100644
--- a/docs/contributors/code/coding-guidelines.md
+++ b/docs/contributors/code/coding-guidelines.md
@@ -607,7 +607,7 @@ Many third-party dependencies will distribute their own TypeScript typings. For
If you use a [TypeScript integration](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Editor-Support) for your editor, you can typically see that this works if the type resolves to anything other than the fallback `any` type.
-For packages which do not distribute their own TypeScript types, you are welcomed to install and use the [DefinitelyTyped](http://definitelytyped.org/) community-maintained types definitions, if one exists.
+For packages which do not distribute their own TypeScript types, you are welcomed to install and use the [DefinitelyTyped](https://definitelytyped.org/) community-maintained types definitions, if one exists.
### Generic types
diff --git a/docs/contributors/code/getting-started-with-code-contribution.md b/docs/contributors/code/getting-started-with-code-contribution.md
index df6b305f35983..9afcc3e46ca1b 100644
--- a/docs/contributors/code/getting-started-with-code-contribution.md
+++ b/docs/contributors/code/getting-started-with-code-contribution.md
@@ -104,7 +104,9 @@ You can access the Dashboard at: `http://localhost:8888/wp-admin/` using **Usern
#### Accessing the MySQL Database
-To access the MySQL database on the `wp-env` instance you will first need the connection details. To do this:
+phpMyAdmin is available by default for the Gutenberg project. You can access the MySQL Database at: `http://localhost:9000/`.
+
+If you want to access the database through another tool, you will first need the connection details. To do this:
1. In a terminal, navigate to your local Gutenberg repo.
2. Run `npm run wp-env start` - various information about the `wp-env` environment should be logged into the terminal.
diff --git a/docs/contributors/code/testing-overview.md b/docs/contributors/code/testing-overview.md
index 6afa5aed865b7..8b487c0016635 100644
--- a/docs/contributors/code/testing-overview.md
+++ b/docs/contributors/code/testing-overview.md
@@ -29,7 +29,7 @@ Assuming you've followed the [instructions](/docs/contributors/code/getting-star
npm test
```
-Linting is static code analysis used to enforce coding standards and to avoid potential errors. This project uses [ESLint](http://eslint.org/) and [TypeScript's JavaScript type-checking](https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html) to capture these issues. While the above `npm test` will execute both unit tests and code linting, code linting can be verified independently by running `npm run lint`. Some JavaScript issues can be fixed automatically by running `npm run lint:js:fix`.
+Linting is static code analysis used to enforce coding standards and to avoid potential errors. This project uses [ESLint](https://eslint.org/) and [TypeScript's JavaScript type-checking](https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html) to capture these issues. While the above `npm test` will execute both unit tests and code linting, code linting can be verified independently by running `npm run lint`. Some JavaScript issues can be fixed automatically by running `npm run lint:js:fix`.
To improve your developer workflow, you should setup an editor linting integration. See the [getting started documentation](/docs/contributors/code/getting-started-with-code-contribution.md) for additional information.
diff --git a/docs/how-to-guides/themes/global-settings-and-styles.md b/docs/how-to-guides/themes/global-settings-and-styles.md
index 205a3ee862ce6..359b36b4ad205 100644
--- a/docs/how-to-guides/themes/global-settings-and-styles.md
+++ b/docs/how-to-guides/themes/global-settings-and-styles.md
@@ -111,7 +111,7 @@ body {
## Specification
-This specification is the same for the three different origins that use this format: core, themes, and users. Themes can override core's defaults by creating a file called `theme.json`. Users, via the site editor, will also be able to override theme's or core's preferences via an user interface that is being worked on.
+This specification is the same for the three different origins that use this format: core, themes, and users. Themes can override core's defaults by creating a file called `theme.json`. Users, via the site editor, will also be able to override theme's or core's preferences via a user interface that is being worked on.
```json
{
diff --git a/docs/reference-guides/block-api/block-registration.md b/docs/reference-guides/block-api/block-registration.md
index 92be19ee48c9f..a2f9fac64f616 100644
--- a/docs/reference-guides/block-api/block-registration.md
+++ b/docs/reference-guides/block-api/block-registration.md
@@ -312,10 +312,6 @@ The key is the name of the block (`string`) to hook into, and the value is the p
}
```
-It’s crucial to emphasize that the Block Hooks feature is only designed to work with _static_ block-based templates, template parts, and patterns. For patterns, this includes those provided by the theme, from [Block Pattern Directory](https://wordpress.org/patterns/), or from calls to [`register_block_pattern`](https://developer.wordpress.org/reference/functions/register_block_pattern/).
-
-Block Hooks will not work with post content or patterns crafted by the user, such as synced patterns, or theme templates and template parts that have been modified by the user.
-
## Block collections
## `registerBlockCollection`
diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md
index 10ceb797e28c0..6a8f3255297c4 100644
--- a/docs/reference-guides/core-blocks.md
+++ b/docs/reference-guides/core-blocks.md
@@ -14,7 +14,7 @@ Display a date archive of your posts. ([Source](https://github.com/WordPress/gut
- **Name:** core/archives
- **Category:** widgets
-- **Supports:** align, interactivity (clientNavigation), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~
+- **Supports:** align, color (background, gradients, link, text), interactivity (clientNavigation), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~
- **Attributes:** displayAsDropdown, showLabel, showPostCounts, type
## Audio
@@ -78,7 +78,7 @@ Display a list of all terms of a given taxonomy. ([Source](https://github.com/Wo
- **Name:** core/categories
- **Category:** widgets
-- **Supports:** align, interactivity (clientNavigation), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~
+- **Supports:** align, color (background, gradients, link, text), interactivity (clientNavigation), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~
- **Attributes:** displayAsDropdown, label, showEmpty, showHierarchy, showLabel, showOnlyTopLevel, showPostCounts, taxonomy
## Code
@@ -255,7 +255,7 @@ Hide and show additional content. ([Source](https://github.com/WordPress/gutenbe
- **Name:** core/details
- **Category:** text
- **Supports:** align (full, wide), anchor, color (background, gradients, link, text), interactivity (clientNavigation), layout (~~allowEditing~~), spacing (blockGap, margin, padding), typography (fontSize, lineHeight), ~~html~~
-- **Attributes:** allowedBlocks, name, showContent, summary
+- **Attributes:** allowedBlocks, name, placeholder, showContent, summary
## Embed
@@ -811,7 +811,7 @@ Display entries from any RSS or Atom feed. ([Source](https://github.com/WordPres
- **Name:** core/rss
- **Category:** widgets
-- **Supports:** align, color (background, gradients, link, text), interactivity (clientNavigation), ~~html~~
+- **Supports:** align, color (background, gradients, link, text), interactivity (clientNavigation), spacing (margin, padding), ~~html~~
- **Attributes:** blockLayout, columns, displayAuthor, displayDate, displayExcerpt, excerptLength, feedURL, itemsToShow
## Search
diff --git a/docs/reference-guides/interactivity-api/README.md b/docs/reference-guides/interactivity-api/README.md
index 3a5bbb84ff159..5504f8fd19faf 100644
--- a/docs/reference-guides/interactivity-api/README.md
+++ b/docs/reference-guides/interactivity-api/README.md
@@ -113,7 +113,7 @@ Here you have some more resources to learn/read more about the Interactivity API
- [Merge announcement](https://make.wordpress.org/core/2024/02/19/merge-announcement-interactivity-api/)
- [Proposal: The Interactivity API – A better developer experience in building interactive blocks](https://make.wordpress.org/core/2023/03/30/proposal-the-interactivity-api-a-better-developer-experience-in-building-interactive-blocks/)
- [Interactivity API Discussions](https://github.com/WordPress/gutenberg/discussions/52882), especially the [showcase](https://github.com/WordPress/gutenberg/discussions/55642#discussioncomment-9667164) discussions.
-- [wpmovies.dev](http://wpmovies.dev/) demo and its [wp-movies-demo](https://github.com/WordPress/wp-movies-demo) repo
+- [wpmovies.dev](https://wpmovies.dev/) demo and its [wp-movies-demo](https://github.com/WordPress/wp-movies-demo) repo
- Examples using the Interactivity API at [block-development-examples](https://github.com/WordPress/block-development-examples):
- [`interactivity-api-block-833d15`](https://github.com/WordPress/block-development-examples/tree/trunk/plugins/interactivity-api-block-833d15)
- [`interactivity-api-countdown-3cd73e`](https://github.com/WordPress/block-development-examples/tree/trunk/plugins/interactivity-api-countdown-3cd73e)
diff --git a/docs/reference-guides/slotfills/main-dashboard-button.md b/docs/reference-guides/slotfills/main-dashboard-button.md
index b55ed50648db1..593c5c57ca297 100644
--- a/docs/reference-guides/slotfills/main-dashboard-button.md
+++ b/docs/reference-guides/slotfills/main-dashboard-button.md
@@ -33,7 +33,7 @@ registerPlugin( 'main-dashboard-button-test', {
### Change the icon and link
-This example will change the icon in the header to indicate an external link that will take the user to http://wordpress.org when clicked.
+This example will change the icon in the header to indicate an external link that will take the user to https://wordpress.org when clicked.
```js
import { registerPlugin } from '@wordpress/plugins';
@@ -45,7 +45,7 @@ import { external } from '@wordpress/icons';
const MainDashboardButtonIconTest = () => (
-
+
);
@@ -54,4 +54,4 @@ registerPlugin( 'main-dashboard-button-icon-test', {
} );
```
-
+
diff --git a/gutenberg.php b/gutenberg.php
index e3f4c81ef808f..58e04e0b9e4f5 100644
--- a/gutenberg.php
+++ b/gutenberg.php
@@ -5,7 +5,7 @@
* Description: Printing since 1440. This is the development plugin for the block editor, site editor, and other future WordPress core functionality.
* Requires at least: 6.6
* Requires PHP: 7.2
- * Version: 20.1.0-rc.1
+ * Version: 20.3.0-rc.1
* Author: Gutenberg Team
* Text Domain: gutenberg
*
diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php
index 1f45d897a77cc..ddba48f88483d 100644
--- a/lib/class-wp-theme-json-resolver-gutenberg.php
+++ b/lib/class-wp-theme-json-resolver-gutenberg.php
@@ -359,7 +359,7 @@ public static function get_theme_data( $deprecated = array(), $options = array()
}
if ( current_theme_supports( 'experimental-link-color' ) ) {
_doing_it_wrong(
- current_theme_supports( 'experimental-link-color' ),
+ "add_theme_support( 'experimental-link-color' )",
__( '`experimental-link-color` is no longer supported. Use `link-color` instead.', 'gutenberg' ),
'6.3.0'
);
diff --git a/lib/client-assets.php b/lib/client-assets.php
index f95ac27f81d01..4a94ca212c342 100644
--- a/lib/client-assets.php
+++ b/lib/client-assets.php
@@ -539,7 +539,7 @@ function gutenberg_enqueue_stored_styles( $options = array() ) {
// Combines Core styles.
if ( ! empty( $compiled_core_stylesheet ) ) {
- wp_register_style( $style_tag_id, false, array(), true, true );
+ wp_register_style( $style_tag_id, false, array(), true );
wp_add_inline_style( $style_tag_id, $compiled_core_stylesheet );
wp_enqueue_style( $style_tag_id );
}
@@ -562,7 +562,7 @@ function gutenberg_enqueue_stored_styles( $options = array() ) {
$styles = gutenberg_style_engine_get_stylesheet_from_context( $store_name, $options );
if ( ! empty( $styles ) ) {
$key = "wp-style-engine-$store_name";
- wp_register_style( $key, false, array(), true, true );
+ wp_register_style( $key, false, array(), true );
wp_add_inline_style( $key, $styles );
wp_enqueue_style( $key );
}
diff --git a/lib/compat/wordpress-6.8/blocks.php b/lib/compat/wordpress-6.8/blocks.php
index 6cfa98691020e..7fd4237bc81d3 100644
--- a/lib/compat/wordpress-6.8/blocks.php
+++ b/lib/compat/wordpress-6.8/blocks.php
@@ -5,88 +5,133 @@
* @package gutenberg
*/
-function gutenberg_apply_block_hooks_to_post_content( $content ) {
- // The `the_content` filter does not provide the post that the content is coming from.
- // However, we can infer it by calling `get_post()`, which will return the current post
- // if no post ID is provided.
- return apply_block_hooks_to_content( $content, get_post(), 'insert_hooked_blocks' );
-}
-// We need to apply this filter before `do_blocks` (which is hooked to `the_content` at priority 9).
-add_filter( 'the_content', 'gutenberg_apply_block_hooks_to_post_content', 8 );
+if ( ! function_exists( 'apply_block_hooks_to_content_from_post_object' ) ) {
+ /**
+ * Run the Block Hooks algorithm on a post object's content.
+ *
+ * This function is different from `apply_block_hooks_to_content` in that
+ * it takes ignored hooked block information from the post's metadata into
+ * account. This ensures that any blocks hooked as first or last child
+ * of the block that corresponds to the post type are handled correctly.
+ *
+ * @since 6.8.0
+ * @access private
+ *
+ * @param string $content Serialized content.
+ * @param WP_Post|null $post A post object that the content belongs to. If set to `null`,
+ * `get_post()` will be called to use the current post as context.
+ * Default: `null`.
+ * @param callable $callback A function that will be called for each block to generate
+ * the markup for a given list of blocks that are hooked to it.
+ * Default: 'insert_hooked_blocks'.
+ * @return string The serialized markup.
+ */
+ function apply_block_hooks_to_content_from_post_object( $content, WP_Post $post = null, $callback = 'insert_hooked_blocks' ) {
+ // Default to the current post if no context is provided.
+ if ( null === $post ) {
+ $post = get_post();
+ }
-/**
- * Hooks into the REST API response for the Posts endpoint and adds the first and last inner blocks.
- *
- * @since 6.6.0
- * @since 6.8.0 Support non-`wp_navigation` post types.
- *
- * @param WP_REST_Response $response The response object.
- * @param WP_Post $post Post object.
- * @return WP_REST_Response The response object.
- */
-function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) {
- if ( empty( $response->data['content']['raw'] ) ) {
- return $response;
- }
+ if ( ! $post instanceof WP_Post ) {
+ return apply_block_hooks_to_content( $content, $post, $callback );
+ }
- $attributes = array();
- $ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true );
- if ( ! empty( $ignored_hooked_blocks ) ) {
- $ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true );
- $attributes['metadata'] = array(
- 'ignoredHookedBlocks' => $ignored_hooked_blocks,
- );
- }
+ $attributes = array();
- if ( 'wp_navigation' === $post->post_type ) {
- $wrapper_block_type = 'core/navigation';
- } elseif ( 'wp_block' === $post->post_type ) {
- $wrapper_block_type = 'core/block';
- } else {
- $wrapper_block_type = 'core/post-content';
- }
+ // If context is a post object, `ignoredHookedBlocks` information is stored in its post meta.
+ $ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true );
+ if ( ! empty( $ignored_hooked_blocks ) ) {
+ $ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true );
+ $attributes['metadata'] = array(
+ 'ignoredHookedBlocks' => $ignored_hooked_blocks,
+ );
+ }
- $content = get_comment_delimited_block_content(
- $wrapper_block_type,
- $attributes,
- $response->data['content']['raw']
- );
+ // We need to wrap the content in a temporary wrapper block with that metadata
+ // so the Block Hooks algorithm can insert blocks that are hooked as first or last child
+ // of the wrapper block.
+ // To that end, we need to determine the wrapper block type based on the post type.
+ if ( 'wp_navigation' === $post->post_type ) {
+ $wrapper_block_type = 'core/navigation';
+ } elseif ( 'wp_block' === $post->post_type ) {
+ $wrapper_block_type = 'core/block';
+ } else {
+ $wrapper_block_type = 'core/post-content';
+ }
- $content = apply_block_hooks_to_content(
- $content,
- $post,
- 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata'
- );
+ $content = get_comment_delimited_block_content(
+ $wrapper_block_type,
+ $attributes,
+ $content
+ );
- // Remove mock block wrapper.
- $content = remove_serialized_parent_block( $content );
+ // Apply Block Hooks.
+ $content = apply_block_hooks_to_content( $content, $post, $callback );
- $response->data['content']['raw'] = $content;
+ // Finally, we need to remove the temporary wrapper block.
+ $content = remove_serialized_parent_block( $content );
- // If the rendered content was previously empty, we leave it like that.
- if ( empty( $response->data['content']['rendered'] ) ) {
- return $response;
+ return $content;
}
+ // We need to apply this filter before `do_blocks` (which is hooked to `the_content` at priority 9).
+ add_filter( 'the_content', 'apply_block_hooks_to_content_from_post_object', 8 );
+ // Remove apply_block_hooks_to_content filter (previously added in Core).
+ remove_filter( 'the_content', 'apply_block_hooks_to_content', 8 );
- // No need to inject hooked blocks twice.
- $priority = has_filter( 'the_content', 'apply_block_hooks_to_content' );
- if ( false !== $priority ) {
- remove_filter( 'the_content', 'apply_block_hooks_to_content', $priority );
- }
+ /**
+ * Hooks into the REST API response for the Posts endpoint and adds the first and last inner blocks.
+ *
+ * @since 6.6.0
+ * @since 6.8.0 Support non-`wp_navigation` post types.
+ *
+ * @param WP_REST_Response $response The response object.
+ * @param WP_Post $post Post object.
+ * @return WP_REST_Response The response object.
+ */
+ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) {
+ if ( empty( $response->data['content']['raw'] ) ) {
+ return $response;
+ }
+
+ $response->data['content']['raw'] = apply_block_hooks_to_content_from_post_object(
+ $response->data['content']['raw'],
+ $post,
+ 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata'
+ );
- /** This filter is documented in wp-includes/post-template.php */
- $response->data['content']['rendered'] = apply_filters( 'the_content', $content );
+ // If the rendered content was previously empty, we leave it like that.
+ if ( empty( $response->data['content']['rendered'] ) ) {
+ return $response;
+ }
+
+ // No need to inject hooked blocks twice.
+ $priority = has_filter( 'the_content', 'apply_block_hooks_to_content_from_post_object' );
+ if ( false !== $priority ) {
+ remove_filter( 'the_content', 'apply_block_hooks_to_content_from_post_object', $priority );
+ }
+
+ /** This filter is documented in wp-includes/post-template.php */
+ $response->data['content']['rendered'] = apply_filters(
+ 'the_content',
+ $response->data['content']['raw']
+ );
+
+ // Add back the filter.
+ if ( false !== $priority ) {
+ add_filter( 'the_content', 'apply_block_hooks_to_content_from_post_object', $priority );
+ }
- // Add back the filter.
- if ( false !== $priority ) {
- add_filter( 'the_content', 'apply_block_hooks_to_content', $priority );
+ return $response;
}
+ remove_filter( 'rest_prepare_page', 'insert_hooked_blocks_into_rest_response' );
+ add_filter( 'rest_prepare_page', 'gutenberg_insert_hooked_blocks_into_rest_response', 10, 2 );
+
+ remove_filter( 'rest_prepare_post', 'insert_hooked_blocks_into_rest_response' );
+ add_filter( 'rest_prepare_post', 'gutenberg_insert_hooked_blocks_into_rest_response', 10, 2 );
- return $response;
+ remove_filter( 'rest_prepare_wp_block', 'insert_hooked_blocks_into_rest_response' );
+ add_filter( 'rest_prepare_wp_block', 'gutenberg_insert_hooked_blocks_into_rest_response', 10, 2 );
}
-add_filter( 'rest_prepare_page', 'gutenberg_insert_hooked_blocks_into_rest_response', 10, 2 );
-add_filter( 'rest_prepare_post', 'gutenberg_insert_hooked_blocks_into_rest_response', 10, 2 );
-add_filter( 'rest_prepare_wp_block', 'gutenberg_insert_hooked_blocks_into_rest_response', 10, 2 );
/**
* Updates the wp_postmeta with the list of ignored hooked blocks
@@ -177,3 +222,35 @@ function gutenberg_update_ignored_hooked_blocks_postmeta( $post ) {
add_filter( 'rest_pre_insert_page', 'gutenberg_update_ignored_hooked_blocks_postmeta' );
add_filter( 'rest_pre_insert_post', 'gutenberg_update_ignored_hooked_blocks_postmeta' );
add_filter( 'rest_pre_insert_wp_block', 'gutenberg_update_ignored_hooked_blocks_postmeta' );
+
+/**
+ * Update Query `parents` argument validation for hierarchical post types.
+ * A zero is a valid parent ID for hierarchical post types. Used to display top-level items.
+ *
+ * Add new handler for `sticky` query argument.
+ *
+ * @param array $query The query vars.
+ * @param WP_Block $block Block instance.
+ * @return array The filtered query vars.
+ */
+function gutenberg_update_query_vars_from_query_block_6_8( $query, $block ) {
+ if ( ! empty( $block->context['query']['parents'] ) && is_post_type_hierarchical( $query['post_type'] ) ) {
+ $query['post_parent__in'] = array_unique( array_map( 'intval', $block->context['query']['parents'] ) );
+ }
+
+ if ( isset( $block->context['query']['sticky'] ) && ! empty( $block->context['query']['sticky'] ) ) {
+ if ( 'ignore' === $block->context['query']['sticky'] ) {
+ $sticky = get_option( 'sticky_posts' );
+
+ /**
+ * The core will set `post__not_in` because it asserts that any sticky value other than `only` is `exclude`.
+ * Let's override that while supporting any `post__not_in` values outside sticky post logic.
+ */
+ $query['post__not_in'] = array_diff( $query['post__not_in'], ! empty( $sticky ) ? $sticky : array() );
+ $query['ignore_sticky_posts'] = 1;
+ }
+ }
+
+ return $query;
+}
+add_filter( 'query_loop_block_query_vars', 'gutenberg_update_query_vars_from_query_block_6_8', 10, 2 );
diff --git a/lib/compat/wordpress-6.8/post.php b/lib/compat/wordpress-6.8/post.php
index 2477e94f7393c..344cd7e311d0f 100644
--- a/lib/compat/wordpress-6.8/post.php
+++ b/lib/compat/wordpress-6.8/post.php
@@ -4,23 +4,16 @@
* Set the default editor mode for the page post type to `template-locked`.
*
* Note: This backports into `create_initial_post_types` in WordPress Core.
- *
- * @param array $args Array of post type arguments.
- * @return array Updated array of post type arguments.
*/
-function gutenberg_update_page_editor_support( $args ) {
- if ( empty( $args['supports'] ) ) {
- return $args;
+function gutenberg_update_page_editor_support() {
+ // Avoid enabling the editor for pages when it's not supported.
+ // This is plugin specific safeguard.
+ if ( ! post_type_supports( 'page', 'editor' ) ) {
+ return;
}
- $editor_support_key = array_search( 'editor', $args['supports'], true );
- if ( false !== $editor_support_key ) {
- unset( $args['supports'][ $editor_support_key ] );
- $args['supports']['editor'] = array(
- 'default-mode' => 'template-locked',
- );
+ if ( wp_is_block_theme() && current_theme_supports( 'block-templates' ) ) {
+ add_post_type_support( 'page', 'editor', array( 'default-mode' => 'template-locked' ) );
}
-
- return $args;
}
-add_action( 'register_page_post_type_args', 'gutenberg_update_page_editor_support' );
+add_action( 'init', 'gutenberg_update_page_editor_support' );
diff --git a/lib/compat/wordpress-6.8/rest-api.php b/lib/compat/wordpress-6.8/rest-api.php
index cc3d3e89014e9..f6844184ea610 100644
--- a/lib/compat/wordpress-6.8/rest-api.php
+++ b/lib/compat/wordpress-6.8/rest-api.php
@@ -48,7 +48,6 @@ function gutenberg_add_default_template_part_areas_to_index( WP_REST_Response $r
$response->data['default_template_part_areas'] = get_allowed_block_template_part_areas();
return $response;
}
-
add_filter( 'rest_index', 'gutenberg_add_default_template_part_areas_to_index' );
/**
@@ -70,5 +69,48 @@ function gutenberg_add_default_template_types_to_index( WP_REST_Response $respon
$response->data['default_template_types'] = $indexed_template_types;
return $response;
}
-
add_filter( 'rest_index', 'gutenberg_add_default_template_types_to_index' );
+
+/**
+ * Adds `ignore_sticky` parameter to the post collection endpoint.
+ *
+ * Note: Backports into the wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php file.
+ *
+ * @param array $query_params JSON Schema-formatted collection parameters.
+ * @param WP_Post_Type $post_type Post type object.
+ * @return array
+ */
+function gutenberg_modify_post_collection_param( $query_params, WP_Post_Type $post_type ) {
+ if ( 'post' === $post_type->name && ! isset( $query_params['ignore_sticky'] ) ) {
+ $query_params['ignore_sticky'] = array(
+ 'description' => __( 'Whether to ignore sticky posts or not.' ),
+ 'type' => 'boolean',
+ 'default' => false,
+ );
+ }
+
+ return $query_params;
+}
+add_filter( 'rest_post_collection_params', 'gutenberg_modify_post_collection_param', 10, 2 );
+
+/**
+ * Modify posts query based on `ignore_sticky` parameter.
+ *
+ * Note: Backports into the wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php file.
+ *
+ * @param array $prepared_args Array of arguments for WP_User_Query.
+ * @param WP_REST_Request $request The REST API request.
+ * @return array Modified arguments
+ */
+function gutenberg_modify_post_collection_query( $args, WP_REST_Request $request ) {
+ /*
+ * Honor the original REST API `post__in` behavior. Don't prepend sticky posts
+ * when `post__in` has been specified.
+ */
+ if ( isset( $request['ignore_sticky'] ) && empty( $args['post__in'] ) ) {
+ $args['ignore_sticky_posts'] = $request['ignore_sticky'];
+ }
+
+ return $args;
+}
+add_filter( 'rest_post_query', 'gutenberg_modify_post_collection_query', 10, 2 );
diff --git a/lib/compat/wordpress-6.8/site-editor.php b/lib/compat/wordpress-6.8/site-editor.php
index 9b2575676047d..82ac118b013c1 100644
--- a/lib/compat/wordpress-6.8/site-editor.php
+++ b/lib/compat/wordpress-6.8/site-editor.php
@@ -15,6 +15,16 @@ function ( $settings ) {
}
);
+/**
+ * Maps old site editor urls to the new updated ones.
+ *
+ * @since 6.8.0
+ * @access private
+ *
+ * @global string $pagenow The filename of the current screen.
+ *
+ * @return string|false The new URL to redirect to, or false if no redirection is needed.
+ */
function gutenberg_get_site_editor_redirection() {
global $pagenow;
if ( 'site-editor.php' !== $pagenow || isset( $_REQUEST['p'] ) || ! $_SERVER['QUERY_STRING'] ) {
@@ -96,10 +106,13 @@ function gutenberg_get_site_editor_redirection() {
return add_query_arg( array( 'p' => '/' ) );
}
+/**
+ * Redirect old site editor urls to the new updated ones.
+ */
function gutenberg_redirect_site_editor_deprecated_urls() {
$redirection = gutenberg_get_site_editor_redirection();
if ( false !== $redirection ) {
- wp_redirect( $redirection, 301 );
+ wp_safe_redirect( $redirection );
exit;
}
}
diff --git a/lib/compat/wordpress-6.8/block-comments.php b/lib/experimental/block-comments.php
similarity index 85%
rename from lib/compat/wordpress-6.8/block-comments.php
rename to lib/experimental/block-comments.php
index ff9f03b69aa1c..3381882589ef6 100644
--- a/lib/compat/wordpress-6.8/block-comments.php
+++ b/lib/experimental/block-comments.php
@@ -1,6 +1,6 @@
query_vars['type'] ) && '' === $query->query_vars['type'] ) {
diff --git a/lib/compat/wordpress-6.8/class-gutenberg-rest-comment-controller-6-8.php b/lib/experimental/class-gutenberg-rest-comment-controller.php
similarity index 87%
rename from lib/compat/wordpress-6.8/class-gutenberg-rest-comment-controller-6-8.php
rename to lib/experimental/class-gutenberg-rest-comment-controller.php
index 60b45b1a63ade..8409c59503296 100644
--- a/lib/compat/wordpress-6.8/class-gutenberg-rest-comment-controller-6-8.php
+++ b/lib/experimental/class-gutenberg-rest-comment-controller.php
@@ -7,7 +7,7 @@
*/
// Create a new class that extends WP_REST_Comments_Controller
-class Gutenberg_REST_Comment_Controller_6_8 extends WP_REST_Comments_Controller {
+class Gutenberg_REST_Comment_Controller extends WP_REST_Comments_Controller {
public function create_item_permissions_check( $request ) {
if ( empty( $request['comment_type'] ) || 'comment' === $request['comment_type'] ) {
@@ -18,7 +18,7 @@ public function create_item_permissions_check( $request ) {
if ( get_option( 'comment_registration' ) ) {
return new WP_Error(
'rest_comment_login_required',
- __( 'Sorry, you must be logged in to comment.' ),
+ __( 'Sorry, you must be logged in to comment.', 'gutenberg' ),
array( 'status' => 401 )
);
}
@@ -40,7 +40,7 @@ public function create_item_permissions_check( $request ) {
if ( ! $allow_anonymous ) {
return new WP_Error(
'rest_comment_login_required',
- __( 'Sorry, you must be logged in to comment.' ),
+ __( 'Sorry, you must be logged in to comment.', 'gutenberg' ),
array( 'status' => 401 )
);
}
@@ -51,7 +51,7 @@ public function create_item_permissions_check( $request ) {
return new WP_Error(
'rest_comment_invalid_author',
/* translators: %s: Request parameter. */
- sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'author' ),
+ sprintf( __( "Sorry, you are not allowed to edit '%s' for comments.", 'gutenberg' ), 'author' ),
array( 'status' => rest_authorization_required_code() )
);
}
@@ -61,7 +61,7 @@ public function create_item_permissions_check( $request ) {
return new WP_Error(
'rest_comment_invalid_author_ip',
/* translators: %s: Request parameter. */
- sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'author_ip' ),
+ sprintf( __( "Sorry, you are not allowed to edit '%s' for comments.", 'gutenberg' ), 'author_ip' ),
array( 'status' => rest_authorization_required_code() )
);
}
@@ -71,7 +71,7 @@ public function create_item_permissions_check( $request ) {
return new WP_Error(
'rest_comment_invalid_status',
/* translators: %s: Request parameter. */
- sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'status' ),
+ sprintf( __( "Sorry, you are not allowed to edit '%s' for comments.", 'gutenberg' ), 'status' ),
array( 'status' => rest_authorization_required_code() )
);
}
@@ -79,7 +79,7 @@ public function create_item_permissions_check( $request ) {
if ( empty( $request['post'] ) ) {
return new WP_Error(
'rest_comment_invalid_post_id',
- __( 'Sorry, you are not allowed to create this comment without a post.' ),
+ __( 'Sorry, you are not allowed to create this comment without a post.', 'gutenberg' ),
array( 'status' => 403 )
);
}
@@ -89,7 +89,7 @@ public function create_item_permissions_check( $request ) {
if ( ! $post ) {
return new WP_Error(
'rest_comment_invalid_post_id',
- __( 'Sorry, you are not allowed to create this comment without a post.' ),
+ __( 'Sorry, you are not allowed to create this comment without a post.', 'gutenberg' ),
array( 'status' => 403 )
);
}
@@ -97,7 +97,7 @@ public function create_item_permissions_check( $request ) {
if ( 'trash' === $post->post_status ) {
return new WP_Error(
'rest_comment_trash_post',
- __( 'Sorry, you are not allowed to create a comment on this post.' ),
+ __( 'Sorry, you are not allowed to create a comment on this post.', 'gutenberg' ),
array( 'status' => 403 )
);
}
@@ -105,7 +105,7 @@ public function create_item_permissions_check( $request ) {
if ( ! $this->check_read_post_permission( $post, $request ) ) {
return new WP_Error(
'rest_cannot_read_post',
- __( 'Sorry, you are not allowed to read the post for this comment.' ),
+ __( 'Sorry, you are not allowed to read the post for this comment.', 'gutenberg' ),
array( 'status' => rest_authorization_required_code() )
);
}
@@ -117,7 +117,7 @@ public function create_item_permissions_check( $request ) {
add_action(
'rest_api_init',
function () {
- $controller = new Gutenberg_REST_Comment_Controller_6_8();
+ $controller = new Gutenberg_REST_Comment_Controller();
$controller->register_routes();
}
);
diff --git a/lib/experimental/navigation-theme-opt-in.php b/lib/experimental/navigation-theme-opt-in.php
index 547aa8b88ea7d..27dbabaf23448 100644
--- a/lib/experimental/navigation-theme-opt-in.php
+++ b/lib/experimental/navigation-theme-opt-in.php
@@ -29,6 +29,8 @@
*
* @see https://core.trac.wordpress.org/ticket/50544
*
+ * @global WP_Customize_Manager $wp_customize
+ *
* @param int $menu_id ID of the updated menu.
* @param int $menu_item_db_id ID of the new menu item.
* @param array $args An array of arguments used to update/add the menu item.
diff --git a/lib/experimental/sync/class-gutenberg-http-signaling-server.php b/lib/experimental/sync/class-gutenberg-http-signaling-server.php
index a41e26fdac163..3448e82a4c31d 100644
--- a/lib/experimental/sync/class-gutenberg-http-signaling-server.php
+++ b/lib/experimental/sync/class-gutenberg-http-signaling-server.php
@@ -172,7 +172,7 @@ private static function handle_read_pending_messages( $subscriber_to_messages_pa
if ( ! $fd ) {
$retries = isset( $_COOKIE['signaling_server_retries'] ) ? intval( $_COOKIE['signaling_server_retries'] ) : 0;
$secure = ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) );
- setcookie( 'signaling_server_retries', $retries + 1, time() + DAY_IN_SECONDS, SITECOOKIEPATH, '', $secure );
+ setcookie( 'signaling_server_retries', (string) ( $retries + 1 ), time() + DAY_IN_SECONDS, SITECOOKIEPATH, '', $secure );
echo 'id: ' . time() . PHP_EOL;
echo 'event: error' . PHP_EOL;
echo 'data: ' . 'Could not open required file.' . PHP_EOL . PHP_EOL;
@@ -183,7 +183,7 @@ private static function handle_read_pending_messages( $subscriber_to_messages_pa
if ( isset( $_COOKIE['signaling_server_retries'] ) ) {
$secure = ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) );
// unset the cookie using a past expiration date.
- setcookie( 'signaling_server_retries', 0, time() - DAY_IN_SECONDS, SITECOOKIEPATH, '', $secure );
+ setcookie( 'signaling_server_retries', '0', time() - DAY_IN_SECONDS, SITECOOKIEPATH, '', $secure );
}
echo 'retry: 3000' . PHP_EOL;
diff --git a/lib/load.php b/lib/load.php
index 69ba59e371884..789c9f9980e9a 100644
--- a/lib/load.php
+++ b/lib/load.php
@@ -42,8 +42,6 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/compat/wordpress-6.7/rest-api.php';
// WordPress 6.8 compat.
- require __DIR__ . '/compat/wordpress-6.8/block-comments.php';
- require __DIR__ . '/compat/wordpress-6.8/class-gutenberg-rest-comment-controller-6-8.php';
require __DIR__ . '/compat/wordpress-6.8/class-gutenberg-hierarchical-sort.php';
require __DIR__ . '/compat/wordpress-6.8/rest-api.php';
@@ -54,6 +52,12 @@ function gutenberg_is_experiment_enabled( $name ) {
require_once __DIR__ . '/experimental/rest-api.php';
require_once __DIR__ . '/experimental/kses-allowed-html.php';
+
+ // Block Comments.
+ if ( gutenberg_is_experiment_enabled( 'gutenberg-block-comment' ) ) {
+ require __DIR__ . '/experimental/block-comments.php';
+ require __DIR__ . '/experimental/class-gutenberg-rest-comment-controller.php';
+ }
}
// Experimental signaling server.
diff --git a/package-lock.json b/package-lock.json
index 56fc08877bfa0..b5bd7ed6c1b7e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "gutenberg",
- "version": "20.1.0-rc.1",
+ "version": "20.3.0-rc.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "gutenberg",
- "version": "20.1.0-rc.1",
+ "version": "20.3.0-rc.1",
"hasInstallScript": true,
"license": "GPL-2.0-or-later",
"workspaces": [
@@ -45328,9 +45328,9 @@
}
},
"node_modules/undici": {
- "version": "5.28.4",
- "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz",
- "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==",
+ "version": "5.28.5",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.5.tgz",
+ "integrity": "sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==",
"license": "MIT",
"dependencies": {
"@fastify/busboy": "^2.0.0"
@@ -48711,7 +48711,7 @@
},
"packages/a11y": {
"name": "@wordpress/a11y",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -48725,7 +48725,7 @@
},
"packages/annotations": {
"name": "@wordpress/annotations",
- "version": "3.16.0",
+ "version": "3.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -48753,7 +48753,7 @@
},
"packages/api-fetch": {
"name": "@wordpress/api-fetch",
- "version": "7.16.0",
+ "version": "7.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -48767,7 +48767,7 @@
},
"packages/autop": {
"name": "@wordpress/autop",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@@ -48779,7 +48779,7 @@
},
"packages/babel-plugin-import-jsx-pragma": {
"name": "@wordpress/babel-plugin-import-jsx-pragma",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"engines": {
"node": ">=18.12.0",
@@ -48791,7 +48791,7 @@
},
"packages/babel-plugin-makepot": {
"name": "@wordpress/babel-plugin-makepot",
- "version": "6.16.0",
+ "version": "6.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"deepmerge": "^4.3.0",
@@ -48808,7 +48808,7 @@
},
"packages/babel-preset-default": {
"name": "@wordpress/babel-preset-default",
- "version": "8.16.0",
+ "version": "8.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/core": "7.25.7",
@@ -49939,7 +49939,7 @@
},
"packages/base-styles": {
"name": "@wordpress/base-styles",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"engines": {
"node": ">=18.12.0",
@@ -49948,7 +49948,7 @@
},
"packages/blob": {
"name": "@wordpress/blob",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@@ -49960,7 +49960,7 @@
},
"packages/block-directory": {
"name": "@wordpress/block-directory",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -49996,7 +49996,7 @@
},
"packages/block-editor": {
"name": "@wordpress/block-editor",
- "version": "14.11.0",
+ "version": "14.13.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -50097,7 +50097,7 @@
},
"packages/block-library": {
"name": "@wordpress/block-library",
- "version": "9.16.0",
+ "version": "9.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -50163,7 +50163,7 @@
},
"packages/block-serialization-default-parser": {
"name": "@wordpress/block-serialization-default-parser",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@@ -50175,7 +50175,7 @@
},
"packages/block-serialization-spec-parser": {
"name": "@wordpress/block-serialization-spec-parser",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"pegjs": "^0.10.0",
@@ -50188,7 +50188,7 @@
},
"packages/blocks": {
"name": "@wordpress/blocks",
- "version": "14.5.0",
+ "version": "14.7.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -50242,7 +50242,7 @@
},
"packages/browserslist-config": {
"name": "@wordpress/browserslist-config",
- "version": "6.16.0",
+ "version": "6.18.0",
"license": "GPL-2.0-or-later",
"engines": {
"node": ">=18.12.0",
@@ -50251,7 +50251,7 @@
},
"packages/commands": {
"name": "@wordpress/commands",
- "version": "1.16.0",
+ "version": "1.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -50490,7 +50490,7 @@
},
"packages/components": {
"name": "@wordpress/components",
- "version": "29.2.0",
+ "version": "29.4.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@ariakit/react": "^0.4.15",
@@ -50581,7 +50581,7 @@
},
"packages/compose": {
"name": "@wordpress/compose",
- "version": "7.16.0",
+ "version": "7.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -50618,7 +50618,7 @@
},
"packages/core-commands": {
"name": "@wordpress/core-commands",
- "version": "1.16.0",
+ "version": "1.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -50647,7 +50647,7 @@
},
"packages/core-data": {
"name": "@wordpress/core-data",
- "version": "7.16.0",
+ "version": "7.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -50692,7 +50692,7 @@
},
"packages/create-block": {
"name": "@wordpress/create-block",
- "version": "4.59.0",
+ "version": "4.61.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@inquirer/prompts": "^7.2.0",
@@ -50719,7 +50719,7 @@
},
"packages/create-block-interactive-template": {
"name": "@wordpress/create-block-interactive-template",
- "version": "2.16.0",
+ "version": "2.18.0",
"license": "GPL-2.0-or-later",
"engines": {
"node": ">=18.12.0",
@@ -50728,7 +50728,7 @@
},
"packages/create-block-tutorial-template": {
"name": "@wordpress/create-block-tutorial-template",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"engines": {
"node": ">=18.12.0",
@@ -50737,7 +50737,7 @@
},
"packages/customize-widgets": {
"name": "@wordpress/customize-widgets",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -50775,7 +50775,7 @@
},
"packages/data": {
"name": "@wordpress/data",
- "version": "10.16.0",
+ "version": "10.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -50804,7 +50804,7 @@
},
"packages/data-controls": {
"name": "@wordpress/data-controls",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -50822,7 +50822,7 @@
},
"packages/dataviews": {
"name": "@wordpress/dataviews",
- "version": "4.12.0",
+ "version": "4.14.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@ariakit/react": "^0.4.15",
@@ -50849,7 +50849,7 @@
},
"packages/date": {
"name": "@wordpress/date",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -50864,7 +50864,7 @@
},
"packages/dependency-extraction-webpack-plugin": {
"name": "@wordpress/dependency-extraction-webpack-plugin",
- "version": "6.16.0",
+ "version": "6.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"json2php": "^0.0.7"
@@ -50879,7 +50879,7 @@
},
"packages/deprecated": {
"name": "@wordpress/deprecated",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -50892,7 +50892,7 @@
},
"packages/docgen": {
"name": "@wordpress/docgen",
- "version": "2.16.0",
+ "version": "2.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/core": "7.25.7",
@@ -50913,7 +50913,7 @@
},
"packages/dom": {
"name": "@wordpress/dom",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -50926,7 +50926,7 @@
},
"packages/dom-ready": {
"name": "@wordpress/dom-ready",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@@ -50938,7 +50938,7 @@
},
"packages/e2e-test-utils": {
"name": "@wordpress/e2e-test-utils",
- "version": "11.16.0",
+ "version": "11.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -50960,7 +50960,7 @@
},
"packages/e2e-test-utils-playwright": {
"name": "@wordpress/e2e-test-utils-playwright",
- "version": "1.16.0",
+ "version": "1.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"change-case": "^4.1.2",
@@ -50986,7 +50986,7 @@
},
"packages/e2e-tests": {
"name": "@wordpress/e2e-tests",
- "version": "8.16.0",
+ "version": "8.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@wordpress/e2e-test-utils": "file:../e2e-test-utils",
@@ -51024,7 +51024,7 @@
},
"packages/edit-post": {
"name": "@wordpress/edit-post",
- "version": "8.16.0",
+ "version": "8.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51071,7 +51071,7 @@
},
"packages/edit-site": {
"name": "@wordpress/edit-site",
- "version": "6.16.0",
+ "version": "6.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51134,7 +51134,7 @@
},
"packages/edit-widgets": {
"name": "@wordpress/edit-widgets",
- "version": "6.16.0",
+ "version": "6.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51177,7 +51177,7 @@
},
"packages/editor": {
"name": "@wordpress/editor",
- "version": "14.16.0",
+ "version": "14.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51239,7 +51239,7 @@
},
"packages/element": {
"name": "@wordpress/element",
- "version": "6.16.0",
+ "version": "6.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51258,7 +51258,7 @@
},
"packages/env": {
"name": "@wordpress/env",
- "version": "10.16.0",
+ "version": "10.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@inquirer/prompts": "^7.2.0",
@@ -51307,7 +51307,7 @@
},
"packages/escape-html": {
"name": "@wordpress/escape-html",
- "version": "3.16.0",
+ "version": "3.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@@ -51319,7 +51319,7 @@
},
"packages/eslint-plugin": {
"name": "@wordpress/eslint-plugin",
- "version": "22.2.0",
+ "version": "22.4.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/eslint-parser": "7.25.7",
@@ -51388,7 +51388,7 @@
},
"packages/fields": {
"name": "@wordpress/fields",
- "version": "0.8.0",
+ "version": "0.10.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51430,7 +51430,7 @@
},
"packages/format-library": {
"name": "@wordpress/format-library",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51458,7 +51458,7 @@
},
"packages/hooks": {
"name": "@wordpress/hooks",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@@ -51470,7 +51470,7 @@
},
"packages/html-entities": {
"name": "@wordpress/html-entities",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@@ -51482,7 +51482,7 @@
},
"packages/i18n": {
"name": "@wordpress/i18n",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51502,7 +51502,7 @@
},
"packages/icons": {
"name": "@wordpress/icons",
- "version": "10.16.0",
+ "version": "10.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51516,7 +51516,7 @@
},
"packages/interactivity": {
"name": "@wordpress/interactivity",
- "version": "6.16.0",
+ "version": "6.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@preact/signals": "^1.3.0",
@@ -51529,7 +51529,7 @@
},
"packages/interactivity-router": {
"name": "@wordpress/interactivity-router",
- "version": "2.16.0",
+ "version": "2.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@wordpress/a11y": "file:../a11y",
@@ -51542,7 +51542,7 @@
},
"packages/interface": {
"name": "@wordpress/interface",
- "version": "9.1.0",
+ "version": "9.3.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51570,7 +51570,7 @@
},
"packages/is-shallow-equal": {
"name": "@wordpress/is-shallow-equal",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@@ -51582,7 +51582,7 @@
},
"packages/jest-console": {
"name": "@wordpress/jest-console",
- "version": "8.16.0",
+ "version": "8.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51598,7 +51598,7 @@
},
"packages/jest-preset-default": {
"name": "@wordpress/jest-preset-default",
- "version": "12.16.0",
+ "version": "12.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@wordpress/jest-console": "file:../jest-console",
@@ -51615,7 +51615,7 @@
},
"packages/jest-puppeteer-axe": {
"name": "@wordpress/jest-puppeteer-axe",
- "version": "7.16.0",
+ "version": "7.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@axe-core/puppeteer": "^4.0.0",
@@ -51637,7 +51637,7 @@
},
"packages/keyboard-shortcuts": {
"name": "@wordpress/keyboard-shortcuts",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51655,7 +51655,7 @@
},
"packages/keycodes": {
"name": "@wordpress/keycodes",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51668,7 +51668,7 @@
},
"packages/lazy-import": {
"name": "@wordpress/lazy-import",
- "version": "2.16.0",
+ "version": "2.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"execa": "^4.0.2",
@@ -51682,7 +51682,7 @@
},
"packages/list-reusable-blocks": {
"name": "@wordpress/list-reusable-blocks",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51705,7 +51705,7 @@
},
"packages/media-utils": {
"name": "@wordpress/media-utils",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51722,7 +51722,7 @@
},
"packages/notices": {
"name": "@wordpress/notices",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51739,7 +51739,7 @@
},
"packages/npm-package-json-lint-config": {
"name": "@wordpress/npm-package-json-lint-config",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"engines": {
"node": ">=18.12.0",
@@ -51751,7 +51751,7 @@
},
"packages/nux": {
"name": "@wordpress/nux",
- "version": "9.16.0",
+ "version": "9.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51774,7 +51774,7 @@
},
"packages/patterns": {
"name": "@wordpress/patterns",
- "version": "2.16.0",
+ "version": "2.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51804,7 +51804,7 @@
},
"packages/plugins": {
"name": "@wordpress/plugins",
- "version": "7.16.0",
+ "version": "7.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51828,7 +51828,7 @@
},
"packages/postcss-plugins-preset": {
"name": "@wordpress/postcss-plugins-preset",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@wordpress/base-styles": "file:../base-styles",
@@ -51897,7 +51897,7 @@
},
"packages/postcss-themes": {
"name": "@wordpress/postcss-themes",
- "version": "6.16.0",
+ "version": "6.18.0",
"license": "GPL-2.0-or-later",
"engines": {
"node": ">=18.12.0",
@@ -51909,7 +51909,7 @@
},
"packages/preferences": {
"name": "@wordpress/preferences",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51935,7 +51935,7 @@
},
"packages/preferences-persistence": {
"name": "@wordpress/preferences-persistence",
- "version": "2.16.0",
+ "version": "2.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51948,7 +51948,7 @@
},
"packages/prettier-config": {
"name": "@wordpress/prettier-config",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"engines": {
"node": ">=18.12.0",
@@ -51960,7 +51960,7 @@
},
"packages/primitives": {
"name": "@wordpress/primitives",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51977,7 +51977,7 @@
},
"packages/priority-queue": {
"name": "@wordpress/priority-queue",
- "version": "3.16.0",
+ "version": "3.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -51990,7 +51990,7 @@
},
"packages/private-apis": {
"name": "@wordpress/private-apis",
- "version": "1.16.0",
+ "version": "1.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@@ -52002,7 +52002,7 @@
},
"packages/project-management-automation": {
"name": "@wordpress/project-management-automation",
- "version": "2.16.0",
+ "version": "2.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@actions/core": "1.9.1",
@@ -52030,7 +52030,7 @@
},
"packages/react-i18n": {
"name": "@wordpress/react-i18n",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -52186,7 +52186,7 @@
},
"packages/readable-js-assets-webpack-plugin": {
"name": "@wordpress/readable-js-assets-webpack-plugin",
- "version": "3.16.0",
+ "version": "3.18.0",
"license": "GPL-2.0-or-later",
"engines": {
"node": ">=18.12.0",
@@ -52198,7 +52198,7 @@
},
"packages/redux-routine": {
"name": "@wordpress/redux-routine",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -52241,7 +52241,7 @@
},
"packages/reusable-blocks": {
"name": "@wordpress/reusable-blocks",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -52268,7 +52268,7 @@
},
"packages/rich-text": {
"name": "@wordpress/rich-text",
- "version": "7.16.0",
+ "version": "7.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -52292,7 +52292,7 @@
},
"packages/router": {
"name": "@wordpress/router",
- "version": "1.16.0",
+ "version": "1.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -52313,7 +52313,7 @@
},
"packages/scripts": {
"name": "@wordpress/scripts",
- "version": "30.9.0",
+ "version": "30.11.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/core": "7.25.7",
@@ -52451,7 +52451,7 @@
},
"packages/server-side-render": {
"name": "@wordpress/server-side-render",
- "version": "5.16.0",
+ "version": "5.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -52477,7 +52477,7 @@
},
"packages/shortcode": {
"name": "@wordpress/shortcode",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -52490,7 +52490,7 @@
},
"packages/style-engine": {
"name": "@wordpress/style-engine",
- "version": "2.16.0",
+ "version": "2.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -52503,7 +52503,7 @@
},
"packages/stylelint-config": {
"name": "@wordpress/stylelint-config",
- "version": "23.8.0",
+ "version": "23.10.0",
"license": "MIT",
"dependencies": {
"@stylistic/stylelint-plugin": "^3.0.1",
@@ -52614,7 +52614,7 @@
},
"packages/sync": {
"name": "@wordpress/sync",
- "version": "1.16.0",
+ "version": "1.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -52635,7 +52635,7 @@
},
"packages/token-list": {
"name": "@wordpress/token-list",
- "version": "3.16.0",
+ "version": "3.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
@@ -52647,7 +52647,7 @@
},
"packages/undo-manager": {
"name": "@wordpress/undo-manager",
- "version": "1.16.0",
+ "version": "1.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -52660,7 +52660,7 @@
},
"packages/upload-media": {
"name": "@wordpress/upload-media",
- "version": "0.1.0",
+ "version": "0.3.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -52687,7 +52687,7 @@
},
"packages/url": {
"name": "@wordpress/url",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -52700,7 +52700,7 @@
},
"packages/viewport": {
"name": "@wordpress/viewport",
- "version": "6.16.0",
+ "version": "6.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -52730,7 +52730,7 @@
},
"packages/warning": {
"name": "@wordpress/warning",
- "version": "3.16.0",
+ "version": "3.18.0",
"license": "GPL-2.0-or-later",
"engines": {
"node": ">=18.12.0",
@@ -52739,7 +52739,7 @@
},
"packages/widgets": {
"name": "@wordpress/widgets",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7",
@@ -52767,7 +52767,7 @@
},
"packages/wordcount": {
"name": "@wordpress/wordcount",
- "version": "4.16.0",
+ "version": "4.18.0",
"license": "GPL-2.0-or-later",
"dependencies": {
"@babel/runtime": "7.25.7"
diff --git a/package.json b/package.json
index 1dbf7d44df405..5459c72eb1472 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "gutenberg",
- "version": "20.1.0-rc.1",
+ "version": "20.3.0-rc.1",
"private": true,
"description": "A new WordPress editor experience.",
"author": "The WordPress Contributors",
@@ -181,7 +181,7 @@
"build": "npm run build:packages && wp-scripts build",
"build:analyze-bundles": "npm run build -- --webpack-bundle-analyzer",
"build:package-types": "node ./bin/packages/validate-typescript-version.js && ( tsc --build || ( echo 'tsc failed. Try cleaning up first: `npm run clean:package-types`'; exit 1 ) ) && node ./bin/packages/check-build-type-declaration-files.js",
- "build:profile-types": "rimraf ./ts-traces && npm run clean:package-types && node ./bin/packages/validate-typescript-version.js && ( tsc --build --extendedDiagnostics --generateTrace ./ts-traces || ( echo 'tsc failed.'; exit 1 ) ) && node ./bin/packages/check-build-type-declaration-files.js && npx --yes @typescript/analyze-trace ts-traces > ts-traces/analysis.txt && echo $'\n\nDone! Build traces saved to ts-traces/ directory.\nTrace analysis saved to ts-traces/analysis.txt.'",
+ "build:profile-types": "rimraf ./ts-traces && npm run clean:package-types && node ./bin/packages/validate-typescript-version.js && ( tsc --build --extendedDiagnostics --generateTrace ./ts-traces || ( echo 'tsc failed.'; exit 1 ) ) && node ./bin/packages/check-build-type-declaration-files.js && npx --yes @typescript/analyze-trace ts-traces > ts-traces/analysis.txt && node -p \"'\\n\\nDone! Build traces saved to ts-traces/ directory.\\nTrace analysis saved to ts-traces/analysis.txt.'\"",
"prebuild:packages": "npm run clean:packages && npm run --if-present --workspaces build",
"build:packages": "npm run --silent build:package-types && node ./bin/packages/build.js",
"postbuild:packages": " npm run --if-present --workspaces build:wp",
diff --git a/packages/README.md b/packages/README.md
index 79f07af29382c..9a3d077ba671b 100644
--- a/packages/README.md
+++ b/packages/README.md
@@ -214,7 +214,7 @@ If you are publishing new versions of packages, note that there are versioning r
## TypeScript
-The [TypeScript](http://www.typescriptlang.org/) language is a typed superset of JavaScript that compiles to plain JavaScript.
+The [TypeScript](https://www.typescriptlang.org/) language is a typed superset of JavaScript that compiles to plain JavaScript.
Gutenberg does not use the TypeScript language, however TypeScript has powerful tooling that can be applied to JavaScript projects.
Gutenberg uses TypeScript for several reasons, including:
diff --git a/packages/a11y/CHANGELOG.md b/packages/a11y/CHANGELOG.md
index 036d332c5a0b0..fd74179d52ace 100644
--- a/packages/a11y/CHANGELOG.md
+++ b/packages/a11y/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 4.18.0 (2025-02-12)
+
+## 4.17.0 (2025-01-29)
+
## 4.16.0 (2025-01-15)
## 4.15.0 (2025-01-02)
diff --git a/packages/a11y/package.json b/packages/a11y/package.json
index 8bc6e23a46126..bd38351dc08c7 100644
--- a/packages/a11y/package.json
+++ b/packages/a11y/package.json
@@ -1,6 +1,6 @@
{
"name": "@wordpress/a11y",
- "version": "4.16.0",
+ "version": "4.18.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 6b3bc3564d58d..4bd66ad29cc8c 100644
--- a/packages/annotations/CHANGELOG.md
+++ b/packages/annotations/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 3.18.0 (2025-02-12)
+
+## 3.17.0 (2025-01-29)
+
## 3.16.0 (2025-01-15)
## 3.15.0 (2025-01-02)
diff --git a/packages/annotations/package.json b/packages/annotations/package.json
index a426bfa3d6ef7..f36523a6a6d69 100644
--- a/packages/annotations/package.json
+++ b/packages/annotations/package.json
@@ -1,6 +1,6 @@
{
"name": "@wordpress/annotations",
- "version": "3.16.0",
+ "version": "3.18.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 47cfb75849ce9..addb72db662c7 100644
--- a/packages/api-fetch/CHANGELOG.md
+++ b/packages/api-fetch/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 7.18.0 (2025-02-12)
+
+## 7.17.0 (2025-01-29)
+
## 7.16.0 (2025-01-15)
## 7.15.0 (2025-01-02)
diff --git a/packages/api-fetch/package.json b/packages/api-fetch/package.json
index 44e5968e0b1b4..8c6d91542dbd0 100644
--- a/packages/api-fetch/package.json
+++ b/packages/api-fetch/package.json
@@ -1,6 +1,6 @@
{
"name": "@wordpress/api-fetch",
- "version": "7.16.0",
+ "version": "7.18.0",
"description": "Utility to make WordPress REST API requests.",
"author": "The WordPress Contributors",
"license": "GPL-2.0-or-later",
diff --git a/packages/api-fetch/src/middlewares/preloading.js b/packages/api-fetch/src/middlewares/preloading.js
index ac293738513bd..3eaab48dc8392 100644
--- a/packages/api-fetch/src/middlewares/preloading.js
+++ b/packages/api-fetch/src/middlewares/preloading.js
@@ -68,15 +68,40 @@ function createPreloadingMiddleware( preloadedData ) {
* @return {Promise} Promise with the response.
*/
function prepareResponse( responseData, parse ) {
- return Promise.resolve(
- parse
- ? responseData.body
- : new window.Response( JSON.stringify( responseData.body ), {
- status: 200,
- statusText: 'OK',
- headers: responseData.headers,
- } )
- );
+ if ( parse ) {
+ return Promise.resolve( responseData.body );
+ }
+
+ try {
+ return Promise.resolve(
+ new window.Response( JSON.stringify( responseData.body ), {
+ status: 200,
+ statusText: 'OK',
+ headers: responseData.headers,
+ } )
+ );
+ } catch {
+ // See: https://github.com/WordPress/gutenberg/issues/67358#issuecomment-2621163926.
+ Object.entries( responseData.headers ).forEach( ( [ key, value ] ) => {
+ if ( key.toLowerCase() === 'link' ) {
+ responseData.headers[ key ] = value.replace(
+ /<([^>]+)>/,
+ ( /** @type {any} */ _, /** @type {string} */ url ) =>
+ `<${ encodeURI( url ) }>`
+ );
+ }
+ } );
+
+ return Promise.resolve(
+ parse
+ ? responseData.body
+ : new window.Response( JSON.stringify( responseData.body ), {
+ status: 200,
+ statusText: 'OK',
+ headers: responseData.headers,
+ } )
+ );
+ }
}
export default createPreloadingMiddleware;
diff --git a/packages/api-fetch/src/middlewares/test/preloading.js b/packages/api-fetch/src/middlewares/test/preloading.js
index 696d8a3764865..a3ffedbdef46d 100644
--- a/packages/api-fetch/src/middlewares/test/preloading.js
+++ b/packages/api-fetch/src/middlewares/test/preloading.js
@@ -265,6 +265,57 @@ describe( 'Preloading Middleware', () => {
expect( secondMiddleware ).toHaveBeenCalledTimes( 1 );
} );
+ it( 'should not throw an error when non-ASCII headers are present', async () => {
+ const noResponseMock = 'undefined' === typeof window.Response;
+ if ( noResponseMock ) {
+ window.Response = class {
+ constructor( body, options ) {
+ this.body = JSON.parse( body );
+ this.headers = options.headers;
+
+ // Check for non-ASCII characters in headers
+ for ( const [ key, value ] of Object.entries(
+ this.headers || {}
+ ) ) {
+ if ( /[^\x00-\x7F]/.test( value ) ) {
+ throw new Error(
+ `Invalid non-ASCII character found in header: ${ key }`
+ );
+ }
+ }
+ }
+ };
+ }
+
+ const data = {
+ body: 'Hello',
+ headers: {
+ Link: '; rel="alternate"; type=text/html',
+ },
+ };
+
+ const preloadedData = {
+ 'wp/v2/example': data,
+ };
+
+ const preloadingMiddleware =
+ createPreloadingMiddleware( preloadedData );
+
+ const requestOptions = {
+ method: 'GET',
+ path: 'wp/v2/example',
+ parse: false,
+ };
+
+ await expect(
+ preloadingMiddleware( requestOptions, () => {} )
+ ).resolves.not.toThrow();
+
+ if ( noResponseMock ) {
+ delete window.Response;
+ }
+ } );
+
describe.each( [ [ 'GET' ], [ 'OPTIONS' ] ] )( '%s', ( method ) => {
describe.each( [
[ 'all empty', {} ],
diff --git a/packages/autop/CHANGELOG.md b/packages/autop/CHANGELOG.md
index 9b73fe7ecaaea..8daf97afc88e2 100644
--- a/packages/autop/CHANGELOG.md
+++ b/packages/autop/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 4.18.0 (2025-02-12)
+
+## 4.17.0 (2025-01-29)
+
## 4.16.0 (2025-01-15)
## 4.15.0 (2025-01-02)
diff --git a/packages/autop/package.json b/packages/autop/package.json
index b334be020f6f9..aa29e8c277da4 100644
--- a/packages/autop/package.json
+++ b/packages/autop/package.json
@@ -1,6 +1,6 @@
{
"name": "@wordpress/autop",
- "version": "4.16.0",
+ "version": "4.18.0",
"description": "WordPress's automatic paragraph functions `autop` and `removep`.",
"author": "The WordPress Contributors",
"license": "GPL-2.0-or-later",
diff --git a/packages/babel-plugin-import-jsx-pragma/CHANGELOG.md b/packages/babel-plugin-import-jsx-pragma/CHANGELOG.md
index 1c4e5fa416687..9a8440fe6c493 100644
--- a/packages/babel-plugin-import-jsx-pragma/CHANGELOG.md
+++ b/packages/babel-plugin-import-jsx-pragma/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 5.18.0 (2025-02-12)
+
+## 5.17.0 (2025-01-29)
+
## 5.16.0 (2025-01-15)
## 5.15.0 (2025-01-02)
diff --git a/packages/babel-plugin-import-jsx-pragma/README.md b/packages/babel-plugin-import-jsx-pragma/README.md
index ebc260277b21a..7c8ad8c6ac316 100644
--- a/packages/babel-plugin-import-jsx-pragma/README.md
+++ b/packages/babel-plugin-import-jsx-pragma/README.md
@@ -1,6 +1,6 @@
# Babel Plugin Import JSX Pragma
-Babel transform plugin for automatically injecting an import to be used as the pragma for the [React JSX Transform plugin](http://babeljs.io/docs/en/babel-plugin-transform-react-jsx).
+Babel transform plugin for automatically injecting an import to be used as the pragma for the [React JSX Transform plugin](https://babeljs.io/docs/babel-plugin-transform-react-jsx).
[JSX](https://reactjs.org/docs/jsx-in-depth.html) is merely a syntactic sugar for a function call, typically to `React.createElement` when used with [React](https://reactjs.org/). As such, it requires that the function referenced by this transform be within the scope of the file where the JSX occurs. In a typical React project, this means React must be imported in any file where JSX exists.
@@ -18,9 +18,9 @@ npm install @wordpress/babel-plugin-import-jsx-pragma
## Usage
-Refer to the [Babel Plugins documentation](http://babeljs.io/docs/en/plugins) if you don't yet have experience working with Babel plugins.
+Refer to the [Babel Plugins documentation](https://babeljs.io/docs/plugins) if you don't yet have experience working with Babel plugins.
-Include `@wordpress/babel-plugin-import-jsx-pragma` (and [@babel/plugin-transform-react-jsx](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx/)) as plugins in your Babel configuration. If you don't include both you will receive errors when encountering JSX tokens.
+Include `@wordpress/babel-plugin-import-jsx-pragma` (and [@babel/plugin-transform-react-jsx](https://babeljs.io/docs/babel-plugin-transform-react-jsx/)) as plugins in your Babel configuration. If you don't include both you will receive errors when encountering JSX tokens.
```js
// .babelrc.js
diff --git a/packages/babel-plugin-import-jsx-pragma/package.json b/packages/babel-plugin-import-jsx-pragma/package.json
index f27d527c84c69..0752261edc577 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.16.0",
+ "version": "5.18.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 73b357e78768d..ce3b825fd0f89 100644
--- a/packages/babel-plugin-makepot/CHANGELOG.md
+++ b/packages/babel-plugin-makepot/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 6.18.0 (2025-02-12)
+
+## 6.17.0 (2025-01-29)
+
## 6.16.0 (2025-01-15)
## 6.15.0 (2025-01-02)
diff --git a/packages/babel-plugin-makepot/package.json b/packages/babel-plugin-makepot/package.json
index 56dc01c4fa9ac..5d81bc61f4d0a 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.16.0",
+ "version": "6.18.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 08633f5903d95..625ef7f09e863 100644
--- a/packages/babel-preset-default/CHANGELOG.md
+++ b/packages/babel-preset-default/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 8.18.0 (2025-02-12)
+
+## 8.17.0 (2025-01-29)
+
## 8.16.0 (2025-01-15)
## 8.15.0 (2025-01-02)
diff --git a/packages/babel-preset-default/package.json b/packages/babel-preset-default/package.json
index db0aad976eea5..220d9317ccc1a 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.16.0",
+ "version": "8.18.0",
"description": "Default Babel preset for WordPress development.",
"author": "The WordPress Contributors",
"license": "GPL-2.0-or-later",
diff --git a/packages/babel-preset-default/polyfill-exclusions.js b/packages/babel-preset-default/polyfill-exclusions.js
index ca8c045d12414..9d0d18737540c 100644
--- a/packages/babel-preset-default/polyfill-exclusions.js
+++ b/packages/babel-preset-default/polyfill-exclusions.js
@@ -28,4 +28,9 @@ module.exports = [
//
// @see https://github.com/WordPress/gutenberg/pull/67230
/^es(next)?\.set\./,
+ // Remove Iterator feature polyfills.
+ // For the same reasoning as for Set exlusion above, we're excluding all iterator helper polyfills.
+ //
+ // @see https://github.com/WordPress/wordpress-develop/pull/8224#issuecomment-2636390007.
+ /^es(next)?\.iterator\./,
];
diff --git a/packages/base-styles/CHANGELOG.md b/packages/base-styles/CHANGELOG.md
index 51a6d9500efe9..7c3ef6a48774b 100644
--- a/packages/base-styles/CHANGELOG.md
+++ b/packages/base-styles/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 5.18.0 (2025-02-12)
+
+## 5.17.0 (2025-01-29)
+
## 5.16.0 (2025-01-15)
## 5.15.0 (2025-01-02)
diff --git a/packages/base-styles/README.md b/packages/base-styles/README.md
index 9c57d91ac5a98..25034c13a977b 100644
--- a/packages/base-styles/README.md
+++ b/packages/base-styles/README.md
@@ -40,6 +40,10 @@ To make that work with [`sass`](https://www.npmjs.com/package/sass) or [`node-sa
}
```
+### CSS Admin Themes
+
+The package also includes a built version of the output generated by the `wordpress-admin-schemes()` mixin which can be used directly in your project. The CSS file is located at `node_modules/@wordpress/base-styles/build-style/admin-schemes.css`.
+
## Contributing to this package
This is an individual package that's part of the Gutenberg project. The project is organized as a monorepo. It's made up of multiple self-contained software packages, each with a specific purpose. The packages in this monorepo are published to [npm](https://www.npmjs.com/) and used by [WordPress](https://make.wordpress.org/core/) as well as other software projects.
diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss
index af679edb91064..6f7e3f2f13c30 100644
--- a/packages/base-styles/_z-index.scss
+++ b/packages/base-styles/_z-index.scss
@@ -25,7 +25,6 @@ $z-layers: (
".components-popover__close": 5,
".block-editor-block-list__insertion-point": 6,
".block-editor-warning": 5,
- ".block-library-gallery-item__inline-menu": 20,
".block-editor-url-input__suggestions": 30,
".edit-post-layout__footer": 30,
".interface-interface-skeleton__header": 30,
diff --git a/packages/base-styles/package.json b/packages/base-styles/package.json
index 2ff26eb2f475d..c87d3c18e8dc3 100644
--- a/packages/base-styles/package.json
+++ b/packages/base-styles/package.json
@@ -1,6 +1,6 @@
{
"name": "@wordpress/base-styles",
- "version": "5.16.0",
+ "version": "5.18.0",
"description": "Base SCSS utilities and variables for WordPress.",
"author": "The WordPress Contributors",
"license": "GPL-2.0-or-later",
diff --git a/packages/base-styles/src/admin-schemes.scss b/packages/base-styles/src/admin-schemes.scss
new file mode 100644
index 0000000000000..9aee5a6aed3c6
--- /dev/null
+++ b/packages/base-styles/src/admin-schemes.scss
@@ -0,0 +1 @@
+@include wordpress-admin-schemes();
diff --git a/packages/blob/CHANGELOG.md b/packages/blob/CHANGELOG.md
index 126b56cd81350..2b12b40acd9be 100644
--- a/packages/blob/CHANGELOG.md
+++ b/packages/blob/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 4.18.0 (2025-02-12)
+
+## 4.17.0 (2025-01-29)
+
## 4.16.0 (2025-01-15)
## 4.15.0 (2025-01-02)
diff --git a/packages/blob/package.json b/packages/blob/package.json
index d2dd0c206892f..85b897653f904 100644
--- a/packages/blob/package.json
+++ b/packages/blob/package.json
@@ -1,6 +1,6 @@
{
"name": "@wordpress/blob",
- "version": "4.16.0",
+ "version": "4.18.0",
"description": "Blob utilities for WordPress.",
"author": "The WordPress Contributors",
"license": "GPL-2.0-or-later",
diff --git a/packages/block-directory/CHANGELOG.md b/packages/block-directory/CHANGELOG.md
index 80b139c9a966d..589ed8b0008d4 100644
--- a/packages/block-directory/CHANGELOG.md
+++ b/packages/block-directory/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 5.18.0 (2025-02-12)
+
+## 5.17.0 (2025-01-29)
+
## 5.16.0 (2025-01-15)
## 5.15.0 (2025-01-02)
diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json
index e1f4cc0cefa98..7d9e15bc06940 100644
--- a/packages/block-directory/package.json
+++ b/packages/block-directory/package.json
@@ -1,6 +1,6 @@
{
"name": "@wordpress/block-directory",
- "version": "5.16.0",
+ "version": "5.18.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-directory/src/components/downloadable-blocks-panel/no-results.js b/packages/block-directory/src/components/downloadable-blocks-panel/no-results.js
index f2344061f9566..e4d04cd244687 100644
--- a/packages/block-directory/src/components/downloadable-blocks-panel/no-results.js
+++ b/packages/block-directory/src/components/downloadable-blocks-panel/no-results.js
@@ -2,17 +2,12 @@
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
-import { Icon, blockDefault } from '@wordpress/icons';
import { Tip, ExternalLink } from '@wordpress/components';
function DownloadableBlocksNoResults() {
return (
<>
-
{ __( 'No results found.' ) }
diff --git a/packages/block-directory/src/plugins/index.js b/packages/block-directory/src/plugins/index.js
index 283ff0ea4d271..50418a9944d31 100644
--- a/packages/block-directory/src/plugins/index.js
+++ b/packages/block-directory/src/plugins/index.js
@@ -13,6 +13,9 @@ import InstalledBlocksPrePublishPanel from './installed-blocks-pre-publish-panel
import getInstallMissing from './get-install-missing';
registerPlugin( 'block-directory', {
+ // The icon is explicitly set to undefined to prevent PluginPrePublishPanel
+ // from rendering the fallback icon pluginIcon.
+ icon: undefined,
render() {
return (
<>
diff --git a/packages/block-directory/src/plugins/installed-blocks-pre-publish-panel/index.js b/packages/block-directory/src/plugins/installed-blocks-pre-publish-panel/index.js
index 17630c9904e8b..233f3261c79fc 100644
--- a/packages/block-directory/src/plugins/installed-blocks-pre-publish-panel/index.js
+++ b/packages/block-directory/src/plugins/installed-blocks-pre-publish-panel/index.js
@@ -3,7 +3,6 @@
*/
import { _n, sprintf } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';
-import { blockDefault } from '@wordpress/icons';
import { PluginPrePublishPanel } from '@wordpress/editor';
/**
@@ -24,7 +23,6 @@ export default function InstalledBlocksPrePublishPanel() {
return (
{
- if ( filesList?.length > 1 ) {
- onUploadError(
- __( 'Only one image can be used as a background image.' )
- );
- return;
- }
getSettings().mediaUpload( {
allowedTypes: [ IMAGE_BACKGROUND_TYPE ],
filesList,
@@ -326,6 +320,7 @@ function BackgroundImageControls( {
onSelectMedia( image );
},
onError: onUploadError,
+ multiple: false,
} );
};
diff --git a/packages/block-editor/src/components/block-canvas/style.scss b/packages/block-editor/src/components/block-canvas/style.scss
index ea54646e64a59..c6688f5f387e0 100644
--- a/packages/block-editor/src/components/block-canvas/style.scss
+++ b/packages/block-editor/src/components/block-canvas/style.scss
@@ -4,7 +4,8 @@ iframe[name="editor-canvas"] {
height: 100%;
display: block;
// Handles transitions between device previews
- transition: all 400ms cubic-bezier(0.46, 0.03, 0.52, 0.96);
- @include reduce-motion("transition");
+ @media not ( prefers-reduced-motion ) {
+ transition: all 400ms cubic-bezier(0.46, 0.03, 0.52, 0.96);
+ }
background-color: $gray-300;
}
diff --git a/packages/block-editor/src/components/block-draggable/style.scss b/packages/block-editor/src/components/block-draggable/style.scss
index f716f2d32a1d4..f420251510ac6 100644
--- a/packages/block-editor/src/components/block-draggable/style.scss
+++ b/packages/block-editor/src/components/block-draggable/style.scss
@@ -59,7 +59,9 @@
justify-content: center;
align-items: center;
background-color: transparent;
- transition: all 0.1s linear 0.1s;
+ @media not ( prefers-reduced-motion ) {
+ transition: all 0.1s linear 0.1s;
+ }
.block-editor-block-draggable-chip__disabled-icon {
width: $grid-unit-50 * 0.5;
diff --git a/packages/block-editor/src/components/block-list/content.scss b/packages/block-editor/src/components/block-list/content.scss
index cd517fced833e..b39e9b144bbc9 100644
--- a/packages/block-editor/src/components/block-list/content.scss
+++ b/packages/block-editor/src/components/block-list/content.scss
@@ -58,10 +58,12 @@ _::-webkit-full-page-media, _:future, :root [data-has-multi-selection="true"] .b
background: var(--wp-admin-theme-color);
opacity: 0.4;
- // Animate.
- animation: selection-overlay__fade-in-animation 0.1s ease-out;
- animation-fill-mode: forwards;
- @include reduce-motion("animation");
+ @media not ( prefers-reduced-motion ) {
+
+ // Animate.
+ animation: selection-overlay__fade-in-animation 0.1s ease-out;
+ animation-fill-mode: forwards;
+ }
// Show outline in high contrast mode.
outline: 2px solid transparent;
@@ -271,8 +273,9 @@ _::-webkit-full-page-media, _:future, :root [data-has-multi-selection="true"] .b
// Spotlight mode. Fade out blocks unless they contain a selected block.
.is-focus-mode .block-editor-block-list__block:not(.has-child-selected) {
opacity: 0.2;
- transition: opacity 0.1s linear;
- @include reduce-motion("transition");
+ @media not ( prefers-reduced-motion ) {
+ transition: opacity 0.1s linear;
+ }
// Nested blocks should never be faded. If the parent block is already faded
// out, it shouldn't be faded out more. If the parent block in not faded
@@ -339,9 +342,10 @@ _::-webkit-full-page-media, _:future, :root [data-has-multi-selection="true"] .b
// Hide the appender that sits at the end of block lists, when inside a nested block,
// unless the block itself, or a parent, is selected.
.wp-block .block-list-appender .block-editor-inserter__toggle {
- animation: block-editor-inserter__toggle__fade-in-animation 0.1s ease;
- animation-fill-mode: forwards;
- @include reduce-motion("animation");
+ @media not ( prefers-reduced-motion ) {
+ animation: block-editor-inserter__toggle__fade-in-animation 0.1s ease;
+ animation-fill-mode: forwards;
+ }
}
.block-editor-block-list__block:not(.is-selected):not(.has-child-selected) .block-editor-default-block-appender {
@@ -367,8 +371,9 @@ _::-webkit-full-page-media, _:future, :root [data-has-multi-selection="true"] .b
font-family: $editor-html-font;
font-size: $text-editor-font-size;
line-height: 1.5;
- transition: padding 0.2s linear;
- @include reduce-motion("transition");
+ @media not ( prefers-reduced-motion ) {
+ transition: padding 0.2s linear;
+ }
&:focus {
box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
@@ -400,7 +405,9 @@ _::-webkit-full-page-media, _:future, :root [data-has-multi-selection="true"] .b
// Additional -1px is required to avoid sub pixel rounding errors allowing background to show.
margin-left: -1px;
margin-right: -1px;
- transition: background-color 0.3s ease;
+ @media not ( prefers-reduced-motion ) {
+ transition: background-color 0.3s ease;
+ }
display: flex;
align-items: center;
justify-content: center;
diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js
index bcf6783a10d1c..61c5cc277c135 100644
--- a/packages/block-editor/src/components/block-list/index.js
+++ b/packages/block-editor/src/components/block-list/index.js
@@ -19,6 +19,7 @@ import {
useCallback,
useEffect,
} from '@wordpress/element';
+import { getDefaultBlockName } from '@wordpress/blocks';
/**
* Internal dependencies
@@ -171,13 +172,13 @@ function Items( {
const {
getSettings,
getBlockOrder,
- getSelectedBlockClientId,
getSelectedBlockClientIds,
__unstableGetVisibleBlocks,
getTemplateLock,
getBlockEditingMode,
isSectionBlock,
isZoomOut: _isZoomOut,
+ canInsertBlockType,
} = unlock( select( blockEditorStore ) );
const _order = getBlockOrder( rootClientId );
@@ -190,10 +191,25 @@ function Items( {
};
}
- const selectedBlockClientId = getSelectedBlockClientId();
+ const selectedBlockClientIds = getSelectedBlockClientIds();
+ const selectedBlockClientId = selectedBlockClientIds[ 0 ];
+ const showRootAppender =
+ ! rootClientId &&
+ ! selectedBlockClientId &&
+ ( ! _order.length ||
+ ! canInsertBlockType(
+ getDefaultBlockName(),
+ rootClientId
+ ) );
+ const hasSelectedRoot = !! (
+ rootClientId &&
+ selectedBlockClientId &&
+ rootClientId === selectedBlockClientId
+ );
+
return {
order: _order,
- selectedBlocks: getSelectedBlockClientIds(),
+ selectedBlocks: selectedBlockClientIds,
visibleBlocks: __unstableGetVisibleBlocks(),
isZoomOut: _isZoomOut(),
shouldRenderAppender:
@@ -203,10 +219,8 @@ function Items( {
hasAppender &&
! _isZoomOut() &&
( hasCustomAppender ||
- rootClientId === selectedBlockClientId ||
- ( ! rootClientId &&
- ! selectedBlockClientId &&
- ! _order.length ) ),
+ hasSelectedRoot ||
+ showRootAppender ),
};
},
[ rootClientId, hasAppender, hasCustomAppender ]
diff --git a/packages/block-editor/src/components/block-mover/style.scss b/packages/block-editor/src/components/block-mover/style.scss
index 7d23c0f1e5a98..2560fe59de4fa 100644
--- a/packages/block-editor/src/components/block-mover/style.scss
+++ b/packages/block-editor/src/components/block-mover/style.scss
@@ -87,10 +87,11 @@
right: $grid-unit-10;
z-index: -1;
- // Animate in.
- animation: components-button__appear-animation 0.1s ease;
- animation-fill-mode: forwards;
- @include reduce-motion("animation");
+ @media not ( prefers-reduced-motion ) {
+ // Animate in.
+ animation: components-button__appear-animation 0.1s ease;
+ animation-fill-mode: forwards;
+ }
}
// Don't show the focus inherited by the Button component.
diff --git a/packages/block-editor/src/components/block-pattern-setup/style.scss b/packages/block-editor/src/components/block-pattern-setup/style.scss
index 10582a7a2ce49..98537f9cb9b7d 100644
--- a/packages/block-editor/src/components/block-pattern-setup/style.scss
+++ b/packages/block-editor/src/components/block-pattern-setup/style.scss
@@ -130,7 +130,9 @@
background-color: $white;
margin: auto;
padding: 0;
- transition: transform 0.5s, z-index 0.5s;
+ @media not ( prefers-reduced-motion ) {
+ transition: transform 0.5s, z-index 0.5s;
+ }
z-index: z-index(".block-editor-block-pattern-setup .pattern-slide");
&.active-slide {
diff --git a/packages/block-editor/src/components/block-patterns-list/style.scss b/packages/block-editor/src/components/block-patterns-list/style.scss
index 8b1b0b54c9b1a..fcf1a23c0b7ca 100644
--- a/packages/block-editor/src/components/block-patterns-list/style.scss
+++ b/packages/block-editor/src/components/block-patterns-list/style.scss
@@ -44,9 +44,9 @@
outline: $border-width solid rgba($black, 0.1);
outline-offset: -$border-width;
border-radius: $radius-medium;
-
- transition: outline 0.1s linear;
- @include reduce-motion("transition");
+ @media not ( prefers-reduced-motion ) {
+ transition: outline 0.1s linear;
+ }
}
}
diff --git a/packages/block-editor/src/components/block-popover/use-popover-scroll.js b/packages/block-editor/src/components/block-popover/use-popover-scroll.js
index 8aeb768e302f6..97bc4c5b29937 100644
--- a/packages/block-editor/src/components/block-popover/use-popover-scroll.js
+++ b/packages/block-editor/src/components/block-popover/use-popover-scroll.js
@@ -2,24 +2,29 @@
* WordPress dependencies
*/
import { useRefEffect } from '@wordpress/compose';
+import { getScrollContainer } from '@wordpress/dom';
+
+const scrollContainerCache = new WeakMap();
/**
* Allow scrolling "through" popovers over the canvas. This is only called for
* as long as the pointer is over a popover. Do not use React events because it
* will bubble through portals.
*
- * @param {Object} scrollableRef
+ * @param {Object} contentRef
*/
-function usePopoverScroll( scrollableRef ) {
+function usePopoverScroll( contentRef ) {
return useRefEffect(
( node ) => {
- if ( ! scrollableRef ) {
- return;
- }
-
function onWheel( event ) {
const { deltaX, deltaY } = event;
- scrollableRef.current.scrollBy( deltaX, deltaY );
+ const contentEl = contentRef.current;
+ let scrollContainer = scrollContainerCache.get( contentEl );
+ if ( ! scrollContainer ) {
+ scrollContainer = getScrollContainer( contentEl );
+ scrollContainerCache.set( contentEl, scrollContainer );
+ }
+ scrollContainer.scrollBy( deltaX, deltaY );
}
// Tell the browser that we do not call event.preventDefault
// See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#improving_scrolling_performance_with_passive_listeners
@@ -29,7 +34,7 @@ function usePopoverScroll( scrollableRef ) {
node.removeEventListener( 'wheel', onWheel, options );
};
},
- [ scrollableRef ]
+ [ contentRef ]
);
}
diff --git a/packages/block-editor/src/components/block-switcher/style.scss b/packages/block-editor/src/components/block-switcher/style.scss
index 62a7bebe95d27..2762308eec961 100644
--- a/packages/block-editor/src/components/block-switcher/style.scss
+++ b/packages/block-editor/src/components/block-switcher/style.scss
@@ -129,7 +129,9 @@
.block-editor-block-switcher__preview-patterns-container-list__item {
height: 100%;
border-radius: $radius-small;
- transition: all 0.05s ease-in-out;
+ @media not ( prefers-reduced-motion ) {
+ transition: all 0.05s ease-in-out;
+ }
position: relative;
border: $border-width solid transparent;
diff --git a/packages/block-editor/src/components/block-toolbar/style.scss b/packages/block-editor/src/components/block-toolbar/style.scss
index 26bf71356925e..2a3543f5ec797 100644
--- a/packages/block-editor/src/components/block-toolbar/style.scss
+++ b/packages/block-editor/src/components/block-toolbar/style.scss
@@ -12,9 +12,11 @@
overflow-y: hidden;
overflow-x: auto;
- // Animation
- transition: border-color 0.1s linear, box-shadow 0.1s linear;
- @include reduce-motion("transition");
+ @media not ( prefers-reduced-motion ) {
+
+ // Animation
+ transition: border-color 0.1s linear, box-shadow 0.1s linear;
+ }
@include break-small() {
overflow: inherit;
diff --git a/packages/block-editor/src/components/block-tools/block-toolbar-popover.js b/packages/block-editor/src/components/block-tools/block-toolbar-popover.js
index c6378130b7da4..0724928cfeacb 100644
--- a/packages/block-editor/src/components/block-tools/block-toolbar-popover.js
+++ b/packages/block-editor/src/components/block-tools/block-toolbar-popover.js
@@ -11,7 +11,7 @@ import { useShortcut } from '@wordpress/keyboard-shortcuts';
/**
* Internal dependencies
*/
-import BlockPopover from '../block-popover';
+import { PrivateBlockPopover } from '../block-popover';
import useBlockToolbarPopoverProps from './use-block-toolbar-popover-props';
import useSelectedBlockToolProps from './use-selected-block-tool-props';
import { store as blockEditorStore } from '../../store';
@@ -58,7 +58,7 @@ export default function BlockToolbarPopover( {
return (
! isTyping && (
-
-
+
)
);
}
diff --git a/packages/block-editor/src/components/block-tools/style.scss b/packages/block-editor/src/components/block-tools/style.scss
index 35d075c1a99b7..35d0f99c827b6 100644
--- a/packages/block-editor/src/components/block-tools/style.scss
+++ b/packages/block-editor/src/components/block-tools/style.scss
@@ -191,9 +191,12 @@
.is-dragging-components-draggable & {
opacity: 0;
- // Use a minimal duration to delay hiding the element, see hide-during-dragging animation for more details.
- // It's essential to hide the toolbar/popover so that `dragEnter` events can pass through them to the underlying elements.
- animation: hide-during-dragging 1ms linear forwards;
+ @media not ( prefers-reduced-motion ) {
+
+ // Use a minimal duration to delay hiding the element, see hide-during-dragging animation for more details.
+ // It's essential to hide the toolbar/popover so that `dragEnter` events can pass through them to the underlying elements.
+ animation: hide-during-dragging 1ms linear forwards;
+ }
}
.block-editor-block-parent-selector {
diff --git a/packages/block-editor/src/components/button-block-appender/content.scss b/packages/block-editor/src/components/button-block-appender/content.scss
index f5486d3f6f608..dd6f092483567 100644
--- a/packages/block-editor/src/components/button-block-appender/content.scss
+++ b/packages/block-editor/src/components/button-block-appender/content.scss
@@ -79,10 +79,8 @@
background-color: var(--wp-admin-theme-color);
box-shadow: inset 0 0 0 $border-width $light-gray-placeholder;
color: $light-gray-placeholder;
- transition: background-color 0.2s ease-in-out;
-
- @media ( prefers-reduced-motion: reduce ) {
- transition: none;
+ @media not ( prefers-reduced-motion ) {
+ transition: background-color 0.2s ease-in-out;
}
}
}
diff --git a/packages/block-editor/src/components/colors-gradients/style.scss b/packages/block-editor/src/components/colors-gradients/style.scss
index 661318e558241..6a882c4b1883c 100644
--- a/packages/block-editor/src/components/colors-gradients/style.scss
+++ b/packages/block-editor/src/components/colors-gradients/style.scss
@@ -129,8 +129,9 @@ $swatch-gap: 12px;
top: $grid-unit;
margin: auto $grid-unit auto;
opacity: 0;
- transition: opacity 0.1s ease-in-out;
- @include reduce-motion("transition");
+ @media not ( prefers-reduced-motion ) {
+ transition: opacity 0.1s ease-in-out;
+ }
&.block-editor-panel-color-gradient-settings__reset {
border-radius: $radius-small;
diff --git a/packages/block-editor/src/components/global-styles/filters-panel.js b/packages/block-editor/src/components/global-styles/filters-panel.js
index 64322d0fd5d5c..3aed7255e411b 100644
--- a/packages/block-editor/src/components/global-styles/filters-panel.js
+++ b/packages/block-editor/src/components/global-styles/filters-panel.js
@@ -9,8 +9,6 @@ import clsx from 'clsx';
import {
__experimentalToolsPanel as ToolsPanel,
__experimentalToolsPanelItem as ToolsPanelItem,
- __experimentalItemGroup as ItemGroup,
- __experimentalItem as Item,
__experimentalHStack as HStack,
__experimentalZStack as ZStack,
__experimentalDropdownContentWrapper as DropdownContentWrapper,
@@ -21,9 +19,11 @@ import {
Dropdown,
Flex,
FlexItem,
+ Button,
} from '@wordpress/components';
import { __, _x } from '@wordpress/i18n';
-import { useCallback, useMemo } from '@wordpress/element';
+import { useCallback, useMemo, useRef } from '@wordpress/element';
+import { reset as resetIcon } from '@wordpress/icons';
/**
* Internal dependencies
@@ -117,6 +117,50 @@ const LabeledColorIndicator = ( { indicator, label } ) => (
);
+const renderToggle =
+ ( duotone, resetDuotone ) =>
+ ( { onToggle, isOpen } ) => {
+ const duotoneButtonRef = useRef( undefined );
+
+ const toggleProps = {
+ onClick: onToggle,
+ className: clsx( { 'is-open': isOpen } ),
+ 'aria-expanded': isOpen,
+ ref: duotoneButtonRef,
+ };
+
+ const removeButtonProps = {
+ onClick: () => {
+ if ( isOpen ) {
+ onToggle();
+ }
+ resetDuotone();
+ // Return focus to parent button.
+ duotoneButtonRef.current?.focus();
+ },
+ className: 'block-editor-panel-duotone-settings__reset',
+ label: __( 'Reset' ),
+ };
+
+ return (
+ <>
+
+ { duotone && (
+
+ ) }
+ >
+ );
+ };
+
export default function FiltersPanel( {
as: Wrapper = FiltersToolsPanel,
value,
@@ -182,24 +226,7 @@ export default function FiltersPanel( {
{
- const toggleProps = {
- onClick: onToggle,
- className: clsx( { 'is-open': isOpen } ),
- 'aria-expanded': isOpen,
- };
-
- return (
-
-
-
-
-
- );
- } }
+ renderToggle={ renderToggle( duotone, resetDuotone ) }
renderContent={ () => (
diff --git a/packages/block-editor/src/components/global-styles/shadow-panel-components.js b/packages/block-editor/src/components/global-styles/shadow-panel-components.js
index 1cfdff0be286e..25da4150a090f 100644
--- a/packages/block-editor/src/components/global-styles/shadow-panel-components.js
+++ b/packages/block-editor/src/components/global-styles/shadow-panel-components.js
@@ -13,8 +13,8 @@ import {
Composite,
Tooltip,
} from '@wordpress/components';
-import { useMemo } from '@wordpress/element';
-import { shadow as shadowIcon, Icon, check } from '@wordpress/icons';
+import { useMemo, useRef } from '@wordpress/element';
+import { shadow as shadowIcon, Icon, check, reset } from '@wordpress/icons';
/**
* External dependencies
@@ -46,6 +46,8 @@ export function ShadowPopoverContainer( { shadow, onShadowChange, settings } ) {
__next40pxDefaultSize
variant="tertiary"
onClick={ () => onShadowChange( undefined ) }
+ disabled={ ! shadow }
+ accessibleWhenDisabled
>
{ __( 'Clear' ) }
@@ -119,7 +121,7 @@ export function ShadowPopover( { shadow, onShadowChange, settings } ) {
(
{
+ const shadowButtonRef = useRef( undefined );
+
const toggleProps = {
onClick: onToggle,
className: clsx( { 'is-open': isOpen } ),
'aria-expanded': isOpen,
+ ref: shadowButtonRef,
+ };
+
+ const removeButtonProps = {
+ onClick: () => {
+ if ( isOpen ) {
+ onToggle();
+ }
+ onShadowChange( undefined );
+ // Return focus to parent button.
+ shadowButtonRef.current?.focus();
+ },
+ className: clsx(
+ 'block-editor-global-styles__shadow-editor__remove-button',
+ { 'is-open': isOpen }
+ ),
+ label: __( 'Remove' ),
};
return (
-
+ ) }
+ >
);
};
}
diff --git a/packages/block-editor/src/components/global-styles/style.scss b/packages/block-editor/src/components/global-styles/style.scss
index e0782fdb01b1d..3645586f28311 100644
--- a/packages/block-editor/src/components/global-styles/style.scss
+++ b/packages/block-editor/src/components/global-styles/style.scss
@@ -24,6 +24,7 @@
.block-editor-global-styles__shadow-dropdown {
display: block;
padding: 0;
+ position: relative;
button {
width: 100%;
@@ -35,6 +36,33 @@
}
}
+.block-editor-global-styles__shadow-editor__remove-button {
+ position: absolute;
+ right: 0;
+ top: $grid-unit;
+ margin: auto $grid-unit auto;
+ opacity: 0;
+ @media not (prefers-reduced-motion) {
+ transition: opacity 0.1s ease-in-out;
+ }
+
+ .block-editor-global-styles__shadow-dropdown:hover &,
+ &:focus,
+ &:hover {
+ opacity: 1;
+ }
+
+ @media (hover: none) {
+ // Show reset button on devices that do not support hover.
+ opacity: 1;
+ }
+}
+
+.block-editor-global-styles-filters-panel__dropdown {
+ border: 1px solid $gray-300;
+ border-radius: $radius-small;
+}
+
// These styles are similar to the color palette.
.block-editor-global-styles__shadow-indicator {
appearance: none;
@@ -53,7 +81,9 @@
box-sizing: border-box;
transform: scale(1);
- transition: transform 0.1s ease;
+ @media not ( prefers-reduced-motion ) {
+ transition: transform 0.1s ease;
+ }
will-change: transform;
&:focus {
@@ -75,3 +105,25 @@
/*rtl:ignore*/
direction: ltr;
}
+
+.block-editor-panel-duotone-settings__reset {
+ position: absolute;
+ right: 0;
+ top: $grid-unit;
+ margin: auto $grid-unit auto;
+ opacity: 0;
+ @media not (prefers-reduced-motion) {
+ transition: opacity 0.1s ease-in-out;
+ }
+
+ .block-editor-global-styles-filters-panel__dropdown:hover &,
+ &:focus,
+ &:hover {
+ opacity: 1;
+ }
+
+ @media (hover: none) {
+ // Show reset button on devices that do not support hover.
+ opacity: 1;
+ }
+}
diff --git a/packages/block-editor/src/components/grid/grid-visualizer.js b/packages/block-editor/src/components/grid/grid-visualizer.js
index 9d89866bbff5f..c272691ab5656 100644
--- a/packages/block-editor/src/components/grid/grid-visualizer.js
+++ b/packages/block-editor/src/components/grid/grid-visualizer.js
@@ -54,29 +54,18 @@ const GridVisualizerGrid = forwardRef(
const [ isDroppingAllowed, setIsDroppingAllowed ] = useState( false );
useEffect( () => {
- const observers = [];
- for ( const element of [ gridElement, ...gridElement.children ] ) {
- const observer = new window.ResizeObserver( () => {
- setGridInfo( getGridInfo( gridElement ) );
- } );
- observer.observe( element );
- observers.push( observer );
- }
-
- const mutationObserver = new window.MutationObserver( () => {
+ const resizeCallback = () =>
setGridInfo( getGridInfo( gridElement ) );
- } );
- mutationObserver.observe( gridElement, {
- attributeFilter: [ 'style', 'class' ],
- childList: true,
- subtree: true,
- } );
- observers.push( mutationObserver );
-
+ // Both border-box and content-box are observed as they may change
+ // independently. This requires two observers because a single one
+ // can’t be made to monitor both on the same element.
+ const borderBoxSpy = new window.ResizeObserver( resizeCallback );
+ borderBoxSpy.observe( gridElement, { box: 'border-box' } );
+ const contentBoxSpy = new window.ResizeObserver( resizeCallback );
+ contentBoxSpy.observe( gridElement );
return () => {
- for ( const observer of observers ) {
- observer.disconnect();
- }
+ borderBoxSpy.disconnect();
+ contentBoxSpy.disconnect();
};
}, [ gridElement ] );
diff --git a/packages/block-editor/src/components/grid/style.scss b/packages/block-editor/src/components/grid/style.scss
index 3a04eb006e791..ab36ed12984bd 100644
--- a/packages/block-editor/src/components/grid/style.scss
+++ b/packages/block-editor/src/components/grid/style.scss
@@ -20,6 +20,7 @@
.block-editor-grid-visualizer__grid {
display: grid;
+ position: absolute;
}
.block-editor-grid-visualizer__cell {
@@ -125,10 +126,11 @@
right: $grid-unit-10;
z-index: -1;
- // Animate in.
- animation: components-button__appear-animation 0.1s ease;
- animation-fill-mode: forwards;
- @include reduce-motion("animation");
+ @media not ( prefers-reduced-motion ) {
+ // Animate in.
+ animation: components-button__appear-animation 0.1s ease;
+ animation-fill-mode: forwards;
+ }
}
// Don't show the focus inherited by the Button component.
diff --git a/packages/block-editor/src/components/grid/utils.js b/packages/block-editor/src/components/grid/utils.js
index 2101410808542..ada02755f2609 100644
--- a/packages/block-editor/src/components/grid/utils.js
+++ b/packages/block-editor/src/components/grid/utils.js
@@ -187,10 +187,12 @@ export function getGridInfo( gridElement ) {
gridTemplateColumns,
gridTemplateRows,
gap: getComputedCSS( gridElement, 'gap' ),
- paddingTop: `calc(${ paddingTop } + ${ borderTopWidth })`,
- paddingRight: `calc(${ paddingRight } + ${ borderRightWidth })`,
- paddingBottom: `calc(${ paddingBottom } + ${ borderBottomWidth })`,
- paddingLeft: `calc(${ paddingLeft } + ${ borderLeftWidth })`,
+ inset: `
+ calc(${ paddingTop } + ${ borderTopWidth })
+ calc(${ paddingRight } + ${ borderRightWidth })
+ calc(${ paddingBottom } + ${ borderBottomWidth })
+ calc(${ paddingLeft } + ${ borderLeftWidth })
+ `,
},
};
}
diff --git a/packages/block-editor/src/components/iframe/content.scss b/packages/block-editor/src/components/iframe/content.scss
index 05bbdb25c2dc6..8a85ea186b2e6 100644
--- a/packages/block-editor/src/components/iframe/content.scss
+++ b/packages/block-editor/src/components/iframe/content.scss
@@ -4,8 +4,11 @@
.block-editor-iframe__html {
transform-origin: top center;
- // Prevents a flash of background color change when entering/exiting zoom out
- transition: background-color 400ms;
+
+ @media not ( prefers-reduced-motion ) {
+ // Prevents a flash of background color change when entering/exiting zoom out
+ transition: background-color 400ms;
+ }
&.zoom-out-animation {
$scroll-top: var(--wp-block-editor-iframe-zoom-out-scroll-top, 0);
diff --git a/packages/block-editor/src/components/image-editor/aspect-ratio-dropdown.js b/packages/block-editor/src/components/image-editor/aspect-ratio-dropdown.js
index b8432d1669f28..4862acd63d548 100644
--- a/packages/block-editor/src/components/image-editor/aspect-ratio-dropdown.js
+++ b/packages/block-editor/src/components/image-editor/aspect-ratio-dropdown.js
@@ -93,7 +93,7 @@ export default function AspectRatioDropdown( { toggleProps } ) {
{
slug: 'original',
name: __( 'Original' ),
- aspect: defaultAspect,
+ ratio: defaultAspect,
},
...( showDefaultRatios
? defaultRatios
diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js
index ae58772027820..58faf9f9a34e1 100644
--- a/packages/block-editor/src/components/inner-blocks/index.js
+++ b/packages/block-editor/src/components/inner-blocks/index.js
@@ -174,11 +174,11 @@ const ForwardedInnerBlocks = forwardRef( ( props, ref ) => {
* returns. Optionally, you can also pass any other props through this hook, and
* they will be merged and returned.
*
+ * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md
+ *
* @param {Object} props Optional. Props to pass to the element. Must contain
* the ref if one is defined.
* @param {Object} options Optional. Inner blocks options.
- *
- * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md
*/
export function useInnerBlocksProps( props = {}, options = {} ) {
const {
diff --git a/packages/block-editor/src/components/inner-blocks/index.native.js b/packages/block-editor/src/components/inner-blocks/index.native.js
index 1398a5abd51e4..635c44d2e085c 100644
--- a/packages/block-editor/src/components/inner-blocks/index.native.js
+++ b/packages/block-editor/src/components/inner-blocks/index.native.js
@@ -35,11 +35,11 @@ import { MAX_NESTING_DEPTH } from './constants';
* returns. Optionally, you can also pass any other props through this hook, and
* they will be merged and returned.
*
+ * @see https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/inner-blocks/README.md
+ *
* @param {Object} props Optional. Props to pass to the element. Must contain
* the ref if one is defined.
* @param {Object} options Optional. Inner blocks options.
- *
- * @see https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/inner-blocks/README.md
*/
export function useInnerBlocksProps( props = {}, options = {} ) {
const fallbackRef = useRef();
diff --git a/packages/block-editor/src/components/inserter-list-item/style.scss b/packages/block-editor/src/components/inserter-list-item/style.scss
index 435f60ed9e2f1..68d4059340f5c 100644
--- a/packages/block-editor/src/components/inserter-list-item/style.scss
+++ b/packages/block-editor/src/components/inserter-list-item/style.scss
@@ -43,8 +43,9 @@
cursor: pointer;
background: transparent;
word-break: break-word;
- transition: all 0.05s ease-in-out;
- @include reduce-motion("transition");
+ @media not ( prefers-reduced-motion ) {
+ transition: all 0.05s ease-in-out;
+ }
position: relative;
height: auto;
@@ -97,8 +98,9 @@
.block-editor-block-types-list__item-icon {
padding: 12px 20px;
color: $gray-900;
- transition: all 0.05s ease-in-out;
- @include reduce-motion("transition");
+ @media not ( prefers-reduced-motion ) {
+ transition: all 0.05s ease-in-out;
+ }
.block-editor-block-icon {
margin-left: auto;
@@ -106,8 +108,9 @@
}
svg {
- transition: all 0.15s ease-out;
- @include reduce-motion("transition");
+ @media not ( prefers-reduced-motion ) {
+ transition: all 0.15s ease-out;
+ }
}
.block-editor-block-types-list__list-item[draggable="true"] & {
diff --git a/packages/block-editor/src/components/inserter/no-results.js b/packages/block-editor/src/components/inserter/no-results.js
index 3ca6569dc14ea..e005622f3cf3d 100644
--- a/packages/block-editor/src/components/inserter/no-results.js
+++ b/packages/block-editor/src/components/inserter/no-results.js
@@ -2,15 +2,10 @@
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
-import { Icon, blockDefault } from '@wordpress/icons';
function InserterNoResults() {
return (
-
{ __( 'No results found.' ) }
);
diff --git a/packages/block-editor/src/components/inserter/quick-inserter.js b/packages/block-editor/src/components/inserter/quick-inserter.js
index 498030a0019dc..baedf91b87a90 100644
--- a/packages/block-editor/src/components/inserter/quick-inserter.js
+++ b/packages/block-editor/src/components/inserter/quick-inserter.js
@@ -21,6 +21,7 @@ import { store as blockEditorStore } from '../../store';
const SEARCH_THRESHOLD = 6;
const SHOWN_BLOCK_TYPES = 6;
+const SHOWN_BLOCK_PATTERNS = 2;
export default function QuickInserter( {
onSelect,
@@ -106,7 +107,9 @@ export default function QuickInserter( {
rootClientId={ rootClientId }
clientId={ clientId }
isAppender={ isAppender }
- maxBlockPatterns={ 0 }
+ maxBlockPatterns={
+ !! filterValue ? SHOWN_BLOCK_PATTERNS : 0
+ }
maxBlockTypes={ SHOWN_BLOCK_TYPES }
isDraggable={ false }
selectBlockOnInsert={ selectBlockOnInsert }
diff --git a/packages/block-editor/src/components/inserter/search-results.js b/packages/block-editor/src/components/inserter/search-results.js
index 5a5725a3bb08c..c020e86f99a63 100644
--- a/packages/block-editor/src/components/inserter/search-results.js
+++ b/packages/block-editor/src/components/inserter/search-results.js
@@ -84,7 +84,9 @@ function InserterSearchResults( {
] = useBlockTypesState( destinationRootClientId, onInsertBlocks, isQuick );
const [ patterns, , onClickPattern ] = usePatternsState(
onInsertBlocks,
- destinationRootClientId
+ destinationRootClientId,
+ undefined,
+ isQuick
);
const filteredBlockPatterns = useMemo( () => {
diff --git a/packages/block-editor/src/components/inserter/style.scss b/packages/block-editor/src/components/inserter/style.scss
index c6522671f938d..20aa1c288103d 100644
--- a/packages/block-editor/src/components/inserter/style.scss
+++ b/packages/block-editor/src/components/inserter/style.scss
@@ -83,8 +83,9 @@ $block-inserter-tabs-height: 44px;
border: none;
outline: none;
padding: 0;
- transition: color 0.2s ease;
- @include reduce-motion("transition");
+ @media not ( prefers-reduced-motion ) {
+ transition: color 0.2s ease;
+ }
}
.block-editor-inserter__menu {
@@ -167,10 +168,6 @@ $block-inserter-tabs-height: 44px;
text-align: center;
}
-.block-editor-inserter__no-results-icon {
- fill: $gray-600;
-}
-
.block-editor-inserter__child-blocks {
padding: 0 $grid-unit-20;
}
@@ -563,8 +560,9 @@ $block-inserter-tabs-height: 44px;
outline-color: var(--wp-admin-theme-color);
outline-width: var(--wp-admin-border-width-focus);
outline-offset: calc((-1 * var(--wp-admin-border-width-focus)));
- transition: outline 0.1s linear;
- @include reduce-motion("transition");
+ @media not ( prefers-reduced-motion ) {
+ transition: outline 0.1s linear;
+ }
}
}
diff --git a/packages/block-editor/src/components/inspector-controls-tabs/position-controls-panel.js b/packages/block-editor/src/components/inspector-controls-tabs/position-controls-panel.js
index 42a8597227dee..17f65d58b8f74 100644
--- a/packages/block-editor/src/components/inspector-controls-tabs/position-controls-panel.js
+++ b/packages/block-editor/src/components/inspector-controls-tabs/position-controls-panel.js
@@ -2,11 +2,11 @@
* WordPress dependencies
*/
import {
- PanelBody,
__experimentalUseSlotFills as useSlotFills,
+ __experimentalToolsPanel as ToolsPanel,
+ __experimentalToolsPanelItem as ToolsPanelItem,
} from '@wordpress/components';
-import { useSelect } from '@wordpress/data';
-import { useLayoutEffect, useState } from '@wordpress/element';
+import { useDispatch, useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
/**
@@ -15,40 +15,75 @@ import { __ } from '@wordpress/i18n';
import InspectorControlsGroups from '../inspector-controls/groups';
import { default as InspectorControls } from '../inspector-controls';
import { store as blockEditorStore } from '../../store';
+import { useToolsPanelDropdownMenuProps } from '../global-styles/utils';
+import { cleanEmptyObject } from '../../hooks/utils';
const PositionControlsPanel = () => {
- const [ initialOpen, setInitialOpen ] = useState();
+ const { selectedClientIds, selectedBlocks, hasPositionAttribute } =
+ useSelect( ( select ) => {
+ const { getBlocksByClientId, getSelectedBlockClientIds } =
+ select( blockEditorStore );
- // Determine whether the panel should be expanded.
- const { multiSelectedBlocks } = useSelect( ( select ) => {
- const { getBlocksByClientId, getSelectedBlockClientIds } =
- select( blockEditorStore );
- const clientIds = getSelectedBlockClientIds();
- return {
- multiSelectedBlocks: getBlocksByClientId( clientIds ),
- };
- }, [] );
+ const selectedBlockClientIds = getSelectedBlockClientIds();
+ const _selectedBlocks = getBlocksByClientId(
+ selectedBlockClientIds
+ );
- useLayoutEffect( () => {
- // If any selected block has a position set, open the panel by default.
- // The first block's value will still be used within the control though.
- if ( initialOpen === undefined ) {
- setInitialOpen(
- multiSelectedBlocks.some(
+ return {
+ selectedClientIds: selectedBlockClientIds,
+ selectedBlocks: _selectedBlocks,
+ hasPositionAttribute: _selectedBlocks?.some(
( { attributes } ) => !! attributes?.style?.position?.type
- )
- );
+ ),
+ };
+ }, [] );
+
+ const { updateBlockAttributes } = useDispatch( blockEditorStore );
+ const dropdownMenuProps = useToolsPanelDropdownMenuProps();
+
+ function resetPosition() {
+ if ( ! selectedClientIds?.length || ! selectedBlocks?.length ) {
+ return;
}
- }, [ initialOpen, multiSelectedBlocks, setInitialOpen ] );
+
+ const attributesByClientId = Object.fromEntries(
+ selectedBlocks?.map( ( { clientId, attributes } ) => [
+ clientId,
+ {
+ style: cleanEmptyObject( {
+ ...attributes?.style,
+ position: {
+ ...attributes?.style?.position,
+ type: undefined,
+ top: undefined,
+ right: undefined,
+ bottom: undefined,
+ left: undefined,
+ },
+ } ),
+ },
+ ] )
+ );
+
+ updateBlockAttributes( selectedClientIds, attributesByClientId, true );
+ }
return (
-
-
-
+ hasPositionAttribute }
+ onDeselect={ resetPosition }
+ >
+
+
+
);
};
diff --git a/packages/block-editor/src/components/keyboard-shortcuts/index.js b/packages/block-editor/src/components/keyboard-shortcuts/index.js
index fcc2cea404375..4d368e6c1d0ab 100644
--- a/packages/block-editor/src/components/keyboard-shortcuts/index.js
+++ b/packages/block-editor/src/components/keyboard-shortcuts/index.js
@@ -29,7 +29,7 @@ function KeyboardShortcutsRegister() {
category: 'block',
description: __( 'Remove the selected block(s).' ),
keyCombination: {
- modifier: 'shift',
+ modifier: 'primaryShift',
character: 'backspace',
},
} );
diff --git a/packages/block-editor/src/components/link-control/style.scss b/packages/block-editor/src/components/link-control/style.scss
index 16493e1a5aa7f..c10135f8e441a 100644
--- a/packages/block-editor/src/components/link-control/style.scss
+++ b/packages/block-editor/src/components/link-control/style.scss
@@ -289,8 +289,10 @@ $block-editor-link-control-number-of-actions: 1;
right: 0;
bottom: 0;
border-radius: 100%;
- animation: loadingpulse 1s linear infinite;
- animation-delay: 0.5s; // avoid animating for fast network responses
+ @media not ( prefers-reduced-motion ) {
+ animation: loadingpulse 1s linear infinite;
+ animation-delay: 0.5s; // avoid animating for fast network responses
+ }
}
}
}
@@ -381,16 +383,19 @@ $block-editor-link-control-number-of-actions: 1;
// Point downwards when open (same as list view expander)
&[aria-expanded="true"] svg {
visibility: visible;
- transition: transform 0.1s ease;
+ @media not ( prefers-reduced-motion ) {
+ transition: transform 0.1s ease;
+ }
transform: rotate(90deg);
- @include reduce-motion("transition");
+
}
// Point rightwards when closed (same as list view expander)
&[aria-expanded="false"] svg {
visibility: visible;
transform: rotate(0deg);
- transition: transform 0.1s ease;
- @include reduce-motion("transition");
+ @media not ( prefers-reduced-motion ) {
+ transition: transform 0.1s ease;
+ }
}
}
}
diff --git a/packages/block-editor/src/components/list-view/style.scss b/packages/block-editor/src/components/list-view/style.scss
index 138029262cd7f..bc68cb2663790 100644
--- a/packages/block-editor/src/components/list-view/style.scss
+++ b/packages/block-editor/src/components/list-view/style.scss
@@ -158,21 +158,27 @@
// without attaching the transition to the list view leaf itself. This prevents rows
// from animating too much once the user has dropped the block.
&.is-displacement-normal {
- transition: transform 0.2s;
+ @media not ( prefers-reduced-motion ) {
+ transition: transform 0.2s;
+ }
transform: translateY(0);
- @include reduce-motion("transition");
+
}
&.is-displacement-up {
- transition: transform 0.2s;
+ @media not ( prefers-reduced-motion ) {
+ transition: transform 0.2s;
+ }
transform: translateY(-32px);
- @include reduce-motion("transition");
+
}
&.is-displacement-down {
- transition: transform 0.2s;
+ @media not ( prefers-reduced-motion ) {
+ transition: transform 0.2s;
+ }
transform: translateY(32px);
- @include reduce-motion("transition");
+
}
// Collapse multi-selections down into a single row space while dragging. The following
@@ -180,23 +186,30 @@
// when displacing up and down. The result is that there should only ever be a single row's
// worth of space for the visual indicator of where a block will be placed when dropped.
&.is-after-dragged-blocks {
- transition: transform 0.2s;
+
+ @media not ( prefers-reduced-motion ) {
+ transition: transform 0.2s;
+ }
transform: translateY(calc(var(--wp-admin--list-view-dragged-items-height, 32px) * -1));
- @include reduce-motion("transition");
+
}
&.is-after-dragged-blocks.is-displacement-up {
- transition: transform 0.2s;
+ @media not ( prefers-reduced-motion ) {
+ transition: transform 0.2s;
+ }
transform: translateY(calc(-32px + var(--wp-admin--list-view-dragged-items-height, 32px) * -1));
- @include reduce-motion("transition");
+
}
&.is-after-dragged-blocks.is-displacement-down {
- transition: transform 0.2s;
+ @media not ( prefers-reduced-motion ) {
+ transition: transform 0.2s;
+ }
transform:
translateY(calc(32px + var(--wp-admin--list-view-dragged-items-height, 32px) *
-1));
- @include reduce-motion("transition");
+
}
// To ensure displaced rows behave correctly, ensure that blocks that are currently being dragged
@@ -233,7 +246,9 @@
font-weight: 400;
margin: 0;
text-decoration: none;
- transition: box-shadow 0.1s linear;
+ @media not ( prefers-reduced-motion ) {
+ transition: box-shadow 0.1s linear;
+ }
.components-modal__content & {
padding-left: 0;
@@ -496,9 +511,10 @@ $block-navigation-max-indent: 8;
.block-editor-list-view__expander
svg {
visibility: visible;
- transition: transform 0.2s ease;
+ @media not ( prefers-reduced-motion ) {
+ transition: transform 0.2s ease;
+ }
transform: rotate(90deg);
- @include reduce-motion("transition");
}
// Point rightwards when closed
@@ -507,8 +523,9 @@ svg {
svg {
visibility: visible;
transform: rotate(0deg);
- transition: transform 0.2s ease;
- @include reduce-motion("transition");
+ @media not ( prefers-reduced-motion ) {
+ transition: transform 0.2s ease;
+ }
}
.block-editor-list-view-drop-indicator {
diff --git a/packages/block-editor/src/components/media-placeholder/index.js b/packages/block-editor/src/components/media-placeholder/index.js
index e19e350f959b2..3d6578dcd39c2 100644
--- a/packages/block-editor/src/components/media-placeholder/index.js
+++ b/packages/block-editor/src/components/media-placeholder/index.js
@@ -227,6 +227,7 @@ export function MediaPlaceholder( {
filesList: files,
onFileChange: setMedia,
onError,
+ multiple,
} );
};
diff --git a/packages/block-editor/src/components/rich-text/event-listeners/delete.js b/packages/block-editor/src/components/rich-text/event-listeners/delete.js
index 8373ca3c9f72a..ad59ae8a70d32 100644
--- a/packages/block-editor/src/components/rich-text/event-listeners/delete.js
+++ b/packages/block-editor/src/components/rich-text/event-listeners/delete.js
@@ -6,7 +6,7 @@ import { isCollapsed, isEmpty } from '@wordpress/rich-text';
export default ( props ) => ( element ) => {
function onKeyDown( event ) {
- const { keyCode, shiftKey } = event;
+ const { keyCode, shiftKey, ctrlKey, metaKey } = event;
if ( event.defaultPrevented ) {
return;
@@ -30,8 +30,8 @@ export default ( props ) => ( element ) => {
return;
}
- // Exclude shift+backspace as they are shortcuts for deleting blocks.
- if ( shiftKey ) {
+ // Exclude (command|ctrl)+shift+backspace as they are shortcuts for deleting blocks.
+ if ( shiftKey && ( ctrlKey || metaKey ) ) {
return;
}
diff --git a/packages/block-editor/src/components/spacing-sizes-control/README.md b/packages/block-editor/src/components/spacing-sizes-control/README.md
new file mode 100644
index 0000000000000..c8e280c680712
--- /dev/null
+++ b/packages/block-editor/src/components/spacing-sizes-control/README.md
@@ -0,0 +1,93 @@
+# Spacing Sizes Control
+
+The SpacingSizesControl component provides a flexible user interface for controlling spacing values in blocks, allowing users to modify values for different sides. It supports three viewing modes:
+
+1. Single: Control one side at a time.
+2. Axial: Control horizontal and vertical sides together.
+3. Custom: Control each side separately.
+
+## Usage
+
+```jsx
+import { __experimentalSpacingSizesControl as SpacingSizesControl } from '@wordpress/block-editor';
+import { useState } from '@wordpress/element';
+
+function Example() {
+ const [ sides, setSides ] = useState( {
+ top: '0px',
+ right: '0px',
+ bottom: '0px',
+ left: '0px',
+ } );
+
+ return (
+
+ );
+}
+```
+
+## Props
+
+### `inputProps`
+
+- Type: `Object`
+- Required: No
+- Description: Additional props to pass to the input controls.
+
+### `label`
+
+- Type: `String`
+- Required: Yes
+- Description: Label for the control.
+
+### `minimumCustomValue`
+
+- Type: `Number`
+- Default: 0
+- Description: Minimum value allowed for custom input.
+
+### `onChange`
+
+- Type: `Function`
+- Required: Yes
+- Description: Callback function called when spacing values change. Receives an object containing the updated values.
+
+### `onMouseOut`
+
+- Type: `Function`
+- Required: No
+- Description: Callback function called when mouse leaves the control.
+
+### `onMouseOver`
+
+- Type: `Function`
+- Required: No
+- Description: Callback function called when mouse enters the control.
+
+### `showSideInLabel`
+
+- Type: `Boolean`
+- Default: true
+- Description: Whether to show the side (top, right, etc.) in the control label.
+
+### `sides`
+
+- Type: `Array`
+- Default: ALL_SIDES (top, right, bottom, left)
+- Description: Array of sides that can be controlled.
+
+### `useSelect`
+
+- Type: `Boolean`
+- Required: No
+- Description: Whether to use a select control for predefined values.
+
+### `values`
+
+- Type: `Object`
+- Required: No
+- Description: Object containing the current spacing values for each side.
diff --git a/packages/block-editor/src/components/spacing-sizes-control/index.js b/packages/block-editor/src/components/spacing-sizes-control/index.js
index 458b0abee60f2..5adbe5548556f 100644
--- a/packages/block-editor/src/components/spacing-sizes-control/index.js
+++ b/packages/block-editor/src/components/spacing-sizes-control/index.js
@@ -12,11 +12,11 @@ import { _x, sprintf } from '@wordpress/i18n';
/**
* Internal dependencies
*/
+import useSpacingSizes from './hooks/use-spacing-sizes';
import AxialInputControls from './input-controls/axial';
import SeparatedInputControls from './input-controls/separated';
import SingleInputControl from './input-controls/single';
import LinkedButton from './linked-button';
-import useSpacingSizes from './hooks/use-spacing-sizes';
import {
ALL_SIDES,
DEFAULT_VALUES,
@@ -25,6 +25,49 @@ import {
getInitialView,
} from './utils';
+/**
+ * A flexible control for managing spacing values in the block editor. Supports single, axial,
+ * and separated input controls for different spacing configurations with automatic view selection
+ * based on current values and available sides.
+ *
+ * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/spacing-sizes-control/README.md
+ *
+ * @example
+ * ```jsx
+ * import { __experimentalSpacingSizesControl as SpacingSizesControl } from '@wordpress/block-editor';
+ * import { useState } from '@wordpress/element';
+ *
+ * function Example() {
+ * const [ sides, setSides ] = useState( {
+ * top: '0px',
+ * right: '0px',
+ * bottom: '0px',
+ * left: '0px',
+ * } );
+ *
+ * return (
+ *
+ * );
+ * }
+ * ```
+ *
+ * @param {Object} props Component props.
+ * @param {Object} props.inputProps Additional props for input controls.
+ * @param {string} props.label Label for the control.
+ * @param {number} props.minimumCustomValue Minimum value for custom input.
+ * @param {Function} props.onChange Called when spacing values change.
+ * @param {Function} props.onMouseOut Called when mouse leaves the control.
+ * @param {Function} props.onMouseOver Called when mouse enters the control.
+ * @param {boolean} props.showSideInLabel Show side in control label.
+ * @param {Array} props.sides Available sides for control.
+ * @param {boolean} props.useSelect Use select control for predefined values.
+ * @param {Object} props.values Current spacing values.
+ * @return {Element} Spacing sizes control component.
+ */
export default function SpacingSizesControl( {
inputProps,
label: labelProp,
diff --git a/packages/block-editor/src/components/spacing-sizes-control/linked-button.js b/packages/block-editor/src/components/spacing-sizes-control/linked-button.js
index f6d56be66072a..413dc88a52e9b 100644
--- a/packages/block-editor/src/components/spacing-sizes-control/linked-button.js
+++ b/packages/block-editor/src/components/spacing-sizes-control/linked-button.js
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
-import { Button, Tooltip } from '@wordpress/components';
+import { Button } from '@wordpress/components';
import { link, linkOff } from '@wordpress/icons';
import { __ } from '@wordpress/i18n';
@@ -9,14 +9,12 @@ export default function LinkedButton( { isLinked, ...props } ) {
const label = isLinked ? __( 'Unlink sides' ) : __( 'Link sides' );
return (
-
-
-
+
);
}
diff --git a/packages/block-editor/src/components/spacing-sizes-control/test/utils.js b/packages/block-editor/src/components/spacing-sizes-control/test/utils.js
index a8440bb5be8ca..3692a1ea4c445 100644
--- a/packages/block-editor/src/components/spacing-sizes-control/test/utils.js
+++ b/packages/block-editor/src/components/spacing-sizes-control/test/utils.js
@@ -3,20 +3,15 @@
*/
import {
ALL_SIDES,
- getAllRawValue,
getCustomValueFromPreset,
getInitialView,
getPresetValueFromCustomValue,
getSliderValueFromPreset,
getSpacingPresetCssVar,
getSpacingPresetSlug,
- getSupportedMenuItems,
hasAxisSupport,
hasBalancedSidesSupport,
- isValuesDefined,
- isValuesMixed,
isValueSpacingPreset,
- LABELS,
VIEWS,
} from '../utils';
@@ -114,88 +109,6 @@ describe( 'getSliderValueFromPreset', () => {
} );
} );
-describe( 'getAllRawValue', () => {
- const customValues = {
- top: '5px',
- bottom: '5px',
- left: '6px',
- right: '2px',
- };
- it( 'should return the most common custom value from the values object', () => {
- expect( getAllRawValue( customValues ) ).toBe( '5px' );
- } );
- const presetValues = {
- top: 'var:preset|spacing|30',
- bottom: 'var:preset|spacing|20',
- left: 'var:preset|spacing|10',
- right: 'var:preset|spacing|30',
- };
- it( 'should return the most common preset value from the values object', () => {
- expect( getAllRawValue( presetValues ) ).toBe(
- 'var:preset|spacing|30'
- );
- } );
-} );
-
-describe( 'isValuesMixed', () => {
- const unmixedValues = {
- top: '5px',
- bottom: '5px',
- left: '5px',
- right: '5px',
- };
- it( 'should return false if all values are the same', () => {
- expect( isValuesMixed( unmixedValues ) ).toBe( false );
- } );
- const mixedValues = {
- top: 'var:preset|spacing|30',
- bottom: 'var:preset|spacing|20',
- left: 'var:preset|spacing|10',
- right: 'var:preset|spacing|30',
- };
- it( 'should return true if all the values are not the same', () => {
- expect( isValuesMixed( mixedValues ) ).toBe( true );
- } );
- const singleValue = {
- top: 'var:preset|spacing|30',
- };
- it( 'should return true if only one side set', () => {
- expect( isValuesMixed( singleValue ) ).toBe( true );
- } );
- const incompleteValues = {
- top: 'var:preset|spacing|30',
- bottom: 'var:preset|spacing|30',
- left: 'var:preset|spacing|30',
- };
- it( 'should return true if all sides not set', () => {
- expect( isValuesMixed( incompleteValues ) ).toBe( true );
- } );
-} );
-
-describe( 'isValuesDefined', () => {
- const undefinedValues = {
- top: undefined,
- bottom: undefined,
- left: undefined,
- right: undefined,
- };
- it( 'should return false if values are not defined', () => {
- expect( isValuesDefined( undefinedValues ) ).toBe( false );
- } );
- it( 'should return false if values is passed in as null', () => {
- expect( isValuesDefined( null ) ).toBe( false );
- } );
- const definedValues = {
- top: 'var:preset|spacing|30',
- bottom: 'var:preset|spacing|20',
- left: 'var:preset|spacing|10',
- right: 'var:preset|spacing|30',
- };
- it( 'should return true if all the values are not the same', () => {
- expect( isValuesDefined( definedValues ) ).toBe( true );
- } );
-} );
-
describe( 'hasAxisSupport', () => {
it( 'should return true for horizontal support if it is in sides', () => {
expect( hasAxisSupport( [ 'horizontal' ], 'horizontal' ) ).toBe( true );
@@ -228,70 +141,6 @@ describe( 'hasAxisSupport', () => {
} );
} );
-describe( 'getSupportedMenuItems', () => {
- it( 'returns no items when sides are not configured', () => {
- expect( getSupportedMenuItems( [] ) ).toEqual( {} );
- expect( getSupportedMenuItems() ).toEqual( {} );
- } );
-
- const sideConfigs = [
- [ LABELS.axial, [ 'horizontal', 'vertical' ] ],
- [ LABELS.axial, [ 'top', 'right', 'bottom', 'left' ] ],
- [ LABELS.horizontal, [ 'horizontal' ] ],
- [ LABELS.horizontal, [ 'left', 'right' ] ],
- [ LABELS.vertical, [ 'vertical' ] ],
- [ LABELS.vertical, [ 'top', 'bottom' ] ],
- [ LABELS.horizontal, [ 'horizontal' ] ],
- ];
-
- test.each( sideConfigs )(
- 'should include %s axial menu with %s sides',
- ( label, sides ) => {
- expect( getSupportedMenuItems( sides ) ).toHaveProperty(
- 'axial.label',
- label
- );
- }
- );
-
- it( 'returns no axial item when not not supported', () => {
- expect( getSupportedMenuItems( [ 'left', 'top' ] ) ).not.toHaveProperty(
- 'axial'
- );
- } );
-
- it( 'should include the correct individual side options', () => {
- expect( getSupportedMenuItems( [ 'top' ] ) ).toHaveProperty(
- 'top.label',
- LABELS.top
- );
- expect( getSupportedMenuItems( [ 'right' ] ) ).toHaveProperty(
- 'right.label',
- LABELS.right
- );
- expect( getSupportedMenuItems( [ 'bottom' ] ) ).toHaveProperty(
- 'bottom.label',
- LABELS.bottom
- );
- expect( getSupportedMenuItems( [ 'left' ] ) ).toHaveProperty(
- 'left.label',
- LABELS.left
- );
- } );
- it( 'should include the custom option only when applicable', () => {
- expect( getSupportedMenuItems( [ 'top', 'left' ] ) ).toHaveProperty(
- 'custom.label',
- LABELS.custom
- );
- expect( getSupportedMenuItems( [ 'top' ] ) ).not.toHaveProperty(
- 'custom'
- );
- expect(
- getSupportedMenuItems( [ 'horizontal', 'vertical' ] )
- ).not.toHaveProperty( 'custom.label' );
- } );
-} );
-
describe( 'hasBalancedSidesSupport', () => {
it( 'should determine balanced sides', () => {
expect( hasBalancedSidesSupport( ALL_SIDES ) ).toBe( true );
diff --git a/packages/block-editor/src/components/spacing-sizes-control/utils.js b/packages/block-editor/src/components/spacing-sizes-control/utils.js
index 046bee98761bf..9c803c0bef1ab 100644
--- a/packages/block-editor/src/components/spacing-sizes-control/utils.js
+++ b/packages/block-editor/src/components/spacing-sizes-control/utils.js
@@ -184,64 +184,6 @@ export function getSliderValueFromPreset( presetValue, spacingSizes ) {
return sliderValue !== -1 ? sliderValue : NaN;
}
-/**
- * Gets an items with the most occurrence within an array
- * https://stackoverflow.com/a/20762713
- *
- * @param {Array} arr Array of items to check.
- * @return {any} The item with the most occurrences.
- */
-function mode( arr ) {
- return arr
- .sort(
- ( a, b ) =>
- arr.filter( ( v ) => v === a ).length -
- arr.filter( ( v ) => v === b ).length
- )
- .pop();
-}
-
-/**
- * Gets the 'all' input value from values data.
- *
- * @param {Object} values Box spacing values
- *
- * @return {string} The most common value from all sides of box.
- */
-export function getAllRawValue( values = {} ) {
- return mode( Object.values( values ) );
-}
-
-/**
- * Checks to determine if values are mixed.
- *
- * @param {Object} values Box values.
- * @param {Array} sides Sides that values relate to.
- *
- * @return {boolean} Whether values are mixed.
- */
-export function isValuesMixed( values = {}, sides = ALL_SIDES ) {
- return (
- ( Object.values( values ).length >= 1 &&
- Object.values( values ).length < sides.length ) ||
- new Set( Object.values( values ) ).size > 1
- );
-}
-
-/**
- * Checks to determine if values are defined.
- *
- * @param {Object} values Box values.
- *
- * @return {boolean} Whether values are defined.
- */
-export function isValuesDefined( values ) {
- if ( values === undefined || values === null ) {
- return false;
- }
- return Object.values( values ).filter( ( value ) => !! value ).length > 0;
-}
-
/**
* Determines whether a particular axis has support. If no axis is
* specified, this function checks if either axis is supported.
@@ -275,54 +217,6 @@ export function hasAxisSupport( sides, axis ) {
return hasHorizontalSupport || hasVerticalSupport;
}
-/**
- * Determines which menu options should be included in the SidePicker.
- *
- * @param {Array} sides Supported sides.
- *
- * @return {Object} Menu options with each option containing label & icon.
- */
-export function getSupportedMenuItems( sides ) {
- if ( ! sides || ! sides.length ) {
- return {};
- }
-
- const menuItems = {};
-
- // Determine the primary "side" menu options.
- const hasHorizontalSupport = hasAxisSupport( sides, 'horizontal' );
- const hasVerticalSupport = hasAxisSupport( sides, 'vertical' );
-
- if ( hasHorizontalSupport && hasVerticalSupport ) {
- menuItems.axial = { label: LABELS.axial, icon: ICONS.axial };
- } else if ( hasHorizontalSupport ) {
- menuItems.axial = { label: LABELS.horizontal, icon: ICONS.horizontal };
- } else if ( hasVerticalSupport ) {
- menuItems.axial = { label: LABELS.vertical, icon: ICONS.vertical };
- }
-
- // Track whether we have any individual sides so we can omit the custom
- // option if required.
- let numberOfIndividualSides = 0;
-
- ALL_SIDES.forEach( ( side ) => {
- if ( sides.includes( side ) ) {
- numberOfIndividualSides += 1;
- menuItems[ side ] = {
- label: LABELS[ side ],
- icon: ICONS[ side ],
- };
- }
- } );
-
- // Add custom item if there are enough sides to warrant a separated view.
- if ( numberOfIndividualSides > 1 ) {
- menuItems.custom = { label: LABELS.custom, icon: ICONS.custom };
- }
-
- return menuItems;
-}
-
/**
* Checks if the supported sides are balanced for each axis.
* - Horizontal - both left and right sides are supported.
diff --git a/packages/block-editor/src/components/tool-selector/index.js b/packages/block-editor/src/components/tool-selector/index.js
index 8c4b5c86c4082..c4c216cbe68a7 100644
--- a/packages/block-editor/src/components/tool-selector/index.js
+++ b/packages/block-editor/src/components/tool-selector/index.js
@@ -95,7 +95,7 @@ function ToolSelector( props, ref ) {
{ __(
- 'Tools provide different sets of interactions for blocks. Toggle between simplified content tools (Write) and advanced visual editing tools (Design).'
+ 'Tools provide different sets of interactions for blocks. Choose between simplified content tools (Write) and advanced visual editing tools (Design).'
) }
-
-
- {
- // Some attributes are stored in an escaped form. It's a legacy issue.
- // Ideally they would be stored in a raw, unescaped form.
- // Unescape is used here to "recover" the escaped characters
- // so they display without encoding.
- // See `updateAttributes` for more details.
- `${ decodeEntities( label ) } ${
- isInvalid || isDraft
- ? placeholderText
- : ''
- }`.trim()
- }
-
-
+
+
+ {
+ // Some attributes are stored in an escaped form. It's a legacy issue.
+ // Ideally they would be stored in a raw, unescaped form.
+ // Unescape is used here to "recover" the escaped characters
+ // so they display without encoding.
+ // See `updateAttributes` for more details.
+ `${ decodeEntities( label ) } ${
+ isInvalid || isDraft
+ ? placeholderText
+ : ''
+ }`.trim()
+ }
+
) }
>
diff --git a/packages/block-library/src/navigation-link/editor.scss b/packages/block-library/src/navigation-link/editor.scss
index 84cd6f6d4ee36..b27c4520921fd 100644
--- a/packages/block-library/src/navigation-link/editor.scss
+++ b/packages/block-library/src/navigation-link/editor.scss
@@ -80,24 +80,33 @@
background-image: none !important;
// Draw a wavy underline.
- .wp-block-navigation-link__placeholder-text span {
- $blur: 10%;
- $width: 6%;
- $stop1: 30%;
- $stop2: 64%;
-
- --wp-underline-color: var(--wp-admin-theme-color);
-
- background-image:
- linear-gradient(45deg, transparent ($stop1 - $blur), var(--wp-underline-color) $stop1, var(--wp-underline-color) ($stop1 + $width), transparent ($stop1 + $width + $blur)),
- linear-gradient(135deg, transparent ($stop2 - $blur), var(--wp-underline-color) $stop2, var(--wp-underline-color) ($stop2 + $width), transparent ($stop2 + $width + $blur));
- background-position: 0 100%;
- background-size: 6px 3px;
- background-repeat: repeat-x;
-
- // Since applied to a span, it doesn't change the footprint of the item,
- // but it does vertically shift the underline to better align.
- padding-bottom: 0.1em;
+ .wp-block-navigation-link__placeholder-text {
+ span {
+ $blur: 10%;
+ $width: 6%;
+ $stop1: 30%;
+ $stop2: 64%;
+
+ --wp-underline-color: var(--wp-admin-theme-color);
+
+ background-image:
+ linear-gradient(45deg, transparent ($stop1 - $blur), var(--wp-underline-color) $stop1, var(--wp-underline-color) ($stop1 + $width), transparent ($stop1 + $width + $blur)),
+ linear-gradient(135deg, transparent ($stop2 - $blur), var(--wp-underline-color) $stop2, var(--wp-underline-color) ($stop2 + $width), transparent ($stop2 + $width + $blur));
+ background-position: 0 100%;
+ background-size: 6px 3px;
+ background-repeat: repeat-x;
+
+ // Since applied to a span, it doesn't change the footprint of the item,
+ // but it does vertically shift the underline to better align.
+ padding-bottom: 0.1em;
+ }
+
+ &.is-invalid,
+ &.is-draft {
+ span {
+ --wp-underline-color: #{$alert-red};
+ }
+ }
}
// This needs extra specificity.
diff --git a/packages/block-library/src/navigation-submenu/index.js b/packages/block-library/src/navigation-submenu/index.js
index 69e97fb85325a..f5eb1e2346d76 100644
--- a/packages/block-library/src/navigation-submenu/index.js
+++ b/packages/block-library/src/navigation-submenu/index.js
@@ -2,6 +2,7 @@
* WordPress dependencies
*/
import { page, addSubmenu } from '@wordpress/icons';
+import { _x } from '@wordpress/i18n';
/**
* Internal dependencies
@@ -37,6 +38,12 @@ export const settings = {
return label;
},
edit,
+ example: {
+ attributes: {
+ label: _x( 'About', 'Example link text for Navigation Submenu' ),
+ type: 'page',
+ },
+ },
save,
transforms,
};
diff --git a/packages/block-library/src/navigation-submenu/index.php b/packages/block-library/src/navigation-submenu/index.php
index 0f560e2849fac..016e708c3256e 100644
--- a/packages/block-library/src/navigation-submenu/index.php
+++ b/packages/block-library/src/navigation-submenu/index.php
@@ -82,7 +82,6 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
$font_sizes = block_core_navigation_submenu_build_css_font_sizes( $block->context );
$style_attribute = $font_sizes['inline_styles'];
- $css_classes = trim( implode( ' ', $font_sizes['css_classes'] ) );
$has_submenu = count( $block->inner_blocks ) > 0;
$kind = empty( $attributes['kind'] ) ? 'post_type' : str_replace( '-', '_', $attributes['kind'] );
$is_active = ! empty( $attributes['id'] ) && get_queried_object_id() === (int) $attributes['id'] && ! empty( get_queried_object()->$kind );
@@ -99,11 +98,29 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
$open_on_hover_and_click = isset( $block->context['openSubmenusOnClick'] ) && ! $block->context['openSubmenusOnClick'] &&
$show_submenu_indicators;
+ $classes = array(
+ 'wp-block-navigation-item',
+ );
+ $classes = array_merge(
+ $classes,
+ $font_sizes['css_classes']
+ );
+ if ( $has_submenu ) {
+ $classes[] = 'has-child';
+ }
+ if ( $open_on_click ) {
+ $classes[] = 'open-on-click';
+ }
+ if ( $open_on_hover_and_click ) {
+ $classes[] = 'open-on-hover-click';
+ }
+ if ( $is_active ) {
+ $classes[] = 'current-menu-item';
+ }
+
$wrapper_attributes = get_block_wrapper_attributes(
array(
- 'class' => $css_classes . ' wp-block-navigation-item' . ( $has_submenu ? ' has-child' : '' ) .
- ( $open_on_click ? ' open-on-click' : '' ) . ( $open_on_hover_and_click ? ' open-on-hover-click' : '' ) .
- ( $is_active ? ' current-menu-item' : '' ),
+ 'class' => implode( ' ', $classes ),
'style' => $style_attribute,
)
);
diff --git a/packages/block-library/src/navigation/edit/use-convert-classic-menu-to-block-menu.js b/packages/block-library/src/navigation/edit/use-convert-classic-menu-to-block-menu.js
index 300672fa91e8a..0984f601959a0 100644
--- a/packages/block-library/src/navigation/edit/use-convert-classic-menu-to-block-menu.js
+++ b/packages/block-library/src/navigation/edit/use-convert-classic-menu-to-block-menu.js
@@ -47,7 +47,7 @@ function useConvertClassicToBlockMenu(
} catch ( err ) {
throw new Error(
sprintf(
- // translators: %s: the name of a menu (e.g. Header navigation).
+ // translators: %s: The name of a menu (e.g. Header menu).
__( `Unable to fetch classic menu "%s" from API.` ),
menuName
),
@@ -61,7 +61,7 @@ function useConvertClassicToBlockMenu(
if ( classicMenuItems === null ) {
throw new Error(
sprintf(
- // translators: %s: the name of a menu (e.g. Header navigation).
+ // translators: %s: The name of a menu (e.g. Header menu).
__( `Unable to fetch classic menu "%s" from API.` ),
menuName
)
@@ -98,7 +98,7 @@ function useConvertClassicToBlockMenu(
} catch ( err ) {
throw new Error(
sprintf(
- // translators: %s: the name of a menu (e.g. Header navigation).
+ // translators: %s: The name of a menu (e.g. Header menu).
__( `Unable to create Navigation Menu "%s".` ),
menuName
),
@@ -155,7 +155,7 @@ function useConvertClassicToBlockMenu(
if ( throwOnError ) {
throw new Error(
sprintf(
- // translators: %s: the name of a menu (e.g. Header navigation).
+ // translators: %s: The name of a menu (e.g. Header menu).
__( `Unable to create Navigation Menu "%s".` ),
menuName
),
diff --git a/packages/block-library/src/navigation/edit/use-generate-default-navigation-title.js b/packages/block-library/src/navigation/edit/use-generate-default-navigation-title.js
index 0a134a256e664..9784a5fd75a6b 100644
--- a/packages/block-library/src/navigation/edit/use-generate-default-navigation-title.js
+++ b/packages/block-library/src/navigation/edit/use-generate-default-navigation-title.js
@@ -50,12 +50,12 @@ export default function useGenerateDefaultNavigationTitle( clientId ) {
const title = area
? sprintf(
- // translators: %s: the name of a menu (e.g. Header navigation).
- __( '%s navigation' ),
+ // translators: %s: the name of a menu (e.g. Header menu).
+ __( '%s menu' ),
area
)
- : // translators: 'navigation' as in website navigation.
- __( 'Navigation' );
+ : // translators: 'menu' as in website navigation menu.
+ __( 'Menu' );
// Determine how many menus start with the automatic title.
const matchingMenuTitleCount = [
diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php
index 43ca833153427..d52b67b7e1958 100644
--- a/packages/block-library/src/navigation/index.php
+++ b/packages/block-library/src/navigation/index.php
@@ -241,11 +241,12 @@ private static function get_inner_blocks_from_navigation_post( $attributes ) {
// it encounters whitespace. This code strips it.
$blocks = block_core_navigation_filter_out_empty_blocks( $parsed_blocks );
- // Run Block Hooks algorithm to inject hooked blocks.
- $markup = block_core_navigation_insert_hooked_blocks( $blocks, $navigation_post );
- $root_nav_block = parse_blocks( $markup )[0];
-
- $blocks = isset( $root_nav_block['innerBlocks'] ) ? $root_nav_block['innerBlocks'] : $blocks;
+ // Re-serialize, and run Block Hooks algorithm to inject hooked blocks.
+ // TODO: See if we can move the apply_block_hooks_to_content_from_post_object() call
+ // before the parse_blocks() call further above, to avoid the extra serialization/parsing.
+ $markup = serialize_blocks( $blocks );
+ $markup = apply_block_hooks_to_content_from_post_object( $markup, $navigation_post );
+ $blocks = parse_blocks( $markup );
// TODO - this uses the full navigation block attributes for the
// context which could be refined.
@@ -1077,12 +1078,11 @@ function block_core_navigation_get_fallback_blocks() {
// Run Block Hooks algorithm to inject hooked blocks.
// We have to run it here because we need the post ID of the Navigation block to track ignored hooked blocks.
- $markup = block_core_navigation_insert_hooked_blocks( $fallback_blocks, $navigation_post );
- $blocks = parse_blocks( $markup );
-
- if ( isset( $blocks[0]['innerBlocks'] ) ) {
- $fallback_blocks = $blocks[0]['innerBlocks'];
- }
+ // TODO: See if we can move the apply_block_hooks_to_content_from_post_object() call
+ // before the parse_blocks() call further above, to avoid the extra serialization/parsing.
+ $markup = serialize_blocks( $fallback_blocks );
+ $markup = apply_block_hooks_to_content_from_post_object( $markup, $navigation_post );
+ $fallback_blocks = parse_blocks( $markup );
}
/**
@@ -1436,61 +1436,3 @@ function block_core_navigation_get_most_recently_published_navigation() {
return null;
}
-
-/**
- * Mock a parsed block for the Navigation block given its inner blocks and the `wp_navigation` post object.
- * The `wp_navigation` post's `_wp_ignored_hooked_blocks` meta is queried to add the `metadata.ignoredHookedBlocks` attribute.
- *
- * @since 6.5.0
- *
- * @param array $inner_blocks Parsed inner blocks of a Navigation block.
- * @param WP_Post $post `wp_navigation` post object corresponding to the block.
- *
- * @return array the normalized parsed blocks.
- */
-function block_core_navigation_mock_parsed_block( $inner_blocks, $post ) {
- $attributes = array();
-
- if ( isset( $post->ID ) ) {
- $ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true );
- if ( ! empty( $ignored_hooked_blocks ) ) {
- $ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true );
- $attributes['metadata'] = array(
- 'ignoredHookedBlocks' => $ignored_hooked_blocks,
- );
- }
- }
-
- $mock_anchor_parent_block = array(
- 'blockName' => 'core/navigation',
- 'attrs' => $attributes,
- 'innerBlocks' => $inner_blocks,
- 'innerContent' => array_fill( 0, count( $inner_blocks ), null ),
- );
-
- return $mock_anchor_parent_block;
-}
-
-/**
- * Insert hooked blocks into a Navigation block.
- *
- * Given a Navigation block's inner blocks and its corresponding `wp_navigation` post object,
- * this function inserts hooked blocks into it, and returns the serialized inner blocks in a
- * mock Navigation block wrapper.
- *
- * If there are any hooked blocks that need to be inserted as the Navigation block's first or last
- * children, the `wp_navigation` post's `_wp_ignored_hooked_blocks` meta is checked to see if any
- * of those hooked blocks should be exempted from insertion.
- *
- * @since 6.5.0
- *
- * @param array $inner_blocks Parsed inner blocks of a Navigation block.
- * @param WP_Post $post `wp_navigation` post object corresponding to the block.
- * @return string Serialized inner blocks in mock Navigation block wrapper, with hooked blocks inserted, if any.
- */
-function block_core_navigation_insert_hooked_blocks( $inner_blocks, $post ) {
- $mock_navigation_block = block_core_navigation_mock_parsed_block( $inner_blocks, $post );
-
- $mock_navigation_block_markup = serialize_block( $mock_navigation_block );
- return apply_block_hooks_to_content( $mock_navigation_block_markup, $post, 'insert_hooked_blocks' );
-}
diff --git a/packages/block-library/src/post-content/index.php b/packages/block-library/src/post-content/index.php
index e0a06b7217eeb..25be880cc4788 100644
--- a/packages/block-library/src/post-content/index.php
+++ b/packages/block-library/src/post-content/index.php
@@ -46,33 +46,10 @@ function render_block_core_post_content( $attributes, $content, $block ) {
$content .= wp_link_pages( array( 'echo' => 0 ) );
}
- $ignored_hooked_blocks = get_post_meta( $post_id, '_wp_ignored_hooked_blocks', true );
- if ( ! empty( $ignored_hooked_blocks ) ) {
- $ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true );
- $attributes['metadata'] = array(
- 'ignoredHookedBlocks' => $ignored_hooked_blocks,
- );
- }
-
- // Wrap in Post Content block so the Block Hooks algorithm can insert blocks
- // that are hooked as first or last child of `core/post-content`.
- $content = get_comment_delimited_block_content(
- 'core/post-content',
- $attributes,
- $content
- );
-
- // We need to remove the `core/post-content` block wrapper after the Block Hooks algorithm,
- // but before `do_blocks` runs, as it would otherwise attempt to render the same block again --
- // thus recursing infinitely.
- add_filter( 'the_content', 'remove_serialized_parent_block', 8 );
-
/** This filter is documented in wp-includes/post-template.php */
$content = apply_filters( 'the_content', str_replace( ']]>', ']]>', $content ) );
unset( $seen_ids[ $post_id ] );
- remove_filter( 'the_content', 'remove_serialized_parent_block', 8 );
-
if ( empty( $content ) ) {
return '';
}
diff --git a/packages/block-library/src/post-featured-image/dimension-controls.js b/packages/block-library/src/post-featured-image/dimension-controls.js
index 9a71a96b2db84..4bc343635f2f9 100644
--- a/packages/block-library/src/post-featured-image/dimension-controls.js
+++ b/packages/block-library/src/post-featured-image/dimension-controls.js
@@ -10,19 +10,7 @@ import {
__experimentalUseCustomUnits as useCustomUnits,
__experimentalToolsPanelItem as ToolsPanelItem,
} from '@wordpress/components';
-import {
- useSettings,
- privateApis as blockEditorPrivateApis,
- store as blockEditorStore,
-} from '@wordpress/block-editor';
-import { useSelect } from '@wordpress/data';
-
-/**
- * Internal dependencies
- */
-import { unlock } from '../lock-unlock';
-
-const { ResolutionTool } = unlock( blockEditorPrivateApis );
+import { useSettings } from '@wordpress/block-editor';
const SCALE_OPTIONS = (
<>
@@ -45,7 +33,6 @@ const SCALE_OPTIONS = (
);
const DEFAULT_SCALE = 'cover';
-const DEFAULT_SIZE = 'full';
const scaleHelp = {
cover: __(
@@ -61,9 +48,8 @@ const scaleHelp = {
const DimensionControls = ( {
clientId,
- attributes: { aspectRatio, width, height, scale, sizeSlug },
+ attributes: { aspectRatio, width, height, scale },
setAttributes,
- media,
} ) => {
const [ availableUnits, defaultRatios, themeRatios, showDefaultRatios ] =
useSettings(
@@ -75,18 +61,6 @@ const DimensionControls = ( {
const units = useCustomUnits( {
availableUnits: availableUnits || [ 'px', '%', 'vw', 'em', 'rem' ],
} );
- const imageSizes = useSelect(
- ( select ) => select( blockEditorStore ).getSettings().imageSizes,
- []
- );
- const imageSizeOptions = imageSizes
- .filter( ( { slug } ) => {
- return media?.media_details?.sizes?.[ slug ]?.source_url;
- } )
- .map( ( { name, slug } ) => ( {
- value: slug,
- label: name,
- } ) );
const onDimensionChange = ( dimension, nextValue ) => {
const parsedValue = parseFloat( nextValue );
@@ -230,21 +204,6 @@ const DimensionControls = ( {
) }
- { !! imageSizeOptions.length && (
-
- setAttributes( { sizeSlug: nextSizeSlug } )
- }
- isShownByDefault={ false }
- resetAllFilter={ () => ( {
- sizeSlug: DEFAULT_SIZE,
- } ) }
- />
- ) }
>
);
};
diff --git a/packages/block-library/src/post-featured-image/edit.js b/packages/block-library/src/post-featured-image/edit.js
index 05888c41fecf2..9fd64b29908e4 100644
--- a/packages/block-library/src/post-featured-image/edit.js
+++ b/packages/block-library/src/post-featured-image/edit.js
@@ -27,6 +27,8 @@ import {
__experimentalUseBorderProps as useBorderProps,
__experimentalGetShadowClassesAndStyles as getShadowClassesAndStyles,
useBlockEditingMode,
+ privateApis as blockEditorPrivateApis,
+ store as blockEditorStore,
} from '@wordpress/block-editor';
import { useMemo, useEffect, useState } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
@@ -40,20 +42,40 @@ import DimensionControls from './dimension-controls';
import OverlayControls from './overlay-controls';
import Overlay from './overlay';
import { useToolsPanelDropdownMenuProps } from '../utils/hooks';
+import { unlock } from '../lock-unlock';
const ALLOWED_MEDIA_TYPES = [ 'image' ];
+const { ResolutionTool } = unlock( blockEditorPrivateApis );
+const DEFAULT_MEDIA_SIZE_SLUG = 'full';
+
+function FeaturedImageResolutionTool( { image, value, onChange } ) {
+ const { imageSizes } = useSelect( ( select ) => {
+ const { getSettings } = select( blockEditorStore );
+ return {
+ imageSizes: getSettings().imageSizes,
+ };
+ }, [] );
+
+ if ( ! imageSizes?.length ) {
+ return null;
+ }
+
+ const imageSizeOptions = imageSizes
+ .filter(
+ ( { slug } ) => image?.media_details?.sizes?.[ slug ]?.source_url
+ )
+ .map( ( { name, slug } ) => ( { value: slug, label: name } ) );
-function getMediaSourceUrlBySizeSlug( media, slug ) {
return (
- media?.media_details?.sizes?.[ slug ]?.source_url || media?.source_url
+
);
}
-const disabledClickProps = {
- onClick: ( event ) => event.preventDefault(),
- 'aria-disabled': true,
-};
-
export default function PostFeaturedImageEdit( {
clientId,
attributes,
@@ -130,7 +152,9 @@ export default function PostFeaturedImageEdit( {
[ featuredImage, postTypeSlug, postId ]
);
- const mediaUrl = getMediaSourceUrlBySizeSlug( media, sizeSlug );
+ const mediaUrl =
+ media?.media_details?.sizes?.[ sizeSlug ]?.source_url ||
+ media?.source_url;
const blockProps = useBlockProps( {
style: { width, height, aspectRatio },
@@ -296,6 +320,13 @@ export default function PostFeaturedImageEdit( {
/>
) }
+
+ setAttributes( { sizeSlug: nextSizeSlug } )
+ }
+ />
>
@@ -318,11 +349,7 @@ export default function PostFeaturedImageEdit( {
{ controls }
{ !! isLink ? (
-
+
{ placeholder() }
) : (
@@ -430,11 +457,7 @@ export default function PostFeaturedImageEdit( {
{ /* If the featured image is linked, wrap in an tag to trigger any inherited link element styles */ }
{ !! isLink ? (
-
+
{ image }
) : (
diff --git a/packages/block-library/src/post-featured-image/editor.scss b/packages/block-library/src/post-featured-image/editor.scss
index 5fab62c571b1c..3295fe14e62ac 100644
--- a/packages/block-library/src/post-featured-image/editor.scss
+++ b/packages/block-library/src/post-featured-image/editor.scss
@@ -100,9 +100,9 @@
// When the Post Featured Image block is linked,
// it's wrapped with a disabled tag.
- // Restore cursor style so it doesn't appear 'clickable'.
+ // Ensure that the link is not clickable.
> a {
- cursor: default;
+ pointer-events: none;
}
// When the Post Featured Image block is linked,
diff --git a/packages/block-library/src/post-template/edit.js b/packages/block-library/src/post-template/edit.js
index c58990233f361..35d0a95501a1b 100644
--- a/packages/block-library/src/post-template/edit.js
+++ b/packages/block-library/src/post-template/edit.js
@@ -177,18 +177,27 @@ export default function PostTemplateEdit( {
query.format = format;
}
- // If sticky is not set, it will return all posts in the results.
- // If sticky is set to `only`, it will limit the results to sticky posts only.
- // If it is anything else, it will exclude sticky posts from results. For the record the value stored is `exclude`.
- if ( sticky ) {
+ /*
+ * Handle cases where sticky is set to `exclude` or `only`.
+ * Which works as a `post__in/post__not_in` query for sticky posts.
+ */
+ if ( sticky && sticky !== 'ignore' ) {
query.sticky = sticky === 'only';
}
+
+ if ( sticky === 'ignore' ) {
+ // Remove any leftover sticky query parameter.
+ delete query.sticky;
+ query.ignore_sticky = true;
+ }
+
// If `inherit` is truthy, adjust conditionally the query to create a better preview.
+ let currentPostType = postType;
if ( inherit ) {
// Change the post-type if needed.
if ( templateSlug?.startsWith( 'archive-' ) ) {
query.postType = templateSlug.replace( 'archive-', '' );
- postType = query.postType;
+ currentPostType = query.postType;
} else if ( templateCategory ) {
query.categories = templateCategory[ 0 ]?.id;
} else if ( templateTag ) {
@@ -205,7 +214,7 @@ export default function PostTemplateEdit( {
}
// When we preview Query Loop blocks we should prefer the current
// block's postType, which is passed through block context.
- const usedPostType = previewPostType || postType;
+ const usedPostType = previewPostType || currentPostType;
return {
posts: getEntityRecords( 'postType', usedPostType, {
...query,
diff --git a/packages/block-library/src/query/edit/inspector-controls/sticky-control.js b/packages/block-library/src/query/edit/inspector-controls/sticky-control.js
index ee7ee31ba977a..f478337998f38 100644
--- a/packages/block-library/src/query/edit/inspector-controls/sticky-control.js
+++ b/packages/block-library/src/query/edit/inspector-controls/sticky-control.js
@@ -6,6 +6,7 @@ import { __ } from '@wordpress/i18n';
const stickyOptions = [
{ label: __( 'Include' ), value: '' },
+ { label: __( 'Ignore' ), value: 'ignore' },
{ label: __( 'Exclude' ), value: 'exclude' },
{ label: __( 'Only' ), value: 'only' },
];
diff --git a/packages/block-library/src/rss/block.json b/packages/block-library/src/rss/block.json
index 844104b7d8113..112dec4a32c78 100644
--- a/packages/block-library/src/rss/block.json
+++ b/packages/block-library/src/rss/block.json
@@ -47,6 +47,20 @@
"interactivity": {
"clientNavigation": true
},
+ "__experimentalBorder": {
+ "radius": true,
+ "color": true,
+ "width": true,
+ "style": true
+ },
+ "spacing": {
+ "margin": true,
+ "padding": true,
+ "__experimentalDefaultControls": {
+ "padding": false,
+ "margin": false
+ }
+ },
"color": {
"background": true,
"text": true,
diff --git a/packages/block-library/src/rss/edit.js b/packages/block-library/src/rss/edit.js
index 39564da79b16e..d931bc8cb01d8 100644
--- a/packages/block-library/src/rss/edit.js
+++ b/packages/block-library/src/rss/edit.js
@@ -119,6 +119,19 @@ export default function RSSEdit( { attributes, setAttributes } ) {
},
];
+ /*
+ * This function merges the existing attributes with additional style properties.
+ * The `border` and `spacing` properties are set to `undefined` to ensure that
+ * these styles are reset and not applied on the server side.
+ */
+ const serverSideAttributes = {
+ ...attributes,
+ style: {
+ ...attributes?.style,
+ border: undefined,
+ spacing: undefined,
+ },
+ };
return (
<>
@@ -190,7 +203,7 @@ export default function RSSEdit( { attributes, setAttributes } ) {
diff --git a/packages/block-library/src/rss/editor.scss b/packages/block-library/src/rss/editor.scss
index c5e79d6254460..83fef1d73f4f3 100644
--- a/packages/block-library/src/rss/editor.scss
+++ b/packages/block-library/src/rss/editor.scss
@@ -5,3 +5,10 @@
.wp-block-rss__placeholder-form .wp-block-rss__placeholder-input {
flex: 1 1 auto;
}
+// Reset all styles when skipping block supports while server-side rendering.
+// This prevents issues such as duplicate padding, borders etc.
+.wp-block-rss .wp-block-rss {
+ all: inherit;
+ margin: 0;
+ padding: 0;
+}
diff --git a/packages/block-library/src/rss/style.scss b/packages/block-library/src/rss/style.scss
index f7360ec76f85a..76cc232044ff3 100644
--- a/packages/block-library/src/rss/style.scss
+++ b/packages/block-library/src/rss/style.scss
@@ -1,11 +1,4 @@
ul.wp-block-rss { // The ul is needed for specificity to override the reset styles in the editor.
- list-style: none;
- padding: 0;
-
- // This needs extra specificity due to the reset mixin on the parent: https://github.com/WordPress/gutenberg/blob/a250e9e5fe00dd5195624f96a3d924e7078951c3/packages/edit-post/src/style.scss#L54
- &.wp-block-rss {
- box-sizing: border-box;
- }
&.alignleft {
/*rtl:ignore*/
@@ -19,7 +12,6 @@ ul.wp-block-rss { // The ul is needed for specificity to override the reset styl
display: flex;
flex-wrap: wrap;
padding: 0;
- list-style: none;
li {
margin: 0 1em 1em 0;
@@ -41,3 +33,9 @@ ul.wp-block-rss { // The ul is needed for specificity to override the reset styl
display: block;
font-size: 0.8125em;
}
+.wp-block-rss {
+ // This block has customizable padding, border-box makes that more predictable.
+ box-sizing: border-box;
+ list-style: none;
+ padding: 0;
+}
diff --git a/packages/block-library/src/site-logo/edit.js b/packages/block-library/src/site-logo/edit.js
index d2d2327736fd7..f1ba371bfb35e 100644
--- a/packages/block-library/src/site-logo/edit.js
+++ b/packages/block-library/src/site-logo/edit.js
@@ -499,11 +499,6 @@ export default function LogoEdit( {
};
const onFilesDrop = ( filesList ) => {
- if ( filesList?.length > 1 ) {
- onUploadError( __( 'Only one image can be used as a site logo.' ) );
- return;
- }
-
getSettings().mediaUpload( {
allowedTypes: ALLOWED_MEDIA_TYPES,
filesList,
@@ -515,6 +510,7 @@ export default function LogoEdit( {
onInitialSelectLogo( image );
},
onError: onUploadError,
+ multiple: false,
} );
};
diff --git a/packages/block-library/src/social-link/editor.scss b/packages/block-library/src/social-link/editor.scss
index d61cf7c1a7cf5..af818d82eba49 100644
--- a/packages/block-library/src/social-link/editor.scss
+++ b/packages/block-library/src/social-link/editor.scss
@@ -16,6 +16,7 @@
height: auto;
font-weight: inherit;
font-family: inherit;
+ margin: 0;
// This rule ensures social link buttons display correctly in template parts.
opacity: 1;
diff --git a/packages/block-library/src/social-link/icons/discord.js b/packages/block-library/src/social-link/icons/discord.js
new file mode 100644
index 0000000000000..6cb6165515369
--- /dev/null
+++ b/packages/block-library/src/social-link/icons/discord.js
@@ -0,0 +1,10 @@
+/**
+ * WordPress dependencies
+ */
+import { Path, SVG } from '@wordpress/primitives';
+
+export const DiscordIcon = () => (
+
+);
diff --git a/packages/block-library/src/social-link/icons/index.js b/packages/block-library/src/social-link/icons/index.js
index 422ff6f02dd20..bcc1976a7efb0 100644
--- a/packages/block-library/src/social-link/icons/index.js
+++ b/packages/block-library/src/social-link/icons/index.js
@@ -5,6 +5,7 @@ export * from './bluesky';
export * from './chain';
export * from './codepen';
export * from './deviantart';
+export * from './discord';
export * from './dribbble';
export * from './dropbox';
export * from './etsy';
diff --git a/packages/block-library/src/social-link/index.php b/packages/block-library/src/social-link/index.php
index f241daff2a11a..9775f6dece5d7 100644
--- a/packages/block-library/src/social-link/index.php
+++ b/packages/block-library/src/social-link/index.php
@@ -169,6 +169,10 @@ function block_core_social_link_services( $service = '', $field = '' ) {
'name' => 'DeviantArt',
'icon' => '',
),
+ 'discord' => array(
+ 'name' => 'Discord',
+ 'icon' => '',
+ ),
'dribbble' => array(
'name' => 'Dribbble',
'icon' => '',
diff --git a/packages/block-library/src/social-link/socials-with-bg.scss b/packages/block-library/src/social-link/socials-with-bg.scss
index 35420fc624c0e..b51b718459739 100644
--- a/packages/block-library/src/social-link/socials-with-bg.scss
+++ b/packages/block-library/src/social-link/socials-with-bg.scss
@@ -33,6 +33,11 @@
color: #fff;
}
+.wp-social-link-discord {
+ background-color: #5865f2;
+ color: #fff;
+}
+
.wp-social-link-dribbble {
background-color: #e94c89;
color: #fff;
diff --git a/packages/block-library/src/social-link/socials-without-bg.scss b/packages/block-library/src/social-link/socials-without-bg.scss
index 24538b29824b1..12b8620efb9f7 100644
--- a/packages/block-library/src/social-link/socials-without-bg.scss
+++ b/packages/block-library/src/social-link/socials-without-bg.scss
@@ -22,6 +22,10 @@
color: #02e49b;
}
+.wp-social-link-discord {
+ color: #5865f2;
+}
+
.wp-social-link-dribbble {
color: #e94c89;
}
diff --git a/packages/block-library/src/social-link/variations.js b/packages/block-library/src/social-link/variations.js
index a97a396882d76..59fb469181449 100644
--- a/packages/block-library/src/social-link/variations.js
+++ b/packages/block-library/src/social-link/variations.js
@@ -9,6 +9,7 @@ import {
ChainIcon,
CodepenIcon,
DeviantArtIcon,
+ DiscordIcon,
DribbbleIcon,
DropboxIcon,
EtsyIcon,
@@ -108,6 +109,12 @@ const variations = [
title: 'DeviantArt',
icon: DeviantArtIcon,
},
+ {
+ name: 'discord',
+ attributes: { service: 'discord' },
+ title: 'Discord',
+ icon: DiscordIcon,
+ },
{
name: 'dribbble',
attributes: { service: 'dribbble' },
diff --git a/packages/block-library/src/social-links/editor.scss b/packages/block-library/src/social-links/editor.scss
index 11f1ed86d1122..6b1286c94757d 100644
--- a/packages/block-library/src/social-links/editor.scss
+++ b/packages/block-library/src/social-links/editor.scss
@@ -89,7 +89,6 @@
// Unconfigured placeholder links are semitransparent.
.wp-social-link.wp-social-link__is-incomplete {
opacity: 0.5;
- @include reduce-motion("transition");
}
.wp-block-social-links .is-selected .wp-social-link__is-incomplete,
@@ -101,6 +100,10 @@
.wp-block-social-links .block-list-appender {
position: static; // display inline.
+ .block-editor-inserter {
+ font-size: inherit;
+ }
+
.block-editor-button-block-appender {
height: 1.5em;
width: 1.5em;
diff --git a/packages/block-library/src/spacer/controls.js b/packages/block-library/src/spacer/controls.js
index b5f73a259419d..8ebc2b825bee0 100644
--- a/packages/block-library/src/spacer/controls.js
+++ b/packages/block-library/src/spacer/controls.js
@@ -44,10 +44,6 @@ function DimensionInput( { label, onChange, isResizing, value = '' } ) {
defaultValues: { px: 100, em: 10, rem: 10, vw: 10, vh: 25 },
} );
- const handleOnChange = ( unprocessedValue ) => {
- onChange( unprocessedValue.all );
- };
-
// Force the unit to update to `px` when the Spacer is being resized.
const [ parsedQuantity, parsedUnit ] =
parseQuantityAndUnitFromRawValue( value );
@@ -57,23 +53,24 @@ function DimensionInput( { label, onChange, isResizing, value = '' } ) {
return (
<>
- { ( ! spacingSizes || spacingSizes?.length === 0 ) && (
+ { spacingSizes?.length < 2 ? (
- ) }
- { spacingSizes?.length > 0 && (
+ ) : (
{
+ onChange( all );
+ } }
label={ label }
sides={ [ 'all' ] }
units={ units }
diff --git a/packages/block-library/src/spacer/edit.js b/packages/block-library/src/spacer/edit.js
index 1e0ffb9700d68..b2de69ad9a6a8 100644
--- a/packages/block-library/src/spacer/edit.js
+++ b/packages/block-library/src/spacer/edit.js
@@ -16,7 +16,7 @@ import {
import { ResizableBox } from '@wordpress/components';
import { useState, useEffect } from '@wordpress/element';
import { View } from '@wordpress/primitives';
-import { useSelect } from '@wordpress/data';
+import { useSelect, useDispatch } from '@wordpress/data';
/**
* Internal dependencies
@@ -124,6 +124,9 @@ const SpacerEdit = ( {
const onResizeStart = () => toggleSelection( false );
const onResizeStop = () => toggleSelection( true );
+ const { __unstableMarkNextChangeAsNotPersistent } =
+ useDispatch( blockEditorStore );
+
const handleOnVerticalResizeStop = ( newHeight ) => {
onResizeStop();
@@ -256,11 +259,19 @@ const SpacerEdit = ( {
};
useEffect( () => {
+ // To avoid interfering with undo/redo operations any changes in this
+ // effect must not make history and should be preceded by
+ // `__unstableMarkNextChangeAsNotPersistent()`.
+ const setAttributesCovertly = ( nextAttributes ) => {
+ __unstableMarkNextChangeAsNotPersistent();
+ setAttributes( nextAttributes );
+ };
+
if (
isFlexLayout &&
selfStretch !== 'fill' &&
selfStretch !== 'fit' &&
- ! flexSize
+ flexSize === undefined
) {
if ( inheritedOrientation === 'horizontal' ) {
// If spacer is moving from a vertical container to a horizontal container,
@@ -269,7 +280,7 @@ const SpacerEdit = ( {
getCustomValueFromPreset( width, spacingSizes ) ||
getCustomValueFromPreset( height, spacingSizes ) ||
'100px';
- setAttributes( {
+ setAttributesCovertly( {
width: '0px',
style: {
...blockStyle,
@@ -285,7 +296,7 @@ const SpacerEdit = ( {
getCustomValueFromPreset( height, spacingSizes ) ||
getCustomValueFromPreset( width, spacingSizes ) ||
'100px';
- setAttributes( {
+ setAttributesCovertly( {
height: '0px',
style: {
...blockStyle,
@@ -301,26 +312,16 @@ const SpacerEdit = ( {
isFlexLayout &&
( selfStretch === 'fill' || selfStretch === 'fit' )
) {
- if ( inheritedOrientation === 'horizontal' ) {
- setAttributes( {
- width: undefined,
- } );
- } else {
- setAttributes( {
- height: undefined,
- } );
- }
+ setAttributesCovertly(
+ inheritedOrientation === 'horizontal'
+ ? { width: undefined }
+ : { height: undefined }
+ );
} else if ( ! isFlexLayout && ( selfStretch || flexSize ) ) {
- if ( inheritedOrientation === 'horizontal' ) {
- setAttributes( {
- width: flexSize,
- } );
- } else {
- setAttributes( {
- height: flexSize,
- } );
- }
- setAttributes( {
+ setAttributesCovertly( {
+ ...( inheritedOrientation === 'horizontal'
+ ? { width: flexSize }
+ : { height: flexSize } ),
style: {
...blockStyle,
layout: {
@@ -342,6 +343,7 @@ const SpacerEdit = ( {
setAttributes,
spacingSizes,
width,
+ __unstableMarkNextChangeAsNotPersistent,
] );
return (
diff --git a/packages/block-serialization-default-parser/CHANGELOG.md b/packages/block-serialization-default-parser/CHANGELOG.md
index e35805be07d06..c6d17488c91f2 100644
--- a/packages/block-serialization-default-parser/CHANGELOG.md
+++ b/packages/block-serialization-default-parser/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 5.18.0 (2025-02-12)
+
+## 5.17.0 (2025-01-29)
+
## 5.16.0 (2025-01-15)
## 5.15.0 (2025-01-02)
diff --git a/packages/block-serialization-default-parser/package.json b/packages/block-serialization-default-parser/package.json
index 4fc3bff8afb64..742d5c10804ff 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.16.0",
+ "version": "5.18.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 285ee69d78310..d9db0a9c0b54a 100644
--- a/packages/block-serialization-spec-parser/CHANGELOG.md
+++ b/packages/block-serialization-spec-parser/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 5.18.0 (2025-02-12)
+
+## 5.17.0 (2025-01-29)
+
## 5.16.0 (2025-01-15)
## 5.15.0 (2025-01-02)
diff --git a/packages/block-serialization-spec-parser/package.json b/packages/block-serialization-spec-parser/package.json
index e9ac344ff34a1..03251c27157ca 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.16.0",
+ "version": "5.18.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 bf63c0089bb8e..b83f66306873e 100644
--- a/packages/blocks/CHANGELOG.md
+++ b/packages/blocks/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+## 14.7.0 (2025-02-12)
+
+## 14.6.0 (2025-01-29)
+
## 14.5.0 (2025-01-15)
## 14.4.0 (2025-01-02)
diff --git a/packages/blocks/package.json b/packages/blocks/package.json
index 5940cfbeb4664..8a0dc2f8c03c4 100644
--- a/packages/blocks/package.json
+++ b/packages/blocks/package.json
@@ -1,6 +1,6 @@
{
"name": "@wordpress/blocks",
- "version": "14.5.0",
+ "version": "14.7.0",
"description": "Block API for WordPress.",
"author": "The WordPress Contributors",
"license": "GPL-2.0-or-later",
diff --git a/packages/blocks/src/api/parser/apply-built-in-validation-fixes.js b/packages/blocks/src/api/parser/apply-built-in-validation-fixes.js
index 13dbb1e6825c9..52d6583265e6b 100644
--- a/packages/blocks/src/api/parser/apply-built-in-validation-fixes.js
+++ b/packages/blocks/src/api/parser/apply-built-in-validation-fixes.js
@@ -2,6 +2,7 @@
* Internal dependencies
*/
import { fixCustomClassname } from './fix-custom-classname';
+import { fixAriaLabel } from './fix-aria-label';
/**
* Attempts to fix block invalidation by applying build-in validation fixes
@@ -15,11 +16,22 @@ import { fixCustomClassname } from './fix-custom-classname';
* @return {WPBlock} Fixed block object
*/
export function applyBuiltInValidationFixes( block, blockType ) {
- const updatedBlockAttributes = fixCustomClassname(
- block.attributes,
+ const { attributes, originalContent } = block;
+ let updatedBlockAttributes = attributes;
+
+ // Fix block invalidation for className attribute.
+ updatedBlockAttributes = fixCustomClassname(
+ attributes,
+ blockType,
+ originalContent
+ );
+ // Fix block invalidation for ariaLabel attribute.
+ updatedBlockAttributes = fixAriaLabel(
+ updatedBlockAttributes,
blockType,
- block.originalContent
+ originalContent
);
+
return {
...block,
attributes: updatedBlockAttributes,
diff --git a/packages/blocks/src/api/parser/fix-aria-label.js b/packages/blocks/src/api/parser/fix-aria-label.js
new file mode 100644
index 0000000000000..79fa30c713da2
--- /dev/null
+++ b/packages/blocks/src/api/parser/fix-aria-label.js
@@ -0,0 +1,51 @@
+/**
+ * Internal dependencies
+ */
+import { hasBlockSupport } from '../registration';
+import { parseWithAttributeSchema } from './get-block-attributes';
+
+const ARIA_LABEL_ATTR_SCHEMA = {
+ type: 'string',
+ source: 'attribute',
+ selector: '[data-aria-label] > *',
+ attribute: 'aria-label',
+};
+
+/**
+ * Given an HTML string, returns the aria-label attribute assigned to
+ * the root element in the markup.
+ *
+ * @param {string} innerHTML Markup string from which to extract the aria-label.
+ *
+ * @return {string} The aria-label assigned to the root element.
+ */
+export function getHTMLRootElementAriaLabel( innerHTML ) {
+ const parsed = parseWithAttributeSchema(
+ `