Skip to content

Conversation

@talldan
Copy link
Contributor

@talldan talldan commented Nov 4, 2025

What?

Fixes #49048

Also extracts some of the refactoring changes from #72044, so this PR can be seen as laying the groundwork for that one.

Why?

When the 'Modify' option is used on a contentOnly template locked set of blocks, those blocks are unlocked to allow them to be freely edited, but if the user saves before clicking 'Done', the unlocking is persisted.

This is because the code in trunk actually removes templateLock: contentOnly from the block.

How?

In this PR we instead do the following when the user clicks modify:

  • Make the getTemplateLock selector return false for the block in question.
  • Change the (derived) block editing modes to default for all of the blocks that are being modified.

Neither of those changes are persisted, they're in-memory only, so saving will still retain the templateLock.

In addition to this I've updated the naming of the private actions/selectors/reducers.

I've also removed the concept of 'reverting focus mode'. Instead the isFocusMode selector will return true whenever the 'Modify' option is used, this allows for quite a lot of simplification. I've deleted one of the unstable (but public) selectors related to this, that might be controversial, but I think it's really not useful to anyone, so I can't see it being used.

Testing Instructions

  1. Add a group block that has a templateLock: contentOnly attribute set, and has some inner blocks (paragraphs, headings etc.). Here's some block markup that you can paste into the editor:
<!-- wp:group {"templateLock":"contentOnly","layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:heading -->
<h2 class="wp-block-heading">test</h2>
<!-- /wp:heading -->

<!-- wp:paragraph {"metadata":{"name":"test"}} -->
<p>test</p>
<!-- /wp:paragraph -->

<!-- wp:separator -->
<hr class="wp-block-separator has-alpha-channel-opacity"/>
<!-- /wp:separator -->

<!-- wp:paragraph {"metadata":{"name":"test"}} -->
<p>test</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"metadata":{"name":"test"}} -->
<p>test</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->
  1. Select the group and from the block settings dropdown choose 'Modify'.
  2. The inner blocks of the group should no longer be 'contentOnly' (and should now be freely editable)
  3. The 'spotlight'/'focus' feature should be applied which makes the blocks outside the group appear faded
  4. A 'Done' button should appear on the block toolbar.
  5. Save the post and reload
  6. Click the group again - observe the block is back in contentOnly mode.
  7. Try 'Modify' again, and test that you can freely modify all the inner blocks of the group, and that clicking outside and using the done button reverts the block back to contentOnly mode.

Screenshots or screencast

Kapture.2025-11-04.at.13.33.19.mp4

@talldan talldan self-assigned this Nov 4, 2025
@talldan talldan added [Type] Bug An existing feature does not function as intended [Feature] Block Locking The API allowing for the ability to lock/unlock blocks labels Nov 4, 2025
}
}

