@wordpress/editor 13.14.0 → 13.16.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 +4 -0
- package/build/components/entities-saved-states/entity-record-item.js +3 -37
- package/build/components/entities-saved-states/entity-record-item.js.map +1 -1
- package/build/components/entities-saved-states/entity-type-list.js +2 -4
- package/build/components/entities-saved-states/entity-type-list.js.map +1 -1
- package/build/components/entities-saved-states/index.js +0 -1
- package/build/components/entities-saved-states/index.js.map +1 -1
- package/build/components/global-keyboard-shortcuts/{save-shortcut.js → index.js} +13 -25
- package/build/components/global-keyboard-shortcuts/index.js.map +1 -0
- package/build/components/index.js +32 -19
- package/build/components/index.js.map +1 -1
- package/build/components/post-comments/index.js +12 -15
- package/build/components/post-comments/index.js.map +1 -1
- package/build/components/post-excerpt/index.js +9 -20
- package/build/components/post-excerpt/index.js.map +1 -1
- package/build/components/post-pingbacks/index.js +12 -15
- package/build/components/post-pingbacks/index.js.map +1 -1
- package/build/components/post-preview-button/index.js +62 -157
- package/build/components/post-preview-button/index.js.map +1 -1
- package/build/components/post-publish-button/index.js +4 -9
- package/build/components/post-publish-button/index.js.map +1 -1
- package/build/components/post-publish-button/label.js +2 -4
- package/build/components/post-publish-button/label.js.map +1 -1
- package/build/components/post-publish-panel/index.js +1 -3
- package/build/components/post-publish-panel/index.js.map +1 -1
- package/build/components/post-saved-state/index.js +2 -5
- package/build/components/post-saved-state/index.js.map +1 -1
- package/build/components/post-schedule/label.js +4 -4
- package/build/components/post-schedule/label.js.map +1 -1
- package/build/components/post-sync-status/index.js +84 -5
- package/build/components/post-sync-status/index.js.map +1 -1
- package/build/components/post-text-editor/index.js +51 -58
- package/build/components/post-text-editor/index.js.map +1 -1
- package/build/components/post-type-support-check/index.js +10 -14
- package/build/components/post-type-support-check/index.js.map +1 -1
- package/build/hooks/custom-sources-backwards-compatibility.js +1 -24
- package/build/hooks/custom-sources-backwards-compatibility.js.map +1 -1
- package/build/store/actions.js +37 -3
- package/build/store/actions.js.map +1 -1
- package/build/store/selectors.js +55 -63
- package/build/store/selectors.js.map +1 -1
- package/build-module/components/entities-saved-states/entity-record-item.js +6 -40
- package/build-module/components/entities-saved-states/entity-record-item.js.map +1 -1
- package/build-module/components/entities-saved-states/entity-type-list.js +2 -4
- package/build-module/components/entities-saved-states/entity-type-list.js.map +1 -1
- package/build-module/components/entities-saved-states/index.js +0 -1
- package/build-module/components/entities-saved-states/index.js.map +1 -1
- package/build-module/components/global-keyboard-shortcuts/{save-shortcut.js → index.js} +12 -23
- package/build-module/components/global-keyboard-shortcuts/index.js.map +1 -0
- package/build-module/components/index.js +9 -4
- package/build-module/components/index.js.map +1 -1
- package/build-module/components/post-comments/index.js +13 -14
- package/build-module/components/post-comments/index.js.map +1 -1
- package/build-module/components/post-excerpt/index.js +10 -19
- package/build-module/components/post-excerpt/index.js.map +1 -1
- package/build-module/components/post-pingbacks/index.js +13 -14
- package/build-module/components/post-pingbacks/index.js.map +1 -1
- package/build-module/components/post-preview-button/index.js +63 -149
- package/build-module/components/post-preview-button/index.js.map +1 -1
- package/build-module/components/post-publish-button/index.js +4 -9
- package/build-module/components/post-publish-button/index.js.map +1 -1
- package/build-module/components/post-publish-button/label.js +2 -4
- package/build-module/components/post-publish-button/label.js.map +1 -1
- package/build-module/components/post-publish-panel/index.js +1 -3
- package/build-module/components/post-publish-panel/index.js.map +1 -1
- package/build-module/components/post-saved-state/index.js +2 -5
- package/build-module/components/post-saved-state/index.js.map +1 -1
- package/build-module/components/post-schedule/label.js +4 -4
- package/build-module/components/post-schedule/label.js.map +1 -1
- package/build-module/components/post-sync-status/index.js +84 -8
- package/build-module/components/post-sync-status/index.js.map +1 -1
- package/build-module/components/post-text-editor/index.js +48 -56
- package/build-module/components/post-text-editor/index.js.map +1 -1
- package/build-module/components/post-type-support-check/index.js +11 -14
- package/build-module/components/post-type-support-check/index.js.map +1 -1
- package/build-module/hooks/custom-sources-backwards-compatibility.js +2 -24
- package/build-module/hooks/custom-sources-backwards-compatibility.js.map +1 -1
- package/build-module/store/actions.js +31 -1
- package/build-module/store/actions.js.map +1 -1
- package/build-module/store/selectors.js +48 -57
- package/build-module/store/selectors.js.map +1 -1
- package/build-style/style-rtl.css +0 -18
- package/build-style/style.css +0 -18
- package/package.json +30 -30
- package/src/components/entities-saved-states/entity-record-item.js +3 -61
- package/src/components/entities-saved-states/entity-type-list.js +0 -2
- package/src/components/entities-saved-states/index.js +0 -1
- package/src/components/entities-saved-states/style.scss +0 -15
- package/src/components/global-keyboard-shortcuts/index.js +49 -0
- package/src/components/index.js +12 -3
- package/src/components/post-author/test/check.js +18 -12
- package/src/components/post-comments/index.js +11 -17
- package/src/components/post-excerpt/index.js +10 -16
- package/src/components/post-pingbacks/index.js +11 -15
- package/src/components/post-preview-button/index.js +73 -156
- package/src/components/post-preview-button/test/index.js +94 -158
- package/src/components/post-publish-button/index.js +2 -7
- package/src/components/post-publish-button/label.js +2 -2
- package/src/components/post-publish-button/test/index.js +0 -10
- package/src/components/post-publish-panel/index.js +1 -3
- package/src/components/post-saved-state/index.js +2 -5
- package/src/components/post-schedule/label.js +4 -4
- package/src/components/post-sync-status/index.js +100 -7
- package/src/components/post-text-editor/index.js +34 -57
- package/src/components/post-title/style.native.scss +5 -5
- package/src/components/post-type-support-check/index.js +8 -10
- package/src/components/post-type-support-check/test/index.js +35 -19
- package/src/hooks/custom-sources-backwards-compatibility.js +1 -25
- package/src/store/actions.js +34 -2
- package/src/store/selectors.js +47 -43
- package/src/store/test/selectors.js +49 -38
- package/build/components/global-keyboard-shortcuts/save-shortcut.js.map +0 -1
- package/build/components/global-keyboard-shortcuts/text-editor-shortcuts.js +0 -22
- package/build/components/global-keyboard-shortcuts/text-editor-shortcuts.js.map +0 -1
- package/build/components/global-keyboard-shortcuts/visual-editor-shortcuts.js +0 -45
- package/build/components/global-keyboard-shortcuts/visual-editor-shortcuts.js.map +0 -1
- package/build-module/components/global-keyboard-shortcuts/save-shortcut.js.map +0 -1
- package/build-module/components/global-keyboard-shortcuts/text-editor-shortcuts.js +0 -12
- package/build-module/components/global-keyboard-shortcuts/text-editor-shortcuts.js.map +0 -1
- package/build-module/components/global-keyboard-shortcuts/visual-editor-shortcuts.js +0 -32
- package/build-module/components/global-keyboard-shortcuts/visual-editor-shortcuts.js.map +0 -1
- package/src/components/global-keyboard-shortcuts/save-shortcut.js +0 -55
- package/src/components/global-keyboard-shortcuts/text-editor-shortcuts.js +0 -8
- package/src/components/global-keyboard-shortcuts/visual-editor-shortcuts.js +0 -29
- package/src/components/post-text-editor/test/index.js +0 -156
|
@@ -7,8 +7,9 @@ import Textarea from 'react-autosize-textarea';
|
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
9
|
import { __ } from '@wordpress/i18n';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
11
|
+
import { useMemo } from '@wordpress/element';
|
|
12
|
+
import { __unstableSerializeAndClean } from '@wordpress/blocks';
|
|
12
13
|
import { useDispatch, useSelect } from '@wordpress/data';
|
|
13
14
|
import { useInstanceId } from '@wordpress/compose';
|
|
14
15
|
import { VisuallyHidden } from '@wordpress/components';
|
|
@@ -19,63 +20,34 @@ import { VisuallyHidden } from '@wordpress/components';
|
|
|
19
20
|
import { store as editorStore } from '../../store';
|
|
20
21
|
|
|
21
22
|
export default function PostTextEditor() {
|
|
22
|
-
const postContent = useSelect(
|
|
23
|
-
( select ) => select( editorStore ).getEditedPostContent(),
|
|
24
|
-
[]
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
const { editPost, resetEditorBlocks } = useDispatch( editorStore );
|
|
28
|
-
|
|
29
|
-
const [ value, setValue ] = useState( postContent );
|
|
30
|
-
const [ isDirty, setIsDirty ] = useState( false );
|
|
31
23
|
const instanceId = useInstanceId( PostTextEditor );
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
24
|
+
const { content, blocks, type, id } = useSelect( ( select ) => {
|
|
25
|
+
const { getEditedEntityRecord } = select( coreStore );
|
|
26
|
+
const { getCurrentPostType, getCurrentPostId } = select( editorStore );
|
|
27
|
+
const _type = getCurrentPostType();
|
|
28
|
+
const _id = getCurrentPostId();
|
|
29
|
+
const editedRecord = getEditedEntityRecord( 'postType', _type, _id );
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
* be followed by a reset to dirty state via `stopEditing`.
|
|
44
|
-
*
|
|
45
|
-
* @see stopEditing
|
|
46
|
-
*
|
|
47
|
-
* @param {Event} event Change event.
|
|
48
|
-
*/
|
|
49
|
-
const onChange = ( event ) => {
|
|
50
|
-
const newValue = event.target.value;
|
|
51
|
-
editPost( { content: newValue } );
|
|
52
|
-
setValue( newValue );
|
|
53
|
-
setIsDirty( true );
|
|
54
|
-
valueRef.current = newValue;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Function called when the user has completed their edits, responsible for
|
|
59
|
-
* ensuring that changes, if made, are surfaced to the onPersist prop
|
|
60
|
-
* callback and resetting dirty state.
|
|
61
|
-
*/
|
|
62
|
-
const stopEditing = () => {
|
|
63
|
-
if ( isDirty ) {
|
|
64
|
-
const blocks = parse( value );
|
|
65
|
-
resetEditorBlocks( blocks );
|
|
66
|
-
setIsDirty( false );
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// Ensure changes aren't lost when component unmounts.
|
|
71
|
-
useEffect( () => {
|
|
72
|
-
return () => {
|
|
73
|
-
if ( valueRef.current ) {
|
|
74
|
-
const blocks = parse( valueRef.current );
|
|
75
|
-
resetEditorBlocks( blocks );
|
|
76
|
-
}
|
|
31
|
+
return {
|
|
32
|
+
content: editedRecord?.content,
|
|
33
|
+
blocks: editedRecord?.blocks,
|
|
34
|
+
type: _type,
|
|
35
|
+
id: _id,
|
|
77
36
|
};
|
|
78
37
|
}, [] );
|
|
38
|
+
const { editEntityRecord } = useDispatch( coreStore );
|
|
39
|
+
// Replicates the logic found in getEditedPostContent().
|
|
40
|
+
const value = useMemo( () => {
|
|
41
|
+
if ( content instanceof Function ) {
|
|
42
|
+
return content( { blocks } );
|
|
43
|
+
} else if ( blocks ) {
|
|
44
|
+
// If we have parsed blocks already, they should be our source of truth.
|
|
45
|
+
// Parsing applies block deprecations and legacy block conversions that
|
|
46
|
+
// unparsed content will not have.
|
|
47
|
+
return __unstableSerializeAndClean( blocks );
|
|
48
|
+
}
|
|
49
|
+
return content;
|
|
50
|
+
}, [ content, blocks ] );
|
|
79
51
|
|
|
80
52
|
return (
|
|
81
53
|
<>
|
|
@@ -89,8 +61,13 @@ export default function PostTextEditor() {
|
|
|
89
61
|
autoComplete="off"
|
|
90
62
|
dir="auto"
|
|
91
63
|
value={ value }
|
|
92
|
-
onChange={
|
|
93
|
-
|
|
64
|
+
onChange={ ( event ) => {
|
|
65
|
+
editEntityRecord( 'postType', type, id, {
|
|
66
|
+
content: event.target.value,
|
|
67
|
+
blocks: undefined,
|
|
68
|
+
selection: undefined,
|
|
69
|
+
} );
|
|
70
|
+
} }
|
|
94
71
|
className="editor-post-text-editor"
|
|
95
72
|
id={ `post-content-${ instanceId }` }
|
|
96
73
|
placeholder={ __( 'Start writing with text or HTML' ) }
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
|
|
2
2
|
.titleContainer {
|
|
3
|
-
padding-left:
|
|
4
|
-
padding-right:
|
|
5
|
-
padding-top:
|
|
6
|
-
padding-bottom:
|
|
7
|
-
margin-top:
|
|
3
|
+
padding-left: $block-edge-to-content;
|
|
4
|
+
padding-right: $block-edge-to-content;
|
|
5
|
+
padding-top: 6;
|
|
6
|
+
padding-bottom: 6;
|
|
7
|
+
margin-top: 12;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
.dimmed {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { useSelect } from '@wordpress/data';
|
|
5
5
|
import { store as coreStore } from '@wordpress/core-data';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -14,7 +14,6 @@ import { store as editorStore } from '../../store';
|
|
|
14
14
|
* type supports one of the given `supportKeys` prop.
|
|
15
15
|
*
|
|
16
16
|
* @param {Object} props Props.
|
|
17
|
-
* @param {string} [props.postType] Current post type.
|
|
18
17
|
* @param {WPElement} props.children Children to be rendered if post
|
|
19
18
|
* type supports.
|
|
20
19
|
* @param {(string|string[])} props.supportKeys String or string array of keys
|
|
@@ -22,7 +21,12 @@ import { store as editorStore } from '../../store';
|
|
|
22
21
|
*
|
|
23
22
|
* @return {WPComponent} The component to be rendered.
|
|
24
23
|
*/
|
|
25
|
-
export function PostTypeSupportCheck( {
|
|
24
|
+
export function PostTypeSupportCheck( { children, supportKeys } ) {
|
|
25
|
+
const postType = useSelect( ( select ) => {
|
|
26
|
+
const { getEditedPostAttribute } = select( editorStore );
|
|
27
|
+
const { getPostType } = select( coreStore );
|
|
28
|
+
return getPostType( getEditedPostAttribute( 'type' ) );
|
|
29
|
+
}, [] );
|
|
26
30
|
let isSupported = true;
|
|
27
31
|
if ( postType ) {
|
|
28
32
|
isSupported = (
|
|
@@ -37,10 +41,4 @@ export function PostTypeSupportCheck( { postType, children, supportKeys } ) {
|
|
|
37
41
|
return children;
|
|
38
42
|
}
|
|
39
43
|
|
|
40
|
-
export default
|
|
41
|
-
const { getEditedPostAttribute } = select( editorStore );
|
|
42
|
-
const { getPostType } = select( coreStore );
|
|
43
|
-
return {
|
|
44
|
-
postType: getPostType( getEditedPostAttribute( 'type' ) ),
|
|
45
|
-
};
|
|
46
|
-
} )( PostTypeSupportCheck );
|
|
44
|
+
export default PostTypeSupportCheck;
|
|
@@ -3,15 +3,37 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { render } from '@testing-library/react';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { useSelect } from '@wordpress/data';
|
|
10
|
+
|
|
6
11
|
/**
|
|
7
12
|
* Internal dependencies
|
|
8
13
|
*/
|
|
9
14
|
import { PostTypeSupportCheck } from '../';
|
|
10
15
|
|
|
16
|
+
jest.mock( '@wordpress/data/src/components/use-select', () => {
|
|
17
|
+
// This allows us to tweak the returned value on each test.
|
|
18
|
+
const mock = jest.fn();
|
|
19
|
+
return mock;
|
|
20
|
+
} );
|
|
21
|
+
|
|
22
|
+
function setupUseSelectMock( postType ) {
|
|
23
|
+
useSelect.mockImplementation( ( cb ) => {
|
|
24
|
+
return cb( () => ( {
|
|
25
|
+
getPostType: () => postType,
|
|
26
|
+
getEditedPostAttribute: () => 'post',
|
|
27
|
+
} ) );
|
|
28
|
+
} );
|
|
29
|
+
}
|
|
30
|
+
|
|
11
31
|
describe( 'PostTypeSupportCheck', () => {
|
|
12
32
|
it( 'renders its children when post type is not known', () => {
|
|
33
|
+
setupUseSelectMock( undefined );
|
|
34
|
+
|
|
13
35
|
const { container } = render(
|
|
14
|
-
<PostTypeSupportCheck
|
|
36
|
+
<PostTypeSupportCheck supportKeys="title">
|
|
15
37
|
Supported
|
|
16
38
|
</PostTypeSupportCheck>
|
|
17
39
|
);
|
|
@@ -20,11 +42,11 @@ describe( 'PostTypeSupportCheck', () => {
|
|
|
20
42
|
} );
|
|
21
43
|
|
|
22
44
|
it( 'does not render its children when post type is known and not supports', () => {
|
|
23
|
-
|
|
45
|
+
setupUseSelectMock( {
|
|
24
46
|
supports: {},
|
|
25
|
-
};
|
|
47
|
+
} );
|
|
26
48
|
const { container } = render(
|
|
27
|
-
<PostTypeSupportCheck
|
|
49
|
+
<PostTypeSupportCheck supportKeys="title">
|
|
28
50
|
Supported
|
|
29
51
|
</PostTypeSupportCheck>
|
|
30
52
|
);
|
|
@@ -33,13 +55,13 @@ describe( 'PostTypeSupportCheck', () => {
|
|
|
33
55
|
} );
|
|
34
56
|
|
|
35
57
|
it( 'renders its children when post type is known and supports', () => {
|
|
36
|
-
|
|
58
|
+
setupUseSelectMock( {
|
|
37
59
|
supports: {
|
|
38
60
|
title: true,
|
|
39
61
|
},
|
|
40
|
-
};
|
|
62
|
+
} );
|
|
41
63
|
const { container } = render(
|
|
42
|
-
<PostTypeSupportCheck
|
|
64
|
+
<PostTypeSupportCheck supportKeys="title">
|
|
43
65
|
Supported
|
|
44
66
|
</PostTypeSupportCheck>
|
|
45
67
|
);
|
|
@@ -48,16 +70,13 @@ describe( 'PostTypeSupportCheck', () => {
|
|
|
48
70
|
} );
|
|
49
71
|
|
|
50
72
|
it( 'renders its children if some of keys supported', () => {
|
|
51
|
-
|
|
73
|
+
setupUseSelectMock( {
|
|
52
74
|
supports: {
|
|
53
75
|
title: true,
|
|
54
76
|
},
|
|
55
|
-
};
|
|
77
|
+
} );
|
|
56
78
|
const { container } = render(
|
|
57
|
-
<PostTypeSupportCheck
|
|
58
|
-
postType={ postType }
|
|
59
|
-
supportKeys={ [ 'title', 'thumbnail' ] }
|
|
60
|
-
>
|
|
79
|
+
<PostTypeSupportCheck supportKeys={ [ 'title', 'thumbnail' ] }>
|
|
61
80
|
Supported
|
|
62
81
|
</PostTypeSupportCheck>
|
|
63
82
|
);
|
|
@@ -66,14 +85,11 @@ describe( 'PostTypeSupportCheck', () => {
|
|
|
66
85
|
} );
|
|
67
86
|
|
|
68
87
|
it( 'does not render its children if none of keys supported', () => {
|
|
69
|
-
|
|
88
|
+
setupUseSelectMock( {
|
|
70
89
|
supports: {},
|
|
71
|
-
};
|
|
90
|
+
} );
|
|
72
91
|
const { container } = render(
|
|
73
|
-
<PostTypeSupportCheck
|
|
74
|
-
postType={ postType }
|
|
75
|
-
supportKeys={ [ 'title', 'thumbnail' ] }
|
|
76
|
-
>
|
|
92
|
+
<PostTypeSupportCheck supportKeys={ [ 'title', 'thumbnail' ] }>
|
|
77
93
|
Supported
|
|
78
94
|
</PostTypeSupportCheck>
|
|
79
95
|
);
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
import { select as globalSelect, useSelect } from '@wordpress/data';
|
|
4
|
+
import { useSelect } from '@wordpress/data';
|
|
6
5
|
import { useEntityProp } from '@wordpress/core-data';
|
|
7
6
|
import { useMemo } from '@wordpress/element';
|
|
8
7
|
import { createHigherOrderComponent } from '@wordpress/compose';
|
|
@@ -124,26 +123,3 @@ addFilter(
|
|
|
124
123
|
'core/editor/custom-sources-backwards-compatibility/shim-attribute-source',
|
|
125
124
|
shimAttributeSource
|
|
126
125
|
);
|
|
127
|
-
|
|
128
|
-
// The above filter will only capture blocks registered after the filter was
|
|
129
|
-
// added. There may already be blocks registered by this point, and those must
|
|
130
|
-
// be updated to apply the shim.
|
|
131
|
-
//
|
|
132
|
-
// The following implementation achieves this, albeit with a couple caveats:
|
|
133
|
-
// - Only blocks registered on the global store will be modified.
|
|
134
|
-
// - The block settings are directly mutated, since there is currently no
|
|
135
|
-
// mechanism to update an existing block registration. This is the reason for
|
|
136
|
-
// `getBlockType` separate from `getBlockTypes`, since the latter returns a
|
|
137
|
-
// _copy_ of the block registration (i.e. the mutation would not affect the
|
|
138
|
-
// actual registered block settings).
|
|
139
|
-
//
|
|
140
|
-
// `getBlockTypes` or `getBlockType` implementation could change in the future
|
|
141
|
-
// in regards to creating settings clones, but the corresponding end-to-end
|
|
142
|
-
// tests for meta blocks should cover against any potential regressions.
|
|
143
|
-
//
|
|
144
|
-
// In the future, we could support updating block settings, at which point this
|
|
145
|
-
// implementation could use that mechanism instead.
|
|
146
|
-
globalSelect( blocksStore )
|
|
147
|
-
.getBlockTypes()
|
|
148
|
-
.map( ( { name } ) => globalSelect( blocksStore ).getBlockType( name ) )
|
|
149
|
-
.forEach( shimAttributeSource );
|
package/src/store/actions.js
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { store as noticesStore } from '@wordpress/notices';
|
|
12
12
|
import { store as coreStore } from '@wordpress/core-data';
|
|
13
13
|
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
14
|
+
import { applyFilters } from '@wordpress/hooks';
|
|
14
15
|
import { store as preferencesStore } from '@wordpress/preferences';
|
|
15
16
|
|
|
16
17
|
/**
|
|
@@ -177,15 +178,26 @@ export const savePost =
|
|
|
177
178
|
edits,
|
|
178
179
|
options
|
|
179
180
|
);
|
|
180
|
-
dispatch( { type: 'REQUEST_POST_UPDATE_FINISH', options } );
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
let error = registry
|
|
183
183
|
.select( coreStore )
|
|
184
184
|
.getLastEntitySaveError(
|
|
185
185
|
'postType',
|
|
186
186
|
previousRecord.type,
|
|
187
187
|
previousRecord.id
|
|
188
188
|
);
|
|
189
|
+
|
|
190
|
+
if ( ! error ) {
|
|
191
|
+
await applyFilters(
|
|
192
|
+
'editor.__unstableSavePost',
|
|
193
|
+
Promise.resolve(),
|
|
194
|
+
options
|
|
195
|
+
).catch( ( err ) => {
|
|
196
|
+
error = err;
|
|
197
|
+
} );
|
|
198
|
+
}
|
|
199
|
+
dispatch( { type: 'REQUEST_POST_UPDATE_FINISH', options } );
|
|
200
|
+
|
|
189
201
|
if ( error ) {
|
|
190
202
|
const args = getNotificationArgumentsForSaveFail( {
|
|
191
203
|
post: previousRecord,
|
|
@@ -289,6 +301,26 @@ export const autosave =
|
|
|
289
301
|
}
|
|
290
302
|
};
|
|
291
303
|
|
|
304
|
+
export const __unstableSaveForPreview =
|
|
305
|
+
( { forceIsAutosaveable } = {} ) =>
|
|
306
|
+
async ( { select, dispatch } ) => {
|
|
307
|
+
if (
|
|
308
|
+
( forceIsAutosaveable || select.isEditedPostAutosaveable() ) &&
|
|
309
|
+
! select.isPostLocked()
|
|
310
|
+
) {
|
|
311
|
+
const isDraft = [ 'draft', 'auto-draft' ].includes(
|
|
312
|
+
select.getEditedPostAttribute( 'status' )
|
|
313
|
+
);
|
|
314
|
+
if ( isDraft ) {
|
|
315
|
+
await dispatch.savePost( { isPreview: true } );
|
|
316
|
+
} else {
|
|
317
|
+
await dispatch.autosave( { isPreview: true } );
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return select.getEditedPostPreviewLink();
|
|
322
|
+
};
|
|
323
|
+
|
|
292
324
|
/**
|
|
293
325
|
* Action that restores last popped state in undo history.
|
|
294
326
|
*/
|
package/src/store/selectors.js
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
getFreeformContentHandlerName,
|
|
11
11
|
getDefaultBlockName,
|
|
12
12
|
__unstableSerializeAndClean,
|
|
13
|
+
parse,
|
|
13
14
|
} from '@wordpress/blocks';
|
|
14
15
|
import { isInTheFuture, getDate } from '@wordpress/date';
|
|
15
16
|
import { addQueryArgs, cleanForSlug } from '@wordpress/url';
|
|
@@ -42,15 +43,6 @@ import { getTemplatePartIcon } from '../utils/get-template-part-icon';
|
|
|
42
43
|
*/
|
|
43
44
|
const EMPTY_OBJECT = {};
|
|
44
45
|
|
|
45
|
-
/**
|
|
46
|
-
* Shared reference to an empty array for cases where it is important to avoid
|
|
47
|
-
* returning a new array reference on every invocation, as in a connected or
|
|
48
|
-
* other pure component which performs `shouldComponentUpdate` check on props.
|
|
49
|
-
* This should be used as a last resort, since the normalized data should be
|
|
50
|
-
* maintained by the reducer result in state.
|
|
51
|
-
*/
|
|
52
|
-
const EMPTY_ARRAY = [];
|
|
53
|
-
|
|
54
46
|
/**
|
|
55
47
|
* Returns true if any past editor history snapshots exist, or false otherwise.
|
|
56
48
|
*
|
|
@@ -507,16 +499,31 @@ export function isEditedPostSaveable( state ) {
|
|
|
507
499
|
*
|
|
508
500
|
* @return {boolean} Whether post has content.
|
|
509
501
|
*/
|
|
510
|
-
export
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
502
|
+
export const isEditedPostEmpty = createRegistrySelector(
|
|
503
|
+
( select ) => ( state ) => {
|
|
504
|
+
// While the condition of truthy content string is sufficient to determine
|
|
505
|
+
// emptiness, testing saveable blocks length is a trivial operation. Since
|
|
506
|
+
// this function can be called frequently, optimize for the fast case as a
|
|
507
|
+
// condition of the mere existence of blocks. Note that the value of edited
|
|
508
|
+
// content takes precedent over block content, and must fall through to the
|
|
509
|
+
// default logic.
|
|
510
|
+
const postId = getCurrentPostId( state );
|
|
511
|
+
const postType = getCurrentPostType( state );
|
|
512
|
+
const record = select( coreStore ).getEditedEntityRecord(
|
|
513
|
+
'postType',
|
|
514
|
+
postType,
|
|
515
|
+
postId
|
|
516
|
+
);
|
|
517
|
+
if ( typeof record.content !== 'function' ) {
|
|
518
|
+
return ! record.content;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
const blocks = getEditedPostAttribute( state, 'blocks' );
|
|
522
|
+
|
|
523
|
+
if ( blocks.length === 0 ) {
|
|
524
|
+
return true;
|
|
525
|
+
}
|
|
518
526
|
|
|
519
|
-
if ( blocks.length ) {
|
|
520
527
|
// Pierce the abstraction of the serializer in knowing that blocks are
|
|
521
528
|
// joined with newlines such that even if every individual block
|
|
522
529
|
// produces an empty save result, the serialized content is non-empty.
|
|
@@ -542,10 +549,10 @@ export function isEditedPostEmpty( state ) {
|
|
|
542
549
|
) {
|
|
543
550
|
return false;
|
|
544
551
|
}
|
|
545
|
-
}
|
|
546
552
|
|
|
547
|
-
|
|
548
|
-
}
|
|
553
|
+
return ! getEditedPostContent( state );
|
|
554
|
+
}
|
|
555
|
+
);
|
|
549
556
|
|
|
550
557
|
/**
|
|
551
558
|
* Returns true if the post can be autosaved, or false otherwise.
|
|
@@ -604,8 +611,8 @@ export const isEditedPostAutosaveable = createRegistrySelector(
|
|
|
604
611
|
return true;
|
|
605
612
|
}
|
|
606
613
|
|
|
607
|
-
// If
|
|
608
|
-
return [ 'title', 'excerpt' ].some(
|
|
614
|
+
// If title, excerpt, or meta have changed, the post is autosaveable.
|
|
615
|
+
return [ 'title', 'excerpt', 'meta' ].some(
|
|
609
616
|
( field ) =>
|
|
610
617
|
getPostRawValue( autosave[ field ] ) !==
|
|
611
618
|
getEditedPostAttribute( state, field )
|
|
@@ -681,15 +688,9 @@ export function isDeletingPost( state ) {
|
|
|
681
688
|
*
|
|
682
689
|
* @return {boolean} Whether post is being saved.
|
|
683
690
|
*/
|
|
684
|
-
export
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
return select( coreStore ).isSavingEntityRecord(
|
|
688
|
-
'postType',
|
|
689
|
-
postType,
|
|
690
|
-
postId
|
|
691
|
-
);
|
|
692
|
-
} );
|
|
691
|
+
export function isSavingPost( state ) {
|
|
692
|
+
return !! state.saving.pending;
|
|
693
|
+
}
|
|
693
694
|
|
|
694
695
|
/**
|
|
695
696
|
* Returns true if non-post entities are currently being saved, or false otherwise.
|
|
@@ -760,10 +761,7 @@ export const didPostSaveRequestFail = createRegistrySelector(
|
|
|
760
761
|
* @return {boolean} Whether the post is autosaving.
|
|
761
762
|
*/
|
|
762
763
|
export function isAutosavingPost( state ) {
|
|
763
|
-
|
|
764
|
-
return false;
|
|
765
|
-
}
|
|
766
|
-
return Boolean( state.saving.options?.isAutosave );
|
|
764
|
+
return isSavingPost( state ) && Boolean( state.saving.options?.isAutosave );
|
|
767
765
|
}
|
|
768
766
|
|
|
769
767
|
/**
|
|
@@ -774,10 +772,7 @@ export function isAutosavingPost( state ) {
|
|
|
774
772
|
* @return {boolean} Whether the post is being previewed.
|
|
775
773
|
*/
|
|
776
774
|
export function isPreviewingPost( state ) {
|
|
777
|
-
|
|
778
|
-
return false;
|
|
779
|
-
}
|
|
780
|
-
return Boolean( state.saving.options?.isPreview );
|
|
775
|
+
return isSavingPost( state ) && Boolean( state.saving.options?.isPreview );
|
|
781
776
|
}
|
|
782
777
|
|
|
783
778
|
/**
|
|
@@ -1100,9 +1095,18 @@ export const isPublishSidebarEnabled = createRegistrySelector(
|
|
|
1100
1095
|
* @param {Object} state
|
|
1101
1096
|
* @return {Array} Block list.
|
|
1102
1097
|
*/
|
|
1103
|
-
export
|
|
1104
|
-
|
|
1105
|
-
|
|
1098
|
+
export const getEditorBlocks = createSelector(
|
|
1099
|
+
( state ) => {
|
|
1100
|
+
return (
|
|
1101
|
+
getEditedPostAttribute( state, 'blocks' ) ||
|
|
1102
|
+
parse( getEditedPostContent( state ) )
|
|
1103
|
+
);
|
|
1104
|
+
},
|
|
1105
|
+
( state ) => [
|
|
1106
|
+
getEditedPostAttribute( state, 'blocks' ),
|
|
1107
|
+
getEditedPostContent( state ),
|
|
1108
|
+
]
|
|
1109
|
+
);
|
|
1106
1110
|
|
|
1107
1111
|
/**
|
|
1108
1112
|
* A block selection object.
|