@wordpress/editor 14.41.0 → 14.41.2-next.v.202603161435.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (326) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/build/components/collab-sidebar/index.cjs +7 -4
  3. package/build/components/collab-sidebar/index.cjs.map +2 -2
  4. package/build/components/collab-sidebar/utils.cjs +13 -15
  5. package/build/components/collab-sidebar/utils.cjs.map +2 -2
  6. package/build/components/collaborators-overlay/avatar-iframe-styles.cjs +141 -0
  7. package/build/components/collaborators-overlay/avatar-iframe-styles.cjs.map +7 -0
  8. package/build/components/collaborators-overlay/collaborator-styles.cjs +38 -2
  9. package/build/components/collaborators-overlay/collaborator-styles.cjs.map +2 -2
  10. package/build/components/collaborators-overlay/compute-selection.cjs +181 -0
  11. package/build/components/collaborators-overlay/compute-selection.cjs.map +7 -0
  12. package/build/components/collaborators-overlay/cursor-dom-utils.cjs +243 -0
  13. package/build/components/collaborators-overlay/cursor-dom-utils.cjs.map +7 -0
  14. package/build/components/collaborators-overlay/overlay-iframe-styles.cjs +148 -0
  15. package/build/components/collaborators-overlay/overlay-iframe-styles.cjs.map +7 -0
  16. package/build/components/collaborators-overlay/overlay.cjs +100 -229
  17. package/build/components/collaborators-overlay/overlay.cjs.map +3 -3
  18. package/build/components/collaborators-overlay/use-block-highlighting.cjs +90 -42
  19. package/build/components/collaborators-overlay/use-block-highlighting.cjs.map +2 -2
  20. package/build/components/collaborators-overlay/use-debounced-recompute.cjs +49 -0
  21. package/build/components/collaborators-overlay/use-debounced-recompute.cjs.map +7 -0
  22. package/build/components/collaborators-overlay/use-render-cursors.cjs +80 -171
  23. package/build/components/collaborators-overlay/use-render-cursors.cjs.map +3 -3
  24. package/build/components/collaborators-presence/avatar/component.cjs +121 -0
  25. package/build/components/collaborators-presence/avatar/component.cjs.map +7 -0
  26. package/build/components/collaborators-presence/avatar/index.cjs +37 -0
  27. package/build/components/collaborators-presence/avatar/index.cjs.map +7 -0
  28. package/build/components/collaborators-presence/avatar/types.cjs +19 -0
  29. package/build/components/collaborators-presence/avatar/types.cjs.map +7 -0
  30. package/build/components/collaborators-presence/avatar/use-image-loading-status.cjs +44 -0
  31. package/build/components/collaborators-presence/avatar/use-image-loading-status.cjs.map +7 -0
  32. package/build/components/collaborators-presence/avatar-group/component.cjs +78 -0
  33. package/build/components/collaborators-presence/avatar-group/component.cjs.map +7 -0
  34. package/build/components/collaborators-presence/avatar-group/index.cjs +37 -0
  35. package/build/components/collaborators-presence/avatar-group/index.cjs.map +7 -0
  36. package/build/components/collaborators-presence/avatar-group/types.cjs +19 -0
  37. package/build/components/collaborators-presence/avatar-group/types.cjs.map +7 -0
  38. package/build/components/collaborators-presence/index.cjs +54 -17
  39. package/build/components/collaborators-presence/index.cjs.map +3 -3
  40. package/build/components/collaborators-presence/list.cjs +43 -37
  41. package/build/components/collaborators-presence/list.cjs.map +3 -3
  42. package/build/components/collaborators-presence/use-collaborator-notifications.cjs +79 -107
  43. package/build/components/collaborators-presence/use-collaborator-notifications.cjs.map +3 -3
  44. package/build/components/editor-interface/index.cjs +9 -6
  45. package/build/components/editor-interface/index.cjs.map +2 -2
  46. package/build/components/entities-saved-states/hooks/use-is-dirty.cjs +14 -5
  47. package/build/components/entities-saved-states/hooks/use-is-dirty.cjs.map +2 -2
  48. package/build/components/global-styles/index.cjs +15 -24
  49. package/build/components/global-styles/index.cjs.map +3 -3
  50. package/build/components/global-styles-sidebar/index.cjs +6 -3
  51. package/build/components/global-styles-sidebar/index.cjs.map +2 -2
  52. package/build/components/inserter-sidebar/index.cjs +2 -1
  53. package/build/components/inserter-sidebar/index.cjs.map +2 -2
  54. package/build/components/page-attributes/parent.cjs +2 -1
  55. package/build/components/page-attributes/parent.cjs.map +2 -2
  56. package/build/components/post-revisions-preview/revisions-canvas.cjs +8 -58
  57. package/build/components/post-revisions-preview/revisions-canvas.cjs.map +3 -3
  58. package/build/components/post-revisions-preview/revisions-slider.cjs +5 -1
  59. package/build/components/post-revisions-preview/revisions-slider.cjs.map +2 -2
  60. package/build/components/post-url/panel.cjs +1 -0
  61. package/build/components/post-url/panel.cjs.map +2 -2
  62. package/build/components/preferences-modal/index.cjs +24 -0
  63. package/build/components/preferences-modal/index.cjs.map +2 -2
  64. package/build/components/provider/disable-non-page-content-blocks.cjs +31 -28
  65. package/build/components/provider/disable-non-page-content-blocks.cjs.map +3 -3
  66. package/build/components/provider/index.cjs +17 -5
  67. package/build/components/provider/index.cjs.map +2 -2
  68. package/build/components/provider/use-block-editor-settings.cjs +21 -6
  69. package/build/components/provider/use-block-editor-settings.cjs.map +3 -3
  70. package/build/components/provider/{use-post-content-blocks.cjs → use-post-content-block-types.cjs} +8 -19
  71. package/build/components/provider/use-post-content-block-types.cjs.map +7 -0
  72. package/build/components/provider/use-revision-blocks.cjs +106 -0
  73. package/build/components/provider/use-revision-blocks.cjs.map +7 -0
  74. package/build/components/sidebar/dataform-post-summary.cjs +182 -0
  75. package/build/components/sidebar/dataform-post-summary.cjs.map +7 -0
  76. package/build/components/sidebar/header.cjs +1 -1
  77. package/build/components/sidebar/header.cjs.map +2 -2
  78. package/build/components/sidebar/post-summary.cjs +11 -0
  79. package/build/components/sidebar/post-summary.cjs.map +3 -3
  80. package/build/components/sync-connection-modal/index.cjs +8 -5
  81. package/build/components/sync-connection-modal/index.cjs.map +2 -2
  82. package/build/components/template-content-panel/index.cjs +35 -31
  83. package/build/components/template-content-panel/index.cjs.map +3 -3
  84. package/build/components/visual-editor/index.cjs +1 -1
  85. package/build/components/visual-editor/index.cjs.map +2 -2
  86. package/build/dataviews/store/private-actions.cjs +4 -0
  87. package/build/dataviews/store/private-actions.cjs.map +2 -2
  88. package/build/store/private-actions.cjs +11 -2
  89. package/build/store/private-actions.cjs.map +2 -2
  90. package/build/store/private-selectors.cjs +52 -13
  91. package/build/store/private-selectors.cjs.map +2 -2
  92. package/build/store/reducer.cjs +12 -0
  93. package/build/store/reducer.cjs.map +2 -2
  94. package/build/utils/media-upload/on-success.cjs +46 -0
  95. package/build/utils/media-upload/on-success.cjs.map +7 -0
  96. package/build-module/components/collab-sidebar/index.mjs +7 -4
  97. package/build-module/components/collab-sidebar/index.mjs.map +2 -2
  98. package/build-module/components/collab-sidebar/utils.mjs +13 -15
  99. package/build-module/components/collab-sidebar/utils.mjs.map +2 -2
  100. package/build-module/components/collaborators-overlay/avatar-iframe-styles.mjs +128 -0
  101. package/build-module/components/collaborators-overlay/avatar-iframe-styles.mjs.map +7 -0
  102. package/build-module/components/collaborators-overlay/collaborator-styles.mjs +25 -1
  103. package/build-module/components/collaborators-overlay/collaborator-styles.mjs.map +2 -2
  104. package/build-module/components/collaborators-overlay/compute-selection.mjs +162 -0
  105. package/build-module/components/collaborators-overlay/compute-selection.mjs.map +7 -0
  106. package/build-module/components/collaborators-overlay/cursor-dom-utils.mjs +213 -0
  107. package/build-module/components/collaborators-overlay/cursor-dom-utils.mjs.map +7 -0
  108. package/build-module/components/collaborators-overlay/overlay-iframe-styles.mjs +130 -0
  109. package/build-module/components/collaborators-overlay/overlay-iframe-styles.mjs.map +7 -0
  110. package/build-module/components/collaborators-overlay/overlay.mjs +91 -230
  111. package/build-module/components/collaborators-overlay/overlay.mjs.map +2 -2
  112. package/build-module/components/collaborators-overlay/use-block-highlighting.mjs +91 -43
  113. package/build-module/components/collaborators-overlay/use-block-highlighting.mjs.map +2 -2
  114. package/build-module/components/collaborators-overlay/use-debounced-recompute.mjs +24 -0
  115. package/build-module/components/collaborators-overlay/use-debounced-recompute.mjs.map +7 -0
  116. package/build-module/components/collaborators-overlay/use-render-cursors.mjs +81 -172
  117. package/build-module/components/collaborators-overlay/use-render-cursors.mjs.map +2 -2
  118. package/build-module/components/collaborators-presence/avatar/component.mjs +90 -0
  119. package/build-module/components/collaborators-presence/avatar/component.mjs.map +7 -0
  120. package/build-module/components/collaborators-presence/avatar/index.mjs +6 -0
  121. package/build-module/components/collaborators-presence/avatar/index.mjs.map +7 -0
  122. package/build-module/components/collaborators-presence/avatar/types.mjs +1 -0
  123. package/build-module/components/collaborators-presence/avatar/types.mjs.map +7 -0
  124. package/build-module/components/collaborators-presence/avatar/use-image-loading-status.mjs +19 -0
  125. package/build-module/components/collaborators-presence/avatar/use-image-loading-status.mjs.map +7 -0
  126. package/build-module/components/collaborators-presence/avatar-group/component.mjs +47 -0
  127. package/build-module/components/collaborators-presence/avatar-group/component.mjs.map +7 -0
  128. package/build-module/components/collaborators-presence/avatar-group/index.mjs +6 -0
  129. package/build-module/components/collaborators-presence/avatar-group/index.mjs.map +7 -0
  130. package/build-module/components/collaborators-presence/avatar-group/types.mjs +1 -0
  131. package/build-module/components/collaborators-presence/avatar-group/types.mjs.map +7 -0
  132. package/build-module/components/collaborators-presence/index.mjs +45 -21
  133. package/build-module/components/collaborators-presence/index.mjs.map +2 -2
  134. package/build-module/components/collaborators-presence/list.mjs +35 -43
  135. package/build-module/components/collaborators-presence/list.mjs.map +2 -2
  136. package/build-module/components/collaborators-presence/use-collaborator-notifications.mjs +80 -108
  137. package/build-module/components/collaborators-presence/use-collaborator-notifications.mjs.map +2 -2
  138. package/build-module/components/editor-interface/index.mjs +10 -7
  139. package/build-module/components/editor-interface/index.mjs.map +2 -2
  140. package/build-module/components/entities-saved-states/hooks/use-is-dirty.mjs +14 -5
  141. package/build-module/components/entities-saved-states/hooks/use-is-dirty.mjs.map +2 -2
  142. package/build-module/components/global-styles/index.mjs +15 -24
  143. package/build-module/components/global-styles/index.mjs.map +2 -2
  144. package/build-module/components/global-styles-sidebar/index.mjs +6 -3
  145. package/build-module/components/global-styles-sidebar/index.mjs.map +2 -2
  146. package/build-module/components/inserter-sidebar/index.mjs +2 -1
  147. package/build-module/components/inserter-sidebar/index.mjs.map +2 -2
  148. package/build-module/components/page-attributes/parent.mjs +2 -1
  149. package/build-module/components/page-attributes/parent.mjs.map +2 -2
  150. package/build-module/components/post-revisions-preview/revisions-canvas.mjs +10 -63
  151. package/build-module/components/post-revisions-preview/revisions-canvas.mjs.map +2 -2
  152. package/build-module/components/post-revisions-preview/revisions-slider.mjs +5 -1
  153. package/build-module/components/post-revisions-preview/revisions-slider.mjs.map +2 -2
  154. package/build-module/components/post-url/panel.mjs +1 -0
  155. package/build-module/components/post-url/panel.mjs.map +2 -2
  156. package/build-module/components/preferences-modal/index.mjs +24 -0
  157. package/build-module/components/preferences-modal/index.mjs.map +2 -2
  158. package/build-module/components/provider/disable-non-page-content-blocks.mjs +31 -28
  159. package/build-module/components/provider/disable-non-page-content-blocks.mjs.map +2 -2
  160. package/build-module/components/provider/index.mjs +17 -5
  161. package/build-module/components/provider/index.mjs.map +2 -2
  162. package/build-module/components/provider/use-block-editor-settings.mjs +21 -6
  163. package/build-module/components/provider/use-block-editor-settings.mjs.map +2 -2
  164. package/build-module/components/provider/use-post-content-block-types.mjs +23 -0
  165. package/build-module/components/provider/use-post-content-block-types.mjs.map +7 -0
  166. package/build-module/components/provider/use-revision-blocks.mjs +81 -0
  167. package/build-module/components/provider/use-revision-blocks.mjs.map +7 -0
  168. package/build-module/components/sidebar/dataform-post-summary.mjs +151 -0
  169. package/build-module/components/sidebar/dataform-post-summary.mjs.map +7 -0
  170. package/build-module/components/sidebar/header.mjs +1 -1
  171. package/build-module/components/sidebar/header.mjs.map +2 -2
  172. package/build-module/components/sidebar/post-summary.mjs +11 -0
  173. package/build-module/components/sidebar/post-summary.mjs.map +2 -2
  174. package/build-module/components/sync-connection-modal/index.mjs +8 -5
  175. package/build-module/components/sync-connection-modal/index.mjs.map +2 -2
  176. package/build-module/components/template-content-panel/index.mjs +25 -31
  177. package/build-module/components/template-content-panel/index.mjs.map +2 -2
  178. package/build-module/components/visual-editor/index.mjs +1 -1
  179. package/build-module/components/visual-editor/index.mjs.map +2 -2
  180. package/build-module/dataviews/store/private-actions.mjs +8 -1
  181. package/build-module/dataviews/store/private-actions.mjs.map +2 -2
  182. package/build-module/store/private-actions.mjs +10 -2
  183. package/build-module/store/private-actions.mjs.map +2 -2
  184. package/build-module/store/private-selectors.mjs +50 -12
  185. package/build-module/store/private-selectors.mjs.map +2 -2
  186. package/build-module/store/reducer.mjs +11 -0
  187. package/build-module/store/reducer.mjs.map +2 -2
  188. package/build-module/utils/media-upload/on-success.mjs +25 -0
  189. package/build-module/utils/media-upload/on-success.mjs.map +7 -0
  190. package/build-style/style-rtl.css +961 -159
  191. package/build-style/style.css +961 -159
  192. package/build-types/components/collab-sidebar/index.d.ts.map +1 -1
  193. package/build-types/components/collab-sidebar/utils.d.ts.map +1 -1
  194. package/build-types/components/collaborators-overlay/avatar-iframe-styles.d.ts +11 -0
  195. package/build-types/components/collaborators-overlay/avatar-iframe-styles.d.ts.map +1 -0
  196. package/build-types/components/collaborators-overlay/collaborator-styles.d.ts +17 -2
  197. package/build-types/components/collaborators-overlay/collaborator-styles.d.ts.map +1 -1
  198. package/build-types/components/collaborators-overlay/compute-selection.d.ts +24 -0
  199. package/build-types/components/collaborators-overlay/compute-selection.d.ts.map +1 -0
  200. package/build-types/components/collaborators-overlay/cursor-dom-utils.d.ts +72 -0
  201. package/build-types/components/collaborators-overlay/cursor-dom-utils.d.ts.map +1 -0
  202. package/build-types/components/collaborators-overlay/overlay-iframe-styles.d.ts +6 -0
  203. package/build-types/components/collaborators-overlay/overlay-iframe-styles.d.ts.map +1 -0
  204. package/build-types/components/collaborators-overlay/overlay.d.ts.map +1 -1
  205. package/build-types/components/collaborators-overlay/use-block-highlighting.d.ts +21 -5
  206. package/build-types/components/collaborators-overlay/use-block-highlighting.d.ts.map +1 -1
  207. package/build-types/components/collaborators-overlay/use-debounced-recompute.d.ts +10 -0
  208. package/build-types/components/collaborators-overlay/use-debounced-recompute.d.ts.map +1 -0
  209. package/build-types/components/collaborators-overlay/use-render-cursors.d.ts +6 -1
  210. package/build-types/components/collaborators-overlay/use-render-cursors.d.ts.map +1 -1
  211. package/build-types/components/collaborators-presence/avatar/component.d.ts +7 -0
  212. package/build-types/components/collaborators-presence/avatar/component.d.ts.map +1 -0
  213. package/build-types/components/collaborators-presence/avatar/index.d.ts +3 -0
  214. package/build-types/components/collaborators-presence/avatar/index.d.ts.map +1 -0
  215. package/build-types/components/collaborators-presence/avatar/types.d.ts +66 -0
  216. package/build-types/components/collaborators-presence/avatar/types.d.ts.map +1 -0
  217. package/build-types/components/collaborators-presence/avatar/use-image-loading-status.d.ts +17 -0
  218. package/build-types/components/collaborators-presence/avatar/use-image-loading-status.d.ts.map +1 -0
  219. package/build-types/components/collaborators-presence/avatar-group/component.d.ts +7 -0
  220. package/build-types/components/collaborators-presence/avatar-group/component.d.ts.map +1 -0
  221. package/build-types/components/collaborators-presence/avatar-group/index.d.ts +3 -0
  222. package/build-types/components/collaborators-presence/avatar-group/index.d.ts.map +1 -0
  223. package/build-types/components/collaborators-presence/avatar-group/types.d.ts +14 -0
  224. package/build-types/components/collaborators-presence/avatar-group/types.d.ts.map +1 -0
  225. package/build-types/components/collaborators-presence/index.d.ts.map +1 -1
  226. package/build-types/components/collaborators-presence/list.d.ts +2 -1
  227. package/build-types/components/collaborators-presence/list.d.ts.map +1 -1
  228. package/build-types/components/collaborators-presence/use-collaborator-notifications.d.ts.map +1 -1
  229. package/build-types/components/editor-interface/index.d.ts.map +1 -1
  230. package/build-types/components/entities-saved-states/hooks/use-is-dirty.d.ts.map +1 -1
  231. package/build-types/components/global-styles/index.d.ts +2 -1
  232. package/build-types/components/global-styles/index.d.ts.map +1 -1
  233. package/build-types/components/global-styles-sidebar/index.d.ts.map +1 -1
  234. package/build-types/components/inserter-sidebar/index.d.ts.map +1 -1
  235. package/build-types/components/page-attributes/parent.d.ts.map +1 -1
  236. package/build-types/components/post-author/hook.d.ts +1 -1
  237. package/build-types/components/post-revisions-preview/revisions-canvas.d.ts +2 -5
  238. package/build-types/components/post-revisions-preview/revisions-canvas.d.ts.map +1 -1
  239. package/build-types/components/post-revisions-preview/revisions-slider.d.ts.map +1 -1
  240. package/build-types/components/provider/disable-non-page-content-blocks.d.ts.map +1 -1
  241. package/build-types/components/provider/index.d.ts.map +1 -1
  242. package/build-types/components/provider/use-block-editor-settings.d.ts.map +1 -1
  243. package/build-types/components/provider/use-post-content-block-types.d.ts +9 -0
  244. package/build-types/components/provider/use-post-content-block-types.d.ts.map +1 -0
  245. package/build-types/components/provider/use-revision-blocks.d.ts +10 -0
  246. package/build-types/components/provider/use-revision-blocks.d.ts.map +1 -0
  247. package/build-types/components/sidebar/dataform-post-summary.d.ts +4 -0
  248. package/build-types/components/sidebar/dataform-post-summary.d.ts.map +1 -0
  249. package/build-types/components/sidebar/post-summary.d.ts.map +1 -1
  250. package/build-types/components/sync-connection-modal/index.d.ts.map +1 -1
  251. package/build-types/components/template-content-panel/index.d.ts.map +1 -1
  252. package/build-types/dataviews/store/private-actions.d.ts.map +1 -1
  253. package/build-types/store/private-actions.d.ts +7 -0
  254. package/build-types/store/private-actions.d.ts.map +1 -1
  255. package/build-types/store/private-selectors.d.ts +7 -0
  256. package/build-types/store/private-selectors.d.ts.map +1 -1
  257. package/build-types/store/reducer.d.ts +14 -3
  258. package/build-types/store/reducer.d.ts.map +1 -1
  259. package/build-types/utils/media-upload/on-success.d.ts +9 -0
  260. package/build-types/utils/media-upload/on-success.d.ts.map +1 -0
  261. package/package.json +45 -44
  262. package/src/components/collab-sidebar/index.js +7 -4
  263. package/src/components/collab-sidebar/utils.js +9 -10
  264. package/src/components/collaborators-overlay/avatar-iframe-styles.ts +134 -0
  265. package/src/components/collaborators-overlay/collaborator-styles.ts +43 -2
  266. package/src/components/collaborators-overlay/compute-selection.ts +307 -0
  267. package/src/components/collaborators-overlay/cursor-dom-utils.ts +382 -0
  268. package/src/components/collaborators-overlay/overlay-iframe-styles.ts +131 -0
  269. package/src/components/collaborators-overlay/overlay.tsx +86 -226
  270. package/src/components/collaborators-overlay/use-block-highlighting.ts +147 -63
  271. package/src/components/collaborators-overlay/use-debounced-recompute.ts +32 -0
  272. package/src/components/collaborators-overlay/use-render-cursors.ts +113 -279
  273. package/src/components/collaborators-presence/avatar/component.tsx +123 -0
  274. package/src/components/collaborators-presence/avatar/index.ts +2 -0
  275. package/src/components/collaborators-presence/avatar/styles.scss +184 -0
  276. package/src/components/collaborators-presence/avatar/test/index.tsx +389 -0
  277. package/src/components/collaborators-presence/avatar/types.ts +66 -0
  278. package/src/components/collaborators-presence/avatar/use-image-loading-status.ts +36 -0
  279. package/src/components/collaborators-presence/avatar-group/component.tsx +55 -0
  280. package/src/components/collaborators-presence/avatar-group/index.ts +2 -0
  281. package/src/components/collaborators-presence/avatar-group/styles.scss +33 -0
  282. package/src/components/collaborators-presence/avatar-group/test/index.tsx +139 -0
  283. package/src/components/collaborators-presence/avatar-group/types.ts +13 -0
  284. package/src/components/collaborators-presence/index.tsx +34 -11
  285. package/src/components/collaborators-presence/list.tsx +44 -40
  286. package/src/components/collaborators-presence/styles/collaborators-list.scss +26 -19
  287. package/src/components/collaborators-presence/styles/collaborators-presence.scss +6 -2
  288. package/src/components/collaborators-presence/test/use-collaborator-notifications.ts +188 -246
  289. package/src/components/collaborators-presence/use-collaborator-notifications.ts +109 -166
  290. package/src/components/document-bar/style.scss +1 -1
  291. package/src/components/editor-interface/index.js +8 -6
  292. package/src/components/entities-saved-states/hooks/use-is-dirty.js +14 -5
  293. package/src/components/global-styles/index.js +20 -27
  294. package/src/components/global-styles-sidebar/index.js +3 -0
  295. package/src/components/inserter-sidebar/index.js +4 -1
  296. package/src/components/page-attributes/parent.js +2 -1
  297. package/src/components/post-publish-panel/test/__snapshots__/index.js.snap +2 -2
  298. package/src/components/post-revisions-preview/revisions-canvas.js +15 -84
  299. package/src/components/post-revisions-preview/revisions-slider.js +6 -1
  300. package/src/components/post-url/panel.js +1 -0
  301. package/src/components/post-url/style.scss +5 -0
  302. package/src/components/preferences-modal/index.js +18 -0
  303. package/src/components/provider/disable-non-page-content-blocks.js +42 -40
  304. package/src/components/provider/index.js +20 -2
  305. package/src/components/provider/use-block-editor-settings.js +24 -8
  306. package/src/components/provider/use-post-content-block-types.js +30 -0
  307. package/src/components/provider/use-revision-blocks.js +105 -0
  308. package/src/components/sidebar/dataform-post-summary.js +170 -0
  309. package/src/components/sidebar/header.js +1 -1
  310. package/src/components/sidebar/post-summary.js +15 -0
  311. package/src/components/sync-connection-modal/index.js +12 -6
  312. package/src/components/sync-connection-modal/style.scss +5 -0
  313. package/src/components/template-content-panel/index.js +30 -38
  314. package/src/components/visual-editor/index.js +1 -1
  315. package/src/dataviews/store/private-actions.ts +14 -0
  316. package/src/store/private-actions.js +21 -2
  317. package/src/store/private-selectors.js +75 -10
  318. package/src/store/reducer.js +19 -0
  319. package/src/style.scss +3 -0
  320. package/src/utils/media-upload/on-success.js +34 -0
  321. package/build/components/provider/use-post-content-blocks.cjs.map +0 -7
  322. package/build-module/components/provider/use-post-content-blocks.mjs +0 -34
  323. package/build-module/components/provider/use-post-content-blocks.mjs.map +0 -7
  324. package/build-types/components/provider/use-post-content-blocks.d.ts +0 -2
  325. package/build-types/components/provider/use-post-content-blocks.d.ts.map +0 -1
  326. package/src/components/provider/use-post-content-blocks.js +0 -42
