@wordpress/editor 14.41.2-next.v.202603161435.0 → 14.43.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 (311) hide show
  1. package/CHANGELOG.md +3 -1
  2. package/build/components/collaborators-overlay/compute-selection.cjs +10 -10
  3. package/build/components/collaborators-overlay/compute-selection.cjs.map +2 -2
  4. package/build/components/collaborators-overlay/cursor-registry.cjs +86 -0
  5. package/build/components/collaborators-overlay/cursor-registry.cjs.map +7 -0
  6. package/build/components/collaborators-overlay/index.cjs +7 -2
  7. package/build/components/collaborators-overlay/index.cjs.map +2 -2
  8. package/build/components/collaborators-overlay/overlay-iframe-styles.cjs +1 -1
  9. package/build/components/collaborators-overlay/overlay-iframe-styles.cjs.map +2 -2
  10. package/build/components/collaborators-overlay/overlay.cjs +42 -1
  11. package/build/components/collaborators-overlay/overlay.cjs.map +2 -2
  12. package/build/components/collaborators-overlay/timing-utils.cjs +46 -0
  13. package/build/components/collaborators-overlay/timing-utils.cjs.map +7 -0
  14. package/build/components/collaborators-overlay/use-render-cursors.cjs +1 -1
  15. package/build/components/collaborators-overlay/use-render-cursors.cjs.map +2 -2
  16. package/build/components/collaborators-presence/index.cjs +14 -4
  17. package/build/components/collaborators-presence/index.cjs.map +2 -2
  18. package/build/components/collaborators-presence/list.cjs +20 -4
  19. package/build/components/collaborators-presence/list.cjs.map +2 -2
  20. package/build/components/post-card-panel/index.cjs +4 -15
  21. package/build/components/post-card-panel/index.cjs.map +2 -2
  22. package/build/components/post-content-information/index.cjs +10 -13
  23. package/build/components/post-content-information/index.cjs.map +2 -2
  24. package/build/components/post-locked-modal/index.cjs +16 -3
  25. package/build/components/post-locked-modal/index.cjs.map +2 -2
  26. package/build/components/post-revisions-panel/index.cjs +164 -0
  27. package/build/components/post-revisions-panel/index.cjs.map +7 -0
  28. package/build/components/post-revisions-preview/block-diff.cjs +39 -11
  29. package/build/components/post-revisions-preview/block-diff.cjs.map +2 -2
  30. package/build/components/post-revisions-preview/diff-markers.cjs +2 -2
  31. package/build/components/post-revisions-preview/diff-markers.cjs.map +2 -2
  32. package/build/components/post-revisions-preview/revisions-canvas.cjs +1 -1
  33. package/build/components/post-revisions-preview/revisions-canvas.cjs.map +2 -2
  34. package/build/components/post-revisions-preview/revisions-slider.cjs +24 -5
  35. package/build/components/post-revisions-preview/revisions-slider.cjs.map +2 -2
  36. package/build/components/post-template/block-theme.cjs +7 -4
  37. package/build/components/post-template/block-theme.cjs.map +2 -2
  38. package/build/components/post-template/create-new-template-modal.cjs +39 -46
  39. package/build/components/post-template/create-new-template-modal.cjs.map +2 -2
  40. package/build/components/post-template/hooks.cjs +91 -8
  41. package/build/components/post-template/hooks.cjs.map +2 -2
  42. package/build/components/post-template/panel.cjs +5 -42
  43. package/build/components/post-template/panel.cjs.map +3 -3
  44. package/build/components/post-template/swap-template-button.cjs +31 -20
  45. package/build/components/post-template/swap-template-button.cjs.map +2 -2
  46. package/build/components/preferences-modal/index.cjs +35 -27
  47. package/build/components/preferences-modal/index.cjs.map +2 -2
  48. package/build/components/provider/use-block-editor-settings.cjs +2 -0
  49. package/build/components/provider/use-block-editor-settings.cjs.map +3 -3
  50. package/build/components/revision-block-diff/index.cjs +61 -0
  51. package/build/components/revision-block-diff/index.cjs.map +7 -0
  52. package/build/components/revision-diff-panel/index.cjs +68 -0
  53. package/build/components/revision-diff-panel/index.cjs.map +7 -0
  54. package/build/components/revision-fields-diff/index.cjs +96 -0
  55. package/build/components/revision-fields-diff/index.cjs.map +7 -0
  56. package/build/components/sidebar/dataform-post-summary.cjs +25 -55
  57. package/build/components/sidebar/dataform-post-summary.cjs.map +2 -2
  58. package/build/components/sidebar/index.cjs +30 -23
  59. package/build/components/sidebar/index.cjs.map +3 -3
  60. package/build/components/sidebar/post-revision-summary.cjs +74 -0
  61. package/build/components/sidebar/post-revision-summary.cjs.map +7 -0
  62. package/build/components/sidebar/post-summary.cjs +35 -42
  63. package/build/components/sidebar/post-summary.cjs.map +3 -3
  64. package/build/components/style-book/index.cjs +4 -3
  65. package/build/components/style-book/index.cjs.map +2 -2
  66. package/build/components/{sync-connection-modal → sync-connection-error-modal}/index.cjs +89 -80
  67. package/build/components/sync-connection-error-modal/index.cjs.map +7 -0
  68. package/build/components/{sync-connection-modal → sync-connection-error-modal}/use-retry-countdown.cjs +14 -27
  69. package/build/components/sync-connection-error-modal/use-retry-countdown.cjs.map +7 -0
  70. package/build/components/template-actions-panel/block-theme-content.cjs +188 -0
  71. package/build/components/template-actions-panel/block-theme-content.cjs.map +7 -0
  72. package/build/components/template-actions-panel/classic-theme-content.cjs +159 -0
  73. package/build/components/template-actions-panel/classic-theme-content.cjs.map +7 -0
  74. package/build/components/template-actions-panel/index.cjs +59 -0
  75. package/build/components/template-actions-panel/index.cjs.map +7 -0
  76. package/build/components/visual-editor/index.cjs +2 -2
  77. package/build/components/visual-editor/index.cjs.map +2 -2
  78. package/build/dataviews/store/private-actions.cjs +2 -0
  79. package/build/dataviews/store/private-actions.cjs.map +2 -2
  80. package/build/store/actions.cjs +1 -3
  81. package/build/store/actions.cjs.map +2 -2
  82. package/build/store/private-actions.cjs +21 -2
  83. package/build/store/private-actions.cjs.map +2 -2
  84. package/build/store/private-selectors.cjs +40 -15
  85. package/build/store/private-selectors.cjs.map +2 -2
  86. package/build/utils/media-finalize/index.cjs +43 -0
  87. package/build/utils/media-finalize/index.cjs.map +7 -0
  88. package/build/utils/sync-error-messages.cjs +29 -16
  89. package/build/utils/sync-error-messages.cjs.map +3 -3
  90. package/build-module/components/collaborators-overlay/compute-selection.mjs +10 -10
  91. package/build-module/components/collaborators-overlay/compute-selection.mjs.map +2 -2
  92. package/build-module/components/collaborators-overlay/cursor-registry.mjs +61 -0
  93. package/build-module/components/collaborators-overlay/cursor-registry.mjs.map +7 -0
  94. package/build-module/components/collaborators-overlay/index.mjs +7 -2
  95. package/build-module/components/collaborators-overlay/index.mjs.map +2 -2
  96. package/build-module/components/collaborators-overlay/overlay-iframe-styles.mjs +1 -1
  97. package/build-module/components/collaborators-overlay/overlay-iframe-styles.mjs.map +2 -2
  98. package/build-module/components/collaborators-overlay/overlay.mjs +43 -2
  99. package/build-module/components/collaborators-overlay/overlay.mjs.map +2 -2
  100. package/build-module/components/collaborators-overlay/timing-utils.mjs +21 -0
  101. package/build-module/components/collaborators-overlay/timing-utils.mjs.map +7 -0
  102. package/build-module/components/collaborators-overlay/use-render-cursors.mjs +1 -1
  103. package/build-module/components/collaborators-overlay/use-render-cursors.mjs.map +2 -2
  104. package/build-module/components/collaborators-presence/index.mjs +14 -4
  105. package/build-module/components/collaborators-presence/index.mjs.map +2 -2
  106. package/build-module/components/collaborators-presence/list.mjs +20 -4
  107. package/build-module/components/collaborators-presence/list.mjs.map +2 -2
  108. package/build-module/components/post-card-panel/index.mjs +6 -17
  109. package/build-module/components/post-card-panel/index.mjs.map +2 -2
  110. package/build-module/components/post-content-information/index.mjs +6 -13
  111. package/build-module/components/post-content-information/index.mjs.map +2 -2
  112. package/build-module/components/post-locked-modal/index.mjs +16 -3
  113. package/build-module/components/post-locked-modal/index.mjs.map +2 -2
  114. package/build-module/components/post-revisions-panel/index.mjs +139 -0
  115. package/build-module/components/post-revisions-panel/index.mjs.map +7 -0
  116. package/build-module/components/post-revisions-preview/block-diff.mjs +39 -11
  117. package/build-module/components/post-revisions-preview/block-diff.mjs.map +2 -2
  118. package/build-module/components/post-revisions-preview/diff-markers.mjs +2 -2
  119. package/build-module/components/post-revisions-preview/diff-markers.mjs.map +2 -2
  120. package/build-module/components/post-revisions-preview/revisions-canvas.mjs +1 -1
  121. package/build-module/components/post-revisions-preview/revisions-canvas.mjs.map +2 -2
  122. package/build-module/components/post-revisions-preview/revisions-slider.mjs +24 -5
  123. package/build-module/components/post-revisions-preview/revisions-slider.mjs.map +2 -2
  124. package/build-module/components/post-template/block-theme.mjs +7 -4
  125. package/build-module/components/post-template/block-theme.mjs.map +2 -2
  126. package/build-module/components/post-template/create-new-template-modal.mjs +39 -46
  127. package/build-module/components/post-template/create-new-template-modal.mjs.map +2 -2
  128. package/build-module/components/post-template/hooks.mjs +90 -8
  129. package/build-module/components/post-template/hooks.mjs.map +2 -2
  130. package/build-module/components/post-template/panel.mjs +5 -42
  131. package/build-module/components/post-template/panel.mjs.map +2 -2
  132. package/build-module/components/post-template/swap-template-button.mjs +27 -20
  133. package/build-module/components/post-template/swap-template-button.mjs.map +2 -2
  134. package/build-module/components/preferences-modal/index.mjs +35 -27
  135. package/build-module/components/preferences-modal/index.mjs.map +2 -2
  136. package/build-module/components/provider/use-block-editor-settings.mjs +2 -0
  137. package/build-module/components/provider/use-block-editor-settings.mjs.map +2 -2
  138. package/build-module/components/revision-block-diff/index.mjs +30 -0
  139. package/build-module/components/revision-block-diff/index.mjs.map +7 -0
  140. package/build-module/components/revision-diff-panel/index.mjs +37 -0
  141. package/build-module/components/revision-diff-panel/index.mjs.map +7 -0
  142. package/build-module/components/revision-fields-diff/index.mjs +65 -0
  143. package/build-module/components/revision-fields-diff/index.mjs.map +7 -0
  144. package/build-module/components/sidebar/dataform-post-summary.mjs +25 -55
  145. package/build-module/components/sidebar/dataform-post-summary.mjs.map +2 -2
  146. package/build-module/components/sidebar/index.mjs +30 -23
  147. package/build-module/components/sidebar/index.mjs.map +2 -2
  148. package/build-module/components/sidebar/post-revision-summary.mjs +43 -0
  149. package/build-module/components/sidebar/post-revision-summary.mjs.map +7 -0
  150. package/build-module/components/sidebar/post-summary.mjs +31 -42
  151. package/build-module/components/sidebar/post-summary.mjs.map +2 -2
  152. package/build-module/components/style-book/index.mjs +4 -3
  153. package/build-module/components/style-book/index.mjs.map +2 -2
  154. package/build-module/components/sync-connection-error-modal/index.mjs +177 -0
  155. package/build-module/components/sync-connection-error-modal/index.mjs.map +7 -0
  156. package/build-module/components/sync-connection-error-modal/use-retry-countdown.mjs +36 -0
  157. package/build-module/components/sync-connection-error-modal/use-retry-countdown.mjs.map +7 -0
  158. package/build-module/components/template-actions-panel/block-theme-content.mjs +167 -0
  159. package/build-module/components/template-actions-panel/block-theme-content.mjs.map +7 -0
  160. package/build-module/components/template-actions-panel/classic-theme-content.mjs +138 -0
  161. package/build-module/components/template-actions-panel/classic-theme-content.mjs.map +7 -0
  162. package/build-module/components/template-actions-panel/index.mjs +28 -0
  163. package/build-module/components/template-actions-panel/index.mjs.map +7 -0
  164. package/build-module/components/visual-editor/index.mjs +2 -2
  165. package/build-module/components/visual-editor/index.mjs.map +2 -2
  166. package/build-module/dataviews/store/private-actions.mjs +5 -1
  167. package/build-module/dataviews/store/private-actions.mjs.map +2 -2
  168. package/build-module/store/actions.mjs +1 -3
  169. package/build-module/store/actions.mjs.map +2 -2
  170. package/build-module/store/private-actions.mjs +21 -2
  171. package/build-module/store/private-actions.mjs.map +2 -2
  172. package/build-module/store/private-selectors.mjs +40 -15
  173. package/build-module/store/private-selectors.mjs.map +2 -2
  174. package/build-module/utils/media-finalize/index.mjs +12 -0
  175. package/build-module/utils/media-finalize/index.mjs.map +7 -0
  176. package/build-module/utils/sync-error-messages.mjs +24 -16
  177. package/build-module/utils/sync-error-messages.mjs.map +3 -3
  178. package/build-style/style-rtl.css +135 -50
  179. package/build-style/style.css +135 -50
  180. package/build-types/components/collaborators-overlay/cursor-registry.d.ts +36 -0
  181. package/build-types/components/collaborators-overlay/cursor-registry.d.ts.map +1 -0
  182. package/build-types/components/collaborators-overlay/index.d.ts +7 -4
  183. package/build-types/components/collaborators-overlay/index.d.ts.map +1 -1
  184. package/build-types/components/collaborators-overlay/overlay-iframe-styles.d.ts +1 -1
  185. package/build-types/components/collaborators-overlay/overlay-iframe-styles.d.ts.map +1 -1
  186. package/build-types/components/collaborators-overlay/overlay.d.ts +4 -1
  187. package/build-types/components/collaborators-overlay/overlay.d.ts.map +1 -1
  188. package/build-types/components/collaborators-overlay/timing-utils.d.ts +11 -0
  189. package/build-types/components/collaborators-overlay/timing-utils.d.ts.map +1 -0
  190. package/build-types/components/collaborators-presence/index.d.ts.map +1 -1
  191. package/build-types/components/collaborators-presence/list.d.ts +4 -1
  192. package/build-types/components/collaborators-presence/list.d.ts.map +1 -1
  193. package/build-types/components/post-card-panel/index.d.ts.map +1 -1
  194. package/build-types/components/post-content-information/index.d.ts +4 -1
  195. package/build-types/components/post-content-information/index.d.ts.map +1 -1
  196. package/build-types/components/post-locked-modal/index.d.ts +2 -2
  197. package/build-types/components/post-locked-modal/index.d.ts.map +1 -1
  198. package/build-types/components/post-revisions-panel/index.d.ts +2 -0
  199. package/build-types/components/post-revisions-panel/index.d.ts.map +1 -0
  200. package/build-types/components/post-revisions-preview/block-diff.d.ts.map +1 -1
  201. package/build-types/components/post-revisions-preview/revisions-slider.d.ts.map +1 -1
  202. package/build-types/components/post-template/block-theme.d.ts +1 -3
  203. package/build-types/components/post-template/block-theme.d.ts.map +1 -1
  204. package/build-types/components/post-template/create-new-template-modal.d.ts.map +1 -1
  205. package/build-types/components/post-template/hooks.d.ts +2 -1
  206. package/build-types/components/post-template/hooks.d.ts.map +1 -1
  207. package/build-types/components/post-template/panel.d.ts.map +1 -1
  208. package/build-types/components/post-template/swap-template-button.d.ts +4 -0
  209. package/build-types/components/post-template/swap-template-button.d.ts.map +1 -1
  210. package/build-types/components/provider/use-block-editor-settings.d.ts.map +1 -1
  211. package/build-types/components/revision-block-diff/index.d.ts +6 -0
  212. package/build-types/components/revision-block-diff/index.d.ts.map +1 -0
  213. package/build-types/components/revision-diff-panel/index.d.ts +14 -0
  214. package/build-types/components/revision-diff-panel/index.d.ts.map +1 -0
  215. package/build-types/components/revision-fields-diff/index.d.ts +6 -0
  216. package/build-types/components/revision-fields-diff/index.d.ts.map +1 -0
  217. package/build-types/components/sidebar/dataform-post-summary.d.ts.map +1 -1
  218. package/build-types/components/sidebar/index.d.ts.map +1 -1
  219. package/build-types/components/sidebar/post-revision-summary.d.ts +2 -0
  220. package/build-types/components/sidebar/post-revision-summary.d.ts.map +1 -0
  221. package/build-types/components/sidebar/post-summary.d.ts +3 -0
  222. package/build-types/components/sidebar/post-summary.d.ts.map +1 -1
  223. package/build-types/components/style-book/index.d.ts +2 -1
  224. package/build-types/components/style-book/index.d.ts.map +1 -1
  225. package/build-types/components/sync-connection-error-modal/index.d.ts +22 -0
  226. package/build-types/components/sync-connection-error-modal/index.d.ts.map +1 -0
  227. package/build-types/components/sync-connection-error-modal/use-retry-countdown.d.ts +11 -0
  228. package/build-types/components/sync-connection-error-modal/use-retry-countdown.d.ts.map +1 -0
  229. package/build-types/components/template-actions-panel/block-theme-content.d.ts +2 -0
  230. package/build-types/components/template-actions-panel/block-theme-content.d.ts.map +1 -0
  231. package/build-types/components/template-actions-panel/classic-theme-content.d.ts +2 -0
  232. package/build-types/components/template-actions-panel/classic-theme-content.d.ts.map +1 -0
  233. package/build-types/components/template-actions-panel/index.d.ts +2 -0
  234. package/build-types/components/template-actions-panel/index.d.ts.map +1 -0
  235. package/build-types/dataviews/store/private-actions.d.ts.map +1 -1
  236. package/build-types/store/actions.d.ts.map +1 -1
  237. package/build-types/store/private-actions.d.ts.map +1 -1
  238. package/build-types/store/private-selectors.d.ts.map +1 -1
  239. package/build-types/utils/media-finalize/index.d.ts +2 -0
  240. package/build-types/utils/media-finalize/index.d.ts.map +1 -0
  241. package/build-types/utils/sync-error-messages.d.ts +17 -3
  242. package/build-types/utils/sync-error-messages.d.ts.map +1 -1
  243. package/package.json +45 -44
  244. package/src/components/collaborators-overlay/compute-selection.ts +13 -13
  245. package/src/components/collaborators-overlay/cursor-registry.ts +96 -0
  246. package/src/components/collaborators-overlay/index.tsx +12 -4
  247. package/src/components/collaborators-overlay/overlay-iframe-styles.ts +1 -1
  248. package/src/components/collaborators-overlay/overlay.tsx +64 -1
  249. package/src/components/collaborators-overlay/timing-utils.ts +30 -0
  250. package/src/components/collaborators-overlay/use-render-cursors.ts +1 -1
  251. package/src/components/collaborators-presence/index.tsx +9 -1
  252. package/src/components/collaborators-presence/list.tsx +25 -1
  253. package/src/components/post-card-panel/index.js +7 -21
  254. package/src/components/post-content-information/index.js +5 -16
  255. package/src/components/post-locked-modal/index.js +21 -3
  256. package/src/components/post-revisions-panel/index.js +151 -0
  257. package/src/components/post-revisions-panel/style.scss +16 -0
  258. package/src/components/post-revisions-preview/block-diff.js +59 -20
  259. package/src/components/post-revisions-preview/diff-markers.js +2 -2
  260. package/src/components/post-revisions-preview/revisions-canvas.js +1 -1
  261. package/src/components/post-revisions-preview/revisions-slider.js +29 -7
  262. package/src/components/post-revisions-preview/test/block-diff.js +69 -31
  263. package/src/components/post-template/block-theme.js +4 -1
  264. package/src/components/post-template/create-new-template-modal.js +1 -4
  265. package/src/components/post-template/hooks.js +107 -9
  266. package/src/components/post-template/panel.js +5 -59
  267. package/src/components/post-template/style.scss +0 -6
  268. package/src/components/post-template/swap-template-button.js +30 -21
  269. package/src/components/preferences-modal/index.js +37 -25
  270. package/src/components/provider/use-block-editor-settings.js +2 -0
  271. package/src/components/revision-block-diff/index.js +39 -0
  272. package/src/components/revision-diff-panel/index.js +59 -0
  273. package/src/components/revision-diff-panel/style.scss +13 -0
  274. package/src/components/revision-fields-diff/index.js +91 -0
  275. package/src/components/sidebar/dataform-post-summary.js +45 -68
  276. package/src/components/sidebar/index.js +35 -22
  277. package/src/components/sidebar/post-revision-summary.js +50 -0
  278. package/src/components/sidebar/post-summary.js +22 -40
  279. package/src/components/sidebar/style.scss +7 -0
  280. package/src/components/style-book/index.js +4 -2
  281. package/src/components/sync-connection-error-modal/index.tsx +265 -0
  282. package/src/components/sync-connection-error-modal/style.scss +14 -0
  283. package/src/components/sync-connection-error-modal/use-retry-countdown.ts +57 -0
  284. package/src/components/template-actions-panel/block-theme-content.js +196 -0
  285. package/src/components/template-actions-panel/classic-theme-content.js +170 -0
  286. package/src/components/template-actions-panel/index.js +32 -0
  287. package/src/components/template-actions-panel/style.scss +39 -0
  288. package/src/components/visual-editor/index.js +2 -2
  289. package/src/dataviews/store/private-actions.ts +6 -0
  290. package/src/store/actions.js +1 -4
  291. package/src/store/private-actions.js +24 -3
  292. package/src/store/private-selectors.js +46 -16
  293. package/src/style.scss +4 -1
  294. package/src/utils/media-finalize/index.js +11 -0
  295. package/src/utils/media-finalize/test/index.js +34 -0
  296. package/src/utils/sync-error-messages.ts +72 -0
  297. package/src/utils/test/sync-error-messages.js +9 -32
  298. package/build/components/sync-connection-modal/index.cjs.map +0 -7
  299. package/build/components/sync-connection-modal/use-retry-countdown.cjs.map +0 -7
  300. package/build-module/components/sync-connection-modal/index.mjs +0 -170
  301. package/build-module/components/sync-connection-modal/index.mjs.map +0 -7
  302. package/build-module/components/sync-connection-modal/use-retry-countdown.mjs +0 -49
  303. package/build-module/components/sync-connection-modal/use-retry-countdown.mjs.map +0 -7
  304. package/build-types/components/sync-connection-modal/index.d.ts +0 -8
  305. package/build-types/components/sync-connection-modal/index.d.ts.map +0 -1
  306. package/build-types/components/sync-connection-modal/use-retry-countdown.d.ts +0 -9
  307. package/build-types/components/sync-connection-modal/use-retry-countdown.d.ts.map +0 -1
  308. package/src/components/sync-connection-modal/index.js +0 -206
  309. package/src/components/sync-connection-modal/style.scss +0 -14
  310. package/src/components/sync-connection-modal/use-retry-countdown.js +0 -70
  311. package/src/utils/sync-error-messages.js +0 -58
