@wordpress/block-library 7.14.1 → 7.14.3

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.
Files changed (41) hide show
  1. package/build/comments-pagination-next/index.js +1 -1
  2. package/build/comments-pagination-numbers/index.js +1 -1
  3. package/build/comments-pagination-previous/index.js +1 -1
  4. package/build/gallery/deprecated.js +4 -4
  5. package/build/gallery/deprecated.js.map +1 -1
  6. package/build/navigation/menu-items-to-blocks.js +16 -6
  7. package/build/navigation/menu-items-to-blocks.js.map +1 -1
  8. package/build/post-template/edit.js +13 -28
  9. package/build/post-template/edit.js.map +1 -1
  10. package/build/quote/transforms.js +2 -2
  11. package/build/quote/transforms.js.map +1 -1
  12. package/build/template-part/edit/index.js +2 -2
  13. package/build/template-part/edit/index.js.map +1 -1
  14. package/build-module/comments-pagination-next/index.js +1 -1
  15. package/build-module/comments-pagination-numbers/index.js +1 -1
  16. package/build-module/comments-pagination-previous/index.js +1 -1
  17. package/build-module/gallery/deprecated.js +4 -4
  18. package/build-module/gallery/deprecated.js.map +1 -1
  19. package/build-module/navigation/menu-items-to-blocks.js +16 -6
  20. package/build-module/navigation/menu-items-to-blocks.js.map +1 -1
  21. package/build-module/post-template/edit.js +14 -29
  22. package/build-module/post-template/edit.js.map +1 -1
  23. package/build-module/quote/transforms.js +2 -2
  24. package/build-module/quote/transforms.js.map +1 -1
  25. package/build-module/template-part/edit/index.js +3 -3
  26. package/build-module/template-part/edit/index.js.map +1 -1
  27. package/build-style/classic-rtl.css +85 -0
  28. package/build-style/classic.css +85 -0
  29. package/package.json +28 -28
  30. package/src/classic.scss +15 -0
  31. package/src/comment-template/index.php +18 -8
  32. package/src/comments-pagination-next/block.json +1 -1
  33. package/src/comments-pagination-numbers/block.json +1 -1
  34. package/src/comments-pagination-previous/block.json +1 -1
  35. package/src/gallery/deprecated.js +4 -4
  36. package/src/navigation/menu-items-to-blocks.js +39 -22
  37. package/src/navigation/test/menu-items-to-blocks.js +6 -0
  38. package/src/navigation-submenu/index.php +10 -1
  39. package/src/post-template/edit.js +14 -23
  40. package/src/quote/transforms.js +1 -1
  41. package/src/template-part/edit/index.js +60 -58
@@ -659,8 +659,8 @@ const v3 = {
659
659
  attribute: 'data-link',
660
660
  },
661
661
  caption: {
662
- type: 'array',
663
- source: 'children',
662
+ type: 'string',
663
+ source: 'html',
664
664
  selector: 'figcaption',
665
665
  },
666
666
  },
@@ -779,8 +779,8 @@ const v2 = {
779
779
  attribute: 'data-link',
780
780
  },
781
781
  caption: {
782
- type: 'array',
783
- source: 'children',
782
+ type: 'string',
783
+ source: 'html',
784
784
  selector: 'figcaption',
785
785
  },
786
786
  },
