diff --git a/bin/plugin/commands/performance.js b/bin/plugin/commands/performance.js
index 31a537f373731..81aa39820c8b5 100644
--- a/bin/plugin/commands/performance.js
+++ b/bin/plugin/commands/performance.js
@@ -37,6 +37,7 @@ const config = require( '../config' );
* @property {number[]} firstContentfulPaint Represents the time when the browser first renders any text or media.
* @property {number[]} firstBlock Represents the time when Puppeteer first sees a block selector in the DOM.
* @property {number[]} type Average type time.
+ * @property {number[]} typeContainer Average type time within a container.
* @property {number[]} focus Average block selection time.
* @property {number[]} inserterOpen Average time to open global inserter.
* @property {number[]} inserterSearch Average time to search the inserter.
@@ -56,6 +57,9 @@ const config = require( '../config' );
* @property {number=} type Average type time.
* @property {number=} minType Minimum type time.
* @property {number=} maxType Maximum type time.
+ * @property {number=} typeContainer Average type time within a container.
+ * @property {number=} minTypeContainer Minimum type time within a container.
+ * @property {number=} maxTypeContainer Maximum type time within a container.
* @property {number=} focus Average block selection time.
* @property {number=} minFocus Min block selection time.
* @property {number=} maxFocus Max block selection time.
@@ -129,6 +133,9 @@ function curateResults( results ) {
type: average( results.type ),
minType: Math.min( ...results.type ),
maxType: Math.max( ...results.type ),
+ typeContainer: average( results.typeContainer ),
+ minTypeContainer: Math.min( ...results.typeContainer ),
+ maxTypeContainer: Math.max( ...results.typeContainer ),
focus: average( results.focus ),
minFocus: Math.min( ...results.focus ),
maxFocus: Math.max( ...results.focus ),
@@ -393,6 +400,15 @@ async function runPerformanceTests( branches, options ) {
type: rawResults.map( ( r ) => r[ branch ].type ),
minType: rawResults.map( ( r ) => r[ branch ].minType ),
maxType: rawResults.map( ( r ) => r[ branch ].maxType ),
+ typeContainer: rawResults.map(
+ ( r ) => r[ branch ].typeContainer
+ ),
+ minTypeContainer: rawResults.map(
+ ( r ) => r[ branch ].minTypeContainer
+ ),
+ maxTypeContainer: rawResults.map(
+ ( r ) => r[ branch ].maxTypeContainer
+ ),
focus: rawResults.map( ( r ) => r[ branch ].focus ),
minFocus: rawResults.map( ( r ) => r[ branch ].minFocus ),
maxFocus: rawResults.map( ( r ) => r[ branch ].maxFocus ),
diff --git a/changelog.txt b/changelog.txt
index 5427245e8d468..8774c72580adf 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,5 +1,327 @@
== Changelog ==
+= 14.8.0-rc.1 =
+
+## Changelog
+
+### Enhancements
+
+#### Block Library
+- Add a current-menu-ancestor class to navigation items. ([40778](https://github.com/WordPress/gutenberg/pull/40778))
+- Page List Block: Adds a longdash tree to the parent selector. ([46336](https://github.com/WordPress/gutenberg/pull/46336))
+- Page List Block: Hide page list edit button if no pages are available. ([46331](https://github.com/WordPress/gutenberg/pull/46331))
+- Reusable block: Pluralize the message "Convert to regular blocks" depending on the number of blocks contained. ([45819](https://github.com/WordPress/gutenberg/pull/45819))
+- Add page list to Link UI transforms in Nav block. ([46426](https://github.com/WordPress/gutenberg/pull/46426))
+- Heading Block: Don't rely on the experimental selector anymore. ([46284](https://github.com/WordPress/gutenberg/pull/46284))
+- Media & Text Block: Create undo history when media width is changed. ([46084](https://github.com/WordPress/gutenberg/pull/46084))
+- Navigation block: Add location->primary to fallback nav creation for classic menus. ([45976](https://github.com/WordPress/gutenberg/pull/45976))
+- Navigation block: Update fallback nav creation to the most recently created menu. ([46286](https://github.com/WordPress/gutenberg/pull/46286))
+- Navigation: Add a 'open list view' button. ([46335](https://github.com/WordPress/gutenberg/pull/46335))
+- Navigation: Removes the header from the navigation list view in the experiment. ([46070](https://github.com/WordPress/gutenberg/pull/46070))
+- Page List: Add convert panel to Inspector Controls when within Nav block. ([46352](https://github.com/WordPress/gutenberg/pull/46352))
+- Page List: Prevent users from adding inner blocks to Page List. ([46269](https://github.com/WordPress/gutenberg/pull/46269))
+- Query: Remove color block supports. ([46147](https://github.com/WordPress/gutenberg/pull/46147))
+- Table block: Make `figcaption` styles consistent between editor and front end. ([46172](https://github.com/WordPress/gutenberg/pull/46172))
+- List/quote: Unwrap inner block when pressing Backspace at start. ([45075](https://github.com/WordPress/gutenberg/pull/45075))
+
+#### Inspector Controls
+- Sidebar Tabs: Refine the use of inspector tabs and disable filters for Nav blocks. ([46346](https://github.com/WordPress/gutenberg/pull/46346))
+- Sidebar Tabs: Use editor settings to override display. ([46321](https://github.com/WordPress/gutenberg/pull/46321))
+- Summary panel: Try improving spacing and grid. ([46267](https://github.com/WordPress/gutenberg/pull/46267))
+
+#### Global Styles
+- Add Style Book to Global Styles. ([45960](https://github.com/WordPress/gutenberg/pull/45960))
+- Add block preview component in global styles. ([45719](https://github.com/WordPress/gutenberg/pull/45719))
+- Move border from layout to own menu. ([45995](https://github.com/WordPress/gutenberg/pull/45995))
+- Add a css style to theme.json to allow setting of custom css strings. ([46255](https://github.com/WordPress/gutenberg/pull/46255))
+- Expose before filter hook in useSettings for injecting block settings in the editor. ([45089](https://github.com/WordPress/gutenberg/pull/45089))
+- Global styles: Add custom CSS panel to site editor. ([46141](https://github.com/WordPress/gutenberg/pull/46141))
+
+#### Site Editor
+- Allow adding new templates and template parts directly from the sidebar. ([46458](https://github.com/WordPress/gutenberg/pull/46458))
+- Synchronize the sidebar state in the URL. ([46433](https://github.com/WordPress/gutenberg/pull/46433))
+- Try template drill down on the shell sidebar (browse mode). ([45100](https://github.com/WordPress/gutenberg/pull/45100))
+
+#### Block Editor
+- Update the synced block hover styles in Inserter. ([46442](https://github.com/WordPress/gutenberg/pull/46442))
+- Add new selector getLastInsertedBlockClientId. ([46531](https://github.com/WordPress/gutenberg/pull/46531))
+- Block editor: Hide fixed contextual toolbar. ([46298](https://github.com/WordPress/gutenberg/pull/46298))
+- Inserter: Pattern title tooltip. ([46419](https://github.com/WordPress/gutenberg/pull/46419))
+- useNestedSettingsUpdate: Prevent unneeded syncing of falsy templateLock values. ([46357](https://github.com/WordPress/gutenberg/pull/46357))
+- Design: Augmented shadows for modals and popovers. ([46228](https://github.com/WordPress/gutenberg/pull/46228))
+
+#### Components
+- Tabs: Try a simpler tab focus style, alt. ([46276](https://github.com/WordPress/gutenberg/pull/46276))
+- BaseControl: Add convenience hook to generate id-related props. ([46170](https://github.com/WordPress/gutenberg/pull/46170))
+- Dashicon: Refactor to TypeScript. ([45924](https://github.com/WordPress/gutenberg/pull/45924))
+- Lighten borders to gray-600. ([46252](https://github.com/WordPress/gutenberg/pull/46252))
+- Popover: Check positioning by adding and testing is-positioned class. ([46429](https://github.com/WordPress/gutenberg/pull/46429))
+
+### Icons
+- Icons: Update the border icon. ([46264](https://github.com/WordPress/gutenberg/pull/46264))
+
+#### Testing
+- Tests: Fix `toBePositionedPopover` matcher message function. ([46239](https://github.com/WordPress/gutenberg/pull/46239))
+
+#### Accessibility
+- Reorganize the site editor to introduce Browse Mode. ([44770](https://github.com/WordPress/gutenberg/pull/44770))
+
+#### Plugin
+- Update the Gutenberg plugin to require at least the WP 6.0 version. ([46102](https://github.com/WordPress/gutenberg/pull/46102))
+- PHP: Backport changes from core theme resolver. ([46250](https://github.com/WordPress/gutenberg/pull/46250))
+- Update: Move gutenberg_register_core_block_patterns from 6.1 to 6.2. ([46249](https://github.com/WordPress/gutenberg/pull/46249))
+- Upgrade React packages to v18. ([45235](https://github.com/WordPress/gutenberg/pull/45235))
+
+#### Themes
+- Empty Theme: Add the `$schema` property in `theme.json` and rename template directories. ([46300](https://github.com/WordPress/gutenberg/pull/46300))
+
+#### Mobile
+- Mobile: Disable Unsupported Block Editor Tests (Android). ([46542](https://github.com/WordPress/gutenberg/pull/46542))
+- Mobile: Inserter - Remove `.done()` usage. ([46460](https://github.com/WordPress/gutenberg/pull/46460))
+- Mobile: Update Heading block end-to-end test. ([46220](https://github.com/WordPress/gutenberg/pull/46220))
+- Mobile: Updates packages to not use Git HTTPS URLs. ([46422](https://github.com/WordPress/gutenberg/pull/46422))
+
+### Bug Fixes
+
+#### Block Library
+- Fix Nav Submenu block Link UI text control. ([46243](https://github.com/WordPress/gutenberg/pull/46243))
+- Fix auto Nav menu creation due to page list inner blocks. ([46223](https://github.com/WordPress/gutenberg/pull/46223))
+- Handle innerContent too when removing innerBlocks. ([46377](https://github.com/WordPress/gutenberg/pull/46377))
+- Image Block: Ensure drag handle matches cursor position when resizing a center aligned image. ([46497](https://github.com/WordPress/gutenberg/pull/46497))
+- Navigation Block: Add social link singular to list of blocks to be allowed. ([46374](https://github.com/WordPress/gutenberg/pull/46374))
+- Navigation Block: Fixes adding a submenu. ([46364](https://github.com/WordPress/gutenberg/pull/46364))
+- Navigation Block: Prevent circular references in navigation block rendering. ([46387](https://github.com/WordPress/gutenberg/pull/46387))
+- Navigation Block: Recursively remove Navigation block’s from appearing inside Navigation block on front of site. ([46279](https://github.com/WordPress/gutenberg/pull/46279))
+- Navigation link: Use stripHTML. ([46317](https://github.com/WordPress/gutenberg/pull/46317))
+- Page List Block: Fix error loading page list parent options. ([46327](https://github.com/WordPress/gutenberg/pull/46327))
+- Query Loop Block: Add migration of colors to v2 deprecation. ([46522](https://github.com/WordPress/gutenberg/pull/46522))
+- Site Logo: Correctly set the image's natural height and width. ([46214](https://github.com/WordPress/gutenberg/pull/46214))
+- Strip markup from link label data in inspector. ([46171](https://github.com/WordPress/gutenberg/pull/46171))
+- Template Parts: Fix modal search stacking context. ([46421](https://github.com/WordPress/gutenberg/pull/46421))
+- Video: Avoid an error when removal is locked. ([46324](https://github.com/WordPress/gutenberg/pull/46324))
+- Layout child fixed size should not be fixed by default and should always have a value set. ([46139](https://github.com/WordPress/gutenberg/pull/46139))
+
+#### Blocks
+- Paste handler: Remove styles on inline paste. ([46402](https://github.com/WordPress/gutenberg/pull/46402))
+- Improve performance of gutenberg_render_layout_support_flag. ([46074](https://github.com/WordPress/gutenberg/pull/46074))
+
+#### Global Styles
+- Allow indirect properties when unfiltered_html is not allowed. ([46388](https://github.com/WordPress/gutenberg/pull/46388))
+- Fix Reset to defaults action by moving fills to be within context provider. ([46486](https://github.com/WordPress/gutenberg/pull/46486))
+- Fix duplication of synced block colors in CSS output. ([46297](https://github.com/WordPress/gutenberg/pull/46297))
+- Make style book label font size 11px. ([46341](https://github.com/WordPress/gutenberg/pull/46341))
+- Style Book: Clear Global Styles navigation history when selecting a block. ([46391](https://github.com/WordPress/gutenberg/pull/46391))
+
+#### Block Editor
+- Block Editor: Fix content locked patterns. ([46494](https://github.com/WordPress/gutenberg/pull/46494))
+- Block Editor: Fix memoized pattern selector dependant arguments. ([46238](https://github.com/WordPress/gutenberg/pull/46238))
+- Block Editor: Restore draggable chip styles. ([46396](https://github.com/WordPress/gutenberg/pull/46396))
+- Block Editor: Revert deoptimization useNestedSettingsUpdate. ([46350](https://github.com/WordPress/gutenberg/pull/46350))
+- Block Editor: Fix some usages of useSelect that return unstable results. ([46226](https://github.com/WordPress/gutenberg/pull/46226))
+- useInnerBlockTemplateSync: Cancel template sync on innerBlocks change or unmount. ([46307](https://github.com/WordPress/gutenberg/pull/46307))
+
+#### Patterns
+- Add new pattern categories. ([46144](https://github.com/WordPress/gutenberg/pull/46144))
+- Block Editor: Add initial view mode in `BlockPatternSetup`. ([46399](https://github.com/WordPress/gutenberg/pull/46399))
+
+#### Site Editor
+- Do not remount iframe. ([46431](https://github.com/WordPress/gutenberg/pull/46431))
+- Fix the top bar 'exit' animation. ([46533](https://github.com/WordPress/gutenberg/pull/46533))
+- Keep edited entity in sync when Editor canvas isn't mounted. ([46524](https://github.com/WordPress/gutenberg/pull/46524))
+- [Site Editor]: Add default white background for themes with no `background color` set. ([46314](https://github.com/WordPress/gutenberg/pull/46314))
+
+#### Components
+- InputControl: Fix `Flex` wrapper usage. ([46213](https://github.com/WordPress/gutenberg/pull/46213))
+- Modal: Fix unexpected modal closing in IME Composition. ([46453](https://github.com/WordPress/gutenberg/pull/46453))
+- MaybeCategoryPanel: Avoid 403 requests for users with low permissions. ([46349](https://github.com/WordPress/gutenberg/pull/46349))
+- Rich text: Add button to clear unknown format. ([44086](https://github.com/WordPress/gutenberg/pull/44086))
+
+#### Document Settings
+- Fix template title in `summary` panel and requests for low privileged users. ([46304](https://github.com/WordPress/gutenberg/pull/46304))
+- Permalink: Hide edit field for users without publishing capabilities. ([46361](https://github.com/WordPress/gutenberg/pull/46361))
+
+#### Patterns
+- Content lock: Make filter hook namespace unique. ([46344](https://github.com/WordPress/gutenberg/pull/46344))
+
+#### Layout
+- Child Layout controls: Fix help text for height. ([46319](https://github.com/WordPress/gutenberg/pull/46319))
+
+#### Widgets Editor
+- Shortcuts: Add Ctrl+Y for redo to all editor instances on Windows. ([43392](https://github.com/WordPress/gutenberg/pull/43392))
+
+#### Block API
+- HTML block: Fix parsing. ([27268](https://github.com/WordPress/gutenberg/pull/27268))
+
+#### Mobile
+- Social Links mobile test: Wait for URL bottom sheet to appear. ([46308](https://github.com/WordPress/gutenberg/pull/46308))
+
+### Performance
+
+#### Components
+- Avoid paint on popover when hovering content. ([46201](https://github.com/WordPress/gutenberg/pull/46201))
+- CircularOption: Avoid paint on circular option hover. ([46197](https://github.com/WordPress/gutenberg/pull/46197))
+- Lodash: Replace `_.isEqual()` with `fastDeepEqual`. ([46200](https://github.com/WordPress/gutenberg/pull/46200))
+- Popover: Avoid paint on popovers when scrolling. ([46187](https://github.com/WordPress/gutenberg/pull/46187))
+- Resizable Box: Avoid paint on resizable-box handles. ([46196](https://github.com/WordPress/gutenberg/pull/46196))
+- ListView: Avoid paint on list view item hover. ([46188](https://github.com/WordPress/gutenberg/pull/46188))
+
+#### Code Quality
+- Lodash: Refactor `blocks` away from `_.find()`. ([46428](https://github.com/WordPress/gutenberg/pull/46428))
+- Lodash: Refactor `core-data` away from `_.find()`. ([46468](https://github.com/WordPress/gutenberg/pull/46468))
+- Lodash: Refactor `edit-site` away from `_.find()`. ([46539](https://github.com/WordPress/gutenberg/pull/46539))
+- Lodash: Refactor away from `_.orderBy()`. ([45146](https://github.com/WordPress/gutenberg/pull/45146))
+- Lodash: Refactor block library away from `_.find()`. ([46430](https://github.com/WordPress/gutenberg/pull/46430))
+- Remove usage of get_default_block_editor_settings. ([46112](https://github.com/WordPress/gutenberg/pull/46112))
+
+#### Post Editor
+- Lodash: Refactor editor away from `_.find()`. ([46464](https://github.com/WordPress/gutenberg/pull/46464))
+- Lodash: Refactor post editor away from `_.find()`. ([46432](https://github.com/WordPress/gutenberg/pull/46432))
+
+#### Block Editor
+- Avoid paint on inserter animation. ([46185](https://github.com/WordPress/gutenberg/pull/46185))
+- Improve inserter search performance. ([46153](https://github.com/WordPress/gutenberg/pull/46153))
+- Block Editor: Refactor the "order" state in the block editor reducer to use a map instead of a plain object. ([46221](https://github.com/WordPress/gutenberg/pull/46221))
+- Block Editor: Refactor the block-editor parents state to use maps instead of objects. ([46225](https://github.com/WordPress/gutenberg/pull/46225))
+- Refactor the block-editor "tree" state to use maps instead of objects. ([46229](https://github.com/WordPress/gutenberg/pull/46229))
+- Refactor the block-editor byClientId redux state to use maps instead of plain objects. ([46204](https://github.com/WordPress/gutenberg/pull/46204))
+- Fix typing performance issue for container blocks. ([46527](https://github.com/WordPress/gutenberg/pull/46527))
+
+#### Testing
+- E2E: Fix performance tests by making inserter search container waiting optional. ([46268](https://github.com/WordPress/gutenberg/pull/46268))
+
+#### Mobile
+- Columns mobile block: Avoid returning unstable innerWidths from useSelect. ([46403](https://github.com/WordPress/gutenberg/pull/46403))
+
+### Experiments
+
+#### Block Library
+- Navigation List View: Remove empty cell when there is no edit button. ([46439](https://github.com/WordPress/gutenberg/pull/46439))
+
+#### Web Fonts
+- WP Webfonts: Avoid duplicated font families if the font family name was defined using fallback values. ([46378](https://github.com/WordPress/gutenberg/pull/46378))
+
+### Documentation
+- Adds clarifications and clears up inaccuracies. ([46283](https://github.com/WordPress/gutenberg/pull/46283))
+- Adds details of how to find the .zip file. ([46305](https://github.com/WordPress/gutenberg/pull/46305))
+- Doc: Fix description and documentation for link color support. ([46405](https://github.com/WordPress/gutenberg/pull/46405))
+- Docs: Add missing useState import in BorderBoxControl documentation. ([42067](https://github.com/WordPress/gutenberg/pull/42067))
+- Docs: Add missing useState import in color picker docs. ([42069](https://github.com/WordPress/gutenberg/pull/42069))
+- Docs: Add missing useState import in confirm dialog docs. ([42071](https://github.com/WordPress/gutenberg/pull/42071))
+- Docs: Adds reminder to use Node.js v14 in Quick Start. ([46216](https://github.com/WordPress/gutenberg/pull/46216))
+- Docs: Fix missing link to `primitives` package. ([46290](https://github.com/WordPress/gutenberg/pull/46290))
+- Docs: Update reference to IE 11. ([46296](https://github.com/WordPress/gutenberg/pull/46296))
+
+### Code Quality
+- Block Editor: Fix `no-node-access` violations in `BlockPreview`. ([46409](https://github.com/WordPress/gutenberg/pull/46409))
+- Block Editor: Fix `no-node-access` violations in `BlockSelectionClearer`. ([46408](https://github.com/WordPress/gutenberg/pull/46408))
+- Columns mobile edit: Remove unused updateBlockSettings action bind. ([46455](https://github.com/WordPress/gutenberg/pull/46455))
+- ESLint: Fix warning in `getBlockAttribute` documentation. ([46500](https://github.com/WordPress/gutenberg/pull/46500))
+- List View: Use default parameters instead of defaultProps. ([46266](https://github.com/WordPress/gutenberg/pull/46266))
+- Removed: Remove small APIs marked to be removed in WP 6.2. ([46106](https://github.com/WordPress/gutenberg/pull/46106))
+- Site Editor: Remove invalid CSS. ([46288](https://github.com/WordPress/gutenberg/pull/46288))
+
+#### Block Library
+- Group Block: Remove placeholder leftovers. ([46423](https://github.com/WordPress/gutenberg/pull/46423))
+- Group: Remove unnecessary 'useCallback'. ([46418](https://github.com/WordPress/gutenberg/pull/46418))
+- Navigation Block: Add tests for Nav block uncontrolled blocks dirty state checking. ([46329](https://github.com/WordPress/gutenberg/pull/46329))
+- Navigation Block: Update attribute test for `are-blocks-dirty.js`. ([46355](https://github.com/WordPress/gutenberg/pull/46355))
+- Page List Block: Move shared "convert" description to constant. ([46368](https://github.com/WordPress/gutenberg/pull/46368))
+- Page List Block: Simplify Page List convert to links function API. ([46365](https://github.com/WordPress/gutenberg/pull/46365))
+- Query: Cleanup variation picker component. ([46424](https://github.com/WordPress/gutenberg/pull/46424))
+- RNMobile: Add an inline comment to clarify usage of 'hard' limit vs. unbounded query. ([46245](https://github.com/WordPress/gutenberg/pull/46245))
+- Shared standard Link UI component between Nav Link and Submenu blocks. ([46370](https://github.com/WordPress/gutenberg/pull/46370))
+- Template Parts: Remove unnecessary 'useCallback'. ([46420](https://github.com/WordPress/gutenberg/pull/46420))
+
+#### Components
+- AlignmentMatrixControl: Refactor to TypeScript. ([46162](https://github.com/WordPress/gutenberg/pull/46162))
+- Also ignore `no-node-access` for some components. ([46501](https://github.com/WordPress/gutenberg/pull/46501))
+- Fix `no-node-access` violations in `FocalPointPicker` tests. ([46312](https://github.com/WordPress/gutenberg/pull/46312))
+- Fix `no-node-access` violations in `Popover`. ([46311](https://github.com/WordPress/gutenberg/pull/46311))
+- Fix `no-node-access` violations in `Theme`. ([46310](https://github.com/WordPress/gutenberg/pull/46310))
+- Fix `no-node-access` violations in `ToolsPanel` tests. ([46313](https://github.com/WordPress/gutenberg/pull/46313))
+- withFilters: Use 'act' from React Testing Library. ([46237](https://github.com/WordPress/gutenberg/pull/46237))
+
+#### Data Layer
+- Data: Add ability to subscribe to one store, remove __unstableSubscribeStore. ([45513](https://github.com/WordPress/gutenberg/pull/45513))
+- ESLint: Fix warnings in the data package. ([46499](https://github.com/WordPress/gutenberg/pull/46499))
+
+#### Global Styles
+- Add "custom-css" as an acceptable value in the documentation for gutenberg_get_global_stylesheet. ([46493](https://github.com/WordPress/gutenberg/pull/46493))
+- PaletteEdit: Add changelog. ([46095](https://github.com/WordPress/gutenberg/pull/46095))
+
+#### Block Editor
+- Inserter: Update mobile tab navigation styles. ([46186](https://github.com/WordPress/gutenberg/pull/46186))
+
+#### Layout
+- Clarify inline comment about switching to `safecss_filter_attr`. ([46061](https://github.com/WordPress/gutenberg/pull/46061))
+
+### Tools
+
+#### Build Tooling
+- Adds Github Action to validate Gradle Wrapper. ([46247](https://github.com/WordPress/gutenberg/pull/46247))
+- Prevent api-fetch and core-data from being imported in the block editor package. ([46302](https://github.com/WordPress/gutenberg/pull/46302))
+- Serialize the map objects properly in the Redux dev tools. ([46282](https://github.com/WordPress/gutenberg/pull/46282))
+
+#### Testing
+- E2E: Fix flaky Block Switcher tests. ([46406](https://github.com/WordPress/gutenberg/pull/46406))
+- end-to-end tests: Add width and color test to button block. ([46452](https://github.com/WordPress/gutenberg/pull/46452))
+
+
+## First time contributors
+
+The following PRs were merged by first time contributors:
+
+- @corentin-gautier: Avoid paint on popover when hovering content. ([46201](https://github.com/WordPress/gutenberg/pull/46201))
+- @ingeniumed: Expose before filter hook in useSettings for injecting block settings in the editor. ([45089](https://github.com/WordPress/gutenberg/pull/45089))
+- @janusqa: Reusable block: Pluralize the message "Convert to regular blocks" depending on the number of blocks contained. ([45819](https://github.com/WordPress/gutenberg/pull/45819))
+
+
+## Contributors
+
+The following contributors merged PRs in this release:
+
+@aaronrobertshaw @ajlende @andrewserong @aristath @chad1008 @chintu51 @corentin-gautier @derekblank @draganescu @ellatrix @geriux @getdave @glendaviesnz @hideokamoto @ingeniumed @jameskoster @janusqa @jasmussen @jffng @jorgefilipecosta @jsnajdr @madhusudhand @MaggieCabrera @Mamaduka @matiasbenedetto @mburridge @mikachan @mirka @noisysocks @ntsekouras @oandregal @oguzkocer @ramonjd @scruffian @SiobhyB @spacedmonkey @t-hamano @talldan @tellthemachines @tyxla @WunderBart @youknowriad
+
+
+= 14.7.3 =
+
+## Changelog
+
+### Bug fixes
+
+- Fix typing performance issue for container blocks. ([46527](https://github.com/WordPress/gutenberg/pull/46527))
+
+## Contributors
+
+The following contributors merged PRs in this release:
+
+@youknowriad
+
+
+= 14.7.2 =
+
+
+
+## Changelog
+
+### Bug Fixes
+
+- Fix fatal error when using the plugin with PHP 8 and WordPress 6.0 by checking if block_type asset properties are set. ([46488](https://github.com/WordPress/gutenberg/pull/46488))
+
+
+## First time contributors
+
+The following PRs were merged by first time contributors:
+
+
+
+## Contributors
+
+The following contributors merged PRs in this release:
+
+@noahtallen
+
+
= 14.7.1 =
diff --git a/docs/contributors/code/release.md b/docs/contributors/code/release.md
index f463cb319f665..492813376b2c9 100644
--- a/docs/contributors/code/release.md
+++ b/docs/contributors/code/release.md
@@ -34,6 +34,10 @@ To release a release candidate (RC) version of the plugin, enter `rc`. To releas
This will trigger a GitHub Actions (GHA) workflow that bumps the plugin version, builds the Gutenberg plugin .zip file, creates a release draft, and attaches the plugin .zip file to it. This part of the process typically takes a little under six minutes. You'll see that workflow appear at the top of the list, right under the blue banner. Once it's finished, it'll change its status icon from a yellow dot to a green checkmark. You can follow along in a more detailed view by clicking on the workflow.
+#### Publishing the @wordpress packages to NPM
+
+As part of the release candidate (RC) process, all of the `@wordpress` packages are published to NPM. You may see messaging after the ["Build Gutenberg Plugin Zip" action](https://github.com/WordPress/gutenberg/actions/workflows/build-plugin-zip.yml) action has created the draft release that the ["Publish npm packages"](https://github.com/WordPress/gutenberg/actions/workflows/publish-npm-packages.yml) action requires someone with appropriate permissions to trigger the action. This is not the case as this process is automated and it will automatically run after the release notes are published.
+
#### View the release draft
As soon as the workflow has finished, you'll find the release draft under [https://github.com/WordPress/gutenberg/releases](https://github.com/WordPress/gutenberg/releases). The draft is pre-populated with changelog entries based on previous release candidates for this version, and any changes that have since been cherry-picked to the release branch. Thus, when releasing the first stable version of a series, make sure to delete any RC version headers (that are only there for your information) and to move the more recent changes to the correct section (see below).
diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md
index 5320ec1731941..ce574465a5a15 100644
--- a/docs/reference-guides/core-blocks.md
+++ b/docs/reference-guides/core-blocks.md
@@ -428,7 +428,7 @@ Display a list of all pages. ([Source](https://github.com/WordPress/gutenberg/tr
- **Name:** core/page-list
- **Category:** widgets
-- **Supports:** ~~html~~, ~~reusable~~
+- **Supports:** typography (fontSize, lineHeight), ~~html~~, ~~reusable~~
- **Attributes:** parentPageID
## Page List Item
@@ -572,7 +572,7 @@ Contains the block elements used to render a post, like the title, date, feature
- **Name:** core/post-template
- **Category:** theme
-- **Supports:** align, typography (fontSize, lineHeight), ~~html~~, ~~reusable~~
+- **Supports:** align, color (background, gradients, link, text), typography (fontSize, lineHeight), ~~html~~, ~~reusable~~
- **Attributes:**
## Post Terms
@@ -617,7 +617,7 @@ An advanced block that allows displaying post types based on different query par
- **Name:** core/query
- **Category:** theme
-- **Supports:** align (full, wide), color (background, gradients, link, text), ~~html~~
+- **Supports:** align (full, wide), ~~html~~
- **Attributes:** displayLayout, namespace, query, queryId, tagName
## No results
diff --git a/docs/reference-guides/data/data-core-block-editor.md b/docs/reference-guides/data/data-core-block-editor.md
index 5123dc6adc131..0580aa0141b2b 100644
--- a/docs/reference-guides/data/data-core-block-editor.md
+++ b/docs/reference-guides/data/data-core-block-editor.md
@@ -556,6 +556,18 @@ _Properties_
- _isDisabled_ `boolean`: Whether or not the user should be prevented from inserting this item.
- _frecency_ `number`: Heuristic that combines frequency and recency.
+### getLastInsertedBlockClientId
+
+Gets the client id of the last inserted block.
+
+_Parameters_
+
+- _state_ `Object`: Global application state.
+
+_Returns_
+
+- `string|undefined`: Client Id of the last inserted block.
+
### getLastMultiSelectedBlockClientId
Returns the client ID of the last block in the multi-selection set, or null
diff --git a/docs/reference-guides/theme-json-reference/theme-json-living.md b/docs/reference-guides/theme-json-reference/theme-json-living.md
index a694cf63e909f..9b074edace6ae 100644
--- a/docs/reference-guides/theme-json-reference/theme-json-living.md
+++ b/docs/reference-guides/theme-json-reference/theme-json-living.md
@@ -119,7 +119,7 @@ Settings related to typography.
| customFontSize | boolean | true | |
| fontStyle | boolean | true | |
| fontWeight | boolean | true | |
-| fluid | boolean | | |
+| fluid | undefined | false | |
| letterSpacing | boolean | true | |
| lineHeight | boolean | false | |
| textDecoration | boolean | true | |
diff --git a/gutenberg.php b/gutenberg.php
index c5f94c50522db..4d4489ef4c061 100644
--- a/gutenberg.php
+++ b/gutenberg.php
@@ -5,7 +5,7 @@
* Description: Printing since 1440. This is the development plugin for the new block editor in core.
* Requires at least: 6.0
* Requires PHP: 5.6
- * Version: 14.7.1
+ * Version: 14.8.0-rc.1
* Author: Gutenberg Team
* Text Domain: gutenberg
*
diff --git a/lib/block-supports/typography.php b/lib/block-supports/typography.php
index 01d223b84281e..809fba1a6e7ac 100644
--- a/lib/block-supports/typography.php
+++ b/lib/block-supports/typography.php
@@ -451,18 +451,25 @@ function gutenberg_get_typography_font_size_value( $preset, $should_use_fluid_ty
// Checks if fluid font sizes are activated.
$typography_settings = gutenberg_get_global_settings( array( 'typography' ) );
- $should_use_fluid_typography = isset( $typography_settings['fluid'] ) && true === $typography_settings['fluid'] ? true : $should_use_fluid_typography;
+ $should_use_fluid_typography
+ = isset( $typography_settings['fluid'] ) &&
+ ( true === $typography_settings['fluid'] || is_array( $typography_settings['fluid'] ) ) ?
+ true :
+ $should_use_fluid_typography;
if ( ! $should_use_fluid_typography ) {
return $preset['size'];
}
+ $fluid_settings = isset( $typography_settings['fluid'] ) && is_array( $typography_settings['fluid'] ) ? $typography_settings['fluid'] : array();
+
// Defaults.
$default_maximum_viewport_width = '1600px';
$default_minimum_viewport_width = '768px';
$default_minimum_font_size_factor = 0.75;
$default_scale_factor = 1;
- $default_minimum_font_size_limit = '14px';
+ $has_min_font_size = isset( $fluid_settings['minFontSize'] ) && ! empty( gutenberg_get_typography_value_and_unit( $fluid_settings['minFontSize'] ) );
+ $default_minimum_font_size_limit = $has_min_font_size ? $fluid_settings['minFontSize'] : '14px';
// Font sizes.
$fluid_font_size_settings = isset( $preset['fluid'] ) ? $preset['fluid'] : null;
diff --git a/lib/compat/wordpress-6.1/class-gutenberg-rest-block-patterns-controller.php b/lib/compat/wordpress-6.1/class-gutenberg-rest-block-patterns-controller-6-1.php
similarity index 60%
rename from lib/compat/wordpress-6.1/class-gutenberg-rest-block-patterns-controller.php
rename to lib/compat/wordpress-6.1/class-gutenberg-rest-block-patterns-controller-6-1.php
index c053a678083da..b40f3aa2497f1 100644
--- a/lib/compat/wordpress-6.1/class-gutenberg-rest-block-patterns-controller.php
+++ b/lib/compat/wordpress-6.1/class-gutenberg-rest-block-patterns-controller-6-1.php
@@ -1,6 +1,6 @@
namespace = 'wp/v2';
- $this->rest_base = 'block-patterns/patterns';
- }
-
- /**
- * Registers the routes for the objects of the controller.
- *
- * @since 6.0.0
- */
- public function register_routes() {
- register_rest_route(
- $this->namespace,
- '/' . $this->rest_base,
- array(
- array(
- 'methods' => WP_REST_Server::READABLE,
- 'callback' => array( $this, 'get_items' ),
- 'permission_callback' => array( $this, 'get_items_permissions_check' ),
- ),
- 'schema' => array( $this, 'get_public_item_schema' ),
- ),
- true
- );
- }
-
- /**
- * Checks whether a given request has permission to read block patterns.
- *
- * @since 6.0.0
- *
- * @param WP_REST_Request $request Full details about the request.
- * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
- */
- public function get_items_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
- if ( current_user_can( 'edit_posts' ) ) {
- return true;
- }
-
- foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) {
- if ( current_user_can( $post_type->cap->edit_posts ) ) {
- return true;
- }
- }
-
- return new WP_Error(
- 'rest_cannot_view',
- __( 'Sorry, you are not allowed to view the registered block patterns.', 'gutenberg' ),
- array( 'status' => rest_authorization_required_code() )
- );
- }
-
- /**
- * Retrieves all block patterns.
- *
- * @since 6.0.0
- *
- * @param WP_REST_Request $request Full details about the request.
- * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
- */
- public function get_items( $request ) {
- if ( ! $this->remote_patterns_loaded ) {
- // Load block patterns from w.org.
- _load_remote_block_patterns(); // Patterns with the `core` keyword.
- _load_remote_featured_patterns(); // Patterns in the `featured` category.
- _register_remote_theme_patterns(); // Patterns requested by current theme.
-
- $this->remote_patterns_loaded = true;
- }
-
- $response = array();
- $patterns = WP_Block_Patterns_Registry::get_instance()->get_all_registered();
- foreach ( $patterns as $pattern ) {
- $prepared_pattern = $this->prepare_item_for_response( $pattern, $request );
- $response[] = $this->prepare_response_for_collection( $prepared_pattern );
- }
- return rest_ensure_response( $response );
- }
-
+class Gutenberg_REST_Block_Patterns_Controller_6_1 extends WP_REST_Block_Patterns_Controller {
/**
* Prepare a raw block pattern before it gets output in a REST API response.
*
* @since 6.0.0
+ * @since 6.1.0 Added `postTypes` property.
*
* @param array $item Raw pattern as registered, before any changes.
* @param WP_REST_Request $request Request object.
@@ -147,6 +55,7 @@ public function prepare_item_for_response( $item, $request ) {
* Retrieves the block pattern schema, conforming to JSON Schema.
*
* @since 6.0.0
+ * @since 6.1.0 Added `post_types` property.
*
* @return array Item schema data.
*/
diff --git a/lib/compat/wordpress-6.1/rest-api.php b/lib/compat/wordpress-6.1/rest-api.php
index f3391389d9e38..5dd06d3aad855 100644
--- a/lib/compat/wordpress-6.1/rest-api.php
+++ b/lib/compat/wordpress-6.1/rest-api.php
@@ -35,15 +35,6 @@ function gutenberg_update_post_types_rest_response( $response, $post_type ) {
}
add_filter( 'rest_prepare_post_type', 'gutenberg_update_post_types_rest_response', 10, 2 );
-/**
- * Registers the block patterns REST API routes.
- */
-function gutenberg_register_gutenberg_rest_block_patterns() {
- $block_patterns = new Gutenberg_REST_Block_Patterns_Controller();
- $block_patterns->register_routes();
-}
-add_action( 'rest_api_init', 'gutenberg_register_gutenberg_rest_block_patterns', 100 );
-
/**
* Exposes the site logo URL through the WordPress REST API.
*
diff --git a/lib/compat/wordpress-6.2/block-editor-settings.php b/lib/compat/wordpress-6.2/block-editor-settings.php
new file mode 100644
index 0000000000000..7323d34eb667c
--- /dev/null
+++ b/lib/compat/wordpress-6.2/block-editor-settings.php
@@ -0,0 +1,28 @@
+ gutenberg_get_global_stylesheet( array( 'custom-css' ) ),
+ '__unstableType' => 'user',
+ 'isGlobalStyles' => true,
+ );
+ }
+
+ return $settings;
+}
+
+add_filter( 'block_editor_settings_all', 'gutenberg_get_block_editor_settings_6_2', PHP_INT_MAX );
diff --git a/lib/compat/wordpress-6.2/block-patterns.php b/lib/compat/wordpress-6.2/block-patterns.php
index 8f50c9ff33c5d..1e529faf96321 100644
--- a/lib/compat/wordpress-6.2/block-patterns.php
+++ b/lib/compat/wordpress-6.2/block-patterns.php
@@ -8,7 +8,7 @@
/**
* Registers the block pattern categories.
*/
-function gutenberg_register_core_block_patterns_and_categories() {
+function gutenberg_register_core_block_patterns_categories() {
register_block_pattern_category(
'banner',
array(
@@ -30,49 +30,115 @@ function gutenberg_register_core_block_patterns_and_categories() {
)
);
register_block_pattern_category(
- 'footer',
+ 'text',
array(
- 'label' => _x( 'Footers', 'Block pattern category', 'gutenberg' ),
- 'description' => __( 'A variety of footer designs displaying information and site navigation.', 'gutenberg' ),
+ 'label' => _x( 'Text', 'Block pattern category', 'gutenberg' ),
+ 'description' => __( 'Patterns containing mostly text.', 'gutenberg' ),
)
);
register_block_pattern_category(
- 'gallery',
+ 'query',
array(
- 'label' => _x( 'Gallery', 'Block pattern category', 'gutenberg' ),
- 'description' => __( 'Patterns containing mostly images or other media.', 'gutenberg' ),
+ 'label' => _x( 'Posts', 'Block pattern category', 'gutenberg' ),
+ 'description' => __( 'Display your latest posts in lists, grids or other layouts.', 'gutenberg' ),
)
);
register_block_pattern_category(
- 'header',
+ 'featured',
array(
- 'label' => _x( 'Headers', 'Block pattern category', 'gutenberg' ),
- 'description' => __( 'A variety of header designs displaying your site title and navigation.', 'gutenberg' ),
+ 'label' => _x( 'Featured', 'Block pattern category', 'gutenberg' ),
+ 'description' => __( 'A set of high quality curated patterns.', 'gutenberg' ),
)
);
+
+ // Register new core block pattern categories.
register_block_pattern_category(
- 'text',
+ 'call-to-action',
array(
- 'label' => _x( 'Text', 'Block pattern category', 'gutenberg' ),
- 'description' => __( 'Patterns containing mostly text.', 'gutenberg' ),
+ 'label' => _x( 'Call to Action', 'Block pattern category', 'gutenberg' ),
+ 'description' => __( 'Sections whose purpose is to trigger a specific action.', 'gutenberg' ),
)
);
register_block_pattern_category(
- 'query',
+ 'team',
+ array(
+ 'label' => _x( 'Team', 'Block pattern category', 'gutenberg' ),
+ 'description' => __( 'A variety of designs to display your team members.', 'gutenberg' ),
+ )
+ );
+ register_block_pattern_category(
+ 'testimonials',
+ array(
+ 'label' => _x( 'Testimonials', 'Block pattern category', 'gutenberg' ),
+ 'description' => __( 'Share reviews and feedback about your brand/business.', 'gutenberg' ),
+ )
+ );
+ register_block_pattern_category(
+ 'services',
+ array(
+ 'label' => _x( 'Services', 'Block pattern category', 'gutenberg' ),
+ 'description' => __( 'Briefly describe what your business does and how you can help.', 'gutenberg' ),
+ )
+ );
+ register_block_pattern_category(
+ 'contact',
+ array(
+ 'label' => _x( 'Contact', 'Block pattern category', 'gutenberg' ),
+ 'description' => __( 'Display your contact information.', 'gutenberg' ),
+ )
+ );
+ register_block_pattern_category(
+ 'about',
+ array(
+ 'label' => _x( 'About', 'Block pattern category', 'gutenberg' ),
+ 'description' => __( 'Introduce yourself.', 'gutenberg' ),
+ )
+ );
+ register_block_pattern_category(
+ 'portfolio',
+ array(
+ 'label' => _x( 'Portfolio', 'Block pattern category', 'gutenberg' ),
+ 'description' => __( 'Showcase your latest work.', 'gutenberg' ),
+ )
+ );
+ register_block_pattern_category(
+ 'gallery',
+ array(
+ 'label' => _x( 'Gallery', 'Block pattern category', 'gutenberg' ),
+ 'description' => __( 'Different layouts for displaying images.', 'gutenberg' ),
+ )
+ );
+ register_block_pattern_category(
+ 'media',
+ array(
+ 'label' => _x( 'Media', 'Block pattern category', 'gutenberg' ),
+ 'description' => __( 'Different layouts containing video or audio.', 'gutenberg' ),
+ )
+ );
+ register_block_pattern_category(
+ 'posts',
array(
'label' => _x( 'Posts', 'Block pattern category', 'gutenberg' ),
'description' => __( 'Display your latest posts in lists, grids or other layouts.', 'gutenberg' ),
)
);
+ // Site building pattern categories.
register_block_pattern_category(
- 'featured',
+ 'footer',
array(
- 'label' => _x( 'Featured', 'Block pattern category', 'gutenberg' ),
- 'description' => __( 'A set of high quality curated patterns.', 'gutenberg' ),
+ 'label' => _x( 'Footers', 'Block pattern category', 'gutenberg' ),
+ 'description' => __( 'A variety of footer designs displaying information and site navigation.', 'gutenberg' ),
+ )
+ );
+ register_block_pattern_category(
+ 'header',
+ array(
+ 'label' => _x( 'Headers', 'Block pattern category', 'gutenberg' ),
+ 'description' => __( 'A variety of header designs displaying your site title and navigation.', 'gutenberg' ),
)
);
}
-add_action( 'init', 'gutenberg_register_core_block_patterns_and_categories' );
+add_action( 'init', 'gutenberg_register_core_block_patterns_categories' );
/**
* Registers Gutenberg-bundled patterns, with a focus on headers and footers
diff --git a/lib/compat/wordpress-6.2/class-gutenberg-rest-block-patterns-controller-6-2.php b/lib/compat/wordpress-6.2/class-gutenberg-rest-block-patterns-controller-6-2.php
new file mode 100644
index 0000000000000..d34160edb2af0
--- /dev/null
+++ b/lib/compat/wordpress-6.2/class-gutenberg-rest-block-patterns-controller-6-2.php
@@ -0,0 +1,107 @@
+ 'call-to-action',
+ 'columns' => 'text',
+ 'query' => 'posts',
+ );
+
+ /**
+ * Registers the routes for the objects of the controller.
+ *
+ * @since 6.0.0
+ */
+ public function register_routes() {
+ register_rest_route(
+ $this->namespace,
+ '/' . $this->rest_base,
+ array(
+ array(
+ 'methods' => WP_REST_Server::READABLE,
+ 'callback' => array( $this, 'get_items' ),
+ 'permission_callback' => array( $this, 'get_items_permissions_check' ),
+ ),
+ 'schema' => array( $this, 'get_public_item_schema' ),
+ ),
+ true
+ );
+ }
+ /**
+ * Retrieves all block patterns.
+ *
+ * @since 6.0.0
+ * @since 6.2.0 Added migration for old core pattern categories to the new ones.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
+ */
+ public function get_items( $request ) {
+ if ( ! $this->remote_patterns_loaded ) {
+ // Load block patterns from w.org.
+ _load_remote_block_patterns(); // Patterns with the `core` keyword.
+ _load_remote_featured_patterns(); // Patterns in the `featured` category.
+ _register_remote_theme_patterns(); // Patterns requested by current theme.
+
+ $this->remote_patterns_loaded = true;
+ }
+
+ $response = array();
+ $patterns = WP_Block_Patterns_Registry::get_instance()->get_all_registered();
+ foreach ( $patterns as $pattern ) {
+ $migrated_pattern = $this->migrate_pattern_categories( $pattern );
+ $prepared_pattern = $this->prepare_item_for_response( $migrated_pattern, $request );
+ $response[] = $this->prepare_response_for_collection( $prepared_pattern );
+ }
+ return rest_ensure_response( $response );
+ }
+
+ /**
+ * Migrates old core pattern categories to new ones.
+ *
+ * Core pattern categories are being revamped and we need to handle the migration
+ * to the new ones and ensure backwards compatibility.
+ *
+ * @since 6.2.0
+ *
+ * @param array $pattern Raw pattern as registered, before applying any changes.
+ * @return array Migrated pattern.
+ */
+ protected function migrate_pattern_categories( $pattern ) {
+ if ( isset( $pattern['categories'] ) && is_array( $pattern['categories'] ) ) {
+ foreach ( $pattern['categories'] as $i => $category ) {
+ if ( array_key_exists( $category, static::$categories_migration ) ) {
+ $pattern['categories'][ $i ] = static::$categories_migration[ $category ];
+ }
+ }
+ }
+ return $pattern;
+ }
+}
diff --git a/lib/compat/wordpress-6.2/class-gutenberg-rest-global-styles-controller-6-2.php b/lib/compat/wordpress-6.2/class-gutenberg-rest-global-styles-controller-6-2.php
new file mode 100644
index 0000000000000..684786ef22d76
--- /dev/null
+++ b/lib/compat/wordpress-6.2/class-gutenberg-rest-global-styles-controller-6-2.php
@@ -0,0 +1,204 @@
+post_content, true );
+ $is_global_styles_user_theme_json = isset( $raw_config['isGlobalStylesUserThemeJSON'] ) && true === $raw_config['isGlobalStylesUserThemeJSON'];
+ $config = array();
+ if ( $is_global_styles_user_theme_json ) {
+ $config = ( new WP_Theme_JSON_Gutenberg( $raw_config, 'custom' ) )->get_raw_data();
+ }
+
+ // Base fields for every post.
+ $data = array();
+ $fields = $this->get_fields_for_response( $request );
+
+ if ( rest_is_field_included( 'id', $fields ) ) {
+ $data['id'] = $post->ID;
+ }
+
+ if ( rest_is_field_included( 'title', $fields ) ) {
+ $data['title'] = array();
+ }
+ if ( rest_is_field_included( 'title.raw', $fields ) ) {
+ $data['title']['raw'] = $post->post_title;
+ }
+ if ( rest_is_field_included( 'title.rendered', $fields ) ) {
+ add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
+
+ $data['title']['rendered'] = get_the_title( $post->ID );
+
+ remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
+ }
+
+ if ( rest_is_field_included( 'settings', $fields ) ) {
+ $data['settings'] = ! empty( $config['settings'] ) && $is_global_styles_user_theme_json ? $config['settings'] : new stdClass();
+ }
+
+ if ( rest_is_field_included( 'styles', $fields ) ) {
+ $data['styles'] = ! empty( $config['styles'] ) && $is_global_styles_user_theme_json ? $config['styles'] : new stdClass();
+ }
+
+ $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
+ $data = $this->add_additional_fields_to_object( $data, $request );
+ $data = $this->filter_response_by_context( $data, $context );
+
+ // Wrap the data in a response object.
+ $response = rest_ensure_response( $data );
+
+ if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
+ $links = $this->prepare_links( $post->ID );
+ $response->add_links( $links );
+ if ( ! empty( $links['self']['href'] ) ) {
+ $actions = $this->get_available_actions();
+ $self = $links['self']['href'];
+ foreach ( $actions as $rel ) {
+ $response->add_link( $rel, $self );
+ }
+ }
+ }
+
+ return $response;
+ }
+
+ /**
+ * Updates a single global style config.
+ *
+ * @since 5.9.0
+ * @since 6.2.0 Added validation of styles.css property.
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
+ */
+ public function update_item( $request ) {
+ $post_before = $this->get_post( $request['id'] );
+ if ( is_wp_error( $post_before ) ) {
+ return $post_before;
+ }
+
+ $changes = $this->prepare_item_for_database( $request );
+ if ( is_wp_error( $changes ) ) {
+ return $changes;
+ }
+
+ $result = wp_update_post( wp_slash( (array) $changes ), true, false );
+ if ( is_wp_error( $result ) ) {
+ return $result;
+ }
+
+ $post = get_post( $request['id'] );
+ $fields_update = $this->update_additional_fields_for_object( $post, $request );
+ if ( is_wp_error( $fields_update ) ) {
+ return $fields_update;
+ }
+
+ wp_after_insert_post( $post, true, $post_before );
+
+ $response = $this->prepare_item_for_response( $post, $request );
+
+ return rest_ensure_response( $response );
+ }
+ /**
+ * Prepares a single global styles config for update.
+ *
+ * @since 5.9.0
+ * @since 6.2.0 Added validation of styles.css property.
+ *
+ * @param WP_REST_Request $request Request object.
+ * @return stdClass Changes to pass to wp_update_post.
+ */
+ protected function prepare_item_for_database( $request ) {
+ $changes = new stdClass();
+ $changes->ID = $request['id'];
+ $post = get_post( $request['id'] );
+ $existing_config = array();
+ if ( $post ) {
+ $existing_config = json_decode( $post->post_content, true );
+ $json_decoding_error = json_last_error();
+ if ( JSON_ERROR_NONE !== $json_decoding_error || ! isset( $existing_config['isGlobalStylesUserThemeJSON'] ) ||
+ ! $existing_config['isGlobalStylesUserThemeJSON'] ) {
+ $existing_config = array();
+ }
+ }
+ if ( isset( $request['styles'] ) || isset( $request['settings'] ) ) {
+ $config = array();
+ if ( isset( $request['styles'] ) ) {
+ $config['styles'] = $request['styles'];
+ if ( isset( $request['styles']['css'] ) ) {
+ $validate_custom_css = $this->validate_custom_css( $request['styles']['css'] );
+ if ( is_wp_error( $validate_custom_css ) ) {
+ return $validate_custom_css;
+ }
+ }
+ } elseif ( isset( $existing_config['styles'] ) ) {
+ $config['styles'] = $existing_config['styles'];
+ }
+ if ( isset( $request['settings'] ) ) {
+ $config['settings'] = $request['settings'];
+ } elseif ( isset( $existing_config['settings'] ) ) {
+ $config['settings'] = $existing_config['settings'];
+ }
+ $config['isGlobalStylesUserThemeJSON'] = true;
+ $config['version'] = WP_Theme_JSON_Gutenberg::LATEST_SCHEMA;
+ $changes->post_content = wp_json_encode( $config );
+ }
+ // Post title.
+ if ( isset( $request['title'] ) ) {
+ if ( is_string( $request['title'] ) ) {
+ $changes->post_title = $request['title'];
+ } elseif ( ! empty( $request['title']['raw'] ) ) {
+ $changes->post_title = $request['title']['raw'];
+ }
+ }
+ return $changes;
+ }
+
+ /**
+ * Validate style.css as valid CSS.
+ *
+ * Currently just checks for invalid markup.
+ *
+ * @since 6.2.0
+ *
+ * @param string $css CSS to validate.
+ * @return true|WP_Error True if the input was validated, otherwise WP_Error.
+ */
+ private function validate_custom_css( $css ) {
+ if ( preg_match( '#?\w+#', $css ) ) {
+ return new WP_Error(
+ 'rest_custom_css_illegal_markup',
+ __( 'Markup is not allowed in CSS.', 'gutenberg' ),
+ array( 'status' => 400 )
+ );
+ }
+ return true;
+ }
+}
diff --git a/lib/compat/wordpress-6.2/class-wp-theme-json-6-2.php b/lib/compat/wordpress-6.2/class-wp-theme-json-6-2.php
index 4c6a1f50612a8..fe01eb273066e 100644
--- a/lib/compat/wordpress-6.2/class-wp-theme-json-6-2.php
+++ b/lib/compat/wordpress-6.2/class-wp-theme-json-6-2.php
@@ -97,6 +97,25 @@ class WP_Theme_JSON_6_2 extends WP_Theme_JSON_6_1 {
'box-shadow' => array( 'shadow' ),
);
+ /**
+ * Indirect metadata for style properties that are not directly output.
+ *
+ * Each element is a direct mapping from a CSS property name to the
+ * path to the value in theme.json & block attributes.
+ *
+ * Indirect properties are not output directly by `compute_style_properties`,
+ * but are used elsewhere in the processing of global styles. The indirect
+ * property is used to validate whether or not a style value is allowed.
+ *
+ * @since 6.2.0
+ * @var array
+ */
+ const INDIRECT_PROPERTIES_METADATA = array(
+ 'gap' => array( 'spacing', 'blockGap' ),
+ 'column-gap' => array( 'spacing', 'blockGap', 'left' ),
+ 'row-gap' => array( 'spacing', 'blockGap', 'top' ),
+ );
+
/**
* The valid properties under the settings key.
*
@@ -175,6 +194,7 @@ class WP_Theme_JSON_6_2 extends WP_Theme_JSON_6_1 {
* @since 6.1.0 Added new side properties for `border`,
* added new property `shadow`,
* updated `blockGap` to be allowed at any level.
+ * @since 6.2.0 Added new property `css`.
* @var array
*/
const VALID_STYLES = array(
@@ -215,5 +235,157 @@ class WP_Theme_JSON_6_2 extends WP_Theme_JSON_6_1 {
'textDecoration' => null,
'textTransform' => null,
),
+ 'css' => null,
);
+
+ /**
+ * Processes a style node and returns the same node
+ * without the insecure styles.
+ *
+ * @since 5.9.0
+ * @since 6.2.0 Allow indirect properties used outside of `compute_style_properties`.
+ *
+ * @param array $input Node to process.
+ * @return array
+ */
+ protected static function remove_insecure_styles( $input ) {
+ $output = array();
+ $declarations = static::compute_style_properties( $input );
+
+ foreach ( $declarations as $declaration ) {
+ if ( static::is_safe_css_declaration( $declaration['name'], $declaration['value'] ) ) {
+ $path = static::PROPERTIES_METADATA[ $declaration['name'] ];
+
+ // Check the value isn't an array before adding so as to not
+ // double up shorthand and longhand styles.
+ $value = _wp_array_get( $input, $path, array() );
+ if ( ! is_array( $value ) ) {
+ _wp_array_set( $output, $path, $value );
+ }
+ }
+ }
+
+ // Ensure indirect properties not handled by `compute_style_properties` are allowed.
+ foreach ( static::INDIRECT_PROPERTIES_METADATA as $property => $path ) {
+ $value = _wp_array_get( $input, $path, array() );
+ if (
+ isset( $value ) &&
+ ! is_array( $value ) &&
+ static::is_safe_css_declaration( $property, $value )
+ ) {
+ _wp_array_set( $output, $path, $value );
+ }
+ }
+
+ return $output;
+ }
+
+ /**
+ * Returns the stylesheet that results of processing
+ * the theme.json structure this object represents.
+ *
+ * @param array $types Types of styles to load. Will load all by default. It accepts:
+ * 'variables': only the CSS Custom Properties for presets & custom ones.
+ * 'styles': only the styles section in theme.json.
+ * 'presets': only the classes for the presets.
+ * 'custom-css': only the css from global styles.css.
+ * @param array $origins A list of origins to include. By default it includes VALID_ORIGINS.
+ * @param array $options An array of options for now used for internal purposes only (may change without notice).
+ * The options currently supported are 'scope' that makes sure all style are scoped to a given selector,
+ * and root_selector which overwrites and forces a given selector to be used on the root node.
+ * @return string Stylesheet.
+ */
+ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' ), $origins = null, $options = array() ) {
+ if ( null === $origins ) {
+ $origins = static::VALID_ORIGINS;
+ }
+
+ if ( is_string( $types ) ) {
+ // Dispatch error and map old arguments to new ones.
+ _deprecated_argument( __FUNCTION__, '5.9' );
+ if ( 'block_styles' === $types ) {
+ $types = array( 'styles', 'presets' );
+ } elseif ( 'css_variables' === $types ) {
+ $types = array( 'variables' );
+ } else {
+ $types = array( 'variables', 'styles', 'presets' );
+ }
+ }
+
+ $blocks_metadata = static::get_blocks_metadata();
+ $style_nodes = static::get_style_nodes( $this->theme_json, $blocks_metadata );
+ $setting_nodes = static::get_setting_nodes( $this->theme_json, $blocks_metadata );
+
+ $root_style_key = array_search( static::ROOT_BLOCK_SELECTOR, array_column( $style_nodes, 'selector' ), true );
+ $root_settings_key = array_search( static::ROOT_BLOCK_SELECTOR, array_column( $setting_nodes, 'selector' ), true );
+
+ if ( ! empty( $options['scope'] ) ) {
+ foreach ( $setting_nodes as &$node ) {
+ $node['selector'] = static::scope_selector( $options['scope'], $node['selector'] );
+ }
+ foreach ( $style_nodes as &$node ) {
+ $node['selector'] = static::scope_selector( $options['scope'], $node['selector'] );
+ }
+ }
+
+ if ( ! empty( $options['root_selector'] ) ) {
+ if ( false !== $root_settings_key ) {
+ $setting_nodes[ $root_settings_key ]['selector'] = $options['root_selector'];
+ }
+ if ( false !== $root_style_key ) {
+ $setting_nodes[ $root_style_key ]['selector'] = $options['root_selector'];
+ }
+ }
+
+ $stylesheet = '';
+
+ if ( in_array( 'variables', $types, true ) ) {
+ $stylesheet .= $this->get_css_variables( $setting_nodes, $origins );
+ }
+
+ if ( in_array( 'styles', $types, true ) ) {
+ if ( false !== $root_style_key ) {
+ $stylesheet .= $this->get_root_layout_rules( $style_nodes[ $root_style_key ]['selector'], $style_nodes[ $root_style_key ] );
+ }
+ $stylesheet .= $this->get_block_classes( $style_nodes );
+ } elseif ( in_array( 'base-layout-styles', $types, true ) ) {
+ $root_selector = static::ROOT_BLOCK_SELECTOR;
+ $columns_selector = '.wp-block-columns';
+ if ( ! empty( $options['scope'] ) ) {
+ $root_selector = static::scope_selector( $options['scope'], $root_selector );
+ $columns_selector = static::scope_selector( $options['scope'], $columns_selector );
+ }
+ if ( ! empty( $options['root_selector'] ) ) {
+ $root_selector = $options['root_selector'];
+ }
+ // Base layout styles are provided as part of `styles`, so only output separately if explicitly requested.
+ // For backwards compatibility, the Columns block is explicitly included, to support a different default gap value.
+ $base_styles_nodes = array(
+ array(
+ 'path' => array( 'styles' ),
+ 'selector' => $root_selector,
+ ),
+ array(
+ 'path' => array( 'styles', 'blocks', 'core/columns' ),
+ 'selector' => $columns_selector,
+ 'name' => 'core/columns',
+ ),
+ );
+
+ foreach ( $base_styles_nodes as $base_style_node ) {
+ $stylesheet .= $this->get_layout_styles( $base_style_node );
+ }
+ }
+
+ if ( in_array( 'presets', $types, true ) ) {
+ $stylesheet .= $this->get_preset_classes( $setting_nodes, $origins );
+ }
+
+ // Load the custom CSS last so it has the highest specificity.
+ if ( in_array( 'custom-css', $types, true ) ) {
+ $stylesheet .= _wp_array_get( $this->theme_json, array( 'styles', 'css' ) );
+ }
+
+ return $stylesheet;
+ }
}
diff --git a/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php b/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php
index 2cce8cec7e46e..110c8bac7b147 100644
--- a/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php
+++ b/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php
@@ -168,4 +168,63 @@ public static function get_merged_data( $origin = 'custom' ) {
$result->set_spacing_sizes();
return $result;
}
+
+ /**
+ * Returns the user's origin config.
+ *
+ * @since 6.2 Added check for the WP_Theme_JSON_Gutenberg class to prevent $user
+ * values set in core fron overriding the new custom css values added to VALID_STYLES.
+ * This does not need to be backported to core as the new VALID_STYLES[css] value will
+ * be added to core with 6.2.
+ *
+ * @return WP_Theme_JSON_Gutenberg Entity that holds styles for user data.
+ */
+ public static function get_user_data() {
+ if ( null !== static::$user && static::$user instanceof WP_Theme_JSON_Gutenberg ) {
+ return static::$user;
+ }
+
+ $config = array();
+ $user_cpt = static::get_user_data_from_wp_global_styles( wp_get_theme() );
+
+ if ( array_key_exists( 'post_content', $user_cpt ) ) {
+ $decoded_data = json_decode( $user_cpt['post_content'], true );
+
+ $json_decoding_error = json_last_error();
+ if ( JSON_ERROR_NONE !== $json_decoding_error ) {
+ trigger_error( 'Error when decoding a theme.json schema for user data. ' . json_last_error_msg() );
+ /**
+ * Filters the data provided by the user for global styles & settings.
+ *
+ * @param WP_Theme_JSON_Data_Gutenberg Class to access and update the underlying data.
+ */
+ $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data_Gutenberg( $config, 'custom' ) );
+ $config = $theme_json->get_data();
+ return new WP_Theme_JSON_Gutenberg( $config, 'custom' );
+ }
+
+ // Very important to verify if the flag isGlobalStylesUserThemeJSON is true.
+ // If is not true the content was not escaped and is not safe.
+ if (
+ is_array( $decoded_data ) &&
+ isset( $decoded_data['isGlobalStylesUserThemeJSON'] ) &&
+ $decoded_data['isGlobalStylesUserThemeJSON']
+ ) {
+ unset( $decoded_data['isGlobalStylesUserThemeJSON'] );
+ $config = $decoded_data;
+ }
+ }
+
+ /**
+ * Filters the data provided by the user for global styles & settings.
+ *
+ * @param WP_Theme_JSON_Data_Gutenberg Class to access and update the underlying data.
+ */
+ $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data_Gutenberg( $config, 'custom' ) );
+ $config = $theme_json->get_data();
+
+ static::$user = new WP_Theme_JSON_Gutenberg( $config, 'custom' );
+
+ return static::$user;
+ }
}
diff --git a/lib/compat/wordpress-6.2/get-global-styles-and-settings.php b/lib/compat/wordpress-6.2/get-global-styles-and-settings.php
index 1bf1ea23b6417..8556a0be1663f 100644
--- a/lib/compat/wordpress-6.2/get-global-styles-and-settings.php
+++ b/lib/compat/wordpress-6.2/get-global-styles-and-settings.php
@@ -63,7 +63,7 @@ function wp_theme_has_theme_json_clean_cache() {
* Returns the stylesheet resulting of merging core, theme, and user data.
*
* @param array $types Types of styles to load. Optional.
- * It accepts 'variables', 'styles', 'presets' as values.
+ * It accepts 'variables', 'styles', 'presets', 'custom-css' as values.
* If empty, it'll load all for themes with theme.json support
* and only [ 'variables', 'presets' ] for themes without theme.json support.
*
@@ -85,7 +85,7 @@ function gutenberg_get_global_stylesheet( $types = array() ) {
if ( empty( $types ) && ! $supports_theme_json ) {
$types = array( 'variables', 'presets', 'base-layout-styles' );
} elseif ( empty( $types ) ) {
- $types = array( 'variables', 'styles', 'presets' );
+ $types = array( 'variables', 'styles', 'presets', 'custom-css' );
}
/*
diff --git a/lib/compat/wordpress-6.2/rest-api.php b/lib/compat/wordpress-6.2/rest-api.php
index 023a79e3db95f..12f7afda3b4d5 100644
--- a/lib/compat/wordpress-6.2/rest-api.php
+++ b/lib/compat/wordpress-6.2/rest-api.php
@@ -23,6 +23,15 @@ function gutenberg_register_rest_pattern_directory() {
}
add_action( 'rest_api_init', 'gutenberg_register_rest_pattern_directory' );
+/**
+ * Registers the block patterns REST API routes.
+ */
+function gutenberg_register_rest_block_patterns() {
+ $block_patterns = new Gutenberg_REST_Block_Patterns_Controller_6_2();
+ $block_patterns->register_routes();
+}
+add_action( 'rest_api_init', 'gutenberg_register_rest_block_patterns' );
+
/**
* Add extra collection params to pattern directory requests.
*
@@ -83,3 +92,27 @@ function gutenberg_pattern_directory_collection_params_6_2( $query_params ) {
return $query_params;
}
add_filter( 'rest_pattern_directory_collection_params', 'gutenberg_pattern_directory_collection_params_6_2' );
+
+/**
+ * Registers the Global Styles REST API routes.
+ */
+function gutenberg_register_global_styles_endpoints() {
+ $editor_settings = new Gutenberg_REST_Global_Styles_Controller_6_2();
+ $editor_settings->register_routes();
+}
+add_action( 'rest_api_init', 'gutenberg_register_global_styles_endpoints' );
+
+/**
+ * Updates REST API response for the sidebars and marks them as 'inactive'.
+ *
+ * Note: This can be a part of the `prepare_item_for_response` in `class-wp-rest-sidebars-controller.php`.
+ *
+ * @param WP_REST_Response $response The sidebar response object.
+ * @return WP_REST_Response $response Updated response object.
+ */
+function gutenberg_modify_rest_sidebars_response( $response ) {
+ $response->data['status'] = wp_is_block_theme() ? 'inactive' : 'active';
+
+ return $response;
+}
+add_filter( 'rest_prepare_sidebar', 'gutenberg_modify_rest_sidebars_response' );
diff --git a/lib/compat/wordpress-6.2/script-loader.php b/lib/compat/wordpress-6.2/script-loader.php
index 84681b3151238..e08bfa6e46ca8 100644
--- a/lib/compat/wordpress-6.2/script-loader.php
+++ b/lib/compat/wordpress-6.2/script-loader.php
@@ -90,16 +90,18 @@ function gutenberg_resolve_assets_override() {
$block_registry = WP_Block_Type_Registry::get_instance();
foreach ( $block_registry->get_all_registered() as $block_type ) {
- $style_handles = array_merge(
- $style_handles,
- $block_type->style_handles,
- $block_type->editor_style_handles
- );
-
- $script_handles = array_merge(
- $script_handles,
- $block_type->script_handles
- );
+ // In older WordPress versions, like 6.0, these properties are not defined.
+ if ( isset( $block_type->style_handles ) && is_array( $block_type->style_handles ) ) {
+ $style_handles = array_merge( $style_handles, $block_type->style_handles );
+ }
+
+ if ( isset( $block_type->editor_style_handles ) && is_array( $block_type->editor_style_handles ) ) {
+ $style_handles = array_merge( $style_handles, $block_type->editor_style_handles );
+ }
+
+ if ( isset( $block_type->script_handles ) && is_array( $block_type->script_handles ) ) {
+ $script_handles = array_merge( $script_handles, $block_type->script_handles );
+ }
}
$style_handles = array_unique( $style_handles );
diff --git a/lib/compat/wordpress-6.2/theme.php b/lib/compat/wordpress-6.2/theme.php
new file mode 100644
index 0000000000000..79d5520644947
--- /dev/null
+++ b/lib/compat/wordpress-6.2/theme.php
@@ -0,0 +1,23 @@
+is_block_theme() ) {
+ set_theme_mod( 'wp_legacy_sidebars', $wp_registered_sidebars );
+ }
+}
+add_action( 'switch_theme', 'gutenberg_set_legacy_sidebars', 10, 2 );
diff --git a/lib/compat/wordpress-6.2/widgets.php b/lib/compat/wordpress-6.2/widgets.php
new file mode 100644
index 0000000000000..19591ae64607e
--- /dev/null
+++ b/lib/compat/wordpress-6.2/widgets.php
@@ -0,0 +1,32 @@
+ array( 'post-editor', 'site-editor', 'widgets-editor' ),
),
+ '__experimentalBlockInspectorAnimation' => array(
+ 'description' => __( 'Whether to enable animation when showing and hiding the block inspector.', 'gutenberg' ),
+ 'type' => 'object',
+ 'context' => array( 'site-editor' ),
+ ),
+
'alignWide' => array(
'description' => __( 'Enable/Disable Wide/Full Alignments.', 'gutenberg' ),
'type' => 'boolean',
diff --git a/lib/experimental/kses.php b/lib/experimental/kses.php
new file mode 100644
index 0000000000000..fd7531617939f
--- /dev/null
+++ b/lib/experimental/kses.php
@@ -0,0 +1,66 @@
+;
+ const renderedIcon = (
+