@wordpress/editor 13.25.0 → 13.26.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 +6 -0
- package/LICENSE.md +1 -1
- package/build/components/document-bar/index.js +19 -7
- package/build/components/document-bar/index.js.map +1 -1
- package/build/components/document-outline/index.js +82 -1
- package/build/components/document-outline/index.js.map +1 -1
- package/build/components/document-tools/index.js +160 -0
- package/build/components/document-tools/index.js.map +1 -0
- package/build/components/editor-canvas/index.js +10 -4
- package/build/components/editor-canvas/index.js.map +1 -1
- package/build/components/entities-saved-states/index.js +3 -1
- package/build/components/entities-saved-states/index.js.map +1 -1
- package/build/components/global-keyboard-shortcuts/index.js +12 -2
- package/build/components/global-keyboard-shortcuts/index.js.map +1 -1
- package/build/components/global-keyboard-shortcuts/register-shortcuts.js +9 -0
- package/build/components/global-keyboard-shortcuts/register-shortcuts.js.map +1 -1
- package/build/components/index.js +56 -8
- package/build/components/index.js.map +1 -1
- package/build/components/index.native.js +9 -1
- package/build/components/index.native.js.map +1 -1
- package/build/components/inserter-sidebar/index.js +77 -0
- package/build/components/inserter-sidebar/index.js.map +1 -0
- package/build/components/list-view-sidebar/index.js +150 -0
- package/build/components/list-view-sidebar/index.js.map +1 -0
- package/build/components/list-view-sidebar/list-view-outline.js +28 -0
- package/build/components/list-view-sidebar/list-view-outline.js.map +1 -0
- package/build/components/offline-status/index.native.js +85 -0
- package/build/components/offline-status/index.native.js.map +1 -0
- package/build/components/page-attributes/panel.js +63 -0
- package/build/components/page-attributes/panel.js.map +1 -0
- package/build/components/post-discussion/panel.js +59 -0
- package/build/components/post-discussion/panel.js.map +1 -0
- package/build/components/post-excerpt/check.js +19 -0
- package/build/components/post-excerpt/check.js.map +1 -1
- package/build/components/post-excerpt/panel.js +55 -0
- package/build/components/post-excerpt/panel.js.map +1 -0
- package/build/components/post-excerpt/plugin.js +72 -0
- package/build/components/post-excerpt/plugin.js.map +1 -0
- package/build/components/post-featured-image/index.js +5 -8
- package/build/components/post-featured-image/index.js.map +1 -1
- package/build/components/post-featured-image/panel.js +60 -0
- package/build/components/post-featured-image/panel.js.map +1 -0
- package/build/components/post-last-revision/panel.js +27 -0
- package/build/components/post-last-revision/panel.js.map +1 -0
- package/build/components/post-saved-state/index.js +12 -8
- package/build/components/post-saved-state/index.js.map +1 -1
- package/build/components/post-taxonomies/panel.js +68 -0
- package/build/components/post-taxonomies/panel.js.map +1 -0
- package/build/components/post-template/block-theme.js +2 -1
- package/build/components/post-template/block-theme.js.map +1 -1
- package/build/components/post-template/hooks.js +6 -6
- package/build/components/post-template/hooks.js.map +1 -1
- package/build/components/post-template/panel.js +1 -2
- package/build/components/post-template/panel.js.map +1 -1
- package/build/components/post-template/swap-template-button.js +4 -2
- package/build/components/post-template/swap-template-button.js.map +1 -1
- package/build/components/post-title/index.native.js +25 -14
- package/build/components/post-title/index.native.js.map +1 -1
- package/build/components/post-view-link/index.js +58 -0
- package/build/components/post-view-link/index.js.map +1 -0
- package/build/components/post-visibility/check.js +5 -17
- package/build/components/post-visibility/check.js.map +1 -1
- package/build/components/preview-dropdown/index.js +8 -3
- package/build/components/preview-dropdown/index.js.map +1 -1
- package/build/components/provider/index.native.js +19 -0
- package/build/components/provider/index.native.js.map +1 -1
- package/build/components/provider/use-block-editor-settings.js +29 -5
- package/build/components/provider/use-block-editor-settings.js.map +1 -1
- package/build/private-apis.js +10 -0
- package/build/private-apis.js.map +1 -1
- package/build/store/actions.js +102 -2
- package/build/store/actions.js.map +1 -1
- package/build/store/index.js +2 -0
- package/build/store/index.js.map +1 -1
- package/build/store/private-selectors.js +52 -0
- package/build/store/private-selectors.js.map +1 -0
- package/build/store/reducer.js +78 -1
- package/build/store/reducer.js.map +1 -1
- package/build/store/selectors.js +76 -2
- package/build/store/selectors.js.map +1 -1
- package/build/utils/media-upload/index.js +8 -2
- package/build/utils/media-upload/index.js.map +1 -1
- package/build-module/components/document-bar/index.js +19 -7
- package/build-module/components/document-bar/index.js.map +1 -1
- package/build-module/components/document-outline/index.js +82 -1
- package/build-module/components/document-outline/index.js.map +1 -1
- package/build-module/components/document-tools/index.js +151 -0
- package/build-module/components/document-tools/index.js.map +1 -0
- package/build-module/components/editor-canvas/index.js +10 -4
- package/build-module/components/editor-canvas/index.js.map +1 -1
- package/build-module/components/entities-saved-states/index.js +3 -1
- package/build-module/components/entities-saved-states/index.js.map +1 -1
- package/build-module/components/global-keyboard-shortcuts/index.js +12 -2
- package/build-module/components/global-keyboard-shortcuts/index.js.map +1 -1
- package/build-module/components/global-keyboard-shortcuts/register-shortcuts.js +9 -0
- package/build-module/components/global-keyboard-shortcuts/register-shortcuts.js.map +1 -1
- package/build-module/components/index.js +6 -0
- package/build-module/components/index.js.map +1 -1
- package/build-module/components/index.native.js +1 -0
- package/build-module/components/index.native.js.map +1 -1
- package/build-module/components/inserter-sidebar/index.js +70 -0
- package/build-module/components/inserter-sidebar/index.js.map +1 -0
- package/build-module/components/list-view-sidebar/index.js +142 -0
- package/build-module/components/list-view-sidebar/index.js.map +1 -0
- package/build-module/components/list-view-sidebar/list-view-outline.js +20 -0
- package/build-module/components/list-view-sidebar/list-view-outline.js.map +1 -0
- package/build-module/components/offline-status/index.native.js +77 -0
- package/build-module/components/offline-status/index.native.js.map +1 -0
- package/build-module/components/page-attributes/panel.js +53 -0
- package/build-module/components/page-attributes/panel.js.map +1 -0
- package/build-module/components/post-discussion/panel.js +50 -0
- package/build-module/components/post-discussion/panel.js.map +1 -0
- package/build-module/components/post-excerpt/check.js +19 -0
- package/build-module/components/post-excerpt/check.js.map +1 -1
- package/build-module/components/post-excerpt/panel.js +48 -0
- package/build-module/components/post-excerpt/panel.js.map +1 -0
- package/build-module/components/post-excerpt/plugin.js +64 -0
- package/build-module/components/post-excerpt/plugin.js.map +1 -0
- package/build-module/components/post-featured-image/index.js +5 -8
- package/build-module/components/post-featured-image/index.js.map +1 -1
- package/build-module/components/post-featured-image/panel.js +51 -0
- package/build-module/components/post-featured-image/panel.js.map +1 -0
- package/build-module/components/post-last-revision/panel.js +18 -0
- package/build-module/components/post-last-revision/panel.js.map +1 -0
- package/build-module/components/post-saved-state/index.js +12 -8
- package/build-module/components/post-saved-state/index.js.map +1 -1
- package/build-module/components/post-taxonomies/panel.js +59 -0
- package/build-module/components/post-taxonomies/panel.js.map +1 -0
- package/build-module/components/post-template/block-theme.js +2 -1
- package/build-module/components/post-template/block-theme.js.map +1 -1
- package/build-module/components/post-template/hooks.js +6 -6
- package/build-module/components/post-template/hooks.js.map +1 -1
- package/build-module/components/post-template/panel.js +1 -2
- package/build-module/components/post-template/panel.js.map +1 -1
- package/build-module/components/post-template/swap-template-button.js +4 -2
- package/build-module/components/post-template/swap-template-button.js.map +1 -1
- package/build-module/components/post-title/index.native.js +26 -15
- package/build-module/components/post-title/index.native.js.map +1 -1
- package/build-module/components/post-view-link/index.js +51 -0
- package/build-module/components/post-view-link/index.js.map +1 -0
- package/build-module/components/post-visibility/check.js +6 -16
- package/build-module/components/post-visibility/check.js.map +1 -1
- package/build-module/components/preview-dropdown/index.js +8 -3
- package/build-module/components/preview-dropdown/index.js.map +1 -1
- package/build-module/components/provider/index.native.js +19 -0
- package/build-module/components/provider/index.native.js.map +1 -1
- package/build-module/components/provider/use-block-editor-settings.js +29 -5
- package/build-module/components/provider/use-block-editor-settings.js.map +1 -1
- package/build-module/private-apis.js +10 -0
- package/build-module/private-apis.js.map +1 -1
- package/build-module/store/actions.js +94 -0
- package/build-module/store/actions.js.map +1 -1
- package/build-module/store/index.js +2 -0
- package/build-module/store/index.js.map +1 -1
- package/build-module/store/private-selectors.js +43 -0
- package/build-module/store/private-selectors.js.map +1 -0
- package/build-module/store/reducer.js +74 -1
- package/build-module/store/reducer.js.map +1 -1
- package/build-module/store/selectors.js +67 -0
- package/build-module/store/selectors.js.map +1 -1
- package/build-module/utils/media-upload/index.js +8 -2
- package/build-module/utils/media-upload/index.js.map +1 -1
- package/build-style/style-rtl.css +251 -0
- package/build-style/style.css +251 -0
- package/package.json +32 -32
- package/src/components/document-bar/index.js +39 -28
- package/src/components/document-outline/index.js +48 -1
- package/src/components/document-outline/style.scss +12 -0
- package/src/components/document-tools/index.js +177 -0
- package/src/components/document-tools/style.scss +98 -0
- package/src/components/editor-canvas/index.js +12 -7
- package/src/components/editor-canvas/style.scss +5 -0
- package/src/components/entities-saved-states/index.js +3 -1
- package/src/components/entities-saved-states/style.scss +4 -0
- package/src/components/global-keyboard-shortcuts/index.js +12 -2
- package/src/components/global-keyboard-shortcuts/register-shortcuts.js +10 -0
- package/src/components/index.js +6 -0
- package/src/components/index.native.js +1 -0
- package/src/components/inserter-sidebar/index.js +73 -0
- package/src/components/inserter-sidebar/style.scss +22 -0
- package/src/components/list-view-sidebar/index.js +169 -0
- package/src/components/list-view-sidebar/list-view-outline.js +37 -0
- package/src/components/list-view-sidebar/style.scss +84 -0
- package/src/components/offline-status/index.native.js +101 -0
- package/src/components/offline-status/style.native.scss +28 -0
- package/src/components/offline-status/test/index.native.js +108 -0
- package/src/components/page-attributes/panel.js +62 -0
- package/src/components/post-discussion/panel.js +57 -0
- package/src/components/post-excerpt/check.js +18 -0
- package/src/components/post-excerpt/panel.js +57 -0
- package/src/components/post-excerpt/plugin.js +61 -0
- package/src/components/post-excerpt/test/plugin.js +36 -0
- package/src/components/post-featured-image/index.js +3 -7
- package/src/components/post-featured-image/panel.js +55 -0
- package/src/components/post-last-revision/panel.js +22 -0
- package/src/components/post-last-revision/style.scss +10 -0
- package/src/components/post-saved-state/index.js +8 -8
- package/src/components/post-taxonomies/panel.js +66 -0
- package/src/components/post-template/block-theme.js +2 -1
- package/src/components/post-template/hooks.js +6 -6
- package/src/components/post-template/panel.js +1 -2
- package/src/components/post-template/swap-template-button.js +7 -4
- package/src/components/post-title/index.native.js +32 -17
- package/src/components/post-title/style.scss +1 -0
- package/src/components/post-title/test/__snapshots__/index.native.js.snap +25 -0
- package/src/components/post-title/test/index.native.js +78 -0
- package/src/components/post-view-link/index.js +47 -0
- package/src/components/post-visibility/check.js +10 -15
- package/src/components/post-visibility/test/check.js +24 -13
- package/src/components/preview-dropdown/index.js +7 -10
- package/src/components/provider/index.native.js +29 -2
- package/src/components/provider/use-block-editor-settings.js +36 -8
- package/src/private-apis.js +10 -0
- package/src/store/actions.js +109 -0
- package/src/store/index.js +2 -0
- package/src/store/private-selectors.js +51 -0
- package/src/store/reducer.js +72 -0
- package/src/store/selectors.js +80 -0
- package/src/store/test/actions.js +56 -0
- package/src/store/test/reducer.js +98 -0
- package/src/store/test/selectors.js +49 -0
- package/src/style.scss +4 -0
- package/src/utils/media-upload/index.js +9 -2
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`PostTitle does not update title with existing content when pasting HTML 1`] = `
|
|
4
|
+
"<!-- wp:heading -->
|
|
5
|
+
<h2 class="wp-block-heading">Howdy</h2>
|
|
6
|
+
<!-- /wp:heading -->
|
|
7
|
+
|
|
8
|
+
<!-- wp:heading -->
|
|
9
|
+
<h2 class="wp-block-heading">This is a heading.</h2>
|
|
10
|
+
<!-- /wp:heading -->
|
|
11
|
+
|
|
12
|
+
<!-- wp:paragraph -->
|
|
13
|
+
<p>This is a paragraph.</p>
|
|
14
|
+
<!-- /wp:paragraph -->"
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
exports[`PostTitle populates empty title with first block content when pasting HTML 1`] = `
|
|
18
|
+
"<!-- wp:heading -->
|
|
19
|
+
<h2 class="wp-block-heading">This is a heading.</h2>
|
|
20
|
+
<!-- /wp:heading -->
|
|
21
|
+
|
|
22
|
+
<!-- wp:paragraph -->
|
|
23
|
+
<p>This is a paragraph.</p>
|
|
24
|
+
<!-- /wp:paragraph -->"
|
|
25
|
+
`;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
getEditorHtml,
|
|
6
|
+
getEditorTitle,
|
|
7
|
+
initializeEditor,
|
|
8
|
+
pasteIntoRichText,
|
|
9
|
+
selectRangeInRichText,
|
|
10
|
+
screen,
|
|
11
|
+
setupCoreBlocks,
|
|
12
|
+
within,
|
|
13
|
+
} from 'test/helpers';
|
|
14
|
+
|
|
15
|
+
setupCoreBlocks();
|
|
16
|
+
|
|
17
|
+
const HTML_MULTIPLE_TAGS = `<h2>Howdy</h2>
|
|
18
|
+
<h2>This is a heading.</h2>
|
|
19
|
+
<p>This is a paragraph.</p>`;
|
|
20
|
+
|
|
21
|
+
describe( 'PostTitle', () => {
|
|
22
|
+
it( 'populates empty title with first block content when pasting HTML', async () => {
|
|
23
|
+
await initializeEditor( { initialTitle: '' } );
|
|
24
|
+
|
|
25
|
+
const postTitle = within(
|
|
26
|
+
screen.getByTestId( 'post-title' )
|
|
27
|
+
).getByPlaceholderText( 'Add title' );
|
|
28
|
+
pasteIntoRichText( postTitle, { html: HTML_MULTIPLE_TAGS } );
|
|
29
|
+
|
|
30
|
+
expect( console ).toHaveLogged();
|
|
31
|
+
expect( getEditorTitle() ).toBe( 'Howdy' );
|
|
32
|
+
expect( getEditorHtml() ).toMatchSnapshot();
|
|
33
|
+
} );
|
|
34
|
+
|
|
35
|
+
it( 'does not update title with existing content when pasting HTML', async () => {
|
|
36
|
+
const initialTitle = 'Hello';
|
|
37
|
+
await initializeEditor( { initialTitle } );
|
|
38
|
+
|
|
39
|
+
const postTitle = within(
|
|
40
|
+
screen.getByTestId( 'post-title' )
|
|
41
|
+
).getByPlaceholderText( 'Add title' );
|
|
42
|
+
selectRangeInRichText( postTitle, 0 );
|
|
43
|
+
pasteIntoRichText( postTitle, { html: HTML_MULTIPLE_TAGS } );
|
|
44
|
+
|
|
45
|
+
expect( console ).toHaveLogged();
|
|
46
|
+
expect( getEditorTitle() ).toBe( initialTitle );
|
|
47
|
+
expect( getEditorHtml() ).toMatchSnapshot();
|
|
48
|
+
} );
|
|
49
|
+
|
|
50
|
+
it( 'updates title with existing content when pasting text', async () => {
|
|
51
|
+
await initializeEditor( { initialTitle: 'World' } );
|
|
52
|
+
|
|
53
|
+
const postTitle = within(
|
|
54
|
+
screen.getByTestId( 'post-title' )
|
|
55
|
+
).getByPlaceholderText( 'Add title' );
|
|
56
|
+
selectRangeInRichText( postTitle, 0 );
|
|
57
|
+
pasteIntoRichText( postTitle, { text: 'Hello' } );
|
|
58
|
+
|
|
59
|
+
expect( console ).toHaveLogged();
|
|
60
|
+
expect( getEditorTitle() ).toBe( 'HelloWorld' );
|
|
61
|
+
expect( getEditorHtml() ).toBe( '' );
|
|
62
|
+
} );
|
|
63
|
+
|
|
64
|
+
it( 'does not add HTML to title when pasting span tag', async () => {
|
|
65
|
+
const pasteHTML = `<span style="border: 1px solid black">l</span>`;
|
|
66
|
+
await initializeEditor( { initialTitle: 'Helo' } );
|
|
67
|
+
|
|
68
|
+
const postTitle = within(
|
|
69
|
+
screen.getByTestId( 'post-title' )
|
|
70
|
+
).getByPlaceholderText( 'Add title' );
|
|
71
|
+
selectRangeInRichText( postTitle, 2 );
|
|
72
|
+
pasteIntoRichText( postTitle, { html: pasteHTML } );
|
|
73
|
+
|
|
74
|
+
expect( console ).toHaveLogged();
|
|
75
|
+
expect( getEditorTitle() ).toBe( 'Hello' );
|
|
76
|
+
expect( getEditorHtml() ).toBe( '' );
|
|
77
|
+
} );
|
|
78
|
+
} );
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
import { Button } from '@wordpress/components';
|
|
6
|
+
import { external } from '@wordpress/icons';
|
|
7
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
8
|
+
import { useSelect } from '@wordpress/data';
|
|
9
|
+
import { store as preferencesStore } from '@wordpress/preferences';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies
|
|
13
|
+
*/
|
|
14
|
+
import { store as editorStore } from '../../store';
|
|
15
|
+
|
|
16
|
+
export default function PostViewLink() {
|
|
17
|
+
const { hasLoaded, permalink, isPublished, label, showIconLabels } =
|
|
18
|
+
useSelect( ( select ) => {
|
|
19
|
+
// Grab post type to retrieve the view_item label.
|
|
20
|
+
const postTypeSlug = select( editorStore ).getCurrentPostType();
|
|
21
|
+
const postType = select( coreStore ).getPostType( postTypeSlug );
|
|
22
|
+
const { get } = select( preferencesStore );
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
permalink: select( editorStore ).getPermalink(),
|
|
26
|
+
isPublished: select( editorStore ).isCurrentPostPublished(),
|
|
27
|
+
label: postType?.labels.view_item,
|
|
28
|
+
hasLoaded: !! postType,
|
|
29
|
+
showIconLabels: get( 'core', 'showIconLabels' ),
|
|
30
|
+
};
|
|
31
|
+
}, [] );
|
|
32
|
+
|
|
33
|
+
// Only render the view button if the post is published and has a permalink.
|
|
34
|
+
if ( ! isPublished || ! permalink || ! hasLoaded ) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<Button
|
|
40
|
+
icon={ external }
|
|
41
|
+
label={ label || __( 'View post' ) }
|
|
42
|
+
href={ permalink }
|
|
43
|
+
target="_blank"
|
|
44
|
+
showTooltip={ ! showIconLabels }
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -1,26 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
import { withSelect } from '@wordpress/data';
|
|
4
|
+
import { useSelect } from '@wordpress/data';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* Internal dependencies
|
|
9
8
|
*/
|
|
10
9
|
import { store as editorStore } from '../../store';
|
|
11
10
|
|
|
12
|
-
export function PostVisibilityCheck( {
|
|
13
|
-
const canEdit =
|
|
11
|
+
export default function PostVisibilityCheck( { render } ) {
|
|
12
|
+
const canEdit = useSelect( ( select ) => {
|
|
13
|
+
return (
|
|
14
|
+
select( editorStore ).getCurrentPost()._links?.[
|
|
15
|
+
'wp:action-publish'
|
|
16
|
+
] ?? false
|
|
17
|
+
);
|
|
18
|
+
} );
|
|
19
|
+
|
|
14
20
|
return render( { canEdit } );
|
|
15
21
|
}
|
|
16
|
-
|
|
17
|
-
export default compose( [
|
|
18
|
-
withSelect( ( select ) => {
|
|
19
|
-
const { getCurrentPost, getCurrentPostType } = select( editorStore );
|
|
20
|
-
return {
|
|
21
|
-
hasPublishAction:
|
|
22
|
-
getCurrentPost()._links?.[ 'wp:action-publish' ] ?? false,
|
|
23
|
-
postType: getCurrentPostType(),
|
|
24
|
-
};
|
|
25
|
-
} ),
|
|
26
|
-
] )( PostVisibilityCheck );
|
|
@@ -3,32 +3,43 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { render, screen } from '@testing-library/react';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { useSelect } from '@wordpress/data';
|
|
10
|
+
|
|
11
|
+
jest.mock( '@wordpress/data/src/components/use-select', () => jest.fn() );
|
|
12
|
+
|
|
6
13
|
/**
|
|
7
14
|
* Internal dependencies
|
|
8
15
|
*/
|
|
9
|
-
import
|
|
16
|
+
import PostVisibilityCheck from '../check';
|
|
17
|
+
|
|
18
|
+
function setupMockSelect( hasPublishAction ) {
|
|
19
|
+
useSelect.mockImplementation( ( mapSelect ) => {
|
|
20
|
+
return mapSelect( () => ( {
|
|
21
|
+
getCurrentPost: () => ( {
|
|
22
|
+
_links: {
|
|
23
|
+
'wp:action-publish': hasPublishAction,
|
|
24
|
+
},
|
|
25
|
+
} ),
|
|
26
|
+
} ) );
|
|
27
|
+
} );
|
|
28
|
+
}
|
|
10
29
|
|
|
11
30
|
describe( 'PostVisibilityCheck', () => {
|
|
12
31
|
const renderProp = ( { canEdit } ) => ( canEdit ? 'yes' : 'no' );
|
|
13
32
|
|
|
14
33
|
it( "should not render the edit link if the user doesn't have the right capability", () => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
hasPublishAction={ false }
|
|
18
|
-
render={ renderProp }
|
|
19
|
-
/>
|
|
20
|
-
);
|
|
34
|
+
setupMockSelect( false );
|
|
35
|
+
render( <PostVisibilityCheck render={ renderProp } /> );
|
|
21
36
|
expect( screen.queryByText( 'yes' ) ).not.toBeInTheDocument();
|
|
22
37
|
expect( screen.getByText( 'no' ) ).toBeVisible();
|
|
23
38
|
} );
|
|
24
39
|
|
|
25
40
|
it( 'should render if the user has the correct capability', () => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
hasPublishAction={ true }
|
|
29
|
-
render={ renderProp }
|
|
30
|
-
/>
|
|
31
|
-
);
|
|
41
|
+
setupMockSelect( true );
|
|
42
|
+
render( <PostVisibilityCheck render={ renderProp } /> );
|
|
32
43
|
expect( screen.queryByText( 'no' ) ).not.toBeInTheDocument();
|
|
33
44
|
expect( screen.getByText( 'yes' ) ).toBeVisible();
|
|
34
45
|
} );
|
|
@@ -13,6 +13,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
13
13
|
import { check, desktop, mobile, tablet, external } from '@wordpress/icons';
|
|
14
14
|
import { useSelect, useDispatch } from '@wordpress/data';
|
|
15
15
|
import { store as coreStore } from '@wordpress/core-data';
|
|
16
|
+
import { store as preferencesStore } from '@wordpress/preferences';
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Internal dependencies
|
|
@@ -20,25 +21,21 @@ import { store as coreStore } from '@wordpress/core-data';
|
|
|
20
21
|
import { store as editorStore } from '../../store';
|
|
21
22
|
import PostPreviewButton from '../post-preview-button';
|
|
22
23
|
|
|
23
|
-
export default function PreviewDropdown( {
|
|
24
|
-
showIconLabels
|
|
25
|
-
|
|
26
|
-
disabled,
|
|
27
|
-
} ) {
|
|
28
|
-
const { deviceType, homeUrl, isTemplate, isViewable } = useSelect(
|
|
29
|
-
( select ) => {
|
|
24
|
+
export default function PreviewDropdown( { forceIsAutosaveable, disabled } ) {
|
|
25
|
+
const { deviceType, homeUrl, isTemplate, isViewable, showIconLabels } =
|
|
26
|
+
useSelect( ( select ) => {
|
|
30
27
|
const { getDeviceType, getCurrentPostType } = select( editorStore );
|
|
31
28
|
const { getUnstableBase, getPostType } = select( coreStore );
|
|
29
|
+
const { get } = select( preferencesStore );
|
|
32
30
|
const _currentPostType = getCurrentPostType();
|
|
33
31
|
return {
|
|
34
32
|
deviceType: getDeviceType(),
|
|
35
33
|
homeUrl: getUnstableBase()?.home,
|
|
36
34
|
isTemplate: _currentPostType === 'wp_template',
|
|
37
35
|
isViewable: getPostType( _currentPostType )?.viewable ?? false,
|
|
36
|
+
showIconLabels: get( 'core', 'showIconLabels' ),
|
|
38
37
|
};
|
|
39
|
-
},
|
|
40
|
-
[]
|
|
41
|
-
);
|
|
38
|
+
}, [] );
|
|
42
39
|
const { setDeviceType } = useDispatch( editorStore );
|
|
43
40
|
const isMobile = useViewportMatch( 'medium', '<' );
|
|
44
41
|
if ( isMobile ) return null;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
+
import { BackHandler } from 'react-native';
|
|
4
5
|
import memize from 'memize';
|
|
5
6
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
6
7
|
|
|
@@ -79,6 +80,8 @@ class NativeEditorProvider extends Component {
|
|
|
79
80
|
this.post
|
|
80
81
|
);
|
|
81
82
|
|
|
83
|
+
this.onHardwareBackPress = this.onHardwareBackPress.bind( this );
|
|
84
|
+
|
|
82
85
|
this.getEditorSettings = memize(
|
|
83
86
|
( settings, capabilities ) => ( {
|
|
84
87
|
...settings,
|
|
@@ -191,6 +194,11 @@ class NativeEditorProvider extends Component {
|
|
|
191
194
|
this.setState( { isHelpVisible: true } );
|
|
192
195
|
} );
|
|
193
196
|
|
|
197
|
+
this.hardwareBackPressListener = BackHandler.addEventListener(
|
|
198
|
+
'hardwareBackPress',
|
|
199
|
+
this.onHardwareBackPress
|
|
200
|
+
);
|
|
201
|
+
|
|
194
202
|
// Request current block impressions from native app.
|
|
195
203
|
requestBlockTypeImpressions( ( storedImpressions ) => {
|
|
196
204
|
const impressions = { ...NEW_BLOCK_TYPES, ...storedImpressions };
|
|
@@ -250,6 +258,10 @@ class NativeEditorProvider extends Component {
|
|
|
250
258
|
if ( this.subscriptionParentShowEditorHelp ) {
|
|
251
259
|
this.subscriptionParentShowEditorHelp.remove();
|
|
252
260
|
}
|
|
261
|
+
|
|
262
|
+
if ( this.hardwareBackPressListener ) {
|
|
263
|
+
this.hardwareBackPressListener.remove();
|
|
264
|
+
}
|
|
253
265
|
}
|
|
254
266
|
|
|
255
267
|
getThemeColors( { rawStyles, rawFeatures } ) {
|
|
@@ -280,6 +292,16 @@ class NativeEditorProvider extends Component {
|
|
|
280
292
|
}
|
|
281
293
|
}
|
|
282
294
|
|
|
295
|
+
onHardwareBackPress() {
|
|
296
|
+
const { clearSelectedBlock, selectedBlockIndex } = this.props;
|
|
297
|
+
|
|
298
|
+
if ( selectedBlockIndex !== -1 ) {
|
|
299
|
+
clearSelectedBlock();
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
|
|
283
305
|
serializeToNativeAction() {
|
|
284
306
|
const title = this.props.title;
|
|
285
307
|
let html;
|
|
@@ -397,8 +419,12 @@ const ComposedNativeProvider = compose( [
|
|
|
397
419
|
withDispatch( ( dispatch ) => {
|
|
398
420
|
const { editPost, resetEditorBlocks, updateEditorSettings } =
|
|
399
421
|
dispatch( editorStore );
|
|
400
|
-
const {
|
|
401
|
-
|
|
422
|
+
const {
|
|
423
|
+
clearSelectedBlock,
|
|
424
|
+
updateSettings,
|
|
425
|
+
insertBlock,
|
|
426
|
+
replaceBlock,
|
|
427
|
+
} = dispatch( blockEditorStore );
|
|
402
428
|
const { switchEditorMode } = dispatch( editPostStore );
|
|
403
429
|
const { addEntities, receiveEntityRecords } = dispatch( coreStore );
|
|
404
430
|
const { createSuccessNotice, createErrorNotice } =
|
|
@@ -411,6 +437,7 @@ const ComposedNativeProvider = compose( [
|
|
|
411
437
|
insertBlock,
|
|
412
438
|
createSuccessNotice,
|
|
413
439
|
createErrorNotice,
|
|
440
|
+
clearSelectedBlock,
|
|
414
441
|
editTitle( title ) {
|
|
415
442
|
editPost( { title } );
|
|
416
443
|
},
|
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
__experimentalFetchUrlData as fetchUrlData,
|
|
10
10
|
} from '@wordpress/core-data';
|
|
11
11
|
import { __ } from '@wordpress/i18n';
|
|
12
|
+
import { store as preferencesStore } from '@wordpress/preferences';
|
|
13
|
+
import { useViewportMatch } from '@wordpress/compose';
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* Internal dependencies
|
|
@@ -25,7 +27,6 @@ const BLOCK_EDITOR_SETTINGS = [
|
|
|
25
27
|
'__experimentalFeatures',
|
|
26
28
|
'__experimentalGlobalStylesBaseStyles',
|
|
27
29
|
'__experimentalPreferredStyleVariations',
|
|
28
|
-
'__experimentalSetIsInserterOpened',
|
|
29
30
|
'__unstableGalleryWithImageBlocks',
|
|
30
31
|
'alignWide',
|
|
31
32
|
'allowedBlockTypes',
|
|
@@ -46,20 +47,16 @@ const BLOCK_EDITOR_SETTINGS = [
|
|
|
46
47
|
'enableCustomSpacing',
|
|
47
48
|
'enableCustomUnits',
|
|
48
49
|
'enableOpenverseMediaCategory',
|
|
49
|
-
'focusMode',
|
|
50
|
-
'distractionFree',
|
|
51
50
|
'fontSizes',
|
|
52
51
|
'gradients',
|
|
53
52
|
'generateAnchors',
|
|
54
|
-
'
|
|
53
|
+
'getPostLinkProps',
|
|
55
54
|
'hasInlineToolbar',
|
|
56
|
-
'isDistractionFree',
|
|
57
55
|
'imageDefaultSize',
|
|
58
56
|
'imageDimensions',
|
|
59
57
|
'imageEditing',
|
|
60
58
|
'imageSizes',
|
|
61
59
|
'isRTL',
|
|
62
|
-
'keepCaretInsideBlock',
|
|
63
60
|
'locale',
|
|
64
61
|
'maxWidth',
|
|
65
62
|
'onUpdateDefaultBlockStyles',
|
|
@@ -88,7 +85,13 @@ const BLOCK_EDITOR_SETTINGS = [
|
|
|
88
85
|
* @return {Object} Block Editor Settings.
|
|
89
86
|
*/
|
|
90
87
|
function useBlockEditorSettings( settings, postType, postId ) {
|
|
88
|
+
const isLargeViewport = useViewportMatch( 'medium' );
|
|
91
89
|
const {
|
|
90
|
+
allowRightClickOverrides,
|
|
91
|
+
focusMode,
|
|
92
|
+
hasFixedToolbar,
|
|
93
|
+
isDistractionFree,
|
|
94
|
+
keepCaretInsideBlock,
|
|
92
95
|
reusableBlocks,
|
|
93
96
|
hasUploadPermissions,
|
|
94
97
|
canUseUnfilteredHTML,
|
|
@@ -110,17 +113,27 @@ function useBlockEditorSettings( settings, postType, postId ) {
|
|
|
110
113
|
getBlockPatterns,
|
|
111
114
|
getBlockPatternCategories,
|
|
112
115
|
} = select( coreStore );
|
|
116
|
+
const { get } = select( preferencesStore );
|
|
113
117
|
|
|
114
118
|
const siteSettings = canUser( 'read', 'settings' )
|
|
115
119
|
? getEntityRecord( 'root', 'site' )
|
|
116
120
|
: undefined;
|
|
117
121
|
|
|
118
122
|
return {
|
|
123
|
+
allowRightClickOverrides: get(
|
|
124
|
+
'core',
|
|
125
|
+
'allowRightClickOverrides'
|
|
126
|
+
),
|
|
119
127
|
canUseUnfilteredHTML: getRawEntityRecord(
|
|
120
128
|
'postType',
|
|
121
129
|
postType,
|
|
122
130
|
postId
|
|
123
131
|
)?._links?.hasOwnProperty( 'wp:action-unfiltered-html' ),
|
|
132
|
+
focusMode: get( 'core', 'focusMode' ),
|
|
133
|
+
hasFixedToolbar:
|
|
134
|
+
get( 'core', 'fixedToolbar' ) || ! isLargeViewport,
|
|
135
|
+
isDistractionFree: get( 'core', 'distractionFree' ),
|
|
136
|
+
keepCaretInsideBlock: get( 'core', 'keepCaretInsideBlock' ),
|
|
124
137
|
reusableBlocks: isWeb
|
|
125
138
|
? getEntityRecords( 'postType', 'wp_block', {
|
|
126
139
|
per_page: -1,
|
|
@@ -135,7 +148,7 @@ function useBlockEditorSettings( settings, postType, postId ) {
|
|
|
135
148
|
restBlockPatternCategories: getBlockPatternCategories(),
|
|
136
149
|
};
|
|
137
150
|
},
|
|
138
|
-
[ postType, postId ]
|
|
151
|
+
[ postType, postId, isLargeViewport ]
|
|
139
152
|
);
|
|
140
153
|
|
|
141
154
|
const settingsBlockPatterns =
|
|
@@ -177,7 +190,7 @@ function useBlockEditorSettings( settings, postType, postId ) {
|
|
|
177
190
|
[ settingsBlockPatternCategories, restBlockPatternCategories ]
|
|
178
191
|
);
|
|
179
192
|
|
|
180
|
-
const { undo } = useDispatch( editorStore );
|
|
193
|
+
const { undo, setIsInserterOpened } = useDispatch( editorStore );
|
|
181
194
|
|
|
182
195
|
const { saveEntityRecord } = useDispatch( coreStore );
|
|
183
196
|
|
|
@@ -202,6 +215,8 @@ function useBlockEditorSettings( settings, postType, postId ) {
|
|
|
202
215
|
[ saveEntityRecord, userCanCreatePages ]
|
|
203
216
|
);
|
|
204
217
|
|
|
218
|
+
const forceDisableFocusMode = settings.focusMode === false;
|
|
219
|
+
|
|
205
220
|
return useMemo(
|
|
206
221
|
() => ( {
|
|
207
222
|
...Object.fromEntries(
|
|
@@ -209,6 +224,11 @@ function useBlockEditorSettings( settings, postType, postId ) {
|
|
|
209
224
|
BLOCK_EDITOR_SETTINGS.includes( key )
|
|
210
225
|
)
|
|
211
226
|
),
|
|
227
|
+
allowRightClickOverrides,
|
|
228
|
+
focusMode: focusMode && ! forceDisableFocusMode,
|
|
229
|
+
hasFixedToolbar,
|
|
230
|
+
isDistractionFree,
|
|
231
|
+
keepCaretInsideBlock,
|
|
212
232
|
mediaUpload: hasUploadPermissions ? mediaUpload : undefined,
|
|
213
233
|
__experimentalReusableBlocks: reusableBlocks,
|
|
214
234
|
__experimentalBlockPatterns: blockPatterns,
|
|
@@ -238,8 +258,15 @@ function useBlockEditorSettings( settings, postType, postId ) {
|
|
|
238
258
|
postType === 'wp_navigation'
|
|
239
259
|
? [ [ 'core/navigation', {}, [] ] ]
|
|
240
260
|
: settings.template,
|
|
261
|
+
__experimentalSetIsInserterOpened: setIsInserterOpened,
|
|
241
262
|
} ),
|
|
242
263
|
[
|
|
264
|
+
allowRightClickOverrides,
|
|
265
|
+
focusMode,
|
|
266
|
+
forceDisableFocusMode,
|
|
267
|
+
hasFixedToolbar,
|
|
268
|
+
isDistractionFree,
|
|
269
|
+
keepCaretInsideBlock,
|
|
243
270
|
settings,
|
|
244
271
|
hasUploadPermissions,
|
|
245
272
|
reusableBlocks,
|
|
@@ -253,6 +280,7 @@ function useBlockEditorSettings( settings, postType, postId ) {
|
|
|
253
280
|
pageOnFront,
|
|
254
281
|
pageForPosts,
|
|
255
282
|
postType,
|
|
283
|
+
setIsInserterOpened,
|
|
256
284
|
]
|
|
257
285
|
);
|
|
258
286
|
}
|
package/src/private-apis.js
CHANGED
|
@@ -6,16 +6,26 @@ import { ExperimentalEditorProvider } from './components/provider';
|
|
|
6
6
|
import { lock } from './lock-unlock';
|
|
7
7
|
import { EntitiesSavedStatesExtensible } from './components/entities-saved-states';
|
|
8
8
|
import useBlockEditorSettings from './components/provider/use-block-editor-settings';
|
|
9
|
+
import DocumentTools from './components/document-tools';
|
|
10
|
+
import InserterSidebar from './components/inserter-sidebar';
|
|
11
|
+
import ListViewSidebar from './components/list-view-sidebar';
|
|
9
12
|
import PostPanelRow from './components/post-panel-row';
|
|
13
|
+
import PostViewLink from './components/post-view-link';
|
|
10
14
|
import PreviewDropdown from './components/preview-dropdown';
|
|
15
|
+
import PluginPostExcerpt from './components/post-excerpt/plugin';
|
|
11
16
|
|
|
12
17
|
export const privateApis = {};
|
|
13
18
|
lock( privateApis, {
|
|
19
|
+
DocumentTools,
|
|
14
20
|
EditorCanvas,
|
|
15
21
|
ExperimentalEditorProvider,
|
|
16
22
|
EntitiesSavedStatesExtensible,
|
|
23
|
+
InserterSidebar,
|
|
24
|
+
ListViewSidebar,
|
|
17
25
|
PostPanelRow,
|
|
26
|
+
PostViewLink,
|
|
18
27
|
PreviewDropdown,
|
|
28
|
+
PluginPostExcerpt,
|
|
19
29
|
|
|
20
30
|
// This is a temporary private API while we're updating the site editor to use EditorProvider.
|
|
21
31
|
useBlockEditorSettings,
|
package/src/store/actions.js
CHANGED
|
@@ -611,6 +611,115 @@ export function setDeviceType( deviceType ) {
|
|
|
611
611
|
};
|
|
612
612
|
}
|
|
613
613
|
|
|
614
|
+
/**
|
|
615
|
+
* Returns an action object used to enable or disable a panel in the editor.
|
|
616
|
+
*
|
|
617
|
+
* @param {string} panelName A string that identifies the panel to enable or disable.
|
|
618
|
+
*
|
|
619
|
+
* @return {Object} Action object.
|
|
620
|
+
*/
|
|
621
|
+
export const toggleEditorPanelEnabled =
|
|
622
|
+
( panelName ) =>
|
|
623
|
+
( { registry } ) => {
|
|
624
|
+
const inactivePanels =
|
|
625
|
+
registry
|
|
626
|
+
.select( preferencesStore )
|
|
627
|
+
.get( 'core', 'inactivePanels' ) ?? [];
|
|
628
|
+
|
|
629
|
+
const isPanelInactive = !! inactivePanels?.includes( panelName );
|
|
630
|
+
|
|
631
|
+
// If the panel is inactive, remove it to enable it, else add it to
|
|
632
|
+
// make it inactive.
|
|
633
|
+
let updatedInactivePanels;
|
|
634
|
+
if ( isPanelInactive ) {
|
|
635
|
+
updatedInactivePanels = inactivePanels.filter(
|
|
636
|
+
( invactivePanelName ) => invactivePanelName !== panelName
|
|
637
|
+
);
|
|
638
|
+
} else {
|
|
639
|
+
updatedInactivePanels = [ ...inactivePanels, panelName ];
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
registry
|
|
643
|
+
.dispatch( preferencesStore )
|
|
644
|
+
.set( 'core', 'inactivePanels', updatedInactivePanels );
|
|
645
|
+
};
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Opens a closed panel and closes an open panel.
|
|
649
|
+
*
|
|
650
|
+
* @param {string} panelName A string that identifies the panel to open or close.
|
|
651
|
+
*/
|
|
652
|
+
export const toggleEditorPanelOpened =
|
|
653
|
+
( panelName ) =>
|
|
654
|
+
( { registry } ) => {
|
|
655
|
+
const openPanels =
|
|
656
|
+
registry.select( preferencesStore ).get( 'core', 'openPanels' ) ??
|
|
657
|
+
[];
|
|
658
|
+
|
|
659
|
+
const isPanelOpen = !! openPanels?.includes( panelName );
|
|
660
|
+
|
|
661
|
+
// If the panel is open, remove it to close it, else add it to
|
|
662
|
+
// make it open.
|
|
663
|
+
let updatedOpenPanels;
|
|
664
|
+
if ( isPanelOpen ) {
|
|
665
|
+
updatedOpenPanels = openPanels.filter(
|
|
666
|
+
( openPanelName ) => openPanelName !== panelName
|
|
667
|
+
);
|
|
668
|
+
} else {
|
|
669
|
+
updatedOpenPanels = [ ...openPanels, panelName ];
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
registry
|
|
673
|
+
.dispatch( preferencesStore )
|
|
674
|
+
.set( 'core', 'openPanels', updatedOpenPanels );
|
|
675
|
+
};
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Returns an action object used to remove a panel from the editor.
|
|
679
|
+
*
|
|
680
|
+
* @param {string} panelName A string that identifies the panel to remove.
|
|
681
|
+
*
|
|
682
|
+
* @return {Object} Action object.
|
|
683
|
+
*/
|
|
684
|
+
export function removeEditorPanel( panelName ) {
|
|
685
|
+
return {
|
|
686
|
+
type: 'REMOVE_PANEL',
|
|
687
|
+
panelName,
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* Returns an action object used to open/close the inserter.
|
|
693
|
+
*
|
|
694
|
+
* @param {boolean|Object} value Whether the inserter should be
|
|
695
|
+
* opened (true) or closed (false).
|
|
696
|
+
* To specify an insertion point,
|
|
697
|
+
* use an object.
|
|
698
|
+
* @param {string} value.rootClientId The root client ID to insert at.
|
|
699
|
+
* @param {number} value.insertionIndex The index to insert at.
|
|
700
|
+
*
|
|
701
|
+
* @return {Object} Action object.
|
|
702
|
+
*/
|
|
703
|
+
export function setIsInserterOpened( value ) {
|
|
704
|
+
return {
|
|
705
|
+
type: 'SET_IS_INSERTER_OPENED',
|
|
706
|
+
value,
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* Returns an action object used to open/close the list view.
|
|
712
|
+
*
|
|
713
|
+
* @param {boolean} isOpen A boolean representing whether the list view should be opened or closed.
|
|
714
|
+
* @return {Object} Action object.
|
|
715
|
+
*/
|
|
716
|
+
export function setIsListViewOpened( isOpen ) {
|
|
717
|
+
return {
|
|
718
|
+
type: 'SET_IS_LIST_VIEW_OPENED',
|
|
719
|
+
isOpen,
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
|
|
614
723
|
/**
|
|
615
724
|
* Backward compatibility
|
|
616
725
|
*/
|
package/src/store/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import reducer from './reducer';
|
|
|
10
10
|
import * as selectors from './selectors';
|
|
11
11
|
import * as actions from './actions';
|
|
12
12
|
import * as privateActions from './private-actions';
|
|
13
|
+
import * as privateSelectors from './private-selectors';
|
|
13
14
|
import { STORE_NAME } from './constants';
|
|
14
15
|
import { unlock } from '../lock-unlock';
|
|
15
16
|
|
|
@@ -39,3 +40,4 @@ export const store = createReduxStore( STORE_NAME, {
|
|
|
39
40
|
|
|
40
41
|
register( store );
|
|
41
42
|
unlock( store ).registerPrivateActions( privateActions );
|
|
43
|
+
unlock( store ).registerPrivateSelectors( privateSelectors );
|