@@ -29,9 +29,10 @@ export default function menuItemsToBlocks( menuItems ) {
29
29
  * A recursive function that maps menu item nodes to blocks.
30
30
  *
31
31
  * @param {WPNavMenuItem[]} menuItems An array of WPNavMenuItem items.
32
+ * @param {number} level An integer representing the nesting level.
32
33
  * @return {Object} Object containing innerBlocks and mapping.
33
34
  */
34
- function mapMenuItemsToBlocks( menuItems ) {
35
+ function mapMenuItemsToBlocks( menuItems, level = 0 ) {
35
36
  let mapping = {};
36
37
 
37
38
  // The menuItem should be in menu_order sort order.
@@ -52,14 +53,22 @@ function mapMenuItemsToBlocks( menuItems ) {
52
53
  return block;
53
54
  }
54
55
 
55
- const attributes = menuItemToBlockAttributes( menuItem );
56
+ const blockType = menuItem.children?.length
57
+ ? 'core/navigation-submenu'
58
+ : 'core/navigation-link';
59
+
60
+ const attributes = menuItemToBlockAttributes(
61
+ menuItem,
62
+ blockType,
63
+ level
64
+ );
56
65
 
57
66
  // If there are children recurse to build those nested blocks.
58
67
  const {
59
68
  innerBlocks: nestedBlocks = [], // alias to avoid shadowing
60
69
  mapping: nestedMapping = {}, // alias to avoid shadowing
61
70
  } = menuItem.children?.length
62
- ? mapMenuItemsToBlocks( menuItem.children )
71
+ ? mapMenuItemsToBlocks( menuItem.children, level + 1 )
63
72
  : {};
64
73
 
65
74
  // Update parent mapping with nested mapping.
@@ -68,10 +77,6 @@ function mapMenuItemsToBlocks( menuItems ) {
68
77
  ...nestedMapping,
69
78
  };
70
79
 
71
- const blockType = menuItem.children?.length
72
- ? 'core/navigation-submenu'
73
- : 'core/navigation-link';
74
-
75
80
  // Create block with nested "innerBlocks".
76
81
  const block = createBlock( blockType, attributes, nestedBlocks );
77
82
 
@@ -111,23 +116,29 @@ function mapMenuItemsToBlocks( menuItems ) {
111
116
  /**
112
117
  * Convert block attributes to menu item.
113
118
  *
114
- * @param {WPNavMenuItem} menuItem the menu item to be converted to block attributes.
119
+ * @param {WPNavMenuItem} menuItem the menu item to be converted to block attributes.
120
+ * @param {string} blockType The block type.
121
+ * @param {number} level An integer representing the nesting level.
115
122
  * @return {Object} the block attributes converted from the WPNavMenuItem item.
116
123
  */
117
- function menuItemToBlockAttributes( {
118
- title: menuItemTitleField,
119
- xfn,
120
- classes,
121
- // eslint-disable-next-line camelcase
122
- attr_title,
123
- object,
124
- // eslint-disable-next-line camelcase
125
- object_id,
126
- description,
127
- url,
128
- type: menuItemTypeField,
129
- target,
130
- } ) {
124
+ function menuItemToBlockAttributes(
125
+ {
126
+ title: menuItemTitleField,
127
+ xfn,
128
+ classes,
129
+ // eslint-disable-next-line camelcase
130
+ attr_title,
131
+ object,
132
+ // eslint-disable-next-line camelcase
133
+ object_id,
134
+ description,
135
+ url,
136
+ type: menuItemTypeField,
137
+ target,
138
+ },
139
+ blockType,
140
+ level
141
+ ) {
131
142
  // For historical reasons, the `core/navigation-link` variation type is `tag`
132
143
  // whereas WP Core expects `post_tag` as the `object` type.
133
144
  // To avoid writing a block migration we perform a conversion here.
@@ -166,6 +177,12 @@ function menuItemToBlockAttributes( {
166
177
  ...( target === '_blank' && {
167
178
  opensInNewTab: true,
168
179
  } ),
180
+ ...( blockType === 'core/navigation-submenu' && {
181
+ isTopLevelItem: level === 0,
182
+ } ),
183
+ ...( blockType === 'core/navigation-link' && {
184
+ isTopLevelLink: level === 0,
185
+ } ),
169
186
  };
170
187
  }
171
188
 
@@ -189,12 +189,14 @@ describe( 'converting menu items to blocks', () => {
189
189
  name: 'core/navigation-submenu',
190
190
  attributes: expect.objectContaining( {
191
191
  label: 'Top Level',
192
+ isTopLevelItem: true,
192
193
  } ),
193
194
  innerBlocks: [
194
195
  expect.objectContaining( {
195
196
  name: 'core/navigation-link',
196
197
  attributes: expect.objectContaining( {
197
198
  label: 'Child 1',
199
+ isTopLevelLink: false,
198
200
  } ),
199
201
  innerBlocks: [],
200
202
  } ),
@@ -202,18 +204,21 @@ describe( 'converting menu items to blocks', () => {
202
204
  name: 'core/navigation-submenu',
203
205
  attributes: expect.objectContaining( {
204
206
  label: 'Child 2',
207
+ isTopLevelItem: false,
205
208
  } ),
206
209
  innerBlocks: [
207
210
  expect.objectContaining( {
208
211
  name: 'core/navigation-submenu',
209
212
  attributes: expect.objectContaining( {
210
213
  label: 'Sub Child',
214
+ isTopLevelItem: false,
211
215
  } ),
212
216
  innerBlocks: [
213
217
  expect.objectContaining( {
214
218
  name: 'core/navigation-link',
215
219
  attributes: expect.objectContaining( {
216
220
  label: 'Sub Sub Child',
221
+ isTopLevelLink: false,
217
222
  } ),
218
223
  innerBlocks: [],
219
224
  } ),
@@ -227,6 +232,7 @@ describe( 'converting menu items to blocks', () => {
227
232
  name: 'core/navigation-link',
228
233
  attributes: expect.objectContaining( {
229
234
  label: 'Top Level 2',
235
+ isTopLevelLink: true,
230
236
  } ),
231
237
  innerBlocks: [],
232
238
  } ),
@@ -183,7 +183,16 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
183
183
  if ( ! $open_on_click ) {
184
184
  $item_url = isset( $attributes['url'] ) ? $attributes['url'] : '';
185
185
  // Start appending HTML attributes to anchor tag.
186
- $html .= '<a class="wp-block-navigation-item__content" href="' . esc_url( $item_url ) . '"';
186
+ $html .= '<a class="wp-block-navigation-item__content"';
187
+
188
+ // The href attribute on a and area elements is not required;
189
+ // when those elements do not have href attributes they do not create hyperlinks.
190
+ // But also The href attribute must have a value that is a valid URL potentially
191
+ // surrounded by spaces.
192
+ // see: https://html.spec.whatwg.org/multipage/links.html#links-created-by-a-and-area-elements.
193
+ if ( ! empty( $item_url ) ) {
194
+ $html .= ' href="' . esc_url( $item_url ) . '"';
195
+ }
187
196
 
188
197
  if ( $is_active ) {
189
198
  $html .= ' aria-current="page"';
@@ -17,7 +17,7 @@ import {
17
17
  store as blockEditorStore,
18
18
  } from '@wordpress/block-editor';
19
19
  import { Spinner } from '@wordpress/components';
20
- import { store as coreStore, useEntityRecords } from '@wordpress/core-data';
20
+ import { store as coreStore } from '@wordpress/core-data';
21
21
 
22
22
  const TEMPLATE = [
23
23
  [ 'core/post-title' ],
@@ -101,19 +101,6 @@ export default function PostTemplateEdit( {
101
101
  } ) {
102
102
  const [ { page } ] = queryContext;
103
103
  const [ activeBlockContextId, setActiveBlockContextId ] = useState();
104
-
105
- let categorySlug = null;
106
- if ( templateSlug?.startsWith( 'category-' ) ) {
107
- categorySlug = templateSlug.replace( 'category-', '' );
108
- }
109
- const { records: categories, hasResolved: hasResolvedCategories } =
110
- useEntityRecords( 'taxonomy', 'category', {
111
- context: 'view',
112
- per_page: -1,
113
- _fields: [ 'id' ],
114
- slug: categorySlug,
115
- } );
116
-
117
104
  const { posts, blocks } = useSelect(
118
105
  ( select ) => {
119
106
  const { getEntityRecords, getTaxonomies } = select( coreStore );
@@ -123,12 +110,22 @@ export default function PostTemplateEdit( {
123
110
  per_page: -1,
124
111
  context: 'view',
125
112
  } );
113
+ const templateCategory =
114
+ inherit &&
115
+ templateSlug?.startsWith( 'category-' ) &&
116
+ getEntityRecords( 'taxonomy', 'category', {
117
+ context: 'view',
118
+ per_page: 1,
119
+ _fields: [ 'id' ],
120
+ slug: templateSlug.replace( 'category-', '' ),
121
+ } );
126
122
  const query = {
127
123
  offset: perPage ? perPage * ( page - 1 ) + offset : 0,
128
124
  order,
129
125
  orderby: orderBy,
130
126
  };
131
- if ( taxQuery ) {
127
+ // There is no need to build the taxQuery if we inherit.
128
+ if ( taxQuery && ! inherit ) {
132
129
  // We have to build the tax query for the REST API and use as
133
130
  // keys the taxonomies `rest_base` with the `term ids` as values.
134
131
  const builtTaxQuery = Object.entries( taxQuery ).reduce(
@@ -174,11 +171,8 @@ export default function PostTemplateEdit( {
174
171
  if ( templateSlug?.startsWith( 'archive-' ) ) {
175
172
  query.postType = templateSlug.replace( 'archive-', '' );
176
173
  postType = query.postType;
177
- } else if ( !! categorySlug && hasResolvedCategories ) {
178
- query.taxQuery = {
179
- category: categories.map( ( { id } ) => id ),
180
- };
181
- taxQuery = query.taxQuery;
174
+ } else if ( templateCategory ) {
175
+ query.categories = templateCategory[ 0 ]?.id;
182
176
  }
183
177
  }
184
178
  // When we preview Query Loop blocks we should prefer the current
@@ -210,9 +204,6 @@ export default function PostTemplateEdit( {
210
204
  parents,
211
205
  restQueryArgs,
212
206
  previewPostType,
213
- categories,
214
- categorySlug,
215
- hasResolvedCategories,
216
207
  ]
217
208
  );
218
209
  const blockContexts = useMemo(
@@ -17,7 +17,7 @@ const transforms = {
17
17
  fontSize,
18
18
  style,
19
19
  },
20
- createBlock( 'core/paragraph', { content: value } )
20
+ [ createBlock( 'core/paragraph', { content: value } ) ]
21
21
  );
22
22
  },
23
23
  },
@@ -133,64 +133,66 @@ export default function TemplatePartEdit( {
133
133
  }
134
134
 
135
135
  return (
136
- <RecursionProvider uniqueId={ templatePartId }>
137
- <TemplatePartAdvancedControls
138
- tagName={ tagName }
139
- setAttributes={ setAttributes }
140
- isEntityAvailable={ isEntityAvailable }
141
- templatePartId={ templatePartId }
142
- defaultWrapper={ areaObject.tagName }
143
- />
144
- { isPlaceholder && (
145
- <TagName { ...blockProps }>
146
- <TemplatePartPlaceholder
147
- area={ attributes.area }
148
- templatePartId={ templatePartId }
149
- clientId={ clientId }
150
- setAttributes={ setAttributes }
151
- onOpenSelectionModal={ () =>
152
- setIsTemplatePartSelectionOpen( true )
153
- }
154
- />
155
- </TagName>
156
- ) }
157
- { canReplace && (
158
- <BlockSettingsMenuControls>
159
- { () => (
160
- <MenuItem
161
- onClick={ () => {
162
- setIsTemplatePartSelectionOpen( true );
163
- } }
164
- >
165
- { createInterpolateElement(
166
- __( 'Replace <BlockTitle />' ),
167
- {
168
- BlockTitle: (
169
- <BlockTitle
170
- clientId={ clientId }
171
- maximumLength={ 25 }
172
- />
173
- ),
174
- }
175
- ) }
176
- </MenuItem>
177
- ) }
178
- </BlockSettingsMenuControls>
179
- ) }
180
- { isEntityAvailable && (
181
- <TemplatePartInnerBlocks
182
- tagName={ TagName }
183
- blockProps={ blockProps }
184
- postId={ templatePartId }
185
- hasInnerBlocks={ innerBlocks.length > 0 }
186
- layout={ layout }
136
+ <>
137
+ <RecursionProvider uniqueId={ templatePartId }>
138
+ <TemplatePartAdvancedControls
139
+ tagName={ tagName }
140
+ setAttributes={ setAttributes }
141
+ isEntityAvailable={ isEntityAvailable }
142
+ templatePartId={ templatePartId }
143
+ defaultWrapper={ areaObject.tagName }
187
144
  />
188
- ) }
189
- { ! isPlaceholder && ! isResolved && (
190
- <TagName { ...blockProps }>
191
- <Spinner />
192
- </TagName>
193
- ) }
145
+ { isPlaceholder && (
146
+ <TagName { ...blockProps }>
147
+ <TemplatePartPlaceholder
148
+ area={ attributes.area }
149
+ templatePartId={ templatePartId }
150
+ clientId={ clientId }
151
+ setAttributes={ setAttributes }
152
+ onOpenSelectionModal={ () =>
153
+ setIsTemplatePartSelectionOpen( true )
154
+ }
155
+ />
156
+ </TagName>
157
+ ) }
158
+ { canReplace && (
159
+ <BlockSettingsMenuControls>
160
+ { () => (
161
+ <MenuItem
162
+ onClick={ () => {
163
+ setIsTemplatePartSelectionOpen( true );
164
+ } }
165
+ >
166
+ { createInterpolateElement(
167
+ __( 'Replace <BlockTitle />' ),
168
+ {
169
+ BlockTitle: (
170
+ <BlockTitle
171
+ clientId={ clientId }
172
+ maximumLength={ 25 }
173
+ />
174
+ ),
175
+ }
176
+ ) }
177
+ </MenuItem>
178
+ ) }
179
+ </BlockSettingsMenuControls>
180
+ ) }
181
+ { isEntityAvailable && (
182
+ <TemplatePartInnerBlocks
183
+ tagName={ TagName }
184
+ blockProps={ blockProps }
185
+ postId={ templatePartId }
186
+ hasInnerBlocks={ innerBlocks.length > 0 }
187
+ layout={ layout }
188
+ />
189
+ ) }
190
+ { ! isPlaceholder && ! isResolved && (
191
+ <TagName { ...blockProps }>
192
+ <Spinner />
193
+ </TagName>
194
+ ) }
195
+ </RecursionProvider>
194
196
  { isTemplatePartSelectionOpen && (
195
197
  <Modal
196
198
  overlayClassName="block-editor-template-part__selection-modal"
@@ -215,6 +217,6 @@ export default function TemplatePartEdit( {
215
217
  />
216
218
  </Modal>
217
219
  ) }
218
- </RecursionProvider>
220
+ </>
219
221
  );
220
222
  }