@@ -7,13 +7,9 @@ import clsx from 'clsx';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { Spinner } from '@wordpress/components';
10
- import {
11
- privateApis as blockEditorPrivateApis,
12
- store as blockEditorStore,
13
- } from '@wordpress/block-editor';
14
- import { createBlock, parse } from '@wordpress/blocks';
10
+ import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
15
11
  import { useSelect } from '@wordpress/data';
16
- import { useEffect, useMemo, useRef } from '@wordpress/element';
12
+ import { useEffect } from '@wordpress/element';
17
13
  import { addFilter } from '@wordpress/hooks';
18
14
 
19
15
  /**
@@ -27,12 +23,8 @@ import {
27
23
  unregisterDiffFormatTypes,
28
24
  } from './diff-format-types';
29
25
  import { useDiffMarkers } from './diff-markers';
30
- import { preserveClientIds } from './preserve-client-ids';
31
- import { diffRevisionContent } from './block-diff';
32
26
 
33
- const { ExperimentalBlockEditorProvider, usePrivateStyleOverride } = unlock(
34
- blockEditorPrivateApis
35
- );
27
+ const { usePrivateStyleOverride } = unlock( blockEditorPrivateApis );
36
28
 
37
29
  // SVG filter for removed blocks: grayscale + red tint
38
30
  const REVISION_REMOVED_FILTER_SVG = `
@@ -150,12 +142,11 @@ function CanvasContent( { showDiff } ) {
150
142
 
151
143
  /**
152
144
  * Canvas component that renders a post revision in read-only mode.
145
+ * Block preparation and settings are handled by the parent EditorProvider.
153
146
  *
154
- * @param {Object} props Component props.
155
- * @param {boolean} props.showDiff Whether to show diff highlighting.
156
147
  * @return {React.JSX.Element} The revisions canvas component.
157
148
  */
