@wordpress/block-editor 9.6.0 → 9.7.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 +2 -0
- package/build/components/block-list/block.js +12 -2
- package/build/components/block-list/block.js.map +1 -1
- package/build/components/block-list/index.native.js +1 -1
- package/build/components/block-list/index.native.js.map +1 -1
- package/build/components/block-popover/inbetween.js +1 -1
- package/build/components/block-popover/inbetween.js.map +1 -1
- package/build/components/block-styles/index.js +3 -6
- package/build/components/block-styles/index.js.map +1 -1
- package/build/components/block-types-list/index.js +1 -1
- package/build/components/block-types-list/index.js.map +1 -1
- package/build/components/border-radius-control/index.js +3 -1
- package/build/components/border-radius-control/index.js.map +1 -1
- package/build/components/colors/utils.js +6 -2
- package/build/components/colors/utils.js.map +1 -1
- package/build/components/colors-gradients/control.js +7 -4
- package/build/components/colors-gradients/control.js.map +1 -1
- package/build/components/colors-gradients/dropdown.js +5 -2
- package/build/components/colors-gradients/dropdown.js.map +1 -1
- package/build/components/font-appearance-control/index.js +10 -4
- package/build/components/font-appearance-control/index.js.map +1 -1
- package/build/components/image-size-control/index.js +3 -1
- package/build/components/image-size-control/index.js.map +1 -1
- package/build/components/index.js +13 -6
- package/build/components/index.js.map +1 -1
- package/build/components/index.native.js +11 -4
- package/build/components/index.native.js.map +1 -1
- package/build/components/inserter/index.native.js +8 -3
- package/build/components/inserter/index.native.js.map +1 -1
- package/build/components/inserter-list-item/index.js +2 -19
- package/build/components/inserter-list-item/index.js.map +1 -1
- package/build/components/letter-spacing-control/index.js +6 -3
- package/build/components/letter-spacing-control/index.js.map +1 -1
- package/build/components/line-height-control/index.js +6 -3
- package/build/components/line-height-control/index.js.map +1 -1
- package/build/components/link-control/is-url-like.js +1 -7
- package/build/components/link-control/is-url-like.js.map +1 -1
- package/build/components/link-control/use-search-handler.js +1 -7
- package/build/components/link-control/use-search-handler.js.map +1 -1
- package/build/components/list-view/expander.js +3 -1
- package/build/components/list-view/expander.js.map +1 -1
- package/build/components/media-upload/index.native.js +8 -3
- package/build/components/media-upload/index.native.js.map +1 -1
- package/build/components/preview-options/index.js +2 -2
- package/build/components/preview-options/index.js.map +1 -1
- package/build/components/{use-no-recursive-renders → recursion-provider}/index.js +40 -18
- package/build/components/recursion-provider/index.js.map +1 -0
- package/build/components/rich-text/index.js +6 -1
- package/build/components/rich-text/index.js.map +1 -1
- package/build/components/rich-text/index.native.js +3 -1
- package/build/components/rich-text/index.native.js.map +1 -1
- package/build/components/rich-text/use-before-input-rules.js +110 -0
- package/build/components/rich-text/use-before-input-rules.js.map +1 -0
- package/build/components/text-decoration-control/index.js +3 -1
- package/build/components/text-decoration-control/index.js.map +1 -1
- package/build/components/text-transform-control/index.js +3 -1
- package/build/components/text-transform-control/index.js.map +1 -1
- package/build/components/url-popover/image-url-input-ui.js +4 -1
- package/build/components/url-popover/image-url-input-ui.js.map +1 -1
- package/build/components/writing-flow/use-arrow-nav.js +4 -25
- package/build/components/writing-flow/use-arrow-nav.js.map +1 -1
- package/build/components/writing-flow/use-drag-selection.js +9 -2
- package/build/components/writing-flow/use-drag-selection.js.map +1 -1
- package/build/components/writing-flow/use-select-all.js +3 -1
- package/build/components/writing-flow/use-select-all.js.map +1 -1
- package/build/hooks/layout.js +9 -2
- package/build/hooks/layout.js.map +1 -1
- package/build/utils/block-variation-transforms.js +15 -9
- package/build/utils/block-variation-transforms.js.map +1 -1
- package/build/utils/pasting.js +9 -1
- package/build/utils/pasting.js.map +1 -1
- package/build-module/components/block-list/block.js +13 -3
- package/build-module/components/block-list/block.js.map +1 -1
- package/build-module/components/block-list/index.native.js +1 -1
- package/build-module/components/block-list/index.native.js.map +1 -1
- package/build-module/components/block-popover/inbetween.js +1 -1
- package/build-module/components/block-popover/inbetween.js.map +1 -1
- package/build-module/components/block-styles/index.js +4 -7
- package/build-module/components/block-styles/index.js.map +1 -1
- package/build-module/components/block-types-list/index.js +1 -1
- package/build-module/components/block-types-list/index.js.map +1 -1
- package/build-module/components/border-radius-control/index.js +4 -2
- package/build-module/components/border-radius-control/index.js.map +1 -1
- package/build-module/components/colors/utils.js +7 -3
- package/build-module/components/colors/utils.js.map +1 -1
- package/build-module/components/colors-gradients/control.js +7 -4
- package/build-module/components/colors-gradients/control.js.map +1 -1
- package/build-module/components/colors-gradients/dropdown.js +5 -2
- package/build-module/components/colors-gradients/dropdown.js.map +1 -1
- package/build-module/components/font-appearance-control/index.js +7 -4
- package/build-module/components/font-appearance-control/index.js.map +1 -1
- package/build-module/components/image-size-control/index.js +3 -1
- package/build-module/components/image-size-control/index.js.map +1 -1
- package/build-module/components/index.js +1 -1
- package/build-module/components/index.js.map +1 -1
- package/build-module/components/index.native.js +1 -1
- package/build-module/components/index.native.js.map +1 -1
- package/build-module/components/inserter/index.native.js +9 -2
- package/build-module/components/inserter/index.native.js.map +1 -1
- package/build-module/components/inserter-list-item/index.js +1 -17
- package/build-module/components/inserter-list-item/index.js.map +1 -1
- package/build-module/components/letter-spacing-control/index.js +5 -3
- package/build-module/components/letter-spacing-control/index.js.map +1 -1
- package/build-module/components/line-height-control/index.js +5 -3
- package/build-module/components/line-height-control/index.js.map +1 -1
- package/build-module/components/link-control/is-url-like.js +1 -6
- package/build-module/components/link-control/is-url-like.js.map +1 -1
- package/build-module/components/link-control/use-search-handler.js +1 -6
- package/build-module/components/link-control/use-search-handler.js.map +1 -1
- package/build-module/components/list-view/expander.js +3 -2
- package/build-module/components/list-view/expander.js.map +1 -1
- package/build-module/components/media-upload/index.native.js +9 -2
- package/build-module/components/media-upload/index.native.js.map +1 -1
- package/build-module/components/preview-options/index.js +2 -2
- package/build-module/components/preview-options/index.js.map +1 -1
- package/build-module/components/{use-no-recursive-renders → recursion-provider}/index.js +39 -19
- package/build-module/components/recursion-provider/index.js.map +1 -0
- package/build-module/components/rich-text/index.js +5 -1
- package/build-module/components/rich-text/index.js.map +1 -1
- package/build-module/components/rich-text/index.native.js +3 -1
- package/build-module/components/rich-text/index.native.js.map +1 -1
- package/build-module/components/rich-text/use-before-input-rules.js +96 -0
- package/build-module/components/rich-text/use-before-input-rules.js.map +1 -0
- package/build-module/components/text-decoration-control/index.js +4 -2
- package/build-module/components/text-decoration-control/index.js.map +1 -1
- package/build-module/components/text-transform-control/index.js +4 -2
- package/build-module/components/text-transform-control/index.js.map +1 -1
- package/build-module/components/url-popover/image-url-input-ui.js +4 -1
- package/build-module/components/url-popover/image-url-input-ui.js.map +1 -1
- package/build-module/components/writing-flow/use-arrow-nav.js +5 -26
- package/build-module/components/writing-flow/use-arrow-nav.js.map +1 -1
- package/build-module/components/writing-flow/use-drag-selection.js +9 -2
- package/build-module/components/writing-flow/use-drag-selection.js.map +1 -1
- package/build-module/components/writing-flow/use-select-all.js +3 -1
- package/build-module/components/writing-flow/use-select-all.js.map +1 -1
- package/build-module/hooks/layout.js +9 -2
- package/build-module/hooks/layout.js.map +1 -1
- package/build-module/utils/block-variation-transforms.js +14 -7
- package/build-module/utils/block-variation-transforms.js.map +1 -1
- package/build-module/utils/pasting.js +9 -1
- package/build-module/utils/pasting.js.map +1 -1
- package/build-style/style-rtl.css +39 -7
- package/build-style/style.css +39 -7
- package/package.json +28 -28
- package/src/components/block-list/block.js +13 -2
- package/src/components/block-list/index.native.js +1 -1
- package/src/components/block-popover/inbetween.js +1 -0
- package/src/components/block-popover/style.scss +25 -2
- package/src/components/block-styles/index.js +4 -7
- package/src/components/block-styles/style.scss +10 -0
- package/src/components/block-types-list/index.js +1 -1
- package/src/components/border-radius-control/index.js +4 -1
- package/src/components/color-palette/test/__snapshots__/control.js.snap +93 -77
- package/src/components/colors/utils.js +5 -2
- package/src/components/colors-gradients/control.js +12 -8
- package/src/components/colors-gradients/dropdown.js +7 -2
- package/src/components/colors-gradients/style.scss +27 -5
- package/src/components/colors-gradients/test/control.js +3 -3
- package/src/components/font-appearance-control/index.js +3 -0
- package/src/components/image-size-control/README.md +7 -0
- package/src/components/image-size-control/index.js +2 -0
- package/src/components/index.js +4 -1
- package/src/components/index.native.js +4 -1
- package/src/components/inserter/index.native.js +7 -2
- package/src/components/inserter-list-item/index.js +1 -17
- package/src/components/letter-spacing-control/index.js +2 -0
- package/src/components/line-height-control/index.js +2 -0
- package/src/components/link-control/is-url-like.js +1 -6
- package/src/components/link-control/use-search-handler.js +1 -6
- package/src/components/list-view/expander.js +4 -2
- package/src/components/media-upload/index.native.js +7 -3
- package/src/components/preview-options/index.js +2 -2
- package/src/components/{use-no-recursive-renders → recursion-provider}/index.js +39 -28
- package/src/components/{use-no-recursive-renders/test/use-no-recursive-renders.js → recursion-provider/test/index.js} +5 -6
- package/src/components/rich-text/README.md +13 -1
- package/src/components/rich-text/index.js +2 -0
- package/src/components/rich-text/index.native.js +2 -0
- package/src/components/rich-text/use-before-input-rules.js +91 -0
- package/src/components/text-decoration-control/index.js +4 -2
- package/src/components/text-transform-control/index.js +4 -2
- package/src/components/url-popover/image-url-input-ui.js +3 -0
- package/src/components/writing-flow/use-arrow-nav.js +4 -33
- package/src/components/writing-flow/use-drag-selection.js +7 -1
- package/src/components/writing-flow/use-select-all.js +2 -1
- package/src/hooks/layout.js +8 -2
- package/src/utils/block-variation-transforms.js +13 -6
- package/src/utils/pasting.js +10 -1
- package/src/utils/test/block-variation-transforms.js +24 -0
- package/src/utils/test/pasting.js +10 -0
- package/build/components/use-no-recursive-renders/index.js.map +0 -1
- package/build-module/components/use-no-recursive-renders/index.js.map +0 -1
|
@@ -33,10 +33,10 @@ export default function PreviewOptions( {
|
|
|
33
33
|
className: 'block-editor-post-preview__button-toggle',
|
|
34
34
|
disabled: ! isEnabled,
|
|
35
35
|
/* translators: button label text should, if possible, be under 16 characters. */
|
|
36
|
-
children: __( '
|
|
36
|
+
children: __( 'View' ),
|
|
37
37
|
};
|
|
38
38
|
const menuProps = {
|
|
39
|
-
'aria-label': __( '
|
|
39
|
+
'aria-label': __( 'View options' ),
|
|
40
40
|
};
|
|
41
41
|
return (
|
|
42
42
|
<DropdownMenu
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
createContext,
|
|
6
|
-
useCallback,
|
|
7
|
-
useContext,
|
|
8
|
-
useMemo,
|
|
9
|
-
} from '@wordpress/element';
|
|
4
|
+
import { createContext, useContext, useMemo } from '@wordpress/element';
|
|
10
5
|
|
|
11
6
|
/**
|
|
12
7
|
* Internal dependencies
|
|
@@ -37,37 +32,53 @@ function addToBlockType( renderedBlocks, blockName, uniqueId ) {
|
|
|
37
32
|
}
|
|
38
33
|
|
|
39
34
|
/**
|
|
40
|
-
* A React
|
|
41
|
-
*
|
|
42
|
-
* function to prevent said recursion.
|
|
35
|
+
* A React context provider for use with the `useHasRecursion` hook to prevent recursive
|
|
36
|
+
* renders.
|
|
43
37
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
38
|
+
* Wrap block content with this provider and provide the same `uniqueId` prop as used
|
|
39
|
+
* with `useHasRecursion`.
|
|
40
|
+
*
|
|
41
|
+
* @param {Object} props
|
|
42
|
+
* @param {*} props.uniqueId Any value that acts as a unique identifier for a block instance.
|
|
43
|
+
* @param {string} props.blockName Optional block name.
|
|
44
|
+
* @param {JSX.Element} props.children React children.
|
|
46
45
|
*
|
|
47
|
-
* @return {
|
|
48
|
-
* - a boolean describing whether the provided id
|
|
49
|
-
* has already been rendered;
|
|
50
|
-
* - a React context provider to be used to wrap
|
|
51
|
-
* other elements.
|
|
46
|
+
* @return {JSX.Element} A React element.
|
|
52
47
|
*/
|
|
53
|
-
export
|
|
48
|
+
export function RecursionProvider( { children, uniqueId, blockName = '' } ) {
|
|
54
49
|
const previouslyRenderedBlocks = useContext( RenderedRefsContext );
|
|
55
50
|
const { name } = useBlockEditContext();
|
|
51
|
+
|
|
56
52
|
blockName = blockName || name;
|
|
57
|
-
|
|
58
|
-
previouslyRenderedBlocks[ blockName ]?.has( uniqueId )
|
|
59
|
-
);
|
|
53
|
+
|
|
60
54
|
const newRenderedBlocks = useMemo(
|
|
61
55
|
() => addToBlockType( previouslyRenderedBlocks, blockName, uniqueId ),
|
|
62
56
|
[ previouslyRenderedBlocks, blockName, uniqueId ]
|
|
63
57
|
);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
),
|
|
70
|
-
[ newRenderedBlocks ]
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<RenderedRefsContext.Provider value={ newRenderedBlocks }>
|
|
61
|
+
{ children }
|
|
62
|
+
</RenderedRefsContext.Provider>
|
|
71
63
|
);
|
|
72
|
-
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* A React hook for keeping track of blocks previously rendered up in the block
|
|
68
|
+
* tree. Blocks susceptible to recursion can use this hook in their `Edit`
|
|
69
|
+
* function to prevent said recursion.
|
|
70
|
+
*
|
|
71
|
+
* Use this with the `RecursionProvider` component, using the same `uniqueId` value
|
|
72
|
+
* for both the hook and the provider.
|
|
73
|
+
*
|
|
74
|
+
* @param {*} uniqueId Any value that acts as a unique identifier for a block instance.
|
|
75
|
+
* @param {string} blockName Optional block name.
|
|
76
|
+
*
|
|
77
|
+
* @return {boolean} A boolean describing whether the provided id has already been rendered.
|
|
78
|
+
*/
|
|
79
|
+
export function useHasRecursion( uniqueId, blockName = '' ) {
|
|
80
|
+
const previouslyRenderedBlocks = useContext( RenderedRefsContext );
|
|
81
|
+
const { name } = useBlockEditContext();
|
|
82
|
+
blockName = blockName || name;
|
|
83
|
+
return Boolean( previouslyRenderedBlocks[ blockName ]?.has( uniqueId ) );
|
|
73
84
|
}
|
|
@@ -6,7 +6,7 @@ import { render } from '@testing-library/react';
|
|
|
6
6
|
/**
|
|
7
7
|
* Internal dependencies
|
|
8
8
|
*/
|
|
9
|
-
import
|
|
9
|
+
import { useHasRecursion, RecursionProvider } from '..';
|
|
10
10
|
import {
|
|
11
11
|
BlockEditContextProvider,
|
|
12
12
|
useBlockEditContext,
|
|
@@ -16,15 +16,14 @@ import {
|
|
|
16
16
|
// of calling itself depending on its `uniqueId` attribute.
|
|
17
17
|
function Edit( { attributes: { uniqueId } } ) {
|
|
18
18
|
const { name } = useBlockEditContext();
|
|
19
|
-
const
|
|
20
|
-
useNoRecursiveRenders( uniqueId );
|
|
19
|
+
const hasRecursion = useHasRecursion( uniqueId );
|
|
21
20
|
|
|
22
|
-
if (
|
|
21
|
+
if ( hasRecursion ) {
|
|
23
22
|
return <div className={ `wp-block__${ name }--halted` }>Halt</div>;
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
return (
|
|
27
|
-
<RecursionProvider>
|
|
26
|
+
<RecursionProvider uniqueId={ uniqueId }>
|
|
28
27
|
<div className={ `wp-block__${ name }` }>
|
|
29
28
|
{ uniqueId === 'SIMPLE' && <p>Done</p> }
|
|
30
29
|
{ uniqueId === 'SINGLY-RECURSIVE' && (
|
|
@@ -48,7 +47,7 @@ function Edit( { attributes: { uniqueId } } ) {
|
|
|
48
47
|
);
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
describe( '
|
|
50
|
+
describe( 'useHasRecursion/RecursionProvider', () => {
|
|
52
51
|
const context = { name: 'reusable-block' };
|
|
53
52
|
|
|
54
53
|
it( 'allows a single block to render', () => {
|
|
@@ -43,7 +43,19 @@ _Optional._ Called when the block can be removed. `forward` is true when the sel
|
|
|
43
43
|
|
|
44
44
|
### `allowedFormats: Array`
|
|
45
45
|
|
|
46
|
-
_Optional._ By default, all registered formats are allowed. This setting can be used to fine-tune the allowed formats. Example: `[ 'core/bold', 'core/link' ]`.
|
|
46
|
+
_Optional._ By default, all registered formats are allowed. This setting can be used to fine-tune the allowed formats. If you want to limit the formats allowed, you can specify using allowedFormats property in your code. If you want to allow only bold and italic settings, then you need to pass it in array. Example: `[ 'core/bold', 'core/link' ]`.
|
|
47
|
+
|
|
48
|
+
{% ESNext %}
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
<RichText
|
|
52
|
+
tagName="h2"
|
|
53
|
+
value={ attributes.content }
|
|
54
|
+
allowedFormats={ [ 'core/bold', 'core/italic' ] } // Allow the content to be made bold or italic, but do not allow othe formatting options
|
|
55
|
+
onChange={ ( content ) => setAttributes( { content } ) }
|
|
56
|
+
placeholder={ __( 'Heading...' ) }
|
|
57
|
+
/>
|
|
58
|
+
```
|
|
47
59
|
|
|
48
60
|
### `withoutInteractiveFormatting: Boolean`
|
|
49
61
|
|
|
@@ -38,6 +38,7 @@ import { store as blockEditorStore } from '../../store';
|
|
|
38
38
|
import { useUndoAutomaticChange } from './use-undo-automatic-change';
|
|
39
39
|
import { useMarkPersistent } from './use-mark-persistent';
|
|
40
40
|
import { usePasteHandler } from './use-paste-handler';
|
|
41
|
+
import { useBeforeInputRules } from './use-before-input-rules';
|
|
41
42
|
import { useInputRules } from './use-input-rules';
|
|
42
43
|
import { useEnter } from './use-enter';
|
|
43
44
|
import { useFormatTypes } from './use-format-types';
|
|
@@ -359,6 +360,7 @@ function RichTextWrapper(
|
|
|
359
360
|
autocompleteProps.ref,
|
|
360
361
|
props.ref,
|
|
361
362
|
richTextRef,
|
|
363
|
+
useBeforeInputRules( { value, onChange } ),
|
|
362
364
|
useInputRules( {
|
|
363
365
|
value,
|
|
364
366
|
onChange,
|
|
@@ -113,6 +113,7 @@ function RichTextWrapper(
|
|
|
113
113
|
setRef,
|
|
114
114
|
disableSuggestions,
|
|
115
115
|
disableAutocorrection,
|
|
116
|
+
containerWidth,
|
|
116
117
|
...props
|
|
117
118
|
},
|
|
118
119
|
forwardedRef
|
|
@@ -639,6 +640,7 @@ function RichTextWrapper(
|
|
|
639
640
|
setRef={ setRef }
|
|
640
641
|
disableSuggestions={ disableSuggestions }
|
|
641
642
|
disableAutocorrection={ disableAutocorrection }
|
|
643
|
+
containerWidth={ containerWidth }
|
|
642
644
|
// Props to be set on the editable container are destructured on the
|
|
643
645
|
// element itself for web (see below), but passed through rich text
|
|
644
646
|
// for native.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useRef } from '@wordpress/element';
|
|
5
|
+
import { useRefEffect } from '@wordpress/compose';
|
|
6
|
+
import { insert, isCollapsed } from '@wordpress/rich-text';
|
|
7
|
+
import { useDispatch } from '@wordpress/data';
|
|
8
|
+
import { applyFilters } from '@wordpress/hooks';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Internal dependencies
|
|
12
|
+
*/
|
|
13
|
+
import { store as blockEditorStore } from '../../store';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* When typing over a selection, the selection will we wrapped by a matching
|
|
17
|
+
* character pair. The second character is optional, it defaults to the first
|
|
18
|
+
* character.
|
|
19
|
+
*
|
|
20
|
+
* @type {string[]} Array of character pairs.
|
|
21
|
+
*/
|
|
22
|
+
const wrapSelectionSettings = [ '`', '"', "'", '“”', '‘’' ];
|
|
23
|
+
|
|
24
|
+
export function useBeforeInputRules( props ) {
|
|
25
|
+
const {
|
|
26
|
+
__unstableMarkLastChangeAsPersistent,
|
|
27
|
+
__unstableMarkAutomaticChange,
|
|
28
|
+
} = useDispatch( blockEditorStore );
|
|
29
|
+
const propsRef = useRef( props );
|
|
30
|
+
propsRef.current = props;
|
|
31
|
+
return useRefEffect( ( element ) => {
|
|
32
|
+
function onInput( event ) {
|
|
33
|
+
const { inputType, data } = event;
|
|
34
|
+
const { value, onChange } = propsRef.current;
|
|
35
|
+
|
|
36
|
+
// Only run the rules when inserting text.
|
|
37
|
+
if ( inputType !== 'insertText' ) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if ( isCollapsed( value ) ) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const pair = applyFilters(
|
|
46
|
+
'blockEditor.wrapSelectionSettings',
|
|
47
|
+
wrapSelectionSettings
|
|
48
|
+
).find(
|
|
49
|
+
( [ startChar, endChar ] ) =>
|
|
50
|
+
startChar === data || endChar === data
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
if ( ! pair ) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const [ startChar, endChar = startChar ] = pair;
|
|
58
|
+
const start = value.start;
|
|
59
|
+
const end = value.end + startChar.length;
|
|
60
|
+
|
|
61
|
+
let newValue = insert( value, startChar, start, start );
|
|
62
|
+
newValue = insert( newValue, endChar, end, end );
|
|
63
|
+
|
|
64
|
+
__unstableMarkLastChangeAsPersistent();
|
|
65
|
+
onChange( newValue );
|
|
66
|
+
__unstableMarkAutomaticChange();
|
|
67
|
+
|
|
68
|
+
const init = {};
|
|
69
|
+
|
|
70
|
+
for ( const key in event ) {
|
|
71
|
+
init[ key ] = event[ key ];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
init.data = endChar;
|
|
75
|
+
|
|
76
|
+
const { ownerDocument } = element;
|
|
77
|
+
const { defaultView } = ownerDocument;
|
|
78
|
+
const newEvent = new defaultView.InputEvent( 'input', init );
|
|
79
|
+
|
|
80
|
+
// Dispatch an input event with the new data. This will trigger the
|
|
81
|
+
// input rules.
|
|
82
|
+
event.target.dispatchEvent( newEvent );
|
|
83
|
+
event.preventDefault();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
element.addEventListener( 'beforeinput', onInput );
|
|
87
|
+
return () => {
|
|
88
|
+
element.removeEventListener( 'beforeinput', onInput );
|
|
89
|
+
};
|
|
90
|
+
}, [] );
|
|
91
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { Button } from '@wordpress/components';
|
|
4
|
+
import { BaseControl, Button } from '@wordpress/components';
|
|
5
5
|
import { formatStrikethrough, formatUnderline } from '@wordpress/icons';
|
|
6
6
|
import { __ } from '@wordpress/i18n';
|
|
7
7
|
|
|
@@ -30,7 +30,9 @@ const TEXT_DECORATIONS = [
|
|
|
30
30
|
export default function TextDecorationControl( { value, onChange } ) {
|
|
31
31
|
return (
|
|
32
32
|
<fieldset className="block-editor-text-decoration-control">
|
|
33
|
-
<
|
|
33
|
+
<BaseControl.VisualLabel as="legend">
|
|
34
|
+
{ __( 'Decoration' ) }
|
|
35
|
+
</BaseControl.VisualLabel>
|
|
34
36
|
<div className="block-editor-text-decoration-control__buttons">
|
|
35
37
|
{ TEXT_DECORATIONS.map( ( textDecoration ) => {
|
|
36
38
|
return (
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { Button } from '@wordpress/components';
|
|
4
|
+
import { BaseControl, Button } from '@wordpress/components';
|
|
5
5
|
import { __ } from '@wordpress/i18n';
|
|
6
6
|
import {
|
|
7
7
|
formatCapitalize,
|
|
@@ -39,7 +39,9 @@ const TEXT_TRANSFORMS = [
|
|
|
39
39
|
export default function TextTransformControl( { value, onChange } ) {
|
|
40
40
|
return (
|
|
41
41
|
<fieldset className="block-editor-text-transform-control">
|
|
42
|
-
<
|
|
42
|
+
<BaseControl.VisualLabel as="legend">
|
|
43
|
+
{ __( 'Letter case' ) }
|
|
44
|
+
</BaseControl.VisualLabel>
|
|
43
45
|
<div className="block-editor-text-transform-control__buttons">
|
|
44
46
|
{ TEXT_TRANSFORMS.map( ( textTransform ) => {
|
|
45
47
|
return (
|
|
@@ -51,6 +51,7 @@ const ImageURLInputUI = ( {
|
|
|
51
51
|
rel,
|
|
52
52
|
} ) => {
|
|
53
53
|
const [ isOpen, setIsOpen ] = useState( false );
|
|
54
|
+
const buttonRef = useRef( null );
|
|
54
55
|
const openLinkUI = useCallback( () => {
|
|
55
56
|
setIsOpen( true );
|
|
56
57
|
} );
|
|
@@ -245,9 +246,11 @@ const ImageURLInputUI = ( {
|
|
|
245
246
|
label={ url ? __( 'Edit link' ) : __( 'Insert link' ) }
|
|
246
247
|
aria-expanded={ isOpen }
|
|
247
248
|
onClick={ openLinkUI }
|
|
249
|
+
ref={ buttonRef }
|
|
248
250
|
/>
|
|
249
251
|
{ isOpen && (
|
|
250
252
|
<URLPopover
|
|
253
|
+
anchorRef={ buttonRef }
|
|
251
254
|
onFocusOutside={ onFocusOutside() }
|
|
252
255
|
onClose={ closeLinkUI }
|
|
253
256
|
renderSettings={ () => advancedOptions }
|
|
@@ -17,7 +17,7 @@ import { useRefEffect } from '@wordpress/compose';
|
|
|
17
17
|
/**
|
|
18
18
|
* Internal dependencies
|
|
19
19
|
*/
|
|
20
|
-
import {
|
|
20
|
+
import { getBlockClientId } from '../../utils/dom';
|
|
21
21
|
import { store as blockEditorStore } from '../../store';
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -130,11 +130,8 @@ export function getClosestTabbable(
|
|
|
130
130
|
|
|
131
131
|
export default function useArrowNav() {
|
|
132
132
|
const {
|
|
133
|
-
getSelectedBlockClientId,
|
|
134
133
|
getMultiSelectedBlocksStartClientId,
|
|
135
134
|
getMultiSelectedBlocksEndClientId,
|
|
136
|
-
getPreviousBlockClientId,
|
|
137
|
-
getNextBlockClientId,
|
|
138
135
|
getSettings,
|
|
139
136
|
hasMultiSelection,
|
|
140
137
|
__unstableIsFullySelected,
|
|
@@ -150,26 +147,13 @@ export default function useArrowNav() {
|
|
|
150
147
|
verticalRect = null;
|
|
151
148
|
}
|
|
152
149
|
|
|
153
|
-
|
|
154
|
-
* Returns true if the given target field is the last in its block which
|
|
155
|
-
* can be considered for tab transition. For example, in a block with
|
|
156
|
-
* two text fields, this would return true when reversing from the first
|
|
157
|
-
* of the two fields, but false when reversing from the second.
|
|
158
|
-
*
|
|
159
|
-
* @param {Element} target Currently focused text field.
|
|
160
|
-
* @param {boolean} isReverse True if considering as the first field.
|
|
161
|
-
*
|
|
162
|
-
* @return {boolean} Whether field is at edge for tab transition.
|
|
163
|
-
*/
|
|
164
|
-
function isTabbableEdge( target, isReverse ) {
|
|
150
|
+
function isClosestTabbableABlock( target, isReverse ) {
|
|
165
151
|
const closestTabbable = getClosestTabbable(
|
|
166
152
|
target,
|
|
167
153
|
isReverse,
|
|
168
154
|
node
|
|
169
155
|
);
|
|
170
|
-
return (
|
|
171
|
-
! closestTabbable || ! isInSameBlock( target, closestTabbable )
|
|
172
|
-
);
|
|
156
|
+
return closestTabbable && getBlockClientId( closestTabbable );
|
|
173
157
|
}
|
|
174
158
|
|
|
175
159
|
function onKeyDown( event ) {
|
|
@@ -254,23 +238,10 @@ export default function useArrowNav() {
|
|
|
254
238
|
// next, which is the exact reverse of LTR.
|
|
255
239
|
const isReverseDir = isRTL( target ) ? ! isReverse : isReverse;
|
|
256
240
|
const { keepCaretInsideBlock } = getSettings();
|
|
257
|
-
const selectedBlockClientId = getSelectedBlockClientId();
|
|
258
241
|
|
|
259
242
|
if ( isShift ) {
|
|
260
|
-
const selectionEndClientId =
|
|
261
|
-
getMultiSelectedBlocksEndClientId();
|
|
262
|
-
const selectionBeforeEndClientId = getPreviousBlockClientId(
|
|
263
|
-
selectionEndClientId || selectedBlockClientId
|
|
264
|
-
);
|
|
265
|
-
const selectionAfterEndClientId = getNextBlockClientId(
|
|
266
|
-
selectionEndClientId || selectedBlockClientId
|
|
267
|
-
);
|
|
268
|
-
|
|
269
243
|
if (
|
|
270
|
-
|
|
271
|
-
( ( isReverse && selectionBeforeEndClientId ) ||
|
|
272
|
-
( ! isReverse && selectionAfterEndClientId ) ) &&
|
|
273
|
-
isTabbableEdge( target, isReverse ) &&
|
|
244
|
+
isClosestTabbableABlock( target, isReverse ) &&
|
|
274
245
|
isNavEdge( target, isReverse )
|
|
275
246
|
) {
|
|
276
247
|
node.contentEditable = true;
|
|
@@ -27,7 +27,7 @@ function setContentEditableWrapper( node, value ) {
|
|
|
27
27
|
export default function useDragSelection() {
|
|
28
28
|
const { startMultiSelect, stopMultiSelect } =
|
|
29
29
|
useDispatch( blockEditorStore );
|
|
30
|
-
const { isSelectionEnabled, hasMultiSelection } =
|
|
30
|
+
const { isSelectionEnabled, hasMultiSelection, isDraggingBlocks } =
|
|
31
31
|
useSelect( blockEditorStore );
|
|
32
32
|
return useRefEffect(
|
|
33
33
|
( node ) => {
|
|
@@ -72,6 +72,12 @@ export default function useDragSelection() {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
function onMouseLeave( { buttons, target } ) {
|
|
75
|
+
// Avoid triggering a multi-selection if the user is already
|
|
76
|
+
// dragging blocks.
|
|
77
|
+
if ( isDraggingBlocks() ) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
75
81
|
// The primary button must be pressed to initiate selection.
|
|
76
82
|
// See https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons
|
|
77
83
|
if ( buttons !== 1 ) {
|
|
@@ -19,7 +19,7 @@ import { store as blockEditorStore } from '../../store';
|
|
|
19
19
|
export default function useSelectAll() {
|
|
20
20
|
const { getBlockOrder, getSelectedBlockClientIds, getBlockRootClientId } =
|
|
21
21
|
useSelect( blockEditorStore );
|
|
22
|
-
const { multiSelect } = useDispatch( blockEditorStore );
|
|
22
|
+
const { multiSelect, selectBlock } = useDispatch( blockEditorStore );
|
|
23
23
|
const isMatch = useShortcutEventMatch();
|
|
24
24
|
|
|
25
25
|
return useRefEffect( ( node ) => {
|
|
@@ -53,6 +53,7 @@ export default function useSelectAll() {
|
|
|
53
53
|
const lastClientId = last( blockClientIds );
|
|
54
54
|
|
|
55
55
|
if ( firstClientId === lastClientId ) {
|
|
56
|
+
selectBlock( firstClientId );
|
|
56
57
|
return;
|
|
57
58
|
}
|
|
58
59
|
|
package/src/hooks/layout.js
CHANGED
|
@@ -264,10 +264,16 @@ export const withInspectorControls = createHigherOrderComponent(
|
|
|
264
264
|
export const withLayoutStyles = createHigherOrderComponent(
|
|
265
265
|
( BlockListBlock ) => ( props ) => {
|
|
266
266
|
const { name, attributes } = props;
|
|
267
|
-
const
|
|
267
|
+
const hasLayoutBlockSupport = hasBlockSupport(
|
|
268
268
|
name,
|
|
269
269
|
layoutBlockSupportKey
|
|
270
270
|
);
|
|
271
|
+
const disableLayoutStyles = useSelect( ( select ) => {
|
|
272
|
+
const { getSettings } = select( blockEditorStore );
|
|
273
|
+
return !! getSettings().disableLayoutStyles;
|
|
274
|
+
} );
|
|
275
|
+
const shouldRenderLayoutStyles =
|
|
276
|
+
hasLayoutBlockSupport && ! disableLayoutStyles;
|
|
271
277
|
const id = useInstanceId( BlockListBlock );
|
|
272
278
|
const defaultThemeLayout = useSetting( 'layout' ) || {};
|
|
273
279
|
const element = useContext( BlockList.__unstableElementContext );
|
|
@@ -277,7 +283,7 @@ export const withLayoutStyles = createHigherOrderComponent(
|
|
|
277
283
|
const usedLayout = layout?.inherit
|
|
278
284
|
? defaultThemeLayout
|
|
279
285
|
: layout || defaultBlockLayout || {};
|
|
280
|
-
const layoutClasses =
|
|
286
|
+
const layoutClasses = hasLayoutBlockSupport
|
|
281
287
|
? useLayoutClasses( usedLayout, defaultThemeLayout?.definitions )
|
|
282
288
|
: null;
|
|
283
289
|
const selector = `.${ getBlockDefaultClassName(
|
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* External dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { isMatch } from 'lodash';
|
|
5
|
-
|
|
6
1
|
/** @typedef {import('@wordpress/blocks').WPBlockVariation} WPBlockVariation */
|
|
7
2
|
|
|
3
|
+
function matchesAttributes( blockAttributes, variation ) {
|
|
4
|
+
return Object.entries( variation ).every( ( [ key, value ] ) => {
|
|
5
|
+
if (
|
|
6
|
+
typeof value === 'object' &&
|
|
7
|
+
typeof blockAttributes[ key ] === 'object'
|
|
8
|
+
) {
|
|
9
|
+
return matchesAttributes( blockAttributes[ key ], value );
|
|
10
|
+
}
|
|
11
|
+
return blockAttributes[ key ] === value;
|
|
12
|
+
} );
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
/**
|
|
9
16
|
* Matches the provided block variations with a block's attributes. If no match
|
|
10
17
|
* or more than one matches are found it returns `undefined`. If a single match is
|
|
@@ -24,7 +31,7 @@ export const __experimentalGetMatchingVariation = (
|
|
|
24
31
|
if ( ! variations || ! blockAttributes ) return;
|
|
25
32
|
const matches = variations.filter( ( { attributes } ) => {
|
|
26
33
|
if ( ! attributes || ! Object.keys( attributes ).length ) return false;
|
|
27
|
-
return
|
|
34
|
+
return matchesAttributes( blockAttributes, attributes );
|
|
28
35
|
} );
|
|
29
36
|
if ( matches.length !== 1 ) return;
|
|
30
37
|
return matches[ 0 ];
|
package/src/utils/pasting.js
CHANGED
|
@@ -70,7 +70,16 @@ export function shouldDismissPastedFiles( files, html /*, plainText */ ) {
|
|
|
70
70
|
// other elements found, like <figure>, but we assume that the user's
|
|
71
71
|
// intention is to paste the actual image file.
|
|
72
72
|
const IMAGE_TAG = /<\s*img\b/gi;
|
|
73
|
-
|
|
73
|
+
if ( html.match( IMAGE_TAG )?.length !== 1 ) return true;
|
|
74
|
+
|
|
75
|
+
// Even when there is exactly one <img> tag in the HTML payload, we
|
|
76
|
+
// choose to weed out local images, i.e. those whose source starts with
|
|
77
|
+
// "file://". These payloads occur in specific configurations, such as
|
|
78
|
+
// when copying an entire document from Microsoft Word, that contains
|
|
79
|
+
// text and exactly one image, and pasting that content using Google
|
|
80
|
+
// Chrome.
|
|
81
|
+
const IMG_WITH_LOCAL_SRC = /<\s*img\b[^>]*\bsrc="file:\/\//i;
|
|
82
|
+
if ( html.match( IMG_WITH_LOCAL_SRC ) ) return true;
|
|
74
83
|
}
|
|
75
84
|
|
|
76
85
|
return false;
|
|
@@ -40,6 +40,18 @@ describe( 'getMatchingVariation', () => {
|
|
|
40
40
|
getMatchingVariation( { level: 1, other: 'prop' }, variations )
|
|
41
41
|
).toBeUndefined();
|
|
42
42
|
} );
|
|
43
|
+
it( 'when variation has a nested attribute', () => {
|
|
44
|
+
const variations = [
|
|
45
|
+
{ name: 'one', attributes: { query: { author: 'somebody' } } },
|
|
46
|
+
{ name: 'two', attributes: { query: { author: 'nobody' } } },
|
|
47
|
+
];
|
|
48
|
+
expect(
|
|
49
|
+
getMatchingVariation(
|
|
50
|
+
{ query: { author: 'foobar' }, other: 'prop' },
|
|
51
|
+
variations
|
|
52
|
+
)
|
|
53
|
+
).toBeUndefined();
|
|
54
|
+
} );
|
|
43
55
|
} );
|
|
44
56
|
describe( 'should find a match', () => {
|
|
45
57
|
it( 'when variation has one attribute', () => {
|
|
@@ -66,5 +78,17 @@ describe( 'getMatchingVariation', () => {
|
|
|
66
78
|
).name
|
|
67
79
|
).toEqual( 'one' );
|
|
68
80
|
} );
|
|
81
|
+
it( 'when variation has a nested attribute', () => {
|
|
82
|
+
const variations = [
|
|
83
|
+
{ name: 'one', attributes: { query: { author: 'somebody' } } },
|
|
84
|
+
{ name: 'two', attributes: { query: { author: 'nobody' } } },
|
|
85
|
+
];
|
|
86
|
+
expect(
|
|
87
|
+
getMatchingVariation(
|
|
88
|
+
{ query: { author: 'somebody' }, other: 'prop' },
|
|
89
|
+
variations
|
|
90
|
+
).name
|
|
91
|
+
).toEqual( 'one' );
|
|
92
|
+
} );
|
|
69
93
|
} );
|
|
70
94
|
} );
|
|
@@ -81,4 +81,14 @@ describe( 'shouldDismissPastedFiles', () => {
|
|
|
81
81
|
)
|
|
82
82
|
).toBe( true );
|
|
83
83
|
} );
|
|
84
|
+
|
|
85
|
+
it( 'should return true when pasting an image-containing MS Word document via Chrome', () => {
|
|
86
|
+
expect(
|
|
87
|
+
shouldDismissPastedFiles(
|
|
88
|
+
[ mocks.pngImageFile ],
|
|
89
|
+
'<p>A</p><img src="file:////.../clip_image001.png" alt="..."><p>B</p>',
|
|
90
|
+
'A\nB'
|
|
91
|
+
)
|
|
92
|
+
).toBe( true );
|
|
93
|
+
} );
|
|
84
94
|
} );
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["@wordpress/block-editor/src/components/use-no-recursive-renders/index.js"],"names":["RenderedRefsContext","addToBlockType","renderedBlocks","blockName","uniqueId","result","Set","add","useNoRecursiveRenders","previouslyRenderedBlocks","name","hasAlreadyRendered","Boolean","has","newRenderedBlocks","Provider","children"],"mappings":";;;;;;;AAGA;;AAUA;;AAbA;AACA;AACA;;AAQA;AACA;AACA;AAGA,MAAMA,mBAAmB,GAAG,4BAAe,EAAf,CAA5B;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,SAASC,cAAT,CAAyBC,cAAzB,EAAyCC,SAAzC,EAAoDC,QAApD,EAA+D;AAC9D,QAAMC,MAAM,GAAG,EACd,GAAGH,cADW;AAEd,KAAEC,SAAF,GAAeD,cAAc,CAAEC,SAAF,CAAd,GACZ,IAAIG,GAAJ,CAASJ,cAAc,CAAEC,SAAF,CAAvB,CADY,GAEZ,IAAIG,GAAJ;AAJW,GAAf;AAMAD,EAAAA,MAAM,CAAEF,SAAF,CAAN,CAAoBI,GAApB,CAAyBH,QAAzB;AAEA,SAAOC,MAAP;AACA;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACe,SAASG,qBAAT,CAAgCJ,QAAhC,EAA2D;AAAA;;AAAA,MAAjBD,SAAiB,uEAAL,EAAK;AACzE,QAAMM,wBAAwB,GAAG,yBAAYT,mBAAZ,CAAjC;AACA,QAAM;AAAEU,IAAAA;AAAF,MAAW,mCAAjB;AACAP,EAAAA,SAAS,GAAGA,SAAS,IAAIO,IAAzB;AACA,QAAMC,kBAAkB,GAAGC,OAAO,0BACjCH,wBAAwB,CAAEN,SAAF,CADS,0DACjC,sBAAuCU,GAAvC,CAA4CT,QAA5C,CADiC,CAAlC;AAGA,QAAMU,iBAAiB,GAAG,sBACzB,MAAMb,cAAc,CAAEQ,wBAAF,EAA4BN,SAA5B,EAAuCC,QAAvC,CADK,EAEzB,CAAEK,wBAAF,EAA4BN,SAA5B,EAAuCC,QAAvC,CAFyB,CAA1B;AAIA,QAAMW,QAAQ,GAAG,0BAChB;AAAA,QAAE;AAAEC,MAAAA;AAAF,KAAF;AAAA,WACC,4BAAC,mBAAD,CAAqB,QAArB;AAA8B,MAAA,KAAK,EAAGF;AAAtC,OACGE,QADH,CADD;AAAA,GADgB,EAMhB,CAAEF,iBAAF,CANgB,CAAjB;AAQA,SAAO,CAAEH,kBAAF,EAAsBI,QAAtB,CAAP;AACA","sourcesContent":["/**\n * WordPress dependencies\n */\nimport {\n\tcreateContext,\n\tuseCallback,\n\tuseContext,\n\tuseMemo,\n} from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { useBlockEditContext } from '../block-edit/context';\n\nconst RenderedRefsContext = createContext( {} );\n\n/**\n * Immutably adds an unique identifier to a set scoped for a given block type.\n *\n * @param {Object} renderedBlocks Rendered blocks grouped by block name\n * @param {string} blockName Name of the block.\n * @param {*} uniqueId Any value that acts as a unique identifier for a block instance.\n *\n * @return {Object} The list of rendered blocks grouped by block name.\n */\nfunction addToBlockType( renderedBlocks, blockName, uniqueId ) {\n\tconst result = {\n\t\t...renderedBlocks,\n\t\t[ blockName ]: renderedBlocks[ blockName ]\n\t\t\t? new Set( renderedBlocks[ blockName ] )\n\t\t\t: new Set(),\n\t};\n\tresult[ blockName ].add( uniqueId );\n\n\treturn result;\n}\n\n/**\n * A React hook for keeping track of blocks previously rendered up in the block\n * tree. Blocks susceptible to recursion can use this hook in their `Edit`\n * function to prevent said recursion.\n *\n * @param {*} uniqueId Any value that acts as a unique identifier for a block instance.\n * @param {string} blockName Optional block name.\n *\n * @return {[boolean, Function]} A tuple of:\n * - a boolean describing whether the provided id\n * has already been rendered;\n * - a React context provider to be used to wrap\n * other elements.\n */\nexport default function useNoRecursiveRenders( uniqueId, blockName = '' ) {\n\tconst previouslyRenderedBlocks = useContext( RenderedRefsContext );\n\tconst { name } = useBlockEditContext();\n\tblockName = blockName || name;\n\tconst hasAlreadyRendered = Boolean(\n\t\tpreviouslyRenderedBlocks[ blockName ]?.has( uniqueId )\n\t);\n\tconst newRenderedBlocks = useMemo(\n\t\t() => addToBlockType( previouslyRenderedBlocks, blockName, uniqueId ),\n\t\t[ previouslyRenderedBlocks, blockName, uniqueId ]\n\t);\n\tconst Provider = useCallback(\n\t\t( { children } ) => (\n\t\t\t<RenderedRefsContext.Provider value={ newRenderedBlocks }>\n\t\t\t\t{ children }\n\t\t\t</RenderedRefsContext.Provider>\n\t\t),\n\t\t[ newRenderedBlocks ]\n\t);\n\treturn [ hasAlreadyRendered, Provider ];\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["@wordpress/block-editor/src/components/use-no-recursive-renders/index.js"],"names":["createContext","useCallback","useContext","useMemo","useBlockEditContext","RenderedRefsContext","addToBlockType","renderedBlocks","blockName","uniqueId","result","Set","add","useNoRecursiveRenders","previouslyRenderedBlocks","name","hasAlreadyRendered","Boolean","has","newRenderedBlocks","Provider","children"],"mappings":";;AAAA;AACA;AACA;AACA,SACCA,aADD,EAECC,WAFD,EAGCC,UAHD,EAICC,OAJD,QAKO,oBALP;AAOA;AACA;AACA;;AACA,SAASC,mBAAT,QAAoC,uBAApC;AAEA,MAAMC,mBAAmB,GAAGL,aAAa,CAAE,EAAF,CAAzC;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,SAASM,cAAT,CAAyBC,cAAzB,EAAyCC,SAAzC,EAAoDC,QAApD,EAA+D;AAC9D,QAAMC,MAAM,GAAG,EACd,GAAGH,cADW;AAEd,KAAEC,SAAF,GAAeD,cAAc,CAAEC,SAAF,CAAd,GACZ,IAAIG,GAAJ,CAASJ,cAAc,CAAEC,SAAF,CAAvB,CADY,GAEZ,IAAIG,GAAJ;AAJW,GAAf;AAMAD,EAAAA,MAAM,CAAEF,SAAF,CAAN,CAAoBI,GAApB,CAAyBH,QAAzB;AAEA,SAAOC,MAAP;AACA;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,eAAe,SAASG,qBAAT,CAAgCJ,QAAhC,EAA2D;AAAA;;AAAA,MAAjBD,SAAiB,uEAAL,EAAK;AACzE,QAAMM,wBAAwB,GAAGZ,UAAU,CAAEG,mBAAF,CAA3C;AACA,QAAM;AAAEU,IAAAA;AAAF,MAAWX,mBAAmB,EAApC;AACAI,EAAAA,SAAS,GAAGA,SAAS,IAAIO,IAAzB;AACA,QAAMC,kBAAkB,GAAGC,OAAO,0BACjCH,wBAAwB,CAAEN,SAAF,CADS,0DACjC,sBAAuCU,GAAvC,CAA4CT,QAA5C,CADiC,CAAlC;AAGA,QAAMU,iBAAiB,GAAGhB,OAAO,CAChC,MAAMG,cAAc,CAAEQ,wBAAF,EAA4BN,SAA5B,EAAuCC,QAAvC,CADY,EAEhC,CAAEK,wBAAF,EAA4BN,SAA5B,EAAuCC,QAAvC,CAFgC,CAAjC;AAIA,QAAMW,QAAQ,GAAGnB,WAAW,CAC3B;AAAA,QAAE;AAAEoB,MAAAA;AAAF,KAAF;AAAA,WACC,cAAC,mBAAD,CAAqB,QAArB;AAA8B,MAAA,KAAK,EAAGF;AAAtC,OACGE,QADH,CADD;AAAA,GAD2B,EAM3B,CAAEF,iBAAF,CAN2B,CAA5B;AAQA,SAAO,CAAEH,kBAAF,EAAsBI,QAAtB,CAAP;AACA","sourcesContent":["/**\n * WordPress dependencies\n */\nimport {\n\tcreateContext,\n\tuseCallback,\n\tuseContext,\n\tuseMemo,\n} from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { useBlockEditContext } from '../block-edit/context';\n\nconst RenderedRefsContext = createContext( {} );\n\n/**\n * Immutably adds an unique identifier to a set scoped for a given block type.\n *\n * @param {Object} renderedBlocks Rendered blocks grouped by block name\n * @param {string} blockName Name of the block.\n * @param {*} uniqueId Any value that acts as a unique identifier for a block instance.\n *\n * @return {Object} The list of rendered blocks grouped by block name.\n */\nfunction addToBlockType( renderedBlocks, blockName, uniqueId ) {\n\tconst result = {\n\t\t...renderedBlocks,\n\t\t[ blockName ]: renderedBlocks[ blockName ]\n\t\t\t? new Set( renderedBlocks[ blockName ] )\n\t\t\t: new Set(),\n\t};\n\tresult[ blockName ].add( uniqueId );\n\n\treturn result;\n}\n\n/**\n * A React hook for keeping track of blocks previously rendered up in the block\n * tree. Blocks susceptible to recursion can use this hook in their `Edit`\n * function to prevent said recursion.\n *\n * @param {*} uniqueId Any value that acts as a unique identifier for a block instance.\n * @param {string} blockName Optional block name.\n *\n * @return {[boolean, Function]} A tuple of:\n * - a boolean describing whether the provided id\n * has already been rendered;\n * - a React context provider to be used to wrap\n * other elements.\n */\nexport default function useNoRecursiveRenders( uniqueId, blockName = '' ) {\n\tconst previouslyRenderedBlocks = useContext( RenderedRefsContext );\n\tconst { name } = useBlockEditContext();\n\tblockName = blockName || name;\n\tconst hasAlreadyRendered = Boolean(\n\t\tpreviouslyRenderedBlocks[ blockName ]?.has( uniqueId )\n\t);\n\tconst newRenderedBlocks = useMemo(\n\t\t() => addToBlockType( previouslyRenderedBlocks, blockName, uniqueId ),\n\t\t[ previouslyRenderedBlocks, blockName, uniqueId ]\n\t);\n\tconst Provider = useCallback(\n\t\t( { children } ) => (\n\t\t\t<RenderedRefsContext.Provider value={ newRenderedBlocks }>\n\t\t\t\t{ children }\n\t\t\t</RenderedRefsContext.Provider>\n\t\t),\n\t\t[ newRenderedBlocks ]\n\t);\n\treturn [ hasAlreadyRendered, Provider ];\n}\n"]}
|