@wordpress/edit-post 6.15.0 → 6.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.
@@ -28,6 +28,8 @@ import {
28
28
  __unstableUseMouseMoveTypingReset as useMouseMoveTypingReset,
29
29
  __unstableIframe as Iframe,
30
30
  __experimentalRecursionProvider as RecursionProvider,
31
+ __experimentaluseLayoutClasses as useLayoutClasses,
32
+ __experimentaluseLayoutStyles as useLayoutStyles,
31
33
  } from '@wordpress/block-editor';
32
34
  import { useEffect, useRef, useMemo } from '@wordpress/element';
33
35
  import { Button, __unstableMotion as motion } from '@wordpress/components';
@@ -35,6 +37,7 @@ import { useSelect, useDispatch } from '@wordpress/data';
35
37
  import { useMergeRefs } from '@wordpress/compose';
36
38
  import { arrowLeft } from '@wordpress/icons';
37
39
  import { __ } from '@wordpress/i18n';
40
+ import { parse } from '@wordpress/blocks';
38
41
 
39
42
  /**
40
43
  * Internal dependencies
@@ -82,11 +85,37 @@ function MaybeIframe( {
82
85
  );
83
86
  }
84
87
 
88
+ /**
89
+ * Given an array of nested blocks, find the first Post Content
90
+ * block inside it, recursing through any nesting levels.
91
+ *
92
+ * @param {Array} blocks A list of blocks.
93
+ *
94
+ * @return {Object} The Post Content block.
95
+ */
96
+ function findPostContent( blocks ) {
97
+ for ( let i = 0; i < blocks.length; i++ ) {
98
+ if ( blocks[ i ].name === 'core/post-content' ) {
99
+ return blocks[ i ];
100
+ }
101
+ if ( blocks[ i ].innerBlocks.length ) {
102
+ const nestedPostContent = findPostContent(
103
+ blocks[ i ].innerBlocks
104
+ );
105
+
106
+ if ( nestedPostContent ) {
107
+ return nestedPostContent;
108
+ }
109
+ }
110
+ }
111
+ }
112
+
85
113
  export default function VisualEditor( { styles } ) {
86
114
  const {
87
115
  deviceType,
88
116
  isWelcomeGuideVisible,
89
117
  isTemplateMode,
118
+ editedPostTemplate = {},
90
119
  wrapperBlockName,
91
120
  wrapperUniqueId,
92
121
  } = useSelect( ( select ) => {
@@ -94,8 +123,10 @@ export default function VisualEditor( { styles } ) {
94
123
  isFeatureActive,
95
124
  isEditingTemplate,
96
125
  __experimentalGetPreviewDeviceType,
126
+ getEditedPostTemplate,
97
127
  } = select( editPostStore );
98
- const { getCurrentPostId, getCurrentPostType } = select( editorStore );
128
+ const { getCurrentPostId, getCurrentPostType, getEditorSettings } =
129
+ select( editorStore );
99
130
  const _isTemplateMode = isEditingTemplate();
100
131
  let _wrapperBlockName;
101
132
 
@@ -105,10 +136,17 @@ export default function VisualEditor( { styles } ) {
105
136
  _wrapperBlockName = 'core/post-content';
106
137
  }
107
138
 
139
+ const supportsTemplateMode = getEditorSettings().supportsTemplateMode;
140
+
108
141
  return {
109
142
  deviceType: __experimentalGetPreviewDeviceType(),
110
143
  isWelcomeGuideVisible: isFeatureActive( 'welcomeGuide' ),
111
144
  isTemplateMode: _isTemplateMode,
145
+ // Post template fetch returns a 404 on classic themes, which
146
+ // messes with e2e tests, so we check it's a block theme first.
147
+ editedPostTemplate: supportsTemplateMode
148
+ ? getEditedPostTemplate()
149
+ : {},
112
150
  wrapperBlockName: _wrapperBlockName,
113
151
  wrapperUniqueId: getCurrentPostId(),
114
152
  };
@@ -122,7 +160,6 @@ export default function VisualEditor( { styles } ) {
122
160
  themeHasDisabledLayoutStyles,
123
161
  themeSupportsLayout,
124
162
  assets,
125
- useRootPaddingAwareAlignments,
126
163
  isFocusMode,
127
164
  } = useSelect( ( select ) => {
128
165
  const _settings = select( blockEditorStore ).getSettings();
@@ -130,8 +167,6 @@ export default function VisualEditor( { styles } ) {
130
167
  themeHasDisabledLayoutStyles: _settings.disableLayoutStyles,
131
168
  themeSupportsLayout: _settings.supportsLayout,
132
169
  assets: _settings.__unstableResolvedAssets,
133
- useRootPaddingAwareAlignments:
134
- _settings.__experimentalFeatures?.useRootPaddingAwareAlignments,
135
170
  isFocusMode: _settings.focusMode,
136
171
  };
137
172
  }, [] );
@@ -154,7 +189,7 @@ export default function VisualEditor( { styles } ) {
154
189
  borderBottom: 0,
155
190
  };
156
191
  const resizedCanvasStyles = useResizeCanvas( deviceType, isTemplateMode );
157
- const defaultLayout = useSetting( 'layout' );
192
+ const globalLayoutSettings = useSetting( 'layout' );
158
193
  const previewMode = 'is-' + deviceType.toLowerCase() + '-preview';
159
194
 
160
195
  let animatedStyles = isTemplateMode
@@ -183,7 +218,9 @@ export default function VisualEditor( { styles } ) {
183
218
 
184
219
  const blockSelectionClearerRef = useBlockSelectionClearer();
185
220
 
186
- const layout = useMemo( () => {
221
+ // fallbackLayout is used if there is no Post Content,
222
+ // and for Post Title.
223
+ const fallbackLayout = useMemo( () => {
187
224
  if ( isTemplateMode ) {
188
225
  return { type: 'default' };
189
226
  }
@@ -191,17 +228,65 @@ export default function VisualEditor( { styles } ) {
191
228
  if ( themeSupportsLayout ) {
192
229
  // We need to ensure support for wide and full alignments,
193
230
  // so we add the constrained type.
194
- return { ...defaultLayout, type: 'constrained' };
231
+ return { ...globalLayoutSettings, type: 'constrained' };
195
232
  }
196
233
  // Set default layout for classic themes so all alignments are supported.
197
234
  return { type: 'default' };
198
- }, [ isTemplateMode, themeSupportsLayout, defaultLayout ] );
235
+ }, [ isTemplateMode, themeSupportsLayout, globalLayoutSettings ] );
236
+
237
+ const postContentBlock = useMemo( () => {
238
+ // When in template editing mode, we can access the blocks directly.
239
+ if ( editedPostTemplate?.blocks ) {
240
+ return findPostContent( editedPostTemplate?.blocks );
241
+ }
242
+ // If there are no blocks, we have to parse the content string.
243
+ // Best double-check it's a string otherwise the parse function gets unhappy.
244
+ const parseableContent =
245
+ typeof editedPostTemplate?.content === 'string'
246
+ ? editedPostTemplate?.content
247
+ : '';
199
248
 
200
- const blockListLayoutClass = classnames( {
201
- 'is-layout-constrained': themeSupportsLayout,
202
- 'is-layout-flow': ! themeSupportsLayout,
203
- 'has-global-padding': useRootPaddingAwareAlignments,
204
- } );
249
+ return findPostContent( parse( parseableContent ) ) || {};
250
+ }, [ editedPostTemplate?.content, editedPostTemplate?.blocks ] );
251
+
252
+ const postContentLayoutClasses = useLayoutClasses( postContentBlock );
253
+
254
+ const blockListLayoutClass = classnames(
255
+ {
256
+ 'is-layout-flow': ! themeSupportsLayout,
257
+ },
258
+ themeSupportsLayout && postContentLayoutClasses
259
+ );
260
+
261
+ const postContentLayoutStyles = useLayoutStyles(
262
+ postContentBlock,
263
+ '.block-editor-block-list__layout.is-root-container'
264
+ );
265
+
266
+ const layout = postContentBlock?.attributes?.layout || {};
267
+
268
+ // Update type for blocks using legacy layouts.
269
+ const postContentLayout = useMemo( () => {
270
+ return layout &&
271
+ ( layout?.type === 'constrained' ||
272
+ layout?.inherit ||
273
+ layout?.contentSize ||
274
+ layout?.wideSize )
275
+ ? { ...globalLayoutSettings, ...layout, type: 'constrained' }
276
+ : { ...globalLayoutSettings, ...layout, type: 'default' };
277
+ }, [
278
+ layout?.type,
279
+ layout?.inherit,
280
+ layout?.contentSize,
281
+ layout?.wideSize,
282
+ globalLayoutSettings,
283
+ ] );
284
+
285
+ // If there is a Post Content block we use its layout for the block list;
286
+ // if not, this must be a classic theme, in which case we use the fallback layout.
287
+ const blockListLayout = postContentBlock
288
+ ? postContentLayout
289
+ : fallbackLayout;
205
290
 
206
291
  const titleRef = useRef();
207
292
  useEffect( () => {
@@ -257,13 +342,24 @@ export default function VisualEditor( { styles } ) {
257
342
  { themeSupportsLayout &&
258
343
  ! themeHasDisabledLayoutStyles &&
259
344
  ! isTemplateMode && (
260
- <LayoutStyle
261
- selector=".edit-post-visual-editor__post-title-wrapper, .block-editor-block-list__layout.is-root-container"
262
- layout={ layout }
263
- layoutDefinitions={
264
- defaultLayout?.definitions
265
- }
266
- />
345
+ <>
346
+ <LayoutStyle
347
+ selector=".edit-post-visual-editor__post-title-wrapper, .block-editor-block-list__layout.is-root-container"
348
+ layout={ fallbackLayout }
349
+ layoutDefinitions={
350
+ globalLayoutSettings?.definitions
351
+ }
352
+ />
353
+ { postContentLayoutStyles && (
354
+ <LayoutStyle
355
+ layout={ postContentLayout }
356
+ css={ postContentLayoutStyles }
357
+ layoutDefinitions={
358
+ globalLayoutSettings?.definitions
359
+ }
360
+ />
361
+ ) }
362
+ </>
267
363
  ) }
268
364
  { ! isTemplateMode && (
269
365
  <div
@@ -288,7 +384,7 @@ export default function VisualEditor( { styles } ) {
288
384
  ? 'wp-site-blocks'
289
385
  : `${ blockListLayoutClass } wp-block-post-content` // Ensure root level blocks receive default/flow blockGap styling rules.
290
386
  }
291
- __experimentalLayout={ layout }
387
+ __experimentalLayout={ blockListLayout }
292
388
  />
293
389
  </RecursionProvider>
294
390
  </MaybeIframe>
package/src/index.js CHANGED
@@ -80,22 +80,6 @@ export function initializeEditor(
80
80
  settings,
81
81
  initialEdits
82
82
  ) {
83
- // Prevent adding template part in the post editor.
84
- // Only add the filter when the post editor is initialized, not imported.
85
- addFilter(
86
- 'blockEditor.__unstableCanInsertBlockType',
87
- 'removeTemplatePartsFromInserter',
88
- ( can, blockType ) => {
89
- if (
90
- ! select( editPostStore ).isEditingTemplate() &&
91
- blockType.name === 'core/template-part'
92
- ) {
93
- return false;
94
- }
95
- return can;
96
- }
97
- );
98
-
99
83
  const target = document.getElementById( id );
100
84
  const reboot = reinitializeEditor.bind(
101
85
  null,
@@ -137,6 +121,26 @@ export function initializeEditor(
137
121
  } );
138
122
  }
139
123
 
124
+ /*
125
+ * Prevent adding template part in the post editor.
126
+ * Only add the filter when the post editor is initialized, not imported.
127
+ * Also only add the filter(s) after registerCoreBlocks()
128
+ * so that common filters in the block library are not overwritten.
129
+ */
130
+ addFilter(
131
+ 'blockEditor.__unstableCanInsertBlockType',
132
+ 'removeTemplatePartsFromInserter',
133
+ ( canInsert, blockType ) => {
134
+ if (
135
+ ! select( editPostStore ).isEditingTemplate() &&
136
+ blockType.name === 'core/template-part'
137
+ ) {
138
+ return false;
139
+ }
140
+ return canInsert;
141
+ }
142
+ );
143
+
140
144
  // Show a console log warning if the browser is not in Standards rendering mode.
141
145
  const documentMode =
142
146
  document.compatMode === 'CSS1Compat' ? 'Standards' : 'Quirks';
package/src/style.scss CHANGED
@@ -98,3 +98,17 @@ body.block-editor-page {
98
98
  }
99
99
 
100
100
  @include wordpress-admin-schemes();
101
+
102
+ // The edit-site package adds or removes the sidebar when it's opened or closed.
103
+ // The edit-post package, however, always has the sidebar in the canvas.
104
+ // These edit-post specific rules ensures there isn't a border on the right of
105
+ // the canvas when a sidebar is visually closed.
106
+ .interface-interface-skeleton__sidebar {
107
+ border-left: none;
108
+
109
+ .is-sidebar-opened & {
110
+ @include break-medium() {
111
+ border-left: $border-width solid $gray-200;
112
+ }
113
+ }
114
+ }