@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
|
@@ -6,6 +6,7 @@ import Textarea from 'react-autosize-textarea';
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
|
+
import { useLayoutEffect, useRef } from '@wordpress/element';
|
|
9
10
|
import { __ } from '@wordpress/i18n';
|
|
10
11
|
import { store as coreStore } from '@wordpress/core-data';
|
|
11
12
|
import { useDispatch, useSelect } from '@wordpress/data';
|
|
@@ -16,6 +17,7 @@ import { VisuallyHidden } from '@wordpress/ui';
|
|
|
16
17
|
* Internal dependencies
|
|
17
18
|
*/
|
|
18
19
|
import { store as editorStore } from '../../store';
|
|
20
|
+
import { adjustPosition, getDiff } from './utils';
|
|
19
21
|
|
|
20
22
|
/**
|
|
21
23
|
* Displays the Post Text Editor along with content in Visual and Text mode.
|
|
@@ -24,6 +26,9 @@ import { store as editorStore } from '../../store';
|
|
|
24
26
|
*/
|
|
25
27
|
export default function PostTextEditor() {
|
|
26
28
|
const instanceId = useInstanceId( PostTextEditor );
|
|
29
|
+
const textareaRef = useRef();
|
|
30
|
+
const previousValueRef = useRef();
|
|
31
|
+
const selectionRef = useRef();
|
|
27
32
|
const { value, type, id } = useSelect( ( select ) => {
|
|
28
33
|
const { getCurrentPostType, getCurrentPostId, getEditedPostContent } =
|
|
29
34
|
select( editorStore );
|
|
@@ -35,6 +40,58 @@ export default function PostTextEditor() {
|
|
|
35
40
|
}, [] );
|
|
36
41
|
const { editEntityRecord } = useDispatch( coreStore );
|
|
37
42
|
|
|
43
|
+
useLayoutEffect( () => {
|
|
44
|
+
const textarea = textareaRef.current;
|
|
45
|
+
const previousValue = previousValueRef.current;
|
|
46
|
+
previousValueRef.current = value;
|
|
47
|
+
|
|
48
|
+
if (
|
|
49
|
+
! textarea ||
|
|
50
|
+
previousValue === undefined ||
|
|
51
|
+
previousValue === value ||
|
|
52
|
+
! selectionRef.current
|
|
53
|
+
) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const { selectionStart, selectionEnd, selectionDirection } =
|
|
58
|
+
selectionRef.current;
|
|
59
|
+
const changes = getDiff( previousValue, value );
|
|
60
|
+
const adjustedSelectionStart = adjustPosition(
|
|
61
|
+
selectionStart,
|
|
62
|
+
changes,
|
|
63
|
+
previousValue,
|
|
64
|
+
value
|
|
65
|
+
);
|
|
66
|
+
const adjustedSelectionEnd = adjustPosition(
|
|
67
|
+
selectionEnd,
|
|
68
|
+
changes,
|
|
69
|
+
previousValue,
|
|
70
|
+
value
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
textarea.setSelectionRange(
|
|
74
|
+
adjustedSelectionStart,
|
|
75
|
+
adjustedSelectionEnd,
|
|
76
|
+
selectionDirection
|
|
77
|
+
);
|
|
78
|
+
selectionRef.current = {
|
|
79
|
+
selectionStart: adjustedSelectionStart,
|
|
80
|
+
selectionEnd: adjustedSelectionEnd,
|
|
81
|
+
selectionDirection,
|
|
82
|
+
};
|
|
83
|
+
}, [ value ] );
|
|
84
|
+
|
|
85
|
+
const updateSelection = ( event ) => {
|
|
86
|
+
const { selectionStart, selectionEnd, selectionDirection } =
|
|
87
|
+
event.target;
|
|
88
|
+
selectionRef.current = {
|
|
89
|
+
selectionStart,
|
|
90
|
+
selectionEnd,
|
|
91
|
+
selectionDirection,
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
|
|
38
95
|
return (
|
|
39
96
|
<>
|
|
40
97
|
<VisuallyHidden
|
|
@@ -46,14 +103,22 @@ export default function PostTextEditor() {
|
|
|
46
103
|
<Textarea
|
|
47
104
|
autoComplete="off"
|
|
48
105
|
dir="auto"
|
|
106
|
+
ref={ textareaRef }
|
|
49
107
|
value={ value }
|
|
50
108
|
onChange={ ( event ) => {
|
|
109
|
+
updateSelection( event );
|
|
110
|
+
previousValueRef.current = event.target.value;
|
|
51
111
|
editEntityRecord( 'postType', type, id, {
|
|
52
112
|
content: event.target.value,
|
|
53
113
|
blocks: undefined,
|
|
54
114
|
selection: undefined,
|
|
55
115
|
} );
|
|
56
116
|
} }
|
|
117
|
+
onFocus={ updateSelection }
|
|
118
|
+
// A click or arrow-key caret move does not fire `select` (only
|
|
119
|
+
// range selections do), so track those moves via mouseup/keyup.
|
|
120
|
+
onMouseUp={ updateSelection }
|
|
121
|
+
onKeyUp={ updateSelection }
|
|
57
122
|
className="editor-post-text-editor"
|
|
58
123
|
id={ `post-content-${ instanceId }` }
|
|
59
124
|
placeholder={ __( 'Start writing with text or HTML' ) }
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { getAdjustedCursorPosition } from '../utils';
|
|
5
|
+
|
|
6
|
+
describe( 'PostTextEditor', () => {
|
|
7
|
+
describe( 'getAdjustedCursorPosition', () => {
|
|
8
|
+
it( 'keeps the cursor in place when text is inserted after it', () => {
|
|
9
|
+
expect(
|
|
10
|
+
getAdjustedCursorPosition( 3, 'foo bar', 'foo bar baz' )
|
|
11
|
+
).toBe( 3 );
|
|
12
|
+
} );
|
|
13
|
+
|
|
14
|
+
it( 'moves the cursor when text is inserted before it', () => {
|
|
15
|
+
expect( getAdjustedCursorPosition( 4, 'abcd', 'abXYcd' ) ).toBe(
|
|
16
|
+
6
|
|
17
|
+
);
|
|
18
|
+
} );
|
|
19
|
+
|
|
20
|
+
it( 'moves the cursor when text is deleted before it', () => {
|
|
21
|
+
expect( getAdjustedCursorPosition( 6, 'abcdef', 'abef' ) ).toBe(
|
|
22
|
+
4
|
|
23
|
+
);
|
|
24
|
+
} );
|
|
25
|
+
|
|
26
|
+
it( 'moves the cursor to the end of a replacement around it', () => {
|
|
27
|
+
expect( getAdjustedCursorPosition( 3, 'abcdef', 'abXYef' ) ).toBe(
|
|
28
|
+
4
|
|
29
|
+
);
|
|
30
|
+
} );
|
|
31
|
+
|
|
32
|
+
it( 'handles multiple separated changes in one update', () => {
|
|
33
|
+
expect(
|
|
34
|
+
getAdjustedCursorPosition( 7, 'abcdefghij', 'abXXcdefYYghij' )
|
|
35
|
+
).toBe( 11 );
|
|
36
|
+
} );
|
|
37
|
+
|
|
38
|
+
it( 'keeps the cursor in place when large text is inserted after it', () => {
|
|
39
|
+
const oldValue = `cursor\n${ 'a\n'.repeat( 6000 ) }`;
|
|
40
|
+
const newValue = `${ oldValue }remote\n`;
|
|
41
|
+
|
|
42
|
+
expect(
|
|
43
|
+
getAdjustedCursorPosition( 'cursor'.length, oldValue, newValue )
|
|
44
|
+
).toBe( 'cursor'.length );
|
|
45
|
+
} );
|
|
46
|
+
|
|
47
|
+
it( 'moves the cursor when large text is inserted before it', () => {
|
|
48
|
+
const oldValue = `cursor\n${ 'a\n'.repeat( 6000 ) }`;
|
|
49
|
+
const newValue = `remote\n${ oldValue }`;
|
|
50
|
+
|
|
51
|
+
expect(
|
|
52
|
+
getAdjustedCursorPosition( 'cursor'.length, oldValue, newValue )
|
|
53
|
+
).toBe( 'remote\n'.length + 'cursor'.length );
|
|
54
|
+
} );
|
|
55
|
+
|
|
56
|
+
it( 'moves the cursor when large text is deleted before it', () => {
|
|
57
|
+
const deletedPrefix = 'remote\n';
|
|
58
|
+
const newValue = `cursor\n${ 'a\n'.repeat( 6000 ) }`;
|
|
59
|
+
const oldValue = `${ deletedPrefix }${ newValue }`;
|
|
60
|
+
const position = deletedPrefix.length + 'cursor'.length;
|
|
61
|
+
|
|
62
|
+
expect(
|
|
63
|
+
getAdjustedCursorPosition( position, oldValue, newValue )
|
|
64
|
+
).toBe( 'cursor'.length );
|
|
65
|
+
} );
|
|
66
|
+
|
|
67
|
+
it( 'moves the cursor when large single-line HTML is inserted before it', () => {
|
|
68
|
+
const opening = '<!-- wp:paragraph -->\n<p>';
|
|
69
|
+
const closing = '</p>\n<!-- /wp:paragraph -->';
|
|
70
|
+
const content = 'a'.repeat( 120000 );
|
|
71
|
+
const insertedText = 'remote';
|
|
72
|
+
const tailText = 'tail';
|
|
73
|
+
const oldValue = `${ opening }${ content }${ closing }`;
|
|
74
|
+
const newValue = `${ opening }${ insertedText }${ content.slice(
|
|
75
|
+
0,
|
|
76
|
+
100000
|
|
77
|
+
) }${ tailText }${ content.slice( 100000 ) }${ closing }`;
|
|
78
|
+
const position = opening.length + 60000;
|
|
79
|
+
|
|
80
|
+
expect(
|
|
81
|
+
getAdjustedCursorPosition( position, oldValue, newValue )
|
|
82
|
+
).toBe( position + insertedText.length );
|
|
83
|
+
} );
|
|
84
|
+
|
|
85
|
+
it( 'moves the cursor when large single-line HTML is deleted before it', () => {
|
|
86
|
+
const opening = '<!-- wp:paragraph -->\n<p>';
|
|
87
|
+
const closing = '</p>\n<!-- /wp:paragraph -->';
|
|
88
|
+
const deletedText = 'remote'.repeat( 1000 );
|
|
89
|
+
const deletedTailText = 'tail';
|
|
90
|
+
const content = 'a'.repeat( 120000 );
|
|
91
|
+
const newValue = `${ opening }${ content }${ closing }`;
|
|
92
|
+
const oldValue = `${ opening }${ deletedText }${ content.slice(
|
|
93
|
+
0,
|
|
94
|
+
100000
|
|
95
|
+
) }${ deletedTailText }${ content.slice( 100000 ) }${ closing }`;
|
|
96
|
+
const position = opening.length + deletedText.length + 60000;
|
|
97
|
+
|
|
98
|
+
expect(
|
|
99
|
+
getAdjustedCursorPosition( position, oldValue, newValue )
|
|
100
|
+
).toBe( position - deletedText.length );
|
|
101
|
+
} );
|
|
102
|
+
|
|
103
|
+
it( 'keeps the cursor in an unchanged same-line prefix before a large replacement', () => {
|
|
104
|
+
const prefix = `${ 'a'.repeat( 300 ) }\n${ 'b'.repeat( 199 ) }`;
|
|
105
|
+
const suffix = 'tail';
|
|
106
|
+
const oldValue = `${ prefix }old${ 'x'.repeat(
|
|
107
|
+
11000
|
|
108
|
+
) }${ suffix }`;
|
|
109
|
+
const newValue = `${ prefix }new${ 'y'.repeat(
|
|
110
|
+
11000
|
|
111
|
+
) }${ suffix }`;
|
|
112
|
+
const position = 450;
|
|
113
|
+
|
|
114
|
+
expect(
|
|
115
|
+
getAdjustedCursorPosition( position, oldValue, newValue )
|
|
116
|
+
).toBe( position );
|
|
117
|
+
} );
|
|
118
|
+
|
|
119
|
+
it( 'moves the cursor when large same-line text is inserted before it and replaced after it', () => {
|
|
120
|
+
const opening = '<!-- wp:paragraph -->\n<p>';
|
|
121
|
+
const closing = '</p>\n<!-- /wp:paragraph -->';
|
|
122
|
+
const content = 'a'.repeat( 120000 );
|
|
123
|
+
const insertedText = 'remote';
|
|
124
|
+
const oldValue = `${ opening }${ content }${ closing }`;
|
|
125
|
+
const newValue = `${ opening }${ content.slice(
|
|
126
|
+
0,
|
|
127
|
+
50000
|
|
128
|
+
) }${ insertedText }${ content.slice(
|
|
129
|
+
50000,
|
|
130
|
+
100000
|
|
131
|
+
) }b${ content.slice( 100001 ) }${ closing }`;
|
|
132
|
+
const position = opening.length + 60000;
|
|
133
|
+
|
|
134
|
+
expect(
|
|
135
|
+
getAdjustedCursorPosition( position, oldValue, newValue )
|
|
136
|
+
).toBe( position + insertedText.length );
|
|
137
|
+
} );
|
|
138
|
+
|
|
139
|
+
it( 'moves the cursor when large same-line text is deleted before it and inserted after it', () => {
|
|
140
|
+
const opening = '<!-- wp:paragraph -->\n<p>';
|
|
141
|
+
const closing = '</p>\n<!-- /wp:paragraph -->';
|
|
142
|
+
const content = 'a'.repeat( 120000 );
|
|
143
|
+
const deletedText = 'remote'.repeat( 1000 );
|
|
144
|
+
const insertedTailText = 'tail';
|
|
145
|
+
const commonTextBeforeCursor = 500;
|
|
146
|
+
const oldValue = `${ opening }${ content.slice(
|
|
147
|
+
0,
|
|
148
|
+
50000
|
|
149
|
+
) }${ deletedText }${ content.slice( 50000 ) }${ closing }`;
|
|
150
|
+
const newValue = `${ opening }${ content.slice(
|
|
151
|
+
0,
|
|
152
|
+
100000
|
|
153
|
+
) }${ insertedTailText }${ content.slice( 100000 ) }${ closing }`;
|
|
154
|
+
const position =
|
|
155
|
+
opening.length +
|
|
156
|
+
50000 +
|
|
157
|
+
deletedText.length +
|
|
158
|
+
commonTextBeforeCursor;
|
|
159
|
+
|
|
160
|
+
expect(
|
|
161
|
+
getAdjustedCursorPosition( position, oldValue, newValue )
|
|
162
|
+
).toBe( position - deletedText.length );
|
|
163
|
+
} );
|
|
164
|
+
|
|
165
|
+
it( 'maps the cursor through a pure insertion in a large single line', () => {
|
|
166
|
+
// "HEAD"/"TAIL" wrap the unchanged content, so the new value contains
|
|
167
|
+
// the old changed window and it routes through the line-diff fallback.
|
|
168
|
+
const opening = '<!-- wp:paragraph -->\n<p>';
|
|
169
|
+
const closing = '</p>\n<!-- /wp:paragraph -->';
|
|
170
|
+
const content = 'a'.repeat( 120000 );
|
|
171
|
+
const oldValue = `${ opening }${ content }${ closing }`;
|
|
172
|
+
const newValue = `${ opening }HEAD${ content }TAIL${ closing }`;
|
|
173
|
+
const position = opening.length + 60000;
|
|
174
|
+
|
|
175
|
+
expect(
|
|
176
|
+
getAdjustedCursorPosition( position, oldValue, newValue )
|
|
177
|
+
).toBe( position + 'HEAD'.length );
|
|
178
|
+
} );
|
|
179
|
+
|
|
180
|
+
it( 'maps the cursor through a pure deletion in a large single line', () => {
|
|
181
|
+
const opening = '<!-- wp:paragraph -->\n<p>';
|
|
182
|
+
const closing = '</p>\n<!-- /wp:paragraph -->';
|
|
183
|
+
const content = 'a'.repeat( 120000 );
|
|
184
|
+
const oldValue = `${ opening }HEAD${ content }TAIL${ closing }`;
|
|
185
|
+
const newValue = `${ opening }${ content }${ closing }`;
|
|
186
|
+
const position = opening.length + 'HEAD'.length + 60000;
|
|
187
|
+
|
|
188
|
+
expect(
|
|
189
|
+
getAdjustedCursorPosition( position, oldValue, newValue )
|
|
190
|
+
).toBe( position - 'HEAD'.length );
|
|
191
|
+
} );
|
|
192
|
+
|
|
193
|
+
it( 'handles a large fully-divergent replacement without blocking', () => {
|
|
194
|
+
// Neither side contains the other and the changed window exceeds the
|
|
195
|
+
// diffChars threshold, so this routes to the line-diff fallback. A
|
|
196
|
+
// character diff here would be O(n^2) and freeze the main thread for
|
|
197
|
+
// seconds; completing within the test timeout guards that path.
|
|
198
|
+
const oldValue = 'a'.repeat( 8000 );
|
|
199
|
+
const newValue = 'b'.repeat( 8000 );
|
|
200
|
+
const result = getAdjustedCursorPosition(
|
|
201
|
+
4000,
|
|
202
|
+
oldValue,
|
|
203
|
+
newValue
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
expect( result ).toBeGreaterThanOrEqual( 0 );
|
|
207
|
+
expect( result ).toBeLessThanOrEqual( newValue.length );
|
|
208
|
+
} );
|
|
209
|
+
} );
|
|
210
|
+
} );
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { diffChars } from 'diff/lib/diff/character';
|
|
5
|
+
import { diffLines } from 'diff/lib/diff/line';
|
|
6
|
+
|
|
7
|
+
// Character diffing (Myers) is cheap when the edit distance is small but
|
|
8
|
+
// degrades toward O(n^2) as the two strings diverge: a full replacement of
|
|
9
|
+
// ~10k differing chars blocks the main thread for seconds. Cap the input handed
|
|
10
|
+
// to diffChars so the worst case stays small (~100ms); larger windows fall back
|
|
11
|
+
// to a line diff, with the cursor remapped by getCursorOffsetFromCommonText...
|
|
12
|
+
const STRING_TOO_LARGE_THRESHOLD = 1000;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Diffs two strings into a list of `{ value, added?, removed? }` change parts.
|
|
16
|
+
*
|
|
17
|
+
* @param {string} oldValue The previous string.
|
|
18
|
+
* @param {string} newValue The next string.
|
|
19
|
+
* @return {Array<Object>} The diff change parts.
|
|
20
|
+
*/
|
|
21
|
+
export function getDiff( oldValue, newValue ) {
|
|
22
|
+
const maxStringLength = Math.max( oldValue.length, newValue.length );
|
|
23
|
+
|
|
24
|
+
if ( maxStringLength <= STRING_TOO_LARGE_THRESHOLD ) {
|
|
25
|
+
return diffChars( oldValue, newValue );
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let start = 0;
|
|
29
|
+
const minStringLength = Math.min( oldValue.length, newValue.length );
|
|
30
|
+
|
|
31
|
+
while (
|
|
32
|
+
start < minStringLength &&
|
|
33
|
+
oldValue[ start ] === newValue[ start ]
|
|
34
|
+
) {
|
|
35
|
+
start++;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let oldEnd = oldValue.length;
|
|
39
|
+
let newEnd = newValue.length;
|
|
40
|
+
|
|
41
|
+
while (
|
|
42
|
+
oldEnd > start &&
|
|
43
|
+
newEnd > start &&
|
|
44
|
+
oldValue[ oldEnd - 1 ] === newValue[ newEnd - 1 ]
|
|
45
|
+
) {
|
|
46
|
+
oldEnd--;
|
|
47
|
+
newEnd--;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const oldChangedValue = oldValue.slice( start, oldEnd );
|
|
51
|
+
const newChangedValue = newValue.slice( start, newEnd );
|
|
52
|
+
const maxChangedStringLength = Math.max(
|
|
53
|
+
oldChangedValue.length,
|
|
54
|
+
newChangedValue.length
|
|
55
|
+
);
|
|
56
|
+
let changes;
|
|
57
|
+
|
|
58
|
+
if ( maxChangedStringLength <= STRING_TOO_LARGE_THRESHOLD ) {
|
|
59
|
+
changes = diffChars( oldChangedValue, newChangedValue );
|
|
60
|
+
} else {
|
|
61
|
+
changes = diffLines( oldChangedValue, newChangedValue );
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if ( start > 0 ) {
|
|
65
|
+
changes.unshift( { value: oldValue.slice( 0, start ) } );
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if ( oldEnd < oldValue.length ) {
|
|
69
|
+
changes.push( { value: oldValue.slice( oldEnd ) } );
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return changes;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function clampCursorPosition( position, value ) {
|
|
76
|
+
return Math.max( 0, Math.min( value.length, position ) );
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// A coarse (line-level) diff reports a whole changed region as one replacement,
|
|
80
|
+
// which would otherwise snap the cursor to the region's end. Recover a precise
|
|
81
|
+
// position by finding the longest run of text ending at the cursor that is
|
|
82
|
+
// preserved in the replacement, then placing the cursor just past where that
|
|
83
|
+
// run starts in the new text. This uses indexOf (near-linear in V8) rather than
|
|
84
|
+
// a character diff, so it stays cheap even across a large single-line region.
|
|
85
|
+
function getCursorOffsetFromCommonTextBeforeCursor(
|
|
86
|
+
oldValue,
|
|
87
|
+
newValue,
|
|
88
|
+
position
|
|
89
|
+
) {
|
|
90
|
+
const oldValueBeforeCursor = oldValue.slice( 0, position );
|
|
91
|
+
let low = 1;
|
|
92
|
+
let high = oldValueBeforeCursor.length;
|
|
93
|
+
let cursorOffset;
|
|
94
|
+
|
|
95
|
+
while ( low <= high ) {
|
|
96
|
+
const length = Math.floor( ( low + high ) / 2 );
|
|
97
|
+
const index = newValue.indexOf(
|
|
98
|
+
oldValueBeforeCursor.slice( oldValueBeforeCursor.length - length )
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
if ( index === -1 ) {
|
|
102
|
+
high = length - 1;
|
|
103
|
+
} else {
|
|
104
|
+
cursorOffset = index + length;
|
|
105
|
+
low = length + 1;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return cursorOffset;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Maps a cursor position from the old string to the new string given a diff.
|
|
114
|
+
*
|
|
115
|
+
* @param {number} position The cursor position in the old string.
|
|
116
|
+
* @param {Array<Object>} changes The diff returned by `getDiff`.
|
|
117
|
+
* @param {string} oldValue The previous string.
|
|
118
|
+
* @param {string} newValue The next string.
|
|
119
|
+
* @return {number} The adjusted cursor position in the new string.
|
|
120
|
+
*/
|
|
121
|
+
export function adjustPosition( position, changes, oldValue, newValue ) {
|
|
122
|
+
let oldIndex = 0;
|
|
123
|
+
let newIndex = 0;
|
|
124
|
+
let adjustedPosition = position;
|
|
125
|
+
|
|
126
|
+
for ( let i = 0; i < changes.length; i++ ) {
|
|
127
|
+
const change = changes[ i ];
|
|
128
|
+
if ( ! change.added && ! change.removed ) {
|
|
129
|
+
oldIndex += change.value.length;
|
|
130
|
+
newIndex += change.value.length;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const oldStart = oldIndex;
|
|
135
|
+
const newStart = newIndex;
|
|
136
|
+
let oldLength = 0;
|
|
137
|
+
let newLength = 0;
|
|
138
|
+
|
|
139
|
+
while (
|
|
140
|
+
i < changes.length &&
|
|
141
|
+
( changes[ i ].added || changes[ i ].removed )
|
|
142
|
+
) {
|
|
143
|
+
if ( changes[ i ].removed ) {
|
|
144
|
+
oldLength += changes[ i ].value.length;
|
|
145
|
+
} else {
|
|
146
|
+
newLength += changes[ i ].value.length;
|
|
147
|
+
}
|
|
148
|
+
i++;
|
|
149
|
+
}
|
|
150
|
+
i--;
|
|
151
|
+
|
|
152
|
+
const oldEnd = oldStart + oldLength;
|
|
153
|
+
const newEnd = newStart + newLength;
|
|
154
|
+
|
|
155
|
+
if ( position < oldStart ) {
|
|
156
|
+
// The cursor is before this change, so nothing here can move it.
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if ( oldLength === 0 ) {
|
|
161
|
+
// Pure insertion at or before the cursor: shift it right by the
|
|
162
|
+
// inserted length.
|
|
163
|
+
adjustedPosition += newLength;
|
|
164
|
+
} else if ( position <= oldEnd ) {
|
|
165
|
+
// The cursor falls inside a replaced region; recover its precise
|
|
166
|
+
// spot from the text preserved around it.
|
|
167
|
+
const cursorOffset = getCursorOffsetFromCommonTextBeforeCursor(
|
|
168
|
+
oldValue.slice( oldStart, oldEnd ),
|
|
169
|
+
newValue.slice( newStart, newEnd ),
|
|
170
|
+
position - oldStart
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
adjustedPosition =
|
|
174
|
+
cursorOffset === undefined ? newEnd : newStart + cursorOffset;
|
|
175
|
+
break;
|
|
176
|
+
} else {
|
|
177
|
+
// The cursor is after this change: shift it by the net length delta.
|
|
178
|
+
adjustedPosition += newLength - oldLength;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
oldIndex += oldLength;
|
|
182
|
+
newIndex += newLength;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return clampCursorPosition( adjustedPosition, newValue );
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Diffs `oldValue` against `newValue` and maps a cursor `position` from the old
|
|
190
|
+
* string to the new one.
|
|
191
|
+
*
|
|
192
|
+
* @param {number} position The cursor position in the old string.
|
|
193
|
+
* @param {string} oldValue The previous string.
|
|
194
|
+
* @param {string} newValue The next string.
|
|
195
|
+
* @return {number} The adjusted cursor position in the new string.
|
|
196
|
+
*/
|
|
197
|
+
export function getAdjustedCursorPosition( position, oldValue, newValue ) {
|
|
198
|
+
return adjustPosition(
|
|
199
|
+
position,
|
|
200
|
+
getDiff( oldValue, newValue ),
|
|
201
|
+
oldValue,
|
|
202
|
+
newValue
|
|
203
|
+
);
|
|
204
|
+
}
|
|
@@ -54,6 +54,17 @@ describe( 'PostTypeSupportCheck', () => {
|
|
|
54
54
|
expect( container ).not.toHaveTextContent( 'Supported' );
|
|
55
55
|
} );
|
|
56
56
|
|
|
57
|
+
it( 'does not crash when the post type has no `supports` object', () => {
|
|
58
|
+
setupUseSelectMock( {} );
|
|
59
|
+
const { container } = render(
|
|
60
|
+
<PostTypeSupportCheck supportKeys="title">
|
|
61
|
+
Supported
|
|
62
|
+
</PostTypeSupportCheck>
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
expect( container ).not.toHaveTextContent( 'Supported' );
|
|
66
|
+
} );
|
|
67
|
+
|
|
57
68
|
it( 'renders its children when post type is known and supports', () => {
|
|
58
69
|
setupUseSelectMock( {
|
|
59
70
|
supports: {
|
|
@@ -58,7 +58,7 @@ export default function PostURL( { onClose } ) {
|
|
|
58
58
|
postSlug: safeDecodeURIComponent(
|
|
59
59
|
select( editorStore ).getEditedPostSlug()
|
|
60
60
|
),
|
|
61
|
-
viewPostLabel: postType?.labels
|
|
61
|
+
viewPostLabel: postType?.labels?.view_item,
|
|
62
62
|
postLink: post.link,
|
|
63
63
|
permalinkPrefix: permalinkParts?.prefix,
|
|
64
64
|
permalinkSuffix: permalinkParts?.suffix,
|
|
@@ -24,7 +24,7 @@ export default function PostViewLink() {
|
|
|
24
24
|
return {
|
|
25
25
|
permalink: select( editorStore ).getPermalink(),
|
|
26
26
|
isPublished: select( editorStore ).isCurrentPostPublished(),
|
|
27
|
-
label: postType?.labels
|
|
27
|
+
label: postType?.labels?.view_item,
|
|
28
28
|
hasLoaded: !! postType,
|
|
29
29
|
showIconLabels: get( 'core', 'showIconLabels' ),
|
|
30
30
|
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { useSelect } from '@wordpress/data';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies
|
|
13
|
+
*/
|
|
14
|
+
import PostViewLink from '../';
|
|
15
|
+
|
|
16
|
+
jest.mock( '@wordpress/data/src/components/use-select', () => jest.fn() );
|
|
17
|
+
|
|
18
|
+
const DEFAULTS = {
|
|
19
|
+
postType: { labels: { view_item: 'View Post' } },
|
|
20
|
+
permalink: 'https://example.com/sample/',
|
|
21
|
+
isPublished: true,
|
|
22
|
+
showIconLabels: false,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function setupUseSelectMock( overrides = {} ) {
|
|
26
|
+
// Use object spread (not destructure defaults) so an explicit `undefined`
|
|
27
|
+
// override actually overrides the default value.
|
|
28
|
+
const data = { ...DEFAULTS, ...overrides };
|
|
29
|
+
useSelect.mockImplementation( ( cb ) =>
|
|
30
|
+
cb( () => ( {
|
|
31
|
+
getCurrentPostType: () => 'post',
|
|
32
|
+
getPostType: () => data.postType,
|
|
33
|
+
getPermalink: () => data.permalink,
|
|
34
|
+
isCurrentPostPublished: () => data.isPublished,
|
|
35
|
+
get: () => data.showIconLabels,
|
|
36
|
+
} ) )
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
describe( 'PostViewLink', () => {
|
|
41
|
+
it( 'renders the post type-specific view label when available', () => {
|
|
42
|
+
setupUseSelectMock();
|
|
43
|
+
render( <PostViewLink /> );
|
|
44
|
+
expect( screen.getByLabelText( 'View Post' ) ).toBeInTheDocument();
|
|
45
|
+
} );
|
|
46
|
+
|
|
47
|
+
it( 'falls back to "View post" without crashing when the post type has no labels', () => {
|
|
48
|
+
// See https://github.com/WordPress/gutenberg/issues/62918.
|
|
49
|
+
setupUseSelectMock( { postType: {} } );
|
|
50
|
+
render( <PostViewLink /> );
|
|
51
|
+
expect( screen.getByLabelText( 'View post' ) ).toBeInTheDocument();
|
|
52
|
+
} );
|
|
53
|
+
|
|
54
|
+
it( 'renders nothing if the post is not published', () => {
|
|
55
|
+
setupUseSelectMock( { isPublished: false } );
|
|
56
|
+
const { container } = render( <PostViewLink /> );
|
|
57
|
+
expect( container ).toBeEmptyDOMElement();
|
|
58
|
+
} );
|
|
59
|
+
|
|
60
|
+
it( 'renders nothing if no permalink is available', () => {
|
|
61
|
+
setupUseSelectMock( { permalink: undefined } );
|
|
62
|
+
const { container } = render( <PostViewLink /> );
|
|
63
|
+
expect( container ).toBeEmptyDOMElement();
|
|
64
|
+
} );
|
|
65
|
+
|
|
66
|
+
it( 'renders nothing while the post type has not loaded', () => {
|
|
67
|
+
setupUseSelectMock( { postType: undefined } );
|
|
68
|
+
const { container } = render( <PostViewLink /> );
|
|
69
|
+
expect( container ).toBeEmptyDOMElement();
|
|
70
|
+
} );
|
|
71
|
+
} );
|
|
@@ -380,7 +380,8 @@ export const ExperimentalEditorProvider = withRegistryProvider(
|
|
|
380
380
|
}, [ post.type, post.id, setEditedPost, removeNotice ] );
|
|
381
381
|
|
|
382
382
|
// Synchronize the editor settings as they change.
|
|
383
|
-
|
|
383
|
+
// Do it as a layout effect so that rendered UI with outdated settings is not painted.
|
|
384
|
+
useLayoutEffect( () => {
|
|
384
385
|
updateEditorSettings( settings );
|
|
385
386
|
}, [ settings, updateEditorSettings ] );
|
|
386
387
|
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
5
|
import { LEFT, RIGHT } from '@wordpress/keycodes';
|
|
6
6
|
import { __unstableMotion as motion } from '@wordpress/components';
|
|
7
|
-
// eslint-disable-next-line @wordpress/use-recommended-components -- `Tooltip` is not yet on the recommended `@wordpress/ui` allow-list; landing as a migration step ahead of the wider rollout.
|
|
8
7
|
import { Tooltip, VisuallyHidden } from '@wordpress/ui';
|
|
9
8
|
|
|
10
9
|
const DELTA_DISTANCE = 20; // The distance to resize per keydown in pixels.
|
|
@@ -15,8 +15,14 @@ import PostPanelRow from '../post-panel-row';
|
|
|
15
15
|
* @param {string} props.title Panel title.
|
|
16
16
|
* @param {Object} props.entries Map of key → diffWords parts arrays.
|
|
17
17
|
* @param {boolean} props.initialOpen Whether the panel starts open.
|
|
18
|
+
* @param {string} [props.className] Optional class for the content wrapper.
|
|
18
19
|
*/
|
|
19
|
-
export default function RevisionDiffPanel( {
|
|
20
|
+
export default function RevisionDiffPanel( {
|
|
21
|
+
title,
|
|
22
|
+
entries,
|
|
23
|
+
initialOpen,
|
|
24
|
+
className,
|
|
25
|
+
} ) {
|
|
20
26
|
if ( ! entries ) {
|
|
21
27
|
return null;
|
|
22
28
|
}
|
|
@@ -53,7 +59,7 @@ export default function RevisionDiffPanel( { title, entries, initialOpen } ) {
|
|
|
53
59
|
|
|
54
60
|
return (
|
|
55
61
|
<PanelBody title={ title } initialOpen={ initialOpen }>
|
|
56
|
-
{ fields }
|
|
62
|
+
<div className={ className }>{ fields }</div>
|
|
57
63
|
</PanelBody>
|
|
58
64
|
);
|
|
59
65
|
}
|