@wordpress/editor 14.48.1 → 14.48.2-next.v.202606191442.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/build/bindings/pattern-overrides.cjs +1 -1
- package/build/bindings/pattern-overrides.cjs.map +2 -2
- package/build/components/collab-sidebar/note-byline.cjs +1 -1
- package/build/components/collab-sidebar/note-byline.cjs.map +2 -2
- package/build/components/collab-sidebar/note.cjs +49 -17
- package/build/components/collab-sidebar/note.cjs.map +3 -3
- package/build/components/collab-sidebar/notes.cjs.map +1 -1
- package/build/components/collab-sidebar/utils.cjs +1 -1
- package/build/components/collab-sidebar/utils.cjs.map +2 -2
- package/build/components/collaborators-overlay/avatar-iframe-styles.cjs.map +1 -1
- package/build/components/collaborators-overlay/collaborator-styles.cjs.map +1 -1
- package/build/components/collaborators-overlay/compute-selection.cjs.map +1 -1
- package/build/components/collaborators-overlay/overlay-iframe-styles.cjs +1 -1
- package/build/components/collaborators-overlay/overlay-iframe-styles.cjs.map +1 -1
- package/build/components/collaborators-overlay/use-block-highlighting.cjs.map +1 -1
- package/build/components/collaborators-presence/avatar/component.cjs.map +2 -2
- package/build/components/collaborators-presence/avatar/use-image-loading-status.cjs.map +1 -1
- package/build/components/document-bar/index.cjs +7 -5
- package/build/components/document-bar/index.cjs.map +2 -2
- package/build/components/global-keyboard-shortcuts/index.cjs +3 -2
- package/build/components/global-keyboard-shortcuts/index.cjs.map +2 -2
- package/build/components/global-styles-sidebar/welcome-guide.cjs +3 -3
- package/build/components/global-styles-sidebar/welcome-guide.cjs.map +1 -1
- package/build/components/local-autosave-monitor/index.cjs +14 -15
- package/build/components/local-autosave-monitor/index.cjs.map +2 -2
- package/build/components/page-attributes/parent.cjs +1 -1
- package/build/components/page-attributes/parent.cjs.map +2 -2
- package/build/components/post-card-panel/index.cjs +1 -1
- package/build/components/post-card-panel/index.cjs.map +2 -2
- package/build/components/post-excerpt/panel.cjs +1 -1
- package/build/components/post-excerpt/panel.cjs.map +2 -2
- package/build/components/post-locked-modal/index.cjs +3 -3
- package/build/components/post-locked-modal/index.cjs.map +1 -1
- package/build/components/post-preview-button/index.cjs +2 -2
- package/build/components/post-preview-button/index.cjs.map +2 -2
- package/build/components/post-publish-button/index.cjs +4 -3
- package/build/components/post-publish-button/index.cjs.map +2 -2
- package/build/components/post-publish-button/label.cjs +2 -2
- package/build/components/post-publish-button/label.cjs.map +2 -2
- package/build/components/post-publish-panel/index.cjs.map +1 -1
- package/build/components/post-publish-panel/postpublish.cjs +1 -1
- package/build/components/post-publish-panel/postpublish.cjs.map +2 -2
- package/build/components/post-revisions-preview/block-diff.cjs.map +1 -1
- package/build/components/post-revisions-preview/diff-markers.cjs.map +2 -2
- package/build/components/post-revisions-preview/revisions-slider.cjs +1 -1
- package/build/components/post-revisions-preview/revisions-slider.cjs.map +2 -2
- package/build/components/post-revisions-timeline/index.cjs +173 -0
- package/build/components/post-revisions-timeline/index.cjs.map +7 -0
- package/build/components/post-saved-state/index.cjs +17 -26
- package/build/components/post-saved-state/index.cjs.map +2 -2
- package/build/components/post-schedule/label.cjs +5 -5
- package/build/components/post-schedule/label.cjs.map +1 -1
- package/build/components/post-taxonomies/flat-term-selector.cjs +2 -1
- package/build/components/post-taxonomies/flat-term-selector.cjs.map +3 -3
- package/build/components/post-taxonomies/hierarchical-term-selector.cjs +1 -1
- package/build/components/post-taxonomies/hierarchical-term-selector.cjs.map +2 -2
- package/build/components/post-text-editor/index.cjs +51 -0
- package/build/components/post-text-editor/index.cjs.map +2 -2
- package/build/components/post-text-editor/utils.cjs +150 -0
- package/build/components/post-text-editor/utils.cjs.map +7 -0
- package/build/components/post-url/index.cjs +1 -1
- package/build/components/post-url/index.cjs.map +2 -2
- package/build/components/post-view-link/index.cjs +1 -1
- package/build/components/post-view-link/index.cjs.map +2 -2
- package/build/components/provider/disable-non-page-content-blocks.cjs.map +1 -1
- package/build/components/provider/index.cjs +1 -1
- package/build/components/provider/index.cjs.map +2 -2
- package/build/components/resizable-editor/resize-handle.cjs.map +2 -2
- package/build/components/revision-diff-panel/index.cjs +7 -2
- package/build/components/revision-diff-panel/index.cjs.map +2 -2
- package/build/components/revision-fields-diff/index.cjs +6 -2
- package/build/components/revision-fields-diff/index.cjs.map +2 -2
- package/build/components/sidebar/dataform-post-summary.cjs +125 -20
- package/build/components/sidebar/dataform-post-summary.cjs.map +3 -3
- package/build/components/sidebar/index.cjs +1 -11
- package/build/components/sidebar/index.cjs.map +3 -3
- package/build/components/sidebar/post-revision-summary.cjs +11 -17
- package/build/components/sidebar/post-revision-summary.cjs.map +3 -3
- package/build/components/sidebar/post-summary.cjs +1 -1
- package/build/components/sidebar/post-summary.cjs.map +2 -2
- package/build/components/style-book/examples.cjs +1 -1
- package/build/components/style-book/examples.cjs.map +1 -1
- package/build/components/style-book/index.cjs +1 -1
- package/build/components/style-book/index.cjs.map +2 -2
- package/build/components/sync-connection-error-modal/index.cjs +3 -3
- package/build/components/sync-connection-error-modal/index.cjs.map +1 -1
- package/build/components/template-actions-panel/block-theme-content.cjs.map +2 -2
- package/build/components/template-actions-panel/index.cjs +0 -9
- package/build/components/template-actions-panel/index.cjs.map +3 -3
- package/build/components/template-validation-notice/index.cjs +1 -1
- package/build/components/template-validation-notice/index.cjs.map +1 -1
- package/build/components/upload-progress-snackbar/index.cjs +3 -3
- package/build/components/upload-progress-snackbar/index.cjs.map +2 -2
- package/build/components/upload-progress-snackbar/tracker.cjs.map +1 -1
- package/build/components/visual-editor/edit-template-blocks-notification.cjs +1 -1
- package/build/components/visual-editor/edit-template-blocks-notification.cjs.map +1 -1
- package/build/{components/revision-author-panel → dataviews/fields/revisions}/index.cjs +18 -26
- package/build/dataviews/fields/revisions/index.cjs.map +7 -0
- package/build/dataviews/fields/revisions/revisions-view.cjs +74 -0
- package/build/dataviews/fields/revisions/revisions-view.cjs.map +7 -0
- package/build/dataviews/store/private-actions.cjs +14 -4
- package/build/dataviews/store/private-actions.cjs.map +3 -3
- package/build/hooks/push-changes-to-global-styles/index.cjs +1 -1
- package/build/hooks/push-changes-to-global-styles/index.cjs.map +1 -1
- package/build/store/actions.cjs +1 -1
- package/build/store/actions.cjs.map +2 -2
- package/build/store/private-selectors.cjs +6 -1
- package/build/store/private-selectors.cjs.map +2 -2
- package/build/utils/media-upload/index.cjs.map +1 -1
- package/build/utils/set-nested-value.cjs.map +1 -1
- package/build-module/bindings/pattern-overrides.mjs +1 -1
- package/build-module/bindings/pattern-overrides.mjs.map +2 -2
- package/build-module/components/collab-sidebar/note-byline.mjs +1 -1
- package/build-module/components/collab-sidebar/note-byline.mjs.map +2 -2
- package/build-module/components/collab-sidebar/note.mjs +50 -18
- package/build-module/components/collab-sidebar/note.mjs.map +2 -2
- package/build-module/components/collab-sidebar/notes.mjs.map +1 -1
- package/build-module/components/collab-sidebar/utils.mjs +1 -1
- package/build-module/components/collab-sidebar/utils.mjs.map +2 -2
- package/build-module/components/collaborators-overlay/avatar-iframe-styles.mjs.map +1 -1
- package/build-module/components/collaborators-overlay/collaborator-styles.mjs.map +1 -1
- package/build-module/components/collaborators-overlay/compute-selection.mjs.map +1 -1
- package/build-module/components/collaborators-overlay/overlay-iframe-styles.mjs +1 -1
- package/build-module/components/collaborators-overlay/overlay-iframe-styles.mjs.map +1 -1
- package/build-module/components/collaborators-overlay/use-block-highlighting.mjs.map +1 -1
- package/build-module/components/collaborators-presence/avatar/component.mjs.map +2 -2
- package/build-module/components/collaborators-presence/avatar/use-image-loading-status.mjs.map +1 -1
- package/build-module/components/document-bar/index.mjs +7 -5
- package/build-module/components/document-bar/index.mjs.map +2 -2
- package/build-module/components/global-keyboard-shortcuts/index.mjs +3 -2
- package/build-module/components/global-keyboard-shortcuts/index.mjs.map +2 -2
- package/build-module/components/global-styles-sidebar/welcome-guide.mjs +3 -3
- package/build-module/components/global-styles-sidebar/welcome-guide.mjs.map +1 -1
- package/build-module/components/local-autosave-monitor/index.mjs +15 -16
- package/build-module/components/local-autosave-monitor/index.mjs.map +2 -2
- package/build-module/components/page-attributes/parent.mjs +1 -1
- package/build-module/components/page-attributes/parent.mjs.map +2 -2
- package/build-module/components/post-card-panel/index.mjs +1 -1
- package/build-module/components/post-card-panel/index.mjs.map +2 -2
- package/build-module/components/post-excerpt/panel.mjs +1 -1
- package/build-module/components/post-excerpt/panel.mjs.map +2 -2
- package/build-module/components/post-locked-modal/index.mjs +3 -3
- package/build-module/components/post-locked-modal/index.mjs.map +1 -1
- package/build-module/components/post-preview-button/index.mjs +2 -2
- package/build-module/components/post-preview-button/index.mjs.map +2 -2
- package/build-module/components/post-publish-button/index.mjs +4 -3
- package/build-module/components/post-publish-button/index.mjs.map +2 -2
- package/build-module/components/post-publish-button/label.mjs +2 -2
- package/build-module/components/post-publish-button/label.mjs.map +2 -2
- package/build-module/components/post-publish-panel/index.mjs.map +1 -1
- package/build-module/components/post-publish-panel/postpublish.mjs +1 -1
- package/build-module/components/post-publish-panel/postpublish.mjs.map +2 -2
- package/build-module/components/post-revisions-preview/block-diff.mjs.map +1 -1
- package/build-module/components/post-revisions-preview/diff-markers.mjs.map +2 -2
- package/build-module/components/post-revisions-preview/revisions-slider.mjs +1 -1
- package/build-module/components/post-revisions-preview/revisions-slider.mjs.map +2 -2
- package/build-module/components/post-revisions-timeline/index.mjs +152 -0
- package/build-module/components/post-revisions-timeline/index.mjs.map +7 -0
- package/build-module/components/post-saved-state/index.mjs +17 -26
- package/build-module/components/post-saved-state/index.mjs.map +2 -2
- package/build-module/components/post-schedule/label.mjs +5 -5
- package/build-module/components/post-schedule/label.mjs.map +1 -1
- package/build-module/components/post-taxonomies/flat-term-selector.mjs +3 -6
- package/build-module/components/post-taxonomies/flat-term-selector.mjs.map +2 -2
- package/build-module/components/post-taxonomies/hierarchical-term-selector.mjs +1 -1
- package/build-module/components/post-taxonomies/hierarchical-term-selector.mjs.map +2 -2
- package/build-module/components/post-text-editor/index.mjs +51 -0
- package/build-module/components/post-text-editor/index.mjs.map +2 -2
- package/build-module/components/post-text-editor/utils.mjs +123 -0
- package/build-module/components/post-text-editor/utils.mjs.map +7 -0
- package/build-module/components/post-url/index.mjs +1 -1
- package/build-module/components/post-url/index.mjs.map +2 -2
- package/build-module/components/post-view-link/index.mjs +1 -1
- package/build-module/components/post-view-link/index.mjs.map +2 -2
- package/build-module/components/provider/disable-non-page-content-blocks.mjs.map +1 -1
- package/build-module/components/provider/index.mjs +1 -1
- package/build-module/components/provider/index.mjs.map +2 -2
- package/build-module/components/resizable-editor/resize-handle.mjs.map +2 -2
- package/build-module/components/revision-diff-panel/index.mjs +7 -2
- package/build-module/components/revision-diff-panel/index.mjs.map +2 -2
- package/build-module/components/revision-fields-diff/index.mjs +6 -2
- package/build-module/components/revision-fields-diff/index.mjs.map +2 -2
- package/build-module/components/sidebar/dataform-post-summary.mjs +125 -20
- package/build-module/components/sidebar/dataform-post-summary.mjs.map +2 -2
- package/build-module/components/sidebar/index.mjs +1 -11
- package/build-module/components/sidebar/index.mjs.map +2 -2
- package/build-module/components/sidebar/post-revision-summary.mjs +11 -17
- package/build-module/components/sidebar/post-revision-summary.mjs.map +2 -2
- package/build-module/components/sidebar/post-summary.mjs +1 -1
- package/build-module/components/sidebar/post-summary.mjs.map +2 -2
- package/build-module/components/style-book/examples.mjs +1 -1
- package/build-module/components/style-book/examples.mjs.map +1 -1
- package/build-module/components/style-book/index.mjs +1 -1
- package/build-module/components/style-book/index.mjs.map +2 -2
- package/build-module/components/sync-connection-error-modal/index.mjs +3 -3
- package/build-module/components/sync-connection-error-modal/index.mjs.map +1 -1
- package/build-module/components/template-actions-panel/block-theme-content.mjs.map +2 -2
- package/build-module/components/template-actions-panel/index.mjs +0 -9
- package/build-module/components/template-actions-panel/index.mjs.map +2 -2
- package/build-module/components/template-validation-notice/index.mjs +1 -1
- package/build-module/components/template-validation-notice/index.mjs.map +1 -1
- package/build-module/components/upload-progress-snackbar/index.mjs +3 -3
- package/build-module/components/upload-progress-snackbar/index.mjs.map +2 -2
- package/build-module/components/upload-progress-snackbar/tracker.mjs.map +1 -1
- package/build-module/components/visual-editor/edit-template-blocks-notification.mjs +1 -1
- package/build-module/components/visual-editor/edit-template-blocks-notification.mjs.map +1 -1
- package/build-module/dataviews/fields/revisions/index.mjs +20 -0
- package/build-module/dataviews/fields/revisions/index.mjs.map +7 -0
- package/build-module/dataviews/fields/revisions/revisions-view.mjs +53 -0
- package/build-module/dataviews/fields/revisions/revisions-view.mjs.map +7 -0
- package/build-module/dataviews/store/private-actions.mjs +23 -7
- package/build-module/dataviews/store/private-actions.mjs.map +2 -2
- package/build-module/hooks/push-changes-to-global-styles/index.mjs +1 -1
- package/build-module/hooks/push-changes-to-global-styles/index.mjs.map +1 -1
- package/build-module/store/actions.mjs +1 -1
- package/build-module/store/actions.mjs.map +2 -2
- package/build-module/store/private-selectors.mjs +7 -1
- package/build-module/store/private-selectors.mjs.map +2 -2
- package/build-module/utils/media-upload/index.mjs.map +1 -1
- package/build-module/utils/set-nested-value.mjs.map +1 -1
- package/build-style/style-rtl.css +270 -206
- package/build-style/style.css +270 -206
- package/build-types/components/collab-sidebar/note-byline.d.ts +0 -3
- package/build-types/components/collab-sidebar/note-byline.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/note.d.ts.map +1 -1
- package/build-types/components/collaborators-presence/avatar/component.d.ts.map +1 -1
- package/build-types/components/document-bar/index.d.ts +2 -2
- package/build-types/components/document-bar/index.d.ts.map +1 -1
- package/build-types/components/global-keyboard-shortcuts/index.d.ts.map +1 -1
- package/build-types/components/local-autosave-monitor/index.d.ts.map +1 -1
- package/build-types/components/post-publish-button/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-timeline/index.d.ts +2 -0
- package/build-types/components/post-revisions-timeline/index.d.ts.map +1 -0
- package/build-types/components/post-saved-state/index.d.ts.map +1 -1
- package/build-types/components/post-taxonomies/flat-term-selector.d.ts.map +1 -1
- package/build-types/components/post-text-editor/index.d.ts +1 -1
- package/build-types/components/post-text-editor/index.d.ts.map +1 -1
- package/build-types/components/provider/index.d.ts.map +1 -1
- package/build-types/components/resizable-editor/resize-handle.d.ts.map +1 -1
- package/build-types/components/revision-diff-panel/index.d.ts +3 -1
- package/build-types/components/revision-diff-panel/index.d.ts.map +1 -1
- package/build-types/components/revision-fields-diff/index.d.ts.map +1 -1
- package/build-types/components/sidebar/dataform-post-summary.d.ts.map +1 -1
- package/build-types/components/sidebar/index.d.ts.map +1 -1
- package/build-types/components/sidebar/post-revision-summary.d.ts.map +1 -1
- package/build-types/components/template-actions-panel/block-theme-content.d.ts.map +1 -1
- package/build-types/components/template-actions-panel/index.d.ts.map +1 -1
- package/build-types/dataviews/fields/revisions/index.d.ts +8 -0
- package/build-types/dataviews/fields/revisions/index.d.ts.map +1 -0
- package/build-types/dataviews/fields/revisions/revisions-view.d.ts +2 -0
- package/build-types/dataviews/fields/revisions/revisions-view.d.ts.map +1 -0
- package/build-types/dataviews/store/private-actions.d.ts.map +1 -1
- package/build-types/store/private-selectors.d.ts +1 -1
- package/build-types/store/private-selectors.d.ts.map +1 -1
- package/build-types/store/selectors.d.ts +1 -1
- package/build-types/store/selectors.d.ts.map +1 -1
- package/package.json +53 -47
- package/src/bindings/pattern-overrides.js +1 -1
- package/src/bindings/test/pattern-overrides.js +65 -0
- package/src/components/collab-sidebar/note-byline.js +0 -1
- package/src/components/collab-sidebar/note.js +64 -29
- package/src/components/collab-sidebar/style.scss +20 -0
- package/src/components/collaborators-presence/avatar/component.tsx +0 -1
- package/src/components/collaborators-presence/avatar/test/index.tsx +0 -1
- package/src/components/document-bar/index.js +8 -3
- package/src/components/document-bar/style.scss +4 -2
- package/src/components/global-keyboard-shortcuts/index.js +2 -1
- package/src/components/local-autosave-monitor/index.js +23 -21
- package/src/components/post-card-panel/index.js +1 -1
- package/src/components/post-publish-button/index.js +6 -3
- package/src/components/post-publish-button/test/index.js +13 -0
- package/src/components/post-revisions-preview/diff-markers.js +0 -1
- package/src/components/post-revisions-timeline/index.js +186 -0
- package/src/components/post-revisions-timeline/style.scss +43 -0
- package/src/components/post-saved-state/index.js +23 -26
- package/src/components/post-saved-state/test/index.js +18 -0
- package/src/components/post-taxonomies/flat-term-selector.js +4 -7
- package/src/components/post-text-editor/index.js +65 -0
- package/src/components/post-text-editor/test/utils.js +210 -0
- package/src/components/post-text-editor/utils.js +204 -0
- package/src/components/post-type-support-check/test/index.js +11 -0
- package/src/components/post-url/index.js +1 -1
- package/src/components/post-view-link/index.js +1 -1
- package/src/components/post-view-link/test/index.js +71 -0
- package/src/components/provider/index.js +2 -1
- package/src/components/resizable-editor/resize-handle.js +0 -1
- package/src/components/revision-diff-panel/index.js +8 -2
- package/src/components/revision-fields-diff/index.js +12 -1
- package/src/components/sidebar/dataform-post-summary.js +196 -25
- package/src/components/sidebar/index.js +2 -12
- package/src/components/sidebar/post-revision-summary.js +8 -15
- package/src/components/sidebar/post-summary.js +1 -1
- package/src/components/style-book/index.js +1 -1
- package/src/components/template-actions-panel/block-theme-content.js +0 -1
- package/src/components/template-actions-panel/index.js +0 -15
- package/src/dataviews/fields/revisions/index.tsx +28 -0
- package/src/dataviews/fields/revisions/revisions-view.tsx +59 -0
- package/src/dataviews/store/private-actions.ts +27 -6
- package/src/store/private-selectors.js +11 -1
- package/src/store/test/private-selectors.js +69 -0
- package/src/style.scss +1 -1
- package/build/components/post-revisions-panel/index.cjs +0 -173
- package/build/components/post-revisions-panel/index.cjs.map +0 -7
- package/build/components/revision-author-panel/index.cjs.map +0 -7
- package/build/components/revision-created-panel/index.cjs +0 -47
- package/build/components/revision-created-panel/index.cjs.map +0 -7
- package/build-module/components/post-revisions-panel/index.mjs +0 -148
- package/build-module/components/post-revisions-panel/index.mjs.map +0 -7
- package/build-module/components/revision-author-panel/index.mjs +0 -28
- package/build-module/components/revision-author-panel/index.mjs.map +0 -7
- package/build-module/components/revision-created-panel/index.mjs +0 -26
- package/build-module/components/revision-created-panel/index.mjs.map +0 -7
- package/build-types/components/collab-sidebar/add-comment.d.ts +0 -6
- package/build-types/components/collab-sidebar/add-comment.d.ts.map +0 -1
- package/build-types/components/collab-sidebar/comment-author-info.d.ts +0 -8
- package/build-types/components/collab-sidebar/comment-author-info.d.ts.map +0 -1
- package/build-types/components/collab-sidebar/comment-form.d.ts +0 -9
- package/build-types/components/collab-sidebar/comment-form.d.ts.map +0 -1
- package/build-types/components/collab-sidebar/comment-indicator-toolbar.d.ts +0 -6
- package/build-types/components/collab-sidebar/comment-indicator-toolbar.d.ts.map +0 -1
- package/build-types/components/collab-sidebar/comment-menu-item.d.ts +0 -6
- package/build-types/components/collab-sidebar/comment-menu-item.d.ts.map +0 -1
- package/build-types/components/collab-sidebar/comments.d.ts +0 -10
- package/build-types/components/collab-sidebar/comments.d.ts.map +0 -1
- 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/build-types/components/post-revisions-panel/index.d.ts +0 -2
- package/build-types/components/post-revisions-panel/index.d.ts.map +0 -1
- package/build-types/components/revision-author-panel/index.d.ts +0 -2
- package/build-types/components/revision-author-panel/index.d.ts.map +0 -1
- package/build-types/components/revision-created-panel/index.d.ts +0 -2
- package/build-types/components/revision-created-panel/index.d.ts.map +0 -1
- package/src/components/editor-help/images/add-dark.png +0 -0
- package/src/components/editor-help/images/add-dark@2x.png +0 -0
- package/src/components/editor-help/images/add-dark@3x.png +0 -0
- package/src/components/editor-help/images/add-light.png +0 -0
- package/src/components/editor-help/images/add-light@2x.png +0 -0
- package/src/components/editor-help/images/add-light@3x.png +0 -0
- package/src/components/editor-help/images/block-layout-collage.png +0 -0
- package/src/components/editor-help/images/block-layout-collage@2x.png +0 -0
- package/src/components/editor-help/images/block-layout-collage@3x.png +0 -0
- package/src/components/editor-help/images/build-layouts-dark.png +0 -0
- package/src/components/editor-help/images/build-layouts-dark@2x.png +0 -0
- package/src/components/editor-help/images/build-layouts-dark@3x.png +0 -0
- package/src/components/editor-help/images/build-layouts-light.png +0 -0
- package/src/components/editor-help/images/build-layouts-light@2x.png +0 -0
- package/src/components/editor-help/images/build-layouts-light@3x.png +0 -0
- package/src/components/editor-help/images/drag-and-drop-dark.png +0 -0
- package/src/components/editor-help/images/drag-and-drop-dark@2x.png +0 -0
- package/src/components/editor-help/images/drag-and-drop-dark@3x.png +0 -0
- package/src/components/editor-help/images/drag-and-drop-light.png +0 -0
- package/src/components/editor-help/images/drag-and-drop-light@2x.png +0 -0
- package/src/components/editor-help/images/drag-and-drop-light@3x.png +0 -0
- package/src/components/editor-help/images/edit-media-dark.png +0 -0
- package/src/components/editor-help/images/edit-media-dark@2x.png +0 -0
- package/src/components/editor-help/images/edit-media-dark@3x.png +0 -0
- package/src/components/editor-help/images/edit-media-light.png +0 -0
- package/src/components/editor-help/images/edit-media-light@2x.png +0 -0
- package/src/components/editor-help/images/edit-media-light@3x.png +0 -0
- package/src/components/editor-help/images/embed-media-dark.png +0 -0
- package/src/components/editor-help/images/embed-media-dark@2x.png +0 -0
- package/src/components/editor-help/images/embed-media-dark@3x.png +0 -0
- package/src/components/editor-help/images/embed-media-light.png +0 -0
- package/src/components/editor-help/images/embed-media-light@2x.png +0 -0
- package/src/components/editor-help/images/embed-media-light@3x.png +0 -0
- package/src/components/editor-help/images/move-dark.png +0 -0
- package/src/components/editor-help/images/move-dark@2x.png +0 -0
- package/src/components/editor-help/images/move-dark@3x.png +0 -0
- package/src/components/editor-help/images/move-light.png +0 -0
- package/src/components/editor-help/images/move-light@2x.png +0 -0
- package/src/components/editor-help/images/move-light@3x.png +0 -0
- package/src/components/editor-help/images/options-dark.png +0 -0
- package/src/components/editor-help/images/options-dark@2x.png +0 -0
- package/src/components/editor-help/images/options-dark@3x.png +0 -0
- package/src/components/editor-help/images/options-light.png +0 -0
- package/src/components/editor-help/images/options-light@2x.png +0 -0
- package/src/components/editor-help/images/options-light@3x.png +0 -0
- package/src/components/editor-help/images/rich-text-dark.png +0 -0
- package/src/components/editor-help/images/rich-text-dark@2x.png +0 -0
- package/src/components/editor-help/images/rich-text-dark@3x.png +0 -0
- package/src/components/editor-help/images/rich-text-light.png +0 -0
- package/src/components/editor-help/images/rich-text-light@2x.png +0 -0
- package/src/components/editor-help/images/rich-text-light@3x.png +0 -0
- package/src/components/editor-help/images/settings-dark.png +0 -0
- package/src/components/editor-help/images/settings-dark@2x.png +0 -0
- package/src/components/editor-help/images/settings-dark@3x.png +0 -0
- package/src/components/editor-help/images/settings-light.png +0 -0
- package/src/components/editor-help/images/settings-light@2x.png +0 -0
- package/src/components/editor-help/images/settings-light@3x.png +0 -0
- package/src/components/editor-help/style.scss +0 -123
- package/src/components/post-revisions-panel/index.js +0 -161
- package/src/components/post-revisions-panel/style.scss +0 -16
- package/src/components/revision-author-panel/index.js +0 -36
- package/src/components/revision-created-panel/index.js +0 -36
|
@@ -35,7 +35,7 @@ var pattern_overrides_default = {
|
|
|
35
35
|
for (const attributeName of Object.keys(bindings)) {
|
|
36
36
|
const overridableValue = patternOverridesContent?.[currentBlockAttributes?.metadata?.name]?.[attributeName];
|
|
37
37
|
if (overridableValue === void 0) {
|
|
38
|
-
overridesValues[attributeName] = currentBlockAttributes[attributeName];
|
|
38
|
+
overridesValues[attributeName] = currentBlockAttributes?.[attributeName];
|
|
39
39
|
continue;
|
|
40
40
|
} else {
|
|
41
41
|
overridesValues[attributeName] = overridableValue === "" ? void 0 : overridableValue;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/bindings/pattern-overrides.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { store as blockEditorStore } from '@wordpress/block-editor';\n\nconst CONTENT = 'content';\n\n/**\n * @type {WPBlockBindingsSource}\n */\nexport default {\n\tname: 'core/pattern-overrides',\n\tgetValues( { select, clientId, context, bindings } ) {\n\t\tconst patternOverridesContent = context[ 'pattern/overrides' ];\n\t\tconst { getBlockAttributes } = select( blockEditorStore );\n\t\tconst currentBlockAttributes = getBlockAttributes( clientId );\n\n\t\tconst overridesValues = {};\n\t\tfor ( const attributeName of Object.keys( bindings ) ) {\n\t\t\tconst overridableValue =\n\t\t\t\tpatternOverridesContent?.[\n\t\t\t\t\tcurrentBlockAttributes?.metadata?.name\n\t\t\t\t]?.[ attributeName ];\n\n\t\t\t// If it has not been overridden, return the original value.\n\t\t\t// Check undefined because empty string is a valid value.\n\t\t\tif ( overridableValue === undefined ) {\n\t\t\t\toverridesValues[ attributeName ] =\n\t\t\t\t\tcurrentBlockAttributes[ attributeName ];\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\toverridesValues[ attributeName ] =\n\t\t\t\t\toverridableValue === '' ? undefined : overridableValue;\n\t\t\t}\n\t\t}\n\t\treturn overridesValues;\n\t},\n\tsetValues( { select, dispatch, clientId, bindings } ) {\n\t\tconst { getBlockAttributes, getBlockParentsByBlockName, getBlocks } =\n\t\t\tselect( blockEditorStore );\n\t\tconst currentBlockAttributes = getBlockAttributes( clientId );\n\t\tconst blockName = currentBlockAttributes?.metadata?.name;\n\t\tif ( ! blockName ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst [ patternClientId ] = getBlockParentsByBlockName(\n\t\t\tclientId,\n\t\t\t'core/block',\n\t\t\ttrue\n\t\t);\n\n\t\t// Extract the updated attributes from the source bindings.\n\t\tconst attributes = Object.entries( bindings ).reduce(\n\t\t\t( attrs, [ key, { newValue } ] ) => {\n\t\t\t\tattrs[ key ] = newValue;\n\t\t\t\treturn attrs;\n\t\t\t},\n\t\t\t{}\n\t\t);\n\n\t\t// If there is no pattern client ID, sync blocks with the same name and same attributes.\n\t\tif ( ! patternClientId ) {\n\t\t\tconst syncBlocksWithSameName = ( blocks ) => {\n\t\t\t\tfor ( const block of blocks ) {\n\t\t\t\t\tif ( block.attributes?.metadata?.name === blockName ) {\n\t\t\t\t\t\tdispatch( blockEditorStore ).updateBlockAttributes(\n\t\t\t\t\t\t\tblock.clientId,\n\t\t\t\t\t\t\tattributes\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tsyncBlocksWithSameName( block.innerBlocks );\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tsyncBlocksWithSameName( getBlocks() );\n\t\t\treturn;\n\t\t}\n\t\tconst currentBindingValue =\n\t\t\tgetBlockAttributes( patternClientId )?.[ CONTENT ];\n\n\t\tdispatch( blockEditorStore ).updateBlockAttributes( patternClientId, {\n\t\t\t[ CONTENT ]: {\n\t\t\t\t...currentBindingValue,\n\t\t\t\t[ blockName ]: {\n\t\t\t\t\t...currentBindingValue?.[ blockName ],\n\t\t\t\t\t...Object.entries( attributes ).reduce(\n\t\t\t\t\t\t( acc, [ key, value ] ) => {\n\t\t\t\t\t\t\t// TODO: We need a way to represent `undefined` in the serialized overrides.\n\t\t\t\t\t\t\t// Also see: https://github.com/WordPress/gutenberg/pull/57249#discussion_r1452987871\n\t\t\t\t\t\t\t// We use an empty string to represent undefined for now until\n\t\t\t\t\t\t\t// we support a richer format for overrides and the block bindings API.\n\t\t\t\t\t\t\tacc[ key ] = value === undefined ? '' : value;\n\t\t\t\t\t\t\treturn acc;\n\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} );\n\t},\n\tcanUserEditValue: () => true,\n};\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,0BAA0C;AAE1C,IAAM,UAAU;AAKhB,IAAO,4BAAQ;AAAA,EACd,MAAM;AAAA,EACN,UAAW,EAAE,QAAQ,UAAU,SAAS,SAAS,GAAI;AACpD,UAAM,0BAA0B,QAAS,mBAAoB;AAC7D,UAAM,EAAE,mBAAmB,IAAI,OAAQ,oBAAAA,KAAiB;AACxD,UAAM,yBAAyB,mBAAoB,QAAS;AAE5D,UAAM,kBAAkB,CAAC;AACzB,eAAY,iBAAiB,OAAO,KAAM,QAAS,GAAI;AACtD,YAAM,mBACL,0BACC,wBAAwB,UAAU,IACnC,IAAK,aAAc;AAIpB,UAAK,qBAAqB,QAAY;AACrC,wBAAiB,aAAc,IAC9B,
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { store as blockEditorStore } from '@wordpress/block-editor';\n\nconst CONTENT = 'content';\n\n/**\n * @type {WPBlockBindingsSource}\n */\nexport default {\n\tname: 'core/pattern-overrides',\n\tgetValues( { select, clientId, context, bindings } ) {\n\t\tconst patternOverridesContent = context[ 'pattern/overrides' ];\n\t\tconst { getBlockAttributes } = select( blockEditorStore );\n\t\tconst currentBlockAttributes = getBlockAttributes( clientId );\n\n\t\tconst overridesValues = {};\n\t\tfor ( const attributeName of Object.keys( bindings ) ) {\n\t\t\tconst overridableValue =\n\t\t\t\tpatternOverridesContent?.[\n\t\t\t\t\tcurrentBlockAttributes?.metadata?.name\n\t\t\t\t]?.[ attributeName ];\n\n\t\t\t// If it has not been overridden, return the original value.\n\t\t\t// Check undefined because empty string is a valid value.\n\t\t\tif ( overridableValue === undefined ) {\n\t\t\t\toverridesValues[ attributeName ] =\n\t\t\t\t\tcurrentBlockAttributes?.[ attributeName ];\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\toverridesValues[ attributeName ] =\n\t\t\t\t\toverridableValue === '' ? undefined : overridableValue;\n\t\t\t}\n\t\t}\n\t\treturn overridesValues;\n\t},\n\tsetValues( { select, dispatch, clientId, bindings } ) {\n\t\tconst { getBlockAttributes, getBlockParentsByBlockName, getBlocks } =\n\t\t\tselect( blockEditorStore );\n\t\tconst currentBlockAttributes = getBlockAttributes( clientId );\n\t\tconst blockName = currentBlockAttributes?.metadata?.name;\n\t\tif ( ! blockName ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst [ patternClientId ] = getBlockParentsByBlockName(\n\t\t\tclientId,\n\t\t\t'core/block',\n\t\t\ttrue\n\t\t);\n\n\t\t// Extract the updated attributes from the source bindings.\n\t\tconst attributes = Object.entries( bindings ).reduce(\n\t\t\t( attrs, [ key, { newValue } ] ) => {\n\t\t\t\tattrs[ key ] = newValue;\n\t\t\t\treturn attrs;\n\t\t\t},\n\t\t\t{}\n\t\t);\n\n\t\t// If there is no pattern client ID, sync blocks with the same name and same attributes.\n\t\tif ( ! patternClientId ) {\n\t\t\tconst syncBlocksWithSameName = ( blocks ) => {\n\t\t\t\tfor ( const block of blocks ) {\n\t\t\t\t\tif ( block.attributes?.metadata?.name === blockName ) {\n\t\t\t\t\t\tdispatch( blockEditorStore ).updateBlockAttributes(\n\t\t\t\t\t\t\tblock.clientId,\n\t\t\t\t\t\t\tattributes\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tsyncBlocksWithSameName( block.innerBlocks );\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tsyncBlocksWithSameName( getBlocks() );\n\t\t\treturn;\n\t\t}\n\t\tconst currentBindingValue =\n\t\t\tgetBlockAttributes( patternClientId )?.[ CONTENT ];\n\n\t\tdispatch( blockEditorStore ).updateBlockAttributes( patternClientId, {\n\t\t\t[ CONTENT ]: {\n\t\t\t\t...currentBindingValue,\n\t\t\t\t[ blockName ]: {\n\t\t\t\t\t...currentBindingValue?.[ blockName ],\n\t\t\t\t\t...Object.entries( attributes ).reduce(\n\t\t\t\t\t\t( acc, [ key, value ] ) => {\n\t\t\t\t\t\t\t// TODO: We need a way to represent `undefined` in the serialized overrides.\n\t\t\t\t\t\t\t// Also see: https://github.com/WordPress/gutenberg/pull/57249#discussion_r1452987871\n\t\t\t\t\t\t\t// We use an empty string to represent undefined for now until\n\t\t\t\t\t\t\t// we support a richer format for overrides and the block bindings API.\n\t\t\t\t\t\t\tacc[ key ] = value === undefined ? '' : value;\n\t\t\t\t\t\t\treturn acc;\n\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} );\n\t},\n\tcanUserEditValue: () => true,\n};\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,0BAA0C;AAE1C,IAAM,UAAU;AAKhB,IAAO,4BAAQ;AAAA,EACd,MAAM;AAAA,EACN,UAAW,EAAE,QAAQ,UAAU,SAAS,SAAS,GAAI;AACpD,UAAM,0BAA0B,QAAS,mBAAoB;AAC7D,UAAM,EAAE,mBAAmB,IAAI,OAAQ,oBAAAA,KAAiB;AACxD,UAAM,yBAAyB,mBAAoB,QAAS;AAE5D,UAAM,kBAAkB,CAAC;AACzB,eAAY,iBAAiB,OAAO,KAAM,QAAS,GAAI;AACtD,YAAM,mBACL,0BACC,wBAAwB,UAAU,IACnC,IAAK,aAAc;AAIpB,UAAK,qBAAqB,QAAY;AACrC,wBAAiB,aAAc,IAC9B,yBAA0B,aAAc;AACzC;AAAA,MACD,OAAO;AACN,wBAAiB,aAAc,IAC9B,qBAAqB,KAAK,SAAY;AAAA,MACxC;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EACA,UAAW,EAAE,QAAQ,UAAU,UAAU,SAAS,GAAI;AACrD,UAAM,EAAE,oBAAoB,4BAA4B,UAAU,IACjE,OAAQ,oBAAAA,KAAiB;AAC1B,UAAM,yBAAyB,mBAAoB,QAAS;AAC5D,UAAM,YAAY,wBAAwB,UAAU;AACpD,QAAK,CAAE,WAAY;AAClB;AAAA,IACD;AAEA,UAAM,CAAE,eAAgB,IAAI;AAAA,MAC3B;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAGA,UAAM,aAAa,OAAO,QAAS,QAAS,EAAE;AAAA,MAC7C,CAAE,OAAO,CAAE,KAAK,EAAE,SAAS,CAAE,MAAO;AACnC,cAAO,GAAI,IAAI;AACf,eAAO;AAAA,MACR;AAAA,MACA,CAAC;AAAA,IACF;AAGA,QAAK,CAAE,iBAAkB;AACxB,YAAM,yBAAyB,CAAE,WAAY;AAC5C,mBAAY,SAAS,QAAS;AAC7B,cAAK,MAAM,YAAY,UAAU,SAAS,WAAY;AACrD,qBAAU,oBAAAA,KAAiB,EAAE;AAAA,cAC5B,MAAM;AAAA,cACN;AAAA,YACD;AAAA,UACD;AACA,iCAAwB,MAAM,WAAY;AAAA,QAC3C;AAAA,MACD;AAEA,6BAAwB,UAAU,CAAE;AACpC;AAAA,IACD;AACA,UAAM,sBACL,mBAAoB,eAAgB,IAAK,OAAQ;AAElD,aAAU,oBAAAA,KAAiB,EAAE,sBAAuB,iBAAiB;AAAA,MACpE,CAAE,OAAQ,GAAG;AAAA,QACZ,GAAG;AAAA,QACH,CAAE,SAAU,GAAG;AAAA,UACd,GAAG,sBAAuB,SAAU;AAAA,UACpC,GAAG,OAAO,QAAS,UAAW,EAAE;AAAA,YAC/B,CAAE,KAAK,CAAE,KAAK,KAAM,MAAO;AAK1B,kBAAK,GAAI,IAAI,UAAU,SAAY,KAAK;AACxC,qBAAO;AAAA,YACR;AAAA,YACA,CAAC;AAAA,UACF;AAAA,QACD;AAAA,MACD;AAAA,IACD,CAAE;AAAA,EACH;AAAA,EACA,kBAAkB,MAAM;AACzB;",
|
|
6
6
|
"names": ["blockEditorStore"]
|
|
7
7
|
}
|
|
@@ -70,7 +70,7 @@ function NoteByline({ avatar, name, date, userId }) {
|
|
|
70
70
|
const commentDateText = shouldShowHumanTimeDiff ? (0, import_date.humanTimeDiff)(commentDate) : (0, import_date.dateI18n)(dateFormat, commentDate);
|
|
71
71
|
const tooltipText = (0, import_date.dateI18n)(
|
|
72
72
|
// translators: Use a non-breaking space between 'g:i' and 'a' if appropriate.
|
|
73
|
-
(0, import_i18n._x)("F j, Y g:i
|
|
73
|
+
(0, import_i18n._x)("F j, Y g:i a", "Note date full date format"),
|
|
74
74
|
date
|
|
75
75
|
);
|
|
76
76
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/collab-sidebar/note-byline.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * WordPress dependencies\n */\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { Stack, Tooltip } from '@wordpress/ui';\nimport { __, _x } from '@wordpress/i18n';\nimport {\n\tdateI18n,\n\tgetSettings as getDateSettings,\n\thumanTimeDiff,\n\tgetDate,\n} from '@wordpress/date';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { useSelect } from '@wordpress/data';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { getAvatarBorderColor } from './utils';\n\nexport function NoteByline( { avatar, name, date, userId } ) {\n\tconst hasAvatar = !! avatar;\n\tconst dateSettings = getDateSettings();\n\tconst {\n\t\tcurrentUserAvatar,\n\t\tcurrentUserName,\n\t\tcurrentUserId,\n\t\tdateFormat = dateSettings.formats.date,\n\t} = useSelect(\n\t\t( select ) => {\n\t\t\tconst { canUser, getCurrentUser, getEntityRecord } =\n\t\t\t\tselect( coreStore );\n\t\t\tconst siteSettings = canUser( 'read', {\n\t\t\t\tkind: 'root',\n\t\t\t\tname: 'site',\n\t\t\t} )\n\t\t\t\t? getEntityRecord( 'root', 'site' )\n\t\t\t\t: undefined;\n\n\t\t\tif ( hasAvatar ) {\n\t\t\t\treturn {\n\t\t\t\t\tdateFormat: siteSettings?.date_format,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst { getSettings } = select( blockEditorStore );\n\t\t\tconst { __experimentalDiscussionSettings } = getSettings();\n\t\t\tconst defaultAvatar = __experimentalDiscussionSettings?.avatarURL;\n\t\t\tconst userData = getCurrentUser();\n\t\t\treturn {\n\t\t\t\tcurrentUserAvatar:\n\t\t\t\t\tuserData?.avatar_urls?.[ 48 ] ?? defaultAvatar,\n\t\t\t\tcurrentUserName: userData?.name,\n\t\t\t\tcurrentUserId: userData?.id,\n\t\t\t\tdateFormat: siteSettings?.date_format,\n\t\t\t};\n\t\t},\n\t\t[ hasAvatar ]\n\t);\n\n\tconst commentDate = getDate( date );\n\tconst commentDateTime = dateI18n( 'c', commentDate );\n\tconst shouldShowHumanTimeDiff =\n\t\tMath.floor( ( new Date() - commentDate ) / ( 1000 * 60 * 60 * 24 ) ) <\n\t\t30;\n\n\tconst commentDateText = shouldShowHumanTimeDiff\n\t\t? humanTimeDiff( commentDate )\n\t\t: dateI18n( dateFormat, commentDate );\n\n\tconst tooltipText = dateI18n(\n\t\t// translators: Use a non-breaking space between 'g:i' and 'a' if appropriate.\n\t\t_x( 'F j, Y g:i\\xa0a', 'Note date full date format' ),\n\t\tdate\n\t);\n\n\treturn (\n\t\t<>\n\t\t\t<img\n\t\t\t\tsrc={ avatar || currentUserAvatar }\n\t\t\t\tclassName=\"editor-collab-sidebar-panel__user-avatar\"\n\t\t\t\t// translators: alt text for user avatar image\n\t\t\t\talt={ __( 'User avatar' ) }\n\t\t\t\twidth={ 32 }\n\t\t\t\theight={ 32 }\n\t\t\t\tstyle={ {\n\t\t\t\t\tborderColor: getAvatarBorderColor(\n\t\t\t\t\t\tuserId ?? currentUserId\n\t\t\t\t\t),\n\t\t\t\t} }\n\t\t\t/>\n\t\t\t<Stack direction=\"column\">\n\t\t\t\t<span className=\"editor-collab-sidebar-panel__user-name\">\n\t\t\t\t\t{ name ?? currentUserName }\n\t\t\t\t</span>\n\t\t\t\t{ date && (\n\t\t\t\t\t<Tooltip.Root>\n\t\t\t\t\t\t<Tooltip.Trigger\n\t\t\t\t\t\t\trender={\n\t\t\t\t\t\t\t\t<time\n\t\t\t\t\t\t\t\t\tdateTime={ commentDateTime }\n\t\t\t\t\t\t\t\t\tclassName=\"editor-collab-sidebar-panel__user-time\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{ commentDateText }\n\t\t\t\t\t\t\t\t</time>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<Tooltip.Popup>{ tooltipText }</Tooltip.Popup>\n\t\t\t\t\t</Tooltip.Root>\n\t\t\t\t) }\n\t\t\t</Stack>\n\t\t</>\n\t);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,gBAA+B;AAC/B,kBAAuB;AACvB,kBAKO;AACP,uBAAmC;AACnC,kBAA0B;AAC1B,0BAA0C;AAK1C,mBAAqC;AA2DnC;AAzDK,SAAS,WAAY,EAAE,QAAQ,MAAM,MAAM,OAAO,GAAI;AAC5D,QAAM,YAAY,CAAC,CAAE;AACrB,QAAM,mBAAe,YAAAA,aAAgB;AACrC,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,aAAa,QAAQ;AAAA,EACnC,QAAI;AAAA,IACH,CAAE,WAAY;AACb,YAAM,EAAE,SAAS,gBAAgB,gBAAgB,IAChD,OAAQ,iBAAAC,KAAU;AACnB,YAAM,eAAe,QAAS,QAAQ;AAAA,QACrC,MAAM;AAAA,QACN,MAAM;AAAA,MACP,CAAE,IACC,gBAAiB,QAAQ,MAAO,IAChC;AAEH,UAAK,WAAY;AAChB,eAAO;AAAA,UACN,YAAY,cAAc;AAAA,QAC3B;AAAA,MACD;AAEA,YAAM,EAAE,YAAY,IAAI,OAAQ,oBAAAC,KAAiB;AACjD,YAAM,EAAE,iCAAiC,IAAI,YAAY;AACzD,YAAM,gBAAgB,kCAAkC;AACxD,YAAM,WAAW,eAAe;AAChC,aAAO;AAAA,QACN,mBACC,UAAU,cAAe,EAAG,KAAK;AAAA,QAClC,iBAAiB,UAAU;AAAA,QAC3B,eAAe,UAAU;AAAA,QACzB,YAAY,cAAc;AAAA,MAC3B;AAAA,IACD;AAAA,IACA,CAAE,SAAU;AAAA,EACb;AAEA,QAAM,kBAAc,qBAAS,IAAK;AAClC,QAAM,sBAAkB,sBAAU,KAAK,WAAY;AACnD,QAAM,0BACL,KAAK,OAAS,oBAAI,KAAK,IAAI,gBAAkB,MAAO,KAAK,KAAK,GAAK,IACnE;AAED,QAAM,kBAAkB,8BACrB,2BAAe,WAAY,QAC3B,sBAAU,YAAY,WAAY;AAErC,QAAM,kBAAc;AAAA;AAAA,QAEnB,gBAAI,gBAAmB,4BAA6B;AAAA,IACpD;AAAA,EACD;AAEA,SACC,4EACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACA,KAAM,UAAU;AAAA,QAChB,WAAU;AAAA,QAEV,SAAM,gBAAI,aAAc;AAAA,QACxB,OAAQ;AAAA,QACR,QAAS;AAAA,QACT,OAAQ;AAAA,UACP,iBAAa;AAAA,YACZ,UAAU;AAAA,UACX;AAAA,QACD;AAAA;AAAA,IACD;AAAA,IACA,6CAAC,mBAAM,WAAU,UAChB;AAAA,kDAAC,UAAK,WAAU,0CACb,kBAAQ,iBACX;AAAA,MACE,QACD,6CAAC,kBAAQ,MAAR,EACA;AAAA;AAAA,UAAC,kBAAQ;AAAA,UAAR;AAAA,YACA,QACC;AAAA,cAAC;AAAA;AAAA,gBACA,UAAW;AAAA,gBACX,WAAU;AAAA,gBAER;AAAA;AAAA,YACH;AAAA;AAAA,QAEF;AAAA,QACA,4CAAC,kBAAQ,OAAR,EAAgB,uBAAa;AAAA,SAC/B;AAAA,OAEF;AAAA,KACD;AAEF;",
|
|
6
6
|
"names": ["getDateSettings", "coreStore", "blockEditorStore"]
|
|
7
7
|
}
|
|
@@ -36,6 +36,7 @@ module.exports = __toCommonJS(note_exports);
|
|
|
36
36
|
var import_clsx = __toESM(require("clsx"));
|
|
37
37
|
var import_element = require("@wordpress/element");
|
|
38
38
|
var import_components = require("@wordpress/components");
|
|
39
|
+
var import_ui = require("@wordpress/ui");
|
|
39
40
|
var import_i18n = require("@wordpress/i18n");
|
|
40
41
|
var import_icons = require("@wordpress/icons");
|
|
41
42
|
var import_note_card = require("./note-card.cjs");
|
|
@@ -80,6 +81,23 @@ function Note({
|
|
|
80
81
|
}) {
|
|
81
82
|
const [actionState, setActionState] = (0, import_element.useState)(null);
|
|
82
83
|
const actionButtonRef = (0, import_element.useRef)(null);
|
|
84
|
+
const commentRef = (0, import_element.useRef)(null);
|
|
85
|
+
const rawContent = note?.content?.raw;
|
|
86
|
+
const [prevContent, setPrevContent] = (0, import_element.useState)(rawContent);
|
|
87
|
+
const [isExpanded, setIsExpanded] = (0, import_element.useState)(false);
|
|
88
|
+
const [isOverflowing, setIsOverflowing] = (0, import_element.useState)(false);
|
|
89
|
+
if (prevContent !== rawContent) {
|
|
90
|
+
setPrevContent(rawContent);
|
|
91
|
+
setIsExpanded(false);
|
|
92
|
+
}
|
|
93
|
+
(0, import_element.useLayoutEffect)(() => {
|
|
94
|
+
const commentElement = commentRef.current;
|
|
95
|
+
if (commentElement) {
|
|
96
|
+
setIsOverflowing(
|
|
97
|
+
commentElement.scrollHeight > commentElement.clientHeight
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
}, [rawContent]);
|
|
83
101
|
const canResolve = note.parent === 0;
|
|
84
102
|
const isResolutionNote = note.type === "note" && note.meta && (note.meta._wp_note_status === "resolved" || note.meta._wp_note_status === "reopen");
|
|
85
103
|
const menuItems = [
|
|
@@ -133,27 +151,31 @@ function Note({
|
|
|
133
151
|
}
|
|
134
152
|
}
|
|
135
153
|
);
|
|
136
|
-
} else
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
(0, import_i18n.
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
154
|
+
} else {
|
|
155
|
+
let content;
|
|
156
|
+
if (isResolutionNote) {
|
|
157
|
+
const actionText = note.meta._wp_note_status === "resolved" ? (0, import_i18n.__)("Marked as resolved") : (0, import_i18n.__)("Reopened");
|
|
158
|
+
const raw = note?.content?.raw;
|
|
159
|
+
content = raw && typeof raw === "string" && raw.trim() !== "" ? (0, import_i18n.sprintf)(
|
|
160
|
+
// translators: %1$s: action label ("Marked as resolved" or "Reopened"); %2$s: note text.
|
|
161
|
+
(0, import_i18n.__)("%1$s: %2$s"),
|
|
162
|
+
actionText,
|
|
163
|
+
raw
|
|
164
|
+
) : actionText;
|
|
165
|
+
} else {
|
|
166
|
+
content = note?.content?.rendered;
|
|
167
|
+
}
|
|
145
168
|
body = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
146
|
-
|
|
169
|
+
"div",
|
|
147
170
|
{
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
"editor-collab-sidebar-panel__resolution-text"
|
|
151
|
-
|
|
152
|
-
|
|
171
|
+
ref: commentRef,
|
|
172
|
+
className: (0, import_clsx.default)("editor-collab-sidebar-panel__note-content", {
|
|
173
|
+
"editor-collab-sidebar-panel__resolution-text": isResolutionNote,
|
|
174
|
+
"is-collapsed": !isExpanded
|
|
175
|
+
}),
|
|
176
|
+
dangerouslySetInnerHTML: { __html: content ?? "" }
|
|
153
177
|
}
|
|
154
178
|
);
|
|
155
|
-
} else {
|
|
156
|
-
body = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_element.RawHTML, { className: "editor-collab-sidebar-panel__note-content", children: note?.content?.rendered });
|
|
157
179
|
}
|
|
158
180
|
const actions = isSelected ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
159
181
|
canResolve && onResolve && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -195,6 +217,16 @@ function Note({
|
|
|
195
217
|
confirmButtonText: (0, import_i18n.__)("Delete"),
|
|
196
218
|
children: deleteConfirmMessage
|
|
197
219
|
}
|
|
220
|
+
),
|
|
221
|
+
isOverflowing && "edit" !== actionState && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
222
|
+
import_ui.Button,
|
|
223
|
+
{
|
|
224
|
+
className: "editor-collab-sidebar-panel__show-more-button",
|
|
225
|
+
variant: "unstyled",
|
|
226
|
+
size: "small",
|
|
227
|
+
onClick: () => setIsExpanded(!isExpanded),
|
|
228
|
+
children: !isExpanded ? (0, import_i18n.__)("Show more") : (0, import_i18n.__)("Show less")
|
|
229
|
+
}
|
|
198
230
|
)
|
|
199
231
|
]
|
|
200
232
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/collab-sidebar/note.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kBAAiB;AAKjB,
|
|
6
|
-
"names": ["componentsPrivateApis", "clsx", "ConfirmDialog"]
|
|
4
|
+
"sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport { useRef, useState, useLayoutEffect } from '@wordpress/element';\nimport {\n\t__experimentalConfirmDialog as ConfirmDialog,\n\tButton,\n\tprivateApis as componentsPrivateApis,\n} from '@wordpress/components';\n// eslint-disable-next-line @wordpress/use-recommended-components\nimport { Button as UIButton } from '@wordpress/ui';\nimport { __, _x, sprintf } from '@wordpress/i18n';\nimport { moreVertical, published } from '@wordpress/icons';\n\n/**\n * Internal dependencies\n */\nimport { NoteCard } from './note-card';\nimport { NoteForm } from './note-form';\nimport { unlock } from '../../lock-unlock';\n\nconst { Menu } = unlock( componentsPrivateApis );\n\nfunction NoteActionsMenu( { items, buttonRef } ) {\n\treturn (\n\t\t<Menu placement=\"bottom-end\">\n\t\t\t<Menu.TriggerButton\n\t\t\t\trender={\n\t\t\t\t\t<Button\n\t\t\t\t\t\tref={ buttonRef }\n\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\ticon={ moreVertical }\n\t\t\t\t\t\tlabel={ __( 'Actions' ) }\n\t\t\t\t\t\tdisabled={ ! items.length }\n\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t<Menu.Popover\n\t\t\t\t// The menu popover is rendered in a portal, which causes focus to be\n\t\t\t\t// lost and the note to be collapsed unintentionally. To prevent this,\n\t\t\t\t// the popover should be rendered as an inline.\n\t\t\t\tmodal={ false }\n\t\t\t>\n\t\t\t\t{ items.map( ( item ) => (\n\t\t\t\t\t<Menu.Item key={ item.id } onClick={ item.onClick }>\n\t\t\t\t\t\t<Menu.ItemLabel>{ item.title }</Menu.ItemLabel>\n\t\t\t\t\t</Menu.Item>\n\t\t\t\t) ) }\n\t\t\t</Menu.Popover>\n\t\t</Menu>\n\t);\n}\n\nexport function Note( {\n\tnote,\n\tparentNote,\n\tisSelected,\n\tonEditNote,\n\tonDeleteNote,\n\tonResolve,\n} ) {\n\tconst [ actionState, setActionState ] = useState( null );\n\tconst actionButtonRef = useRef( null );\n\n\tconst commentRef = useRef( null );\n\tconst rawContent = note?.content?.raw;\n\tconst [ prevContent, setPrevContent ] = useState( rawContent );\n\tconst [ isExpanded, setIsExpanded ] = useState( false );\n\tconst [ isOverflowing, setIsOverflowing ] = useState( false );\n\n\t// Collapse whenever the content changes so it can be re-measured.\n\tif ( prevContent !== rawContent ) {\n\t\tsetPrevContent( rawContent );\n\t\tsetIsExpanded( false );\n\t}\n\n\t// Measure the (clamped) content to decide whether the toggle is needed.\n\tuseLayoutEffect( () => {\n\t\tconst commentElement = commentRef.current;\n\t\tif ( commentElement ) {\n\t\t\tsetIsOverflowing(\n\t\t\t\tcommentElement.scrollHeight > commentElement.clientHeight\n\t\t\t);\n\t\t}\n\t}, [ rawContent ] );\n\n\tconst canResolve = note.parent === 0;\n\tconst isResolutionNote =\n\t\tnote.type === 'note' &&\n\t\tnote.meta &&\n\t\t( note.meta._wp_note_status === 'resolved' ||\n\t\t\tnote.meta._wp_note_status === 'reopen' );\n\n\tconst menuItems = [\n\t\t{\n\t\t\tid: 'edit',\n\t\t\ttitle: __( 'Edit' ),\n\t\t\tisEligible: ( { status } ) => status !== 'approved',\n\t\t\tonClick: () => setActionState( 'edit' ),\n\t\t},\n\t\t{\n\t\t\tid: 'reopen',\n\t\t\ttitle: _x( 'Reopen', 'Reopen note' ),\n\t\t\tisEligible: ( { status } ) => status === 'approved',\n\t\t\tonClick: () => onEditNote( { id: note.id, status: 'hold' } ),\n\t\t},\n\t\t{\n\t\t\tid: 'delete',\n\t\t\ttitle: __( 'Delete' ),\n\t\t\tisEligible: () => true,\n\t\t\tonClick: () => setActionState( 'delete' ),\n\t\t},\n\t];\n\tconst availableItems =\n\t\tparentNote?.status !== 'approved'\n\t\t\t? menuItems.filter( ( item ) => item.isEligible( note ) )\n\t\t\t: [];\n\n\tconst deleteConfirmMessage =\n\t\tnote.parent === 0\n\t\t\t? __(\n\t\t\t\t\t\"Are you sure you want to delete this note? This will also delete all of this note's replies.\"\n\t\t\t )\n\t\t\t: __( 'Are you sure you want to delete this reply?' );\n\n\tconst handleCancel = () => {\n\t\tsetActionState( null );\n\t\tactionButtonRef.current?.focus();\n\t};\n\n\tlet body;\n\tif ( actionState === 'edit' ) {\n\t\tbody = (\n\t\t\t<NoteForm\n\t\t\t\tonSubmit={ ( value ) => {\n\t\t\t\t\tonEditNote( { id: note.id, content: value } );\n\t\t\t\t\tsetActionState( null );\n\t\t\t\t\tactionButtonRef.current?.focus();\n\t\t\t\t} }\n\t\t\t\tonCancel={ handleCancel }\n\t\t\t\tnote={ note }\n\t\t\t\tlabels={ {\n\t\t\t\t\tsubmit: _x( 'Update', 'verb' ),\n\t\t\t\t\tinput: sprintf(\n\t\t\t\t\t\t// translators: %1$s: note identifier, %2$s: author name.\n\t\t\t\t\t\t__( 'Edit note %1$s by %2$s' ),\n\t\t\t\t\t\tnote.id,\n\t\t\t\t\t\tnote.author_name\n\t\t\t\t\t),\n\t\t\t\t} }\n\t\t\t/>\n\t\t);\n\t} else {\n\t\tlet content;\n\t\tif ( isResolutionNote ) {\n\t\t\tconst actionText =\n\t\t\t\tnote.meta._wp_note_status === 'resolved'\n\t\t\t\t\t? __( 'Marked as resolved' )\n\t\t\t\t\t: __( 'Reopened' );\n\t\t\tconst raw = note?.content?.raw;\n\t\t\tcontent =\n\t\t\t\traw && typeof raw === 'string' && raw.trim() !== ''\n\t\t\t\t\t? sprintf(\n\t\t\t\t\t\t\t// translators: %1$s: action label (\"Marked as resolved\" or \"Reopened\"); %2$s: note text.\n\t\t\t\t\t\t\t__( '%1$s: %2$s' ),\n\t\t\t\t\t\t\tactionText,\n\t\t\t\t\t\t\traw\n\t\t\t\t\t )\n\t\t\t\t\t: actionText;\n\t\t} else {\n\t\t\tcontent = note?.content?.rendered;\n\t\t}\n\n\t\tbody = (\n\t\t\t<div\n\t\t\t\tref={ commentRef }\n\t\t\t\tclassName={ clsx( 'editor-collab-sidebar-panel__note-content', {\n\t\t\t\t\t'editor-collab-sidebar-panel__resolution-text':\n\t\t\t\t\t\tisResolutionNote,\n\t\t\t\t\t'is-collapsed': ! isExpanded,\n\t\t\t\t} ) }\n\t\t\t\tdangerouslySetInnerHTML={ { __html: content ?? '' } }\n\t\t\t/>\n\t\t);\n\t}\n\n\tconst actions = isSelected ? (\n\t\t<>\n\t\t\t{ canResolve && onResolve && (\n\t\t\t\t<Button\n\t\t\t\t\tlabel={ _x( 'Resolve', 'Mark note as resolved' ) }\n\t\t\t\t\tsize=\"small\"\n\t\t\t\t\ticon={ published }\n\t\t\t\t\tdisabled={ note.status === 'approved' }\n\t\t\t\t\taccessibleWhenDisabled={ note.status === 'approved' }\n\t\t\t\t\tonClick={ onResolve }\n\t\t\t\t/>\n\t\t\t) }\n\t\t\t<NoteActionsMenu\n\t\t\t\titems={ availableItems }\n\t\t\t\tbuttonRef={ actionButtonRef }\n\t\t\t/>\n\t\t</>\n\t) : null;\n\n\treturn (\n\t\t<NoteCard\n\t\t\tnote={ note }\n\t\t\tactions={ actions }\n\t\t\trole={ note.parent !== 0 ? 'treeitem' : undefined }\n\t\t>\n\t\t\t{ body }\n\t\t\t{ actionState === 'delete' && (\n\t\t\t\t<ConfirmDialog\n\t\t\t\t\tisOpen\n\t\t\t\t\tonConfirm={ () => {\n\t\t\t\t\t\tonDeleteNote( note );\n\t\t\t\t\t\tsetActionState( null );\n\t\t\t\t\t} }\n\t\t\t\t\tonCancel={ handleCancel }\n\t\t\t\t\tconfirmButtonText={ __( 'Delete' ) }\n\t\t\t\t>\n\t\t\t\t\t{ deleteConfirmMessage }\n\t\t\t\t</ConfirmDialog>\n\t\t\t) }\n\t\t\t{ isOverflowing && 'edit' !== actionState && (\n\t\t\t\t<UIButton\n\t\t\t\t\tclassName=\"editor-collab-sidebar-panel__show-more-button\"\n\t\t\t\t\tvariant=\"unstyled\"\n\t\t\t\t\tsize=\"small\"\n\t\t\t\t\tonClick={ () => setIsExpanded( ! isExpanded ) }\n\t\t\t\t>\n\t\t\t\t\t{ ! isExpanded ? __( 'Show more' ) : __( 'Show less' ) }\n\t\t\t\t</UIButton>\n\t\t\t) }\n\t\t</NoteCard>\n\t);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["componentsPrivateApis", "clsx", "ConfirmDialog", "UIButton"]
|
|
7
7
|
}
|
|
@@ -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, 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
|
|
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 — 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
5
|
"mappings": "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",
|
|
6
6
|
"names": ["blockEditorPrivateApis", "editorStore", "blockEditorStore"]
|
|
7
7
|
}
|
|
@@ -75,7 +75,7 @@ function getNoteExcerpt(text, excerptLength = 10) {
|
|
|
75
75
|
trimmedExcerpt = rawText.split("", excerptLength).join("");
|
|
76
76
|
}
|
|
77
77
|
const isTrimmed = trimmedExcerpt !== rawText;
|
|
78
|
-
return isTrimmed ? trimmedExcerpt + "
|
|
78
|
+
return isTrimmed ? trimmedExcerpt + "…" : trimmedExcerpt;
|
|
79
79
|
}
|
|
80
80
|
function getNoteIdsFromMetadata(metadata) {
|
|
81
81
|
const noteId = metadata?.noteId;
|
|
@@ -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'#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": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kBAAmB;AAQZ,SAAS,oBAAqB,KAAM;AAC1C,SAAO,IAAI,KAAK;AACjB;AAEA,IAAM,sBAAsB;AAC5B,IAAM,aAAa;AACnB,IAAM,iBAAiB;AAMvB,IAAM,uBAAuB;AAAA,EAC5B;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACD;AAQO,SAAS,qBAAsB,QAAS;AAC9C,SAAO,qBAAsB,SAAS,qBAAqB,MAAO;AACnE;AASO,SAAS,eAAgB,MAAM,gBAAgB,IAAK;AAC1D,MAAK,CAAE,MAAO;AACb,WAAO;AAAA,EACR;AAOA,QAAM,oBAAgB,gBAAI,SAAS,oCAAqC;AAExE,QAAM,UAAU,KAAK,KAAK;AAC1B,MAAI,iBAAiB;AAErB,MAAK,kBAAkB,SAAU;AAChC,qBAAiB,QAAQ,MAAO,KAAK,aAAc,EAAE,KAAM,GAAI;AAAA,EAChE,WAAY,kBAAkB,+BAAgC;AAS7D,UAAM,iBAAiB,QAAQ,MAAO,IAAI,aAAc,EAAE,KAAM,EAAG;AAEnE,UAAM,iBACL,eAAe,SAAS,eAAe,WAAY,KAAK,EAAG,EAAE;AAE9D,qBAAiB,QACf,MAAO,IAAI,gBAAgB,cAAe,EAC1C,KAAM,EAAG;AAAA,EACZ,WAAY,kBAAkB,+BAAgC;AAC7D,qBAAiB,QAAQ,MAAO,IAAI,aAAc,EAAE,KAAM,EAAG;AAAA,EAC9D;AAEA,QAAM,YAAY,mBAAmB;AACrC,SAAO,YAAY,iBAAiB,
|
|
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 + '…' : 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
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/collaborators-overlay/avatar-iframe-styles.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Compiled CSS for the Avatar component, for injection into the editor canvas\n * iframe where the editor package's SCSS is not available.\n *\n * Source: ../collaborators-presence/avatar/styles.scss\n *\n * Dimmed and status-indicator styles are intentionally omitted
|
|
4
|
+
"sourcesContent": ["/**\n * Compiled CSS for the Avatar component, for injection into the editor canvas\n * iframe where the editor package's SCSS is not available.\n *\n * Source: ../collaborators-presence/avatar/styles.scss\n *\n * Dimmed and status-indicator styles are intentionally omitted — they are not\n * used in the overlay. Keep in sync when editing the SCSS source.\n */\n\nimport {\n\tBUTTON_SIZE_COMPACT,\n\tBUTTON_SIZE_SMALL,\n\tELEVATION_X_SMALL,\n\tFONT_LINE_HEIGHT_SMALL,\n\tFONT_SIZE_MEDIUM,\n\tFONT_SIZE_X_SMALL,\n\tFONT_WEIGHT_MEDIUM,\n\tGRID_UNIT_05,\n\tGRID_UNIT_10,\n\tRADIUS_FULL,\n\tWHITE,\n} from './collaborator-styles';\n\nexport const AVATAR_IFRAME_STYLES = `\n.editor-avatar {\n\tposition: relative;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tborder-radius: ${ RADIUS_FULL };\n\tflex-shrink: 0;\n\tbox-shadow: 0 0 0 var(--wp-admin-border-width-focus, 2px) ${ WHITE }, ${ ELEVATION_X_SMALL };\n}\n.editor-avatar__image {\n\tbox-sizing: border-box;\n\tposition: relative;\n\twidth: ${ BUTTON_SIZE_COMPACT };\n\theight: ${ BUTTON_SIZE_COMPACT };\n\tborder-radius: ${ RADIUS_FULL };\n\tborder: 0;\n\tbackground-color: var(--wp-admin-theme-color, #3858e9);\n\toverflow: hidden;\n\toverflow: clip;\n\tflex-shrink: 0;\n\tfont-size: 0;\n\tcolor: ${ WHITE };\n}\n.is-small > .editor-avatar__image {\n\twidth: ${ BUTTON_SIZE_SMALL };\n\theight: ${ BUTTON_SIZE_SMALL };\n}\n.has-avatar-border-color > .editor-avatar__image {\n\tborder: var(--wp-admin-border-width-focus, 2px) solid var(--editor-avatar-outline-color);\n\tbackground-clip: padding-box;\n}\n.has-avatar-border-color > .editor-avatar__image::after {\n\tcontent: \"\";\n\tposition: absolute;\n\tinset: 0;\n\tborder-radius: inherit;\n\tbox-shadow: inset 0 0 0 var(--wp-admin-border-width-focus, 2px) ${ WHITE };\n\tpointer-events: none;\n\tz-index: 1;\n}\n.editor-avatar__img {\n\tposition: absolute;\n\tinset: 0;\n\twidth: 100%;\n\theight: 100%;\n\tobject-fit: cover;\n\tborder-radius: inherit;\n\topacity: 0;\n}\n.has-src > .editor-avatar__image > .editor-avatar__img {\n\topacity: 1;\n}\n.editor-avatar:not(.has-src) > .editor-avatar__image {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tfont-size: ${ FONT_SIZE_X_SMALL };\n\tfont-weight: ${ FONT_WEIGHT_MEDIUM };\n\tborder: 0;\n\tbackground-clip: border-box;\n}\n.editor-avatar:not(.has-src) > .editor-avatar__image::after {\n\tcontent: none;\n}\n.editor-avatar:not(.has-src).has-avatar-border-color > .editor-avatar__image {\n\tbackground-color: var(--editor-avatar-outline-color);\n}\n.editor-avatar__name {\n\tfont-size: ${ FONT_SIZE_MEDIUM };\n\tfont-weight: ${ FONT_WEIGHT_MEDIUM };\n\tline-height: ${ FONT_LINE_HEIGHT_SMALL };\n\tcolor: var(--editor-avatar-name-color, ${ WHITE });\n\tmin-width: 0;\n\tpadding-bottom: 2px; /* $grid-unit-05 / 2 */\n\toverflow: hidden;\n\topacity: 0;\n\twhite-space: nowrap;\n\ttransition: opacity 0.15s cubic-bezier(0.15, 0, 0.15, 1);\n}\n.editor-avatar.is-badge {\n\tdisplay: inline-grid;\n\tgrid-template-columns: min-content 0fr;\n\tcolumn-gap: 0;\n\tpadding-inline-end: 0;\n\tbackground-color: var(--wp-admin-theme-color, #3858e9);\n\ttransition:\n\t\tgrid-template-columns 0.3s cubic-bezier(0.15, 0, 0.15, 1),\n\t\tcolumn-gap 0.3s cubic-bezier(0.15, 0, 0.15, 1),\n\t\tpadding-inline-end 0.3s cubic-bezier(0.15, 0, 0.15, 1);\n}\n.editor-avatar.is-badge:hover {\n\tgrid-template-columns: min-content 1fr;\n\tcolumn-gap: ${ GRID_UNIT_05 };\n\tpadding-inline-end: ${ GRID_UNIT_10 };\n\ttransition-timing-function: cubic-bezier(0.85, 0, 0.85, 1);\n}\n.editor-avatar.is-badge:hover .editor-avatar__name {\n\topacity: 1;\n\ttransition-timing-function: cubic-bezier(0.85, 0, 0.85, 1);\n}\n.editor-avatar.is-badge.has-avatar-border-color {\n\tbackground-color: var(--editor-avatar-outline-color);\n}\n@media (prefers-reduced-motion: reduce) {\n\t.editor-avatar.is-badge,\n\t.editor-avatar__name {\n\t\ttransition: none;\n\t}\n}\n`;\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,iCAYO;AAEA,IAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA,kBAKjB,sCAAY;AAAA;AAAA,6DAE+B,gCAAM,KAAM,4CAAkB;AAAA;AAAA;AAAA;AAAA;AAAA,UAKjF,8CAAoB;AAAA,WACnB,8CAAoB;AAAA,kBACb,sCAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAOpB,gCAAM;AAAA;AAAA;AAAA,UAGN,4CAAkB;AAAA,WACjB,4CAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mEAWsC,gCAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAoB3D,4CAAkB;AAAA,gBAChB,6CAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAWrB,2CAAiB;AAAA,gBACf,6CAAmB;AAAA,gBACnB,iDAAuB;AAAA,0CACG,gCAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAqBjC,uCAAa;AAAA,uBACL,uCAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/collaborators-overlay/collaborator-styles.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Compiled values of `@wordpress/base-styles` design tokens, for use in\n * CSS strings injected into the editor canvas iframe where Sass is not\n * available.\n *\n * Keep in sync with `@wordpress/base-styles`.\n */\n\n// _variables.scss
|
|
4
|
+
"sourcesContent": ["/**\n * Compiled values of `@wordpress/base-styles` design tokens, for use in\n * CSS strings injected into the editor canvas iframe where Sass is not\n * available.\n *\n * Keep in sync with `@wordpress/base-styles`.\n */\n\n// _variables.scss — $elevation-x-small\nexport const ELEVATION_X_SMALL =\n\t'0 1px 1px rgba(0, 0, 0, 0.03), 0 1px 2px rgba(0, 0, 0, 0.02), 0 3px 3px rgba(0, 0, 0, 0.02), 0 4px 4px rgba(0, 0, 0, 0.01)';\n\n// _variables.scss — $radius-full\nexport const RADIUS_FULL = '9999px';\n\n// _variables.scss — $button-size-compact\nexport const BUTTON_SIZE_COMPACT = '32px';\n\n// _variables.scss — $button-size-small\nexport const BUTTON_SIZE_SMALL = '24px';\n\n// _variables.scss — $grid-unit-05\nexport const GRID_UNIT_05 = '4px';\n\n// _variables.scss — $grid-unit-10\nexport const GRID_UNIT_10 = '8px';\n\n// _variables.scss — $border-width\nexport const BORDER_WIDTH = '1px';\n\n// _variables.scss — $border-width-focus-fallback\nexport const BORDER_WIDTH_FOCUS_FALLBACK = '2px';\n\n// _colors.scss — $white\nexport const WHITE = '#fff';\n\n// _font.scss — $font-size-x-small\nexport const FONT_SIZE_X_SMALL = '11px';\n\n// _font.scss — $font-size-medium\nexport const FONT_SIZE_MEDIUM = '13px';\n\n// _font.scss — $font-weight-medium\nexport const FONT_WEIGHT_MEDIUM = '499';\n\n// _font.scss — $font-line-height-small\nexport const FONT_LINE_HEIGHT_SMALL = '20px';\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASO,IAAM,oBACZ;AAGM,IAAM,cAAc;AAGpB,IAAM,sBAAsB;AAG5B,IAAM,oBAAoB;AAG1B,IAAM,eAAe;AAGrB,IAAM,eAAe;AAGrB,IAAM,eAAe;AAGrB,IAAM,8BAA8B;AAGpC,IAAM,QAAQ;AAGd,IAAM,oBAAoB;AAG1B,IAAM,mBAAmB;AAGzB,IAAM,qBAAqB;AAG3B,IAAM,yBAAyB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/collaborators-overlay/compute-selection.ts"],
|
|
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"],
|
|
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 — 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
5
|
"mappings": "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",
|
|
6
6
|
"names": ["coreDataPrivateApis"]
|
|
7
7
|
}
|
|
@@ -51,7 +51,7 @@ var OVERLAY_IFRAME_STYLES = `
|
|
|
51
51
|
}
|
|
52
52
|
/* Cursor lines render below avatar labels across all users. The parent
|
|
53
53
|
.collaborators-overlay-user has no z-index so it does not create a
|
|
54
|
-
stacking context
|
|
54
|
+
stacking context — children participate in the shared overlay context. */
|
|
55
55
|
.collaborators-overlay-user-cursor {
|
|
56
56
|
position: absolute;
|
|
57
57
|
z-index: 0;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/collaborators-overlay/overlay-iframe-styles.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * CSS for the collaborators overlay
|
|
4
|
+
"sourcesContent": ["/**\n * CSS for the collaborators overlay — cursor indicators, block highlights,\n * and positioning of Avatar labels inside the editor canvas iframe.\n */\n\nimport {\n\tBORDER_WIDTH,\n\tBORDER_WIDTH_FOCUS_FALLBACK,\n\tELEVATION_X_SMALL,\n\tGRID_UNIT_05,\n\tGRID_UNIT_10,\n\tWHITE,\n} from './collaborator-styles';\n\nexport const OVERLAY_IFRAME_STYLES = `\n.block-canvas-cover {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n\tpointer-events: none;\n\tz-index: 20000;\n}\n.block-canvas-cover .collaborators-overlay-full {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n}\n.block-canvas-cover .collaborators-overlay-fixed {\n\tposition: fixed;\n\twidth: 100%;\n\theight: 100%;\n}\n.collaborators-overlay-user {\n\tposition: absolute;\n}\n/* Cursor lines render below avatar labels across all users. The parent\n .collaborators-overlay-user has no z-index so it does not create a\n stacking context — children participate in the shared overlay context. */\n.collaborators-overlay-user-cursor {\n\tposition: absolute;\n\tz-index: 0;\n\twidth: ${ BORDER_WIDTH_FOCUS_FALLBACK };\n\tborder-radius: ${ BORDER_WIDTH };\n\toutline: ${ BORDER_WIDTH } solid ${ WHITE };\n\tbox-shadow: ${ ELEVATION_X_SMALL };\n\tanimation: collaborators-overlay-cursor-blink 1s infinite;\n}\n.collaborators-overlay-selection-rect {\n\tposition: absolute;\n\topacity: 0.15;\n\tpointer-events: none;\n\tborder-radius: 2px;\n}\n\n/* Overlay-specific positioning applied to the Avatar cursor label. */\n.collaborators-overlay-user-label.editor-avatar {\n\tposition: absolute;\n\tz-index: 1;\n\ttransform: translate(-11px, -100%);\n\tmargin-top: -${ GRID_UNIT_05 };\n\tpointer-events: auto;\n\toverflow: visible;\n\twidth: max-content;\n}\n/* Avatar positioned above a highlighted block as a label. */\n.collaborators-overlay-block-label.editor-avatar {\n\tposition: absolute;\n\tz-index: 1;\n\ttransform: translateY(calc(-100% - ${ GRID_UNIT_10 }));\n\tpointer-events: auto;\n\toverflow: visible;\n\twidth: max-content;\n}\n\n@keyframes collaborators-overlay-cursor-blink {\n\t0%, 45% { opacity: 1; }\n\t55%, 95% { opacity: 0; }\n\t100% { opacity: 1; }\n}\n.collaborators-overlay-cursor-highlighted .collaborators-overlay-user-cursor {\n\tanimation: collaborators-overlay-cursor-highlight 0.6s ease-in-out 3;\n}\n.collaborators-overlay-cursor-highlighted .collaborators-overlay-user-label {\n\tanimation: collaborators-overlay-label-highlight 0.6s ease-in-out 3;\n}\n@keyframes collaborators-overlay-cursor-highlight {\n\t0%, 100% {\n\t\ttransform: scale(1);\n\t\tfilter: drop-shadow(0 0 0 transparent);\n\t}\n\t50% {\n\t\ttransform: scale(1.2);\n\t\tfilter: drop-shadow(0 0 8px currentColor);\n\t}\n}\n@keyframes collaborators-overlay-label-highlight {\n\t0%, 100% {\n\t\ttransform: translate(-11px, -100%) scale(1);\n\t\tfilter: drop-shadow(0 0 0 transparent);\n\t}\n\t50% {\n\t\ttransform: translate(-11px, -100%) scale(1.1);\n\t\tfilter: drop-shadow(0 0 6px currentColor);\n\t}\n}\n.block-editor-block-list__block.is-collaborator-selected:not(:focus)::after {\n\tcontent: \"\";\n\tposition: absolute;\n\tpointer-events: none;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\toutline-color: var(--collaborator-outline-color);\n\toutline-style: solid;\n\toutline-width: calc(var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1));\n\toutline-offset: calc(-1 * var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1));\n\tbox-shadow: inset 0 0 0 calc((var(--wp-admin-border-width-focus) / var(--wp-block-editor-iframe-zoom-out-scale, 1)) + 0.5px) rgba(${ WHITE }, 0.7);\n\tz-index: 1;\n}\n@media (prefers-reduced-motion: reduce) {\n\t.collaborators-overlay-user-label,\n\t.collaborators-overlay-user-cursor {\n\t\tanimation: none;\n\t}\n}\n`;\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,iCAOO;AAEA,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UA+B1B,sDAA4B;AAAA,kBACpB,uCAAa;AAAA,YACnB,uCAAa,UAAW,gCAAM;AAAA,eAC3B,4CAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAejB,uCAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCASS,uCAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qIAiDkF,gCAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|