diff --git a/assets/src/block-editor/components/amp-preview-button.js b/assets/src/block-editor/components/preview-menu-item.js similarity index 89% rename from assets/src/block-editor/components/amp-preview-button.js rename to assets/src/block-editor/components/preview-menu-item.js index e2295f2e1e6..ab21036e721 100644 --- a/assets/src/block-editor/components/amp-preview-button.js +++ b/assets/src/block-editor/components/preview-menu-item.js @@ -6,7 +6,8 @@ import PropTypes from 'prop-types'; /** * WordPress dependencies */ -import { Button, Icon, VisuallyHidden } from '@wordpress/components'; +import { PluginPreviewMenuItem } from '@wordpress/editor'; +import { Icon, VisuallyHidden } from '@wordpress/components'; import { compose } from '@wordpress/compose'; import { withDispatch, withSelect } from '@wordpress/data'; import { Component, createRef, renderToString } from '@wordpress/element'; @@ -16,7 +17,7 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import { isAMPEnabled } from '../helpers'; -import { AMPFilledIcon, AMPBlackIcon } from '../../icons'; +import { AMPBlackIcon } from '../../icons'; /** * Writes the message and graphic in the new preview window that was opened. @@ -95,11 +96,10 @@ function writeInterstitialMessage(targetDocument) { } /** - * A 'Preview AMP' button, forked from the Core 'Preview' button: . + * A 'Preview AMP' Menu Item. * - * @see https://github.com/WordPress/gutenberg/blob/95e769df1f82f6b0ef587d81af65dd2f48cd1c38/packages/editor/src/components/post-preview-button/index.js#L95-L200 */ -class AmpPreviewButton extends Component { +class AmpPreviewMenuItem extends Component { /** * Constructs the class. * @@ -108,7 +108,7 @@ class AmpPreviewButton extends Component { constructor(...args) { super(...args); - this.buttonRef = createRef(); + this.itemRef = createRef(); this.openPreviewWindow = this.openPreviewWindow.bind(this); } @@ -139,8 +139,8 @@ class AmpPreviewButton extends Component { if (previewWindow && !previewWindow.closed) { previewWindow.location = url; - if (this.buttonRef.current) { - this.buttonRef.current.focus(); + if (this.itemRef.current) { + this.itemRef.current.focus(); } } } @@ -159,7 +159,7 @@ class AmpPreviewButton extends Component { * @param {Event} event The DOM event. */ openPreviewWindow(event) { - // Our Preview button has its 'href' and 'target' set correctly for a11y + // Our Preview Menu Item has its 'href' and 'target' set correctly for a11y // purposes. Unfortunately, though, we can't rely on the default 'click' // handler since sometimes it incorrectly opens a new tab instead of reusing // the existing one. @@ -208,7 +208,6 @@ class AmpPreviewButton extends Component { currentPostLink, errorMessages, isEnabled, - isSaveable, isStandardMode, } = this.props; @@ -221,29 +220,29 @@ class AmpPreviewButton extends Component { isEnabled && !errorMessages.length && !isStandardMode && ( - + ) ); } } -AmpPreviewButton.propTypes = { +AmpPreviewMenuItem.propTypes = { autosave: PropTypes.func.isRequired, currentPostLink: PropTypes.string.isRequired, postId: PropTypes.number.isRequired, @@ -251,7 +250,6 @@ AmpPreviewButton.propTypes = { isAutosaveable: PropTypes.bool.isRequired, isDraft: PropTypes.bool.isRequired, isEnabled: PropTypes.bool.isRequired, - isSaveable: PropTypes.bool.isRequired, savePost: PropTypes.func.isRequired, errorMessages: PropTypes.array, isStandardMode: PropTypes.bool, @@ -308,4 +306,4 @@ export default compose([ autosave: dispatch('core/editor').autosave, savePost: dispatch('core/editor').savePost, })), -])(AmpPreviewButton); +])(AmpPreviewMenuItem); diff --git a/assets/src/block-editor/plugins/amp-preview-item.js b/assets/src/block-editor/plugins/amp-preview-item.js new file mode 100644 index 00000000000..717c0b7e1dc --- /dev/null +++ b/assets/src/block-editor/plugins/amp-preview-item.js @@ -0,0 +1,15 @@ +/** + * Internal dependencies + */ +import { AMPFilledIcon } from '../../icons'; +import AmpPreviewMenuItem from '../components/preview-menu-item'; + +export const name = 'amp-preview-menu-item'; + +export const icon = ( + +); + +export const onlyPaired = true; + +export const render = AmpPreviewMenuItem; diff --git a/assets/src/block-editor/plugins/wrapped-amp-preview-button.js b/assets/src/block-editor/plugins/wrapped-amp-preview-button.js deleted file mode 100644 index 68bc0065ba1..00000000000 --- a/assets/src/block-editor/plugins/wrapped-amp-preview-button.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * WordPress dependencies - */ -import { createPortal, useLayoutEffect, useRef } from '@wordpress/element'; -import { useSelect } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import AmpPreviewButton from '../components/amp-preview-button'; - -/** - * A wrapper for the AMP preview button that renders it immediately after the 'Post' preview button, when present. - */ -function WrappedAmpPreviewButton() { - const root = useRef(null); - const referenceNode = useRef(null); - - const { isEditedPostSaveable, isViewable } = useSelect( - (select) => ({ - isEditedPostSaveable: select('core/editor').isEditedPostSaveable(), - isViewable: select('core').getPostType( - select('core/editor').getEditedPostAttribute('type') - )?.viewable, - }), - [] - ); - - useLayoutEffect(() => { - // The AMP preview button should always be inserted right before the publish/update button. - referenceNode.current = document.querySelector( - '.editor-post-publish-button__button' - ); - - if (referenceNode.current?.parentNode) { - if (!root.current) { - root.current = document.createElement('div'); - root.current.className = 'amp-wrapper-post-preview'; - } - - referenceNode.current.parentNode.insertBefore( - root.current, - referenceNode.current - ); - } - - return () => { - if (referenceNode.current && root.current) { - referenceNode.current.parentNode.removeChild(root.current); - referenceNode.current = null; - } - }; - // AMP Preview button should be "refreshed" whenever settings in the post editor header are re-rendered. - // The following properties may indicate a change in the toolbar layout: - // - Viewable property gets defined once the toolbar has been rendered. - // - When saveable property changes, the toolbar is reshuffled heavily. - }, [isEditedPostSaveable, isViewable]); - - return root.current - ? createPortal(, root.current) - : null; -} - -export const name = 'amp-preview-button-wrapper'; - -export const onlyPaired = true; - -export const render = WrappedAmpPreviewButton; diff --git a/package-lock.json b/package-lock.json index a9c140f5ca9..e040bd69125 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@wordpress/compose": "7.2.0", "@wordpress/date": "5.2.0", "@wordpress/dom-ready": "4.2.0", - "@wordpress/editor": "14.2.0", + "@wordpress/editor": "14.11.0", "@wordpress/element": "6.2.0", "@wordpress/escape-html": "3.2.0", "@wordpress/html-entities": "4.2.0", @@ -2068,9 +2068,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", + "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -7005,6 +7005,68 @@ "react": "^18.0.0" } }, + "node_modules/@wordpress/dataviews": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/dataviews/-/dataviews-4.7.0.tgz", + "integrity": "sha512-Uc6iKqo7kbeX7eB1TjcWakD7wLLSCeo+61H0r/OnHWBBV61UVl1IekZ2QLbfVDl1wTLYKMZcz49g1WcB6iidZA==", + "dependencies": { + "@ariakit/react": "^0.4.10", + "@babel/runtime": "7.25.7", + "@wordpress/components": "*", + "@wordpress/compose": "*", + "@wordpress/data": "*", + "@wordpress/element": "*", + "@wordpress/i18n": "*", + "@wordpress/icons": "*", + "@wordpress/primitives": "*", + "@wordpress/private-apis": "*", + "@wordpress/warning": "*", + "clsx": "^2.1.1", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, + "node_modules/@wordpress/dataviews/node_modules/@ariakit/core": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/@ariakit/core/-/core-0.4.12.tgz", + "integrity": "sha512-+NNpy88tdP/w9mOBPuDrMTbtapPbo/8yVIzpQB7TAmN0sPh/Cq3nU1f2KCTCIujPmwRvAcMSW9UHOlFmbKEPOA==" + }, + "node_modules/@wordpress/dataviews/node_modules/@ariakit/react": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/@ariakit/react/-/react-0.4.13.tgz", + "integrity": "sha512-pTGYgoqCojfyt2xNJ5VQhejxXwwtcP7VDDqcnnVChv7TA2TWWyYerJ5m4oxViI1pgeNqnHZwKlQ79ZipF7W2kQ==", + "dependencies": { + "@ariakit/react-core": "0.4.13" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ariakit" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@wordpress/dataviews/node_modules/@ariakit/react-core": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/@ariakit/react-core/-/react-core-0.4.13.tgz", + "integrity": "sha512-iIjQeupP9d0pOubOzX4a0UPXbhXbp0ZCduDpkv7+u/pYP/utk/YRECD0M/QpZr6YSeltmDiNxKjdyK8r9Yhv4Q==", + "dependencies": { + "@ariakit/core": "0.4.12", + "@floating-ui/dom": "^1.0.0", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/@wordpress/date": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-5.2.0.tgz", @@ -7167,44 +7229,46 @@ } }, "node_modules/@wordpress/editor": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-14.2.0.tgz", - "integrity": "sha512-1g2ceuV+pptw5isVyq9XtbiBU7wZrz5AVhUwATlCjrEOZePR9hCAd7TCcflEUB6KNqKWyNegCySOgr0DUc3DuQ==", - "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.2.0", - "@wordpress/api-fetch": "^7.2.0", - "@wordpress/blob": "^4.2.0", - "@wordpress/block-editor": "^13.2.0", - "@wordpress/blocks": "^13.2.0", - "@wordpress/commands": "^1.2.0", - "@wordpress/components": "^28.2.0", - "@wordpress/compose": "^7.2.0", - "@wordpress/core-data": "^7.2.0", - "@wordpress/data": "^10.2.0", - "@wordpress/date": "^5.2.0", - "@wordpress/deprecated": "^4.2.0", - "@wordpress/dom": "^4.2.0", - "@wordpress/element": "^6.2.0", - "@wordpress/hooks": "^4.2.0", - "@wordpress/html-entities": "^4.2.0", - "@wordpress/i18n": "^5.2.0", - "@wordpress/icons": "^10.2.0", - "@wordpress/interface": "^6.2.0", - "@wordpress/keyboard-shortcuts": "^5.2.0", - "@wordpress/keycodes": "^4.2.0", - "@wordpress/media-utils": "^5.2.0", - "@wordpress/notices": "^5.2.0", - "@wordpress/patterns": "^2.2.0", - "@wordpress/plugins": "^7.2.0", - "@wordpress/preferences": "^4.2.0", - "@wordpress/private-apis": "^1.2.0", - "@wordpress/reusable-blocks": "^5.2.0", - "@wordpress/rich-text": "^7.2.0", - "@wordpress/server-side-render": "^5.2.0", - "@wordpress/url": "^4.2.0", - "@wordpress/warning": "^3.2.0", - "@wordpress/wordcount": "^4.2.0", + "version": "14.11.0", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-14.11.0.tgz", + "integrity": "sha512-XNwBZ54yQrZszum7OW4wAbFFs7lKlwTkj9ILnbc+a6fuCE9Pg6On/vbtDmRJVXi0TrRb+mY2VhNrsXJybdleQQ==", + "dependencies": { + "@babel/runtime": "7.25.7", + "@wordpress/a11y": "*", + "@wordpress/api-fetch": "*", + "@wordpress/blob": "*", + "@wordpress/block-editor": "*", + "@wordpress/blocks": "*", + "@wordpress/commands": "*", + "@wordpress/components": "*", + "@wordpress/compose": "*", + "@wordpress/core-data": "*", + "@wordpress/data": "*", + "@wordpress/dataviews": "*", + "@wordpress/date": "*", + "@wordpress/deprecated": "*", + "@wordpress/dom": "*", + "@wordpress/element": "*", + "@wordpress/fields": "*", + "@wordpress/hooks": "*", + "@wordpress/html-entities": "*", + "@wordpress/i18n": "*", + "@wordpress/icons": "*", + "@wordpress/interface": "*", + "@wordpress/keyboard-shortcuts": "*", + "@wordpress/keycodes": "*", + "@wordpress/media-utils": "*", + "@wordpress/notices": "*", + "@wordpress/patterns": "*", + "@wordpress/plugins": "*", + "@wordpress/preferences": "*", + "@wordpress/private-apis": "*", + "@wordpress/reusable-blocks": "*", + "@wordpress/rich-text": "*", + "@wordpress/server-side-render": "*", + "@wordpress/url": "*", + "@wordpress/warning": "*", + "@wordpress/wordcount": "*", "change-case": "^4.1.2", "client-zip": "^2.4.5", "clsx": "^2.1.1", @@ -7214,7 +7278,8 @@ "is-plain-object": "^5.0.0", "memize": "^2.1.0", "react-autosize-textarea": "^7.1.0", - "remove-accents": "^0.5.0" + "remove-accents": "^0.5.0", + "uuid": "^9.0.1" }, "engines": { "node": ">=18.12.0", @@ -7225,6 +7290,18 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/editor/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@wordpress/element": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.2.0.tgz", @@ -7597,6 +7674,45 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@wordpress/fields": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/fields/-/fields-0.3.0.tgz", + "integrity": "sha512-775tKsbjCo4cE6Xkqa98kxODHrWeF7i78KabREublsBwn8cXfQLtWgdUotRej/s4DzxN/lDRfQZ5yxVBPRFPjQ==", + "dependencies": { + "@babel/runtime": "7.25.7", + "@wordpress/api-fetch": "*", + "@wordpress/blob": "*", + "@wordpress/blocks": "*", + "@wordpress/components": "*", + "@wordpress/compose": "*", + "@wordpress/core-data": "*", + "@wordpress/data": "*", + "@wordpress/dataviews": "*", + "@wordpress/element": "*", + "@wordpress/hooks": "*", + "@wordpress/html-entities": "*", + "@wordpress/i18n": "*", + "@wordpress/icons": "*", + "@wordpress/media-utils": "*", + "@wordpress/notices": "*", + "@wordpress/patterns": "*", + "@wordpress/primitives": "*", + "@wordpress/private-apis": "*", + "@wordpress/router": "*", + "@wordpress/url": "*", + "@wordpress/warning": "*", + "change-case": "4.1.2", + "client-zip": "^2.4.5", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, "node_modules/@wordpress/hooks": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.2.0.tgz", @@ -8080,7 +8196,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@wordpress/router/-/router-1.2.0.tgz", "integrity": "sha512-eb9nAPBtS4KPYvh/T4amPIkaeJ+W3cF3Te+hiiex0Me2cEtspuIoOB5tRoTYNpPD+aXOBBzm0GHnUgUlAbgOhg==", - "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@wordpress/element": "^6.2.0", @@ -16464,7 +16579,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", - "dev": true, "dependencies": { "@babel/runtime": "^7.7.6" } diff --git a/package.json b/package.json index 9c7b4282dc0..d084852faa7 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "@wordpress/compose": "7.2.0", "@wordpress/date": "5.2.0", "@wordpress/dom-ready": "4.2.0", - "@wordpress/editor": "14.2.0", + "@wordpress/editor": "14.11.0", "@wordpress/element": "6.2.0", "@wordpress/escape-html": "3.2.0", "@wordpress/html-entities": "4.2.0",