@wordpress/editor 14.40.2-next.v.202602241322.0 → 14.40.2
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.
- package/CHANGELOG.md +6 -0
- package/build/components/collab-sidebar/index.cjs +7 -4
- package/build/components/collab-sidebar/index.cjs.map +2 -2
- package/build/components/collab-sidebar/utils.cjs +13 -15
- package/build/components/collab-sidebar/utils.cjs.map +2 -2
- package/build/components/collaborators-overlay/avatar-iframe-styles.cjs +141 -0
- package/build/components/collaborators-overlay/avatar-iframe-styles.cjs.map +7 -0
- package/build/components/collaborators-overlay/collaborator-styles.cjs +38 -2
- package/build/components/collaborators-overlay/collaborator-styles.cjs.map +2 -2
- package/build/components/collaborators-overlay/compute-selection.cjs +185 -0
- package/build/components/collaborators-overlay/compute-selection.cjs.map +7 -0
- package/build/components/collaborators-overlay/cursor-dom-utils.cjs +243 -0
- package/build/components/collaborators-overlay/cursor-dom-utils.cjs.map +7 -0
- package/build/components/collaborators-overlay/cursor-registry.cjs +86 -0
- package/build/components/collaborators-overlay/cursor-registry.cjs.map +7 -0
- package/build/components/collaborators-overlay/index.cjs +7 -2
- package/build/components/collaborators-overlay/index.cjs.map +2 -2
- package/build/components/collaborators-overlay/overlay-iframe-styles.cjs +148 -0
- package/build/components/collaborators-overlay/overlay-iframe-styles.cjs.map +7 -0
- package/build/components/collaborators-overlay/overlay.cjs +146 -236
- package/build/components/collaborators-overlay/overlay.cjs.map +3 -3
- package/build/components/collaborators-overlay/timing-utils.cjs +46 -0
- package/build/components/collaborators-overlay/timing-utils.cjs.map +7 -0
- package/build/components/collaborators-overlay/use-block-highlighting.cjs +91 -42
- package/build/components/collaborators-overlay/use-block-highlighting.cjs.map +2 -2
- package/build/components/collaborators-overlay/use-debounced-recompute.cjs +49 -0
- package/build/components/collaborators-overlay/use-debounced-recompute.cjs.map +7 -0
- package/build/components/collaborators-overlay/use-render-cursors.cjs +82 -172
- package/build/components/collaborators-overlay/use-render-cursors.cjs.map +3 -3
- package/build/components/collaborators-presence/avatar/component.cjs +121 -0
- package/build/components/collaborators-presence/avatar/component.cjs.map +7 -0
- package/build/components/collaborators-presence/avatar/index.cjs +37 -0
- package/build/components/collaborators-presence/avatar/index.cjs.map +7 -0
- package/build/components/collaborators-presence/avatar/types.cjs +19 -0
- package/build/components/collaborators-presence/avatar/types.cjs.map +7 -0
- package/build/components/collaborators-presence/avatar/use-image-loading-status.cjs +44 -0
- package/build/components/collaborators-presence/avatar/use-image-loading-status.cjs.map +7 -0
- package/build/components/collaborators-presence/avatar-group/component.cjs +78 -0
- package/build/components/collaborators-presence/avatar-group/component.cjs.map +7 -0
- package/build/components/collaborators-presence/avatar-group/index.cjs +37 -0
- package/build/components/collaborators-presence/avatar-group/index.cjs.map +7 -0
- package/build/components/collaborators-presence/avatar-group/types.cjs +19 -0
- package/build/components/collaborators-presence/avatar-group/types.cjs.map +7 -0
- package/build/components/collaborators-presence/index.cjs +66 -19
- package/build/components/collaborators-presence/index.cjs.map +3 -3
- package/build/components/collaborators-presence/list.cjs +60 -38
- package/build/components/collaborators-presence/list.cjs.map +3 -3
- package/build/components/collaborators-presence/use-collaborator-notifications.cjs +149 -0
- package/build/components/collaborators-presence/use-collaborator-notifications.cjs.map +7 -0
- package/build/components/editor-interface/index.cjs +11 -6
- package/build/components/editor-interface/index.cjs.map +2 -2
- package/build/components/inserter-sidebar/index.cjs +2 -1
- package/build/components/inserter-sidebar/index.cjs.map +2 -2
- package/build/components/post-last-revision/index.cjs +27 -6
- package/build/components/post-last-revision/index.cjs.map +2 -2
- package/build/components/post-locked-modal/index.cjs +49 -17
- package/build/components/post-locked-modal/index.cjs.map +3 -3
- package/build/components/post-revisions-preview/block-diff.cjs +130 -34
- package/build/components/post-revisions-preview/block-diff.cjs.map +2 -2
- package/build/components/post-revisions-preview/diff-markers.cjs +6 -5
- package/build/components/post-revisions-preview/diff-markers.cjs.map +2 -2
- package/build/components/post-revisions-preview/revisions-canvas.cjs +16 -60
- package/build/components/post-revisions-preview/revisions-canvas.cjs.map +3 -3
- package/build/components/post-revisions-preview/revisions-header.cjs +33 -26
- package/build/components/post-revisions-preview/revisions-header.cjs.map +3 -3
- package/build/components/post-revisions-preview/revisions-slider.cjs +104 -39
- package/build/components/post-revisions-preview/revisions-slider.cjs.map +3 -3
- package/build/components/preferences-modal/index.cjs +36 -4
- package/build/components/preferences-modal/index.cjs.map +2 -2
- package/build/components/provider/disable-non-page-content-blocks.cjs +31 -28
- package/build/components/provider/disable-non-page-content-blocks.cjs.map +3 -3
- package/build/components/provider/index.cjs +17 -5
- package/build/components/provider/index.cjs.map +2 -2
- package/build/components/provider/use-block-editor-settings.cjs +20 -4
- package/build/components/provider/use-block-editor-settings.cjs.map +3 -3
- package/build/components/provider/{use-post-content-blocks.cjs → use-post-content-block-types.cjs} +8 -19
- package/build/components/provider/use-post-content-block-types.cjs.map +7 -0
- package/build/components/provider/use-revision-blocks.cjs +106 -0
- package/build/components/provider/use-revision-blocks.cjs.map +7 -0
- package/build/components/revision-block-diff/index.cjs +61 -0
- package/build/components/revision-block-diff/index.cjs.map +7 -0
- package/build/components/revision-diff-panel/index.cjs +68 -0
- package/build/components/revision-diff-panel/index.cjs.map +7 -0
- package/build/components/revision-fields-diff/index.cjs +96 -0
- package/build/components/revision-fields-diff/index.cjs.map +7 -0
- package/build/components/sidebar/header.cjs +1 -1
- package/build/components/sidebar/header.cjs.map +2 -2
- package/build/components/sidebar/index.cjs +7 -1
- package/build/components/sidebar/index.cjs.map +3 -3
- package/build/components/style-book/index.cjs +4 -3
- package/build/components/style-book/index.cjs.map +2 -2
- package/build/components/sync-connection-error-modal/index.cjs +187 -0
- package/build/components/sync-connection-error-modal/index.cjs.map +7 -0
- package/build/components/sync-connection-error-modal/use-retry-countdown.cjs +84 -0
- package/build/components/sync-connection-error-modal/use-retry-countdown.cjs.map +7 -0
- package/build/components/template-content-panel/index.cjs +35 -31
- package/build/components/template-content-panel/index.cjs.map +3 -3
- package/build/components/template-part-menu-items/convert-to-regular.cjs +54 -11
- package/build/components/template-part-menu-items/convert-to-regular.cjs.map +3 -3
- package/build/components/visual-editor/index.cjs +6 -15
- package/build/components/visual-editor/index.cjs.map +2 -2
- package/build/store/private-actions.cjs +46 -2
- package/build/store/private-actions.cjs.map +2 -2
- package/build/store/private-selectors.cjs +156 -21
- package/build/store/private-selectors.cjs.map +2 -2
- package/build/store/reducer.cjs +27 -0
- package/build/store/reducer.cjs.map +2 -2
- package/build/store/selectors.cjs +0 -14
- package/build/store/selectors.cjs.map +2 -2
- package/build/utils/media-finalize/index.cjs +43 -0
- package/build/utils/media-finalize/index.cjs.map +7 -0
- package/build/utils/media-upload/on-success.cjs +46 -0
- package/build/utils/media-upload/on-success.cjs.map +7 -0
- package/build/utils/sync-error-messages.cjs +32 -15
- package/build/utils/sync-error-messages.cjs.map +3 -3
- package/build-module/components/collab-sidebar/index.mjs +7 -4
- package/build-module/components/collab-sidebar/index.mjs.map +2 -2
- package/build-module/components/collab-sidebar/utils.mjs +13 -15
- package/build-module/components/collab-sidebar/utils.mjs.map +2 -2
- package/build-module/components/collaborators-overlay/avatar-iframe-styles.mjs +128 -0
- package/build-module/components/collaborators-overlay/avatar-iframe-styles.mjs.map +7 -0
- package/build-module/components/collaborators-overlay/collaborator-styles.mjs +25 -1
- package/build-module/components/collaborators-overlay/collaborator-styles.mjs.map +2 -2
- package/build-module/components/collaborators-overlay/compute-selection.mjs +166 -0
- package/build-module/components/collaborators-overlay/compute-selection.mjs.map +7 -0
- package/build-module/components/collaborators-overlay/cursor-dom-utils.mjs +213 -0
- package/build-module/components/collaborators-overlay/cursor-dom-utils.mjs.map +7 -0
- package/build-module/components/collaborators-overlay/cursor-registry.mjs +61 -0
- package/build-module/components/collaborators-overlay/cursor-registry.mjs.map +7 -0
- package/build-module/components/collaborators-overlay/index.mjs +7 -2
- package/build-module/components/collaborators-overlay/index.mjs.map +2 -2
- package/build-module/components/collaborators-overlay/overlay-iframe-styles.mjs +130 -0
- package/build-module/components/collaborators-overlay/overlay-iframe-styles.mjs.map +7 -0
- package/build-module/components/collaborators-overlay/overlay.mjs +137 -237
- package/build-module/components/collaborators-overlay/overlay.mjs.map +2 -2
- package/build-module/components/collaborators-overlay/timing-utils.mjs +21 -0
- package/build-module/components/collaborators-overlay/timing-utils.mjs.map +7 -0
- package/build-module/components/collaborators-overlay/use-block-highlighting.mjs +93 -45
- package/build-module/components/collaborators-overlay/use-block-highlighting.mjs.map +2 -2
- package/build-module/components/collaborators-overlay/use-debounced-recompute.mjs +24 -0
- package/build-module/components/collaborators-overlay/use-debounced-recompute.mjs.map +7 -0
- package/build-module/components/collaborators-overlay/use-render-cursors.mjs +83 -176
- package/build-module/components/collaborators-overlay/use-render-cursors.mjs.map +2 -2
- package/build-module/components/collaborators-presence/avatar/component.mjs +90 -0
- package/build-module/components/collaborators-presence/avatar/component.mjs.map +7 -0
- package/build-module/components/collaborators-presence/avatar/index.mjs +6 -0
- package/build-module/components/collaborators-presence/avatar/index.mjs.map +7 -0
- package/build-module/components/collaborators-presence/avatar/types.mjs +1 -0
- package/build-module/components/collaborators-presence/avatar/types.mjs.map +7 -0
- package/build-module/components/collaborators-presence/avatar/use-image-loading-status.mjs +19 -0
- package/build-module/components/collaborators-presence/avatar/use-image-loading-status.mjs.map +7 -0
- package/build-module/components/collaborators-presence/avatar-group/component.mjs +47 -0
- package/build-module/components/collaborators-presence/avatar-group/component.mjs.map +7 -0
- package/build-module/components/collaborators-presence/avatar-group/index.mjs +6 -0
- package/build-module/components/collaborators-presence/avatar-group/index.mjs.map +7 -0
- package/build-module/components/collaborators-presence/avatar-group/types.mjs +1 -0
- package/build-module/components/collaborators-presence/avatar-group/types.mjs.map +7 -0
- package/build-module/components/collaborators-presence/index.mjs +57 -23
- package/build-module/components/collaborators-presence/index.mjs.map +2 -2
- package/build-module/components/collaborators-presence/list.mjs +52 -44
- package/build-module/components/collaborators-presence/list.mjs.map +2 -2
- package/build-module/components/collaborators-presence/use-collaborator-notifications.mjs +126 -0
- package/build-module/components/collaborators-presence/use-collaborator-notifications.mjs.map +7 -0
- package/build-module/components/editor-interface/index.mjs +12 -7
- package/build-module/components/editor-interface/index.mjs.map +2 -2
- package/build-module/components/inserter-sidebar/index.mjs +2 -1
- package/build-module/components/inserter-sidebar/index.mjs.map +2 -2
- package/build-module/components/post-last-revision/index.mjs +27 -6
- package/build-module/components/post-last-revision/index.mjs.map +2 -2
- package/build-module/components/post-locked-modal/index.mjs +49 -17
- package/build-module/components/post-locked-modal/index.mjs.map +2 -2
- package/build-module/components/post-revisions-preview/block-diff.mjs +130 -34
- package/build-module/components/post-revisions-preview/block-diff.mjs.map +2 -2
- package/build-module/components/post-revisions-preview/diff-markers.mjs +6 -5
- package/build-module/components/post-revisions-preview/diff-markers.mjs.map +2 -2
- package/build-module/components/post-revisions-preview/revisions-canvas.mjs +18 -65
- package/build-module/components/post-revisions-preview/revisions-canvas.mjs.map +2 -2
- package/build-module/components/post-revisions-preview/revisions-header.mjs +36 -33
- package/build-module/components/post-revisions-preview/revisions-header.mjs.map +2 -2
- package/build-module/components/post-revisions-preview/revisions-slider.mjs +112 -42
- package/build-module/components/post-revisions-preview/revisions-slider.mjs.map +2 -2
- package/build-module/components/preferences-modal/index.mjs +36 -4
- package/build-module/components/preferences-modal/index.mjs.map +2 -2
- package/build-module/components/provider/disable-non-page-content-blocks.mjs +31 -28
- package/build-module/components/provider/disable-non-page-content-blocks.mjs.map +2 -2
- package/build-module/components/provider/index.mjs +17 -5
- package/build-module/components/provider/index.mjs.map +2 -2
- package/build-module/components/provider/use-block-editor-settings.mjs +20 -4
- package/build-module/components/provider/use-block-editor-settings.mjs.map +2 -2
- package/build-module/components/provider/use-post-content-block-types.mjs +23 -0
- package/build-module/components/provider/use-post-content-block-types.mjs.map +7 -0
- package/build-module/components/provider/use-revision-blocks.mjs +81 -0
- package/build-module/components/provider/use-revision-blocks.mjs.map +7 -0
- package/build-module/components/revision-block-diff/index.mjs +30 -0
- package/build-module/components/revision-block-diff/index.mjs.map +7 -0
- package/build-module/components/revision-diff-panel/index.mjs +37 -0
- package/build-module/components/revision-diff-panel/index.mjs.map +7 -0
- package/build-module/components/revision-fields-diff/index.mjs +65 -0
- package/build-module/components/revision-fields-diff/index.mjs.map +7 -0
- package/build-module/components/sidebar/header.mjs +1 -1
- package/build-module/components/sidebar/header.mjs.map +2 -2
- package/build-module/components/sidebar/index.mjs +7 -1
- package/build-module/components/sidebar/index.mjs.map +2 -2
- package/build-module/components/style-book/index.mjs +4 -3
- package/build-module/components/style-book/index.mjs.map +2 -2
- package/build-module/components/sync-connection-error-modal/index.mjs +170 -0
- package/build-module/components/sync-connection-error-modal/index.mjs.map +7 -0
- package/build-module/components/sync-connection-error-modal/use-retry-countdown.mjs +59 -0
- package/build-module/components/sync-connection-error-modal/use-retry-countdown.mjs.map +7 -0
- package/build-module/components/template-content-panel/index.mjs +25 -31
- package/build-module/components/template-content-panel/index.mjs.map +2 -2
- package/build-module/components/template-part-menu-items/convert-to-regular.mjs +60 -14
- package/build-module/components/template-part-menu-items/convert-to-regular.mjs.map +2 -2
- package/build-module/components/visual-editor/index.mjs +6 -15
- package/build-module/components/visual-editor/index.mjs.map +2 -2
- package/build-module/store/private-actions.mjs +44 -2
- package/build-module/store/private-actions.mjs.map +2 -2
- package/build-module/store/private-selectors.mjs +155 -21
- package/build-module/store/private-selectors.mjs.map +2 -2
- package/build-module/store/reducer.mjs +25 -0
- package/build-module/store/reducer.mjs.map +2 -2
- package/build-module/store/selectors.mjs +0 -13
- package/build-module/store/selectors.mjs.map +2 -2
- package/build-module/utils/media-finalize/index.mjs +12 -0
- package/build-module/utils/media-finalize/index.mjs.map +7 -0
- package/build-module/utils/media-upload/on-success.mjs +25 -0
- package/build-module/utils/media-upload/on-success.mjs.map +7 -0
- package/build-module/utils/sync-error-messages.mjs +27 -15
- package/build-module/utils/sync-error-messages.mjs.map +3 -3
- package/build-style/style-rtl.css +388 -132
- package/build-style/style.css +388 -132
- package/build-types/components/autocompleters/link.d.ts +8 -0
- package/build-types/components/autocompleters/link.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/add-note-menu-item.d.ts +5 -0
- package/build-types/components/collab-sidebar/add-note-menu-item.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/add-note.d.ts +6 -0
- package/build-types/components/collab-sidebar/add-note.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/board-store.d.ts +9 -0
- package/build-types/components/collab-sidebar/board-store.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/floating-container.d.ts +8 -0
- package/build-types/components/collab-sidebar/floating-container.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/index.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/note-byline.d.ts +10 -0
- package/build-types/components/collab-sidebar/note-byline.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/note-card.d.ts +8 -0
- package/build-types/components/collab-sidebar/note-card.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/note-form.d.ts +7 -0
- package/build-types/components/collab-sidebar/note-form.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/note-indicator-toolbar.d.ts +5 -0
- package/build-types/components/collab-sidebar/note-indicator-toolbar.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/note-thread.d.ts +11 -0
- package/build-types/components/collab-sidebar/note-thread.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/note.d.ts +9 -0
- package/build-types/components/collab-sidebar/note.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/notes.d.ts +7 -0
- package/build-types/components/collab-sidebar/notes.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/utils.d.ts.map +1 -1
- package/build-types/components/collaborators-overlay/avatar-iframe-styles.d.ts +11 -0
- package/build-types/components/collaborators-overlay/avatar-iframe-styles.d.ts.map +1 -0
- package/build-types/components/collaborators-overlay/collaborator-styles.d.ts +17 -2
- package/build-types/components/collaborators-overlay/collaborator-styles.d.ts.map +1 -1
- package/build-types/components/collaborators-overlay/compute-selection.d.ts +24 -0
- package/build-types/components/collaborators-overlay/compute-selection.d.ts.map +1 -0
- package/build-types/components/collaborators-overlay/cursor-dom-utils.d.ts +72 -0
- package/build-types/components/collaborators-overlay/cursor-dom-utils.d.ts.map +1 -0
- package/build-types/components/collaborators-overlay/cursor-registry.d.ts +36 -0
- package/build-types/components/collaborators-overlay/cursor-registry.d.ts.map +1 -0
- package/build-types/components/collaborators-overlay/index.d.ts +7 -4
- package/build-types/components/collaborators-overlay/index.d.ts.map +1 -1
- package/build-types/components/collaborators-overlay/overlay-iframe-styles.d.ts +6 -0
- package/build-types/components/collaborators-overlay/overlay-iframe-styles.d.ts.map +1 -0
- package/build-types/components/collaborators-overlay/overlay.d.ts +4 -1
- package/build-types/components/collaborators-overlay/overlay.d.ts.map +1 -1
- package/build-types/components/collaborators-overlay/timing-utils.d.ts +11 -0
- package/build-types/components/collaborators-overlay/timing-utils.d.ts.map +1 -0
- package/build-types/components/collaborators-overlay/use-block-highlighting.d.ts +21 -5
- package/build-types/components/collaborators-overlay/use-block-highlighting.d.ts.map +1 -1
- package/build-types/components/collaborators-overlay/use-debounced-recompute.d.ts +10 -0
- package/build-types/components/collaborators-overlay/use-debounced-recompute.d.ts.map +1 -0
- package/build-types/components/collaborators-overlay/use-render-cursors.d.ts +6 -1
- package/build-types/components/collaborators-overlay/use-render-cursors.d.ts.map +1 -1
- package/build-types/components/collaborators-presence/avatar/component.d.ts +7 -0
- package/build-types/components/collaborators-presence/avatar/component.d.ts.map +1 -0
- package/build-types/components/collaborators-presence/avatar/index.d.ts +3 -0
- package/build-types/components/collaborators-presence/avatar/index.d.ts.map +1 -0
- package/build-types/components/collaborators-presence/avatar/types.d.ts +66 -0
- package/build-types/components/collaborators-presence/avatar/types.d.ts.map +1 -0
- package/build-types/components/collaborators-presence/avatar/use-image-loading-status.d.ts +17 -0
- package/build-types/components/collaborators-presence/avatar/use-image-loading-status.d.ts.map +1 -0
- package/build-types/components/collaborators-presence/avatar-group/component.d.ts +7 -0
- package/build-types/components/collaborators-presence/avatar-group/component.d.ts.map +1 -0
- package/build-types/components/collaborators-presence/avatar-group/index.d.ts +3 -0
- package/build-types/components/collaborators-presence/avatar-group/index.d.ts.map +1 -0
- package/build-types/components/collaborators-presence/avatar-group/types.d.ts +14 -0
- package/build-types/components/collaborators-presence/avatar-group/types.d.ts.map +1 -0
- package/build-types/components/collaborators-presence/index.d.ts.map +1 -1
- package/build-types/components/collaborators-presence/list.d.ts +6 -2
- package/build-types/components/collaborators-presence/list.d.ts.map +1 -1
- package/build-types/components/collaborators-presence/use-collaborator-notifications.d.ts +9 -0
- package/build-types/components/collaborators-presence/use-collaborator-notifications.d.ts.map +1 -0
- package/build-types/components/editor-interface/index.d.ts.map +1 -1
- package/build-types/components/inserter-sidebar/index.d.ts.map +1 -1
- package/build-types/components/media/media-editor-modal.d.ts +15 -0
- package/build-types/components/media/media-editor-modal.d.ts.map +1 -0
- package/build-types/components/post-last-revision/index.d.ts.map +1 -1
- package/build-types/components/post-locked-modal/index.d.ts.map +1 -1
- package/build-types/components/post-revisions-panel/index.d.ts +2 -0
- package/build-types/components/post-revisions-panel/index.d.ts.map +1 -0
- package/build-types/components/post-revisions-preview/block-diff.d.ts.map +1 -1
- package/build-types/components/post-revisions-preview/diff-markers.d.ts.map +1 -1
- package/build-types/components/post-revisions-preview/revisions-canvas.d.ts +2 -5
- package/build-types/components/post-revisions-preview/revisions-canvas.d.ts.map +1 -1
- package/build-types/components/post-revisions-preview/revisions-header.d.ts.map +1 -1
- package/build-types/components/post-revisions-preview/revisions-slider.d.ts +1 -1
- package/build-types/components/post-revisions-preview/revisions-slider.d.ts.map +1 -1
- package/build-types/components/post-text-editor/utils.d.ts +29 -0
- package/build-types/components/post-text-editor/utils.d.ts.map +1 -0
- package/build-types/components/provider/disable-non-page-content-blocks.d.ts.map +1 -1
- package/build-types/components/provider/index.d.ts.map +1 -1
- package/build-types/components/provider/use-block-editor-settings.d.ts.map +1 -1
- package/build-types/components/provider/use-network-reconnect.d.ts +8 -0
- package/build-types/components/provider/use-network-reconnect.d.ts.map +1 -0
- package/build-types/components/provider/use-post-content-block-types.d.ts +9 -0
- package/build-types/components/provider/use-post-content-block-types.d.ts.map +1 -0
- package/build-types/components/provider/use-revision-blocks.d.ts +10 -0
- package/build-types/components/provider/use-revision-blocks.d.ts.map +1 -0
- package/build-types/components/revision-block-diff/index.d.ts +6 -0
- package/build-types/components/revision-block-diff/index.d.ts.map +1 -0
- package/build-types/components/revision-diff-panel/index.d.ts +14 -0
- package/build-types/components/revision-diff-panel/index.d.ts.map +1 -0
- package/build-types/components/revision-fields-diff/index.d.ts +6 -0
- package/build-types/components/revision-fields-diff/index.d.ts.map +1 -0
- package/build-types/components/sidebar/dataform-post-summary.d.ts +4 -0
- package/build-types/components/sidebar/dataform-post-summary.d.ts.map +1 -0
- package/build-types/components/sidebar/index.d.ts.map +1 -1
- package/build-types/components/sidebar/post-revision-summary.d.ts +2 -0
- package/build-types/components/sidebar/post-revision-summary.d.ts.map +1 -0
- package/build-types/components/style-book/index.d.ts +2 -1
- package/build-types/components/style-book/index.d.ts.map +1 -1
- package/build-types/components/sync-connection-error-modal/index.d.ts +8 -0
- package/build-types/components/sync-connection-error-modal/index.d.ts.map +1 -0
- package/build-types/components/sync-connection-error-modal/use-retry-countdown.d.ts +11 -0
- package/build-types/components/sync-connection-error-modal/use-retry-countdown.d.ts.map +1 -0
- package/build-types/components/template-actions-panel/block-theme-content.d.ts +2 -0
- package/build-types/components/template-actions-panel/block-theme-content.d.ts.map +1 -0
- package/build-types/components/template-actions-panel/classic-theme-content.d.ts +2 -0
- package/build-types/components/template-actions-panel/classic-theme-content.d.ts.map +1 -0
- package/build-types/components/template-actions-panel/index.d.ts +2 -0
- package/build-types/components/template-actions-panel/index.d.ts.map +1 -0
- package/build-types/components/template-content-panel/index.d.ts.map +1 -1
- package/build-types/components/template-part-menu-items/convert-to-regular.d.ts.map +1 -1
- package/build-types/components/upload-progress-snackbar/index.d.ts +19 -0
- package/build-types/components/upload-progress-snackbar/index.d.ts.map +1 -0
- package/build-types/components/upload-progress-snackbar/stories/index.story.d.ts +28 -0
- package/build-types/components/upload-progress-snackbar/stories/index.story.d.ts.map +1 -0
- package/build-types/components/upload-progress-snackbar/tracker.d.ts +41 -0
- package/build-types/components/upload-progress-snackbar/tracker.d.ts.map +1 -0
- package/build-types/components/visual-editor/index.d.ts.map +1 -1
- package/build-types/store/private-actions.d.ts +12 -0
- package/build-types/store/private-actions.d.ts.map +1 -1
- package/build-types/store/private-selectors.d.ts +45 -0
- package/build-types/store/private-selectors.d.ts.map +1 -1
- package/build-types/store/reducer.d.ts +21 -0
- package/build-types/store/reducer.d.ts.map +1 -1
- package/build-types/store/selectors.d.ts +0 -10
- package/build-types/store/selectors.d.ts.map +1 -1
- package/build-types/utils/media-delete/index.d.ts +2 -0
- package/build-types/utils/media-delete/index.d.ts.map +1 -0
- package/build-types/utils/media-finalize/index.d.ts +2 -0
- package/build-types/utils/media-finalize/index.d.ts.map +1 -0
- package/build-types/utils/media-upload/on-success.d.ts +9 -0
- package/build-types/utils/media-upload/on-success.d.ts.map +1 -0
- package/build-types/utils/sync-error-messages.d.ts +17 -3
- package/build-types/utils/sync-error-messages.d.ts.map +1 -1
- package/package.json +45 -44
- package/src/components/collab-sidebar/index.js +7 -4
- package/src/components/collab-sidebar/utils.js +9 -10
- package/src/components/collaborators-overlay/avatar-iframe-styles.ts +134 -0
- package/src/components/collaborators-overlay/collaborator-styles.ts +43 -2
- package/src/components/collaborators-overlay/compute-selection.ts +315 -0
- package/src/components/collaborators-overlay/cursor-dom-utils.ts +382 -0
- package/src/components/collaborators-overlay/cursor-registry.ts +96 -0
- package/src/components/collaborators-overlay/index.tsx +12 -4
- package/src/components/collaborators-overlay/overlay-iframe-styles.ts +131 -0
- package/src/components/collaborators-overlay/overlay.tsx +145 -229
- package/src/components/collaborators-overlay/timing-utils.ts +30 -0
- package/src/components/collaborators-overlay/use-block-highlighting.ts +152 -64
- package/src/components/collaborators-overlay/use-debounced-recompute.ts +32 -0
- package/src/components/collaborators-overlay/use-render-cursors.ts +120 -282
- package/src/components/collaborators-presence/avatar/component.tsx +123 -0
- package/src/components/collaborators-presence/avatar/index.ts +2 -0
- package/src/components/collaborators-presence/avatar/styles.scss +184 -0
- package/src/components/collaborators-presence/avatar/test/index.tsx +389 -0
- package/src/components/collaborators-presence/avatar/types.ts +66 -0
- package/src/components/collaborators-presence/avatar/use-image-loading-status.ts +36 -0
- package/src/components/collaborators-presence/avatar-group/component.tsx +55 -0
- package/src/components/collaborators-presence/avatar-group/index.ts +2 -0
- package/src/components/collaborators-presence/avatar-group/styles.scss +33 -0
- package/src/components/collaborators-presence/avatar-group/test/index.tsx +139 -0
- package/src/components/collaborators-presence/avatar-group/types.ts +13 -0
- package/src/components/collaborators-presence/index.tsx +43 -12
- package/src/components/collaborators-presence/list.tsx +68 -40
- package/src/components/collaborators-presence/styles/collaborators-list.scss +26 -19
- package/src/components/collaborators-presence/styles/collaborators-presence.scss +6 -2
- package/src/components/collaborators-presence/test/use-collaborator-notifications.ts +397 -0
- package/src/components/collaborators-presence/use-collaborator-notifications.ts +203 -0
- package/src/components/document-bar/style.scss +1 -1
- package/src/components/editor-interface/index.js +13 -6
- package/src/components/inserter-sidebar/index.js +4 -1
- package/src/components/post-last-revision/index.js +35 -6
- package/src/components/post-last-revision/style.scss +0 -3
- package/src/components/post-locked-modal/index.js +69 -25
- package/src/components/post-panel-row/style.scss +1 -0
- package/src/components/post-revisions-preview/block-diff.js +224 -61
- package/src/components/post-revisions-preview/diff-markers.js +15 -12
- package/src/components/post-revisions-preview/revisions-canvas.js +23 -86
- package/src/components/post-revisions-preview/revisions-header.js +35 -37
- package/src/components/post-revisions-preview/revisions-slider.js +138 -62
- package/src/components/post-revisions-preview/style.scss +3 -3
- package/src/components/post-revisions-preview/test/block-diff.js +202 -35
- package/src/components/preferences-modal/index.js +37 -7
- package/src/components/provider/disable-non-page-content-blocks.js +42 -40
- package/src/components/provider/index.js +20 -2
- package/src/components/provider/use-block-editor-settings.js +21 -1
- package/src/components/provider/use-post-content-block-types.js +30 -0
- package/src/components/provider/use-revision-blocks.js +105 -0
- package/src/components/revision-block-diff/index.js +39 -0
- package/src/components/revision-diff-panel/index.js +59 -0
- package/src/components/revision-diff-panel/style.scss +13 -0
- package/src/components/revision-fields-diff/index.js +91 -0
- package/src/components/sidebar/header.js +1 -1
- package/src/components/sidebar/index.js +4 -0
- package/src/components/style-book/index.js +4 -2
- package/src/components/sync-connection-error-modal/index.tsx +253 -0
- package/src/components/sync-connection-error-modal/style.scss +14 -0
- package/src/components/sync-connection-error-modal/use-retry-countdown.ts +93 -0
- package/src/components/template-content-panel/index.js +30 -38
- package/src/components/template-part-menu-items/convert-to-regular.js +74 -12
- package/src/components/visual-editor/index.js +6 -23
- package/src/store/private-actions.js +70 -1
- package/src/store/private-selectors.js +216 -28
- package/src/store/reducer.js +41 -0
- package/src/store/selectors.js +0 -19
- package/src/style.scss +4 -1
- package/src/utils/media-finalize/index.js +11 -0
- package/src/utils/media-finalize/test/index.js +34 -0
- package/src/utils/media-upload/on-success.js +34 -0
- package/src/utils/sync-error-messages.ts +72 -0
- package/src/utils/test/sync-error-messages.js +34 -0
- package/build/components/provider/use-post-content-blocks.cjs.map +0 -7
- package/build/components/sync-connection-modal/index.cjs +0 -130
- package/build/components/sync-connection-modal/index.cjs.map +0 -7
- package/build-module/components/provider/use-post-content-blocks.mjs +0 -34
- package/build-module/components/provider/use-post-content-blocks.mjs.map +0 -7
- package/build-module/components/sync-connection-modal/index.mjs +0 -114
- package/build-module/components/sync-connection-modal/index.mjs.map +0 -7
- package/build-types/components/provider/use-post-content-blocks.d.ts +0 -2
- package/build-types/components/provider/use-post-content-blocks.d.ts.map +0 -1
- package/build-types/components/sync-connection-modal/index.d.ts +0 -8
- package/build-types/components/sync-connection-modal/index.d.ts.map +0 -1
- package/src/components/provider/use-post-content-blocks.js +0 -42
- package/src/components/sync-connection-modal/index.js +0 -140
- package/src/components/sync-connection-modal/style.scss +0 -11
- package/src/utils/sync-error-messages.js +0 -53
|
@@ -5,6 +5,7 @@ import { sprintf, __ } from '@wordpress/i18n';
|
|
|
5
5
|
import { Button } from '@wordpress/components';
|
|
6
6
|
import { useSelect, useDispatch } from '@wordpress/data';
|
|
7
7
|
import { backup } from '@wordpress/icons';
|
|
8
|
+
import { addQueryArgs } from '@wordpress/url';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Internal dependencies
|
|
@@ -16,11 +17,16 @@ import { unlock } from '../../lock-unlock';
|
|
|
16
17
|
|
|
17
18
|
function usePostLastRevisionInfo() {
|
|
18
19
|
return useSelect( ( select ) => {
|
|
19
|
-
const {
|
|
20
|
-
|
|
20
|
+
const {
|
|
21
|
+
getCurrentPostLastRevisionId,
|
|
22
|
+
getCurrentPostRevisionsCount,
|
|
23
|
+
getEditorSettings,
|
|
24
|
+
} = select( editorStore );
|
|
21
25
|
return {
|
|
22
26
|
lastRevisionId: getCurrentPostLastRevisionId(),
|
|
23
27
|
revisionsCount: getCurrentPostRevisionsCount(),
|
|
28
|
+
disableVisualRevisions:
|
|
29
|
+
!! getEditorSettings().disableVisualRevisions,
|
|
24
30
|
};
|
|
25
31
|
}, [] );
|
|
26
32
|
}
|
|
@@ -31,14 +37,23 @@ function usePostLastRevisionInfo() {
|
|
|
31
37
|
* @return {React.ReactNode} The rendered component.
|
|
32
38
|
*/
|
|
33
39
|
function PostLastRevision() {
|
|
34
|
-
const { lastRevisionId, revisionsCount } =
|
|
40
|
+
const { lastRevisionId, revisionsCount, disableVisualRevisions } =
|
|
41
|
+
usePostLastRevisionInfo();
|
|
35
42
|
const { setCurrentRevisionId } = unlock( useDispatch( editorStore ) );
|
|
36
43
|
|
|
44
|
+
const buttonProps = disableVisualRevisions
|
|
45
|
+
? {
|
|
46
|
+
href: addQueryArgs( 'revision.php', {
|
|
47
|
+
revision: lastRevisionId,
|
|
48
|
+
} ),
|
|
49
|
+
}
|
|
50
|
+
: { onClick: () => setCurrentRevisionId( lastRevisionId ) };
|
|
51
|
+
|
|
37
52
|
return (
|
|
38
53
|
<PostLastRevisionCheck>
|
|
39
54
|
<Button
|
|
40
55
|
__next40pxDefaultSize
|
|
41
|
-
|
|
56
|
+
{ ...buttonProps }
|
|
42
57
|
className="editor-post-last-revision__title"
|
|
43
58
|
icon={ backup }
|
|
44
59
|
iconPosition="right"
|
|
@@ -53,16 +68,30 @@ function PostLastRevision() {
|
|
|
53
68
|
}
|
|
54
69
|
|
|
55
70
|
export function PrivatePostLastRevision() {
|
|
56
|
-
const { lastRevisionId, revisionsCount } =
|
|
71
|
+
const { lastRevisionId, revisionsCount, disableVisualRevisions } =
|
|
72
|
+
usePostLastRevisionInfo();
|
|
57
73
|
const { setCurrentRevisionId } = unlock( useDispatch( editorStore ) );
|
|
58
74
|
|
|
75
|
+
const buttonProps = disableVisualRevisions
|
|
76
|
+
? {
|
|
77
|
+
href: addQueryArgs( 'revision.php', {
|
|
78
|
+
revision: lastRevisionId,
|
|
79
|
+
} ),
|
|
80
|
+
}
|
|
81
|
+
: { onClick: () => setCurrentRevisionId( lastRevisionId ) };
|
|
82
|
+
|
|
59
83
|
return (
|
|
60
84
|
<PostLastRevisionCheck>
|
|
61
85
|
<PostPanelRow label={ __( 'Revisions' ) }>
|
|
62
86
|
<Button
|
|
63
|
-
|
|
87
|
+
{ ...buttonProps }
|
|
64
88
|
className="editor-private-post-last-revision__button"
|
|
65
89
|
text={ revisionsCount }
|
|
90
|
+
aria-label={ sprintf(
|
|
91
|
+
/* translators: %s: number of revisions. */
|
|
92
|
+
__( 'Open revisions screen: %s revisions' ),
|
|
93
|
+
revisionsCount
|
|
94
|
+
) }
|
|
66
95
|
variant="tertiary"
|
|
67
96
|
size="compact"
|
|
68
97
|
/>
|
|
@@ -15,12 +15,52 @@ import { useEffect, createInterpolateElement } from '@wordpress/element';
|
|
|
15
15
|
import { addAction, removeAction } from '@wordpress/hooks';
|
|
16
16
|
import { useInstanceId } from '@wordpress/compose';
|
|
17
17
|
import { store as coreStore } from '@wordpress/core-data';
|
|
18
|
+
import { unlock } from '../../lock-unlock';
|
|
19
|
+
import { DOCUMENT_SIZE_LIMIT_EXCEEDED } from '../../utils/sync-error-messages';
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
22
|
* Internal dependencies
|
|
21
23
|
*/
|
|
22
24
|
import { store as editorStore } from '../../store';
|
|
23
25
|
|
|
26
|
+
function CollaborationContext() {
|
|
27
|
+
const { isCollaborationSupported, syncConnectionStatus } = useSelect(
|
|
28
|
+
( select ) => {
|
|
29
|
+
const {
|
|
30
|
+
isCollaborationSupported: isSupported,
|
|
31
|
+
getSyncConnectionStatus,
|
|
32
|
+
} = unlock( select( coreStore ) );
|
|
33
|
+
return {
|
|
34
|
+
isCollaborationSupported: isSupported(),
|
|
35
|
+
syncConnectionStatus: getSyncConnectionStatus(),
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
[]
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
if ( isCollaborationSupported ) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if ( DOCUMENT_SIZE_LIMIT_EXCEEDED === syncConnectionStatus?.error?.code ) {
|
|
46
|
+
return (
|
|
47
|
+
<p>
|
|
48
|
+
{ __(
|
|
49
|
+
'Because this post is too large for real-time collaboration, only one person can edit at a time.'
|
|
50
|
+
) }
|
|
51
|
+
</p>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<p>
|
|
57
|
+
{ __(
|
|
58
|
+
'Because this post uses plugins that aren’t compatible with real-time collaboration, only one person can edit at a time.'
|
|
59
|
+
) }
|
|
60
|
+
</p>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
24
64
|
function PostLockedModal() {
|
|
25
65
|
const instanceId = useInstanceId( PostLockedModal );
|
|
26
66
|
const hookName = 'core/editor/post-locked-modal-' + instanceId;
|
|
@@ -37,7 +77,6 @@ function PostLockedModal() {
|
|
|
37
77
|
previewLink,
|
|
38
78
|
} = useSelect( ( select ) => {
|
|
39
79
|
const {
|
|
40
|
-
isCollaborationEnabledForCurrentPost,
|
|
41
80
|
isPostLocked,
|
|
42
81
|
isPostLockTakeover,
|
|
43
82
|
getPostLockUser,
|
|
@@ -46,7 +85,8 @@ function PostLockedModal() {
|
|
|
46
85
|
getEditedPostAttribute,
|
|
47
86
|
getEditedPostPreviewLink,
|
|
48
87
|
getEditorSettings,
|
|
49
|
-
|
|
88
|
+
isCollaborationEnabledForCurrentPost,
|
|
89
|
+
} = unlock( select( editorStore ) );
|
|
50
90
|
const { getPostType } = select( coreStore );
|
|
51
91
|
return {
|
|
52
92
|
isCollaborationEnabled: isCollaborationEnabledForCurrentPost(),
|
|
@@ -197,29 +237,32 @@ function PostLockedModal() {
|
|
|
197
237
|
) }
|
|
198
238
|
<div>
|
|
199
239
|
{ !! isTakeover && (
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
{
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
240
|
+
<>
|
|
241
|
+
<p>
|
|
242
|
+
{ createInterpolateElement(
|
|
243
|
+
userDisplayName
|
|
244
|
+
? sprintf(
|
|
245
|
+
/* translators: %s: user's display name */
|
|
246
|
+
__(
|
|
247
|
+
'<strong>%s</strong> now has editing control of this post (<PreviewLink />). Don’t worry, your changes up to this moment have been saved.'
|
|
248
|
+
),
|
|
249
|
+
userDisplayName
|
|
250
|
+
)
|
|
251
|
+
: __(
|
|
252
|
+
'Another user now has editing control of this post (<PreviewLink />). Don’t worry, your changes up to this moment have been saved.'
|
|
253
|
+
),
|
|
254
|
+
{
|
|
255
|
+
strong: <strong />,
|
|
256
|
+
PreviewLink: (
|
|
257
|
+
<ExternalLink href={ previewLink }>
|
|
258
|
+
{ __( 'preview' ) }
|
|
259
|
+
</ExternalLink>
|
|
260
|
+
),
|
|
261
|
+
}
|
|
262
|
+
) }
|
|
263
|
+
</p>
|
|
264
|
+
<CollaborationContext />
|
|
265
|
+
</>
|
|
223
266
|
) }
|
|
224
267
|
{ ! isTakeover && (
|
|
225
268
|
<>
|
|
@@ -246,6 +289,7 @@ function PostLockedModal() {
|
|
|
246
289
|
}
|
|
247
290
|
) }
|
|
248
291
|
</p>
|
|
292
|
+
<CollaborationContext />
|
|
249
293
|
<p>
|
|
250
294
|
{ __(
|
|
251
295
|
'If you take over, the other user will lose editing control to the post, but their changes will be saved.'
|
|
@@ -29,8 +29,35 @@ import { unlock } from '../../lock-unlock';
|
|
|
29
29
|
const { parseRawBlock } = unlock( blocksPrivateApis );
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
32
|
+
* Safely stringifies a value for display and comparison.
|
|
33
|
+
*
|
|
34
|
+
* @param {*} value The value to stringify.
|
|
35
|
+
* @return {string} The stringified value.
|
|
36
|
+
*/
|
|
37
|
+
function stringifyValue( value ) {
|
|
38
|
+
if ( value === null || value === undefined ) {
|
|
39
|
+
return '';
|
|
40
|
+
}
|
|
41
|
+
if ( typeof value === 'object' ) {
|
|
42
|
+
return JSON.stringify( value, null, 2 );
|
|
43
|
+
}
|
|
44
|
+
return String( value );
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Calculate text similarity using word-set overlap.
|
|
49
|
+
*
|
|
50
|
+
* Uses a variant of the Jaccard index (https://en.wikipedia.org/wiki/Jaccard_index)
|
|
51
|
+
* called the overlap coefficient (https://en.wikipedia.org/wiki/Overlap_coefficient)
|
|
52
|
+
* where we divide by the larger set size rather than the union. This ensures that
|
|
53
|
+
* a small edit to a long paragraph scores high — the few changed words don't
|
|
54
|
+
* dilute the score.
|
|
55
|
+
*
|
|
56
|
+
* This replaces the previous diffWords-based similarity which was O(n*m) per pair.
|
|
57
|
+
* The word-set approach is O(n) where n is the number of words.
|
|
58
|
+
*
|
|
59
|
+
* Words are extracted using Intl.Segmenter for proper multilingual support
|
|
60
|
+
* (CJK, Thai, etc.) rather than splitting on whitespace.
|
|
34
61
|
*
|
|
35
62
|
* @param {string} text1 First text to compare.
|
|
36
63
|
* @param {string} text2 Second text to compare.
|
|
@@ -44,17 +71,53 @@ function textSimilarity( text1, text2 ) {
|
|
|
44
71
|
return 0;
|
|
45
72
|
}
|
|
46
73
|
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
74
|
+
const segmenter = new Intl.Segmenter( undefined, {
|
|
75
|
+
granularity: 'word',
|
|
76
|
+
} );
|
|
77
|
+
// Safari's Intl.Segmenter returns isWordLike: false for numeric segments,
|
|
78
|
+
// so fall back to a Unicode-aware regex for letters and numbers.
|
|
79
|
+
const wordLikeRegex = /[\p{L}\p{N}]/u;
|
|
80
|
+
const getWords = ( text ) => {
|
|
81
|
+
const words = [];
|
|
82
|
+
for ( const { segment, isWordLike } of segmenter.segment( text ) ) {
|
|
83
|
+
if ( isWordLike || wordLikeRegex.test( segment ) ) {
|
|
84
|
+
words.push( segment );
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return words;
|
|
88
|
+
};
|
|
89
|
+
const words1 = getWords( text1 );
|
|
90
|
+
const words2 = getWords( text2 );
|
|
91
|
+
|
|
92
|
+
if ( words1.length === 0 && words2.length === 0 ) {
|
|
93
|
+
return 1;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const set1 = new Set( words1 );
|
|
97
|
+
let intersection = 0;
|
|
98
|
+
for ( const word of words2 ) {
|
|
99
|
+
if ( set1.has( word ) ) {
|
|
100
|
+
intersection++;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const total = Math.max( words1.length, words2.length );
|
|
105
|
+
return total > 0 ? intersection / total : 0;
|
|
53
106
|
}
|
|
54
107
|
|
|
55
108
|
/**
|
|
56
109
|
* Post-process diff result to pair similar removed/added blocks as modifications.
|
|
57
|
-
*
|
|
110
|
+
*
|
|
111
|
+
* After LCS diffing, a block whose content changed appears as a separate "removed"
|
|
112
|
+
* and "added" entry (since the full block signature differs). This function detects
|
|
113
|
+
* such pairs and merges them into a single "modified" block with inline diff.
|
|
114
|
+
*
|
|
115
|
+
* Two pairing strategies are used:
|
|
116
|
+
* 1. When exactly one block of a given type was removed and one was added,
|
|
117
|
+
* they are paired directly — no ambiguity, no similarity check needed.
|
|
118
|
+
* 2. When multiple candidates exist, textSimilarity (overlap coefficient) is
|
|
119
|
+
* used to find the best match. Blocks must share at least 50% of their
|
|
120
|
+
* words to be paired, preventing unrelated paragraphs from being merged.
|
|
58
121
|
*
|
|
59
122
|
* @param {Array} blocks Raw blocks with diff status.
|
|
60
123
|
* @return {Array} Blocks with similar pairs converted to modifications.
|
|
@@ -65,7 +128,7 @@ function pairSimilarBlocks( blocks ) {
|
|
|
65
128
|
|
|
66
129
|
// Separate blocks by status, tracking original indices.
|
|
67
130
|
blocks.forEach( ( block, index ) => {
|
|
68
|
-
const status = block.__revisionDiffStatus;
|
|
131
|
+
const status = block.__revisionDiffStatus?.status;
|
|
69
132
|
if ( status === 'removed' ) {
|
|
70
133
|
removed.push( { block, index } );
|
|
71
134
|
} else if ( status === 'added' ) {
|
|
@@ -78,62 +141,139 @@ function pairSimilarBlocks( blocks ) {
|
|
|
78
141
|
return blocks;
|
|
79
142
|
}
|
|
80
143
|
|
|
81
|
-
const pairedRemoved = new Set(); // Indices of removed blocks
|
|
82
|
-
const
|
|
83
|
-
const
|
|
144
|
+
const pairedRemoved = new Set(); // Indices of removed blocks filtered out.
|
|
145
|
+
const pairedAdded = new Set(); // Indices of added blocks filtered out.
|
|
146
|
+
const modifications = new Map(); // Index → modified block.
|
|
147
|
+
const SIMILARITY_THRESHOLD = 0.5;
|
|
148
|
+
|
|
149
|
+
// Group candidates by block name for efficient lookup.
|
|
150
|
+
const addedByName = new Map();
|
|
151
|
+
for ( const add of added ) {
|
|
152
|
+
const name = add.block.blockName;
|
|
153
|
+
if ( ! addedByName.has( name ) ) {
|
|
154
|
+
addedByName.set( name, [] );
|
|
155
|
+
}
|
|
156
|
+
addedByName.get( name ).push( add );
|
|
157
|
+
}
|
|
158
|
+
const removedByName = new Map();
|
|
159
|
+
for ( const rem of removed ) {
|
|
160
|
+
const name = rem.block.blockName;
|
|
161
|
+
if ( ! removedByName.has( name ) ) {
|
|
162
|
+
removedByName.set( name, [] );
|
|
163
|
+
}
|
|
164
|
+
removedByName.get( name ).push( rem );
|
|
165
|
+
}
|
|
84
166
|
|
|
85
167
|
// For each removed block, find best matching added block.
|
|
168
|
+
// Track the highest added index paired so far — new pairings must
|
|
169
|
+
// not go backwards, or the removed/added text order would break.
|
|
170
|
+
let maxPairedAddedIndex = -1;
|
|
171
|
+
|
|
86
172
|
for ( const rem of removed ) {
|
|
87
|
-
|
|
88
|
-
|
|
173
|
+
const candidates = addedByName.get( rem.block.blockName ) || [];
|
|
174
|
+
const sameNameRemoved = removedByName.get( rem.block.blockName ) || [];
|
|
175
|
+
const unpaired = candidates.filter(
|
|
176
|
+
( add ) =>
|
|
177
|
+
! modifications.has( add.index ) &&
|
|
178
|
+
add.index > maxPairedAddedIndex
|
|
179
|
+
);
|
|
89
180
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
if ( add.block.blockName !== rem.block.blockName ) {
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
181
|
+
if ( unpaired.length === 0 ) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
97
184
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
185
|
+
let bestMatch = null;
|
|
186
|
+
|
|
187
|
+
// If there's exactly one removed and one added of this type,
|
|
188
|
+
// pair them directly — no ambiguity, no similarity check needed.
|
|
189
|
+
if ( sameNameRemoved.length === 1 && unpaired.length === 1 ) {
|
|
190
|
+
const add = unpaired[ 0 ];
|
|
104
191
|
const attrsMatch =
|
|
105
192
|
JSON.stringify( rem.block.attrs ) ===
|
|
106
193
|
JSON.stringify( add.block.attrs );
|
|
107
|
-
if
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
(
|
|
111
|
-
) {
|
|
112
|
-
bestScore = score;
|
|
194
|
+
// Only skip pairing if both content and attrs are identical
|
|
195
|
+
// (position swap, not a modification).
|
|
196
|
+
const contentMatch =
|
|
197
|
+
( rem.block.innerHTML || '' ) === ( add.block.innerHTML || '' );
|
|
198
|
+
if ( ! contentMatch || ! attrsMatch ) {
|
|
113
199
|
bestMatch = add;
|
|
114
200
|
}
|
|
201
|
+
} else {
|
|
202
|
+
// Multiple candidates — use similarity to find best match.
|
|
203
|
+
let bestScore = 0;
|
|
204
|
+
for ( const add of unpaired ) {
|
|
205
|
+
const score = textSimilarity(
|
|
206
|
+
rem.block.innerHTML || '',
|
|
207
|
+
add.block.innerHTML || ''
|
|
208
|
+
);
|
|
209
|
+
// Skip identical blocks (score=1 with same attrs) — those
|
|
210
|
+
// are position swaps, not modifications. They should show
|
|
211
|
+
// as separate removed + added, not as a no-op "modified".
|
|
212
|
+
const attrsMatch =
|
|
213
|
+
JSON.stringify( rem.block.attrs ) ===
|
|
214
|
+
JSON.stringify( add.block.attrs );
|
|
215
|
+
if (
|
|
216
|
+
score > bestScore &&
|
|
217
|
+
score > SIMILARITY_THRESHOLD &&
|
|
218
|
+
( score < 1 || ! attrsMatch )
|
|
219
|
+
) {
|
|
220
|
+
bestScore = score;
|
|
221
|
+
bestMatch = add;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
115
224
|
}
|
|
116
225
|
|
|
117
226
|
if ( bestMatch ) {
|
|
118
|
-
|
|
227
|
+
maxPairedAddedIndex = bestMatch.index;
|
|
119
228
|
|
|
120
|
-
|
|
121
|
-
modifications.set( bestMatch.index, {
|
|
229
|
+
const modifiedBlock = {
|
|
122
230
|
...bestMatch.block,
|
|
123
|
-
__revisionDiffStatus: 'modified',
|
|
231
|
+
__revisionDiffStatus: { status: 'modified' },
|
|
124
232
|
__previousRawBlock: rem.block,
|
|
125
|
-
}
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
// Decide where to place the modified block by checking
|
|
236
|
+
// what's between the removed and added positions.
|
|
237
|
+
// If there are unpaired added blocks between them,
|
|
238
|
+
// placing at the removed position would put the modified
|
|
239
|
+
// block before content that comes before it in the
|
|
240
|
+
// current revision — so use the added position.
|
|
241
|
+
// Otherwise, use the removed position to keep the
|
|
242
|
+
// previous revision's order intact.
|
|
243
|
+
const lo = Math.min( rem.index, bestMatch.index );
|
|
244
|
+
const hi = Math.max( rem.index, bestMatch.index );
|
|
245
|
+
let hasAddedBetween = false;
|
|
246
|
+
for ( let i = lo + 1; i < hi; i++ ) {
|
|
247
|
+
if (
|
|
248
|
+
blocks[ i ].__revisionDiffStatus?.status === 'added' &&
|
|
249
|
+
! pairedAdded.has( i )
|
|
250
|
+
) {
|
|
251
|
+
hasAddedBetween = true;
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if ( hasAddedBetween ) {
|
|
257
|
+
// Use the added position — don't jump before
|
|
258
|
+
// current-revision content.
|
|
259
|
+
modifications.set( bestMatch.index, modifiedBlock );
|
|
260
|
+
pairedRemoved.add( rem.index );
|
|
261
|
+
} else {
|
|
262
|
+
// Use the removed position — keep the previous
|
|
263
|
+
// revision's reading order.
|
|
264
|
+
modifications.set( rem.index, modifiedBlock );
|
|
265
|
+
pairedAdded.add( bestMatch.index );
|
|
266
|
+
}
|
|
126
267
|
}
|
|
127
268
|
}
|
|
128
269
|
|
|
129
|
-
// Rebuild result:
|
|
270
|
+
// Rebuild result: replace modification targets, filter out
|
|
271
|
+
// their paired counterparts.
|
|
130
272
|
return blocks
|
|
131
273
|
.map( ( block, index ) => {
|
|
132
|
-
|
|
133
|
-
if ( pairedRemoved.has( index ) ) {
|
|
274
|
+
if ( pairedRemoved.has( index ) || pairedAdded.has( index ) ) {
|
|
134
275
|
return null;
|
|
135
276
|
}
|
|
136
|
-
// Replace paired added blocks with modified version.
|
|
137
277
|
if ( modifications.has( index ) ) {
|
|
138
278
|
return modifications.get( index );
|
|
139
279
|
}
|
|
@@ -176,14 +316,14 @@ function diffRawBlocks( currentRaw, previousRaw ) {
|
|
|
176
316
|
for ( let i = 0; i < part.count; i++ ) {
|
|
177
317
|
result.push( {
|
|
178
318
|
...currentRaw[ currIdx++ ],
|
|
179
|
-
__revisionDiffStatus: 'added',
|
|
319
|
+
__revisionDiffStatus: { status: 'added' },
|
|
180
320
|
} );
|
|
181
321
|
}
|
|
182
322
|
} else if ( part.removed ) {
|
|
183
323
|
for ( let i = 0; i < part.count; i++ ) {
|
|
184
324
|
result.push( {
|
|
185
325
|
...previousRaw[ prevIdx++ ],
|
|
186
|
-
__revisionDiffStatus: 'removed',
|
|
326
|
+
__revisionDiffStatus: { status: 'removed' },
|
|
187
327
|
} );
|
|
188
328
|
}
|
|
189
329
|
} else {
|
|
@@ -481,26 +621,28 @@ function applyRichTextDiff( currentRichText, previousRichText ) {
|
|
|
481
621
|
}
|
|
482
622
|
|
|
483
623
|
/**
|
|
484
|
-
* Apply
|
|
485
|
-
*
|
|
624
|
+
* Apply diffs to a modified block's attributes.
|
|
625
|
+
* - Rich-text attributes: applies inline diff formatting (ins/del marks).
|
|
626
|
+
* - Other attributes: computes word-level diffs for the sidebar panel.
|
|
486
627
|
*
|
|
487
628
|
* @param {Object} currentBlock Current parsed block.
|
|
488
629
|
* @param {Object} previousBlock Previous parsed block.
|
|
630
|
+
* @param {Object} diffStatus The __revisionDiffStatus object to attach changedAttributes to.
|
|
489
631
|
*/
|
|
490
|
-
function
|
|
632
|
+
function applyDiffToBlock( currentBlock, previousBlock, diffStatus ) {
|
|
491
633
|
const blockType = getBlockType( currentBlock.name );
|
|
492
634
|
if ( ! blockType ) {
|
|
493
635
|
return;
|
|
494
636
|
}
|
|
495
637
|
|
|
496
|
-
|
|
638
|
+
const changedAttributes = {};
|
|
639
|
+
|
|
497
640
|
for ( const [ attrName, attrDef ] of Object.entries(
|
|
498
641
|
blockType.attributes
|
|
499
642
|
) ) {
|
|
500
643
|
if ( attrDef.source === 'rich-text' ) {
|
|
501
644
|
const currentRichText = currentBlock.attributes[ attrName ];
|
|
502
645
|
const previousRichText = previousBlock.attributes[ attrName ];
|
|
503
|
-
|
|
504
646
|
if (
|
|
505
647
|
currentRichText instanceof RichTextData &&
|
|
506
648
|
previousRichText instanceof RichTextData
|
|
@@ -510,8 +652,22 @@ function applyRichTextDiffToBlock( currentBlock, previousBlock ) {
|
|
|
510
652
|
previousRichText
|
|
511
653
|
);
|
|
512
654
|
}
|
|
655
|
+
} else {
|
|
656
|
+
const currStr = stringifyValue(
|
|
657
|
+
currentBlock.attributes[ attrName ]
|
|
658
|
+
);
|
|
659
|
+
const prevStr = stringifyValue(
|
|
660
|
+
previousBlock.attributes[ attrName ]
|
|
661
|
+
);
|
|
662
|
+
if ( currStr !== prevStr ) {
|
|
663
|
+
changedAttributes[ attrName ] = diffWords( prevStr, currStr );
|
|
664
|
+
}
|
|
513
665
|
}
|
|
514
666
|
}
|
|
667
|
+
|
|
668
|
+
if ( Object.keys( changedAttributes ).length > 0 ) {
|
|
669
|
+
diffStatus.changedAttributes = changedAttributes;
|
|
670
|
+
}
|
|
515
671
|
}
|
|
516
672
|
|
|
517
673
|
/**
|
|
@@ -525,18 +681,25 @@ function applyRichTextDiffToBlock( currentBlock, previousBlock ) {
|
|
|
525
681
|
function applyDiffRecursively( parsedBlock, rawBlock ) {
|
|
526
682
|
// Copy diff status from raw block to parsed block.
|
|
527
683
|
if ( rawBlock.__revisionDiffStatus ) {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
684
|
+
// Apply diffs if this block is modified and has a previous raw block.
|
|
685
|
+
if (
|
|
686
|
+
rawBlock.__revisionDiffStatus.status === 'modified' &&
|
|
687
|
+
rawBlock.__previousRawBlock
|
|
688
|
+
) {
|
|
689
|
+
const previousParsed = parseRawBlock( rawBlock.__previousRawBlock );
|
|
690
|
+
if ( previousParsed ) {
|
|
691
|
+
applyDiffToBlock(
|
|
692
|
+
parsedBlock,
|
|
693
|
+
previousParsed,
|
|
694
|
+
rawBlock.__revisionDiffStatus
|
|
695
|
+
);
|
|
696
|
+
}
|
|
539
697
|
}
|
|
698
|
+
|
|
699
|
+
parsedBlock.__revisionDiffStatus = rawBlock.__revisionDiffStatus;
|
|
700
|
+
// Also store in attributes so it survives block-editor store normalization.
|
|
701
|
+
parsedBlock.attributes.__revisionDiffStatus =
|
|
702
|
+
rawBlock.__revisionDiffStatus;
|
|
540
703
|
}
|
|
541
704
|
|
|
542
705
|
// Recursively process inner blocks.
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
store as blockEditorStore,
|
|
16
16
|
} from '@wordpress/block-editor';
|
|
17
17
|
import { __ } from '@wordpress/i18n';
|
|
18
|
+
import { Tooltip } from '@wordpress/components';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Internal dependencies
|
|
@@ -32,10 +33,10 @@ const { useBlockElementRef } = unlock( blockEditorPrivateApis );
|
|
|
32
33
|
function collectDiffBlocks( blocks ) {
|
|
33
34
|
const result = [];
|
|
34
35
|
for ( const block of blocks ) {
|
|
35
|
-
if ( block.__revisionDiffStatus ) {
|
|
36
|
+
if ( block.__revisionDiffStatus?.status ) {
|
|
36
37
|
result.push( {
|
|
37
38
|
clientId: block.clientId,
|
|
38
|
-
status: block.__revisionDiffStatus,
|
|
39
|
+
status: block.__revisionDiffStatus.status,
|
|
39
40
|
} );
|
|
40
41
|
}
|
|
41
42
|
if ( block.innerBlocks?.length ) {
|
|
@@ -97,15 +98,17 @@ function DiffMarkerButton( { clientId, status, subscribe } ) {
|
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
return (
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
101
|
+
<Tooltip text={ STATUS_LABELS[ status ] }>
|
|
102
|
+
<button
|
|
103
|
+
className={ `revision-diff-marker is-${ status }` }
|
|
104
|
+
style={ {
|
|
105
|
+
top: `${ position.top }%`,
|
|
106
|
+
height: `${ Math.max( position.height, 0.5 ) }%`,
|
|
107
|
+
} }
|
|
108
|
+
onClick={ () => blockRef.current?.focus() }
|
|
109
|
+
aria-label={ STATUS_LABELS[ status ] }
|
|
110
|
+
/>
|
|
111
|
+
</Tooltip>
|
|
109
112
|
);
|
|
110
113
|
}
|
|
111
114
|
|
|
@@ -145,7 +148,7 @@ export function useDiffMarkers() {
|
|
|
145
148
|
key="diff-markers"
|
|
146
149
|
className="revision-diff-markers"
|
|
147
150
|
role="navigation"
|
|
148
|
-
aria-label={ __( '
|
|
151
|
+
aria-label={ __( 'Document changes' ) }
|
|
149
152
|
>
|
|
150
153
|
{ isMounted &&
|
|
151
154
|
diffBlocks.map( ( { clientId, status } ) => (
|