.is-focus-mode .block-editor-block-list__block.is-content-locked.has-child-selected,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this selector, I'm not sure what it was used for. I tested and it doesn't seem to work in trunk.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is-content-locked doesn't seem to exist as a class so this was probably missed during an earlier refactor?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't appear to output is-content-locked as a classname in useBlockProps either, so this removal looks fine to me 👍

);
useEffect( () => {
if ( ! isBlockOrDescendantSelected ) {
stopEditingAsBlocks( clientId );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The clientId was incorrectly passed, the selector takes no params.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stopEditingAsBlocks did take a clientId though? if you mean this one: https://github.com/WordPress/gutenberg/pull/72959/files#diff-4d145a0c43689f5a56c00a8e2919550768ebd233e91a6c6d04fee71a44bae9f2L332

stopEditingContentOnlySection is nicer in its simplicity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, so it did!

@github-actions
Copy link

github-actions bot commented Nov 4, 2025

Size Change: -193 B (-0.01%)

Total Size: 2.45 MB

Filename Size Change
build/scripts/block-editor/index.min.js 295 kB -157 B (-0.05%)
build/styles/block-editor/content-rtl.css 4.79 kB -20 B (-0.42%)
build/styles/block-editor/content.css 4.79 kB -16 B (-0.33%)
ℹ️ View Unchanged
Filename Size
build/modules/a11y/index.min.js 355 B
build/modules/block-editor/utils/fit-text-frontend.min.js 435 B
build/modules/block-library/accordion/view.min.js 520 B
build/modules/block-library/file/view.min.js 346 B
build/modules/block-library/form/view.min.js 528 B
build/modules/block-library/image/view.min.js 1.95 kB
build/modules/block-library/navigation/view.min.js 1.03 kB
build/modules/block-library/query/view.min.js 518 B
build/modules/block-library/search/view.min.js 498 B
build/modules/block-library/tabs/view.min.js 776 B
build/modules/boot/index.min.js 76.8 kB
build/modules/interactivity-router/full-page.min.js 451 B
build/modules/interactivity-router/index.min.js 11.5 kB
build/modules/interactivity/index.min.js 14.9 kB
build/modules/latex-to-mathml/index.min.js 56.5 kB
build/modules/latex-to-mathml/loader.min.js 131 B
build/scripts/a11y/index.min.js 1.06 kB
build/scripts/annotations/index.min.js 2.38 kB
build/scripts/api-fetch/index.min.js 2.83 kB
build/scripts/autop/index.min.js 2.18 kB
build/scripts/blob/index.min.js 631 B
build/scripts/block-directory/index.min.js 8.03 kB
build/scripts/block-library/index.min.js 271 kB
build/scripts/block-serialization-default-parser/index.min.js 1.16 kB
build/scripts/block-serialization-spec-parser/index.min.js 3.08 kB
build/scripts/blocks/index.min.js 56.1 kB
build/scripts/commands/index.min.js 17.4 kB
build/scripts/components/index.min.js 271 kB
build/scripts/compose/index.min.js 13.8 kB
build/scripts/core-commands/index.min.js 4.13 kB
build/scripts/core-data/index.min.js 85.9 kB
build/scripts/customize-widgets/index.min.js 12.3 kB
build/scripts/data-controls/index.min.js 793 B
build/scripts/data/index.min.js 9.61 kB
build/scripts/date/index.min.js 23.6 kB
build/scripts/deprecated/index.min.js 752 B
build/scripts/dom-ready/index.min.js 476 B
build/scripts/dom/index.min.js 4.91 kB
build/scripts/edit-post/index.min.js 16.8 kB
build/scripts/edit-site/index.min.js 228 kB
build/scripts/edit-widgets/index.min.js 20 kB
build/scripts/editor/index.min.js 283 kB
build/scripts/element/index.min.js 5.19 kB
build/scripts/escape-html/index.min.js 586 B
build/scripts/format-library/index.min.js 10.6 kB
build/scripts/hooks/index.min.js 1.83 kB
build/scripts/html-entities/index.min.js 494 B
build/scripts/i18n/index.min.js 2.46 kB
build/scripts/is-shallow-equal/index.min.js 568 B
build/scripts/keyboard-shortcuts/index.min.js 1.57 kB
build/scripts/keycodes/index.min.js 1.53 kB
build/scripts/latex-to-mathml/index.min.js 56.7 kB
build/scripts/list-reusable-blocks/index.min.js 2.44 kB
build/scripts/media-utils/index.min.js 64.4 kB
build/scripts/notices/index.min.js 1.11 kB
build/scripts/nux/index.min.js 1.88 kB
build/scripts/patterns/index.min.js 8.62 kB
build/scripts/plugins/index.min.js 2.14 kB
build/scripts/preferences-persistence/index.min.js 2.15 kB
build/scripts/preferences/index.min.js 3.31 kB
build/scripts/primitives/index.min.js 1.01 kB
build/scripts/priority-queue/index.min.js 1.61 kB
build/scripts/private-apis/index.min.js 1.09 kB
build/scripts/react-i18n/index.min.js 832 B
build/scripts/react-refresh-entry/index.min.js 9.44 kB
build/scripts/react-refresh-runtime/index.min.js 3.59 kB
build/scripts/redux-routine/index.min.js 3.36 kB
build/scripts/reusable-blocks/index.min.js 2.92 kB
build/scripts/rich-text/index.min.js 12.9 kB
build/scripts/router/index.min.js 5.96 kB
build/scripts/server-side-render/index.min.js 1.91 kB
build/scripts/shortcode/index.min.js 1.58 kB
build/scripts/style-engine/index.min.js 2.32 kB
build/scripts/theme/index.min.js 21.5 kB
build/scripts/token-list/index.min.js 739 B
build/scripts/undo-manager/index.min.js 917 B
build/scripts/url/index.min.js 3.98 kB
build/scripts/vendors/react-dom.min.js 43 kB
build/scripts/vendors/react-jsx-runtime.min.js 691 B
build/scripts/vendors/react.min.js 4.27 kB
build/scripts/viewport/index.min.js 1.22 kB
build/scripts/warning/index.min.js 454 B
build/scripts/widgets/index.min.js 7.81 kB
build/scripts/wordcount/index.min.js 1.04 kB
build/styles/block-directory/style-rtl.css 1.05 kB
build/styles/block-directory/style.css 1.05 kB
build/styles/block-editor/default-editor-styles-rtl.css 224 B
build/styles/block-editor/default-editor-styles.css 224 B
build/styles/block-editor/style-rtl.css 16.1 kB
build/styles/block-editor/style.css 16.1 kB
build/styles/block-library/accordion-heading/style-rtl.css 335 B
build/styles/block-library/accordion-heading/style.css 335 B
build/styles/block-library/accordion-item/style-rtl.css 213 B
build/styles/block-library/accordion-item/style.css 213 B
build/styles/block-library/accordion-panel/style-rtl.css 99 B
build/styles/block-library/accordion-panel/style.css 99 B
build/styles/block-library/archives/editor-rtl.css 61 B
build/styles/block-library/archives/editor.css 61 B
build/styles/block-library/archives/style-rtl.css 90 B
build/styles/block-library/archives/style.css 90 B
build/styles/block-library/audio/editor-rtl.css 149 B
build/styles/block-library/audio/editor.css 151 B
build/styles/block-library/audio/style-rtl.css 132 B
build/styles/block-library/audio/style.css 132 B
build/styles/block-library/audio/theme-rtl.css 134 B
build/styles/block-library/audio/theme.css 134 B
build/styles/block-library/avatar/editor-rtl.css 115 B
build/styles/block-library/avatar/editor.css 115 B
build/styles/block-library/avatar/style-rtl.css 104 B
build/styles/block-library/avatar/style.css 104 B
build/styles/block-library/breadcrumbs/style-rtl.css 203 B
build/styles/block-library/breadcrumbs/style.css 203 B
build/styles/block-library/button/editor-rtl.css 265 B
build/styles/block-library/button/editor.css 265 B
build/styles/block-library/button/style-rtl.css 554 B
build/styles/block-library/button/style.css 554 B
build/styles/block-library/buttons/editor-rtl.css 291 B
build/styles/block-library/buttons/editor.css 291 B
build/styles/block-library/buttons/style-rtl.css 349 B
build/styles/block-library/buttons/style.css 349 B
build/styles/block-library/calendar/style-rtl.css 239 B
build/styles/block-library/calendar/style.css 239 B
build/styles/block-library/categories/editor-rtl.css 132 B
build/styles/block-library/categories/editor.css 131 B
build/styles/block-library/categories/style-rtl.css 152 B
build/styles/block-library/categories/style.css 152 B
build/styles/block-library/classic-rtl.css 179 B
build/styles/block-library/classic.css 179 B
build/styles/block-library/code/editor-rtl.css 53 B
build/styles/block-library/code/editor.css 53 B
build/styles/block-library/code/style-rtl.css 139 B
build/styles/block-library/code/style.css 139 B
build/styles/block-library/code/theme-rtl.css 122 B
build/styles/block-library/code/theme.css 122 B
build/styles/block-library/columns/editor-rtl.css 108 B
build/styles/block-library/columns/editor.css 108 B
build/styles/block-library/columns/style-rtl.css 421 B
build/styles/block-library/columns/style.css 421 B
build/styles/block-library/comment-author-avatar/editor-rtl.css 124 B
build/styles/block-library/comment-author-avatar/editor.css 124 B
build/styles/block-library/comment-author-name/style-rtl.css 72 B
build/styles/block-library/comment-author-name/style.css 72 B
build/styles/block-library/comment-content/style-rtl.css 120 B
build/styles/block-library/comment-content/style.css 120 B
build/styles/block-library/comment-date/style-rtl.css 65 B
build/styles/block-library/comment-date/style.css 65 B
build/styles/block-library/comment-edit-link/style-rtl.css 70 B
build/styles/block-library/comment-edit-link/style.css 70 B
build/styles/block-library/comment-reply-link/style-rtl.css 71 B
build/styles/block-library/comment-reply-link/style.css 71 B
build/styles/block-library/comment-template/style-rtl.css 191 B
build/styles/block-library/comment-template/style.css 191 B
build/styles/block-library/comments-pagination-numbers/editor-rtl.css 122 B
build/styles/block-library/comments-pagination-numbers/editor.css 121 B
build/styles/block-library/comments-pagination/editor-rtl.css 168 B
build/styles/block-library/comments-pagination/editor.css 168 B
build/styles/block-library/comments-pagination/style-rtl.css 201 B
build/styles/block-library/comments-pagination/style.css 201 B
build/styles/block-library/comments-title/editor-rtl.css 75 B
build/styles/block-library/comments-title/editor.css 75 B
build/styles/block-library/comments/editor-rtl.css 842 B
build/styles/block-library/comments/editor.css 842 B
build/styles/block-library/comments/style-rtl.css 637 B
build/styles/block-library/comments/style.css 637 B
build/styles/block-library/common-rtl.css 1.11 kB
build/styles/block-library/common.css 1.11 kB
build/styles/block-library/cover/editor-rtl.css 631 B
build/styles/block-library/cover/editor.css 631 B
build/styles/block-library/cover/style-rtl.css 1.7 kB
build/styles/block-library/cover/style.css 1.69 kB
build/styles/block-library/details/editor-rtl.css 65 B
build/styles/block-library/details/editor.css 65 B
build/styles/block-library/details/style-rtl.css 86 B
build/styles/block-library/details/style.css 86 B
build/styles/block-library/editor-elements-rtl.css 75 B
build/styles/block-library/editor-elements.css 75 B
build/styles/block-library/editor-rtl.css 11.7 kB
build/styles/block-library/editor.css 11.7 kB
build/styles/block-library/elements-rtl.css 54 B
build/styles/block-library/elements.css 54 B
build/styles/block-library/embed/editor-rtl.css 331 B
build/styles/block-library/embed/editor.css 331 B
build/styles/block-library/embed/style-rtl.css 419 B
build/styles/block-library/embed/style.css 419 B
build/styles/block-library/embed/theme-rtl.css 133 B
build/styles/block-library/embed/theme.css 133 B
build/styles/block-library/file/editor-rtl.css 324 B
build/styles/block-library/file/editor.css 324 B
build/styles/block-library/file/style-rtl.css 278 B
build/styles/block-library/file/style.css 278 B
build/styles/block-library/footnotes/style-rtl.css 198 B
build/styles/block-library/footnotes/style.css 197 B
build/styles/block-library/form-input/editor-rtl.css 229 B
build/styles/block-library/form-input/editor.css 229 B
build/styles/block-library/form-input/style-rtl.css 366 B
build/styles/block-library/form-input/style.css 366 B
build/styles/block-library/form-submission-notification/editor-rtl.css 344 B
build/styles/block-library/form-submission-notification/editor.css 341 B
build/styles/block-library/form-submit-button/style-rtl.css 69 B
build/styles/block-library/form-submit-button/style.css 69 B
build/styles/block-library/freeform/editor-rtl.css 2.59 kB
build/styles/block-library/freeform/editor.css 2.59 kB
build/styles/block-library/gallery/editor-rtl.css 615 B
build/styles/block-library/gallery/editor.css 616 B
build/styles/block-library/gallery/style-rtl.css 1.84 kB
build/styles/block-library/gallery/style.css 1.84 kB
build/styles/block-library/gallery/theme-rtl.css 108 B
build/styles/block-library/gallery/theme.css 108 B
build/styles/block-library/group/editor-rtl.css 335 B
build/styles/block-library/group/editor.css 335 B
build/styles/block-library/group/style-rtl.css 103 B
build/styles/block-library/group/style.css 103 B
build/styles/block-library/group/theme-rtl.css 79 B
build/styles/block-library/group/theme.css 79 B
build/styles/block-library/heading/style-rtl.css 205 B
build/styles/block-library/heading/style.css 205 B
build/styles/block-library/html/editor-rtl.css 357 B
build/styles/block-library/html/editor.css 358 B
build/styles/block-library/image/editor-rtl.css 763 B
build/styles/block-library/image/editor.css 763 B
build/styles/block-library/image/style-rtl.css 1.6 kB
build/styles/block-library/image/style.css 1.59 kB
build/styles/block-library/image/theme-rtl.css 137 B
build/styles/block-library/image/theme.css 137 B
build/styles/block-library/latest-comments/style-rtl.css 355 B
build/styles/block-library/latest-comments/style.css 354 B
build/styles/block-library/latest-posts/editor-rtl.css 139 B
build/styles/block-library/latest-posts/editor.css 138 B
build/styles/block-library/latest-posts/style-rtl.css 520 B
build/styles/block-library/latest-posts/style.css 520 B
build/styles/block-library/list/style-rtl.css 107 B
build/styles/block-library/list/style.css 107 B
build/styles/block-library/loginout/style-rtl.css 61 B
build/styles/block-library/loginout/style.css 61 B
build/styles/block-library/math/editor-rtl.css 105 B
build/styles/block-library/math/editor.css 105 B
build/styles/block-library/math/style-rtl.css 61 B
build/styles/block-library/math/style.css 61 B
build/styles/block-library/media-text/editor-rtl.css 321 B
build/styles/block-library/media-text/editor.css 320 B
build/styles/block-library/media-text/style-rtl.css 543 B
build/styles/block-library/media-text/style.css 542 B
build/styles/block-library/more/editor-rtl.css 393 B
build/styles/block-library/more/editor.css 393 B
build/styles/block-library/navigation-link/editor-rtl.css 626 B
build/styles/block-library/navigation-link/editor.css 628 B
build/styles/block-library/navigation-link/style-rtl.css 190 B
build/styles/block-library/navigation-link/style.css 188 B
build/styles/block-library/navigation-submenu/editor-rtl.css 295 B
build/styles/block-library/navigation-submenu/editor.css 294 B
build/styles/block-library/navigation/editor-rtl.css 2.24 kB
build/styles/block-library/navigation/editor.css 2.24 kB
build/styles/block-library/navigation/style-rtl.css 2.27 kB
build/styles/block-library/navigation/style.css 2.25 kB
build/styles/block-library/nextpage/editor-rtl.css 392 B
build/styles/block-library/nextpage/editor.css 392 B
build/styles/block-library/page-list/editor-rtl.css 356 B
build/styles/block-library/page-list/editor.css 356 B
build/styles/block-library/page-list/style-rtl.css 192 B
build/styles/block-library/page-list/style.css 192 B
build/styles/block-library/paragraph/editor-rtl.css 251 B
build/styles/block-library/paragraph/editor.css 251 B
build/styles/block-library/paragraph/style-rtl.css 341 B
build/styles/block-library/paragraph/style.css 340 B
build/styles/block-library/post-author-biography/style-rtl.css 74 B
build/styles/block-library/post-author-biography/style.css 74 B
build/styles/block-library/post-author-name/style-rtl.css 69 B
build/styles/block-library/post-author-name/style.css 69 B
build/styles/block-library/post-author/style-rtl.css 188 B
build/styles/block-library/post-author/style.css 189 B
build/styles/block-library/post-comments-count/style-rtl.css 72 B
build/styles/block-library/post-comments-count/style.css 72 B
build/styles/block-library/post-comments-form/editor-rtl.css 96 B
build/styles/block-library/post-comments-form/editor.css 96 B
build/styles/block-library/post-comments-form/style-rtl.css 525 B
build/styles/block-library/post-comments-form/style.css 525 B
build/styles/block-library/post-comments-link/style-rtl.css 71 B
build/styles/block-library/post-comments-link/style.css 71 B
build/styles/block-library/post-content/style-rtl.css 61 B
build/styles/block-library/post-content/style.css 61 B
build/styles/block-library/post-date/style-rtl.css 62 B
build/styles/block-library/post-date/style.css 62 B
build/styles/block-library/post-excerpt/editor-rtl.css 71 B
build/styles/block-library/post-excerpt/editor.css 71 B
build/styles/block-library/post-excerpt/style-rtl.css 155 B
build/styles/block-library/post-excerpt/style.css 155 B
build/styles/block-library/post-featured-image/editor-rtl.css 719 B
build/styles/block-library/post-featured-image/editor.css 717 B
build/styles/block-library/post-featured-image/style-rtl.css 347 B
build/styles/block-library/post-featured-image/style.css 347 B
build/styles/block-library/post-navigation-link/style-rtl.css 215 B
build/styles/block-library/post-navigation-link/style.css 214 B
build/styles/block-library/post-template/style-rtl.css 414 B
build/styles/block-library/post-template/style.css 414 B
build/styles/block-library/post-terms/style-rtl.css 96 B
build/styles/block-library/post-terms/style.css 96 B
build/styles/block-library/post-time-to-read/style-rtl.css 70 B
build/styles/block-library/post-time-to-read/style.css 70 B
build/styles/block-library/post-title/style-rtl.css 162 B
build/styles/block-library/post-title/style.css 162 B
build/styles/block-library/preformatted/style-rtl.css 125 B
build/styles/block-library/preformatted/style.css 125 B
build/styles/block-library/pullquote/editor-rtl.css 133 B
build/styles/block-library/pullquote/editor.css 133 B
build/styles/block-library/pullquote/style-rtl.css 365 B
build/styles/block-library/pullquote/style.css 365 B
build/styles/block-library/pullquote/theme-rtl.css 176 B
build/styles/block-library/pullquote/theme.css 176 B
build/styles/block-library/query-pagination-numbers/editor-rtl.css 121 B
build/styles/block-library/query-pagination-numbers/editor.css 118 B
build/styles/block-library/query-pagination/editor-rtl.css 154 B
build/styles/block-library/query-pagination/editor.css 154 B
build/styles/block-library/query-pagination/style-rtl.css 237 B
build/styles/block-library/query-pagination/style.css 237 B
build/styles/block-library/query-title/style-rtl.css 64 B
build/styles/block-library/query-title/style.css 64 B
build/styles/block-library/query-total/style-rtl.css 64 B
build/styles/block-library/query-total/style.css 64 B
build/styles/block-library/query/editor-rtl.css 438 B
build/styles/block-library/query/editor.css 438 B
build/styles/block-library/quote/style-rtl.css 238 B
build/styles/block-library/quote/style.css 238 B
build/styles/block-library/quote/theme-rtl.css 233 B
build/styles/block-library/quote/theme.css 236 B
build/styles/block-library/read-more/style-rtl.css 131 B
build/styles/block-library/read-more/style.css 131 B
build/styles/block-library/reset-rtl.css 472 B
build/styles/block-library/reset.css 472 B
build/styles/block-library/rss/editor-rtl.css 126 B
build/styles/block-library/rss/editor.css 126 B
build/styles/block-library/rss/style-rtl.css 284 B
build/styles/block-library/rss/style.css 283 B
build/styles/block-library/search/editor-rtl.css 199 B
build/styles/block-library/search/editor.css 199 B
build/styles/block-library/search/style-rtl.css 665 B
build/styles/block-library/search/style.css 666 B
build/styles/block-library/search/theme-rtl.css 113 B
build/styles/block-library/search/theme.css 113 B
build/styles/block-library/separator/editor-rtl.css 100 B
build/styles/block-library/separator/editor.css 100 B
build/styles/block-library/separator/style-rtl.css 248 B
build/styles/block-library/separator/style.css 248 B
build/styles/block-library/separator/theme-rtl.css 195 B
build/styles/block-library/separator/theme.css 195 B
build/styles/block-library/shortcode/editor-rtl.css 286 B
build/styles/block-library/shortcode/editor.css 286 B
build/styles/block-library/site-logo/editor-rtl.css 773 B
build/styles/block-library/site-logo/editor.css 770 B
build/styles/block-library/site-logo/style-rtl.css 218 B
build/styles/block-library/site-logo/style.css 218 B
build/styles/block-library/site-tagline/editor-rtl.css 87 B
build/styles/block-library/site-tagline/editor.css 87 B
build/styles/block-library/site-tagline/style-rtl.css 65 B
build/styles/block-library/site-tagline/style.css 65 B
build/styles/block-library/site-title/editor-rtl.css 85 B
build/styles/block-library/site-title/editor.css 85 B
build/styles/block-library/site-title/style-rtl.css 143 B
build/styles/block-library/site-title/style.css 143 B
build/styles/block-library/social-link/editor-rtl.css 314 B
build/styles/block-library/social-link/editor.css 314 B
build/styles/block-library/social-links/editor-rtl.css 339 B
build/styles/block-library/social-links/editor.css 338 B
build/styles/block-library/social-links/style-rtl.css 1.51 kB
build/styles/block-library/social-links/style.css 1.51 kB
build/styles/block-library/spacer/editor-rtl.css 346 B
build/styles/block-library/spacer/editor.css 346 B
build/styles/block-library/spacer/style-rtl.css 48 B
build/styles/block-library/spacer/style.css 48 B
build/styles/block-library/style-rtl.css 16.4 kB
build/styles/block-library/style.css 16.4 kB
build/styles/block-library/tab/style-rtl.css 202 B
build/styles/block-library/tab/style.css 202 B
build/styles/block-library/table-of-contents/style-rtl.css 83 B
build/styles/block-library/table-of-contents/style.css 83 B
build/styles/block-library/table/editor-rtl.css 394 B
build/styles/block-library/table/editor.css 394 B
build/styles/block-library/table/style-rtl.css 641 B
build/styles/block-library/table/style.css 640 B
build/styles/block-library/table/theme-rtl.css 152 B
build/styles/block-library/table/theme.css 152 B
build/styles/block-library/tabs/editor-rtl.css 236 B
build/styles/block-library/tabs/editor.css 236 B
build/styles/block-library/tabs/style-rtl.css 983 B
build/styles/block-library/tabs/style.css 983 B
build/styles/block-library/tag-cloud/editor-rtl.css 92 B
build/styles/block-library/tag-cloud/editor.css 92 B
build/styles/block-library/tag-cloud/style-rtl.css 248 B
build/styles/block-library/tag-cloud/style.css 248 B
build/styles/block-library/template-part/editor-rtl.css 368 B
build/styles/block-library/template-part/editor.css 368 B
build/styles/block-library/template-part/theme-rtl.css 113 B
build/styles/block-library/template-part/theme.css 113 B
build/styles/block-library/term-count/style-rtl.css 63 B
build/styles/block-library/term-count/style.css 63 B
build/styles/block-library/term-description/style-rtl.css 126 B
build/styles/block-library/term-description/style.css 126 B
build/styles/block-library/term-name/style-rtl.css 62 B
build/styles/block-library/term-name/style.css 62 B
build/styles/block-library/term-template/editor-rtl.css 225 B
build/styles/block-library/term-template/editor.css 225 B
build/styles/block-library/term-template/style-rtl.css 114 B
build/styles/block-library/term-template/style.css 114 B
build/styles/block-library/text-columns/editor-rtl.css 95 B
build/styles/block-library/text-columns/editor.css 95 B
build/styles/block-library/text-columns/style-rtl.css 165 B
build/styles/block-library/text-columns/style.css 165 B
build/styles/block-library/theme-rtl.css 715 B
build/styles/block-library/theme.css 719 B
build/styles/block-library/verse/style-rtl.css 98 B
build/styles/block-library/verse/style.css 98 B
build/styles/block-library/video/editor-rtl.css 415 B
build/styles/block-library/video/editor.css 416 B
build/styles/block-library/video/style-rtl.css 202 B
build/styles/block-library/video/style.css 202 B
build/styles/block-library/video/theme-rtl.css 134 B
build/styles/block-library/video/theme.css 134 B
build/styles/commands/style-rtl.css 999 B
build/styles/commands/style.css 1 kB
build/styles/components/style-rtl.css 14 kB
build/styles/components/style.css 14 kB
build/styles/customize-widgets/style-rtl.css 1.44 kB
build/styles/customize-widgets/style.css 1.44 kB
build/styles/edit-post/classic-rtl.css 426 B
build/styles/edit-post/classic.css 427 B
build/styles/edit-post/style-rtl.css 3.33 kB
build/styles/edit-post/style.css 3.33 kB
build/styles/edit-site/posts-rtl.css 9.85 kB
build/styles/edit-site/posts.css 9.84 kB
build/styles/edit-site/style-rtl.css 15.4 kB
build/styles/edit-site/style.css 15.4 kB
build/styles/edit-widgets/style-rtl.css 4.59 kB
build/styles/edit-widgets/style.css 4.59 kB
build/styles/editor/style-rtl.css 18 kB
build/styles/editor/style.css 18 kB
build/styles/format-library/style-rtl.css 326 B
build/styles/format-library/style.css 326 B
build/styles/list-reusable-blocks/style-rtl.css 1.02 kB
build/styles/list-reusable-blocks/style.css 1.02 kB
build/styles/nux/style-rtl.css 622 B
build/styles/nux/style.css 618 B
build/styles/patterns/style-rtl.css 703 B
build/styles/patterns/style.css 703 B
build/styles/preferences/style-rtl.css 415 B
build/styles/preferences/style.css 415 B
build/styles/reusable-blocks/style-rtl.css 275 B
build/styles/reusable-blocks/style.css 275 B
build/styles/widgets/style-rtl.css 1.17 kB
build/styles/widgets/style.css 1.18 kB

compressed-size-action

@github-actions
Copy link

github-actions bot commented Nov 4, 2025

Flaky tests detected in d6c8e9a.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/19090176559
📝 Reported issues:

@talldan talldan changed the title Fix contentOnly temporary editing to not persist on save (+ refactor some of the code) Fix contentOnly temporary editing persisting on save (+ refactor some of the code) Nov 4, 2025
Copy link
Contributor

@tellthemachines tellthemachines left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a good enhancement overall and it works as expected in testing! I just left a few niggles and questions below but nothing major.

Any reason it's still in draft mode? Happy to approve otherwise.

}
}

.is-focus-mode .block-editor-block-list__block.is-content-locked.has-child-selected,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is-content-locked doesn't seem to exist as a class so this was probably missed during an earlier refactor?

isOutlineMode: outlineMode && ! isTyping(),
isFocusMode: focusMode || hasBlockSpotlight(),
temporarilyEditingAsBlocks: getTemporarilyEditingAsBlocks(),
editedContentOnlySection: getEditedContentOnlySection(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be editableContentOnlySection instead? The selector is looking at whether it's in an editable state or not, isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm calling it edited everywhere else as a shorthand for "the section that's being edited". It's not perfect, but I prefer to keep the naming consistent.

);
useEffect( () => {
if ( ! isBlockOrDescendantSelected ) {
stopEditingAsBlocks( clientId );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stopEditingAsBlocks did take a clientId though? if you mean this one: https://github.com/WordPress/gutenberg/pull/72959/files#diff-4d145a0c43689f5a56c00a8e2919550768ebd233e91a6c6d04fee71a44bae9f2L332

stopEditingContentOnlySection is nicer in its simplicity.


// The implementation of content locking is mainly in this file, although the mechanism
// to stop temporarily editing as blocks when an outside block is selected is on component StopEditingAsBlocksOnOutsideSelect
// to stop editing a content only section an outside block is selected is on component StopEditingContentOnlySectionOnOutsideSelect
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: when an outside block is selected

}

const showStopEditingAsBlocks = isEditingAsBlocks && ! isContentLocked;
const showDoneButton = isEditingContentOnlySection && ! isContentLocked;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much clearer name 👍

focusModeToRevert,
};
export function __unstableSetTemporarilyEditingAsBlocks( clientId ) {
return editContentOnlySection( clientId );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still in use now the occurrences below have been deleted? Or are we keeping it because it's public?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unused, I guess it should be deprecated like the selectors. I'll push a commit that does that.

Copy link
Member

@ramonjd ramonjd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works as described.

I also tested:

✅ As far as I can see it doesn't break other focus mode behaviors, e.g., when editing template parts
✅ Nested patterns (in content only mode) behave
✅ I checked stuff like undo/redo, deleting locked blocks while modifying them

I think it'd be neat to select the block if clicking from the list item context menu, what do you reckon?

const stopEditingAsBlockCallback = useCallback( () => {
stopEditingAsBlocks( clientId );
}, [ clientId, stopEditingAsBlocks ] );
stopEditingContentOnlySection( clientId );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does stopEditingContentOnlySection accept any args?

* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at action.clientId, can this also be a String?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be a string 👍

return action.focusModeToRevert;
export function editedContentOnlySection( state = '', action ) {
if ( action.type === 'EDIT_CONTENT_ONLY_SECTION' ) {
return action.clientId;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Profoundly optional 😄 but related to return comment above.

Explicitly return empty string when undefined:

return action.clientId ?? '';

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'' usually refers to the root block, so I don't want to do that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though it is weird that the default state is '' 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed the default state value (it'll just be undefined) and fixed the types.

<MenuItem
onClick={ () => {
modifyContentLockBlock( clientId );
editContentOnlySection( clientId );
Copy link
Member

@ramonjd ramonjd Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is working well for me. One improvement would be to select the block if it's not selected when clicking on "Modify". That would cover clicks on the list view context menu click when the block isn't selected.

See the latter half of this vid:

Kapture.2025-11-05.at.11.12.34.mp4
Here's an example diff that works for me:
diff --git a/packages/block-editor/src/components/content-lock/modify-content-lock-menu-item.js b/packages/block-editor/src/components/content-lock/modify-content-lock-menu-item.js
index 9932ef9895..4cb9b27886 100644
--- a/packages/block-editor/src/components/content-lock/modify-content-lock-menu-item.js
+++ b/packages/block-editor/src/components/content-lock/modify-content-lock-menu-item.js
@@ -18,23 +18,31 @@ import { unlock } from '../../lock-unlock';
 // also includes artifacts on the store (actions, reducers, and selector).
 
 export function ModifyContentOnlySectionMenuItem( { clientId, onClose } ) {
-	const { templateLock, isLockedByParent, isEditingContentOnlySection } =
-		useSelect(
-			( select ) => {
-				const {
-					getContentLockingParent,
-					getTemplateLock,
-					getEditedContentOnlySection,
-				} = unlock( select( blockEditorStore ) );
-				return {
-					templateLock: getTemplateLock( clientId ),
-					isLockedByParent: !! getContentLockingParent( clientId ),
-					isEditingContentOnlySection:
-						getEditedContentOnlySection() === clientId,
-				};
-			},
-			[ clientId ]
-		);
+	const {
+		templateLock,
+		isLockedByParent,
+		isEditingContentOnlySection,
+		isBlockSelected,
+	} = useSelect(
+		( select ) => {
+			const {
+				getContentLockingParent,
+				getTemplateLock,
+				getEditedContentOnlySection,
+			} = unlock( select( blockEditorStore ) );
+			const { isBlockSelected: _isBlockSelected } =
+				select( blockEditorStore );
+			return {
+				templateLock: getTemplateLock( clientId ),
+				isLockedByParent: !! getContentLockingParent( clientId ),
+				isEditingContentOnlySection:
+					getEditedContentOnlySection() === clientId,
+
+				isBlockSelected: _isBlockSelected( clientId ),
+			};
+		},
+		[ clientId ]
+	);
 	const blockEditorActions = useDispatch( blockEditorStore );
 	const isContentLocked =
 		! isLockedByParent && templateLock === 'contentOnly';
@@ -42,7 +50,8 @@ export function ModifyContentOnlySectionMenuItem( { clientId, onClose } ) {
 		return null;
 	}
 
-	const { editContentOnlySection } = unlock( blockEditorActions );
+	const { editContentOnlySection, selectBlock } =
+		unlock( blockEditorActions );
 	const showStartEditingAsBlocks =
 		! isEditingContentOnlySection && isContentLocked;
 
@@ -50,6 +59,10 @@ export function ModifyContentOnlySectionMenuItem( { clientId, onClose } ) {
 		showStartEditingAsBlocks && (
 			<MenuItem
 				onClick={ () => {
+					// Select the block if it's not already selected
+					if ( ! isBlockSelected ) {
+						selectBlock( clientId );
+					}
 					editContentOnlySection( clientId );
 					onClose();
 				} }

Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is testing well for me, too! Nice how this behaviour simplifies the selectors / actions, too 👍

}
}

.is-focus-mode .block-editor-block-list__block.is-content-locked.has-child-selected,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't appear to output is-content-locked as a classname in useBlockProps either, so this removal looks fine to me 👍


// The implementation of content locking is mainly in this file, although the mechanism
// to stop temporarily editing as blocks when an outside block is selected is on component StopEditingAsBlocksOnOutsideSelect
// to stop editing a content only section an outside block is selected is on component StopEditingContentOnlySectionOnOutsideSelect
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tiniest of nits, feel free to ignore!

Suggested change
// to stop editing a content only section an outside block is selected is on component StopEditingContentOnlySectionOnOutsideSelect
// to stop editing a content only section when an outside block is selected is in the component StopEditingContentOnlySectionOnOutsideSelect

rootClientId
)?.templateLock;

// If this is a contentOnly template locked block that's being in the process
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another tiny optional nit (feel free to ignore!)

Suggested change
// If this is a contentOnly template locked block that's being in the process
// If this is a contentOnly template locked block that's in the process

Comment on lines -3225 to -3228
export function __unstableGetTemporarilyEditingFocusModeToRevert( state ) {
deprecated(
"wp.data.select( 'core/block-editor' ).__unstableGetTemporarilyEditingFocusModeToRevert",
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find this being used anywhere and searched https://wpdirectory.net/, so I reckon this is good to remove 👍

@talldan talldan marked this pull request as ready for review November 5, 2025 01:07
@talldan talldan requested a review from ellatrix as a code owner November 5, 2025 01:07
@github-actions
Copy link

github-actions bot commented Nov 5, 2025

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: talldan <talldanwp@git.wordpress.org>
Co-authored-by: tellthemachines <isabel_brison@git.wordpress.org>
Co-authored-by: ramonjd <ramonopoly@git.wordpress.org>
Co-authored-by: andrewserong <andrewserong@git.wordpress.org>
Co-authored-by: Thelmachido <thelmachido@git.wordpress.org>
Co-authored-by: franzaurus <franz00@git.wordpress.org>
Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org>
Co-authored-by: stokesman <presstoke@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM after the latest updates! 🎉

I also liked @ramonjd's idea for the list view menu to select the section block after clicking Modify (#72959 (comment)), but I don't think that needs to happen in this PR necessarily.

Nice refactor 👍

@talldan
Copy link
Contributor Author

talldan commented Nov 5, 2025

I also liked @ramonjd's idea for the list view menu to select the section block after clicking Modify (#72959 (comment)), but I don't think that needs to happen in this PR necessarily.

The UI should eventually be replaced by #72044, so I don't want to spend too much time on it.

Thanks for the reviews. I think I'll push some tests and then merge ❤️

@andrewserong
Copy link
Contributor

The UI should eventually be replaced by #72044, so I don't want to spend too much time on it.

Ah, good call, thanks for the reminder 👍

@ramonjd
Copy link
Member

ramonjd commented Nov 5, 2025

The UI should eventually be replaced by #72044, so I don't want to spend too much time on it.

Sounds good!

Thanks for the reviews. I think I'll push some tests and then merge ❤️

🚀

@talldan talldan merged commit 1a0864d into trunk Nov 5, 2025
34 of 35 checks passed
@talldan talldan deleted the update/content-only-temporary-editing branch November 5, 2025 04:18
@github-actions github-actions bot added this to the Gutenberg 22.1 milestone Nov 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Block Locking The API allowing for the ability to lock/unlock blocks [Type] Bug An existing feature does not function as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

contentOnly template lock can be lost

5 participants