@wordpress/editor 14.45.2-next.v.202605131032.0 → 14.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -1
- package/build/components/collab-sidebar/add-note.cjs +6 -0
- package/build/components/collab-sidebar/add-note.cjs.map +2 -2
- package/build/components/collab-sidebar/hooks.cjs +36 -24
- package/build/components/collab-sidebar/hooks.cjs.map +2 -2
- package/build/components/collab-sidebar/index.cjs +19 -10
- package/build/components/collab-sidebar/index.cjs.map +2 -2
- package/build/components/collab-sidebar/note-byline.cjs +16 -9
- package/build/components/collab-sidebar/note-byline.cjs.map +2 -2
- package/build/components/collab-sidebar/notes.cjs +20 -11
- package/build/components/collab-sidebar/notes.cjs.map +2 -2
- package/build/components/collab-sidebar/utils.cjs +42 -2
- package/build/components/collab-sidebar/utils.cjs.map +2 -2
- package/build/components/collaborators-overlay/compute-selection.cjs +39 -15
- package/build/components/collaborators-overlay/compute-selection.cjs.map +3 -3
- package/build/components/collaborators-overlay/use-block-highlighting.cjs +10 -2
- package/build/components/collaborators-overlay/use-block-highlighting.cjs.map +3 -3
- package/build/components/collaborators-overlay/use-render-cursors.cjs +15 -7
- package/build/components/collaborators-overlay/use-render-cursors.cjs.map +3 -3
- package/build/components/collaborators-presence/avatar/component.cjs +5 -1
- package/build/components/collaborators-presence/avatar/component.cjs.map +3 -3
- package/build/components/collaborators-presence/use-collaborator-notifications.cjs +6 -3
- package/build/components/collaborators-presence/use-collaborator-notifications.cjs.map +2 -2
- package/build/components/editor-interface/index.cjs +17 -16
- package/build/components/editor-interface/index.cjs.map +3 -3
- package/build/components/editor-notices/index.cjs +6 -1
- package/build/components/editor-notices/index.cjs.map +3 -3
- package/build/components/global-styles/hooks.cjs +12 -1
- package/build/components/global-styles/hooks.cjs.map +2 -2
- package/build/components/header/index.cjs +11 -6
- package/build/components/header/index.cjs.map +2 -2
- package/build/components/media/media-editor-modal.cjs +14 -1
- package/build/components/media/media-editor-modal.cjs.map +2 -2
- package/build/components/post-card-panel/index.cjs +7 -1
- package/build/components/post-card-panel/index.cjs.map +3 -3
- package/build/components/post-last-revision/index.cjs +28 -8
- package/build/components/post-last-revision/index.cjs.map +2 -2
- package/build/components/post-locked-modal/index.cjs +9 -6
- package/build/components/post-locked-modal/index.cjs.map +2 -2
- package/build/components/post-publish-button/label.cjs +0 -7
- package/build/components/post-publish-button/label.cjs.map +2 -2
- package/build/components/post-publish-panel/prepublish.cjs +8 -1
- package/build/components/post-publish-panel/prepublish.cjs.map +3 -3
- package/build/components/post-revisions-panel/index.cjs +7 -0
- package/build/components/post-revisions-panel/index.cjs.map +2 -2
- package/build/components/post-revisions-preview/diff-markers.cjs +21 -13
- package/build/components/post-revisions-preview/diff-markers.cjs.map +2 -2
- package/build/components/post-revisions-preview/revisions-canvas.cjs +7 -1
- package/build/components/post-revisions-preview/revisions-canvas.cjs.map +2 -2
- package/build/components/post-taxonomies/check.cjs +1 -2
- package/build/components/post-taxonomies/check.cjs.map +2 -2
- package/build/components/post-taxonomies/index.cjs +1 -2
- package/build/components/post-taxonomies/index.cjs.map +2 -2
- package/build/components/preferences-modal/index.cjs +1 -1
- package/build/components/preferences-modal/index.cjs.map +2 -2
- package/build/components/preview-dropdown/index.cjs.map +3 -3
- package/build/components/provider/index.cjs +5 -21
- package/build/components/provider/index.cjs.map +3 -3
- package/build/components/provider/use-block-editor-settings.cjs +16 -9
- package/build/components/provider/use-block-editor-settings.cjs.map +3 -3
- package/build/components/resizable-editor/resize-handle.cjs +24 -16
- package/build/components/resizable-editor/resize-handle.cjs.map +2 -2
- package/build/components/sidebar/header.cjs +16 -21
- package/build/components/sidebar/header.cjs.map +3 -3
- package/build/components/sidebar/index.cjs +2 -6
- package/build/components/sidebar/index.cjs.map +2 -2
- package/build/components/start-page-options/index.cjs +14 -4
- package/build/components/start-page-options/index.cjs.map +2 -2
- package/build/components/start-template-options/index.cjs +8 -6
- package/build/components/start-template-options/index.cjs.map +2 -2
- package/build/components/styles-canvas/style-book.cjs +59 -2
- package/build/components/styles-canvas/style-book.cjs.map +2 -2
- package/build/components/sync-connection-error-modal/index.cjs +10 -7
- package/build/components/sync-connection-error-modal/index.cjs.map +3 -3
- package/build/components/template-actions-panel/block-theme-content.cjs +21 -12
- package/build/components/template-actions-panel/block-theme-content.cjs.map +2 -2
- package/build/dataviews/store/private-actions.cjs.map +2 -2
- package/build/store/private-actions.cjs +17 -1
- package/build/store/private-actions.cjs.map +3 -3
- package/build/store/private-selectors.cjs +18 -0
- package/build/store/private-selectors.cjs.map +2 -2
- package/build/store/selectors.cjs +0 -17
- package/build/store/selectors.cjs.map +2 -2
- package/build/{components/media → utils/media-delete}/index.cjs +12 -13
- package/build/utils/media-delete/index.cjs.map +7 -0
- package/build/utils/media-finalize/index.cjs +3 -1
- package/build/utils/media-finalize/index.cjs.map +2 -2
- package/build/utils/sync-error-messages.cjs +9 -0
- package/build/utils/sync-error-messages.cjs.map +2 -2
- package/build-module/components/collab-sidebar/add-note.mjs +6 -0
- package/build-module/components/collab-sidebar/add-note.mjs.map +2 -2
- package/build-module/components/collab-sidebar/hooks.mjs +42 -25
- package/build-module/components/collab-sidebar/hooks.mjs.map +2 -2
- package/build-module/components/collab-sidebar/index.mjs +19 -10
- package/build-module/components/collab-sidebar/index.mjs.map +2 -2
- package/build-module/components/collab-sidebar/note-byline.mjs +17 -10
- package/build-module/components/collab-sidebar/note-byline.mjs.map +2 -2
- package/build-module/components/collab-sidebar/notes.mjs +26 -13
- package/build-module/components/collab-sidebar/notes.mjs.map +2 -2
- package/build-module/components/collab-sidebar/utils.mjs +38 -2
- package/build-module/components/collab-sidebar/utils.mjs.map +2 -2
- package/build-module/components/collaborators-overlay/compute-selection.mjs +36 -12
- package/build-module/components/collaborators-overlay/compute-selection.mjs.map +2 -2
- package/build-module/components/collaborators-overlay/use-block-highlighting.mjs +10 -3
- package/build-module/components/collaborators-overlay/use-block-highlighting.mjs.map +2 -2
- package/build-module/components/collaborators-overlay/use-render-cursors.mjs +11 -6
- package/build-module/components/collaborators-overlay/use-render-cursors.mjs.map +2 -2
- package/build-module/components/collaborators-presence/avatar/component.mjs +7 -3
- package/build-module/components/collaborators-presence/avatar/component.mjs.map +2 -2
- package/build-module/components/collaborators-presence/use-collaborator-notifications.mjs +6 -3
- package/build-module/components/collaborators-presence/use-collaborator-notifications.mjs.map +2 -2
- package/build-module/components/editor-interface/index.mjs +22 -17
- package/build-module/components/editor-interface/index.mjs.map +2 -2
- package/build-module/components/editor-notices/index.mjs +6 -1
- package/build-module/components/editor-notices/index.mjs.map +2 -2
- package/build-module/components/global-styles/hooks.mjs +12 -1
- package/build-module/components/global-styles/hooks.mjs.map +2 -2
- package/build-module/components/header/index.mjs +11 -6
- package/build-module/components/header/index.mjs.map +2 -2
- package/build-module/components/media/media-editor-modal.mjs +14 -1
- package/build-module/components/media/media-editor-modal.mjs.map +2 -2
- package/build-module/components/post-card-panel/index.mjs +8 -2
- package/build-module/components/post-card-panel/index.mjs.map +2 -2
- package/build-module/components/post-last-revision/index.mjs +29 -9
- package/build-module/components/post-last-revision/index.mjs.map +2 -2
- package/build-module/components/post-locked-modal/index.mjs +9 -6
- package/build-module/components/post-locked-modal/index.mjs.map +2 -2
- package/build-module/components/post-publish-button/label.mjs +0 -7
- package/build-module/components/post-publish-button/label.mjs.map +2 -2
- package/build-module/components/post-publish-panel/prepublish.mjs +9 -2
- package/build-module/components/post-publish-panel/prepublish.mjs.map +2 -2
- package/build-module/components/post-revisions-panel/index.mjs +7 -0
- package/build-module/components/post-revisions-panel/index.mjs.map +2 -2
- package/build-module/components/post-revisions-preview/diff-markers.mjs +22 -14
- package/build-module/components/post-revisions-preview/diff-markers.mjs.map +2 -2
- package/build-module/components/post-revisions-preview/revisions-canvas.mjs +7 -1
- package/build-module/components/post-revisions-preview/revisions-canvas.mjs.map +2 -2
- package/build-module/components/post-taxonomies/check.mjs +1 -2
- package/build-module/components/post-taxonomies/check.mjs.map +2 -2
- package/build-module/components/post-taxonomies/index.mjs +1 -2
- package/build-module/components/post-taxonomies/index.mjs.map +2 -2
- package/build-module/components/preferences-modal/index.mjs +1 -1
- package/build-module/components/preferences-modal/index.mjs.map +2 -2
- package/build-module/components/preview-dropdown/index.mjs +2 -2
- package/build-module/components/preview-dropdown/index.mjs.map +2 -2
- package/build-module/components/provider/index.mjs +6 -22
- package/build-module/components/provider/index.mjs.map +2 -2
- package/build-module/components/provider/use-block-editor-settings.mjs +16 -9
- package/build-module/components/provider/use-block-editor-settings.mjs.map +2 -2
- package/build-module/components/resizable-editor/resize-handle.mjs +26 -18
- package/build-module/components/resizable-editor/resize-handle.mjs.map +2 -2
- package/build-module/components/sidebar/header.mjs +11 -16
- package/build-module/components/sidebar/header.mjs.map +2 -2
- package/build-module/components/sidebar/index.mjs +2 -7
- package/build-module/components/sidebar/index.mjs.map +2 -2
- package/build-module/components/start-page-options/index.mjs +14 -4
- package/build-module/components/start-page-options/index.mjs.map +2 -2
- package/build-module/components/start-template-options/index.mjs +8 -6
- package/build-module/components/start-template-options/index.mjs.map +2 -2
- package/build-module/components/styles-canvas/style-book.mjs +60 -3
- package/build-module/components/styles-canvas/style-book.mjs.map +2 -2
- package/build-module/components/sync-connection-error-modal/index.mjs +14 -8
- package/build-module/components/sync-connection-error-modal/index.mjs.map +2 -2
- package/build-module/components/template-actions-panel/block-theme-content.mjs +21 -13
- package/build-module/components/template-actions-panel/block-theme-content.mjs.map +2 -2
- package/build-module/dataviews/store/private-actions.mjs.map +2 -2
- package/build-module/store/private-actions.mjs +16 -1
- package/build-module/store/private-actions.mjs.map +2 -2
- package/build-module/store/private-selectors.mjs +18 -0
- package/build-module/store/private-selectors.mjs.map +2 -2
- package/build-module/store/selectors.mjs +0 -16
- package/build-module/store/selectors.mjs.map +2 -2
- package/build-module/utils/media-delete/index.mjs +12 -0
- package/build-module/utils/media-delete/index.mjs.map +7 -0
- package/build-module/utils/media-finalize/index.mjs +3 -1
- package/build-module/utils/media-finalize/index.mjs.map +2 -2
- package/build-module/utils/sync-error-messages.mjs +8 -0
- package/build-module/utils/sync-error-messages.mjs.map +2 -2
- package/build-style/style-rtl.css +462 -408
- package/build-style/style.css +462 -408
- package/build-types/components/collab-sidebar/add-note.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/hooks.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/index.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/note-byline.d.ts +3 -0
- package/build-types/components/collab-sidebar/note-byline.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/notes.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/utils.d.ts +33 -0
- package/build-types/components/collab-sidebar/utils.d.ts.map +1 -1
- package/build-types/components/collaborators-overlay/compute-selection.d.ts.map +1 -1
- package/build-types/components/collaborators-overlay/use-block-highlighting.d.ts +3 -0
- package/build-types/components/collaborators-overlay/use-block-highlighting.d.ts.map +1 -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.map +1 -1
- package/build-types/components/collaborators-presence/use-collaborator-notifications.d.ts.map +1 -1
- package/build-types/components/editor-interface/index.d.ts.map +1 -1
- package/build-types/components/editor-notices/index.d.ts.map +1 -1
- package/build-types/components/global-styles/hooks.d.ts.map +1 -1
- package/build-types/components/media/media-editor-modal.d.ts +6 -2
- package/build-types/components/media/media-editor-modal.d.ts.map +1 -1
- package/build-types/components/post-card-panel/index.d.ts.map +1 -1
- package/build-types/components/post-last-revision/index.d.ts.map +1 -1
- package/build-types/components/post-locked-modal/index.d.ts +1 -6
- package/build-types/components/post-locked-modal/index.d.ts.map +1 -1
- package/build-types/components/post-publish-button/label.d.ts.map +1 -1
- package/build-types/components/post-publish-panel/prepublish.d.ts.map +1 -1
- package/build-types/components/post-revisions-panel/index.d.ts +1 -1
- package/build-types/components/post-revisions-panel/index.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.map +1 -1
- package/build-types/components/post-taxonomies/check.d.ts.map +1 -1
- package/build-types/components/post-taxonomies/flat-term-selector.d.ts +1 -6
- package/build-types/components/post-taxonomies/hierarchical-term-selector.d.ts +1 -6
- package/build-types/components/post-taxonomies/index.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/resizable-editor/resize-handle.d.ts.map +1 -1
- package/build-types/components/sidebar/index.d.ts.map +1 -1
- package/build-types/components/start-page-options/index.d.ts.map +1 -1
- package/build-types/components/start-template-options/index.d.ts.map +1 -1
- package/build-types/components/styles-canvas/style-book.d.ts.map +1 -1
- package/build-types/components/sync-connection-error-modal/index.d.ts.map +1 -1
- package/build-types/components/template-actions-panel/block-theme-content.d.ts.map +1 -1
- package/build-types/dataviews/store/private-actions.d.ts +0 -1
- package/build-types/dataviews/store/private-actions.d.ts.map +1 -1
- package/build-types/store/private-actions.d.ts +15 -0
- package/build-types/store/private-actions.d.ts.map +1 -1
- package/build-types/store/private-selectors.d.ts +10 -0
- package/build-types/store/private-selectors.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/get-template-part-icon.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 +1 -1
- package/build-types/utils/media-finalize/index.d.ts.map +1 -1
- package/build-types/utils/sync-error-messages.d.ts +1 -0
- package/build-types/utils/sync-error-messages.d.ts.map +1 -1
- package/package.json +48 -48
- package/src/components/collab-sidebar/add-note.js +9 -0
- package/src/components/collab-sidebar/hooks.js +53 -29
- package/src/components/collab-sidebar/index.js +28 -14
- package/src/components/collab-sidebar/note-byline.js +15 -10
- package/src/components/collab-sidebar/notes.js +36 -14
- package/src/components/collab-sidebar/test/utils.js +375 -1
- package/src/components/collab-sidebar/utils.js +70 -1
- package/src/components/collaborators-overlay/compute-selection.ts +67 -19
- package/src/components/collaborators-overlay/use-block-highlighting.ts +14 -1
- package/src/components/collaborators-overlay/use-render-cursors.ts +15 -4
- package/src/components/collaborators-presence/avatar/component.tsx +10 -3
- package/src/components/collaborators-presence/avatar/test/index.tsx +50 -18
- package/src/components/collaborators-presence/styles/collaborators-presence.scss +4 -1
- package/src/components/collaborators-presence/test/use-collaborator-notifications.ts +2 -1
- package/src/components/collaborators-presence/use-collaborator-notifications.ts +6 -4
- package/src/components/editor-help/help-topic-row.native.js +2 -2
- package/src/components/editor-interface/index.js +22 -23
- package/src/components/editor-interface/style.scss +4 -0
- package/src/components/editor-notices/index.js +7 -1
- package/src/components/error-boundary/index.native.js +2 -2
- package/src/components/global-styles/hooks.js +26 -0
- package/src/components/global-styles-sidebar/style.scss +0 -9
- package/src/components/header/index.js +12 -12
- package/src/components/media/media-editor-modal.js +20 -2
- package/src/components/offline-status/index.native.js +2 -2
- package/src/components/post-card-panel/index.js +5 -2
- package/src/components/post-last-revision/index.js +37 -9
- package/src/components/post-last-revision/style.scss +0 -3
- package/src/components/post-locked-modal/index.js +8 -5
- package/src/components/post-panel-row/style.scss +1 -0
- package/src/components/post-publish-button/label.js +0 -11
- package/src/components/post-publish-panel/prepublish.js +6 -2
- package/src/components/post-revisions-panel/index.js +8 -0
- package/src/components/post-revisions-preview/diff-markers.js +17 -11
- package/src/components/post-revisions-preview/revisions-canvas.js +7 -1
- package/src/components/post-revisions-preview/style.scss +4 -4
- package/src/components/post-taxonomies/check.js +1 -2
- package/src/components/post-taxonomies/index.js +1 -2
- package/src/components/preferences-modal/index.js +1 -1
- package/src/components/preview-dropdown/index.js +2 -2
- package/src/components/provider/index.js +10 -31
- package/src/components/provider/use-block-editor-settings.js +19 -12
- package/src/components/resizable-editor/resize-handle.js +22 -16
- package/src/components/sidebar/header.js +18 -28
- package/src/components/sidebar/index.js +5 -14
- package/src/components/start-page-options/index.js +19 -4
- package/src/components/start-template-options/index.js +13 -6
- package/src/components/styles-canvas/style-book.js +75 -13
- package/src/components/sync-connection-error-modal/index.tsx +25 -11
- package/src/components/template-actions-panel/block-theme-content.js +19 -13
- package/src/components/text-editor/style.scss +2 -2
- package/src/dataviews/store/private-actions.ts +0 -1
- package/src/store/private-actions.js +27 -0
- package/src/store/private-selectors.js +26 -0
- package/src/store/selectors.js +0 -24
- package/src/store/test/actions.js +34 -0
- package/src/utils/media-delete/index.js +11 -0
- package/src/utils/media-finalize/index.js +6 -1
- package/src/utils/media-finalize/test/index.js +32 -2
- package/src/utils/sync-error-messages.ts +8 -0
- package/src/utils/test/sync-error-messages.js +1 -0
- package/build/components/global-styles-provider/index.cjs +0 -181
- package/build/components/global-styles-provider/index.cjs.map +0 -7
- package/build/components/media/index.cjs.map +0 -7
- package/build/components/media/metadata-panel.cjs +0 -96
- package/build/components/media/metadata-panel.cjs.map +0 -7
- package/build/components/media/preview.cjs +0 -39
- package/build/components/media/preview.cjs.map +0 -7
- package/build-module/components/global-styles-provider/index.mjs +0 -156
- package/build-module/components/global-styles-provider/index.mjs.map +0 -7
- package/build-module/components/media/index.mjs +0 -8
- package/build-module/components/media/index.mjs.map +0 -7
- package/build-module/components/media/metadata-panel.mjs +0 -65
- package/build-module/components/media/metadata-panel.mjs.map +0 -7
- package/build-module/components/media/preview.mjs +0 -21
- package/build-module/components/media/preview.mjs.map +0 -7
- package/build-types/components/global-styles-provider/index.d.ts +0 -16
- package/build-types/components/global-styles-provider/index.d.ts.map +0 -1
- package/build-types/components/media/index.d.ts +0 -3
- package/build-types/components/media/index.d.ts.map +0 -1
- package/build-types/components/media/metadata-panel.d.ts +0 -12
- package/build-types/components/media/metadata-panel.d.ts.map +0 -1
- package/build-types/components/media/preview.d.ts +0 -9
- package/build-types/components/media/preview.d.ts.map +0 -1
- package/src/components/global-styles-provider/index.js +0 -207
- package/src/components/media/index.js +0 -2
- package/src/components/media/metadata-panel.js +0 -77
- package/src/components/media/preview.js +0 -35
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/collab-sidebar/notes.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useEffect, useMemo } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { Stack } from '@wordpress/ui';\nimport {\n\tstore as blockEditorStore,\n\tprivateApis as blockEditorPrivateApis,\n} from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport { NoteThread } from './note-thread';\nimport {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useEffect, useMemo, useRef } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { Stack } from '@wordpress/ui';\nimport {\n\tstore as blockEditorStore,\n\tprivateApis as blockEditorPrivateApis,\n} from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport { NoteThread } from './note-thread';\nimport {\n\tfocusNoteThread,\n\tgetNoteIdsFromMetadata,\n\tpickPrimaryNote,\n} from './utils';\nimport { useFloatingBoard, useNoteActions } from './hooks';\nimport { AddNote } from './add-note';\nimport { store as editorStore } from '../../store';\n\nconst { useBlockElement } = unlock( blockEditorPrivateApis );\n\nexport function Notes( { notes, sidebarRef, isFloating = false, styles } ) {\n\tconst {\n\t\tonCreate: onAddReply,\n\t\tonEdit: onEditNote,\n\t\tonDelete,\n\t} = useNoteActions();\n\tconst { selectNote } = unlock( useDispatch( editorStore ) );\n\tconst { selectBlock, toggleBlockSpotlight } = unlock(\n\t\tuseDispatch( blockEditorStore )\n\t);\n\n\tconst { noteId, selectedBlockClientId, orderedBlockIds } = useSelect(\n\t\t( select ) => {\n\t\t\tconst {\n\t\t\t\tgetBlockAttributes,\n\t\t\t\tgetSelectedBlockClientId,\n\t\t\t\tgetClientIdsWithDescendants,\n\t\t\t} = select( blockEditorStore );\n\t\t\tconst clientId = getSelectedBlockClientId();\n\t\t\treturn {\n\t\t\t\tnoteId: clientId\n\t\t\t\t\t? getBlockAttributes( clientId )?.metadata?.noteId\n\t\t\t\t\t: null,\n\t\t\t\tselectedBlockClientId: clientId,\n\t\t\t\torderedBlockIds: getClientIdsWithDescendants(),\n\t\t\t};\n\t\t},\n\t\t[]\n\t);\n\tconst { selectedNote, noteFocused } = useSelect( ( select ) => {\n\t\tconst { getSelectedNote, isNoteFocused } = unlock(\n\t\t\tselect( editorStore )\n\t\t);\n\t\treturn {\n\t\t\tselectedNote: getSelectedNote(),\n\t\t\tnoteFocused: isNoteFocused(),\n\t\t};\n\t}, [] );\n\n\tconst relatedBlockElement = useBlockElement( selectedBlockClientId );\n\n\tconst threads = useMemo( () => {\n\t\t// In floating mode with a pending new note, splice a placeholder\n\t\t// entry at the selected block's position so the board can float it\n\t\t// alongside regular threads.\n\t\tif ( ! isFloating || selectedNote !== 'new' ) {\n\t\t\treturn notes;\n\t\t}\n\t\tconst newNoteThread = {\n\t\t\tid: 'new',\n\t\t\tblockClientId: selectedBlockClientId,\n\t\t\tcontent: { rendered: '' },\n\t\t};\n\t\tconst out = [];\n\t\torderedBlockIds.forEach( ( blockId ) => {\n\t\t\t// Blocks can carry multiple notes \u2014 surface them all.\n\t\t\tconst threadsForBlock = notes.filter(\n\t\t\t\t( t ) => t.blockClientId === blockId\n\t\t\t);\n\t\t\tout.push( ...threadsForBlock );\n\t\t\tif ( blockId === selectedBlockClientId ) {\n\t\t\t\t// Place the new note placeholder after the block's existing\n\t\t\t\t// threads so the form appears alongside them.\n\t\t\t\tout.push( newNoteThread );\n\t\t\t}\n\t\t} );\n\t\treturn out;\n\t}, [\n\t\tnotes,\n\t\tisFloating,\n\t\tselectedNote,\n\t\tselectedBlockClientId,\n\t\torderedBlockIds,\n\t] );\n\n\tconst handleDelete = async ( note ) => {\n\t\tconst currentIndex = threads.findIndex( ( t ) => t.id === note.id );\n\t\tconst nextThread = threads[ currentIndex + 1 ];\n\t\tconst prevThread = threads[ currentIndex - 1 ];\n\n\t\tawait onDelete( note );\n\n\t\tif ( note.parent !== 0 ) {\n\t\t\t// Move focus to the parent thread when a reply was deleted.\n\t\t\tselectNote( note.parent );\n\t\t\tfocusNoteThread( note.parent, sidebarRef.current );\n\t\t\treturn;\n\t\t}\n\n\t\tconst adjacentThread = nextThread ?? prevThread;\n\t\tif ( adjacentThread ) {\n\t\t\tselectNote( adjacentThread.id );\n\t\t\tfocusNoteThread( adjacentThread.id, sidebarRef.current );\n\t\t\tif ( adjacentThread.blockClientId ) {\n\t\t\t\ttoggleBlockSpotlight( adjacentThread.blockClientId, true );\n\t\t\t\t// Pass `null` as the second parameter to prevent focusing the block.\n\t\t\t\tselectBlock( adjacentThread.blockClientId, null );\n\t\t\t}\n\t\t} else {\n\t\t\tselectNote( undefined );\n\t\t\ttoggleBlockSpotlight( note.blockClientId, false );\n\t\t\t// Move focus to the related block.\n\t\t\trelatedBlockElement?.focus();\n\t\t}\n\t};\n\n\t// Pick the most relevant thread for the selected block. Derived outside\n\t// the effect so the effect body stays minimal.\n\tconst targetNoteId = useMemo( () => {\n\t\tconst blockNoteIds = getNoteIdsFromMetadata( { noteId } );\n\t\tconst blockThreads = notes.filter( ( t ) =>\n\t\t\tblockNoteIds.includes( t.id )\n\t\t);\n\t\treturn pickPrimaryNote( blockThreads )?.id;\n\t}, [ noteId, notes ] );\n\n\t// Sync the selected note to the new block's primary thread when the\n\t// block context changes. The ref tracks the previous block id so the\n\t// effect only fires on block transitions, leaving in-block note changes\n\t// (Escape, Cancel, \"new\" form) alone.\n\tconst prevBlockIdRef = useRef( selectedBlockClientId );\n\tuseEffect( () => {\n\t\tif ( prevBlockIdRef.current === selectedBlockClientId ) {\n\t\t\treturn;\n\t\t}\n\t\tprevBlockIdRef.current = selectedBlockClientId;\n\t\tselectNote( targetNoteId );\n\t}, [ selectedBlockClientId, targetNoteId, selectNote ] );\n\n\t// Focus the selected note when requested.\n\tuseEffect( () => {\n\t\tif ( noteFocused && selectedNote ) {\n\t\t\tfocusNoteThread(\n\t\t\t\tselectedNote,\n\t\t\t\tsidebarRef.current,\n\t\t\t\tselectedNote === 'new' ? 'textarea' : undefined\n\t\t\t);\n\t\t\t// Clear focus flag to avoid re-triggering.\n\t\t\tselectNote( selectedNote );\n\t\t}\n\t}, [ noteFocused, selectedNote, selectNote, sidebarRef ] );\n\n\tconst { notePositions, registerThread, unregisterThread } =\n\t\tuseFloatingBoard( {\n\t\t\tthreads,\n\t\t\tselectedNoteId: selectedNote,\n\t\t\tisFloating,\n\t\t\tsidebarRef,\n\t\t} );\n\n\tconst hasThreads = Array.isArray( threads ) && threads.length > 0;\n\n\tconst navigate = ( event, thread, isSelected ) => {\n\t\tif ( event.defaultPrevented ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentIndex = threads.findIndex( ( t ) => t.id === thread.id );\n\t\tconst isSelfTarget = event.currentTarget === event.target;\n\n\t\tif (\n\t\t\t( event.key === 'Enter' || event.key === 'ArrowRight' ) &&\n\t\t\tisSelfTarget &&\n\t\t\t! isSelected\n\t\t) {\n\t\t\t// Expand thread.\n\t\t\tselectNote( thread.id );\n\t\t\tif ( !! thread.blockClientId ) {\n\t\t\t\t// Pass `null` as the second parameter to prevent focusing the block.\n\t\t\t\tselectBlock( thread.blockClientId, null );\n\t\t\t\ttoggleBlockSpotlight( thread.blockClientId, true );\n\t\t\t}\n\t\t} else if (\n\t\t\t( ( event.key === 'Enter' || event.key === 'ArrowLeft' ) &&\n\t\t\t\tisSelfTarget &&\n\t\t\t\tisSelected ) ||\n\t\t\tevent.key === 'Escape'\n\t\t) {\n\t\t\t// Collapse thread.\n\t\t\tselectNote( undefined );\n\t\t\tif ( thread.blockClientId ) {\n\t\t\t\ttoggleBlockSpotlight( thread.blockClientId, false );\n\t\t\t}\n\t\t\tfocusNoteThread( thread.id, sidebarRef.current );\n\t\t} else if (\n\t\t\tevent.key === 'ArrowDown' &&\n\t\t\tcurrentIndex < threads.length - 1 &&\n\t\t\tisSelfTarget\n\t\t) {\n\t\t\tfocusNoteThread(\n\t\t\t\tthreads[ currentIndex + 1 ].id,\n\t\t\t\tsidebarRef.current\n\t\t\t);\n\t\t} else if (\n\t\t\tevent.key === 'ArrowUp' &&\n\t\t\tcurrentIndex > 0 &&\n\t\t\tisSelfTarget\n\t\t) {\n\t\t\tfocusNoteThread(\n\t\t\t\tthreads[ currentIndex - 1 ].id,\n\t\t\t\tsidebarRef.current\n\t\t\t);\n\t\t} else if ( event.key === 'Home' && isSelfTarget ) {\n\t\t\tfocusNoteThread( threads[ 0 ].id, sidebarRef.current );\n\t\t} else if ( event.key === 'End' && isSelfTarget ) {\n\t\t\tfocusNoteThread(\n\t\t\t\tthreads[ threads.length - 1 ].id,\n\t\t\t\tsidebarRef.current\n\t\t\t);\n\t\t}\n\t};\n\n\treturn (\n\t\t<Stack\n\t\t\tclassName=\"editor-collab-sidebar-panel\"\n\t\t\tstyle={ styles }\n\t\t\trole=\"tree\"\n\t\t\tdirection=\"column\"\n\t\t\tgap=\"md\"\n\t\t\tjustify=\"flex-start\"\n\t\t\tref={ ( node ) => {\n\t\t\t\t// Sometimes previous sidebar unmounts after the new one mounts.\n\t\t\t\t// This ensures we always have the latest reference.\n\t\t\t\tif ( node ) {\n\t\t\t\t\tsidebarRef.current = node;\n\t\t\t\t}\n\t\t\t} }\n\t\t\taria-label={\n\t\t\t\tisFloating ? __( 'Unresolved notes' ) : __( 'All notes' )\n\t\t\t}\n\t\t>\n\t\t\t{ ! hasThreads && ! isFloating ? (\n\t\t\t\t<AddNote onSubmit={ onAddReply } sidebarRef={ sidebarRef } />\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t{ ! isFloating && selectedNote === 'new' && (\n\t\t\t\t\t\t<AddNote\n\t\t\t\t\t\t\tonSubmit={ onAddReply }\n\t\t\t\t\t\t\tsidebarRef={ sidebarRef }\n\t\t\t\t\t\t/>\n\t\t\t\t\t) }\n\t\t\t\t\t{ threads.map( ( thread ) => (\n\t\t\t\t\t\t<NoteThread\n\t\t\t\t\t\t\tkey={ thread.id }\n\t\t\t\t\t\t\tnote={ thread }\n\t\t\t\t\t\t\tonAddReply={ onAddReply }\n\t\t\t\t\t\t\tonDeleteNote={ handleDelete }\n\t\t\t\t\t\t\tonEditNote={ onEditNote }\n\t\t\t\t\t\t\tisSelected={ selectedNote === thread.id }\n\t\t\t\t\t\t\tsidebarRef={ sidebarRef }\n\t\t\t\t\t\t\tfloating={\n\t\t\t\t\t\t\t\tisFloating\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\ty: notePositions[ thread.id ],\n\t\t\t\t\t\t\t\t\t\t\tregisterThread,\n\t\t\t\t\t\t\t\t\t\t\tunregisterThread,\n\t\t\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tonKeyDown={ ( event ) =>\n\t\t\t\t\t\t\t\tnavigate(\n\t\t\t\t\t\t\t\t\tevent,\n\t\t\t\t\t\t\t\t\tthread,\n\t\t\t\t\t\t\t\t\tselectedNote === thread.id\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) ) }\n\t\t\t\t</>\n\t\t\t) }\n\t\t</Stack>\n\t);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["blockEditorPrivateApis", "editorStore", "blockEditorStore"]
|
|
7
7
|
}
|
|
@@ -20,10 +20,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// packages/editor/src/components/collab-sidebar/utils.js
|
|
21
21
|
var utils_exports = {};
|
|
22
22
|
__export(utils_exports, {
|
|
23
|
+
addNoteIdToMetadata: () => addNoteIdToMetadata,
|
|
23
24
|
calculateNotePositions: () => calculateNotePositions,
|
|
24
25
|
focusNoteThread: () => focusNoteThread,
|
|
25
26
|
getAvatarBorderColor: () => getAvatarBorderColor,
|
|
26
27
|
getNoteExcerpt: () => getNoteExcerpt,
|
|
28
|
+
getNoteIdsFromMetadata: () => getNoteIdsFromMetadata,
|
|
29
|
+
pickPrimaryNote: () => pickPrimaryNote,
|
|
30
|
+
removeNoteIdFromMetadata: () => removeNoteIdFromMetadata,
|
|
27
31
|
sanitizeNoteContent: () => sanitizeNoteContent,
|
|
28
32
|
scrollNoteThreadIntoView: () => scrollNoteThreadIntoView
|
|
29
33
|
});
|
|
@@ -38,8 +42,8 @@ var OVERLAP_MARGIN = 20;
|
|
|
38
42
|
var AVATAR_BORDER_COLORS = [
|
|
39
43
|
"#C36EFF",
|
|
40
44
|
// Purple
|
|
41
|
-
"#
|
|
42
|
-
//
|
|
45
|
+
"#D94145",
|
|
46
|
+
// Red
|
|
43
47
|
"#E4780A",
|
|
44
48
|
// Orange
|
|
45
49
|
"#FF35EE",
|
|
@@ -73,6 +77,38 @@ function getNoteExcerpt(text, excerptLength = 10) {
|
|
|
73
77
|
const isTrimmed = trimmedExcerpt !== rawText;
|
|
74
78
|
return isTrimmed ? trimmedExcerpt + "\u2026" : trimmedExcerpt;
|
|
75
79
|
}
|
|
80
|
+
function getNoteIdsFromMetadata(metadata) {
|
|
81
|
+
const noteId = metadata?.noteId;
|
|
82
|
+
const raw = Array.isArray(noteId) ? noteId : [noteId];
|
|
83
|
+
const ids = /* @__PURE__ */ new Set();
|
|
84
|
+
for (const value of raw) {
|
|
85
|
+
const id = Number(value);
|
|
86
|
+
if (Number.isFinite(id) && id > 0) {
|
|
87
|
+
ids.add(id);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return [...ids];
|
|
91
|
+
}
|
|
92
|
+
function addNoteIdToMetadata(metadata, noteId) {
|
|
93
|
+
const ids = new Set(getNoteIdsFromMetadata(metadata));
|
|
94
|
+
const id = Number(noteId);
|
|
95
|
+
if (ids.has(id)) {
|
|
96
|
+
return metadata;
|
|
97
|
+
}
|
|
98
|
+
ids.add(id);
|
|
99
|
+
return { ...metadata, noteId: [...ids] };
|
|
100
|
+
}
|
|
101
|
+
function pickPrimaryNote(threads) {
|
|
102
|
+
return threads.find((thread) => thread.status === "hold") ?? threads[0] ?? null;
|
|
103
|
+
}
|
|
104
|
+
function removeNoteIdFromMetadata(metadata, noteId) {
|
|
105
|
+
const ids = new Set(getNoteIdsFromMetadata(metadata));
|
|
106
|
+
ids.delete(Number(noteId));
|
|
107
|
+
return {
|
|
108
|
+
...metadata,
|
|
109
|
+
noteId: ids.size > 0 ? [...ids] : void 0
|
|
110
|
+
};
|
|
111
|
+
}
|
|
76
112
|
function calculateNotePositions({
|
|
77
113
|
threads,
|
|
78
114
|
selectedNoteId,
|
|
@@ -181,10 +217,14 @@ function scrollNoteThreadIntoView(noteId, container) {
|
|
|
181
217
|
}
|
|
182
218
|
// Annotate the CommonJS export names for ESM import in node:
|
|
183
219
|
0 && (module.exports = {
|
|
220
|
+
addNoteIdToMetadata,
|
|
184
221
|
calculateNotePositions,
|
|
185
222
|
focusNoteThread,
|
|
186
223
|
getAvatarBorderColor,
|
|
187
224
|
getNoteExcerpt,
|
|
225
|
+
getNoteIdsFromMetadata,
|
|
226
|
+
pickPrimaryNote,
|
|
227
|
+
removeNoteIdFromMetadata,
|
|
188
228
|
sanitizeNoteContent,
|
|
189
229
|
scrollNoteThreadIntoView
|
|
190
230
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/collab-sidebar/utils.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { _x } from '@wordpress/i18n';\n\n/**\n * Sanitizes a note string by removing non-printable ASCII characters.\n *\n * @param {string} str - The note string to sanitize.\n * @return {string} - The sanitized note string.\n */\nexport function sanitizeNoteContent( str ) {\n\treturn str.trim();\n}\n\nconst THREAD_ALIGN_OFFSET = -16;\nconst THREAD_GAP = 16;\nconst OVERLAP_MARGIN = 20;\n\n/**\n * Avatar border colors chosen to be visually distinct from each other and from\n * the editor's semantic UI colors (Delta E > 10 between all pairs).\n */\nconst AVATAR_BORDER_COLORS = [\n\t'#C36EFF', // Purple\n\t'#FF51A8', // Pink\n\t'#E4780A', // Orange\n\t'#FF35EE', // Magenta\n\t'#879F11', // Olive\n\t'#46A494', // Teal\n\t'#00A2C3', // Cyan\n];\n\n/**\n * Gets the border color for an avatar based on the user ID.\n *\n * @param {number} userId - The user ID.\n * @return {string} - The border color.\n */\nexport function getAvatarBorderColor( userId ) {\n\treturn AVATAR_BORDER_COLORS[ userId % AVATAR_BORDER_COLORS.length ];\n}\n\n/**\n * Generates a note excerpt from text based on word count type and length.\n *\n * @param {string} text - The note text to generate excerpt from.\n * @param {number} excerptLength - The maximum length for the note excerpt.\n * @return {string} - The generated note excerpt.\n */\nexport function getNoteExcerpt( text, excerptLength = 10 ) {\n\tif ( ! text ) {\n\t\treturn '';\n\t}\n\n\t/*\n\t * translators: If your word count is based on single characters (e.g. East Asian characters),\n\t * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.\n\t * Do not translate into your own language.\n\t */\n\tconst wordCountType = _x( 'words', 'Word count type. Do not translate!' );\n\n\tconst rawText = text.trim();\n\tlet trimmedExcerpt = '';\n\n\tif ( wordCountType === 'words' ) {\n\t\ttrimmedExcerpt = rawText.split( ' ', excerptLength ).join( ' ' );\n\t} else if ( wordCountType === 'characters_excluding_spaces' ) {\n\t\t/*\n\t\t * 1. Split the text at the character limit,\n\t\t * then join the substrings back into one string.\n\t\t * 2. Count the number of spaces in the text\n\t\t * by comparing the lengths of the string with and without spaces.\n\t\t * 3. Add the number to the length of the visible excerpt,\n\t\t * so that the spaces are excluded from the word count.\n\t\t */\n\t\tconst textWithSpaces = rawText.split( '', excerptLength ).join( '' );\n\n\t\tconst numberOfSpaces =\n\t\t\ttextWithSpaces.length - textWithSpaces.replaceAll( ' ', '' ).length;\n\n\t\ttrimmedExcerpt = rawText\n\t\t\t.split( '', excerptLength + numberOfSpaces )\n\t\t\t.join( '' );\n\t} else if ( wordCountType === 'characters_including_spaces' ) {\n\t\ttrimmedExcerpt = rawText.split( '', excerptLength ).join( '' );\n\t}\n\n\tconst isTrimmed = trimmedExcerpt !== rawText;\n\treturn isTrimmed ? trimmedExcerpt + '\u2026' : trimmedExcerpt;\n}\n\n/**\n * Calculate final top positions for all floating note threads in the\n * editor's content coordinate space. Adjusts positions to prevent overlapping\n * by pushing threads above the selected one upward and threads below it downward.\n *\n * @param {Object} params\n * @param {Array} params.threads Ordered list of thread objects.\n * @param {string|number|undefined} params.selectedNoteId ID of the currently selected thread.\n * @param {Object<string,DOMRect>} params.blockRects Pre-read bounding rects keyed by thread ID.\n * @param {Object<string,number>} params.heights Rendered heights keyed by thread ID.\n * @param {number} params.scrollTop Current scroll offset of the editor content.\n * @return {{ positions: Object<string,number> }} Computed top positions.\n */\nexport function calculateNotePositions( {\n\tthreads,\n\tselectedNoteId,\n\tblockRects,\n\theights,\n\tscrollTop = 0,\n} ) {\n\tconst offsets = {};\n\n\tconst anchorIndex = Math.max(\n\t\t0,\n\t\tthreads.findIndex( ( thread ) => thread.id === selectedNoteId )\n\t);\n\n\tconst anchorThread = threads[ anchorIndex ];\n\n\tif ( ! anchorThread || ! blockRects[ anchorThread.id ] ) {\n\t\treturn { positions: {} };\n\t}\n\n\tconst anchorRect = blockRects[ anchorThread.id ];\n\tconst anchorTop = anchorRect.top || 0;\n\tconst anchorHeight = heights[ anchorThread.id ] || 0;\n\n\toffsets[ anchorThread.id ] = THREAD_ALIGN_OFFSET;\n\n\t// Process threads after the anchor, offsetting overlapping threads downward.\n\tlet prevAdjustedTop = anchorTop + THREAD_ALIGN_OFFSET;\n\tlet prevHeight = anchorHeight;\n\n\tfor ( let i = anchorIndex + 1; i < threads.length; i++ ) {\n\t\tconst thread = threads[ i ];\n\t\tconst threadRect = blockRects[ thread.id ];\n\t\tif ( ! threadRect ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst threadTop = threadRect.top || 0;\n\t\tconst threadHeight = heights[ thread.id ] || 0;\n\n\t\tlet offset = THREAD_ALIGN_OFFSET;\n\n\t\tconst prevBottom = prevAdjustedTop + prevHeight;\n\t\tif ( threadTop < prevBottom + THREAD_GAP ) {\n\t\t\toffset = prevBottom - threadTop + OVERLAP_MARGIN;\n\t\t}\n\n\t\toffsets[ thread.id ] = offset;\n\n\t\tprevAdjustedTop = threadTop + offset;\n\t\tprevHeight = threadHeight;\n\t}\n\n\t// Process threads before the anchor, offsetting overlapping threads upward.\n\tlet belowAdjustedTop = anchorTop + THREAD_ALIGN_OFFSET;\n\n\tfor ( let i = anchorIndex - 1; i >= 0; i-- ) {\n\t\tconst thread = threads[ i ];\n\t\tconst threadRect = blockRects[ thread.id ];\n\t\tif ( ! threadRect ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst threadTop = threadRect.top || 0;\n\t\tconst threadHeight = heights[ thread.id ] || 0;\n\n\t\tlet offset = THREAD_ALIGN_OFFSET;\n\n\t\tconst threadBottom = threadTop + threadHeight;\n\n\t\tif ( threadBottom > belowAdjustedTop ) {\n\t\t\toffset =\n\t\t\t\tbelowAdjustedTop - threadTop - threadHeight - OVERLAP_MARGIN;\n\t\t}\n\n\t\toffsets[ thread.id ] = offset;\n\n\t\tbelowAdjustedTop = threadTop + offset;\n\t}\n\n\t// blockRect.top + scrollTop is the block's absolute y within the editor's\n\t// scroll content; CSS translates each thread by -scrollTop at render time.\n\tconst positions = {};\n\tfor ( const thread of threads ) {\n\t\tconst blockRect = blockRects[ thread.id ];\n\t\tif ( blockRect && offsets[ thread.id ] !== undefined ) {\n\t\t\tpositions[ thread.id ] =\n\t\t\t\tblockRect.top + scrollTop + offsets[ thread.id ];\n\t\t}\n\t}\n\n\treturn { positions };\n}\n\n/**\n * Resolve the DOM element for a note thread once it's mounted,\n * or `null` if not found within 3 seconds.\n *\n * @param {string} noteId Note thread ID.\n * @param {?HTMLElement} container Container to search within.\n * @param {string} additionalSelector Optional descendant selector.\n * @return {Promise<HTMLElement|null>} Resolved element, or `null` on timeout.\n */\nfunction findNoteThread( noteId, container, additionalSelector ) {\n\tif ( ! container ) {\n\t\treturn Promise.resolve( null );\n\t}\n\n\t// A thread without a noteId is a new note thread.\n\tconst threadSelector =\n\t\tnoteId && noteId !== 'new'\n\t\t\t? `[role=treeitem][id=\"note-thread-${ noteId }\"]`\n\t\t\t: '[role=treeitem]:not([id])';\n\tconst selector = additionalSelector\n\t\t? `${ threadSelector } ${ additionalSelector }`\n\t\t: threadSelector;\n\n\treturn new Promise( ( resolve ) => {\n\t\tif ( container.querySelector( selector ) ) {\n\t\t\treturn resolve( container.querySelector( selector ) );\n\t\t}\n\n\t\tlet timer = null;\n\t\t// Wait for the element to be added to the DOM.\n\t\tconst observer = new window.MutationObserver( () => {\n\t\t\tif ( container.querySelector( selector ) ) {\n\t\t\t\tclearTimeout( timer );\n\t\t\t\tobserver.disconnect();\n\t\t\t\tresolve( container.querySelector( selector ) );\n\t\t\t}\n\t\t} );\n\n\t\tobserver.observe( container, { childList: true, subtree: true } );\n\n\t\t// Stop trying after 3 seconds.\n\t\ttimer = setTimeout( () => {\n\t\t\tobserver.disconnect();\n\t\t\tresolve( null );\n\t\t}, 3000 );\n\t} );\n}\n\n/**\n * Focus a note thread (or a descendant) and scroll it into view.\n *\n * @param {string} noteId Note thread ID.\n * @param {?HTMLElement} container Container to search within.\n * @param {string} additionalSelector Optional descendant selector.\n */\nexport function focusNoteThread( noteId, container, additionalSelector ) {\n\treturn findNoteThread( noteId, container, additionalSelector ).then(\n\t\t( element ) => {\n\t\t\tif ( ! element ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\telement.focus();\n\t\t\telement.scrollIntoView( { block: 'nearest' } );\n\t\t}\n\t);\n}\n\n/**\n * Scroll a note thread into view without changing focus.\n *\n * @param {string} noteId Note thread ID.\n * @param {?HTMLElement} container Container to search within.\n */\nexport function scrollNoteThreadIntoView( noteId, container ) {\n\treturn findNoteThread( noteId, container ).then( ( element ) => {\n\t\telement?.scrollIntoView( { block: 'nearest' } );\n\t} );\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { _x } from '@wordpress/i18n';\n\n/**\n * Sanitizes a note string by removing non-printable ASCII characters.\n *\n * @param {string} str - The note string to sanitize.\n * @return {string} - The sanitized note string.\n */\nexport function sanitizeNoteContent( str ) {\n\treturn str.trim();\n}\n\nconst THREAD_ALIGN_OFFSET = -16;\nconst THREAD_GAP = 16;\nconst OVERLAP_MARGIN = 20;\n\n/**\n * Avatar border colors chosen to be visually distinct from each other and from\n * the editor's semantic UI colors (Delta E > 10 between all pairs).\n */\nconst AVATAR_BORDER_COLORS = [\n\t'#C36EFF', // Purple\n\t'#D94145', // Red\n\t'#E4780A', // Orange\n\t'#FF35EE', // Magenta\n\t'#879F11', // Olive\n\t'#46A494', // Teal\n\t'#00A2C3', // Cyan\n];\n\n/**\n * Gets the border color for an avatar based on the user ID.\n *\n * @param {number} userId - The user ID.\n * @return {string} - The border color.\n */\nexport function getAvatarBorderColor( userId ) {\n\treturn AVATAR_BORDER_COLORS[ userId % AVATAR_BORDER_COLORS.length ];\n}\n\n/**\n * Generates a note excerpt from text based on word count type and length.\n *\n * @param {string} text - The note text to generate excerpt from.\n * @param {number} excerptLength - The maximum length for the note excerpt.\n * @return {string} - The generated note excerpt.\n */\nexport function getNoteExcerpt( text, excerptLength = 10 ) {\n\tif ( ! text ) {\n\t\treturn '';\n\t}\n\n\t/*\n\t * translators: If your word count is based on single characters (e.g. East Asian characters),\n\t * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.\n\t * Do not translate into your own language.\n\t */\n\tconst wordCountType = _x( 'words', 'Word count type. Do not translate!' );\n\n\tconst rawText = text.trim();\n\tlet trimmedExcerpt = '';\n\n\tif ( wordCountType === 'words' ) {\n\t\ttrimmedExcerpt = rawText.split( ' ', excerptLength ).join( ' ' );\n\t} else if ( wordCountType === 'characters_excluding_spaces' ) {\n\t\t/*\n\t\t * 1. Split the text at the character limit,\n\t\t * then join the substrings back into one string.\n\t\t * 2. Count the number of spaces in the text\n\t\t * by comparing the lengths of the string with and without spaces.\n\t\t * 3. Add the number to the length of the visible excerpt,\n\t\t * so that the spaces are excluded from the word count.\n\t\t */\n\t\tconst textWithSpaces = rawText.split( '', excerptLength ).join( '' );\n\n\t\tconst numberOfSpaces =\n\t\t\ttextWithSpaces.length - textWithSpaces.replaceAll( ' ', '' ).length;\n\n\t\ttrimmedExcerpt = rawText\n\t\t\t.split( '', excerptLength + numberOfSpaces )\n\t\t\t.join( '' );\n\t} else if ( wordCountType === 'characters_including_spaces' ) {\n\t\ttrimmedExcerpt = rawText.split( '', excerptLength ).join( '' );\n\t}\n\n\tconst isTrimmed = trimmedExcerpt !== rawText;\n\treturn isTrimmed ? trimmedExcerpt + '\u2026' : trimmedExcerpt;\n}\n\n/**\n * Normalizes noteId metadata to always return an array of unique numeric ids,\n * preserving insertion order. Handles both scalar (legacy, possibly\n * string-typed) and array (new) values.\n *\n * @param {Object} metadata Block metadata object\n * @return {number[]} Array of note IDs (may be empty)\n */\nexport function getNoteIdsFromMetadata( metadata ) {\n\tconst noteId = metadata?.noteId;\n\tconst raw = Array.isArray( noteId ) ? noteId : [ noteId ];\n\tconst ids = new Set();\n\tfor ( const value of raw ) {\n\t\tconst id = Number( value );\n\t\tif ( Number.isFinite( id ) && id > 0 ) {\n\t\t\tids.add( id );\n\t\t}\n\t}\n\treturn [ ...ids ];\n}\n\n/**\n * Adds a note ID to the metadata.\n * Converts scalar to array if needed, otherwise appends.\n *\n * @param {Object} metadata Existing block metadata\n * @param {number} noteId Note ID to add\n * @return {Object} Updated metadata object\n */\nexport function addNoteIdToMetadata( metadata, noteId ) {\n\tconst ids = new Set( getNoteIdsFromMetadata( metadata ) );\n\tconst id = Number( noteId );\n\tif ( ids.has( id ) ) {\n\t\treturn metadata;\n\t}\n\tids.add( id );\n\treturn { ...metadata, noteId: [ ...ids ] };\n}\n\n/**\n * Picks the most relevant thread from a list: first unresolved, else first.\n *\n * @param {Array} threads Ordered list of thread objects.\n * @return {Object|null} Selected thread or null when the list is empty.\n */\nexport function pickPrimaryNote( threads ) {\n\treturn (\n\t\tthreads.find( ( thread ) => thread.status === 'hold' ) ??\n\t\tthreads[ 0 ] ??\n\t\tnull\n\t);\n}\n\n/**\n * Removes a note ID from the metadata.\n *\n * @param {Object} metadata Existing block metadata\n * @param {number} noteId Note ID to remove\n * @return {Object} Updated metadata object\n */\nexport function removeNoteIdFromMetadata( metadata, noteId ) {\n\tconst ids = new Set( getNoteIdsFromMetadata( metadata ) );\n\tids.delete( Number( noteId ) );\n\treturn {\n\t\t...metadata,\n\t\tnoteId: ids.size > 0 ? [ ...ids ] : undefined,\n\t};\n}\n\n/**\n * Calculate final top positions for all floating note threads in the\n * editor's content coordinate space. Adjusts positions to prevent overlapping\n * by pushing threads above the selected one upward and threads below it downward.\n *\n * @param {Object} params\n * @param {Array} params.threads Ordered list of thread objects.\n * @param {string|number|undefined} params.selectedNoteId ID of the currently selected thread.\n * @param {Object<string,DOMRect>} params.blockRects Pre-read bounding rects keyed by thread ID.\n * @param {Object<string,number>} params.heights Rendered heights keyed by thread ID.\n * @param {number} params.scrollTop Current scroll offset of the editor content.\n * @return {{ positions: Object<string,number> }} Computed top positions.\n */\nexport function calculateNotePositions( {\n\tthreads,\n\tselectedNoteId,\n\tblockRects,\n\theights,\n\tscrollTop = 0,\n} ) {\n\tconst offsets = {};\n\n\tconst anchorIndex = Math.max(\n\t\t0,\n\t\tthreads.findIndex( ( thread ) => thread.id === selectedNoteId )\n\t);\n\n\tconst anchorThread = threads[ anchorIndex ];\n\n\tif ( ! anchorThread || ! blockRects[ anchorThread.id ] ) {\n\t\treturn { positions: {} };\n\t}\n\n\tconst anchorRect = blockRects[ anchorThread.id ];\n\tconst anchorTop = anchorRect.top || 0;\n\tconst anchorHeight = heights[ anchorThread.id ] || 0;\n\n\toffsets[ anchorThread.id ] = THREAD_ALIGN_OFFSET;\n\n\t// Process threads after the anchor, offsetting overlapping threads downward.\n\tlet prevAdjustedTop = anchorTop + THREAD_ALIGN_OFFSET;\n\tlet prevHeight = anchorHeight;\n\n\tfor ( let i = anchorIndex + 1; i < threads.length; i++ ) {\n\t\tconst thread = threads[ i ];\n\t\tconst threadRect = blockRects[ thread.id ];\n\t\tif ( ! threadRect ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst threadTop = threadRect.top || 0;\n\t\tconst threadHeight = heights[ thread.id ] || 0;\n\n\t\tlet offset = THREAD_ALIGN_OFFSET;\n\n\t\tconst prevBottom = prevAdjustedTop + prevHeight;\n\t\tif ( threadTop < prevBottom + THREAD_GAP ) {\n\t\t\toffset = prevBottom - threadTop + OVERLAP_MARGIN;\n\t\t}\n\n\t\toffsets[ thread.id ] = offset;\n\n\t\tprevAdjustedTop = threadTop + offset;\n\t\tprevHeight = threadHeight;\n\t}\n\n\t// Process threads before the anchor, offsetting overlapping threads upward.\n\tlet belowAdjustedTop = anchorTop + THREAD_ALIGN_OFFSET;\n\n\tfor ( let i = anchorIndex - 1; i >= 0; i-- ) {\n\t\tconst thread = threads[ i ];\n\t\tconst threadRect = blockRects[ thread.id ];\n\t\tif ( ! threadRect ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst threadTop = threadRect.top || 0;\n\t\tconst threadHeight = heights[ thread.id ] || 0;\n\n\t\tlet offset = THREAD_ALIGN_OFFSET;\n\n\t\tconst threadBottom = threadTop + threadHeight;\n\n\t\tif ( threadBottom > belowAdjustedTop ) {\n\t\t\toffset =\n\t\t\t\tbelowAdjustedTop - threadTop - threadHeight - OVERLAP_MARGIN;\n\t\t}\n\n\t\toffsets[ thread.id ] = offset;\n\n\t\tbelowAdjustedTop = threadTop + offset;\n\t}\n\n\t// blockRect.top + scrollTop is the block's absolute y within the editor's\n\t// scroll content; CSS translates each thread by -scrollTop at render time.\n\tconst positions = {};\n\tfor ( const thread of threads ) {\n\t\tconst blockRect = blockRects[ thread.id ];\n\t\tif ( blockRect && offsets[ thread.id ] !== undefined ) {\n\t\t\tpositions[ thread.id ] =\n\t\t\t\tblockRect.top + scrollTop + offsets[ thread.id ];\n\t\t}\n\t}\n\n\treturn { positions };\n}\n\n/**\n * Resolve the DOM element for a note thread once it's mounted,\n * or `null` if not found within 3 seconds.\n *\n * @param {string} noteId Note thread ID.\n * @param {?HTMLElement} container Container to search within.\n * @param {string} additionalSelector Optional descendant selector.\n * @return {Promise<HTMLElement|null>} Resolved element, or `null` on timeout.\n */\nfunction findNoteThread( noteId, container, additionalSelector ) {\n\tif ( ! container ) {\n\t\treturn Promise.resolve( null );\n\t}\n\n\t// A thread without a noteId is a new note thread.\n\tconst threadSelector =\n\t\tnoteId && noteId !== 'new'\n\t\t\t? `[role=treeitem][id=\"note-thread-${ noteId }\"]`\n\t\t\t: '[role=treeitem]:not([id])';\n\tconst selector = additionalSelector\n\t\t? `${ threadSelector } ${ additionalSelector }`\n\t\t: threadSelector;\n\n\treturn new Promise( ( resolve ) => {\n\t\tif ( container.querySelector( selector ) ) {\n\t\t\treturn resolve( container.querySelector( selector ) );\n\t\t}\n\n\t\tlet timer = null;\n\t\t// Wait for the element to be added to the DOM.\n\t\tconst observer = new window.MutationObserver( () => {\n\t\t\tif ( container.querySelector( selector ) ) {\n\t\t\t\tclearTimeout( timer );\n\t\t\t\tobserver.disconnect();\n\t\t\t\tresolve( container.querySelector( selector ) );\n\t\t\t}\n\t\t} );\n\n\t\tobserver.observe( container, { childList: true, subtree: true } );\n\n\t\t// Stop trying after 3 seconds.\n\t\ttimer = setTimeout( () => {\n\t\t\tobserver.disconnect();\n\t\t\tresolve( null );\n\t\t}, 3000 );\n\t} );\n}\n\n/**\n * Focus a note thread (or a descendant) and scroll it into view.\n *\n * @param {string} noteId Note thread ID.\n * @param {?HTMLElement} container Container to search within.\n * @param {string} additionalSelector Optional descendant selector.\n */\nexport function focusNoteThread( noteId, container, additionalSelector ) {\n\treturn findNoteThread( noteId, container, additionalSelector ).then(\n\t\t( element ) => {\n\t\t\tif ( ! element ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\telement.focus();\n\t\t\telement.scrollIntoView( { block: 'nearest' } );\n\t\t}\n\t);\n}\n\n/**\n * Scroll a note thread into view without changing focus.\n *\n * @param {string} noteId Note thread ID.\n * @param {?HTMLElement} container Container to search within.\n */\nexport function scrollNoteThreadIntoView( noteId, container ) {\n\treturn findNoteThread( noteId, container ).then( ( element ) => {\n\t\telement?.scrollIntoView( { block: 'nearest' } );\n\t} );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -24,12 +24,31 @@ __export(compute_selection_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(compute_selection_exports);
|
|
26
26
|
var import_core_data = require("@wordpress/core-data");
|
|
27
|
+
var import_lock_unlock = require("../../lock-unlock.cjs");
|
|
27
28
|
var import_cursor_dom_utils = require("./cursor-dom-utils.cjs");
|
|
29
|
+
var { SelectionDirection, SelectionType } = (0, import_lock_unlock.unlock)(
|
|
30
|
+
import_core_data.privateApis
|
|
31
|
+
);
|
|
32
|
+
function resolveTargetElement(editorDocument, resolvedSelection) {
|
|
33
|
+
if (!resolvedSelection.localClientId) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const blockElement = editorDocument.querySelector(
|
|
37
|
+
`[data-block="${resolvedSelection.localClientId}"]`
|
|
38
|
+
);
|
|
39
|
+
if (!blockElement || !resolvedSelection.attributeKey) {
|
|
40
|
+
return blockElement;
|
|
41
|
+
}
|
|
42
|
+
const attrKey = CSS.escape(resolvedSelection.attributeKey);
|
|
43
|
+
return blockElement.querySelector(
|
|
44
|
+
`[data-wp-block-attribute-key="${attrKey}"]`
|
|
45
|
+
) ?? blockElement;
|
|
46
|
+
}
|
|
28
47
|
function computeSelectionVisual(selection, start, end, overlayContext) {
|
|
29
|
-
if (selection.type ===
|
|
48
|
+
if (selection.type === SelectionType.None || selection.type === SelectionType.WholeBlock) {
|
|
30
49
|
return {};
|
|
31
50
|
}
|
|
32
|
-
if (selection.type ===
|
|
51
|
+
if (selection.type === SelectionType.Cursor) {
|
|
33
52
|
return computeCursorOnly(start, overlayContext);
|
|
34
53
|
}
|
|
35
54
|
if (!end) {
|
|
@@ -41,13 +60,14 @@ function computeCursorOnly(start, overlayContext) {
|
|
|
41
60
|
if (!start.localClientId) {
|
|
42
61
|
return {};
|
|
43
62
|
}
|
|
44
|
-
const
|
|
45
|
-
|
|
63
|
+
const targetElement = resolveTargetElement(
|
|
64
|
+
overlayContext.editorDocument,
|
|
65
|
+
start
|
|
46
66
|
);
|
|
47
67
|
return {
|
|
48
68
|
coords: (0, import_cursor_dom_utils.getCursorPosition)(
|
|
49
69
|
start.richTextOffset,
|
|
50
|
-
|
|
70
|
+
targetElement,
|
|
51
71
|
overlayContext.editorDocument,
|
|
52
72
|
overlayContext.overlayRect
|
|
53
73
|
)
|
|
@@ -57,11 +77,11 @@ function computeTextSelection(selection, start, end, overlayContext) {
|
|
|
57
77
|
if (!start.localClientId || !end.localClientId || start.richTextOffset === null || end.richTextOffset === null) {
|
|
58
78
|
return {};
|
|
59
79
|
}
|
|
60
|
-
const isReverse = selection.selectionDirection ===
|
|
80
|
+
const isReverse = selection.selectionDirection === SelectionDirection.Backward;
|
|
61
81
|
const activeEnd = isReverse ? start : end;
|
|
62
82
|
let allRects;
|
|
63
83
|
let activeEndBlock = null;
|
|
64
|
-
if (selection.type ===
|
|
84
|
+
if (selection.type === SelectionType.SelectionInOneBlock) {
|
|
65
85
|
const result = computeSingleBlockRects(start, end, overlayContext);
|
|
66
86
|
allRects = result.rects;
|
|
67
87
|
activeEndBlock = result.blockElement;
|
|
@@ -81,8 +101,9 @@ function computeTextSelection(selection, start, end, overlayContext) {
|
|
|
81
101
|
selectionRects: allRects
|
|
82
102
|
};
|
|
83
103
|
}
|
|
84
|
-
const startBlock =
|
|
85
|
-
|
|
104
|
+
const startBlock = resolveTargetElement(
|
|
105
|
+
overlayContext.editorDocument,
|
|
106
|
+
start
|
|
86
107
|
);
|
|
87
108
|
return {
|
|
88
109
|
coords: (0, import_cursor_dom_utils.getCursorPosition)(
|
|
@@ -94,8 +115,9 @@ function computeTextSelection(selection, start, end, overlayContext) {
|
|
|
94
115
|
};
|
|
95
116
|
}
|
|
96
117
|
function computeSingleBlockRects(start, end, overlayContext) {
|
|
97
|
-
const blockElement =
|
|
98
|
-
|
|
118
|
+
const blockElement = resolveTargetElement(
|
|
119
|
+
overlayContext.editorDocument,
|
|
120
|
+
start
|
|
99
121
|
);
|
|
100
122
|
if (!blockElement || start.richTextOffset === null || end.richTextOffset === null) {
|
|
101
123
|
return { rects: [], blockElement: null };
|
|
@@ -114,11 +136,13 @@ function computeSingleBlockRects(start, end, overlayContext) {
|
|
|
114
136
|
function computeMultiBlockRects(start, end, overlayContext) {
|
|
115
137
|
let docFirst = start;
|
|
116
138
|
let docLast = end;
|
|
117
|
-
let firstBlock =
|
|
118
|
-
|
|
139
|
+
let firstBlock = resolveTargetElement(
|
|
140
|
+
overlayContext.editorDocument,
|
|
141
|
+
docFirst
|
|
119
142
|
);
|
|
120
|
-
let lastBlock =
|
|
121
|
-
|
|
143
|
+
let lastBlock = resolveTargetElement(
|
|
144
|
+
overlayContext.editorDocument,
|
|
145
|
+
docLast
|
|
122
146
|
);
|
|
123
147
|
if (firstBlock && lastBlock && (0, import_cursor_dom_utils.isNodeBefore)(lastBlock, firstBlock)) {
|
|
124
148
|
docFirst = end;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/collaborators-overlay/compute-selection.ts"],
|
|
4
|
-
"sourcesContent": ["import { SelectionDirection, SelectionType } from '@wordpress/core-data';\nimport type { ResolvedSelection } from '@wordpress/core-data';\n\nimport {\n\tgetCursorPosition,\n\tgetSelectionRects,\n\tgetFullBlockSelectionRects,\n\tgetBlocksBetween,\n\tisNodeBefore,\n} from './cursor-dom-utils';\nimport type { CursorCoords, SelectionRect } from './cursor-dom-utils';\n\n/** Common parameters passed to cursor/selection computation helpers. */\ninterface OverlayContext {\n\teditorDocument: Document;\n\toverlayRect: DOMRect;\n}\n\n/** Selection rects and the resolved block element for a single-block selection. */\ninterface SingleBlockResult {\n\trects: SelectionRect[];\n\tblockElement: HTMLElement | null;\n}\n\n/** Selection rects and the resolved block elements for a multi-block selection. */\ninterface MultiBlockResult {\n\trects: SelectionRect[];\n\tfirstBlock: HTMLElement | null;\n\tlastBlock: HTMLElement | null;\n\tfirstBlockClientId: string | null;\n}\n\n/** Result of computing visual cursor/selection state for a single user. */\nexport interface SelectionVisual {\n\tcoords?: CursorCoords | null;\n\tselectionRects?: SelectionRect[];\n}\n\n/**\n * Compute cursor coords and optional selection rects for a single user's selection.\n *\n * @param selection - The selection state from the awareness layer.\n * @param start - Start position (block clientId + text index).\n * @param end - End position (only for range selections).\n * @param overlayContext - Shared editor document / overlay references.\n * @return Cursor coordinates and optional selection rectangles.\n */\nexport function computeSelectionVisual(\n\tselection: any,\n\tstart: ResolvedSelection,\n\tend: ResolvedSelection | undefined,\n\toverlayContext: OverlayContext\n): SelectionVisual {\n\tif (\n\t\tselection.type === SelectionType.None ||\n\t\tselection.type === SelectionType.WholeBlock\n\t) {\n\t\treturn {};\n\t}\n\n\tif ( selection.type === SelectionType.Cursor ) {\n\t\treturn computeCursorOnly( start, overlayContext );\n\t}\n\n\t// SelectionInOneBlock or SelectionInMultipleBlocks.\n\tif ( ! end ) {\n\t\treturn {};\n\t}\n\treturn computeTextSelection( selection, start, end, overlayContext );\n}\n\n/**\n * Compute cursor coordinates for a simple cursor (no highlighted text).\n *\n * @param start - Cursor position (block clientId + text index).\n * @param overlayContext - Shared editor document / overlay references.\n * @return Cursor coordinates.\n */\nfunction computeCursorOnly(\n\tstart: ResolvedSelection,\n\toverlayContext: OverlayContext\n): SelectionVisual {\n\tif ( ! start.localClientId ) {\n\t\treturn {};\n\t}\n\tconst blockElement =\n\t\toverlayContext.editorDocument.querySelector< HTMLElement >(\n\t\t\t`[data-block=\"${ start.localClientId }\"]`\n\t\t);\n\treturn {\n\t\tcoords: getCursorPosition(\n\t\t\tstart.richTextOffset,\n\t\t\tblockElement,\n\t\t\toverlayContext.editorDocument,\n\t\t\toverlayContext.overlayRect\n\t\t),\n\t};\n}\n\n/**\n * Compute cursor coordinates and selection highlight rects for a text selection\n * (single-block or multi-block).\n *\n * @param selection - The selection state.\n * @param start - Start position (block clientId + text index).\n * @param end - End position (block clientId + text index).\n * @param overlayContext - Shared editor document / overlay references.\n * @return Cursor coordinates and optional selection rectangles.\n */\nfunction computeTextSelection(\n\tselection: any,\n\tstart: ResolvedSelection,\n\tend: ResolvedSelection,\n\toverlayContext: OverlayContext\n): SelectionVisual {\n\tif (\n\t\t! start.localClientId ||\n\t\t! end.localClientId ||\n\t\tstart.richTextOffset === null ||\n\t\tend.richTextOffset === null\n\t) {\n\t\treturn {};\n\t}\n\n\tconst isReverse =\n\t\tselection.selectionDirection === SelectionDirection.Backward;\n\tconst activeEnd = isReverse ? start : end;\n\n\tlet allRects: SelectionRect[];\n\tlet activeEndBlock: HTMLElement | null = null;\n\n\tif ( selection.type === SelectionType.SelectionInOneBlock ) {\n\t\tconst result = computeSingleBlockRects( start, end, overlayContext );\n\t\tallRects = result.rects;\n\t\t// Single block: start and end share the same block element.\n\t\tactiveEndBlock = result.blockElement;\n\t} else {\n\t\tconst result = computeMultiBlockRects( start, end, overlayContext );\n\t\tallRects = result.rects;\n\t\t// Pick the block element that matches the active end.\n\t\tactiveEndBlock =\n\t\t\tactiveEnd.localClientId === result.firstBlockClientId\n\t\t\t\t? result.firstBlock\n\t\t\t\t: result.lastBlock;\n\t}\n\n\tif ( allRects.length > 0 ) {\n\t\treturn {\n\t\t\tcoords: getCursorPosition(\n\t\t\t\tactiveEnd.richTextOffset,\n\t\t\t\tactiveEndBlock,\n\t\t\t\toverlayContext.editorDocument,\n\t\t\t\toverlayContext.overlayRect\n\t\t\t),\n\t\t\tselectionRects: allRects,\n\t\t};\n\t}\n\n\t// Fallback: cursor at start position only.\n\tconst startBlock =\n\t\toverlayContext.editorDocument.querySelector< HTMLElement >(\n\t\t\t`[data-block=\"${ start.localClientId }\"]`\n\t\t);\n\n\treturn {\n\t\tcoords: getCursorPosition(\n\t\t\tstart.richTextOffset,\n\t\t\tstartBlock,\n\t\t\toverlayContext.editorDocument,\n\t\t\toverlayContext.overlayRect\n\t\t),\n\t};\n}\n\n/**\n * Compute selection rects for a selection within a single block.\n *\n * @param start - Start position (block clientId + text index).\n * @param end - End position (block clientId + text index).\n * @param overlayContext - Shared editor document / overlay references.\n * @return Array of selection rectangles.\n */\nfunction computeSingleBlockRects(\n\tstart: ResolvedSelection,\n\tend: ResolvedSelection,\n\toverlayContext: OverlayContext\n): SingleBlockResult {\n\tconst blockElement =\n\t\toverlayContext.editorDocument.querySelector< HTMLElement >(\n\t\t\t`[data-block=\"${ start.localClientId }\"]`\n\t\t);\n\tif (\n\t\t! blockElement ||\n\t\tstart.richTextOffset === null ||\n\t\tend.richTextOffset === null\n\t) {\n\t\treturn { rects: [], blockElement: null };\n\t}\n\treturn {\n\t\trects:\n\t\t\tgetSelectionRects(\n\t\t\t\tblockElement,\n\t\t\t\tstart.richTextOffset,\n\t\t\t\tend.richTextOffset,\n\t\t\t\toverlayContext.editorDocument,\n\t\t\t\toverlayContext.overlayRect\n\t\t\t) ?? [],\n\t\tblockElement,\n\t};\n}\n\n/**\n * Compute selection rects for a selection spanning multiple blocks.\n *\n * Normalizes to document order \u2014 for backward selections the block editor\n * reports start after end.\n *\n * @param start - Start position (block clientId + text index).\n * @param end - End position (block clientId + text index).\n * @param overlayContext - Shared editor document / overlay references.\n * @return Array of selection rectangles.\n */\nfunction computeMultiBlockRects(\n\tstart: ResolvedSelection,\n\tend: ResolvedSelection,\n\toverlayContext: OverlayContext\n): MultiBlockResult {\n\tlet docFirst = start;\n\tlet docLast = end;\n\tlet firstBlock = overlayContext.editorDocument.querySelector< HTMLElement >(\n\t\t`[data-block=\"${ docFirst.localClientId }\"]`\n\t);\n\tlet lastBlock = overlayContext.editorDocument.querySelector< HTMLElement >(\n\t\t`[data-block=\"${ docLast.localClientId }\"]`\n\t);\n\n\t// Swap to document order if needed.\n\tif ( firstBlock && lastBlock && isNodeBefore( lastBlock, firstBlock ) ) {\n\t\tdocFirst = end;\n\t\tdocLast = start;\n\t\t[ firstBlock, lastBlock ] = [ lastBlock, firstBlock ];\n\t}\n\n\tif (\n\t\t! firstBlock ||\n\t\t! lastBlock ||\n\t\tdocFirst.richTextOffset === null ||\n\t\tdocLast.richTextOffset === null ||\n\t\t! docFirst.localClientId ||\n\t\t! docLast.localClientId\n\t) {\n\t\treturn {\n\t\t\trects: [],\n\t\t\tfirstBlock: null,\n\t\t\tlastBlock: null,\n\t\t\tfirstBlockClientId: null,\n\t\t};\n\t}\n\n\tconst allRects: SelectionRect[] = [];\n\n\t// First block: from start offset to end of block.\n\tconst startRects = getSelectionRects(\n\t\tfirstBlock,\n\t\tdocFirst.richTextOffset,\n\t\tNumber.MAX_SAFE_INTEGER,\n\t\toverlayContext.editorDocument,\n\t\toverlayContext.overlayRect\n\t);\n\tif ( startRects ) {\n\t\tallRects.push( ...startRects );\n\t}\n\n\t// Intermediate blocks: full content.\n\tconst intermediateBlocks = getBlocksBetween(\n\t\tdocFirst.localClientId,\n\t\tdocLast.localClientId,\n\t\toverlayContext.editorDocument\n\t);\n\tfor ( const intermediateBlock of intermediateBlocks ) {\n\t\tconst rects = getFullBlockSelectionRects(\n\t\t\tintermediateBlock,\n\t\t\toverlayContext.editorDocument,\n\t\t\toverlayContext.overlayRect\n\t\t);\n\t\tallRects.push( ...rects );\n\t}\n\n\t// Last block: from 0 to end offset.\n\tconst endRects = getSelectionRects(\n\t\tlastBlock,\n\t\t0,\n\t\tdocLast.richTextOffset,\n\t\toverlayContext.editorDocument,\n\t\toverlayContext.overlayRect\n\t);\n\tif ( endRects ) {\n\t\tallRects.push( ...endRects );\n\t}\n\n\treturn {\n\t\trects: allRects,\n\t\tfirstBlock,\n\t\tlastBlock,\n\t\tfirstBlockClientId: docFirst.localClientId,\n\t};\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["import { privateApis as coreDataPrivateApis } from '@wordpress/core-data';\nimport type {\n\tCoreDataPrivateApis,\n\tResolvedSelection,\n} from '@wordpress/core-data';\n\nimport { unlock } from '../../lock-unlock';\nimport {\n\tgetCursorPosition,\n\tgetSelectionRects,\n\tgetFullBlockSelectionRects,\n\tgetBlocksBetween,\n\tisNodeBefore,\n} from './cursor-dom-utils';\nimport type { CursorCoords, SelectionRect } from './cursor-dom-utils';\n\nconst { SelectionDirection, SelectionType } = unlock(\n\tcoreDataPrivateApis\n) as Pick< CoreDataPrivateApis, 'SelectionDirection' | 'SelectionType' >;\n\n/** Common parameters passed to cursor/selection computation helpers. */\ninterface OverlayContext {\n\teditorDocument: Document;\n\toverlayRect: DOMRect;\n}\n\n/** Selection rects and the resolved block element for a single-block selection. */\ninterface SingleBlockResult {\n\trects: SelectionRect[];\n\tblockElement: HTMLElement | null;\n}\n\n/** Selection rects and the resolved block elements for a multi-block selection. */\ninterface MultiBlockResult {\n\trects: SelectionRect[];\n\tfirstBlock: HTMLElement | null;\n\tlastBlock: HTMLElement | null;\n\tfirstBlockClientId: string | null;\n}\n\n/** Result of computing visual cursor/selection state for a single user. */\nexport interface SelectionVisual {\n\tcoords?: CursorCoords | null;\n\tselectionRects?: SelectionRect[];\n}\n\n/**\n * Resolve the most specific editor element the selection refers to.\n *\n * When the sender carries an `attributeKey`, narrow to the RichText element\n * matching `data-wp-block-attribute-key` inside the block. This is what makes\n * cursor placement work for blocks with multiple RichText fields (e.g.\n * `core/table` cells: `body.0.cells.0.content`, etc.). Falls back to the\n * block element when `attributeKey` is missing (WholeBlock selections,\n * older senders, or DOM lookup miss).\n *\n * @param editorDocument - The editor document.\n * @param resolvedSelection - The resolved selection.\n * @return The target element (RichText editable or block), or null.\n */\nfunction resolveTargetElement(\n\teditorDocument: Document,\n\tresolvedSelection: ResolvedSelection\n): HTMLElement | null {\n\tif ( ! resolvedSelection.localClientId ) {\n\t\treturn null;\n\t}\n\n\tconst blockElement = editorDocument.querySelector< HTMLElement >(\n\t\t`[data-block=\"${ resolvedSelection.localClientId }\"]`\n\t);\n\n\tif ( ! blockElement || ! resolvedSelection.attributeKey ) {\n\t\treturn blockElement;\n\t}\n\n\tconst attrKey = CSS.escape( resolvedSelection.attributeKey );\n\treturn (\n\t\tblockElement.querySelector< HTMLElement >(\n\t\t\t`[data-wp-block-attribute-key=\"${ attrKey }\"]`\n\t\t) ?? blockElement\n\t);\n}\n\n/**\n * Compute cursor coords and optional selection rects for a single user's selection.\n *\n * @param selection - The selection state from the awareness layer.\n * @param start - Start position (block clientId + text index).\n * @param end - End position (only for range selections).\n * @param overlayContext - Shared editor document / overlay references.\n * @return Cursor coordinates and optional selection rectangles.\n */\nexport function computeSelectionVisual(\n\tselection: any,\n\tstart: ResolvedSelection,\n\tend: ResolvedSelection | undefined,\n\toverlayContext: OverlayContext\n): SelectionVisual {\n\tif (\n\t\tselection.type === SelectionType.None ||\n\t\tselection.type === SelectionType.WholeBlock\n\t) {\n\t\treturn {};\n\t}\n\n\tif ( selection.type === SelectionType.Cursor ) {\n\t\treturn computeCursorOnly( start, overlayContext );\n\t}\n\n\t// SelectionInOneBlock or SelectionInMultipleBlocks.\n\tif ( ! end ) {\n\t\treturn {};\n\t}\n\treturn computeTextSelection( selection, start, end, overlayContext );\n}\n\n/**\n * Compute cursor coordinates for a simple cursor (no highlighted text).\n *\n * @param start - Cursor position (block clientId + text index).\n * @param overlayContext - Shared editor document / overlay references.\n * @return Cursor coordinates.\n */\nfunction computeCursorOnly(\n\tstart: ResolvedSelection,\n\toverlayContext: OverlayContext\n): SelectionVisual {\n\tif ( ! start.localClientId ) {\n\t\treturn {};\n\t}\n\tconst targetElement = resolveTargetElement(\n\t\toverlayContext.editorDocument,\n\t\tstart\n\t);\n\treturn {\n\t\tcoords: getCursorPosition(\n\t\t\tstart.richTextOffset,\n\t\t\ttargetElement,\n\t\t\toverlayContext.editorDocument,\n\t\t\toverlayContext.overlayRect\n\t\t),\n\t};\n}\n\n/**\n * Compute cursor coordinates and selection highlight rects for a text selection\n * (single-block or multi-block).\n *\n * @param selection - The selection state.\n * @param start - Start position (block clientId + text index).\n * @param end - End position (block clientId + text index).\n * @param overlayContext - Shared editor document / overlay references.\n * @return Cursor coordinates and optional selection rectangles.\n */\nfunction computeTextSelection(\n\tselection: any,\n\tstart: ResolvedSelection,\n\tend: ResolvedSelection,\n\toverlayContext: OverlayContext\n): SelectionVisual {\n\tif (\n\t\t! start.localClientId ||\n\t\t! end.localClientId ||\n\t\tstart.richTextOffset === null ||\n\t\tend.richTextOffset === null\n\t) {\n\t\treturn {};\n\t}\n\n\tconst isReverse =\n\t\tselection.selectionDirection === SelectionDirection.Backward;\n\tconst activeEnd = isReverse ? start : end;\n\n\tlet allRects: SelectionRect[];\n\tlet activeEndBlock: HTMLElement | null = null;\n\n\tif ( selection.type === SelectionType.SelectionInOneBlock ) {\n\t\tconst result = computeSingleBlockRects( start, end, overlayContext );\n\t\tallRects = result.rects;\n\t\t// Single block: start and end share the same block element.\n\t\tactiveEndBlock = result.blockElement;\n\t} else {\n\t\tconst result = computeMultiBlockRects( start, end, overlayContext );\n\t\tallRects = result.rects;\n\t\t// Pick the block element that matches the active end.\n\t\tactiveEndBlock =\n\t\t\tactiveEnd.localClientId === result.firstBlockClientId\n\t\t\t\t? result.firstBlock\n\t\t\t\t: result.lastBlock;\n\t}\n\n\tif ( allRects.length > 0 ) {\n\t\treturn {\n\t\t\tcoords: getCursorPosition(\n\t\t\t\tactiveEnd.richTextOffset,\n\t\t\t\tactiveEndBlock,\n\t\t\t\toverlayContext.editorDocument,\n\t\t\t\toverlayContext.overlayRect\n\t\t\t),\n\t\t\tselectionRects: allRects,\n\t\t};\n\t}\n\n\t// Fallback: cursor at start position only.\n\tconst startBlock = resolveTargetElement(\n\t\toverlayContext.editorDocument,\n\t\tstart\n\t);\n\n\treturn {\n\t\tcoords: getCursorPosition(\n\t\t\tstart.richTextOffset,\n\t\t\tstartBlock,\n\t\t\toverlayContext.editorDocument,\n\t\t\toverlayContext.overlayRect\n\t\t),\n\t};\n}\n\n/**\n * Compute selection rects for a selection within a single block.\n *\n * @param start - Start position (block clientId + text index).\n * @param end - End position (block clientId + text index).\n * @param overlayContext - Shared editor document / overlay references.\n * @return Array of selection rectangles.\n */\nfunction computeSingleBlockRects(\n\tstart: ResolvedSelection,\n\tend: ResolvedSelection,\n\toverlayContext: OverlayContext\n): SingleBlockResult {\n\tconst blockElement = resolveTargetElement(\n\t\toverlayContext.editorDocument,\n\t\tstart\n\t);\n\tif (\n\t\t! blockElement ||\n\t\tstart.richTextOffset === null ||\n\t\tend.richTextOffset === null\n\t) {\n\t\treturn { rects: [], blockElement: null };\n\t}\n\treturn {\n\t\trects:\n\t\t\tgetSelectionRects(\n\t\t\t\tblockElement,\n\t\t\t\tstart.richTextOffset,\n\t\t\t\tend.richTextOffset,\n\t\t\t\toverlayContext.editorDocument,\n\t\t\t\toverlayContext.overlayRect\n\t\t\t) ?? [],\n\t\tblockElement,\n\t};\n}\n\n/**\n * Compute selection rects for a selection spanning multiple blocks.\n *\n * Normalizes to document order \u2014 for backward selections the block editor\n * reports start after end.\n *\n * @param start - Start position (block clientId + text index).\n * @param end - End position (block clientId + text index).\n * @param overlayContext - Shared editor document / overlay references.\n * @return Array of selection rectangles.\n */\nfunction computeMultiBlockRects(\n\tstart: ResolvedSelection,\n\tend: ResolvedSelection,\n\toverlayContext: OverlayContext\n): MultiBlockResult {\n\tlet docFirst = start;\n\tlet docLast = end;\n\tlet firstBlock = resolveTargetElement(\n\t\toverlayContext.editorDocument,\n\t\tdocFirst\n\t);\n\tlet lastBlock = resolveTargetElement(\n\t\toverlayContext.editorDocument,\n\t\tdocLast\n\t);\n\n\t// Swap to document order if needed.\n\tif ( firstBlock && lastBlock && isNodeBefore( lastBlock, firstBlock ) ) {\n\t\tdocFirst = end;\n\t\tdocLast = start;\n\t\t[ firstBlock, lastBlock ] = [ lastBlock, firstBlock ];\n\t}\n\n\tif (\n\t\t! firstBlock ||\n\t\t! lastBlock ||\n\t\tdocFirst.richTextOffset === null ||\n\t\tdocLast.richTextOffset === null ||\n\t\t! docFirst.localClientId ||\n\t\t! docLast.localClientId\n\t) {\n\t\treturn {\n\t\t\trects: [],\n\t\t\tfirstBlock: null,\n\t\t\tlastBlock: null,\n\t\t\tfirstBlockClientId: null,\n\t\t};\n\t}\n\n\tconst allRects: SelectionRect[] = [];\n\n\t// First block: from start offset to end of block.\n\tconst startRects = getSelectionRects(\n\t\tfirstBlock,\n\t\tdocFirst.richTextOffset,\n\t\tNumber.MAX_SAFE_INTEGER,\n\t\toverlayContext.editorDocument,\n\t\toverlayContext.overlayRect\n\t);\n\tif ( startRects ) {\n\t\tallRects.push( ...startRects );\n\t}\n\n\t// Intermediate blocks: full content.\n\tconst intermediateBlocks = getBlocksBetween(\n\t\tdocFirst.localClientId,\n\t\tdocLast.localClientId,\n\t\toverlayContext.editorDocument\n\t);\n\tfor ( const intermediateBlock of intermediateBlocks ) {\n\t\tconst rects = getFullBlockSelectionRects(\n\t\t\tintermediateBlock,\n\t\t\toverlayContext.editorDocument,\n\t\t\toverlayContext.overlayRect\n\t\t);\n\t\tallRects.push( ...rects );\n\t}\n\n\t// Last block: from 0 to end offset.\n\tconst endRects = getSelectionRects(\n\t\tlastBlock,\n\t\t0,\n\t\tdocLast.richTextOffset,\n\t\toverlayContext.editorDocument,\n\t\toverlayContext.overlayRect\n\t);\n\tif ( endRects ) {\n\t\tallRects.push( ...endRects );\n\t}\n\n\treturn {\n\t\trects: allRects,\n\t\tfirstBlock,\n\t\tlastBlock,\n\t\tfirstBlockClientId: docFirst.localClientId,\n\t};\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["coreDataPrivateApis"]
|
|
7
7
|
}
|
|
@@ -23,13 +23,16 @@ __export(use_block_highlighting_exports, {
|
|
|
23
23
|
useBlockHighlighting: () => useBlockHighlighting
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(use_block_highlighting_exports);
|
|
26
|
+
var import_block_editor = require("@wordpress/block-editor");
|
|
26
27
|
var import_core_data = require("@wordpress/core-data");
|
|
28
|
+
var import_data = require("@wordpress/data");
|
|
27
29
|
var import_element = require("@wordpress/element");
|
|
28
30
|
var import_lock_unlock = require("../../lock-unlock.cjs");
|
|
29
31
|
var import_utils = require("../collab-sidebar/utils.cjs");
|
|
30
32
|
var import_get_avatar_url = require("./get-avatar-url.cjs");
|
|
31
33
|
var import_use_debounced_recompute = require("./use-debounced-recompute.cjs");
|
|
32
34
|
var { useActiveCollaborators, useResolvedSelection } = (0, import_lock_unlock.unlock)(import_core_data.privateApis);
|
|
35
|
+
var { SelectionType } = (0, import_lock_unlock.unlock)(import_core_data.privateApis);
|
|
33
36
|
function useBlockHighlighting(overlayElement, blockEditorDocument, postId, postType, delayMs) {
|
|
34
37
|
const highlightedBlockIds = (0, import_element.useRef)(/* @__PURE__ */ new Set());
|
|
35
38
|
const userStates = useActiveCollaborators(
|
|
@@ -44,6 +47,10 @@ function useBlockHighlighting(overlayElement, blockEditorDocument, postId, postT
|
|
|
44
47
|
[]
|
|
45
48
|
);
|
|
46
49
|
const [recomputeToken, rerenderHighlightsAfterDelay] = (0, import_use_debounced_recompute.useDebouncedRecompute)(delayMs);
|
|
50
|
+
const blockClientIds = (0, import_data.useSelect)(
|
|
51
|
+
(select) => select(import_block_editor.store).getClientIdsWithDescendants(),
|
|
52
|
+
[]
|
|
53
|
+
);
|
|
47
54
|
(0, import_element.useEffect)(() => {
|
|
48
55
|
if (!blockEditorDocument) {
|
|
49
56
|
setHighlights([]);
|
|
@@ -52,7 +59,7 @@ function useBlockHighlighting(overlayElement, blockEditorDocument, postId, postT
|
|
|
52
59
|
const currentHighlightedIds = highlightedBlockIds.current;
|
|
53
60
|
const seen = /* @__PURE__ */ new Set();
|
|
54
61
|
const blocksToHighlight = userStates.filter((userState) => {
|
|
55
|
-
const isWholeBlockSelected = userState.editorState?.selection?.type ===
|
|
62
|
+
const isWholeBlockSelected = userState.editorState?.selection?.type === SelectionType.WholeBlock;
|
|
56
63
|
return !userState.isMe && isWholeBlockSelected;
|
|
57
64
|
}).map((userState) => {
|
|
58
65
|
let localClientId;
|
|
@@ -147,7 +154,8 @@ function useBlockHighlighting(overlayElement, blockEditorDocument, postId, postT
|
|
|
147
154
|
blockEditorDocument,
|
|
148
155
|
overlayElement,
|
|
149
156
|
recomputeToken,
|
|
150
|
-
resolveSelection
|
|
157
|
+
resolveSelection,
|
|
158
|
+
blockClientIds
|
|
151
159
|
]);
|
|
152
160
|
return { highlights, rerenderHighlightsAfterDelay };
|
|
153
161
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/collaborators-overlay/use-block-highlighting.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport {\n\tprivateApis as coreDataPrivateApis,\n\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
6
|
-
"names": ["coreDataPrivateApis"]
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\n// @ts-expect-error No exported types\nimport { store as blockEditorStore } from '@wordpress/block-editor';\nimport {\n\tprivateApis as coreDataPrivateApis,\n\ttype CoreDataPrivateApis,\n\ttype PostEditorAwarenessState as ActiveCollaborator,\n} from '@wordpress/core-data';\nimport { useSelect } from '@wordpress/data';\nimport { useEffect, useRef, useState } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport { getAvatarBorderColor } from '../collab-sidebar/utils';\nimport { getAvatarUrl } from './get-avatar-url';\nimport { useDebouncedRecompute } from './use-debounced-recompute';\n\nconst { useActiveCollaborators, useResolvedSelection } =\n\tunlock( coreDataPrivateApis );\nconst { SelectionType } = unlock( coreDataPrivateApis ) as Pick<\n\tCoreDataPrivateApis,\n\t'SelectionType'\n>;\n\nexport interface BlockHighlightData {\n\tblockId: string;\n\tuserName: string;\n\tavatarUrl?: string;\n\tcolor: string;\n\tx: number;\n\ty: number;\n}\n\n/**\n * Custom hook for highlighting selected blocks in the editor and computing\n * their positions for rendering avatar labels in the overlay.\n *\n * @param overlayElement - The overlay element used as position reference.\n * @param blockEditorDocument - Ref to the block editor document.\n * @param postId - The ID of the post.\n * @param postType - The type of the post.\n * @param delayMs - Milliseconds to wait before recomputing highlight positions.\n * @return Highlight data for rendering and a delayed recompute function.\n */\nexport function useBlockHighlighting(\n\toverlayElement: HTMLElement | null,\n\tblockEditorDocument: Document | null,\n\tpostId: number | null,\n\tpostType: string | null,\n\tdelayMs: number\n): {\n\thighlights: BlockHighlightData[];\n\trerenderHighlightsAfterDelay: () => () => void;\n} {\n\tconst highlightedBlockIds = useRef< Set< string > >( new Set() );\n\tconst userStates: ActiveCollaborator[] = useActiveCollaborators(\n\t\tpostId ?? null,\n\t\tpostType ?? null\n\t);\n\tconst resolveSelection = useResolvedSelection(\n\t\tpostId ?? null,\n\t\tpostType ?? null\n\t);\n\n\tconst [ highlights, setHighlights ] = useState< BlockHighlightData[] >(\n\t\t[]\n\t);\n\n\t// Bump this counter to force the effect to re-run (e.g. after a layout shift).\n\tconst [ recomputeToken, rerenderHighlightsAfterDelay ] =\n\t\tuseDebouncedRecompute( delayMs );\n\n\tconst blockClientIds = useSelect(\n\t\t( select ) => select( blockEditorStore ).getClientIdsWithDescendants(),\n\t\t[]\n\t);\n\n\t// All DOM mutations and position computations live inside useEffect.\n\tuseEffect( () => {\n\t\tif ( ! blockEditorDocument ) {\n\t\t\tsetHighlights( [] );\n\t\t\treturn;\n\t\t}\n\n\t\t// Capture the ref value so the cleanup closure sees the same Set\n\t\t// even if a later render replaces it.\n\t\tconst currentHighlightedIds = highlightedBlockIds.current;\n\n\t\t// Deduplicate by blockId \u2014 when multiple collaborators select the\n\t\t// same block, only the first one gets the highlight and avatar label.\n\t\tconst seen = new Set< string >();\n\t\tconst blocksToHighlight = userStates\n\t\t\t.filter( ( userState: ActiveCollaborator ) => {\n\t\t\t\tconst isWholeBlockSelected =\n\t\t\t\t\tuserState.editorState?.selection?.type ===\n\t\t\t\t\tSelectionType.WholeBlock;\n\n\t\t\t\treturn ! userState.isMe && isWholeBlockSelected;\n\t\t\t} )\n\t\t\t.map( ( userState ) => {\n\t\t\t\tlet localClientId;\n\t\t\t\ttry {\n\t\t\t\t\t( { localClientId } = resolveSelection(\n\t\t\t\t\t\tuserState.editorState?.selection\n\t\t\t\t\t) );\n\t\t\t\t} catch {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tif ( ! localClientId ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tblockId: localClientId,\n\t\t\t\t\tcolor: userState.isMe\n\t\t\t\t\t\t? 'var(--wp-admin-theme-color)'\n\t\t\t\t\t\t: getAvatarBorderColor( userState.collaboratorInfo.id ),\n\t\t\t\t\tuserName: userState.collaboratorInfo.name,\n\t\t\t\t\tavatarUrl: getAvatarUrl(\n\t\t\t\t\t\tuserState.collaboratorInfo.avatar_urls\n\t\t\t\t\t),\n\t\t\t\t};\n\t\t\t} )\n\t\t\t.filter( ( block ): block is NonNullable< typeof block > => {\n\t\t\t\tif ( ! block ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif ( seen.has( block.blockId ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tseen.add( block.blockId );\n\t\t\t\treturn true;\n\t\t\t} );\n\n\t\t// Unhighlight blocks that are no longer selected.\n\t\tconst selectedBlockIds = new Set(\n\t\t\tblocksToHighlight.map( ( block ) => block.blockId )\n\t\t);\n\n\t\tfor ( const blockId of currentHighlightedIds ) {\n\t\t\tif ( ! selectedBlockIds.has( blockId ) ) {\n\t\t\t\tconst blockElement = getBlockElementById(\n\t\t\t\t\tblockEditorDocument,\n\t\t\t\t\tblockId\n\t\t\t\t);\n\n\t\t\t\tif ( blockElement ) {\n\t\t\t\t\tblockElement.classList.remove( 'is-collaborator-selected' );\n\t\t\t\t\tblockElement.style.removeProperty(\n\t\t\t\t\t\t'--collaborator-outline-color'\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tcurrentHighlightedIds.delete( blockId );\n\t\t\t}\n\t\t}\n\n\t\t// Highlight blocks and compute positions for avatar labels.\n\t\tconst results: BlockHighlightData[] = [];\n\t\tconst overlayRect = overlayElement?.getBoundingClientRect() ?? null;\n\n\t\tblocksToHighlight.forEach( ( block ) => {\n\t\t\tconst { color, blockId, userName, avatarUrl } = block;\n\t\t\tconst blockElement = getBlockElementById(\n\t\t\t\tblockEditorDocument,\n\t\t\t\tblockId\n\t\t\t);\n\n\t\t\tif ( ! blockElement ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tblockElement.classList.add( 'is-collaborator-selected' );\n\t\t\tblockElement.style.setProperty(\n\t\t\t\t'--collaborator-outline-color',\n\t\t\t\tcolor\n\t\t\t);\n\t\t\tcurrentHighlightedIds.add( blockId );\n\n\t\t\tif ( overlayRect ) {\n\t\t\t\tconst blockRect = blockElement.getBoundingClientRect();\n\n\t\t\t\tresults.push( {\n\t\t\t\t\tblockId,\n\t\t\t\t\tuserName,\n\t\t\t\t\tavatarUrl,\n\t\t\t\t\tcolor,\n\t\t\t\t\tx: blockRect.left - overlayRect.left,\n\t\t\t\t\ty: blockRect.top - overlayRect.top,\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\tsetHighlights( results );\n\n\t\t// Clean up all highlights on unmount.\n\t\treturn () => {\n\t\t\tfor ( const blockId of currentHighlightedIds ) {\n\t\t\t\tconst el = getBlockElementById( blockEditorDocument, blockId );\n\t\t\t\tif ( el ) {\n\t\t\t\t\tel.classList.remove( 'is-collaborator-selected' );\n\t\t\t\t\tel.style.removeProperty( '--collaborator-outline-color' );\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurrentHighlightedIds.clear();\n\t\t};\n\t}, [\n\t\tuserStates,\n\t\tblockEditorDocument,\n\t\toverlayElement,\n\t\trecomputeToken,\n\t\tresolveSelection,\n\t\tblockClientIds,\n\t] );\n\n\treturn { highlights, rerenderHighlightsAfterDelay };\n}\n\nconst getBlockElementById = (\n\tblockEditorDocument: Document,\n\tblockId: string\n): HTMLElement | null => {\n\treturn blockEditorDocument.querySelector( `[data-block=\"${ blockId }\"]` );\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["coreDataPrivateApis", "blockEditorStore"]
|
|
7
7
|
}
|
|
@@ -23,6 +23,7 @@ __export(use_render_cursors_exports, {
|
|
|
23
23
|
useRenderCursors: () => useRenderCursors
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(use_render_cursors_exports);
|
|
26
|
+
var import_block_editor = require("@wordpress/block-editor");
|
|
26
27
|
var import_core_data = require("@wordpress/core-data");
|
|
27
28
|
var import_data = require("@wordpress/data");
|
|
28
29
|
var import_element = require("@wordpress/element");
|
|
@@ -33,6 +34,7 @@ var import_utils = require("../collab-sidebar/utils.cjs");
|
|
|
33
34
|
var import_compute_selection = require("./compute-selection.cjs");
|
|
34
35
|
var import_use_debounced_recompute = require("./use-debounced-recompute.cjs");
|
|
35
36
|
var { useActiveCollaborators, useResolvedSelection } = (0, import_lock_unlock.unlock)(import_core_data.privateApis);
|
|
37
|
+
var { SelectionType } = (0, import_lock_unlock.unlock)(import_core_data.privateApis);
|
|
36
38
|
function useRenderCursors(overlayElement, blockEditorDocument, postId, postType, delayMs) {
|
|
37
39
|
const sortedUsers = useActiveCollaborators(
|
|
38
40
|
postId ?? null,
|
|
@@ -46,6 +48,10 @@ function useRenderCursors(overlayElement, blockEditorDocument, postId, postType,
|
|
|
46
48
|
(select) => select(import_preferences.store).get("core", "showCollaborationCursor"),
|
|
47
49
|
[]
|
|
48
50
|
);
|
|
51
|
+
const blockClientIds = (0, import_data.useSelect)(
|
|
52
|
+
(select) => select(import_block_editor.store).getClientIdsWithDescendants(),
|
|
53
|
+
[]
|
|
54
|
+
);
|
|
49
55
|
const [cursorPositions, setCursorPositions] = (0, import_element.useState)(
|
|
50
56
|
[]
|
|
51
57
|
);
|
|
@@ -69,27 +75,28 @@ function useRenderCursors(overlayElement, blockEditorDocument, postId, postType,
|
|
|
69
75
|
return;
|
|
70
76
|
}
|
|
71
77
|
const selection = user.editorState?.selection ?? {
|
|
72
|
-
type:
|
|
78
|
+
type: SelectionType.None
|
|
73
79
|
};
|
|
74
80
|
let start = {
|
|
75
81
|
richTextOffset: null,
|
|
76
|
-
localClientId: null
|
|
82
|
+
localClientId: null,
|
|
83
|
+
attributeKey: null
|
|
77
84
|
};
|
|
78
85
|
let end;
|
|
79
|
-
if (selection.type ===
|
|
86
|
+
if (selection.type === SelectionType.Cursor) {
|
|
80
87
|
try {
|
|
81
88
|
start = resolveSelection(selection);
|
|
82
89
|
} catch {
|
|
83
90
|
return;
|
|
84
91
|
}
|
|
85
|
-
} else if (selection.type ===
|
|
92
|
+
} else if (selection.type === SelectionType.SelectionInOneBlock || selection.type === SelectionType.SelectionInMultipleBlocks) {
|
|
86
93
|
try {
|
|
87
94
|
start = resolveSelection({
|
|
88
|
-
type:
|
|
95
|
+
type: SelectionType.Cursor,
|
|
89
96
|
cursorPosition: selection.cursorStartPosition
|
|
90
97
|
});
|
|
91
98
|
end = resolveSelection({
|
|
92
|
-
type:
|
|
99
|
+
type: SelectionType.Cursor,
|
|
93
100
|
cursorPosition: selection.cursorEndPosition
|
|
94
101
|
});
|
|
95
102
|
} catch {
|
|
@@ -128,7 +135,8 @@ function useRenderCursors(overlayElement, blockEditorDocument, postId, postType,
|
|
|
128
135
|
overlayElement,
|
|
129
136
|
sortedUsers,
|
|
130
137
|
showOwnCursor,
|
|
131
|
-
recomputeToken
|
|
138
|
+
recomputeToken,
|
|
139
|
+
blockClientIds
|
|
132
140
|
]);
|
|
133
141
|
return { cursors: cursorPositions, rerenderCursorsAfterDelay };
|
|
134
142
|
}
|