158
- export default function RevisionsCanvas( { showDiff } ) {
149
+ export default function RevisionsCanvas() {
159
150
  useEffect( () => {
160
151
  registerDiffFormatTypes();
161
152
  return () => {
@@ -163,83 +154,23 @@ export default function RevisionsCanvas( { showDiff } ) {
163
154
  };
164
155
  }, [] );
165
156
 
166
- const { revision, previousRevision, postType, blockEditorSettings } =
167
- useSelect( ( select ) => {
168
- const {
169
- getCurrentRevision,
170
- getPreviousRevision,
171
- getCurrentPostType,
172
- } = unlock( select( editorStore ) );
173
- return {
174
- revision: getCurrentRevision(),
175
- previousRevision: getPreviousRevision(),
176
- postType: getCurrentPostType(),
177
- blockEditorSettings: select( blockEditorStore ).getSettings(),
178
- };
179
- }, [] );
180
-
181
- // Track previously rendered blocks to preserve clientIds between renders.
182
- const previousBlocksRef = useRef( [] );
183
-
184
- const blocks = useMemo( () => {
185
- const currentContent = revision?.content?.raw ?? '';
186
-
187
- let parsedBlocks;
188
- if ( showDiff ) {
189
- const previousContent = previousRevision?.content?.raw || '';
190
- // diffRevisionContent handles both normal diffing and the case
191
- // where there's no previous revision (oldest revision shows all as added).
192
- parsedBlocks = diffRevisionContent(
193
- currentContent,
194
- previousContent
195
- );
196
- } else {
197
- // When diff is disabled, just parse the current revision content.
198
- parsedBlocks = parse( currentContent );
199
- }
200
-
201
- if ( postType === 'wp_navigation' ) {
202
- parsedBlocks = [
203
- createBlock(
204
- 'core/navigation',
205
- { templateLock: false },
206
- parsedBlocks
207
- ),
208
- ];
209
- }
210
-
211
- // Preserve clientIds from previous render to prevent React unmount/remount.
212
- const blocksWithStableIds = preserveClientIds(
213
- parsedBlocks,
214
- previousBlocksRef.current
157
+ const { revision, showDiff } = useSelect( ( select ) => {
158
+ const { getCurrentRevision, isShowingRevisionDiff } = unlock(
159
+ select( editorStore )
215
160
  );
216
-
217
- // Update ref for next render.
218
- previousBlocksRef.current = blocksWithStableIds;
219
-
220
- return blocksWithStableIds;
221
- }, [
222
- revision?.content?.raw,
223
- previousRevision?.content?.raw,
224
- postType,
225
- showDiff,
226
- ] );
227
-
228
- const settings = useMemo(
229
- () => ( {
230
- ...blockEditorSettings,
231
- isPreviewMode: true,
232
- } ),
233
- [ blockEditorSettings ]
234
- );
161
+ return {
162
+ revision: getCurrentRevision(),
163
+ showDiff: isShowingRevisionDiff(),
164
+ };
165
+ }, [] );
235
166
 
236
167
  return revision ? (
237
- <ExperimentalBlockEditorProvider value={ blocks } settings={ settings }>
168
+ <>
238
169
  <DiffStyleOverrides showDiff={ showDiff } />
239
170
  <div className="editor-revisions-canvas__content">
240
171
  <CanvasContent showDiff={ showDiff } />
241
172
  </div>
242
- </ExperimentalBlockEditorProvider>
173
+ </>
243
174
  ) : (
244
175
  <div className="editor-revisions-canvas__loading">
245
176
  <Spinner />
@@ -35,7 +35,12 @@ function RevisionsSlider() {
35
35
  }
36
36
 
37
37
  const entityConfig = getEntityConfig( 'postType', postType );
38
- const query = { per_page: -1, context: 'edit' };
38
+ const query = {
39
+ per_page: -1,
40
+ context: 'edit',
41
+ _fields:
42
+ 'id,date,author,meta,title.raw,excerpt.raw,content.raw',
43
+ };
39
44
  return {
40
45
  revisions: getRevisions( 'postType', postType, postId, query ),
41
46
  isLoading: isResolving( 'getRevisions', [
@@ -90,6 +90,7 @@ function PostURLToggle( { isOpen, onClick } ) {
90
90
  return (
91
91
  <Button
92
92
  size="compact"
93
+ className="editor-post-url__panel-toggle"
93
94
  variant="tertiary"
94
95
  aria-expanded={ isOpen }
95
96
  aria-label={
@@ -47,6 +47,11 @@
47
47
  padding-inline-start: 0 !important;
48
48
  }
49
49
 
50
+ .editor-post-url__panel-toggle,
51
+ .editor-post-parent__panel-toggle {
52
+ word-break: break-word;
53
+ }
54
+
50
55
  .editor-post-url__intro {
51
56
  margin: 0;
52
57
  }
@@ -120,6 +120,24 @@ function PreferencesModalContents( { extraSections = {} } ) {
120
120
  ) }
121
121
  label={ __( 'Show starter patterns' ) }
122
122
  />
123
+ <PreferenceToggleControl
124
+ scope="core"
125
+ featureName="showCollaborationCursor"
126
+ help={ __(
127
+ 'Show your own avatar inside blocks during collaborative editing sessions.'
128
+ ) }
129
+ label={ __( 'Show avatar in blocks' ) }
130
+ />
131
+ <PreferenceToggleControl
132
+ scope="core"
133
+ featureName="showCollaborationNotifications"
134
+ help={ __(
135
+ 'Show notifications when collaborators join, leave, or save the post.'
136
+ ) }
137
+ label={ __(
138
+ 'Show collaboration notifications'
139
+ ) }
140
+ />
123
141
  </PreferencesModalSection>
124
142
  <PreferencesModalSection
125
143
  title={ __( 'Document settings' ) }
@@ -8,21 +8,33 @@ import { useEffect } from '@wordpress/element';
8
8
  /**
9
9
  * Internal dependencies
10
10
  */
11
- import usePostContentBlocks from './use-post-content-blocks';
11
+ import { store as editorStore } from '../../store';
12
+ import { unlock } from '../../lock-unlock';
13
+ import usePostContentBlockTypes from './use-post-content-block-types';
12
14
 
13
15
  /**
14
16
  * Component that when rendered, makes it so that the site editor allows only
15
17
  * page content to be edited.
16
18
  */
17
19
  export default function DisableNonPageContentBlocks() {
18
- const contentOnlyIds = usePostContentBlocks();
19
- const { templateParts } = useSelect( ( select ) => {
20
- const { getBlocksByName } = select( blockEditorStore );
21
- return {
22
- templateParts: getBlocksByName( 'core/template-part' ),
23
- };
24
- }, [] );
25
- const disabledIds = useSelect(
20
+ const postContentBlockTypes = usePostContentBlockTypes();
21
+ const { contentOnlyIds, templateParts } = useSelect(
22
+ ( select ) => {
23
+ const { getPostBlocksByName } = unlock( select( editorStore ) );
24
+ const { getBlocksByName } = select( blockEditorStore );
25
+ return {
26
+ contentOnlyIds: getPostBlocksByName( postContentBlockTypes ),
27
+ templateParts: getBlocksByName( 'core/template-part' ),
28
+ };
29
+ },
30
+ [ postContentBlockTypes ]
31
+ );
32
+ // This is a separate `useSelect` because `templatePartChildren` is
33
+ // derived via flatMap, which always produces a new array. Combining it
34
+ // with the above subscription causes an infinite render loop: the new
35
+ // array fails useSelect's shallow equality check → re-render → effect
36
+ // fires setBlockEditingMode → store changes → useSelect re-runs → …
37
+ const templatePartChildren = useSelect(
26
38
  ( select ) => {
27
39
  const { getBlockOrder } = select( blockEditorStore );
28
40
  return templateParts.flatMap( ( clientId ) =>
@@ -34,14 +46,11 @@ export default function DisableNonPageContentBlocks() {
34
46
 
35
47
  const registry = useRegistry();
36
48
 
37
- // The code here is split into multiple `useEffects` calls.
38
- // This is done to avoid setting/unsetting block editing modes multiple times unnecessarily.
39
- //
40
- // For example, the block editing mode of the root block (clientId: '') only
41
- // needs to be set once, not when `contentOnlyIds` or `disabledIds` change.
42
- //
43
- // It's also unlikely that these different types of blocks are being inserted
44
- // or removed at the same time, so using different effects reflects that.
49
+ // The effects below are split so that changes to one group of blocks
50
+ // don't cause unnecessary set/unset cycles for the others. For example,
51
+ // the root block ('') editing mode only needs to be set once.
52
+ // Child blocks of templates and templateParts are also loaded separately,
53
+ // so these are kept in separate effects.
45
54
  useEffect( () => {
46
55
  const { setBlockEditingMode, unsetBlockEditingMode } =
47
56
  registry.dispatch( blockEditorStore );
@@ -53,25 +62,6 @@ export default function DisableNonPageContentBlocks() {
53
62
  };
54
63
  }, [ registry ] );
55
64
 
56
- useEffect( () => {
57
- const { setBlockEditingMode, unsetBlockEditingMode } =
58
- registry.dispatch( blockEditorStore );
59
-
60
- registry.batch( () => {
61
- for ( const clientId of contentOnlyIds ) {
62
- setBlockEditingMode( clientId, 'contentOnly' );
63
- }
64
- } );
65
-
66
- return () => {
67
- registry.batch( () => {
68
- for ( const clientId of contentOnlyIds ) {
69
- unsetBlockEditingMode( clientId );
70
- }
71
- } );
72
- };
73
- }, [ contentOnlyIds, registry ] );
74
-
75
65
  useEffect( () => {
76
66
  const { setBlockEditingMode, unsetBlockEditingMode } =
77
67
  registry.dispatch( blockEditorStore );
@@ -95,20 +85,32 @@ export default function DisableNonPageContentBlocks() {
95
85
  const { setBlockEditingMode, unsetBlockEditingMode } =
96
86
  registry.dispatch( blockEditorStore );
97
87
 
88
+ const contentOnlySet = new Set( contentOnlyIds );
89
+
98
90
  registry.batch( () => {
99
- for ( const clientId of disabledIds ) {
100
- setBlockEditingMode( clientId, 'disabled' );
91
+ for ( const clientId of contentOnlyIds ) {
92
+ setBlockEditingMode( clientId, 'contentOnly' );
93
+ }
94
+ for ( const clientId of templatePartChildren ) {
95
+ if ( ! contentOnlySet.has( clientId ) ) {
96
+ setBlockEditingMode( clientId, 'disabled' );
97
+ }
101
98
  }
102
99
  } );
103
100
 
104
101
  return () => {
105
102
  registry.batch( () => {
106
- for ( const clientId of disabledIds ) {
103
+ for ( const clientId of contentOnlyIds ) {
107
104
  unsetBlockEditingMode( clientId );
108
105
  }
106
+ for ( const clientId of templatePartChildren ) {
107
+ if ( ! contentOnlySet.has( clientId ) ) {
108
+ unsetBlockEditingMode( clientId );
109
+ }
110
+ }
109
111
  } );
110
112
  };
111
- }, [ disabledIds, registry ] );
113
+ }, [ contentOnlyIds, templatePartChildren, registry ] );
112
114
 
113
115
  return null;
114
116
  }
@@ -34,6 +34,7 @@ import { unlock } from '../../lock-unlock';
34
34
  import DisableNonPageContentBlocks from './disable-non-page-content-blocks';
35
35
  import NavigationBlockEditingMode from './navigation-block-editing-mode';
36
36
  import { useHideBlocksFromInserter } from './use-hide-blocks-from-inserter';
37
+ import { useRevisionBlocks } from './use-revision-blocks';
37
38
  import useCommands from '../commands';
38
39
  import useUploadSaveLock from './use-upload-save-lock';
39
40
  import BlockRemovalWarnings from '../block-removal-warnings';
@@ -78,6 +79,7 @@ const NON_CONTEXTUAL_POST_TYPES = [
78
79
  * @return {Array} Block editor props.
79
80
  */
80
81
  function useBlockEditorProps( post, template, mode ) {
82
+ const revisionBlocks = useRevisionBlocks();
81
83
  const rootLevelPost = mode === 'template-locked' ? 'template' : 'post';
82
84
  const [ postBlocks, onInput, onChange ] = useEntityBlockEditor(
83
85
  'postType',
@@ -116,6 +118,11 @@ function useBlockEditorProps( post, template, mode ) {
116
118
  return postBlocks;
117
119
  }, [ maybeNavigationBlocks, rootLevelPost, templateBlocks, postBlocks ] );
118
120
 
121
+ // In revisions mode, use the revision blocks and disable editing.
122
+ if ( revisionBlocks !== null ) {
123
+ return [ revisionBlocks, noop, noop ];
124
+ }
125
+
119
126
  // Handle fallback to postBlocks outside of the above useMemo, to ensure
120
127
  // that constructed block templates that call `createBlock` are not generated
121
128
  // too frequently. This ensures that clientIds are stable.
@@ -177,6 +184,8 @@ export const ExperimentalEditorProvider = withRegistryProvider(
177
184
  mode,
178
185
  defaultMode,
179
186
  postTypeEntities,
187
+ isInRevisionsMode,
188
+ currentRevisionId,
180
189
  } = useSelect(
181
190
  ( select ) => {
182
191
  const {
@@ -184,6 +193,8 @@ export const ExperimentalEditorProvider = withRegistryProvider(
184
193
  getRenderingMode,
185
194
  __unstableIsEditorReady,
186
195
  getDefaultRenderingMode,
196
+ isRevisionsMode: _isRevisionsMode,
197
+ getCurrentRevisionId: _getCurrentRevisionId,
187
198
  } = unlock( select( editorStore ) );
188
199
  const { getEntitiesConfig, getEntityRecordEdits } =
189
200
  select( coreStore );
@@ -224,6 +235,8 @@ export const ExperimentalEditorProvider = withRegistryProvider(
224
235
  post.type === 'wp_template'
225
236
  ? getEntitiesConfig( 'postType' )
226
237
  : null,
238
+ isInRevisionsMode: _isRevisionsMode(),
239
+ currentRevisionId: _getCurrentRevisionId(),
227
240
  };
228
241
  },
229
242
  [ post.type, post.id, hasTemplate ]
@@ -418,14 +431,19 @@ export const ExperimentalEditorProvider = withRegistryProvider(
418
431
  kind="postType"
419
432
  type={ post.type }
420
433
  id={ post.id }
434
+ revisionId={ currentRevisionId ?? undefined }
421
435
  >
422
436
  <BlockContextProvider value={ defaultBlockContext }>
423
437
  <BlockEditorProviderComponent
424
438
  value={ blocks }
425
439
  onChange={ onChange }
426
440
  onInput={ onInput }
427
- selection={ selection }
428
- onChangeSelection={ onChangeSelection }
441
+ selection={
442
+ isInRevisionsMode ? undefined : selection
443
+ }
444
+ onChangeSelection={
445
+ isInRevisionsMode ? noop : onChangeSelection
446
+ }
429
447
  settings={ blockEditorSettings }
430
448
  useSubRegistry={ false }
431
449
  >
@@ -23,6 +23,7 @@ import {
23
23
  */
24
24
  import inserterMediaCategories from '../media-categories';
25
25
  import { mediaUpload } from '../../utils';
26
+ import mediaUploadOnSuccess from '../../utils/media-upload/on-success';
26
27
  import { default as mediaSideload } from '../../utils/media-sideload';
27
28
  import { store as editorStore } from '../../store';
28
29
  import { unlock } from '../../lock-unlock';
@@ -103,6 +104,8 @@ const {
103
104
  isIsolatedEditorKey,
104
105
  deviceTypeKey,
105
106
  isNavigationOverlayContextKey,
107
+ isNavigationPostEditorKey,
108
+ mediaUploadOnSuccessKey,
106
109
  } = unlock( privateApis );
107
110
 
108
111
  /**
@@ -137,6 +140,7 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
137
140
  sectionRootClientId,
138
141
  deviceType,
139
142
  isNavigationOverlayContext,
143
+ isRevisionsMode,
140
144
  } = useSelect(
141
145
  ( select ) => {
142
146
  const {
@@ -148,7 +152,9 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
148
152
  } = select( coreStore );
149
153
  const { get } = select( preferencesStore );
150
154
  const { getBlockTypes } = select( blocksStore );
151
- const { getDeviceType } = unlock( select( editorStore ) );
155
+ const { getDeviceType, isRevisionsMode: _isRevisionsMode } = unlock(
156
+ select( editorStore )
157
+ );
152
158
  const { getBlocksByName, getBlockAttributes } =
153
159
  select( blockEditorStore );
154
160
  const siteSettings = canUser( 'read', {
@@ -216,6 +222,7 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
216
222
  postId
217
223
  )?.area === 'navigation-overlay'
218
224
  : false,
225
+ isRevisionsMode: _isRevisionsMode(),
219
226
  };
220
227
  },
221
228
  [ postType, postId, isLargeViewport, renderingMode ]
@@ -307,12 +314,9 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
307
314
  return useMemo( () => {
308
315
  const blockEditorSettings = {
309
316
  ...Object.fromEntries(
310
- Object.entries( settings )
311
- .filter( ( [ key ] ) =>
312
- BLOCK_EDITOR_SETTINGS.includes( key )
313
- )
314
- // Exclude onNavigateToEntityRecord since we're wrapping it
315
- .filter( ( [ key ] ) => key !== 'onNavigateToEntityRecord' )
317
+ Object.entries( settings ).filter( ( [ key ] ) =>
318
+ BLOCK_EDITOR_SETTINGS.includes( key )
319
+ )
316
320
  ),
317
321
  [ globalStylesDataKey ]: globalStylesData,
318
322
  [ globalStylesLinksDataKey ]: globalStylesLinksData,
@@ -324,7 +328,6 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
324
328
  hasFixedToolbar,
325
329
  isDistractionFree,
326
330
  keepCaretInsideBlock,
327
- onNavigateToEntityRecord: settings.onNavigateToEntityRecord,
328
331
  [ getMediaSelectKey ]: ( select, attachmentId ) => {
329
332
  return select( coreStore ).getEntityRecord(
330
333
  'postType',
@@ -336,6 +339,9 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
336
339
  ? editMediaEntity
337
340
  : undefined,
338
341
  mediaUpload: hasUploadPermissions ? mediaUpload : undefined,
342
+ [ mediaUploadOnSuccessKey ]: hasUploadPermissions
343
+ ? mediaUploadOnSuccess
344
+ : undefined,
339
345
  mediaSideload: hasUploadPermissions ? mediaSideload : undefined,
340
346
  __experimentalBlockPatterns: blockPatterns,
341
347
  [ selectBlockPatternsKey ]: ( select ) => {
@@ -386,12 +392,22 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
386
392
  'wp_block',
387
393
  'wp_navigation',
388
394
  ].includes( postType ),
395
+ [ isNavigationPostEditorKey ]: postType === 'wp_navigation',
396
+ // When in template-locked mode (e.g., "Show Template" in the post editor),
397
+ // don't treat template parts as contentOnly sections.
398
+ disableContentOnlyForTemplateParts:
399
+ renderingMode === 'template-locked',
389
400
  ...( deviceType ? { [ deviceTypeKey ]: deviceType } : {} ),
390
401
  [ isNavigationOverlayContextKey ]: isNavigationOverlayContext,
391
402
  };
392
403
 
404
+ if ( isRevisionsMode ) {
405
+ blockEditorSettings.isPreviewMode = true;
406
+ }
407
+
393
408
  return blockEditorSettings;
394
409
  }, [
410
+ isRevisionsMode,
395
411
  allowedBlockTypes,
396
412
  allowRightClickOverrides,
397
413
  focusMode,
@@ -0,0 +1,30 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useMemo } from '@wordpress/element';
5
+ import { applyFilters } from '@wordpress/hooks';
6
+
7
+ const POST_CONTENT_BLOCK_TYPES = [
8
+ 'core/post-title',
9
+ 'core/post-featured-image',
10
+ 'core/post-content',
11
+ ];
12
+
13
+ /**
14
+ * Returns the list of post content block types, including any added via the
15
+ * `editor.postContentBlockTypes` filter. The result is memoized so it can be
16
+ * used as a stable dependency in `useSelect` calls.
17
+ *
18
+ * @return {string[]} Block type names considered post content.
19
+ */
20
+ export default function usePostContentBlockTypes() {
21
+ return useMemo(
22
+ () => [
23
+ ...applyFilters(
24
+ 'editor.postContentBlockTypes',
25
+ POST_CONTENT_BLOCK_TYPES
26
+ ),
27
+ ],
28
+ []
29
+ );
30
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect } from '@wordpress/data';
5
+ import { useMemo, useRef } from '@wordpress/element';
6
+ import { createBlock, parse } from '@wordpress/blocks';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import { store as editorStore } from '../../store';
12
+ import { unlock } from '../../lock-unlock';
13
+ import { diffRevisionContent } from '../post-revisions-preview/block-diff';
14
+ import { preserveClientIds } from '../post-revisions-preview/preserve-client-ids';
15
+
16
+ /**
17
+ * Hook that computes revision blocks when in revisions mode.
18
+ *
19
+ * Returns `null` when not in revisions mode, `[]` when loading,
20
+ * or the computed blocks array when ready.
21
+ *
22
+ * @return {Array|null} The revision blocks, or null if not in revisions mode.
23
+ */
24
+ export function useRevisionBlocks() {
25
+ const {
26
+ isInRevisionsMode,
27
+ showDiff,
28
+ revision,
29
+ previousRevision,
30
+ postType,
31
+ } = useSelect( ( select ) => {
32
+ const {
33
+ isRevisionsMode,
34
+ isShowingRevisionDiff,
35
+ getCurrentRevision,
36
+ getPreviousRevision,
37
+ } = unlock( select( editorStore ) );
38
+ const { getCurrentPostType } = select( editorStore );
39
+
40
+ const inRevisions = isRevisionsMode();
41
+ return {
42
+ isInRevisionsMode: inRevisions,
43
+ showDiff: isShowingRevisionDiff(),
44
+ revision: inRevisions ? getCurrentRevision() : undefined,
45
+ previousRevision: inRevisions ? getPreviousRevision() : undefined,
46
+ postType: getCurrentPostType(),
47
+ };
48
+ }, [] );
49
+
50
+ // Track previously rendered blocks to preserve clientIds between renders.
51
+ const previousBlocksRef = useRef( [] );
52
+
53
+ const blocks = useMemo( () => {
54
+ if ( ! isInRevisionsMode ) {
55
+ // Clear the ref when exiting revisions mode.
56
+ previousBlocksRef.current = [];
57
+ return null;
58
+ }
59
+
60
+ // Revision not loaded yet.
61
+ if ( ! revision ) {
62
+ return [];
63
+ }
64
+
65
+ const currentContent = revision?.content?.raw ?? '';
66
+
67
+ let parsedBlocks;
68
+ if ( showDiff ) {
69
+ const previousContent = previousRevision?.content?.raw || '';
70
+ parsedBlocks = diffRevisionContent(
71
+ currentContent,
72
+ previousContent
73
+ );
74
+ } else {
75
+ parsedBlocks = parse( currentContent );
76
+ }
77
+
78
+ if ( postType === 'wp_navigation' ) {
79
+ parsedBlocks = [
80
+ createBlock(
81
+ 'core/navigation',
82
+ { templateLock: false },
83
+ parsedBlocks
84
+ ),
85
+ ];
86
+ }
87
+
88
+ const blocksWithStableIds = preserveClientIds(
89
+ parsedBlocks,
90
+ previousBlocksRef.current
91
+ );
92
+ previousBlocksRef.current = blocksWithStableIds;
93
+
94
+ return blocksWithStableIds;
95
+ }, [
96
+ isInRevisionsMode,
97
+ revision,
98
+ revision?.content?.raw,
99
+ previousRevision?.content?.raw,
100
+ postType,
101
+ showDiff,
102
+ ] );
103
+
104
+ return blocks;
105
+ }