@@ -119,7 +119,7 @@ export const OVERLAY_IFRAME_STYLES = `
119
119
  outline-style: solid;
120
120
  outline-width: calc(var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1));
121
121
  outline-offset: calc(-1 * var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1));
122
- box-shadow: inset 0 0 0 calc(var(--wp-admin-border-width-focus, ${ BORDER_WIDTH_FOCUS_FALLBACK }) + ${ BORDER_WIDTH }) ${ WHITE }, 0 0 0 ${ BORDER_WIDTH } ${ WHITE }, ${ ELEVATION_X_SMALL };
122
+ box-shadow: inset 0 0 0 calc((var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1)) + 0.5px) rgba(${ WHITE }, 0.7);
123
123
  z-index: 1;
124
124
  }
125
125
  @media (prefers-reduced-motion: reduce) {
@@ -1,19 +1,29 @@
1
1
  import { useResizeObserver, useMergeRefs } from '@wordpress/compose';
2
- import { useCallback, useEffect, useState } from '@wordpress/element';
2
+ import { useCallback, useEffect, useRef, useState } from '@wordpress/element';
3
3
  import { __ } from '@wordpress/i18n';
4
4
 
5
5
  import Avatar from '../collaborators-presence/avatar';
6
6
  import { AVATAR_IFRAME_STYLES } from './avatar-iframe-styles';
7
7
  import { OVERLAY_IFRAME_STYLES } from './overlay-iframe-styles';
8
+ import { setDelayedInterval } from './timing-utils';
8
9
  import { useBlockHighlighting } from './use-block-highlighting';
9
10
  import { useRenderCursors } from './use-render-cursors';
11
+ import { type CursorRegistry } from './cursor-registry';
10
12
 
13
+ // Milliseconds to wait after a change before recomputing cursor positions.
11
14
  const RERENDER_DELAY_MS = 500;
12
15
 
16
+ // Periodically recompute cursor positions to account for DOM layout
17
+ // changes that don't trigger awareness state updates (e.g. a collaborator
18
+ // applying formatting shifts text but the cursor's logical position is
19
+ // unchanged). Only active when remote cursors are visible.
20
+ const CURSOR_REDRAW_INTERVAL_MS = 10_000;
21
+
13
22
  interface OverlayProps {
14
23
  blockEditorDocument?: Document;
15
24
  postId: number | null;
16
25
  postType: string | null;
26
+ cursorRegistry?: CursorRegistry;
17
27
  }
18
28
 
19
29
  /**
@@ -23,12 +33,14 @@ interface OverlayProps {
23
33
  * @param props.blockEditorDocument - The block editor document.
24
34
  * @param props.postId - The ID of the post.
25
35
  * @param props.postType - The type of the post.
36
+ * @param props.cursorRegistry - The shared cursor registry.
26
37
  * @return The Overlay component.
27
38
  */
28
39
  export function Overlay( {
29
40
  blockEditorDocument,
30
41
  postId,
31
42
  postType,
43
+ cursorRegistry,
32
44
  }: OverlayProps ) {
33
45
  // Use state for the overlay element so that the hook re-runs once the ref is attached.
34
46
  const [ overlayElement, setOverlayElement ] =
@@ -68,12 +80,62 @@ export function Overlay( {
68
80
  };
69
81
  }, [ rerenderCursorsAfterDelay, rerenderHighlightsAfterDelay ] );
70
82
 
83
+ useEffect( () => {
84
+ if ( cursors.length === 0 ) {
85
+ return;
86
+ }
87
+
88
+ return setDelayedInterval(
89
+ rerenderCursorsAfterDelay,
90
+ CURSOR_REDRAW_INTERVAL_MS
91
+ );
92
+ }, [ cursors.length, rerenderCursorsAfterDelay ] );
93
+
71
94
  // Merge the refs to use the same element for both overlay and resize observation
72
95
  const mergedRef = useMergeRefs< HTMLDivElement | null >( [
73
96
  setOverlayElement,
74
97
  resizeObserverRef,
75
98
  ] );
76
99
 
100
+ // Track cursor element refs for registry registration.
101
+ const cursorRefsMap = useRef< Map< number, HTMLElement > >( new Map() );
102
+
103
+ // Keep the registry in sync whenever the rendered cursors change.
104
+ useEffect( () => {
105
+ if ( ! cursorRegistry ) {
106
+ return;
107
+ }
108
+ const refs = cursorRefsMap.current;
109
+ const currentIds = new Set( cursors.map( ( c ) => c.clientId ) );
110
+
111
+ // Unregister cursors that are no longer rendered.
112
+ for ( const id of refs.keys() ) {
113
+ if ( ! currentIds.has( id ) ) {
114
+ cursorRegistry.unregisterCursor( id );
115
+ refs.delete( id );
116
+ }
117
+ }
118
+
119
+ // Register or update cursors that are currently rendered.
120
+ for ( const [ id, el ] of refs.entries() ) {
121
+ cursorRegistry.registerCursor( id, el );
122
+ }
123
+
124
+ return () => cursorRegistry.removeAll();
125
+ }, [ cursors, cursorRegistry ] );
126
+
127
+ // Callback ref factory to capture each cursor's DOM element.
128
+ const setCursorRef = useCallback(
129
+ ( clientId: number ) => ( el: HTMLDivElement | null ) => {
130
+ if ( el ) {
131
+ cursorRefsMap.current.set( clientId, el );
132
+ } else {
133
+ cursorRefsMap.current.delete( clientId );
134
+ }
135
+ },
136
+ []
137
+ );
138
+
77
139
  // This is a full overlay that covers the entire iframe document. Good for
78
140
  // scrollable elements like cursor indicators.
79
141
  return (
@@ -96,6 +158,7 @@ export function Overlay( {
96
158
  />
97
159
  ) ) }
98
160
  <div
161
+ ref={ setCursorRef( cursor.clientId ) }
99
162
  className="collaborators-overlay-user"
100
163
  style={ {
101
164
  left: `${ cursor.x }px`,
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Like setInterval but chains setTimeout calls, so the delay is measured from
3
+ * the end of one run to the start of the next. This prevents callbacks from
4
+ * stacking up when the main thread is busy.
5
+ *
6
+ * @param callback The function to call repeatedly.
7
+ * @param delayMs Milliseconds between runs.
8
+ * @return A cleanup function that stops the timer.
9
+ */
10
+ export function setDelayedInterval( callback: () => void, delayMs: number ) {
11
+ let timerHandle: ReturnType< typeof setTimeout > | null = null;
12
+
13
+ const runner = () => {
14
+ try {
15
+ callback();
16
+ } catch ( error ) {
17
+ // Do nothing
18
+ }
19
+
20
+ timerHandle = setTimeout( runner, delayMs );
21
+ };
22
+
23
+ timerHandle = setTimeout( runner, delayMs );
24
+
25
+ return () => {
26
+ if ( timerHandle ) {
27
+ clearTimeout( timerHandle );
28
+ }
29
+ };
30
+ }
@@ -102,7 +102,7 @@ export function useRenderCursors(
102
102
  };
103
103
 
104
104
  let start: ResolvedSelection = {
105
- textIndex: null,
105
+ richTextOffset: null,
106
106
  localClientId: null,
107
107
  };
108
108
  let end: ResolvedSelection | undefined;
@@ -12,6 +12,7 @@ import { CollaboratorsList } from './list';
12
12
  import { unlock } from '../../lock-unlock';
13
13
  import { getAvatarUrl } from '../collaborators-overlay/get-avatar-url';
14
14
  import { getAvatarBorderColor } from '../collab-sidebar/utils';
15
+ import { createCursorRegistry } from '../collaborators-overlay/cursor-registry';
15
16
 
16
17
  import './styles/collaborators-presence.scss';
17
18
  import { CollaboratorsOverlay } from '../collaborators-overlay';
@@ -57,6 +58,8 @@ export function CollaboratorsPresence( {
57
58
  } );
58
59
  }, [ activeCollaborators ] );
59
60
 
61
+ const [ cursorRegistry ] = useState( createCursorRegistry );
62
+
60
63
  const [ isPopoverVisible, setIsPopoverVisible ] = useState( false );
61
64
  const [ popoverAnchor, setPopoverAnchor ] = useState< HTMLElement | null >(
62
65
  null
@@ -123,10 +126,15 @@ export function CollaboratorsPresence( {
123
126
  activeCollaborators={ collaboratorsForList }
124
127
  popoverAnchor={ popoverAnchor }
125
128
  setIsPopoverVisible={ setIsPopoverVisible }
129
+ cursorRegistry={ cursorRegistry }
126
130
  />
127
131
  ) }
128
132
  </div>
129
- <CollaboratorsOverlay postId={ postId } postType={ postType } />
133
+ <CollaboratorsOverlay
134
+ postId={ postId }
135
+ postType={ postType }
136
+ cursorRegistry={ cursorRegistry }
137
+ />
130
138
  </>
131
139
  );
132
140
  }
@@ -2,10 +2,12 @@ import { __ } from '@wordpress/i18n';
2
2
  import { Popover, Button } from '@wordpress/components';
3
3
  import { closeSmall } from '@wordpress/icons';
4
4
  import { type PostEditorAwarenessState } from '@wordpress/core-data';
5
+ import { speak } from '@wordpress/a11y';
5
6
 
6
7
  import Avatar from './avatar';
7
8
  import { getAvatarUrl } from '../collaborators-overlay/get-avatar-url';
8
9
  import { getAvatarBorderColor } from '../collab-sidebar/utils';
10
+ import { type CursorRegistry } from '../collaborators-overlay/cursor-registry';
9
11
 
10
12
  import './styles/collaborators-list.scss';
11
13
 
@@ -13,6 +15,7 @@ interface CollaboratorsListProps {
13
15
  activeCollaborators: PostEditorAwarenessState[];
14
16
  popoverAnchor?: HTMLElement | null;
15
17
  setIsPopoverVisible: ( isVisible: boolean ) => void;
18
+ cursorRegistry: CursorRegistry;
16
19
  }
17
20
 
18
21
  /**
@@ -23,12 +26,28 @@ interface CollaboratorsListProps {
23
26
  * @param props.activeCollaborators List of active collaborators
24
27
  * @param props.popoverAnchor Anchor element for the popover
25
28
  * @param props.setIsPopoverVisible Callback to set the visibility of the popover
29
+ * @param props.cursorRegistry Shared registry for scroll-to-cursor support
26
30
  */
27
31
  export function CollaboratorsList( {
28
32
  activeCollaborators,
29
33
  popoverAnchor,
30
34
  setIsPopoverVisible,
35
+ cursorRegistry,
31
36
  }: CollaboratorsListProps ) {
37
+ const handleCollaboratorClick = ( clientId: number ) => {
38
+ const success = cursorRegistry.scrollToCursor( clientId, {
39
+ behavior: 'smooth',
40
+ block: 'center',
41
+ highlightDuration: 2000,
42
+ } );
43
+
44
+ if ( success ) {
45
+ speak( __( 'Scrolled to cursor' ), 'polite' );
46
+
47
+ setIsPopoverVisible( false );
48
+ }
49
+ };
50
+
32
51
  return (
33
52
  <Popover
34
53
  anchor={ popoverAnchor }
@@ -60,7 +79,12 @@ export function CollaboratorsList( {
60
79
  <button
61
80
  key={ collaboratorState.clientId }
62
81
  className="editor-collaborators-presence__list-item"
63
- disabled
82
+ disabled={ isCurrentUser }
83
+ onClick={ () =>
84
+ handleCollaboratorClick(
85
+ collaboratorState.clientId
86
+ )
87
+ }
64
88
  >
65
89
  <Avatar
66
90
  src={ getAvatarUrl(
@@ -9,7 +9,7 @@ import {
9
9
  __experimentalText as Text,
10
10
  privateApis as componentsPrivateApis,
11
11
  } from '@wordpress/components';
12
- import { moreVertical, close } from '@wordpress/icons';
12
+ import { close } from '@wordpress/icons';
13
13
  import { store as coreStore } from '@wordpress/core-data';
14
14
  import { useSelect } from '@wordpress/data';
15
15
  import { useMemo } from '@wordpress/element';
@@ -52,7 +52,7 @@ export default function PostCardPanel( {
52
52
  () => ( Array.isArray( postId ) ? postId : [ postId ] ),
53
53
  [ postId ]
54
54
  );
55
- const { postTitle, icon, labels, isRevision } = useSelect(
55
+ const { postTitle, icon, labels } = useSelect(
56
56
  ( select ) => {
57
57
  const { getEditedEntityRecord, getCurrentTheme, getPostType } =
58
58
  select( coreStore );
@@ -75,7 +75,6 @@ export default function PostCardPanel( {
75
75
  area: _record?.area,
76
76
  } ),
77
77
  labels: getPostType( parentPostType )?.labels,
78
- isRevision: true,
79
78
  };
80
79
  }
81
80
 
@@ -146,24 +145,11 @@ export default function PostCardPanel( {
146
145
  ) }
147
146
  </Text>
148
147
  { ! hideActions && postIds.length === 1 && (
149
- <>
150
- { isRevision ? (
151
- <Button
152
- size="small"
153
- icon={ moreVertical }
154
- label={ __( 'Actions' ) }
155
- disabled
156
- accessibleWhenDisabled
157
- className="editor-all-actions-button"
158
- />
159
- ) : (
160
- <PostActions
161
- postType={ postType }
162
- postId={ postIds[ 0 ] }
163
- onActionPerformed={ onActionPerformed }
164
- />
165
- ) }
166
- </>
148
+ <PostActions
149
+ postType={ postType }
150
+ postId={ postIds[ 0 ] }
151
+ onActionPerformed={ onActionPerformed }
152
+ />
167
153
  ) }
168
154
  { onClose && (
169
155
  <Button
@@ -12,7 +12,6 @@ import { store as coreStore } from '@wordpress/core-data';
12
12
  * Internal dependencies
13
13
  */
14
14
  import { store as editorStore } from '../../store';
15
- import { unlock } from '../../lock-unlock';
16
15
  import {
17
16
  TEMPLATE_POST_TYPE,
18
17
  TEMPLATE_PART_POST_TYPE,
@@ -23,19 +22,9 @@ const AVERAGE_READING_RATE = 189;
23
22
 
24
23
  // This component renders the wordcount and reading time for the post.
25
24
  export default function PostContentInformation() {
26
- const { postContent } = useSelect( ( select ) => {
25
+ const postContent = useSelect( ( select ) => {
27
26
  const { getEditedPostAttribute, getCurrentPostType, getCurrentPostId } =
28
27
  select( editorStore );
29
- const { getCurrentRevision, isRevisionsMode } = unlock(
30
- select( editorStore )
31
- );
32
-
33
- if ( isRevisionsMode() ) {
34
- return {
35
- postContent: getCurrentRevision()?.content?.raw,
36
- };
37
- }
38
-
39
28
  const { canUser } = select( coreStore );
40
29
  const { getEntityRecord } = select( coreStore );
41
30
  const siteSettings = canUser( 'read', {
@@ -52,12 +41,12 @@ export default function PostContentInformation() {
52
41
  ! [ TEMPLATE_POST_TYPE, TEMPLATE_PART_POST_TYPE ].includes(
53
42
  postType
54
43
  );
55
- return {
56
- postContent:
57
- showPostContentInfo && getEditedPostAttribute( 'content' ),
58
- };
44
+ return showPostContentInfo && getEditedPostAttribute( 'content' );
59
45
  }, [] );
46
+ return <PostContentInformationUI postContent={ postContent } />;
47
+ }
60
48
 
49
+ export function PostContentInformationUI( { postContent } ) {
61
50
  /*
62
51
  * translators: If your word count is based on single characters (e.g. East Asian characters),
63
52
  * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.
@@ -16,6 +16,7 @@ import { addAction, removeAction } from '@wordpress/hooks';
16
16
  import { useInstanceId } from '@wordpress/compose';
17
17
  import { store as coreStore } from '@wordpress/core-data';
18
18
  import { unlock } from '../../lock-unlock';
19
+ import { DOCUMENT_SIZE_LIMIT_EXCEEDED } from '../../utils/sync-error-messages';
19
20
 
20
21
  /**
21
22
  * Internal dependencies
@@ -23,14 +24,31 @@ import { unlock } from '../../lock-unlock';
23
24
  import { store as editorStore } from '../../store';
24
25
 
25
26
  function CollaborationContext() {
26
- const isCollaborationSupported = useSelect( ( select ) => {
27
- return unlock( select( coreStore ) ).isCollaborationSupported();
28
- }, [] );
27
+ const { isCollaborationSupported, syncConnectionStatus } = useSelect(
28
+ ( select ) => {
29
+ const selectors = unlock( select( coreStore ) );
30
+ return {
31
+ isCollaborationSupported: selectors.isCollaborationSupported(),
32
+ syncConnectionStatus: selectors.getSyncConnectionStatus(),
33
+ };
34
+ },
35
+ []
36
+ );
29
37
 
30
38
  if ( isCollaborationSupported ) {
31
39
  return null;
32
40
  }
33
41
 
42
+ if ( DOCUMENT_SIZE_LIMIT_EXCEEDED === syncConnectionStatus?.error?.code ) {
43
+ return (
44
+ <p>
45
+ { __(
46
+ 'Because this post is too large for real-time collaboration, only one person can edit at a time.'
47
+ ) }
48
+ </p>
49
+ );
50
+ }
51
+
34
52
  return (
35
53
  <p>
36
54
  { __(
@@ -0,0 +1,151 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ PanelBody,
6
+ Button,
7
+ __experimentalHStack as HStack,
8
+ __experimentalVStack as VStack,
9
+ privateApis as componentsPrivateApis,
10
+ } from '@wordpress/components';
11
+ import { store as coreStore } from '@wordpress/core-data';
12
+ import { DataViews } from '@wordpress/dataviews';
13
+ import { dateI18n, getDate, humanTimeDiff, getSettings } from '@wordpress/date';
14
+ import { useSelect, useDispatch } from '@wordpress/data';
15
+ import { __ } from '@wordpress/i18n';
16
+ import { authorField } from '@wordpress/fields';
17
+
18
+ /**
19
+ * Internal dependencies
20
+ */
21
+ import PostLastRevisionCheck from '../post-last-revision/check';
22
+ import { store as editorStore } from '../../store';
23
+ import { unlock } from '../../lock-unlock';
24
+
25
+ const { Badge } = unlock( componentsPrivateApis );
26
+ const DAY_IN_MILLISECONDS = 86400000;
27
+ const EMPTY_ARRAY = [];
28
+
29
+ const REVISIONS_QUERY = {
30
+ per_page: 3,
31
+ orderby: 'date',
32
+ order: 'desc',
33
+ context: 'embed',
34
+ _fields: 'id,date,author',
35
+ };
36
+ const defaultLayouts = { activity: {} };
37
+ const view = {
38
+ type: 'activity',
39
+ titleField: 'date',
40
+ fields: [ 'author' ],
41
+ layout: {
42
+ density: 'compact',
43
+ },
44
+ };
45
+ const fields = [
46
+ {
47
+ id: 'date',
48
+ label: __( 'Date' ),
49
+ render: ( { item } ) => {
50
+ const dateNowInMs = getDate( null ).getTime();
51
+ const date = getDate( item.date ?? null );
52
+ const displayDate =
53
+ dateNowInMs - date.getTime() > DAY_IN_MILLISECONDS
54
+ ? dateI18n(
55
+ getSettings().formats.datetimeAbbreviated,
56
+ date
57
+ )
58
+ : humanTimeDiff( date );
59
+ return (
60
+ <time
61
+ className="editor-post-revisions-panel__revision-date"
62
+ dateTime={ item.date }
63
+ >
64
+ { displayDate }
65
+ </time>
66
+ );
67
+ },
68
+ enableSorting: false,
69
+ enableHiding: false,
70
+ },
71
+ authorField,
72
+ ];
73
+ const noop = () => {};
74
+ const paginationInfo = {};
75
+
76
+ function PostRevisionsPanelContent() {
77
+ const { setCurrentRevisionId } = unlock( useDispatch( editorStore ) );
78
+ const { revisionsCount, revisions, isLoading, lastRevisionId } = useSelect(
79
+ ( select ) => {
80
+ const { getCurrentPostId, getCurrentPostType } =
81
+ select( editorStore );
82
+ const {
83
+ getCurrentPostRevisionsCount,
84
+ getCurrentPostLastRevisionId,
85
+ } = select( editorStore );
86
+ const { getRevisions, isResolving } = select( coreStore );
87
+ const query = [
88
+ 'postType',
89
+ getCurrentPostType(),
90
+ getCurrentPostId(),
91
+ REVISIONS_QUERY,
92
+ ];
93
+ const _revisions = getRevisions( ...query );
94
+ return {
95
+ revisionsCount: getCurrentPostRevisionsCount(),
96
+ lastRevisionId: getCurrentPostLastRevisionId(),
97
+ revisions: _revisions,
98
+ isLoading: isResolving( 'getRevisions', query ),
99
+ };
100
+ },
101
+ []
102
+ );
103
+ return (
104
+ <PanelBody
105
+ title={
106
+ <HStack justify="space-between" align="center" as="span">
107
+ <span>{ __( 'Revisions' ) }</span>
108
+ <Badge className="editor-post-revisions-panel__revisions-count">
109
+ { revisionsCount }
110
+ </Badge>
111
+ </HStack>
112
+ }
113
+ initialOpen={ false }
114
+ >
115
+ <VStack className="editor-post-revisions-panel">
116
+ <DataViews
117
+ view={ view }
118
+ onChangeView={ noop }
119
+ fields={ fields }
120
+ data={ revisions || EMPTY_ARRAY }
121
+ isLoading={ isLoading }
122
+ paginationInfo={ paginationInfo }
123
+ defaultLayouts={ defaultLayouts }
124
+ getItemId={ ( item ) => item.id }
125
+ isItemClickable={ () => true }
126
+ onClickItem={ ( item ) => {
127
+ setCurrentRevisionId( item.id );
128
+ } }
129
+ >
130
+ <DataViews.Layout />
131
+ </DataViews>
132
+ <Button
133
+ className="editor-post-revisions-panel__view-all"
134
+ __next40pxDefaultSize
135
+ variant="secondary"
136
+ onClick={ () => setCurrentRevisionId( lastRevisionId ) }
137
+ >
138
+ { __( 'View all revisions' ) }
139
+ </Button>
140
+ </VStack>
141
+ </PanelBody>
142
+ );
143
+ }
144
+
145
+ export default function PostRevisionsPanel() {
146
+ return (
147
+ <PostLastRevisionCheck>
148
+ <PostRevisionsPanelContent />
149
+ </PostLastRevisionCheck>
150
+ );
151
+ }
@@ -0,0 +1,16 @@
1
+ .editor-post-revisions-panel {
2
+ .editor-post-revisions-panel__view-all {
3
+ justify-content: center;
4
+ }
5
+
6
+ .editor-post-revisions-panel__revision-date {
7
+ text-transform: uppercase;
8
+ font-weight: 600;
9
+ font-size: 12px;
10
+ }
11
+ }
12
+
13
+ .editor-post-revisions-panel__revisions-count {
14
+ margin-top: -4.5px;
15
+ margin-bottom: -4.5px;
16
+ }