diff --git a/.eslintrc.js b/.eslintrc.js index dfe779b4683523..d0c22090b93e87 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -156,6 +156,7 @@ module.exports = { 'plugin:eslint-comments/recommended', 'plugin:storybook/recommended', ], + plugins: [ 'react-compiler' ], globals: { wp: 'off', globalThis: 'readonly', @@ -222,6 +223,15 @@ module.exports = { definedTags: [ 'jest-environment' ], }, ], + 'react-compiler/react-compiler': [ + 'error', + { + environment: { + enableTreatRefLikeIdentifiersAsRefs: true, + validateRefAccessDuringRender: false, + }, + }, + ], }, overrides: [ { @@ -236,6 +246,7 @@ module.exports = { 'import/no-unresolved': 'off', 'import/named': 'off', '@wordpress/data-no-store-string-literals': 'off', + 'react-compiler/react-compiler': 'off', }, }, { @@ -551,6 +562,7 @@ module.exports = { { files: [ 'packages/interactivity*/src/**' ], rules: { + 'react-compiler/react-compiler': 'off', 'react/react-in-jsx-scope': 'error', }, }, diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 54378765bd26ff..2bb5676ae9ed66 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -6,7 +6,9 @@ jobs: name: 'Validation' runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - - uses: gradle/wrapper-validation-action@v3 + - name: Validate checksums + uses: gradle/actions/wrapper-validation@cc4fc85e6b35bafd578d5ffbc76a5518407e1af0 # v4.2.1 diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 6c8c984602edcb..4a5b576b424b53 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -69,13 +69,13 @@ jobs: - name: Compare performance with base branch if: github.event_name == 'push' # The base hash used here need to be a commit that is compatible with the current WP version - # The current one is 5f4c9c853b15092ed885d5280edefb973c37d9e9 and it needs to be updated every WP major release. + # The current one is c7722262e65a3f4d0f1a2d1ad29eccb2069509e4 and it needs to be updated every WP major release. # It is used as a base comparison point to avoid fluctuation in the performance metrics. run: | WP_VERSION=$(awk -F ': ' '/^Tested up to/{print $2}' readme.txt) IFS=. read -ra WP_VERSION_ARRAY <<< "$WP_VERSION" WP_MAJOR="${WP_VERSION_ARRAY[0]}.${WP_VERSION_ARRAY[1]}" - ./bin/plugin/cli.js perf $GITHUB_SHA 5f4c9c853b15092ed885d5280edefb973c37d9e9 --tests-branch $GITHUB_SHA --wp-version "$WP_MAJOR" + ./bin/plugin/cli.js perf $GITHUB_SHA c7722262e65a3f4d0f1a2d1ad29eccb2069509e4 --tests-branch $GITHUB_SHA --wp-version "$WP_MAJOR" - name: Compare performance with custom branches if: github.event_name == 'workflow_dispatch' @@ -101,7 +101,7 @@ jobs: CODEHEALTH_PROJECT_TOKEN: ${{ secrets.CODEHEALTH_PROJECT_TOKEN }} run: | COMMITTED_AT=$(git show -s $GITHUB_SHA --format="%cI") - ./bin/log-performance-results.js $CODEHEALTH_PROJECT_TOKEN trunk $GITHUB_SHA 5f4c9c853b15092ed885d5280edefb973c37d9e9 $COMMITTED_AT + ./bin/log-performance-results.js $CODEHEALTH_PROJECT_TOKEN trunk $GITHUB_SHA c7722262e65a3f4d0f1a2d1ad29eccb2069509e4 $COMMITTED_AT - name: Archive debug artifacts (screenshots, HTML snapshots) uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 diff --git a/.github/workflows/rnmobile-android-runner.yml b/.github/workflows/rnmobile-android-runner.yml index 65bb55e3f63201..f8ff0441a95b7b 100644 --- a/.github/workflows/rnmobile-android-runner.yml +++ b/.github/workflows/rnmobile-android-runner.yml @@ -28,7 +28,7 @@ jobs: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - name: Use desired version of Java - uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0 + uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 with: distribution: 'corretto' java-version: '17' @@ -47,7 +47,7 @@ jobs: run: npm run native test:e2e:setup - name: Gradle cache - uses: gradle/actions/setup-gradle@d156388eb19639ec20ade50009f3d199ce1e2808 # v4.1.0 + uses: gradle/actions/setup-gradle@cc4fc85e6b35bafd578d5ffbc76a5518407e1af0 # v4.2.1 # AVD cache disabled as it caused emulator termination to hang indefinitely. # https://github.com/ReactiveCircus/android-emulator-runner/issues/385 diff --git a/.github/workflows/rnmobile-ios-runner.yml b/.github/workflows/rnmobile-ios-runner.yml index 8851c7c12c4a4a..d28ee65c719e43 100644 --- a/.github/workflows/rnmobile-ios-runner.yml +++ b/.github/workflows/rnmobile-ios-runner.yml @@ -27,7 +27,7 @@ jobs: with: show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - - uses: ruby/setup-ruby@7bae1d00b5db9166f4f0fc47985a3a5702cb58f0 # v1.197.0 + - uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc # v1.202.0 with: # `.ruby-version` file location working-directory: packages/react-native-editor/ios diff --git a/.gitignore b/.gitignore index 4cd1d9706b7370..1d75f9f429d869 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ build build-module build-style build-types +build-wp node_modules gutenberg.zip coverage diff --git a/backport-changelog/6.7/7676.md b/backport-changelog/6.7/7676.md new file mode 100644 index 00000000000000..19d9dc59048457 --- /dev/null +++ b/backport-changelog/6.7/7676.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/7676 + +* https://github.com/WordPress/gutenberg/pull/66359 diff --git a/backport-changelog/6.8/7069.md b/backport-changelog/6.8/7069.md index ea3c717ec3c93a..69edbde58902d1 100644 --- a/backport-changelog/6.8/7069.md +++ b/backport-changelog/6.8/7069.md @@ -1,3 +1,5 @@ https://github.com/WordPress/wordpress-develop/pull/7069 * https://github.com/WordPress/gutenberg/pull/63401 +* https://github.com/WordPress/gutenberg/pull/66918 +* https://github.com/WordPress/gutenberg/pull/67018 diff --git a/backport-changelog/6.8/7129.md b/backport-changelog/6.8/7129.md new file mode 100644 index 00000000000000..90c9168cdc6f8a --- /dev/null +++ b/backport-changelog/6.8/7129.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/7129 + +* https://github.com/WordPress/gutenberg/pull/62304 diff --git a/backport-changelog/6.8/7265.md b/backport-changelog/6.8/7265.md new file mode 100644 index 00000000000000..44ba36053aa0d9 --- /dev/null +++ b/backport-changelog/6.8/7265.md @@ -0,0 +1,4 @@ +https://github.com/WordPress/wordpress-develop/pull/7265 + +* https://github.com/WordPress/gutenberg/pull/66850 +* https://github.com/WordPress/gutenberg/pull/66947 diff --git a/backport-changelog/6.8/7759.md b/backport-changelog/6.8/7759.md new file mode 100644 index 00000000000000..a0ad85b06e6b05 --- /dev/null +++ b/backport-changelog/6.8/7759.md @@ -0,0 +1,4 @@ +https://github.com/WordPress/wordpress-develop/pull/7759 + +* https://github.com/WordPress/gutenberg/pull/66896 + diff --git a/backport-changelog/6.8/7784.md b/backport-changelog/6.8/7784.md new file mode 100644 index 00000000000000..b18dca88112a71 --- /dev/null +++ b/backport-changelog/6.8/7784.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/7784 + +* https://github.com/WordPress/gutenberg/pull/66948 diff --git a/backport-changelog/6.8/7825.md b/backport-changelog/6.8/7825.md new file mode 100644 index 00000000000000..42d09c86b7f3ba --- /dev/null +++ b/backport-changelog/6.8/7825.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/7825 + +* https://github.com/WordPress/gutenberg/pull/67061 diff --git a/backport-changelog/6.8/7848.md b/backport-changelog/6.8/7848.md new file mode 100644 index 00000000000000..84600eb4847cdb --- /dev/null +++ b/backport-changelog/6.8/7848.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/7848 + +* https://github.com/WordPress/gutenberg/pull/67154 diff --git a/backport-changelog/6.8/7895.md b/backport-changelog/6.8/7895.md new file mode 100644 index 00000000000000..4750ab545ada3b --- /dev/null +++ b/backport-changelog/6.8/7895.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/7895 + +* https://github.com/WordPress/gutenberg/pull/66459 diff --git a/changelog.txt b/changelog.txt index bcbfbb2dc48449..bf13c6b273e9b6 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,874 @@ == Changelog == += 19.8.0-rc.1 = + + +## Changelog + +### Enhancements + +#### Block Library +- Details block: Use summary content as default label. ([67217](https://github.com/WordPress/gutenberg/pull/67217)) +- Make social icon navigation one arrow keypress. ([64883](https://github.com/WordPress/gutenberg/pull/64883)) +- Page List : Add border and spacing support. ([66385](https://github.com/WordPress/gutenberg/pull/66385)) +- Query Loop block: Remove 'add new post' prompt in the sidebar. ([67189](https://github.com/WordPress/gutenberg/pull/67189)) +- Query block: Update Enhanced Pagination help text. ([67173](https://github.com/WordPress/gutenberg/pull/67173)) +- Social Link: Add contentOnly editing support. ([66622](https://github.com/WordPress/gutenberg/pull/66622)) + +#### Components +- Autocomplete: Increase option height. ([67214](https://github.com/WordPress/gutenberg/pull/67214)) +- CircularOptionPicker: Update Button sizes. ([67285](https://github.com/WordPress/gutenberg/pull/67285)) +- ColorPalette: Disable `Clear` button if there's no color value. ([67108](https://github.com/WordPress/gutenberg/pull/67108)) +- ColorPicker: Update sizes of format select and copy button. ([67093](https://github.com/WordPress/gutenberg/pull/67093)) +- ComboboxControl: Update reset button size. ([67215](https://github.com/WordPress/gutenberg/pull/67215)) + +#### DataViews +- Add density option to `table` layout. ([67170](https://github.com/WordPress/gutenberg/pull/67170)) +- DataForm: Enable fields to declare a different layout. ([66531](https://github.com/WordPress/gutenberg/pull/66531)) +- DataViews list layout: Hide actions menu when there is only one action and is primary. ([67015](https://github.com/WordPress/gutenberg/pull/67015)) +- DataViews table layout: Hide actions menu when there is only one action and is primary. ([67020](https://github.com/WordPress/gutenberg/pull/67020)) +- Reduce the size of action button in Grid layout. ([67032](https://github.com/WordPress/gutenberg/pull/67032)) +- DataViews: Allow register/unregister fields. ([67175](https://github.com/WordPress/gutenberg/pull/67175)) + +#### Global Styles +- Block Supports: Extend stabilization to common experimental block support flags. ([67018](https://github.com/WordPress/gutenberg/pull/67018)) +- Borders: Stabilize border block supports within block processing. ([66918](https://github.com/WordPress/gutenberg/pull/66918)) +- Site Editor > Styles: Open styles inspector when clicking preview canvas. ([66996](https://github.com/WordPress/gutenberg/pull/66996)) + +#### Media +- Block Editor: Add notice action to revert image to original after cropping. ([67314](https://github.com/WordPress/gutenberg/pull/67314)) +- Block Editor: Add success notices for image editing. ([67312](https://github.com/WordPress/gutenberg/pull/67312)) + +#### REST API +- Feature: Set editor rendering mode by post type. ([62304](https://github.com/WordPress/gutenberg/pull/62304)) +- Terms: Respect order specified by register_taxonomy(). ([67154](https://github.com/WordPress/gutenberg/pull/67154)) + +#### Zoom Out +- Leave help text regardless of zoom state. ([67132](https://github.com/WordPress/gutenberg/pull/67132)) +- Preserve footer template bar in zoom out. ([67135](https://github.com/WordPress/gutenberg/pull/67135)) +- Add section styles switch button in block toolbar in zoom out mode. ([67140](https://github.com/WordPress/gutenberg/pull/67140)) + +#### Post Editor +- Move default template types and template part areas to REST API. ([66459](https://github.com/WordPress/gutenberg/pull/66459)) +- Move `usePostFields` to `wordpress/editor` package. ([67024](https://github.com/WordPress/gutenberg/pull/67024)) + +#### Site Editor +- Blocks: Adds check for parent before showing convert to pattern button. ([66158](https://github.com/WordPress/gutenberg/pull/66158)) +- Try dark toolbar for the write mode. ([66116](https://github.com/WordPress/gutenberg/pull/66116)) + +#### Design Tools +- Heading: Hide border controls by default. ([67105](https://github.com/WordPress/gutenberg/pull/67105)) +- Font family preview in the font family picker. ([67118](https://github.com/WordPress/gutenberg/pull/67118)) + +### Bug Fixes + + + + +#### Block Library +- Fix block mover clickable area. ([67261](https://github.com/WordPress/gutenberg/pull/67261)) +- Fix dropping media from inserter into Cover block. ([67056](https://github.com/WordPress/gutenberg/pull/67056)) +- Fix: Preserve Display Preview State in File Block. ([67263](https://github.com/WordPress/gutenberg/pull/67263)) +- Paragraph: Update condition for rendering Drop Cap for a selected block. ([67111](https://github.com/WordPress/gutenberg/pull/67111)) +- RSS block: Check for description field before rendering excerpt. ([66985](https://github.com/WordPress/gutenberg/pull/66985)) +- Resolve search block button text overlapping issue. ([66868](https://github.com/WordPress/gutenberg/pull/66868)) +- Social Links: Fix font family and weight inconsistency in editor. ([67204](https://github.com/WordPress/gutenberg/pull/67204)) + +#### Components +- Composite: Restore `Hover` and `Typeahead` functionality. ([67212](https://github.com/WordPress/gutenberg/pull/67212)) +- Menu.ItemHelpText: Better line breaking. ([67011](https://github.com/WordPress/gutenberg/pull/67011)) +- SlotFill: Fix a bug with storing stale fillProps. ([67000](https://github.com/WordPress/gutenberg/pull/67000)) +- Storybook: Fix DataViews layout. ([66999](https://github.com/WordPress/gutenberg/pull/66999)) +- `FormFileUpload`: Prevent HEIC and HEIF files from always being uploaded on Safari. ([67139](https://github.com/WordPress/gutenberg/pull/67139)) + +#### Block Editor +- Add all color palettes to select from editor panel. ([65148](https://github.com/WordPress/gutenberg/pull/65148)) +- Correctly mark Block Comment SlotFills private. ([67271](https://github.com/WordPress/gutenberg/pull/67271)) +- Fix media placeholder to only activate for media objects. ([66986](https://github.com/WordPress/gutenberg/pull/66986)) +- Rich text: Preserve comments. ([62128](https://github.com/WordPress/gutenberg/pull/62128)) +- Fix TS types for the editor package. ([67196](https://github.com/WordPress/gutenberg/pull/67196)) +- PostTitle: Exit early when post type doesn't support titles. ([67086](https://github.com/WordPress/gutenberg/pull/67086)) + +#### Global Styles +- Avoid zooming out when browsing styles if the preview mode is active. ([67190](https://github.com/WordPress/gutenberg/pull/67190)) +- Remove styles from blocks' previews. ([67144](https://github.com/WordPress/gutenberg/pull/67144)) +- Style panel: Use correct revisions count. ([67180](https://github.com/WordPress/gutenberg/pull/67180)) +- Theme JSON: Include block style variations in path only output of get_block_nodes. ([66948](https://github.com/WordPress/gutenberg/pull/66948)) +- Fix: Logic for Highlight/text-color format availability. ([65530](https://github.com/WordPress/gutenberg/pull/65530)) +- Fix complex variation selectors when using selectors API. ([67061](https://github.com/WordPress/gutenberg/pull/67061)) +#### Site Editor +- Prevent Pre-Publish Panel from Displaying Incorrect Information After Navigating away. ([67010](https://github.com/WordPress/gutenberg/pull/67010)) +- Site Editor Sidebar: Fixed focus/hover style for navigation item buttons. ([67251](https://github.com/WordPress/gutenberg/pull/67251)) +- Site Hub: Fix height in mobile layout. ([67110](https://github.com/WordPress/gutenberg/pull/67110)) +- Site Editor: Styles: Fix inspector opening. ([67004](https://github.com/WordPress/gutenberg/pull/67004)) +- Improve accessibility and consistency of the 'Last modified' Revisions button. ([66606](https://github.com/WordPress/gutenberg/pull/66606)) +- Remove styles from examples. ([67098](https://github.com/WordPress/gutenberg/pull/67098)) +- Editor: Correctly select post title support in 'DocumentOutline'. ([67109](https://github.com/WordPress/gutenberg/pull/67109)) + + +#### DataViews +- Fix action visibility logic. ([67197](https://github.com/WordPress/gutenberg/pull/67197)) +- Fix primary field misalignment in grid layout. ([66995](https://github.com/WordPress/gutenberg/pull/66995)) +- Fix spacing when combining combined fields. ([67226](https://github.com/WordPress/gutenberg/pull/67226)) + +#### Zoom Out +- Zoom In/Out to correct canvas location. ([66917](https://github.com/WordPress/gutenberg/pull/66917)) +- Zoom in/out to correct location. ([67126](https://github.com/WordPress/gutenberg/pull/67126)) +- Zoom Out: Disable zooming out when Distraction Free mode is activated. ([67028](https://github.com/WordPress/gutenberg/pull/67028)) + +#### Layout +- Allow flex justification controls to be disabled at the block level. ([67059](https://github.com/WordPress/gutenberg/pull/67059)) +- Show vertical alignment toolbar with allowSwitching enabled. ([67022](https://github.com/WordPress/gutenberg/pull/67022)) + +#### Patterns +- Fix: JavaScript error when pattern category is unregistered. ([67063](https://github.com/WordPress/gutenberg/pull/67063)) +- Block Locking: Remove edit locking for Synced Patterns. ([67021](https://github.com/WordPress/gutenberg/pull/67021)) + +### Accessibility + +#### Components +- ColorPicker: Add accessible label for copy button. ([67094](https://github.com/WordPress/gutenberg/pull/67094)) +- Modal: Increase size of the Close button. ([66792](https://github.com/WordPress/gutenberg/pull/66792)) +- DataViews: Fix focus loss when removing all filters or resetting. ([67003](https://github.com/WordPress/gutenberg/pull/67003)) + +#### Block Library +- Improve accessibility of the video track editor. ([66832](https://github.com/WordPress/gutenberg/pull/66832)) +- Navigation: Fix 'ariaLabel' block support. ([66943](https://github.com/WordPress/gutenberg/pull/66943)) + +#### Post Editor +- Improve the featured image UI when it cannot retrieve the image file and data. ([66936](https://github.com/WordPress/gutenberg/pull/66936)) + +### Experiments + +- Inline Commenting: Update placement of reply input and add author info header. ([66580](https://github.com/WordPress/gutenberg/pull/66580)) +- Place "Write mode" functionality behind a Gutenberg experiment. ([67008](https://github.com/WordPress/gutenberg/pull/67008)) + +### Documentation + +- Add documentation about required Core changes when updating minimum WordPress version. ([67167](https://github.com/WordPress/gutenberg/pull/67167)) +- BoxControl: Auto-generate readme. ([67284](https://github.com/WordPress/gutenberg/pull/67284)) +- Components contributing guide: Fix relative links. ([67323](https://github.com/WordPress/gutenberg/pull/67323)) +- DataViews: Reorganize documentation for actions. ([67159](https://github.com/WordPress/gutenberg/pull/67159)) +- Docs: Correct `@return` type in `block_core_query_disable_enhanced_pagination()`. ([67128](https://github.com/WordPress/gutenberg/pull/67128)) +- Feat: Storybook: Improve component organisation - Layout Category - Issue #66275. ([66659](https://github.com/WordPress/gutenberg/pull/66659)) +- Feat: Storybook: Improve component organisation - Selection & Input Category - Issue #66275. ([66635](https://github.com/WordPress/gutenberg/pull/66635)) +- GradientPicker: Auto-generate readme. ([67250](https://github.com/WordPress/gutenberg/pull/67250)) +- Icon: Auto-generate readme. ([67282](https://github.com/WordPress/gutenberg/pull/67282)) +- Icon: Improve `icon` prop usage documentation in Storybook. ([67280](https://github.com/WordPress/gutenberg/pull/67280)) +- Storybook: Restore stable components back into categories. ([67216](https://github.com/WordPress/gutenberg/pull/67216)) +- Update BlockMover Stories and README. ([66519](https://github.com/WordPress/gutenberg/pull/66519)) +- Update custom store readme to use thunks instead of controls. ([67006](https://github.com/WordPress/gutenberg/pull/67006)) +- Update versions-in-wordpress.md. ([67298](https://github.com/WordPress/gutenberg/pull/67298)) + +### Code Quality + +- ESLint: Enable `eslint-plugin-react-compiler`. ([61788](https://github.com/WordPress/gutenberg/pull/61788)) +- Extract selectors from useResolveEditedEntity hook. ([67031](https://github.com/WordPress/gutenberg/pull/67031)) +- Pattern: Remove backward compatibility code for WordPress < 6.4. ([67131](https://github.com/WordPress/gutenberg/pull/67131)) +- Post fields: Move `author` from `edit-site` to `fields` package. ([66939](https://github.com/WordPress/gutenberg/pull/66939)) +- Posts DataViews: Refactor the router to use route registration. ([67160](https://github.com/WordPress/gutenberg/pull/67160)) +- Comments controller: Fix issue where comments are allowed when closed. ([66976](https://github.com/WordPress/gutenberg/pull/66976)) +- Fix fatal error in in_array call in post_type_default_rendering_mode. ([67225](https://github.com/WordPress/gutenberg/pull/67225)) +- Data: Add changelog for Redux update. ([66968](https://github.com/WordPress/gutenberg/pull/66968)) + +#### Components +- BorderBoxControl: Suppress redundant warnings for deprecated 36px size. ([67213](https://github.com/WordPress/gutenberg/pull/67213)) +- ComboboxControl : Deprecate 36px default size. ([66900](https://github.com/WordPress/gutenberg/pull/66900)) +- CustomGradientPicker: Prepare `Button`s for 40px default size. ([67286](https://github.com/WordPress/gutenberg/pull/67286)) +- Dashicons: Remove non-existent icons from type. ([67235](https://github.com/WordPress/gutenberg/pull/67235)) +- DimensionControl: Deprecate 36px default size. ([66705](https://github.com/WordPress/gutenberg/pull/66705)) +- Feat: Adds the deprecation warning for 36px default size in range control. ([66721](https://github.com/WordPress/gutenberg/pull/66721)) +- FontSizePicker : Deprecate 36px default size. ([66920](https://github.com/WordPress/gutenberg/pull/66920)) +- Remove createPrivateSlotFill function. ([67238](https://github.com/WordPress/gutenberg/pull/67238)) +- SlotFill: Fix dependencies of registration effects, deduplicate code. ([67071](https://github.com/WordPress/gutenberg/pull/67071)) +- SlotFill: Remove registration API from useSlot result. ([67070](https://github.com/WordPress/gutenberg/pull/67070)) +- SlotFill: Rewrite base Slot to functional, unify rerenderable refs. ([67153](https://github.com/WordPress/gutenberg/pull/67153)) +- TextControl: Deprecate 36px default size. ([66745](https://github.com/WordPress/gutenberg/pull/66745)) +- ToggleGroupControl : Deprecate 36px default size. ([66747](https://github.com/WordPress/gutenberg/pull/66747)) + +#### Post Editor +- ESLint: Bump `eslint-plugin-react-compiler` to latest beta. ([67106](https://github.com/WordPress/gutenberg/pull/67106)) +- Edit Post: Refactor 'MetaBoxVisibility' component. ([67265](https://github.com/WordPress/gutenberg/pull/67265)) +- Edit Post: Remove unused 'hasHistory' flag. ([67293](https://github.com/WordPress/gutenberg/pull/67293)) +- Editor: Update focus return handler for the Featured Image. ([67236](https://github.com/WordPress/gutenberg/pull/67236)) +- Make `BlockManager` component reusable. ([67052](https://github.com/WordPress/gutenberg/pull/67052)) +- Preferences: Use hooks instead of HoC in 'EnableCustomFieldsOption'. ([67023](https://github.com/WordPress/gutenberg/pull/67023)) +- Preferences: Use hooks instead of HoC in 'EnablePanelOption'. ([66994](https://github.com/WordPress/gutenberg/pull/66994)) +- Preferences: Use hooks instead of HoC in 'EnablePublishSidebarOption'. ([67002](https://github.com/WordPress/gutenberg/pull/67002)) + +#### Block Library +- Fix React Compiler error for shortcuts. ([67019](https://github.com/WordPress/gutenberg/pull/67019)) +- Home Link: Remove label attribute synchronization. ([67151](https://github.com/WordPress/gutenberg/pull/67151)) +- Use rems for Nav overlay left padding. ([67168](https://github.com/WordPress/gutenberg/pull/67168)) +- useBlockNameForPatterns: Refactor as a single useSelect call. ([67171](https://github.com/WordPress/gutenberg/pull/67171)) +- Navigation Block: Remove obsolete Block Hooks filters. ([64676](https://github.com/WordPress/gutenberg/pull/64676)) +- [mini] 🧹 remove obsolete rich text css. ([67264](https://github.com/WordPress/gutenberg/pull/67264)) + +#### Global Styles +- Don't call store actions during the render. ([67146](https://github.com/WordPress/gutenberg/pull/67146)) +- Edit Site: Fix settings mutation in `ScreenBlock`. ([67085](https://github.com/WordPress/gutenberg/pull/67085)) +- Remove unused 'Fragment' import. ([67104](https://github.com/WordPress/gutenberg/pull/67104)) + +#### Block Editor +- Block Manager: Make it a private component in the block editor package. ([67255](https://github.com/WordPress/gutenberg/pull/67255)) +- Inserter: Set initial active tab ID during render. ([67103](https://github.com/WordPress/gutenberg/pull/67103)) + +#### Site Editor +- Deprecate edited entity state. ([66965](https://github.com/WordPress/gutenberg/pull/66965)) +- Remove redundant style-edit route. ([67057](https://github.com/WordPress/gutenberg/pull/67057)) + +### Tools + +#### Testing +- Fix ESLint Jest reporting entire body of the test function rather than the identifier. ([67222](https://github.com/WordPress/gutenberg/pull/67222)) +- Fix typo in use-block-sync tests. ([67145](https://github.com/WordPress/gutenberg/pull/67145)) +- Migrate Gradle wrapper validation action. ([66602](https://github.com/WordPress/gutenberg/pull/66602)) + +#### Plugin +- Bump minimum required WordPress version to 6.6. ([67117](https://github.com/WordPress/gutenberg/pull/67117)) +- Add #7895 Core Backport PR to the changelog. ([67319](https://github.com/WordPress/gutenberg/pull/67319)) +- WP Scripts: Revert changes that inline CSS imports early in the build process. ([66975](https://github.com/WordPress/gutenberg/pull/66975)) + +## First-time contributors + +The following PRs were merged by first-time contributors: + +- @AKSHAT2802: Add all color palettes to select from editor panel. ([65148](https://github.com/WordPress/gutenberg/pull/65148)) +- @benazeer-ben: Page List : Add border and spacing support. ([66385](https://github.com/WordPress/gutenberg/pull/66385)) +- @himanshupathak95: Menu.ItemHelpText: Better line breaking. ([67011](https://github.com/WordPress/gutenberg/pull/67011)) +- @SainathPoojary: Social Links: Fix font family and weight inconsistency in editor. ([67204](https://github.com/WordPress/gutenberg/pull/67204)) +- @sarthaknagoshe2002: Prevent Pre-Publish Panel from Displaying Incorrect Information After Navigating away. ([67010](https://github.com/WordPress/gutenberg/pull/67010)) +- @Sukhendu2002: Fix: Preserve Display Preview State in File Block. ([67263](https://github.com/WordPress/gutenberg/pull/67263)) + + +## Contributors + +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) + + += 19.6.3 = + +- Revert "Set image width to fit-content to solve aspect ratio problems in Firefox. ([#66217](https://github.com/WordPress/gutenberg/pull/66804)) + + += 19.7.0-rc.2 = + + +- Comments controller: fix issue where comments are allowed when closed (https://github.com/WordPress/gutenberg/pull/66976) + + += 19.6.2 = + +- Comments controller: fix issue where comments are allowed when closed [#66976](https://github.com/WordPress/gutenberg/pull/66976) + + += 19.7.0-rc.1 = + + +## 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)) + +#### 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.1 = + + +## Changelog + +### Bug Fixes + +#### List View +- Block Editor: Fix stale dependencies of selectors depending on editorTool preference. ([66833](https://github.com/WordPress/gutenberg/pull/66833)) + + + + +## Contributors + +The following contributors merged PRs in this release: + +@mcsf + + = 19.6.0 = diff --git a/docs/contributors/versions-in-wordpress.md b/docs/contributors/versions-in-wordpress.md index 62347f2d644a61..c2be7e3fa4e884 100644 --- a/docs/contributors/versions-in-wordpress.md +++ b/docs/contributors/versions-in-wordpress.md @@ -6,7 +6,9 @@ If anything looks incorrect here, please bring it up in #core-editor in [WordPre | Gutenberg Versions | WordPress Version | | ------------------ | ----------------- | +| 18.6-19.3 | 6.7.1 | | 18.6-19.3 | 6.7 | +| 17.8-18.5 | 6.6.2 | | 17.8-18.5 | 6.6.1 | | 17.8-18.5 | 6.6 | | 16.8-17.7 | 6.5.5 | diff --git a/docs/explanations/architecture/performance.md b/docs/explanations/architecture/performance.md index 4c8b6386b9263b..8c1034ad9de331 100644 --- a/docs/explanations/architecture/performance.md +++ b/docs/explanations/architecture/performance.md @@ -84,6 +84,12 @@ The new reference commit hash that is chosen needs to meet the following require - Be compatible with the new WP version used in the "Tested up to" flag. - Is already tracked on "codevitals.run" for all existing metrics. +When releasing a plugin update with changes to the minimum WordPress version requirements, the end-to-end test GitHub Action workflow in Core SVN will need to be updated for any branch losing support. Otherwise the first run of that workflow on that branch following the release will fail. + +The version of the plugin used in the workflow can be pinned by adding the `gutenberg-version` input to the test matrix. [Core-59221](https://core.trac.wordpress.org/changeset/59221) is an example of this change for the 6.4 branch. + +**Note:** Always use the final release including bug fixes (ie. `x.y.2` or `x.y.3`). If the final release is not yet known, create a [Trac ticket](https://core.trac.wordpress.org/ticket/62488) so it's not forgotten. + **A simple way to choose commit is to pick a very recent commit on trunk with a passing performance job.** ## Going further diff --git a/docs/explanations/architecture/styles.md b/docs/explanations/architecture/styles.md index 68f09f04d21d32..5f5e73d1372f7b 100644 --- a/docs/explanations/architecture/styles.md +++ b/docs/explanations/architecture/styles.md @@ -37,8 +37,10 @@ The user may change the state of this block by applying different styles: a text After some user modifications to the block, the initial markup may become something like this: ```html -

+

``` This is what we refer to as "user-provided block styles", also know as "local styles" or "serialized styles". Essentially, each tool (font size, color, etc) ends up adding some classes and/or inline styles to the block markup. The CSS styling for these classes is part of the block, global, or theme stylesheets. @@ -123,7 +125,7 @@ The block supports API only serializes the font size value to the wrapper, resul This is an active area of work you can follow [in the tracking issue](https://github.com/WordPress/gutenberg/issues/38167). The linked proposal is exploring a different way to serialize the user changes: instead of each block support serializing its own data (for example, classes such as `has-small-font-size`, `has-green-color`) the idea is the block would get a single class instead (for example, `wp-style-UUID`) and the CSS styling for that class will be generated in the server by WordPress. -While work continues in that proposal, there's an escape hatch, an experimental option block authors can use. Any block support can skip the serialization to HTML markup by using `__experimentalSkipSerialization`. For example: +While work continues in that proposal, there's an escape hatch, an experimental option block authors can use. Any block support can skip the serialization to HTML markup by using `skipSerialization`. For example: ```json { @@ -132,7 +134,7 @@ While work continues in that proposal, there's an escape hatch, an experimental "supports": { "typography": { "fontSize": true, - "__experimentalSkipSerialization": true + "skipSerialization": true } } } @@ -140,7 +142,7 @@ While work continues in that proposal, there's an escape hatch, an experimental This means that the typography block support will do all of the things (create a UI control, bind the block attribute to the control, etc) except serializing the user values into the HTML markup. The classes and inline styles will not be automatically applied to the wrapper and it is the block author's responsibility to implement this in the `edit`, `save`, and `render_callback` functions. See [this issue](https://github.com/WordPress/gutenberg/issues/28913) for examples of how it was done for some blocks provided by WordPress. -Note that, if `__experimentalSkipSerialization` is enabled for a group (typography, color, spacing) it affects _all_ block supports within this group. In the example above _all_ the properties within the `typography` group will be affected (e.g. `fontSize`, `lineHeight`, `fontFamily` .etc). +Note that, if `skipSerialization` is enabled for a group (typography, color, spacing) it affects _all_ block supports within this group. In the example above _all_ the properties within the `typography` group will be affected (e.g. `fontSize`, `lineHeight`, `fontFamily` .etc). To enable for a _single_ property only, you may use an array to declare which properties are to be skipped. In the example below, only `fontSize` will skip serialization, leaving other items within the `typography` group (e.g. `lineHeight`, `fontFamily` .etc) unaffected. @@ -152,7 +154,7 @@ To enable for a _single_ property only, you may use an array to declare which pr "typography": { "fontSize": true, "lineHeight": true, - "__experimentalSkipSerialization": [ "fontSize" ] + "skipSerialization": [ "fontSize" ] } } } @@ -473,7 +475,7 @@ If blocks do this, they need to be registered in the server using the `block.jso Every chunk of styles can only use a single selector. -This is particularly relevant if the block is using `__experimentalSkipSerialization` to serialize the different style properties to different nodes other than the wrapper. See "Current limitations of blocks supports" for more. +This is particularly relevant if the block is using `skipSerialization` to serialize the different style properties to different nodes other than the wrapper. See "Current limitations of blocks supports" for more. #### 3. **Only a single property per block** diff --git a/docs/getting-started/fundamentals/block-in-the-editor.md b/docs/getting-started/fundamentals/block-in-the-editor.md index d1f2a25063e6c6..1d51239907d8b5 100644 --- a/docs/getting-started/fundamentals/block-in-the-editor.md +++ b/docs/getting-started/fundamentals/block-in-the-editor.md @@ -139,6 +139,8 @@ export default function Edit( { attributes, setAttributes } ) { setAttributes( { message: val } ) } style={ { diff --git a/docs/getting-started/tutorial.md b/docs/getting-started/tutorial.md index 4e43241f63fb16..2a5dd979d3a569 100644 --- a/docs/getting-started/tutorial.md +++ b/docs/getting-started/tutorial.md @@ -480,6 +480,8 @@ export default function Edit( { attributes, setAttributes } ) { { showStartingYear && ( @@ -139,6 +141,8 @@ function EditPageForm( { pageId, onCancel, onSaveFinished } ) { return (
@@ -164,6 +168,8 @@ function VanillaReactForm({ initialTitle }) { const [title, setTitle] = useState( initialTitle ); return ( @@ -233,6 +239,8 @@ function EditPageForm( { pageId, onCancel, onSaveFinished } ) { return (
diff --git a/docs/reference-guides/block-api/block-edit-save.md b/docs/reference-guides/block-api/block-edit-save.md index 9e4dd3d1a916bd..86721c77e463c6 100644 --- a/docs/reference-guides/block-api/block-edit-save.md +++ b/docs/reference-guides/block-api/block-edit-save.md @@ -210,6 +210,8 @@ edit: ( { attributes, setAttributes } ) => { return (
{ return (
{ diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 4db90e9b2f8142..34db859f71d1de 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -254,7 +254,7 @@ Hide and show additional content. ([Source](https://github.com/WordPress/gutenbe - **Name:** core/details - **Category:** text -- **Supports:** align (full, wide), color (background, gradients, link, text), interactivity (clientNavigation), layout (~~allowEditing~~), spacing (blockGap, margin, padding), typography (fontSize, lineHeight), ~~html~~ +- **Supports:** align (full, wide), anchor, color (background, gradients, link, text), interactivity (clientNavigation), layout (~~allowEditing~~), spacing (blockGap, margin, padding), typography (fontSize, lineHeight), ~~html~~ - **Attributes:** showContent, summary ## Embed @@ -512,7 +512,7 @@ Display a list of all pages. ([Source](https://github.com/WordPress/gutenberg/tr - **Name:** core/page-list - **Category:** widgets - **Allowed Blocks:** core/page-list-item -- **Supports:** interactivity (clientNavigation), typography (fontSize, lineHeight), ~~html~~, ~~reusable~~ +- **Supports:** interactivity (clientNavigation), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~, ~~reusable~~ - **Attributes:** isNested, parentPageID ## Page List Item diff --git a/docs/reference-guides/data/data-core-edit-site.md b/docs/reference-guides/data/data-core-edit-site.md index 775dd66a821ef0..a16c53861daada 100644 --- a/docs/reference-guides/data/data-core-edit-site.md +++ b/docs/reference-guides/data/data-core-edit-site.md @@ -52,6 +52,8 @@ _Returns_ ### getEditedPostId +> **Deprecated** + Returns the ID of the currently edited template or template part. _Parameters_ @@ -64,6 +66,8 @@ _Returns_ ### getEditedPostType +> **Deprecated** + Returns the current edited post type (wp_template or wp_template_part). _Parameters_ @@ -189,6 +193,8 @@ _Returns_ ### isPage +> **Deprecated** + Whether or not the editor has a page loaded into it. _Related_ @@ -273,6 +279,8 @@ _Parameters_ ### setEditedEntity +> **Deprecated** + Action that sets an edited entity. _Parameters_ @@ -287,6 +295,8 @@ _Returns_ ### setEditedPostContext +> **Deprecated** + Set's the current block editor context. _Parameters_ @@ -345,6 +355,8 @@ _Parameters_ ### setNavigationMenu +> **Deprecated** + Action that sets a navigation menu. _Parameters_ @@ -385,6 +397,8 @@ _Returns_ ### setTemplatePart +> **Deprecated** + Action that sets a template part. _Parameters_ diff --git a/docs/reference-guides/data/data-core-editor.md b/docs/reference-guides/data/data-core-editor.md index 9567d8e4b954fa..44078ab284e94f 100644 --- a/docs/reference-guides/data/data-core-editor.md +++ b/docs/reference-guides/data/data-core-editor.md @@ -1148,7 +1148,8 @@ Action that autosaves the current post. This includes server-side autosaving (de _Parameters_ -- _options_ `Object?`: Extra flags to identify the autosave. +- _options_ `[Object]`: Extra flags to identify the autosave. +- _options.local_ `[boolean]`: Whether to perform a local autosave. ### clearSelectedBlock @@ -1204,7 +1205,7 @@ const getFeaturedMediaUrl = useSelect( ( select ) => { _Parameters_ - _edits_ `Object`: Post attributes to edit. -- _options_ `Object`: Options for the edit. +- _options_ `[Object]`: Options for the edit. _Returns_ @@ -1417,7 +1418,7 @@ Returns an action object used to signal that the blocks have been updated. _Parameters_ - _blocks_ `Array`: Block Array. -- _options_ `?Object`: Optional options. +- _options_ `[Object]`: Optional options. ### resetPost @@ -1431,7 +1432,7 @@ Action for saving the current post in the editor. _Parameters_ -- _options_ `Object`: +- _options_ `[Object]`: ### selectBlock @@ -1519,7 +1520,7 @@ _Parameters_ - _post_ `Object`: Post object. - _edits_ `Object`: Initial edited attributes object. -- _template_ `Array?`: Block Template. +- _template_ `[Array]`: Block Template. ### setupEditorState diff --git a/docs/reference-guides/slotfills/plugin-sidebar-more-menu-item.md b/docs/reference-guides/slotfills/plugin-sidebar-more-menu-item.md index 4a4ff98697b5f3..1a1b2540b258b9 100644 --- a/docs/reference-guides/slotfills/plugin-sidebar-more-menu-item.md +++ b/docs/reference-guides/slotfills/plugin-sidebar-more-menu-item.md @@ -45,6 +45,8 @@ const PluginSidebarMoreMenuItemTest = () => { ) }

setText( newText ) } diff --git a/docs/reference-guides/slotfills/plugin-sidebar.md b/docs/reference-guides/slotfills/plugin-sidebar.md index 9bf911b3bb13f2..7191b80e54e2d6 100644 --- a/docs/reference-guides/slotfills/plugin-sidebar.md +++ b/docs/reference-guides/slotfills/plugin-sidebar.md @@ -38,6 +38,8 @@ const PluginSidebarExample = () => { ) }

setText( newText ) } diff --git a/gutenberg.php b/gutenberg.php index 89e65de4e94794..40c4e86fbb1bf5 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -3,9 +3,9 @@ * Plugin Name: Gutenberg * Plugin URI: https://github.com/WordPress/gutenberg * 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.5 + * Requires at least: 6.6 * Requires PHP: 7.2 - * Version: 19.6.0 + * Version: 19.8.0-rc.1 * Author: Gutenberg Team * Text Domain: gutenberg * @@ -15,7 +15,7 @@ ### BEGIN AUTO-GENERATED DEFINES defined( 'GUTENBERG_DEVELOPMENT_MODE' ) or define( 'GUTENBERG_DEVELOPMENT_MODE', true ); ### END AUTO-GENERATED DEFINES -defined( 'GUTENBERG_MINIMUM_WP_VERSION' ) or define( 'GUTENBERG_MINIMUM_WP_VERSION', '6.5' ); +defined( 'GUTENBERG_MINIMUM_WP_VERSION' ) or define( 'GUTENBERG_MINIMUM_WP_VERSION', '6.6' ); gutenberg_pre_init(); diff --git a/lib/block-supports/border.php b/lib/block-supports/border.php index bd4c772675a5ed..f890ed84566b7f 100644 --- a/lib/block-supports/border.php +++ b/lib/block-supports/border.php @@ -17,7 +17,7 @@ function gutenberg_register_border_support( $block_type ) { $block_type->attributes = array(); } - if ( block_has_support( $block_type, array( '__experimentalBorder' ) ) && ! array_key_exists( 'style', $block_type->attributes ) ) { + if ( block_has_support( $block_type, array( 'border' ) ) && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); @@ -52,7 +52,7 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) { if ( gutenberg_has_border_feature_support( $block_type, 'radius' ) && isset( $block_attributes['style']['border']['radius'] ) && - ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'radius' ) + ! wp_should_skip_block_supports_serialization( $block_type, 'border', 'radius' ) ) { $border_radius = $block_attributes['style']['border']['radius']; @@ -67,7 +67,7 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) { if ( gutenberg_has_border_feature_support( $block_type, 'style' ) && isset( $block_attributes['style']['border']['style'] ) && - ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'style' ) + ! wp_should_skip_block_supports_serialization( $block_type, 'border', 'style' ) ) { $border_block_styles['style'] = $block_attributes['style']['border']['style']; } @@ -76,7 +76,7 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) { if ( $has_border_width_support && isset( $block_attributes['style']['border']['width'] ) && - ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' ) + ! wp_should_skip_block_supports_serialization( $block_type, 'border', 'width' ) ) { $border_width = $block_attributes['style']['border']['width']; @@ -91,7 +91,7 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) { // Border color. if ( $has_border_color_support && - ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' ) + ! wp_should_skip_block_supports_serialization( $block_type, 'border', 'color' ) ) { $preset_border_color = array_key_exists( 'borderColor', $block_attributes ) ? "var:preset|color|{$block_attributes['borderColor']}" : null; $custom_border_color = $block_attributes['style']['border']['color'] ?? null; @@ -103,9 +103,9 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) { foreach ( array( 'top', 'right', 'bottom', 'left' ) as $side ) { $border = $block_attributes['style']['border'][ $side ] ?? null; $border_side_values = array( - 'width' => isset( $border['width'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' ) ? $border['width'] : null, - 'color' => isset( $border['color'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' ) ? $border['color'] : null, - 'style' => isset( $border['style'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'style' ) ? $border['style'] : null, + 'width' => isset( $border['width'] ) && ! wp_should_skip_block_supports_serialization( $block_type, 'border', 'width' ) ? $border['width'] : null, + 'color' => isset( $border['color'] ) && ! wp_should_skip_block_supports_serialization( $block_type, 'border', 'color' ) ? $border['color'] : null, + 'style' => isset( $border['style'] ) && ! wp_should_skip_block_supports_serialization( $block_type, 'border', 'style' ) ? $border['style'] : null, ); $border_block_styles[ $side ] = $border_side_values; } @@ -129,9 +129,9 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) { /** * Checks whether the current block type supports the border feature requested. * - * If the `__experimentalBorder` support flag is a boolean `true` all border + * If the `border` support flag is a boolean `true` all border * support features are available. Otherwise, the specific feature's support - * flag nested under `experimentalBorder` must be enabled for the feature + * flag nested under `border` must be enabled for the feature * to be opted into. * * @param WP_Block_Type $block_type Block type to check for support. @@ -141,17 +141,17 @@ function gutenberg_apply_border_support( $block_type, $block_attributes ) { * @return boolean Whether or not the feature is supported. */ function gutenberg_has_border_feature_support( $block_type, $feature, $default_value = false ) { - // Check if all border support features have been opted into via `"__experimentalBorder": true`. + // Check if all border support features have been opted into via `"border": true`. if ( $block_type instanceof WP_Block_Type ) { - $block_type_supports_border = $block_type->supports['__experimentalBorder'] ?? $default_value; + $block_type_supports_border = $block_type->supports['border'] ?? $default_value; if ( true === $block_type_supports_border ) { return true; } } // Check if the specific feature has been opted into individually - // via nested flag under `__experimentalBorder`. - return block_has_support( $block_type, array( '__experimentalBorder', $feature ), $default_value ); + // via nested flag under `border`. + return block_has_support( $block_type, array( 'border', $feature ), $default_value ); } // Register the block support. diff --git a/lib/block-template-utils.php b/lib/block-template-utils.php index a644047d3cfdc1..7dba2ff518104d 100644 --- a/lib/block-template-utils.php +++ b/lib/block-template-utils.php @@ -60,7 +60,7 @@ function gutenberg_generate_block_templates_export_file() { } // Load templates into the zip file. - $templates = gutenberg_get_block_templates(); + $templates = get_block_templates(); foreach ( $templates as $template ) { $template->content = traverse_and_serialize_blocks( parse_blocks( $template->content ), @@ -74,7 +74,7 @@ function gutenberg_generate_block_templates_export_file() { } // Load template parts into the zip file. - $template_parts = gutenberg_get_block_templates( array(), 'wp_template_part' ); + $template_parts = get_block_templates( array(), 'wp_template_part' ); foreach ( $template_parts as $template_part ) { $zip->addFromString( 'parts/' . $template_part->slug . '.html', diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index dafa8b25f278fc..083ce3516b71af 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -615,10 +615,10 @@ class WP_Theme_JSON_Gutenberg { * @var string[] */ const BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS = array( - '__experimentalBorder' => 'border', - 'color' => 'color', - 'spacing' => 'spacing', - 'typography' => 'typography', + 'border' => 'border', + 'color' => 'color', + 'spacing' => 'spacing', + 'typography' => 'typography', ); /** @@ -2749,9 +2749,21 @@ private static function get_block_nodes( $theme_json, $selectors = array(), $opt foreach ( $theme_json['styles']['blocks'] as $name => $node ) { $node_path = array( 'styles', 'blocks', $name ); if ( $include_node_paths_only ) { - $nodes[] = array( + $variation_paths = array(); + if ( $include_variations && isset( $node['variations'] ) ) { + foreach ( $node['variations'] as $variation => $variation_node ) { + $variation_paths[] = array( + 'path' => array( 'styles', 'blocks', $name, 'variations', $variation ), + ); + } + } + $node = array( 'path' => $node_path, ); + if ( ! empty( $variation_paths ) ) { + $node['variations'] = $variation_paths; + } + $nodes[] = $node; } else { $selector = null; if ( isset( $selectors[ $name ]['selector'] ) ) { @@ -2862,8 +2874,14 @@ public function get_styles_for_block( $block_metadata ) { // Combine selectors with style variation's selector and add to overall style variation declarations. foreach ( $variation_declarations as $current_selector => $new_declarations ) { - // If current selector includes block classname, remove it but leave the whitespace in. - $shortened_selector = str_replace( $block_metadata['selector'] . ' ', ' ', $current_selector ); + /* + * Clean up any whitespace between comma separated selectors. + * This prevents these spaces breaking compound selectors such as: + * - `.wp-block-list:not(.wp-block-list .wp-block-list)` + * - `.wp-block-image img, .wp-block-image.my-class img` + */ + $clean_current_selector = preg_replace( '/,\s+/', ',', $current_selector ); + $shortened_selector = str_replace( $block_metadata['selector'], '', $clean_current_selector ); // Prepend the variation selector to the current selector. $split_selectors = explode( ',', $shortened_selector ); @@ -3565,26 +3583,12 @@ public static function remove_insecure_properties( $theme_json, $origin = 'theme $variation_output = static::remove_insecure_styles( $variation_input ); - // Process a variation's elements and element pseudo selector styles. - if ( isset( $variation_input['elements'] ) ) { - foreach ( $valid_element_names as $element_name ) { - $element_input = $variation_input['elements'][ $element_name ] ?? null; - if ( $element_input ) { - $element_output = static::remove_insecure_styles( $element_input ); - - if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] ) ) { - foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] as $pseudo_selector ) { - if ( isset( $element_input[ $pseudo_selector ] ) ) { - $element_output[ $pseudo_selector ] = static::remove_insecure_styles( $element_input[ $pseudo_selector ] ); - } - } - } + if ( isset( $variation_input['blocks'] ) ) { + $variation_output['blocks'] = static::remove_insecure_inner_block_styles( $variation_input['blocks'] ); + } - if ( ! empty( $element_output ) ) { - _wp_array_set( $variation_output, array( 'elements', $element_name ), $element_output ); - } - } - } + if ( isset( $variation_input['elements'] ) ) { + $variation_output['elements'] = static::remove_insecure_element_styles( $variation_input['elements'] ); } if ( ! empty( $variation_output ) ) { @@ -3622,6 +3626,59 @@ public static function remove_insecure_properties( $theme_json, $origin = 'theme return $theme_json; } + /** + * Remove insecure element styles within a variation or block. + * + * @since 6.8.0 + * + * @param array $elements The elements to process. + * @return array The sanitized elements styles. + */ + protected static function remove_insecure_element_styles( $elements ) { + $sanitized = array(); + $valid_element_names = array_keys( static::ELEMENTS ); + + foreach ( $valid_element_names as $element_name ) { + $element_input = $elements[ $element_name ] ?? null; + if ( $element_input ) { + $element_output = static::remove_insecure_styles( $element_input ); + + if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] ) ) { + foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] as $pseudo_selector ) { + if ( isset( $element_input[ $pseudo_selector ] ) ) { + $element_output[ $pseudo_selector ] = static::remove_insecure_styles( $element_input[ $pseudo_selector ] ); + } + } + } + + $sanitized[ $element_name ] = $element_output; + } + } + return $sanitized; + } + + /** + * Remove insecure styles from inner blocks and their elements. + * + * @since 6.8.0 + * + * @param array $blocks The block styles to process. + * @return array Sanitized block type styles. + */ + protected static function remove_insecure_inner_block_styles( $blocks ) { + $sanitized = array(); + foreach ( $blocks as $block_type => $block_input ) { + $block_output = static::remove_insecure_styles( $block_input ); + + if ( isset( $block_input['elements'] ) ) { + $block_output['elements'] = static::remove_insecure_element_styles( $block_input['elements'] ); + } + + $sanitized[ $block_type ] = $block_output; + } + return $sanitized; + } + /** * Processes a setting node and returns the same node * without the insecure settings. diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php index cd02b5a45c22f7..1f45d897a77cc0 100644 --- a/lib/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/class-wp-theme-json-resolver-gutenberg.php @@ -316,7 +316,7 @@ public static function get_theme_data( $deprecated = array(), $options = array() * So we take theme supports, transform it to theme.json shape * and merge the static::$theme upon that. */ - $theme_support_data = WP_Theme_JSON_Gutenberg::get_from_editor_settings( gutenberg_get_classic_theme_supports_block_editor_settings() ); + $theme_support_data = WP_Theme_JSON_Gutenberg::get_from_editor_settings( get_classic_theme_supports_block_editor_settings() ); if ( ! wp_theme_has_theme_json() ) { /* * Unlike block themes, classic themes without a theme.json disable diff --git a/lib/compat/wordpress-6.6/admin-bar.php b/lib/compat/wordpress-6.6/admin-bar.php deleted file mode 100644 index b7a77faebea72a..00000000000000 --- a/lib/compat/wordpress-6.6/admin-bar.php +++ /dev/null @@ -1,48 +0,0 @@ -add_node( - array( - 'id' => 'site-editor', - 'title' => __( 'Edit site' ), - 'href' => add_query_arg( - array( - 'postType' => 'wp_template', - 'postId' => $_wp_current_template_id, - 'canvas' => 'edit', - ), - admin_url( 'site-editor.php' ) - ), - ) - ); -} -remove_action( 'admin_bar_menu', 'wp_admin_bar_edit_site_menu', 40 ); -add_action( 'admin_bar_menu', 'gutenberg_admin_bar_edit_site_menu', 41 ); diff --git a/lib/compat/wordpress-6.6/block-bindings/pattern-overrides.php b/lib/compat/wordpress-6.6/block-bindings/pattern-overrides.php deleted file mode 100644 index e5f9891f04c471..00000000000000 --- a/lib/compat/wordpress-6.6/block-bindings/pattern-overrides.php +++ /dev/null @@ -1,62 +0,0 @@ - "foo" ). - * @param WP_Block $block_instance The block instance. - * @param string $attribute_name The name of the target attribute. - * @return mixed The value computed for the source. - */ -function gutenberg_block_bindings_pattern_overrides_callback( $source_attrs, $block_instance, $attribute_name ) { - if ( ! isset( $block_instance->context['pattern/overrides'] ) ) { - return null; - } - - $override_content = $block_instance->context['pattern/overrides']; - - // Back compat. Pattern overrides previously used a metadata `id` instead of `name`. - // We check first for the name, and if it exists, use that value. - if ( isset( $block_instance->attributes['metadata']['name'] ) ) { - $metadata_name = $block_instance->attributes['metadata']['name']; - if ( array_key_exists( $metadata_name, $override_content ) ) { - return _wp_array_get( $override_content, array( $metadata_name, $attribute_name ), null ); - } - } - - // Next check for the `id`. - if ( isset( $block_instance->attributes['metadata']['id'] ) ) { - $metadata_id = $block_instance->attributes['metadata']['id']; - if ( array_key_exists( $metadata_id, $override_content ) ) { - return _wp_array_get( $override_content, array( $metadata_id, $attribute_name ), null ); - } - } - - return null; -} - -/** - * Registers Pattern Overrides source in the Block Bindings registry. - */ -function gutenberg_register_block_bindings_pattern_overrides_source() { - // Override the "core/pattern-overrides" source from core. - if ( array_key_exists( 'core/pattern-overrides', get_all_registered_block_bindings_sources() ) ) { - unregister_block_bindings_source( 'core/pattern-overrides' ); - } - register_block_bindings_source( - 'core/pattern-overrides', - array( - 'label' => _x( 'Pattern Overrides', 'block bindings source' ), - 'get_value_callback' => 'gutenberg_block_bindings_pattern_overrides_callback', - 'uses_context' => array( 'pattern/overrides' ), - ) - ); -} - -add_action( 'init', 'gutenberg_register_block_bindings_pattern_overrides_source' ); diff --git a/lib/compat/wordpress-6.6/block-editor.php b/lib/compat/wordpress-6.6/block-editor.php deleted file mode 100644 index 6253f6a0adca4f..00000000000000 --- a/lib/compat/wordpress-6.6/block-editor.php +++ /dev/null @@ -1,50 +0,0 @@ - get_theme_support( 'disable-custom-colors' ), - 'disableCustomFontSizes' => get_theme_support( 'disable-custom-font-sizes' ), - 'disableCustomGradients' => get_theme_support( 'disable-custom-gradients' ), - 'disableLayoutStyles' => get_theme_support( 'disable-layout-styles' ), - 'enableCustomLineHeight' => get_theme_support( 'custom-line-height' ), - 'enableCustomSpacing' => get_theme_support( 'custom-spacing' ), - 'enableCustomUnits' => get_theme_support( 'custom-units' ), - ); - - // Theme settings. - $color_palette = current( (array) get_theme_support( 'editor-color-palette' ) ); - if ( false !== $color_palette ) { - $theme_settings['colors'] = $color_palette; - } - - $font_sizes = current( (array) get_theme_support( 'editor-font-sizes' ) ); - if ( false !== $font_sizes ) { - $theme_settings['fontSizes'] = $font_sizes; - } - - $gradient_presets = current( (array) get_theme_support( 'editor-gradient-presets' ) ); - if ( false !== $gradient_presets ) { - $theme_settings['gradients'] = $gradient_presets; - } - - $spacing_sizes = current( (array) get_theme_support( 'editor-spacing-sizes' ) ); - if ( false !== $spacing_sizes ) { - $theme_settings['spacingSizes'] = $spacing_sizes; - } - - return $theme_settings; -} diff --git a/lib/compat/wordpress-6.6/block-template-utils.php b/lib/compat/wordpress-6.6/block-template-utils.php deleted file mode 100644 index 953f6bf20c077e..00000000000000 --- a/lib/compat/wordpress-6.6/block-template-utils.php +++ /dev/null @@ -1,362 +0,0 @@ - strlen( $item ) + 1 ) { - $template_hierarchy[] = "$type-$item"; - $template_hierarchy[] = $type; - break; - } - } - } - // Handle `archive` template. - if ( - str_starts_with( $slug, 'author' ) || - str_starts_with( $slug, 'taxonomy' ) || - str_starts_with( $slug, 'category' ) || - str_starts_with( $slug, 'tag' ) || - 'date' === $slug - ) { - $template_hierarchy[] = 'archive'; - } - // Handle `single` template. - if ( 'attachment' === $slug ) { - $template_hierarchy[] = 'single'; - } - // Handle `singular` template. - if ( - str_starts_with( $slug, 'single' ) || - str_starts_with( $slug, 'page' ) || - 'attachment' === $slug - ) { - $template_hierarchy[] = 'singular'; - } - $template_hierarchy[] = 'index'; - - $template_type = ''; - if ( ! empty( $template_prefix ) ) { - list( $template_type ) = explode( '-', $template_prefix ); - } else { - list( $template_type ) = explode( '-', $slug ); - } - $valid_template_types = array( '404', 'archive', 'attachment', 'author', 'category', 'date', 'embed', 'frontpage', 'home', 'index', 'page', 'paged', 'privacypolicy', 'search', 'single', 'singular', 'tag', 'taxonomy' ); - if ( in_array( $template_type, $valid_template_types, true ) ) { - /** This filter is documented in wp-includes/template.php */ - return apply_filters( "{$template_type}_template_hierarchy", $template_hierarchy ); - } - return $template_hierarchy; -} - -/** - * Retrieves the template files from the theme. - * - * @since 5.9.0 - * @since 6.3.0 Added the `$query` parameter. - * @access private - * - * @param string $template_type Template type. Either 'wp_template' or 'wp_template_part'. - * @param array $query { - * Arguments to retrieve templates. Optional, empty by default. - * - * @type string[] $slug__in List of slugs to include. - * @type string[] $slug__not_in List of slugs to skip. - * @type string $area A 'wp_template_part_area' taxonomy value to filter by (for 'wp_template_part' template type only). - * @type string $post_type Post type to get the templates for. - * } - * - * @return array Template - */ -function _gutenberg_get_block_templates_files( $template_type, $query = array() ) { - if ( 'wp_template' !== $template_type && 'wp_template_part' !== $template_type ) { - return null; - } - - // @core-merge: This code will go into Core's '_get_block_templates_files' function. - $default_template_types = array(); - if ( 'wp_template' === $template_type ) { - $default_template_types = get_default_block_template_types(); - } - // @core-merge: End of the code that will go into Core. - - // Prepare metadata from $query. - $slugs_to_include = isset( $query['slug__in'] ) ? $query['slug__in'] : array(); - $slugs_to_skip = isset( $query['slug__not_in'] ) ? $query['slug__not_in'] : array(); - $area = isset( $query['area'] ) ? $query['area'] : null; - $post_type = isset( $query['post_type'] ) ? $query['post_type'] : ''; - - $stylesheet = get_stylesheet(); - $template = get_template(); - $themes = array( - $stylesheet => get_stylesheet_directory(), - ); - // Add the parent theme if it's not the same as the current theme. - if ( $stylesheet !== $template ) { - $themes[ $template ] = get_template_directory(); - } - $template_files = array(); - foreach ( $themes as $theme_slug => $theme_dir ) { - $template_base_paths = get_block_theme_folders( $theme_slug ); - $theme_template_files = _get_block_templates_paths( $theme_dir . '/' . $template_base_paths[ $template_type ] ); - foreach ( $theme_template_files as $template_file ) { - $template_base_path = $template_base_paths[ $template_type ]; - $template_slug = substr( - $template_file, - // Starting position of slug. - strpos( $template_file, $template_base_path . DIRECTORY_SEPARATOR ) + 1 + strlen( $template_base_path ), - // Subtract ending '.html'. - -5 - ); - - // Skip this item if its slug doesn't match any of the slugs to include. - if ( ! empty( $slugs_to_include ) && ! in_array( $template_slug, $slugs_to_include, true ) ) { - continue; - } - - // Skip this item if its slug matches any of the slugs to skip. - if ( ! empty( $slugs_to_skip ) && in_array( $template_slug, $slugs_to_skip, true ) ) { - continue; - } - - /* - * The child theme items (stylesheet) are processed before the parent theme's (template). - * If a child theme defines a template, prevent the parent template from being added to the list as well. - */ - if ( isset( $template_files[ $template_slug ] ) ) { - continue; - } - - $new_template_item = array( - 'slug' => $template_slug, - 'path' => $template_file, - 'theme' => $theme_slug, - 'type' => $template_type, - ); - - if ( 'wp_template_part' === $template_type ) { - $candidate = _add_block_template_part_area_info( $new_template_item ); - if ( ! isset( $area ) || ( isset( $area ) && $area === $candidate['area'] ) ) { - $template_files[ $template_slug ] = $candidate; - } - } - - if ( 'wp_template' === $template_type ) { - $candidate = _add_block_template_info( $new_template_item ); - $is_custom = ! isset( $default_template_types[ $candidate['slug'] ] ); - - if ( - ! $post_type || - ( $post_type && isset( $candidate['postTypes'] ) && in_array( $post_type, $candidate['postTypes'], true ) ) - ) { - $template_files[ $template_slug ] = $candidate; - } - - // @core-merge: This code will go into Core's '_get_block_templates_files' function. - // The custom templates with no associated post-types are available for all post-types. - if ( $post_type && ! isset( $candidate['postTypes'] ) && $is_custom ) { - $template_files[ $template_slug ] = $candidate; - } - // @core-merge: End of the code that will go into Core. - } - } - } - - return array_values( $template_files ); -} - -/** - * Retrieves a list of unified template objects based on a query. - * - * @since 5.8.0 - * - * @param array $query { - * Optional. Arguments to retrieve templates. - * - * @type string[] $slug__in List of slugs to include. - * @type int $wp_id Post ID of customized template. - * @type string $area A 'wp_template_part_area' taxonomy value to filter by (for 'wp_template_part' template type only). - * @type string $post_type Post type to get the templates for. - * } - * @param string $template_type Template type. Either 'wp_template' or 'wp_template_part'. - * @return WP_Block_Template[] Array of block templates. - */ -function gutenberg_get_block_templates( $query = array(), $template_type = 'wp_template' ) { - /** - * Filters the block templates array before the query takes place. - * - * Return a non-null value to bypass the WordPress queries. - * - * @since 5.9.0 - * - * @param WP_Block_Template[]|null $block_templates Return an array of block templates to short-circuit the default query, - * or null to allow WP to run its normal queries. - * @param array $query { - * Arguments to retrieve templates. All arguments are optional. - * - * @type string[] $slug__in List of slugs to include. - * @type int $wp_id Post ID of customized template. - * @type string $area A 'wp_template_part_area' taxonomy value to filter by (for 'wp_template_part' template type only). - * @type string $post_type Post type to get the templates for. - * } - * @param string $template_type Template type. Either 'wp_template' or 'wp_template_part'. - */ - $templates = apply_filters( 'pre_get_block_templates', null, $query, $template_type ); - if ( ! is_null( $templates ) ) { - return $templates; - } - - $post_type = isset( $query['post_type'] ) ? $query['post_type'] : ''; - $wp_query_args = array( - 'post_status' => array( 'auto-draft', 'draft', 'publish' ), - 'post_type' => $template_type, - 'posts_per_page' => -1, - 'no_found_rows' => true, - 'lazy_load_term_meta' => false, - 'tax_query' => array( - array( - 'taxonomy' => 'wp_theme', - 'field' => 'name', - 'terms' => get_stylesheet(), - ), - ), - ); - - if ( 'wp_template_part' === $template_type && isset( $query['area'] ) ) { - $wp_query_args['tax_query'][] = array( - 'taxonomy' => 'wp_template_part_area', - 'field' => 'name', - 'terms' => $query['area'], - ); - $wp_query_args['tax_query']['relation'] = 'AND'; - } - - if ( ! empty( $query['slug__in'] ) ) { - $wp_query_args['post_name__in'] = $query['slug__in']; - $wp_query_args['posts_per_page'] = count( array_unique( $query['slug__in'] ) ); - } - - // This is only needed for the regular templates/template parts post type listing and editor. - if ( isset( $query['wp_id'] ) ) { - $wp_query_args['p'] = $query['wp_id']; - } else { - $wp_query_args['post_status'] = 'publish'; - } - - $template_query = new WP_Query( $wp_query_args ); - $query_result = array(); - foreach ( $template_query->posts as $post ) { - $template = _build_block_template_result_from_post( $post ); - - if ( is_wp_error( $template ) ) { - continue; - } - - if ( $post_type && ! $template->is_custom ) { - continue; - } - - if ( - $post_type && - isset( $template->post_types ) && - ! in_array( $post_type, $template->post_types, true ) - ) { - continue; - } - - $query_result[] = $template; - } - - if ( ! isset( $query['wp_id'] ) ) { - /* - * If the query has found some use templates, those have priority - * over the theme-provided ones, so we skip querying and building them. - */ - $query['slug__not_in'] = wp_list_pluck( $query_result, 'slug' ); - $template_files = _gutenberg_get_block_templates_files( $template_type, $query ); - foreach ( $template_files as $template_file ) { - $query_result[] = _build_block_template_result_from_file( $template_file, $template_type ); - } - } - - /** - * Filters the array of queried block templates array after they've been fetched. - * - * @since 5.9.0 - * - * @param WP_Block_Template[] $query_result Array of found block templates. - * @param array $query { - * Arguments to retrieve templates. All arguments are optional. - * - * @type string[] $slug__in List of slugs to include. - * @type int $wp_id Post ID of customized template. - * @type string $area A 'wp_template_part_area' taxonomy value to filter by (for 'wp_template_part' template type only). - * @type string $post_type Post type to get the templates for. - * } - * @param string $template_type wp_template or wp_template_part. - */ - return apply_filters( 'get_block_templates', $query_result, $query, $template_type ); -} diff --git a/lib/compat/wordpress-6.6/blocks.php b/lib/compat/wordpress-6.6/blocks.php deleted file mode 100644 index 0d8805a489d9cb..00000000000000 --- a/lib/compat/wordpress-6.6/blocks.php +++ /dev/null @@ -1,46 +0,0 @@ - array( 'content' ), - 'core/heading' => array( 'content' ), - 'core/image' => array( 'id', 'url', 'title', 'alt' ), - 'core/button' => array( 'url', 'text', 'linkTarget', 'rel' ), - ); - - $bindings = $parsed_block['attrs']['metadata']['bindings'] ?? array(); - if ( - isset( $bindings['__default']['source'] ) && - 'core/pattern-overrides' === $bindings['__default']['source'] - ) { - $updated_bindings = array(); - - // Build an binding array of all supported attributes. - // Note that this also omits the `__default` attribute from the - // resulting array. - foreach ( $supported_block_attrs[ $parsed_block['blockName'] ] as $attribute_name ) { - // Retain any non-pattern override bindings that might be present. - $updated_bindings[ $attribute_name ] = isset( $bindings[ $attribute_name ] ) - ? $bindings[ $attribute_name ] - : array( 'source' => 'core/pattern-overrides' ); - } - $parsed_block['attrs']['metadata']['bindings'] = $updated_bindings; - } - - return $parsed_block; -} - -add_filter( 'render_block_data', 'gutenberg_replace_pattern_override_default_binding', 10, 1 ); diff --git a/lib/compat/wordpress-6.6/class-gutenberg-rest-global-styles-revisions-controller-6-6.php b/lib/compat/wordpress-6.6/class-gutenberg-rest-global-styles-revisions-controller-6-6.php deleted file mode 100644 index 3e5d4cdd68454a..00000000000000 --- a/lib/compat/wordpress-6.6/class-gutenberg-rest-global-styles-revisions-controller-6-6.php +++ /dev/null @@ -1,97 +0,0 @@ -get_parent( $request['parent'] ); - $global_styles_config = $this->get_decoded_global_styles_json( $post->post_content ); - - if ( is_wp_error( $global_styles_config ) ) { - return $global_styles_config; - } - - $fields = $this->get_fields_for_response( $request ); - $data = array(); - $theme_json = array(); - - if ( ! empty( $global_styles_config['styles'] ) || ! empty( $global_styles_config['settings'] ) ) { - $theme_json = new WP_Theme_JSON_Gutenberg( $global_styles_config, 'custom' ); - $global_styles_config = ( $theme_json )->get_raw_data(); - - if ( rest_is_field_included( 'settings', $fields ) ) { - $data['settings'] = ! empty( $global_styles_config['settings'] ) ? $global_styles_config['settings'] : new stdClass(); - } - if ( rest_is_field_included( 'styles', $fields ) ) { - $data['styles'] = ! empty( $global_styles_config['styles'] ) ? $global_styles_config['styles'] : new stdClass(); - } - } - - if ( rest_is_field_included( 'author', $fields ) ) { - $data['author'] = (int) $post->post_author; - } - - if ( rest_is_field_included( 'date', $fields ) ) { - $data['date'] = $this->prepare_date_response( $post->post_date_gmt, $post->post_date ); - } - - if ( rest_is_field_included( 'date_gmt', $fields ) ) { - $data['date_gmt'] = $this->prepare_date_response( $post->post_date_gmt ); - } - - if ( rest_is_field_included( 'id', $fields ) ) { - $data['id'] = (int) $post->ID; - } - - if ( rest_is_field_included( 'modified', $fields ) ) { - $data['modified'] = $this->prepare_date_response( $post->post_modified_gmt, $post->post_modified ); - } - - if ( rest_is_field_included( 'modified_gmt', $fields ) ) { - $data['modified_gmt'] = $this->prepare_date_response( $post->post_modified_gmt ); - } - - if ( rest_is_field_included( 'parent', $fields ) ) { - $data['parent'] = (int) $parent->ID; - } - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - // Add resolved URIs to the response. - $links = array(); - $resolved_theme_uris = WP_Theme_JSON_Resolver_Gutenberg::get_resolved_theme_uris( $theme_json ); - if ( ! empty( $resolved_theme_uris ) ) { - $links['https://api.w.org/theme-file'] = $resolved_theme_uris; - } - $response->add_links( $links ); - - return $response; - } -} diff --git a/lib/compat/wordpress-6.6/class-gutenberg-rest-templates-controller-6-6.php b/lib/compat/wordpress-6.6/class-gutenberg-rest-templates-controller-6-6.php deleted file mode 100644 index 034187ca9a70ae..00000000000000 --- a/lib/compat/wordpress-6.6/class-gutenberg-rest-templates-controller-6-6.php +++ /dev/null @@ -1,131 +0,0 @@ - true ), 'objects' ) as $post_type ) { - if ( current_user_can( $post_type->cap->edit_posts ) ) { - return true; - } - } - - return new WP_Error( - 'rest_cannot_manage_templates', - __( 'Sorry, you are not allowed to access the templates on this site.', 'default' ), - array( - 'status' => rest_authorization_required_code(), - ) - ); - } - - /** - * Returns a list of templates. - * - * @since 5.8.0 - * - * @param WP_REST_Request $request The request instance. - * @return WP_REST_Response - */ - public function get_items( $request ) { - $query = array(); - if ( isset( $request['wp_id'] ) ) { - $query['wp_id'] = $request['wp_id']; - } - if ( isset( $request['area'] ) ) { - $query['area'] = $request['area']; - } - if ( isset( $request['post_type'] ) ) { - $query['post_type'] = $request['post_type']; - } - - $templates = array(); - foreach ( gutenberg_get_block_templates( $query, $this->post_type ) as $template ) { - $data = $this->prepare_item_for_response( $template, $request ); - $templates[] = $this->prepare_response_for_collection( $data ); - } - - return rest_ensure_response( $templates ); - } - - /** - * Checks if a given request has access to read templates. - * - * @since 6.6.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_item_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_manage_templates', - __( 'Sorry, you are not allowed to access the templates on this site.', 'default' ), - array( - 'status' => rest_authorization_required_code(), - ) - ); - } - - /** - * Returns the fallback template for the given slug. - * - * @since 6.1.0 - * - * @param WP_REST_Request $request The request instance. - * @return WP_REST_Response|WP_Error - */ - public function get_template_fallback( $request ) { - $hierarchy = gutenberg_get_template_hierarchy( $request['slug'], $request['is_custom'], $request['template_prefix'] ); - - do { - $fallback_template = resolve_block_template( $request['slug'], $hierarchy, '' ); - array_shift( $hierarchy ); - } while ( ! empty( $hierarchy ) && empty( $fallback_template->content ) ); - - // To maintain original behavior, return an empty object rather than a 404 error when no template is found. - $response = $fallback_template ? $this->prepare_item_for_response( $fallback_template, $request ) : new stdClass(); - - return rest_ensure_response( $response ); - } - - /** - * See WP_REST_Templates_Controller::prepare_item_for_response - */ - public function prepare_item_for_response( $item, $request ) { - $blocks = parse_blocks( $item->content ); - $blocks = gutenberg_replace_pattern_blocks( $blocks ); - $item->content = serialize_blocks( $blocks ); - return parent::prepare_item_for_response( $item, $request ); - } -} diff --git a/lib/compat/wordpress-6.6/class-gutenberg-token-map-6-6.php b/lib/compat/wordpress-6.6/class-gutenberg-token-map-6-6.php deleted file mode 100644 index 1df1fe91dab141..00000000000000 --- a/lib/compat/wordpress-6.6/class-gutenberg-token-map-6-6.php +++ /dev/null @@ -1,818 +0,0 @@ - '😯', - * ':(' => '🙁', - * ':)' => '🙂', - * ':?' => '😕', - * ) ); - * - * true === $smilies->contains( ':)' ); - * false === $smilies->contains( 'simile' ); - * - * '😕' === $smilies->read_token( 'Not sure :?.', 9, $length_of_smily_syntax ); - * 2 === $length_of_smily_syntax; - * - * ## Precomputing the Token Map. - * - * Creating the class involves some work sorting and organizing the tokens and their - * replacement values. In order to skip this, it's possible for the class to export - * its state and be used as actual PHP source code. - * - * Example: - * - * // Export with four spaces as the indent, only for the sake of this docblock. - * // The default indent is a tab character. - * $indent = ' '; - * echo $smilies->precomputed_php_source_table( $indent ); - * - * // Output, to be pasted into a PHP source file: - * WP_Token_Map::from_precomputed_table( - * array( - * "storage_version" => "6.6.0", - * "key_length" => 2, - * "groups" => "", - * "long_words" => array(), - * "small_words" => "8O\x00:)\x00:(\x00:?\x00", - * "small_mappings" => array( "😯", "🙂", "🙁", "😕" ) - * ) - * ); - * - * ## Large vs. small words. - * - * This class uses a short prefix called the "key" to optimize lookup of its tokens. - * This means that some tokens may be shorter than or equal in length to that key. - * Those words that are longer than the key are called "large" while those shorter - * than or equal to the key length are called "small." - * - * This separation of large and small words is incidental to the way this class - * optimizes lookup, and should be considered an internal implementation detail - * of the class. It may still be important to be aware of it, however. - * - * ## Determining Key Length. - * - * The choice of the size of the key length should be based on the data being stored in - * the token map. It should divide the data as evenly as possible, but should not create - * so many groups that a large fraction of the groups only contain a single token. - * - * For the HTML5 named character references, a key length of 2 was found to provide a - * sufficient spread and should be a good default for relatively large sets of tokens. - * - * However, for some data sets this might be too long. For example, a list of smilies - * may be too small for a key length of 2. Perhaps 1 would be more appropriate. It's - * best to experiment and determine empirically which values are appropriate. - * - * ## Generate Pre-Computed Source Code. - * - * Since the `WP_Token_Map` is designed for relatively static lookups, it can be - * advantageous to precompute the values and instantiate a table that has already - * sorted and grouped the tokens and built the lookup strings. - * - * This can be done with `WP_Token_Map::precomputed_php_source_table()`. - * - * Note that if there is a leading character that all tokens need, such as `&` for - * HTML named character references, it can be beneficial to exclude this from the - * token map. Instead, find occurrences of the leading character and then use the - * token map to see if the following characters complete the token. - * - * Example: - * - * $map = WP_Token_Map::from_array( array( 'simple_smile:' => '🙂', 'sob:' => '😭', 'soba:' => '🍜' ) ); - * echo $map->precomputed_php_source_table(); - * // Output - * WP_Token_Map::from_precomputed_table( - * array( - * "storage_version" => "6.6.0", - * "key_length" => 2, - * "groups" => "si\x00so\x00", - * "long_words" => array( - * // simple_smile:[🙂]. - * "\x0bmple_smile:\x04🙂", - * // soba:[🍜] sob:[😭]. - * "\x03ba:\x04🍜\x02b:\x04😭", - * ), - * "short_words" => "", - * "short_mappings" => array() - * } - * ); - * - * This precomputed value can be stored directly in source code and will skip the - * startup cost of generating the lookup strings. See `$html5_named_character_entities`. - * - * Note that any updates to the precomputed format should update the storage version - * constant. It would also be best to provide an update function to take older known - * versions and upgrade them in place when loading into `from_precomputed_table()`. - * - * ## Future Direction. - * - * It may be viable to dynamically increase the length limits such that there's no need to impose them. - * The limit appears because of the packing structure, which indicates how many bytes each segment of - * text in the lookup tables spans. If, however, care were taken to track the longest word length, then - * the packing structure could change its representation to allow for that. Each additional byte storing - * length, however, increases the memory overhead and lookup runtime. - * - * An alternative approach could be to borrow the UTF-8 variable-length encoding and store lengths of less - * than 127 as a single byte with the high bit unset, storing longer lengths as the combination of - * continuation bytes. - * - * Since it has not been shown during the development of this class that longer strings are required, this - * update is deferred until such a need is clear. - * - * @since 6.6.0 - */ -class Gutenberg_Token_Map_6_6 { - /** - * Denotes the version of the code which produces pre-computed source tables. - * - * This version will be used not only to verify pre-computed data, but also - * to upgrade pre-computed data from older versions. Choosing a name that - * corresponds to the WordPress release will help people identify where an - * old copy of data came from. - */ - const STORAGE_VERSION = '6.6.0-trunk'; - - /** - * Maximum length for each key and each transformed value in the table (in bytes). - * - * @since 6.6.0 - */ - const MAX_LENGTH = 256; - - /** - * How many bytes of each key are used to form a group key for lookup. - * This also determines whether a word is considered short or long. - * - * @since 6.6.0 - * - * @var int - */ - private $key_length = 2; - - /** - * Stores an optimized form of the word set, where words are grouped - * by a prefix of the `$key_length` and then collapsed into a string. - * - * In each group, the keys and lookups form a packed data structure. - * The keys in the string are stripped of their "group key," which is - * the prefix of length `$this->key_length` shared by all of the items - * in the group. Each word in the string is prefixed by a single byte - * whose raw unsigned integer value represents how many bytes follow. - * - * ┌────────────────┬───────────────┬─────────────────┬────────┐ - * │ Length of rest │ Rest of key │ Length of value │ Value │ - * │ of key (bytes) │ │ (bytes) │ │ - * ├────────────────┼───────────────┼─────────────────┼────────┤ - * │ 0x08 │ nterDot; │ 0x02 │ · │ - * └────────────────┴───────────────┴─────────────────┴────────┘ - * - * In this example, the key `CenterDot;` has a group key `Ce`, leaving - * eight bytes for the rest of the key, `nterDot;`, and two bytes for - * the transformed value `·` (or U+B7 or "\xC2\xB7"). - * - * Example: - * - * // Stores array( 'CenterDot;' => '·', 'Cedilla;' => '¸' ). - * $groups = "Ce\x00"; - * $large_words = array( "\x08nterDot;\x02·\x06dilla;\x02¸" ) - * - * The prefixes appear in the `$groups` string, each followed by a null - * byte. This makes for quick lookup of where in the group string the key - * is found, and then a simple division converts that offset into the index - * in the `$large_words` array where the group string is to be found. - * - * This lookup data structure is designed to optimize cache locality and - * minimize indirect memory reads when matching strings in the set. - * - * @since 6.6.0 - * - * @var array - */ - private $large_words = array(); - - /** - * Stores the group keys for sequential string lookup. - * - * The offset into this string where the group key appears corresponds with the index - * into the group array where the rest of the group string appears. This is an optimization - * to improve cache locality while searching and minimize indirect memory accesses. - * - * @since 6.6.0 - * - * @var string - */ - private $groups = ''; - - /** - * Stores an optimized row of small words, where every entry is - * `$this->key_size + 1` bytes long and zero-extended. - * - * This packing allows for direct lookup of a short word followed - * by the null byte, if extended to `$this->key_size + 1`. - * - * Example: - * - * // Stores array( 'GT', 'LT', 'gt', 'lt' ). - * "GT\x00LT\x00gt\x00lt\x00" - * - * @since 6.6.0 - * - * @var string - */ - private $small_words = ''; - - /** - * Replacements for the small words, in the same order they appear. - * - * With the position of a small word it's possible to index the translation - * directly, as its position in the `$small_words` string corresponds to - * the index of the replacement in the `$small_mapping` array. - * - * Example: - * - * array( '>', '<', '>', '<' ) - * - * @since 6.6.0 - * - * @var string[] - */ - private $small_mappings = array(); - - /** - * Create a token map using an associative array of key/value pairs as the input. - * - * Example: - * - * $smilies = WP_Token_Map::from_array( array( - * '8O' => '😯', - * ':(' => '🙁', - * ':)' => '🙂', - * ':?' => '😕', - * ) ); - * - * @since 6.6.0 - * - * @param array $mappings The keys transform into the values, both are strings. - * @param int $key_length Determines the group key length. Leave at the default value - * of 2 unless there's an empirical reason to change it. - * - * @return WP_Token_Map|null Token map, unless unable to create it. - */ - public static function from_array( $mappings, $key_length = 2 ) { - $map = new static(); - $map->key_length = $key_length; - - // Start by grouping words. - - $groups = array(); - $shorts = array(); - foreach ( $mappings as $word => $mapping ) { - if ( - self::MAX_LENGTH <= strlen( $word ) || - self::MAX_LENGTH <= strlen( $mapping ) - ) { - _doing_it_wrong( - __METHOD__, - sprintf( - /* translators: 1: maximum byte length (a count) */ - __( 'Token Map tokens and substitutions must all be shorter than %1$d bytes.' ), - self::MAX_LENGTH - ), - '6.6.0' - ); - return null; - } - - $length = strlen( $word ); - - if ( $key_length >= $length ) { - $shorts[] = $word; - } else { - $group = substr( $word, 0, $key_length ); - - if ( ! isset( $groups[ $group ] ) ) { - $groups[ $group ] = array(); - } - - $groups[ $group ][] = array( substr( $word, $key_length ), $mapping ); - } - } - - /* - * Sort the words to ensure that no smaller substring of a match masks the full match. - * For example, `Cap` should not match before `CapitalDifferentialD`. - */ - usort( $shorts, 'static::longest_first_then_alphabetical' ); - foreach ( $groups as $group_key => $group ) { - usort( - $groups[ $group_key ], - static function ( $a, $b ) { - return self::longest_first_then_alphabetical( $a[0], $b[0] ); - } - ); - } - - // Finally construct the optimized lookups. - - foreach ( $shorts as $word ) { - $map->small_words .= str_pad( $word, $key_length + 1, "\x00", STR_PAD_RIGHT ); - $map->small_mappings[] = $mappings[ $word ]; - } - - $group_keys = array_keys( $groups ); - sort( $group_keys ); - - foreach ( $group_keys as $group ) { - $map->groups .= "{$group}\x00"; - - $group_string = ''; - - foreach ( $groups[ $group ] as $group_word ) { - list( $word, $mapping ) = $group_word; - - $word_length = pack( 'C', strlen( $word ) ); - $mapping_length = pack( 'C', strlen( $mapping ) ); - $group_string .= "{$word_length}{$word}{$mapping_length}{$mapping}"; - } - - $map->large_words[] = $group_string; - } - - return $map; - } - - /** - * Creates a token map from a pre-computed table. - * This skips the initialization cost of generating the table. - * - * This function should only be used to load data created with - * WP_Token_Map::precomputed_php_source_tag(). - * - * @since 6.6.0 - * - * @param array $state { - * Stores pre-computed state for directly loading into a Token Map. - * - * @type string $storage_version Which version of the code produced this state. - * @type int $key_length Group key length. - * @type string $groups Group lookup index. - * @type array $large_words Large word groups and packed strings. - * @type string $small_words Small words packed string. - * @type array $small_mappings Small word mappings. - * } - * - * @return WP_Token_Map Map with precomputed data loaded. - */ - public static function from_precomputed_table( $state ) { - $has_necessary_state = isset( - $state['storage_version'], - $state['key_length'], - $state['groups'], - $state['large_words'], - $state['small_words'], - $state['small_mappings'] - ); - - if ( ! $has_necessary_state ) { - _doing_it_wrong( - __METHOD__, - __( 'Missing required inputs to pre-computed WP_Token_Map.' ), - '6.6.0' - ); - return null; - } - - if ( self::STORAGE_VERSION !== $state['storage_version'] ) { - _doing_it_wrong( - __METHOD__, - /* translators: 1: version string, 2: version string. */ - sprintf( __( 'Loaded version \'%1$s\' incompatible with expected version \'%2$s\'.' ), $state['storage_version'], self::STORAGE_VERSION ), - '6.6.0' - ); - return null; - } - - $map = new static(); - - $map->key_length = $state['key_length']; - $map->groups = $state['groups']; - $map->large_words = $state['large_words']; - $map->small_words = $state['small_words']; - $map->small_mappings = $state['small_mappings']; - - return $map; - } - - /** - * Indicates if a given word is a lookup key in the map. - * - * Example: - * - * true === $smilies->contains( ':)' ); - * false === $smilies->contains( 'simile' ); - * - * @since 6.6.0 - * - * @param string $word Determine if this word is a lookup key in the map. - * @param string $case_sensitivity Optional. Pass 'ascii-case-insensitive' to ignore ASCII case when matching. Default 'case-sensitive'. - * @return bool Whether there's an entry for the given word in the map. - */ - public function contains( $word, $case_sensitivity = 'case-sensitive' ) { - $ignore_case = 'ascii-case-insensitive' === $case_sensitivity; - - if ( $this->key_length >= strlen( $word ) ) { - if ( 0 === strlen( $this->small_words ) ) { - return false; - } - - $term = str_pad( $word, $this->key_length + 1, "\x00", STR_PAD_RIGHT ); - $word_at = $ignore_case ? stripos( $this->small_words, $term ) : strpos( $this->small_words, $term ); - if ( false === $word_at ) { - return false; - } - - return true; - } - - $group_key = substr( $word, 0, $this->key_length ); - $group_at = $ignore_case ? stripos( $this->groups, $group_key ) : strpos( $this->groups, $group_key ); - if ( false === $group_at ) { - return false; - } - $group = $this->large_words[ $group_at / ( $this->key_length + 1 ) ]; - $group_length = strlen( $group ); - $slug = substr( $word, $this->key_length ); - $length = strlen( $slug ); - $at = 0; - - while ( $at < $group_length ) { - $token_length = unpack( 'C', $group[ $at++ ] )[1]; - $token_at = $at; - $at += $token_length; - $mapping_length = unpack( 'C', $group[ $at++ ] )[1]; - $mapping_at = $at; - - if ( $token_length === $length && 0 === substr_compare( $group, $slug, $token_at, $token_length, $ignore_case ) ) { - return true; - } - - $at = $mapping_at + $mapping_length; - } - - return false; - } - - /** - * If the text starting at a given offset is a lookup key in the map, - * return the corresponding transformation from the map, else `false`. - * - * This function returns the translated string, but accepts an optional - * parameter `$matched_token_byte_length`, which communicates how many - * bytes long the lookup key was, if it found one. This can be used to - * advance a cursor in calling code if a lookup key was found. - * - * Example: - * - * false === $smilies->read_token( 'Not sure :?.', 0, $token_byte_length ); - * '😕' === $smilies->read_token( 'Not sure :?.', 9, $token_byte_length ); - * 2 === $token_byte_length; - * - * Example: - * - * while ( $at < strlen( $input ) ) { - * $next_at = strpos( $input, ':', $at ); - * if ( false === $next_at ) { - * break; - * } - * - * $smily = $smilies->read_token( $input, $next_at, $token_byte_length ); - * if ( false === $next_at ) { - * ++$at; - * continue; - * } - * - * $prefix = substr( $input, $at, $next_at - $at ); - * $at += $token_byte_length; - * $output .= "{$prefix}{$smily}"; - * } - * - * @since 6.6.0 - * - * @param string $text String in which to search for a lookup key. - * @param int $offset Optional. How many bytes into the string where the lookup key ought to start. Default 0. - * @param ?int &$matched_token_byte_length Optional. Holds byte-length of found token matched, otherwise not set. Default null. - * @param string $case_sensitivity Optional. Pass 'ascii-case-insensitive' to ignore ASCII case when matching. Default 'case-sensitive'. - * @return string|null Mapped value of lookup key if found, otherwise `null`. - */ - public function read_token( $text, $offset = 0, &$matched_token_byte_length = null, $case_sensitivity = 'case-sensitive' ) { - $ignore_case = 'ascii-case-insensitive' === $case_sensitivity; - $text_length = strlen( $text ); - - // Search for a long word first, if the text is long enough, and if that fails, a short one. - if ( $text_length > $this->key_length ) { - $group_key = substr( $text, $offset, $this->key_length ); - - $group_at = $ignore_case ? stripos( $this->groups, $group_key ) : strpos( $this->groups, $group_key ); - if ( false === $group_at ) { - // Perhaps a short word then. - return strlen( $this->small_words ) > 0 - ? $this->read_small_token( $text, $offset, $matched_token_byte_length, $case_sensitivity ) - : null; - } - - $group = $this->large_words[ $group_at / ( $this->key_length + 1 ) ]; - $group_length = strlen( $group ); - $at = 0; - while ( $at < $group_length ) { - $token_length = unpack( 'C', $group[ $at++ ] )[1]; - $token = substr( $group, $at, $token_length ); - $at += $token_length; - $mapping_length = unpack( 'C', $group[ $at++ ] )[1]; - $mapping_at = $at; - - if ( 0 === substr_compare( $text, $token, $offset + $this->key_length, $token_length, $ignore_case ) ) { - $matched_token_byte_length = $this->key_length + $token_length; - return substr( $group, $mapping_at, $mapping_length ); - } - - $at = $mapping_at + $mapping_length; - } - } - - // Perhaps a short word then. - return strlen( $this->small_words ) > 0 - ? $this->read_small_token( $text, $offset, $matched_token_byte_length, $case_sensitivity ) - : null; - } - - /** - * Finds a match for a short word at the index. - * - * @since 6.6.0. - * - * @param string $text String in which to search for a lookup key. - * @param int $offset Optional. How many bytes into the string where the lookup key ought to start. Default 0. - * @param ?int &$matched_token_byte_length Optional. Holds byte-length of found lookup key if matched, otherwise not set. Default null. - * @param string $case_sensitivity Optional. Pass 'ascii-case-insensitive' to ignore ASCII case when matching. Default 'case-sensitive'. - * @return string|null Mapped value of lookup key if found, otherwise `null`. - */ - private function read_small_token( $text, $offset, &$matched_token_byte_length, $case_sensitivity = 'case-sensitive' ) { - $ignore_case = 'ascii-case-insensitive' === $case_sensitivity; - $small_length = strlen( $this->small_words ); - $search_text = substr( $text, $offset, $this->key_length ); - if ( $ignore_case ) { - $search_text = strtoupper( $search_text ); - } - $starting_char = $search_text[0]; - - $at = 0; - while ( $at < $small_length ) { - if ( - $starting_char !== $this->small_words[ $at ] && - ( ! $ignore_case || strtoupper( $this->small_words[ $at ] ) !== $starting_char ) - ) { - $at += $this->key_length + 1; - continue; - } - - for ( $adjust = 1; $adjust < $this->key_length; $adjust++ ) { - if ( "\x00" === $this->small_words[ $at + $adjust ] ) { - $matched_token_byte_length = $adjust; - return $this->small_mappings[ $at / ( $this->key_length + 1 ) ]; - } - - if ( - $search_text[ $adjust ] !== $this->small_words[ $at + $adjust ] && - ( ! $ignore_case || strtoupper( $this->small_words[ $at + $adjust ] !== $search_text[ $adjust ] ) ) - ) { - $at += $this->key_length + 1; - continue 2; - } - } - - $matched_token_byte_length = $adjust; - return $this->small_mappings[ $at / ( $this->key_length + 1 ) ]; - } - - return null; - } - - /** - * Exports the token map into an associate array of key/value pairs. - * - * Example: - * - * $smilies->to_array() === array( - * '8O' => '😯', - * ':(' => '🙁', - * ':)' => '🙂', - * ':?' => '😕', - * ); - * - * @return array The lookup key/substitution values as an associate array. - */ - public function to_array() { - $tokens = array(); - - $at = 0; - $small_mapping = 0; - $small_length = strlen( $this->small_words ); - while ( $at < $small_length ) { - $key = rtrim( substr( $this->small_words, $at, $this->key_length + 1 ), "\x00" ); - $value = $this->small_mappings[ $small_mapping++ ]; - $tokens[ $key ] = $value; - - $at += $this->key_length + 1; - } - - foreach ( $this->large_words as $index => $group ) { - $prefix = substr( $this->groups, $index * ( $this->key_length + 1 ), 2 ); - $group_length = strlen( $group ); - $at = 0; - while ( $at < $group_length ) { - $length = unpack( 'C', $group[ $at++ ] )[1]; - $key = $prefix . substr( $group, $at, $length ); - - $at += $length; - $length = unpack( 'C', $group[ $at++ ] )[1]; - $value = substr( $group, $at, $length ); - - $tokens[ $key ] = $value; - $at += $length; - } - } - - return $tokens; - } - - /** - * Export the token map for quick loading in PHP source code. - * - * This function has a specific purpose, to make loading of static token maps fast. - * It's used to ensure that the HTML character reference lookups add a minimal cost - * to initializing the PHP process. - * - * Example: - * - * echo $smilies->precomputed_php_source_table(); - * - * // Output. - * WP_Token_Map::from_precomputed_table( - * array( - * "storage_version" => "6.6.0", - * "key_length" => 2, - * "groups" => "", - * "long_words" => array(), - * "small_words" => "8O\x00:)\x00:(\x00:?\x00", - * "small_mappings" => array( "😯", "🙂", "🙁", "😕" ) - * ) - * ); - * - * @since 6.6.0 - * - * @param string $indent Optional. Use this string for indentation, or rely on the default horizontal tab character. Default "\t". - * @return string Value which can be pasted into a PHP source file for quick loading of table. - */ - public function precomputed_php_source_table( $indent = "\t" ) { - $i1 = $indent; - $i2 = $i1 . $indent; - $i3 = $i2 . $indent; - - $class_version = self::STORAGE_VERSION; - - $output = self::class . "::from_precomputed_table(\n"; - $output .= "{$i1}array(\n"; - $output .= "{$i2}\"storage_version\" => \"{$class_version}\",\n"; - $output .= "{$i2}\"key_length\" => {$this->key_length},\n"; - - $group_line = str_replace( "\x00", "\\x00", $this->groups ); - $output .= "{$i2}\"groups\" => \"{$group_line}\",\n"; - - $output .= "{$i2}\"large_words\" => array(\n"; - - $prefixes = explode( "\x00", $this->groups ); - foreach ( $prefixes as $index => $prefix ) { - if ( '' === $prefix ) { - break; - } - $group = $this->large_words[ $index ]; - $group_length = strlen( $group ); - $comment_line = "{$i3}//"; - $data_line = "{$i3}\""; - $at = 0; - while ( $at < $group_length ) { - $token_length = unpack( 'C', $group[ $at++ ] )[1]; - $token = substr( $group, $at, $token_length ); - $at += $token_length; - $mapping_length = unpack( 'C', $group[ $at++ ] )[1]; - $mapping = substr( $group, $at, $mapping_length ); - $at += $mapping_length; - - $token_digits = str_pad( dechex( $token_length ), 2, '0', STR_PAD_LEFT ); - $mapping_digits = str_pad( dechex( $mapping_length ), 2, '0', STR_PAD_LEFT ); - - $mapping = preg_replace_callback( - "~[\\x00-\\x1f\\x22\\x5c]~", - static function ( $match_result ) { - switch ( $match_result[0] ) { - case '"': - return '\\"'; - - case '\\': - return '\\\\'; - - default: - $hex = dechex( ord( $match_result[0] ) ); - return "\\x{$hex}"; - } - }, - $mapping - ); - - $comment_line .= " {$prefix}{$token}[{$mapping}]"; - $data_line .= "\\x{$token_digits}{$token}\\x{$mapping_digits}{$mapping}"; - } - $comment_line .= ".\n"; - $data_line .= "\",\n"; - - $output .= $comment_line; - $output .= $data_line; - } - - $output .= "{$i2}),\n"; - - $small_words = array(); - $small_length = strlen( $this->small_words ); - $at = 0; - while ( $at < $small_length ) { - $small_words[] = substr( $this->small_words, $at, $this->key_length + 1 ); - $at += $this->key_length + 1; - } - - $small_text = str_replace( "\x00", '\x00', implode( '', $small_words ) ); - $output .= "{$i2}\"small_words\" => \"{$small_text}\",\n"; - - $output .= "{$i2}\"small_mappings\" => array(\n"; - foreach ( $this->small_mappings as $mapping ) { - $output .= "{$i3}\"{$mapping}\",\n"; - } - $output .= "{$i2})\n"; - $output .= "{$i1})\n"; - $output .= ')'; - - return $output; - } - - /** - * Compares two strings, returning the longest, or whichever - * is first alphabetically if they are the same length. - * - * This is an important sort when building the token map because - * it should not form a match on a substring of a longer potential - * match. For example, it should not detect `Cap` when matching - * against the string `CapitalDifferentialD`. - * - * @since 6.6.0 - * - * @param string $a First string to compare. - * @param string $b Second string to compare. - * @return int -1 or lower if `$a` is less than `$b`; 1 or greater if `$a` is greater than `$b`, and 0 if they are equal. - */ - private static function longest_first_then_alphabetical( $a, $b ) { - if ( $a === $b ) { - return 0; - } - - $length_a = strlen( $a ); - $length_b = strlen( $b ); - - // Longer strings are less-than for comparison's sake. - if ( $length_a !== $length_b ) { - return $length_b - $length_a; - } - - return strcmp( $a, $b ); - } -} diff --git a/lib/compat/wordpress-6.6/compat.php b/lib/compat/wordpress-6.6/compat.php deleted file mode 100644 index 4e444d3149824a..00000000000000 --- a/lib/compat/wordpress-6.6/compat.php +++ /dev/null @@ -1,32 +0,0 @@ -= 6.6.0. - * - * @global array $submenu - */ -function gutenberg_change_patterns_link_and_remove_template_parts_submenu_item() { - if ( ! wp_is_block_theme() ) { - global $submenu; - - if ( empty( $submenu['themes.php'] ) ) { - return; - } - - foreach ( $submenu['themes.php'] as $key => $item ) { - if ( 'edit.php?post_type=wp_block' === $item[2] ) { - $submenu['themes.php'][ $key ][2] = 'site-editor.php?path=/patterns'; - } elseif ( 'site-editor.php?path=/wp_template_part/all' === $item[2] ) { - unset( $submenu['themes.php'][ $key ] ); - } - } - } -} -add_action( 'admin_init', 'gutenberg_change_patterns_link_and_remove_template_parts_submenu_item' ); diff --git a/lib/compat/wordpress-6.6/html-api/class-gutenberg-html-decoder-6-6.php b/lib/compat/wordpress-6.6/html-api/class-gutenberg-html-decoder-6-6.php deleted file mode 100644 index d0b9f18bf5b29b..00000000000000 --- a/lib/compat/wordpress-6.6/html-api/class-gutenberg-html-decoder-6-6.php +++ /dev/null @@ -1,463 +0,0 @@ -= $end ) { - break; - } - - $character_reference = self::read_character_reference( $context, $text, $next_character_reference_at, $token_length ); - if ( isset( $character_reference ) ) { - $at = $next_character_reference_at; - $decoded .= substr( $text, $was_at, $at - $was_at ); - $decoded .= $character_reference; - $at += $token_length; - $was_at = $at; - continue; - } - - ++$at; - } - - if ( 0 === $was_at ) { - return $text; - } - - if ( $was_at < $end ) { - $decoded .= substr( $text, $was_at, $end - $was_at ); - } - - return $decoded; - } - - /** - * Attempt to read a character reference at the given location in a given string, - * depending on the context in which it's found. - * - * If a character reference is found, this function will return the translated value - * that the reference maps to. It will then set `$match_byte_length` the - * number of bytes of input it read while consuming the character reference. This - * gives calling code the opportunity to advance its cursor when traversing a string - * and decoding. - * - * Example: - * - * null === WP_HTML_Decoder::read_character_reference( 'attribute', 'Ships…', 0 ); - * '…' === WP_HTML_Decoder::read_character_reference( 'attribute', 'Ships…', 5, $token_length ); - * 8 === $token_length; // `…` - * - * null === WP_HTML_Decoder::read_character_reference( 'attribute', '¬in', 0 ); - * '∉' === WP_HTML_Decoder::read_character_reference( 'attribute', '∉', 0, $token_length ); - * 7 === $token_length; // `∉` - * - * '¬' === WP_HTML_Decoder::read_character_reference( 'data', '¬in', 0, $token_length ); - * 4 === $token_length; // `¬` - * '∉' === WP_HTML_Decoder::read_character_reference( 'data', '∉', 0, $token_length ); - * 7 === $token_length; // `∉` - * - * @since 6.6.0 - * - * @global WP_Token_Map $html5_named_character_references - * - * @param string $context `attribute` for decoding attribute values, `data` otherwise. - * @param string $text Text document containing span of text to decode. - * @param int $at Optional. Byte offset into text where span begins, defaults to the beginning (0). - * @param int &$match_byte_length Optional. Set to byte-length of character reference if provided and if a match - * is found, otherwise not set. Default null. - * @return string|false Decoded character reference in UTF-8 if found, otherwise `false`. - */ - public static function read_character_reference( $context, $text, $at = 0, &$match_byte_length = null ) { - /** - * Mappings for HTML5 named character references. - * - * @var WP_Token_Map $html5_named_character_references - */ - global $html5_named_character_references; - - $length = strlen( $text ); - if ( $at + 1 >= $length ) { - return null; - } - - if ( '&' !== $text[ $at ] ) { - return null; - } - - /* - * Numeric character references. - * - * When truncated, these will encode the code point found by parsing the - * digits that are available. For example, when `🅰` is truncated - * to `DZ` it will encode `DZ`. It does not: - * - know how to parse the original `🅰`. - * - fail to parse and return plaintext `DZ`. - * - fail to parse and return the replacement character `�` - */ - if ( '#' === $text[ $at + 1 ] ) { - if ( $at + 2 >= $length ) { - return null; - } - - /** Tracks inner parsing within the numeric character reference. */ - $digits_at = $at + 2; - - if ( 'x' === $text[ $digits_at ] || 'X' === $text[ $digits_at ] ) { - $numeric_base = 16; - $numeric_digits = '0123456789abcdefABCDEF'; - $max_digits = 6; // 􏿿 - ++$digits_at; - } else { - $numeric_base = 10; - $numeric_digits = '0123456789'; - $max_digits = 7; // 􏿿 - } - - // Cannot encode invalid Unicode code points. Max is to U+10FFFF. - $zero_count = strspn( $text, '0', $digits_at ); - $digit_count = strspn( $text, $numeric_digits, $digits_at + $zero_count ); - $after_digits = $digits_at + $zero_count + $digit_count; - $has_semicolon = $after_digits < $length && ';' === $text[ $after_digits ]; - $end_of_span = $has_semicolon ? $after_digits + 1 : $after_digits; - - // `&#` or `&#x` without digits returns into plaintext. - if ( 0 === $digit_count && 0 === $zero_count ) { - return null; - } - - // Whereas `&#` and only zeros is invalid. - if ( 0 === $digit_count ) { - $match_byte_length = $end_of_span - $at; - return '�'; - } - - // If there are too many digits then it's not worth parsing. It's invalid. - if ( $digit_count > $max_digits ) { - $match_byte_length = $end_of_span - $at; - return '�'; - } - - $digits = substr( $text, $digits_at + $zero_count, $digit_count ); - $code_point = intval( $digits, $numeric_base ); - - /* - * Noncharacters, 0x0D, and non-ASCII-whitespace control characters. - * - * > A noncharacter is a code point that is in the range U+FDD0 to U+FDEF, - * > inclusive, or U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, U+2FFFE, U+2FFFF, - * > U+3FFFE, U+3FFFF, U+4FFFE, U+4FFFF, U+5FFFE, U+5FFFF, U+6FFFE, - * > U+6FFFF, U+7FFFE, U+7FFFF, U+8FFFE, U+8FFFF, U+9FFFE, U+9FFFF, - * > U+AFFFE, U+AFFFF, U+BFFFE, U+BFFFF, U+CFFFE, U+CFFFF, U+DFFFE, - * > U+DFFFF, U+EFFFE, U+EFFFF, U+FFFFE, U+FFFFF, U+10FFFE, or U+10FFFF. - * - * A C0 control is a code point that is in the range of U+00 to U+1F, - * but ASCII whitespace includes U+09, U+0A, U+0C, and U+0D. - * - * These characters are invalid but still decode as any valid character. - * This comment is here to note and explain why there's no check to - * remove these characters or replace them. - * - * @see https://infra.spec.whatwg.org/#noncharacter - */ - - /* - * Code points in the C1 controls area need to be remapped as if they - * were stored in Windows-1252. Note! This transformation only happens - * for numeric character references. The raw code points in the byte - * stream are not translated. - * - * > If the number is one of the numbers in the first column of - * > the following table, then find the row with that number in - * > the first column, and set the character reference code to - * > the number in the second column of that row. - */ - if ( $code_point >= 0x80 && $code_point <= 0x9F ) { - $windows_1252_mapping = array( - 0x20AC, // 0x80 -> EURO SIGN (€). - 0x81, // 0x81 -> (no change). - 0x201A, // 0x82 -> SINGLE LOW-9 QUOTATION MARK (‚). - 0x0192, // 0x83 -> LATIN SMALL LETTER F WITH HOOK (ƒ). - 0x201E, // 0x84 -> DOUBLE LOW-9 QUOTATION MARK („). - 0x2026, // 0x85 -> HORIZONTAL ELLIPSIS (…). - 0x2020, // 0x86 -> DAGGER (†). - 0x2021, // 0x87 -> DOUBLE DAGGER (‡). - 0x02C6, // 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT (ˆ). - 0x2030, // 0x89 -> PER MILLE SIGN (‰). - 0x0160, // 0x8A -> LATIN CAPITAL LETTER S WITH CARON (Š). - 0x2039, // 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK (‹). - 0x0152, // 0x8C -> LATIN CAPITAL LIGATURE OE (Œ). - 0x8D, // 0x8D -> (no change). - 0x017D, // 0x8E -> LATIN CAPITAL LETTER Z WITH CARON (Ž). - 0x8F, // 0x8F -> (no change). - 0x90, // 0x90 -> (no change). - 0x2018, // 0x91 -> LEFT SINGLE QUOTATION MARK (‘). - 0x2019, // 0x92 -> RIGHT SINGLE QUOTATION MARK (’). - 0x201C, // 0x93 -> LEFT DOUBLE QUOTATION MARK (“). - 0x201D, // 0x94 -> RIGHT DOUBLE QUOTATION MARK (”). - 0x2022, // 0x95 -> BULLET (•). - 0x2013, // 0x96 -> EN DASH (–). - 0x2014, // 0x97 -> EM DASH (—). - 0x02DC, // 0x98 -> SMALL TILDE (˜). - 0x2122, // 0x99 -> TRADE MARK SIGN (™). - 0x0161, // 0x9A -> LATIN SMALL LETTER S WITH CARON (š). - 0x203A, // 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (›). - 0x0153, // 0x9C -> LATIN SMALL LIGATURE OE (œ). - 0x9D, // 0x9D -> (no change). - 0x017E, // 0x9E -> LATIN SMALL LETTER Z WITH CARON (ž). - 0x0178, // 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS (Ÿ). - ); - - $code_point = $windows_1252_mapping[ $code_point - 0x80 ]; - } - - $match_byte_length = $end_of_span - $at; - return self::code_point_to_utf8_bytes( $code_point ); - } - - /** Tracks inner parsing within the named character reference. */ - $name_at = $at + 1; - // Minimum named character reference is two characters. E.g. `GT`. - if ( $name_at + 2 > $length ) { - return null; - } - - $name_length = 0; - $replacement = $html5_named_character_references->read_token( $text, $name_at, $name_length ); - if ( false === $replacement ) { - return null; - } - - $after_name = $name_at + $name_length; - - // If the match ended with a semicolon then it should always be decoded. - if ( ';' === $text[ $name_at + $name_length - 1 ] ) { - $match_byte_length = $after_name - $at; - return $replacement; - } - - /* - * At this point though there's a match for an entry in the named - * character reference table but the match doesn't end in `;`. - * It may be allowed if it's followed by something unambiguous. - */ - $ambiguous_follower = ( - $after_name < $length && - $name_at < $length && - ( - ctype_alnum( $text[ $after_name ] ) || - '=' === $text[ $after_name ] - ) - ); - - // It's non-ambiguous, safe to leave it in. - if ( ! $ambiguous_follower ) { - $match_byte_length = $after_name - $at; - return $replacement; - } - - // It's ambiguous, which isn't allowed inside attributes. - if ( 'attribute' === $context ) { - return null; - } - - $match_byte_length = $after_name - $at; - return $replacement; - } - - /** - * Encode a code point number into the UTF-8 encoding. - * - * This encoder implements the UTF-8 encoding algorithm for converting - * a code point into a byte sequence. If it receives an invalid code - * point it will return the Unicode Replacement Character U+FFFD `�`. - * - * Example: - * - * '🅰' === WP_HTML_Decoder::code_point_to_utf8_bytes( 0x1f170 ); - * - * // Half of a surrogate pair is an invalid code point. - * '�' === WP_HTML_Decoder::code_point_to_utf8_bytes( 0xd83c ); - * - * @since 6.6.0 - * - * @see https://www.rfc-editor.org/rfc/rfc3629 For the UTF-8 standard. - * - * @param int $code_point Which code point to convert. - * @return string Converted code point, or `�` if invalid. - */ - public static function code_point_to_utf8_bytes( $code_point ) { - // Pre-check to ensure a valid code point. - if ( - $code_point <= 0 || - ( $code_point >= 0xD800 && $code_point <= 0xDFFF ) || - $code_point > 0x10FFFF - ) { - return '�'; - } - - if ( $code_point <= 0x7F ) { - return chr( $code_point ); - } - - if ( $code_point <= 0x7FF ) { - $byte1 = ( $code_point >> 6 ) | 0xC0; - $byte2 = $code_point & 0x3F | 0x80; - - return pack( 'CC', $byte1, $byte2 ); - } - - if ( $code_point <= 0xFFFF ) { - $byte1 = ( $code_point >> 12 ) | 0xE0; - $byte2 = ( $code_point >> 6 ) & 0x3F | 0x80; - $byte3 = $code_point & 0x3F | 0x80; - - return pack( 'CCC', $byte1, $byte2, $byte3 ); - } - - // Any values above U+10FFFF are eliminated above in the pre-check. - $byte1 = ( $code_point >> 18 ) | 0xF0; - $byte2 = ( $code_point >> 12 ) & 0x3F | 0x80; - $byte3 = ( $code_point >> 6 ) & 0x3F | 0x80; - $byte4 = $code_point & 0x3F | 0x80; - - return pack( 'CCCC', $byte1, $byte2, $byte3, $byte4 ); - } -} diff --git a/lib/compat/wordpress-6.6/html-api/class-gutenberg-html-open-elements-6-6.php b/lib/compat/wordpress-6.6/html-api/class-gutenberg-html-open-elements-6-6.php deleted file mode 100644 index da237e02bc63ba..00000000000000 --- a/lib/compat/wordpress-6.6/html-api/class-gutenberg-html-open-elements-6-6.php +++ /dev/null @@ -1,541 +0,0 @@ - Initially, the stack of open elements is empty. The stack grows - * > downwards; the topmost node on the stack is the first one added - * > to the stack, and the bottommost node of the stack is the most - * > recently added node in the stack (notwithstanding when the stack - * > is manipulated in a random access fashion as part of the handling - * > for misnested tags). - * - * @since 6.4.0 - * - * @access private - * - * @see https://html.spec.whatwg.org/#stack-of-open-elements - * @see WP_HTML_Processor - */ -class Gutenberg_HTML_Open_Elements_6_6 { - /** - * Holds the stack of open element references. - * - * @since 6.4.0 - * - * @var WP_HTML_Token[] - */ - public $stack = array(); - - /** - * Whether a P element is in button scope currently. - * - * This class optimizes scope lookup by pre-calculating - * this value when elements are added and removed to the - * stack of open elements which might change its value. - * This avoids frequent iteration over the stack. - * - * @since 6.4.0 - * - * @var bool - */ - private $has_p_in_button_scope = false; - - /** - * A function that will be called when an item is popped off the stack of open elements. - * - * The function will be called with the popped item as its argument. - * - * @since 6.6.0 - * - * @var Closure - */ - private $pop_handler = null; - - /** - * A function that will be called when an item is pushed onto the stack of open elements. - * - * The function will be called with the pushed item as its argument. - * - * @since 6.6.0 - * - * @var Closure - */ - private $push_handler = null; - - /** - * Sets a pop handler that will be called when an item is popped off the stack of - * open elements. - * - * The function will be called with the pushed item as its argument. - * - * @since 6.6.0 - * - * @param Closure $handler The handler function. - */ - public function set_pop_handler( Closure $handler ) { - $this->pop_handler = $handler; - } - - /** - * Sets a push handler that will be called when an item is pushed onto the stack of - * open elements. - * - * The function will be called with the pushed item as its argument. - * - * @since 6.6.0 - * - * @param Closure $handler The handler function. - */ - public function set_push_handler( Closure $handler ) { - $this->push_handler = $handler; - } - - /** - * Reports if a specific node is in the stack of open elements. - * - * @since 6.4.0 - * - * @param WP_HTML_Token $token Look for this node in the stack. - * @return bool Whether the referenced node is in the stack of open elements. - */ - public function contains_node( $token ) { - foreach ( $this->walk_up() as $item ) { - if ( $token->bookmark_name === $item->bookmark_name ) { - return true; - } - } - - return false; - } - - /** - * Returns how many nodes are currently in the stack of open elements. - * - * @since 6.4.0 - * - * @return int How many node are in the stack of open elements. - */ - public function count() { - return count( $this->stack ); - } - - /** - * Returns the node at the end of the stack of open elements, - * if one exists. If the stack is empty, returns null. - * - * @since 6.4.0 - * - * @return WP_HTML_Token|null Last node in the stack of open elements, if one exists, otherwise null. - */ - public function current_node() { - $current_node = end( $this->stack ); - - return $current_node ? $current_node : null; - } - - /** - * Returns whether an element is in a specific scope. - * - * ## HTML Support - * - * This function skips checking for the termination list because there - * are no supported elements which appear in the termination list. - * - * @since 6.4.0 - * - * @see https://html.spec.whatwg.org/#has-an-element-in-the-specific-scope - * - * @param string $tag_name Name of tag check. - * @param string[] $termination_list List of elements that terminate the search. - * @return bool Whether the element was found in a specific scope. - */ - public function has_element_in_specific_scope( $tag_name, $termination_list ) { - foreach ( $this->walk_up() as $node ) { - if ( $node->node_name === $tag_name ) { - return true; - } - - if ( - '(internal: H1 through H6 - do not use)' === $tag_name && - in_array( $node->node_name, array( 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ), true ) - ) { - return true; - } - - switch ( $node->node_name ) { - case 'HTML': - return false; - } - - if ( in_array( $node->node_name, $termination_list, true ) ) { - return false; - } - } - - return false; - } - - /** - * Returns whether a particular element is in scope. - * - * @since 6.4.0 - * - * @see https://html.spec.whatwg.org/#has-an-element-in-scope - * - * @param string $tag_name Name of tag to check. - * @return bool Whether given element is in scope. - */ - public function has_element_in_scope( $tag_name ) { - return $this->has_element_in_specific_scope( - $tag_name, - array( - - /* - * Because it's not currently possible to encounter - * one of the termination elements, they don't need - * to be listed here. If they were, they would be - * unreachable and only waste CPU cycles while - * scanning through HTML. - */ - ) - ); - } - - /** - * Returns whether a particular element is in list item scope. - * - * @since 6.4.0 - * @since 6.5.0 Implemented: no longer throws on every invocation. - * - * @see https://html.spec.whatwg.org/#has-an-element-in-list-item-scope - * - * @param string $tag_name Name of tag to check. - * @return bool Whether given element is in scope. - */ - public function has_element_in_list_item_scope( $tag_name ) { - return $this->has_element_in_specific_scope( - $tag_name, - array( - // There are more elements that belong here which aren't currently supported. - 'OL', - 'UL', - ) - ); - } - - /** - * Returns whether a particular element is in button scope. - * - * @since 6.4.0 - * - * @see https://html.spec.whatwg.org/#has-an-element-in-button-scope - * - * @param string $tag_name Name of tag to check. - * @return bool Whether given element is in scope. - */ - public function has_element_in_button_scope( $tag_name ) { - return $this->has_element_in_specific_scope( $tag_name, array( 'BUTTON' ) ); - } - - /** - * Returns whether a particular element is in table scope. - * - * @since 6.4.0 - * - * @see https://html.spec.whatwg.org/#has-an-element-in-table-scope - * - * @throws WP_HTML_Unsupported_Exception Always until this function is implemented. - * - * @param string $tag_name Name of tag to check. - * @return bool Whether given element is in scope. - */ - public function has_element_in_table_scope( $tag_name ) { - throw new WP_HTML_Unsupported_Exception( 'Cannot process elements depending on table scope.' ); - - return false; // The linter requires this unreachable code until the function is implemented and can return. - } - - /** - * Returns whether a particular element is in select scope. - * - * @since 6.4.0 - * - * @see https://html.spec.whatwg.org/#has-an-element-in-select-scope - * - * @throws WP_HTML_Unsupported_Exception Always until this function is implemented. - * - * @param string $tag_name Name of tag to check. - * @return bool Whether given element is in scope. - */ - public function has_element_in_select_scope( $tag_name ) { - throw new WP_HTML_Unsupported_Exception( 'Cannot process elements depending on select scope.' ); - - return false; // The linter requires this unreachable code until the function is implemented and can return. - } - - /** - * Returns whether a P is in BUTTON scope. - * - * @since 6.4.0 - * - * @see https://html.spec.whatwg.org/#has-an-element-in-button-scope - * - * @return bool Whether a P is in BUTTON scope. - */ - public function has_p_in_button_scope() { - return $this->has_p_in_button_scope; - } - - /** - * Pops a node off of the stack of open elements. - * - * @since 6.4.0 - * - * @see https://html.spec.whatwg.org/#stack-of-open-elements - * - * @return bool Whether a node was popped off of the stack. - */ - public function pop() { - $item = array_pop( $this->stack ); - if ( null === $item ) { - return false; - } - - if ( 'context-node' === $item->bookmark_name ) { - $this->stack[] = $item; - return false; - } - - $this->after_element_pop( $item ); - return true; - } - - /** - * Pops nodes off of the stack of open elements until one with the given tag name has been popped. - * - * @since 6.4.0 - * - * @see WP_HTML_Open_Elements::pop - * - * @param string $tag_name Name of tag that needs to be popped off of the stack of open elements. - * @return bool Whether a tag of the given name was found and popped off of the stack of open elements. - */ - public function pop_until( $tag_name ) { - foreach ( $this->walk_up() as $item ) { - if ( 'context-node' === $item->bookmark_name ) { - return true; - } - - $this->pop(); - - if ( - '(internal: H1 through H6 - do not use)' === $tag_name && - in_array( $item->node_name, array( 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ), true ) - ) { - return true; - } - - if ( $tag_name === $item->node_name ) { - return true; - } - } - - return false; - } - - /** - * Pushes a node onto the stack of open elements. - * - * @since 6.4.0 - * - * @see https://html.spec.whatwg.org/#stack-of-open-elements - * - * @param WP_HTML_Token $stack_item Item to add onto stack. - */ - public function push( $stack_item ) { - $this->stack[] = $stack_item; - $this->after_element_push( $stack_item ); - } - - /** - * Removes a specific node from the stack of open elements. - * - * @since 6.4.0 - * - * @param WP_HTML_Token $token The node to remove from the stack of open elements. - * @return bool Whether the node was found and removed from the stack of open elements. - */ - public function remove_node( $token ) { - if ( 'context-node' === $token->bookmark_name ) { - return false; - } - - foreach ( $this->walk_up() as $position_from_end => $item ) { - if ( $token->bookmark_name !== $item->bookmark_name ) { - continue; - } - - $position_from_start = $this->count() - $position_from_end - 1; - array_splice( $this->stack, $position_from_start, 1 ); - $this->after_element_pop( $item ); - return true; - } - - return false; - } - - - /** - * Steps through the stack of open elements, starting with the top element - * (added first) and walking downwards to the one added last. - * - * This generator function is designed to be used inside a "foreach" loop. - * - * Example: - * - * $html = 'We are here'; - * foreach ( $stack->walk_down() as $node ) { - * echo "{$node->node_name} -> "; - * } - * > EM -> STRONG -> A -> - * - * To start with the most-recently added element and walk towards the top, - * see WP_HTML_Open_Elements::walk_up(). - * - * @since 6.4.0 - */ - public function walk_down() { - $count = count( $this->stack ); - - for ( $i = 0; $i < $count; $i++ ) { - yield $this->stack[ $i ]; - } - } - - /** - * Steps through the stack of open elements, starting with the bottom element - * (added last) and walking upwards to the one added first. - * - * This generator function is designed to be used inside a "foreach" loop. - * - * Example: - * - * $html = 'We are here'; - * foreach ( $stack->walk_up() as $node ) { - * echo "{$node->node_name} -> "; - * } - * > A -> STRONG -> EM -> - * - * To start with the first added element and walk towards the bottom, - * see WP_HTML_Open_Elements::walk_down(). - * - * @since 6.4.0 - * @since 6.5.0 Accepts $above_this_node to start traversal above a given node, if it exists. - * - * @param ?WP_HTML_Token $above_this_node Start traversing above this node, if provided and if the node exists. - */ - public function walk_up( $above_this_node = null ) { - $has_found_node = null === $above_this_node; - - for ( $i = count( $this->stack ) - 1; $i >= 0; $i-- ) { - $node = $this->stack[ $i ]; - - if ( ! $has_found_node ) { - $has_found_node = $node === $above_this_node; - continue; - } - - yield $node; - } - } - - /* - * Internal helpers. - */ - - /** - * Updates internal flags after adding an element. - * - * Certain conditions (such as "has_p_in_button_scope") are maintained here as - * flags that are only modified when adding and removing elements. This allows - * the HTML Processor to quickly check for these conditions instead of iterating - * over the open stack elements upon each new tag it encounters. These flags, - * however, need to be maintained as items are added and removed from the stack. - * - * @since 6.4.0 - * - * @param WP_HTML_Token $item Element that was added to the stack of open elements. - */ - public function after_element_push( $item ) { - /* - * When adding support for new elements, expand this switch to trap - * cases where the precalculated value needs to change. - */ - switch ( $item->node_name ) { - case 'BUTTON': - $this->has_p_in_button_scope = false; - break; - - case 'P': - $this->has_p_in_button_scope = true; - break; - } - - if ( null !== $this->push_handler ) { - ( $this->push_handler )( $item ); - } - } - - /** - * Updates internal flags after removing an element. - * - * Certain conditions (such as "has_p_in_button_scope") are maintained here as - * flags that are only modified when adding and removing elements. This allows - * the HTML Processor to quickly check for these conditions instead of iterating - * over the open stack elements upon each new tag it encounters. These flags, - * however, need to be maintained as items are added and removed from the stack. - * - * @since 6.4.0 - * - * @param WP_HTML_Token $item Element that was removed from the stack of open elements. - */ - public function after_element_pop( $item ) { - /* - * When adding support for new elements, expand this switch to trap - * cases where the precalculated value needs to change. - */ - switch ( $item->node_name ) { - case 'BUTTON': - $this->has_p_in_button_scope = $this->has_element_in_button_scope( 'P' ); - break; - - case 'P': - $this->has_p_in_button_scope = $this->has_element_in_button_scope( 'P' ); - break; - } - - if ( null !== $this->pop_handler ) { - ( $this->pop_handler )( $item ); - } - } - - /** - * Wakeup magic method. - * - * @since 6.6.0 - */ - public function __wakeup() { - throw new \LogicException( __CLASS__ . ' should never be unserialized' ); - } -} diff --git a/lib/compat/wordpress-6.6/html-api/class-gutenberg-html-processor-6-6.php b/lib/compat/wordpress-6.6/html-api/class-gutenberg-html-processor-6-6.php deleted file mode 100644 index 77801535ff3683..00000000000000 --- a/lib/compat/wordpress-6.6/html-api/class-gutenberg-html-processor-6-6.php +++ /dev/null @@ -1,2472 +0,0 @@ -next_tag( array( 'breadcrumbs' => array( 'DIV', 'FIGURE', 'IMG' ) ) ) ) { - * $processor->add_class( 'responsive-image' ); - * } - * - * #### Breadcrumbs - * - * Breadcrumbs represent the stack of open elements from the root - * of the document or fragment down to the currently-matched node, - * if one is currently selected. Call WP_HTML_Processor::get_breadcrumbs() - * to inspect the breadcrumbs for a matched tag. - * - * Breadcrumbs can specify nested HTML structure and are equivalent - * to a CSS selector comprising tag names separated by the child - * combinator, such as "DIV > FIGURE > IMG". - * - * Since all elements find themselves inside a full HTML document - * when parsed, the return value from `get_breadcrumbs()` will always - * contain any implicit outermost elements. For example, when parsing - * with `create_fragment()` in the `BODY` context (the default), any - * tag in the given HTML document will contain `array( 'HTML', 'BODY', … )` - * in its breadcrumbs. - * - * Despite containing the implied outermost elements in their breadcrumbs, - * tags may be found with the shortest-matching breadcrumb query. That is, - * `array( 'IMG' )` matches all IMG elements and `array( 'P', 'IMG' )` - * matches all IMG elements directly inside a P element. To ensure that no - * partial matches erroneously match it's possible to specify in a query - * the full breadcrumb match all the way down from the root HTML element. - * - * Example: - * - * $html = '
A lovely day outside
'; - * // ----- Matches here. - * $processor->next_tag( array( 'breadcrumbs' => array( 'FIGURE', 'IMG' ) ) ); - * - * $html = '
A lovely day outside
'; - * // ---- Matches here. - * $processor->next_tag( array( 'breadcrumbs' => array( 'FIGURE', 'FIGCAPTION', 'EM' ) ) ); - * - * $html = '
'; - * // ----- Matches here, because IMG must be a direct child of the implicit BODY. - * $processor->next_tag( array( 'breadcrumbs' => array( 'BODY', 'IMG' ) ) ); - * - * ## HTML Support - * - * This class implements a small part of the HTML5 specification. - * It's designed to operate within its support and abort early whenever - * encountering circumstances it can't properly handle. This is - * the principle way in which this class remains as simple as possible - * without cutting corners and breaking compliance. - * - * ### Supported elements - * - * If any unsupported element appears in the HTML input the HTML Processor - * will abort early and stop all processing. This draconian measure ensures - * that the HTML Processor won't break any HTML it doesn't fully understand. - * - * The following list specifies the HTML tags that _are_ supported: - * - * - Containers: ADDRESS, BLOCKQUOTE, DETAILS, DIALOG, DIV, FOOTER, HEADER, MAIN, MENU, SPAN, SUMMARY. - * - Custom elements: All custom elements are supported. :) - * - Form elements: BUTTON, DATALIST, FIELDSET, INPUT, LABEL, LEGEND, METER, PROGRESS, SEARCH. - * - Formatting elements: B, BIG, CODE, EM, FONT, I, PRE, SMALL, STRIKE, STRONG, TT, U, WBR. - * - Heading elements: H1, H2, H3, H4, H5, H6, HGROUP. - * - Links: A. - * - Lists: DD, DL, DT, LI, OL, UL. - * - Media elements: AUDIO, CANVAS, EMBED, FIGCAPTION, FIGURE, IMG, MAP, PICTURE, SOURCE, TRACK, VIDEO. - * - Paragraph: BR, P. - * - Phrasing elements: ABBR, AREA, BDI, BDO, CITE, DATA, DEL, DFN, INS, MARK, OUTPUT, Q, SAMP, SUB, SUP, TIME, VAR. - * - Sectioning elements: ARTICLE, ASIDE, HR, NAV, SECTION. - * - Templating elements: SLOT. - * - Text decoration: RUBY. - * - Deprecated elements: ACRONYM, BLINK, CENTER, DIR, ISINDEX, KEYGEN, LISTING, MULTICOL, NEXTID, PARAM, SPACER. - * - * ### Supported markup - * - * Some kinds of non-normative HTML involve reconstruction of formatting elements and - * re-parenting of mis-nested elements. For example, a DIV tag found inside a TABLE - * may in fact belong _before_ the table in the DOM. If the HTML Processor encounters - * such a case it will stop processing. - * - * The following list specifies HTML markup that _is_ supported: - * - * - Markup involving only those tags listed above. - * - Fully-balanced and non-overlapping tags. - * - HTML with unexpected tag closers. - * - Some unbalanced or overlapping tags. - * - P tags after unclosed P tags. - * - BUTTON tags after unclosed BUTTON tags. - * - A tags after unclosed A tags that don't involve any active formatting elements. - * - * @since 6.4.0 - * - * @see WP_HTML_Tag_Processor - * @see https://html.spec.whatwg.org/ - */ -class Gutenberg_HTML_Processor_6_6 extends Gutenberg_HTML_Tag_Processor_6_6 { - /** - * The maximum number of bookmarks allowed to exist at any given time. - * - * HTML processing requires more bookmarks than basic tag processing, - * so this class constant from the Tag Processor is overwritten. - * - * @since 6.4.0 - * - * @var int - */ - const MAX_BOOKMARKS = 100; - - /** - * Holds the working state of the parser, including the stack of - * open elements and the stack of active formatting elements. - * - * Initialized in the constructor. - * - * @since 6.4.0 - * - * @var WP_HTML_Processor_State - */ - private $state = null; - - /** - * Used to create unique bookmark names. - * - * This class sets a bookmark for every tag in the HTML document that it encounters. - * The bookmark name is auto-generated and increments, starting with `1`. These are - * internal bookmarks and are automatically released when the referring WP_HTML_Token - * goes out of scope and is garbage-collected. - * - * @since 6.4.0 - * - * @see WP_HTML_Processor::$release_internal_bookmark_on_destruct - * - * @var int - */ - private $bookmark_counter = 0; - - /** - * Stores an explanation for why something failed, if it did. - * - * @see self::get_last_error - * - * @since 6.4.0 - * - * @var string|null - */ - private $last_error = null; - - /** - * Releases a bookmark when PHP garbage-collects its wrapping WP_HTML_Token instance. - * - * This function is created inside the class constructor so that it can be passed to - * the stack of open elements and the stack of active formatting elements without - * exposing it as a public method on the class. - * - * @since 6.4.0 - * - * @var closure - */ - private $release_internal_bookmark_on_destruct = null; - - /** - * Stores stack events which arise during parsing of the - * HTML document, which will then supply the "match" events. - * - * @since 6.6.0 - * - * @var WP_HTML_Stack_Event[] - */ - private $element_queue = array(); - - /** - * Current stack event, if set, representing a matched token. - * - * Because the parser may internally point to a place further along in a document - * than the nodes which have already been processed (some "virtual" nodes may have - * appeared while scanning the HTML document), this will point at the "current" node - * being processed. It comes from the front of the element queue. - * - * @since 6.6.0 - * - * @var ?WP_HTML_Stack_Event - */ - private $current_element = null; - - /** - * Context node if created as a fragment parser. - * - * @var ?WP_HTML_Token - */ - private $context_node = null; - - /** - * Whether the parser has yet processed the context node, - * if created as a fragment parser. - * - * The context node will be initially pushed onto the stack of open elements, - * but when created as a fragment parser, this context element (and the implicit - * HTML document node above it) should not be exposed as a matched token or node. - * - * This boolean indicates whether the processor should skip over the current - * node in its initial search for the first node created from the input HTML. - * - * @var bool - */ - private $has_seen_context_node = false; - - /* - * Public Interface Functions - */ - - /** - * Creates an HTML processor in the fragment parsing mode. - * - * Use this for cases where you are processing chunks of HTML that - * will be found within a bigger HTML document, such as rendered - * block output that exists within a post, `the_content` inside a - * rendered site layout. - * - * Fragment parsing occurs within a context, which is an HTML element - * that the document will eventually be placed in. It becomes important - * when special elements have different rules than others, such as inside - * a TEXTAREA or a TITLE tag where things that look like tags are text, - * or inside a SCRIPT tag where things that look like HTML syntax are JS. - * - * The context value should be a representation of the tag into which the - * HTML is found. For most cases this will be the body element. The HTML - * form is provided because a context element may have attributes that - * impact the parse, such as with a SCRIPT tag and its `type` attribute. - * - * ## Current HTML Support - * - * - The only supported context is ``, which is the default value. - * - The only supported document encoding is `UTF-8`, which is the default value. - * - * @since 6.4.0 - * @since 6.6.0 Returns `static` instead of `self` so it can create subclass instances. - * - * @param string $html Input HTML fragment to process. - * @param string $context Context element for the fragment, must be default of ``. - * @param string $encoding Text encoding of the document; must be default of 'UTF-8'. - * @return static|null The created processor if successful, otherwise null. - */ - public static function create_fragment( $html, $context = '', $encoding = 'UTF-8' ) { - if ( '' !== $context || 'UTF-8' !== $encoding ) { - return null; - } - - $processor = new static( $html, self::CONSTRUCTOR_UNLOCK_CODE ); - $processor->state->context_node = array( 'BODY', array() ); - $processor->state->insertion_mode = Gutenberg_HTML_Processor_State_6_6::INSERTION_MODE_IN_BODY; - - // @todo Create "fake" bookmarks for non-existent but implied nodes. - $processor->bookmarks['root-node'] = new WP_HTML_Span( 0, 0 ); - $processor->bookmarks['context-node'] = new WP_HTML_Span( 0, 0 ); - - $processor->state->stack_of_open_elements->push( - new WP_HTML_Token( - 'root-node', - 'HTML', - false - ) - ); - - $context_node = new WP_HTML_Token( - 'context-node', - $processor->state->context_node[0], - false - ); - - $processor->state->stack_of_open_elements->push( $context_node ); - $processor->context_node = $context_node; - - return $processor; - } - - /** - * Constructor. - * - * Do not use this method. Use the static creator methods instead. - * - * @access private - * - * @since 6.4.0 - * - * @see WP_HTML_Processor::create_fragment() - * - * @param string $html HTML to process. - * @param string|null $use_the_static_create_methods_instead This constructor should not be called manually. - */ - public function __construct( $html, $use_the_static_create_methods_instead = null ) { - parent::__construct( $html ); - - if ( self::CONSTRUCTOR_UNLOCK_CODE !== $use_the_static_create_methods_instead ) { - _doing_it_wrong( - __METHOD__, - sprintf( - /* translators: %s: WP_HTML_Processor::create_fragment(). */ - __( 'Call %s to create an HTML Processor instead of calling the constructor directly.' ), - 'WP_HTML_Processor::create_fragment()' - ), - '6.4.0' - ); - } - - $this->state = new Gutenberg_HTML_Processor_State_6_6(); - - $this->state->stack_of_open_elements->set_push_handler( - function ( WP_HTML_Token $token ) { - $is_virtual = ! isset( $this->state->current_token ) || $this->is_tag_closer(); - $same_node = isset( $this->state->current_token ) && $token->node_name === $this->state->current_token->node_name; - $provenance = ( ! $same_node || $is_virtual ) ? 'virtual' : 'real'; - $this->element_queue[] = new Gutenberg_HTML_Stack_Event_6_6( $token, Gutenberg_HTML_Stack_Event_6_6::PUSH, $provenance ); - } - ); - - $this->state->stack_of_open_elements->set_pop_handler( - function ( WP_HTML_Token $token ) { - $is_virtual = ! isset( $this->state->current_token ) || ! $this->is_tag_closer(); - $same_node = isset( $this->state->current_token ) && $token->node_name === $this->state->current_token->node_name; - $provenance = ( ! $same_node || $is_virtual ) ? 'virtual' : 'real'; - $this->element_queue[] = new Gutenberg_HTML_Stack_Event_6_6( $token, Gutenberg_HTML_Stack_Event_6_6::POP, $provenance ); - } - ); - - /* - * Create this wrapper so that it's possible to pass - * a private method into WP_HTML_Token classes without - * exposing it to any public API. - */ - $this->release_internal_bookmark_on_destruct = function ( $name ) { - parent::release_bookmark( $name ); - }; - } - - /** - * Returns the last error, if any. - * - * Various situations lead to parsing failure but this class will - * return `false` in all those cases. To determine why something - * failed it's possible to request the last error. This can be - * helpful to know to distinguish whether a given tag couldn't - * be found or if content in the document caused the processor - * to give up and abort processing. - * - * Example - * - * $processor = WP_HTML_Processor::create_fragment( '