@wordpress/edit-post 8.39.1-next.v.202602111440.0 → 8.40.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.
@@ -12,7 +12,6 @@ import {
12
12
  LocalAutosaveMonitor,
13
13
  UnsavedChangesWarning,
14
14
  EditorKeyboardShortcutsRegister,
15
- EditorSnackbars,
16
15
  ErrorBoundary,
17
16
  PostLockedModal,
18
17
  store as editorStore,
@@ -31,7 +30,7 @@ import {
31
30
  useState,
32
31
  } from '@wordpress/element';
33
32
  import { chevronDown, chevronUp } from '@wordpress/icons';
34
- import { store as noticesStore } from '@wordpress/notices';
33
+ import { SnackbarNotices, store as noticesStore } from '@wordpress/notices';
35
34
  import { store as preferencesStore } from '@wordpress/preferences';
36
35
  import { privateApis as commandsPrivateApis } from '@wordpress/commands';
37
36
  import { privateApis as blockLibraryPrivateApis } from '@wordpress/block-library';
@@ -134,7 +133,7 @@ function useEditorStyles( settings ) {
134
133
 
135
134
  /**
136
135
  * @param {Object} props
137
- * @param {boolean} props.isLegacy True when the editor canvas is not in an iframe.
136
+ * @param {boolean} props.isLegacy True for device previews where split view is disabled.
138
137
  */
139
138
  function MetaBoxesMain( { isLegacy } ) {
140
139
  const [ isOpen, openHeight, hasAnyVisible ] = useSelect( ( select ) => {
@@ -379,7 +378,6 @@ function Layout( {
379
378
  currentPost: { postId: currentPostId, postType: currentPostType },
380
379
  onNavigateToEntityRecord,
381
380
  onNavigateToPreviousEntityRecord,
382
- previousSelectedBlockPath,
383
381
  } = useNavigateToEntityRecord(
384
382
  initialPostId,
385
383
  initialPostType,
@@ -595,18 +593,13 @@ function Layout( {
595
593
  // eslint-disable-next-line jsx-a11y/no-autofocus
596
594
  autoFocus={ ! isWelcomeGuideVisible }
597
595
  onActionPerformed={ onActionPerformed }
598
- initialSelection={ previousSelectedBlockPath }
599
596
  extraSidebarPanels={
600
597
  showMetaBoxes && <MetaBoxes location="side" />
601
598
  }
602
599
  extraContent={
603
600
  ! isDistractionFree &&
604
601
  showMetaBoxes && (
605
- <MetaBoxesMain
606
- isLegacy={
607
- ! shouldIframe || isDevicePreview
608
- }
609
- />
602
+ <MetaBoxesMain isLegacy={ isDevicePreview } />
610
603
  )
611
604
  }
612
605
  >
@@ -626,7 +619,7 @@ function Layout( {
626
619
  <PluginArea onError={ onPluginAreaError } />
627
620
  <PostEditorMoreMenu />
628
621
  { backButton }
629
- <EditorSnackbars />
622
+ <SnackbarNotices className="edit-post-layout__snackbar" />
630
623
  </Editor>
631
624
  </div>
632
625
  </ErrorBoundary>
@@ -110,24 +110,16 @@
110
110
  clear: both;
111
111
  }
112
112
 
113
- // Only when the split view is active the visual editor should allow shrinking and
114
- // its main size should be zero.
113
+ // Only when the split view is active the visual editor should allow shrinking,
114
+ // its main size should be zero, and overflow should be hidden so that the inner
115
+ // container provides the scrollable viewport.
115
116
  .has-metaboxes .interface-interface-skeleton__content:has(.edit-post-meta-boxes-main) .editor-visual-editor {
116
117
  flex-shrink: 1;
117
118
  flex-basis: 0%;
118
- }
119
-
120
- .has-metaboxes .editor-visual-editor.is-iframed {
119
+ overflow: hidden;
121
120
  isolation: isolate;
122
121
  }
123
122
 
124
- // Adjust the position of the notices
125
- .components-editor-notices__snackbar {
126
- position: fixed;
127
- right: 0;
128
- bottom: 24px;
129
- padding-left: 24px;
130
- padding-right: 24px;
123
+ .edit-post-layout__snackbar {
124
+ @include snackbar-container();
131
125
  }
132
-
133
- @include editor-left(".edit-post-layout .components-editor-notices__snackbar");
@@ -15,25 +15,31 @@ const isGutenbergPlugin = globalThis.IS_GUTENBERG_PLUGIN ? true : false;
15
15
 
16
16
  export function useShouldIframe() {
17
17
  return useSelect( ( select ) => {
18
- const { getEditorSettings, getCurrentPostType, getDeviceType } =
19
- select( editorStore );
18
+ const { getCurrentPostType, getDeviceType } = select( editorStore );
19
+ const { getClientIdsWithDescendants, getBlockName } =
20
+ select( blockEditorStore );
21
+ const { getBlockType } = select( blocksStore );
22
+
20
23
  return (
21
- // If the theme is block based and the Gutenberg plugin is active,
22
- // we ALWAYS use the iframe for consistency across the post and site
23
- // editor.
24
- ( isGutenbergPlugin &&
25
- getEditorSettings().__unstableIsBlockBasedTheme ) ||
24
+ // If the Gutenberg plugin is active, we ALWAYS use the iframe for
25
+ // consistency across the post and site editor. We plan on enforcing
26
+ // the iframe in the future, so Gutenberg both serves as way for us
27
+ // to warn plugin developers and for plugin developers to test their
28
+ // blocks easily. Before GB v22.5, we only enforced it for
29
+ // block-based themes (classic themes used the same rules as core).
30
+ isGutenbergPlugin ||
26
31
  // We also still want to iframe all the special
27
32
  // editor features and modes such as device previews, zoom out, and
28
33
  // template/pattern editing.
29
34
  getDeviceType() !== 'Desktop' ||
30
35
  [ 'wp_template', 'wp_block' ].includes( getCurrentPostType() ) ||
31
36
  unlock( select( blockEditorStore ) ).isZoomOut() ||
32
- // Finally, still iframe the editor if all blocks are v3 (which means
33
- // they are marked as iframe-compatible).
34
- select( blocksStore )
35
- .getBlockTypes()
36
- .every( ( type ) => type.apiVersion >= 3 )
37
+ // Finally, still iframe the editor if all present blocks are v3
38
+ // (which means they are marked as iframe-compatible).
39
+ [ ...new Set( getClientIdsWithDescendants().map( getBlockName ) ) ]
40
+ .map( getBlockType )
41
+ .filter( Boolean )
42
+ .every( ( blockType ) => blockType.apiVersion >= 3 )
37
43
  );
38
44
  }, [] );
39
45
  }
@@ -2,15 +2,9 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { useCallback, useReducer } from '@wordpress/element';
5
- import { useSelect, useDispatch } from '@wordpress/data';
6
- import { store as editorStore, privateApis } from '@wordpress/editor';
7
-
8
- /**
9
- * Internal dependencies
10
- */
11
- import { unlock } from '../lock-unlock';
12
-
13
- const { useGenerateBlockPath } = unlock( privateApis );
5
+ import { useSelect, useDispatch, useRegistry } from '@wordpress/data';
6
+ import { store as editorStore } from '@wordpress/editor';
7
+ import { store as coreStore } from '@wordpress/core-data';
14
8
 
15
9
  /**
16
10
  * A hook that records the 'entity' history in the post editor as a user
@@ -32,19 +26,19 @@ export default function useNavigateToEntityRecord(
32
26
  initialPostType,
33
27
  defaultRenderingMode
34
28
  ) {
35
- const generateBlockPath = useGenerateBlockPath();
29
+ const registry = useRegistry();
36
30
  const [ postHistory, dispatch ] = useReducer(
37
31
  (
38
32
  historyState,
39
- { type, post, previousRenderingMode, selectedBlockPath }
33
+ { type, post, previousRenderingMode, selectedBlockClientId }
40
34
  ) => {
41
35
  if ( type === 'push' ) {
42
- // Update the current item with the selected block path before pushing new item
36
+ // Update the current item with the selected block clientId before pushing new item
43
37
  const updatedHistory = [ ...historyState ];
44
38
  const currentIndex = updatedHistory.length - 1;
45
39
  updatedHistory[ currentIndex ] = {
46
40
  ...updatedHistory[ currentIndex ],
47
- selectedBlockPath,
41
+ selectedBlockClientId,
48
42
  };
49
43
  return [ ...updatedHistory, { post, previousRenderingMode } ];
50
44
  }
@@ -62,44 +56,79 @@ export default function useNavigateToEntityRecord(
62
56
  },
63
57
  ]
64
58
  );
65
- const { post, previousRenderingMode, selectedBlockPath } =
59
+ const { post, previousRenderingMode } =
66
60
  postHistory[ postHistory.length - 1 ];
67
61
 
68
62
  const { getRenderingMode } = useSelect( editorStore );
69
63
  const { setRenderingMode } = useDispatch( editorStore );
64
+ const { editEntityRecord } = useDispatch( coreStore );
70
65
 
71
66
  const onNavigateToEntityRecord = useCallback(
72
67
  ( params ) => {
73
- // Generate block path from clientId if provided
74
- const blockPath = params.selectedBlockClientId
75
- ? generateBlockPath( params.selectedBlockClientId )
76
- : null;
68
+ // Read entity selection (already has external IDs from onChangeSelection)
69
+ const entityEdits = registry
70
+ .select( coreStore )
71
+ .getEntityRecordEdits( 'postType', post.postType, post.postId );
72
+ const externalClientId =
73
+ entityEdits?.selection?.selectionStart?.clientId ?? null;
77
74
 
78
75
  dispatch( {
79
76
  type: 'push',
80
77
  post: { postId: params.postId, postType: params.postType },
81
78
  // Save the current rendering mode so we can restore it when navigating back.
82
79
  previousRenderingMode: getRenderingMode(),
83
- selectedBlockPath: blockPath,
80
+ selectedBlockClientId: externalClientId,
84
81
  } );
85
82
  setRenderingMode( defaultRenderingMode );
86
83
  },
87
84
  [
85
+ registry,
86
+ post.postType,
87
+ post.postId,
88
88
  getRenderingMode,
89
89
  setRenderingMode,
90
90
  defaultRenderingMode,
91
- generateBlockPath,
92
91
  ]
93
92
  );
94
93
 
95
94
  const onNavigateToPreviousEntityRecord = useCallback( () => {
95
+ // Get the item we're navigating back to (second to last in history)
96
+ // to set its selection on the entity record
97
+ if ( postHistory.length > 1 ) {
98
+ const previousItem = postHistory[ postHistory.length - 2 ];
99
+
100
+ if ( previousItem.selectedBlockClientId ) {
101
+ // Set the selection on the entity we're navigating back to
102
+ editEntityRecord(
103
+ 'postType',
104
+ previousItem.post.postType,
105
+ previousItem.post.postId,
106
+ {
107
+ selection: {
108
+ selectionStart: {
109
+ clientId: previousItem.selectedBlockClientId,
110
+ },
111
+ selectionEnd: {
112
+ clientId: previousItem.selectedBlockClientId,
113
+ },
114
+ },
115
+ },
116
+ { undoIgnore: true }
117
+ );
118
+ }
119
+ }
96
120
  dispatch( {
97
121
  type: 'pop',
98
122
  } );
99
123
  if ( previousRenderingMode ) {
100
124
  setRenderingMode( previousRenderingMode );
101
125
  }
102
- }, [ setRenderingMode, previousRenderingMode ] );
126
+ }, [
127
+ setRenderingMode,
128
+ previousRenderingMode,
129
+ postHistory,
130
+ editEntityRecord,
131
+ ] );
103
132
 
104
133
  return {
105
134
  currentPost: post,
@@ -108,7 +137,5 @@ export default function useNavigateToEntityRecord(
108
137
  postHistory.length > 1
109
138
  ? onNavigateToPreviousEntityRecord
110
139
  : undefined,
111
- // Return the selected block path from the current history item
112
- previousSelectedBlockPath: selectedBlockPath,
113
140
  };
114
141
  }