@wordpress/editor 14.47.0 → 14.48.1

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 (213) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/build/components/block-removal-warnings/index.cjs +0 -3
  3. package/build/components/block-removal-warnings/index.cjs.map +2 -2
  4. package/build/components/collab-sidebar/note-indicator-toolbar.cjs +49 -43
  5. package/build/components/collab-sidebar/note-indicator-toolbar.cjs.map +3 -3
  6. package/build/components/collaborators-overlay/use-block-highlighting.cjs +1 -8
  7. package/build/components/collaborators-overlay/use-block-highlighting.cjs.map +3 -3
  8. package/build/components/collaborators-overlay/use-render-cursors.cjs +1 -7
  9. package/build/components/collaborators-overlay/use-render-cursors.cjs.map +3 -3
  10. package/build/components/more-menu/view-more-menu-group.cjs +1 -2
  11. package/build/components/more-menu/view-more-menu-group.cjs.map +2 -2
  12. package/build/components/page-attributes/parent.cjs +1 -0
  13. package/build/components/page-attributes/parent.cjs.map +2 -2
  14. package/build/components/post-publish-button/index.cjs +114 -157
  15. package/build/components/post-publish-button/index.cjs.map +3 -3
  16. package/build/components/post-revisions-preview/block-diff.cjs +21 -9
  17. package/build/components/post-revisions-preview/block-diff.cjs.map +2 -2
  18. package/build/components/post-revisions-preview/preserve-client-ids.cjs +2 -2
  19. package/build/components/post-revisions-preview/preserve-client-ids.cjs.map +2 -2
  20. package/build/components/provider/index.cjs +2 -0
  21. package/build/components/provider/index.cjs.map +3 -3
  22. package/build/components/provider/use-block-editor-settings.cjs +1 -1
  23. package/build/components/provider/use-block-editor-settings.cjs.map +2 -2
  24. package/build/components/provider/use-network-reconnect.cjs +51 -0
  25. package/build/components/provider/use-network-reconnect.cjs.map +7 -0
  26. package/build/components/revision-fields-diff/index.cjs +2 -2
  27. package/build/components/revision-fields-diff/index.cjs.map +2 -2
  28. package/build/components/sidebar/index.cjs +1 -4
  29. package/build/components/sidebar/index.cjs.map +2 -2
  30. package/build/components/template-actions-panel/block-theme-content.cjs +7 -1
  31. package/build/components/template-actions-panel/block-theme-content.cjs.map +2 -2
  32. package/build/components/upload-progress-snackbar/index.cjs +161 -0
  33. package/build/components/upload-progress-snackbar/index.cjs.map +7 -0
  34. package/build/components/upload-progress-snackbar/tracker.cjs +90 -0
  35. package/build/components/upload-progress-snackbar/tracker.cjs.map +7 -0
  36. package/build/private-apis.cjs +2 -0
  37. package/build/private-apis.cjs.map +3 -3
  38. package/build/store/selectors.cjs +1 -2
  39. package/build/store/selectors.cjs.map +2 -2
  40. package/build/utils/media-upload/index.cjs +16 -0
  41. package/build/utils/media-upload/index.cjs.map +3 -3
  42. package/build-module/components/block-removal-warnings/index.mjs +0 -3
  43. package/build-module/components/block-removal-warnings/index.mjs.map +2 -2
  44. package/build-module/components/collab-sidebar/note-indicator-toolbar.mjs +53 -44
  45. package/build-module/components/collab-sidebar/note-indicator-toolbar.mjs.map +2 -2
  46. package/build-module/components/collaborators-overlay/use-block-highlighting.mjs +1 -8
  47. package/build-module/components/collaborators-overlay/use-block-highlighting.mjs.map +2 -2
  48. package/build-module/components/collaborators-overlay/use-render-cursors.mjs +1 -7
  49. package/build-module/components/collaborators-overlay/use-render-cursors.mjs.map +2 -2
  50. package/build-module/components/more-menu/view-more-menu-group.mjs +1 -2
  51. package/build-module/components/more-menu/view-more-menu-group.mjs.map +2 -2
  52. package/build-module/components/page-attributes/parent.mjs +1 -0
  53. package/build-module/components/page-attributes/parent.mjs.map +2 -2
  54. package/build-module/components/post-publish-button/index.mjs +116 -159
  55. package/build-module/components/post-publish-button/index.mjs.map +2 -2
  56. package/build-module/components/post-revisions-preview/block-diff.mjs +20 -8
  57. package/build-module/components/post-revisions-preview/block-diff.mjs.map +2 -2
  58. package/build-module/components/post-revisions-preview/preserve-client-ids.mjs +1 -1
  59. package/build-module/components/post-revisions-preview/preserve-client-ids.mjs.map +1 -1
  60. package/build-module/components/provider/index.mjs +2 -0
  61. package/build-module/components/provider/index.mjs.map +2 -2
  62. package/build-module/components/provider/use-block-editor-settings.mjs +1 -1
  63. package/build-module/components/provider/use-block-editor-settings.mjs.map +2 -2
  64. package/build-module/components/provider/use-network-reconnect.mjs +30 -0
  65. package/build-module/components/provider/use-network-reconnect.mjs.map +7 -0
  66. package/build-module/components/revision-fields-diff/index.mjs +2 -2
  67. package/build-module/components/revision-fields-diff/index.mjs.map +2 -2
  68. package/build-module/components/sidebar/index.mjs +2 -11
  69. package/build-module/components/sidebar/index.mjs.map +2 -2
  70. package/build-module/components/template-actions-panel/block-theme-content.mjs +7 -1
  71. package/build-module/components/template-actions-panel/block-theme-content.mjs.map +2 -2
  72. package/build-module/components/upload-progress-snackbar/index.mjs +135 -0
  73. package/build-module/components/upload-progress-snackbar/index.mjs.map +7 -0
  74. package/build-module/components/upload-progress-snackbar/tracker.mjs +61 -0
  75. package/build-module/components/upload-progress-snackbar/tracker.mjs.map +7 -0
  76. package/build-module/private-apis.mjs +2 -0
  77. package/build-module/private-apis.mjs.map +2 -2
  78. package/build-module/store/selectors.mjs +1 -2
  79. package/build-module/store/selectors.mjs.map +2 -2
  80. package/build-module/utils/media-upload/index.mjs +19 -0
  81. package/build-module/utils/media-upload/index.mjs.map +2 -2
  82. package/build-style/style-rtl.css +479 -84
  83. package/build-style/style.css +479 -84
  84. package/build-types/components/block-removal-warnings/index.d.ts.map +1 -1
  85. package/build-types/components/collab-sidebar/add-comment.d.ts +6 -0
  86. package/build-types/components/collab-sidebar/add-comment.d.ts.map +1 -0
  87. package/build-types/components/collab-sidebar/comment-author-info.d.ts +8 -0
  88. package/build-types/components/collab-sidebar/comment-author-info.d.ts.map +1 -0
  89. package/build-types/components/collab-sidebar/comment-form.d.ts +9 -0
  90. package/build-types/components/collab-sidebar/comment-form.d.ts.map +1 -0
  91. package/build-types/components/collab-sidebar/comment-indicator-toolbar.d.ts +6 -0
  92. package/build-types/components/collab-sidebar/comment-indicator-toolbar.d.ts.map +1 -0
  93. package/build-types/components/collab-sidebar/comment-menu-item.d.ts +6 -0
  94. package/build-types/components/collab-sidebar/comment-menu-item.d.ts.map +1 -0
  95. package/build-types/components/collab-sidebar/comments.d.ts +10 -0
  96. package/build-types/components/collab-sidebar/comments.d.ts.map +1 -0
  97. package/build-types/components/collab-sidebar/note-indicator-toolbar.d.ts.map +1 -1
  98. package/build-types/components/collaborators-overlay/use-block-highlighting.d.ts +0 -3
  99. package/build-types/components/collaborators-overlay/use-block-highlighting.d.ts.map +1 -1
  100. package/build-types/components/collaborators-overlay/use-render-cursors.d.ts.map +1 -1
  101. package/build-types/components/document-bar/index.d.ts +2 -2
  102. package/build-types/components/document-bar/index.d.ts.map +1 -1
  103. package/build-types/components/global-styles-provider/index.d.ts +16 -0
  104. package/build-types/components/global-styles-provider/index.d.ts.map +1 -0
  105. package/build-types/components/media/index.d.ts +3 -0
  106. package/build-types/components/media/index.d.ts.map +1 -0
  107. package/build-types/components/media/metadata-panel.d.ts +12 -0
  108. package/build-types/components/media/metadata-panel.d.ts.map +1 -0
  109. package/build-types/components/media/preview.d.ts +9 -0
  110. package/build-types/components/media/preview.d.ts.map +1 -0
  111. package/build-types/components/more-menu/view-more-menu-group.d.ts.map +1 -1
  112. package/build-types/components/page-attributes/parent.d.ts.map +1 -1
  113. package/build-types/components/post-locked-modal/index.d.ts +6 -1
  114. package/build-types/components/post-publish-button/index.d.ts +9 -9
  115. package/build-types/components/post-publish-button/index.d.ts.map +1 -1
  116. package/build-types/components/post-revisions-preview/block-diff.d.ts +3 -0
  117. package/build-types/components/post-revisions-preview/block-diff.d.ts.map +1 -1
  118. package/build-types/components/post-taxonomies/flat-term-selector.d.ts +6 -1
  119. package/build-types/components/post-taxonomies/hierarchical-term-selector.d.ts +6 -1
  120. package/build-types/components/post-text-editor/index.d.ts +1 -1
  121. package/build-types/components/post-text-editor/index.d.ts.map +1 -1
  122. package/build-types/components/post-text-editor/utils.d.ts +29 -0
  123. package/build-types/components/post-text-editor/utils.d.ts.map +1 -0
  124. package/build-types/components/provider/index.d.ts.map +1 -1
  125. package/build-types/components/provider/use-network-reconnect.d.ts +8 -0
  126. package/build-types/components/provider/use-network-reconnect.d.ts.map +1 -0
  127. package/build-types/components/revision-fields-diff/index.d.ts +3 -0
  128. package/build-types/components/revision-fields-diff/index.d.ts.map +1 -1
  129. package/build-types/components/sidebar/index.d.ts.map +1 -1
  130. package/build-types/components/template-actions-panel/block-theme-content.d.ts.map +1 -1
  131. package/build-types/components/upload-progress-snackbar/index.d.ts +19 -0
  132. package/build-types/components/upload-progress-snackbar/index.d.ts.map +1 -0
  133. package/build-types/components/upload-progress-snackbar/stories/index.story.d.ts +28 -0
  134. package/build-types/components/upload-progress-snackbar/stories/index.story.d.ts.map +1 -0
  135. package/build-types/components/upload-progress-snackbar/tracker.d.ts +41 -0
  136. package/build-types/components/upload-progress-snackbar/tracker.d.ts.map +1 -0
  137. package/build-types/private-apis.d.ts.map +1 -1
  138. package/build-types/store/selectors.d.ts.map +1 -1
  139. package/build-types/utils/get-template-part-icon.d.ts.map +1 -1
  140. package/build-types/utils/media-upload/index.d.ts.map +1 -1
  141. package/package.json +55 -52
  142. package/src/components/README.md +1 -1
  143. package/src/components/block-removal-warnings/index.js +0 -7
  144. package/src/components/collab-sidebar/note-indicator-toolbar.js +73 -60
  145. package/src/components/collaborators-overlay/use-block-highlighting.ts +0 -9
  146. package/src/components/collaborators-overlay/use-render-cursors.ts +0 -8
  147. package/src/components/collaborators-presence/avatar/test/index.tsx +8 -3
  148. package/src/components/more-menu/view-more-menu-group.js +1 -2
  149. package/src/components/page-attributes/parent.js +1 -0
  150. package/src/components/post-publish-button/index.js +143 -192
  151. package/src/components/post-publish-button/test/index.js +137 -114
  152. package/src/components/post-revisions-preview/block-diff.js +63 -19
  153. package/src/components/post-revisions-preview/preserve-client-ids.js +1 -1
  154. package/src/components/post-revisions-preview/test/block-diff.js +109 -6
  155. package/src/components/provider/index.js +4 -0
  156. package/src/components/provider/test/use-network-reconnect.js +137 -0
  157. package/src/components/provider/use-block-editor-settings.js +2 -2
  158. package/src/components/provider/use-network-reconnect.js +44 -0
  159. package/src/components/revision-fields-diff/index.js +7 -2
  160. package/src/components/sidebar/index.js +2 -11
  161. package/src/components/template-actions-panel/block-theme-content.js +10 -1
  162. package/src/components/upload-progress-snackbar/README.md +26 -0
  163. package/src/components/upload-progress-snackbar/index.js +216 -0
  164. package/src/components/upload-progress-snackbar/stories/index.story.tsx +85 -0
  165. package/src/components/upload-progress-snackbar/style.scss +30 -0
  166. package/src/components/upload-progress-snackbar/test/index.js +199 -0
  167. package/src/components/upload-progress-snackbar/tracker.js +105 -0
  168. package/src/private-apis.js +2 -0
  169. package/src/store/selectors.js +1 -3
  170. package/src/style.scss +1 -0
  171. package/src/utils/media-upload/index.js +27 -0
  172. package/src/components/commands/index.native.js +0 -2
  173. package/src/components/deprecated.native.js +0 -47
  174. package/src/components/editor-help/add-blocks.native.js +0 -40
  175. package/src/components/editor-help/customize-blocks.native.js +0 -40
  176. package/src/components/editor-help/help-detail-navigation-screen.native.js +0 -67
  177. package/src/components/editor-help/help-get-support-button.native.js +0 -38
  178. package/src/components/editor-help/help-section-title.native.js +0 -29
  179. package/src/components/editor-help/help-topic-row.native.js +0 -33
  180. package/src/components/editor-help/icon-move-blocks.native.js +0 -10
  181. package/src/components/editor-help/index.native.js +0 -208
  182. package/src/components/editor-help/intro-to-blocks.native.js +0 -91
  183. package/src/components/editor-help/move-blocks.native.js +0 -55
  184. package/src/components/editor-help/remove-blocks.native.js +0 -35
  185. package/src/components/editor-help/style.android.scss +0 -6
  186. package/src/components/editor-help/style.ios.scss +0 -6
  187. package/src/components/editor-help/test/index.native.js +0 -81
  188. package/src/components/editor-help/view-sections.native.js +0 -79
  189. package/src/components/error-boundary/index.native.js +0 -192
  190. package/src/components/error-boundary/style.native.scss +0 -116
  191. package/src/components/index.native.js +0 -15
  192. package/src/components/offline-status/index.native.js +0 -99
  193. package/src/components/offline-status/style.native.scss +0 -28
  194. package/src/components/offline-status/test/index.native.js +0 -108
  195. package/src/components/post-title/index.native.js +0 -282
  196. package/src/components/post-title/style.native.scss +0 -13
  197. package/src/components/post-title/test/__snapshots__/index.native.js.snap +0 -25
  198. package/src/components/post-title/test/index.native.js +0 -78
  199. package/src/components/provider/index.native.js +0 -497
  200. package/src/components/provider/use-block-editor-settings.native.js +0 -48
  201. package/src/components/template-part-menu-items/index.native.js +0 -3
  202. package/src/hooks/index.native.js +0 -0
  203. package/src/index.native.js +0 -16
  204. package/src/private-apis.native.js +0 -33
  205. package/src/store/actions.native.js +0 -27
  206. package/src/store/reducer.native.js +0 -94
  207. package/src/store/selectors.native.js +0 -57
  208. package/src/store/test/actions.native.js +0 -16
  209. package/src/store/test/reducer.native.js +0 -36
  210. package/src/store/test/selectors.native.js +0 -28
  211. package/src/utils/index.native.js +0 -6
  212. package/src/utils/media-sideload/index.native.js +0 -1
  213. package/src/utils/media-upload/index.native.js +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/post-publish-button/index.js"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { Button } from '@wordpress/components';\nimport { Component } from '@wordpress/element';\nimport { withSelect, withDispatch } from '@wordpress/data';\nimport { compose } from '@wordpress/compose';\n\n/**\n * Internal dependencies\n */\nimport PublishButtonLabel from './label';\nimport { store as editorStore } from '../../store';\n\nconst noop = () => {};\n\nexport class PostPublishButton extends Component {\n\tconstructor( props ) {\n\t\tsuper( props );\n\n\t\tthis.createOnClick = this.createOnClick.bind( this );\n\t\tthis.closeEntitiesSavedStates =\n\t\t\tthis.closeEntitiesSavedStates.bind( this );\n\n\t\tthis.state = {\n\t\t\tentitiesSavedStatesCallback: false,\n\t\t};\n\t}\n\n\tcreateOnClick( callback ) {\n\t\treturn ( ...args ) => {\n\t\t\tconst { hasNonPostEntityChanges, setEntitiesSavedStatesCallback } =\n\t\t\t\tthis.props;\n\t\t\t// If a post with non-post entities is published, but the user\n\t\t\t// elects to not save changes to the non-post entities, those\n\t\t\t// entities will still be dirty when the Publish button is clicked.\n\t\t\t// We also need to check that the `setEntitiesSavedStatesCallback`\n\t\t\t// prop was passed. See https://github.com/WordPress/gutenberg/pull/37383\n\t\t\tif ( hasNonPostEntityChanges && setEntitiesSavedStatesCallback ) {\n\t\t\t\t// The modal for multiple entity saving will open,\n\t\t\t\t// hold the callback for saving/publishing the post\n\t\t\t\t// so that we can call it if the post entity is checked.\n\t\t\t\tthis.setState( {\n\t\t\t\t\tentitiesSavedStatesCallback: () => callback( ...args ),\n\t\t\t\t} );\n\n\t\t\t\t// Open the save panel by setting its callback.\n\t\t\t\t// To set a function on the useState hook, we must set it\n\t\t\t\t// with another function (() => myFunction). Passing the\n\t\t\t\t// function on its own will cause an error when called.\n\t\t\t\tsetEntitiesSavedStatesCallback(\n\t\t\t\t\t() => this.closeEntitiesSavedStates\n\t\t\t\t);\n\t\t\t\treturn noop;\n\t\t\t}\n\n\t\t\treturn callback( ...args );\n\t\t};\n\t}\n\n\tcloseEntitiesSavedStates( savedEntities ) {\n\t\tconst { postType, postId } = this.props;\n\t\tconst { entitiesSavedStatesCallback } = this.state;\n\t\tthis.setState( { entitiesSavedStatesCallback: false }, () => {\n\t\t\tif (\n\t\t\t\tsavedEntities &&\n\t\t\t\tsavedEntities.some(\n\t\t\t\t\t( elt ) =>\n\t\t\t\t\t\telt.kind === 'postType' &&\n\t\t\t\t\t\telt.name === postType &&\n\t\t\t\t\t\telt.key === postId\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\t// The post entity was checked, call the held callback from `createOnClick`.\n\t\t\t\tentitiesSavedStatesCallback();\n\t\t\t}\n\t\t} );\n\t}\n\n\trender() {\n\t\tconst {\n\t\t\tforceIsDirty,\n\t\t\thasPublishAction,\n\t\t\tisBeingScheduled,\n\t\t\tisOpen,\n\t\t\tisPostSavingLocked,\n\t\t\tisPublishable,\n\t\t\tisPublished,\n\t\t\tisSaveable,\n\t\t\tisSaving,\n\t\t\tisAutoSaving,\n\t\t\tisToggle,\n\t\t\tsavePostStatus,\n\t\t\tonSubmit = noop,\n\t\t\tonToggle,\n\t\t\tvisibility,\n\t\t\thasNonPostEntityChanges,\n\t\t\tisSavingNonPostEntityChanges,\n\t\t\tpostStatus,\n\t\t\tpostStatusHasChanged,\n\t\t} = this.props;\n\n\t\tconst isButtonDisabled =\n\t\t\tisPostSavingLocked ||\n\t\t\t( ( isSaving ||\n\t\t\t\t! isSaveable ||\n\t\t\t\t( ! isPublishable && ! forceIsDirty ) ) &&\n\t\t\t\t( ! hasNonPostEntityChanges || isSavingNonPostEntityChanges ) );\n\n\t\tconst isToggleDisabled =\n\t\t\tisPostSavingLocked ||\n\t\t\t( ( isPublished ||\n\t\t\t\tisSaving ||\n\t\t\t\t! isSaveable ||\n\t\t\t\t( ! isPublishable && ! forceIsDirty ) ) &&\n\t\t\t\t( ! hasNonPostEntityChanges || isSavingNonPostEntityChanges ) );\n\n\t\t// If the new status has not changed explicitly, we derive it from\n\t\t// other factors, like having a publish action, etc.. We need to preserve\n\t\t// this because it affects when to show the pre and post publish panels.\n\t\t// If it has changed though explicitly, we need to respect that.\n\t\tlet publishStatus = 'publish';\n\t\tif ( postStatusHasChanged ) {\n\t\t\tpublishStatus = postStatus;\n\t\t} else if ( ! hasPublishAction ) {\n\t\t\tpublishStatus = 'pending';\n\t\t} else if ( visibility === 'private' ) {\n\t\t\tpublishStatus = 'private';\n\t\t} else if ( isBeingScheduled ) {\n\t\t\tpublishStatus = 'future';\n\t\t}\n\n\t\tconst onClickButton = () => {\n\t\t\tif ( isButtonDisabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tonSubmit();\n\t\t\tsavePostStatus( publishStatus );\n\t\t};\n\n\t\t// Callback to open the publish panel.\n\t\tconst onClickToggle = () => {\n\t\t\tif ( isToggleDisabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tonToggle();\n\t\t};\n\n\t\tconst buttonProps = {\n\t\t\t'aria-disabled': isButtonDisabled,\n\t\t\tclassName: 'editor-post-publish-button',\n\t\t\tisBusy: ! isAutoSaving && isSaving,\n\t\t\tvariant: 'primary',\n\t\t\tonClick: this.createOnClick( onClickButton ),\n\t\t\t'aria-haspopup': hasNonPostEntityChanges ? 'dialog' : undefined,\n\t\t};\n\n\t\tconst toggleProps = {\n\t\t\t'aria-disabled': isToggleDisabled,\n\t\t\t'aria-expanded': isOpen,\n\t\t\tclassName: 'editor-post-publish-panel__toggle',\n\t\t\tisBusy: isSaving && isPublished,\n\t\t\tvariant: 'primary',\n\t\t\tsize: 'compact',\n\t\t\tonClick: this.createOnClick( onClickToggle ),\n\t\t\t'aria-haspopup': hasNonPostEntityChanges ? 'dialog' : undefined,\n\t\t};\n\t\tconst componentProps = isToggle ? toggleProps : buttonProps;\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<Button\n\t\t\t\t\t{ ...componentProps }\n\t\t\t\t\tclassName={ `${ componentProps.className } editor-post-publish-button__button` }\n\t\t\t\t\tsize=\"compact\"\n\t\t\t\t>\n\t\t\t\t\t<PublishButtonLabel />\n\t\t\t\t</Button>\n\t\t\t</>\n\t\t);\n\t}\n}\n\n/**\n * Renders the publish button.\n */\nexport default compose( [\n\twithSelect( ( select ) => {\n\t\tconst {\n\t\t\tisSavingPost,\n\t\t\tisAutosavingPost,\n\t\t\tisEditedPostBeingScheduled,\n\t\t\tgetEditedPostVisibility,\n\t\t\tisCurrentPostPublished,\n\t\t\tisEditedPostSaveable,\n\t\t\tisEditedPostPublishable,\n\t\t\tisPostSavingLocked,\n\t\t\tgetCurrentPost,\n\t\t\tgetCurrentPostType,\n\t\t\tgetCurrentPostId,\n\t\t\thasNonPostEntityChanges,\n\t\t\tisSavingNonPostEntityChanges,\n\t\t\tgetEditedPostAttribute,\n\t\t\tgetPostEdits,\n\t\t} = select( editorStore );\n\t\treturn {\n\t\t\tisSaving: isSavingPost(),\n\t\t\tisAutoSaving: isAutosavingPost(),\n\t\t\tisBeingScheduled: isEditedPostBeingScheduled(),\n\t\t\tvisibility: getEditedPostVisibility(),\n\t\t\tisSaveable: isEditedPostSaveable(),\n\t\t\tisPostSavingLocked: isPostSavingLocked(),\n\t\t\tisPublishable: isEditedPostPublishable(),\n\t\t\tisPublished: isCurrentPostPublished(),\n\t\t\thasPublishAction:\n\t\t\t\tgetCurrentPost()._links?.[ 'wp:action-publish' ] ?? false,\n\t\t\tpostType: getCurrentPostType(),\n\t\t\tpostId: getCurrentPostId(),\n\t\t\tpostStatus: getEditedPostAttribute( 'status' ),\n\t\t\tpostStatusHasChanged: getPostEdits()?.status,\n\t\t\thasNonPostEntityChanges: hasNonPostEntityChanges(),\n\t\t\tisSavingNonPostEntityChanges: isSavingNonPostEntityChanges(),\n\t\t};\n\t} ),\n\twithDispatch( ( dispatch ) => {\n\t\tconst { editPost, savePost } = dispatch( editorStore );\n\t\treturn {\n\t\t\tsavePostStatus: ( status ) => {\n\t\t\t\teditPost( { status }, { undoIgnore: true } );\n\t\t\t\tsavePost();\n\t\t\t},\n\t\t};\n\t} ),\n] )( PostPublishButton );\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { Button } from '@wordpress/components';\nimport { useDispatch, useSelect } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport PublishButtonLabel from './label';\nimport { store as editorStore } from '../../store';\n\nconst noop = () => {};\n\nexport function PostPublishButton( {\n\tforceIsDirty,\n\tisOpen,\n\tisToggle,\n\tonSubmit = noop,\n\tonToggle,\n\tsetEntitiesSavedStatesCallback,\n} ) {\n\tconst {\n\t\thasPublishAction,\n\t\tisBeingScheduled,\n\t\tisPostSavingLocked,\n\t\tisPublishable,\n\t\tisPublished,\n\t\tisSaveable,\n\t\tisSaving,\n\t\tisAutoSaving,\n\t\tvisibility,\n\t\thasNonPostEntityChanges,\n\t\tisSavingNonPostEntityChanges,\n\t\tpostStatus,\n\t\tpostStatusHasChanged,\n\t\tpostType,\n\t\tpostId,\n\t} = useSelect( ( select ) => {\n\t\tconst store = select( editorStore );\n\t\treturn {\n\t\t\tisSaving: store.isSavingPost(),\n\t\t\tisAutoSaving: store.isAutosavingPost(),\n\t\t\tisBeingScheduled: store.isEditedPostBeingScheduled(),\n\t\t\tvisibility: store.getEditedPostVisibility(),\n\t\t\tisSaveable: store.isEditedPostSaveable(),\n\t\t\tisPostSavingLocked: store.isPostSavingLocked(),\n\t\t\tisPublishable: store.isEditedPostPublishable(),\n\t\t\tisPublished: store.isCurrentPostPublished(),\n\t\t\thasPublishAction:\n\t\t\t\tstore.getCurrentPost()._links?.[ 'wp:action-publish' ] ?? false,\n\t\t\tpostType: store.getCurrentPostType(),\n\t\t\tpostId: store.getCurrentPostId(),\n\t\t\tpostStatus: store.getEditedPostAttribute( 'status' ),\n\t\t\tpostStatusHasChanged: store.getPostEdits()?.status,\n\t\t\thasNonPostEntityChanges: store.hasNonPostEntityChanges(),\n\t\t\tisSavingNonPostEntityChanges: store.isSavingNonPostEntityChanges(),\n\t\t};\n\t}, [] );\n\n\tconst { editPost, savePost } = useDispatch( editorStore );\n\n\tconst savePostStatus = ( status ) => {\n\t\teditPost( { status }, { undoIgnore: true } );\n\t\tsavePost();\n\t};\n\n\tconst createOnClick =\n\t\t( callback ) =>\n\t\t( ...args ) => {\n\t\t\t// If a post with non-post entities is published, but the user\n\t\t\t// elects to not save changes to the non-post entities, those\n\t\t\t// entities will still be dirty when the Publish button is clicked.\n\t\t\t// We also need to check that the `setEntitiesSavedStatesCallback`\n\t\t\t// prop was passed. See https://github.com/WordPress/gutenberg/pull/37383\n\t\t\tif ( hasNonPostEntityChanges && setEntitiesSavedStatesCallback ) {\n\t\t\t\t// The modal for multiple entity saving will open. If the post\n\t\t\t\t// entity is checked when it closes, run the held callback.\n\t\t\t\tconst onClose = ( savedEntities ) => {\n\t\t\t\t\tif (\n\t\t\t\t\t\tsavedEntities &&\n\t\t\t\t\t\tsavedEntities.some(\n\t\t\t\t\t\t\t( elt ) =>\n\t\t\t\t\t\t\t\telt.kind === 'postType' &&\n\t\t\t\t\t\t\t\telt.name === postType &&\n\t\t\t\t\t\t\t\telt.key === postId\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tcallback( ...args );\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Open the save panel by setting its callback.\n\t\t\t\t// To set a function on the useState hook, we must set it\n\t\t\t\t// with another function (() => myFunction). Passing the\n\t\t\t\t// function on its own will cause an error when called.\n\t\t\t\tsetEntitiesSavedStatesCallback( () => onClose );\n\t\t\t\treturn noop;\n\t\t\t}\n\n\t\t\treturn callback( ...args );\n\t\t};\n\n\tconst isButtonDisabled =\n\t\tisPostSavingLocked ||\n\t\t( ( isSaving ||\n\t\t\t! isSaveable ||\n\t\t\t( ! isPublishable && ! forceIsDirty ) ) &&\n\t\t\t( ! hasNonPostEntityChanges || isSavingNonPostEntityChanges ) );\n\n\tconst isToggleDisabled =\n\t\tisPostSavingLocked ||\n\t\t( ( isPublished ||\n\t\t\tisSaving ||\n\t\t\t! isSaveable ||\n\t\t\t( ! isPublishable && ! forceIsDirty ) ) &&\n\t\t\t( ! hasNonPostEntityChanges || isSavingNonPostEntityChanges ) );\n\n\t// If the new status has not changed explicitly, we derive it from\n\t// other factors, like having a publish action, etc.. We need to preserve\n\t// this because it affects when to show the pre and post publish panels.\n\t// If it has changed though explicitly, we need to respect that.\n\tlet publishStatus = 'publish';\n\tif ( postStatusHasChanged ) {\n\t\tpublishStatus = postStatus;\n\t} else if ( ! hasPublishAction ) {\n\t\tpublishStatus = 'pending';\n\t} else if ( visibility === 'private' ) {\n\t\tpublishStatus = 'private';\n\t} else if ( isBeingScheduled ) {\n\t\tpublishStatus = 'future';\n\t}\n\n\tconst onClickButton = () => {\n\t\tif ( isButtonDisabled ) {\n\t\t\treturn;\n\t\t}\n\t\tonSubmit();\n\t\tsavePostStatus( publishStatus );\n\t};\n\n\t// Callback to open the publish panel.\n\tconst onClickToggle = () => {\n\t\tif ( isToggleDisabled ) {\n\t\t\treturn;\n\t\t}\n\t\tonToggle();\n\t};\n\n\tconst buttonProps = {\n\t\t'aria-disabled': isButtonDisabled,\n\t\tclassName: 'editor-post-publish-button',\n\t\tisBusy: ! isAutoSaving && isSaving,\n\t\tvariant: 'primary',\n\t\tonClick: createOnClick( onClickButton ),\n\t\t'aria-haspopup': hasNonPostEntityChanges ? 'dialog' : undefined,\n\t};\n\n\tconst toggleProps = {\n\t\t'aria-disabled': isToggleDisabled,\n\t\t'aria-expanded': isOpen,\n\t\tclassName: 'editor-post-publish-panel__toggle',\n\t\tisBusy: isSaving && isPublished,\n\t\tvariant: 'primary',\n\t\tsize: 'compact',\n\t\tonClick: createOnClick( onClickToggle ),\n\t\t'aria-haspopup': hasNonPostEntityChanges ? 'dialog' : undefined,\n\t};\n\tconst componentProps = isToggle ? toggleProps : buttonProps;\n\treturn (\n\t\t<Button\n\t\t\t{ ...componentProps }\n\t\t\tclassName={ `${ componentProps.className } editor-post-publish-button__button` }\n\t\t\tsize=\"compact\"\n\t\t>\n\t\t\t<PublishButtonLabel />\n\t\t</Button>\n\t);\n}\n\n/**\n * Renders the publish button.\n */\nexport default PostPublishButton;\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,5 @@
