diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7ba9e884259ea4..a324657fad6f7d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -82,12 +82,14 @@ /packages/scripts @gziolo @ntwb @nerrad @ajitbohra @ryanwelcher /packages/stylelint-config @ntwb /test/e2e @kevin940726 @Mamaduka +/test/php/gutenberg-coding-standards @anton-vlasenko # UI Components /packages/components @ajitbohra /packages/compose @ajitbohra /packages/element @ajitbohra /packages/notices @ajitbohra +/packages/nux @ajitbohra @peterwilsoncc /packages/viewport @ajitbohra /packages/base-styles /packages/icons diff --git a/changelog.txt b/changelog.txt index 375a1d7199ece0..ede5cff91e4eda 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,299 @@ == Changelog == += 16.3.0-rc.1 = + + + +## Changelog + +### Enhancements + +#### Site Editor +- Edit Site: Add delay and fade-in animation to loading spinner. ([51902](https://github.com/WordPress/gutenberg/pull/51902)) +- Make "My patterns" category permanently visible. ([52531](https://github.com/WordPress/gutenberg/pull/52531)) +- Remove "Theme patterns" heading in Pattern library. ([52570](https://github.com/WordPress/gutenberg/pull/52570)) +- Remove sidebar group descriptions. ([52453](https://github.com/WordPress/gutenberg/pull/52453)) +- Show warning on removal of Post Template block in the site editor. ([52666](https://github.com/WordPress/gutenberg/pull/52666)) +- Swap pattern creation options. ([52726](https://github.com/WordPress/gutenberg/pull/52726)) +- Update Dashboard button tooltips in the site editor. ([52465](https://github.com/WordPress/gutenberg/pull/52465)) +- Update Site Editor frame z-index. ([52180](https://github.com/WordPress/gutenberg/pull/52180)) +- Update descriptions in Pattern library. ([52468](https://github.com/WordPress/gutenberg/pull/52468)) +- Update locked pattern tooltips. ([52497](https://github.com/WordPress/gutenberg/pull/52497)) +- Update navigation menu title size & weight in detail panels. ([52477](https://github.com/WordPress/gutenberg/pull/52477)) +- Update pattern library copy. ([52340](https://github.com/WordPress/gutenberg/pull/52340)) +- Update: Show more intuitive archive titles on Query Title block. ([52521](https://github.com/WordPress/gutenberg/pull/52521)) + +#### Patterns +- Add hint to show template part move. ([52395](https://github.com/WordPress/gutenberg/pull/52395)) +- Add renaming, duplication, and deletion options. ([52270](https://github.com/WordPress/gutenberg/pull/52270)) +- Add sync tooltip. ([52458](https://github.com/WordPress/gutenberg/pull/52458)) +- Display all custom template part areas in sidebar nav. ([52355](https://github.com/WordPress/gutenberg/pull/52355)) +- Don't override the rootClientID in create menu - only set if undefined. ([52713](https://github.com/WordPress/gutenberg/pull/52713)) +- Enable focus mode editing. ([52427](https://github.com/WordPress/gutenberg/pull/52427)) +- Remove `reusable` text from menu once rename hint has been dismissed. ([52664](https://github.com/WordPress/gutenberg/pull/52664)) +- Stop endless snackbars appearing. ([52012](https://github.com/WordPress/gutenberg/pull/52012)) +- Try: Sticky header and pagination on Patterns page. ([52663](https://github.com/WordPress/gutenberg/pull/52663)) +- Update manage pattern links to go to site editor if available. ([52403](https://github.com/WordPress/gutenberg/pull/52403)) +- [Patterns] Separate sync status into a filter control. ([52303](https://github.com/WordPress/gutenberg/pull/52303)) + +#### Components +- Adapt template part hint copy. ([52527](https://github.com/WordPress/gutenberg/pull/52527)) +- Adding support for defined IDs in `TextControl` component. ([52028](https://github.com/WordPress/gutenberg/pull/52028)) +- Updated "position" default value. ([52148](https://github.com/WordPress/gutenberg/pull/52148)) + +#### Interactivity API +- Add filter to turn off Interactivity API for a block. ([52579](https://github.com/WordPress/gutenberg/pull/52579)) +- Add runtime support for the `wp-style` directive. ([52645](https://github.com/WordPress/gutenberg/pull/52645)) + +#### Block Library +- Add back old Navigation and File blocks JavaScript implementation when Gutenberg is not installed. ([52553](https://github.com/WordPress/gutenberg/pull/52553)) +- Home link block: Add 'current-menu-item'. ([51478](https://github.com/WordPress/gutenberg/pull/51478)) + +#### Block Editor +- Add maxLength to LinkControl search item URLs. ([52523](https://github.com/WordPress/gutenberg/pull/52523)) +- i18n: Make the tab labels of `ColorGradientSettingsDropdown` component translatable. ([52669](https://github.com/WordPress/gutenberg/pull/52669)) + +#### NUX +- Restore `@wordpress/nux` to trunk. ([52455](https://github.com/WordPress/gutenberg/pull/52455)) + +#### Block API +- Block Editor: Add support for arrays to `setImmutably` util. ([52280](https://github.com/WordPress/gutenberg/pull/52280)) + +#### Inspector Controls +- Use next40pxDefaultSize on RangeControl components. ([52257](https://github.com/WordPress/gutenberg/pull/52257)) + +#### Fonts API +- Font Face: To generate and print font-face styles for theme.json fonts. ([51770](https://github.com/WordPress/gutenberg/pull/51770)) + + +### New APIs + +#### Nested / Inner Blocks +- Stabilize `defaultBlock`, `directInsert` API's and `getDirectInsertBlock` selector. ([52083](https://github.com/WordPress/gutenberg/pull/52083)) + + +### Bug Fixes + +#### Patterns +- Alternative grid layout to improve keyboard accessibility. ([52357](https://github.com/WordPress/gutenberg/pull/52357)) +- Add handling of sync status to the wp-admin patterns list page. ([52346](https://github.com/WordPress/gutenberg/pull/52346)) +- Add missing decoding entities processing in Patterns and Template/Parts pages. ([52449](https://github.com/WordPress/gutenberg/pull/52449)) +- Add option to set sync status when adding from wp-admin patterns list. ([52352](https://github.com/WordPress/gutenberg/pull/52352)) +- Avoid copying global style presets via the styles compatibility hook. ([52640](https://github.com/WordPress/gutenberg/pull/52640)) +- Command Palette: Update label and icon for Patterns. ([52742](https://github.com/WordPress/gutenberg/pull/52742)) +- Ensure that the unsaved title is not persisted when reopening the modal. ([52473](https://github.com/WordPress/gutenberg/pull/52473)) +- Fix bug with Create Patterns menu not showing in site editor page editing. ([52671](https://github.com/WordPress/gutenberg/pull/52671)) +- Fix renaming in Site View sidebar rename saves all edits for Template Parts and Navigation Menus. ([52373](https://github.com/WordPress/gutenberg/pull/52373)) +- Fix: Patterns & template parts: Remove "apply globally" option from block settings. ([52160](https://github.com/WordPress/gutenberg/pull/52160)) +- Rename edit label to Edit Block Pattern to resolve edge case in Chrome. ([52496](https://github.com/WordPress/gutenberg/pull/52496)) +- Show uncategorized patterns on the Editor > Patterns page. ([52633](https://github.com/WordPress/gutenberg/pull/52633)) +- Site Editor Patterns: Filter out patterns that are not available in the inserter. ([52675](https://github.com/WordPress/gutenberg/pull/52675)) +- Update the title of Pattern block in the block inspector card. ([52010](https://github.com/WordPress/gutenberg/pull/52010)) + +#### Site Editor +- Edit Site: Fix the pattern with the post types becomes the placeholder pattern when editing template part. ([52503](https://github.com/WordPress/gutenberg/pull/52503)) +- Fix "Manage all patterns" link appearance. ([52532](https://github.com/WordPress/gutenberg/pull/52532)) +- Fix document title icon appearance. ([52424](https://github.com/WordPress/gutenberg/pull/52424)) +- Fix entering edit mode in site editor. ([52406](https://github.com/WordPress/gutenberg/pull/52406)) +- Fix missing Add Template Part button in Template Parts page. ([52542](https://github.com/WordPress/gutenberg/pull/52542)) +- Fix undo/redo in site editor code editor's mode. ([52695](https://github.com/WordPress/gutenberg/pull/52695)) +- Remove status icon. ([52457](https://github.com/WordPress/gutenberg/pull/52457)) +- Reset device preview type when exiting the editing mode. ([52566](https://github.com/WordPress/gutenberg/pull/52566)) +- ResizableFrame: Fix styling in Firefox. ([52700](https://github.com/WordPress/gutenberg/pull/52700)) +- Site Editor Pages: Load the appropriate template if posts page set. ([52266](https://github.com/WordPress/gutenberg/pull/52266)) +- Site Editor Patterns: Ensure sidebar does not shrink when long pattern titles are used. ([52547](https://github.com/WordPress/gutenberg/pull/52547)) +- Use lowercase p in in "Manage Patterns". ([52617](https://github.com/WordPress/gutenberg/pull/52617)) +- Do not navigate to the styles pages unless you're in a random listing page. ([52728](https://github.com/WordPress/gutenberg/pull/52728)) +- Fix multiple navigation blocks in pattern template. ([52707](https://github.com/WordPress/gutenberg/pull/52707)) + +#### Block Library +- Fix console warning by improving error handling in Nav block classic menu conversion. ([52591](https://github.com/WordPress/gutenberg/pull/52591)) +- Fix importing classic menus. ([52573](https://github.com/WordPress/gutenberg/pull/52573)) +- Fix: Focus loss on navigation link label editing on Firefox. ([52428](https://github.com/WordPress/gutenberg/pull/52428)) +- List block: Fix selected numbering style option. ([52472](https://github.com/WordPress/gutenberg/pull/52472)) +- Post Title: The changes should be reflected when previewing a post. ([52369](https://github.com/WordPress/gutenberg/pull/52369)) +- Quote block: Add transform to paragraph. ([51809](https://github.com/WordPress/gutenberg/pull/51809)) +- Remove synced blocks from lastBlockInserted. ([52558](https://github.com/WordPress/gutenberg/pull/52558)) +- Rich Text/Footnotes: Fix getRichTextValues for useInnerBlocksProps.save. ([52682](https://github.com/WordPress/gutenberg/pull/52682)) +- Search block: Enqueue view script through block.json. ([52552](https://github.com/WordPress/gutenberg/pull/52552)) +- Use `_get_block_template_file` function and set $area variable. ([52708](https://github.com/WordPress/gutenberg/pull/52708)) + +#### Accessibility +- Change Delete page menu item to Move to trash. ([52641](https://github.com/WordPress/gutenberg/pull/52641)) +- Change password input to type text so contents are visible. ([52622](https://github.com/WordPress/gutenberg/pull/52622)) +- Do not autofocus page title field in the 'Draft a new page' modal dialog. ([52603](https://github.com/WordPress/gutenberg/pull/52603)) +- Fix Shift+Tab to Block Toolbar. ([52613](https://github.com/WordPress/gutenberg/pull/52613)) +- Item: Unify focus style and add default font styles. ([52495](https://github.com/WordPress/gutenberg/pull/52495)) +- Navigation block: Add notice on reduced accessibility. ([52251](https://github.com/WordPress/gutenberg/pull/52251)) +- Password protected field: Remove autofocus and improve placeholder text consistency. ([52634](https://github.com/WordPress/gutenberg/pull/52634)) +- ResizableFrame: Make keyboard accessible. ([52443](https://github.com/WordPress/gutenberg/pull/52443)) +- Site Editor: Fix navigation menu sidebar actions order and label. ([52592](https://github.com/WordPress/gutenberg/pull/52592)) + +#### Block Editor +- Add 'reusable' keyword to Pattern blocks. ([52543](https://github.com/WordPress/gutenberg/pull/52543)) +- Avoid errors in Dimension visualizers when switching between iframed and non-iframed editors. ([52588](https://github.com/WordPress/gutenberg/pull/52588)) +- Ensure synced patterns are accounted for in 'getAllowedBlocks'. ([52546](https://github.com/WordPress/gutenberg/pull/52546)) +- Fix: Remove link action of Link UI for draft pages created from Nav block does not correctly remove link. ([52415](https://github.com/WordPress/gutenberg/pull/52415)) +- LinkControl: Add width to ensure ellipsis truncating works. ([52575](https://github.com/WordPress/gutenberg/pull/52575)) +- LinkControl: Fix mark highlight to bold. ([52517](https://github.com/WordPress/gutenberg/pull/52517)) +- Post Content link color should not be applied to placeholder component links. ([52367](https://github.com/WordPress/gutenberg/pull/52367)) +- Fix highlight change when using transform menu. ([52752](https://github.com/WordPress/gutenberg/pull/52752)) +- Fix: Apply text color selection to link color. ([52379](https://github.com/WordPress/gutenberg/pull/52379)) + +#### Components +- Block Editor: Display variation icon in the 'BlockDraggable' component. ([52502](https://github.com/WordPress/gutenberg/pull/52502)) +- Copy tweak for the reusable block rename hint. ([52581](https://github.com/WordPress/gutenberg/pull/52581)) +- Fix react-dropdown-menu version to avoid breaking change from one of …. ([52356](https://github.com/WordPress/gutenberg/pull/52356)) +- FormTokenField: Fix token overflow when moving cursor left or right. ([52662](https://github.com/WordPress/gutenberg/pull/52662)) +- Site Editor: Make sidebar back button go *back* instead of *up* if possible. ([52456](https://github.com/WordPress/gutenberg/pull/52456)) +- Top Toolbar: Move the preferences selection into the main useSelect. ([52332](https://github.com/WordPress/gutenberg/pull/52332)) + +#### Post Editor +- Editor: Remove a block select button from the multi-entity saving flow. ([52753](https://github.com/WordPress/gutenberg/pull/52753)) +- Fix Site editor page when JS support is disabled. ([52376](https://github.com/WordPress/gutenberg/pull/52376)) +- Fix initial block parsing. ([52417](https://github.com/WordPress/gutenberg/pull/52417)) +- Simplify the code editor of edit-post. ([52751](https://github.com/WordPress/gutenberg/pull/52751)) + +#### Global Styles +- DimensionsPanel: Fix unexpected value decoding/encoding. ([52661](https://github.com/WordPress/gutenberg/pull/52661)) +- Global font sizes: Ensure sizes are unique. ([52483](https://github.com/WordPress/gutenberg/pull/52483)) +- Spacing Sizes: Fix zero size typo and to be output directly. ([52711](https://github.com/WordPress/gutenberg/pull/52711)) + +#### Themes +- Fix admin_url() for preview link of block themes. ([52399](https://github.com/WordPress/gutenberg/pull/52399)) +- Site Editor: Don't allow creating template part on the Patterns page for non-block themes. ([52656](https://github.com/WordPress/gutenberg/pull/52656)) + +#### Fonts API +- Deprecate and make Fonts API non-functional. ([52485](https://github.com/WordPress/gutenberg/pull/52485)) +- Fix font printing regression when metabox exists. ([52343](https://github.com/WordPress/gutenberg/pull/52343)) + +#### Extensibility +- Page Content Focus: Ignore page content within a Query Loop block. ([52351](https://github.com/WordPress/gutenberg/pull/52351)) + +#### Page Content Focus +- Exit template focus when opening the W menu. ([52235](https://github.com/WordPress/gutenberg/pull/52235)) + +#### Block Validation/Deprecation +- Cover Block: Fix block deprecation when fixed background is enabled. ([51612](https://github.com/WordPress/gutenberg/pull/51612)) + + +### Performance + +#### Post Editor +- Fix performance regression for isEditedPostEmpty selector. ([52759](https://github.com/WordPress/gutenberg/pull/52759)) + +#### Patterns +- Add client side pagination to patterns list. ([52538](https://github.com/WordPress/gutenberg/pull/52538)) + +#### Site Editor +- Fix entity cache misses for single posts due to string as recordKey. ([52338](https://github.com/WordPress/gutenberg/pull/52338)) + +#### Block Library +- Experimental: Disable TinyMCE compat with classic editor. ([52325](https://github.com/WordPress/gutenberg/pull/52325)) + + +### Experiments + +#### Project Management +- Github workflow: Add a PHP backport changes action. ([52096](https://github.com/WordPress/gutenberg/pull/52096)) + +#### Interactivity API +- Prevent scripts from loading if behaviors are not used. ([52140](https://github.com/WordPress/gutenberg/pull/52140)) + + +### Documentation + +- (readme.md) Document the new process for releasing point releases for old release branches. ([49968](https://github.com/WordPress/gutenberg/pull/49968)) +- Add layout API documentation. ([52673](https://github.com/WordPress/gutenberg/pull/52673)) +- Added README for the "caption" component. ([52033](https://github.com/WordPress/gutenberg/pull/52033)) +- Added documentation text-transform component #52072. ([52243](https://github.com/WordPress/gutenberg/pull/52243)) +- Block Editor: Add README for `BlockControls`. ([52366](https://github.com/WordPress/gutenberg/pull/52366)) +- Lodash: Remove completely. ([52571](https://github.com/WordPress/gutenberg/pull/52571)) +- Removed line break within the code block. ([46920](https://github.com/WordPress/gutenberg/pull/46920)) +- Theme JSON schema: Add missing block names and unify block properties. ([51293](https://github.com/WordPress/gutenberg/pull/51293)) +- Update layout architecture documentation after stabilisation. ([52316](https://github.com/WordPress/gutenberg/pull/52316)) + + +### Code Quality + +- Add missing `@emotion/react` dep to block-editor. ([52475](https://github.com/WordPress/gutenberg/pull/52475)) +- Code Data: Fix ESLint warning for 'useEntityProp' hook. ([52757](https://github.com/WordPress/gutenberg/pull/52757)) +- Lodash: Deprecate `_.set()`. ([52407](https://github.com/WordPress/gutenberg/pull/52407)) +- Lodash: Remove remaining `_.get()` from block editor and deprecate. ([52561](https://github.com/WordPress/gutenberg/pull/52561)) +- Make use of accessing private APIs from thunks directly. ([52214](https://github.com/WordPress/gutenberg/pull/52214)) + +#### Block Library +- Footnotes: Backport core changes to excerpt trim. ([52709](https://github.com/WordPress/gutenberg/pull/52709)) +- Navigation: Simplify the useSelect for useNavigationMenus. ([51977](https://github.com/WordPress/gutenberg/pull/51977)) +- Query Pagination: Set 'clientId' as useSelect dependency. ([52358](https://github.com/WordPress/gutenberg/pull/52358)) +- Search: Remove unnecessary useEffect. ([52604](https://github.com/WordPress/gutenberg/pull/52604)) +- Template Parts: Set attributes 'area' as useSelect dependency. ([52330](https://github.com/WordPress/gutenberg/pull/52330)) + +#### Global Styles +- Lodash: Refactor away from `_.set()` in `PushChangesToGlobalStylesControl`. ([52404](https://github.com/WordPress/gutenberg/pull/52404)) +- Lodash: Refactor away from `_.set()` in `getNodesWithSettings()`. ([52278](https://github.com/WordPress/gutenberg/pull/52278)) +- Lodash: Refactor away from `_.set()` in global styles. ([52279](https://github.com/WordPress/gutenberg/pull/52279)) +- Lodash: Remove completely from site editor. ([52480](https://github.com/WordPress/gutenberg/pull/52480)) + +#### Post Editor +- EntityRecordItem: Fix ESLint warnings and remove unnecessary memoization. ([52630](https://github.com/WordPress/gutenberg/pull/52630)) +- PostPreviewButton: Rewrite to functional, avoid state transitions in lifecycles. ([44971](https://github.com/WordPress/gutenberg/pull/44971)) +- correct a typo: Sapce -> space. ([52578](https://github.com/WordPress/gutenberg/pull/52578)) + +#### Site Editor +- Fix incorrect 'useSelect' usage. ([52683](https://github.com/WordPress/gutenberg/pull/52683)) +- SiteHub: Combine site data selector hooks. ([52567](https://github.com/WordPress/gutenberg/pull/52567)) + +#### Reusable Blocks +- Update package to use relative path. ([52712](https://github.com/WordPress/gutenberg/pull/52712)) + + +### Tools + +#### Testing +- Iframe: Silence style compat warnings when in a BlockPreview. ([52627](https://github.com/WordPress/gutenberg/pull/52627)) +- Make `query` optional in `visitAdminPage`. ([52413](https://github.com/WordPress/gutenberg/pull/52413)) +- Migrate Adding Inline Token test to Playwright. ([52020](https://github.com/WordPress/gutenberg/pull/52020)) +- Migrate site editor multi-entity save flow tests. ([52372](https://github.com/WordPress/gutenberg/pull/52372)) +- Move request utils reset to global setup. ([52412](https://github.com/WordPress/gutenberg/pull/52412)) +- Nav block: Link text color inheritance fixes and tests. ([51710](https://github.com/WordPress/gutenberg/pull/51710)) +- Refactor and split navigation block end-to-end tests into separate files. ([52647](https://github.com/WordPress/gutenberg/pull/52647)) +- Try fixing block context end-to-end test failure. ([52513](https://github.com/WordPress/gutenberg/pull/52513)) +- Use posts instead of template parts for navigation color tests. ([52654](https://github.com/WordPress/gutenberg/pull/52654)) +- end-to-end Test Utils: Improve test reliability in plugins/themes and login procedures. ([52144](https://github.com/WordPress/gutenberg/pull/52144)) +- test: Enable jest-watch-typeahead for native tests. ([51869](https://github.com/WordPress/gutenberg/pull/51869)) +- test: Expand mobile editor tests. ([52446](https://github.com/WordPress/gutenberg/pull/52446)) + +#### Build Tooling +- Backport tools: Sort PRs to be cherry picked by merged/closed date. ([52667](https://github.com/WordPress/gutenberg/pull/52667)) +- Create block interactive template. ([52612](https://github.com/WordPress/gutenberg/pull/52612)) +- Fix Webpack to watch the `interactivity` package files. ([52642](https://github.com/WordPress/gutenberg/pull/52642)) +- Update caniuse-lite, browserslist and core-js. ([52420](https://github.com/WordPress/gutenberg/pull/52420)) + +#### Project Management +- Update issue gardening automation with new label. ([52173](https://github.com/WordPress/gutenberg/pull/52173)) + +### Various + +- Revert "Update Changelog for 16.1.2". ([52433](https://github.com/WordPress/gutenberg/pull/52433)) + + +## First time contributors + +The following PRs were merged by first time contributors: + +- @andrewhayward: Adding support for defined IDs in `TextControl` component. ([52028](https://github.com/WordPress/gutenberg/pull/52028)) +- @ghorivipul97: Post Content link color should not be applied to placeholder component links. ([52367](https://github.com/WordPress/gutenberg/pull/52367)) +- @sethrubenstein: Stabilize `defaultBlock`, `directInsert` API's and `getDirectInsertBlock` selector. ([52083](https://github.com/WordPress/gutenberg/pull/52083)) + + +## Contributors + +The following contributors merged PRs in this release: + +@aaronrobertshaw @afercia @andrewhayward @andrewserong @anomiex @arthur791004 @BenjaminZekavica @bfintal @carolinan @Clorith @dcalhoun @derekblank @diegohaz @draganescu @ellatrix @fluiddot @fullofcaffeine @geriux @getdave @ghorivipul97 @glendaviesnz @hellofromtonya @jameskoster @jeryj @jorgefilipecosta @jsnajdr @juanmaguitar @kevin940726 @luisherranz @MaggieCabrera @Mamaduka @michalczaplinski @mirka @noisysocks @ntsekouras @peterwilsoncc @pooja-muchandikar @Presskopp @priethor @ramonjd @richtabor @SantosGuillamot @SavPhill @SaxonF @scruffian @sethrubenstein @spacedmonkey @swissspidy @t-hamano @tellthemachines @tyxla @walbo @westonruter @youknowriad + + = 16.2.1 = ## Changelog diff --git a/composer.json b/composer.json index 3f16ba495a94ca..134e366befdb94 100644 --- a/composer.json +++ b/composer.json @@ -32,8 +32,18 @@ "wp-coding-standards/wpcs": "^2.2", "sirbrillig/phpcs-variable-analysis": "^2.8", "spatie/phpunit-watcher": "^1.23", - "yoast/phpunit-polyfills": "^1.0" + "yoast/phpunit-polyfills": "^1.0", + "gutenberg/gutenberg-coding-standards": "@dev" }, + "repositories": [ + { + "type": "path", + "url": "./test/php/gutenberg-coding-standards", + "options": { + "symlink": false + } + } + ], "require": { "composer/installers": "~1.0" }, diff --git a/docs/assets/text-transform-component.png b/docs/assets/text-transform-component.png new file mode 100644 index 00000000000000..2155fbdb8ebef6 Binary files /dev/null and b/docs/assets/text-transform-component.png differ diff --git a/docs/contributors/code/scripts.md b/docs/contributors/code/scripts.md index 5cd7efd2fffdad..1483a409a4d08f 100644 --- a/docs/contributors/code/scripts.md +++ b/docs/contributors/code/scripts.md @@ -31,6 +31,7 @@ The editor includes a number of packages to enable various pieces of functionali | [Is Shallow Equal](/packages/is-shallow-equal/README.md) | wp-is-shallow-equal | A function for performing a shallow comparison between two objects or arrays | | [Keycodes](/packages/keycodes/README.md) | wp-keycodes | Keycodes utilities for WordPress, used to check the key pressed in events like `onKeyDown` | | [List Reusable blocks](/packages/list-reusable-blocks/README.md) | wp-list-reusable-blocks | Package used to add import/export links to the listing page of the reusable blocks | +| [NUX](/packages/nux/README.md) | wp-nux | Components, and wp.data methods useful for onboarding a new user to the WordPress admin interface | | [Plugins](/packages/plugins/README.md) | wp-plugins | Plugins module for WordPress | | [Redux Routine](/packages/redux-routine/README.md) | wp-redux-routine | Redux middleware for generator coroutines | | [Rich Text](/packages/rich-text/README.md) | wp-rich-text | Helper functions to convert HTML or a DOM tree into a rich text value and back | diff --git a/docs/how-to-guides/themes/theme-support.md b/docs/how-to-guides/themes/theme-support.md index eae72f255fac2c..b978ede928b83d 100644 --- a/docs/how-to-guides/themes/theme-support.md +++ b/docs/how-to-guides/themes/theme-support.md @@ -472,6 +472,8 @@ Use this setting to enable the following Global Styles settings: - color: link - spacing: blockGap, margin, padding - typography: lineHeight +- dimensions: minHeight +- position: sticky ```php add_theme_support( 'appearance-tools' ); diff --git a/docs/manifest.json b/docs/manifest.json index ec55132cd7d4b2..5f75e49924f355 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1757,6 +1757,12 @@ "markdown_source": "../packages/npm-package-json-lint-config/README.md", "parent": "packages" }, + { + "title": "@wordpress/nux", + "slug": "packages-nux", + "markdown_source": "../packages/nux/README.md", + "parent": "packages" + }, { "title": "@wordpress/plugins", "slug": "packages-plugins", @@ -2003,6 +2009,12 @@ "markdown_source": "../docs/reference-guides/data/data-core-notices.md", "parent": "data" }, + { + "title": "The NUX (New User Experience) Data", + "slug": "data-core-nux", + "markdown_source": "../docs/reference-guides/data/data-core-nux.md", + "parent": "data" + }, { "title": "Preferences", "slug": "data-core-preferences", diff --git a/docs/reference-guides/README.md b/docs/reference-guides/README.md index f13c838697f2de..33fdd9aa602414 100644 --- a/docs/reference-guides/README.md +++ b/docs/reference-guides/README.md @@ -63,6 +63,7 @@ - [**core/editor**: The Post Editor’s Data](/docs/reference-guides/data/data-core-editor.md) - [**core/keyboard-shortcuts**: The Keyboard Shortcuts Data](/docs/reference-guides/data/data-core-keyboard-shortcuts.md) - [**core/notices**: Notices Data](/docs/reference-guides/data/data-core-notices.md) + - [**core/nux**: The NUX (New User Experience) Data](/docs/reference-guides/data/data-core-nux.md) - [**core/preferences**: Preferences](/docs/reference-guides/data/data-core-preferences.md) - [**core/reusable-blocks**: Reusable blocks](/docs/reference-guides/data/data-core-reusable-blocks.md) - [**core/rich-text**: Rich Text](/docs/reference-guides/data/data-core-rich-text.md) diff --git a/docs/reference-guides/data/README.md b/docs/reference-guides/data/README.md index 5f4d8d92d4bd49..1134c1d5ddd307 100644 --- a/docs/reference-guides/data/README.md +++ b/docs/reference-guides/data/README.md @@ -12,6 +12,7 @@ - [**core/editor**: The Post Editor’s Data](/docs/reference-guides/data/data-core-editor.md) - [**core/keyboard-shortcuts**: The Keyboard Shortcuts Data](/docs/reference-guides/data/data-core-keyboard-shortcuts.md) - [**core/notices**: Notices Data](/docs/reference-guides/data/data-core-notices.md) +- [**core/nux**: The NUX (New User Experience) Data](/docs/reference-guides/data/data-core-nux.md) - [**core/preferences**: Preferences](/docs/reference-guides/data/data-core-preferences.md) - [**core/reusable-blocks**: Reusable blocks](/docs/reference-guides/data/data-core-reusable-blocks.md) - [**core/rich-text**: Rich Text](/docs/reference-guides/data/data-core-rich-text.md) diff --git a/docs/reference-guides/data/data-core-block-editor.md b/docs/reference-guides/data/data-core-block-editor.md index fd29b1c6e1388c..744b7b2896e26a 100644 --- a/docs/reference-guides/data/data-core-block-editor.md +++ b/docs/reference-guides/data/data-core-block-editor.md @@ -168,29 +168,6 @@ _Returns_ - `Array?`: The list of allowed block types. -### getBehaviors - -Returns the behaviors registered with the editor. - -Behaviors are named, reusable pieces of functionality that can be attached to blocks. They are registered with the editor using the `theme.json` file. - -_Usage_ - -```js -const behaviors = select( blockEditorStore ).getBehaviors(); -if ( behaviors?.lightbox ) { - // Do something with the lightbox. -} -``` - -_Parameters_ - -- _state_ `Object`: Editor state. - -_Returns_ - -- `Object`: The editor behaviors object. - ### getBlock Returns a block given its client ID. This is a parsed copy of the block, containing its `blockName`, `clientId`, and current `attributes` state. This is not the block's registration settings, which must be retrieved from the blocks module registration store. diff --git a/docs/reference-guides/data/data-core-nux.md b/docs/reference-guides/data/data-core-nux.md new file mode 100644 index 00000000000000..eb6a1c3b5c9a5b --- /dev/null +++ b/docs/reference-guides/data/data-core-nux.md @@ -0,0 +1,93 @@ +# The NUX (New User Experience) Data + +Namespace: `core/nux`. + +## Selectors + + + +### areTipsEnabled + +Returns whether or not tips are globally enabled. + +_Parameters_ + +- _state_ `Object`: Global application state. + +_Returns_ + +- `boolean`: Whether tips are globally enabled. + +### getAssociatedGuide + +Returns an object describing the guide, if any, that the given tip is a part of. + +_Parameters_ + +- _state_ `Object`: Global application state. +- _tipId_ `string`: The tip to query. + +_Returns_ + +- `?NUXGuideInfo`: Information about the associated guide. + +### isTipVisible + +Determines whether or not the given tip is showing. Tips are hidden if they are disabled, have been dismissed, or are not the current tip in any guide that they have been added to. + +_Parameters_ + +- _state_ `Object`: Global application state. +- _tipId_ `string`: The tip to query. + +_Returns_ + +- `boolean`: Whether or not the given tip is showing. + + + +## Actions + + + +### disableTips + +Returns an action object that, when dispatched, prevents all tips from showing again. + +_Returns_ + +- `Object`: Action object. + +### dismissTip + +Returns an action object that, when dispatched, dismisses the given tip. A dismissed tip will not show again. + +_Parameters_ + +- _id_ `string`: The tip to dismiss. + +_Returns_ + +- `Object`: Action object. + +### enableTips + +Returns an action object that, when dispatched, makes all tips show again. + +_Returns_ + +- `Object`: Action object. + +### triggerGuide + +Returns an action object that, when dispatched, presents a guide that takes the user through a series of tips step by step. + +_Parameters_ + +- _tipIds_ `string[]`: Which tips to show in the guide. + +_Returns_ + +- `Object`: Action object. + + diff --git a/docs/toc.json b/docs/toc.json index 085bbb536ece2b..1660afdcc29497 100644 --- a/docs/toc.json +++ b/docs/toc.json @@ -284,6 +284,7 @@ "docs/reference-guides/data/data-core-keyboard-shortcuts.md": [] }, { "docs/reference-guides/data/data-core-notices.md": [] }, + { "docs/reference-guides/data/data-core-nux.md": [] }, { "docs/reference-guides/data/data-core-preferences.md": [] }, diff --git a/gutenberg.php b/gutenberg.php index 8a5b9e110a51c6..cb3300bfae0b4f 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the block editor, site editor, and other future WordPress core functionality. * Requires at least: 6.1 * Requires PHP: 5.6 - * Version: 16.2.1 + * Version: 16.3.0-rc.1 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/lib/class-wp-duotone-gutenberg.php b/lib/class-wp-duotone-gutenberg.php index 816f7e414ad793..41120a882ed235 100644 --- a/lib/class-wp-duotone-gutenberg.php +++ b/lib/class-wp-duotone-gutenberg.php @@ -32,6 +32,10 @@ * @since 6.3.0 */ +if ( class_exists( 'WP_Duotone_Gutenberg' ) ) { + return; +} + /** * Manages duotone block supports and global styles. * diff --git a/lib/class-wp-theme-json-data-gutenberg.php b/lib/class-wp-theme-json-data-gutenberg.php index 2e5ea474346a92..db0737ebea08b6 100644 --- a/lib/class-wp-theme-json-data-gutenberg.php +++ b/lib/class-wp-theme-json-data-gutenberg.php @@ -6,6 +6,10 @@ * @since 6.1.0 */ +if ( class_exists( 'WP_Theme_JSON_Data_Gutenberg' ) ) { + return; +} + /** * Class to provide access to update a theme.json structure. */ diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 0745ee06b84a23..60e69632eedb62 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -6,6 +6,10 @@ * @since 5.8.0 */ +if ( class_exists( 'WP_Theme_JSON_Gutenberg' ) ) { + return; +} + /** * Class that encapsulates the processing of structures that adhere to the theme.json spec. * diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php index 1e825e3c6bbe4f..39721742946cd1 100644 --- a/lib/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/class-wp-theme-json-resolver-gutenberg.php @@ -6,6 +6,10 @@ * @since 5.8.0 */ +if ( class_exists( 'WP_Theme_JSON_Resolver_Gutenberg' ) ) { + return; +} + /** * Class that abstracts the processing of the different data sources * for site-level config and offers an API to work with them. diff --git a/lib/client-assets.php b/lib/client-assets.php index 99aa7f147ecbfc..891eb05eabdbeb 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -368,6 +368,15 @@ function gutenberg_register_packages_styles( $styles ) { ); $styles->add_data( 'wp-edit-blocks', 'rtl', 'replace' ); + gutenberg_override_style( + $styles, + 'wp-nux', + gutenberg_url( 'build/nux/style.css' ), + array( 'wp-components' ), + $version + ); + $styles->add_data( 'wp-nux', 'rtl', 'replace' ); + gutenberg_override_style( $styles, 'wp-block-library-theme', diff --git a/lib/compat/wordpress-6.2/html-api/class-wp-html-attribute-token.php b/lib/compat/wordpress-6.2/html-api/class-wp-html-attribute-token.php index 2c52164a979f02..cc03c1441ee042 100644 --- a/lib/compat/wordpress-6.2/html-api/class-wp-html-attribute-token.php +++ b/lib/compat/wordpress-6.2/html-api/class-wp-html-attribute-token.php @@ -7,6 +7,10 @@ * @since 6.2.0 */ +if ( class_exists( 'WP_HTML_Attribute_Token' ) ) { + return; +} + /** * Data structure for the attribute token that allows to drastically improve performance. * diff --git a/lib/compat/wordpress-6.2/html-api/class-wp-html-span.php b/lib/compat/wordpress-6.2/html-api/class-wp-html-span.php index d92778cd3a2223..e38bc551923170 100644 --- a/lib/compat/wordpress-6.2/html-api/class-wp-html-span.php +++ b/lib/compat/wordpress-6.2/html-api/class-wp-html-span.php @@ -7,6 +7,10 @@ * @since 6.2.0 */ +if ( class_exists( 'WP_HTML_Span' ) ) { + return; +} + /** * Represents a textual span inside an HTML document. * diff --git a/lib/compat/wordpress-6.2/html-api/class-wp-html-tag-processor.php b/lib/compat/wordpress-6.2/html-api/class-wp-html-tag-processor.php index 7edb67f9f0423e..d61180074f608d 100644 --- a/lib/compat/wordpress-6.2/html-api/class-wp-html-tag-processor.php +++ b/lib/compat/wordpress-6.2/html-api/class-wp-html-tag-processor.php @@ -26,6 +26,10 @@ * @since 6.2.0 */ +if ( class_exists( 'WP_HTML_Tag_Processor' ) ) { + return; +} + /** * Modifies attributes in an HTML document for tags matching a query. * diff --git a/lib/compat/wordpress-6.2/html-api/class-wp-html-text-replacement.php b/lib/compat/wordpress-6.2/html-api/class-wp-html-text-replacement.php index 912b4a56a5eb42..b3f70c8e7c57f4 100644 --- a/lib/compat/wordpress-6.2/html-api/class-wp-html-text-replacement.php +++ b/lib/compat/wordpress-6.2/html-api/class-wp-html-text-replacement.php @@ -7,6 +7,10 @@ * @since 6.2.0 */ +if ( class_exists( 'WP_HTML_Text_Replacement' ) ) { + return; +} + /** * Data structure used to replace existing content from start to end that allows to drastically improve performance. * diff --git a/lib/compat/wordpress-6.2/rest-api.php b/lib/compat/wordpress-6.2/rest-api.php index c0f098fa6893ac..97f7daecdff2f7 100644 --- a/lib/compat/wordpress-6.2/rest-api.php +++ b/lib/compat/wordpress-6.2/rest-api.php @@ -91,43 +91,46 @@ function gutenberg_modify_rest_sidebars_response( $response ) { } add_filter( 'rest_prepare_sidebar', 'gutenberg_modify_rest_sidebars_response' ); - -/** - * Add the `block_types` value to the `pattern-directory-item` schema. - * - * @since 6.2.0 Added 'block_types' property. - */ -function add_block_pattern_block_types_schema() { - register_rest_field( - 'pattern-directory-item', - 'block_types', - array( - 'schema' => array( - 'description' => __( 'The block types which can use this pattern.', 'gutenberg' ), - 'type' => 'array', - 'uniqueItems' => true, - 'items' => array( 'type' => 'string' ), - 'context' => array( 'view', 'embed' ), - ), - ) - ); +if ( ! function_exists( 'add_block_pattern_block_types_schema' ) ) { + /** + * Add the `block_types` value to the `pattern-directory-item` schema. + * + * @since 6.2.0 Added 'block_types' property. + */ + function add_block_pattern_block_types_schema() { + register_rest_field( + 'pattern-directory-item', + 'block_types', + array( + 'schema' => array( + 'description' => __( 'The block types which can use this pattern.', 'gutenberg' ), + 'type' => 'array', + 'uniqueItems' => true, + 'items' => array( 'type' => 'string' ), + 'context' => array( 'view', 'embed' ), + ), + ) + ); + } } add_filter( 'rest_api_init', 'add_block_pattern_block_types_schema' ); -/** - * Add the `block_types` value into the API response. - * - * @since 6.2.0 Added 'block_types' property. - * - * @param WP_REST_Response $response The response object. - * @param object $raw_pattern The unprepared pattern. - */ -function filter_block_pattern_response( $response, $raw_pattern ) { - $data = $response->get_data(); - $data['block_types'] = array_map( 'sanitize_text_field', $raw_pattern->meta->wpop_block_types ); - $response->set_data( $data ); - return $response; +if ( ! function_exists( 'filter_block_pattern_response' ) ) { + /** + * Add the `block_types` value into the API response. + * + * @since 6.2.0 Added 'block_types' property. + * + * @param WP_REST_Response $response The response object. + * @param object $raw_pattern The unprepared pattern. + */ + function filter_block_pattern_response( $response, $raw_pattern ) { + $data = $response->get_data(); + $data['block_types'] = array_map( 'sanitize_text_field', $raw_pattern->meta->wpop_block_types ); + $response->set_data( $data ); + return $response; + } } add_filter( 'rest_prepare_block_pattern', 'filter_block_pattern_response', 10, 2 ); diff --git a/lib/compat/wordpress-6.3/class-gutenberg-rest-global-styles-revisions-controller-6-3.php b/lib/compat/wordpress-6.3/class-gutenberg-rest-global-styles-revisions-controller-6-3.php index c45ce23c5d4ea7..e9c73a717d3d0d 100644 --- a/lib/compat/wordpress-6.3/class-gutenberg-rest-global-styles-revisions-controller-6-3.php +++ b/lib/compat/wordpress-6.3/class-gutenberg-rest-global-styles-revisions-controller-6-3.php @@ -21,7 +21,7 @@ class Gutenberg_REST_Global_Styles_Revisions_Controller_6_3 extends WP_REST_Cont * @since 6.3.0 * @var string */ - private $parent_post_type; + protected $parent_post_type; /** * The base of the parent controller's route. @@ -102,7 +102,7 @@ public function get_collection_params() { * @param string $raw_json Encoded JSON from global styles custom post content. * @return Array|WP_Error */ - private function get_decoded_global_styles_json( $raw_json ) { + protected function get_decoded_global_styles_json( $raw_json ) { $decoded_json = json_decode( $raw_json, true ); if ( is_array( $decoded_json ) && isset( $decoded_json['isGlobalStylesUserThemeJSON'] ) && true === $decoded_json['isGlobalStylesUserThemeJSON'] ) { diff --git a/lib/compat/wordpress-6.3/footnotes.php b/lib/compat/wordpress-6.3/footnotes.php index 45f4c74b05e37b..6225b280e1b6c2 100644 --- a/lib/compat/wordpress-6.3/footnotes.php +++ b/lib/compat/wordpress-6.3/footnotes.php @@ -18,8 +18,15 @@ function gutenberg_trim_footnotes( $content ) { return $content; } - static $footnote_pattern = '_\s*\d+\s*_'; - return preg_replace( $footnote_pattern, '', $content ); + if ( ! str_contains( $content, 'data-fn=' ) ) { + return $content; + } + + return preg_replace( + '_\s*\d+\s*_', + '', + $content + ); } add_filter( 'the_content', 'gutenberg_trim_footnotes' ); diff --git a/lib/compat/wordpress-6.3/kses.php b/lib/compat/wordpress-6.3/kses.php index 23eee580f831ab..b0b7356d2dac1c 100644 --- a/lib/compat/wordpress-6.3/kses.php +++ b/lib/compat/wordpress-6.3/kses.php @@ -7,21 +7,23 @@ * @package gutenberg */ -/** - * Mark CSS safe if it contains grid functions - * - * This function should not be backported to core. - * - * @param bool $allow_css Whether the CSS is allowed. - * @param string $css_test_string The CSS to test. - */ -function allow_grid_functions_in_styles( $allow_css, $css_test_string ) { - if ( preg_match( - '/^grid-template-columns:\s*repeat\([0-9,a-z-\s\(\)]*\)$/', - $css_test_string - ) ) { - return true; +if ( ! function_exists( 'allow_grid_functions_in_styles' ) ) { + /** + * Mark CSS safe if it contains grid functions + * + * This function should not be backported to core. + * + * @param bool $allow_css Whether the CSS is allowed. + * @param string $css_test_string The CSS to test. + */ + function allow_grid_functions_in_styles( $allow_css, $css_test_string ) { + if ( preg_match( + '/^grid-template-columns:\s*repeat\([0-9,a-z-\s\(\)]*\)$/', + $css_test_string + ) ) { + return true; + } + return $allow_css; } - return $allow_css; } add_filter( 'safecss_filter_attr_allow_css', 'allow_grid_functions_in_styles', 10, 2 ); diff --git a/lib/compat/wordpress-6.3/rest-api.php b/lib/compat/wordpress-6.3/rest-api.php index 144ad4d50c83f1..ecb8f52392fef9 100644 --- a/lib/compat/wordpress-6.3/rest-api.php +++ b/lib/compat/wordpress-6.3/rest-api.php @@ -52,30 +52,13 @@ function gutenberg_update_templates_template_parts_rest_controller( $args, $post } add_filter( 'register_post_type_args', 'gutenberg_update_templates_template_parts_rest_controller', 10, 2 ); -/** - * Registers the Global Styles Revisions REST API routes. - */ -function gutenberg_register_global_styles_revisions_endpoints() { - $global_styles_revisions_controller = new Gutenberg_REST_Global_Styles_Revisions_Controller_6_3(); - $global_styles_revisions_controller->register_routes(); -} -add_action( 'rest_api_init', 'gutenberg_register_global_styles_revisions_endpoints' ); - -/** - * Registers the Global Styles REST API routes. - */ -function gutenberg_register_global_styles_endpoints() { - $global_styles_controller = new Gutenberg_REST_Global_Styles_Controller_6_3(); - $global_styles_controller->register_routes(); -} -add_action( 'rest_api_init', 'gutenberg_register_global_styles_endpoints' ); - -/** - * Add the `modified` value to the `wp_template` schema. - * - * @since 6.3.0 Added 'modified' property and response value. - */ -function add_modified_wp_template_schema() { +if ( ! function_exists( 'add_modified_wp_template_schema' ) ) { + /** + * Add the `modified` value to the `wp_template` schema. + * + * @since 6.3.0 Added 'modified' property and response value. + */ + function add_modified_wp_template_schema() { register_rest_field( array( 'wp_template', 'wp_template_part' ), 'modified', @@ -98,6 +81,7 @@ function add_modified_wp_template_schema() { }, ) ); + } } add_filter( 'rest_api_init', 'add_modified_wp_template_schema' ); diff --git a/lib/compat/wordpress-6.3/theme-previews.php b/lib/compat/wordpress-6.3/theme-previews.php index 26153d74878b58..e885d389b94fe0 100644 --- a/lib/compat/wordpress-6.3/theme-previews.php +++ b/lib/compat/wordpress-6.3/theme-previews.php @@ -51,14 +51,15 @@ function gutenberg_attach_theme_preview_middleware() { ); } -/** - * Temporary function to add a live preview button to block themes. - * Remove when https://core.trac.wordpress.org/ticket/58190 lands. - */ -function add_live_preview_button() { - global $pagenow; - if ( 'themes.php' === $pagenow ) { - ?> +if ( ! function_exists( 'add_live_preview_button' ) ) { + /** + * Temporary function to add a live preview button to block themes. + * Remove when https://core.trac.wordpress.org/ticket/58190 lands. + */ + function add_live_preview_button() { + global $pagenow; + if ( 'themes.php' === $pagenow ) { + ?> - +if ( ! function_exists( 'block_theme_activate_nonce' ) ) { + /** + * Adds a nonce for the theme activation link. + */ + function block_theme_activate_nonce() { + $nonce_handle = 'switch-theme_' . gutenberg_get_theme_preview_path(); + ?> - schema ) { + return $this->add_additional_fields_schema( $this->schema ); + } + + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'ID of global styles config.', 'default' ), + 'type' => 'string', + 'context' => array( 'embed', 'view', 'edit' ), + 'readonly' => true, + ), + 'styles' => array( + 'description' => __( 'Global styles.', 'default' ), + 'type' => array( 'object' ), + 'context' => array( 'view', 'edit' ), + ), + 'settings' => array( + 'description' => __( 'Global settings.', 'default' ), + 'type' => array( 'object' ), + 'context' => array( 'view', 'edit' ), + ), + 'behaviors' => array( + 'description' => __( 'Global behaviors.', 'default' ), + 'type' => array( 'object' ), + 'context' => array( 'view', 'edit' ), + ), + 'title' => array( + 'description' => __( 'Title of the global styles variation.', 'default' ), + 'type' => array( 'object', 'string' ), + 'default' => '', + 'context' => array( 'embed', 'view', 'edit' ), + 'properties' => array( + 'raw' => array( + 'description' => __( 'Title for the global styles variation, as it exists in the database.', 'default' ), + 'type' => 'string', + 'context' => array( 'view', 'edit', 'embed' ), + ), + 'rendered' => array( + 'description' => __( 'HTML title for the post, transformed for display.', 'default' ), + 'type' => 'string', + 'context' => array( 'view', 'edit', 'embed' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + $this->schema = $schema; + + return $this->add_additional_fields_schema( $this->schema ); + } + + /** + * Prepare a global styles config output for response. + * + * @since 5.9.0 + * @since 6.2 Handling of style.css was added to WP_Theme_JSON. + * + * @param WP_Post $post Global Styles post object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response Response object. + */ + public function prepare_item_for_response( $post, $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + $raw_config = json_decode( $post->post_content, true ); + $is_global_styles_user_theme_json = isset( $raw_config['isGlobalStylesUserThemeJSON'] ) && true === $raw_config['isGlobalStylesUserThemeJSON']; + $config = array(); + if ( $is_global_styles_user_theme_json ) { + $config = ( new WP_Theme_JSON_Gutenberg( $raw_config, 'custom' ) )->get_raw_data(); + } + + // Base fields for every post. + $data = array(); + $fields = $this->get_fields_for_response( $request ); + + if ( rest_is_field_included( 'id', $fields ) ) { + $data['id'] = $post->ID; + } + + if ( rest_is_field_included( 'title', $fields ) ) { + $data['title'] = array(); + } + if ( rest_is_field_included( 'title.raw', $fields ) ) { + $data['title']['raw'] = $post->post_title; + } + if ( rest_is_field_included( 'title.rendered', $fields ) ) { + add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); + + $data['title']['rendered'] = get_the_title( $post->ID ); + + remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); + } + + if ( rest_is_field_included( 'settings', $fields ) ) { + $data['settings'] = ! empty( $config['settings'] ) && $is_global_styles_user_theme_json ? $config['settings'] : new stdClass(); + } + + if ( rest_is_field_included( 'styles', $fields ) ) { + $data['styles'] = ! empty( $config['styles'] ) && $is_global_styles_user_theme_json ? $config['styles'] : new stdClass(); + } + + if ( rest_is_field_included( 'behaviors', $fields ) ) { + $data['behaviors'] = ! empty( $config['behaviors'] ) && $is_global_styles_user_theme_json ? $config['behaviors'] : new stdClass(); + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { + $links = $this->prepare_links( $post->ID ); + $response->add_links( $links ); + if ( ! empty( $links['self']['href'] ) ) { + $actions = $this->get_available_actions(); + $self = $links['self']['href']; + foreach ( $actions as $rel ) { + $response->add_link( $rel, $self ); + } + } + } + + return $response; + } + + /** + * Returns the given theme global styles config. + * Duplicated from core. + * The only change is that we call WP_Theme_JSON_Resolver_Gutenberg::get_merged_data( 'theme' ) instead of WP_Theme_JSON_Resolver::get_merged_data( 'theme' ). + * + * @since 6.2.0 + * + * @param WP_REST_Request $request The request instance. + * @return WP_REST_Response|WP_Error + */ + public function get_theme_item( $request ) { + if ( get_stylesheet() !== $request['stylesheet'] ) { + // This endpoint only supports the active theme for now. + return new WP_Error( + 'rest_theme_not_found', + __( 'Theme not found.', 'default' ), + array( 'status' => 404 ) + ); + } + + $theme = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data( 'theme' ); + $data = array(); + $fields = $this->get_fields_for_response( $request ); + + if ( rest_is_field_included( 'settings', $fields ) ) { + $data['settings'] = $theme->get_settings(); + } + + if ( rest_is_field_included( 'styles', $fields ) ) { + $raw_data = $theme->get_raw_data(); + $data['styles'] = isset( $raw_data['styles'] ) ? $raw_data['styles'] : array(); + } + + if ( rest_is_field_included( 'behaviors', $fields ) ) { + $raw_data = $theme->get_raw_data(); + $data['behaviors'] = isset( $raw_data['behaviors'] ) ? $raw_data['behaviors'] : array(); + } + + $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 ); + + if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '%s/%s/themes/%s', $this->namespace, $this->rest_base, $request['stylesheet'] ) ), + ), + ); + $response->add_links( $links ); + } + + return $response; + } + + /** + * Prepares a single global styles config for update. + * + * @since 5.9.0 + * @since 6.2.0 Added validation of styles.css property. + * + * @param WP_REST_Request $request Request object. + * @return stdClass Changes to pass to wp_update_post. + */ + protected function prepare_item_for_database( $request ) { + $changes = new stdClass(); + $changes->ID = $request['id']; + $post = get_post( $request['id'] ); + $existing_config = array(); + if ( $post ) { + $existing_config = json_decode( $post->post_content, true ); + $json_decoding_error = json_last_error(); + if ( JSON_ERROR_NONE !== $json_decoding_error || ! isset( $existing_config['isGlobalStylesUserThemeJSON'] ) || + ! $existing_config['isGlobalStylesUserThemeJSON'] ) { + $existing_config = array(); + } + } + if ( isset( $request['styles'] ) || isset( $request['settings'] ) || isset( $request['behaviors'] ) ) { + $config = array(); + if ( isset( $request['styles'] ) ) { + $config['styles'] = $request['styles']; + if ( isset( $request['styles']['css'] ) ) { + $validate_custom_css = $this->validate_custom_css( $request['styles']['css'] ); + if ( is_wp_error( $validate_custom_css ) ) { + return $validate_custom_css; + } + } + } elseif ( isset( $existing_config['styles'] ) ) { + $config['styles'] = $existing_config['styles']; + } + if ( isset( $request['settings'] ) ) { + $config['settings'] = $request['settings']; + } elseif ( isset( $existing_config['settings'] ) ) { + $config['settings'] = $existing_config['settings']; + } + if ( isset( $request['behaviors'] ) ) { + $config['behaviors'] = $request['behaviors']; + } elseif ( isset( $existing_config['behaviors'] ) ) { + $config['behaviors'] = $existing_config['behaviors']; + } + $config['isGlobalStylesUserThemeJSON'] = true; + $config['version'] = WP_Theme_JSON_Gutenberg::LATEST_SCHEMA; + $changes->post_content = wp_json_encode( $config ); + } + // Post title. + if ( isset( $request['title'] ) ) { + if ( is_string( $request['title'] ) ) { + $changes->post_title = $request['title']; + } elseif ( ! empty( $request['title']['raw'] ) ) { + $changes->post_title = $request['title']['raw']; + } + } + return $changes; + } + +} diff --git a/lib/compat/wordpress-6.4/class-gutenberg-rest-global-styles-revisions-controller-6-4.php b/lib/compat/wordpress-6.4/class-gutenberg-rest-global-styles-revisions-controller-6-4.php new file mode 100644 index 00000000000000..42120b44bdcb62 --- /dev/null +++ b/lib/compat/wordpress-6.4/class-gutenberg-rest-global-styles-revisions-controller-6-4.php @@ -0,0 +1,172 @@ +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(); + + if ( ! empty( $global_styles_config['styles'] ) || ! empty( $global_styles_config['settings'] ) || ! empty( $global_styles_config['behaviors'] ) ) { + $global_styles_config = ( new WP_Theme_JSON_Gutenberg( $global_styles_config, 'custom' ) )->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( 'behaviors', $fields ) ) { + $data['behaviors'] = ! empty( $global_styles_config['behaviors'] ) ? $global_styles_config['behaviors'] : 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 ); + + return rest_ensure_response( $data ); + } + + /** + * Retrieves the revision's schema, conforming to JSON Schema. + * + * @since 6.3.0 + * + * @return array Item schema data. + */ + public function get_item_schema() { + if ( $this->schema ) { + return $this->add_additional_fields_schema( $this->schema ); + } + + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => "{$this->parent_post_type}-revision", + 'type' => 'object', + // Base properties for every Revision. + 'properties' => array( + + /* + * Adds settings and styles from the WP_REST_Revisions_Controller item fields. + * Leaves out GUID as global styles shouldn't be accessible via URL. + */ + 'author' => array( + 'description' => __( 'The ID for the author of the revision.', 'gutenberg' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit', 'embed' ), + ), + 'date' => array( + 'description' => __( "The date the revision was published, in the site's timezone.", 'gutenberg' ), + 'type' => 'string', + 'format' => 'date-time', + 'context' => array( 'view', 'edit', 'embed' ), + ), + 'date_gmt' => array( + 'description' => __( 'The date the revision was published, as GMT.', 'gutenberg' ), + 'type' => 'string', + 'format' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'id' => array( + 'description' => __( 'Unique identifier for the revision.', 'gutenberg' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit', 'embed' ), + ), + 'modified' => array( + 'description' => __( "The date the revision was last modified, in the site's timezone.", 'gutenberg' ), + 'type' => 'string', + 'format' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'modified_gmt' => array( + 'description' => __( 'The date the revision was last modified, as GMT.', 'gutenberg' ), + 'type' => 'string', + 'format' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'parent' => array( + 'description' => __( 'The ID for the parent of the revision.', 'gutenberg' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit', 'embed' ), + ), + + // Adds settings and styles from the WP_REST_Global_Styles_Controller parent schema. + 'styles' => array( + 'description' => __( 'Global styles.', 'gutenberg' ), + 'type' => array( 'object' ), + 'context' => array( 'view', 'edit' ), + ), + 'settings' => array( + 'description' => __( 'Global settings.', 'gutenberg' ), + 'type' => array( 'object' ), + 'context' => array( 'view', 'edit' ), + ), + 'behaviors' => array( + 'description' => __( 'Global behaviors.', 'gutenberg' ), + 'type' => array( 'object' ), + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + $this->schema = $schema; + + return $this->add_additional_fields_schema( $this->schema ); + } +} diff --git a/lib/compat/wordpress-6.4/rest-api.php b/lib/compat/wordpress-6.4/rest-api.php new file mode 100644 index 00000000000000..53979f832c09a6 --- /dev/null +++ b/lib/compat/wordpress-6.4/rest-api.php @@ -0,0 +1,29 @@ +register_routes(); +} +add_action( 'rest_api_init', 'gutenberg_register_global_styles_revisions_endpoints' ); + +/** + * Registers the Global Styles REST API routes. + */ +function gutenberg_register_global_styles_endpoints() { + $global_styles_controller = new Gutenberg_REST_Global_Styles_Controller_6_4(); + $global_styles_controller->register_routes(); +} +add_action( 'rest_api_init', 'gutenberg_register_global_styles_endpoints' ); diff --git a/lib/experimental/behaviors.php b/lib/experimental/behaviors.php deleted file mode 100644 index 62e7be7a252d49..00000000000000 --- a/lib/experimental/behaviors.php +++ /dev/null @@ -1,20 +0,0 @@ -get_data(); - if ( array_key_exists( 'behaviors', $theme_data ) ) { - $settings['behaviors'] = $theme_data['behaviors']; - } - return $settings; - }, - PHP_INT_MAX -); diff --git a/lib/experimental/class--wp-editors.php b/lib/experimental/class--wp-editors.php index bc49ea80a99421..41062db75c0700 100644 --- a/lib/experimental/class--wp-editors.php +++ b/lib/experimental/class--wp-editors.php @@ -8,6 +8,10 @@ // phpcs:disable PEAR.NamingConventions.ValidClassName.StartWithCapital +if ( class_exists( '_WP_Editors' ) ) { + return; +} + /** * Placeholder class. * Used to disable loading of TinyMCE assets. diff --git a/lib/experimental/class-wp-rest-block-editor-settings-controller.php b/lib/experimental/class-wp-rest-block-editor-settings-controller.php index 52dd328fc7f2db..510ae573e3de8e 100644 --- a/lib/experimental/class-wp-rest-block-editor-settings-controller.php +++ b/lib/experimental/class-wp-rest-block-editor-settings-controller.php @@ -6,6 +6,10 @@ * @subpackage REST_API */ +if ( class_exists( 'WP_REST_Block_Editor_Settings_Controller' ) ) { + return; +} + /** * Core class used to retrieve the block editor settings via the REST API. * diff --git a/lib/experimental/class-wp-rest-customizer-nonces.php b/lib/experimental/class-wp-rest-customizer-nonces.php index 4fc35209ae99de..15c587295557d8 100644 --- a/lib/experimental/class-wp-rest-customizer-nonces.php +++ b/lib/experimental/class-wp-rest-customizer-nonces.php @@ -5,6 +5,10 @@ * @package gutenberg */ +if ( class_exists( 'WP_Rest_Customizer_Nonces' ) ) { + return; +} + /** * Class that returns the customizer "save" nonce that's required for the * batch save operation using the customizer API endpoint. diff --git a/lib/experimental/fonts/bc-layer/class-gutenberg-fonts-api-bc-layer.php b/lib/experimental/fonts/bc-layer/class-gutenberg-fonts-api-bc-layer.php new file mode 100644 index 00000000000000..7cf041148eedd0 --- /dev/null +++ b/lib/experimental/fonts/bc-layer/class-gutenberg-fonts-api-bc-layer.php @@ -0,0 +1,49 @@ +` element for wrapping the `@font-face` CSS. + * + * @since X.X.X + * @deprecated 16.3.0 Get style element is not supported. + * + * @return string Empty string. + */ + protected function get_style_element() { + _deprecated_function( __METHOD__, 'Gutenberg 16.3.0' ); + return ''; + } +} diff --git a/lib/experimental/fonts/bc-layer/class-wp-fonts-resolver.php b/lib/experimental/fonts/bc-layer/class-wp-fonts-resolver.php new file mode 100644 index 00000000000000..c2702348b95232 --- /dev/null +++ b/lib/experimental/fonts/bc-layer/class-wp-fonts-resolver.php @@ -0,0 +1,64 @@ +get_registered_font_families(). + * @deprecated 16.3.0 Register is not supported. + * + * @return array Empty array. + */ + public function get_registered_font_families() { + _deprecated_function( __METHOD__, 'Gutenberg 15.8.0' ); + return array(); + } + + /** + * Gets the list of registered fonts. + * + * @since 6.0.0 + * @deprecated 14.9.1 Use wp_fonts()->get_registered(). + * @deprecated 16.3.0 Register is not supported. + * + * @return array Empty array. + */ + public function get_registered_webfonts() { + _deprecated_function( __METHOD__, 'Gutenberg 14.9.1' ); + + return array(); + } + + /** + * Gets the list of enqueued fonts. + * + * @since 6.0.0 + * @deprecated 14.9.1 Use wp_fonts()->get_enqueued(). + * @deprecated 16.3.0 Enqueue is not supported. + * + * @return array Empty array. + */ + public function get_enqueued_webfonts() { + _deprecated_function( __METHOD__, 'Gutenberg 14.9.1' ); + return array(); + } + + /** + * Gets the list of all fonts. + * + * @since X.X.X + * @deprecated GB 14.9.1 Use wp_fonts()->get_registered(). + * @deprecated 16.3.0 This method is not supported. + * + * @return array[] + */ + public function get_all_webfonts() { + _deprecated_function( __METHOD__, 'Gutenberg 14.9.1', 'wp_fonts()->get_registered()' ); + return array(); + } + + /** + * Registers a webfont. + * + * @since 6.0.0 + * @deprecated GB 14.9.1 Use wp_register_fonts(). + * @deprecated 16.3.0 Register is not supported. + * + * @return bool False. + */ + public function register_webfont() { + _deprecated_function( __METHOD__, 'GB 14.9.1', 'wp_register_fonts()' ); + return false; + } + + /** + * Enqueue a font-family that has been already registered. + * + * @since XX.X + * @deprecated 14.9.1 Use wp_enqueue_fonts(). + * @deprecated 16.3.0 Register is not supported. + * + * @return bool False. + */ + public function enqueue_webfont() { + _deprecated_function( __METHOD__, 'Gutenberg 14.9.1' ); + return false; + } +} diff --git a/lib/experimental/fonts/bc-layer/webfonts-deprecations.php b/lib/experimental/fonts/bc-layer/webfonts-deprecations.php new file mode 100644 index 00000000000000..4de2e6221d50bf --- /dev/null +++ b/lib/experimental/fonts/bc-layer/webfonts-deprecations.php @@ -0,0 +1,291 @@ +get_providers(). + * @deprecated 16.3.0 Providers are not supported. + * + * @return array Empty array. + */ + function wp_get_webfont_providers() { + _deprecated_function( __FUNCTION__, '14.9.1' ); + + return array(); + } +} + +if ( ! function_exists( 'wp_register_webfont_provider' ) ) { + /** + * Registers a custom font service provider. + * + * @since X.X.X + * @deprecated 15.1 Use wp_register_font_provider() instead. + * @deprecated 16.3.0 Providers are not supported. + * + * @return bool False. + */ + function wp_register_webfont_provider() { + _deprecated_function( __FUNCTION__, 'GB 15.1', 'wp_register_font_provider' ); + return false; + } +} + +if ( ! function_exists( 'wp_print_webfonts' ) ) { + /** + * Invokes each provider to process and print its styles. + * + * @since 14.9.1 + * @deprecated 15.1 Use wp_print_fonts() instead. + * @deprecated 16.3.0 Webfonts API is not supported. + * + * @return array Empty array. + */ + function wp_print_webfonts() { + _deprecated_function( __FUNCTION__, 'Gutenberg 15.1', 'wp_print_font_faces' ); + return array(); + } +} + +if ( ! function_exists( 'wp_fonts' ) ) { + /** + * Initialize $wp_fonts if it has not been set. + * + * @since X.X.X + * @deprecated 16.3.0 Use Fonts Library and Font Face. Fonts API is not supported. + * + * @global WP_Fonts $wp_fonts + * + * @return WP_Fonts WP_Fonts instance. + */ + function wp_fonts() { + _deprecated_function( __FUNCTION__, 'Gutenberg 16.3' ); + + global $wp_fonts; + + if ( ! ( $wp_fonts instanceof WP_Fonts ) ) { + $wp_fonts = new WP_Fonts(); + } + + return $wp_fonts; + } +} + +if ( ! function_exists( 'wp_register_fonts' ) ) { + /** + * Registers one or more font-families and each of their variations. + * + * @since X.X.X + * @deprecated 16.3.0 Register is not supported. + * + * @return array Empty array. + */ + function wp_register_fonts() { + _deprecated_function( __FUNCTION__, 'Gutenberg 16.3' ); + return array(); + } +} + +if ( ! function_exists( 'wp_enqueue_fonts' ) ) { + /** + * Enqueues one or more font family and all of its variations. + * + * @since X.X.X + * @deprecated 16.3.0 Enqueue is not supported. + */ + function wp_enqueue_fonts() { + _deprecated_function( __FUNCTION__, 'Gutenberg 16.3' ); + } +} + +if ( ! function_exists( 'wp_enqueue_font_variations' ) ) { + /** + * Enqueues a specific set of font variations. + * + * @since X.X.X + * @deprecated 16.3.0 Enqueue is not supported. + */ + function wp_enqueue_font_variations() { + _deprecated_function( __FUNCTION__, 'Gutenberg 16.3' ); + } +} + +if ( ! function_exists( 'wp_deregister_font_family' ) ) { + /** + * Deregisters a font family and all of its registered variations. + * + * @since X.X.X + * @deprecated 16.3.0 Deregister is not supported. + */ + function wp_deregister_font_family() { + _deprecated_function( __FUNCTION__, 'Gutenberg 16.3' ); + } +} + +if ( ! function_exists( 'wp_deregister_font_variation' ) ) { + /** + * Deregisters a font variation. + * + * @since X.X.X + * @deprecated 16.3.0 Deregister is not supported. + */ + function wp_deregister_font_variation() { + _deprecated_function( __FUNCTION__, 'Gutenberg 16.3' ); + } +} + +if ( ! function_exists( 'wp_register_font_provider' ) ) { + /** + * Registers a custom font service provider. + * + * @since X.X.X + * @deprecated 16.3.0 Providers are not supported. + * + * @return bool False. + */ + function wp_register_font_provider() { + _deprecated_function( __FUNCTION__, 'Gutenberg 16.3' ); + return false; + } +} + +if ( ! function_exists( 'wp_print_fonts' ) ) { + /** + * Invokes each provider to process and print its styles. + * + * @since X.X.X + * @deprecated 16.3.0 For classic themes, use wp_print_font_faces(). For all other sites, + * Font Face will automatically print all fonts in theme.json merged data layer, + * including in theme and user activated fonts from the Fonts Library. + * + * @return array Empty array. + */ + function wp_print_fonts() { + _deprecated_function( __FUNCTION__, 'Gutenberg 16.3', 'wp_print_font_faces' ); + return array(); + } +} diff --git a/lib/experimental/interactivity-api/class-wp-directive-context.php b/lib/experimental/interactivity-api/class-wp-directive-context.php index 7186922d137a89..6e28db83509f52 100644 --- a/lib/experimental/interactivity-api/class-wp-directive-context.php +++ b/lib/experimental/interactivity-api/class-wp-directive-context.php @@ -6,6 +6,10 @@ * @subpackage Interactivity API */ +if ( class_exists( 'WP_Directive_Context' ) ) { + return; +} + /** * This is a data structure to hold the current context. * diff --git a/lib/experimental/interactivity-api/class-wp-directive-processor.php b/lib/experimental/interactivity-api/class-wp-directive-processor.php index 69c72a222fdc71..e57000b3663ce4 100644 --- a/lib/experimental/interactivity-api/class-wp-directive-processor.php +++ b/lib/experimental/interactivity-api/class-wp-directive-processor.php @@ -6,6 +6,10 @@ * @subpackage Interactivity API */ +if ( class_exists( 'WP_Directive_Processor' ) ) { + return; +} + /** * This processor is built on top of the HTML Tag Processor and augments its * capabilities to process the Interactivity API directives. diff --git a/lib/experimental/interactivity-api/class-wp-interactivity-store.php b/lib/experimental/interactivity-api/class-wp-interactivity-store.php index fe96af4786d3bf..8b43dbb6d9e248 100644 --- a/lib/experimental/interactivity-api/class-wp-interactivity-store.php +++ b/lib/experimental/interactivity-api/class-wp-interactivity-store.php @@ -9,6 +9,10 @@ * @subpackage Interactivity API */ +if ( class_exists( 'WP_Interactivity_Store' ) ) { + return; +} + /** * Manages the initial state of the Interactivity API store in the server and * its serialization so it can be restored in the browser upon hydration. diff --git a/lib/experimental/interactivity-api/store.php b/lib/experimental/interactivity-api/store.php index 5e793514e54c90..05c8b35f780d4f 100644 --- a/lib/experimental/interactivity-api/store.php +++ b/lib/experimental/interactivity-api/store.php @@ -6,18 +6,20 @@ * @subpackage Interactivity API */ -/** - * Merge data with the existing store. - * - * @param array $data Data that will be merged with the existing store. - * - * @return $data The current store data. - */ -function wp_store( $data = null ) { - if ( $data ) { - WP_Interactivity_Store::merge_data( $data ); +if ( ! function_exists( 'wp_store' ) ) { + /** + * Merge data with the existing store. + * + * @param array $data Data that will be merged with the existing store. + * + * @return $data The current store data. + */ + function wp_store( $data = null ) { + if ( $data ) { + WP_Interactivity_Store::merge_data( $data ); + } + return WP_Interactivity_Store::get_data(); } - return WP_Interactivity_Store::get_data(); } /** diff --git a/lib/experimental/kses.php b/lib/experimental/kses.php index 115fa3a7d2284c..6fa8ca641772a2 100644 --- a/lib/experimental/kses.php +++ b/lib/experimental/kses.php @@ -66,24 +66,25 @@ function gutenberg_override_core_kses_init_filters() { add_action( 'init', 'gutenberg_override_core_kses_init_filters', 20 ); add_action( 'set_current_user', 'gutenberg_override_core_kses_init_filters' ); -/** - * See https://github.com/WordPress/wordpress-develop/pull/4108 - * - * Mark CSS safe if it contains a "filter: url('#wp-duotone-...')" rule. - * - * This function should not be backported to core. - * - * @param bool $allow_css Whether the CSS is allowed. - * @param string $css_test_string The CSS to test. - */ -function allow_filter_in_styles( $allow_css, $css_test_string ) { - if ( preg_match( - "/^filter:\s*url\((['\"]?)#wp-duotone-[-a-zA-Z0-9]+\\1\)(\s+!important)?$/", - $css_test_string - ) ) { - return true; +if ( ! function_exists( 'allow_filter_in_styles' ) ) { + /** + * See https://github.com/WordPress/wordpress-develop/pull/4108 + * + * Mark CSS safe if it contains a "filter: url('#wp-duotone-...')" rule. + * + * This function should not be backported to core. + * + * @param bool $allow_css Whether the CSS is allowed. + * @param string $css_test_string The CSS to test. + */ + function allow_filter_in_styles( $allow_css, $css_test_string ) { + if ( preg_match( + "/^filter:\s*url\((['\"]?)#wp-duotone-[-a-zA-Z0-9]+\\1\)(\s+!important)?$/", + $css_test_string + ) ) { + return true; + } + return $allow_css; } - return $allow_css; } - add_filter( 'safecss_filter_attr_allow_css', 'allow_filter_in_styles', 10, 2 ); diff --git a/lib/experimental/rest-api.php b/lib/experimental/rest-api.php index 2fc7a7af576f82..7c6a9bf74d7395 100644 --- a/lib/experimental/rest-api.php +++ b/lib/experimental/rest-api.php @@ -102,23 +102,24 @@ function gutenberg_auto_draft_get_sample_permalink( $permalink, $id, $title, $na } add_filter( 'get_sample_permalink', 'gutenberg_auto_draft_get_sample_permalink', 10, 5 ); -/** - * Hook in to the template and template part post types and decorate - * the rest endpoint with the revision count. - * - * When merging to core, this can be removed once Gutenberg_REST_Template_Revision_Count is - * merged with WP_REST_Template_Controller. - * - * @param array $args Current registered post type args. - * @param string $post_type Name of post type. - * - * @return array - */ -function wp_api_template_revision_args( $args, $post_type ) { - if ( 'wp_template' === $post_type || 'wp_template_part' === $post_type ) { - $args['rest_controller_class'] = 'Gutenberg_REST_Template_Revision_Count'; +if ( ! function_exists( 'wp_api_template_revision_args' ) ) { + /** + * Hook in to the template and template part post types and decorate + * the rest endpoint with the revision count. + * + * When merging to core, this can be removed once Gutenberg_REST_Template_Revision_Count is + * merged with WP_REST_Template_Controller. + * + * @param array $args Current registered post type args. + * @param string $post_type Name of post type. + * + * @return array + */ + function wp_api_template_revision_args( $args, $post_type ) { + if ( 'wp_template' === $post_type || 'wp_template_part' === $post_type ) { + $args['rest_controller_class'] = 'Gutenberg_REST_Template_Revision_Count'; + } + return $args; } - - return $args; } add_filter( 'register_post_type_args', 'wp_api_template_revision_args', 10, 2 ); diff --git a/lib/experiments-page.php b/lib/experiments-page.php index de1d3dbce71a14..ea298784aec0c9 100644 --- a/lib/experiments-page.php +++ b/lib/experiments-page.php @@ -5,26 +5,28 @@ * @package gutenberg */ -/** - * The main entry point for the Gutenberg experiments page. - * - * @since 6.3.0 - */ -function the_gutenberg_experiments() { - ?> -
-

