@wordpress/editor 14.49.1 → 14.51.1-next.v.202607070741.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/build/components/collab-sidebar/format.cjs +83 -0
- package/build/components/collab-sidebar/format.cjs.map +7 -0
- package/build/components/collab-sidebar/hooks.cjs +117 -16
- package/build/components/collab-sidebar/hooks.cjs.map +2 -2
- package/build/components/collab-sidebar/index.cjs +18 -2
- package/build/components/collab-sidebar/index.cjs.map +2 -2
- package/build/components/collab-sidebar/note-highlight-styles.cjs +67 -0
- package/build/components/collab-sidebar/note-highlight-styles.cjs.map +7 -0
- package/build/components/collab-sidebar/utils.cjs +139 -0
- package/build/components/collab-sidebar/utils.cjs.map +2 -2
- package/build/components/collaborators-presence/use-collaborator-notifications.cjs +55 -30
- package/build/components/collaborators-presence/use-collaborator-notifications.cjs.map +2 -2
- package/build/components/commands/index.cjs +99 -3
- package/build/components/commands/index.cjs.map +2 -2
- package/build/components/document-bar/index.cjs +28 -34
- package/build/components/document-bar/index.cjs.map +2 -2
- package/build/components/entities-saved-states/index.cjs +1 -4
- package/build/components/entities-saved-states/index.cjs.map +2 -2
- package/build/components/header/index.cjs +1 -8
- package/build/components/header/index.cjs.map +2 -2
- package/build/components/media-categories/index.cjs +92 -6
- package/build/components/media-categories/index.cjs.map +2 -2
- package/build/components/page-attributes/parent.cjs +0 -1
- package/build/components/page-attributes/parent.cjs.map +2 -2
- package/build/components/post-author/combobox.cjs +0 -1
- package/build/components/post-author/combobox.cjs.map +2 -2
- package/build/components/post-author/select.cjs +0 -1
- package/build/components/post-author/select.cjs.map +2 -2
- package/build/components/post-preview-button/index.cjs +29 -2
- package/build/components/post-preview-button/index.cjs.map +2 -2
- package/build/components/post-publish-panel/maybe-upload-media.cjs +15 -26
- package/build/components/post-publish-panel/maybe-upload-media.cjs.map +3 -3
- package/build/components/post-revisions-preview/revisions-slider.cjs +3 -1
- package/build/components/post-revisions-preview/revisions-slider.cjs.map +2 -2
- package/build/components/post-taxonomies/flat-term-selector.cjs +0 -1
- package/build/components/post-taxonomies/flat-term-selector.cjs.map +2 -2
- package/build/components/post-taxonomies/hierarchical-term-selector.cjs +0 -2
- package/build/components/post-taxonomies/hierarchical-term-selector.cjs.map +2 -2
- package/build/components/post-template/classic-theme.cjs +0 -1
- package/build/components/post-template/classic-theme.cjs.map +2 -2
- package/build/components/preferences-modal/index.cjs +54 -28
- package/build/components/preferences-modal/index.cjs.map +2 -2
- package/build/components/preview-dropdown/index.cjs +38 -9
- package/build/components/preview-dropdown/index.cjs.map +3 -3
- package/build/components/provider/use-block-editor-settings.cjs +23 -9
- package/build/components/provider/use-block-editor-settings.cjs.map +3 -3
- package/build/components/resizable-editor/index.cjs +54 -9
- package/build/components/resizable-editor/index.cjs.map +3 -3
- package/build/components/sidebar/dataform-post-summary.cjs +5 -1
- package/build/components/sidebar/dataform-post-summary.cjs.map +3 -3
- package/build/components/sidebar/index.cjs +29 -38
- package/build/components/sidebar/index.cjs.map +3 -3
- package/build/components/sidebar/post-summary.cjs +0 -13
- package/build/components/sidebar/post-summary.cjs.map +3 -3
- package/build/components/visual-editor/index.cjs +15 -11
- package/build/components/visual-editor/index.cjs.map +3 -3
- package/build/dataviews/store/private-actions.cjs +24 -19
- package/build/dataviews/store/private-actions.cjs.map +2 -2
- package/build/store/actions.cjs +5 -3
- package/build/store/actions.cjs.map +2 -2
- package/build/store/constants.cjs +26 -0
- package/build/store/constants.cjs.map +2 -2
- package/build/store/private-actions.cjs +25 -18
- package/build/store/private-actions.cjs.map +3 -3
- package/build/store/private-selectors.cjs +5 -0
- package/build/store/private-selectors.cjs.map +2 -2
- package/build/store/reducer.cjs +6 -6
- package/build/store/reducer.cjs.map +2 -2
- package/build/store/selectors.cjs +3 -1
- package/build/store/selectors.cjs.map +2 -2
- package/build/utils/device-type.cjs +52 -0
- package/build/utils/device-type.cjs.map +7 -0
- package/build/utils/media-sideload-from-url/index.cjs +63 -0
- package/build/utils/media-sideload-from-url/index.cjs.map +7 -0
- package/build-module/components/collab-sidebar/format.mjs +57 -0
- package/build-module/components/collab-sidebar/format.mjs.map +7 -0
- package/build-module/components/collab-sidebar/hooks.mjs +121 -16
- package/build-module/components/collab-sidebar/hooks.mjs.map +2 -2
- package/build-module/components/collab-sidebar/index.mjs +21 -5
- package/build-module/components/collab-sidebar/index.mjs.map +2 -2
- package/build-module/components/collab-sidebar/note-highlight-styles.mjs +41 -0
- package/build-module/components/collab-sidebar/note-highlight-styles.mjs.map +7 -0
- package/build-module/components/collab-sidebar/utils.mjs +133 -0
- package/build-module/components/collab-sidebar/utils.mjs.map +2 -2
- package/build-module/components/collaborators-presence/use-collaborator-notifications.mjs +55 -30
- package/build-module/components/collaborators-presence/use-collaborator-notifications.mjs.map +2 -2
- package/build-module/components/commands/index.mjs +99 -3
- package/build-module/components/commands/index.mjs.map +2 -2
- package/build-module/components/document-bar/index.mjs +28 -34
- package/build-module/components/document-bar/index.mjs.map +2 -2
- package/build-module/components/entities-saved-states/index.mjs +1 -4
- package/build-module/components/entities-saved-states/index.mjs.map +2 -2
- package/build-module/components/header/index.mjs +1 -13
- package/build-module/components/header/index.mjs.map +2 -2
- package/build-module/components/media-categories/index.mjs +93 -7
- package/build-module/components/media-categories/index.mjs.map +2 -2
- package/build-module/components/page-attributes/parent.mjs +0 -1
- package/build-module/components/page-attributes/parent.mjs.map +2 -2
- package/build-module/components/post-author/combobox.mjs +0 -1
- package/build-module/components/post-author/combobox.mjs.map +2 -2
- package/build-module/components/post-author/select.mjs +0 -1
- package/build-module/components/post-author/select.mjs.map +2 -2
- package/build-module/components/post-preview-button/index.mjs +29 -2
- package/build-module/components/post-preview-button/index.mjs.map +2 -2
- package/build-module/components/post-publish-panel/maybe-upload-media.mjs +19 -27
- package/build-module/components/post-publish-panel/maybe-upload-media.mjs.map +2 -2
- package/build-module/components/post-revisions-preview/revisions-slider.mjs +3 -1
- package/build-module/components/post-revisions-preview/revisions-slider.mjs.map +2 -2
- package/build-module/components/post-taxonomies/flat-term-selector.mjs +0 -1
- package/build-module/components/post-taxonomies/flat-term-selector.mjs.map +2 -2
- package/build-module/components/post-taxonomies/hierarchical-term-selector.mjs +0 -2
- package/build-module/components/post-taxonomies/hierarchical-term-selector.mjs.map +2 -2
- package/build-module/components/post-template/classic-theme.mjs +0 -1
- package/build-module/components/post-template/classic-theme.mjs.map +2 -2
- package/build-module/components/preferences-modal/index.mjs +54 -28
- package/build-module/components/preferences-modal/index.mjs.map +2 -2
- package/build-module/components/preview-dropdown/index.mjs +38 -9
- package/build-module/components/preview-dropdown/index.mjs.map +2 -2
- package/build-module/components/provider/use-block-editor-settings.mjs +23 -9
- package/build-module/components/provider/use-block-editor-settings.mjs.map +2 -2
- package/build-module/components/resizable-editor/index.mjs +55 -10
- package/build-module/components/resizable-editor/index.mjs.map +2 -2
- package/build-module/components/sidebar/dataform-post-summary.mjs +6 -2
- package/build-module/components/sidebar/dataform-post-summary.mjs.map +2 -2
- package/build-module/components/sidebar/index.mjs +29 -42
- package/build-module/components/sidebar/index.mjs.map +2 -2
- package/build-module/components/sidebar/post-summary.mjs +0 -13
- package/build-module/components/sidebar/post-summary.mjs.map +2 -2
- package/build-module/components/visual-editor/index.mjs +16 -13
- package/build-module/components/visual-editor/index.mjs.map +2 -2
- package/build-module/dataviews/store/private-actions.mjs +26 -19
- package/build-module/dataviews/store/private-actions.mjs.map +2 -2
- package/build-module/store/actions.mjs +5 -3
- package/build-module/store/actions.mjs.map +2 -2
- package/build-module/store/constants.mjs +25 -0
- package/build-module/store/constants.mjs.map +2 -2
- package/build-module/store/private-actions.mjs +27 -17
- package/build-module/store/private-actions.mjs.map +2 -2
- package/build-module/store/private-selectors.mjs +4 -0
- package/build-module/store/private-selectors.mjs.map +2 -2
- package/build-module/store/reducer.mjs +5 -5
- package/build-module/store/reducer.mjs.map +2 -2
- package/build-module/store/selectors.mjs +3 -1
- package/build-module/store/selectors.mjs.map +2 -2
- package/build-module/utils/device-type.mjs +25 -0
- package/build-module/utils/device-type.mjs.map +7 -0
- package/build-module/utils/media-sideload-from-url/index.mjs +32 -0
- package/build-module/utils/media-sideload-from-url/index.mjs.map +7 -0
- package/build-style/style-rtl.css +84 -39
- package/build-style/style.css +84 -39
- package/build-types/components/collab-sidebar/format.d.ts +17 -0
- package/build-types/components/collab-sidebar/format.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/hooks.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/index.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/note-highlight-styles.d.ts +31 -0
- package/build-types/components/collab-sidebar/note-highlight-styles.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/utils.d.ts +82 -2
- package/build-types/components/collab-sidebar/utils.d.ts.map +1 -1
- package/build-types/components/collaborators-presence/use-collaborator-notifications.d.ts.map +1 -1
- package/build-types/components/commands/index.d.ts.map +1 -1
- package/build-types/components/document-bar/index.d.ts.map +1 -1
- package/build-types/components/entities-saved-states/index.d.ts.map +1 -1
- package/build-types/components/header/index.d.ts.map +1 -1
- package/build-types/components/media-categories/index.d.ts +12 -3
- package/build-types/components/media-categories/index.d.ts.map +1 -1
- package/build-types/components/page-attributes/parent.d.ts.map +1 -1
- package/build-types/components/post-author/combobox.d.ts.map +1 -1
- package/build-types/components/post-author/select.d.ts.map +1 -1
- package/build-types/components/post-preview-button/index.d.ts.map +1 -1
- package/build-types/components/post-publish-panel/maybe-upload-media.d.ts.map +1 -1
- package/build-types/components/post-revisions-preview/revisions-slider.d.ts.map +1 -1
- package/build-types/components/post-taxonomies/flat-term-selector.d.ts.map +1 -1
- package/build-types/components/post-taxonomies/hierarchical-term-selector.d.ts.map +1 -1
- package/build-types/components/post-template/classic-theme.d.ts.map +1 -1
- package/build-types/components/preview-dropdown/index.d.ts.map +1 -1
- package/build-types/components/provider/use-block-editor-settings.d.ts.map +1 -1
- package/build-types/components/resizable-editor/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-summary.d.ts.map +1 -1
- package/build-types/components/visual-editor/index.d.ts.map +1 -1
- package/build-types/dataviews/store/private-actions.d.ts.map +1 -1
- package/build-types/store/actions.d.ts.map +1 -1
- package/build-types/store/constants.d.ts +6 -0
- package/build-types/store/constants.d.ts.map +1 -1
- package/build-types/store/index.d.ts +2 -2
- package/build-types/store/private-actions.d.ts +9 -15
- package/build-types/store/private-actions.d.ts.map +1 -1
- package/build-types/store/private-selectors.d.ts +7 -0
- package/build-types/store/private-selectors.d.ts.map +1 -1
- package/build-types/store/reducer.d.ts +6 -7
- package/build-types/store/reducer.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/build-types/utils/device-type.d.ts +23 -0
- package/build-types/utils/device-type.d.ts.map +1 -0
- package/build-types/utils/get-template-part-icon.d.ts.map +1 -1
- package/build-types/utils/media-sideload-from-url/index.d.ts +18 -0
- package/build-types/utils/media-sideload-from-url/index.d.ts.map +1 -0
- package/package.json +48 -46
- package/src/components/collab-sidebar/format.js +72 -0
- package/src/components/collab-sidebar/hooks.js +203 -22
- package/src/components/collab-sidebar/index.js +19 -5
- package/src/components/collab-sidebar/note-highlight-styles.js +83 -0
- package/src/components/collab-sidebar/style.scss +9 -0
- package/src/components/collab-sidebar/test/note-highlight-styles.js +106 -0
- package/src/components/collab-sidebar/test/utils.js +471 -0
- package/src/components/collab-sidebar/utils.js +225 -2
- package/src/components/collaborators-presence/test/use-collaborator-notifications.ts +265 -262
- package/src/components/collaborators-presence/use-collaborator-notifications.ts +70 -34
- package/src/components/commands/index.js +142 -0
- package/src/components/document-bar/index.js +0 -9
- package/src/components/document-bar/style.scss +0 -17
- package/src/components/entities-saved-states/index.js +1 -5
- package/src/components/header/index.js +1 -15
- package/src/components/header/style.scss +7 -3
- package/src/components/media-categories/index.js +160 -6
- package/src/components/media-categories/test/index.js +202 -0
- package/src/components/page-attributes/parent.js +0 -1
- package/src/components/post-author/combobox.js +0 -1
- package/src/components/post-author/select.js +0 -1
- package/src/components/post-preview-button/index.js +68 -2
- package/src/components/post-publish-panel/maybe-upload-media.js +25 -30
- package/src/components/post-publish-panel/style.scss +1 -1
- package/src/components/post-publish-panel/test/__snapshots__/index.js.snap +11 -127
- package/src/components/post-revisions-preview/revisions-slider.js +4 -1
- package/src/components/post-revisions-preview/test/block-diff.js +2 -2
- package/src/components/post-taxonomies/flat-term-selector.js +0 -1
- package/src/components/post-taxonomies/hierarchical-term-selector.js +0 -2
- package/src/components/post-template/classic-theme.js +0 -1
- package/src/components/preferences-modal/index.js +40 -22
- package/src/components/preferences-modal/test/index.js +83 -0
- package/src/components/preview-dropdown/index.js +42 -3
- package/src/components/provider/use-block-editor-settings.js +42 -7
- package/src/components/resizable-editor/index.js +71 -9
- package/src/components/resizable-editor/style.scss +7 -0
- package/src/components/sidebar/dataform-post-summary.js +13 -1
- package/src/components/sidebar/index.js +32 -47
- package/src/components/sidebar/post-summary.js +0 -17
- package/src/components/styles-canvas/style.scss +1 -2
- package/src/components/visual-editor/index.js +19 -15
- package/src/components/visual-editor/style.scss +11 -4
- package/src/dataviews/store/private-actions.ts +30 -26
- package/src/store/actions.js +6 -3
- package/src/store/constants.ts +45 -0
- package/src/store/private-actions.js +38 -28
- package/src/store/private-selectors.js +10 -0
- package/src/store/reducer.js +7 -9
- package/src/store/selectors.js +3 -1
- package/src/store/test/actions.js +31 -22
- package/src/utils/device-type.js +46 -0
- package/src/utils/media-sideload-from-url/index.js +54 -0
- package/src/utils/media-sideload-from-url/test/index.js +162 -0
- package/build/components/post-publish-panel/media-util.cjs +0 -72
- package/build/components/post-publish-panel/media-util.cjs.map +0 -7
- package/build-module/components/post-publish-panel/media-util.mjs +0 -46
- package/build-module/components/post-publish-panel/media-util.mjs.map +0 -7
- package/build-types/components/post-publish-panel/media-util.d.ts +0 -20
- package/build-types/components/post-publish-panel/media-util.d.ts.map +0 -1
- package/src/components/post-publish-panel/media-util.js +0 -87
- package/src/components/post-publish-panel/test/media-util.js +0 -118
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/editor",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.51.1-next.v.202607070741.0+a51d59513",
|
|
4
4
|
"description": "Enhanced block editor for WordPress posts.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -59,50 +59,50 @@
|
|
|
59
59
|
"build-module/bindings/**"
|
|
60
60
|
],
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@wordpress/a11y": "^4.
|
|
63
|
-
"@wordpress/api-fetch": "^7.
|
|
64
|
-
"@wordpress/base-styles": "^10.1.0",
|
|
65
|
-
"@wordpress/blob": "^4.
|
|
66
|
-
"@wordpress/block-editor": "^
|
|
67
|
-
"@wordpress/block-serialization-default-parser": "^5.
|
|
68
|
-
"@wordpress/blocks": "^15.
|
|
69
|
-
"@wordpress/commands": "^1.
|
|
70
|
-
"@wordpress/components": "^
|
|
71
|
-
"@wordpress/compose": "^8.
|
|
72
|
-
"@wordpress/core-data": "^7.
|
|
73
|
-
"@wordpress/data": "^10.
|
|
74
|
-
"@wordpress/dataviews": "^17.0
|
|
75
|
-
"@wordpress/date": "^5.
|
|
76
|
-
"@wordpress/deprecated": "^4.
|
|
77
|
-
"@wordpress/dom": "^4.
|
|
78
|
-
"@wordpress/element": "^8.1.0",
|
|
79
|
-
"@wordpress/fields": "^0.
|
|
80
|
-
"@wordpress/global-styles-engine": "^1.
|
|
81
|
-
"@wordpress/global-styles-ui": "^1.
|
|
82
|
-
"@wordpress/hooks": "^4.
|
|
83
|
-
"@wordpress/html-entities": "^4.
|
|
84
|
-
"@wordpress/i18n": "^6.
|
|
85
|
-
"@wordpress/icons": "^15.
|
|
86
|
-
"@wordpress/interface": "^9.
|
|
87
|
-
"@wordpress/keyboard-shortcuts": "^5.
|
|
88
|
-
"@wordpress/keycodes": "^4.
|
|
89
|
-
"@wordpress/media-editor": "^0.
|
|
90
|
-
"@wordpress/media-fields": "^0.
|
|
91
|
-
"@wordpress/media-utils": "^5.
|
|
92
|
-
"@wordpress/notices": "^5.
|
|
93
|
-
"@wordpress/patterns": "^2.
|
|
94
|
-
"@wordpress/plugins": "^7.
|
|
95
|
-
"@wordpress/preferences": "^4.
|
|
96
|
-
"@wordpress/private-apis": "^1.
|
|
97
|
-
"@wordpress/reusable-blocks": "^5.
|
|
98
|
-
"@wordpress/rich-text": "^7.
|
|
99
|
-
"@wordpress/server-side-render": "^6.
|
|
100
|
-
"@wordpress/ui": "^0.
|
|
101
|
-
"@wordpress/upload-media": "^0.
|
|
102
|
-
"@wordpress/url": "^4.
|
|
103
|
-
"@wordpress/views": "^1.
|
|
104
|
-
"@wordpress/warning": "^3.
|
|
105
|
-
"@wordpress/wordcount": "^4.
|
|
62
|
+
"@wordpress/a11y": "^4.50.1-next.v.202607070741.0+a51d59513",
|
|
63
|
+
"@wordpress/api-fetch": "^7.50.1-next.v.202607070741.0+a51d59513",
|
|
64
|
+
"@wordpress/base-styles": "^10.3.1-next.v.202607070741.0+a51d59513",
|
|
65
|
+
"@wordpress/blob": "^4.50.1-next.v.202607070741.0+a51d59513",
|
|
66
|
+
"@wordpress/block-editor": "^16.0.1-next.v.202607070741.0+a51d59513",
|
|
67
|
+
"@wordpress/block-serialization-default-parser": "^5.50.1-next.v.202607070741.0+a51d59513",
|
|
68
|
+
"@wordpress/blocks": "^15.23.1-next.v.202607070741.0+a51d59513",
|
|
69
|
+
"@wordpress/commands": "^1.50.1-next.v.202607070741.0+a51d59513",
|
|
70
|
+
"@wordpress/components": "^37.0.1-next.v.202607070741.0+a51d59513",
|
|
71
|
+
"@wordpress/compose": "^8.3.1-next.v.202607070741.0+a51d59513",
|
|
72
|
+
"@wordpress/core-data": "^7.50.1-next.v.202607070741.0+a51d59513",
|
|
73
|
+
"@wordpress/data": "^10.50.1-next.v.202607070741.0+a51d59513",
|
|
74
|
+
"@wordpress/dataviews": "^17.1.2-next.v.202607070741.0+a51d59513",
|
|
75
|
+
"@wordpress/date": "^5.50.1-next.v.202607070741.0+a51d59513",
|
|
76
|
+
"@wordpress/deprecated": "^4.50.1-next.v.202607070741.0+a51d59513",
|
|
77
|
+
"@wordpress/dom": "^4.50.1-next.v.202607070741.0+a51d59513",
|
|
78
|
+
"@wordpress/element": "^8.2.1-next.v.202607070741.0+a51d59513",
|
|
79
|
+
"@wordpress/fields": "^0.42.1-next.v.202607070741.0+a51d59513",
|
|
80
|
+
"@wordpress/global-styles-engine": "^1.17.1-next.v.202607070741.0+a51d59513",
|
|
81
|
+
"@wordpress/global-styles-ui": "^1.17.1-next.v.202607070741.0+a51d59513",
|
|
82
|
+
"@wordpress/hooks": "^4.50.1-next.v.202607070741.0+a51d59513",
|
|
83
|
+
"@wordpress/html-entities": "^4.50.1-next.v.202607070741.0+a51d59513",
|
|
84
|
+
"@wordpress/i18n": "^6.23.1-next.v.202607070741.0+a51d59513",
|
|
85
|
+
"@wordpress/icons": "^15.1.1-next.v.202607070741.0+a51d59513",
|
|
86
|
+
"@wordpress/interface": "^9.35.1-next.v.202607070741.0+a51d59513",
|
|
87
|
+
"@wordpress/keyboard-shortcuts": "^5.50.1-next.v.202607070741.0+a51d59513",
|
|
88
|
+
"@wordpress/keycodes": "^4.50.1-next.v.202607070741.0+a51d59513",
|
|
89
|
+
"@wordpress/media-editor": "^0.13.1-next.v.202607070741.0+a51d59513",
|
|
90
|
+
"@wordpress/media-fields": "^0.15.1-next.v.202607070741.0+a51d59513",
|
|
91
|
+
"@wordpress/media-utils": "^5.50.1-next.v.202607070741.0+a51d59513",
|
|
92
|
+
"@wordpress/notices": "^5.50.1-next.v.202607070741.0+a51d59513",
|
|
93
|
+
"@wordpress/patterns": "^2.50.1-next.v.202607070741.0+a51d59513",
|
|
94
|
+
"@wordpress/plugins": "^7.50.1-next.v.202607070741.0+a51d59513",
|
|
95
|
+
"@wordpress/preferences": "^4.50.1-next.v.202607070741.0+a51d59513",
|
|
96
|
+
"@wordpress/private-apis": "^1.50.1-next.v.202607070741.0+a51d59513",
|
|
97
|
+
"@wordpress/reusable-blocks": "^5.51.1-next.v.202607070741.0+a51d59513",
|
|
98
|
+
"@wordpress/rich-text": "^7.50.1-next.v.202607070741.0+a51d59513",
|
|
99
|
+
"@wordpress/server-side-render": "^6.26.1-next.v.202607070741.0+a51d59513",
|
|
100
|
+
"@wordpress/ui": "^0.18.1-next.v.202607070741.0+a51d59513",
|
|
101
|
+
"@wordpress/upload-media": "^0.36.1-next.v.202607070741.0+a51d59513",
|
|
102
|
+
"@wordpress/url": "^4.50.1-next.v.202607070741.0+a51d59513",
|
|
103
|
+
"@wordpress/views": "^1.17.1-next.v.202607070741.0+a51d59513",
|
|
104
|
+
"@wordpress/warning": "^3.50.1-next.v.202607070741.0+a51d59513",
|
|
105
|
+
"@wordpress/wordcount": "^4.50.1-next.v.202607070741.0+a51d59513",
|
|
106
106
|
"change-case": "^4.1.2",
|
|
107
107
|
"client-zip": "^2.4.5",
|
|
108
108
|
"clsx": "^2.1.1",
|
|
@@ -117,9 +117,11 @@
|
|
|
117
117
|
"uuid": "^14.0.0"
|
|
118
118
|
},
|
|
119
119
|
"devDependencies": {
|
|
120
|
+
"@storybook/react-vite": "^10.4.3",
|
|
120
121
|
"@testing-library/dom": "^10.4.1",
|
|
121
122
|
"@testing-library/react": "^16.3.2",
|
|
122
123
|
"@testing-library/user-event": "^14.6.1",
|
|
124
|
+
"@wordpress/block-library": "^10.1.1-next.v.202607070741.0+a51d59513",
|
|
123
125
|
"deep-freeze": "^0.0.1"
|
|
124
126
|
},
|
|
125
127
|
"peerDependencies": {
|
|
@@ -135,5 +137,5 @@
|
|
|
135
137
|
"publishConfig": {
|
|
136
138
|
"access": "public"
|
|
137
139
|
},
|
|
138
|
-
"gitHead": "
|
|
140
|
+
"gitHead": "f637726e370c8b23695ed9af82adbe171ad235d8"
|
|
139
141
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
import { RichTextToolbarButton } from '@wordpress/block-editor';
|
|
6
|
+
import { useDispatch, useSelect } from '@wordpress/data';
|
|
7
|
+
import { comment as commentIcon } from '@wordpress/icons';
|
|
8
|
+
import { isCollapsed } from '@wordpress/rich-text';
|
|
9
|
+
import { store as interfaceStore } from '@wordpress/interface';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies
|
|
13
|
+
*/
|
|
14
|
+
import { ALL_NOTES_SIDEBAR, FLOATING_NOTES_SIDEBAR } from './constants';
|
|
15
|
+
import { store as editorStore } from '../../store';
|
|
16
|
+
import { unlock } from '../../lock-unlock';
|
|
17
|
+
|
|
18
|
+
export const NOTE_FORMAT_NAME = 'core/note';
|
|
19
|
+
|
|
20
|
+
export const noteFormat = {
|
|
21
|
+
title: __( 'Add note' ),
|
|
22
|
+
tagName: 'mark',
|
|
23
|
+
className: 'wp-note',
|
|
24
|
+
attributes: {
|
|
25
|
+
'data-id': 'data-id',
|
|
26
|
+
},
|
|
27
|
+
edit: NoteFormatEdit,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function NoteFormatEdit( { value, isActive, activeAttributes } ) {
|
|
31
|
+
const dispatch = useDispatch();
|
|
32
|
+
// Static selector getter: the active area is only read when the button is
|
|
33
|
+
// clicked, so there's no need to subscribe and re-render on its changes.
|
|
34
|
+
const { getActiveComplementaryArea } = useSelect( interfaceStore );
|
|
35
|
+
|
|
36
|
+
// Toolbar button only relevant on an active selection or when standing on
|
|
37
|
+
// an existing inline note marker.
|
|
38
|
+
if ( ! isActive && isCollapsed( value ) ) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const onClick = () => {
|
|
43
|
+
// Bias the floating sidebar when no fixed sidebar is mounted; the
|
|
44
|
+
// floating panel is the default placement and avoids a layout shift.
|
|
45
|
+
const currentArea = getActiveComplementaryArea( 'core' );
|
|
46
|
+
const targetSidebar =
|
|
47
|
+
currentArea === ALL_NOTES_SIDEBAR
|
|
48
|
+
? ALL_NOTES_SIDEBAR
|
|
49
|
+
: FLOATING_NOTES_SIDEBAR;
|
|
50
|
+
if ( currentArea !== targetSidebar ) {
|
|
51
|
+
dispatch( interfaceStore ).enableComplementaryArea(
|
|
52
|
+
'core',
|
|
53
|
+
targetSidebar
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const id = activeAttributes[ 'data-id' ];
|
|
58
|
+
unlock( dispatch( editorStore ) ).selectNote(
|
|
59
|
+
id ? Number( id ) : 'new',
|
|
60
|
+
{ focus: true }
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<RichTextToolbarButton
|
|
66
|
+
icon={ commentIcon }
|
|
67
|
+
title={ __( 'Add note' ) }
|
|
68
|
+
onClick={ onClick }
|
|
69
|
+
isActive={ isActive }
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
@@ -18,6 +18,7 @@ import { store as noticesStore } from '@wordpress/notices';
|
|
|
18
18
|
import { getScrollContainer } from '@wordpress/dom';
|
|
19
19
|
import { decodeEntities } from '@wordpress/html-entities';
|
|
20
20
|
import { store as interfaceStore } from '@wordpress/interface';
|
|
21
|
+
import { RichTextData, create } from '@wordpress/rich-text';
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Internal dependencies
|
|
@@ -26,10 +27,15 @@ import { store as editorStore } from '../../store';
|
|
|
26
27
|
import { FLOATING_NOTES_SIDEBAR } from './constants';
|
|
27
28
|
import { unlock } from '../../lock-unlock';
|
|
28
29
|
import { createBoardStore } from './board-store';
|
|
30
|
+
import { NOTE_FORMAT_NAME } from './format';
|
|
29
31
|
import {
|
|
32
|
+
applyNoteFormat,
|
|
30
33
|
calculateNotePositions,
|
|
34
|
+
findNoteInBlock,
|
|
35
|
+
getInlineMarkerStart,
|
|
31
36
|
getNoteIdsFromMetadata,
|
|
32
37
|
addNoteIdToMetadata,
|
|
38
|
+
removeNoteFormat,
|
|
33
39
|
removeNoteIdFromMetadata,
|
|
34
40
|
} from './utils';
|
|
35
41
|
|
|
@@ -110,16 +116,36 @@ export function useNoteThreads( postId ) {
|
|
|
110
116
|
return { notes: [], unresolvedNotes: [] };
|
|
111
117
|
}
|
|
112
118
|
|
|
113
|
-
//
|
|
114
|
-
//
|
|
119
|
+
// Order within a block: block-level notes (no inline anchor) come
|
|
120
|
+
// first as the "overall comment", then inline notes ascending by
|
|
121
|
+
// marker start offset. Ties (rare; two markers at the same offset)
|
|
122
|
+
// fall back to creation order via thread id. Blocks themselves are
|
|
123
|
+
// already iterated in document order above.
|
|
115
124
|
const unresolved = [];
|
|
116
125
|
const resolved = [];
|
|
117
|
-
for ( const noteIds of Object.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
126
|
+
for ( const [ clientId, noteIds ] of Object.entries(
|
|
127
|
+
blocksWithNotes
|
|
128
|
+
) ) {
|
|
129
|
+
const attributes = getBlockAttributes( clientId );
|
|
130
|
+
const orderedThreads = noteIds
|
|
131
|
+
.map( ( noteId ) => {
|
|
132
|
+
const thread = threadsById.get( noteId );
|
|
133
|
+
if ( ! thread ) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
thread,
|
|
138
|
+
start: getInlineMarkerStart( thread, attributes ),
|
|
139
|
+
};
|
|
140
|
+
} )
|
|
141
|
+
.filter( Boolean )
|
|
142
|
+
.sort( ( a, b ) => {
|
|
143
|
+
if ( a.start !== b.start ) {
|
|
144
|
+
return a.start - b.start;
|
|
145
|
+
}
|
|
146
|
+
return a.thread.id - b.thread.id;
|
|
147
|
+
} );
|
|
148
|
+
for ( const { thread } of orderedThreads ) {
|
|
123
149
|
if ( thread.status === 'hold' ) {
|
|
124
150
|
unresolved.push( thread );
|
|
125
151
|
} else if ( thread.status === 'approved' ) {
|
|
@@ -145,12 +171,115 @@ export function useNoteThreads( postId ) {
|
|
|
145
171
|
};
|
|
146
172
|
}
|
|
147
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Read an inline selection from block-editor selection state, returning
|
|
176
|
+
* normalized anchor data when a non-collapsed selection sits inside a single
|
|
177
|
+
* rich-text attribute. Returns null for block-level or collapsed selections.
|
|
178
|
+
*
|
|
179
|
+
* @param {Function} getSelectionStart Block-editor selector.
|
|
180
|
+
* @param {Function} getSelectionEnd Block-editor selector.
|
|
181
|
+
* @return {?Object} { clientId, attributeKey, start, end } or null.
|
|
182
|
+
*/
|
|
183
|
+
function readInlineSelection( getSelectionStart, getSelectionEnd ) {
|
|
184
|
+
const start = getSelectionStart();
|
|
185
|
+
const end = getSelectionEnd();
|
|
186
|
+
if (
|
|
187
|
+
! start?.clientId ||
|
|
188
|
+
start.clientId !== end.clientId ||
|
|
189
|
+
! start.attributeKey ||
|
|
190
|
+
start.offset === undefined ||
|
|
191
|
+
end.offset === undefined ||
|
|
192
|
+
start.offset === end.offset
|
|
193
|
+
) {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
// Normalize direction so callers don't have to think about reversed ranges.
|
|
197
|
+
const [ startOffset, endOffset ] =
|
|
198
|
+
start.offset < end.offset
|
|
199
|
+
? [ start.offset, end.offset ]
|
|
200
|
+
: [ end.offset, start.offset ];
|
|
201
|
+
return {
|
|
202
|
+
clientId: start.clientId,
|
|
203
|
+
attributeKey: start.attributeKey,
|
|
204
|
+
start: startOffset,
|
|
205
|
+
end: endOffset,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Wrap a rich-text range with a core/note marker. Returns a new
|
|
211
|
+
* RichTextData ready to write back into block attributes, or null when the
|
|
212
|
+
* incoming value isn't a rich-text instance (legacy/string attributes).
|
|
213
|
+
*
|
|
214
|
+
* @param {*} value Existing block attribute value.
|
|
215
|
+
* @param {number} id New note id to embed as `data-id`.
|
|
216
|
+
* @param {number} start Range start offset.
|
|
217
|
+
* @param {number} end Range end offset.
|
|
218
|
+
* @return {?RichTextData} Wrapped value or null when the attribute isn't rich text.
|
|
219
|
+
*/
|
|
220
|
+
function wrapInlineNote( value, id, start, end ) {
|
|
221
|
+
if ( ! ( value instanceof RichTextData ) ) {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
const record = applyNoteFormat(
|
|
225
|
+
create( { html: value.toHTMLString() } ),
|
|
226
|
+
{ type: NOTE_FORMAT_NAME, attributes: { 'data-id': String( id ) } },
|
|
227
|
+
start,
|
|
228
|
+
end
|
|
229
|
+
);
|
|
230
|
+
// Round-trip through HTML to normalise format references (applyNoteFormat
|
|
231
|
+
// leaves them un-normalised) so the stored value matches a fresh reload.
|
|
232
|
+
return RichTextData.fromHTMLString(
|
|
233
|
+
new RichTextData( record ).toHTMLString()
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Strip a note's inline `core/note` marker from whichever block holds it, if
|
|
239
|
+
* any, so a deleted or resolved note's highlight does not linger in the content.
|
|
240
|
+
* No-op for block-level notes (those carry no marker). Used by the resolve path,
|
|
241
|
+
* which only knows the note id; the delete path strips the marker inline since
|
|
242
|
+
* it already has the block.
|
|
243
|
+
*
|
|
244
|
+
* @param {number} noteId Note id whose marker to remove.
|
|
245
|
+
* @param {Function} getClientIdsWithDescendants Block-editor selector.
|
|
246
|
+
* @param {Function} getBlockAttributes Block-editor selector.
|
|
247
|
+
* @param {Function} updateBlockAttributes Block-editor action.
|
|
248
|
+
*/
|
|
249
|
+
function clearInlineNoteMarker(
|
|
250
|
+
noteId,
|
|
251
|
+
getClientIdsWithDescendants,
|
|
252
|
+
getBlockAttributes,
|
|
253
|
+
updateBlockAttributes
|
|
254
|
+
) {
|
|
255
|
+
for ( const clientId of getClientIdsWithDescendants() ) {
|
|
256
|
+
const attributes = getBlockAttributes( clientId );
|
|
257
|
+
const found = findNoteInBlock( attributes, noteId );
|
|
258
|
+
if ( ! found ) {
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
const next = removeNoteFormat(
|
|
262
|
+
attributes[ found.attributeKey ],
|
|
263
|
+
noteId
|
|
264
|
+
);
|
|
265
|
+
if ( next ) {
|
|
266
|
+
updateBlockAttributes( clientId, { [ found.attributeKey ]: next } );
|
|
267
|
+
}
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
148
272
|
export function useNoteActions() {
|
|
149
273
|
const { createNotice } = useDispatch( noticesStore );
|
|
150
274
|
const { saveEntityRecord, deleteEntityRecord } = useDispatch( coreStore );
|
|
151
275
|
const { getCurrentPostId } = useSelect( editorStore );
|
|
152
|
-
const {
|
|
153
|
-
|
|
276
|
+
const {
|
|
277
|
+
getBlockAttributes,
|
|
278
|
+
getClientIdsWithDescendants,
|
|
279
|
+
getSelectedBlockClientId,
|
|
280
|
+
getSelectionStart,
|
|
281
|
+
getSelectionEnd,
|
|
282
|
+
} = useSelect( blockEditorStore );
|
|
154
283
|
const { updateBlockAttributes } = useDispatch( blockEditorStore );
|
|
155
284
|
|
|
156
285
|
const onError = ( error ) => {
|
|
@@ -166,6 +295,14 @@ export function useNoteActions() {
|
|
|
166
295
|
|
|
167
296
|
const onCreate = async ( { content, parent } ) => {
|
|
168
297
|
try {
|
|
298
|
+
// Capture inline selection *before* the async save: focus may shift
|
|
299
|
+
// during the round-trip and the editor's stored selection can
|
|
300
|
+
// collapse if the user clicks elsewhere. The selection drives the
|
|
301
|
+
// in-content marker written below, which is the note's only anchor.
|
|
302
|
+
const inlineSelection = ! parent
|
|
303
|
+
? readInlineSelection( getSelectionStart, getSelectionEnd )
|
|
304
|
+
: null;
|
|
305
|
+
|
|
169
306
|
const savedRecord = await saveEntityRecord(
|
|
170
307
|
'root',
|
|
171
308
|
'comment',
|
|
@@ -185,18 +322,36 @@ export function useNoteActions() {
|
|
|
185
322
|
// a 2-element array and the later write wins, dropping the other
|
|
186
323
|
// id. Tracking issue: https://github.com/WordPress/gutenberg/issues/74751.
|
|
187
324
|
if ( ! parent && savedRecord?.id ) {
|
|
188
|
-
const clientId =
|
|
325
|
+
const clientId =
|
|
326
|
+
inlineSelection?.clientId || getSelectedBlockClientId();
|
|
189
327
|
if ( ! clientId ) {
|
|
190
328
|
return savedRecord;
|
|
191
329
|
}
|
|
192
|
-
const
|
|
330
|
+
const attributes = getBlockAttributes( clientId );
|
|
331
|
+
const metadata = attributes?.metadata;
|
|
193
332
|
const updatedMetadata = addNoteIdToMetadata(
|
|
194
333
|
metadata,
|
|
195
334
|
savedRecord.id
|
|
196
335
|
);
|
|
197
|
-
|
|
336
|
+
const newAttributes = {
|
|
198
337
|
metadata: cleanEmptyObject( updatedMetadata ),
|
|
199
|
-
}
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
// Inline path: also wrap the selected text with a core/note
|
|
341
|
+
// marker so the anchor survives later edits.
|
|
342
|
+
if ( inlineSelection ) {
|
|
343
|
+
const wrapped = wrapInlineNote(
|
|
344
|
+
attributes?.[ inlineSelection.attributeKey ],
|
|
345
|
+
savedRecord.id,
|
|
346
|
+
inlineSelection.start,
|
|
347
|
+
inlineSelection.end
|
|
348
|
+
);
|
|
349
|
+
if ( wrapped ) {
|
|
350
|
+
newAttributes[ inlineSelection.attributeKey ] = wrapped;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
updateBlockAttributes( clientId, newAttributes );
|
|
200
355
|
}
|
|
201
356
|
|
|
202
357
|
createNotice(
|
|
@@ -253,6 +408,17 @@ export function useNoteActions() {
|
|
|
253
408
|
await saveEntityRecord( 'root', 'comment', newNoteData, {
|
|
254
409
|
throwOnError: true,
|
|
255
410
|
} );
|
|
411
|
+
|
|
412
|
+
// Resolving a note drops its inline highlight: strip the marker
|
|
413
|
+
// so the note falls back to a block-level note in the content.
|
|
414
|
+
if ( status === 'approved' ) {
|
|
415
|
+
clearInlineNoteMarker(
|
|
416
|
+
id,
|
|
417
|
+
getClientIdsWithDescendants,
|
|
418
|
+
getBlockAttributes,
|
|
419
|
+
updateBlockAttributes
|
|
420
|
+
);
|
|
421
|
+
}
|
|
256
422
|
} else {
|
|
257
423
|
const updateData = {
|
|
258
424
|
id,
|
|
@@ -291,14 +457,29 @@ export function useNoteActions() {
|
|
|
291
457
|
if ( ! clientId ) {
|
|
292
458
|
return;
|
|
293
459
|
}
|
|
294
|
-
const
|
|
295
|
-
const
|
|
296
|
-
metadata
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
460
|
+
const attributes = getBlockAttributes( clientId );
|
|
461
|
+
const newAttributes = {
|
|
462
|
+
metadata: cleanEmptyObject(
|
|
463
|
+
removeNoteIdFromMetadata(
|
|
464
|
+
attributes?.metadata,
|
|
465
|
+
note.id
|
|
466
|
+
)
|
|
467
|
+
),
|
|
468
|
+
};
|
|
469
|
+
// Strip the inline marker too (if any) so the deleted note's
|
|
470
|
+
// highlight doesn't linger in the content. Folded into the same
|
|
471
|
+
// attribute update so it's a single undo step.
|
|
472
|
+
const found = findNoteInBlock( attributes, note.id );
|
|
473
|
+
if ( found ) {
|
|
474
|
+
const next = removeNoteFormat(
|
|
475
|
+
attributes[ found.attributeKey ],
|
|
476
|
+
note.id
|
|
477
|
+
);
|
|
478
|
+
if ( next ) {
|
|
479
|
+
newAttributes[ found.attributeKey ] = next;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
updateBlockAttributes( clientId, newAttributes );
|
|
302
483
|
}
|
|
303
484
|
|
|
304
485
|
createNotice( 'snackbar', __( 'Note deleted.' ), {
|
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
|
-
import {
|
|
6
|
-
import { useRef } from '@wordpress/element';
|
|
5
|
+
import { useDispatch, useSelect } from '@wordpress/data';
|
|
6
|
+
import { useEffect, useRef } from '@wordpress/element';
|
|
7
7
|
import { useViewportMatch } from '@wordpress/compose';
|
|
8
8
|
import { useShortcut } from '@wordpress/keyboard-shortcuts';
|
|
9
9
|
import { comment as commentIcon } from '@wordpress/icons';
|
|
10
10
|
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
11
11
|
import { store as interfaceStore } from '@wordpress/interface';
|
|
12
12
|
import { store as preferencesStore } from '@wordpress/preferences';
|
|
13
|
+
import { registerFormatType, unregisterFormatType } from '@wordpress/rich-text';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Internal dependencies
|
|
@@ -24,13 +25,22 @@ import { Notes } from './notes';
|
|
|
24
25
|
import { store as editorStore } from '../../store';
|
|
25
26
|
import { AddNoteMenuItem } from './add-note-menu-item';
|
|
26
27
|
import { NoteAvatarIndicator } from './note-indicator-toolbar';
|
|
28
|
+
import { NoteHighlightStyles } from './note-highlight-styles';
|
|
27
29
|
import { useGlobalStyles } from '../global-styles';
|
|
28
|
-
import {
|
|
30
|
+
import { useEnableFloatingSidebar, useNoteThreads } from './hooks';
|
|
29
31
|
import { getNoteIdsFromMetadata, pickPrimaryNote } from './utils';
|
|
32
|
+
import { NOTE_FORMAT_NAME, noteFormat } from './format';
|
|
30
33
|
import PostTypeSupportCheck from '../post-type-support-check';
|
|
31
34
|
import { unlock } from '../../lock-unlock';
|
|
32
35
|
|
|
33
36
|
function NotesSidebar( { postId } ) {
|
|
37
|
+
useEffect( () => {
|
|
38
|
+
registerFormatType( NOTE_FORMAT_NAME, noteFormat );
|
|
39
|
+
return () => {
|
|
40
|
+
unregisterFormatType( NOTE_FORMAT_NAME );
|
|
41
|
+
};
|
|
42
|
+
}, [] );
|
|
43
|
+
|
|
34
44
|
const { getActiveComplementaryArea } = useSelect( interfaceStore );
|
|
35
45
|
const { enableComplementaryArea } = useDispatch( interfaceStore );
|
|
36
46
|
const { toggleBlockSpotlight, selectBlock } = unlock(
|
|
@@ -62,7 +72,7 @@ function NotesSidebar( { postId } ) {
|
|
|
62
72
|
isDistractionFree: get( 'core', 'distractionFree' ),
|
|
63
73
|
};
|
|
64
74
|
}, [] );
|
|
65
|
-
const
|
|
75
|
+
const selectedNoteId = useSelect(
|
|
66
76
|
( select ) => unlock( select( editorStore ) ).getSelectedNote(),
|
|
67
77
|
[]
|
|
68
78
|
);
|
|
@@ -75,7 +85,7 @@ function NotesSidebar( { postId } ) {
|
|
|
75
85
|
const showAllNotesSidebar = notes.length > 0 || ! showFloatingSidebar;
|
|
76
86
|
useEnableFloatingSidebar(
|
|
77
87
|
showFloatingSidebar &&
|
|
78
|
-
( unresolvedNotes.length > 0 ||
|
|
88
|
+
( unresolvedNotes.length > 0 || selectedNoteId !== undefined )
|
|
79
89
|
);
|
|
80
90
|
|
|
81
91
|
async function focusNote( {
|
|
@@ -159,6 +169,10 @@ function NotesSidebar( { postId } ) {
|
|
|
159
169
|
|
|
160
170
|
return (
|
|
161
171
|
<>
|
|
172
|
+
<NoteHighlightStyles
|
|
173
|
+
threads={ unresolvedNotes }
|
|
174
|
+
selectedId={ selectedNoteId }
|
|
175
|
+
/>
|
|
162
176
|
{ !! currentThread && (
|
|
163
177
|
<NoteAvatarIndicator
|
|
164
178
|
note={ currentThread }
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useMemo } from '@wordpress/element';
|
|
5
|
+
import { useStyleOverride } from '@wordpress/block-editor';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Internal dependencies
|
|
9
|
+
*/
|
|
10
|
+
import { getAvatarBorderColor } from './utils';
|
|
11
|
+
|
|
12
|
+
// Hex alpha suffixes for the rest / active states. Kept low so the marker
|
|
13
|
+
// reads as a soft tint at rest and gets noticeably stronger when focused or
|
|
14
|
+
// hovered. (0x40 ≈ 25%, 0x80 ≈ 50%.)
|
|
15
|
+
const REST_ALPHA = '40';
|
|
16
|
+
const ACTIVE_ALPHA = '80';
|
|
17
|
+
|
|
18
|
+
// Reset the browser's default `<mark>` styling so the per-author rules below
|
|
19
|
+
// are what readers actually see (without it, `mark` ships with a bright yellow
|
|
20
|
+
// background in every browser). The `core/note` anchor marker serializes as a
|
|
21
|
+
// `<mark>` and would otherwise inherit the yellow default in the editor canvas.
|
|
22
|
+
const BASE_RESET = 'mark.wp-note{background-color:transparent;color:inherit;}';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Build the CSS rule set that tints each inline-note marker with its author's
|
|
26
|
+
* avatar color. Pure helper extracted so it can be unit-tested without React.
|
|
27
|
+
*
|
|
28
|
+
* @param {Array} threads Unresolved note threads (each with `id` and `author`).
|
|
29
|
+
* @param {string|null} selectedId ID of the currently selected note, if any.
|
|
30
|
+
* @return {string} A serialized CSS string targeting the in-content note markers.
|
|
31
|
+
*/
|
|
32
|
+
export function buildHighlightCss( threads, selectedId = null ) {
|
|
33
|
+
const rules = [ BASE_RESET ];
|
|
34
|
+
for ( const thread of threads ?? [] ) {
|
|
35
|
+
if ( ! thread?.id ) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const color = getAvatarBorderColor( thread.author ?? 0 );
|
|
39
|
+
// The `core/note` format serializes the id into `data-id`, so the marker
|
|
40
|
+
// can be targeted directly without a separate annotation layer.
|
|
41
|
+
// `thread.id` is a server comment ID (always a positive integer), but
|
|
42
|
+
// escape `"`/`\` defensively since it composes a quoted attribute value
|
|
43
|
+
// from stored data.
|
|
44
|
+
const escapedId = String( thread.id ).replace( /["\\]/g, '\\$&' );
|
|
45
|
+
const sel = `mark.wp-note[data-id="${ escapedId }"]`;
|
|
46
|
+
rules.push( `${ sel }{background-color:${ color }${ REST_ALPHA };}` );
|
|
47
|
+
rules.push(
|
|
48
|
+
`${ sel }:hover,${ sel }:focus-within{background-color:${ color }${ ACTIVE_ALPHA };}`
|
|
49
|
+
);
|
|
50
|
+
if ( selectedId && String( selectedId ) === String( thread.id ) ) {
|
|
51
|
+
rules.push(
|
|
52
|
+
`${ sel }{background-color:${ color }${ ACTIVE_ALPHA };}`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return rules.join( '' );
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Injects per-note background rules into the editor canvas so inline-note
|
|
61
|
+
* markers carry their author's avatar color. The `core/note` format serializes
|
|
62
|
+
* each marker as `<mark class="wp-note" data-id="{noteId}">`, which we target
|
|
63
|
+
* directly.
|
|
64
|
+
*
|
|
65
|
+
* Uses `useStyleOverride` so the styles reach the iframed canvas; a plain
|
|
66
|
+
* `<style>` element rendered in the sidebar would only affect the parent doc.
|
|
67
|
+
*
|
|
68
|
+
* Opacity boosts on `:hover`, `:focus-within`, and when the matching thread is
|
|
69
|
+
* the editor's selected note.
|
|
70
|
+
*
|
|
71
|
+
* @param {Object} props
|
|
72
|
+
* @param {Array} props.threads Unresolved note threads.
|
|
73
|
+
* @param {string|null} [props.selectedId] ID of the currently selected note.
|
|
74
|
+
* @return {null} Renders nothing; styles are applied via `useStyleOverride`.
|
|
75
|
+
*/
|
|
76
|
+
export function NoteHighlightStyles( { threads, selectedId } ) {
|
|
77
|
+
const css = useMemo(
|
|
78
|
+
() => buildHighlightCss( threads, selectedId ),
|
|
79
|
+
[ threads, selectedId ]
|
|
80
|
+
);
|
|
81
|
+
useStyleOverride( { id: 'core-note-highlights', css } );
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
@@ -218,3 +218,12 @@
|
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
|
+
|
|
222
|
+
// Inline-note highlight applied to the `core/note` marker (`mark.wp-note`).
|
|
223
|
+
// Each marker is tinted by `<NoteHighlightStyles>` using the note author's
|
|
224
|
+
// color from `AVATAR_BORDER_COLORS`; this base rule only provides shared
|
|
225
|
+
// layout/transition properties.
|
|
226
|
+
mark.wp-note {
|
|
227
|
+
border-radius: 1px;
|
|
228
|
+
transition: background-color 0.1s ease-in-out;
|
|
229
|
+
}
|