@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
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
export interface SelectionRect {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface CursorCoords {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
height: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const MAX_NODE_OFFSET_COUNT = 500;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Given a selection, returns the coordinates of the cursor in the block.
|
|
18
|
+
*
|
|
19
|
+
* @param absolutePositionIndex - The absolute position index
|
|
20
|
+
* @param blockElement - The block element (or null if deleted)
|
|
21
|
+
* @param editorDocument - The editor document
|
|
22
|
+
* @param overlayRect - Pre-computed bounding rect of the overlay element
|
|
23
|
+
* @return The position of the cursor
|
|
24
|
+
*/
|
|
25
|
+
export const getCursorPosition = (
|
|
26
|
+
absolutePositionIndex: number | null,
|
|
27
|
+
blockElement: HTMLElement | null,
|
|
28
|
+
editorDocument: Document,
|
|
29
|
+
overlayRect: DOMRect
|
|
30
|
+
): CursorCoords | null => {
|
|
31
|
+
if ( absolutePositionIndex === null || ! blockElement ) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
getOffsetPositionInBlock(
|
|
37
|
+
blockElement,
|
|
38
|
+
absolutePositionIndex,
|
|
39
|
+
editorDocument,
|
|
40
|
+
overlayRect
|
|
41
|
+
) ?? null
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Given a block element and a character offset, returns the coordinates for drawing a visual cursor in the block.
|
|
47
|
+
*
|
|
48
|
+
* @param blockElement - The block element
|
|
49
|
+
* @param charOffset - The character offset
|
|
50
|
+
* @param editorDocument - The editor document
|
|
51
|
+
* @param overlayRect - Pre-computed bounding rect of the overlay element
|
|
52
|
+
* @return The position of the cursor
|
|
53
|
+
*/
|
|
54
|
+
const getOffsetPositionInBlock = (
|
|
55
|
+
blockElement: HTMLElement,
|
|
56
|
+
charOffset: number,
|
|
57
|
+
editorDocument: Document,
|
|
58
|
+
overlayRect: DOMRect
|
|
59
|
+
) => {
|
|
60
|
+
const { node, offset } = findInnerBlockOffset(
|
|
61
|
+
blockElement,
|
|
62
|
+
charOffset,
|
|
63
|
+
editorDocument
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const cursorRange = editorDocument.createRange();
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
cursorRange.setStart( node, offset );
|
|
70
|
+
} catch ( error ) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Ensure the range only represents single point in the DOM.
|
|
75
|
+
cursorRange.collapse( true );
|
|
76
|
+
|
|
77
|
+
const cursorRect = cursorRange.getBoundingClientRect();
|
|
78
|
+
const blockRect = blockElement.getBoundingClientRect();
|
|
79
|
+
|
|
80
|
+
let cursorX = 0;
|
|
81
|
+
let cursorY = 0;
|
|
82
|
+
|
|
83
|
+
if (
|
|
84
|
+
cursorRect.x === 0 &&
|
|
85
|
+
cursorRect.y === 0 &&
|
|
86
|
+
cursorRect.width === 0 &&
|
|
87
|
+
cursorRect.height === 0
|
|
88
|
+
) {
|
|
89
|
+
// This can happen for empty blocks.
|
|
90
|
+
cursorX = blockRect.left - overlayRect.left;
|
|
91
|
+
cursorY = blockRect.top - overlayRect.top;
|
|
92
|
+
} else {
|
|
93
|
+
cursorX = cursorRect.left - overlayRect.left;
|
|
94
|
+
cursorY = cursorRect.top - overlayRect.top;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
let cursorHeight = cursorRect.height;
|
|
98
|
+
if ( cursorHeight === 0 ) {
|
|
99
|
+
const view = editorDocument.defaultView ?? window;
|
|
100
|
+
cursorHeight =
|
|
101
|
+
parseInt( view.getComputedStyle( blockElement ).lineHeight, 10 ) ||
|
|
102
|
+
blockRect.height;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
x: cursorX,
|
|
107
|
+
y: cursorY,
|
|
108
|
+
height: cursorHeight,
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Computes selection highlight rectangles for a text range within a single block.
|
|
114
|
+
*
|
|
115
|
+
* @param blockElement - The block element
|
|
116
|
+
* @param startOffset - Start character offset within the block
|
|
117
|
+
* @param endOffset - End character offset within the block
|
|
118
|
+
* @param editorDocument - The editor document
|
|
119
|
+
* @param overlayRect - Pre-computed bounding rect of the overlay element
|
|
120
|
+
* @return Array of selection rectangles relative to the overlay, or null on failure
|
|
121
|
+
*/
|
|
122
|
+
export const getSelectionRects = (
|
|
123
|
+
blockElement: HTMLElement,
|
|
124
|
+
startOffset: number,
|
|
125
|
+
endOffset: number,
|
|
126
|
+
editorDocument: Document,
|
|
127
|
+
overlayRect: DOMRect
|
|
128
|
+
): SelectionRect[] | null => {
|
|
129
|
+
// Normalize direction.
|
|
130
|
+
let normalizedStart = startOffset;
|
|
131
|
+
let normalizedEnd = endOffset;
|
|
132
|
+
if ( normalizedStart > normalizedEnd ) {
|
|
133
|
+
[ normalizedStart, normalizedEnd ] = [ normalizedEnd, normalizedStart ];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const startPos = findInnerBlockOffset(
|
|
137
|
+
blockElement,
|
|
138
|
+
normalizedStart,
|
|
139
|
+
editorDocument
|
|
140
|
+
);
|
|
141
|
+
const endPos = findInnerBlockOffset(
|
|
142
|
+
blockElement,
|
|
143
|
+
normalizedEnd,
|
|
144
|
+
editorDocument
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
const range = editorDocument.createRange();
|
|
148
|
+
try {
|
|
149
|
+
range.setStart( startPos.node, startPos.offset );
|
|
150
|
+
range.setEnd( endPos.node, endPos.offset );
|
|
151
|
+
} catch {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const clientRects = range.getClientRects();
|
|
156
|
+
const rects: SelectionRect[] = [];
|
|
157
|
+
|
|
158
|
+
for ( const rect of clientRects ) {
|
|
159
|
+
if ( rect.width === 0 && rect.height === 0 ) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const x = rect.left - overlayRect.left;
|
|
163
|
+
const y = rect.top - overlayRect.top;
|
|
164
|
+
|
|
165
|
+
// Range.getClientRects() can return duplicate rects at inline
|
|
166
|
+
// formatting boundaries (e.g. <em>, <strong>). Skip exact matches.
|
|
167
|
+
const isDuplicate = rects.some(
|
|
168
|
+
( r ) =>
|
|
169
|
+
r.x === x &&
|
|
170
|
+
r.y === y &&
|
|
171
|
+
r.width === rect.width &&
|
|
172
|
+
r.height === rect.height
|
|
173
|
+
);
|
|
174
|
+
if ( isDuplicate ) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
rects.push( {
|
|
179
|
+
x,
|
|
180
|
+
y,
|
|
181
|
+
width: rect.width,
|
|
182
|
+
height: rect.height,
|
|
183
|
+
} );
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return rects.length > 0 ? rects : null;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Computes selection highlight rectangles for the full content of a block.
|
|
191
|
+
* Used for intermediate blocks in a multi-block selection.
|
|
192
|
+
*
|
|
193
|
+
* @param blockElement - The block element
|
|
194
|
+
* @param editorDocument - The editor document
|
|
195
|
+
* @param overlayRect - Pre-computed bounding rect of the overlay element
|
|
196
|
+
* @return Array of selection rectangles relative to the overlay
|
|
197
|
+
*/
|
|
198
|
+
export const getFullBlockSelectionRects = (
|
|
199
|
+
blockElement: HTMLElement,
|
|
200
|
+
editorDocument: Document,
|
|
201
|
+
overlayRect: DOMRect
|
|
202
|
+
): SelectionRect[] => {
|
|
203
|
+
const range = editorDocument.createRange();
|
|
204
|
+
range.selectNodeContents( blockElement );
|
|
205
|
+
const clientRects = range.getClientRects();
|
|
206
|
+
const rects: SelectionRect[] = [];
|
|
207
|
+
|
|
208
|
+
for ( const rect of clientRects ) {
|
|
209
|
+
if ( rect.width === 0 && rect.height === 0 ) {
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
rects.push( {
|
|
213
|
+
x: rect.left - overlayRect.left,
|
|
214
|
+
y: rect.top - overlayRect.top,
|
|
215
|
+
width: rect.width,
|
|
216
|
+
height: rect.height,
|
|
217
|
+
} );
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Fallback: if getClientRects returned nothing, use the block's bounding rect.
|
|
221
|
+
if ( rects.length === 0 ) {
|
|
222
|
+
const blockRect = blockElement.getBoundingClientRect();
|
|
223
|
+
if ( blockRect.width > 0 && blockRect.height > 0 ) {
|
|
224
|
+
rects.push( {
|
|
225
|
+
x: blockRect.left - overlayRect.left,
|
|
226
|
+
y: blockRect.top - overlayRect.top,
|
|
227
|
+
width: blockRect.width,
|
|
228
|
+
height: blockRect.height,
|
|
229
|
+
} );
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return rects;
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Finds all block elements between two blocks in DOM order (exclusive of start and end).
|
|
238
|
+
*
|
|
239
|
+
* @param startBlockId - The clientId of the start block
|
|
240
|
+
* @param endBlockId - The clientId of the end block
|
|
241
|
+
* @param editorDocument - The editor document
|
|
242
|
+
* @return Array of intermediate block HTMLElements in document order
|
|
243
|
+
*/
|
|
244
|
+
export const getBlocksBetween = (
|
|
245
|
+
startBlockId: string,
|
|
246
|
+
endBlockId: string,
|
|
247
|
+
editorDocument: Document
|
|
248
|
+
): HTMLElement[] => {
|
|
249
|
+
const allBlocks =
|
|
250
|
+
editorDocument.querySelectorAll< HTMLElement >( '[data-block]' );
|
|
251
|
+
|
|
252
|
+
let startIndex = -1;
|
|
253
|
+
let endIndex = -1;
|
|
254
|
+
|
|
255
|
+
for ( let i = 0; i < allBlocks.length; i++ ) {
|
|
256
|
+
const blockId = allBlocks[ i ].getAttribute( 'data-block' );
|
|
257
|
+
if ( blockId === startBlockId ) {
|
|
258
|
+
startIndex = i;
|
|
259
|
+
}
|
|
260
|
+
if ( blockId === endBlockId ) {
|
|
261
|
+
endIndex = i;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if ( startIndex === -1 || endIndex === -1 ) {
|
|
266
|
+
return [];
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Normalize order.
|
|
270
|
+
if ( startIndex > endIndex ) {
|
|
271
|
+
[ startIndex, endIndex ] = [ endIndex, startIndex ];
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const result: HTMLElement[] = [];
|
|
275
|
+
for ( let i = startIndex + 1; i < endIndex; i++ ) {
|
|
276
|
+
result.push( allBlocks[ i ] );
|
|
277
|
+
}
|
|
278
|
+
return result;
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Given a block element and a character offset, returns an exact inner node and offset for use in a range.
|
|
283
|
+
*
|
|
284
|
+
* @param blockElement - The block element
|
|
285
|
+
* @param offset - The character offset
|
|
286
|
+
* @param editorDocument - The editor document
|
|
287
|
+
* @return The node and offset of the character at the offset
|
|
288
|
+
*/
|
|
289
|
+
export const findInnerBlockOffset = (
|
|
290
|
+
blockElement: HTMLElement,
|
|
291
|
+
offset: number,
|
|
292
|
+
editorDocument: Document
|
|
293
|
+
) => {
|
|
294
|
+
const treeWalker = editorDocument.createTreeWalker(
|
|
295
|
+
blockElement,
|
|
296
|
+
NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT // eslint-disable-line no-bitwise
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
let currentOffset = 0;
|
|
300
|
+
let lastTextNode: Node | null = null;
|
|
301
|
+
|
|
302
|
+
let node: Node | null = null;
|
|
303
|
+
let nodeCount = 1;
|
|
304
|
+
|
|
305
|
+
while ( ( node = treeWalker.nextNode() ) ) {
|
|
306
|
+
nodeCount++;
|
|
307
|
+
|
|
308
|
+
if ( nodeCount > MAX_NODE_OFFSET_COUNT ) {
|
|
309
|
+
// If we've walked too many nodes, return the last text node or the beginning of the block.
|
|
310
|
+
if ( lastTextNode ) {
|
|
311
|
+
return { node: lastTextNode, offset: 0 };
|
|
312
|
+
}
|
|
313
|
+
return { node: blockElement, offset: 0 };
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const nodeLength = node.nodeValue?.length ?? 0;
|
|
317
|
+
|
|
318
|
+
if ( node.nodeType === Node.ELEMENT_NODE ) {
|
|
319
|
+
if ( node.nodeName === 'BR' ) {
|
|
320
|
+
// Treat <br> as a single "\n" character.
|
|
321
|
+
|
|
322
|
+
if ( currentOffset + 1 >= offset ) {
|
|
323
|
+
// If the <br> occurs right on the target offset, return the next text node.
|
|
324
|
+
const nodeAfterBr = treeWalker.nextNode();
|
|
325
|
+
|
|
326
|
+
if ( nodeAfterBr?.nodeType === Node.TEXT_NODE ) {
|
|
327
|
+
return { node: nodeAfterBr, offset: 0 };
|
|
328
|
+
} else if ( lastTextNode ) {
|
|
329
|
+
// If there's no text node after the <br>, return the end offset of the last text node.
|
|
330
|
+
return {
|
|
331
|
+
node: lastTextNode,
|
|
332
|
+
offset: lastTextNode.nodeValue?.length ?? 0,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
// Just in case, if there's no last text node, return the beginning of the block.
|
|
336
|
+
return { node: blockElement, offset: 0 };
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// The <br> is before the target offset. Count it as a single character.
|
|
340
|
+
currentOffset += 1;
|
|
341
|
+
continue;
|
|
342
|
+
} else {
|
|
343
|
+
// Skip other element types.
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if ( nodeLength === 0 ) {
|
|
349
|
+
// Skip empty nodes.
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if ( currentOffset + nodeLength >= offset ) {
|
|
354
|
+
// This node exceeds the target offset. Return the node and the position of the offset within it.
|
|
355
|
+
return { node, offset: offset - currentOffset };
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
currentOffset += nodeLength;
|
|
359
|
+
|
|
360
|
+
if ( node.nodeType === Node.TEXT_NODE ) {
|
|
361
|
+
lastTextNode = node;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if ( lastTextNode && lastTextNode.nodeValue?.length ) {
|
|
366
|
+
// We didn't reach the target offset. Return the last text node's last character.
|
|
367
|
+
return { node: lastTextNode, offset: lastTextNode.nodeValue.length };
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// We didn't find any text nodes. Return the beginning of the block.
|
|
371
|
+
return { node: blockElement, offset: 0 };
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Check if node `a` precedes node `b` in document order.
|
|
376
|
+
*
|
|
377
|
+
* @param a - First node.
|
|
378
|
+
* @param b - Second node.
|
|
379
|
+
* @return True if `a` comes before `b`.
|
|
380
|
+
*/
|
|
381
|
+
export const isNodeBefore = ( a: Node, b: Node ): boolean =>
|
|
382
|
+
a.compareDocumentPosition( b ) === Node.DOCUMENT_POSITION_FOLLOWING;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
interface ScrollToCursorOptions {
|
|
2
|
+
behavior?: ScrollBehavior;
|
|
3
|
+
block?: ScrollLogicalPosition;
|
|
4
|
+
inline?: ScrollLogicalPosition;
|
|
5
|
+
highlightDuration?: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Cursor Registry
|
|
10
|
+
* ===
|
|
11
|
+
* This registry stores references to cursor elements so that we can access them
|
|
12
|
+
* in different parts of the component tree. This would more ideally be solved
|
|
13
|
+
* with React context or state in the awareness store, but:
|
|
14
|
+
*
|
|
15
|
+
* 1. EditorPresence and BlockCanvasCover slot/fill break context propagation. We
|
|
16
|
+
* don't currently have a way to provide context to both the slot and fill.
|
|
17
|
+
* 2. Storing pointers to the cursor elements in the awareness store might be a
|
|
18
|
+
* better solution, but would require broader refactoring.
|
|
19
|
+
*
|
|
20
|
+
* For now, we create a single instance of this registry and pass it down to the
|
|
21
|
+
* components that need it. It's important that we create a single instance and
|
|
22
|
+
* not a new instance per component or render; use useState with a lazy
|
|
23
|
+
* initializer to accomplish this.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
function highlightCursor( element: HTMLElement, duration: number ): void {
|
|
27
|
+
element.classList.add( 'collaborators-overlay-cursor-highlighted' );
|
|
28
|
+
|
|
29
|
+
setTimeout( () => {
|
|
30
|
+
element.classList.remove( 'collaborators-overlay-cursor-highlighted' );
|
|
31
|
+
}, duration );
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function createCursorRegistry() {
|
|
35
|
+
const cursorMap = new Map< number, HTMLElement >();
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
/**
|
|
39
|
+
* Register a cursor element when it's created.
|
|
40
|
+
*
|
|
41
|
+
* @param clientId - The clientId of the cursor to register.
|
|
42
|
+
* @param element - The cursor element to register.
|
|
43
|
+
*/
|
|
44
|
+
registerCursor( clientId: number, element: HTMLElement ): void {
|
|
45
|
+
cursorMap.set( clientId, element );
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Unregister a cursor element when it's removed.
|
|
50
|
+
*
|
|
51
|
+
* @param clientId - The clientId of the cursor to unregister.
|
|
52
|
+
*/
|
|
53
|
+
unregisterCursor( clientId: number ): void {
|
|
54
|
+
cursorMap.delete( clientId );
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Scroll to a cursor by clientId.
|
|
59
|
+
*
|
|
60
|
+
* @param clientId - The clientId of the cursor to scroll to.
|
|
61
|
+
* @param options - The options for the scroll.
|
|
62
|
+
* @return true if cursor was found and scrolled to, false otherwise.
|
|
63
|
+
*/
|
|
64
|
+
scrollToCursor(
|
|
65
|
+
clientId: number,
|
|
66
|
+
options?: ScrollToCursorOptions
|
|
67
|
+
): boolean {
|
|
68
|
+
const cursorElement = cursorMap.get( clientId );
|
|
69
|
+
|
|
70
|
+
if ( ! cursorElement ) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
cursorElement.scrollIntoView( {
|
|
75
|
+
behavior: options?.behavior ?? 'smooth',
|
|
76
|
+
block: options?.block ?? 'center',
|
|
77
|
+
inline: options?.inline ?? 'nearest',
|
|
78
|
+
} );
|
|
79
|
+
|
|
80
|
+
if ( options?.highlightDuration ) {
|
|
81
|
+
highlightCursor( cursorElement, options.highlightDuration );
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return true;
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Clear the registry.
|
|
89
|
+
*/
|
|
90
|
+
removeAll(): void {
|
|
91
|
+
cursorMap.clear();
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export type CursorRegistry = ReturnType< typeof createCursorRegistry >;
|
|
@@ -9,22 +9,29 @@ import { privateApis } from '@wordpress/block-editor';
|
|
|
9
9
|
*/
|
|
10
10
|
import { unlock } from '../../lock-unlock';
|
|
11
11
|
import { Overlay } from './overlay';
|
|
12
|
+
import { type CursorRegistry } from './cursor-registry';
|
|
12
13
|
|
|
13
14
|
const { BlockCanvasCover } = unlock( privateApis );
|
|
14
15
|
|
|
15
16
|
interface Props {
|
|
16
17
|
postId: number | null;
|
|
17
18
|
postType: string | null;
|
|
19
|
+
cursorRegistry?: CursorRegistry;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
/**
|
|
21
23
|
* Collaborators Overlay component
|
|
22
|
-
* @param props
|
|
23
|
-
* @param props.postId
|
|
24
|
-
* @param props.postType
|
|
24
|
+
* @param props - The props for the CollaboratorsOverlay component
|
|
25
|
+
* @param props.postId - The ID of the post
|
|
26
|
+
* @param props.postType - The type of the post
|
|
27
|
+
* @param props.cursorRegistry - The shared cursor registry
|
|
25
28
|
* @return The CollaboratorsOverlay component
|
|
26
29
|
*/
|
|
27
|
-
export function CollaboratorsOverlay( {
|
|
30
|
+
export function CollaboratorsOverlay( {
|
|
31
|
+
postId,
|
|
32
|
+
postType,
|
|
33
|
+
cursorRegistry,
|
|
34
|
+
}: Props ) {
|
|
28
35
|
return (
|
|
29
36
|
<BlockCanvasCover.Fill>
|
|
30
37
|
{ ( {
|
|
@@ -36,6 +43,7 @@ export function CollaboratorsOverlay( { postId, postType }: Props ) {
|
|
|
36
43
|
blockEditorDocument={ containerRef.current?.ownerDocument }
|
|
37
44
|
postId={ postId }
|
|
38
45
|
postType={ postType }
|
|
46
|
+
cursorRegistry={ cursorRegistry }
|
|
39
47
|
/>
|
|
40
48
|
) }
|
|
41
49
|
</BlockCanvasCover.Fill>
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS for the collaborators overlay — cursor indicators, block highlights,
|
|
3
|
+
* and positioning of Avatar labels inside the editor canvas iframe.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
BORDER_WIDTH,
|
|
8
|
+
BORDER_WIDTH_FOCUS_FALLBACK,
|
|
9
|
+
ELEVATION_X_SMALL,
|
|
10
|
+
GRID_UNIT_05,
|
|
11
|
+
GRID_UNIT_10,
|
|
12
|
+
WHITE,
|
|
13
|
+
} from './collaborator-styles';
|
|
14
|
+
|
|
15
|
+
export const OVERLAY_IFRAME_STYLES = `
|
|
16
|
+
.block-canvas-cover {
|
|
17
|
+
position: absolute;
|
|
18
|
+
top: 0;
|
|
19
|
+
left: 0;
|
|
20
|
+
width: 100%;
|
|
21
|
+
height: 100%;
|
|
22
|
+
pointer-events: none;
|
|
23
|
+
z-index: 20000;
|
|
24
|
+
}
|
|
25
|
+
.block-canvas-cover .collaborators-overlay-full {
|
|
26
|
+
position: absolute;
|
|
27
|
+
top: 0;
|
|
28
|
+
left: 0;
|
|
29
|
+
width: 100%;
|
|
30
|
+
height: 100%;
|
|
31
|
+
}
|
|
32
|
+
.block-canvas-cover .collaborators-overlay-fixed {
|
|
33
|
+
position: fixed;
|
|
34
|
+
width: 100%;
|
|
35
|
+
height: 100%;
|
|
36
|
+
}
|
|
37
|
+
.collaborators-overlay-user {
|
|
38
|
+
position: absolute;
|
|
39
|
+
}
|
|
40
|
+
/* Cursor lines render below avatar labels across all users. The parent
|
|
41
|
+
.collaborators-overlay-user has no z-index so it does not create a
|
|
42
|
+
stacking context — children participate in the shared overlay context. */
|
|
43
|
+
.collaborators-overlay-user-cursor {
|
|
44
|
+
position: absolute;
|
|
45
|
+
z-index: 0;
|
|
46
|
+
width: ${ BORDER_WIDTH_FOCUS_FALLBACK };
|
|
47
|
+
border-radius: ${ BORDER_WIDTH };
|
|
48
|
+
outline: ${ BORDER_WIDTH } solid ${ WHITE };
|
|
49
|
+
box-shadow: ${ ELEVATION_X_SMALL };
|
|
50
|
+
animation: collaborators-overlay-cursor-blink 1s infinite;
|
|
51
|
+
}
|
|
52
|
+
.collaborators-overlay-selection-rect {
|
|
53
|
+
position: absolute;
|
|
54
|
+
opacity: 0.15;
|
|
55
|
+
pointer-events: none;
|
|
56
|
+
border-radius: 2px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* Overlay-specific positioning applied to the Avatar cursor label. */
|
|
60
|
+
.collaborators-overlay-user-label.editor-avatar {
|
|
61
|
+
position: absolute;
|
|
62
|
+
z-index: 1;
|
|
63
|
+
transform: translate(-11px, -100%);
|
|
64
|
+
margin-top: -${ GRID_UNIT_05 };
|
|
65
|
+
pointer-events: auto;
|
|
66
|
+
overflow: visible;
|
|
67
|
+
width: max-content;
|
|
68
|
+
}
|
|
69
|
+
/* Avatar positioned above a highlighted block as a label. */
|
|
70
|
+
.collaborators-overlay-block-label.editor-avatar {
|
|
71
|
+
position: absolute;
|
|
72
|
+
z-index: 1;
|
|
73
|
+
transform: translateY(calc(-100% - ${ GRID_UNIT_10 }));
|
|
74
|
+
pointer-events: auto;
|
|
75
|
+
overflow: visible;
|
|
76
|
+
width: max-content;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@keyframes collaborators-overlay-cursor-blink {
|
|
80
|
+
0%, 45% { opacity: 1; }
|
|
81
|
+
55%, 95% { opacity: 0; }
|
|
82
|
+
100% { opacity: 1; }
|
|
83
|
+
}
|
|
84
|
+
.collaborators-overlay-cursor-highlighted .collaborators-overlay-user-cursor {
|
|
85
|
+
animation: collaborators-overlay-cursor-highlight 0.6s ease-in-out 3;
|
|
86
|
+
}
|
|
87
|
+
.collaborators-overlay-cursor-highlighted .collaborators-overlay-user-label {
|
|
88
|
+
animation: collaborators-overlay-label-highlight 0.6s ease-in-out 3;
|
|
89
|
+
}
|
|
90
|
+
@keyframes collaborators-overlay-cursor-highlight {
|
|
91
|
+
0%, 100% {
|
|
92
|
+
transform: scale(1);
|
|
93
|
+
filter: drop-shadow(0 0 0 transparent);
|
|
94
|
+
}
|
|
95
|
+
50% {
|
|
96
|
+
transform: scale(1.2);
|
|
97
|
+
filter: drop-shadow(0 0 8px currentColor);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
@keyframes collaborators-overlay-label-highlight {
|
|
101
|
+
0%, 100% {
|
|
102
|
+
transform: translate(-11px, -100%) scale(1);
|
|
103
|
+
filter: drop-shadow(0 0 0 transparent);
|
|
104
|
+
}
|
|
105
|
+
50% {
|
|
106
|
+
transform: translate(-11px, -100%) scale(1.1);
|
|
107
|
+
filter: drop-shadow(0 0 6px currentColor);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
.block-editor-block-list__block.is-collaborator-selected:not(:focus)::after {
|
|
111
|
+
content: "";
|
|
112
|
+
position: absolute;
|
|
113
|
+
pointer-events: none;
|
|
114
|
+
top: 0;
|
|
115
|
+
right: 0;
|
|
116
|
+
bottom: 0;
|
|
117
|
+
left: 0;
|
|
118
|
+
outline-color: var(--collaborator-outline-color);
|
|
119
|
+
outline-style: solid;
|
|
120
|
+
outline-width: calc(var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1));
|
|
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) / var(--wp-block-editor-iframe-zoom-out-scale, 1)) + 0.5px) rgba(${ WHITE }, 0.7);
|
|
123
|
+
z-index: 1;
|
|
124
|
+
}
|
|
125
|
+
@media (prefers-reduced-motion: reduce) {
|
|
126
|
+
.collaborators-overlay-user-label,
|
|
127
|
+
.collaborators-overlay-user-cursor {
|
|
128
|
+
animation: none;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
`;
|