1
1
  // packages/editor/src/components/post-revisions-preview/block-diff.js
2
- import { diffArrays } from "diff/lib/diff/array";
3
- import { diffWords } from "diff/lib/diff/word";
2
+ import { diffArrays, diffWordsWithSpace } from "diff";
4
3
  import { parse as grammarParse } from "@wordpress/block-serialization-default-parser";
5
4
  import {
6
5
  privateApis as blocksPrivateApis,
@@ -16,6 +15,9 @@ import {
16
15
  import { __, _n, sprintf } from "@wordpress/i18n";
17
16
  import { unlock } from "../../lock-unlock.mjs";
18
17
  var { parseRawBlock } = unlock(blocksPrivateApis);
18
+ function isWhitespaceRawBlock(rawBlock) {
19
+ return rawBlock.blockName === null && (!rawBlock.innerHTML || !rawBlock.innerHTML.trim());
20
+ }
19
21
  function stringifyValue(value) {
20
22
  if (value === null || value === void 0) {
21
23
  return "";
@@ -135,14 +137,19 @@ function pairSimilarBlocks(blocks) {
135
137
  };
136
138
  const lo = Math.min(rem.index, bestMatch.index);
137
139
  const hi = Math.max(rem.index, bestMatch.index);
138
- let hasAddedBetween = false;
140
+ let crossesCurrentContent = false;
139
141
  for (let i = lo + 1; i < hi; i++) {
140
- if (blocks[i].__revisionDiffStatus?.status === "added" && !pairedAdded.has(i)) {
141
- hasAddedBetween = true;
142
+ const status = blocks[i].__revisionDiffStatus?.status;
143
+ if (status === void 0) {
144
+ crossesCurrentContent = true;
145
+ break;
146
+ }
147
+ if (status === "added" && !pairedAdded.has(i)) {
148
+ crossesCurrentContent = true;
142
149
  break;
143
150
  }
144
151
  }
145
- if (hasAddedBetween) {
152
+ if (crossesCurrentContent) {
146
153
  modifications.set(bestMatch.index, modifiedBlock);
147
154
  pairedRemoved.add(rem.index);
148
155
  } else {
@@ -162,6 +169,8 @@ function pairSimilarBlocks(blocks) {
162
169
  }).filter(Boolean);
163
170
  }
164
171
  function diffRawBlocks(currentRaw, previousRaw) {
172
+ currentRaw = currentRaw.filter((b) => !isWhitespaceRawBlock(b));
173
+ previousRaw = previousRaw.filter((b) => !isWhitespaceRawBlock(b));
165
174
  const createBlockSignature = (rawBlock) => JSON.stringify({
166
175
  name: rawBlock.blockName,
167
176
  attrs: rawBlock.attrs,
@@ -301,7 +310,7 @@ function describeFormatChange(currentFormats, previousFormats, currIdx, prevIdx)
301
310
  function applyRichTextDiff(currentRichText, previousRichText) {
302
311
  const currentText = currentRichText.toPlainText();
303
312
  const previousText = previousRichText.toPlainText();
304
- const textDiff = diffWords(previousText, currentText);
313
+ const textDiff = diffWordsWithSpace(previousText, currentText);
305
314
  let result = create({ text: "" });
306
315
  let currentIdx = 0;
307
316
  let previousIdx = 0;
@@ -421,7 +430,10 @@ function applyDiffToBlock(currentBlock, previousBlock, diffStatus) {
421
430
  previousBlock.attributes[attrName]
422
431
  );
423
432
  if (currStr !== prevStr) {
424
- changedAttributes[attrName] = diffWords(prevStr, currStr);
433
+ changedAttributes[attrName] = diffWordsWithSpace(
434
+ prevStr,
435
+ currStr
436
+ );
425
437
  }
426
438
  }
427
439
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/post-revisions-preview/block-diff.js"],
4
- "sourcesContent": ["/**\n * External dependencies\n */\nimport { diffArrays } from 'diff/lib/diff/array';\nimport { diffWords } from 'diff/lib/diff/word';\n\n/**\n * WordPress dependencies\n */\nimport { parse as grammarParse } from '@wordpress/block-serialization-default-parser';\nimport {\n\tprivateApis as blocksPrivateApis,\n\tgetBlockType,\n} from '@wordpress/blocks';\nimport {\n\tRichTextData,\n\tcreate,\n\tslice,\n\tconcat,\n\tapplyFormat,\n} from '@wordpress/rich-text';\nimport { __, _n, sprintf } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\n\nconst { parseRawBlock } = unlock( blocksPrivateApis );\n\n/**\n * Safely stringifies a value for display and comparison.\n *\n * @param {*} value The value to stringify.\n * @return {string} The stringified value.\n */\nfunction stringifyValue( value ) {\n\tif ( value === null || value === undefined ) {\n\t\treturn '';\n\t}\n\tif ( typeof value === 'object' ) {\n\t\treturn JSON.stringify( value, null, 2 );\n\t}\n\treturn String( value );\n}\n\n/**\n * Calculate text similarity using word-set overlap.\n *\n * Uses a variant of the Jaccard index (https://en.wikipedia.org/wiki/Jaccard_index)\n * called the overlap coefficient (https://en.wikipedia.org/wiki/Overlap_coefficient)\n * where we divide by the larger set size rather than the union. This ensures that\n * a small edit to a long paragraph scores high \u2014 the few changed words don't\n * dilute the score.\n *\n * This replaces the previous diffWords-based similarity which was O(n*m) per pair.\n * The word-set approach is O(n) where n is the number of words.\n *\n * Words are extracted using Intl.Segmenter for proper multilingual support\n * (CJK, Thai, etc.) rather than splitting on whitespace.\n *\n * @param {string} text1 First text to compare.\n * @param {string} text2 Second text to compare.\n * @return {number} Similarity score between 0 and 1.\n */\nfunction textSimilarity( text1, text2 ) {\n\tif ( ! text1 && ! text2 ) {\n\t\treturn 1;\n\t}\n\tif ( ! text1 || ! text2 ) {\n\t\treturn 0;\n\t}\n\n\tconst segmenter = new Intl.Segmenter( undefined, {\n\t\tgranularity: 'word',\n\t} );\n\t// Safari's Intl.Segmenter returns isWordLike: false for numeric segments,\n\t// so fall back to a Unicode-aware regex for letters and numbers.\n\tconst wordLikeRegex = /[\\p{L}\\p{N}]/u;\n\tconst getWords = ( text ) => {\n\t\tconst words = [];\n\t\tfor ( const { segment, isWordLike } of segmenter.segment( text ) ) {\n\t\t\tif ( isWordLike || wordLikeRegex.test( segment ) ) {\n\t\t\t\twords.push( segment );\n\t\t\t}\n\t\t}\n\t\treturn words;\n\t};\n\tconst words1 = getWords( text1 );\n\tconst words2 = getWords( text2 );\n\n\tif ( words1.length === 0 && words2.length === 0 ) {\n\t\treturn 1;\n\t}\n\n\tconst set1 = new Set( words1 );\n\tlet intersection = 0;\n\tfor ( const word of words2 ) {\n\t\tif ( set1.has( word ) ) {\n\t\t\tintersection++;\n\t\t}\n\t}\n\n\tconst total = Math.max( words1.length, words2.length );\n\treturn total > 0 ? intersection / total : 0;\n}\n\n/**\n * Post-process diff result to pair similar removed/added blocks as modifications.\n *\n * After LCS diffing, a block whose content changed appears as a separate \"removed\"\n * and \"added\" entry (since the full block signature differs). This function detects\n * such pairs and merges them into a single \"modified\" block with inline diff.\n *\n * Two pairing strategies are used:\n * 1. When exactly one block of a given type was removed and one was added,\n * they are paired directly \u2014 no ambiguity, no similarity check needed.\n * 2. When multiple candidates exist, textSimilarity (overlap coefficient) is\n * used to find the best match. Blocks must share at least 50% of their\n * words to be paired, preventing unrelated paragraphs from being merged.\n *\n * @param {Array} blocks Raw blocks with diff status.\n * @return {Array} Blocks with similar pairs converted to modifications.\n */\nfunction pairSimilarBlocks( blocks ) {\n\tconst removed = [];\n\tconst added = [];\n\n\t// Separate blocks by status, tracking original indices.\n\tblocks.forEach( ( block, index ) => {\n\t\tconst status = block.__revisionDiffStatus?.status;\n\t\tif ( status === 'removed' ) {\n\t\t\tremoved.push( { block, index } );\n\t\t} else if ( status === 'added' ) {\n\t\t\tadded.push( { block, index } );\n\t\t}\n\t} );\n\n\t// If no removed or no added, nothing to pair.\n\tif ( removed.length === 0 || added.length === 0 ) {\n\t\treturn blocks;\n\t}\n\n\tconst pairedRemoved = new Set(); // Indices of removed blocks filtered out.\n\tconst pairedAdded = new Set(); // Indices of added blocks filtered out.\n\tconst modifications = new Map(); // Index \u2192 modified block.\n\tconst SIMILARITY_THRESHOLD = 0.5;\n\n\t// Group candidates by block name for efficient lookup.\n\tconst addedByName = new Map();\n\tfor ( const add of added ) {\n\t\tconst name = add.block.blockName;\n\t\tif ( ! addedByName.has( name ) ) {\n\t\t\taddedByName.set( name, [] );\n\t\t}\n\t\taddedByName.get( name ).push( add );\n\t}\n\tconst removedByName = new Map();\n\tfor ( const rem of removed ) {\n\t\tconst name = rem.block.blockName;\n\t\tif ( ! removedByName.has( name ) ) {\n\t\t\tremovedByName.set( name, [] );\n\t\t}\n\t\tremovedByName.get( name ).push( rem );\n\t}\n\n\t// For each removed block, find best matching added block.\n\t// Track the highest added index paired so far \u2014 new pairings must\n\t// not go backwards, or the removed/added text order would break.\n\tlet maxPairedAddedIndex = -1;\n\n\tfor ( const rem of removed ) {\n\t\tconst candidates = addedByName.get( rem.block.blockName ) || [];\n\t\tconst sameNameRemoved = removedByName.get( rem.block.blockName ) || [];\n\t\tconst unpaired = candidates.filter(\n\t\t\t( add ) =>\n\t\t\t\t! modifications.has( add.index ) &&\n\t\t\t\tadd.index > maxPairedAddedIndex\n\t\t);\n\n\t\tif ( unpaired.length === 0 ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet bestMatch = null;\n\n\t\t// If there's exactly one removed and one added of this type,\n\t\t// pair them directly \u2014 no ambiguity, no similarity check needed.\n\t\tif ( sameNameRemoved.length === 1 && unpaired.length === 1 ) {\n\t\t\tconst add = unpaired[ 0 ];\n\t\t\tconst attrsMatch =\n\t\t\t\tJSON.stringify( rem.block.attrs ) ===\n\t\t\t\tJSON.stringify( add.block.attrs );\n\t\t\t// Only skip pairing if both content and attrs are identical\n\t\t\t// (position swap, not a modification).\n\t\t\tconst contentMatch =\n\t\t\t\t( rem.block.innerHTML || '' ) === ( add.block.innerHTML || '' );\n\t\t\tif ( ! contentMatch || ! attrsMatch ) {\n\t\t\t\tbestMatch = add;\n\t\t\t}\n\t\t} else {\n\t\t\t// Multiple candidates \u2014 use similarity to find best match.\n\t\t\tlet bestScore = 0;\n\t\t\tfor ( const add of unpaired ) {\n\t\t\t\tconst score = textSimilarity(\n\t\t\t\t\trem.block.innerHTML || '',\n\t\t\t\t\tadd.block.innerHTML || ''\n\t\t\t\t);\n\t\t\t\t// Skip identical blocks (score=1 with same attrs) \u2014 those\n\t\t\t\t// are position swaps, not modifications. They should show\n\t\t\t\t// as separate removed + added, not as a no-op \"modified\".\n\t\t\t\tconst attrsMatch =\n\t\t\t\t\tJSON.stringify( rem.block.attrs ) ===\n\t\t\t\t\tJSON.stringify( add.block.attrs );\n\t\t\t\tif (\n\t\t\t\t\tscore > bestScore &&\n\t\t\t\t\tscore > SIMILARITY_THRESHOLD &&\n\t\t\t\t\t( score < 1 || ! attrsMatch )\n\t\t\t\t) {\n\t\t\t\t\tbestScore = score;\n\t\t\t\t\tbestMatch = add;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( bestMatch ) {\n\t\t\tmaxPairedAddedIndex = bestMatch.index;\n\n\t\t\tconst modifiedBlock = {\n\t\t\t\t...bestMatch.block,\n\t\t\t\t__revisionDiffStatus: { status: 'modified' },\n\t\t\t\t__previousRawBlock: rem.block,\n\t\t\t};\n\n\t\t\t// Decide where to place the modified block by checking\n\t\t\t// what's between the removed and added positions.\n\t\t\t// If there are unpaired added blocks between them,\n\t\t\t// placing at the removed position would put the modified\n\t\t\t// block before content that comes before it in the\n\t\t\t// current revision \u2014 so use the added position.\n\t\t\t// Otherwise, use the removed position to keep the\n\t\t\t// previous revision's order intact.\n\t\t\tconst lo = Math.min( rem.index, bestMatch.index );\n\t\t\tconst hi = Math.max( rem.index, bestMatch.index );\n\t\t\tlet hasAddedBetween = false;\n\t\t\tfor ( let i = lo + 1; i < hi; i++ ) {\n\t\t\t\tif (\n\t\t\t\t\tblocks[ i ].__revisionDiffStatus?.status === 'added' &&\n\t\t\t\t\t! pairedAdded.has( i )\n\t\t\t\t) {\n\t\t\t\t\thasAddedBetween = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( hasAddedBetween ) {\n\t\t\t\t// Use the added position \u2014 don't jump before\n\t\t\t\t// current-revision content.\n\t\t\t\tmodifications.set( bestMatch.index, modifiedBlock );\n\t\t\t\tpairedRemoved.add( rem.index );\n\t\t\t} else {\n\t\t\t\t// Use the removed position \u2014 keep the previous\n\t\t\t\t// revision's reading order.\n\t\t\t\tmodifications.set( rem.index, modifiedBlock );\n\t\t\t\tpairedAdded.add( bestMatch.index );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Rebuild result: replace modification targets, filter out\n\t// their paired counterparts.\n\treturn blocks\n\t\t.map( ( block, index ) => {\n\t\t\tif ( pairedRemoved.has( index ) || pairedAdded.has( index ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif ( modifications.has( index ) ) {\n\t\t\t\treturn modifications.get( index );\n\t\t\t}\n\t\t\treturn block;\n\t\t} )\n\t\t.filter( Boolean );\n}\n\n/**\n * Diff raw block arrays using LCS, recursively handling innerBlocks.\n * Detects modifications when exactly 1 block is removed and 1 is added\n * with the same blockName (1:1 replacement = modification).\n *\n * @param {Array} currentRaw Current revision's raw blocks.\n * @param {Array} previousRaw Previous revision's raw blocks.\n * @return {Array} Merged raw blocks with diff status injected.\n */\nfunction diffRawBlocks( currentRaw, previousRaw ) {\n\tconst createBlockSignature = ( rawBlock ) =>\n\t\tJSON.stringify( {\n\t\t\tname: rawBlock.blockName,\n\t\t\tattrs: rawBlock.attrs,\n\t\t\t// Use innerContent filtered to non-null and non-whitespace-only strings.\n\t\t\t// This excludes whitespace between inner blocks which changes based on count.\n\t\t\thtml: ( rawBlock.innerContent || [] ).filter(\n\t\t\t\t( c ) => c !== null && c.trim() !== ''\n\t\t\t),\n\t\t} );\n\tconst currentSigs = currentRaw.map( createBlockSignature );\n\tconst previousSigs = previousRaw.map( createBlockSignature );\n\n\tconst diff = diffArrays( previousSigs, currentSigs );\n\n\tconst result = [];\n\tlet currIdx = 0;\n\tlet prevIdx = 0;\n\n\tfor ( const part of diff ) {\n\t\tif ( part.added ) {\n\t\t\tfor ( let i = 0; i < part.count; i++ ) {\n\t\t\t\tresult.push( {\n\t\t\t\t\t...currentRaw[ currIdx++ ],\n\t\t\t\t\t__revisionDiffStatus: { status: 'added' },\n\t\t\t\t} );\n\t\t\t}\n\t\t} else if ( part.removed ) {\n\t\t\tfor ( let i = 0; i < part.count; i++ ) {\n\t\t\t\tresult.push( {\n\t\t\t\t\t...previousRaw[ prevIdx++ ],\n\t\t\t\t\t__revisionDiffStatus: { status: 'removed' },\n\t\t\t\t} );\n\t\t\t}\n\t\t} else {\n\t\t\t// Matched blocks - recursively diff their innerBlocks.\n\t\t\tfor ( let i = 0; i < part.count; i++ ) {\n\t\t\t\tconst currBlock = currentRaw[ currIdx++ ];\n\t\t\t\tconst prevBlock = previousRaw[ prevIdx++ ];\n\n\t\t\t\t// Recursively diff inner blocks.\n\t\t\t\tconst diffedInnerBlocks = diffRawBlocks(\n\t\t\t\t\tcurrBlock.innerBlocks || [],\n\t\t\t\t\tprevBlock.innerBlocks || []\n\t\t\t\t);\n\n\t\t\t\tresult.push( {\n\t\t\t\t\t...currBlock,\n\t\t\t\t\tinnerBlocks: diffedInnerBlocks,\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Post-process to pair similar removed/added blocks as modifications.\n\treturn pairSimilarBlocks( result );\n}\n\n/**\n * Check if formatting has changed at specific character indices.\n *\n * @param {Array} currentFormats Current formats array.\n * @param {Array} previousFormats Previous formats array.\n * @param {number} currentIndex Character index in current.\n * @param {number} previousIndex Character index in previous.\n * @return {boolean} True if formatting changed at these indices.\n */\nfunction hasFormatChangedAtIndex(\n\tcurrentFormats,\n\tpreviousFormats,\n\tcurrentIndex,\n\tpreviousIndex\n) {\n\tconst currFmts = currentFormats[ currentIndex ] || [];\n\tconst prevFmts = previousFormats[ previousIndex ] || [];\n\n\tif ( currFmts.length !== prevFmts.length ) {\n\t\treturn true;\n\t}\n\n\t// Check if each format in current exists in previous\n\tfor ( const fmt of currFmts ) {\n\t\tconst match = prevFmts.find(\n\t\t\t( pf ) =>\n\t\t\t\tpf.type === fmt.type &&\n\t\t\t\tJSON.stringify( pf.attributes ) ===\n\t\t\t\t\tJSON.stringify( fmt.attributes )\n\t\t);\n\t\tif ( ! match ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Analyze what formatting changed between two character positions.\n * Returns both the change type (for styling) and a description (for tooltip).\n *\n * @param {Array} currentFormats Current formats array.\n * @param {Array} previousFormats Previous formats array.\n * @param {number} currIdx Character index in current.\n * @param {number} prevIdx Character index in previous.\n * @return {{ type: 'added'|'removed'|'changed', description: string }} Change info.\n */\nfunction describeFormatChange(\n\tcurrentFormats,\n\tpreviousFormats,\n\tcurrIdx,\n\tprevIdx\n) {\n\tconst currFmts = currentFormats[ currIdx ] || [];\n\tconst prevFmts = previousFormats[ prevIdx ] || [];\n\n\tlet addedCount = 0;\n\tlet removedCount = 0;\n\tlet changedCount = 0;\n\n\t// Find added formats and attribute changes\n\tfor ( const fmt of currFmts ) {\n\t\tconst match = prevFmts.find( ( pf ) => pf.type === fmt.type );\n\t\tif ( ! match ) {\n\t\t\taddedCount++;\n\t\t} else if (\n\t\t\tJSON.stringify( fmt.attributes ) !==\n\t\t\tJSON.stringify( match.attributes )\n\t\t) {\n\t\t\tchangedCount++;\n\t\t}\n\t}\n\n\t// Find removed formats\n\tfor ( const fmt of prevFmts ) {\n\t\tconst match = currFmts.find( ( cf ) => cf.type === fmt.type );\n\t\tif ( ! match ) {\n\t\t\tremovedCount++;\n\t\t}\n\t}\n\n\t// Determine primary change type for styling\n\tif ( addedCount > 0 && removedCount === 0 && changedCount === 0 ) {\n\t\treturn {\n\t\t\ttype: 'added',\n\t\t\tdescription: sprintf(\n\t\t\t\t/* translators: %d: number of formats added */\n\t\t\t\t_n( '%d format added', '%d formats added', addedCount ),\n\t\t\t\taddedCount\n\t\t\t),\n\t\t};\n\t}\n\tif ( removedCount > 0 && addedCount === 0 && changedCount === 0 ) {\n\t\treturn {\n\t\t\ttype: 'removed',\n\t\t\tdescription: sprintf(\n\t\t\t\t/* translators: %d: number of formats removed */\n\t\t\t\t_n( '%d format removed', '%d formats removed', removedCount ),\n\t\t\t\tremovedCount\n\t\t\t),\n\t\t};\n\t}\n\n\t// Mixed or attribute-only changes\n\tconst parts = [];\n\tif ( addedCount > 0 ) {\n\t\tparts.push(\n\t\t\tsprintf(\n\t\t\t\t/* translators: %d: number of formats added */\n\t\t\t\t_n( '%d format added', '%d formats added', addedCount ),\n\t\t\t\taddedCount\n\t\t\t)\n\t\t);\n\t}\n\tif ( removedCount > 0 ) {\n\t\tparts.push(\n\t\t\tsprintf(\n\t\t\t\t/* translators: %d: number of formats removed */\n\t\t\t\t_n( '%d format removed', '%d formats removed', removedCount ),\n\t\t\t\tremovedCount\n\t\t\t)\n\t\t);\n\t}\n\tif ( changedCount > 0 ) {\n\t\tparts.push(\n\t\t\tsprintf(\n\t\t\t\t/* translators: %d: number of formats changed */\n\t\t\t\t_n( '%d format changed', '%d formats changed', changedCount ),\n\t\t\t\tchangedCount\n\t\t\t)\n\t\t);\n\t}\n\treturn {\n\t\ttype: 'changed',\n\t\tdescription: parts.join( ', ' ) || __( 'Formatting changed' ),\n\t};\n}\n\n/**\n * Apply inline diff formatting comparing two RichTextData values.\n * - Text changes: apply revision/diff-removed and revision/diff-added formats\n * - Format-only changes (text unchanged): apply revision/diff-format-changed format\n *\n * @param {RichTextData} currentRichText Current revision's rich text.\n * @param {RichTextData} previousRichText Previous revision's rich text.\n * @return {RichTextData} New rich text with diff formatting applied.\n */\nfunction applyRichTextDiff( currentRichText, previousRichText ) {\n\tconst currentText = currentRichText.toPlainText();\n\tconst previousText = previousRichText.toPlainText();\n\n\t// Diff the plain text (words for cleaner output)\n\tconst textDiff = diffWords( previousText, currentText );\n\n\tlet result = create( { text: '' } );\n\tlet currentIdx = 0;\n\tlet previousIdx = 0;\n\n\tfor ( const part of textDiff ) {\n\t\tif ( part.removed ) {\n\t\t\t// Text deleted - slice from PREVIOUS, apply <del>\n\t\t\tconst removedSlice = slice(\n\t\t\t\tpreviousRichText,\n\t\t\t\tpreviousIdx,\n\t\t\t\tpreviousIdx + part.value.length\n\t\t\t);\n\t\t\tconst formatted = applyFormat(\n\t\t\t\tremovedSlice,\n\t\t\t\t{\n\t\t\t\t\ttype: 'revision/diff-removed',\n\t\t\t\t\tattributes: { title: __( 'Removed' ) },\n\t\t\t\t},\n\t\t\t\t0,\n\t\t\t\tpart.value.length\n\t\t\t);\n\t\t\tresult = concat( result, formatted );\n\t\t\tpreviousIdx += part.value.length;\n\t\t} else if ( part.added ) {\n\t\t\t// Text added - slice from CURRENT, apply <ins>\n\t\t\tconst addedSlice = slice(\n\t\t\t\tcurrentRichText,\n\t\t\t\tcurrentIdx,\n\t\t\t\tcurrentIdx + part.value.length\n\t\t\t);\n\t\t\tconst formatted = applyFormat(\n\t\t\t\taddedSlice,\n\t\t\t\t{\n\t\t\t\t\ttype: 'revision/diff-added',\n\t\t\t\t\tattributes: { title: __( 'Added' ) },\n\t\t\t\t},\n\t\t\t\t0,\n\t\t\t\tpart.value.length\n\t\t\t);\n\t\t\tresult = concat( result, formatted );\n\t\t\tcurrentIdx += part.value.length;\n\t\t} else {\n\t\t\t// Text unchanged - check formatting at each character position.\n\t\t\t// Only apply <mark> to specific ranges where formatting differs.\n\t\t\tconst currentFormats = currentRichText.formats || [];\n\t\t\tconst previousFormats = previousRichText.formats || [];\n\t\t\tconst len = part.value.length;\n\n\t\t\t// Helper to check format change at offset within this unchanged part.\n\t\t\tconst checkFormatChanged = ( offset ) =>\n\t\t\t\thasFormatChangedAtIndex(\n\t\t\t\t\tcurrentFormats,\n\t\t\t\t\tpreviousFormats,\n\t\t\t\t\tcurrentIdx + offset,\n\t\t\t\t\tpreviousIdx + offset\n\t\t\t\t);\n\n\t\t\t// Find ranges of characters grouped by whether format changed.\n\t\t\tlet rangeStart = 0;\n\t\t\tlet rangeFormatChanged = checkFormatChanged( 0 );\n\n\t\t\tfor ( let i = 1; i <= len; i++ ) {\n\t\t\t\tconst formatChanged = i < len && checkFormatChanged( i );\n\n\t\t\t\t// When format-changed status changes or we reach the end, emit range.\n\t\t\t\tif ( i === len || formatChanged !== rangeFormatChanged ) {\n\t\t\t\t\tconst rangeSlice = slice(\n\t\t\t\t\t\tcurrentRichText,\n\t\t\t\t\t\tcurrentIdx + rangeStart,\n\t\t\t\t\t\tcurrentIdx + i\n\t\t\t\t\t);\n\n\t\t\t\t\tif ( rangeFormatChanged ) {\n\t\t\t\t\t\t// Get type and description of what changed\n\t\t\t\t\t\tconst { type, description } = describeFormatChange(\n\t\t\t\t\t\t\tcurrentFormats,\n\t\t\t\t\t\t\tpreviousFormats,\n\t\t\t\t\t\t\tcurrentIdx + rangeStart,\n\t\t\t\t\t\t\tpreviousIdx + rangeStart\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// Map change type to format type for styling\n\t\t\t\t\t\tconst formatType = {\n\t\t\t\t\t\t\tadded: 'revision/diff-format-added',\n\t\t\t\t\t\t\tremoved: 'revision/diff-format-removed',\n\t\t\t\t\t\t\tchanged: 'revision/diff-format-changed',\n\t\t\t\t\t\t}[ type ];\n\n\t\t\t\t\t\tconst marked = applyFormat(\n\t\t\t\t\t\t\trangeSlice,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: formatType,\n\t\t\t\t\t\t\t\tattributes: { title: description },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\ti - rangeStart\n\t\t\t\t\t\t);\n\t\t\t\t\t\tresult = concat( result, marked );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = concat( result, rangeSlice );\n\t\t\t\t\t}\n\n\t\t\t\t\trangeStart = i;\n\t\t\t\t\trangeFormatChanged = formatChanged;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcurrentIdx += part.value.length;\n\t\t\tpreviousIdx += part.value.length;\n\t\t}\n\t}\n\n\treturn new RichTextData( result );\n}\n\n/**\n * Apply diffs to a modified block's attributes.\n * - Rich-text attributes: applies inline diff formatting (ins/del marks).\n * - Other attributes: computes word-level diffs for the sidebar panel.\n *\n * @param {Object} currentBlock Current parsed block.\n * @param {Object} previousBlock Previous parsed block.\n * @param {Object} diffStatus The __revisionDiffStatus object to attach changedAttributes to.\n */\nfunction applyDiffToBlock( currentBlock, previousBlock, diffStatus ) {\n\tconst blockType = getBlockType( currentBlock.name );\n\tif ( ! blockType ) {\n\t\treturn;\n\t}\n\n\tconst changedAttributes = {};\n\n\tfor ( const [ attrName, attrDef ] of Object.entries(\n\t\tblockType.attributes\n\t) ) {\n\t\tif ( attrDef.source === 'rich-text' ) {\n\t\t\tconst currentRichText = currentBlock.attributes[ attrName ];\n\t\t\tconst previousRichText = previousBlock.attributes[ attrName ];\n\t\t\tif (\n\t\t\t\tcurrentRichText instanceof RichTextData &&\n\t\t\t\tpreviousRichText instanceof RichTextData\n\t\t\t) {\n\t\t\t\tcurrentBlock.attributes[ attrName ] = applyRichTextDiff(\n\t\t\t\t\tcurrentRichText,\n\t\t\t\t\tpreviousRichText\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tconst currStr = stringifyValue(\n\t\t\t\tcurrentBlock.attributes[ attrName ]\n\t\t\t);\n\t\t\tconst prevStr = stringifyValue(\n\t\t\t\tpreviousBlock.attributes[ attrName ]\n\t\t\t);\n\t\t\tif ( currStr !== prevStr ) {\n\t\t\t\tchangedAttributes[ attrName ] = diffWords( prevStr, currStr );\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( Object.keys( changedAttributes ).length > 0 ) {\n\t\tdiffStatus.changedAttributes = changedAttributes;\n\t}\n}\n\n/**\n * Recursively apply diff status and rich text diff to blocks in the tree.\n * Copies __revisionDiffStatus from raw blocks to parsed blocks and applies\n * rich text diffs to modified blocks.\n *\n * @param {Object} parsedBlock Parsed block (with inner blocks).\n * @param {Object} rawBlock Raw block (with __revisionDiffStatus and __previousRawBlock).\n */\nfunction applyDiffRecursively( parsedBlock, rawBlock ) {\n\t// Copy diff status from raw block to parsed block.\n\tif ( rawBlock.__revisionDiffStatus ) {\n\t\t// Apply diffs if this block is modified and has a previous raw block.\n\t\tif (\n\t\t\trawBlock.__revisionDiffStatus.status === 'modified' &&\n\t\t\trawBlock.__previousRawBlock\n\t\t) {\n\t\t\tconst previousParsed = parseRawBlock( rawBlock.__previousRawBlock );\n\t\t\tif ( previousParsed ) {\n\t\t\t\tapplyDiffToBlock(\n\t\t\t\t\tparsedBlock,\n\t\t\t\t\tpreviousParsed,\n\t\t\t\t\trawBlock.__revisionDiffStatus\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tparsedBlock.__revisionDiffStatus = rawBlock.__revisionDiffStatus;\n\t\t// Also store in attributes so it survives block-editor store normalization.\n\t\tparsedBlock.attributes.__revisionDiffStatus =\n\t\t\trawBlock.__revisionDiffStatus;\n\t}\n\n\t// Recursively process inner blocks.\n\tif ( parsedBlock.innerBlocks && rawBlock.innerBlocks ) {\n\t\tfor ( let i = 0; i < parsedBlock.innerBlocks.length; i++ ) {\n\t\t\tconst parsedInner = parsedBlock.innerBlocks[ i ];\n\t\t\tconst rawInner = rawBlock.innerBlocks[ i ];\n\t\t\tif ( parsedInner && rawInner ) {\n\t\t\t\tapplyDiffRecursively( parsedInner, rawInner );\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Diff two revision contents at the grammar level.\n *\n * @param {string} currentContent Current revision's raw content.\n * @param {string} previousContent Previous revision's raw content.\n * @return {Array} Array of parsed blocks with diff status attributes.\n */\nexport function diffRevisionContent( currentContent, previousContent ) {\n\t// Grammar parse both contents.\n\tconst currentRaw = grammarParse( currentContent || '' );\n\tconst previousRaw = grammarParse( previousContent || '' );\n\n\t// Diff the raw block arrays.\n\tconst mergedRaw = diffRawBlocks( currentRaw, previousRaw );\n\n\t// Parse each raw block and apply diff status.\n\treturn mergedRaw\n\t\t.map( ( rawBlock ) => {\n\t\t\tconst parsed = parseRawBlock( rawBlock );\n\t\t\tif ( parsed ) {\n\t\t\t\tapplyDiffRecursively( parsed, rawBlock );\n\t\t\t}\n\t\t\treturn parsed;\n\t\t} )\n\t\t.filter( Boolean );\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * External dependencies\n */\n/*\n * `diffWordsWithSpace` preserves the v4-style per-word output. v6+\n * stopped treating whitespace as a token in `diffWords`, which coalesces\n * adjacent word changes into a single removed/added pair.\n */\nimport { diffArrays, diffWordsWithSpace } from 'diff';\n\n/**\n * WordPress dependencies\n */\nimport { parse as grammarParse } from '@wordpress/block-serialization-default-parser';\nimport {\n\tprivateApis as blocksPrivateApis,\n\tgetBlockType,\n} from '@wordpress/blocks';\nimport {\n\tRichTextData,\n\tcreate,\n\tslice,\n\tconcat,\n\tapplyFormat,\n} from '@wordpress/rich-text';\nimport { __, _n, sprintf } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\n\nconst { parseRawBlock } = unlock( blocksPrivateApis );\n\n/**\n * Whether a grammar-parsed raw block is a whitespace-only freeform pseudo-block\n * (the `\\n\\n` between block markers, etc). These are stripped from both arrays\n * before LCS to keep the matching pivot stable: under `diff` v6's tie-breaker,\n * a whitespace block could otherwise be selected as the LCS anchor in\n * `[paragraph, whitespace, paragraph]` swaps, mis-pairing the surrounding\n * paragraphs in `pairSimilarBlocks`. Whitespace pseudo-blocks don't render\n * anyway (`parseRawBlock` returns undefined for them), so dropping them\n * before the diff has no user-visible effect.\n *\n * @param {Object} rawBlock A raw block from `@wordpress/block-serialization-default-parser`.\n * @return {boolean} True if the block should be excluded from LCS matching.\n */\nfunction isWhitespaceRawBlock( rawBlock ) {\n\treturn (\n\t\trawBlock.blockName === null &&\n\t\t( ! rawBlock.innerHTML || ! rawBlock.innerHTML.trim() )\n\t);\n}\n\n/**\n * Safely stringifies a value for display and comparison.\n *\n * @param {*} value The value to stringify.\n * @return {string} The stringified value.\n */\nfunction stringifyValue( value ) {\n\tif ( value === null || value === undefined ) {\n\t\treturn '';\n\t}\n\tif ( typeof value === 'object' ) {\n\t\treturn JSON.stringify( value, null, 2 );\n\t}\n\treturn String( value );\n}\n\n/**\n * Calculate text similarity using word-set overlap.\n *\n * Uses a variant of the Jaccard index (https://en.wikipedia.org/wiki/Jaccard_index)\n * called the overlap coefficient (https://en.wikipedia.org/wiki/Overlap_coefficient)\n * where we divide by the larger set size rather than the union. This ensures that\n * a small edit to a long paragraph scores high \u2014 the few changed words don't\n * dilute the score.\n *\n * This replaces the previous diffWords-based similarity which was O(n*m) per pair.\n * The word-set approach is O(n) where n is the number of words.\n *\n * Words are extracted using Intl.Segmenter for proper multilingual support\n * (CJK, Thai, etc.) rather than splitting on whitespace.\n *\n * @param {string} text1 First text to compare.\n * @param {string} text2 Second text to compare.\n * @return {number} Similarity score between 0 and 1.\n */\nfunction textSimilarity( text1, text2 ) {\n\tif ( ! text1 && ! text2 ) {\n\t\treturn 1;\n\t}\n\tif ( ! text1 || ! text2 ) {\n\t\treturn 0;\n\t}\n\n\tconst segmenter = new Intl.Segmenter( undefined, {\n\t\tgranularity: 'word',\n\t} );\n\t// Safari's Intl.Segmenter returns isWordLike: false for numeric segments,\n\t// so fall back to a Unicode-aware regex for letters and numbers.\n\tconst wordLikeRegex = /[\\p{L}\\p{N}]/u;\n\tconst getWords = ( text ) => {\n\t\tconst words = [];\n\t\tfor ( const { segment, isWordLike } of segmenter.segment( text ) ) {\n\t\t\tif ( isWordLike || wordLikeRegex.test( segment ) ) {\n\t\t\t\twords.push( segment );\n\t\t\t}\n\t\t}\n\t\treturn words;\n\t};\n\tconst words1 = getWords( text1 );\n\tconst words2 = getWords( text2 );\n\n\tif ( words1.length === 0 && words2.length === 0 ) {\n\t\treturn 1;\n\t}\n\n\tconst set1 = new Set( words1 );\n\tlet intersection = 0;\n\tfor ( const word of words2 ) {\n\t\tif ( set1.has( word ) ) {\n\t\t\tintersection++;\n\t\t}\n\t}\n\n\tconst total = Math.max( words1.length, words2.length );\n\treturn total > 0 ? intersection / total : 0;\n}\n\n/**\n * Post-process diff result to pair similar removed/added blocks as modifications.\n *\n * After LCS diffing, a block whose content changed appears as a separate \"removed\"\n * and \"added\" entry (since the full block signature differs). This function detects\n * such pairs and merges them into a single \"modified\" block with inline diff.\n *\n * Two pairing strategies are used:\n * 1. When exactly one block of a given type was removed and one was added,\n * they are paired directly \u2014 no ambiguity, no similarity check needed.\n * 2. When multiple candidates exist, textSimilarity (overlap coefficient) is\n * used to find the best match. Blocks must share at least 50% of their\n * words to be paired, preventing unrelated paragraphs from being merged.\n *\n * @param {Array} blocks Raw blocks with diff status.\n * @return {Array} Blocks with similar pairs converted to modifications.\n */\nfunction pairSimilarBlocks( blocks ) {\n\tconst removed = [];\n\tconst added = [];\n\n\t// Separate blocks by status, tracking original indices.\n\tblocks.forEach( ( block, index ) => {\n\t\tconst status = block.__revisionDiffStatus?.status;\n\t\tif ( status === 'removed' ) {\n\t\t\tremoved.push( { block, index } );\n\t\t} else if ( status === 'added' ) {\n\t\t\tadded.push( { block, index } );\n\t\t}\n\t} );\n\n\t// If no removed or no added, nothing to pair.\n\tif ( removed.length === 0 || added.length === 0 ) {\n\t\treturn blocks;\n\t}\n\n\tconst pairedRemoved = new Set(); // Indices of removed blocks filtered out.\n\tconst pairedAdded = new Set(); // Indices of added blocks filtered out.\n\tconst modifications = new Map(); // Index \u2192 modified block.\n\tconst SIMILARITY_THRESHOLD = 0.5;\n\n\t// Group candidates by block name for efficient lookup.\n\tconst addedByName = new Map();\n\tfor ( const add of added ) {\n\t\tconst name = add.block.blockName;\n\t\tif ( ! addedByName.has( name ) ) {\n\t\t\taddedByName.set( name, [] );\n\t\t}\n\t\taddedByName.get( name ).push( add );\n\t}\n\tconst removedByName = new Map();\n\tfor ( const rem of removed ) {\n\t\tconst name = rem.block.blockName;\n\t\tif ( ! removedByName.has( name ) ) {\n\t\t\tremovedByName.set( name, [] );\n\t\t}\n\t\tremovedByName.get( name ).push( rem );\n\t}\n\n\t// For each removed block, find best matching added block.\n\t// Track the highest added index paired so far \u2014 new pairings must\n\t// not go backwards, or the removed/added text order would break.\n\tlet maxPairedAddedIndex = -1;\n\n\tfor ( const rem of removed ) {\n\t\tconst candidates = addedByName.get( rem.block.blockName ) || [];\n\t\tconst sameNameRemoved = removedByName.get( rem.block.blockName ) || [];\n\t\tconst unpaired = candidates.filter(\n\t\t\t( add ) =>\n\t\t\t\t! modifications.has( add.index ) &&\n\t\t\t\tadd.index > maxPairedAddedIndex\n\t\t);\n\n\t\tif ( unpaired.length === 0 ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet bestMatch = null;\n\n\t\t// If there's exactly one removed and one added of this type,\n\t\t// pair them directly \u2014 no ambiguity, no similarity check needed.\n\t\tif ( sameNameRemoved.length === 1 && unpaired.length === 1 ) {\n\t\t\tconst add = unpaired[ 0 ];\n\t\t\tconst attrsMatch =\n\t\t\t\tJSON.stringify( rem.block.attrs ) ===\n\t\t\t\tJSON.stringify( add.block.attrs );\n\t\t\t// Only skip pairing if both content and attrs are identical\n\t\t\t// (position swap, not a modification).\n\t\t\tconst contentMatch =\n\t\t\t\t( rem.block.innerHTML || '' ) === ( add.block.innerHTML || '' );\n\t\t\tif ( ! contentMatch || ! attrsMatch ) {\n\t\t\t\tbestMatch = add;\n\t\t\t}\n\t\t} else {\n\t\t\t// Multiple candidates \u2014 use similarity to find best match.\n\t\t\tlet bestScore = 0;\n\t\t\tfor ( const add of unpaired ) {\n\t\t\t\tconst score = textSimilarity(\n\t\t\t\t\trem.block.innerHTML || '',\n\t\t\t\t\tadd.block.innerHTML || ''\n\t\t\t\t);\n\t\t\t\t// Skip identical blocks (score=1 with same attrs) \u2014 those\n\t\t\t\t// are position swaps, not modifications. They should show\n\t\t\t\t// as separate removed + added, not as a no-op \"modified\".\n\t\t\t\tconst attrsMatch =\n\t\t\t\t\tJSON.stringify( rem.block.attrs ) ===\n\t\t\t\t\tJSON.stringify( add.block.attrs );\n\t\t\t\tif (\n\t\t\t\t\tscore > bestScore &&\n\t\t\t\t\tscore > SIMILARITY_THRESHOLD &&\n\t\t\t\t\t( score < 1 || ! attrsMatch )\n\t\t\t\t) {\n\t\t\t\t\tbestScore = score;\n\t\t\t\t\tbestMatch = add;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( bestMatch ) {\n\t\t\tmaxPairedAddedIndex = bestMatch.index;\n\n\t\t\tconst modifiedBlock = {\n\t\t\t\t...bestMatch.block,\n\t\t\t\t__revisionDiffStatus: { status: 'modified' },\n\t\t\t\t__previousRawBlock: rem.block,\n\t\t\t};\n\n\t\t\t// Decide where to place the modified block by checking\n\t\t\t// what's between the removed and added positions. If any\n\t\t\t// block between them is in the current revision (an\n\t\t\t// unchanged block, or an unpaired added block), placing\n\t\t\t// the modification at the removed position would put it\n\t\t\t// before content that already comes before it in the\n\t\t\t// current revision \u2014 so use the added position instead.\n\t\t\t// Otherwise, use the removed position to keep the previous\n\t\t\t// revision's reading order intact.\n\t\t\t//\n\t\t\t// 'removed' blocks (and added blocks already absorbed via\n\t\t\t// `pairedAdded`) aren't checked because they aren't in the\n\t\t\t// current revision and so don't count as crossing it.\n\t\t\tconst lo = Math.min( rem.index, bestMatch.index );\n\t\t\tconst hi = Math.max( rem.index, bestMatch.index );\n\t\t\tlet crossesCurrentContent = false;\n\t\t\tfor ( let i = lo + 1; i < hi; i++ ) {\n\t\t\t\tconst status = blocks[ i ].__revisionDiffStatus?.status;\n\t\t\t\tif ( status === undefined ) {\n\t\t\t\t\tcrossesCurrentContent = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif ( status === 'added' && ! pairedAdded.has( i ) ) {\n\t\t\t\t\tcrossesCurrentContent = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( crossesCurrentContent ) {\n\t\t\t\t// Use the added position \u2014 don't jump before\n\t\t\t\t// current-revision content.\n\t\t\t\tmodifications.set( bestMatch.index, modifiedBlock );\n\t\t\t\tpairedRemoved.add( rem.index );\n\t\t\t} else {\n\t\t\t\t// Use the removed position \u2014 keep the previous\n\t\t\t\t// revision's reading order.\n\t\t\t\tmodifications.set( rem.index, modifiedBlock );\n\t\t\t\tpairedAdded.add( bestMatch.index );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Rebuild result: replace modification targets, filter out\n\t// their paired counterparts.\n\treturn blocks\n\t\t.map( ( block, index ) => {\n\t\t\tif ( pairedRemoved.has( index ) || pairedAdded.has( index ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif ( modifications.has( index ) ) {\n\t\t\t\treturn modifications.get( index );\n\t\t\t}\n\t\t\treturn block;\n\t\t} )\n\t\t.filter( Boolean );\n}\n\n/**\n * Diff raw block arrays using LCS, recursively handling innerBlocks.\n * Detects modifications when exactly 1 block is removed and 1 is added\n * with the same blockName (1:1 replacement = modification).\n *\n * Whitespace-only freeform pseudo-blocks are filtered at every recursive\n * level so this function is safe to call directly with raw output from\n * `@wordpress/block-serialization-default-parser`. The duplicate work for\n * inner-block recursion is negligible and keeps the contract self-contained.\n *\n * @param {Array} currentRaw Current revision's raw blocks.\n * @param {Array} previousRaw Previous revision's raw blocks.\n * @return {Array} Merged raw blocks with diff status injected.\n */\nfunction diffRawBlocks( currentRaw, previousRaw ) {\n\t// Strip whitespace-only freeform pseudo-blocks before LCS \u2014 see\n\t// `isWhitespaceRawBlock` for why.\n\tcurrentRaw = currentRaw.filter( ( b ) => ! isWhitespaceRawBlock( b ) );\n\tpreviousRaw = previousRaw.filter( ( b ) => ! isWhitespaceRawBlock( b ) );\n\n\tconst createBlockSignature = ( rawBlock ) =>\n\t\tJSON.stringify( {\n\t\t\tname: rawBlock.blockName,\n\t\t\tattrs: rawBlock.attrs,\n\t\t\t// Use innerContent filtered to non-null and non-whitespace-only strings.\n\t\t\t// This excludes whitespace between inner blocks which changes based on count.\n\t\t\thtml: ( rawBlock.innerContent || [] ).filter(\n\t\t\t\t( c ) => c !== null && c.trim() !== ''\n\t\t\t),\n\t\t} );\n\tconst currentSigs = currentRaw.map( createBlockSignature );\n\tconst previousSigs = previousRaw.map( createBlockSignature );\n\n\tconst diff = diffArrays( previousSigs, currentSigs );\n\n\tconst result = [];\n\tlet currIdx = 0;\n\tlet prevIdx = 0;\n\n\tfor ( const part of diff ) {\n\t\tif ( part.added ) {\n\t\t\tfor ( let i = 0; i < part.count; i++ ) {\n\t\t\t\tresult.push( {\n\t\t\t\t\t...currentRaw[ currIdx++ ],\n\t\t\t\t\t__revisionDiffStatus: { status: 'added' },\n\t\t\t\t} );\n\t\t\t}\n\t\t} else if ( part.removed ) {\n\t\t\tfor ( let i = 0; i < part.count; i++ ) {\n\t\t\t\tresult.push( {\n\t\t\t\t\t...previousRaw[ prevIdx++ ],\n\t\t\t\t\t__revisionDiffStatus: { status: 'removed' },\n\t\t\t\t} );\n\t\t\t}\n\t\t} else {\n\t\t\t// Matched blocks - recursively diff their innerBlocks.\n\t\t\tfor ( let i = 0; i < part.count; i++ ) {\n\t\t\t\tconst currBlock = currentRaw[ currIdx++ ];\n\t\t\t\tconst prevBlock = previousRaw[ prevIdx++ ];\n\n\t\t\t\t// Recursively diff inner blocks.\n\t\t\t\tconst diffedInnerBlocks = diffRawBlocks(\n\t\t\t\t\tcurrBlock.innerBlocks || [],\n\t\t\t\t\tprevBlock.innerBlocks || []\n\t\t\t\t);\n\n\t\t\t\tresult.push( {\n\t\t\t\t\t...currBlock,\n\t\t\t\t\tinnerBlocks: diffedInnerBlocks,\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Post-process to pair similar removed/added blocks as modifications.\n\treturn pairSimilarBlocks( result );\n}\n\n/**\n * Check if formatting has changed at specific character indices.\n *\n * @param {Array} currentFormats Current formats array.\n * @param {Array} previousFormats Previous formats array.\n * @param {number} currentIndex Character index in current.\n * @param {number} previousIndex Character index in previous.\n * @return {boolean} True if formatting changed at these indices.\n */\nfunction hasFormatChangedAtIndex(\n\tcurrentFormats,\n\tpreviousFormats,\n\tcurrentIndex,\n\tpreviousIndex\n) {\n\tconst currFmts = currentFormats[ currentIndex ] || [];\n\tconst prevFmts = previousFormats[ previousIndex ] || [];\n\n\tif ( currFmts.length !== prevFmts.length ) {\n\t\treturn true;\n\t}\n\n\t// Check if each format in current exists in previous\n\tfor ( const fmt of currFmts ) {\n\t\tconst match = prevFmts.find(\n\t\t\t( pf ) =>\n\t\t\t\tpf.type === fmt.type &&\n\t\t\t\tJSON.stringify( pf.attributes ) ===\n\t\t\t\t\tJSON.stringify( fmt.attributes )\n\t\t);\n\t\tif ( ! match ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Analyze what formatting changed between two character positions.\n * Returns both the change type (for styling) and a description (for tooltip).\n *\n * @param {Array} currentFormats Current formats array.\n * @param {Array} previousFormats Previous formats array.\n * @param {number} currIdx Character index in current.\n * @param {number} prevIdx Character index in previous.\n * @return {{ type: 'added'|'removed'|'changed', description: string }} Change info.\n */\nfunction describeFormatChange(\n\tcurrentFormats,\n\tpreviousFormats,\n\tcurrIdx,\n\tprevIdx\n) {\n\tconst currFmts = currentFormats[ currIdx ] || [];\n\tconst prevFmts = previousFormats[ prevIdx ] || [];\n\n\tlet addedCount = 0;\n\tlet removedCount = 0;\n\tlet changedCount = 0;\n\n\t// Find added formats and attribute changes\n\tfor ( const fmt of currFmts ) {\n\t\tconst match = prevFmts.find( ( pf ) => pf.type === fmt.type );\n\t\tif ( ! match ) {\n\t\t\taddedCount++;\n\t\t} else if (\n\t\t\tJSON.stringify( fmt.attributes ) !==\n\t\t\tJSON.stringify( match.attributes )\n\t\t) {\n\t\t\tchangedCount++;\n\t\t}\n\t}\n\n\t// Find removed formats\n\tfor ( const fmt of prevFmts ) {\n\t\tconst match = currFmts.find( ( cf ) => cf.type === fmt.type );\n\t\tif ( ! match ) {\n\t\t\tremovedCount++;\n\t\t}\n\t}\n\n\t// Determine primary change type for styling\n\tif ( addedCount > 0 && removedCount === 0 && changedCount === 0 ) {\n\t\treturn {\n\t\t\ttype: 'added',\n\t\t\tdescription: sprintf(\n\t\t\t\t/* translators: %d: number of formats added */\n\t\t\t\t_n( '%d format added', '%d formats added', addedCount ),\n\t\t\t\taddedCount\n\t\t\t),\n\t\t};\n\t}\n\tif ( removedCount > 0 && addedCount === 0 && changedCount === 0 ) {\n\t\treturn {\n\t\t\ttype: 'removed',\n\t\t\tdescription: sprintf(\n\t\t\t\t/* translators: %d: number of formats removed */\n\t\t\t\t_n( '%d format removed', '%d formats removed', removedCount ),\n\t\t\t\tremovedCount\n\t\t\t),\n\t\t};\n\t}\n\n\t// Mixed or attribute-only changes\n\tconst parts = [];\n\tif ( addedCount > 0 ) {\n\t\tparts.push(\n\t\t\tsprintf(\n\t\t\t\t/* translators: %d: number of formats added */\n\t\t\t\t_n( '%d format added', '%d formats added', addedCount ),\n\t\t\t\taddedCount\n\t\t\t)\n\t\t);\n\t}\n\tif ( removedCount > 0 ) {\n\t\tparts.push(\n\t\t\tsprintf(\n\t\t\t\t/* translators: %d: number of formats removed */\n\t\t\t\t_n( '%d format removed', '%d formats removed', removedCount ),\n\t\t\t\tremovedCount\n\t\t\t)\n\t\t);\n\t}\n\tif ( changedCount > 0 ) {\n\t\tparts.push(\n\t\t\tsprintf(\n\t\t\t\t/* translators: %d: number of formats changed */\n\t\t\t\t_n( '%d format changed', '%d formats changed', changedCount ),\n\t\t\t\tchangedCount\n\t\t\t)\n\t\t);\n\t}\n\treturn {\n\t\ttype: 'changed',\n\t\tdescription: parts.join( ', ' ) || __( 'Formatting changed' ),\n\t};\n}\n\n/**\n * Apply inline diff formatting comparing two RichTextData values.\n * - Text changes: apply revision/diff-removed and revision/diff-added formats\n * - Format-only changes (text unchanged): apply revision/diff-format-changed format\n *\n * @param {RichTextData} currentRichText Current revision's rich text.\n * @param {RichTextData} previousRichText Previous revision's rich text.\n * @return {RichTextData} New rich text with diff formatting applied.\n */\nfunction applyRichTextDiff( currentRichText, previousRichText ) {\n\tconst currentText = currentRichText.toPlainText();\n\tconst previousText = previousRichText.toPlainText();\n\n\t// Diff the plain text (words for cleaner output).\n\tconst textDiff = diffWordsWithSpace( previousText, currentText );\n\n\tlet result = create( { text: '' } );\n\tlet currentIdx = 0;\n\tlet previousIdx = 0;\n\n\tfor ( const part of textDiff ) {\n\t\tif ( part.removed ) {\n\t\t\t// Text deleted - slice from PREVIOUS, apply <del>\n\t\t\tconst removedSlice = slice(\n\t\t\t\tpreviousRichText,\n\t\t\t\tpreviousIdx,\n\t\t\t\tpreviousIdx + part.value.length\n\t\t\t);\n\t\t\tconst formatted = applyFormat(\n\t\t\t\tremovedSlice,\n\t\t\t\t{\n\t\t\t\t\ttype: 'revision/diff-removed',\n\t\t\t\t\tattributes: { title: __( 'Removed' ) },\n\t\t\t\t},\n\t\t\t\t0,\n\t\t\t\tpart.value.length\n\t\t\t);\n\t\t\tresult = concat( result, formatted );\n\t\t\tpreviousIdx += part.value.length;\n\t\t} else if ( part.added ) {\n\t\t\t// Text added - slice from CURRENT, apply <ins>\n\t\t\tconst addedSlice = slice(\n\t\t\t\tcurrentRichText,\n\t\t\t\tcurrentIdx,\n\t\t\t\tcurrentIdx + part.value.length\n\t\t\t);\n\t\t\tconst formatted = applyFormat(\n\t\t\t\taddedSlice,\n\t\t\t\t{\n\t\t\t\t\ttype: 'revision/diff-added',\n\t\t\t\t\tattributes: { title: __( 'Added' ) },\n\t\t\t\t},\n\t\t\t\t0,\n\t\t\t\tpart.value.length\n\t\t\t);\n\t\t\tresult = concat( result, formatted );\n\t\t\tcurrentIdx += part.value.length;\n\t\t} else {\n\t\t\t// Text unchanged - check formatting at each character position.\n\t\t\t// Only apply <mark> to specific ranges where formatting differs.\n\t\t\tconst currentFormats = currentRichText.formats || [];\n\t\t\tconst previousFormats = previousRichText.formats || [];\n\t\t\tconst len = part.value.length;\n\n\t\t\t// Helper to check format change at offset within this unchanged part.\n\t\t\tconst checkFormatChanged = ( offset ) =>\n\t\t\t\thasFormatChangedAtIndex(\n\t\t\t\t\tcurrentFormats,\n\t\t\t\t\tpreviousFormats,\n\t\t\t\t\tcurrentIdx + offset,\n\t\t\t\t\tpreviousIdx + offset\n\t\t\t\t);\n\n\t\t\t// Find ranges of characters grouped by whether format changed.\n\t\t\tlet rangeStart = 0;\n\t\t\tlet rangeFormatChanged = checkFormatChanged( 0 );\n\n\t\t\tfor ( let i = 1; i <= len; i++ ) {\n\t\t\t\tconst formatChanged = i < len && checkFormatChanged( i );\n\n\t\t\t\t// When format-changed status changes or we reach the end, emit range.\n\t\t\t\tif ( i === len || formatChanged !== rangeFormatChanged ) {\n\t\t\t\t\tconst rangeSlice = slice(\n\t\t\t\t\t\tcurrentRichText,\n\t\t\t\t\t\tcurrentIdx + rangeStart,\n\t\t\t\t\t\tcurrentIdx + i\n\t\t\t\t\t);\n\n\t\t\t\t\tif ( rangeFormatChanged ) {\n\t\t\t\t\t\t// Get type and description of what changed\n\t\t\t\t\t\tconst { type, description } = describeFormatChange(\n\t\t\t\t\t\t\tcurrentFormats,\n\t\t\t\t\t\t\tpreviousFormats,\n\t\t\t\t\t\t\tcurrentIdx + rangeStart,\n\t\t\t\t\t\t\tpreviousIdx + rangeStart\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// Map change type to format type for styling\n\t\t\t\t\t\tconst formatType = {\n\t\t\t\t\t\t\tadded: 'revision/diff-format-added',\n\t\t\t\t\t\t\tremoved: 'revision/diff-format-removed',\n\t\t\t\t\t\t\tchanged: 'revision/diff-format-changed',\n\t\t\t\t\t\t}[ type ];\n\n\t\t\t\t\t\tconst marked = applyFormat(\n\t\t\t\t\t\t\trangeSlice,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: formatType,\n\t\t\t\t\t\t\t\tattributes: { title: description },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\ti - rangeStart\n\t\t\t\t\t\t);\n\t\t\t\t\t\tresult = concat( result, marked );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = concat( result, rangeSlice );\n\t\t\t\t\t}\n\n\t\t\t\t\trangeStart = i;\n\t\t\t\t\trangeFormatChanged = formatChanged;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcurrentIdx += part.value.length;\n\t\t\tpreviousIdx += part.value.length;\n\t\t}\n\t}\n\n\treturn new RichTextData( result );\n}\n\n/**\n * Apply diffs to a modified block's attributes.\n * - Rich-text attributes: applies inline diff formatting (ins/del marks).\n * - Other attributes: computes word-level diffs for the sidebar panel.\n *\n * @param {Object} currentBlock Current parsed block.\n * @param {Object} previousBlock Previous parsed block.\n * @param {Object} diffStatus The __revisionDiffStatus object to attach changedAttributes to.\n */\nfunction applyDiffToBlock( currentBlock, previousBlock, diffStatus ) {\n\tconst blockType = getBlockType( currentBlock.name );\n\tif ( ! blockType ) {\n\t\treturn;\n\t}\n\n\tconst changedAttributes = {};\n\n\tfor ( const [ attrName, attrDef ] of Object.entries(\n\t\tblockType.attributes\n\t) ) {\n\t\tif ( attrDef.source === 'rich-text' ) {\n\t\t\tconst currentRichText = currentBlock.attributes[ attrName ];\n\t\t\tconst previousRichText = previousBlock.attributes[ attrName ];\n\t\t\tif (\n\t\t\t\tcurrentRichText instanceof RichTextData &&\n\t\t\t\tpreviousRichText instanceof RichTextData\n\t\t\t) {\n\t\t\t\tcurrentBlock.attributes[ attrName ] = applyRichTextDiff(\n\t\t\t\t\tcurrentRichText,\n\t\t\t\t\tpreviousRichText\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tconst currStr = stringifyValue(\n\t\t\t\tcurrentBlock.attributes[ attrName ]\n\t\t\t);\n\t\t\tconst prevStr = stringifyValue(\n\t\t\t\tpreviousBlock.attributes[ attrName ]\n\t\t\t);\n\t\t\tif ( currStr !== prevStr ) {\n\t\t\t\tchangedAttributes[ attrName ] = diffWordsWithSpace(\n\t\t\t\t\tprevStr,\n\t\t\t\t\tcurrStr\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( Object.keys( changedAttributes ).length > 0 ) {\n\t\tdiffStatus.changedAttributes = changedAttributes;\n\t}\n}\n\n/**\n * Recursively apply diff status and rich text diff to blocks in the tree.\n * Copies __revisionDiffStatus from raw blocks to parsed blocks and applies\n * rich text diffs to modified blocks.\n *\n * @param {Object} parsedBlock Parsed block (with inner blocks).\n * @param {Object} rawBlock Raw block (with __revisionDiffStatus and __previousRawBlock).\n */\nfunction applyDiffRecursively( parsedBlock, rawBlock ) {\n\t// Copy diff status from raw block to parsed block.\n\tif ( rawBlock.__revisionDiffStatus ) {\n\t\t// Apply diffs if this block is modified and has a previous raw block.\n\t\tif (\n\t\t\trawBlock.__revisionDiffStatus.status === 'modified' &&\n\t\t\trawBlock.__previousRawBlock\n\t\t) {\n\t\t\tconst previousParsed = parseRawBlock( rawBlock.__previousRawBlock );\n\t\t\tif ( previousParsed ) {\n\t\t\t\tapplyDiffToBlock(\n\t\t\t\t\tparsedBlock,\n\t\t\t\t\tpreviousParsed,\n\t\t\t\t\trawBlock.__revisionDiffStatus\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tparsedBlock.__revisionDiffStatus = rawBlock.__revisionDiffStatus;\n\t\t// Also store in attributes so it survives block-editor store normalization.\n\t\tparsedBlock.attributes.__revisionDiffStatus =\n\t\t\trawBlock.__revisionDiffStatus;\n\t}\n\n\t// Recursively process inner blocks.\n\tif ( parsedBlock.innerBlocks && rawBlock.innerBlocks ) {\n\t\tfor ( let i = 0; i < parsedBlock.innerBlocks.length; i++ ) {\n\t\t\tconst parsedInner = parsedBlock.innerBlocks[ i ];\n\t\t\tconst rawInner = rawBlock.innerBlocks[ i ];\n\t\t\tif ( parsedInner && rawInner ) {\n\t\t\t\tapplyDiffRecursively( parsedInner, rawInner );\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Diff two revision contents at the grammar level.\n *\n * @param {string} currentContent Current revision's raw content.\n * @param {string} previousContent Previous revision's raw content.\n * @return {Array} Array of parsed blocks with diff status attributes.\n */\nexport function diffRevisionContent( currentContent, previousContent ) {\n\t// Grammar parse both contents.\n\tconst currentRaw = grammarParse( currentContent || '' );\n\tconst previousRaw = grammarParse( previousContent || '' );\n\n\t// Diff the raw block arrays.\n\tconst mergedRaw = diffRawBlocks( currentRaw, previousRaw );\n\n\t// Parse each raw block and apply diff status.\n\treturn mergedRaw\n\t\t.map( ( rawBlock ) => {\n\t\t\tconst parsed = parseRawBlock( rawBlock );\n\t\t\tif ( parsed ) {\n\t\t\t\tapplyDiffRecursively( parsed, rawBlock );\n\t\t\t}\n\t\t\treturn parsed;\n\t\t} )\n\t\t.filter( Boolean );\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,5 @@
1
1
  // packages/editor/src/components/post-revisions-preview/preserve-client-ids.js
2
- import { diffArrays } from "diff/lib/diff/array";
2
+ import { diffArrays } from "diff";
3
3
  function preserveClientIds(newBlocks, prevBlocks) {
4
4
  if (!prevBlocks?.length || !newBlocks?.length) {
5
5
  return newBlocks;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/post-revisions-preview/preserve-client-ids.js"],
4
- "sourcesContent": ["/**\n * External dependencies\n */\nimport { diffArrays } from 'diff/lib/diff/array';\n\n/**\n * Preserves clientIds from previously rendered blocks to prevent flashing.\n * Uses LCS algorithm to match blocks by name.\n *\n * This compares the newly parsed blocks against the last rendered blocks\n * to maintain React key stability.\n *\n * @param {Array} newBlocks Newly parsed blocks with fresh clientIds.\n * @param {Array} prevBlocks Previously rendered blocks with stable clientIds.\n * @return {Array} Blocks with preserved clientIds where possible.\n */\nexport function preserveClientIds( newBlocks, prevBlocks ) {\n\tif ( ! prevBlocks?.length || ! newBlocks?.length ) {\n\t\treturn newBlocks;\n\t}\n\n\t// Create signatures for LCS matching using block name.\n\tconst newSigs = newBlocks.map( ( block ) => block.name );\n\tconst prevSigs = prevBlocks.map( ( block ) => block.name );\n\n\tconst diffResult = diffArrays( prevSigs, newSigs );\n\n\tlet newIndex = 0;\n\tlet prevIndex = 0;\n\tconst result = [];\n\n\tfor ( const chunk of diffResult ) {\n\t\tif ( chunk.removed ) {\n\t\t\t// Blocks only in prev render - skip them.\n\t\t\tprevIndex += chunk.count;\n\t\t} else if ( chunk.added ) {\n\t\t\t// Blocks only in new render - keep new clientIds.\n\t\t\tfor ( let i = 0; i < chunk.count; i++ ) {\n\t\t\t\tresult.push( newBlocks[ newIndex++ ] );\n\t\t\t}\n\t\t} else {\n\t\t\t// Matched blocks - preserve clientIds from prev render.\n\t\t\tfor ( let i = 0; i < chunk.count; i++ ) {\n\t\t\t\tconst newBlock = newBlocks[ newIndex++ ];\n\t\t\t\tconst prevBlock = prevBlocks[ prevIndex++ ];\n\t\t\t\tresult.push( {\n\t\t\t\t\t...newBlock,\n\t\t\t\t\tclientId: prevBlock.clientId,\n\t\t\t\t\tinnerBlocks: preserveClientIds(\n\t\t\t\t\t\tnewBlock.innerBlocks,\n\t\t\t\t\t\tprevBlock.innerBlocks\n\t\t\t\t\t),\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n"],
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport { diffArrays } from 'diff';\n\n/**\n * Preserves clientIds from previously rendered blocks to prevent flashing.\n * Uses LCS algorithm to match blocks by name.\n *\n * This compares the newly parsed blocks against the last rendered blocks\n * to maintain React key stability.\n *\n * @param {Array} newBlocks Newly parsed blocks with fresh clientIds.\n * @param {Array} prevBlocks Previously rendered blocks with stable clientIds.\n * @return {Array} Blocks with preserved clientIds where possible.\n */\nexport function preserveClientIds( newBlocks, prevBlocks ) {\n\tif ( ! prevBlocks?.length || ! newBlocks?.length ) {\n\t\treturn newBlocks;\n\t}\n\n\t// Create signatures for LCS matching using block name.\n\tconst newSigs = newBlocks.map( ( block ) => block.name );\n\tconst prevSigs = prevBlocks.map( ( block ) => block.name );\n\n\tconst diffResult = diffArrays( prevSigs, newSigs );\n\n\tlet newIndex = 0;\n\tlet prevIndex = 0;\n\tconst result = [];\n\n\tfor ( const chunk of diffResult ) {\n\t\tif ( chunk.removed ) {\n\t\t\t// Blocks only in prev render - skip them.\n\t\t\tprevIndex += chunk.count;\n\t\t} else if ( chunk.added ) {\n\t\t\t// Blocks only in new render - keep new clientIds.\n\t\t\tfor ( let i = 0; i < chunk.count; i++ ) {\n\t\t\t\tresult.push( newBlocks[ newIndex++ ] );\n\t\t\t}\n\t\t} else {\n\t\t\t// Matched blocks - preserve clientIds from prev render.\n\t\t\tfor ( let i = 0; i < chunk.count; i++ ) {\n\t\t\t\tconst newBlock = newBlocks[ newIndex++ ];\n\t\t\t\tconst prevBlock = prevBlocks[ prevIndex++ ];\n\t\t\t\tresult.push( {\n\t\t\t\t\t...newBlock,\n\t\t\t\t\tclientId: prevBlock.clientId,\n\t\t\t\t\tinnerBlocks: preserveClientIds(\n\t\t\t\t\t\tnewBlock.innerBlocks,\n\t\t\t\t\t\tprevBlock.innerBlocks\n\t\t\t\t\t),\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n"],
5
5
  "mappings": ";AAGA,SAAS,kBAAkB;AAapB,SAAS,kBAAmB,WAAW,YAAa;AAC1D,MAAK,CAAE,YAAY,UAAU,CAAE,WAAW,QAAS;AAClD,WAAO;AAAA,EACR;AAGA,QAAM,UAAU,UAAU,IAAK,CAAE,UAAW,MAAM,IAAK;AACvD,QAAM,WAAW,WAAW,IAAK,CAAE,UAAW,MAAM,IAAK;AAEzD,QAAM,aAAa,WAAY,UAAU,OAAQ;AAEjD,MAAI,WAAW;AACf,MAAI,YAAY;AAChB,QAAM,SAAS,CAAC;AAEhB,aAAY,SAAS,YAAa;AACjC,QAAK,MAAM,SAAU;AAEpB,mBAAa,MAAM;AAAA,IACpB,WAAY,MAAM,OAAQ;AAEzB,eAAU,IAAI,GAAG,IAAI,MAAM,OAAO,KAAM;AACvC,eAAO,KAAM,UAAW,UAAW,CAAE;AAAA,MACtC;AAAA,IACD,OAAO;AAEN,eAAU,IAAI,GAAG,IAAI,MAAM,OAAO,KAAM;AACvC,cAAM,WAAW,UAAW,UAAW;AACvC,cAAM,YAAY,WAAY,WAAY;AAC1C,eAAO,KAAM;AAAA,UACZ,GAAG;AAAA,UACH,UAAU,UAAU;AAAA,UACpB,aAAa;AAAA,YACZ,SAAS;AAAA,YACT,UAAU;AAAA,UACX;AAAA,QACD,CAAE;AAAA,MACH;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AACR;",
6
6
  "names": []
7
7
  }
@@ -30,6 +30,7 @@ import { useHideBlocksFromInserter } from "./use-hide-blocks-from-inserter.mjs";
30
30
  import { useRevisionBlocks } from "./use-revision-blocks.mjs";
31
31
  import useCommands from "../commands/index.mjs";
32
32
  import useUploadSaveLock from "./use-upload-save-lock.mjs";
33
+ import useNetworkReconnect from "./use-network-reconnect.mjs";
33
34
  import BlockRemovalWarnings from "../block-removal-warnings/index.mjs";
34
35
  import StartPageOptions from "../start-page-options/index.mjs";
35
36
  import KeyboardShortcutHelpModal from "../keyboard-shortcut-help-modal/index.mjs";
@@ -264,6 +265,7 @@ var ExperimentalEditorProvider = withRegistryProvider(
264
265
  useHideBlocksFromInserter(post.type, mode);
265
266
  useCommands();
266
267
  useUploadSaveLock();
268
+ useNetworkReconnect();
267
269
  if (!isReady || !mode) {
268
270
  return null;
269
271
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/provider/index.js"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport {\n\tuseCallback,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseMemo,\n} from '@wordpress/element';\nimport { useDispatch, useSelect, useRegistry } from '@wordpress/data';\nimport { __ } from '@wordpress/i18n';\nimport {\n\tEntityProvider,\n\tuseEntityBlockEditor,\n\tstore as coreStore,\n} from '@wordpress/core-data';\nimport {\n\tBlockEditorProvider,\n\tBlockContextProvider,\n\tprivateApis as blockEditorPrivateApis,\n} from '@wordpress/block-editor';\nimport { store as noticesStore } from '@wordpress/notices';\nimport { privateApis as editPatternsPrivateApis } from '@wordpress/patterns';\nimport { createBlock } from '@wordpress/blocks';\n\n/**\n * Internal dependencies\n */\nimport withRegistryProvider from './with-registry-provider';\nimport { store as editorStore } from '../../store';\nimport useBlockEditorSettings from './use-block-editor-settings';\nimport { unlock } from '../../lock-unlock';\nimport DisableNonPageContentBlocks from './disable-non-page-content-blocks';\nimport NavigationBlockEditingMode from './navigation-block-editing-mode';\nimport { useHideBlocksFromInserter } from './use-hide-blocks-from-inserter';\nimport { useRevisionBlocks } from './use-revision-blocks';\nimport useCommands from '../commands';\nimport useUploadSaveLock from './use-upload-save-lock';\nimport BlockRemovalWarnings from '../block-removal-warnings';\nimport StartPageOptions from '../start-page-options';\nimport KeyboardShortcutHelpModal from '../keyboard-shortcut-help-modal';\nimport StartTemplateOptions from '../start-template-options';\nimport EditorKeyboardShortcuts from '../global-keyboard-shortcuts';\nimport PatternRenameModal from '../pattern-rename-modal';\nimport PatternDuplicateModal from '../pattern-duplicate-modal';\nimport TemplatePartMenuItems from '../template-part-menu-items';\nimport MediaEditorModalMount from '../media/media-editor-modal';\n\nconst { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis );\nconst { PatternsMenuItems } = unlock( editPatternsPrivateApis );\n\nconst noop = () => {};\n\n/**\n * These are global entities that are only there to split blocks into logical units\n * They don't provide a \"context\" for the current post/page being rendered.\n * So we should not use their ids as post context. This is important to allow post blocks\n * (post content, post title) to be used within them without issues.\n */\nconst NON_CONTEXTUAL_POST_TYPES = [\n\t'wp_block',\n\t'wp_navigation',\n\t'wp_template_part',\n];\n\n/**\n * Depending on the post, template and template mode,\n * returns the appropriate blocks and change handlers for the block editor provider.\n *\n * @param {Array} post Block list.\n * @param {boolean} template Whether the page content has focus (and the surrounding template is inert). If `true` return page content blocks. Default `false`.\n * @param {string} mode Rendering mode.\n *\n * @example\n * ```jsx\n * const [ blocks, onInput, onChange ] = useBlockEditorProps( post, template, mode );\n * ```\n *\n * @return {Array} Block editor props.\n */\nfunction useBlockEditorProps( post, template, mode ) {\n\tconst revisionBlocks = useRevisionBlocks();\n\tconst rootLevelPost = mode === 'template-locked' ? 'template' : 'post';\n\tconst [ postBlocks, onInput, onChange ] = useEntityBlockEditor(\n\t\t'postType',\n\t\tpost.type,\n\t\t{ id: post.id }\n\t);\n\tconst [ templateBlocks, onInputTemplate, onChangeTemplate ] =\n\t\tuseEntityBlockEditor( 'postType', template?.type, {\n\t\t\tid: template?.id,\n\t\t} );\n\tconst maybeNavigationBlocks = useMemo( () => {\n\t\tif ( post.type === 'wp_navigation' ) {\n\t\t\treturn [\n\t\t\t\tcreateBlock( 'core/navigation', {\n\t\t\t\t\tref: post.id,\n\t\t\t\t\t// As the parent editor is locked with `templateLock`, the template locking\n\t\t\t\t\t// must be explicitly \"unset\" on the block itself to allow the user to modify\n\t\t\t\t\t// the block's content.\n\t\t\t\t\ttemplateLock: false,\n\t\t\t\t} ),\n\t\t\t];\n\t\t}\n\t}, [ post.type, post.id ] );\n\n\t// It is important that we don't create a new instance of blocks on every change\n\t// We should only create a new instance if the blocks them selves change, not a dependency of them.\n\tconst blocks = useMemo( () => {\n\t\tif ( maybeNavigationBlocks ) {\n\t\t\treturn maybeNavigationBlocks;\n\t\t}\n\n\t\tif ( rootLevelPost === 'template' ) {\n\t\t\treturn templateBlocks;\n\t\t}\n\n\t\treturn postBlocks;\n\t}, [ maybeNavigationBlocks, rootLevelPost, templateBlocks, postBlocks ] );\n\n\t// In revisions mode, use the revision blocks and disable editing.\n\tif ( revisionBlocks !== null ) {\n\t\treturn [ revisionBlocks, noop, noop ];\n\t}\n\n\t// Handle fallback to postBlocks outside of the above useMemo, to ensure\n\t// that constructed block templates that call `createBlock` are not generated\n\t// too frequently. This ensures that clientIds are stable.\n\tconst disableRootLevelChanges =\n\t\t( !! template && mode === 'template-locked' ) ||\n\t\tpost.type === 'wp_navigation';\n\tif ( disableRootLevelChanges ) {\n\t\treturn [ blocks, noop, noop ];\n\t}\n\n\treturn [\n\t\tblocks,\n\t\trootLevelPost === 'post' ? onInput : onInputTemplate,\n\t\trootLevelPost === 'post' ? onChange : onChangeTemplate,\n\t];\n}\n\n/**\n * This component provides the editor context and manages the state of the block editor.\n *\n * @param {Object} props The component props.\n * @param {Object} props.post The post object.\n * @param {Object} props.settings The editor settings.\n * @param {boolean} props.recovery Indicates if the editor is in recovery mode.\n * @param {Array} props.initialEdits The initial edits for the editor.\n * @param {Object} props.children The child components.\n * @param {Object} [props.BlockEditorProviderComponent] The block editor provider component to use. Defaults to ExperimentalBlockEditorProvider.\n * @param {Object} [props.__unstableTemplate] The template object.\n *\n * @example\n * ```jsx\n * <ExperimentalEditorProvider\n * post={ post }\n * settings={ settings }\n * recovery={ recovery }\n * initialEdits={ initialEdits }\n * __unstableTemplate={ template }\n * >\n * { children }\n * </ExperimentalEditorProvider>\n *\n * @return {Object} The rendered ExperimentalEditorProvider component.\n */\nexport const ExperimentalEditorProvider = withRegistryProvider(\n\t( {\n\t\tpost,\n\t\tsettings,\n\t\trecovery,\n\t\tinitialEdits,\n\t\tchildren,\n\t\tBlockEditorProviderComponent = ExperimentalBlockEditorProvider,\n\t\t__unstableTemplate: template,\n\t} ) => {\n\t\tconst hasTemplate = !! template;\n\t\tconst {\n\t\t\teditorSettings,\n\t\t\tselection,\n\t\t\tisReady,\n\t\t\tmode,\n\t\t\tdefaultMode,\n\t\t\tpostTypeEntities,\n\t\t\tisInRevisionsMode,\n\t\t\tcurrentRevisionId,\n\t\t} = useSelect(\n\t\t\t( select ) => {\n\t\t\t\tconst {\n\t\t\t\t\tgetEditorSettings,\n\t\t\t\t\tgetRenderingMode,\n\t\t\t\t\t__unstableIsEditorReady,\n\t\t\t\t\tgetDefaultRenderingMode,\n\t\t\t\t\tisRevisionsMode: _isRevisionsMode,\n\t\t\t\t\tgetCurrentRevisionId: _getCurrentRevisionId,\n\t\t\t\t} = unlock( select( editorStore ) );\n\t\t\t\tconst { getEntitiesConfig, getEntityRecordEdits } =\n\t\t\t\t\tselect( coreStore );\n\n\t\t\t\tconst _mode = getRenderingMode();\n\t\t\t\tconst _defaultMode = getDefaultRenderingMode( post.type );\n\t\t\t\t/**\n\t\t\t\t * To avoid content \"flash\", wait until rendering mode has been resolved.\n\t\t\t\t * This is important for the initial render of the editor.\n\t\t\t\t *\n\t\t\t\t * - Wait for template to be resolved if the default mode is 'template-locked'.\n\t\t\t\t * - Wait for default mode to be resolved otherwise.\n\t\t\t\t */\n\t\t\t\tconst hasResolvedDefaultMode =\n\t\t\t\t\t_defaultMode === 'template-locked'\n\t\t\t\t\t\t? hasTemplate\n\t\t\t\t\t\t: _defaultMode !== undefined;\n\t\t\t\t// Wait until the default mode is retrieved and start rendering canvas.\n\t\t\t\tconst isRenderingModeReady = _defaultMode !== undefined;\n\n\t\t\t\t// Read selection directly from entity edits using the post prop,\n\t\t\t\t// bypassing getCurrentPostId() which lags behind in useEffect.\n\t\t\t\tconst entityEdits = getEntityRecordEdits(\n\t\t\t\t\t'postType',\n\t\t\t\t\tpost.type,\n\t\t\t\t\tpost.id\n\t\t\t\t);\n\n\t\t\t\treturn {\n\t\t\t\t\teditorSettings: getEditorSettings(),\n\t\t\t\t\tisReady: __unstableIsEditorReady(),\n\t\t\t\t\tmode: isRenderingModeReady ? _mode : undefined,\n\t\t\t\t\tdefaultMode: hasResolvedDefaultMode\n\t\t\t\t\t\t? _defaultMode\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\tselection: entityEdits?.selection,\n\t\t\t\t\tpostTypeEntities:\n\t\t\t\t\t\tpost.type === 'wp_template'\n\t\t\t\t\t\t\t? getEntitiesConfig( 'postType' )\n\t\t\t\t\t\t\t: null,\n\t\t\t\t\tisInRevisionsMode: _isRevisionsMode(),\n\t\t\t\t\tcurrentRevisionId: _getCurrentRevisionId(),\n\t\t\t\t};\n\t\t\t},\n\t\t\t[ post.type, post.id, hasTemplate ]\n\t\t);\n\n\t\tconst shouldRenderTemplate = hasTemplate && mode !== 'post-only';\n\t\tconst rootLevelPost = shouldRenderTemplate ? template : post;\n\t\tconst defaultBlockContext = useMemo( () => {\n\t\t\tconst postContext = {};\n\t\t\t// If it is a template, try to inherit the post type from the name.\n\t\t\tif ( post.type === 'wp_template' ) {\n\t\t\t\tif ( post.slug === 'page' ) {\n\t\t\t\t\tpostContext.postType = 'page';\n\t\t\t\t} else if ( post.slug === 'single' ) {\n\t\t\t\t\tpostContext.postType = 'post';\n\t\t\t\t} else if ( post.slug.split( '-' )[ 0 ] === 'single' ) {\n\t\t\t\t\t// If the slug is single-{postType}, infer the post type from the name.\n\t\t\t\t\tconst postTypeNames =\n\t\t\t\t\t\tpostTypeEntities?.map( ( entity ) => entity.name ) ||\n\t\t\t\t\t\t[];\n\t\t\t\t\tconst match = post.slug.match(\n\t\t\t\t\t\t`^single-(${ postTypeNames.join( '|' ) })(?:-.+)?$`\n\t\t\t\t\t);\n\t\t\t\t\tif ( match ) {\n\t\t\t\t\t\tpostContext.postType = match[ 1 ];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\t! NON_CONTEXTUAL_POST_TYPES.includes( rootLevelPost.type ) ||\n\t\t\t\tshouldRenderTemplate\n\t\t\t) {\n\t\t\t\tpostContext.postId = post.id;\n\t\t\t\tpostContext.postType = post.type;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\t...postContext,\n\t\t\t\ttemplateSlug:\n\t\t\t\t\trootLevelPost.type === 'wp_template'\n\t\t\t\t\t\t? rootLevelPost.slug\n\t\t\t\t\t\t: undefined,\n\t\t\t};\n\t\t}, [\n\t\t\tshouldRenderTemplate,\n\t\t\tpost.id,\n\t\t\tpost.type,\n\t\t\tpost.slug,\n\t\t\trootLevelPost.type,\n\t\t\trootLevelPost.slug,\n\t\t\tpostTypeEntities,\n\t\t] );\n\t\tconst { id, type } = rootLevelPost;\n\t\tconst blockEditorSettings = useBlockEditorSettings(\n\t\t\teditorSettings,\n\t\t\ttype,\n\t\t\tid,\n\t\t\tmode\n\t\t);\n\t\tconst [ blocks, onInput, onChange ] = useBlockEditorProps(\n\t\t\tpost,\n\t\t\ttemplate,\n\t\t\tmode\n\t\t);\n\n\t\tconst {\n\t\t\tupdatePostLock,\n\t\t\tsetupEditor,\n\t\t\tupdateEditorSettings,\n\t\t\tsetCurrentTemplateId,\n\t\t\tsetEditedPost,\n\t\t\tsetRenderingMode,\n\t\t} = unlock( useDispatch( editorStore ) );\n\t\tconst { editEntityRecord } = useDispatch( coreStore );\n\t\tconst registry = useRegistry();\n\n\t\tconst onChangeSelection = useCallback(\n\t\t\t( newSelection ) => {\n\t\t\t\teditEntityRecord(\n\t\t\t\t\t'postType',\n\t\t\t\t\tpost.type,\n\t\t\t\t\tpost.id,\n\t\t\t\t\t{ selection: newSelection },\n\t\t\t\t\t{ undoIgnore: true }\n\t\t\t\t);\n\t\t\t},\n\t\t\t[ editEntityRecord, post.type, post.id ]\n\t\t);\n\t\tconst { createWarningNotice, removeNotice } =\n\t\t\tuseDispatch( noticesStore );\n\n\t\t// Ideally this should be synced on each change and not just something you do once.\n\t\tuseLayoutEffect( () => {\n\t\t\t// Assume that we don't need to initialize in the case of an error recovery.\n\t\t\tif ( recovery ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tupdatePostLock( settings.postLock );\n\t\t\t// `setupEditor` may already have been dispatched by the\n\t\t\t// editor's pre-mount kickoff (see edit-post's\n\t\t\t// `initializeEditor`). Skip the redundant dispatch \u2014 it\n\t\t\t// would otherwise re-parse + reset blocks for new posts.\n\t\t\tif ( ! registry.select( editorStore ).__unstableIsEditorReady() ) {\n\t\t\t\tsetupEditor( post, initialEdits, settings.template );\n\t\t\t}\n\t\t\tif ( settings.autosave ) {\n\t\t\t\tcreateWarningNotice(\n\t\t\t\t\t__(\n\t\t\t\t\t\t'There is an autosave of this post that is more recent than the version below.'\n\t\t\t\t\t),\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'autosave-exists',\n\t\t\t\t\t\tactions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlabel: __( 'View the autosave' ),\n\t\t\t\t\t\t\t\turl: settings.autosave.editLink,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// The dependencies of the hook are omitted deliberately\n\t\t\t// We only want to run setupEditor (with initialEdits) only once per post.\n\t\t\t// A better solution in the future would be to split this effect into multiple ones.\n\t\t}, [] );\n\n\t\t// Synchronizes the active post with the state\n\t\tuseEffect( () => {\n\t\t\tsetEditedPost( post.type, post.id );\n\t\t\tif (\n\t\t\t\ttypeof window !== 'undefined' &&\n\t\t\t\twindow.__experimentalTemplateActivate\n\t\t\t) {\n\t\t\t\t// Clear any notices dependent on the post context.\n\t\t\t\tremoveNotice( 'template-activate-notice' );\n\t\t\t}\n\n\t\t\treturn () => setEditedPost( null, null );\n\t\t}, [ post.type, post.id, setEditedPost, removeNotice ] );\n\n\t\t// Synchronize the editor settings as they change.\n\t\tuseEffect( () => {\n\t\t\tupdateEditorSettings( settings );\n\t\t}, [ settings, updateEditorSettings ] );\n\n\t\t// Synchronizes the active template with the state.\n\t\tuseEffect( () => {\n\t\t\tsetCurrentTemplateId( template?.id );\n\t\t}, [ template?.id, setCurrentTemplateId ] );\n\n\t\t// Sets the right rendering mode when loading the editor.\n\t\tuseEffect( () => {\n\t\t\tif ( defaultMode ) {\n\t\t\t\tsetRenderingMode( defaultMode );\n\t\t\t}\n\t\t}, [ defaultMode, setRenderingMode ] );\n\n\t\tuseHideBlocksFromInserter( post.type, mode );\n\n\t\t// Register the editor commands.\n\t\tuseCommands();\n\n\t\t// Lock post saving when media uploads are in progress (experimental feature).\n\t\tuseUploadSaveLock();\n\n\t\tif ( ! isReady || ! mode ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn (\n\t\t\t<EntityProvider kind=\"root\" type=\"site\">\n\t\t\t\t<EntityProvider\n\t\t\t\t\tkind=\"postType\"\n\t\t\t\t\ttype={ post.type }\n\t\t\t\t\tid={ post.id }\n\t\t\t\t\trevisionId={ currentRevisionId ?? undefined }\n\t\t\t\t>\n\t\t\t\t\t<BlockContextProvider value={ defaultBlockContext }>\n\t\t\t\t\t\t<BlockEditorProviderComponent\n\t\t\t\t\t\t\tvalue={ blocks }\n\t\t\t\t\t\t\tonChange={ onChange }\n\t\t\t\t\t\t\tonInput={ onInput }\n\t\t\t\t\t\t\tselection={\n\t\t\t\t\t\t\t\tisInRevisionsMode ? undefined : selection\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tonChangeSelection={\n\t\t\t\t\t\t\t\tisInRevisionsMode ? noop : onChangeSelection\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsettings={ blockEditorSettings }\n\t\t\t\t\t\t\tuseSubRegistry={ false }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ children }\n\t\t\t\t\t\t\t{ ! settings.isPreviewMode && (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<PatternsMenuItems />\n\t\t\t\t\t\t\t\t\t<TemplatePartMenuItems />\n\t\t\t\t\t\t\t\t\t{ mode === 'template-locked' && (\n\t\t\t\t\t\t\t\t\t\t<DisableNonPageContentBlocks />\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t{ type === 'wp_navigation' && (\n\t\t\t\t\t\t\t\t\t\t<NavigationBlockEditingMode />\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t<EditorKeyboardShortcuts />\n\t\t\t\t\t\t\t\t\t<KeyboardShortcutHelpModal />\n\t\t\t\t\t\t\t\t\t<BlockRemovalWarnings />\n\t\t\t\t\t\t\t\t\t<StartPageOptions />\n\t\t\t\t\t\t\t\t\t<StartTemplateOptions />\n\t\t\t\t\t\t\t\t\t<PatternRenameModal />\n\t\t\t\t\t\t\t\t\t<PatternDuplicateModal />\n\t\t\t\t\t\t\t\t\t<MediaEditorModalMount />\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t</BlockEditorProviderComponent>\n\t\t\t\t\t</BlockContextProvider>\n\t\t\t\t</EntityProvider>\n\t\t\t</EntityProvider>\n\t\t);\n\t}\n);\n\n/**\n * This component establishes a new post editing context, and serves as the entry point for a new post editor (or post with template editor).\n *\n * It supports a large number of post types, including post, page, templates,\n * custom post types, patterns, template parts.\n *\n * All modification and changes are performed to the `@wordpress/core-data` store.\n *\n * @param {Object} props The component props.\n * @param {Object} [props.post] The post object to edit. This is required.\n * @param {Object} [props.__unstableTemplate] The template object wrapper the edited post.\n * This is optional and can only be used when the post type supports templates (like posts and pages).\n * @param {Object} [props.settings] The settings object to use for the editor.\n * This is optional and can be used to override the default settings.\n * @param {React.ReactNode} [props.children] Children elements for which the BlockEditorProvider context should apply.\n * This is optional.\n *\n * @example\n * ```jsx\n * <EditorProvider\n * post={ post }\n * settings={ settings }\n * __unstableTemplate={ template }\n * >\n * { children }\n * </EditorProvider>\n * ```\n *\n * @return {React.ReactNode} The rendered EditorProvider component.\n */\nexport function EditorProvider( props ) {\n\treturn (\n\t\t<ExperimentalEditorProvider\n\t\t\t{ ...props }\n\t\t\tBlockEditorProviderComponent={ BlockEditorProvider }\n\t\t>\n\t\t\t{ props.children }\n\t\t</ExperimentalEditorProvider>\n\t);\n}\n\nexport default EditorProvider;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport {\n\tuseCallback,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseMemo,\n} from '@wordpress/element';\nimport { useDispatch, useSelect, useRegistry } from '@wordpress/data';\nimport { __ } from '@wordpress/i18n';\nimport {\n\tEntityProvider,\n\tuseEntityBlockEditor,\n\tstore as coreStore,\n} from '@wordpress/core-data';\nimport {\n\tBlockEditorProvider,\n\tBlockContextProvider,\n\tprivateApis as blockEditorPrivateApis,\n} from '@wordpress/block-editor';\nimport { store as noticesStore } from '@wordpress/notices';\nimport { privateApis as editPatternsPrivateApis } from '@wordpress/patterns';\nimport { createBlock } from '@wordpress/blocks';\n\n/**\n * Internal dependencies\n */\nimport withRegistryProvider from './with-registry-provider';\nimport { store as editorStore } from '../../store';\nimport useBlockEditorSettings from './use-block-editor-settings';\nimport { unlock } from '../../lock-unlock';\nimport DisableNonPageContentBlocks from './disable-non-page-content-blocks';\nimport NavigationBlockEditingMode from './navigation-block-editing-mode';\nimport { useHideBlocksFromInserter } from './use-hide-blocks-from-inserter';\nimport { useRevisionBlocks } from './use-revision-blocks';\nimport useCommands from '../commands';\nimport useUploadSaveLock from './use-upload-save-lock';\nimport useNetworkReconnect from './use-network-reconnect';\nimport BlockRemovalWarnings from '../block-removal-warnings';\nimport StartPageOptions from '../start-page-options';\nimport KeyboardShortcutHelpModal from '../keyboard-shortcut-help-modal';\nimport StartTemplateOptions from '../start-template-options';\nimport EditorKeyboardShortcuts from '../global-keyboard-shortcuts';\nimport PatternRenameModal from '../pattern-rename-modal';\nimport PatternDuplicateModal from '../pattern-duplicate-modal';\nimport TemplatePartMenuItems from '../template-part-menu-items';\nimport MediaEditorModalMount from '../media/media-editor-modal';\n\nconst { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis );\nconst { PatternsMenuItems } = unlock( editPatternsPrivateApis );\n\nconst noop = () => {};\n\n/**\n * These are global entities that are only there to split blocks into logical units\n * They don't provide a \"context\" for the current post/page being rendered.\n * So we should not use their ids as post context. This is important to allow post blocks\n * (post content, post title) to be used within them without issues.\n */\nconst NON_CONTEXTUAL_POST_TYPES = [\n\t'wp_block',\n\t'wp_navigation',\n\t'wp_template_part',\n];\n\n/**\n * Depending on the post, template and template mode,\n * returns the appropriate blocks and change handlers for the block editor provider.\n *\n * @param {Array} post Block list.\n * @param {boolean} template Whether the page content has focus (and the surrounding template is inert). If `true` return page content blocks. Default `false`.\n * @param {string} mode Rendering mode.\n *\n * @example\n * ```jsx\n * const [ blocks, onInput, onChange ] = useBlockEditorProps( post, template, mode );\n * ```\n *\n * @return {Array} Block editor props.\n */\nfunction useBlockEditorProps( post, template, mode ) {\n\tconst revisionBlocks = useRevisionBlocks();\n\tconst rootLevelPost = mode === 'template-locked' ? 'template' : 'post';\n\tconst [ postBlocks, onInput, onChange ] = useEntityBlockEditor(\n\t\t'postType',\n\t\tpost.type,\n\t\t{ id: post.id }\n\t);\n\tconst [ templateBlocks, onInputTemplate, onChangeTemplate ] =\n\t\tuseEntityBlockEditor( 'postType', template?.type, {\n\t\t\tid: template?.id,\n\t\t} );\n\tconst maybeNavigationBlocks = useMemo( () => {\n\t\tif ( post.type === 'wp_navigation' ) {\n\t\t\treturn [\n\t\t\t\tcreateBlock( 'core/navigation', {\n\t\t\t\t\tref: post.id,\n\t\t\t\t\t// As the parent editor is locked with `templateLock`, the template locking\n\t\t\t\t\t// must be explicitly \"unset\" on the block itself to allow the user to modify\n\t\t\t\t\t// the block's content.\n\t\t\t\t\ttemplateLock: false,\n\t\t\t\t} ),\n\t\t\t];\n\t\t}\n\t}, [ post.type, post.id ] );\n\n\t// It is important that we don't create a new instance of blocks on every change\n\t// We should only create a new instance if the blocks them selves change, not a dependency of them.\n\tconst blocks = useMemo( () => {\n\t\tif ( maybeNavigationBlocks ) {\n\t\t\treturn maybeNavigationBlocks;\n\t\t}\n\n\t\tif ( rootLevelPost === 'template' ) {\n\t\t\treturn templateBlocks;\n\t\t}\n\n\t\treturn postBlocks;\n\t}, [ maybeNavigationBlocks, rootLevelPost, templateBlocks, postBlocks ] );\n\n\t// In revisions mode, use the revision blocks and disable editing.\n\tif ( revisionBlocks !== null ) {\n\t\treturn [ revisionBlocks, noop, noop ];\n\t}\n\n\t// Handle fallback to postBlocks outside of the above useMemo, to ensure\n\t// that constructed block templates that call `createBlock` are not generated\n\t// too frequently. This ensures that clientIds are stable.\n\tconst disableRootLevelChanges =\n\t\t( !! template && mode === 'template-locked' ) ||\n\t\tpost.type === 'wp_navigation';\n\tif ( disableRootLevelChanges ) {\n\t\treturn [ blocks, noop, noop ];\n\t}\n\n\treturn [\n\t\tblocks,\n\t\trootLevelPost === 'post' ? onInput : onInputTemplate,\n\t\trootLevelPost === 'post' ? onChange : onChangeTemplate,\n\t];\n}\n\n/**\n * This component provides the editor context and manages the state of the block editor.\n *\n * @param {Object} props The component props.\n * @param {Object} props.post The post object.\n * @param {Object} props.settings The editor settings.\n * @param {boolean} props.recovery Indicates if the editor is in recovery mode.\n * @param {Array} props.initialEdits The initial edits for the editor.\n * @param {Object} props.children The child components.\n * @param {Object} [props.BlockEditorProviderComponent] The block editor provider component to use. Defaults to ExperimentalBlockEditorProvider.\n * @param {Object} [props.__unstableTemplate] The template object.\n *\n * @example\n * ```jsx\n * <ExperimentalEditorProvider\n * post={ post }\n * settings={ settings }\n * recovery={ recovery }\n * initialEdits={ initialEdits }\n * __unstableTemplate={ template }\n * >\n * { children }\n * </ExperimentalEditorProvider>\n *\n * @return {Object} The rendered ExperimentalEditorProvider component.\n */\nexport const ExperimentalEditorProvider = withRegistryProvider(\n\t( {\n\t\tpost,\n\t\tsettings,\n\t\trecovery,\n\t\tinitialEdits,\n\t\tchildren,\n\t\tBlockEditorProviderComponent = ExperimentalBlockEditorProvider,\n\t\t__unstableTemplate: template,\n\t} ) => {\n\t\tconst hasTemplate = !! template;\n\t\tconst {\n\t\t\teditorSettings,\n\t\t\tselection,\n\t\t\tisReady,\n\t\t\tmode,\n\t\t\tdefaultMode,\n\t\t\tpostTypeEntities,\n\t\t\tisInRevisionsMode,\n\t\t\tcurrentRevisionId,\n\t\t} = useSelect(\n\t\t\t( select ) => {\n\t\t\t\tconst {\n\t\t\t\t\tgetEditorSettings,\n\t\t\t\t\tgetRenderingMode,\n\t\t\t\t\t__unstableIsEditorReady,\n\t\t\t\t\tgetDefaultRenderingMode,\n\t\t\t\t\tisRevisionsMode: _isRevisionsMode,\n\t\t\t\t\tgetCurrentRevisionId: _getCurrentRevisionId,\n\t\t\t\t} = unlock( select( editorStore ) );\n\t\t\t\tconst { getEntitiesConfig, getEntityRecordEdits } =\n\t\t\t\t\tselect( coreStore );\n\n\t\t\t\tconst _mode = getRenderingMode();\n\t\t\t\tconst _defaultMode = getDefaultRenderingMode( post.type );\n\t\t\t\t/**\n\t\t\t\t * To avoid content \"flash\", wait until rendering mode has been resolved.\n\t\t\t\t * This is important for the initial render of the editor.\n\t\t\t\t *\n\t\t\t\t * - Wait for template to be resolved if the default mode is 'template-locked'.\n\t\t\t\t * - Wait for default mode to be resolved otherwise.\n\t\t\t\t */\n\t\t\t\tconst hasResolvedDefaultMode =\n\t\t\t\t\t_defaultMode === 'template-locked'\n\t\t\t\t\t\t? hasTemplate\n\t\t\t\t\t\t: _defaultMode !== undefined;\n\t\t\t\t// Wait until the default mode is retrieved and start rendering canvas.\n\t\t\t\tconst isRenderingModeReady = _defaultMode !== undefined;\n\n\t\t\t\t// Read selection directly from entity edits using the post prop,\n\t\t\t\t// bypassing getCurrentPostId() which lags behind in useEffect.\n\t\t\t\tconst entityEdits = getEntityRecordEdits(\n\t\t\t\t\t'postType',\n\t\t\t\t\tpost.type,\n\t\t\t\t\tpost.id\n\t\t\t\t);\n\n\t\t\t\treturn {\n\t\t\t\t\teditorSettings: getEditorSettings(),\n\t\t\t\t\tisReady: __unstableIsEditorReady(),\n\t\t\t\t\tmode: isRenderingModeReady ? _mode : undefined,\n\t\t\t\t\tdefaultMode: hasResolvedDefaultMode\n\t\t\t\t\t\t? _defaultMode\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\tselection: entityEdits?.selection,\n\t\t\t\t\tpostTypeEntities:\n\t\t\t\t\t\tpost.type === 'wp_template'\n\t\t\t\t\t\t\t? getEntitiesConfig( 'postType' )\n\t\t\t\t\t\t\t: null,\n\t\t\t\t\tisInRevisionsMode: _isRevisionsMode(),\n\t\t\t\t\tcurrentRevisionId: _getCurrentRevisionId(),\n\t\t\t\t};\n\t\t\t},\n\t\t\t[ post.type, post.id, hasTemplate ]\n\t\t);\n\n\t\tconst shouldRenderTemplate = hasTemplate && mode !== 'post-only';\n\t\tconst rootLevelPost = shouldRenderTemplate ? template : post;\n\t\tconst defaultBlockContext = useMemo( () => {\n\t\t\tconst postContext = {};\n\t\t\t// If it is a template, try to inherit the post type from the name.\n\t\t\tif ( post.type === 'wp_template' ) {\n\t\t\t\tif ( post.slug === 'page' ) {\n\t\t\t\t\tpostContext.postType = 'page';\n\t\t\t\t} else if ( post.slug === 'single' ) {\n\t\t\t\t\tpostContext.postType = 'post';\n\t\t\t\t} else if ( post.slug.split( '-' )[ 0 ] === 'single' ) {\n\t\t\t\t\t// If the slug is single-{postType}, infer the post type from the name.\n\t\t\t\t\tconst postTypeNames =\n\t\t\t\t\t\tpostTypeEntities?.map( ( entity ) => entity.name ) ||\n\t\t\t\t\t\t[];\n\t\t\t\t\tconst match = post.slug.match(\n\t\t\t\t\t\t`^single-(${ postTypeNames.join( '|' ) })(?:-.+)?$`\n\t\t\t\t\t);\n\t\t\t\t\tif ( match ) {\n\t\t\t\t\t\tpostContext.postType = match[ 1 ];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\t! NON_CONTEXTUAL_POST_TYPES.includes( rootLevelPost.type ) ||\n\t\t\t\tshouldRenderTemplate\n\t\t\t) {\n\t\t\t\tpostContext.postId = post.id;\n\t\t\t\tpostContext.postType = post.type;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\t...postContext,\n\t\t\t\ttemplateSlug:\n\t\t\t\t\trootLevelPost.type === 'wp_template'\n\t\t\t\t\t\t? rootLevelPost.slug\n\t\t\t\t\t\t: undefined,\n\t\t\t};\n\t\t}, [\n\t\t\tshouldRenderTemplate,\n\t\t\tpost.id,\n\t\t\tpost.type,\n\t\t\tpost.slug,\n\t\t\trootLevelPost.type,\n\t\t\trootLevelPost.slug,\n\t\t\tpostTypeEntities,\n\t\t] );\n\t\tconst { id, type } = rootLevelPost;\n\t\tconst blockEditorSettings = useBlockEditorSettings(\n\t\t\teditorSettings,\n\t\t\ttype,\n\t\t\tid,\n\t\t\tmode\n\t\t);\n\t\tconst [ blocks, onInput, onChange ] = useBlockEditorProps(\n\t\t\tpost,\n\t\t\ttemplate,\n\t\t\tmode\n\t\t);\n\n\t\tconst {\n\t\t\tupdatePostLock,\n\t\t\tsetupEditor,\n\t\t\tupdateEditorSettings,\n\t\t\tsetCurrentTemplateId,\n\t\t\tsetEditedPost,\n\t\t\tsetRenderingMode,\n\t\t} = unlock( useDispatch( editorStore ) );\n\t\tconst { editEntityRecord } = useDispatch( coreStore );\n\t\tconst registry = useRegistry();\n\n\t\tconst onChangeSelection = useCallback(\n\t\t\t( newSelection ) => {\n\t\t\t\teditEntityRecord(\n\t\t\t\t\t'postType',\n\t\t\t\t\tpost.type,\n\t\t\t\t\tpost.id,\n\t\t\t\t\t{ selection: newSelection },\n\t\t\t\t\t{ undoIgnore: true }\n\t\t\t\t);\n\t\t\t},\n\t\t\t[ editEntityRecord, post.type, post.id ]\n\t\t);\n\t\tconst { createWarningNotice, removeNotice } =\n\t\t\tuseDispatch( noticesStore );\n\n\t\t// Ideally this should be synced on each change and not just something you do once.\n\t\tuseLayoutEffect( () => {\n\t\t\t// Assume that we don't need to initialize in the case of an error recovery.\n\t\t\tif ( recovery ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tupdatePostLock( settings.postLock );\n\t\t\t// `setupEditor` may already have been dispatched by the\n\t\t\t// editor's pre-mount kickoff (see edit-post's\n\t\t\t// `initializeEditor`). Skip the redundant dispatch \u2014 it\n\t\t\t// would otherwise re-parse + reset blocks for new posts.\n\t\t\tif ( ! registry.select( editorStore ).__unstableIsEditorReady() ) {\n\t\t\t\tsetupEditor( post, initialEdits, settings.template );\n\t\t\t}\n\t\t\tif ( settings.autosave ) {\n\t\t\t\tcreateWarningNotice(\n\t\t\t\t\t__(\n\t\t\t\t\t\t'There is an autosave of this post that is more recent than the version below.'\n\t\t\t\t\t),\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'autosave-exists',\n\t\t\t\t\t\tactions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlabel: __( 'View the autosave' ),\n\t\t\t\t\t\t\t\turl: settings.autosave.editLink,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// The dependencies of the hook are omitted deliberately\n\t\t\t// We only want to run setupEditor (with initialEdits) only once per post.\n\t\t\t// A better solution in the future would be to split this effect into multiple ones.\n\t\t}, [] );\n\n\t\t// Synchronizes the active post with the state\n\t\tuseEffect( () => {\n\t\t\tsetEditedPost( post.type, post.id );\n\t\t\tif (\n\t\t\t\ttypeof window !== 'undefined' &&\n\t\t\t\twindow.__experimentalTemplateActivate\n\t\t\t) {\n\t\t\t\t// Clear any notices dependent on the post context.\n\t\t\t\tremoveNotice( 'template-activate-notice' );\n\t\t\t}\n\n\t\t\treturn () => setEditedPost( null, null );\n\t\t}, [ post.type, post.id, setEditedPost, removeNotice ] );\n\n\t\t// Synchronize the editor settings as they change.\n\t\tuseEffect( () => {\n\t\t\tupdateEditorSettings( settings );\n\t\t}, [ settings, updateEditorSettings ] );\n\n\t\t// Synchronizes the active template with the state.\n\t\tuseEffect( () => {\n\t\t\tsetCurrentTemplateId( template?.id );\n\t\t}, [ template?.id, setCurrentTemplateId ] );\n\n\t\t// Sets the right rendering mode when loading the editor.\n\t\tuseEffect( () => {\n\t\t\tif ( defaultMode ) {\n\t\t\t\tsetRenderingMode( defaultMode );\n\t\t\t}\n\t\t}, [ defaultMode, setRenderingMode ] );\n\n\t\tuseHideBlocksFromInserter( post.type, mode );\n\n\t\t// Register the editor commands.\n\t\tuseCommands();\n\n\t\t// Lock post saving when media uploads are in progress (experimental feature).\n\t\tuseUploadSaveLock();\n\n\t\t// Pause/resume media upload queue on network disconnect/reconnect.\n\t\tuseNetworkReconnect();\n\n\t\tif ( ! isReady || ! mode ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn (\n\t\t\t<EntityProvider kind=\"root\" type=\"site\">\n\t\t\t\t<EntityProvider\n\t\t\t\t\tkind=\"postType\"\n\t\t\t\t\ttype={ post.type }\n\t\t\t\t\tid={ post.id }\n\t\t\t\t\trevisionId={ currentRevisionId ?? undefined }\n\t\t\t\t>\n\t\t\t\t\t<BlockContextProvider value={ defaultBlockContext }>\n\t\t\t\t\t\t<BlockEditorProviderComponent\n\t\t\t\t\t\t\tvalue={ blocks }\n\t\t\t\t\t\t\tonChange={ onChange }\n\t\t\t\t\t\t\tonInput={ onInput }\n\t\t\t\t\t\t\tselection={\n\t\t\t\t\t\t\t\tisInRevisionsMode ? undefined : selection\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tonChangeSelection={\n\t\t\t\t\t\t\t\tisInRevisionsMode ? noop : onChangeSelection\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsettings={ blockEditorSettings }\n\t\t\t\t\t\t\tuseSubRegistry={ false }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ children }\n\t\t\t\t\t\t\t{ ! settings.isPreviewMode && (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<PatternsMenuItems />\n\t\t\t\t\t\t\t\t\t<TemplatePartMenuItems />\n\t\t\t\t\t\t\t\t\t{ mode === 'template-locked' && (\n\t\t\t\t\t\t\t\t\t\t<DisableNonPageContentBlocks />\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t{ type === 'wp_navigation' && (\n\t\t\t\t\t\t\t\t\t\t<NavigationBlockEditingMode />\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t<EditorKeyboardShortcuts />\n\t\t\t\t\t\t\t\t\t<KeyboardShortcutHelpModal />\n\t\t\t\t\t\t\t\t\t<BlockRemovalWarnings />\n\t\t\t\t\t\t\t\t\t<StartPageOptions />\n\t\t\t\t\t\t\t\t\t<StartTemplateOptions />\n\t\t\t\t\t\t\t\t\t<PatternRenameModal />\n\t\t\t\t\t\t\t\t\t<PatternDuplicateModal />\n\t\t\t\t\t\t\t\t\t<MediaEditorModalMount />\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t</BlockEditorProviderComponent>\n\t\t\t\t\t</BlockContextProvider>\n\t\t\t\t</EntityProvider>\n\t\t\t</EntityProvider>\n\t\t);\n\t}\n);\n\n/**\n * This component establishes a new post editing context, and serves as the entry point for a new post editor (or post with template editor).\n *\n * It supports a large number of post types, including post, page, templates,\n * custom post types, patterns, template parts.\n *\n * All modification and changes are performed to the `@wordpress/core-data` store.\n *\n * @param {Object} props The component props.\n * @param {Object} [props.post] The post object to edit. This is required.\n * @param {Object} [props.__unstableTemplate] The template object wrapper the edited post.\n * This is optional and can only be used when the post type supports templates (like posts and pages).\n * @param {Object} [props.settings] The settings object to use for the editor.\n * This is optional and can be used to override the default settings.\n * @param {React.ReactNode} [props.children] Children elements for which the BlockEditorProvider context should apply.\n * This is optional.\n *\n * @example\n * ```jsx\n * <EditorProvider\n * post={ post }\n * settings={ settings }\n * __unstableTemplate={ template }\n * >\n * { children }\n * </EditorProvider>\n * ```\n *\n * @return {React.ReactNode} The rendered EditorProvider component.\n */\nexport function EditorProvider( props ) {\n\treturn (\n\t\t<ExperimentalEditorProvider\n\t\t\t{ ...props }\n\t\t\tBlockEditorProviderComponent={ BlockEditorProvider }\n\t\t>\n\t\t\t{ props.children }\n\t\t</ExperimentalEditorProvider>\n\t);\n}\n\nexport default EditorProvider;\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -276,7 +276,7 @@ function useBlockEditorSettings(settings, postType, postId, renderingMode) {
276
276
  );
277
277
  },
278
278
  [mediaEditKey]: hasUploadPermissions ? editMediaEntity : void 0,
279
- [openMediaEditorModalKey]: ({ id, onUpdate }) => openMediaEditorModal({ id, onUpdate }),
279
+ [openMediaEditorModalKey]: ({ id, onUpdate, onClose }) => openMediaEditorModal({ id, onUpdate, onClose }),
280
280
  mediaUpload: hasUploadPermissions ? mediaUpload : void 0,
281
281
  [mediaUploadOnSuccessKey]: hasUploadPermissions ? mediaUploadOnSuccess : void 0,
282
282
  mediaSideload: hasUploadPermissions ? mediaSideload : void 0,