@wordpress/editor 13.22.0 → 13.24.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/index.js +15 -1
- package/build/components/entities-saved-states/index.js.map +1 -1
- package/build/components/index.js +32 -0
- package/build/components/index.js.map +1 -1
- package/build/components/page-attributes/order.js +1 -0
- package/build/components/page-attributes/order.js.map +1 -1
- package/build/components/post-author/panel.js +24 -0
- package/build/components/post-author/panel.js.map +1 -0
- package/build/components/post-featured-image/index.js +3 -1
- package/build/components/post-featured-image/index.js.map +1 -1
- package/build/components/post-panel-row/index.js +36 -0
- package/build/components/post-panel-row/index.js.map +1 -0
- package/build/components/post-saved-state/index.js +21 -16
- package/build/components/post-saved-state/index.js.map +1 -1
- package/build/components/post-schedule/panel.js +67 -0
- package/build/components/post-schedule/panel.js.map +1 -0
- package/build/components/post-sync-status/index.js +9 -5
- package/build/components/post-sync-status/index.js.map +1 -1
- package/build/components/post-title/constants.js +11 -0
- package/build/components/post-title/constants.js.map +1 -0
- package/build/components/post-title/index.js +61 -90
- package/build/components/post-title/index.js.map +1 -1
- package/build/components/post-title/index.native.js +1 -1
- package/build/components/post-title/index.native.js.map +1 -1
- package/build/components/post-title/post-title-raw.js +92 -0
- package/build/components/post-title/post-title-raw.js.map +1 -0
- package/build/components/post-title/use-post-title-focus.js +64 -0
- package/build/components/post-title/use-post-title-focus.js.map +1 -0
- package/build/components/post-title/use-post-title.js +41 -0
- package/build/components/post-title/use-post-title.js.map +1 -0
- package/build/components/post-url/panel.js +70 -0
- package/build/components/post-url/panel.js.map +1 -0
- package/build/components/provider/constants.js +9 -0
- package/build/components/provider/constants.js.map +1 -0
- package/build/components/provider/disable-non-page-content-blocks.js +63 -0
- package/build/components/provider/disable-non-page-content-blocks.js.map +1 -0
- package/build/components/provider/index.js +126 -14
- package/build/components/provider/index.js.map +1 -1
- package/build/components/provider/use-block-editor-settings.js +22 -17
- package/build/components/provider/use-block-editor-settings.js.map +1 -1
- package/build/components/provider/use-block-editor-settings.native.js +2 -2
- package/build/components/provider/use-block-editor-settings.native.js.map +1 -1
- package/build/private-apis.js +7 -1
- package/build/private-apis.js.map +1 -1
- package/build/store/actions.js +23 -2
- package/build/store/actions.js.map +1 -1
- package/build/store/reducer.js +10 -1
- package/build/store/reducer.js.map +1 -1
- package/build/store/selectors.js +16 -2
- package/build/store/selectors.js.map +1 -1
- package/build-module/components/entities-saved-states/index.js +16 -2
- package/build-module/components/entities-saved-states/index.js.map +1 -1
- package/build-module/components/index.js +4 -0
- package/build-module/components/index.js.map +1 -1
- package/build-module/components/page-attributes/order.js +1 -0
- package/build-module/components/page-attributes/order.js.map +1 -1
- package/build-module/components/post-author/panel.js +14 -0
- package/build-module/components/post-author/panel.js.map +1 -0
- package/build-module/components/post-featured-image/index.js +3 -1
- package/build-module/components/post-featured-image/index.js.map +1 -1
- package/build-module/components/post-panel-row/index.js +27 -0
- package/build-module/components/post-panel-row/index.js.map +1 -0
- package/build-module/components/post-saved-state/index.js +22 -17
- package/build-module/components/post-saved-state/index.js.map +1 -1
- package/build-module/components/post-schedule/panel.js +59 -0
- package/build-module/components/post-schedule/panel.js.map +1 -0
- package/build-module/components/post-sync-status/index.js +10 -7
- package/build-module/components/post-sync-status/index.js.map +1 -1
- package/build-module/components/post-title/constants.js +3 -0
- package/build-module/components/post-title/constants.js.map +1 -0
- package/build-module/components/post-title/index.js +62 -92
- package/build-module/components/post-title/index.js.map +1 -1
- package/build-module/components/post-title/index.native.js +3 -3
- package/build-module/components/post-title/index.native.js.map +1 -1
- package/build-module/components/post-title/post-title-raw.js +83 -0
- package/build-module/components/post-title/post-title-raw.js.map +1 -0
- package/build-module/components/post-title/use-post-title-focus.js +57 -0
- package/build-module/components/post-title/use-post-title-focus.js.map +1 -0
- package/build-module/components/post-title/use-post-title.js +33 -0
- package/build-module/components/post-title/use-post-title.js.map +1 -0
- package/build-module/components/post-url/panel.js +62 -0
- package/build-module/components/post-url/panel.js.map +1 -0
- package/build-module/components/provider/constants.js +2 -0
- package/build-module/components/provider/constants.js.map +1 -0
- package/build-module/components/provider/disable-non-page-content-blocks.js +56 -0
- package/build-module/components/provider/disable-non-page-content-blocks.js.map +1 -0
- package/build-module/components/provider/index.js +127 -15
- package/build-module/components/provider/index.js.map +1 -1
- package/build-module/components/provider/use-block-editor-settings.js +22 -17
- package/build-module/components/provider/use-block-editor-settings.js.map +1 -1
- package/build-module/components/provider/use-block-editor-settings.native.js +2 -2
- package/build-module/components/provider/use-block-editor-settings.native.js.map +1 -1
- package/build-module/private-apis.js +6 -1
- package/build-module/private-apis.js.map +1 -1
- package/build-module/store/actions.js +21 -0
- package/build-module/store/actions.js.map +1 -1
- package/build-module/store/reducer.js +9 -1
- package/build-module/store/reducer.js.map +1 -1
- package/build-module/store/selectors.js +11 -0
- package/build-module/store/selectors.js.map +1 -1
- package/build-style/style-rtl.css +70 -10
- package/build-style/style.css +70 -10
- package/package.json +31 -31
- package/src/components/entities-saved-states/index.js +16 -1
- package/src/components/index.js +4 -0
- package/src/components/page-attributes/order.js +1 -0
- package/src/components/post-author/panel.js +18 -0
- package/src/components/post-author/style.scss +7 -0
- package/src/components/post-featured-image/index.js +3 -1
- package/src/components/post-panel-row/index.js +26 -0
- package/src/components/post-panel-row/style.scss +21 -0
- package/src/components/post-saved-state/index.js +46 -37
- package/src/components/post-schedule/panel.js +65 -0
- package/src/components/post-schedule/style.scss +23 -0
- package/src/components/post-sync-status/index.js +10 -8
- package/src/components/post-sync-status/style.scss +3 -18
- package/src/components/post-title/constants.js +4 -0
- package/src/components/post-title/index.js +56 -88
- package/src/components/post-title/index.native.js +4 -8
- package/src/components/post-title/post-title-raw.js +82 -0
- package/src/components/post-title/style.scss +5 -0
- package/src/components/post-title/use-post-title-focus.js +50 -0
- package/src/components/post-title/use-post-title.js +25 -0
- package/src/components/post-url/panel.js +60 -0
- package/src/components/post-url/style.scss +19 -0
- package/src/components/provider/README.md +37 -0
- package/src/components/provider/constants.js +5 -0
- package/src/components/provider/disable-non-page-content-blocks.js +55 -0
- package/src/components/provider/index.js +200 -14
- package/src/components/provider/use-block-editor-settings.js +54 -35
- package/src/components/provider/use-block-editor-settings.native.js +2 -2
- package/src/private-apis.js +6 -0
- package/src/store/actions.js +21 -0
- package/src/store/reducer.js +10 -0
- package/src/store/selectors.js +11 -0
- package/src/style.scss +4 -0
|
@@ -7,18 +7,12 @@ import classnames from 'classnames';
|
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
9
|
import { __ } from '@wordpress/i18n';
|
|
10
|
-
import {
|
|
11
|
-
forwardRef,
|
|
12
|
-
useEffect,
|
|
13
|
-
useImperativeHandle,
|
|
14
|
-
useRef,
|
|
15
|
-
useState,
|
|
16
|
-
} from '@wordpress/element';
|
|
10
|
+
import { forwardRef, useState } from '@wordpress/element';
|
|
17
11
|
import { decodeEntities } from '@wordpress/html-entities';
|
|
18
|
-
import { ENTER } from '@wordpress/keycodes';
|
|
19
12
|
import { useSelect, useDispatch } from '@wordpress/data';
|
|
20
|
-
import { pasteHandler } from '@wordpress/blocks';
|
|
21
13
|
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
14
|
+
import { ENTER } from '@wordpress/keycodes';
|
|
15
|
+
import { pasteHandler } from '@wordpress/blocks';
|
|
22
16
|
import {
|
|
23
17
|
__unstableUseRichText as useRichText,
|
|
24
18
|
create,
|
|
@@ -31,78 +25,45 @@ import { __unstableStripHTML as stripHTML } from '@wordpress/dom';
|
|
|
31
25
|
/**
|
|
32
26
|
* Internal dependencies
|
|
33
27
|
*/
|
|
34
|
-
import PostTypeSupportCheck from '../post-type-support-check';
|
|
35
28
|
import { store as editorStore } from '../../store';
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const REGEXP_NEWLINES = /[\r\n]+/g;
|
|
29
|
+
import { DEFAULT_CLASSNAMES, REGEXP_NEWLINES } from './constants';
|
|
30
|
+
import usePostTitleFocus from './use-post-title-focus';
|
|
31
|
+
import usePostTitle from './use-post-title';
|
|
32
|
+
import PostTypeSupportCheck from '../post-type-support-check';
|
|
41
33
|
|
|
42
34
|
function PostTitle( _, forwardedRef ) {
|
|
43
|
-
const
|
|
35
|
+
const { placeholder, hasFixedToolbar } = useSelect( ( select ) => {
|
|
36
|
+
const { getEditedPostAttribute } = select( editorStore );
|
|
37
|
+
const { getSettings } = select( blockEditorStore );
|
|
38
|
+
const { titlePlaceholder, hasFixedToolbar: _hasFixedToolbar } =
|
|
39
|
+
getSettings();
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
title: getEditedPostAttribute( 'title' ),
|
|
43
|
+
placeholder: titlePlaceholder,
|
|
44
|
+
hasFixedToolbar: _hasFixedToolbar,
|
|
45
|
+
};
|
|
46
|
+
}, [] );
|
|
47
|
+
|
|
44
48
|
const [ isSelected, setIsSelected ] = useState( false );
|
|
45
|
-
const { editPost } = useDispatch( editorStore );
|
|
46
|
-
const { insertDefaultBlock, clearSelectedBlock, insertBlocks } =
|
|
47
|
-
useDispatch( blockEditorStore );
|
|
48
|
-
const { isCleanNewPost, title, placeholder, hasFixedToolbar } = useSelect(
|
|
49
|
-
( select ) => {
|
|
50
|
-
const { getEditedPostAttribute, isCleanNewPost: _isCleanNewPost } =
|
|
51
|
-
select( editorStore );
|
|
52
|
-
const { getSettings } = select( blockEditorStore );
|
|
53
|
-
const { titlePlaceholder, hasFixedToolbar: _hasFixedToolbar } =
|
|
54
|
-
getSettings();
|
|
55
|
-
|
|
56
|
-
return {
|
|
57
|
-
isCleanNewPost: _isCleanNewPost(),
|
|
58
|
-
title: getEditedPostAttribute( 'title' ),
|
|
59
|
-
placeholder: titlePlaceholder,
|
|
60
|
-
hasFixedToolbar: _hasFixedToolbar,
|
|
61
|
-
};
|
|
62
|
-
},
|
|
63
|
-
[]
|
|
64
|
-
);
|
|
65
49
|
|
|
66
|
-
|
|
67
|
-
focus: () => {
|
|
68
|
-
ref?.current?.focus();
|
|
69
|
-
},
|
|
70
|
-
} ) );
|
|
50
|
+
const { ref: focusRef } = usePostTitleFocus( forwardedRef );
|
|
71
51
|
|
|
72
|
-
|
|
73
|
-
if ( ! ref.current ) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
52
|
+
const { title, setTitle: onUpdate } = usePostTitle();
|
|
76
53
|
|
|
77
|
-
|
|
78
|
-
const { name, parent } = defaultView;
|
|
79
|
-
const ownerDocument =
|
|
80
|
-
name === 'editor-canvas' ? parent.document : defaultView.document;
|
|
81
|
-
const { activeElement, body } = ownerDocument;
|
|
82
|
-
|
|
83
|
-
// Only autofocus the title when the post is entirely empty. This should
|
|
84
|
-
// only happen for a new post, which means we focus the title on new
|
|
85
|
-
// post so the author can start typing right away, without needing to
|
|
86
|
-
// click anything.
|
|
87
|
-
if ( isCleanNewPost && ( ! activeElement || body === activeElement ) ) {
|
|
88
|
-
ref.current.focus();
|
|
89
|
-
}
|
|
90
|
-
}, [ isCleanNewPost ] );
|
|
54
|
+
const [ selection, setSelection ] = useState( {} );
|
|
91
55
|
|
|
92
|
-
|
|
93
|
-
|
|
56
|
+
const { clearSelectedBlock, insertBlocks, insertDefaultBlock } =
|
|
57
|
+
useDispatch( blockEditorStore );
|
|
58
|
+
|
|
59
|
+
function onChange( value ) {
|
|
60
|
+
onUpdate( value.replace( REGEXP_NEWLINES, ' ' ) );
|
|
94
61
|
}
|
|
95
62
|
|
|
96
63
|
function onInsertBlockAfter( blocks ) {
|
|
97
64
|
insertBlocks( blocks, 0 );
|
|
98
65
|
}
|
|
99
66
|
|
|
100
|
-
function onUpdate( newTitle ) {
|
|
101
|
-
editPost( { title: newTitle } );
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const [ selection, setSelection ] = useState( {} );
|
|
105
|
-
|
|
106
67
|
function onSelect() {
|
|
107
68
|
setIsSelected( true );
|
|
108
69
|
clearSelectedBlock();
|
|
@@ -113,8 +74,8 @@ function PostTitle( _, forwardedRef ) {
|
|
|
113
74
|
setSelection( {} );
|
|
114
75
|
}
|
|
115
76
|
|
|
116
|
-
function
|
|
117
|
-
|
|
77
|
+
function onEnterPress() {
|
|
78
|
+
insertDefaultBlock( undefined, undefined, 0 );
|
|
118
79
|
}
|
|
119
80
|
|
|
120
81
|
function onKeyDown( event ) {
|
|
@@ -170,7 +131,13 @@ function PostTitle( _, forwardedRef ) {
|
|
|
170
131
|
( firstBlock.name === 'core/heading' ||
|
|
171
132
|
firstBlock.name === 'core/paragraph' )
|
|
172
133
|
) {
|
|
173
|
-
|
|
134
|
+
// Strip HTML to avoid unwanted HTML being added to the title.
|
|
135
|
+
// In the majority of cases it is assumed that HTML in the title
|
|
136
|
+
// is undesirable.
|
|
137
|
+
const contentNoHTML = stripHTML(
|
|
138
|
+
firstBlock.attributes.content
|
|
139
|
+
);
|
|
140
|
+
onUpdate( contentNoHTML );
|
|
174
141
|
onInsertBlockAfter( content.slice( 1 ) );
|
|
175
142
|
} else {
|
|
176
143
|
onInsertBlockAfter( content );
|
|
@@ -180,10 +147,13 @@ function PostTitle( _, forwardedRef ) {
|
|
|
180
147
|
...create( { html: title } ),
|
|
181
148
|
...selection,
|
|
182
149
|
};
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
150
|
+
|
|
151
|
+
// Strip HTML to avoid unwanted HTML being added to the title.
|
|
152
|
+
// In the majority of cases it is assumed that HTML in the title
|
|
153
|
+
// is undesirable.
|
|
154
|
+
const contentNoHTML = stripHTML( content );
|
|
155
|
+
|
|
156
|
+
const newValue = insert( value, create( { html: contentNoHTML } ) );
|
|
187
157
|
onUpdate( toHTMLString( { value: newValue } ) );
|
|
188
158
|
setSelection( {
|
|
189
159
|
start: newValue.start,
|
|
@@ -192,17 +162,9 @@ function PostTitle( _, forwardedRef ) {
|
|
|
192
162
|
}
|
|
193
163
|
}
|
|
194
164
|
|
|
195
|
-
// The wp-block className is important for editor styles.
|
|
196
|
-
// This same block is used in both the visual and the code editor.
|
|
197
|
-
const className = classnames(
|
|
198
|
-
'wp-block wp-block-post-title block-editor-block-list__block editor-post-title editor-post-title__input rich-text',
|
|
199
|
-
{
|
|
200
|
-
'is-selected': isSelected,
|
|
201
|
-
'has-fixed-toolbar': hasFixedToolbar,
|
|
202
|
-
}
|
|
203
|
-
);
|
|
204
165
|
const decodedPlaceholder =
|
|
205
166
|
decodeEntities( placeholder ) || __( 'Add title' );
|
|
167
|
+
|
|
206
168
|
const { ref: richTextRef } = useRichText( {
|
|
207
169
|
value: title,
|
|
208
170
|
onChange,
|
|
@@ -221,15 +183,21 @@ function PostTitle( _, forwardedRef ) {
|
|
|
221
183
|
};
|
|
222
184
|
} );
|
|
223
185
|
},
|
|
224
|
-
__unstableDisableFormats:
|
|
225
|
-
|
|
186
|
+
__unstableDisableFormats: false,
|
|
187
|
+
} );
|
|
188
|
+
|
|
189
|
+
// The wp-block className is important for editor styles.
|
|
190
|
+
// This same block is used in both the visual and the code editor.
|
|
191
|
+
const className = classnames( DEFAULT_CLASSNAMES, {
|
|
192
|
+
'is-selected': isSelected,
|
|
193
|
+
'has-fixed-toolbar': hasFixedToolbar,
|
|
226
194
|
} );
|
|
227
195
|
|
|
228
|
-
/* eslint-disable jsx-a11y/heading-has-content, jsx-a11y/no-noninteractive-element-to-interactive-role */
|
|
229
196
|
return (
|
|
197
|
+
/* eslint-disable jsx-a11y/heading-has-content, jsx-a11y/no-noninteractive-element-to-interactive-role */
|
|
230
198
|
<PostTypeSupportCheck supportKeys="title">
|
|
231
199
|
<h1
|
|
232
|
-
ref={ useMergeRefs( [ richTextRef,
|
|
200
|
+
ref={ useMergeRefs( [ richTextRef, focusRef ] ) }
|
|
233
201
|
contentEditable
|
|
234
202
|
className={ className }
|
|
235
203
|
aria-label={ decodedPlaceholder }
|
|
@@ -242,8 +210,8 @@ function PostTitle( _, forwardedRef ) {
|
|
|
242
210
|
onPaste={ onPaste }
|
|
243
211
|
/>
|
|
244
212
|
</PostTypeSupportCheck>
|
|
213
|
+
/* eslint-enable jsx-a11y/heading-has-content, jsx-a11y/no-noninteractive-element-to-interactive-role */
|
|
245
214
|
);
|
|
246
|
-
/* eslint-enable jsx-a11y/heading-has-content, jsx-a11y/no-noninteractive-element-to-interactive-role */
|
|
247
215
|
}
|
|
248
216
|
|
|
249
217
|
export default forwardRef( PostTitle );
|
|
@@ -7,18 +7,14 @@ import { View } from 'react-native';
|
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
9
|
import { Component } from '@wordpress/element';
|
|
10
|
-
import {
|
|
11
|
-
__experimentalRichText as RichText,
|
|
12
|
-
create,
|
|
13
|
-
insert,
|
|
14
|
-
} from '@wordpress/rich-text';
|
|
10
|
+
import { create, insert } from '@wordpress/rich-text';
|
|
15
11
|
import { decodeEntities } from '@wordpress/html-entities';
|
|
16
12
|
import { withDispatch, withSelect } from '@wordpress/data';
|
|
17
13
|
import { withFocusOutside } from '@wordpress/components';
|
|
18
14
|
import { withInstanceId, compose } from '@wordpress/compose';
|
|
19
15
|
import { __, sprintf } from '@wordpress/i18n';
|
|
20
16
|
import { pasteHandler } from '@wordpress/blocks';
|
|
21
|
-
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
17
|
+
import { store as blockEditorStore, RichText } from '@wordpress/block-editor';
|
|
22
18
|
import { store as editorStore } from '@wordpress/editor';
|
|
23
19
|
|
|
24
20
|
/**
|
|
@@ -152,7 +148,7 @@ class PostTitle extends Component {
|
|
|
152
148
|
accessibilityLabel={ this.getTitle( title, postType ) }
|
|
153
149
|
accessibilityHint={ __( 'Updates the title.' ) }
|
|
154
150
|
>
|
|
155
|
-
<RichText
|
|
151
|
+
<RichText.Raw
|
|
156
152
|
setRef={ this.setRef }
|
|
157
153
|
accessibilityLabel={ this.getTitle( title, postType ) }
|
|
158
154
|
tagName={ 'p' }
|
|
@@ -177,7 +173,7 @@ class PostTitle extends Component {
|
|
|
177
173
|
disableEditingMenu={ true }
|
|
178
174
|
__unstableIsSelected={ this.props.isSelected }
|
|
179
175
|
__unstableOnCreateUndoLevel={ () => {} }
|
|
180
|
-
|
|
176
|
+
/>
|
|
181
177
|
</View>
|
|
182
178
|
);
|
|
183
179
|
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import classnames from 'classnames';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { TextareaControl } from '@wordpress/components';
|
|
10
|
+
import { __ } from '@wordpress/i18n';
|
|
11
|
+
import { decodeEntities } from '@wordpress/html-entities';
|
|
12
|
+
import { useSelect } from '@wordpress/data';
|
|
13
|
+
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
14
|
+
import { useState, forwardRef } from '@wordpress/element';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Internal dependencies
|
|
18
|
+
*/
|
|
19
|
+
import { DEFAULT_CLASSNAMES, REGEXP_NEWLINES } from './constants';
|
|
20
|
+
import usePostTitleFocus from './use-post-title-focus';
|
|
21
|
+
import usePostTitle from './use-post-title';
|
|
22
|
+
|
|
23
|
+
function PostTitleRaw( _, forwardedRef ) {
|
|
24
|
+
const { placeholder, hasFixedToolbar } = useSelect( ( select ) => {
|
|
25
|
+
const { getSettings } = select( blockEditorStore );
|
|
26
|
+
const { titlePlaceholder, hasFixedToolbar: _hasFixedToolbar } =
|
|
27
|
+
getSettings();
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
placeholder: titlePlaceholder,
|
|
31
|
+
hasFixedToolbar: _hasFixedToolbar,
|
|
32
|
+
};
|
|
33
|
+
}, [] );
|
|
34
|
+
|
|
35
|
+
const [ isSelected, setIsSelected ] = useState( false );
|
|
36
|
+
|
|
37
|
+
const { title, setTitle: onUpdate } = usePostTitle();
|
|
38
|
+
const { ref: focusRef } = usePostTitleFocus( forwardedRef );
|
|
39
|
+
|
|
40
|
+
function onChange( value ) {
|
|
41
|
+
onUpdate( value.replace( REGEXP_NEWLINES, ' ' ) );
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function onSelect() {
|
|
45
|
+
setIsSelected( true );
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function onUnselect() {
|
|
49
|
+
setIsSelected( false );
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// The wp-block className is important for editor styles.
|
|
53
|
+
// This same block is used in both the visual and the code editor.
|
|
54
|
+
const className = classnames( DEFAULT_CLASSNAMES, {
|
|
55
|
+
'is-selected': isSelected,
|
|
56
|
+
'has-fixed-toolbar': hasFixedToolbar,
|
|
57
|
+
'is-raw-text': true,
|
|
58
|
+
} );
|
|
59
|
+
|
|
60
|
+
const decodedPlaceholder =
|
|
61
|
+
decodeEntities( placeholder ) || __( 'Add title' );
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<TextareaControl
|
|
65
|
+
ref={ focusRef }
|
|
66
|
+
value={ title }
|
|
67
|
+
onChange={ onChange }
|
|
68
|
+
onFocus={ onSelect }
|
|
69
|
+
onBlur={ onUnselect }
|
|
70
|
+
label={ placeholder }
|
|
71
|
+
className={ className }
|
|
72
|
+
placeholder={ decodedPlaceholder }
|
|
73
|
+
hideLabelFromVision={ true }
|
|
74
|
+
autoComplete="off"
|
|
75
|
+
dir="auto"
|
|
76
|
+
rows={ 1 }
|
|
77
|
+
__nextHasNoMarginBottom
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export default forwardRef( PostTitleRaw );
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useEffect, useImperativeHandle, useRef } from '@wordpress/element';
|
|
5
|
+
import { useSelect } from '@wordpress/data';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Internal dependencies
|
|
9
|
+
*/
|
|
10
|
+
import { store as editorStore } from '../../store';
|
|
11
|
+
|
|
12
|
+
export default function usePostTitleFocus( forwardedRef ) {
|
|
13
|
+
const ref = useRef();
|
|
14
|
+
|
|
15
|
+
const { isCleanNewPost } = useSelect( ( select ) => {
|
|
16
|
+
const { isCleanNewPost: _isCleanNewPost } = select( editorStore );
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
isCleanNewPost: _isCleanNewPost(),
|
|
20
|
+
};
|
|
21
|
+
}, [] );
|
|
22
|
+
|
|
23
|
+
useImperativeHandle( forwardedRef, () => ( {
|
|
24
|
+
focus: () => {
|
|
25
|
+
ref?.current?.focus();
|
|
26
|
+
},
|
|
27
|
+
} ) );
|
|
28
|
+
|
|
29
|
+
useEffect( () => {
|
|
30
|
+
if ( ! ref.current ) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const { defaultView } = ref.current.ownerDocument;
|
|
35
|
+
const { name, parent } = defaultView;
|
|
36
|
+
const ownerDocument =
|
|
37
|
+
name === 'editor-canvas' ? parent.document : defaultView.document;
|
|
38
|
+
const { activeElement, body } = ownerDocument;
|
|
39
|
+
|
|
40
|
+
// Only autofocus the title when the post is entirely empty. This should
|
|
41
|
+
// only happen for a new post, which means we focus the title on new
|
|
42
|
+
// post so the author can start typing right away, without needing to
|
|
43
|
+
// click anything.
|
|
44
|
+
if ( isCleanNewPost && ( ! activeElement || body === activeElement ) ) {
|
|
45
|
+
ref.current.focus();
|
|
46
|
+
}
|
|
47
|
+
}, [ isCleanNewPost ] );
|
|
48
|
+
|
|
49
|
+
return { ref };
|
|
50
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useSelect, useDispatch } from '@wordpress/data';
|
|
5
|
+
/**
|
|
6
|
+
* Internal dependencies
|
|
7
|
+
*/
|
|
8
|
+
import { store as editorStore } from '../../store';
|
|
9
|
+
|
|
10
|
+
export default function usePostTitle() {
|
|
11
|
+
const { editPost } = useDispatch( editorStore );
|
|
12
|
+
const { title } = useSelect( ( select ) => {
|
|
13
|
+
const { getEditedPostAttribute } = select( editorStore );
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
title: getEditedPostAttribute( 'title' ),
|
|
17
|
+
};
|
|
18
|
+
}, [] );
|
|
19
|
+
|
|
20
|
+
function updateTitle( newTitle ) {
|
|
21
|
+
editPost( { title: newTitle } );
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return { title, setTitle: updateTitle };
|
|
25
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useMemo, useState } from '@wordpress/element';
|
|
5
|
+
import { Dropdown, Button } from '@wordpress/components';
|
|
6
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Internal dependencies
|
|
10
|
+
*/
|
|
11
|
+
import PostURLCheck from './check';
|
|
12
|
+
import PostURL from './index';
|
|
13
|
+
import { usePostURLLabel } from './label';
|
|
14
|
+
import PostPanelRow from '../post-panel-row';
|
|
15
|
+
|
|
16
|
+
export default function PostURLPanel() {
|
|
17
|
+
// Use internal state instead of a ref to make sure that the component
|
|
18
|
+
// re-renders when the popover's anchor updates.
|
|
19
|
+
const [ popoverAnchor, setPopoverAnchor ] = useState( null );
|
|
20
|
+
// Memoize popoverProps to avoid returning a new object every time.
|
|
21
|
+
const popoverProps = useMemo(
|
|
22
|
+
() => ( { anchor: popoverAnchor, placement: 'bottom-end' } ),
|
|
23
|
+
[ popoverAnchor ]
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<PostURLCheck>
|
|
28
|
+
<PostPanelRow label={ __( 'URL' ) } ref={ setPopoverAnchor }>
|
|
29
|
+
<Dropdown
|
|
30
|
+
popoverProps={ popoverProps }
|
|
31
|
+
className="editor-post-url__panel-dropdown"
|
|
32
|
+
contentClassName="editor-post-url__panel-dialog"
|
|
33
|
+
focusOnMount
|
|
34
|
+
renderToggle={ ( { isOpen, onToggle } ) => (
|
|
35
|
+
<PostURLToggle isOpen={ isOpen } onClick={ onToggle } />
|
|
36
|
+
) }
|
|
37
|
+
renderContent={ ( { onClose } ) => (
|
|
38
|
+
<PostURL onClose={ onClose } />
|
|
39
|
+
) }
|
|
40
|
+
/>
|
|
41
|
+
</PostPanelRow>
|
|
42
|
+
</PostURLCheck>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function PostURLToggle( { isOpen, onClick } ) {
|
|
47
|
+
const label = usePostURLLabel();
|
|
48
|
+
return (
|
|
49
|
+
<Button
|
|
50
|
+
className="editor-post-url__panel-toggle"
|
|
51
|
+
variant="tertiary"
|
|
52
|
+
aria-expanded={ isOpen }
|
|
53
|
+
// translators: %s: Current post URL.
|
|
54
|
+
aria-label={ sprintf( __( 'Change URL: %s' ), label ) }
|
|
55
|
+
onClick={ onClick }
|
|
56
|
+
>
|
|
57
|
+
{ label }
|
|
58
|
+
</Button>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
.editor-post-url__panel-dropdown {
|
|
2
|
+
width: 100%;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.components-button.editor-post-url__panel-toggle {
|
|
6
|
+
display: block;
|
|
7
|
+
max-width: 100%;
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
text-align: left;
|
|
10
|
+
text-overflow: ellipsis;
|
|
11
|
+
white-space: nowrap;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.editor-post-url__panel-dialog .editor-post-url {
|
|
15
|
+
// sidebar width - popover padding - form margin
|
|
16
|
+
min-width: $sidebar-width - $grid-unit-20 - $grid-unit-20;
|
|
17
|
+
margin: $grid-unit-10;
|
|
18
|
+
}
|
|
19
|
+
|
|
1
20
|
.editor-post-url__link-label {
|
|
2
21
|
font-size: $default-font-size;
|
|
3
22
|
font-weight: 400;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# EditorProvider
|
|
2
|
+
|
|
3
|
+
EditorProvider is a component which establishes a new post editing context, and serves as the entry point for a new post editor (or post with template editor).
|
|
4
|
+
|
|
5
|
+
It supports a big number of post types, including post, page, templates, custom post types, patterns, template parts.
|
|
6
|
+
|
|
7
|
+
All modification and changes are performed to the `@wordpress/core-data` store.
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
### `post`
|
|
12
|
+
|
|
13
|
+
- **Type:** `Object`
|
|
14
|
+
- **Required** `yes`
|
|
15
|
+
|
|
16
|
+
The post object to edit
|
|
17
|
+
|
|
18
|
+
### `__unstableTemplate`
|
|
19
|
+
|
|
20
|
+
- **Type:** `Object`
|
|
21
|
+
- **Required** `no`
|
|
22
|
+
|
|
23
|
+
The template object wrapper the edited post. This is optional and can only be used when the post type supports templates (like posts and pages).
|
|
24
|
+
|
|
25
|
+
### `settings`
|
|
26
|
+
|
|
27
|
+
- **Type:** `Object`
|
|
28
|
+
- **Required** `no`
|
|
29
|
+
|
|
30
|
+
The settings object to use for the editor. This is optional and can be used to override the default settings.
|
|
31
|
+
|
|
32
|
+
### `children`
|
|
33
|
+
|
|
34
|
+
- **Type:** `Element`
|
|
35
|
+
- **Required** `no`
|
|
36
|
+
|
|
37
|
+
Children elements for which the BlockEditorProvider context should apply.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useSelect, useDispatch } from '@wordpress/data';
|
|
5
|
+
import {
|
|
6
|
+
useBlockEditingMode,
|
|
7
|
+
store as blockEditorStore,
|
|
8
|
+
} from '@wordpress/block-editor';
|
|
9
|
+
import { useEffect } from '@wordpress/element';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies
|
|
13
|
+
*/
|
|
14
|
+
import { PAGE_CONTENT_BLOCK_TYPES } from './constants';
|
|
15
|
+
|
|
16
|
+
function DisableBlock( { clientId } ) {
|
|
17
|
+
const isDescendentOfQueryLoop = useSelect(
|
|
18
|
+
( select ) => {
|
|
19
|
+
const { getBlockParentsByBlockName } = select( blockEditorStore );
|
|
20
|
+
return (
|
|
21
|
+
getBlockParentsByBlockName( clientId, 'core/query' ).length !==
|
|
22
|
+
0
|
|
23
|
+
);
|
|
24
|
+
},
|
|
25
|
+
[ clientId ]
|
|
26
|
+
);
|
|
27
|
+
const mode = isDescendentOfQueryLoop ? undefined : 'contentOnly';
|
|
28
|
+
const { setBlockEditingMode, unsetBlockEditingMode } =
|
|
29
|
+
useDispatch( blockEditorStore );
|
|
30
|
+
useEffect( () => {
|
|
31
|
+
if ( mode ) {
|
|
32
|
+
setBlockEditingMode( clientId, mode );
|
|
33
|
+
return () => {
|
|
34
|
+
unsetBlockEditingMode( clientId );
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}, [ clientId, mode, setBlockEditingMode, unsetBlockEditingMode ] );
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Component that when rendered, makes it so that the site editor allows only
|
|
42
|
+
* page content to be edited.
|
|
43
|
+
*/
|
|
44
|
+
export default function DisableNonPageContentBlocks() {
|
|
45
|
+
useBlockEditingMode( 'disabled' );
|
|
46
|
+
const clientIds = useSelect( ( select ) => {
|
|
47
|
+
const { __experimentalGetGlobalBlocksByName } =
|
|
48
|
+
select( blockEditorStore );
|
|
49
|
+
return __experimentalGetGlobalBlocksByName( PAGE_CONTENT_BLOCK_TYPES );
|
|
50
|
+
}, [] );
|
|
51
|
+
|
|
52
|
+
return clientIds.map( ( clientId ) => {
|
|
53
|
+
return <DisableBlock key={ clientId } clientId={ clientId } />;
|
|
54
|
+
} );
|
|
55
|
+
}
|