- -
- - - -
-
- +
+

+ +
+ + + +
+
+ + ) + ); +} + +export default BlockOutline; diff --git a/packages/block-editor/src/components/block-list/block.native.js b/packages/block-editor/src/components/block-list/block.native.js index 4f1e335f152717..405a883ed3b231 100644 --- a/packages/block-editor/src/components/block-list/block.native.js +++ b/packages/block-editor/src/components/block-list/block.native.js @@ -35,6 +35,7 @@ import { compose, ifCondition, pure } from '@wordpress/compose'; import BlockEdit from '../block-edit'; import BlockDraggable from '../block-draggable'; import BlockInvalidWarning from './block-invalid-warning'; +import BlockOutline from './block-outline'; import { store as blockEditorStore } from '../../store'; import { useLayout } from './layout'; import useSetting from '../use-setting'; @@ -59,15 +60,19 @@ function getWrapperProps( value, getWrapperPropsFunction ) { function BlockWrapper( { accessibilityLabel, + blockCategory, children, clientId, draggingClientId, draggingEnabled, + hasInnerBlocks, isDescendentBlockSelected, + isRootList, isSelected, isTouchable, marginHorizontal, marginVertical, + name, onFocus, } ) { const blockWrapperStyles = { flex: 1 }; @@ -89,6 +94,13 @@ function BlockWrapper( { onPress={ onFocus } style={ blockWrapperStyle } > + 0; + const blockHasInnerBlocks = getBlockCount( clientId ) > 0; // For blocks with inner blocks, we only enable the dragging in the nested // blocks if any of them are selected. This way we prevent the long-press // gesture from being disabled for elements within the block UI. const isDraggingEnabled = - ! hasInnerBlocks || isSelected || ! descendentBlockSelected; + ! blockHasInnerBlocks || + isSelected || + ! descendentBlockSelected; // Dragging nested blocks is not supported yet. For this reason, the block to be dragged // will be the top in the hierarchy. const currentDraggingClientId = @@ -179,9 +196,11 @@ function BlockListBlock( { return { baseGlobalStyles: globalStylesBaseStyles, + blockCategory: currentBlockCategory, blockType: currentBlockType, draggingClientId: currentDraggingClientId, draggingEnabled: isDraggingEnabled, + hasInnerBlocks: blockHasInnerBlocks, isDescendantOfParentSelected: descendantOfParentSelected, isDescendentBlockSelected: descendentBlockSelected, isParentSelected: parentSelected, @@ -279,16 +298,20 @@ function BlockListBlock( { return ( { () => diff --git a/packages/block-editor/src/components/block-list/block.native.scss b/packages/block-editor/src/components/block-list/block.native.scss index 654bc4861a5d1b..547a6129659a28 100644 --- a/packages/block-editor/src/components/block-list/block.native.scss +++ b/packages/block-editor/src/components/block-list/block.native.scss @@ -2,6 +2,14 @@ flex: 1 1 auto; } +.solidBorderColor { + border-color: $blue-40; +} + +.solidBorderColorDark { + border-color: $blue-50; +} + .dimmed { opacity: $dimmed-opacity; } @@ -25,6 +33,30 @@ min-height: 50px; } +.solidBorder { + position: absolute; + top: -6px; + bottom: -6px; + left: -6px; + right: -6px; + border-width: 2px; + border-radius: 2px; + border-style: solid; + z-index: 1; +} + +.solidBorderCompact { + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +.solidBorderTextContent { + left: 0; + right: 0; +} + .fullWidthPadding { padding: $block-selected-to-content; } diff --git a/packages/block-editor/src/components/block-settings/button.native.js b/packages/block-editor/src/components/block-settings/button.native.js index 9fa1a037494294..40c16858839dd4 100644 --- a/packages/block-editor/src/components/block-settings/button.native.js +++ b/packages/block-editor/src/components/block-settings/button.native.js @@ -1,7 +1,11 @@ /** * WordPress dependencies */ -import { createSlotFill, ToolbarButton } from '@wordpress/components'; +import { + createSlotFill, + ToolbarButton, + ToolbarGroup, +} from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { withDispatch } from '@wordpress/data'; import { cog } from '@wordpress/icons'; @@ -9,11 +13,13 @@ import { cog } from '@wordpress/icons'; const { Fill, Slot } = createSlotFill( 'SettingsToolbarButton' ); const SettingsButton = ( { openGeneralSidebar } ) => ( - + + + ); const SettingsButtonFill = ( props ) => ( diff --git a/packages/block-editor/src/components/block-toolbar/index.js b/packages/block-editor/src/components/block-toolbar/index.js index 0f968b8a209a73..b5a90bad024fe3 100644 --- a/packages/block-editor/src/components/block-toolbar/index.js +++ b/packages/block-editor/src/components/block-toolbar/index.js @@ -35,9 +35,9 @@ import __unstableBlockNameContext from './block-name-context'; import { unlock } from '../../lock-unlock'; const BlockToolbar = ( { hideDragHandle } ) => { + const { getSelectedBlockClientId } = useSelect( blockEditorStore ); const { blockClientIds, - blockClientId, blockType, hasFixedToolbar, isDistractionFree, @@ -61,7 +61,6 @@ const BlockToolbar = ( { hideDragHandle } ) => { return { blockClientIds: selectedBlockClientIds, - blockClientId: selectedBlockClientId, blockType: selectedBlockClientId && getBlockType( getBlockName( selectedBlockClientId ) ), @@ -91,7 +90,7 @@ const BlockToolbar = ( { hideDragHandle } ) => { if ( isFocused && isDistractionFree ) { return; } - toggleBlockHighlight( blockClientId, isFocused ); + toggleBlockHighlight( getSelectedBlockClientId(), isFocused ); }, } ); diff --git a/packages/block-editor/src/components/block-toolbar/index.native.js b/packages/block-editor/src/components/block-toolbar/index.native.js index bdf4c778ebc151..ad7d6a16b3b47a 100644 --- a/packages/block-editor/src/components/block-toolbar/index.native.js +++ b/packages/block-editor/src/components/block-toolbar/index.native.js @@ -102,7 +102,6 @@ export default function BlockToolbar( { anchorNodeRef } ) { return fills[ 0 ]; } } - diff --git a/packages/block-editor/src/components/block-tools/style.scss b/packages/block-editor/src/components/block-tools/style.scss index 07e400344bfe10..6ff3bbc721a10a 100644 --- a/packages/block-editor/src/components/block-tools/style.scss +++ b/packages/block-editor/src/components/block-tools/style.scss @@ -322,12 +322,15 @@ // for the block inserter the publish button @include break-large() { &.is-fixed { + width: auto; + } + .is-fullscreen-mode &.is-fixed { + // in full screen mode we need to account for // the combined with of the tools at the right of the header and the margin left // of the toolbar which includes four buttons width: calc(100% - 240px - #{4 * $grid-unit-80}); } } - } /** diff --git a/packages/block-editor/src/components/button-block-appender/styles.native.scss b/packages/block-editor/src/components/button-block-appender/styles.native.scss index 7faa8953a4ef03..7df30b74f8d31f 100644 --- a/packages/block-editor/src/components/button-block-appender/styles.native.scss +++ b/packages/block-editor/src/components/button-block-appender/styles.native.scss @@ -3,8 +3,8 @@ align-items: center; justify-content: center; padding: 9px; - margin-left: 0; - margin-right: 0; + margin-left: $grid-unit; + margin-right: $grid-unit; border-radius: 4px; } diff --git a/packages/block-editor/src/components/global-styles/behaviors-panel.js b/packages/block-editor/src/components/global-styles/behaviors-panel.js new file mode 100644 index 00000000000000..fa8c2305ae0374 --- /dev/null +++ b/packages/block-editor/src/components/global-styles/behaviors-panel.js @@ -0,0 +1,71 @@ +/** + * WordPress dependencies + */ +import { SelectControl } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +export default function ( { onChange, value, behaviors } ) { + const defaultBehaviors = { + default: { + value: 'default', + label: __( 'Default' ), + }, + noBehaviors: { + value: '', + label: __( 'No behaviors' ), + }, + }; + + const behaviorsOptions = Object.entries( behaviors ).map( + ( [ behaviorName ] ) => ( { + value: behaviorName, + // Capitalize the first letter of the behavior name. + label: `${ behaviorName.charAt( 0 ).toUpperCase() }${ behaviorName + .slice( 1 ) + .toLowerCase() }`, + } ) + ); + + const options = [ + ...Object.values( defaultBehaviors ), + ...behaviorsOptions, + ]; + + const animations = [ + { + value: 'zoom', + label: __( 'Zoom' ), + }, + { + value: 'fade', + label: __( 'Fade' ), + }, + ]; + return ( +
+ + { value === 'lightbox' && ( + + ) } +
+ ); +} diff --git a/packages/block-editor/src/components/global-styles/color-panel.js b/packages/block-editor/src/components/global-styles/color-panel.js index 83c80f679c115e..3b55ec36fc91db 100644 --- a/packages/block-editor/src/components/global-styles/color-panel.js +++ b/packages/block-editor/src/components/global-styles/color-panel.js @@ -328,22 +328,6 @@ export default function ColorPanel( { : gradientValue; }; - // Text Color - const showTextPanel = useHasTextPanel( settings ); - const textColor = decodeValue( inheritedValue?.color?.text ); - const userTextColor = decodeValue( value?.color?.text ); - const hasTextColor = () => !! userTextColor; - const setTextColor = ( newColor ) => { - onChange( - setImmutably( - value, - [ 'color', 'text' ], - encodeColorValue( newColor ) - ) - ); - }; - const resetTextColor = () => setTextColor( undefined ); - // BackgroundColor const showBackgroundPanel = useHasBackgroundPanel( settings ); const backgroundColor = decodeValue( inheritedValue?.color?.background ); @@ -424,6 +408,29 @@ export default function ColorPanel( { onChange( newValue ); }; + // Text Color + const showTextPanel = useHasTextPanel( settings ); + const textColor = decodeValue( inheritedValue?.color?.text ); + const userTextColor = decodeValue( value?.color?.text ); + const hasTextColor = () => !! userTextColor; + const setTextColor = ( newColor ) => { + let changedObject = setImmutably( + value, + [ 'color', 'text' ], + encodeColorValue( newColor ) + ); + if ( textColor === linkColor ) { + changedObject = setImmutably( + changedObject, + [ 'elements', 'link', 'color', 'text' ], + encodeColorValue( newColor ) + ); + } + + onChange( changedObject ); + }; + const resetTextColor = () => setTextColor( undefined ); + // Elements const elements = [ { diff --git a/packages/block-editor/src/components/global-styles/dimensions-panel.js b/packages/block-editor/src/components/global-styles/dimensions-panel.js index 99367ea9e21b49..b5eb6175c8c5e4 100644 --- a/packages/block-editor/src/components/global-styles/dimensions-panel.js +++ b/packages/block-editor/src/components/global-styles/dimensions-panel.js @@ -207,18 +207,24 @@ export default function DimensionsPanel( { // in global styles but not in block inspector. includeLayoutControls = false, } ) { + const { dimensions, spacing } = settings; + const decodeValue = ( rawValue ) => { if ( rawValue && typeof rawValue === 'object' ) { return Object.keys( rawValue ).reduce( ( acc, key ) => { acc[ key ] = getValueFromVariable( - { settings }, + { settings: { dimensions, spacing } }, '', rawValue[ key ] ); return acc; }, {} ); } - return getValueFromVariable( { settings }, '', rawValue ); + return getValueFromVariable( + { settings: { dimensions, spacing } }, + '', + rawValue + ); }; const showSpacingPresetsControl = useHasSpacingPresets( settings ); diff --git a/packages/block-editor/src/components/global-styles/hooks.js b/packages/block-editor/src/components/global-styles/hooks.js index 3c8b0167279804..96be5779124d74 100644 --- a/packages/block-editor/src/components/global-styles/hooks.js +++ b/packages/block-editor/src/components/global-styles/hooks.js @@ -8,7 +8,7 @@ import fastDeepEqual from 'fast-deep-equal/es6'; */ import { useContext, useCallback, useMemo } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; -import { store as blocksStore } from '@wordpress/blocks'; +import { store as blocksStore, hasBlockSupport } from '@wordpress/blocks'; import { _x } from '@wordpress/i18n'; /** @@ -19,10 +19,11 @@ import { getValueFromObjectPath, setImmutably } from '../../utils/object'; import { GlobalStylesContext } from './context'; import { unlock } from '../../lock-unlock'; -const EMPTY_CONFIG = { settings: {}, styles: {} }; +const EMPTY_CONFIG = { settings: {}, styles: {}, behaviors: {} }; const VALID_SETTINGS = [ 'appearanceTools', + 'behaviors', 'useRootPaddingAwareAlignments', 'border.color', 'border.radius', @@ -88,7 +89,6 @@ export const useGlobalStylesReset = () => { export function useGlobalSetting( propertyPath, blockName, source = 'all' ) { const { setUserConfig, ...configs } = useContext( GlobalStylesContext ); - const appendedBlockPath = blockName ? '.blocks.' + blockName : ''; const appendedPropertyPath = propertyPath ? '.' + propertyPath : ''; const contextualPath = `settings${ appendedBlockPath }${ appendedPropertyPath }`; @@ -135,7 +135,6 @@ export function useGlobalSetting( propertyPath, blockName, source = 'all' ) { setImmutably( currentConfig, contextualPath.split( '.' ), newValue ) ); }; - return [ settingValue, setSetting ]; } @@ -461,3 +460,112 @@ export function useGradientsPerOrigin( settings ) { shouldDisplayDefaultGradients, ] ); } + +export function __experimentalUseGlobalBehaviors( blockName, source = 'all' ) { + const { + merged: mergedConfig, + base: baseConfig, + user: userConfig, + setUserConfig, + } = useContext( GlobalStylesContext ); + const finalPath = ! blockName + ? `behaviors` + : `behaviors.blocks.${ blockName }`; + + let rawResult, result; + switch ( source ) { + case 'all': + rawResult = getValueFromObjectPath( mergedConfig, finalPath ); + result = getValueFromVariable( mergedConfig, blockName, rawResult ); + break; + case 'user': + rawResult = getValueFromObjectPath( userConfig, finalPath ); + result = getValueFromVariable( mergedConfig, blockName, rawResult ); + break; + case 'base': + rawResult = getValueFromObjectPath( baseConfig, finalPath ); + result = getValueFromVariable( baseConfig, blockName, rawResult ); + break; + default: + throw 'Unsupported source'; + } + + const animation = result?.lightbox?.animation || 'zoom'; + + const setBehavior = ( newValue ) => { + let newBehavior; + // The user saves with Apply Globally option. + if ( typeof newValue === 'object' ) { + newBehavior = newValue; + } else { + switch ( newValue ) { + case 'lightbox': + newBehavior = { + lightbox: { + enabled: true, + animation, + }, + }; + break; + case 'fade': + newBehavior = { + lightbox: { + enabled: true, + animation: 'fade', + }, + }; + break; + case 'zoom': + newBehavior = { + lightbox: { + enabled: true, + animation: 'zoom', + }, + }; + break; + case '': + newBehavior = { + lightbox: { + enabled: false, + animation, + }, + }; + break; + default: + break; + } + } + setUserConfig( ( currentConfig ) => + setImmutably( currentConfig, finalPath.split( '.' ), newBehavior ) + ); + }; + let behavior = ''; + if ( result === undefined ) behavior = 'default'; + if ( result?.lightbox.enabled ) behavior = 'lightbox'; + + return { behavior, inheritedBehaviors: result, setBehavior }; +} + +export function __experimentalUseHasBehaviorsPanel( + settings, + name, + { blockSupportOnly = false } = {} +) { + if ( ! settings?.behaviors || ! window?.__experimentalInteractivityAPI ) { + return false; + } + + // If every behavior is disabled on block supports, do not show the behaviors inspector control. + const hasSomeBlockSupport = Object.keys( settings?.behaviors ).some( + ( key ) => hasBlockSupport( name, `behaviors.${ key }` ) + ); + + if ( blockSupportOnly ) { + return hasSomeBlockSupport; + } + + // If every behavior is disabled, do not show the behaviors inspector control. + return Object.values( settings?.behaviors ).some( + ( value ) => value === true && hasSomeBlockSupport + ); +} diff --git a/packages/block-editor/src/components/global-styles/index.js b/packages/block-editor/src/components/global-styles/index.js index 24bab543b9ada6..ee5c66ebe8a65b 100644 --- a/packages/block-editor/src/components/global-styles/index.js +++ b/packages/block-editor/src/components/global-styles/index.js @@ -1,4 +1,6 @@ export { + __experimentalUseGlobalBehaviors, + __experimentalUseHasBehaviorsPanel, useGlobalStylesReset, useGlobalSetting, useGlobalStyle, @@ -23,5 +25,6 @@ export { default as BorderPanel, useHasBorderPanel } from './border-panel'; export { default as ColorPanel, useHasColorPanel } from './color-panel'; export { default as EffectsPanel, useHasEffectsPanel } from './effects-panel'; export { default as FiltersPanel, useHasFiltersPanel } from './filters-panel'; +export { default as __experimentalBehaviorsPanel } from './behaviors-panel'; export { default as AdvancedPanel } from './advanced-panel'; export { areGlobalStyleConfigsEqual } from './utils'; diff --git a/packages/block-editor/src/components/global-styles/utils.js b/packages/block-editor/src/components/global-styles/utils.js index d4f2d959a33659..8f9e1f1f396001 100644 --- a/packages/block-editor/src/components/global-styles/utils.js +++ b/packages/block-editor/src/components/global-styles/utils.js @@ -415,6 +415,7 @@ export function areGlobalStyleConfigsEqual( original, variation ) { } return ( fastDeepEqual( original?.styles, variation?.styles ) && - fastDeepEqual( original?.settings, variation?.settings ) + fastDeepEqual( original?.settings, variation?.settings ) && + fastDeepEqual( original?.behaviors, variation?.behaviors ) ); } diff --git a/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js b/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js index 805a89ca8ff0c4..6d6333587b7d0e 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js +++ b/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js @@ -61,6 +61,7 @@ const usePatternsState = ( onInsert, rootClientId ) => { ), { type: 'snackbar', + id: 'block-pattern-inserted-notice', } ); }, diff --git a/packages/block-editor/src/components/media-placeholder/index.native.js b/packages/block-editor/src/components/media-placeholder/index.native.js index 25f6571fd80f3a..dd36feae1e4152 100644 --- a/packages/block-editor/src/components/media-placeholder/index.native.js +++ b/packages/block-editor/src/components/media-placeholder/index.native.js @@ -1,7 +1,8 @@ /** * External dependencies */ -import { View, Text, TouchableWithoutFeedback } from 'react-native'; +import { View, Text, TouchableOpacity } from 'react-native'; +import { sentenceCase } from 'change-case'; /** * WordPress dependencies @@ -13,14 +14,15 @@ import { MEDIA_TYPE_VIDEO, MEDIA_TYPE_AUDIO, } from '@wordpress/block-editor'; -import { withPreferredColorScheme } from '@wordpress/compose'; -import { useRef } from '@wordpress/element'; +import { usePreferredColorSchemeStyle } from '@wordpress/compose'; +import { cloneElement, useCallback, useRef } from '@wordpress/element'; import { Icon, plusCircleFilled } from '@wordpress/icons'; /** * Internal dependencies */ import styles from './styles.scss'; +import { useBlockEditContext } from '../block-edit/context'; const isMediaEqual = ( media1, media2 ) => media1.id === media2.id || media1.url === media2.url; @@ -35,10 +37,13 @@ const dedupMedia = ( media ) => [] ); +const hitSlop = { top: 22, bottom: 22, left: 22, right: 22 }; + function MediaPlaceholder( props ) { const { addToGallery, allowedTypes = [], + className = '', labels = {}, icon, onSelect, @@ -46,7 +51,6 @@ function MediaPlaceholder( props ) { __experimentalOnlyMediaLibrary, isAppender, disableMediaButtons, - getStylesFromColorScheme, multiple, value = [], children, @@ -61,6 +65,16 @@ function MediaPlaceholder( props ) { const mediaRef = useRef( value ); mediaRef.current = value; + const blockEditContext = useBlockEditContext(); + + const onButtonPress = useCallback( + ( open ) => ( event ) => { + onFocus?.( event ); + open(); + }, + [ onFocus ] + ); + // Append and deduplicate media array for gallery use case. const setMedia = multiple && addToGallery @@ -109,55 +123,104 @@ function MediaPlaceholder( props ) { accessibilityHint = __( 'Double tap to select an audio file' ); } - const emptyStateTitleStyle = getStylesFromColorScheme( - styles.emptyStateTitle, - styles.emptyStateTitleDark + const titleStyles = usePreferredColorSchemeStyle( + styles[ 'media-placeholder__header-title' ], + styles[ 'media-placeholder__header-title--dark' ] ); - const addMediaButtonStyle = getStylesFromColorScheme( + const addMediaButtonStyle = usePreferredColorSchemeStyle( styles.addMediaButton, styles.addMediaButtonDark ); + const buttonStyles = usePreferredColorSchemeStyle( + styles[ 'media-placeholder__button' ], + styles[ 'media-placeholder__button--dark' ] + ); + const emptyStateDescriptionStyles = usePreferredColorSchemeStyle( + styles.emptyStateDescription, + styles.emptyStateDescriptionDark + ); + const iconStyles = usePreferredColorSchemeStyle( + styles[ 'media-placeholder__header-icon' ], + styles[ 'media-placeholder__header-icon--dark' ] + ); + const placeholderIcon = cloneElement( icon, { + fill: iconStyles.fill, + } ); + const accessibilityLabel = sprintf( + /* translators: accessibility text for the media block empty state. %s: media type */ + __( '%s block. Empty' ), + placeholderTitle + ); - const renderContent = () => { + const renderContent = ( open ) => { if ( isAppender === undefined || ! isAppender ) { return ( <> - { icon } - - { placeholderTitle } - + + { placeholderIcon } + { placeholderTitle } + { children } - - { instructions } - + + + { sentenceCase( instructions ) } + + ); } else if ( isAppender && ! disableMediaButtons ) { return ( - - - + + + + + ); } }; - if ( isAppender && disableMediaButtons ) { - return null; - } - - const appenderStyle = getStylesFromColorScheme( + const appenderStyle = usePreferredColorSchemeStyle( styles.appender, styles.appenderDark ); - const emptyStateContainerStyle = getStylesFromColorScheme( - styles.emptyStateContainer, - styles.emptyStateContainerDark + const containerSelectedStyle = usePreferredColorSchemeStyle( + styles[ 'media-placeholder__container-selected' ], + styles[ 'media-placeholder__container-selected--dark' ] ); + const containerStyle = [ + usePreferredColorSchemeStyle( + styles[ 'media-placeholder__container' ], + styles[ 'media-placeholder__container--dark' ] + ), + blockEditContext?.isSelected && + ! className.includes( 'no-block-outline' ) && + containerSelectedStyle, + ]; + + if ( isAppender && disableMediaButtons ) { + return null; + } return ( @@ -173,33 +236,19 @@ function MediaPlaceholder( props ) { autoOpen={ autoOpenMediaUpload } render={ ( { open, getMediaOptions } ) => { return ( - { - onFocus?.( event ); - open(); - } } + - - { getMediaOptions() } - { ! hideContent && renderContent() } - - + { getMediaOptions() } + { ! hideContent && renderContent( open ) } + ); } } /> @@ -207,4 +256,4 @@ function MediaPlaceholder( props ) { ); } -export default withPreferredColorScheme( MediaPlaceholder ); +export default MediaPlaceholder; diff --git a/packages/block-editor/src/components/media-placeholder/styles.native.scss b/packages/block-editor/src/components/media-placeholder/styles.native.scss index 708c2f07755e38..93b4dd945e044e 100644 --- a/packages/block-editor/src/components/media-placeholder/styles.native.scss +++ b/packages/block-editor/src/components/media-placeholder/styles.native.scss @@ -1,50 +1,63 @@ -.emptyStateContainer { +.media-placeholder__container { flex: 1; height: 142; flex-direction: column; align-items: center; justify-content: center; - background-color: $gray-lighten-30; + background-color: #e0e0e0; // $light-dim padding-left: 12; padding-right: 12; padding-top: 12; padding-bottom: 12; - border-top-left-radius: 4; - border-top-right-radius: 4; - border-bottom-left-radius: 4; - border-bottom-right-radius: 4; + border-top-left-radius: 2; + border-top-right-radius: 2; + border-bottom-left-radius: 2; + border-bottom-right-radius: 2; } -.emptyStateContainerDark { - background-color: $background-dark-secondary; +.media-placeholder__container--dark { + background-color: #1f1f1f; // $dark-dim } -.emptyStateTitle { - text-align: center; - margin-top: 4; - margin-bottom: 16; - font-size: 14; - color: #2e4453; +.media-placeholder__container-selected { + border-width: 2px; + border-color: $blue-40; } -.emptyStateTitleDark { - color: $white; +.media-placeholder__container-selected--dark { + border-color: $blue-50; } .emptyStateDescription { - width: 100%; text-align: center; - color: $blue-wordpress; - font-size: 14; - font-weight: 500; + color: $white; + font-size: 16; + font-weight: 400; +} + +.emptyStateDescriptionDark { + color: $black; } -.modalIcon { +.media-placeholder__header-icon { width: 24px; height: 24px; - justify-content: center; - align-items: center; - fill: $gray-dark; + margin-right: $grid-unit; + fill: $light-secondary; +} + +.media-placeholder__header-icon--dark { + fill: $dark-tertiary; +} + +.media-placeholder__header-title { + text-align: center; + font-size: 16; + color: $light-secondary; +} + +.media-placeholder__header-title--dark { + color: $dark-tertiary; } .appender { @@ -71,3 +84,25 @@ color: $background-dark-secondary; background-color: $gray-20; } + +.media-placeholder__button { + background-color: $light-primary; + border-radius: 3px; + padding: $grid-unit $grid-unit-20; +} + +.media-placeholder__button--dark { + background-color: $dark-primary; +} + +.media-placeholder__header { + flex-direction: row; + align-items: center; + margin-top: 4; + margin-bottom: 16; +} + +.media-placeholder__appender { + width: 100%; + align-items: center; +} diff --git a/packages/block-editor/src/components/spacing-sizes-control/hooks/use-spacing-sizes.js b/packages/block-editor/src/components/spacing-sizes-control/hooks/use-spacing-sizes.js index 7fc96caa7fd47a..4a24482f3b1e42 100644 --- a/packages/block-editor/src/components/spacing-sizes-control/hooks/use-spacing-sizes.js +++ b/packages/block-editor/src/components/spacing-sizes-control/hooks/use-spacing-sizes.js @@ -10,7 +10,7 @@ import useSetting from '../../use-setting'; export default function useSpacingSizes() { const spacingSizes = [ - { name: 0, slug: '0', side: 0 }, + { name: 0, slug: '0', size: 0 }, ...( useSetting( 'spacing.spacingSizes' ) || [] ), ]; diff --git a/packages/block-editor/src/components/spacing-sizes-control/input-controls/axial.js b/packages/block-editor/src/components/spacing-sizes-control/input-controls/axial.js index 3ca76d9c8f4827..6811349b74ad74 100644 --- a/packages/block-editor/src/components/spacing-sizes-control/input-controls/axial.js +++ b/packages/block-editor/src/components/spacing-sizes-control/input-controls/axial.js @@ -2,7 +2,12 @@ * Internal dependencies */ import SpacingInputControl from './spacing-input-control'; -import { LABELS, ICONS, hasAxisSupport } from '../utils'; +import { + LABELS, + ICONS, + getPresetValueFromCustomValue, + hasAxisSupport, +} from '../utils'; const groupedSides = [ 'vertical', 'horizontal' ]; @@ -20,7 +25,17 @@ export default function AxialInputControls( { if ( ! onChange ) { return; } - const nextValues = { ...values }; + + // Encode the existing value into the preset value if the passed in value matches the value of one of the spacingSizes. + const nextValues = { + ...Object.keys( values ).reduce( ( acc, key ) => { + acc[ key ] = getPresetValueFromCustomValue( + values[ key ], + spacingSizes + ); + return acc; + }, {} ), + }; if ( side === 'vertical' ) { nextValues.top = next; diff --git a/packages/block-editor/src/components/spacing-sizes-control/input-controls/separated.js b/packages/block-editor/src/components/spacing-sizes-control/input-controls/separated.js index ddfa3ebca8e99b..e9e2f828808549 100644 --- a/packages/block-editor/src/components/spacing-sizes-control/input-controls/separated.js +++ b/packages/block-editor/src/components/spacing-sizes-control/input-controls/separated.js @@ -2,7 +2,12 @@ * Internal dependencies */ import SpacingInputControl from './spacing-input-control'; -import { ALL_SIDES, LABELS, ICONS } from '../utils'; +import { + ALL_SIDES, + LABELS, + ICONS, + getPresetValueFromCustomValue, +} from '../utils'; export default function SeparatedInputControls( { minimumCustomValue, @@ -20,7 +25,17 @@ export default function SeparatedInputControls( { : ALL_SIDES; const createHandleOnChange = ( side ) => ( next ) => { - const nextValues = { ...values }; + // Encode the existing value into the preset value if the passed in value matches the value of one of the spacingSizes. + const nextValues = { + ...Object.keys( values ).reduce( ( acc, key ) => { + acc[ key ] = getPresetValueFromCustomValue( + values[ key ], + spacingSizes + ); + return acc; + }, {} ), + }; + nextValues[ side ] = next; onChange( nextValues ); diff --git a/packages/block-editor/src/components/spacing-sizes-control/input-controls/single.js b/packages/block-editor/src/components/spacing-sizes-control/input-controls/single.js index 2bb0a409da0dd2..df6beb0f8f7b73 100644 --- a/packages/block-editor/src/components/spacing-sizes-control/input-controls/single.js +++ b/packages/block-editor/src/components/spacing-sizes-control/input-controls/single.js @@ -2,7 +2,7 @@ * Internal dependencies */ import SpacingInputControl from './spacing-input-control'; -import { LABELS } from '../utils'; +import { LABELS, getPresetValueFromCustomValue } from '../utils'; export default function SingleInputControl( { minimumCustomValue, @@ -16,7 +16,17 @@ export default function SingleInputControl( { values, } ) { const createHandleOnChange = ( currentSide ) => ( next ) => { - const nextValues = { ...values }; + // Encode the existing value into the preset value if the passed in value matches the value of one of the spacingSizes. + const nextValues = { + ...Object.keys( values ).reduce( ( acc, key ) => { + acc[ key ] = getPresetValueFromCustomValue( + values[ key ], + spacingSizes + ); + return acc; + }, {} ), + }; + nextValues[ currentSide ] = next; onChange( nextValues ); diff --git a/packages/block-editor/src/components/spacing-sizes-control/utils.js b/packages/block-editor/src/components/spacing-sizes-control/utils.js index fe8d89509cdbda..340abb0322e9a2 100644 --- a/packages/block-editor/src/components/spacing-sizes-control/utils.js +++ b/packages/block-editor/src/components/spacing-sizes-control/utils.js @@ -102,7 +102,7 @@ export function getCustomValueFromPreset( value, spacingSizes ) { */ export function getPresetValueFromCustomValue( value, spacingSizes ) { // Return value as-is if it is already a preset; - if ( isValueSpacingPreset( value ) ) { + if ( isValueSpacingPreset( value ) || value === '0' ) { return value; } diff --git a/packages/block-editor/src/components/text-transform-control/README.md b/packages/block-editor/src/components/text-transform-control/README.md new file mode 100644 index 00000000000000..511b73b0ec696b --- /dev/null +++ b/packages/block-editor/src/components/text-transform-control/README.md @@ -0,0 +1,44 @@ +# TextTransformControl + +The `TextTransformControl` component is responsible for rendering a control element that allows users to select and apply text transformation options to blocks or elements in the Gutenberg editor. It provides an intuitive interface for changing the text appearance by applying different transformations such as `none`, `uppercase`, `lowercase`, `capitalize`. + +![TextTransformConrol Element in Inspector Control](https://raw.githubusercontent.com/WordPress/gutenberg/HEAD/docs/assets/text-transform-component.png?raw=true) + +## Table of contents + +1. [Development guidelines](#development-guidelines) + +## Development guidelines + +### Usage + +Renders the Text Transform Component with `none`, `uppercase`, `lowercase`, `capitalize` options. + +```jsx +import { TextTransformControl } from '@wordpress/block-editor'; + +const MyTextTransformControlComponent = () => ( + { + setAttributes( { textTransform: value } ); + } } + /> +); +``` + +### Props + +### `value` + +- **Type:** `String` +- **Default:** `none` +- **Options:** `none`, `uppercase`, `lowercase`, `capitalize` + +The current value of the Text Transform setting. You may only choose from the `Options` listed above. + +### `onChange` + +- **Type:** `Function` + +A callback function invoked when the Text Transform value is changed via an interaction with any of the buttons. Called with the Text Transform value (`none`, `uppercase`, `lowercase`, `capitalize`) as the only argument. \ No newline at end of file diff --git a/packages/block-editor/src/hooks/behaviors.js b/packages/block-editor/src/hooks/behaviors.js index 42cb42e8023684..27ef5b7afbfe93 100644 --- a/packages/block-editor/src/hooks/behaviors.js +++ b/packages/block-editor/src/hooks/behaviors.js @@ -22,15 +22,13 @@ function BehaviorsControl( { onChangeAnimation, disabled = false, } ) { - const { settings, themeBehaviors } = useSelect( + const { settings } = useSelect( ( select ) => { - const { getBehaviors, getSettings } = select( blockEditorStore ); - + const { getSettings } = select( blockEditorStore ); return { settings: getSettings()?.__experimentalFeatures?.blocks?.[ blockName ] - ?.behaviors, - themeBehaviors: getBehaviors()?.blocks?.[ blockName ], + ?.behaviors || {}, }; }, [ blockName ] @@ -46,7 +44,6 @@ function BehaviorsControl( { label: __( 'No behaviors' ), }, }; - const behaviorsOptions = Object.entries( settings ) .filter( ( [ behaviorName, behaviorValue ] ) => @@ -60,7 +57,6 @@ function BehaviorsControl( { .slice( 1 ) .toLowerCase() }`, } ) ); - const options = [ ...Object.values( defaultBehaviors ), ...behaviorsOptions, @@ -68,7 +64,6 @@ function BehaviorsControl( { const { behaviors, behaviorsValue } = useMemo( () => { const mergedBehaviors = { - ...themeBehaviors, ...( blockBehaviors || {} ), }; @@ -83,7 +78,8 @@ function BehaviorsControl( { behaviors: mergedBehaviors, behaviorsValue: value, }; - }, [ blockBehaviors, themeBehaviors ] ); + }, [ blockBehaviors ] ); + // If every behavior is disabled, do not show the behaviors inspector control. if ( behaviorsOptions.length === 0 ) { return null; diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 3aaec39a986ccd..c3d8847b032397 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2577,30 +2577,6 @@ export function getSettings( state ) { return state.settings; } -/** - * Returns the behaviors registered with the editor. - * - * Behaviors are named, reusable pieces of functionality that can be - * attached to blocks. They are registered with the editor using the - * `theme.json` file. - * - * @example - * - * ```js - * const behaviors = select( blockEditorStore ).getBehaviors(); - * if ( behaviors?.lightbox ) { - * // Do something with the lightbox. - * } - *``` - * - * @param {Object} state Editor state. - * - * @return {Object} The editor behaviors object. - */ -export function getBehaviors( state ) { - return state.settings.behaviors; -} - /** * Returns true if the most recent block change is be considered persistent, or * false otherwise. A persistent change is one committed by BlockEditorProvider diff --git a/packages/block-library/CHANGELOG.md b/packages/block-library/CHANGELOG.md index fa26d4a346cebd..705bd7d7761a32 100644 --- a/packages/block-library/CHANGELOG.md +++ b/packages/block-library/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 8.15.0 (2023-07-20) + ## 8.14.0 (2023-07-05) ## 8.13.0 (2023-06-23) diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 8799a708620056..af36b5cef74977 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "8.14.0", + "version": "8.15.0", "description": "Block library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-library/src/audio/test/__snapshots__/edit.native.js.snap b/packages/block-library/src/audio/test/__snapshots__/edit.native.js.snap index 22c927a4a657e0..54131121d798d1 100644 --- a/packages/block-library/src/audio/test/__snapshots__/edit.native.js.snap +++ b/packages/block-library/src/audio/test/__snapshots__/edit.native.js.snap @@ -395,22 +395,13 @@ exports[`Audio block renders placeholder without crashing 1`] = ` } > + + + + + Path + + + + + Audio + + - - - Path - - + + Add audio + - - Audio - - - ADD AUDIO - diff --git a/packages/block-library/src/block/editor.native.scss b/packages/block-library/src/block/editor.native.scss index 3aa23e0ddd20ea..b56a50f676600d 100644 --- a/packages/block-library/src/block/editor.native.scss +++ b/packages/block-library/src/block/editor.native.scss @@ -19,8 +19,8 @@ background-color: $light-gray-400; height: 1px; position: absolute; - left: -$block-selected-to-content + $block-selected-border-width; - right: -$block-selected-to-content + $block-selected-border-width; + left: -$grid-unit-05; + right: -$grid-unit-05; bottom: 16; } diff --git a/packages/block-library/src/embed/embed-placeholder.native.js b/packages/block-library/src/embed/embed-placeholder.native.js index 966b96c939217c..35b71b3ab988e1 100644 --- a/packages/block-library/src/embed/embed-placeholder.native.js +++ b/packages/block-library/src/embed/embed-placeholder.native.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { View, Text, TouchableWithoutFeedback } from 'react-native'; +import { View, Text, TouchableOpacity } from 'react-native'; /** * WordPress dependencies @@ -18,6 +18,8 @@ import { useRef } from '@wordpress/element'; import styles from './styles.scss'; import { noticeOutline } from '../../../components/src/mobile/gridicons'; +const hitSlop = { top: 22, bottom: 22, left: 22, right: 22 }; + const EmbedPlaceholder = ( { icon, isSelected, @@ -28,10 +30,17 @@ const EmbedPlaceholder = ( { tryAgain, openEmbedLinkSettings, } ) => { - const containerStyle = usePreferredColorSchemeStyle( - styles.embed__container, - styles[ 'embed__container--dark' ] + const containerSelectedStyle = usePreferredColorSchemeStyle( + styles[ 'embed__container-selected' ], + styles[ 'embed__container-selected--dark' ] ); + const containerStyle = [ + usePreferredColorSchemeStyle( + styles.embed__container, + styles[ 'embed__container--dark' ] + ), + isSelected && containerSelectedStyle, + ]; const labelStyle = usePreferredColorSchemeStyle( styles.embed__label, styles[ 'embed__label--dark' ] @@ -44,6 +53,15 @@ const EmbedPlaceholder = ( { ); const embedIconErrorStyle = styles[ 'embed__icon--error' ]; + const buttonStyles = usePreferredColorSchemeStyle( + styles.embed__button, + styles[ 'embed__button--dark' ] + ); + const iconStyles = usePreferredColorSchemeStyle( + styles.embed__icon, + styles[ 'embed__icon--dark' ] + ); + const cannotEmbedMenuPickerRef = useRef(); const errorPickerOptions = { @@ -89,55 +107,70 @@ const EmbedPlaceholder = ( { return ( <> - - - { cannotEmbed ? ( - <> - - - { __( 'Unable to embed media' ) } - + + { cannotEmbed ? ( + <> + + + { __( 'Unable to embed media' ) } + + { __( 'More options' ) } - - - ) : ( - <> - + + + + ) : ( + <> + + { label } + + - { __( 'ADD LINK' ) } + { __( 'Add link' ) } - - ) } - - + + + ) } + ); }; diff --git a/packages/block-library/src/embed/styles.native.scss b/packages/block-library/src/embed/styles.native.scss index fade4204a975bf..d7f07bc259361f 100644 --- a/packages/block-library/src/embed/styles.native.scss +++ b/packages/block-library/src/embed/styles.native.scss @@ -4,19 +4,28 @@ flex-direction: column; align-items: center; justify-content: center; - background-color: $gray-lighten-30; + background-color: #e0e0e0; // $light-dim padding-left: 12; padding-right: 12; padding-top: 12; padding-bottom: 12; - border-top-left-radius: 4; - border-top-right-radius: 4; - border-bottom-left-radius: 4; - border-bottom-right-radius: 4; + border-top-left-radius: 2; + border-top-right-radius: 2; + border-bottom-left-radius: 2; + border-bottom-right-radius: 2; } .embed__container--dark { - background-color: $background-dark-secondary; + background-color: #1f1f1f; // $dark-dim +} + +.embed__container-selected { + border-width: 2px; + border-color: $blue-40; +} + +.embed__container-selected--dark { + border-color: $blue-50; } .embed__icon--error { @@ -24,23 +33,38 @@ fill: $alert-red; } +.embed__placeholder-header { + flex-direction: row; + align-items: center; + margin-top: 4; + margin-bottom: 16; +} + +.embed__icon { + fill: $light-secondary; +} + +.embed__icon--dark { + fill: $dark-tertiary; +} + .embed__label { text-align: center; - margin-top: 4; - margin-bottom: 4; - font-size: 14; - font-weight: 500; - color: $gray-90; + margin-left: $grid-unit; + font-size: 16; + font-weight: 400; + color: $light-secondary; } .embed__label--dark { - color: $gray-10; + color: $dark-tertiary; } .embed__description { font-size: $default-font-size; text-align: center; - margin-bottom: 4; + margin-top: 4; + margin-bottom: 16; color: $light-secondary; } @@ -53,12 +77,14 @@ } .embed__action { - width: 100%; text-align: center; - color: $blue-wordpress; - font-size: 14; - font-weight: 500; - margin-top: 4; + color: $white; + font-size: 16; + font-weight: 400; +} + +.embed__action--dark { + color: $black; } .embed-preview__loading { @@ -158,3 +184,13 @@ .embed-no-preview__sheet-button--dark { color: $blue-30; } + +.embed__button { + background-color: $light-primary; + border-radius: 3px; + padding: $grid-unit $grid-unit-20; +} + +.embed__button--dark { + background-color: $dark-primary; +} diff --git a/packages/block-library/src/embed/test/index.native.js b/packages/block-library/src/embed/test/index.native.js index 6abdd2509f863b..9a3bad5e6a7340 100644 --- a/packages/block-library/src/embed/test/index.native.js +++ b/packages/block-library/src/embed/test/index.native.js @@ -330,7 +330,7 @@ describe( 'Embed block', () => { const editor = await initializeWithEmbedBlock( EMPTY_EMBED_HTML ); // Edit URL. - fireEvent.press( await editor.findByText( 'ADD LINK' ) ); + fireEvent.press( await editor.findByText( 'Add link' ) ); // Wait for edit URL modal to be visible. const embedEditURLModal = editor.getByTestId( @@ -351,7 +351,7 @@ describe( 'Embed block', () => { const editor = await initializeWithEmbedBlock( EMPTY_EMBED_HTML ); // Edit URL. - fireEvent.press( editor.getByText( 'ADD LINK' ) ); + fireEvent.press( editor.getByText( 'Add link' ) ); // Wait for edit URL modal to be visible. const embedEditURLModal = editor.getByTestId( @@ -392,7 +392,7 @@ describe( 'Embed block', () => { const editor = await initializeWithEmbedBlock( EMPTY_EMBED_HTML ); // Edit URL. - fireEvent.press( editor.getByText( 'ADD LINK' ) ); + fireEvent.press( editor.getByText( 'Add link' ) ); // Wait for edit URL modal to be visible. const embedEditURLModal = editor.getByTestId( @@ -592,7 +592,7 @@ describe( 'Embed block', () => { fireEvent.press( editor.block ); // Edit URL. - fireEvent.press( editor.getByText( 'ADD LINK' ) ); + fireEvent.press( editor.getByText( 'Add link' ) ); // Wait for edit URL modal to be visible. await waitForModalVisible( embedEditURLModal ); @@ -602,7 +602,7 @@ describe( 'Embed block', () => { fireEvent( embedEditURLModal, MODAL_DISMISS_EVENT ); // Edit URL. - fireEvent.press( editor.getByText( 'ADD LINK' ) ); + fireEvent.press( editor.getByText( 'Add link' ) ); // Wait for edit URL modal to be visible. await waitForModalVisible( embedEditURLModal ); diff --git a/packages/block-library/src/file/test/__snapshots__/edit.native.js.snap b/packages/block-library/src/file/test/__snapshots__/edit.native.js.snap index 34750c8559bd08..83a5fe5bce2e68 100644 --- a/packages/block-library/src/file/test/__snapshots__/edit.native.js.snap +++ b/packages/block-library/src/file/test/__snapshots__/edit.native.js.snap @@ -441,22 +441,13 @@ exports[`File block renders placeholder without crashing 1`] = ` } > + + + + + Path + + + + + File + + - - - Path - - + + Choose a file + - - File - - - CHOOSE A FILE - `; diff --git a/packages/block-library/src/footnotes/index.php b/packages/block-library/src/footnotes/index.php index e4bd8dcdeaac2e..d28161d6acdae4 100644 --- a/packages/block-library/src/footnotes/index.php +++ b/packages/block-library/src/footnotes/index.php @@ -78,3 +78,129 @@ function register_block_core_footnotes() { ); } add_action( 'init', 'register_block_core_footnotes' ); + +add_action( + 'wp_after_insert_post', + /** + * Saves the footnotes meta value to the revision. + * + * @param int $revision_id The revision ID. + */ + static function( $revision_id ) { + $post_id = wp_is_post_revision( $revision_id ); + + if ( $post_id ) { + $footnotes = get_post_meta( $post_id, 'footnotes', true ); + + if ( $footnotes ) { + // Can't use update_post_meta() because it doesn't allow revisions. + update_metadata( 'post', $revision_id, 'footnotes', $footnotes ); + } + } + } +); + +add_action( + '_wp_put_post_revision', + /** + * Keeps track of the revision ID for "rest_after_insert_{$post_type}". + * + * @param int $revision_id The revision ID. + */ + static function( $revision_id ) { + global $_gutenberg_revision_id; + $_gutenberg_revision_id = $revision_id; + } +); + +foreach ( array( 'post', 'page' ) as $post_type ) { + add_action( + "rest_after_insert_{$post_type}", + /** + * This is a specific fix for the REST API. The REST API doesn't update + * the post and post meta in one go (through `meta_input`). While it + * does fix the `wp_after_insert_post` hook to be called correctly after + * updating meta, it does NOT fix hooks such as post_updated and + * save_post, which are normally also fired after post meta is updated + * in `wp_insert_post()`. Unfortunately, `wp_save_post_revision` is + * added to the `post_updated` action, which means the meta is not + * available at the time, so we have to add it afterwards through the + * `"rest_after_insert_{$post_type}"` action. + * + * @param WP_Post $post The post object. + */ + static function( $post ) { + global $_gutenberg_revision_id; + + if ( $_gutenberg_revision_id ) { + $revision = get_post( $_gutenberg_revision_id ); + $post_id = $revision->post_parent; + + // Just making sure we're updating the right revision. + if ( $post->ID === $post_id ) { + $footnotes = get_post_meta( $post_id, 'footnotes', true ); + + if ( $footnotes ) { + // Can't use update_post_meta() because it doesn't allow revisions. + update_metadata( 'post', $_gutenberg_revision_id, 'footnotes', $footnotes ); + } + } + } + } + ); +} + +add_action( + 'wp_restore_post_revision', + /** + * Restores the footnotes meta value from the revision. + * + * @param int $post_id The post ID. + * @param int $revision_id The revision ID. + */ + static function( $post_id, $revision_id ) { + $footnotes = get_post_meta( $revision_id, 'footnotes', true ); + + if ( $footnotes ) { + update_post_meta( $post_id, 'footnotes', $footnotes ); + } else { + delete_post_meta( $post_id, 'footnotes' ); + } + }, + 10, + 2 +); + +add_filter( + '_wp_post_revision_fields', + /** + * Adds the footnotes field to the revision. + * + * @param array $fields The revision fields. + * + * @return array The revision fields. + */ + static function( $fields ) { + $fields['footnotes'] = __( 'Footnotes' ); + return $fields; + } +); + +add_filter( + 'wp_post_revision_field_footnotes', + /** + * Gets the footnotes field from the revision. + * + * @param string $revision_field The field value, but $revision->$field + * (footnotes) does not exist. + * @param string $field The field name, in this case "footnotes". + * @param object $revision The revision object to compare against. + * + * @return string The field value. + */ + static function( $revision_field, $field, $revision ) { + return get_metadata( 'post', $revision->ID, $field, true ); + }, + 10, + 3 +); diff --git a/packages/block-library/src/gallery/shared-icon.native.js b/packages/block-library/src/gallery/shared-icon.native.js deleted file mode 100644 index 16e89f5a95ac43..00000000000000 --- a/packages/block-library/src/gallery/shared-icon.native.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * WordPress dependencies - */ -import { Icon } from '@wordpress/components'; -import { withPreferredColorScheme } from '@wordpress/compose'; -import { gallery as icon } from '@wordpress/icons'; - -/** - * Internal dependencies - */ -import styles from './styles.scss'; - -const IconWithColorScheme = withPreferredColorScheme( - ( { getStylesFromColorScheme } ) => { - const colorSchemeStyles = getStylesFromColorScheme( - styles.icon, - styles.iconDark - ); - return ; - } -); - -export const sharedIcon = ; diff --git a/packages/block-library/src/gallery/test/index.native.js b/packages/block-library/src/gallery/test/index.native.js index ef4f445db337bc..fad641d61b7a97 100644 --- a/packages/block-library/src/gallery/test/index.native.js +++ b/packages/block-library/src/gallery/test/index.native.js @@ -134,7 +134,7 @@ describe( 'Gallery block', () => { // Tap on Gallery block const block = await getBlock( screen, 'Gallery' ); fireEvent.press( block ); - fireEvent.press( within( block ).getByText( 'ADD MEDIA' ) ); + fireEvent.press( within( block ).getByText( 'Add media' ) ); // Observe that media options picker is displayed /* eslint-disable jest/no-conditional-expect */ @@ -169,7 +169,7 @@ describe( 'Gallery block', () => { } ); // Tap on Gallery block - fireEvent.press( getByText( 'ADD MEDIA' ) ); + fireEvent.press( getByText( 'Add media' ) ); // Observe that media options picker is displayed expect( getByText( 'Choose images' ) ).toBeVisible(); @@ -283,7 +283,7 @@ describe( 'Gallery block', () => { const { selectOption } = setupPicker( screen, MEDIA_OPTIONS ); // Upload images from device - fireEvent.press( getByText( 'ADD MEDIA' ) ); + fireEvent.press( getByText( 'Add media' ) ); selectOption( 'Choose from device' ); expectMediaPickerCall( 'DEVICE_MEDIA_LIBRARY', [ 'image' ], true ); @@ -321,7 +321,7 @@ describe( 'Gallery block', () => { const { galleryBlock, getByText } = await initializeWithGalleryBlock(); // Upload images from device - fireEvent.press( getByText( 'ADD MEDIA' ) ); + fireEvent.press( getByText( 'Add media' ) ); fireEvent.press( getByText( 'Choose from device' ) ); expectMediaPickerCall( 'DEVICE_MEDIA_LIBRARY', [ 'image' ], true ); @@ -375,7 +375,7 @@ describe( 'Gallery block', () => { const { galleryBlock, getByText } = await initializeWithGalleryBlock(); // Take a photo - fireEvent.press( getByText( 'ADD MEDIA' ) ); + fireEvent.press( getByText( 'Add media' ) ); fireEvent.press( getByText( 'Take a Photo' ) ); expectMediaPickerCall( 'DEVICE_CAMERA', [ 'image' ], true ); @@ -429,7 +429,7 @@ describe( 'Gallery block', () => { ); // Upload images from free photo library - fireEvent.press( getByText( 'ADD MEDIA' ) ); + fireEvent.press( getByText( 'Add media' ) ); fireEvent.press( getByText( 'Free Photo Library' ) ); expectMediaPickerCall( 'stock-photo-library', [ 'image' ], true ); @@ -469,7 +469,7 @@ describe( 'Gallery block', () => { const { galleryBlock, getByText } = await initializeWithGalleryBlock(); // Upload images from device - fireEvent.press( getByText( 'ADD MEDIA' ) ); + fireEvent.press( getByText( 'Add media' ) ); fireEvent.press( getByText( 'Choose from device' ) ); expectMediaPickerCall( 'DEVICE_MEDIA_LIBRARY', [ 'image' ], true ); @@ -569,7 +569,7 @@ describe( 'Gallery block', () => { ); // Upload images from other apps - fireEvent.press( getByText( 'ADD MEDIA' ) ); + fireEvent.press( getByText( 'Add media' ) ); fireEvent.press( getByText( 'Other Apps' ) ); expectMediaPickerCall( 'other-files', [ 'image' ], true ); diff --git a/packages/block-library/src/home-link/index.php b/packages/block-library/src/home-link/index.php index 459979b0d43893..8fb5ed109019d3 100644 --- a/packages/block-library/src/home-link/index.php +++ b/packages/block-library/src/home-link/index.php @@ -98,8 +98,15 @@ function block_core_home_link_build_li_wrapper_attributes( $context ) { $colors['css_classes'], $font_sizes['css_classes'] ); - $classes[] = 'wp-block-navigation-item'; $style_attribute = ( $colors['inline_styles'] . $font_sizes['inline_styles'] ); + $classes[] = 'wp-block-navigation-item'; + + if ( is_front_page() ) { + $classes[] = 'current-menu-item'; + } elseif ( is_home() && ( (int) get_option( 'page_for_posts' ) !== get_queried_object_id() ) ) { + // Edge case where the Reading settings has a posts page set but not a static homepage. + $classes[] = 'current-menu-item'; + } $wrapper_attributes = get_block_wrapper_attributes( array( @@ -124,8 +131,14 @@ function render_block_core_home_link( $attributes, $content, $block ) { if ( empty( $attributes['label'] ) ) { return ''; } + $aria_current = ''; - $aria_current = is_home() || ( is_front_page() && 'page' === get_option( 'show_on_front' ) ) ? ' aria-current="page"' : ''; + if ( is_front_page() ) { + $aria_current = ' aria-current="page"'; + } elseif ( is_home() && ( (int) get_option( 'page_for_posts' ) !== get_queried_object_id() ) ) { + // Edge case where the Reading settings has a posts page set but not a static homepage. + $aria_current = ' aria-current="page"'; + } return sprintf( '
  • %4$s
  • ', diff --git a/packages/block-library/src/image/index.php b/packages/block-library/src/image/index.php index 1e437d860aa097..9c8f66b7ffe185 100644 --- a/packages/block-library/src/image/index.php +++ b/packages/block-library/src/image/index.php @@ -9,11 +9,12 @@ * Renders the `core/image` block on the server, * adding a data-id attribute to the element if core/gallery has added on pre-render. * - * @param array $attributes The block attributes. - * @param string $content The block content. + * @param array $attributes The block attributes. + * @param string $content The block content. + * @param WP_Block $block The block object. * @return string Returns the block content with the data-id attribute added. */ -function render_block_core_image( $attributes, $content ) { +function render_block_core_image( $attributes, $content, $block ) { $processor = new WP_HTML_Tag_Processor( $content ); $processor->next_tag( 'img' ); @@ -30,14 +31,52 @@ function render_block_core_image( $attributes, $content ) { $processor->set_attribute( 'data-id', $attributes['data-id'] ); } + $should_load_view_script = false; + $experiments = get_option( 'gutenberg-experiments' ); + $link_destination = isset( $attributes['linkDestination'] ) ? $attributes['linkDestination'] : 'none'; + // Get the lightbox setting from the block attributes. + if ( isset( $attributes['behaviors']['lightbox'] ) ) { + $lightbox_settings = $attributes['behaviors']['lightbox']; + // If the lightbox setting is not set in the block attributes, get it from the theme.json file. + } else { + $theme_data = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data()->get_data(); + if ( isset( $theme_data['behaviors']['blocks'][ $block->name ]['lightbox'] ) ) { + $lightbox_settings = $theme_data['behaviors']['blocks'][ $block->name ]['lightbox']; + } else { + $lightbox_settings = null; + } + } + + // If the lightbox is enabled, the image is not linked, and the Interactivity API is enabled, load the view script. + if ( isset( $lightbox_settings['enabled'] ) && + true === $lightbox_settings['enabled'] && + 'none' === $link_destination && + ! empty( $experiments['gutenberg-interactivity-api-core-blocks'] ) + ) { + $should_load_view_script = true; + } + + $view_js_file = 'wp-block-image-view'; + if ( ! wp_script_is( $view_js_file ) ) { + $script_handles = $block->block_type->view_script_handles; + + // If the script is not needed, and it is still in the `view_script_handles`, remove it. + if ( ! $should_load_view_script && in_array( $view_js_file, $script_handles, true ) ) { + $block->block_type->view_script_handles = array_diff( $script_handles, array( $view_js_file ) ); + } + // If the script is needed, but it was previously removed, add it again. + if ( $should_load_view_script && ! in_array( $view_js_file, $script_handles, true ) ) { + $block->block_type->view_script_handles = array_merge( $script_handles, array( $view_js_file ) ); + } + } + return $processor->get_updated_html(); } -/** - * Registers the `core/image` block on server. - */ + /** + * Registers the `core/image` block on server. + */ function register_block_core_image() { - register_block_type_from_metadata( __DIR__ . '/image', array( @@ -45,4 +84,4 @@ function register_block_core_image() { ) ); } -add_action( 'init', 'register_block_core_image' ); + add_action( 'init', 'register_block_core_image' ); diff --git a/packages/block-library/src/image/test/edit.native.js b/packages/block-library/src/image/test/edit.native.js index 2e8bc4bf4a49bd..7d614e664c7fec 100644 --- a/packages/block-library/src/image/test/edit.native.js +++ b/packages/block-library/src/image/test/edit.native.js @@ -442,7 +442,7 @@ describe( 'Image Block', () => { `; const screen = await initializeEditor( { initialHtml } ); - fireEvent.press( screen.getByText( 'ADD IMAGE' ) ); + fireEvent.press( screen.getByText( 'Add image' ) ); fireEvent.press( screen.getByText( 'WordPress Media Library' ) ); const expectedHtml = ` diff --git a/packages/block-library/src/media-text/media-container.native.js b/packages/block-library/src/media-text/media-container.native.js index 2057486b73ac9c..dbc30dcf23e7aa 100644 --- a/packages/block-library/src/media-text/media-container.native.js +++ b/packages/block-library/src/media-text/media-container.native.js @@ -316,6 +316,7 @@ class MediaContainer extends Component { onSelect={ this.onSelectMediaUploadOption } allowedTypes={ ALLOWED_MEDIA_TYPES } onFocus={ this.props.onFocus } + className={ 'no-block-outline' } /> ); } diff --git a/packages/block-library/src/missing/edit.native.js b/packages/block-library/src/missing/edit.native.js index 8c93e1f604620a..e8576914065723 100644 --- a/packages/block-library/src/missing/edit.native.js +++ b/packages/block-library/src/missing/edit.native.js @@ -5,7 +5,7 @@ import { View, Text, TouchableWithoutFeedback, - TouchableHighlight, + TouchableOpacity, } from 'react-native'; /** @@ -83,7 +83,7 @@ export class UnsupportedBlockEdit extends Component { ); return ( - - + ); } @@ -282,12 +282,14 @@ export class UnsupportedBlockEdit extends Component { ) } > { this.renderHelpIcon() } - - { title } + + + { title } + { subtitle } { this.renderSheet( title, originalName ) } diff --git a/packages/block-library/src/missing/style.native.scss b/packages/block-library/src/missing/style.native.scss index 6718713f320198..9a56f82f7e3f0d 100644 --- a/packages/block-library/src/missing/style.native.scss +++ b/packages/block-library/src/missing/style.native.scss @@ -31,11 +31,11 @@ height: 36; padding-top: 8; padding-bottom: 8; - color: $gray-darken-20; + color: $light-secondary; } .infoIconDark { - color: $gray-20; + color: $dark-tertiary; } .infoSheetIcon { @@ -82,7 +82,8 @@ } .unsupportedBlock { - background-color: $gray-lighten-30; + height: 142; + background-color: #e0e0e0; // $light-dim padding-top: 24; padding-bottom: 24; padding-left: 8; @@ -96,31 +97,37 @@ } .unsupportedBlockDark { - background-color: $background-dark-secondary; + background-color: #1f1f1f; // $dark-dim +} + +.unsupportedBlockHeader { + flex-direction: row; + align-items: center; + margin-top: 4; + margin-bottom: 8; } .unsupportedBlockIcon { - color: $gray-dark; + color: $light-secondary; } .unsupportedBlockIconDark { - color: $white; + color: $dark-tertiary; } .unsupportedBlockMessage { - margin-top: 4; text-align: center; - color: $gray-dark; - font-size: 14; - font-weight: 600; + color: $light-secondary; + font-size: 16; + font-weight: 400; + margin-left: 6; } .unsupportedBlockMessageDark { - color: $white; + color: $dark-tertiary; } .unsupportedBlockSubtitle { - margin-top: 2; text-align: center; color: $gray-darken-20; font-size: 12; diff --git a/packages/block-library/src/missing/test/__snapshots__/edit.native.js.snap b/packages/block-library/src/missing/test/__snapshots__/edit.native.js.snap index f0f0db7010b54c..b287f58524c6f7 100644 --- a/packages/block-library/src/missing/test/__snapshots__/edit.native.js.snap +++ b/packages/block-library/src/missing/test/__snapshots__/edit.native.js.snap @@ -25,6 +25,7 @@ exports[`Missing block renders without crashing 1`] = ` accessibilityLabel="Help button" accessibilityRole="button" accessible={true} + collapsable={false} focusable={true} onClick={[Function]} onResponderGrant={[Function]} @@ -33,6 +34,11 @@ exports[`Missing block renders without crashing 1`] = ` onResponderTerminate={[Function]} onResponderTerminationRequest={[Function]} onStartShouldSetResponder={[Function]} + style={ + { + "opacity": 1, + } + } > - - Path - - - missing/block/title - + + + Path + + + missing/block/title + + Unsupported diff --git a/packages/block-library/src/query-title/edit.js b/packages/block-library/src/query-title/edit.js index e5fa6f6c396774..b74e03e7583b2d 100644 --- a/packages/block-library/src/query-title/edit.js +++ b/packages/block-library/src/query-title/edit.js @@ -13,9 +13,11 @@ import { useBlockProps, Warning, HeadingLevelDropdown, + store as blockEditorStore, } from '@wordpress/block-editor'; import { ToggleControl, PanelBody } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; +import { __, sprintf } from '@wordpress/i18n'; +import { useSelect } from '@wordpress/data'; const SUPPORTED_TYPES = [ 'archive', 'search' ]; @@ -23,6 +25,18 @@ export default function QueryTitleEdit( { attributes: { type, level, textAlign, showPrefix, showSearchTerm }, setAttributes, } ) { + const { archiveTypeTitle, archiveNameLabel } = useSelect( ( select ) => { + const { getSettings } = select( blockEditorStore ); + const { + __experimentalArchiveTitleNameLabel, + __experimentalArchiveTitleTypeLabel, + } = getSettings(); + return { + archiveTypeTitle: __experimentalArchiveTitleTypeLabel, + archiveNameLabel: __experimentalArchiveTitleNameLabel, + }; + } ); + const TagName = `h${ level }`; const blockProps = useBlockProps( { className: classnames( 'wp-block-query-title__placeholder', { @@ -40,6 +54,38 @@ export default function QueryTitleEdit( { let titleElement; if ( type === 'archive' ) { + let title; + if ( archiveTypeTitle ) { + if ( showPrefix ) { + if ( archiveNameLabel ) { + title = sprintf( + /* translators: 1: Archive type title e.g: "Category", 2: Label of the archive e.g: "Shoes" */ + __( '%1$s: %2$s' ), + archiveTypeTitle, + archiveNameLabel + ); + } else { + title = sprintf( + /* translators: %s: Archive type title e.g: "Category", "Tag"... */ + __( '%s: Name' ), + archiveTypeTitle + ); + } + } else if ( archiveNameLabel ) { + title = archiveNameLabel; + } else { + title = sprintf( + /* translators: %s: Archive type title e.g: "Category", "Tag"... */ + __( '%s name' ), + archiveTypeTitle + ); + } + } else { + title = showPrefix + ? __( 'Archive type: Name' ) + : __( 'Archive title' ); + } + titleElement = ( <> @@ -54,11 +100,7 @@ export default function QueryTitleEdit( { /> - - { showPrefix - ? __( 'Archive type: Name' ) - : __( 'Archive title' ) } - + { title } ); } diff --git a/packages/block-serialization-default-parser/CHANGELOG.md b/packages/block-serialization-default-parser/CHANGELOG.md index d3ca0243114f9c..e35d0a42b8c32b 100644 --- a/packages/block-serialization-default-parser/CHANGELOG.md +++ b/packages/block-serialization-default-parser/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.38.0 (2023-07-20) + ## 4.37.0 (2023-07-05) ## 4.36.0 (2023-06-23) diff --git a/packages/block-serialization-default-parser/package.json b/packages/block-serialization-default-parser/package.json index a0b8414ded1e7f..3e9fb2a7859ebb 100644 --- a/packages/block-serialization-default-parser/package.json +++ b/packages/block-serialization-default-parser/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-serialization-default-parser", - "version": "4.37.0", + "version": "4.38.0", "description": "Block serialization specification parser for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-serialization-spec-parser/CHANGELOG.md b/packages/block-serialization-spec-parser/CHANGELOG.md index 8f3d032be39c62..6ad83e1fddde4f 100644 --- a/packages/block-serialization-spec-parser/CHANGELOG.md +++ b/packages/block-serialization-spec-parser/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.38.0 (2023-07-20) + ## 4.37.0 (2023-07-05) ## 4.36.0 (2023-06-23) diff --git a/packages/block-serialization-spec-parser/package.json b/packages/block-serialization-spec-parser/package.json index db2592278c16c7..1a1a41096f8a59 100644 --- a/packages/block-serialization-spec-parser/package.json +++ b/packages/block-serialization-spec-parser/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-serialization-spec-parser", - "version": "4.37.0", + "version": "4.38.0", "description": "Block serialization specification parser for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blocks/CHANGELOG.md b/packages/blocks/CHANGELOG.md index 249b254a92fa40..ce29426cabdf6e 100644 --- a/packages/blocks/CHANGELOG.md +++ b/packages/blocks/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 12.15.0 (2023-07-20) + ## 12.14.0 (2023-07-05) ## 12.13.0 (2023-06-23) diff --git a/packages/blocks/package.json b/packages/blocks/package.json index 89ed8b687f447b..b1d1614569c591 100644 --- a/packages/blocks/package.json +++ b/packages/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blocks", - "version": "12.14.0", + "version": "12.15.0", "description": "Block API for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/browserslist-config/CHANGELOG.md b/packages/browserslist-config/CHANGELOG.md index ce9ff2903239b1..2d5508a0978e6f 100644 --- a/packages/browserslist-config/CHANGELOG.md +++ b/packages/browserslist-config/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.21.0 (2023-07-20) + ## 5.20.0 (2023-07-05) ## 5.19.0 (2023-06-23) diff --git a/packages/browserslist-config/package.json b/packages/browserslist-config/package.json index be81cad67529ff..f63ad983599b78 100644 --- a/packages/browserslist-config/package.json +++ b/packages/browserslist-config/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/browserslist-config", - "version": "5.20.0", + "version": "5.21.0", "description": "WordPress Browserslist shared configuration.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/commands/CHANGELOG.md b/packages/commands/CHANGELOG.md index 1645fa29f2b44e..74323358ea6854 100644 --- a/packages/commands/CHANGELOG.md +++ b/packages/commands/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.9.0 (2023-07-20) + ## 0.8.0 (2023-07-05) ## 0.7.0 (2023-06-23) diff --git a/packages/commands/package.json b/packages/commands/package.json index 8b08f115820479..5a94853826f624 100644 --- a/packages/commands/package.json +++ b/packages/commands/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/commands", - "version": "0.8.0", + "version": "0.9.0", "description": "Handles the commands menu.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 8f5d2d946fa389..45ed6d2ec13fc8 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 25.4.0 (2023-07-20) + ### Enhancements - `TextControl`: Add `id` prop to allow for custom IDs in `TextControl`s ([#52028](https://github.com/WordPress/gutenberg/pull/52028)). @@ -12,6 +14,7 @@ - `Popover`: Pin `react-dropdown-menu` version to avoid breaking changes in dependency updates. ([#52356](https://github.com/WordPress/gutenberg/pull/52356)). - `Item`: Unify focus style and add default font styles. ([#52495](https://github.com/WordPress/gutenberg/pull/52495)). - `Toolbar`: Fix toolbar items not being tabbable on the first render. ([#52613](https://github.com/WordPress/gutenberg/pull/52613)) +- `FormTokenField`: Fix token overflow when moving cursor left or right. ([#52662](https://github.com/WordPress/gutenberg/pull/52662)) ## 25.3.0 (2023-07-05) diff --git a/packages/components/package.json b/packages/components/package.json index 455d3daa3c089d..84c2ba3af9c2a6 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/components", - "version": "25.3.0", + "version": "25.4.0", "description": "UI components for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/components/src/form-token-field/styles.ts b/packages/components/src/form-token-field/styles.ts index 55cfbe5e242f5b..ee67f44a5f3244 100644 --- a/packages/components/src/form-token-field/styles.ts +++ b/packages/components/src/form-token-field/styles.ts @@ -9,6 +9,7 @@ import { css } from '@emotion/react'; */ import { Flex } from '../flex'; import { space } from '../ui/utils/space'; +import { boxSizingReset } from '../utils'; type TokensAndInputWrapperProps = { __next40pxDefaultSize: boolean; @@ -27,6 +28,7 @@ const deprecatedPaddings = ( { export const TokensAndInputWrapperFlex = styled( Flex )` padding: 7px; + ${ boxSizingReset } ${ deprecatedPaddings } `; diff --git a/packages/components/src/mobile/image/index.native.js b/packages/components/src/mobile/image/index.native.js index 7f69f0bed3afff..064150ec5f728d 100644 --- a/packages/components/src/mobile/image/index.native.js +++ b/packages/components/src/mobile/image/index.native.js @@ -185,6 +185,13 @@ const ImageComponent = ( { imageHeight && { height: imageHeight }, shapeStyle, ]; + const imageSelectedStyles = [ + usePreferredColorSchemeStyle( + styles.imageBorder, + styles.imageBorderDark + ), + { height: containerSize?.height }, + ]; return ( + ) } { ! imageData ? ( diff --git a/packages/components/src/mobile/image/style.native.scss b/packages/components/src/mobile/image/style.native.scss index c5ccd195993519..f6deb3655f3699 100644 --- a/packages/components/src/mobile/image/style.native.scss +++ b/packages/components/src/mobile/image/style.native.scss @@ -7,7 +7,7 @@ } .imageBorder { - border-color: $blue-medium; + border-color: $blue-40; border-width: 2px; border-style: solid; position: absolute; @@ -16,6 +16,10 @@ height: 100%; } +.imageBorderDark { + border-color: $blue-50; +} + .retryIcon { width: 80px; height: 80px; diff --git a/packages/components/src/tooltip/README.md b/packages/components/src/tooltip/README.md index e4d030681240ca..101d642f39eb2e 100644 --- a/packages/components/src/tooltip/README.md +++ b/packages/components/src/tooltip/README.md @@ -28,7 +28,7 @@ The direction in which the tooltip should open relative to its parent node. Spec - Type: `String` - Required: No -- Default: `"top center"` +- Default: `"bottom"` ### children diff --git a/packages/compose/CHANGELOG.md b/packages/compose/CHANGELOG.md index 7750b279efdd75..8b215c17bb2fdd 100644 --- a/packages/compose/CHANGELOG.md +++ b/packages/compose/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 6.15.0 (2023-07-20) + ## 6.14.0 (2023-07-05) ## 6.13.0 (2023-06-23) diff --git a/packages/compose/package.json b/packages/compose/package.json index af4d539bd978fd..5be8a98640159f 100644 --- a/packages/compose/package.json +++ b/packages/compose/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/compose", - "version": "6.14.0", + "version": "6.15.0", "description": "WordPress higher-order components (HOCs).", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/core-commands/CHANGELOG.md b/packages/core-commands/CHANGELOG.md index b0c207cf0fada0..92306d1289e0a6 100644 --- a/packages/core-commands/CHANGELOG.md +++ b/packages/core-commands/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.7.0 (2023-07-20) + ## 0.6.0 (2023-07-05) ## 0.5.0 (2023-06-23) diff --git a/packages/core-commands/package.json b/packages/core-commands/package.json index 5eee67fca77f62..808a0a32e8c52e 100644 --- a/packages/core-commands/package.json +++ b/packages/core-commands/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/core-commands", - "version": "0.6.0", + "version": "0.7.0", "description": "WordPress core reusable commands.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/core-commands/src/site-editor-navigation-commands.js b/packages/core-commands/src/site-editor-navigation-commands.js index 8f2003d0e08a27..3d551619d63b04 100644 --- a/packages/core-commands/src/site-editor-navigation-commands.js +++ b/packages/core-commands/src/site-editor-navigation-commands.js @@ -13,6 +13,7 @@ import { symbolFilled, styles, navigation, + symbol, } from '@wordpress/icons'; import { privateApis as routerPrivateApis } from '@wordpress/router'; import { getQueryArg, addQueryArgs, getPath } from '@wordpress/url'; @@ -199,8 +200,8 @@ function useSiteEditorBasicNavigationCommands() { result.push( { name: 'core/edit-site/open-template-parts', - label: __( 'Open library' ), - icon: symbolFilled, + label: __( 'Open patterns' ), + icon: symbol, callback: ( { close } ) => { const args = { path: '/patterns', diff --git a/packages/core-data/CHANGELOG.md b/packages/core-data/CHANGELOG.md index 025827081db643..be2bf2ea048dd7 100644 --- a/packages/core-data/CHANGELOG.md +++ b/packages/core-data/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 6.15.0 (2023-07-20) + ## 6.14.0 (2023-07-05) ## 6.13.0 (2023-06-23) diff --git a/packages/core-data/package.json b/packages/core-data/package.json index 24b7869a3b0055..f44297ffb713c8 100644 --- a/packages/core-data/package.json +++ b/packages/core-data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/core-data", - "version": "6.14.0", + "version": "6.15.0", "description": "Access to and manipulation of core WordPress entities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/core-data/src/entity-provider.js b/packages/core-data/src/entity-provider.js index 6cc1e021841b4a..fad9fe693a575b 100644 --- a/packages/core-data/src/entity-provider.js +++ b/packages/core-data/src/entity-provider.js @@ -5,7 +5,7 @@ import { createContext, useContext, useCallback, - useEffect, + useMemo, } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; import { parse, __unstableSerializeAndClean } from '@wordpress/blocks'; @@ -129,7 +129,7 @@ export function useEntityProp( kind, name, prop, _id ) { [ prop ]: newValue, } ); }, - [ kind, name, id, prop ] + [ editEntityRecord, kind, name, id, prop ] ); return [ value, setValue, fullValue ]; @@ -156,12 +156,12 @@ export function useEntityProp( kind, name, prop, _id ) { export function useEntityBlockEditor( kind, name, { id: _id } = {} ) { const providerId = useEntityId( kind, name ); const id = _id ?? providerId; - const { content, blocks, meta } = useSelect( + const { content, editedBlocks, meta } = useSelect( ( select ) => { const { getEditedEntityRecord } = select( STORE_NAME ); const editedRecord = getEditedEntityRecord( kind, name, id ); return { - blocks: editedRecord.blocks, + editedBlocks: editedRecord.blocks, content: editedRecord.content, meta: editedRecord.meta, }; @@ -171,23 +171,15 @@ export function useEntityBlockEditor( kind, name, { id: _id } = {} ) { const { __unstableCreateUndoLevel, editEntityRecord } = useDispatch( STORE_NAME ); - useEffect( () => { - // Load the blocks from the content if not already in state - // Guard against other instances that might have - // set content to a function already or the blocks are already in state. - if ( content && typeof content !== 'function' && ! blocks ) { - const parsedContent = parse( content ); - editEntityRecord( - kind, - name, - id, - { - blocks: parsedContent, - }, - { undoIgnore: true } - ); + const blocks = useMemo( () => { + if ( editedBlocks ) { + return editedBlocks; } - }, [ content ] ); + + return content && typeof content !== 'function' + ? parse( content ) + : EMPTY_ARRAY; + }, [ editedBlocks, content ] ); const updateFootnotes = useCallback( ( _blocks ) => { @@ -356,5 +348,5 @@ export function useEntityBlockEditor( kind, name, { id: _id } = {} ) { [ kind, name, id, updateFootnotes, editEntityRecord ] ); - return [ blocks ?? EMPTY_ARRAY, onInput, onChange ]; + return [ blocks, onInput, onChange ]; } diff --git a/packages/create-block-interactive-template/package.json b/packages/create-block-interactive-template/package.json index 1638b33e648478..cc5ffbff5bf59c 100644 --- a/packages/create-block-interactive-template/package.json +++ b/packages/create-block-interactive-template/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/create-block-interactive-template", - "version": "1.0.0", + "version": "1.1.0", "description": "Template for @wordpress/create-block to create interactive blocks with the Interactivity API.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/create-block-tutorial-template/CHANGELOG.md b/packages/create-block-tutorial-template/CHANGELOG.md index 8d2617e4e5e9a6..49b2a58ff12578 100644 --- a/packages/create-block-tutorial-template/CHANGELOG.md +++ b/packages/create-block-tutorial-template/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 2.26.0 (2023-07-20) + ## 2.25.0 (2023-07-05) ## 2.24.0 (2023-06-23) diff --git a/packages/create-block-tutorial-template/package.json b/packages/create-block-tutorial-template/package.json index 423b7d140266be..2928b728e65fb1 100644 --- a/packages/create-block-tutorial-template/package.json +++ b/packages/create-block-tutorial-template/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/create-block-tutorial-template", - "version": "2.25.0", + "version": "2.26.0", "description": "Template for @wordpress/create-block used in the official WordPress tutorial.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/create-block/CHANGELOG.md b/packages/create-block/CHANGELOG.md index 5044041b949b29..b03a8aca72b506 100644 --- a/packages/create-block/CHANGELOG.md +++ b/packages/create-block/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.22.0 (2023-07-20) + ## 4.21.0 (2023-07-05) ## 4.20.0 (2023-06-23) diff --git a/packages/create-block/package.json b/packages/create-block/package.json index 5f8885ec0375b1..0863c36ca23085 100644 --- a/packages/create-block/package.json +++ b/packages/create-block/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/create-block", - "version": "4.21.0", + "version": "4.22.0", "description": "Generates PHP, JS and CSS code for registering a block for a WordPress plugin.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/customize-widgets/CHANGELOG.md b/packages/customize-widgets/CHANGELOG.md index 45a77305107b36..937ad263da7cb8 100644 --- a/packages/customize-widgets/CHANGELOG.md +++ b/packages/customize-widgets/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.15.0 (2023-07-20) + ## 4.14.0 (2023-07-05) ## 4.13.0 (2023-06-23) diff --git a/packages/customize-widgets/package.json b/packages/customize-widgets/package.json index 96e313d27b9d38..ebb0541e37c361 100644 --- a/packages/customize-widgets/package.json +++ b/packages/customize-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/customize-widgets", - "version": "4.14.0", + "version": "4.15.0", "description": "Widgets blocks in Customizer Module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data-controls/CHANGELOG.md b/packages/data-controls/CHANGELOG.md index b2d3fc117207bc..4ac6dac0b71694 100644 --- a/packages/data-controls/CHANGELOG.md +++ b/packages/data-controls/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.7.0 (2023-07-20) + ## 3.6.0 (2023-07-05) ## 3.5.0 (2023-06-23) diff --git a/packages/data-controls/package.json b/packages/data-controls/package.json index dbe372d1ee515c..084260bdcf9567 100644 --- a/packages/data-controls/package.json +++ b/packages/data-controls/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/data-controls", - "version": "3.6.0", + "version": "3.7.0", "description": "A set of common controls for the @wordpress/data api.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data/CHANGELOG.md b/packages/data/CHANGELOG.md index 54d18172e42b3e..793d50910089a5 100644 --- a/packages/data/CHANGELOG.md +++ b/packages/data/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +### Bug Fix + +- Update the type definitions for dispatched actions by accounting for Promisified return values and thunks. Previously, a dispatched action's return type was the same as the return type of the original action creator, which did not account for how dispatch works internally. (Plain actions get wrapped in a Promise, and thunk actions ultimately resolve to the innermost function's return type). +- Update the type definition for dispatch() to handle string store descriptors correctly. + +## 9.8.0 (2023-07-20) + ## 9.7.0 (2023-07-05) ## 9.6.0 (2023-06-23) @@ -60,7 +67,7 @@ ### Breaking Changes -– Add TypeScript types to the built package (via "types": "build-types" in the package.json) +– Add TypeScript types to the built package (via "types": "build-types" in the package.json) ### Bug Fix @@ -98,9 +105,9 @@ ### New Features -- Enabled thunks by default for all stores and removed the `__experimentalUseThunks` flag. -- Store the resolution errors in store metadata and expose them using `hasResolutionFailed` the `getResolutionError` meta-selectors ([#38669](https://github.com/WordPress/gutenberg/pull/38669)). -- Expose the resolution status (undefined, resolving, finished, error) via the `getResolutionState` meta-selector ([#38669](https://github.com/WordPress/gutenberg/pull/38669)). +- Enabled thunks by default for all stores and removed the `__experimentalUseThunks` flag. +- Store the resolution errors in store metadata and expose them using `hasResolutionFailed` the `getResolutionError` meta-selectors ([#38669](https://github.com/WordPress/gutenberg/pull/38669)). +- Expose the resolution status (undefined, resolving, finished, error) via the `getResolutionState` meta-selector ([#38669](https://github.com/WordPress/gutenberg/pull/38669)). ## 6.2.1 (2022-02-10) diff --git a/packages/data/README.md b/packages/data/README.md index 444548dfe982ff..e9b3a2c192d521 100644 --- a/packages/data/README.md +++ b/packages/data/README.md @@ -499,11 +499,11 @@ dispatch( myCustomStore ).setPrice( 'hammer', 9.75 ); _Parameters_ -- _storeNameOrDescriptor_ `string | T`: The store descriptor. The legacy calling convention of passing the store name is also supported. +- _storeNameOrDescriptor_ `StoreNameOrDescriptor`: The store descriptor. The legacy calling convention of passing the store name is also supported. _Returns_ -- `ActionCreatorsOf< ConfigOf< T > >`: Object containing the action creators. +- `DispatchReturn< StoreNameOrDescriptor >`: Object containing the action creators. ### plugins diff --git a/packages/data/package.json b/packages/data/package.json index 810d48c7e7a10e..d0cf48cf10c139 100644 --- a/packages/data/package.json +++ b/packages/data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/data", - "version": "9.7.0", + "version": "9.8.0", "description": "Data module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data/src/dispatch.ts b/packages/data/src/dispatch.ts index e75eb8eb7bffcb..c1f28c21187cce 100644 --- a/packages/data/src/dispatch.ts +++ b/packages/data/src/dispatch.ts @@ -1,12 +1,7 @@ /** * Internal dependencies */ -import type { - ActionCreatorsOf, - AnyConfig, - ConfigOf, - StoreDescriptor, -} from './types'; +import type { AnyConfig, StoreDescriptor, DispatchReturn } from './types'; import defaultRegistry from './default-registry'; /** @@ -28,8 +23,10 @@ import defaultRegistry from './default-registry'; * ``` * @return Object containing the action creators. */ -export function dispatch< T extends StoreDescriptor< AnyConfig > >( - storeNameOrDescriptor: string | T -): ActionCreatorsOf< ConfigOf< T > > { +export function dispatch< + StoreNameOrDescriptor extends StoreDescriptor< AnyConfig > | string +>( + storeNameOrDescriptor: StoreNameOrDescriptor +): DispatchReturn< StoreNameOrDescriptor > { return defaultRegistry.dispatch( storeNameOrDescriptor ); } diff --git a/packages/data/src/types.ts b/packages/data/src/types.ts index defb7218457c7c..af8cf823852755 100644 --- a/packages/data/src/types.ts +++ b/packages/data/src/types.ts @@ -6,7 +6,7 @@ import type { combineReducers as reduxCombineReducers } from 'redux'; type MapOf< T > = { [ name: string ]: T }; -export type ActionCreator = Function | Generator; +export type ActionCreator = ( ...args: any[] ) => any | Generator; export type Resolver = Function | Generator; export type Selector = Function; @@ -43,6 +43,7 @@ export interface ReduxStoreConfig< controls?: MapOf< Function >; } +// Return type for the useSelect() hook. export type UseSelectReturn< F extends MapSelect | StoreDescriptor< any > > = F extends MapSelect ? ReturnType< F > @@ -50,6 +51,7 @@ export type UseSelectReturn< F extends MapSelect | StoreDescriptor< any > > = ? CurriedSelectorsOf< F > : never; +// Return type for the useDispatch() hook. export type UseDispatchReturn< StoreNameOrDescriptor > = StoreNameOrDescriptor extends StoreDescriptor< any > ? ActionCreatorsOf< ConfigOf< StoreNameOrDescriptor > > @@ -59,9 +61,12 @@ export type UseDispatchReturn< StoreNameOrDescriptor > = export type DispatchFunction = < StoreNameOrDescriptor >( store: StoreNameOrDescriptor -) => StoreNameOrDescriptor extends StoreDescriptor< any > - ? ActionCreatorsOf< ConfigOf< StoreNameOrDescriptor > > - : any; +) => DispatchReturn< StoreNameOrDescriptor >; + +export type DispatchReturn< StoreNameOrDescriptor > = + StoreNameOrDescriptor extends StoreDescriptor< any > + ? ActionCreatorsOf< ConfigOf< StoreNameOrDescriptor > > + : unknown; export type MapSelect = ( select: SelectFunction, @@ -170,9 +175,37 @@ export type ConfigOf< S > = S extends StoreDescriptor< infer C > ? C : never; export type ActionCreatorsOf< Config extends AnyConfig > = Config extends ReduxStoreConfig< any, infer ActionCreators, any > - ? ActionCreators + ? PromisifiedActionCreators< ActionCreators > : never; +// Takes an object containing all action creators for a store and updates the +// return type of each action creator to account for internal registry details -- +// for example, dispatched actions are wrapped with a Promise. +export type PromisifiedActionCreators< + ActionCreators extends MapOf< ActionCreator > +> = { + [ Action in keyof ActionCreators ]: PromisifyActionCreator< + ActionCreators[ Action ] + >; +}; + +// Wraps action creator return types with a Promise and handles thunks. +export type PromisifyActionCreator< Action extends ActionCreator > = ( + ...args: Parameters< Action > +) => Promise< + ReturnType< Action > extends ( ..._args: any[] ) => any + ? ThunkReturnType< Action > + : ReturnType< Action > +>; + +// A thunk is an action creator which returns a function, which can optionally +// return a Promise. The double ReturnType unwraps the innermost function's +// return type, and Awaited gets the type the Promise resolves to. If the return +// type is not a Promise, Awaited returns that original type. +export type ThunkReturnType< Action extends ActionCreator > = Awaited< + ReturnType< ReturnType< Action > > +>; + type SelectorsOf< Config extends AnyConfig > = Config extends ReduxStoreConfig< any, any, diff --git a/packages/date/CHANGELOG.md b/packages/date/CHANGELOG.md index a81474839cb264..db57970a51b5f7 100644 --- a/packages/date/CHANGELOG.md +++ b/packages/date/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.38.0 (2023-07-20) + ## 4.37.0 (2023-07-05) ## 4.36.0 (2023-06-23) diff --git a/packages/date/package.json b/packages/date/package.json index 436c85cd27da05..94dd630beef218 100644 --- a/packages/date/package.json +++ b/packages/date/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/date", - "version": "4.37.0", + "version": "4.38.0", "description": "Date module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dependency-extraction-webpack-plugin/CHANGELOG.md b/packages/dependency-extraction-webpack-plugin/CHANGELOG.md index 74fbd51bb0f36a..4f50c48c15f13f 100644 --- a/packages/dependency-extraction-webpack-plugin/CHANGELOG.md +++ b/packages/dependency-extraction-webpack-plugin/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.21.0 (2023-07-20) + ## 4.20.0 (2023-07-05) ## 4.19.0 (2023-06-23) diff --git a/packages/dependency-extraction-webpack-plugin/package.json b/packages/dependency-extraction-webpack-plugin/package.json index 6695e5e7f6002d..b43f1938ae0233 100644 --- a/packages/dependency-extraction-webpack-plugin/package.json +++ b/packages/dependency-extraction-webpack-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dependency-extraction-webpack-plugin", - "version": "4.20.0", + "version": "4.21.0", "description": "Extract WordPress script dependencies from webpack bundles.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/deprecated/CHANGELOG.md b/packages/deprecated/CHANGELOG.md index ae4cc1fccc3e1d..313e6150698709 100644 --- a/packages/deprecated/CHANGELOG.md +++ b/packages/deprecated/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.38.0 (2023-07-20) + ## 3.37.0 (2023-07-05) ## 3.36.0 (2023-06-23) diff --git a/packages/deprecated/package.json b/packages/deprecated/package.json index 09a05bef90c30a..3ea78ae42b0059 100644 --- a/packages/deprecated/package.json +++ b/packages/deprecated/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/deprecated", - "version": "3.37.0", + "version": "3.38.0", "description": "Deprecation utility for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/docgen/CHANGELOG.md b/packages/docgen/CHANGELOG.md index 7cc252c98b0b0f..a52146b3fe623f 100644 --- a/packages/docgen/CHANGELOG.md +++ b/packages/docgen/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.47.0 (2023-07-20) + ## 1.46.0 (2023-07-05) ## 1.45.0 (2023-06-23) diff --git a/packages/docgen/package.json b/packages/docgen/package.json index ee480b67454dd1..33ad216c2b87d5 100644 --- a/packages/docgen/package.json +++ b/packages/docgen/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/docgen", - "version": "1.46.0", + "version": "1.47.0", "description": "Autogenerate public API documentation from exports and JSDoc comments.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dom-ready/CHANGELOG.md b/packages/dom-ready/CHANGELOG.md index fa80e8aa49336d..08dabc9ce566c5 100644 --- a/packages/dom-ready/CHANGELOG.md +++ b/packages/dom-ready/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.38.0 (2023-07-20) + ## 3.37.0 (2023-07-05) ## 3.36.0 (2023-06-23) diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index d813006f11e4e9..9b5d2e4ea4cb33 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "3.37.0", + "version": "3.38.0", "description": "Execute callback after the DOM is loaded.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dom/CHANGELOG.md b/packages/dom/CHANGELOG.md index 542f2f12b91420..76af58f9c4911f 100644 --- a/packages/dom/CHANGELOG.md +++ b/packages/dom/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.38.0 (2023-07-20) + ## 3.37.0 (2023-07-05) ## 3.36.0 (2023-06-23) diff --git a/packages/dom/package.json b/packages/dom/package.json index 87bdd70de09d74..7bf5fe2b2a9171 100644 --- a/packages/dom/package.json +++ b/packages/dom/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom", - "version": "3.37.0", + "version": "3.38.0", "description": "DOM utilities module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-test-utils-playwright/CHANGELOG.md b/packages/e2e-test-utils-playwright/CHANGELOG.md index 7f55bbad7c8186..e00c07e01ec6a0 100644 --- a/packages/e2e-test-utils-playwright/CHANGELOG.md +++ b/packages/e2e-test-utils-playwright/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.6.0 (2023-07-20) + ## 0.5.0 (2023-07-05) ## 0.4.0 (2023-06-23) diff --git a/packages/e2e-test-utils-playwright/package.json b/packages/e2e-test-utils-playwright/package.json index 5320239223ba57..56f81448927ba6 100644 --- a/packages/e2e-test-utils-playwright/package.json +++ b/packages/e2e-test-utils-playwright/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-test-utils-playwright", - "version": "0.5.0", + "version": "0.6.0", "description": "End-To-End (E2E) test utils for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-test-utils-playwright/src/request-utils/plugins.ts b/packages/e2e-test-utils-playwright/src/request-utils/plugins.ts index 5f1639f109d2e3..f018d7d9f3903b 100644 --- a/packages/e2e-test-utils-playwright/src/request-utils/plugins.ts +++ b/packages/e2e-test-utils-playwright/src/request-utils/plugins.ts @@ -27,25 +27,55 @@ async function getPluginsMap( this: RequestUtils, forceRefetch = false ) { for ( const plugin of plugins ) { // Ideally, we should be using sanitize_title() in PHP rather than kebabCase(), // but we don't have the exact port of it in JS. - this.pluginsMap[ kebabCase( plugin.name ) ] = plugin.plugin; + // This is a good approximation though. + const slug = kebabCase( plugin.name.toLowerCase() ); + this.pluginsMap[ slug ] = plugin.plugin; } return this.pluginsMap; } /** - * Activates an installed plugin. + * Finds a plugin in the plugin map. * - * @param this RequestUtils. - * @param slug Plugin slug. + * Attempts to provide a helpful error message if not found. + * + * @param slug Plugin slug. + * @param pluginsMap Plugins map. */ -async function activatePlugin( this: RequestUtils, slug: string ) { - const pluginsMap = await this.getPluginsMap(); +function getPluginFromMap( + slug: string, + pluginsMap: Record< string, string > +) { const plugin = pluginsMap[ slug ]; if ( ! plugin ) { + for ( const key of Object.keys( pluginsMap ) ) { + if ( + key.toLowerCase().replace( /-/g, '' ) === + slug.toLowerCase().replace( /-/g, '' ) + ) { + throw new Error( + `The plugin "${ slug }" isn't installed. Did you perhaps mean "${ key }"?` + ); + } + } + throw new Error( `The plugin "${ slug }" isn't installed` ); } + return plugin; +} + +/** + * Activates an installed plugin. + * + * @param this RequestUtils. + * @param slug Plugin slug. + */ +async function activatePlugin( this: RequestUtils, slug: string ) { + const pluginsMap = await this.getPluginsMap(); + const plugin = getPluginFromMap( slug, pluginsMap ); + await this.rest( { method: 'PUT', path: `/wp/v2/plugins/${ plugin }`, @@ -61,11 +91,7 @@ async function activatePlugin( this: RequestUtils, slug: string ) { */ async function deactivatePlugin( this: RequestUtils, slug: string ) { const pluginsMap = await this.getPluginsMap(); - const plugin = pluginsMap[ slug ]; - - if ( ! plugin ) { - throw new Error( `The plugin "${ slug }" isn't installed` ); - } + const plugin = getPluginFromMap( slug, pluginsMap ); await this.rest( { method: 'PUT', diff --git a/packages/e2e-test-utils/CHANGELOG.md b/packages/e2e-test-utils/CHANGELOG.md index e5a7bd38190174..80ad7d9186ba3c 100644 --- a/packages/e2e-test-utils/CHANGELOG.md +++ b/packages/e2e-test-utils/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 10.9.0 (2023-07-20) + ## 10.8.0 (2023-07-05) ## 10.7.0 (2023-06-23) diff --git a/packages/e2e-test-utils/package.json b/packages/e2e-test-utils/package.json index 1929472c8160e6..2683fafe79d9f4 100644 --- a/packages/e2e-test-utils/package.json +++ b/packages/e2e-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-test-utils", - "version": "10.8.0", + "version": "10.9.0", "description": "End-To-End (E2E) test utils for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-tests/CHANGELOG.md b/packages/e2e-tests/CHANGELOG.md index c591ca9caa0bd7..5ecc8fe2ed6235 100644 --- a/packages/e2e-tests/CHANGELOG.md +++ b/packages/e2e-tests/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 7.9.0 (2023-07-20) + ## 7.8.0 (2023-07-05) ## 7.7.0 (2023-06-23) diff --git a/packages/e2e-tests/package.json b/packages/e2e-tests/package.json index aaef06e196b7c0..f4c678251bab0e 100644 --- a/packages/e2e-tests/package.json +++ b/packages/e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-tests", - "version": "7.8.0", + "version": "7.9.0", "description": "End-To-End (E2E) tests for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-style/block.json b/packages/e2e-tests/plugins/interactive-blocks/directive-style/block.json new file mode 100644 index 00000000000000..6cbfa57b0784f1 --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-style/block.json @@ -0,0 +1,14 @@ +{ + "apiVersion": 2, + "name": "test/directive-style", + "title": "E2E Interactivity tests - directive style", + "category": "text", + "icon": "heart", + "description": "", + "supports": { + "interactivity": true + }, + "textdomain": "e2e-interactivity", + "viewScript": "directive-style-view", + "render": "file:./render.php" +} diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-style/render.php b/packages/e2e-tests/plugins/interactive-blocks/directive-style/render.php new file mode 100644 index 00000000000000..4272333c3ec277 --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-style/render.php @@ -0,0 +1,93 @@ + + +
    + + + + +
    Don't change style if callback returns same value on hydration
    + +
    Remove style if callback returns falsy value on hydration
    + +
    Change style if callback returns a new value on hydration
    + +
    Handles multiple styles and callbacks on hydration
    + +
    Can add style when style attribute is missing on hydration
    + +
    Can toggle style
    + +
    Can remove style
    + +
    Can toggle style in the middle
    + +
    Handles styles names with hyphens
    + +
    +
    + +
    +
    diff --git a/packages/e2e-tests/plugins/interactive-blocks/directive-style/view.js b/packages/e2e-tests/plugins/interactive-blocks/directive-style/view.js new file mode 100644 index 00000000000000..04fbf1aab11403 --- /dev/null +++ b/packages/e2e-tests/plugins/interactive-blocks/directive-style/view.js @@ -0,0 +1,22 @@ +( ( { wp } ) => { + const { store } = wp.interactivity; + + store( { + state: { + falseValue: false, + color: "red", + border: "2px solid yellow" + }, + actions: { + toggleColor: ( { state } ) => { + state.color = state.color === "red" ? "blue" : "red"; + }, + switchColorToFalse: ({ state }) => { + state.color = false; + }, + toggleContext: ( { context } ) => { + context.color = context.color === "red" ? "blue" : "red"; + }, + }, + } ); +} )( window ); diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap index fb3f84595e5e2b..cbcbf0402f8c96 100644 --- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap +++ b/packages/e2e-tests/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap @@ -22,10 +22,11 @@ exports[`InnerBlocks Template Sync Ensures blocks without locking are kept intac

    Content…

    - -

    added paragraph

    - -" + +

    added paragraph

    + + +" `; exports[`InnerBlocks Template Sync Removes blocks that are not expected by the template if a lock all exists 1`] = ` diff --git a/packages/edit-post/CHANGELOG.md b/packages/edit-post/CHANGELOG.md index 5ddb12e69276dd..f99c97f29a0e6a 100644 --- a/packages/edit-post/CHANGELOG.md +++ b/packages/edit-post/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 7.15.0 (2023-07-20) + ## 7.14.0 (2023-07-05) ## 7.13.0 (2023-06-23) diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index 26310deccf4481..06f538ac4bf291 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-post", - "version": "7.14.0", + "version": "7.15.0", "description": "Edit Post module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-post/src/components/header/header-toolbar/index.native.js b/packages/edit-post/src/components/header/header-toolbar/index.native.js index 692136b2c3c204..53574b15306cee 100644 --- a/packages/edit-post/src/components/header/header-toolbar/index.native.js +++ b/packages/edit-post/src/components/header/header-toolbar/index.native.js @@ -100,6 +100,7 @@ function HeaderToolbar( { ( blockType ) => () => { insertBlock( createBlock( blockType ), undefined, undefined, true, { source: 'inserter_menu', + inserterMethod: 'quick-inserter', } ); }, [ insertBlock ] diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index b7aa8bcd025af7..87fc0aa408516d 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -12,6 +12,7 @@ import { UnsavedChangesWarning, EditorNotices, EditorKeyboardShortcutsRegister, + EditorKeyboardShortcuts, EditorSnackbars, PostSyncStatusModal, store as editorStore, @@ -203,6 +204,7 @@ function Layout( { styles } ) { + - { isRichEditingEnabled && (

    { __( 'Editing code' ) }

    diff --git a/packages/edit-post/src/components/visual-editor/index.js b/packages/edit-post/src/components/visual-editor/index.js index 29e6e15da4579f..fe14ef05561134 100644 --- a/packages/edit-post/src/components/visual-editor/index.js +++ b/packages/edit-post/src/components/visual-editor/index.js @@ -6,11 +6,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { - VisualEditorGlobalKeyboardShortcuts, - PostTitle, - store as editorStore, -} from '@wordpress/editor'; +import { PostTitle, store as editorStore } from '@wordpress/editor'; import { WritingFlow, BlockList, @@ -345,7 +341,6 @@ export default function VisualEditor( { styles } ) { 'is-template-mode': isTemplateMode, } ) } > - { const { isFeatureActive, - __experimentalGetPreviewDeviceType, isEditingTemplate, getEditedPostTemplate, getHiddenBlockTypes, @@ -80,9 +79,7 @@ function Editor( { postId, postType, settings, initialEdits, ...props } ) { const canEditTemplate = canUser( 'create', 'templates' ); return { - hasFixedToolbar: - isFeatureActive( 'fixedToolbar' ) || - __experimentalGetPreviewDeviceType() !== 'Desktop', + hasFixedToolbar: isFeatureActive( 'fixedToolbar' ), focusMode: isFeatureActive( 'focusMode' ), isDistractionFree: isFeatureActive( 'distractionFree' ), hasInlineToolbar: isFeatureActive( 'inlineToolbar' ), diff --git a/packages/edit-site/CHANGELOG.md b/packages/edit-site/CHANGELOG.md index cc77bca0e7375c..734db396d059e7 100644 --- a/packages/edit-site/CHANGELOG.md +++ b/packages/edit-site/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 5.15.0 (2023-07-20) + ## 5.14.0 (2023-07-05) ## 5.13.0 (2023-06-23) diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index 06e52ed9fd53e7..b6778e46e57543 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-site", - "version": "5.14.0", + "version": "5.15.0", "description": "Edit Site Page module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-site/src/components/add-new-pattern/index.js b/packages/edit-site/src/components/add-new-pattern/index.js index 7a820558bc3acc..3879498834f42a 100644 --- a/packages/edit-site/src/components/add-new-pattern/index.js +++ b/packages/edit-site/src/components/add-new-pattern/index.js @@ -57,21 +57,26 @@ export default function AddNewPattern() { setShowTemplatePartModal( false ); } + const controls = [ + { + icon: symbol, + onClick: () => setShowPatternModal( true ), + title: __( 'Create pattern' ), + }, + ]; + + if ( ! isTemplatePartsMode ) { + controls.push( { + icon: symbolFilled, + onClick: () => setShowTemplatePartModal( true ), + title: __( 'Create template part' ), + } ); + } + return ( <> setShowTemplatePartModal( true ), - title: __( 'Create template part' ), - }, - { - icon: symbol, - onClick: () => setShowPatternModal( true ), - title: __( 'Create pattern' ), - }, - ].filter( Boolean ) } + controls={ controls } toggleProps={ { as: SidebarButton, } } diff --git a/packages/edit-site/src/components/block-editor/use-site-editor-settings.js b/packages/edit-site/src/components/block-editor/use-site-editor-settings.js index 3d5d05c35fa74e..d70a88e8215c02 100644 --- a/packages/edit-site/src/components/block-editor/use-site-editor-settings.js +++ b/packages/edit-site/src/components/block-editor/use-site-editor-settings.js @@ -11,6 +11,78 @@ import { store as editSiteStore } from '../../store'; import { unlock } from '../../lock-unlock'; import inserterMediaCategories from './inserter-media-categories'; +function useArchiveLabel( templateSlug ) { + const taxonomyMatches = templateSlug?.match( + /^(category|tag|taxonomy-([^-]+))$|^(((category|tag)|taxonomy-([^-]+))-(.+))$/ + ); + let taxonomy; + let term; + let isAuthor = false; + let authorSlug; + if ( taxonomyMatches ) { + // If is for a all taxonomies of a type + if ( taxonomyMatches[ 1 ] ) { + taxonomy = taxonomyMatches[ 2 ] + ? taxonomyMatches[ 2 ] + : taxonomyMatches[ 1 ]; + } + // If is for a all taxonomies of a type + else if ( taxonomyMatches[ 3 ] ) { + taxonomy = taxonomyMatches[ 6 ] + ? taxonomyMatches[ 6 ] + : taxonomyMatches[ 4 ]; + term = taxonomyMatches[ 7 ]; + } + taxonomy = taxonomy === 'tag' ? 'post_tag' : taxonomy; + + //getTaxonomy( 'category' ); + //wp.data.select('core').getEntityRecords( 'taxonomy', 'category', {slug: 'newcat'} ); + } else { + const authorMatches = templateSlug?.match( /^(author)$|^author-(.+)$/ ); + if ( authorMatches ) { + isAuthor = true; + if ( authorMatches[ 2 ] ) { + authorSlug = authorMatches[ 2 ]; + } + } + } + return useSelect( + ( select ) => { + const { getEntityRecords, getTaxonomy, getAuthors } = + select( coreStore ); + let archiveTypeLabel; + let archiveNameLabel; + if ( taxonomy ) { + archiveTypeLabel = + getTaxonomy( taxonomy )?.labels?.singular_name; + } + if ( term ) { + const records = getEntityRecords( 'taxonomy', taxonomy, { + slug: term, + per_page: 1, + } ); + if ( records && records[ 0 ] ) { + archiveNameLabel = records[ 0 ].name; + } + } + if ( isAuthor ) { + archiveTypeLabel = 'Author'; + if ( authorSlug ) { + const authorRecords = getAuthors( { slug: authorSlug } ); + if ( authorRecords && authorRecords[ 0 ] ) { + archiveNameLabel = authorRecords[ 0 ].name; + } + } + } + return { + archiveTypeLabel, + archiveNameLabel, + }; + }, + [ authorSlug, isAuthor, taxonomy, term ] + ); +} + export default function useSiteEditorSettings() { const { setIsInserterOpened } = useDispatch( editSiteStore ); const { storedSettings, canvasMode, templateType } = useSelect( @@ -34,14 +106,27 @@ export default function useSiteEditorSettings() { storedSettings.__experimentalAdditionalBlockPatternCategories ?? // WP 6.0 storedSettings.__experimentalBlockPatternCategories; // WP 5.9 - const { restBlockPatterns, restBlockPatternCategories } = useSelect( - ( select ) => ( { - restBlockPatterns: select( coreStore ).getBlockPatterns(), - restBlockPatternCategories: - select( coreStore ).getBlockPatternCategories(), - } ), - [] - ); + const { restBlockPatterns, restBlockPatternCategories, templateSlug } = + useSelect( ( select ) => { + const { getEditedPostType, getEditedPostId } = + select( editSiteStore ); + const { getEditedEntityRecord } = select( coreStore ); + const usedPostType = getEditedPostType(); + const usedPostId = getEditedPostId(); + const _record = getEditedEntityRecord( + 'postType', + usedPostType, + usedPostId + ); + return { + restBlockPatterns: select( coreStore ).getBlockPatterns(), + restBlockPatternCategories: + select( coreStore ).getBlockPatternCategories(), + templateSlug: _record.slug, + }; + }, [] ); + const archiveLabels = useArchiveLabel( templateSlug ); + const blockPatterns = useMemo( () => [ @@ -87,6 +172,15 @@ export default function useSiteEditorSettings() { __experimentalBlockPatterns: blockPatterns, __experimentalBlockPatternCategories: blockPatternCategories, focusMode: canvasMode === 'view' && focusMode ? false : focusMode, + __experimentalArchiveTitleTypeLabel: archiveLabels.archiveTypeLabel, + __experimentalArchiveTitleNameLabel: archiveLabels.archiveNameLabel, }; - }, [ storedSettings, blockPatterns, blockPatternCategories, canvasMode ] ); + }, [ + storedSettings, + blockPatterns, + blockPatternCategories, + canvasMode, + archiveLabels.archiveTypeLabel, + archiveLabels.archiveNameLabel, + ] ); } diff --git a/packages/edit-site/src/components/code-editor/code-editor-text-area.js b/packages/edit-site/src/components/code-editor/code-editor-text-area.js deleted file mode 100644 index 1a907ca8e59f68..00000000000000 --- a/packages/edit-site/src/components/code-editor/code-editor-text-area.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * External dependencies - */ -import Textarea from 'react-autosize-textarea'; - -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { useEffect, useState, useRef } from '@wordpress/element'; -import { useInstanceId } from '@wordpress/compose'; -import { VisuallyHidden } from '@wordpress/components'; - -export default function CodeEditorTextArea( { value, onChange, onInput } ) { - const [ stateValue, setStateValue ] = useState( value ); - const [ isDirty, setIsDirty ] = useState( false ); - const instanceId = useInstanceId( CodeEditorTextArea ); - const valueRef = useRef(); - - if ( ! isDirty && stateValue !== value ) { - setStateValue( value ); - } - - /** - * Handles a textarea change event to notify the onChange prop callback and - * reflect the new value in the component's own state. This marks the start - * of the user's edits, if not already changed, preventing future props - * changes to value from replacing the rendered value. This is expected to - * be followed by a reset to dirty state via `stopEditing`. - * - * @see stopEditing - * - * @param {Event} event Change event. - */ - const onChangeHandler = ( event ) => { - const newValue = event.target.value; - onInput( newValue ); - setStateValue( newValue ); - setIsDirty( true ); - valueRef.current = newValue; - }; - - /** - * Function called when the user has completed their edits, responsible for - * ensuring that changes, if made, are surfaced to the onPersist prop - * callback and resetting dirty state. - */ - const stopEditing = () => { - if ( isDirty ) { - onChange( stateValue ); - setIsDirty( false ); - } - }; - - // Ensure changes aren't lost when component unmounts. - useEffect( () => { - return () => { - if ( valueRef.current ) { - onChange( valueRef.current ); - } - }; - }, [] ); - - return ( - <> - - { __( 'Type text or HTML' ) } - -