@wordpress/block-library 10.2.0 → 10.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/build/accordion-panel/block.json +1 -0
- package/build/code/edit.cjs +3 -1
- package/build/code/edit.cjs.map +2 -2
- package/build/cover/block.json +1 -0
- package/build/cover/edit/block-controls.cjs +3 -1
- package/build/cover/edit/block-controls.cjs.map +2 -2
- package/build/cover/edit/index.cjs +75 -31
- package/build/cover/edit/index.cjs.map +2 -2
- package/build/embed/edit.cjs +1 -1
- package/build/embed/edit.cjs.map +2 -2
- package/build/embed/embed-placeholder.cjs +1 -1
- package/build/embed/embed-placeholder.cjs.map +2 -2
- package/build/gallery/dynamic-gallery.cjs +104 -61
- package/build/gallery/dynamic-gallery.cjs.map +3 -3
- package/build/gallery/use-dynamic-gallery.cjs +15 -8
- package/build/gallery/use-dynamic-gallery.cjs.map +2 -2
- package/build/heading/edit.cjs +1 -1
- package/build/heading/edit.cjs.map +2 -2
- package/build/html/modal.cjs +63 -54
- package/build/html/modal.cjs.map +3 -3
- package/build/icon/block.json +5 -3
- package/build/image/edit.cjs +1 -1
- package/build/image/edit.cjs.map +2 -2
- package/build/image/image.cjs +29 -5
- package/build/image/image.cjs.map +3 -3
- package/build/image/use-open-image-media-editor-modal.cjs +6 -2
- package/build/image/use-open-image-media-editor-modal.cjs.map +2 -2
- package/build/list-item/hooks/use-indent-list-item.cjs +10 -2
- package/build/list-item/hooks/use-indent-list-item.cjs.map +2 -2
- package/build/math/edit.cjs +39 -56
- package/build/math/edit.cjs.map +3 -3
- package/build/media-text/edit.cjs +2 -1
- package/build/media-text/edit.cjs.map +2 -2
- package/build/more/edit.cjs +2 -2
- package/build/more/edit.cjs.map +2 -2
- package/build/navigation/edit/index.cjs +30 -16
- package/build/navigation/edit/index.cjs.map +3 -3
- package/build/navigation/edit/use-layout-custom-properties.cjs +72 -0
- package/build/navigation/edit/use-layout-custom-properties.cjs.map +7 -0
- package/build/navigation/view.cjs +9 -6
- package/build/navigation/view.cjs.map +2 -2
- package/build/navigation-link/edit.cjs +3 -3
- package/build/navigation-link/edit.cjs.map +2 -2
- package/build/navigation-link/link-ui/index.cjs +2 -2
- package/build/navigation-link/link-ui/index.cjs.map +2 -2
- package/build/paragraph/block.json +0 -1
- package/build/paragraph/edit.cjs +5 -2
- package/build/paragraph/edit.cjs.map +3 -3
- package/build/paragraph/index.cjs +4 -1
- package/build/paragraph/index.cjs.map +2 -2
- package/build/playlist/context.cjs +2 -1
- package/build/playlist/context.cjs.map +2 -2
- package/build/playlist/edit.cjs +113 -26
- package/build/playlist/edit.cjs.map +2 -2
- package/build/playlist/utils.cjs +19 -4
- package/build/playlist/utils.cjs.map +2 -2
- package/build/playlist-track/edit.cjs +21 -6
- package/build/playlist-track/edit.cjs.map +2 -2
- package/build/post-content/edit.cjs +36 -15
- package/build/post-content/edit.cjs.map +2 -2
- package/build/post-featured-image/edit.cjs +3 -2
- package/build/post-featured-image/edit.cjs.map +2 -2
- package/build/post-terms/edit.cjs +2 -2
- package/build/post-terms/edit.cjs.map +2 -2
- package/build/post-title/edit.cjs +2 -2
- package/build/post-title/edit.cjs.map +2 -2
- package/build/preformatted/edit.cjs +3 -1
- package/build/preformatted/edit.cjs.map +2 -2
- package/build/pullquote/edit.cjs +5 -3
- package/build/pullquote/edit.cjs.map +2 -2
- package/build/query/edit/inspector-controls/index.cjs +4 -1
- package/build/query/edit/inspector-controls/index.cjs.map +2 -2
- package/build/query/edit/inspector-controls/offset-controls.cjs +1 -1
- package/build/query/edit/inspector-controls/offset-controls.cjs.map +2 -2
- package/build/read-more/edit.cjs +3 -1
- package/build/read-more/edit.cjs.map +2 -2
- package/build/site-tagline/edit.cjs +3 -1
- package/build/site-tagline/edit.cjs.map +2 -2
- package/build/site-title/edit.cjs +3 -1
- package/build/site-title/edit.cjs.map +2 -2
- package/build/social-links/edit.cjs +11 -4
- package/build/social-links/edit.cjs.map +2 -2
- package/build/tab-list/block.json +2 -1
- package/build/tab-list/edit.cjs +2 -0
- package/build/tab-list/edit.cjs.map +3 -3
- package/build/tab-list/tab-movers.cjs +87 -0
- package/build/tab-list/tab-movers.cjs.map +7 -0
- package/build/tab-panel/edit.cjs +1 -9
- package/build/tab-panel/edit.cjs.map +2 -2
- package/build/table/edit.cjs +1 -1
- package/build/table/edit.cjs.map +2 -2
- package/build/tabs/use-tab-actions.cjs +23 -1
- package/build/tabs/use-tab-actions.cjs.map +2 -2
- package/build/utils/caption.cjs +2 -2
- package/build/utils/caption.cjs.map +2 -2
- package/build/verse/edit.cjs +3 -1
- package/build/verse/edit.cjs.map +2 -2
- package/build/video/tracks-editor.cjs +0 -1
- package/build/video/tracks-editor.cjs.map +2 -2
- package/build-module/accordion-panel/block.json +1 -0
- package/build-module/code/edit.mjs +3 -1
- package/build-module/code/edit.mjs.map +2 -2
- package/build-module/cover/block.json +1 -0
- package/build-module/cover/edit/block-controls.mjs +3 -1
- package/build-module/cover/edit/block-controls.mjs.map +2 -2
- package/build-module/cover/edit/index.mjs +78 -34
- package/build-module/cover/edit/index.mjs.map +2 -2
- package/build-module/embed/edit.mjs +1 -1
- package/build-module/embed/edit.mjs.map +2 -2
- package/build-module/embed/embed-placeholder.mjs +1 -1
- package/build-module/embed/embed-placeholder.mjs.map +2 -2
- package/build-module/gallery/dynamic-gallery.mjs +104 -61
- package/build-module/gallery/dynamic-gallery.mjs.map +2 -2
- package/build-module/gallery/use-dynamic-gallery.mjs +16 -9
- package/build-module/gallery/use-dynamic-gallery.mjs.map +2 -2
- package/build-module/heading/edit.mjs +1 -1
- package/build-module/heading/edit.mjs.map +2 -2
- package/build-module/html/modal.mjs +68 -55
- package/build-module/html/modal.mjs.map +2 -2
- package/build-module/icon/block.json +5 -3
- package/build-module/image/edit.mjs +1 -1
- package/build-module/image/edit.mjs.map +2 -2
- package/build-module/image/image.mjs +19 -5
- package/build-module/image/image.mjs.map +2 -2
- package/build-module/image/use-open-image-media-editor-modal.mjs +6 -2
- package/build-module/image/use-open-image-media-editor-modal.mjs.map +2 -2
- package/build-module/list-item/hooks/use-indent-list-item.mjs +10 -2
- package/build-module/list-item/hooks/use-indent-list-item.mjs.map +2 -2
- package/build-module/math/edit.mjs +41 -60
- package/build-module/math/edit.mjs.map +2 -2
- package/build-module/media-text/edit.mjs +2 -1
- package/build-module/media-text/edit.mjs.map +2 -2
- package/build-module/more/edit.mjs +2 -2
- package/build-module/more/edit.mjs.map +2 -2
- package/build-module/navigation/edit/index.mjs +30 -16
- package/build-module/navigation/edit/index.mjs.map +2 -2
- package/build-module/navigation/edit/use-layout-custom-properties.mjs +51 -0
- package/build-module/navigation/edit/use-layout-custom-properties.mjs.map +7 -0
- package/build-module/navigation/view.mjs +9 -6
- package/build-module/navigation/view.mjs.map +2 -2
- package/build-module/navigation-link/edit.mjs +3 -3
- package/build-module/navigation-link/edit.mjs.map +2 -2
- package/build-module/navigation-link/link-ui/index.mjs +2 -2
- package/build-module/navigation-link/link-ui/index.mjs.map +2 -2
- package/build-module/paragraph/block.json +0 -1
- package/build-module/paragraph/edit.mjs +6 -2
- package/build-module/paragraph/edit.mjs.map +2 -2
- package/build-module/paragraph/index.mjs +4 -1
- package/build-module/paragraph/index.mjs.map +2 -2
- package/build-module/playlist/context.mjs +2 -1
- package/build-module/playlist/context.mjs.map +2 -2
- package/build-module/playlist/edit.mjs +113 -27
- package/build-module/playlist/edit.mjs.map +2 -2
- package/build-module/playlist/utils.mjs +19 -4
- package/build-module/playlist/utils.mjs.map +2 -2
- package/build-module/playlist-track/edit.mjs +21 -6
- package/build-module/playlist-track/edit.mjs.map +2 -2
- package/build-module/post-content/edit.mjs +37 -15
- package/build-module/post-content/edit.mjs.map +2 -2
- package/build-module/post-featured-image/edit.mjs +3 -2
- package/build-module/post-featured-image/edit.mjs.map +2 -2
- package/build-module/post-terms/edit.mjs +2 -2
- package/build-module/post-terms/edit.mjs.map +2 -2
- package/build-module/post-title/edit.mjs +2 -2
- package/build-module/post-title/edit.mjs.map +2 -2
- package/build-module/preformatted/edit.mjs +3 -1
- package/build-module/preformatted/edit.mjs.map +2 -2
- package/build-module/pullquote/edit.mjs +5 -3
- package/build-module/pullquote/edit.mjs.map +2 -2
- package/build-module/query/edit/inspector-controls/index.mjs +5 -2
- package/build-module/query/edit/inspector-controls/index.mjs.map +2 -2
- package/build-module/query/edit/inspector-controls/offset-controls.mjs +2 -2
- package/build-module/query/edit/inspector-controls/offset-controls.mjs.map +2 -2
- package/build-module/read-more/edit.mjs +3 -1
- package/build-module/read-more/edit.mjs.map +2 -2
- package/build-module/site-tagline/edit.mjs +3 -1
- package/build-module/site-tagline/edit.mjs.map +2 -2
- package/build-module/site-title/edit.mjs +3 -1
- package/build-module/site-title/edit.mjs.map +2 -2
- package/build-module/social-links/edit.mjs +11 -4
- package/build-module/social-links/edit.mjs.map +2 -2
- package/build-module/tab-list/block.json +2 -1
- package/build-module/tab-list/edit.mjs +2 -0
- package/build-module/tab-list/edit.mjs.map +2 -2
- package/build-module/tab-list/tab-movers.mjs +59 -0
- package/build-module/tab-list/tab-movers.mjs.map +7 -0
- package/build-module/tab-panel/edit.mjs +1 -9
- package/build-module/tab-panel/edit.mjs.map +2 -2
- package/build-module/table/edit.mjs +1 -1
- package/build-module/table/edit.mjs.map +2 -2
- package/build-module/tabs/use-tab-actions.mjs +23 -1
- package/build-module/tabs/use-tab-actions.mjs.map +2 -2
- package/build-module/utils/caption.mjs +2 -2
- package/build-module/utils/caption.mjs.map +2 -2
- package/build-module/verse/edit.mjs +3 -1
- package/build-module/verse/edit.mjs.map +2 -2
- package/build-module/video/tracks-editor.mjs +0 -1
- package/build-module/video/tracks-editor.mjs.map +2 -2
- package/build-style/cover/editor-rtl.css +3 -0
- package/build-style/cover/editor.css +3 -0
- package/build-style/editor-rtl.css +18 -41
- package/build-style/editor.css +18 -41
- package/build-style/icon/editor-rtl.css +1 -4
- package/build-style/icon/editor.css +1 -4
- package/build-style/image/editor-rtl.css +3 -32
- package/build-style/image/editor.css +3 -32
- package/build-style/playlist/editor-rtl.css +0 -5
- package/build-style/playlist/editor.css +0 -5
- package/build-style/playlist/style-rtl.css +44 -4
- package/build-style/playlist/style.css +44 -4
- package/build-style/pullquote/editor-rtl.css +4 -0
- package/build-style/pullquote/editor.css +4 -0
- package/build-style/style-rtl.css +44 -4
- package/build-style/style.css +44 -4
- package/build-style/tab-list/editor-rtl.css +101 -0
- package/build-style/tab-list/editor.css +101 -0
- package/package.json +43 -43
- package/src/accordion-panel/block.json +1 -0
- package/src/breadcrumbs/index.php +3 -1
- package/src/button/index.php +1 -1
- package/src/code/edit.js +7 -2
- package/src/cover/block.json +1 -0
- package/src/cover/edit/block-controls.js +5 -0
- package/src/cover/edit/index.js +100 -35
- package/src/cover/editor.scss +6 -0
- package/src/cover/index.php +9 -2
- package/src/editor.scss +1 -0
- package/src/embed/edit.js +3 -1
- package/src/embed/embed-placeholder.js +9 -7
- package/src/form/index.php +6 -4
- package/src/gallery/dynamic-gallery.js +133 -74
- package/src/gallery/use-dynamic-gallery.js +27 -12
- package/src/heading/edit.js +1 -1
- package/src/html/modal.js +13 -2
- package/src/icon/README.md +1 -3
- package/src/icon/block.json +5 -3
- package/src/icon/editor.scss +1 -4
- package/src/image/edit.js +1 -5
- package/src/image/editor.scss +6 -46
- package/src/image/image.js +37 -3
- package/src/image/test/use-open-image-media-editor-modal.js +37 -1
- package/src/image/use-open-image-media-editor-modal.js +8 -1
- package/src/latest-posts/index.php +3 -2
- package/src/list-item/hooks/use-indent-list-item.js +10 -1
- package/src/math/edit.js +42 -59
- package/src/media-text/edit.js +1 -0
- package/src/media-text/index.php +11 -2
- package/src/more/edit.js +7 -4
- package/src/navigation/edit/index.js +52 -36
- package/src/navigation/edit/test/layout-custom-properties.js +138 -0
- package/src/navigation/edit/use-layout-custom-properties.js +84 -0
- package/src/navigation/index.php +123 -12
- package/src/navigation/test/view.js +51 -0
- package/src/navigation/view.js +15 -14
- package/src/navigation-link/edit.js +11 -7
- package/src/navigation-link/index.php +64 -0
- package/src/navigation-link/link-ui/index.js +2 -1
- package/src/navigation-link/test/__snapshots__/hooks.js.snap +1 -1
- package/src/page-list/index.php +4 -3
- package/src/paragraph/README.md +0 -1
- package/src/paragraph/block.json +0 -1
- package/src/paragraph/edit.js +9 -2
- package/src/paragraph/index.js +4 -1
- package/src/pattern/index.php +5 -5
- package/src/playlist/context.js +1 -0
- package/src/playlist/edit.js +151 -47
- package/src/playlist/editor.scss +0 -7
- package/src/playlist/index.php +14 -9
- package/src/playlist/style.scss +3 -0
- package/src/playlist/test/edit-component.js +139 -0
- package/src/playlist/test/edit.js +30 -0
- package/src/playlist/utils.js +25 -4
- package/src/playlist-track/edit.js +22 -5
- package/src/playlist-track/index.php +8 -7
- package/src/playlist-track/test/edit.js +87 -3
- package/src/post-content/edit.js +45 -16
- package/src/post-excerpt/index.php +4 -1
- package/src/post-featured-image/edit.js +3 -2
- package/src/post-featured-image/index.php +4 -1
- package/src/post-terms/edit.js +7 -4
- package/src/post-title/edit.js +5 -3
- package/src/preformatted/edit.js +7 -2
- package/src/pullquote/edit.js +9 -4
- package/src/pullquote/editor.scss +6 -0
- package/src/query/edit/inspector-controls/index.js +5 -2
- package/src/query/edit/inspector-controls/offset-controls.js +2 -2
- package/src/read-more/edit.js +7 -2
- package/src/rss/index.php +9 -3
- package/src/site-tagline/edit.js +7 -2
- package/src/site-title/edit.js +7 -2
- package/src/social-link/index.php +19 -9
- package/src/social-links/edit.js +21 -12
- package/src/tab-list/block.json +2 -1
- package/src/tab-list/edit.js +2 -0
- package/src/tab-list/editor.scss +9 -0
- package/src/tab-list/tab-movers.js +72 -0
- package/src/tab-panel/edit.js +1 -9
- package/src/table/edit.js +1 -1
- package/src/table-of-contents/index.php +386 -1
- package/src/tabs/use-tab-actions.js +32 -3
- package/src/tag-cloud/index.php +3 -2
- package/src/template-part/index.php +2 -1
- package/src/utils/caption.js +7 -4
- package/src/utils/test/waveform-utils.js +63 -0
- package/src/verse/edit.js +7 -2
- package/src/video/index.php +2 -2
- package/src/video/tracks-editor.js +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { useMemo } from '@wordpress/element';
|
|
5
|
-
import { useDispatch, useSelect } from '@wordpress/data';
|
|
5
|
+
import { useDispatch, useSelect, useRegistry } from '@wordpress/data';
|
|
6
6
|
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
7
7
|
import { store as coreStore } from '@wordpress/core-data';
|
|
8
8
|
import { createBlock } from '@wordpress/blocks';
|
|
@@ -122,7 +122,9 @@ export default function useDynamicGallery( {
|
|
|
122
122
|
const sourceOrderby = dynamicContent?.args?.orderBy ?? DEFAULT_ORDERBY;
|
|
123
123
|
const sourceOrder = dynamicContent?.args?.order ?? DEFAULT_ORDER;
|
|
124
124
|
|
|
125
|
-
const
|
|
125
|
+
const registry = useRegistry();
|
|
126
|
+
const { replaceInnerBlocks, __unstableMarkNextChangeAsNotPersistent } =
|
|
127
|
+
useDispatch( blockEditorStore );
|
|
126
128
|
|
|
127
129
|
// Resolve the configured source to a media query. `null` (static mode, or an
|
|
128
130
|
// unresolvable source) short-circuits the select below so no request fires.
|
|
@@ -208,21 +210,34 @@ export default function useDynamicGallery( {
|
|
|
208
210
|
// for the pre-innerBlocks format (see `deprecated.js`/`transforms.js`), empty
|
|
209
211
|
// on any gallery reachable here.
|
|
210
212
|
function enableDynamicMode() {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
+
// Batch the attribute change and the inner-block reset into a single
|
|
214
|
+
// undo level: they're two halves of one mode switch, so one undo should
|
|
215
|
+
// revert both. Marking the second dispatch non-persistent stops it from
|
|
216
|
+
// opening a second undo level, which would otherwise leave the gallery
|
|
217
|
+
// in a half-switched state (dynamic source set, images still present).
|
|
218
|
+
registry.batch( () => {
|
|
219
|
+
setAttributes( { dynamicContent: { source: ATTACHED_MEDIA } } );
|
|
220
|
+
__unstableMarkNextChangeAsNotPersistent();
|
|
221
|
+
replaceInnerBlocks( clientId, [] );
|
|
222
|
+
} );
|
|
213
223
|
}
|
|
214
224
|
|
|
215
225
|
// "Pins" a dynamic gallery: materializes the currently-resolved media as
|
|
216
226
|
// real, editable image blocks and leaves dynamic mode.
|
|
217
227
|
function convertToStatic() {
|
|
218
|
-
//
|
|
219
|
-
//
|
|
220
|
-
//
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
228
|
+
// Batch the inner-block materialization and the attribute change into a
|
|
229
|
+
// single undo level so one undo reverts the whole conversion (see
|
|
230
|
+
// `enableDynamicMode`). Build fresh blocks rather than reusing the
|
|
231
|
+
// preview's `dynamicImageBlocks` so the materialized inner blocks get
|
|
232
|
+
// their own client IDs, distinct from the (disabled) preview instances.
|
|
233
|
+
registry.batch( () => {
|
|
234
|
+
replaceInnerBlocks(
|
|
235
|
+
clientId,
|
|
236
|
+
buildImageBlocks( dynamicMedia, imageAttributes )
|
|
237
|
+
);
|
|
238
|
+
__unstableMarkNextChangeAsNotPersistent();
|
|
239
|
+
setAttributes( { dynamicContent: undefined } );
|
|
240
|
+
} );
|
|
226
241
|
}
|
|
227
242
|
|
|
228
243
|
// Updates the source ordering within `dynamicContent.args`. Passing
|
package/src/heading/edit.js
CHANGED
|
@@ -94,7 +94,7 @@ function HeadingEdit( props ) {
|
|
|
94
94
|
onChange={ onContentChange }
|
|
95
95
|
onMerge={ mergeBlocks }
|
|
96
96
|
onReplace={ onReplace }
|
|
97
|
-
onRemove={ () => onReplace( [] ) }
|
|
97
|
+
onRemove={ onReplace ? () => onReplace( [] ) : undefined }
|
|
98
98
|
placeholder={ placeholder || __( 'Heading' ) }
|
|
99
99
|
{ ...blockProps }
|
|
100
100
|
/>
|
package/src/html/modal.js
CHANGED
|
@@ -13,7 +13,11 @@ import {
|
|
|
13
13
|
__experimentalVStack as VStack,
|
|
14
14
|
__experimentalHStack as HStack,
|
|
15
15
|
} from '@wordpress/components';
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
PlainText,
|
|
18
|
+
store as blockEditorStore,
|
|
19
|
+
privateApis as blockEditorPrivateApis,
|
|
20
|
+
} from '@wordpress/block-editor';
|
|
17
21
|
import { fullscreen, square } from '@wordpress/icons';
|
|
18
22
|
import { useViewportMatch } from '@wordpress/compose';
|
|
19
23
|
|
|
@@ -25,6 +29,7 @@ import Preview from './preview';
|
|
|
25
29
|
import { parseContent, serializeContent } from './utils';
|
|
26
30
|
|
|
27
31
|
const { Tabs } = unlock( componentsPrivateApis );
|
|
32
|
+
const { useNativeUndo } = unlock( blockEditorPrivateApis );
|
|
28
33
|
|
|
29
34
|
export default function HTMLEditModal( { onRequestClose, content, onUpdate } ) {
|
|
30
35
|
// Parse content into separate sections and use as initial state
|
|
@@ -33,6 +38,9 @@ export default function HTMLEditModal( { onRequestClose, content, onUpdate } ) {
|
|
|
33
38
|
const [ editedCss, setEditedCss ] = useState( css );
|
|
34
39
|
const [ editedJs, setEditedJs ] = useState( js );
|
|
35
40
|
const [ isFullscreen, setIsFullscreen ] = useState( false );
|
|
41
|
+
// The fields hold local state that is only committed when the dialog is
|
|
42
|
+
// saved, so undo and redo within them must remain the browser's own.
|
|
43
|
+
const nativeUndoRef = useNativeUndo();
|
|
36
44
|
|
|
37
45
|
const isMobileViewport = useViewportMatch( 'small', '<' );
|
|
38
46
|
|
|
@@ -132,7 +140,10 @@ export default function HTMLEditModal( { onRequestClose, content, onUpdate } ) {
|
|
|
132
140
|
align="stretch"
|
|
133
141
|
gap={ 8 }
|
|
134
142
|
>
|
|
135
|
-
<div
|
|
143
|
+
<div
|
|
144
|
+
ref={ nativeUndoRef }
|
|
145
|
+
className="block-library-html__modal-content"
|
|
146
|
+
>
|
|
136
147
|
<Tabs.TabPanel
|
|
137
148
|
tabId="html"
|
|
138
149
|
focusable={ false }
|
package/src/icon/README.md
CHANGED
|
@@ -28,9 +28,7 @@ _Defined via the [`supports`](https://developer.wordpress.org/block-editor/refer
|
|
|
28
28
|
- [`ariaLabel`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#arialabel): `true`
|
|
29
29
|
- [`align`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#align): `"left"`, `"center"`, `"right"`
|
|
30
30
|
- [`html`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#html): `false`
|
|
31
|
-
- [`color`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#color):
|
|
32
|
-
- [`background`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#color-background): `true`
|
|
33
|
-
- [`text`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#color-text): `true`
|
|
31
|
+
- [`color`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#color): `true`
|
|
34
32
|
- [`interactivity`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#interactivity):
|
|
35
33
|
- `clientNavigation`: `true`
|
|
36
34
|
- [`spacing`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#spacing):
|
package/src/icon/block.json
CHANGED
|
@@ -33,9 +33,11 @@
|
|
|
33
33
|
"align": [ "left", "center", "right" ],
|
|
34
34
|
"html": false,
|
|
35
35
|
"color": {
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
|
|
36
|
+
"__experimentalSkipSerialization": true,
|
|
37
|
+
"__experimentalDefaultControls": {
|
|
38
|
+
"background": true,
|
|
39
|
+
"text": true
|
|
40
|
+
}
|
|
39
41
|
},
|
|
40
42
|
"interactivity": {
|
|
41
43
|
"clientNavigation": true
|
package/src/icon/editor.scss
CHANGED
|
@@ -66,10 +66,7 @@
|
|
|
66
66
|
.wp-block-icon__inserter-grid-icons-list-item-title {
|
|
67
67
|
font-size: $font-size-small;
|
|
68
68
|
padding: $grid-unit-05 $grid-unit-05 $grid-unit-10;
|
|
69
|
-
overflow:
|
|
70
|
-
text-overflow: ellipsis;
|
|
71
|
-
white-space: nowrap;
|
|
72
|
-
width: 100%;
|
|
69
|
+
overflow-wrap: break-word;
|
|
73
70
|
}
|
|
74
71
|
|
|
75
72
|
.wp-block-icon__toolbar-content {
|
package/src/image/edit.js
CHANGED
|
@@ -353,11 +353,7 @@ export function ImageEdit( {
|
|
|
353
353
|
|
|
354
354
|
const isSideloading = useSelect(
|
|
355
355
|
( select ) => {
|
|
356
|
-
if (
|
|
357
|
-
( ! window.__clientSideMediaProcessing &&
|
|
358
|
-
! window.__heicUploadSupport ) ||
|
|
359
|
-
! id
|
|
360
|
-
) {
|
|
356
|
+
if ( ! window.__clientSideMediaProcessing || ! id ) {
|
|
361
357
|
return false;
|
|
362
358
|
}
|
|
363
359
|
return select( uploadStore ).isUploadingById( id );
|
package/src/image/editor.scss
CHANGED
|
@@ -22,12 +22,16 @@ figure.wp-block-image:not(.wp-block) {
|
|
|
22
22
|
// width (e.g. a small animated GIF being transcoded to a video) otherwise
|
|
23
23
|
// leaves the spinner off to one side. Wide and full alignments keep their
|
|
24
24
|
// own width.
|
|
25
|
-
|
|
25
|
+
// The media editor swap state marks the img rather than the figure (its
|
|
26
|
+
// state lives alongside the img's load handlers), hence the :has() variant.
|
|
27
|
+
&.is-transient:not(.alignwide):not(.alignfull),
|
|
28
|
+
&:has(img.is-swapping-media):not(.alignwide):not(.alignfull) {
|
|
26
29
|
width: fit-content;
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
.is-applying img,
|
|
30
|
-
&.is-transient img
|
|
33
|
+
&.is-transient img,
|
|
34
|
+
img.is-swapping-media {
|
|
31
35
|
opacity: 0.3;
|
|
32
36
|
}
|
|
33
37
|
|
|
@@ -123,49 +127,6 @@ figure.wp-block-image:not(.wp-block) {
|
|
|
123
127
|
position: relative;
|
|
124
128
|
}
|
|
125
129
|
|
|
126
|
-
.wp-block-image__crop-area {
|
|
127
|
-
position: relative;
|
|
128
|
-
max-width: 100%;
|
|
129
|
-
width: 100%;
|
|
130
|
-
overflow: hidden;
|
|
131
|
-
|
|
132
|
-
// stylelint-disable selector-class-pattern -- react-easy-crop library class names.
|
|
133
|
-
.reactEasyCrop_Container {
|
|
134
|
-
// The linked Image block has `pointer-events: none` applied. Override it
|
|
135
|
-
// here to enable the crop action.
|
|
136
|
-
pointer-events: auto;
|
|
137
|
-
|
|
138
|
-
// This removes the border from the img within the image cropper so it
|
|
139
|
-
// can be applied to the cropper itself. This then allows the image to be
|
|
140
|
-
// cropped within the visual border providing more accurate editing and
|
|
141
|
-
// smoother UX.
|
|
142
|
-
.reactEasyCrop_Image {
|
|
143
|
-
border: none;
|
|
144
|
-
border-radius: 0; // Prevent's theme.json radius bleeding into cropper.
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
// stylelint-enable selector-class-pattern
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
.wp-block-image__crop-icon {
|
|
151
|
-
padding: 0 8px;
|
|
152
|
-
min-width: 48px;
|
|
153
|
-
display: flex;
|
|
154
|
-
justify-content: center;
|
|
155
|
-
align-items: center;
|
|
156
|
-
|
|
157
|
-
svg {
|
|
158
|
-
fill: currentColor;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
.wp-block-image__zoom {
|
|
163
|
-
.components-popover__content {
|
|
164
|
-
min-width: 260px;
|
|
165
|
-
overflow: visible !important;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
130
|
.wp-block-image__toolbar_content_textarea__container {
|
|
170
131
|
padding: $grid-unit;
|
|
171
132
|
}
|
|
@@ -174,4 +135,3 @@ figure.wp-block-image:not(.wp-block) {
|
|
|
174
135
|
// Corresponds to the size of the textarea in the block inspector.
|
|
175
136
|
width: 250px;
|
|
176
137
|
}
|
|
177
|
-
|
package/src/image/image.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* WordPress dependencies
|
|
3
8
|
*/
|
|
@@ -390,6 +395,12 @@ export default function Image( {
|
|
|
390
395
|
);
|
|
391
396
|
const { getBlock, getSettings } = useSelect( blockEditorStore );
|
|
392
397
|
const cropButtonRef = useRef();
|
|
398
|
+
// URL of a freshly generated file (crop/rotate result) from the media
|
|
399
|
+
// editor that the browser may not have finished loading; cleared by the
|
|
400
|
+
// <img> load/error handlers, or by the settle effect below when the
|
|
401
|
+
// rendered image already shows it.
|
|
402
|
+
const [ pendingSwapUrl, setPendingSwapUrl ] = useState();
|
|
403
|
+
const isSwappingMedia = !! pendingSwapUrl;
|
|
393
404
|
const handleMediaEditorModalClose = useCallback(
|
|
394
405
|
() => cropButtonRef.current?.focus(),
|
|
395
406
|
[]
|
|
@@ -398,6 +409,7 @@ export default function Image( {
|
|
|
398
409
|
attributes,
|
|
399
410
|
setAttributes,
|
|
400
411
|
onClose: handleMediaEditorModalClose,
|
|
412
|
+
onUrlChange: setPendingSwapUrl,
|
|
401
413
|
} );
|
|
402
414
|
|
|
403
415
|
const {
|
|
@@ -485,18 +497,34 @@ export default function Image( {
|
|
|
485
497
|
};
|
|
486
498
|
}, [ loadedNaturalWidth, loadedNaturalHeight, imageElement?.complete ] );
|
|
487
499
|
|
|
500
|
+
// A media editor update can be undone or superseded before its
|
|
501
|
+
// attributes land, leaving the rendered image untouched. No load event
|
|
502
|
+
// fires in that case, so clear the pending swap whenever the rendered
|
|
503
|
+
// image already shows the pending URL.
|
|
504
|
+
useEffect( () => {
|
|
505
|
+
if (
|
|
506
|
+
pendingSwapUrl &&
|
|
507
|
+
pendingSwapUrl === url &&
|
|
508
|
+
imageElement?.complete
|
|
509
|
+
) {
|
|
510
|
+
setPendingSwapUrl( undefined );
|
|
511
|
+
}
|
|
512
|
+
}, [ pendingSwapUrl, url, imageElement ] );
|
|
513
|
+
|
|
488
514
|
function onImageError() {
|
|
515
|
+
setPendingSwapUrl( undefined );
|
|
489
516
|
setHasImageErrored( true );
|
|
490
517
|
|
|
491
518
|
// Check if there's an embed block that handles this URL, e.g., instagram URL.
|
|
492
519
|
// See: https://github.com/WordPress/gutenberg/pull/11472
|
|
493
520
|
const embedBlock = createUpgradedEmbedBlock( { attributes: { url } } );
|
|
494
|
-
if ( undefined !== embedBlock ) {
|
|
521
|
+
if ( undefined !== embedBlock && onReplace ) {
|
|
495
522
|
onReplace( embedBlock );
|
|
496
523
|
}
|
|
497
524
|
}
|
|
498
525
|
|
|
499
526
|
function onImageLoad( event ) {
|
|
527
|
+
setPendingSwapUrl( undefined );
|
|
500
528
|
setHasImageErrored( false );
|
|
501
529
|
setLoadedNaturalSize( {
|
|
502
530
|
loadedNaturalWidth: event.target?.naturalWidth,
|
|
@@ -902,6 +930,10 @@ export default function Image( {
|
|
|
902
930
|
aria-haspopup="dialog"
|
|
903
931
|
icon={ crop }
|
|
904
932
|
label={ __( 'Crop' ) }
|
|
933
|
+
// Disable rather than hide while the edited image
|
|
934
|
+
// loads, so the button keeps focus when the modal
|
|
935
|
+
// closes instead of dropping it to the canvas.
|
|
936
|
+
disabled={ isSwappingMedia }
|
|
905
937
|
/>
|
|
906
938
|
) }
|
|
907
939
|
{ showCoverControls && (
|
|
@@ -1173,7 +1205,9 @@ export default function Image( {
|
|
|
1173
1205
|
onError={ onImageError }
|
|
1174
1206
|
onLoad={ onImageLoad }
|
|
1175
1207
|
ref={ setRefs }
|
|
1176
|
-
className={ borderProps.className
|
|
1208
|
+
className={ clsx( borderProps.className, {
|
|
1209
|
+
'is-swapping-media': isSwappingMedia,
|
|
1210
|
+
} ) }
|
|
1177
1211
|
width={ naturalWidth }
|
|
1178
1212
|
height={ naturalHeight }
|
|
1179
1213
|
style={ {
|
|
@@ -1222,7 +1256,7 @@ export default function Image( {
|
|
|
1222
1256
|
...shadowProps.style,
|
|
1223
1257
|
} }
|
|
1224
1258
|
/>
|
|
1225
|
-
{ isUploading && <Spinner /> }
|
|
1259
|
+
{ ( isUploading || isSwappingMedia ) && <Spinner /> }
|
|
1226
1260
|
</>
|
|
1227
1261
|
) }
|
|
1228
1262
|
</ImageWrapper>
|
|
@@ -80,6 +80,7 @@ async function runModalUpdate( {
|
|
|
80
80
|
attributes,
|
|
81
81
|
registryOptions = {},
|
|
82
82
|
updatePayload = { id: attributes.id, url: 'updated.jpg' },
|
|
83
|
+
hookOptions = {},
|
|
83
84
|
} ) {
|
|
84
85
|
const registry = createRegistry( registryOptions );
|
|
85
86
|
useRegistry.mockReturnValue( registry );
|
|
@@ -87,7 +88,11 @@ async function runModalUpdate( {
|
|
|
87
88
|
const openMediaEditorModal = jest.fn();
|
|
88
89
|
mockMediaEditorModalSetting( openMediaEditorModal );
|
|
89
90
|
const { result } = renderHook( () =>
|
|
90
|
-
useOpenImageMediaEditorModal( {
|
|
91
|
+
useOpenImageMediaEditorModal( {
|
|
92
|
+
attributes,
|
|
93
|
+
setAttributes,
|
|
94
|
+
...hookOptions,
|
|
95
|
+
} )
|
|
91
96
|
);
|
|
92
97
|
await act( async () => {
|
|
93
98
|
await result.current();
|
|
@@ -105,6 +110,37 @@ describe( 'useOpenImageMediaEditorModal', () => {
|
|
|
105
110
|
jest.clearAllMocks();
|
|
106
111
|
} );
|
|
107
112
|
|
|
113
|
+
it( 'notifies onUrlChange when the update switches to a new attachment URL', async () => {
|
|
114
|
+
const onUrlChange = jest.fn();
|
|
115
|
+
await runModalUpdate( {
|
|
116
|
+
attributes: { id: 1, url: 'original.jpg', alt: '', caption: '' },
|
|
117
|
+
updatePayload: { id: 2, url: 'updated.jpg' },
|
|
118
|
+
hookOptions: { onUrlChange },
|
|
119
|
+
} );
|
|
120
|
+
expect( onUrlChange ).toHaveBeenCalledTimes( 1 );
|
|
121
|
+
expect( onUrlChange ).toHaveBeenCalledWith( 'updated.jpg' );
|
|
122
|
+
} );
|
|
123
|
+
|
|
124
|
+
it( 'does not notify onUrlChange for a same-attachment update', async () => {
|
|
125
|
+
const onUrlChange = jest.fn();
|
|
126
|
+
await runModalUpdate( {
|
|
127
|
+
attributes: { id: 1, url: 'original.jpg', alt: '', caption: '' },
|
|
128
|
+
updatePayload: { id: 1, url: 'original.jpg' },
|
|
129
|
+
hookOptions: { onUrlChange },
|
|
130
|
+
} );
|
|
131
|
+
expect( onUrlChange ).not.toHaveBeenCalled();
|
|
132
|
+
} );
|
|
133
|
+
|
|
134
|
+
it( 'does not notify onUrlChange when the update carries no URL', async () => {
|
|
135
|
+
const onUrlChange = jest.fn();
|
|
136
|
+
await runModalUpdate( {
|
|
137
|
+
attributes: { id: 1, url: 'original.jpg', alt: '', caption: '' },
|
|
138
|
+
updatePayload: { id: 2 },
|
|
139
|
+
hookOptions: { onUrlChange },
|
|
140
|
+
} );
|
|
141
|
+
expect( onUrlChange ).not.toHaveBeenCalled();
|
|
142
|
+
} );
|
|
143
|
+
|
|
108
144
|
it( 'returns no opener when the media editor modal setting is unavailable', () => {
|
|
109
145
|
useRegistry.mockReturnValue( createRegistry() );
|
|
110
146
|
mockMediaEditorModalSetting( undefined );
|
|
@@ -137,6 +137,7 @@ export function useOpenImageMediaEditorModal( {
|
|
|
137
137
|
attributes,
|
|
138
138
|
setAttributes,
|
|
139
139
|
onClose,
|
|
140
|
+
onUrlChange,
|
|
140
141
|
} ) {
|
|
141
142
|
// Keep this hook private to the Image block and pass the block attributes
|
|
142
143
|
// object so the callsite stays compact. Destructure only the attributes
|
|
@@ -246,6 +247,12 @@ export function useOpenImageMediaEditorModal( {
|
|
|
246
247
|
if ( newId !== currentBlockAttributes.id ) {
|
|
247
248
|
nextAttributes.id = newId;
|
|
248
249
|
nextAttributes.url = newUrl ?? currentBlockAttributes.url;
|
|
250
|
+
if ( nextAttributes.url !== currentBlockAttributes.url ) {
|
|
251
|
+
// The block is about to point at a freshly generated file
|
|
252
|
+
// the browser hasn't loaded yet; let the caller show a
|
|
253
|
+
// loading state until its <img> fires load/error.
|
|
254
|
+
onUrlChange?.( nextAttributes.url );
|
|
255
|
+
}
|
|
249
256
|
blockAttributesRef.current = {
|
|
250
257
|
...blockAttributesRef.current,
|
|
251
258
|
id: nextAttributes.id,
|
|
@@ -294,7 +301,7 @@ export function useOpenImageMediaEditorModal( {
|
|
|
294
301
|
setAttributes( nextAttributes );
|
|
295
302
|
}
|
|
296
303
|
},
|
|
297
|
-
[ resolveFreshAttachmentRecord, setAttributes ]
|
|
304
|
+
[ onUrlChange, resolveFreshAttachmentRecord, setAttributes ]
|
|
298
305
|
);
|
|
299
306
|
|
|
300
307
|
const openImageMediaEditorModal = useCallback( async () => {
|
|
@@ -58,8 +58,9 @@ function render_block_core_latest_posts( $attributes ) {
|
|
|
58
58
|
$block_core_latest_posts_excerpt_length = $attributes['excerptLength'];
|
|
59
59
|
add_filter( 'excerpt_length', 'block_core_latest_posts_get_excerpt_length', 20 );
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
$categories = $attributes['categories'] ?? null;
|
|
62
|
+
if ( ! empty( $categories ) && is_array( $categories ) ) {
|
|
63
|
+
$args['category__in'] = array_column( $categories, 'id' );
|
|
63
64
|
}
|
|
64
65
|
if ( isset( $attributes['selectedAuthor'] ) ) {
|
|
65
66
|
$args['author'] = $attributes['selectedAuthor'];
|
|
@@ -16,6 +16,8 @@ export default function useIndentListItem( clientId ) {
|
|
|
16
16
|
getSelectionEnd,
|
|
17
17
|
hasMultiSelection,
|
|
18
18
|
getMultiSelectedBlockClientIds,
|
|
19
|
+
getBlockRootClientId,
|
|
20
|
+
getBlockAttributes,
|
|
19
21
|
} = useSelect( blockEditorStore );
|
|
20
22
|
return useCallback( () => {
|
|
21
23
|
const _hasMultiSelection = hasMultiSelection();
|
|
@@ -27,9 +29,16 @@ export default function useIndentListItem( clientId ) {
|
|
|
27
29
|
);
|
|
28
30
|
const previousSiblingId = getPreviousBlockClientId( clientId );
|
|
29
31
|
const newListItem = cloneBlock( getBlock( previousSiblingId ) );
|
|
32
|
+
// Get the parent list's attributes to inherit the ordered property
|
|
33
|
+
const parentListId = getBlockRootClientId( clientId );
|
|
34
|
+
const parentListAttributes = getBlockAttributes( parentListId );
|
|
30
35
|
// If the sibling has no innerBlocks, create a new `list` block.
|
|
31
36
|
if ( ! newListItem.innerBlocks?.length ) {
|
|
32
|
-
newListItem.innerBlocks = [
|
|
37
|
+
newListItem.innerBlocks = [
|
|
38
|
+
createBlock( 'core/list', {
|
|
39
|
+
ordered: parentListAttributes.ordered,
|
|
40
|
+
} ),
|
|
41
|
+
];
|
|
33
42
|
}
|
|
34
43
|
// A list item usually has one `list`, but it's possible to have
|
|
35
44
|
// more. So we need to preserve the previous `list` blocks and
|
package/src/math/edit.js
CHANGED
|
@@ -1,27 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { __
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
5
|
import {
|
|
6
6
|
useBlockProps,
|
|
7
7
|
store as blockEditorStore,
|
|
8
8
|
} from '@wordpress/block-editor';
|
|
9
9
|
import {
|
|
10
|
-
TextareaControl,
|
|
11
10
|
Popover,
|
|
12
|
-
__experimentalVStack as VStack,
|
|
13
11
|
privateApis as componentsPrivateApis,
|
|
14
12
|
} from '@wordpress/components';
|
|
15
13
|
import { useState, useEffect, useRef } from '@wordpress/element';
|
|
16
14
|
import { useDispatch } from '@wordpress/data';
|
|
17
|
-
import { speak } from '@wordpress/a11y';
|
|
18
15
|
|
|
19
16
|
/**
|
|
20
17
|
* Internal dependencies
|
|
21
18
|
*/
|
|
22
19
|
import { unlock } from '../lock-unlock';
|
|
23
20
|
|
|
24
|
-
const {
|
|
21
|
+
const { ValidatedTextareaControl } = unlock( componentsPrivateApis );
|
|
25
22
|
|
|
26
23
|
export default function MathEdit( { attributes, setAttributes, isSelected } ) {
|
|
27
24
|
const { latex, mathML } = attributes;
|
|
@@ -29,6 +26,7 @@ export default function MathEdit( { attributes, setAttributes, isSelected } ) {
|
|
|
29
26
|
const [ error, setError ] = useState( null );
|
|
30
27
|
const [ latexToMathML, setLatexToMathML ] = useState();
|
|
31
28
|
const initialLatex = useRef( latex );
|
|
29
|
+
const formRef = useRef();
|
|
32
30
|
const { __unstableMarkNextChangeAsNotPersistent } =
|
|
33
31
|
useDispatch( blockEditorStore );
|
|
34
32
|
|
|
@@ -74,63 +72,48 @@ export default function MathEdit( { attributes, setAttributes, isSelected } ) {
|
|
|
74
72
|
offset={ 8 }
|
|
75
73
|
anchor={ blockRef }
|
|
76
74
|
focusOnMount={ false }
|
|
75
|
+
// Surface any parsing error before focus leaves the block.
|
|
76
|
+
// An invalid field is refocused, keeping the popover open.
|
|
77
|
+
onFocusOutside={ () => formRef.current?.reportValidity() }
|
|
77
78
|
__unstableSlotName="__unstable-block-tools-after"
|
|
78
79
|
>
|
|
79
|
-
<
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
__(
|
|
104
|
-
'Error parsing mathematical expression: %s'
|
|
105
|
-
),
|
|
106
|
-
err.message
|
|
107
|
-
)
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
setAttributes( {
|
|
111
|
-
mathML: newMathML,
|
|
112
|
-
latex: newLatex,
|
|
80
|
+
<form
|
|
81
|
+
ref={ formRef }
|
|
82
|
+
style={ { padding: '4px', minWidth: '300px' } }
|
|
83
|
+
onSubmit={ ( event ) => event.preventDefault() }
|
|
84
|
+
>
|
|
85
|
+
<ValidatedTextareaControl
|
|
86
|
+
label={ __( 'LaTeX math syntax' ) }
|
|
87
|
+
hideLabelFromVision
|
|
88
|
+
value={ latex }
|
|
89
|
+
className="wp-block-math__textarea-control"
|
|
90
|
+
customValidity={
|
|
91
|
+
error
|
|
92
|
+
? { type: 'invalid', message: error }
|
|
93
|
+
: undefined
|
|
94
|
+
}
|
|
95
|
+
onChange={ ( newLatex ) => {
|
|
96
|
+
if ( ! latexToMathML ) {
|
|
97
|
+
setAttributes( { latex: newLatex } );
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
let newMathML = '';
|
|
101
|
+
try {
|
|
102
|
+
newMathML = latexToMathML( newLatex, {
|
|
103
|
+
displayMode: true,
|
|
113
104
|
} );
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
error
|
|
127
|
-
) }
|
|
128
|
-
</WCBadge>
|
|
129
|
-
<style children=".wp-block-math__error .components-badge__content{white-space:normal}" />
|
|
130
|
-
</>
|
|
131
|
-
) }
|
|
132
|
-
</VStack>
|
|
133
|
-
</div>
|
|
105
|
+
setError( null );
|
|
106
|
+
} catch ( err ) {
|
|
107
|
+
setError( err.message );
|
|
108
|
+
}
|
|
109
|
+
setAttributes( {
|
|
110
|
+
mathML: newMathML,
|
|
111
|
+
latex: newLatex,
|
|
112
|
+
} );
|
|
113
|
+
} }
|
|
114
|
+
placeholder={ __( 'e.g., x^2, \\frac{a}{b}' ) }
|
|
115
|
+
/>
|
|
116
|
+
</form>
|
|
134
117
|
</Popover>
|
|
135
118
|
) }
|
|
136
119
|
</div>
|
package/src/media-text/edit.js
CHANGED
package/src/media-text/index.php
CHANGED
|
@@ -31,8 +31,17 @@ function render_block_core_media_text( $attributes, $content ) {
|
|
|
31
31
|
|
|
32
32
|
$has_media_on_right = 'right' === ( $attributes['mediaPosition'] ?? null );
|
|
33
33
|
$image_fill = (bool) ( $attributes['imageFill'] ?? false );
|
|
34
|
-
$
|
|
35
|
-
$
|
|
34
|
+
$focal_point_attr = $attributes['focalPoint'] ?? null;
|
|
35
|
+
$focal_point_x = null;
|
|
36
|
+
$focal_point_y = null;
|
|
37
|
+
if ( is_array( $focal_point_attr ) ) {
|
|
38
|
+
$focal_point_x = isset( $focal_point_attr['x'] ) && is_numeric( $focal_point_attr['x'] ) ? $focal_point_attr['x'] : null;
|
|
39
|
+
$focal_point_y = isset( $focal_point_attr['y'] ) && is_numeric( $focal_point_attr['y'] ) ? $focal_point_attr['y'] : null;
|
|
40
|
+
}
|
|
41
|
+
$focal_point = null !== $focal_point_x && null !== $focal_point_y
|
|
42
|
+
? round( $focal_point_x * 100 ) . '% ' . round( $focal_point_y * 100 ) . '%'
|
|
43
|
+
: '50% 50%';
|
|
44
|
+
$unique_id = 'wp-block-media-text__media-' . wp_unique_id();
|
|
36
45
|
|
|
37
46
|
$block_tag_processor = new WP_HTML_Tag_Processor( $content );
|
|
38
47
|
$block_query = array(
|
package/src/more/edit.js
CHANGED
|
@@ -76,10 +76,13 @@ export default function MoreEdit( {
|
|
|
76
76
|
setAttributes( { customText: value } )
|
|
77
77
|
}
|
|
78
78
|
disableLineBreaks
|
|
79
|
-
__unstableOnSplitAtEnd={
|
|
80
|
-
insertBlocksAfter
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
__unstableOnSplitAtEnd={
|
|
80
|
+
insertBlocksAfter
|
|
81
|
+
? () =>
|
|
82
|
+
insertBlocksAfter(
|
|
83
|
+
createBlock( getDefaultBlockName() )
|
|
84
|
+
)
|
|
85
|
+
: undefined
|
|
83
86
|
}
|
|
84
87
|
/>
|
|
85
88
|
</div>
|