@wordpress/block-library 11.1.0 → 11.2.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 +32 -0
- package/build/accordion-heading/block.json +1 -0
- package/build/archives/block.json +3 -0
- package/build/audio/edit.cjs +2 -1
- package/build/audio/edit.cjs.map +2 -2
- package/build/avatar/block.json +4 -0
- package/build/avatar/edit.cjs +31 -1
- package/build/avatar/edit.cjs.map +3 -3
- package/build/button/block.json +6 -0
- package/build/button/edit.cjs +9 -6
- package/build/button/edit.cjs.map +2 -2
- package/build/buttons/block.json +6 -1
- package/build/code/block.json +4 -0
- package/build/column/edit.cjs +5 -0
- package/build/column/edit.cjs.map +2 -2
- package/build/columns/block.json +4 -0
- package/build/columns/edit.cjs +21 -112
- package/build/columns/edit.cjs.map +3 -3
- package/build/comments/edit/placeholder.cjs +95 -87
- package/build/comments/edit/placeholder.cjs.map +2 -2
- package/build/comments-pagination/block.json +11 -0
- package/build/cover/block.json +2 -1
- package/build/cover/edit/index.cjs +26 -5
- package/build/cover/edit/index.cjs.map +2 -2
- package/build/cover/edit/inspector-controls.cjs +4 -1
- package/build/cover/edit/inspector-controls.cjs.map +2 -2
- package/build/cover/embed-video-utils.cjs +9 -8
- package/build/cover/embed-video-utils.cjs.map +2 -2
- package/build/cover/view.cjs +21 -0
- package/build/cover/view.cjs.map +7 -0
- package/build/details/block.json +3 -0
- package/build/embed/block.json +6 -1
- package/build/file/block.json +5 -0
- package/build/footnotes/block.json +4 -0
- package/build/gallery/block.json +13 -0
- package/build/gallery/dynamic-gallery.cjs +32 -93
- package/build/gallery/dynamic-gallery.cjs.map +3 -3
- package/build/gallery/edit.cjs +103 -40
- package/build/gallery/edit.cjs.map +2 -2
- package/build/gallery/order-controls.cjs +107 -0
- package/build/gallery/order-controls.cjs.map +7 -0
- package/build/gallery/order-images.cjs +92 -0
- package/build/gallery/order-images.cjs.map +7 -0
- package/build/gallery/order-options.cjs +62 -0
- package/build/gallery/order-options.cjs.map +7 -0
- package/build/gallery/use-dynamic-gallery.cjs +1 -7
- package/build/gallery/use-dynamic-gallery.cjs.map +2 -2
- package/build/gallery/use-get-media.cjs +2 -3
- package/build/gallery/use-get-media.cjs.map +2 -2
- package/build/group/edit.cjs +3 -3
- package/build/group/edit.cjs.map +2 -2
- package/build/heading/block.json +5 -0
- package/build/home-link/block.json +12 -0
- package/build/icon/components/custom-inserter/index.cjs +3 -1
- package/build/icon/components/custom-inserter/index.cjs.map +2 -2
- package/build/icon/edit.cjs +49 -5
- package/build/icon/edit.cjs.map +2 -2
- package/build/image/use-open-image-media-editor-modal.cjs +32 -28
- package/build/image/use-open-image-media-editor-modal.cjs.map +2 -2
- package/build/image/view.cjs +44 -50
- package/build/image/view.cjs.map +2 -2
- package/build/latest-comments/block.json +10 -0
- package/build/latest-posts/block.json +4 -0
- package/build/list/block.json +12 -1
- package/build/list-item/block.json +8 -1
- package/build/list-item/index.cjs +4 -0
- package/build/list-item/index.cjs.map +3 -3
- package/build/loginout/block.json +4 -0
- package/build/math/block.json +4 -0
- package/build/media-text/block.json +18 -0
- package/build/navigation-link/link-ui/index.cjs +33 -19
- package/build/navigation-link/link-ui/index.cjs.map +2 -2
- package/build/navigation-link/shared/index.cjs +5 -0
- package/build/navigation-link/shared/index.cjs.map +2 -2
- package/build/navigation-link/shared/use-block-suggestions.cjs +141 -0
- package/build/navigation-link/shared/use-block-suggestions.cjs.map +7 -0
- package/build/page-list/block.json +4 -0
- package/build/paragraph/block.json +1 -0
- package/build/post-author-biography/block.json +1 -0
- package/build/post-comments-form/block.json +5 -0
- package/build/post-content/block.json +2 -1
- package/build/post-excerpt/block.json +4 -0
- package/build/post-featured-image/block.json +1 -0
- package/build/post-featured-image/edit.cjs +1 -1
- package/build/post-featured-image/edit.cjs.map +2 -2
- package/build/post-terms/block.json +4 -0
- package/build/post-time-to-read/block.json +4 -0
- package/build/post-title/block.json +4 -0
- package/build/preformatted/block.json +4 -0
- package/build/pullquote/block.json +2 -1
- package/build/query-no-results/block.json +4 -0
- package/build/query-pagination/block.json +17 -0
- package/build/query-total/block.json +4 -0
- package/build/quote/block.json +2 -0
- package/build/read-more/block.json +5 -0
- package/build/rss/block.json +4 -0
- package/build/search/block.json +2 -1
- package/build/site-tagline/block.json +4 -0
- package/build/site-title/block.json +4 -0
- package/build/social-links/block.json +1 -0
- package/build/tab-list/block.json +4 -0
- package/build/tab-list/edit.cjs +3 -1
- package/build/tab-list/edit.cjs.map +3 -3
- package/build/tab-list/save.cjs +3 -1
- package/build/tab-list/save.cjs.map +3 -3
- package/build/tab-panels/block.json +3 -0
- package/build/tabs/block.json +3 -0
- package/build/term-count/block.json +5 -0
- package/build/term-description/block.json +4 -0
- package/build/term-name/block.json +6 -1
- package/build/term-template/block.json +4 -0
- package/build/utils/waveform-utils.cjs +2 -2
- package/build/utils/waveform-utils.cjs.map +2 -2
- package/build/verse/block.json +4 -0
- package/build/video/block.json +7 -1
- package/build/video/edit.cjs +10 -2
- package/build/video/edit.cjs.map +2 -2
- package/build-module/accordion-heading/block.json +1 -0
- package/build-module/archives/block.json +3 -0
- package/build-module/audio/edit.mjs +2 -1
- package/build-module/audio/edit.mjs.map +2 -2
- package/build-module/avatar/block.json +4 -0
- package/build-module/avatar/edit.mjs +33 -2
- package/build-module/avatar/edit.mjs.map +2 -2
- package/build-module/button/block.json +6 -0
- package/build-module/button/edit.mjs +11 -7
- package/build-module/button/edit.mjs.map +2 -2
- package/build-module/buttons/block.json +6 -1
- package/build-module/code/block.json +4 -0
- package/build-module/column/edit.mjs +5 -0
- package/build-module/column/edit.mjs.map +2 -2
- package/build-module/columns/block.json +4 -0
- package/build-module/columns/edit.mjs +22 -122
- package/build-module/columns/edit.mjs.map +2 -2
- package/build-module/comments/edit/placeholder.mjs +95 -87
- package/build-module/comments/edit/placeholder.mjs.map +2 -2
- package/build-module/comments-pagination/block.json +11 -0
- package/build-module/cover/block.json +2 -1
- package/build-module/cover/edit/index.mjs +32 -6
- package/build-module/cover/edit/index.mjs.map +2 -2
- package/build-module/cover/edit/inspector-controls.mjs +5 -2
- package/build-module/cover/edit/inspector-controls.mjs.map +2 -2
- package/build-module/cover/embed-video-utils.mjs +9 -8
- package/build-module/cover/embed-video-utils.mjs.map +2 -2
- package/build-module/cover/view.mjs +19 -0
- package/build-module/cover/view.mjs.map +7 -0
- package/build-module/details/block.json +3 -0
- package/build-module/embed/block.json +6 -1
- package/build-module/file/block.json +5 -0
- package/build-module/footnotes/block.json +4 -0
- package/build-module/gallery/block.json +13 -0
- package/build-module/gallery/dynamic-gallery.mjs +33 -97
- package/build-module/gallery/dynamic-gallery.mjs.map +2 -2
- package/build-module/gallery/edit.mjs +110 -42
- package/build-module/gallery/edit.mjs.map +2 -2
- package/build-module/gallery/order-controls.mjs +87 -0
- package/build-module/gallery/order-controls.mjs.map +7 -0
- package/build-module/gallery/order-images.mjs +66 -0
- package/build-module/gallery/order-images.mjs.map +7 -0
- package/build-module/gallery/order-options.mjs +33 -0
- package/build-module/gallery/order-options.mjs.map +7 -0
- package/build-module/gallery/use-dynamic-gallery.mjs +1 -7
- package/build-module/gallery/use-dynamic-gallery.mjs.map +2 -2
- package/build-module/gallery/use-get-media.mjs +2 -3
- package/build-module/gallery/use-get-media.mjs.map +2 -2
- package/build-module/group/edit.mjs +4 -4
- package/build-module/group/edit.mjs.map +2 -2
- package/build-module/heading/block.json +5 -0
- package/build-module/home-link/block.json +12 -0
- package/build-module/icon/components/custom-inserter/index.mjs +3 -1
- package/build-module/icon/components/custom-inserter/index.mjs.map +2 -2
- package/build-module/icon/edit.mjs +50 -6
- package/build-module/icon/edit.mjs.map +2 -2
- package/build-module/image/use-open-image-media-editor-modal.mjs +32 -28
- package/build-module/image/use-open-image-media-editor-modal.mjs.map +2 -2
- package/build-module/image/view.mjs +44 -50
- package/build-module/image/view.mjs.map +2 -2
- package/build-module/latest-comments/block.json +10 -0
- package/build-module/latest-posts/block.json +4 -0
- package/build-module/list/block.json +12 -1
- package/build-module/list-item/block.json +8 -1
- package/build-module/list-item/index.mjs +4 -0
- package/build-module/list-item/index.mjs.map +2 -2
- package/build-module/loginout/block.json +4 -0
- package/build-module/math/block.json +4 -0
- package/build-module/media-text/block.json +18 -0
- package/build-module/navigation-link/link-ui/index.mjs +39 -20
- package/build-module/navigation-link/link-ui/index.mjs.map +2 -2
- package/build-module/navigation-link/shared/index.mjs +6 -0
- package/build-module/navigation-link/shared/index.mjs.map +2 -2
- package/build-module/navigation-link/shared/use-block-suggestions.mjs +120 -0
- package/build-module/navigation-link/shared/use-block-suggestions.mjs.map +7 -0
- package/build-module/page-list/block.json +4 -0
- package/build-module/paragraph/block.json +1 -0
- package/build-module/post-author-biography/block.json +1 -0
- package/build-module/post-comments-form/block.json +5 -0
- package/build-module/post-content/block.json +2 -1
- package/build-module/post-excerpt/block.json +4 -0
- package/build-module/post-featured-image/block.json +1 -0
- package/build-module/post-featured-image/edit.mjs +1 -1
- package/build-module/post-featured-image/edit.mjs.map +2 -2
- package/build-module/post-terms/block.json +4 -0
- package/build-module/post-time-to-read/block.json +4 -0
- package/build-module/post-title/block.json +4 -0
- package/build-module/preformatted/block.json +4 -0
- package/build-module/pullquote/block.json +2 -1
- package/build-module/query-no-results/block.json +4 -0
- package/build-module/query-pagination/block.json +17 -0
- package/build-module/query-total/block.json +4 -0
- package/build-module/quote/block.json +2 -0
- package/build-module/read-more/block.json +5 -0
- package/build-module/rss/block.json +4 -0
- package/build-module/search/block.json +2 -1
- package/build-module/site-tagline/block.json +4 -0
- package/build-module/site-title/block.json +4 -0
- package/build-module/social-links/block.json +1 -0
- package/build-module/tab-list/block.json +4 -0
- package/build-module/tab-list/edit.mjs +4 -1
- package/build-module/tab-list/edit.mjs.map +2 -2
- package/build-module/tab-list/save.mjs +4 -1
- package/build-module/tab-list/save.mjs.map +2 -2
- package/build-module/tab-panels/block.json +3 -0
- package/build-module/tabs/block.json +3 -0
- package/build-module/term-count/block.json +5 -0
- package/build-module/term-description/block.json +4 -0
- package/build-module/term-name/block.json +6 -1
- package/build-module/term-template/block.json +4 -0
- package/build-module/utils/waveform-utils.mjs +1 -1
- package/build-module/utils/waveform-utils.mjs.map +1 -1
- package/build-module/verse/block.json +4 -0
- package/build-module/video/block.json +7 -1
- package/build-module/video/edit.mjs +10 -2
- package/build-module/video/edit.mjs.map +2 -2
- package/build-style/avatar/editor-rtl.css +4 -0
- package/build-style/avatar/editor.css +4 -0
- package/build-style/comments-pagination/style-rtl.css +3 -0
- package/build-style/comments-pagination/style.css +3 -0
- package/build-style/common-rtl.css +32 -1
- package/build-style/common.css +35 -2
- package/build-style/editor-rtl.css +11 -4
- package/build-style/editor.css +11 -4
- package/build-style/embed/style-rtl.css +4 -1
- package/build-style/embed/style.css +4 -1
- package/build-style/gallery/editor-rtl.css +1 -3
- package/build-style/gallery/editor.css +1 -3
- package/build-style/image/style-rtl.css +11 -2
- package/build-style/image/style.css +11 -2
- package/build-style/media-text/style-rtl.css +4 -1
- package/build-style/media-text/style.css +4 -1
- package/build-style/query-pagination/style-rtl.css +3 -0
- package/build-style/query-pagination/style.css +3 -0
- package/build-style/style-rtl.css +70 -9
- package/build-style/style.css +73 -10
- package/build-style/table/editor-rtl.css +6 -1
- package/build-style/table/editor.css +6 -1
- package/build-style/table/style-rtl.css +4 -2
- package/build-style/table/style.css +4 -2
- package/build-style/tag-cloud/style-rtl.css +1 -1
- package/build-style/tag-cloud/style.css +1 -1
- package/build-style/verse/style-rtl.css +8 -1
- package/build-style/verse/style.css +8 -1
- package/build-types/gallery/order-controls.d.ts +58 -0
- package/build-types/gallery/order-controls.d.ts.map +1 -0
- package/build-types/gallery/order-options.d.ts +67 -0
- package/build-types/gallery/order-options.d.ts.map +1 -0
- package/package.json +44 -41
- package/src/accordion-heading/README.md +1 -0
- package/src/accordion-heading/block.json +1 -0
- package/src/archives/README.md +2 -0
- package/src/archives/block.json +3 -0
- package/src/audio/edit.jsx +2 -1
- package/src/avatar/README.md +2 -0
- package/src/avatar/block.json +4 -0
- package/src/avatar/edit.jsx +48 -2
- package/src/avatar/editor.scss +4 -0
- package/src/avatar/index.php +5 -3
- package/src/breadcrumbs/index.php +1 -1
- package/src/button/README.md +4 -0
- package/src/button/block.json +6 -0
- package/src/button/edit.jsx +47 -52
- package/src/button/index.php +47 -0
- package/src/buttons/README.md +4 -0
- package/src/buttons/block.json +6 -1
- package/src/code/README.md +3 -0
- package/src/code/block.json +4 -0
- package/src/column/edit.jsx +6 -0
- package/src/columns/README.md +3 -0
- package/src/columns/block.json +4 -0
- package/src/columns/edit.jsx +1 -131
- package/src/comments/edit/placeholder.jsx +5 -1
- package/src/comments-pagination/README.md +4 -0
- package/src/comments-pagination/block.json +11 -0
- package/src/comments-pagination/style.scss +3 -0
- package/src/common.scss +38 -0
- package/src/cover/README.md +1 -0
- package/src/cover/block.json +2 -1
- package/src/cover/edit/index.jsx +38 -6
- package/src/cover/edit/inspector-controls.jsx +10 -1
- package/src/cover/embed-video-utils.js +18 -10
- package/src/cover/index.php +44 -15
- package/src/cover/test/edit.browser.test.js +182 -2
- package/src/cover/test/embed-video-utils.test.js +48 -0
- package/src/cover/view.js +22 -0
- package/src/details/README.md +2 -0
- package/src/details/block.json +3 -0
- package/src/embed/README.md +4 -0
- package/src/embed/block.json +6 -1
- package/src/embed/style.scss +7 -1
- package/src/file/README.md +4 -0
- package/src/file/block.json +5 -0
- package/src/footnotes/README.md +3 -0
- package/src/footnotes/block.json +4 -0
- package/src/gallery/README.md +13 -0
- package/src/gallery/block.json +13 -0
- package/src/gallery/dynamic-gallery.jsx +11 -91
- package/src/gallery/edit.jsx +146 -47
- package/src/gallery/editor.scss +5 -9
- package/src/gallery/order-controls.tsx +143 -0
- package/src/gallery/order-images.js +111 -0
- package/src/gallery/order-options.ts +75 -0
- package/src/gallery/test/edit.jsdom.test.js +87 -10
- package/src/gallery/test/order-images.js +162 -0
- package/src/gallery/use-dynamic-gallery.js +1 -9
- package/src/gallery/use-get-media.js +7 -2
- package/src/group/edit.jsx +5 -5
- package/src/heading/README.md +4 -0
- package/src/heading/block.json +5 -0
- package/src/home-link/README.md +6 -0
- package/src/home-link/block.json +12 -0
- package/src/icon/components/custom-inserter/index.jsx +5 -1
- package/src/icon/edit.jsx +68 -7
- package/src/icon/index.php +1 -1
- package/src/image/index.php +3 -4
- package/src/image/style.scss +14 -2
- package/src/image/test/use-open-image-media-editor-modal.jsdom.test.js +122 -60
- package/src/image/use-open-image-media-editor-modal.js +37 -41
- package/src/image/view.js +64 -68
- package/src/latest-comments/README.md +3 -0
- package/src/latest-comments/block.json +10 -0
- package/src/latest-posts/README.md +3 -0
- package/src/latest-posts/block.json +4 -0
- package/src/list/README.md +6 -0
- package/src/list/block.json +12 -1
- package/src/list-item/README.md +6 -0
- package/src/list-item/block.json +8 -1
- package/src/list-item/index.js +5 -0
- package/src/loginout/README.md +3 -0
- package/src/loginout/block.json +4 -0
- package/src/math/README.md +3 -0
- package/src/math/block.json +4 -0
- package/src/media-text/README.md +17 -0
- package/src/media-text/block.json +18 -0
- package/src/media-text/style.scss +5 -1
- package/src/navigation/test/use-navigation-menu.jsdom.test.js +1 -1
- package/src/navigation-link/README.md +1 -1
- package/src/navigation-link/link-ui/index.jsx +60 -27
- package/src/navigation-link/link-ui/test/get-suggestions-query.jsdom.test.js +67 -0
- package/src/navigation-link/shared/index.js +4 -0
- package/src/navigation-link/shared/test/use-block-suggestions.jsdom.test.js +158 -0
- package/src/navigation-link/shared/test/use-entity-binding.jsdom.test.js +1 -7
- package/src/navigation-link/shared/use-block-suggestions.js +192 -0
- package/src/page-list/README.md +3 -0
- package/src/page-list/block.json +4 -0
- package/src/paragraph/README.md +1 -0
- package/src/paragraph/block.json +1 -0
- package/src/playlist/test/edit-component.jsdom.test.jsx +11 -11
- package/src/playlist-track/test/edit.jsdom.test.jsx +3 -3
- package/src/post-author-biography/README.md +1 -0
- package/src/post-author-biography/block.json +1 -0
- package/src/post-comments-form/README.md +3 -0
- package/src/post-comments-form/block.json +5 -0
- package/src/post-content/README.md +1 -0
- package/src/post-content/block.json +2 -1
- package/src/post-excerpt/README.md +3 -0
- package/src/post-excerpt/block.json +4 -0
- package/src/post-featured-image/block.json +1 -0
- package/src/post-featured-image/edit.jsx +2 -2
- package/src/post-terms/README.md +3 -0
- package/src/post-terms/block.json +4 -0
- package/src/post-time-to-read/README.md +3 -0
- package/src/post-time-to-read/block.json +4 -0
- package/src/post-title/README.md +3 -0
- package/src/post-title/block.json +4 -0
- package/src/preformatted/README.md +3 -0
- package/src/preformatted/block.json +4 -0
- package/src/pullquote/README.md +1 -0
- package/src/pullquote/block.json +2 -1
- package/src/query-no-results/README.md +3 -0
- package/src/query-no-results/block.json +4 -0
- package/src/query-pagination/README.md +4 -0
- package/src/query-pagination/block.json +17 -0
- package/src/query-pagination/style.scss +3 -0
- package/src/query-total/README.md +3 -0
- package/src/query-total/block.json +4 -0
- package/src/quote/README.md +2 -0
- package/src/quote/block.json +2 -0
- package/src/read-more/README.md +3 -0
- package/src/read-more/block.json +5 -0
- package/src/rss/README.md +3 -0
- package/src/rss/block.json +4 -0
- package/src/search/README.md +1 -0
- package/src/search/block.json +2 -1
- package/src/site-tagline/README.md +3 -0
- package/src/site-tagline/block.json +4 -0
- package/src/site-title/README.md +3 -0
- package/src/site-title/block.json +4 -0
- package/src/social-links/README.md +1 -0
- package/src/social-links/block.json +1 -0
- package/src/tab-list/README.md +2 -0
- package/src/tab-list/block.json +4 -0
- package/src/tab-list/edit.jsx +3 -0
- package/src/tab-list/save.jsx +3 -0
- package/src/tab-panels/README.md +2 -0
- package/src/tab-panels/block.json +3 -0
- package/src/table/editor.scss +8 -2
- package/src/table/style.scss +4 -4
- package/src/tabs/README.md +2 -0
- package/src/tabs/block.json +3 -0
- package/src/tag-cloud/style.scss +1 -1
- package/src/template-part/index.php +16 -3
- package/src/term-count/README.md +4 -0
- package/src/term-count/block.json +5 -0
- package/src/term-description/README.md +3 -0
- package/src/term-description/block.json +4 -0
- package/src/term-name/README.md +4 -0
- package/src/term-name/block.json +6 -1
- package/src/term-template/README.md +3 -0
- package/src/term-template/block.json +4 -0
- package/src/utils/test/waveform-player-auto-init.jsdom.test.js +25 -0
- package/src/utils/test/waveform-player-dependency.jsdom.test.js +7 -60
- package/src/utils/test/waveform-utils.browser.test.js +3 -15
- package/src/utils/waveform-utils.js +1 -1
- package/src/verse/README.md +4 -0
- package/src/verse/block.json +4 -0
- package/src/verse/style.scss +11 -2
- package/src/video/README.md +4 -0
- package/src/video/block.json +7 -1
- package/src/video/edit.jsx +13 -2
- package/build/columns/utils.cjs +0 -112
- package/build/columns/utils.cjs.map +0 -7
- package/build-module/columns/utils.mjs +0 -78
- package/build-module/columns/utils.mjs.map +0 -7
- package/src/columns/test/utils.js +0 -331
- package/src/columns/utils.js +0 -176
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/waveform-utils.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * Shared utilities for waveform audio player functionality.\n * Used by both the WaveformPlayer component (editor) and view.js (frontend).\n */\nimport { colord } from 'colord';\nimport WaveformPlayerLib from '@arraypress/waveform-player';\n\n/**\n * Configuration constants.\n * Note: DEFAULT_WAVEFORM_HEIGHT should match $waveform-player-height in style.scss.\n */\nconst DEFAULT_WAVEFORM_HEIGHT = 100;\nconst DEFAULT_SEEK_LABEL = 'Seek';\n\n/**\n * Get computed style for an element, using ownerDocument for iframe compatibility.\n *\n * @param {Element} element - The element to get styles from.\n * @return {CSSStyleDeclaration} The computed style.\n */\nfunction getComputedStyle( element ) {\n\treturn element.ownerDocument.defaultView.getComputedStyle( element );\n}\n\nfunction getTopLevelGradientParts( gradientValue ) {\n\tconst match = gradientValue?.trim().match( /^[\\w-]+-gradient\\((.*)\\)$/i );\n\tif ( ! match ) {\n\t\treturn [];\n\t}\n\n\tconst parts = [];\n\tlet depth = 0;\n\tlet current = '';\n\n\tfor ( const character of match[ 1 ] ) {\n\t\tif ( character === '(' ) {\n\t\t\t++depth;\n\t\t} else if ( character === ')' ) {\n\t\t\t--depth;\n\t\t}\n\n\t\tif ( character === ',' && depth === 0 ) {\n\t\t\tparts.push( current.trim() );\n\t\t\tcurrent = '';\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrent += character;\n\t}\n\n\tif ( current.trim() ) {\n\t\tparts.push( current.trim() );\n\t}\n\n\treturn parts;\n}\n\nfunction getLeadingColorFunction( value ) {\n\tconst match = value.match( /^([\\w-]+)\\(/ );\n\tif ( ! match ) {\n\t\treturn;\n\t}\n\n\tconst supportedFunctions = [\n\t\t'color',\n\t\t'color-mix',\n\t\t'hsl',\n\t\t'hsla',\n\t\t'hwb',\n\t\t'lab',\n\t\t'lch',\n\t\t'oklab',\n\t\t'oklch',\n\t\t'rgb',\n\t\t'rgba',\n\t\t'var',\n\t];\n\tif ( ! supportedFunctions.includes( match[ 1 ].toLowerCase() ) ) {\n\t\treturn;\n\t}\n\n\tlet depth = 0;\n\tlet foundOpeningParenthesis = false;\n\tfor ( let index = 0; index < value.length; index++ ) {\n\t\tconst character = value[ index ];\n\t\tif ( character === '(' ) {\n\t\t\tfoundOpeningParenthesis = true;\n\t\t\t++depth;\n\t\t} else if ( character === ')' ) {\n\t\t\t--depth;\n\t\t}\n\n\t\tif ( foundOpeningParenthesis && depth === 0 ) {\n\t\t\treturn value.slice( 0, index + 1 );\n\t\t}\n\t}\n}\n\nfunction getColorStopValue( gradientPart ) {\n\tconst colorFunction = getLeadingColorFunction( gradientPart );\n\tif ( colorFunction ) {\n\t\treturn colorFunction;\n\t}\n\n\tconst [ possibleColor ] = gradientPart.split( /\\s+/ );\n\tif ( colord( possibleColor ).isValid() ) {\n\t\treturn possibleColor;\n\t}\n}\n\nfunction getWaveformGradientDirection( gradientValue ) {\n\tconst parts = getTopLevelGradientParts( gradientValue );\n\tconst direction = parts[ 0 ];\n\tconst angleMatch = direction?.match( /^(-?\\d+(?:\\.\\d+)?)deg$/i );\n\tif ( angleMatch ) {\n\t\tconst angle = ( ( Number( angleMatch[ 1 ] ) % 360 ) + 360 ) % 360;\n\t\tif ( angle === 90 || angle === 270 ) {\n\t\t\treturn 'horizontal';\n\t\t}\n\t\tif ( angle === 0 || angle === 180 ) {\n\t\t\treturn 'vertical';\n\t\t}\n\t\treturn 'diagonal';\n\t}\n\n\tif ( ! direction?.startsWith( 'to ' ) ) {\n\t\treturn undefined;\n\t}\n\n\tconst sideOrCorner = direction.toLowerCase().replace( /^to\\s+/, '' );\n\tconst hasHorizontalSide =\n\t\tsideOrCorner.includes( 'left' ) || sideOrCorner.includes( 'right' );\n\tconst hasVerticalSide =\n\t\tsideOrCorner.includes( 'top' ) || sideOrCorner.includes( 'bottom' );\n\n\tif ( hasHorizontalSide && hasVerticalSide ) {\n\t\treturn 'diagonal';\n\t}\n\tif ( hasHorizontalSide ) {\n\t\treturn 'horizontal';\n\t}\n\tif ( hasVerticalSide ) {\n\t\treturn 'vertical';\n\t}\n}\n\nfunction resolveColorValue( element, colorValue ) {\n\tif ( ! colorValue || colord( colorValue ).isValid() ) {\n\t\treturn colorValue;\n\t}\n\n\tconst colorResolver = element.ownerDocument.createElement( 'span' );\n\tcolorResolver.style.color = colorValue;\n\tif ( ! colorResolver.style.color ) {\n\t\treturn colorValue;\n\t}\n\telement.appendChild( colorResolver );\n\n\tconst resolvedColor = getComputedStyle( colorResolver ).color;\n\tcolorResolver.remove();\n\n\treturn resolvedColor && colord( resolvedColor ).isValid()\n\t\t? resolvedColor\n\t\t: colorValue;\n}\n\nfunction getResolvedGradientStops( element, gradientValue ) {\n\tconst stops = getWaveformGradientStops( gradientValue )\n\t\t?.map( ( colorValue ) => resolveColorValue( element, colorValue ) )\n\t\t.filter( ( colorValue ) => colord( colorValue ).isValid() );\n\n\treturn stops?.length > 1 ? stops : undefined;\n}\n\nfunction applyAlpha( colorValue, alpha ) {\n\tif ( Array.isArray( colorValue ) ) {\n\t\treturn colorValue.map( ( color ) =>\n\t\t\tcolord( color ).alpha( alpha ).toRgbString()\n\t\t);\n\t}\n\treturn colord( colorValue ).alpha( alpha ).toRgbString();\n}\n\nfunction getRepresentativeColor( colorValue ) {\n\tif ( Array.isArray( colorValue ) ) {\n\t\treturn colorValue[ colorValue.length - 1 ];\n\t}\n\treturn colorValue;\n}\n\nexport function getWaveformGradientStops( gradientValue ) {\n\tconst stops = getTopLevelGradientParts( gradientValue )\n\t\t.map( getColorStopValue )\n\t\t.filter( Boolean );\n\n\treturn stops.length > 1 ? stops : undefined;\n}\n\nfunction serializeColorValue( colorValue ) {\n\treturn Array.isArray( colorValue )\n\t\t? JSON.stringify( colorValue )\n\t\t: colorValue;\n}\n\n/**\n * Get all colors needed for the waveform player based on the element's styles.\n *\n * @param {Element} element - The element to derive colors from.\n * @param {string} waveformColorValue - The base waveform color value to use.\n * @param {string} textColorValue - The text color value to use.\n * @param {string} waveformGradientValue - The waveform gradient value to use.\n * @return {Object} Object containing textColor, waveformColor, progressColor.\n */\nexport function getWaveformColors(\n\telement,\n\twaveformColorValue,\n\ttextColorValue,\n\twaveformGradientValue\n) {\n\tconst textColor = textColorValue || getComputedStyle( element ).color;\n\tconst waveformGradientStops = getResolvedGradientStops(\n\t\telement,\n\t\twaveformGradientValue\n\t);\n\tconst waveformBaseColor =\n\t\twaveformGradientStops || waveformColorValue || textColor;\n\tconst waveformColor = applyAlpha( waveformBaseColor, 0.3 );\n\tconst progressColor = applyAlpha( waveformBaseColor, 0.6 );\n\tconst waveformGradient = waveformGradientStops\n\t\t? getWaveformGradientDirection( waveformGradientValue )\n\t\t: undefined;\n\n\treturn {\n\t\ttextColor,\n\t\twaveformColor,\n\t\tprogressColor,\n\t\t...( waveformGradient && { waveformGradient } ),\n\t};\n}\n\n/**\n * Create a waveform container element with the specified attributes.\n *\n * @param {Object} options - The options for the container.\n * @param {string} options.url - The audio URL.\n * @param {string} options.title - The track title.\n * @param {string} options.artist - The track artist.\n * @param {string} options.artwork - The track image URL.\n * @param {string} options.waveformColor - The waveform bar color.\n * @param {string} options.progressColor - The progress indicator color.\n * @param {string} options.waveformGradient - The waveform gradient direction.\n * @param {string} options.buttonColor - The play button color.\n * @param {string} options.seekLabel - Accessible label for the seek control.\n * @param {string} options.seekValueText - Accessible value-text template for the seek control (e.g. '%1$s of %2$s').\n * @param {number} options.height - The waveform height in pixels.\n * @param {string} options.waveformStyle - The visualization style (bars, mirror, line, blocks, dots, seekbar).\n * @return {Element} The configured container element.\n */\nexport function createWaveformContainer( {\n\turl,\n\ttitle,\n\tartist,\n\tartwork,\n\twaveformColor,\n\tprogressColor,\n\twaveformGradient,\n\tbuttonColor,\n\tseekLabel,\n\tseekValueText,\n\theight = DEFAULT_WAVEFORM_HEIGHT,\n\twaveformStyle = 'bars',\n} ) {\n\tconst container = document.createElement( 'div' );\n\tcontainer.setAttribute( 'data-waveform-player', '' );\n\tcontainer.setAttribute( 'data-url', url );\n\tcontainer.setAttribute( 'data-height', String( height ) );\n\tcontainer.setAttribute( 'data-waveform-style', waveformStyle );\n\tcontainer.setAttribute(\n\t\t'data-waveform-color',\n\t\tserializeColorValue( waveformColor )\n\t);\n\tcontainer.setAttribute(\n\t\t'data-progress-color',\n\t\tserializeColorValue( progressColor )\n\t);\n\tif ( waveformGradient ) {\n\t\tcontainer.setAttribute( 'data-waveform-gradient', waveformGradient );\n\t}\n\tcontainer.setAttribute( 'data-button-color', buttonColor );\n\tcontainer.setAttribute(\n\t\t'data-seek-label',\n\t\tgetSeekControlLabel( seekLabel )\n\t);\n\t// The library formats the current time and duration and interpolates them\n\t// into this translated template for the seek slider's aria-valuetext.\n\tif ( seekValueText ) {\n\t\tcontainer.setAttribute( 'data-seek-value-text', seekValueText );\n\t}\n\tcontainer.setAttribute( 'data-text-color', buttonColor );\n\tcontainer.setAttribute( 'data-text-secondary-color', buttonColor );\n\n\tif ( title ) {\n\t\tcontainer.setAttribute( 'data-title', title );\n\t}\n\tif ( artist ) {\n\t\tcontainer.setAttribute( 'data-artist', artist );\n\t}\n\tif ( artwork ) {\n\t\tcontainer.setAttribute( 'data-artwork', artwork );\n\t}\n\treturn container;\n}\n\n/**\n * Apply custom styles to a generated waveform player.\n *\n * @param {Element} container - The generated player container.\n * @param {Object} styles - The player styles.\n * @param {string} styles.backgroundColor - The waveform area background color.\n * @param {string} styles.backgroundGradient - The waveform area background gradient.\n * @param {string} styles.textColor - The player text color.\n * @param {string} styles.playButtonColor - The play button color.\n * @param {string} styles.playButtonGradient - The play button gradient.\n */\nexport function applyWaveformPlayerStyles(\n\tcontainer,\n\t{\n\t\tbackgroundColor,\n\t\tbackgroundGradient,\n\t\ttextColor,\n\t\tplayButtonColor,\n\t\tplayButtonGradient,\n\t} = {}\n) {\n\tconst waveformContainer = container.querySelector( '.waveform-container' );\n\tconst playButton = container.querySelector( '.waveform-btn' );\n\tconst playButtonBaseColor = getRepresentativeColor(\n\t\tgetResolvedGradientStops( container, playButtonGradient ) ||\n\t\t\tplayButtonColor\n\t);\n\n\tif ( playButtonBaseColor ) {\n\t\tcontainer.style.setProperty(\n\t\t\t'--wfp-button-color',\n\t\t\tplayButtonBaseColor\n\t\t);\n\t} else {\n\t\tcontainer.style.removeProperty( '--wfp-button-color' );\n\t}\n\n\tif ( textColor ) {\n\t\tcontainer.style.setProperty( '--wfp-text-color', textColor );\n\t\tcontainer.style.setProperty( '--wfp-text-secondary-color', textColor );\n\t} else {\n\t\tcontainer.style.removeProperty( '--wfp-text-color' );\n\t\tcontainer.style.removeProperty( '--wfp-text-secondary-color' );\n\t}\n\n\tif ( playButton ) {\n\t\tif ( playButtonGradient ) {\n\t\t\tplayButton.style.background = playButtonGradient;\n\t\t} else {\n\t\t\tplayButton.style.removeProperty( 'background' );\n\t\t}\n\t}\n\n\tif ( waveformContainer ) {\n\t\tif ( backgroundGradient ) {\n\t\t\twaveformContainer.style.background = backgroundGradient;\n\t\t} else if ( backgroundColor ) {\n\t\t\twaveformContainer.style.removeProperty( 'background' );\n\t\t\twaveformContainer.style.backgroundColor = backgroundColor;\n\t\t} else {\n\t\t\twaveformContainer.style.removeProperty( 'background' );\n\t\t\twaveformContainer.style.removeProperty( 'background-color' );\n\t\t}\n\t}\n}\n\n/**\n * Apply contrasting color to SVG icon paths for visibility.\n * The icons should contrast with the button background.\n *\n * @param {Element} container - The waveform container element.\n * @param {string} buttonColor - The button background color.\n */\nexport function styleSvgIcons( container, buttonColor ) {\n\t// Compute a contrasting color for the icons based on button brightness.\n\tconst isButtonDark = colord( buttonColor ).isDark();\n\tconst iconColor = isButtonDark ? '#ffffff' : '#000000';\n\n\tconst svgPaths = container.querySelectorAll( 'svg path' );\n\tsvgPaths.forEach( ( path ) => {\n\t\tpath.style.fill = iconColor;\n\t} );\n}\n\n/**\n * Set up play button accessibility: aria-label that toggles on play/pause.\n *\n * @param {Element} container - The waveform container element.\n * @param {Object} labels - Button labels.\n * @param {string} labels.play - Label for the play state.\n * @param {string} labels.pause - Label for the pause state.\n */\nexport function setupPlayButtonAccessibility(\n\tcontainer,\n\t{ play: playLabel = 'Play', pause: pauseLabel = 'Pause' } = {}\n) {\n\tconst playBtn = container.querySelector( '.waveform-btn' );\n\tif ( ! playBtn ) {\n\t\treturn;\n\t}\n\n\tplayBtn.setAttribute( 'aria-label', playLabel );\n\n\tconst onPlay = () => playBtn.setAttribute( 'aria-label', pauseLabel );\n\tconst onPause = () => playBtn.setAttribute( 'aria-label', playLabel );\n\n\tcontainer.addEventListener( 'waveformplayer:play', onPlay );\n\tcontainer.addEventListener( 'waveformplayer:pause', onPause );\n\tcontainer.addEventListener( 'waveformplayer:ended', onPause );\n\n\treturn () => {\n\t\tcontainer.removeEventListener( 'waveformplayer:play', onPlay );\n\t\tcontainer.removeEventListener( 'waveformplayer:pause', onPause );\n\t\tcontainer.removeEventListener( 'waveformplayer:ended', onPause );\n\t};\n}\n\n/**\n * Get the accessible label for the waveform seek control.\n *\n * @param {string} label - Accessible label for the seek control.\n * @return {string} The provided label or translated fallback.\n */\nfunction getSeekControlLabel( label ) {\n\treturn label || DEFAULT_SEEK_LABEL;\n}\n\n/**\n * Update the waveform seek control label.\n *\n * @param {Object} instance - The WaveformPlayer instance.\n * @param {string} label - Accessible label for the seek control.\n */\nexport function updateSeekControlLabel( instance, label ) {\n\tconst seekLabel = getSeekControlLabel( label );\n\tinstance.options.seekLabel = seekLabel;\n\tinstance.applySeekLabel?.( seekLabel );\n\n\tconst seekControl = instance?.container?.querySelector(\n\t\t'.waveform-container'\n\t);\n\n\tif ( seekControl ) {\n\t\tseekControl.setAttribute( 'aria-label', seekLabel );\n\t}\n}\n\n/**\n * Show the current artwork as the play button background.\n *\n * @param {Element} container - The waveform player container element.\n * @param {string} artworkUrl - The track image URL.\n */\nexport function setupPlayButtonArtwork( container, artworkUrl ) {\n\tif ( ! artworkUrl ) {\n\t\tcontainer.classList.remove( 'has-play-button-artwork' );\n\t\tcontainer.style.removeProperty( '--wp--playlist--play-button-artwork' );\n\t\treturn;\n\t}\n\n\tcontainer.classList.add( 'has-play-button-artwork' );\n\tcontainer.style.setProperty(\n\t\t'--wp--playlist--play-button-artwork',\n\t\t`url(${ JSON.stringify( artworkUrl ) })`\n\t);\n}\n\n/**\n * Log play errors, filtering out expected AbortError.\n *\n * @param {Error} error - The error from play().\n */\nexport function logPlayError( error ) {\n\t// The browser throws AbortError when a play() promise is interrupted\n\t// by a subsequent pause() or a new audio source load (track change).\n\t// This is normal during rapid user interaction and safe to ignore.\n\tif ( error.name === 'AbortError' ) {\n\t\treturn;\n\t}\n\t// eslint-disable-next-line no-console\n\tconsole.error( 'Playlist play error:', error );\n}\n\n/**\n * Initialize a WaveformPlayer instance on an element.\n *\n * This is the shared core logic used by both the React component (editor)\n * and the Interactivity API (frontend).\n *\n * @param {Element} element - The container element (must be in DOM).\n * @param {Object} options - Configuration options.\n * @param {string} options.src - The audio file URL.\n * @param {string} options.title - The track title.\n * @param {string} options.artist - The artist name.\n * @param {string} options.image - The track image URL.\n * @param {string} options.imageAlt - The track image alt text.\n * @param {string} options.waveformColor - The waveform color.\n * @param {string} options.waveformGradient - The waveform gradient.\n * @param {string} options.textColor - The player text color.\n * @param {string} options.backgroundColor - The player background color.\n * @param {string} options.backgroundGradient - The player background gradient.\n * @param {boolean} options.autoPlay - Whether to auto-play when ready.\n * @param {Function} options.onEnded - Callback when track ends.\n * @param {Object} options.labels - Translated button labels.\n * @param {string} options.waveformStyle - Waveform style (bars, mirror, line, blocks, dots, seekbar).\n * @param {boolean} options.showPlayButtonArtwork - Whether to show artwork on the play button.\n * @return {Object} Object with instance, container, and destroy function.\n */\nexport function initWaveformPlayer(\n\telement,\n\t{\n\t\tsrc,\n\t\ttitle,\n\t\tartist,\n\t\timage,\n\t\timageAlt,\n\t\twaveformColor: waveformColorValue,\n\t\twaveformGradient: waveformGradientValue,\n\t\ttextColor: textColorValue,\n\t\tbackgroundColor,\n\t\tbackgroundGradient,\n\t\tautoPlay,\n\t\tonEnded,\n\t\tlabels,\n\t\twaveformStyle,\n\t\tshowPlayButtonArtwork = false,\n\t}\n) {\n\tconst playerArtwork = showPlayButtonArtwork ? undefined : image;\n\n\t// Get colors from computed styles.\n\tconst { textColor, waveformColor, progressColor, waveformGradient } =\n\t\tgetWaveformColors(\n\t\t\telement,\n\t\t\twaveformColorValue,\n\t\t\ttextColorValue,\n\t\t\twaveformGradientValue\n\t\t);\n\tconst waveformGradientStops = getResolvedGradientStops(\n\t\telement,\n\t\twaveformGradientValue\n\t);\n\tconst waveformButtonColor = getRepresentativeColor(\n\t\twaveformGradientStops || waveformColorValue\n\t);\n\n\t// Create the waveform container.\n\tconst container = createWaveformContainer( {\n\t\turl: src,\n\t\ttitle,\n\t\tartist,\n\t\tartwork: playerArtwork,\n\t\twaveformColor,\n\t\tprogressColor,\n\t\twaveformGradient,\n\t\tbuttonColor: textColor,\n\t\tseekLabel: title || labels?.seek,\n\t\tseekValueText: labels?.seekValueText,\n\t\twaveformStyle,\n\t} );\n\telement.appendChild( container );\n\n\t// Initialize the WaveformPlayer library. The library reads the translated\n\t// seek label and value-text templates from the container's data attributes\n\t// and owns the seek slider's accessible label and value text.\n\tconst instance = new WaveformPlayerLib( container );\n\tif ( instance.artworkEl ) {\n\t\tinstance.artworkEl.alt = imageAlt || '';\n\t}\n\tapplyWaveformPlayerStyles( container, {\n\t\tbackgroundColor,\n\t\tbackgroundGradient,\n\t\ttextColor,\n\t\tplayButtonColor: showPlayButtonArtwork\n\t\t\t? undefined\n\t\t\t: waveformButtonColor,\n\t\tplayButtonGradient: showPlayButtonArtwork\n\t\t\t? undefined\n\t\t\t: waveformGradientValue,\n\t} );\n\n\t// Set up event handlers.\n\tlet cleanupPlayButtonAccessibility;\n\tconst handlers = {\n\t\tready: () => {\n\t\t\tstyleSvgIcons( container, waveformButtonColor || textColor );\n\t\t\tif ( showPlayButtonArtwork ) {\n\t\t\t\tsetupPlayButtonArtwork( container, image );\n\t\t\t}\n\t\t\tcleanupPlayButtonAccessibility = setupPlayButtonAccessibility(\n\t\t\t\tcontainer,\n\t\t\t\tlabels\n\t\t\t);\n\t\t\tif ( autoPlay ) {\n\t\t\t\tinstance.play()?.catch( logPlayError );\n\t\t\t}\n\t\t},\n\t\tended: () => onEnded?.(),\n\t};\n\n\tcontainer.addEventListener( 'waveformplayer:ready', handlers.ready );\n\tcontainer.addEventListener( 'waveformplayer:ended', handlers.ended );\n\n\t// Return instance, container, and cleanup function.\n\treturn {\n\t\tinstance,\n\t\tcontainer,\n\t\tdestroy: () => {\n\t\t\tcleanupPlayButtonAccessibility?.();\n\t\t\tcontainer.removeEventListener(\n\t\t\t\t'waveformplayer:ready',\n\t\t\t\thandlers.ready\n\t\t\t);\n\t\t\tcontainer.removeEventListener(\n\t\t\t\t'waveformplayer:ended',\n\t\t\t\thandlers.ended\n\t\t\t);\n\t\t\tinstance.destroy();\n\t\t\tcontainer.remove();\n\t\t},\n\t};\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,oBAAuB;AACvB,
|
|
4
|
+
"sourcesContent": ["/**\n * Shared utilities for waveform audio player functionality.\n * Used by both the WaveformPlayer component (editor) and view.js (frontend).\n */\nimport { colord } from 'colord';\nimport WaveformPlayerLib from '@arraypress/waveform-player/no-autoinit';\n\n/**\n * Configuration constants.\n * Note: DEFAULT_WAVEFORM_HEIGHT should match $waveform-player-height in style.scss.\n */\nconst DEFAULT_WAVEFORM_HEIGHT = 100;\nconst DEFAULT_SEEK_LABEL = 'Seek';\n\n/**\n * Get computed style for an element, using ownerDocument for iframe compatibility.\n *\n * @param {Element} element - The element to get styles from.\n * @return {CSSStyleDeclaration} The computed style.\n */\nfunction getComputedStyle( element ) {\n\treturn element.ownerDocument.defaultView.getComputedStyle( element );\n}\n\nfunction getTopLevelGradientParts( gradientValue ) {\n\tconst match = gradientValue?.trim().match( /^[\\w-]+-gradient\\((.*)\\)$/i );\n\tif ( ! match ) {\n\t\treturn [];\n\t}\n\n\tconst parts = [];\n\tlet depth = 0;\n\tlet current = '';\n\n\tfor ( const character of match[ 1 ] ) {\n\t\tif ( character === '(' ) {\n\t\t\t++depth;\n\t\t} else if ( character === ')' ) {\n\t\t\t--depth;\n\t\t}\n\n\t\tif ( character === ',' && depth === 0 ) {\n\t\t\tparts.push( current.trim() );\n\t\t\tcurrent = '';\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrent += character;\n\t}\n\n\tif ( current.trim() ) {\n\t\tparts.push( current.trim() );\n\t}\n\n\treturn parts;\n}\n\nfunction getLeadingColorFunction( value ) {\n\tconst match = value.match( /^([\\w-]+)\\(/ );\n\tif ( ! match ) {\n\t\treturn;\n\t}\n\n\tconst supportedFunctions = [\n\t\t'color',\n\t\t'color-mix',\n\t\t'hsl',\n\t\t'hsla',\n\t\t'hwb',\n\t\t'lab',\n\t\t'lch',\n\t\t'oklab',\n\t\t'oklch',\n\t\t'rgb',\n\t\t'rgba',\n\t\t'var',\n\t];\n\tif ( ! supportedFunctions.includes( match[ 1 ].toLowerCase() ) ) {\n\t\treturn;\n\t}\n\n\tlet depth = 0;\n\tlet foundOpeningParenthesis = false;\n\tfor ( let index = 0; index < value.length; index++ ) {\n\t\tconst character = value[ index ];\n\t\tif ( character === '(' ) {\n\t\t\tfoundOpeningParenthesis = true;\n\t\t\t++depth;\n\t\t} else if ( character === ')' ) {\n\t\t\t--depth;\n\t\t}\n\n\t\tif ( foundOpeningParenthesis && depth === 0 ) {\n\t\t\treturn value.slice( 0, index + 1 );\n\t\t}\n\t}\n}\n\nfunction getColorStopValue( gradientPart ) {\n\tconst colorFunction = getLeadingColorFunction( gradientPart );\n\tif ( colorFunction ) {\n\t\treturn colorFunction;\n\t}\n\n\tconst [ possibleColor ] = gradientPart.split( /\\s+/ );\n\tif ( colord( possibleColor ).isValid() ) {\n\t\treturn possibleColor;\n\t}\n}\n\nfunction getWaveformGradientDirection( gradientValue ) {\n\tconst parts = getTopLevelGradientParts( gradientValue );\n\tconst direction = parts[ 0 ];\n\tconst angleMatch = direction?.match( /^(-?\\d+(?:\\.\\d+)?)deg$/i );\n\tif ( angleMatch ) {\n\t\tconst angle = ( ( Number( angleMatch[ 1 ] ) % 360 ) + 360 ) % 360;\n\t\tif ( angle === 90 || angle === 270 ) {\n\t\t\treturn 'horizontal';\n\t\t}\n\t\tif ( angle === 0 || angle === 180 ) {\n\t\t\treturn 'vertical';\n\t\t}\n\t\treturn 'diagonal';\n\t}\n\n\tif ( ! direction?.startsWith( 'to ' ) ) {\n\t\treturn undefined;\n\t}\n\n\tconst sideOrCorner = direction.toLowerCase().replace( /^to\\s+/, '' );\n\tconst hasHorizontalSide =\n\t\tsideOrCorner.includes( 'left' ) || sideOrCorner.includes( 'right' );\n\tconst hasVerticalSide =\n\t\tsideOrCorner.includes( 'top' ) || sideOrCorner.includes( 'bottom' );\n\n\tif ( hasHorizontalSide && hasVerticalSide ) {\n\t\treturn 'diagonal';\n\t}\n\tif ( hasHorizontalSide ) {\n\t\treturn 'horizontal';\n\t}\n\tif ( hasVerticalSide ) {\n\t\treturn 'vertical';\n\t}\n}\n\nfunction resolveColorValue( element, colorValue ) {\n\tif ( ! colorValue || colord( colorValue ).isValid() ) {\n\t\treturn colorValue;\n\t}\n\n\tconst colorResolver = element.ownerDocument.createElement( 'span' );\n\tcolorResolver.style.color = colorValue;\n\tif ( ! colorResolver.style.color ) {\n\t\treturn colorValue;\n\t}\n\telement.appendChild( colorResolver );\n\n\tconst resolvedColor = getComputedStyle( colorResolver ).color;\n\tcolorResolver.remove();\n\n\treturn resolvedColor && colord( resolvedColor ).isValid()\n\t\t? resolvedColor\n\t\t: colorValue;\n}\n\nfunction getResolvedGradientStops( element, gradientValue ) {\n\tconst stops = getWaveformGradientStops( gradientValue )\n\t\t?.map( ( colorValue ) => resolveColorValue( element, colorValue ) )\n\t\t.filter( ( colorValue ) => colord( colorValue ).isValid() );\n\n\treturn stops?.length > 1 ? stops : undefined;\n}\n\nfunction applyAlpha( colorValue, alpha ) {\n\tif ( Array.isArray( colorValue ) ) {\n\t\treturn colorValue.map( ( color ) =>\n\t\t\tcolord( color ).alpha( alpha ).toRgbString()\n\t\t);\n\t}\n\treturn colord( colorValue ).alpha( alpha ).toRgbString();\n}\n\nfunction getRepresentativeColor( colorValue ) {\n\tif ( Array.isArray( colorValue ) ) {\n\t\treturn colorValue[ colorValue.length - 1 ];\n\t}\n\treturn colorValue;\n}\n\nexport function getWaveformGradientStops( gradientValue ) {\n\tconst stops = getTopLevelGradientParts( gradientValue )\n\t\t.map( getColorStopValue )\n\t\t.filter( Boolean );\n\n\treturn stops.length > 1 ? stops : undefined;\n}\n\nfunction serializeColorValue( colorValue ) {\n\treturn Array.isArray( colorValue )\n\t\t? JSON.stringify( colorValue )\n\t\t: colorValue;\n}\n\n/**\n * Get all colors needed for the waveform player based on the element's styles.\n *\n * @param {Element} element - The element to derive colors from.\n * @param {string} waveformColorValue - The base waveform color value to use.\n * @param {string} textColorValue - The text color value to use.\n * @param {string} waveformGradientValue - The waveform gradient value to use.\n * @return {Object} Object containing textColor, waveformColor, progressColor.\n */\nexport function getWaveformColors(\n\telement,\n\twaveformColorValue,\n\ttextColorValue,\n\twaveformGradientValue\n) {\n\tconst textColor = textColorValue || getComputedStyle( element ).color;\n\tconst waveformGradientStops = getResolvedGradientStops(\n\t\telement,\n\t\twaveformGradientValue\n\t);\n\tconst waveformBaseColor =\n\t\twaveformGradientStops || waveformColorValue || textColor;\n\tconst waveformColor = applyAlpha( waveformBaseColor, 0.3 );\n\tconst progressColor = applyAlpha( waveformBaseColor, 0.6 );\n\tconst waveformGradient = waveformGradientStops\n\t\t? getWaveformGradientDirection( waveformGradientValue )\n\t\t: undefined;\n\n\treturn {\n\t\ttextColor,\n\t\twaveformColor,\n\t\tprogressColor,\n\t\t...( waveformGradient && { waveformGradient } ),\n\t};\n}\n\n/**\n * Create a waveform container element with the specified attributes.\n *\n * @param {Object} options - The options for the container.\n * @param {string} options.url - The audio URL.\n * @param {string} options.title - The track title.\n * @param {string} options.artist - The track artist.\n * @param {string} options.artwork - The track image URL.\n * @param {string} options.waveformColor - The waveform bar color.\n * @param {string} options.progressColor - The progress indicator color.\n * @param {string} options.waveformGradient - The waveform gradient direction.\n * @param {string} options.buttonColor - The play button color.\n * @param {string} options.seekLabel - Accessible label for the seek control.\n * @param {string} options.seekValueText - Accessible value-text template for the seek control (e.g. '%1$s of %2$s').\n * @param {number} options.height - The waveform height in pixels.\n * @param {string} options.waveformStyle - The visualization style (bars, mirror, line, blocks, dots, seekbar).\n * @return {Element} The configured container element.\n */\nexport function createWaveformContainer( {\n\turl,\n\ttitle,\n\tartist,\n\tartwork,\n\twaveformColor,\n\tprogressColor,\n\twaveformGradient,\n\tbuttonColor,\n\tseekLabel,\n\tseekValueText,\n\theight = DEFAULT_WAVEFORM_HEIGHT,\n\twaveformStyle = 'bars',\n} ) {\n\tconst container = document.createElement( 'div' );\n\tcontainer.setAttribute( 'data-waveform-player', '' );\n\tcontainer.setAttribute( 'data-url', url );\n\tcontainer.setAttribute( 'data-height', String( height ) );\n\tcontainer.setAttribute( 'data-waveform-style', waveformStyle );\n\tcontainer.setAttribute(\n\t\t'data-waveform-color',\n\t\tserializeColorValue( waveformColor )\n\t);\n\tcontainer.setAttribute(\n\t\t'data-progress-color',\n\t\tserializeColorValue( progressColor )\n\t);\n\tif ( waveformGradient ) {\n\t\tcontainer.setAttribute( 'data-waveform-gradient', waveformGradient );\n\t}\n\tcontainer.setAttribute( 'data-button-color', buttonColor );\n\tcontainer.setAttribute(\n\t\t'data-seek-label',\n\t\tgetSeekControlLabel( seekLabel )\n\t);\n\t// The library formats the current time and duration and interpolates them\n\t// into this translated template for the seek slider's aria-valuetext.\n\tif ( seekValueText ) {\n\t\tcontainer.setAttribute( 'data-seek-value-text', seekValueText );\n\t}\n\tcontainer.setAttribute( 'data-text-color', buttonColor );\n\tcontainer.setAttribute( 'data-text-secondary-color', buttonColor );\n\n\tif ( title ) {\n\t\tcontainer.setAttribute( 'data-title', title );\n\t}\n\tif ( artist ) {\n\t\tcontainer.setAttribute( 'data-artist', artist );\n\t}\n\tif ( artwork ) {\n\t\tcontainer.setAttribute( 'data-artwork', artwork );\n\t}\n\treturn container;\n}\n\n/**\n * Apply custom styles to a generated waveform player.\n *\n * @param {Element} container - The generated player container.\n * @param {Object} styles - The player styles.\n * @param {string} styles.backgroundColor - The waveform area background color.\n * @param {string} styles.backgroundGradient - The waveform area background gradient.\n * @param {string} styles.textColor - The player text color.\n * @param {string} styles.playButtonColor - The play button color.\n * @param {string} styles.playButtonGradient - The play button gradient.\n */\nexport function applyWaveformPlayerStyles(\n\tcontainer,\n\t{\n\t\tbackgroundColor,\n\t\tbackgroundGradient,\n\t\ttextColor,\n\t\tplayButtonColor,\n\t\tplayButtonGradient,\n\t} = {}\n) {\n\tconst waveformContainer = container.querySelector( '.waveform-container' );\n\tconst playButton = container.querySelector( '.waveform-btn' );\n\tconst playButtonBaseColor = getRepresentativeColor(\n\t\tgetResolvedGradientStops( container, playButtonGradient ) ||\n\t\t\tplayButtonColor\n\t);\n\n\tif ( playButtonBaseColor ) {\n\t\tcontainer.style.setProperty(\n\t\t\t'--wfp-button-color',\n\t\t\tplayButtonBaseColor\n\t\t);\n\t} else {\n\t\tcontainer.style.removeProperty( '--wfp-button-color' );\n\t}\n\n\tif ( textColor ) {\n\t\tcontainer.style.setProperty( '--wfp-text-color', textColor );\n\t\tcontainer.style.setProperty( '--wfp-text-secondary-color', textColor );\n\t} else {\n\t\tcontainer.style.removeProperty( '--wfp-text-color' );\n\t\tcontainer.style.removeProperty( '--wfp-text-secondary-color' );\n\t}\n\n\tif ( playButton ) {\n\t\tif ( playButtonGradient ) {\n\t\t\tplayButton.style.background = playButtonGradient;\n\t\t} else {\n\t\t\tplayButton.style.removeProperty( 'background' );\n\t\t}\n\t}\n\n\tif ( waveformContainer ) {\n\t\tif ( backgroundGradient ) {\n\t\t\twaveformContainer.style.background = backgroundGradient;\n\t\t} else if ( backgroundColor ) {\n\t\t\twaveformContainer.style.removeProperty( 'background' );\n\t\t\twaveformContainer.style.backgroundColor = backgroundColor;\n\t\t} else {\n\t\t\twaveformContainer.style.removeProperty( 'background' );\n\t\t\twaveformContainer.style.removeProperty( 'background-color' );\n\t\t}\n\t}\n}\n\n/**\n * Apply contrasting color to SVG icon paths for visibility.\n * The icons should contrast with the button background.\n *\n * @param {Element} container - The waveform container element.\n * @param {string} buttonColor - The button background color.\n */\nexport function styleSvgIcons( container, buttonColor ) {\n\t// Compute a contrasting color for the icons based on button brightness.\n\tconst isButtonDark = colord( buttonColor ).isDark();\n\tconst iconColor = isButtonDark ? '#ffffff' : '#000000';\n\n\tconst svgPaths = container.querySelectorAll( 'svg path' );\n\tsvgPaths.forEach( ( path ) => {\n\t\tpath.style.fill = iconColor;\n\t} );\n}\n\n/**\n * Set up play button accessibility: aria-label that toggles on play/pause.\n *\n * @param {Element} container - The waveform container element.\n * @param {Object} labels - Button labels.\n * @param {string} labels.play - Label for the play state.\n * @param {string} labels.pause - Label for the pause state.\n */\nexport function setupPlayButtonAccessibility(\n\tcontainer,\n\t{ play: playLabel = 'Play', pause: pauseLabel = 'Pause' } = {}\n) {\n\tconst playBtn = container.querySelector( '.waveform-btn' );\n\tif ( ! playBtn ) {\n\t\treturn;\n\t}\n\n\tplayBtn.setAttribute( 'aria-label', playLabel );\n\n\tconst onPlay = () => playBtn.setAttribute( 'aria-label', pauseLabel );\n\tconst onPause = () => playBtn.setAttribute( 'aria-label', playLabel );\n\n\tcontainer.addEventListener( 'waveformplayer:play', onPlay );\n\tcontainer.addEventListener( 'waveformplayer:pause', onPause );\n\tcontainer.addEventListener( 'waveformplayer:ended', onPause );\n\n\treturn () => {\n\t\tcontainer.removeEventListener( 'waveformplayer:play', onPlay );\n\t\tcontainer.removeEventListener( 'waveformplayer:pause', onPause );\n\t\tcontainer.removeEventListener( 'waveformplayer:ended', onPause );\n\t};\n}\n\n/**\n * Get the accessible label for the waveform seek control.\n *\n * @param {string} label - Accessible label for the seek control.\n * @return {string} The provided label or translated fallback.\n */\nfunction getSeekControlLabel( label ) {\n\treturn label || DEFAULT_SEEK_LABEL;\n}\n\n/**\n * Update the waveform seek control label.\n *\n * @param {Object} instance - The WaveformPlayer instance.\n * @param {string} label - Accessible label for the seek control.\n */\nexport function updateSeekControlLabel( instance, label ) {\n\tconst seekLabel = getSeekControlLabel( label );\n\tinstance.options.seekLabel = seekLabel;\n\tinstance.applySeekLabel?.( seekLabel );\n\n\tconst seekControl = instance?.container?.querySelector(\n\t\t'.waveform-container'\n\t);\n\n\tif ( seekControl ) {\n\t\tseekControl.setAttribute( 'aria-label', seekLabel );\n\t}\n}\n\n/**\n * Show the current artwork as the play button background.\n *\n * @param {Element} container - The waveform player container element.\n * @param {string} artworkUrl - The track image URL.\n */\nexport function setupPlayButtonArtwork( container, artworkUrl ) {\n\tif ( ! artworkUrl ) {\n\t\tcontainer.classList.remove( 'has-play-button-artwork' );\n\t\tcontainer.style.removeProperty( '--wp--playlist--play-button-artwork' );\n\t\treturn;\n\t}\n\n\tcontainer.classList.add( 'has-play-button-artwork' );\n\tcontainer.style.setProperty(\n\t\t'--wp--playlist--play-button-artwork',\n\t\t`url(${ JSON.stringify( artworkUrl ) })`\n\t);\n}\n\n/**\n * Log play errors, filtering out expected AbortError.\n *\n * @param {Error} error - The error from play().\n */\nexport function logPlayError( error ) {\n\t// The browser throws AbortError when a play() promise is interrupted\n\t// by a subsequent pause() or a new audio source load (track change).\n\t// This is normal during rapid user interaction and safe to ignore.\n\tif ( error.name === 'AbortError' ) {\n\t\treturn;\n\t}\n\t// eslint-disable-next-line no-console\n\tconsole.error( 'Playlist play error:', error );\n}\n\n/**\n * Initialize a WaveformPlayer instance on an element.\n *\n * This is the shared core logic used by both the React component (editor)\n * and the Interactivity API (frontend).\n *\n * @param {Element} element - The container element (must be in DOM).\n * @param {Object} options - Configuration options.\n * @param {string} options.src - The audio file URL.\n * @param {string} options.title - The track title.\n * @param {string} options.artist - The artist name.\n * @param {string} options.image - The track image URL.\n * @param {string} options.imageAlt - The track image alt text.\n * @param {string} options.waveformColor - The waveform color.\n * @param {string} options.waveformGradient - The waveform gradient.\n * @param {string} options.textColor - The player text color.\n * @param {string} options.backgroundColor - The player background color.\n * @param {string} options.backgroundGradient - The player background gradient.\n * @param {boolean} options.autoPlay - Whether to auto-play when ready.\n * @param {Function} options.onEnded - Callback when track ends.\n * @param {Object} options.labels - Translated button labels.\n * @param {string} options.waveformStyle - Waveform style (bars, mirror, line, blocks, dots, seekbar).\n * @param {boolean} options.showPlayButtonArtwork - Whether to show artwork on the play button.\n * @return {Object} Object with instance, container, and destroy function.\n */\nexport function initWaveformPlayer(\n\telement,\n\t{\n\t\tsrc,\n\t\ttitle,\n\t\tartist,\n\t\timage,\n\t\timageAlt,\n\t\twaveformColor: waveformColorValue,\n\t\twaveformGradient: waveformGradientValue,\n\t\ttextColor: textColorValue,\n\t\tbackgroundColor,\n\t\tbackgroundGradient,\n\t\tautoPlay,\n\t\tonEnded,\n\t\tlabels,\n\t\twaveformStyle,\n\t\tshowPlayButtonArtwork = false,\n\t}\n) {\n\tconst playerArtwork = showPlayButtonArtwork ? undefined : image;\n\n\t// Get colors from computed styles.\n\tconst { textColor, waveformColor, progressColor, waveformGradient } =\n\t\tgetWaveformColors(\n\t\t\telement,\n\t\t\twaveformColorValue,\n\t\t\ttextColorValue,\n\t\t\twaveformGradientValue\n\t\t);\n\tconst waveformGradientStops = getResolvedGradientStops(\n\t\telement,\n\t\twaveformGradientValue\n\t);\n\tconst waveformButtonColor = getRepresentativeColor(\n\t\twaveformGradientStops || waveformColorValue\n\t);\n\n\t// Create the waveform container.\n\tconst container = createWaveformContainer( {\n\t\turl: src,\n\t\ttitle,\n\t\tartist,\n\t\tartwork: playerArtwork,\n\t\twaveformColor,\n\t\tprogressColor,\n\t\twaveformGradient,\n\t\tbuttonColor: textColor,\n\t\tseekLabel: title || labels?.seek,\n\t\tseekValueText: labels?.seekValueText,\n\t\twaveformStyle,\n\t} );\n\telement.appendChild( container );\n\n\t// Initialize the WaveformPlayer library. The library reads the translated\n\t// seek label and value-text templates from the container's data attributes\n\t// and owns the seek slider's accessible label and value text.\n\tconst instance = new WaveformPlayerLib( container );\n\tif ( instance.artworkEl ) {\n\t\tinstance.artworkEl.alt = imageAlt || '';\n\t}\n\tapplyWaveformPlayerStyles( container, {\n\t\tbackgroundColor,\n\t\tbackgroundGradient,\n\t\ttextColor,\n\t\tplayButtonColor: showPlayButtonArtwork\n\t\t\t? undefined\n\t\t\t: waveformButtonColor,\n\t\tplayButtonGradient: showPlayButtonArtwork\n\t\t\t? undefined\n\t\t\t: waveformGradientValue,\n\t} );\n\n\t// Set up event handlers.\n\tlet cleanupPlayButtonAccessibility;\n\tconst handlers = {\n\t\tready: () => {\n\t\t\tstyleSvgIcons( container, waveformButtonColor || textColor );\n\t\t\tif ( showPlayButtonArtwork ) {\n\t\t\t\tsetupPlayButtonArtwork( container, image );\n\t\t\t}\n\t\t\tcleanupPlayButtonAccessibility = setupPlayButtonAccessibility(\n\t\t\t\tcontainer,\n\t\t\t\tlabels\n\t\t\t);\n\t\t\tif ( autoPlay ) {\n\t\t\t\tinstance.play()?.catch( logPlayError );\n\t\t\t}\n\t\t},\n\t\tended: () => onEnded?.(),\n\t};\n\n\tcontainer.addEventListener( 'waveformplayer:ready', handlers.ready );\n\tcontainer.addEventListener( 'waveformplayer:ended', handlers.ended );\n\n\t// Return instance, container, and cleanup function.\n\treturn {\n\t\tinstance,\n\t\tcontainer,\n\t\tdestroy: () => {\n\t\t\tcleanupPlayButtonAccessibility?.();\n\t\t\tcontainer.removeEventListener(\n\t\t\t\t'waveformplayer:ready',\n\t\t\t\thandlers.ready\n\t\t\t);\n\t\t\tcontainer.removeEventListener(\n\t\t\t\t'waveformplayer:ended',\n\t\t\t\thandlers.ended\n\t\t\t);\n\t\t\tinstance.destroy();\n\t\t\tcontainer.remove();\n\t\t},\n\t};\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["WaveformPlayerLib"]
|
|
7
7
|
}
|
package/build/verse/block.json
CHANGED
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dimensions": {
|
|
39
39
|
"minHeight": true,
|
|
40
|
+
"minWidth": true,
|
|
40
41
|
"__experimentalDefaultControls": {
|
|
41
42
|
"minHeight": false
|
|
42
43
|
}
|
|
@@ -46,12 +47,15 @@
|
|
|
46
47
|
"__experimentalFontFamily": true,
|
|
47
48
|
"lineHeight": true,
|
|
48
49
|
"textAlign": true,
|
|
50
|
+
"textColumns": true,
|
|
51
|
+
"textIndent": true,
|
|
49
52
|
"__experimentalFontStyle": true,
|
|
50
53
|
"__experimentalFontWeight": true,
|
|
51
54
|
"__experimentalLetterSpacing": true,
|
|
52
55
|
"__experimentalTextTransform": true,
|
|
53
56
|
"__experimentalTextDecoration": true,
|
|
54
57
|
"__experimentalWritingMode": true,
|
|
58
|
+
"fitText": true,
|
|
55
59
|
"__experimentalDefaultControls": {
|
|
56
60
|
"fontSize": true
|
|
57
61
|
}
|
package/build/video/block.json
CHANGED
|
@@ -91,6 +91,9 @@
|
|
|
91
91
|
"supports": {
|
|
92
92
|
"anchor": true,
|
|
93
93
|
"align": true,
|
|
94
|
+
"filter": {
|
|
95
|
+
"duotone": true
|
|
96
|
+
},
|
|
94
97
|
"spacing": {
|
|
95
98
|
"margin": true,
|
|
96
99
|
"padding": true,
|
|
@@ -107,7 +110,10 @@
|
|
|
107
110
|
}
|
|
108
111
|
},
|
|
109
112
|
"selectors": {
|
|
110
|
-
"shadow": ".wp-block-video video"
|
|
113
|
+
"shadow": ".wp-block-video video",
|
|
114
|
+
"filter": {
|
|
115
|
+
"duotone": ".wp-block-video video"
|
|
116
|
+
}
|
|
111
117
|
},
|
|
112
118
|
"editorStyle": "wp-block-video-editor",
|
|
113
119
|
"style": "wp-block-video"
|
package/build/video/edit.cjs
CHANGED
|
@@ -38,7 +38,9 @@ var import_blob = require("@wordpress/blob");
|
|
|
38
38
|
var import_components = require("@wordpress/components");
|
|
39
39
|
var import_block_editor = require("@wordpress/block-editor");
|
|
40
40
|
var import_element = require("@wordpress/element");
|
|
41
|
+
var import_compose = require("@wordpress/compose");
|
|
41
42
|
var import_i18n = require("@wordpress/i18n");
|
|
43
|
+
var import_react_inert_value = require("@wordpress/react-inert-value");
|
|
42
44
|
var import_data = require("@wordpress/data");
|
|
43
45
|
var import_icons = require("@wordpress/icons");
|
|
44
46
|
var import_notices = require("@wordpress/notices");
|
|
@@ -83,6 +85,7 @@ function VideoEdit({
|
|
|
83
85
|
const dropdownMenuProps = (0, import_hooks.useToolsPanelDropdownMenuProps)();
|
|
84
86
|
const blockEditingMode = (0, import_block_editor.useBlockEditingMode)();
|
|
85
87
|
const hasNonContentControls = blockEditingMode === "default";
|
|
88
|
+
const prefersReducedMotion = (0, import_compose.useReducedMotion)();
|
|
86
89
|
(0, import_hooks.useUploadMediaFromBlobURL)({
|
|
87
90
|
url: temporaryURL,
|
|
88
91
|
allowedTypes: ALLOWED_MEDIA_TYPES,
|
|
@@ -94,6 +97,11 @@ function VideoEdit({
|
|
|
94
97
|
videoPlayer.current.load();
|
|
95
98
|
}
|
|
96
99
|
}, [poster]);
|
|
100
|
+
(0, import_element.useEffect)(() => {
|
|
101
|
+
if (prefersReducedMotion) {
|
|
102
|
+
videoPlayer.current?.pause();
|
|
103
|
+
}
|
|
104
|
+
}, [prefersReducedMotion]);
|
|
97
105
|
function onSelectVideo(media) {
|
|
98
106
|
if (!media || !media.url) {
|
|
99
107
|
setAttributes({
|
|
@@ -245,11 +253,11 @@ function VideoEdit({
|
|
|
245
253
|
"video",
|
|
246
254
|
{
|
|
247
255
|
controls,
|
|
248
|
-
inert: !isSingleSelected
|
|
256
|
+
inert: (0, import_react_inert_value.inertValue)(!isSingleSelected),
|
|
249
257
|
poster,
|
|
250
258
|
src: src || temporaryURL,
|
|
251
259
|
ref: videoPlayer,
|
|
252
|
-
autoPlay: autoplay,
|
|
260
|
+
autoPlay: autoplay && !prefersReducedMotion,
|
|
253
261
|
loop,
|
|
254
262
|
muted,
|
|
255
263
|
playsInline,
|
package/build/video/edit.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/video/edit.jsx"],
|
|
4
|
-
"sourcesContent": ["import clsx from 'clsx';\nimport { isBlobURL } from '@wordpress/blob';\nimport {\n\tSpinner,\n\tPlaceholder,\n\t__experimentalToolsPanel as ToolsPanel,\n} from '@wordpress/components';\nimport {\n\tBlockControls,\n\tBlockIcon,\n\tInspectorControls,\n\tMediaPlaceholder,\n\tMediaReplaceFlow,\n\tuseBlockProps,\n\tuseBlockEditingMode,\n\t__experimentalGetShadowClassesAndStyles as getShadowClassesAndStyles,\n} from '@wordpress/block-editor';\nimport { useRef, useEffect, useState } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport { useDispatch } from '@wordpress/data';\nimport { video as icon } from '@wordpress/icons';\nimport { store as noticesStore } from '@wordpress/notices';\nimport { prependHTTPS } from '@wordpress/url';\nimport { createUpgradedEmbedBlock } from '../embed/util';\nimport {\n\tuseUploadMediaFromBlobURL,\n\tuseToolsPanelDropdownMenuProps,\n} from '../utils/hooks';\nimport VideoCommonSettings from './edit-common-settings';\nimport TracksEditor from './tracks-editor';\nimport Tracks from './tracks';\nimport { Caption } from '../utils/caption';\nimport PosterImage from '../utils/poster-image';\n\nconst ALLOWED_MEDIA_TYPES = [ 'video' ];\n\nfunction VideoEdit( {\n\tisSelected: isSingleSelected,\n\tattributes,\n\tclassName,\n\tsetAttributes,\n\tinsertBlocksAfter,\n\tonReplace,\n} ) {\n\tconst videoPlayer = useRef();\n\tconst {\n\t\tid,\n\t\tcontrols,\n\t\tposter,\n\t\tsrc,\n\t\ttracks,\n\t\twidth,\n\t\theight,\n\t\tautoplay,\n\t\tloop,\n\t\tmuted,\n\t\tplaysInline,\n\t} = attributes;\n\t// Give the <video> an explicit (non-`auto`) aspect ratio derived from the\n\t// stored dimensions. The width/height attributes alone only yield\n\t// `aspect-ratio: auto W/H`, whose `auto` keyword defers to the element's\n\t// natural ratio while the poster/metadata load - during which Chrome briefly\n\t// computes a runaway height (tens of thousands of pixels) before settling.\n\t// That spike is what reads as a duplicated image during the GIF-to-video\n\t// swap. A non-`auto` ratio governs the box height throughout the load.\n\tconst aspectRatio =\n\t\twidth && height ? `${ width } / ${ height }` : undefined;\n\tconst videoStyle = {\n\t\t...( aspectRatio && { aspectRatio } ),\n\t\t...getShadowClassesAndStyles( attributes ).style,\n\t};\n\tconst [ temporaryURL, setTemporaryURL ] = useState( attributes.blob );\n\tconst dropdownMenuProps = useToolsPanelDropdownMenuProps();\n\tconst blockEditingMode = useBlockEditingMode();\n\tconst hasNonContentControls = blockEditingMode === 'default';\n\n\tuseUploadMediaFromBlobURL( {\n\t\turl: temporaryURL,\n\t\tallowedTypes: ALLOWED_MEDIA_TYPES,\n\t\tonChange: onSelectVideo,\n\t\tonError: onUploadError,\n\t} );\n\n\tuseEffect( () => {\n\t\t// Placeholder may be rendered.\n\t\tif ( videoPlayer.current ) {\n\t\t\tvideoPlayer.current.load();\n\t\t}\n\t}, [ poster ] );\n\t// TODO: Whether the video was obtained from the media library or was provided by URL, obtain the `videoWidth` and `videoHeight` of the video once its metadata has loaded and persist in the block attributes.\n\tfunction onSelectVideo( media ) {\n\t\tif ( ! media || ! media.url ) {\n\t\t\t// In this case there was an error\n\t\t\t// previous attributes should be removed\n\t\t\t// because they may be temporary blob urls.\n\t\t\tsetAttributes( {\n\t\t\t\tsrc: undefined,\n\t\t\t\tid: undefined,\n\t\t\t\tposter: undefined,\n\t\t\t\tcaption: undefined,\n\t\t\t\tblob: undefined,\n\t\t\t} );\n\t\t\tsetTemporaryURL();\n\t\t\treturn;\n\t\t}\n\n\t\tif ( isBlobURL( media.url ) ) {\n\t\t\tsetTemporaryURL( media.url );\n\t\t\treturn;\n\t\t}\n\n\t\t// Sets the block's attribute and updates the edit component from the\n\t\t// selected media.\n\t\tsetAttributes( {\n\t\t\tblob: undefined,\n\t\t\tsrc: media.url,\n\t\t\tid: media.id,\n\t\t\tposter:\n\t\t\t\tmedia.image?.src !== media.icon ? media.image?.src : undefined,\n\t\t\tcaption: media.caption,\n\t\t} );\n\t\tsetTemporaryURL();\n\t}\n\n\tfunction onSelectURL( newSrc ) {\n\t\tif ( newSrc !== src ) {\n\t\t\tconst url = prependHTTPS( newSrc );\n\t\t\t// Check if there's an embed block that handles this URL.\n\t\t\tconst embedBlock = createUpgradedEmbedBlock( {\n\t\t\t\tattributes: { url },\n\t\t\t} );\n\t\t\tif ( undefined !== embedBlock && onReplace ) {\n\t\t\t\tonReplace( embedBlock );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetAttributes( {\n\t\t\t\tblob: undefined,\n\t\t\t\tsrc: url,\n\t\t\t\tid: undefined,\n\t\t\t\tposter: undefined,\n\t\t\t} );\n\t\t\tsetTemporaryURL();\n\t\t}\n\t}\n\n\tconst { createErrorNotice } = useDispatch( noticesStore );\n\tfunction onUploadError( message ) {\n\t\tcreateErrorNotice( message, { type: 'snackbar' } );\n\t}\n\n\t// Much of this description is duplicated from MediaPlaceholder.\n\tconst placeholder = ( content ) => {\n\t\treturn (\n\t\t\t<Placeholder\n\t\t\t\tclassName=\"block-editor-media-placeholder\"\n\t\t\t\twithIllustration={ ! isSingleSelected }\n\t\t\t\ticon={ icon }\n\t\t\t\tlabel={ __( 'Video' ) }\n\t\t\t\tinstructions={ __(\n\t\t\t\t\t'Drag and drop a video, upload, or choose from your library.'\n\t\t\t\t) }\n\t\t\t>\n\t\t\t\t{ content }\n\t\t\t</Placeholder>\n\t\t);\n\t};\n\n\tconst classes = clsx( className, {\n\t\t'is-transient': !! temporaryURL,\n\t} );\n\n\tconst blockProps = useBlockProps( {\n\t\tclassName: classes,\n\t} );\n\n\tif ( ! src && ! temporaryURL ) {\n\t\treturn (\n\t\t\t<div { ...blockProps }>\n\t\t\t\t<MediaPlaceholder\n\t\t\t\t\ticon={ <BlockIcon icon={ icon } /> }\n\t\t\t\t\tonSelect={ onSelectVideo }\n\t\t\t\t\tonSelectURL={ onSelectURL }\n\t\t\t\t\taccept=\"video/*\"\n\t\t\t\t\tallowedTypes={ ALLOWED_MEDIA_TYPES }\n\t\t\t\t\tvalue={ attributes }\n\t\t\t\t\tonError={ onUploadError }\n\t\t\t\t\tplaceholder={ placeholder }\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{ isSingleSelected && (\n\t\t\t\t<>\n\t\t\t\t\t<BlockControls>\n\t\t\t\t\t\t<TracksEditor\n\t\t\t\t\t\t\ttracks={ tracks }\n\t\t\t\t\t\t\tonChange={ ( newTracks ) => {\n\t\t\t\t\t\t\t\tsetAttributes( { tracks: newTracks } );\n\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</BlockControls>\n\t\t\t\t\t<BlockControls group=\"other\">\n\t\t\t\t\t\t<MediaReplaceFlow\n\t\t\t\t\t\t\tmediaId={ id }\n\t\t\t\t\t\t\tmediaURL={ src }\n\t\t\t\t\t\t\tallowedTypes={ ALLOWED_MEDIA_TYPES }\n\t\t\t\t\t\t\taccept=\"video/*\"\n\t\t\t\t\t\t\tonSelect={ onSelectVideo }\n\t\t\t\t\t\t\tonSelectURL={ onSelectURL }\n\t\t\t\t\t\t\tonError={ onUploadError }\n\t\t\t\t\t\t\tonReset={ () => onSelectVideo( undefined ) }\n\t\t\t\t\t\t\tvariant=\"toolbar\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</BlockControls>\n\t\t\t\t</>\n\t\t\t) }\n\t\t\t<InspectorControls>\n\t\t\t\t<ToolsPanel\n\t\t\t\t\tlabel={ __( 'Settings' ) }\n\t\t\t\t\tresetAll={ () => {\n\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\tautoplay: false,\n\t\t\t\t\t\t\tcontrols: true,\n\t\t\t\t\t\t\tloop: false,\n\t\t\t\t\t\t\tmuted: false,\n\t\t\t\t\t\t\tplaysInline: false,\n\t\t\t\t\t\t\tpreload: 'metadata',\n\t\t\t\t\t\t\tposter: undefined,\n\t\t\t\t\t\t} );\n\t\t\t\t\t} }\n\t\t\t\t\tdropdownMenuProps={ dropdownMenuProps }\n\t\t\t\t>\n\t\t\t\t\t<VideoCommonSettings\n\t\t\t\t\t\tsetAttributes={ setAttributes }\n\t\t\t\t\t\tattributes={ attributes }\n\t\t\t\t\t/>\n\t\t\t\t\t<PosterImage\n\t\t\t\t\t\tposter={ poster }\n\t\t\t\t\t\tonChange={ ( posterImage ) =>\n\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\tposter: posterImage?.url,\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t</ToolsPanel>\n\t\t\t</InspectorControls>\n\t\t\t<figure { ...blockProps }>\n\t\t\t\t<video\n\t\t\t\t\tcontrols={ controls }\n\t\t\t\t\tinert={ ! isSingleSelected
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AACjB,kBAA0B;AAC1B,wBAIO;AACP,0BASO;AACP,qBAA4C;AAC5C,kBAAmB;AACnB,kBAA4B;AAC5B,mBAA8B;AAC9B,qBAAsC;AACtC,iBAA6B;AAC7B,kBAAyC;AACzC,mBAGO;AACP,kCAAgC;AAChC,2BAAyB;AACzB,oBAAmB;AACnB,qBAAwB;AACxB,0BAAwB;
|
|
4
|
+
"sourcesContent": ["import clsx from 'clsx';\nimport { isBlobURL } from '@wordpress/blob';\nimport {\n\tSpinner,\n\tPlaceholder,\n\t__experimentalToolsPanel as ToolsPanel,\n} from '@wordpress/components';\nimport {\n\tBlockControls,\n\tBlockIcon,\n\tInspectorControls,\n\tMediaPlaceholder,\n\tMediaReplaceFlow,\n\tuseBlockProps,\n\tuseBlockEditingMode,\n\t__experimentalGetShadowClassesAndStyles as getShadowClassesAndStyles,\n} from '@wordpress/block-editor';\nimport { useRef, useEffect, useState } from '@wordpress/element';\nimport { useReducedMotion } from '@wordpress/compose';\nimport { __ } from '@wordpress/i18n';\nimport { inertValue } from '@wordpress/react-inert-value';\nimport { useDispatch } from '@wordpress/data';\nimport { video as icon } from '@wordpress/icons';\nimport { store as noticesStore } from '@wordpress/notices';\nimport { prependHTTPS } from '@wordpress/url';\nimport { createUpgradedEmbedBlock } from '../embed/util';\nimport {\n\tuseUploadMediaFromBlobURL,\n\tuseToolsPanelDropdownMenuProps,\n} from '../utils/hooks';\nimport VideoCommonSettings from './edit-common-settings';\nimport TracksEditor from './tracks-editor';\nimport Tracks from './tracks';\nimport { Caption } from '../utils/caption';\nimport PosterImage from '../utils/poster-image';\n\nconst ALLOWED_MEDIA_TYPES = [ 'video' ];\n\nfunction VideoEdit( {\n\tisSelected: isSingleSelected,\n\tattributes,\n\tclassName,\n\tsetAttributes,\n\tinsertBlocksAfter,\n\tonReplace,\n} ) {\n\tconst videoPlayer = useRef();\n\tconst {\n\t\tid,\n\t\tcontrols,\n\t\tposter,\n\t\tsrc,\n\t\ttracks,\n\t\twidth,\n\t\theight,\n\t\tautoplay,\n\t\tloop,\n\t\tmuted,\n\t\tplaysInline,\n\t} = attributes;\n\t// Give the <video> an explicit (non-`auto`) aspect ratio derived from the\n\t// stored dimensions. The width/height attributes alone only yield\n\t// `aspect-ratio: auto W/H`, whose `auto` keyword defers to the element's\n\t// natural ratio while the poster/metadata load - during which Chrome briefly\n\t// computes a runaway height (tens of thousands of pixels) before settling.\n\t// That spike is what reads as a duplicated image during the GIF-to-video\n\t// swap. A non-`auto` ratio governs the box height throughout the load.\n\tconst aspectRatio =\n\t\twidth && height ? `${ width } / ${ height }` : undefined;\n\tconst videoStyle = {\n\t\t...( aspectRatio && { aspectRatio } ),\n\t\t...getShadowClassesAndStyles( attributes ).style,\n\t};\n\tconst [ temporaryURL, setTemporaryURL ] = useState( attributes.blob );\n\tconst dropdownMenuProps = useToolsPanelDropdownMenuProps();\n\tconst blockEditingMode = useBlockEditingMode();\n\tconst hasNonContentControls = blockEditingMode === 'default';\n\tconst prefersReducedMotion = useReducedMotion();\n\n\tuseUploadMediaFromBlobURL( {\n\t\turl: temporaryURL,\n\t\tallowedTypes: ALLOWED_MEDIA_TYPES,\n\t\tonChange: onSelectVideo,\n\t\tonError: onUploadError,\n\t} );\n\n\tuseEffect( () => {\n\t\t// Placeholder may be rendered.\n\t\tif ( videoPlayer.current ) {\n\t\t\tvideoPlayer.current.load();\n\t\t}\n\t}, [ poster ] );\n\n\t// `autoPlay` only applies when the video loads, so pause a video that is\n\t// already playing when the user turns on reduced motion.\n\tuseEffect( () => {\n\t\tif ( prefersReducedMotion ) {\n\t\t\tvideoPlayer.current?.pause();\n\t\t}\n\t}, [ prefersReducedMotion ] );\n\t// TODO: Whether the video was obtained from the media library or was provided by URL, obtain the `videoWidth` and `videoHeight` of the video once its metadata has loaded and persist in the block attributes.\n\tfunction onSelectVideo( media ) {\n\t\tif ( ! media || ! media.url ) {\n\t\t\t// In this case there was an error\n\t\t\t// previous attributes should be removed\n\t\t\t// because they may be temporary blob urls.\n\t\t\tsetAttributes( {\n\t\t\t\tsrc: undefined,\n\t\t\t\tid: undefined,\n\t\t\t\tposter: undefined,\n\t\t\t\tcaption: undefined,\n\t\t\t\tblob: undefined,\n\t\t\t} );\n\t\t\tsetTemporaryURL();\n\t\t\treturn;\n\t\t}\n\n\t\tif ( isBlobURL( media.url ) ) {\n\t\t\tsetTemporaryURL( media.url );\n\t\t\treturn;\n\t\t}\n\n\t\t// Sets the block's attribute and updates the edit component from the\n\t\t// selected media.\n\t\tsetAttributes( {\n\t\t\tblob: undefined,\n\t\t\tsrc: media.url,\n\t\t\tid: media.id,\n\t\t\tposter:\n\t\t\t\tmedia.image?.src !== media.icon ? media.image?.src : undefined,\n\t\t\tcaption: media.caption,\n\t\t} );\n\t\tsetTemporaryURL();\n\t}\n\n\tfunction onSelectURL( newSrc ) {\n\t\tif ( newSrc !== src ) {\n\t\t\tconst url = prependHTTPS( newSrc );\n\t\t\t// Check if there's an embed block that handles this URL.\n\t\t\tconst embedBlock = createUpgradedEmbedBlock( {\n\t\t\t\tattributes: { url },\n\t\t\t} );\n\t\t\tif ( undefined !== embedBlock && onReplace ) {\n\t\t\t\tonReplace( embedBlock );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetAttributes( {\n\t\t\t\tblob: undefined,\n\t\t\t\tsrc: url,\n\t\t\t\tid: undefined,\n\t\t\t\tposter: undefined,\n\t\t\t} );\n\t\t\tsetTemporaryURL();\n\t\t}\n\t}\n\n\tconst { createErrorNotice } = useDispatch( noticesStore );\n\tfunction onUploadError( message ) {\n\t\tcreateErrorNotice( message, { type: 'snackbar' } );\n\t}\n\n\t// Much of this description is duplicated from MediaPlaceholder.\n\tconst placeholder = ( content ) => {\n\t\treturn (\n\t\t\t<Placeholder\n\t\t\t\tclassName=\"block-editor-media-placeholder\"\n\t\t\t\twithIllustration={ ! isSingleSelected }\n\t\t\t\ticon={ icon }\n\t\t\t\tlabel={ __( 'Video' ) }\n\t\t\t\tinstructions={ __(\n\t\t\t\t\t'Drag and drop a video, upload, or choose from your library.'\n\t\t\t\t) }\n\t\t\t>\n\t\t\t\t{ content }\n\t\t\t</Placeholder>\n\t\t);\n\t};\n\n\tconst classes = clsx( className, {\n\t\t'is-transient': !! temporaryURL,\n\t} );\n\n\tconst blockProps = useBlockProps( {\n\t\tclassName: classes,\n\t} );\n\n\tif ( ! src && ! temporaryURL ) {\n\t\treturn (\n\t\t\t<div { ...blockProps }>\n\t\t\t\t<MediaPlaceholder\n\t\t\t\t\ticon={ <BlockIcon icon={ icon } /> }\n\t\t\t\t\tonSelect={ onSelectVideo }\n\t\t\t\t\tonSelectURL={ onSelectURL }\n\t\t\t\t\taccept=\"video/*\"\n\t\t\t\t\tallowedTypes={ ALLOWED_MEDIA_TYPES }\n\t\t\t\t\tvalue={ attributes }\n\t\t\t\t\tonError={ onUploadError }\n\t\t\t\t\tplaceholder={ placeholder }\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{ isSingleSelected && (\n\t\t\t\t<>\n\t\t\t\t\t<BlockControls>\n\t\t\t\t\t\t<TracksEditor\n\t\t\t\t\t\t\ttracks={ tracks }\n\t\t\t\t\t\t\tonChange={ ( newTracks ) => {\n\t\t\t\t\t\t\t\tsetAttributes( { tracks: newTracks } );\n\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</BlockControls>\n\t\t\t\t\t<BlockControls group=\"other\">\n\t\t\t\t\t\t<MediaReplaceFlow\n\t\t\t\t\t\t\tmediaId={ id }\n\t\t\t\t\t\t\tmediaURL={ src }\n\t\t\t\t\t\t\tallowedTypes={ ALLOWED_MEDIA_TYPES }\n\t\t\t\t\t\t\taccept=\"video/*\"\n\t\t\t\t\t\t\tonSelect={ onSelectVideo }\n\t\t\t\t\t\t\tonSelectURL={ onSelectURL }\n\t\t\t\t\t\t\tonError={ onUploadError }\n\t\t\t\t\t\t\tonReset={ () => onSelectVideo( undefined ) }\n\t\t\t\t\t\t\tvariant=\"toolbar\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</BlockControls>\n\t\t\t\t</>\n\t\t\t) }\n\t\t\t<InspectorControls>\n\t\t\t\t<ToolsPanel\n\t\t\t\t\tlabel={ __( 'Settings' ) }\n\t\t\t\t\tresetAll={ () => {\n\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\tautoplay: false,\n\t\t\t\t\t\t\tcontrols: true,\n\t\t\t\t\t\t\tloop: false,\n\t\t\t\t\t\t\tmuted: false,\n\t\t\t\t\t\t\tplaysInline: false,\n\t\t\t\t\t\t\tpreload: 'metadata',\n\t\t\t\t\t\t\tposter: undefined,\n\t\t\t\t\t\t} );\n\t\t\t\t\t} }\n\t\t\t\t\tdropdownMenuProps={ dropdownMenuProps }\n\t\t\t\t>\n\t\t\t\t\t<VideoCommonSettings\n\t\t\t\t\t\tsetAttributes={ setAttributes }\n\t\t\t\t\t\tattributes={ attributes }\n\t\t\t\t\t/>\n\t\t\t\t\t<PosterImage\n\t\t\t\t\t\tposter={ poster }\n\t\t\t\t\t\tonChange={ ( posterImage ) =>\n\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\tposter: posterImage?.url,\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t</ToolsPanel>\n\t\t\t</InspectorControls>\n\t\t\t<figure { ...blockProps }>\n\t\t\t\t<video\n\t\t\t\t\tcontrols={ controls }\n\t\t\t\t\tinert={ inertValue( ! isSingleSelected ) }\n\t\t\t\t\tposter={ poster }\n\t\t\t\t\tsrc={ src || temporaryURL }\n\t\t\t\t\tref={ videoPlayer }\n\t\t\t\t\tautoPlay={ autoplay && ! prefersReducedMotion }\n\t\t\t\t\tloop={ loop }\n\t\t\t\t\tmuted={ muted }\n\t\t\t\t\tplaysInline={ playsInline }\n\t\t\t\t\twidth={ width }\n\t\t\t\t\theight={ height }\n\t\t\t\t\tstyle={\n\t\t\t\t\t\tObject.keys( videoStyle ).length\n\t\t\t\t\t\t\t? videoStyle\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\n\t\t\t\t>\n\t\t\t\t\t<Tracks tracks={ tracks } />\n\t\t\t\t</video>\n\t\t\t\t{ !! temporaryURL && <Spinner /> }\n\t\t\t\t<Caption\n\t\t\t\t\tattributes={ attributes }\n\t\t\t\t\tsetAttributes={ setAttributes }\n\t\t\t\t\tisSelected={ isSingleSelected }\n\t\t\t\t\tinsertBlocksAfter={ insertBlocksAfter }\n\t\t\t\t\tlabel={ __( 'Video caption text' ) }\n\t\t\t\t\tshowToolbarButton={\n\t\t\t\t\t\tisSingleSelected && hasNonContentControls\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t</figure>\n\t\t</>\n\t);\n}\n\nexport default VideoEdit;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["getShadowClassesAndStyles", "noticesStore", "icon", "clsx", "TracksEditor", "ToolsPanel", "VideoCommonSettings", "PosterImage", "Tracks"]
|
|
7
7
|
}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
__experimentalToolsPanel as ToolsPanel,
|
|
9
9
|
__experimentalToolsPanelItem as ToolsPanelItem
|
|
10
10
|
} from "@wordpress/components";
|
|
11
|
+
import { inertValue } from "@wordpress/react-inert-value";
|
|
11
12
|
import { Text } from "@wordpress/ui";
|
|
12
13
|
import {
|
|
13
14
|
BlockControls,
|
|
@@ -225,7 +226,7 @@ function AudioEdit({
|
|
|
225
226
|
"audio",
|
|
226
227
|
{
|
|
227
228
|
controls: "controls",
|
|
228
|
-
inert: !isSingleSelected
|
|
229
|
+
inert: inertValue(!isSingleSelected),
|
|
229
230
|
src: src ?? temporaryURL
|
|
230
231
|
}
|
|
231
232
|
),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/audio/edit.jsx"],
|
|
4
|
-
"sourcesContent": ["import clsx from 'clsx';\nimport { isBlobURL } from '@wordpress/blob';\nimport {\n\tSelectControl as WCSelectControl,\n\tSpinner,\n\tToggleControl,\n\t__experimentalToolsPanel as ToolsPanel,\n\t__experimentalToolsPanelItem as ToolsPanelItem,\n} from '@wordpress/components';\nimport { Text } from '@wordpress/ui';\nimport {\n\tBlockControls,\n\tBlockIcon,\n\tInspectorControls,\n\tMediaPlaceholder,\n\tMediaReplaceFlow,\n\tuseBlockProps,\n\tuseBlockEditingMode,\n} from '@wordpress/block-editor';\nimport { __, _x } from '@wordpress/i18n';\nimport { useDispatch } from '@wordpress/data';\nimport { audio as icon } from '@wordpress/icons';\nimport { store as noticesStore } from '@wordpress/notices';\nimport { useState } from '@wordpress/element';\nimport { createUpgradedEmbedBlock } from '../embed/util';\nimport {\n\tuseUploadMediaFromBlobURL,\n\tuseToolsPanelDropdownMenuProps,\n} from '../utils/hooks';\nimport { Caption } from '../utils/caption';\n\nconst ALLOWED_MEDIA_TYPES = [ 'audio' ];\n\n/**\n * Renders the `core/audio` block on the editor.\n *\n * @param {Object} props React props.\n * @param {Object} props.attributes Block attributes: `blob`, `src`, `caption`, `id`, `autoplay`, `loop` and `preload`.\n * @param {string} props.className Class name generated for the block.\n * @param {Function} props.setAttributes Callback for updating block attributes.\n * @param {Function} props.onReplace Callback for replacing this block with other blocks.\n * @param {boolean} props.isSelected Whether the block is the only selected block.\n * @param {Function} props.insertBlocksAfter Callback for inserting blocks after this one.\n *\n * @return {React.JSX.Element} React element.\n */\nfunction AudioEdit( {\n\tattributes,\n\tclassName,\n\tsetAttributes,\n\tonReplace,\n\tisSelected: isSingleSelected,\n\tinsertBlocksAfter,\n} ) {\n\tconst { id, autoplay, loop, preload, src } = attributes;\n\tconst [ temporaryURL, setTemporaryURL ] = useState( attributes.blob );\n\tconst blockEditingMode = useBlockEditingMode();\n\tconst hasNonContentControls = blockEditingMode === 'default';\n\n\tuseUploadMediaFromBlobURL( {\n\t\turl: temporaryURL,\n\t\tallowedTypes: ALLOWED_MEDIA_TYPES,\n\t\tonChange: onSelectAudio,\n\t\tonError: onUploadError,\n\t} );\n\n\tfunction toggleAttribute( attribute ) {\n\t\treturn ( newValue ) => {\n\t\t\tsetAttributes( { [ attribute ]: newValue } );\n\t\t};\n\t}\n\n\tfunction onSelectURL( newSrc ) {\n\t\t// Set the block's src from the edit component's state, and switch off\n\t\t// the editing UI.\n\t\tif ( newSrc !== src ) {\n\t\t\t// Check if there's an embed block that handles this URL.\n\t\t\tconst embedBlock = createUpgradedEmbedBlock( {\n\t\t\t\tattributes: { url: newSrc },\n\t\t\t} );\n\t\t\tif ( undefined !== embedBlock && onReplace ) {\n\t\t\t\tonReplace( embedBlock );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetAttributes( { src: newSrc, id: undefined, blob: undefined } );\n\t\t\tsetTemporaryURL();\n\t\t}\n\t}\n\n\tconst { createErrorNotice } = useDispatch( noticesStore );\n\tfunction onUploadError( message ) {\n\t\tcreateErrorNotice( message, { type: 'snackbar' } );\n\t}\n\n\tfunction onSelectAudio( media ) {\n\t\tif ( ! media || ! media.url ) {\n\t\t\t// In this case there was an error and we should continue in the editing state\n\t\t\t// previous attributes should be removed because they may be temporary blob urls.\n\t\t\tsetAttributes( {\n\t\t\t\tsrc: undefined,\n\t\t\t\tid: undefined,\n\t\t\t\tcaption: undefined,\n\t\t\t\tblob: undefined,\n\t\t\t} );\n\t\t\tsetTemporaryURL();\n\t\t\treturn;\n\t\t}\n\n\t\tif ( isBlobURL( media.url ) ) {\n\t\t\tsetTemporaryURL( media.url );\n\t\t\treturn;\n\t\t}\n\n\t\t// Sets the block's attribute and updates the edit component from the\n\t\t// selected media, then switches off the editing UI.\n\t\tsetAttributes( {\n\t\t\tblob: undefined,\n\t\t\tsrc: media.url,\n\t\t\tid: media.id,\n\t\t\tcaption: media.caption,\n\t\t} );\n\t\tsetTemporaryURL();\n\t}\n\n\tconst classes = clsx( className, {\n\t\t'is-transient': !! temporaryURL,\n\t} );\n\n\tconst blockProps = useBlockProps( {\n\t\tclassName: classes,\n\t} );\n\tconst dropdownMenuProps = useToolsPanelDropdownMenuProps();\n\n\tif ( ! src && ! temporaryURL ) {\n\t\treturn (\n\t\t\t<div { ...blockProps }>\n\t\t\t\t<MediaPlaceholder\n\t\t\t\t\ticon={ <BlockIcon icon={ icon } /> }\n\t\t\t\t\tonSelect={ onSelectAudio }\n\t\t\t\t\tonSelectURL={ onSelectURL }\n\t\t\t\t\taccept=\"audio/*\"\n\t\t\t\t\tallowedTypes={ ALLOWED_MEDIA_TYPES }\n\t\t\t\t\tvalue={ attributes }\n\t\t\t\t\tonError={ onUploadError }\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{ isSingleSelected && (\n\t\t\t\t<BlockControls group=\"other\">\n\t\t\t\t\t<MediaReplaceFlow\n\t\t\t\t\t\tmediaId={ id }\n\t\t\t\t\t\tmediaURL={ src }\n\t\t\t\t\t\tallowedTypes={ ALLOWED_MEDIA_TYPES }\n\t\t\t\t\t\taccept=\"audio/*\"\n\t\t\t\t\t\tonSelect={ onSelectAudio }\n\t\t\t\t\t\tonSelectURL={ onSelectURL }\n\t\t\t\t\t\tonError={ onUploadError }\n\t\t\t\t\t\tonReset={ () => onSelectAudio( undefined ) }\n\t\t\t\t\t\tvariant=\"toolbar\"\n\t\t\t\t\t/>\n\t\t\t\t</BlockControls>\n\t\t\t) }\n\t\t\t<InspectorControls>\n\t\t\t\t<ToolsPanel\n\t\t\t\t\tlabel={ __( 'Settings' ) }\n\t\t\t\t\tresetAll={ () => {\n\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\tautoplay: false,\n\t\t\t\t\t\t\tloop: false,\n\t\t\t\t\t\t\tpreload: undefined,\n\t\t\t\t\t\t} );\n\t\t\t\t\t} }\n\t\t\t\t\tdropdownMenuProps={ dropdownMenuProps }\n\t\t\t\t>\n\t\t\t\t\t<Text className=\"wp-block-audio__autoplay-help-text\">\n\t\t\t\t\t\t{ __(\n\t\t\t\t\t\t\t'Most browsers block audio until a visitor interacts with the page, so autoplay often won’t work, especially on mobile. Unexpected sound can also be disruptive for screen reader users.'\n\t\t\t\t\t\t) }\n\t\t\t\t\t</Text>\n\t\t\t\t\t<ToolsPanelItem\n\t\t\t\t\t\tlabel={ __( 'Autoplay' ) }\n\t\t\t\t\t\tisShownByDefault\n\t\t\t\t\t\thasValue={ () => !! autoplay }\n\t\t\t\t\t\tonDeselect={ () =>\n\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\tautoplay: false,\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ToggleControl\n\t\t\t\t\t\t\tlabel={ __( 'Autoplay' ) }\n\t\t\t\t\t\t\tonChange={ toggleAttribute( 'autoplay' ) }\n\t\t\t\t\t\t\tchecked={ !! autoplay }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</ToolsPanelItem>\n\t\t\t\t\t<ToolsPanelItem\n\t\t\t\t\t\tlabel={ __( 'Loop' ) }\n\t\t\t\t\t\tisShownByDefault\n\t\t\t\t\t\thasValue={ () => !! loop }\n\t\t\t\t\t\tonDeselect={ () =>\n\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\tloop: false,\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ToggleControl\n\t\t\t\t\t\t\tlabel={ __( 'Loop' ) }\n\t\t\t\t\t\t\tonChange={ toggleAttribute( 'loop' ) }\n\t\t\t\t\t\t\tchecked={ !! loop }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</ToolsPanelItem>\n\t\t\t\t\t<ToolsPanelItem\n\t\t\t\t\t\tlabel={ __( 'Preload' ) }\n\t\t\t\t\t\tisShownByDefault\n\t\t\t\t\t\thasValue={ () => !! preload }\n\t\t\t\t\t\tonDeselect={ () =>\n\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\tpreload: undefined,\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t<WCSelectControl\n\t\t\t\t\t\t\tlabel={ _x(\n\t\t\t\t\t\t\t\t'Preload',\n\t\t\t\t\t\t\t\t'noun; Audio block parameter'\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\tvalue={ preload || '' }\n\t\t\t\t\t\t\t// `undefined` is required for the preload attribute to be unset.\n\t\t\t\t\t\t\tonChange={ ( value ) =>\n\t\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\t\tpreload: value || undefined,\n\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\toptions={ [\n\t\t\t\t\t\t\t\t{ value: '', label: __( 'Browser default' ) },\n\t\t\t\t\t\t\t\t{ value: 'auto', label: __( 'Auto' ) },\n\t\t\t\t\t\t\t\t{ value: 'metadata', label: __( 'Metadata' ) },\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tvalue: 'none',\n\t\t\t\t\t\t\t\t\tlabel: _x( 'None', 'Preload value' ),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t] }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</ToolsPanelItem>\n\t\t\t\t</ToolsPanel>\n\t\t\t</InspectorControls>\n\t\t\t<figure { ...blockProps }>\n\t\t\t\t<audio\n\t\t\t\t\tcontrols=\"controls\"\n\t\t\t\t\tinert={ ! isSingleSelected
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import clsx from 'clsx';\nimport { isBlobURL } from '@wordpress/blob';\nimport {\n\tSelectControl as WCSelectControl,\n\tSpinner,\n\tToggleControl,\n\t__experimentalToolsPanel as ToolsPanel,\n\t__experimentalToolsPanelItem as ToolsPanelItem,\n} from '@wordpress/components';\nimport { inertValue } from '@wordpress/react-inert-value';\nimport { Text } from '@wordpress/ui';\nimport {\n\tBlockControls,\n\tBlockIcon,\n\tInspectorControls,\n\tMediaPlaceholder,\n\tMediaReplaceFlow,\n\tuseBlockProps,\n\tuseBlockEditingMode,\n} from '@wordpress/block-editor';\nimport { __, _x } from '@wordpress/i18n';\nimport { useDispatch } from '@wordpress/data';\nimport { audio as icon } from '@wordpress/icons';\nimport { store as noticesStore } from '@wordpress/notices';\nimport { useState } from '@wordpress/element';\nimport { createUpgradedEmbedBlock } from '../embed/util';\nimport {\n\tuseUploadMediaFromBlobURL,\n\tuseToolsPanelDropdownMenuProps,\n} from '../utils/hooks';\nimport { Caption } from '../utils/caption';\n\nconst ALLOWED_MEDIA_TYPES = [ 'audio' ];\n\n/**\n * Renders the `core/audio` block on the editor.\n *\n * @param {Object} props React props.\n * @param {Object} props.attributes Block attributes: `blob`, `src`, `caption`, `id`, `autoplay`, `loop` and `preload`.\n * @param {string} props.className Class name generated for the block.\n * @param {Function} props.setAttributes Callback for updating block attributes.\n * @param {Function} props.onReplace Callback for replacing this block with other blocks.\n * @param {boolean} props.isSelected Whether the block is the only selected block.\n * @param {Function} props.insertBlocksAfter Callback for inserting blocks after this one.\n *\n * @return {React.JSX.Element} React element.\n */\nfunction AudioEdit( {\n\tattributes,\n\tclassName,\n\tsetAttributes,\n\tonReplace,\n\tisSelected: isSingleSelected,\n\tinsertBlocksAfter,\n} ) {\n\tconst { id, autoplay, loop, preload, src } = attributes;\n\tconst [ temporaryURL, setTemporaryURL ] = useState( attributes.blob );\n\tconst blockEditingMode = useBlockEditingMode();\n\tconst hasNonContentControls = blockEditingMode === 'default';\n\n\tuseUploadMediaFromBlobURL( {\n\t\turl: temporaryURL,\n\t\tallowedTypes: ALLOWED_MEDIA_TYPES,\n\t\tonChange: onSelectAudio,\n\t\tonError: onUploadError,\n\t} );\n\n\tfunction toggleAttribute( attribute ) {\n\t\treturn ( newValue ) => {\n\t\t\tsetAttributes( { [ attribute ]: newValue } );\n\t\t};\n\t}\n\n\tfunction onSelectURL( newSrc ) {\n\t\t// Set the block's src from the edit component's state, and switch off\n\t\t// the editing UI.\n\t\tif ( newSrc !== src ) {\n\t\t\t// Check if there's an embed block that handles this URL.\n\t\t\tconst embedBlock = createUpgradedEmbedBlock( {\n\t\t\t\tattributes: { url: newSrc },\n\t\t\t} );\n\t\t\tif ( undefined !== embedBlock && onReplace ) {\n\t\t\t\tonReplace( embedBlock );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetAttributes( { src: newSrc, id: undefined, blob: undefined } );\n\t\t\tsetTemporaryURL();\n\t\t}\n\t}\n\n\tconst { createErrorNotice } = useDispatch( noticesStore );\n\tfunction onUploadError( message ) {\n\t\tcreateErrorNotice( message, { type: 'snackbar' } );\n\t}\n\n\tfunction onSelectAudio( media ) {\n\t\tif ( ! media || ! media.url ) {\n\t\t\t// In this case there was an error and we should continue in the editing state\n\t\t\t// previous attributes should be removed because they may be temporary blob urls.\n\t\t\tsetAttributes( {\n\t\t\t\tsrc: undefined,\n\t\t\t\tid: undefined,\n\t\t\t\tcaption: undefined,\n\t\t\t\tblob: undefined,\n\t\t\t} );\n\t\t\tsetTemporaryURL();\n\t\t\treturn;\n\t\t}\n\n\t\tif ( isBlobURL( media.url ) ) {\n\t\t\tsetTemporaryURL( media.url );\n\t\t\treturn;\n\t\t}\n\n\t\t// Sets the block's attribute and updates the edit component from the\n\t\t// selected media, then switches off the editing UI.\n\t\tsetAttributes( {\n\t\t\tblob: undefined,\n\t\t\tsrc: media.url,\n\t\t\tid: media.id,\n\t\t\tcaption: media.caption,\n\t\t} );\n\t\tsetTemporaryURL();\n\t}\n\n\tconst classes = clsx( className, {\n\t\t'is-transient': !! temporaryURL,\n\t} );\n\n\tconst blockProps = useBlockProps( {\n\t\tclassName: classes,\n\t} );\n\tconst dropdownMenuProps = useToolsPanelDropdownMenuProps();\n\n\tif ( ! src && ! temporaryURL ) {\n\t\treturn (\n\t\t\t<div { ...blockProps }>\n\t\t\t\t<MediaPlaceholder\n\t\t\t\t\ticon={ <BlockIcon icon={ icon } /> }\n\t\t\t\t\tonSelect={ onSelectAudio }\n\t\t\t\t\tonSelectURL={ onSelectURL }\n\t\t\t\t\taccept=\"audio/*\"\n\t\t\t\t\tallowedTypes={ ALLOWED_MEDIA_TYPES }\n\t\t\t\t\tvalue={ attributes }\n\t\t\t\t\tonError={ onUploadError }\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{ isSingleSelected && (\n\t\t\t\t<BlockControls group=\"other\">\n\t\t\t\t\t<MediaReplaceFlow\n\t\t\t\t\t\tmediaId={ id }\n\t\t\t\t\t\tmediaURL={ src }\n\t\t\t\t\t\tallowedTypes={ ALLOWED_MEDIA_TYPES }\n\t\t\t\t\t\taccept=\"audio/*\"\n\t\t\t\t\t\tonSelect={ onSelectAudio }\n\t\t\t\t\t\tonSelectURL={ onSelectURL }\n\t\t\t\t\t\tonError={ onUploadError }\n\t\t\t\t\t\tonReset={ () => onSelectAudio( undefined ) }\n\t\t\t\t\t\tvariant=\"toolbar\"\n\t\t\t\t\t/>\n\t\t\t\t</BlockControls>\n\t\t\t) }\n\t\t\t<InspectorControls>\n\t\t\t\t<ToolsPanel\n\t\t\t\t\tlabel={ __( 'Settings' ) }\n\t\t\t\t\tresetAll={ () => {\n\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\tautoplay: false,\n\t\t\t\t\t\t\tloop: false,\n\t\t\t\t\t\t\tpreload: undefined,\n\t\t\t\t\t\t} );\n\t\t\t\t\t} }\n\t\t\t\t\tdropdownMenuProps={ dropdownMenuProps }\n\t\t\t\t>\n\t\t\t\t\t<Text className=\"wp-block-audio__autoplay-help-text\">\n\t\t\t\t\t\t{ __(\n\t\t\t\t\t\t\t'Most browsers block audio until a visitor interacts with the page, so autoplay often won’t work, especially on mobile. Unexpected sound can also be disruptive for screen reader users.'\n\t\t\t\t\t\t) }\n\t\t\t\t\t</Text>\n\t\t\t\t\t<ToolsPanelItem\n\t\t\t\t\t\tlabel={ __( 'Autoplay' ) }\n\t\t\t\t\t\tisShownByDefault\n\t\t\t\t\t\thasValue={ () => !! autoplay }\n\t\t\t\t\t\tonDeselect={ () =>\n\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\tautoplay: false,\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ToggleControl\n\t\t\t\t\t\t\tlabel={ __( 'Autoplay' ) }\n\t\t\t\t\t\t\tonChange={ toggleAttribute( 'autoplay' ) }\n\t\t\t\t\t\t\tchecked={ !! autoplay }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</ToolsPanelItem>\n\t\t\t\t\t<ToolsPanelItem\n\t\t\t\t\t\tlabel={ __( 'Loop' ) }\n\t\t\t\t\t\tisShownByDefault\n\t\t\t\t\t\thasValue={ () => !! loop }\n\t\t\t\t\t\tonDeselect={ () =>\n\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\tloop: false,\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ToggleControl\n\t\t\t\t\t\t\tlabel={ __( 'Loop' ) }\n\t\t\t\t\t\t\tonChange={ toggleAttribute( 'loop' ) }\n\t\t\t\t\t\t\tchecked={ !! loop }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</ToolsPanelItem>\n\t\t\t\t\t<ToolsPanelItem\n\t\t\t\t\t\tlabel={ __( 'Preload' ) }\n\t\t\t\t\t\tisShownByDefault\n\t\t\t\t\t\thasValue={ () => !! preload }\n\t\t\t\t\t\tonDeselect={ () =>\n\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\tpreload: undefined,\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t<WCSelectControl\n\t\t\t\t\t\t\tlabel={ _x(\n\t\t\t\t\t\t\t\t'Preload',\n\t\t\t\t\t\t\t\t'noun; Audio block parameter'\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\tvalue={ preload || '' }\n\t\t\t\t\t\t\t// `undefined` is required for the preload attribute to be unset.\n\t\t\t\t\t\t\tonChange={ ( value ) =>\n\t\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\t\tpreload: value || undefined,\n\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\toptions={ [\n\t\t\t\t\t\t\t\t{ value: '', label: __( 'Browser default' ) },\n\t\t\t\t\t\t\t\t{ value: 'auto', label: __( 'Auto' ) },\n\t\t\t\t\t\t\t\t{ value: 'metadata', label: __( 'Metadata' ) },\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tvalue: 'none',\n\t\t\t\t\t\t\t\t\tlabel: _x( 'None', 'Preload value' ),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t] }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</ToolsPanelItem>\n\t\t\t\t</ToolsPanel>\n\t\t\t</InspectorControls>\n\t\t\t<figure { ...blockProps }>\n\t\t\t\t<audio\n\t\t\t\t\tcontrols=\"controls\"\n\t\t\t\t\tinert={ inertValue( ! isSingleSelected ) }\n\t\t\t\t\tsrc={ src ?? temporaryURL }\n\t\t\t\t/>\n\t\t\t\t{ !! temporaryURL && <Spinner /> }\n\t\t\t\t<Caption\n\t\t\t\t\tattributes={ attributes }\n\t\t\t\t\tsetAttributes={ setAttributes }\n\t\t\t\t\tisSelected={ isSingleSelected }\n\t\t\t\t\tinsertBlocksAfter={ insertBlocksAfter }\n\t\t\t\t\tlabel={ __( 'Audio caption text' ) }\n\t\t\t\t\tshowToolbarButton={\n\t\t\t\t\t\tisSingleSelected && hasNonContentControls\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t</figure>\n\t\t</>\n\t);\n}\n\nexport default AudioEdit;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -54,12 +54,16 @@
|
|
|
54
54
|
"filter": {
|
|
55
55
|
"duotone": true
|
|
56
56
|
},
|
|
57
|
+
"shadow": {
|
|
58
|
+
"__experimentalSkipSerialization": true
|
|
59
|
+
},
|
|
57
60
|
"interactivity": {
|
|
58
61
|
"clientNavigation": true
|
|
59
62
|
}
|
|
60
63
|
},
|
|
61
64
|
"selectors": {
|
|
62
65
|
"border": ".wp-block-avatar img",
|
|
66
|
+
"shadow": ".wp-block-avatar img",
|
|
63
67
|
"filter": {
|
|
64
68
|
"duotone": ".wp-block-avatar img"
|
|
65
69
|
}
|
|
@@ -3,7 +3,8 @@ import clsx from "clsx";
|
|
|
3
3
|
import {
|
|
4
4
|
InspectorControls,
|
|
5
5
|
useBlockProps,
|
|
6
|
-
__experimentalUseBorderProps as useBorderProps
|
|
6
|
+
__experimentalUseBorderProps as useBorderProps,
|
|
7
|
+
__experimentalGetShadowClassesAndStyles as getShadowClassesAndStyles
|
|
7
8
|
} from "@wordpress/block-editor";
|
|
8
9
|
import {
|
|
9
10
|
RangeControl,
|
|
@@ -12,12 +13,36 @@ import {
|
|
|
12
13
|
__experimentalToolsPanel as ToolsPanel,
|
|
13
14
|
__experimentalToolsPanelItem as ToolsPanelItem
|
|
14
15
|
} from "@wordpress/components";
|
|
16
|
+
import { store as coreStore } from "@wordpress/core-data";
|
|
17
|
+
import { useSelect } from "@wordpress/data";
|
|
18
|
+
import { createInterpolateElement } from "@wordpress/element";
|
|
15
19
|
import { __, isRTL } from "@wordpress/i18n";
|
|
20
|
+
import { Link, Text } from "@wordpress/ui";
|
|
16
21
|
import { addQueryArgs, removeQueryArgs } from "@wordpress/url";
|
|
17
22
|
import { useToolsPanelDropdownMenuProps } from "../utils/hooks.mjs";
|
|
18
23
|
import { useCommentAvatar, useUserAvatar } from "./hooks.mjs";
|
|
19
24
|
import UserControl from "./user-control.mjs";
|
|
20
25
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
26
|
+
function useAvatarHelpText() {
|
|
27
|
+
const canManageSettings = useSelect(
|
|
28
|
+
(select) => select(coreStore).canUser("update", {
|
|
29
|
+
kind: "root",
|
|
30
|
+
name: "site"
|
|
31
|
+
}),
|
|
32
|
+
[]
|
|
33
|
+
);
|
|
34
|
+
if (!canManageSettings) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return createInterpolateElement(
|
|
38
|
+
__(
|
|
39
|
+
"Avatars use the Gravatar service. Go to <a>Discussion settings</a> to change the default avatar."
|
|
40
|
+
),
|
|
41
|
+
{
|
|
42
|
+
a: /* @__PURE__ */ jsx(Link, { href: "options-discussion.php", openInNewTab: true })
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
}
|
|
21
46
|
var AvatarInspectorControls = ({
|
|
22
47
|
setAttributes,
|
|
23
48
|
avatar,
|
|
@@ -25,6 +50,7 @@ var AvatarInspectorControls = ({
|
|
|
25
50
|
selectUser
|
|
26
51
|
}) => {
|
|
27
52
|
const dropdownMenuProps = useToolsPanelDropdownMenuProps();
|
|
53
|
+
const helpText = useAvatarHelpText();
|
|
28
54
|
return /* @__PURE__ */ jsx(InspectorControls, { children: /* @__PURE__ */ jsxs(
|
|
29
55
|
ToolsPanel,
|
|
30
56
|
{
|
|
@@ -39,6 +65,7 @@ var AvatarInspectorControls = ({
|
|
|
39
65
|
},
|
|
40
66
|
dropdownMenuProps,
|
|
41
67
|
children: [
|
|
68
|
+
helpText && /* @__PURE__ */ jsx(Text, { className: "wp-block-avatar__help-text", children: helpText }),
|
|
42
69
|
/* @__PURE__ */ jsx(
|
|
43
70
|
ToolsPanelItem,
|
|
44
71
|
{
|
|
@@ -138,6 +165,7 @@ var ResizableAvatar = ({
|
|
|
138
165
|
isSelected
|
|
139
166
|
}) => {
|
|
140
167
|
const borderProps = useBorderProps(attributes);
|
|
168
|
+
const shadowProps = getShadowClassesAndStyles(attributes);
|
|
141
169
|
const doubledSizedSrc = addQueryArgs(
|
|
142
170
|
removeQueryArgs(avatar?.src, ["s"]),
|
|
143
171
|
{
|
|
@@ -181,7 +209,10 @@ var ResizableAvatar = ({
|
|
|
181
209
|
"wp-block-avatar__image",
|
|
182
210
|
borderProps.className
|
|
183
211
|
),
|
|
184
|
-
style:
|
|
212
|
+
style: {
|
|
213
|
+
...borderProps.style,
|
|
214
|
+
...shadowProps.style
|
|
215
|
+
}
|
|
185
216
|
}
|
|
186
217
|
)
|
|
187
218
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/avatar/edit.jsx"],
|
|
4
|
-
"sourcesContent": ["import clsx from 'clsx';\nimport {\n\tInspectorControls,\n\tuseBlockProps,\n\t__experimentalUseBorderProps as useBorderProps,\n} from '@wordpress/block-editor';\nimport {\n\tRangeControl,\n\tResizableBox,\n\tToggleControl,\n\t__experimentalToolsPanel as ToolsPanel,\n\t__experimentalToolsPanelItem as ToolsPanelItem,\n} from '@wordpress/components';\nimport { __, isRTL } from '@wordpress/i18n';\nimport { addQueryArgs, removeQueryArgs } from '@wordpress/url';\nimport { useToolsPanelDropdownMenuProps } from '../utils/hooks';\nimport { useCommentAvatar, useUserAvatar } from './hooks';\nimport UserControl from './user-control';\n\n/**\n * Renders the inspector controls for the `core/avatar` block.\n *\n * @param {Object} props React props.\n * @param {Function} props.setAttributes Callback for updating block attributes.\n * @param {Object} props.avatar Avatar data returned by `useCommentAvatar` or `useUserAvatar`, with the `minSize` and `maxSize` bounds of the size control.\n * @param {Object} props.attributes Block attributes: `size`, `isLink`, `linkTarget` and `userId`.\n * @param {boolean} props.selectUser Whether to render the user selection control.\n *\n * @return {React.JSX.Element} React element.\n */\nconst AvatarInspectorControls = ( {\n\tsetAttributes,\n\tavatar,\n\tattributes,\n\tselectUser,\n} ) => {\n\tconst dropdownMenuProps = useToolsPanelDropdownMenuProps();\n\treturn (\n\t\t<InspectorControls>\n\t\t\t<ToolsPanel\n\t\t\t\tlabel={ __( 'Settings' ) }\n\t\t\t\tresetAll={ () => {\n\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\tsize: 96,\n\t\t\t\t\t\tisLink: false,\n\t\t\t\t\t\tlinkTarget: '_self',\n\t\t\t\t\t\tuserId: undefined,\n\t\t\t\t\t} );\n\t\t\t\t} }\n\t\t\t\tdropdownMenuProps={ dropdownMenuProps }\n\t\t\t>\n\t\t\t\t<ToolsPanelItem\n\t\t\t\t\tlabel={ __( 'Image size' ) }\n\t\t\t\t\tisShownByDefault\n\t\t\t\t\thasValue={ () => attributes?.size !== 96 }\n\t\t\t\t\tonDeselect={ () => setAttributes( { size: 96 } ) }\n\t\t\t\t>\n\t\t\t\t\t<RangeControl\n\t\t\t\t\t\tlabel={ __( 'Image size' ) }\n\t\t\t\t\t\tonChange={ ( newSize ) =>\n\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\tsize: newSize,\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmin={ avatar.minSize }\n\t\t\t\t\t\tmax={ avatar.maxSize }\n\t\t\t\t\t\tinitialPosition={ attributes?.size }\n\t\t\t\t\t\tvalue={ attributes?.size }\n\t\t\t\t\t/>\n\t\t\t\t</ToolsPanelItem>\n\t\t\t\t<ToolsPanelItem\n\t\t\t\t\tlabel={ __( 'Link to user profile' ) }\n\t\t\t\t\tisShownByDefault\n\t\t\t\t\thasValue={ () => attributes?.isLink }\n\t\t\t\t\tonDeselect={ () => setAttributes( { isLink: false } ) }\n\t\t\t\t>\n\t\t\t\t\t<ToggleControl\n\t\t\t\t\t\tlabel={ __( 'Link to user profile' ) }\n\t\t\t\t\t\tonChange={ () =>\n\t\t\t\t\t\t\tsetAttributes( { isLink: ! attributes.isLink } )\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchecked={ attributes.isLink }\n\t\t\t\t\t/>\n\t\t\t\t</ToolsPanelItem>\n\t\t\t\t{ attributes.isLink && (\n\t\t\t\t\t<ToolsPanelItem\n\t\t\t\t\t\tlabel={ __( 'Open in new tab' ) }\n\t\t\t\t\t\tisShownByDefault\n\t\t\t\t\t\thasValue={ () => attributes?.linkTarget !== '_self' }\n\t\t\t\t\t\tonDeselect={ () =>\n\t\t\t\t\t\t\tsetAttributes( { linkTarget: '_self' } )\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ToggleControl\n\t\t\t\t\t\t\tlabel={ __( 'Open in new tab' ) }\n\t\t\t\t\t\t\tonChange={ ( value ) =>\n\t\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\t\tlinkTarget: value ? '_blank' : '_self',\n\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tchecked={ attributes.linkTarget === '_blank' }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</ToolsPanelItem>\n\t\t\t\t) }\n\t\t\t\t{ selectUser && (\n\t\t\t\t\t<ToolsPanelItem\n\t\t\t\t\t\tlabel={ __( 'User' ) }\n\t\t\t\t\t\tisShownByDefault\n\t\t\t\t\t\thasValue={ () => !! attributes?.userId }\n\t\t\t\t\t\tonDeselect={ () =>\n\t\t\t\t\t\t\tsetAttributes( { userId: undefined } )\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t<UserControl\n\t\t\t\t\t\t\tvalue={ attributes?.userId }\n\t\t\t\t\t\t\tonChange={ ( value ) => {\n\t\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\t\tuserId: value,\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</ToolsPanelItem>\n\t\t\t\t) }\n\t\t\t</ToolsPanel>\n\t\t</InspectorControls>\n\t);\n};\n\n/**\n * Wraps the avatar image in a placeholder link when the block links to the user\n * profile. The link is inert in the editor: it points at a fragment and its\n * click handler prevents navigation.\n *\n * @param {Object} props React props.\n * @param {React.ReactNode} props.children Avatar image to wrap.\n * @param {boolean} props.isLink Whether to wrap the children in a link.\n *\n * @return {React.ReactNode} The children, wrapped in a link when `isLink` is true.\n */\nconst AvatarLinkWrapper = ( { children, isLink } ) =>\n\tisLink ? (\n\t\t<a\n\t\t\thref=\"#avatar-pseudo-link\"\n\t\t\tclassName=\"wp-block-avatar__link\"\n\t\t\tonClick={ ( event ) => event.preventDefault() }\n\t\t>\n\t\t\t{ children }\n\t\t</a>\n\t) : (\n\t\tchildren\n\t);\n\n/**\n * Renders the avatar image inside a `ResizableBox` so its size can be adjusted\n * by dragging. Resizing keeps the aspect ratio and updates the `size` attribute.\n *\n * @param {Object} props React props.\n * @param {Function} props.setAttributes Callback for updating block attributes.\n * @param {Object} props.attributes Block attributes: `size` and `isLink`, plus the border support values read by `useBorderProps`.\n * @param {Object} props.avatar Avatar data returned by `useCommentAvatar` or `useUserAvatar`, with the image `src` and `alt` and the `minSize` and `maxSize` resize bounds.\n * @param {Object} props.blockProps Props returned by `useBlockProps`, applied to the wrapper element.\n * @param {boolean} props.isSelected Whether the block is selected. Resize handles are only shown when it is.\n *\n * @return {React.JSX.Element} React element.\n */\nconst ResizableAvatar = ( {\n\tsetAttributes,\n\tattributes,\n\tavatar,\n\tblockProps,\n\tisSelected,\n} ) => {\n\tconst borderProps = useBorderProps( attributes );\n\tconst doubledSizedSrc = addQueryArgs(\n\t\tremoveQueryArgs( avatar?.src, [ 's' ] ),\n\t\t{\n\t\t\ts: attributes?.size * 2,\n\t\t}\n\t);\n\treturn (\n\t\t<div { ...blockProps }>\n\t\t\t<AvatarLinkWrapper isLink={ attributes.isLink }>\n\t\t\t\t<ResizableBox\n\t\t\t\t\tsize={ {\n\t\t\t\t\t\twidth: attributes.size,\n\t\t\t\t\t\theight: attributes.size,\n\t\t\t\t\t} }\n\t\t\t\t\tshowHandle={ isSelected }\n\t\t\t\t\tonResizeStop={ ( event, direction, elt, delta ) => {\n\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\tsize: parseInt(\n\t\t\t\t\t\t\t\tattributes.size +\n\t\t\t\t\t\t\t\t\t( delta.height || delta.width ),\n\t\t\t\t\t\t\t\t10\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t} );\n\t\t\t\t\t} }\n\t\t\t\t\tlockAspectRatio\n\t\t\t\t\tenable={ {\n\t\t\t\t\t\ttop: false,\n\t\t\t\t\t\tright: ! isRTL(),\n\t\t\t\t\t\tbottom: true,\n\t\t\t\t\t\tleft: isRTL(),\n\t\t\t\t\t} }\n\t\t\t\t\tminWidth={ avatar.minSize }\n\t\t\t\t\tmaxWidth={ avatar.maxSize }\n\t\t\t\t>\n\t\t\t\t\t<img\n\t\t\t\t\t\tsrc={ doubledSizedSrc }\n\t\t\t\t\t\talt={ avatar.alt }\n\t\t\t\t\t\tclassName={ clsx(\n\t\t\t\t\t\t\t'avatar',\n\t\t\t\t\t\t\t'avatar-' + attributes.size,\n\t\t\t\t\t\t\t'photo',\n\t\t\t\t\t\t\t'wp-block-avatar__image',\n\t\t\t\t\t\t\tborderProps.className\n\t\t\t\t\t\t) }\n\t\t\t\t\t\tstyle={ borderProps.style }\n\t\t\t\t\t/>\n\t\t\t\t</ResizableBox>\n\t\t\t</AvatarLinkWrapper>\n\t\t</div>\n\t);\n};\n\n/**\n * Renders the block for a comment author, resolving the avatar from the\n * `commentId` context. The user selection control is not offered here because\n * the author is determined by the comment.\n *\n * @param {Object} props React props.\n * @param {Object} props.attributes Block attributes.\n * @param {Object} props.context Inherited context, from which the comment ID is read.\n * @param {Function} props.setAttributes Callback for updating block attributes.\n * @param {boolean} props.isSelected Whether the block is selected.\n *\n * @return {React.JSX.Element} React element.\n */\nconst CommentEdit = ( { attributes, context, setAttributes, isSelected } ) => {\n\tconst { commentId } = context;\n\tconst blockProps = useBlockProps();\n\tconst avatar = useCommentAvatar( { commentId } );\n\treturn (\n\t\t<>\n\t\t\t<AvatarInspectorControls\n\t\t\t\tavatar={ avatar }\n\t\t\t\tsetAttributes={ setAttributes }\n\t\t\t\tattributes={ attributes }\n\t\t\t\tselectUser={ false }\n\t\t\t/>\n\t\t\t<ResizableAvatar\n\t\t\t\tattributes={ attributes }\n\t\t\t\tavatar={ avatar }\n\t\t\t\tblockProps={ blockProps }\n\t\t\t\tisSelected={ isSelected }\n\t\t\t\tsetAttributes={ setAttributes }\n\t\t\t/>\n\t\t</>\n\t);\n};\n\n/**\n * Renders the block for a user, resolving the avatar from the `userId`\n * attribute when set, and otherwise from the author of the post identified by\n * the `postType` and `postId` context.\n *\n * @param {Object} props React props.\n * @param {Object} props.attributes Block attributes, from which the `userId` is read.\n * @param {Object} props.context Inherited context, from which the post type and post ID are read.\n * @param {Function} props.setAttributes Callback for updating block attributes.\n * @param {boolean} props.isSelected Whether the block is selected.\n *\n * @return {React.JSX.Element} React element.\n */\nconst UserEdit = ( { attributes, context, setAttributes, isSelected } ) => {\n\tconst { postId, postType } = context;\n\tconst avatar = useUserAvatar( {\n\t\tuserId: attributes?.userId,\n\t\tpostId,\n\t\tpostType,\n\t} );\n\tconst blockProps = useBlockProps();\n\treturn (\n\t\t<>\n\t\t\t<AvatarInspectorControls\n\t\t\t\tselectUser\n\t\t\t\tattributes={ attributes }\n\t\t\t\tavatar={ avatar }\n\t\t\t\tsetAttributes={ setAttributes }\n\t\t\t/>\n\n\t\t\t<ResizableAvatar\n\t\t\t\tattributes={ attributes }\n\t\t\t\tavatar={ avatar }\n\t\t\t\tblockProps={ blockProps }\n\t\t\t\tisSelected={ isSelected }\n\t\t\t\tsetAttributes={ setAttributes }\n\t\t\t/>\n\t\t</>\n\t);\n};\n\n/**\n * Renders the `core/avatar` block on the editor. All props are forwarded to\n * either `CommentEdit` or `UserEdit`, depending on whether the block is used\n * inside a comment.\n *\n * @param {Object} props React props.\n * @param {Object} props.attributes Block attributes.\n * @param {Object} props.context Inherited context.\n * @param {number|null} [props.context.commentId] The comment ID when the block is used inside a comment. `null` in the Site Editor, where no comment is resolved but the comment variant is still rendered.\n * @param {string} [props.context.postType] The post type of the current post.\n * @param {number} [props.context.postId] The ID of the current post.\n * @param {Function} props.setAttributes Callback for updating block attributes.\n * @param {boolean} props.isSelected Whether the block is selected.\n *\n * @return {React.JSX.Element} React element.\n */\nexport default function Edit( props ) {\n\t// Don't show the Comment Edit controls if we have a comment ID set, or if we're in the Site Editor (where it is `null`).\n\tif ( props?.context?.commentId || props?.context?.commentId === null ) {\n\t\treturn <CommentEdit { ...props } />;\n\t}\n\treturn <UserEdit { ...props } />;\n}\n"],
|
|
5
|
-
"mappings": ";AAAA,OAAO,UAAU;AACjB;AAAA,EACC;AAAA,EACA;AAAA,EACA,gCAAgC;AAAA,
|
|
4
|
+
"sourcesContent": ["import clsx from 'clsx';\nimport {\n\tInspectorControls,\n\tuseBlockProps,\n\t__experimentalUseBorderProps as useBorderProps,\n\t__experimentalGetShadowClassesAndStyles as getShadowClassesAndStyles,\n} from '@wordpress/block-editor';\nimport {\n\tRangeControl,\n\tResizableBox,\n\tToggleControl,\n\t__experimentalToolsPanel as ToolsPanel,\n\t__experimentalToolsPanelItem as ToolsPanelItem,\n} from '@wordpress/components';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { useSelect } from '@wordpress/data';\nimport { createInterpolateElement } from '@wordpress/element';\nimport { __, isRTL } from '@wordpress/i18n';\nimport { Link, Text } from '@wordpress/ui';\nimport { addQueryArgs, removeQueryArgs } from '@wordpress/url';\nimport { useToolsPanelDropdownMenuProps } from '../utils/hooks';\nimport { useCommentAvatar, useUserAvatar } from './hooks';\nimport UserControl from './user-control';\n\n/**\n * Returns the help text explaining where avatars come from, with a link to the\n * Discussion settings where the default avatar is chosen. Only users who can\n * manage the site's settings get it, since nobody else can act on it.\n *\n * @return {React.ReactNode|null} Help text, or `null` when the user can't manage settings.\n */\nfunction useAvatarHelpText() {\n\tconst canManageSettings = useSelect(\n\t\t( select ) =>\n\t\t\tselect( coreStore ).canUser( 'update', {\n\t\t\t\tkind: 'root',\n\t\t\t\tname: 'site',\n\t\t\t} ),\n\t\t[]\n\t);\n\n\tif ( ! canManageSettings ) {\n\t\treturn null;\n\t}\n\n\treturn createInterpolateElement(\n\t\t__(\n\t\t\t'Avatars use the Gravatar service. Go to <a>Discussion settings</a> to change the default avatar.'\n\t\t),\n\t\t{\n\t\t\ta: <Link href=\"options-discussion.php\" openInNewTab />,\n\t\t}\n\t);\n}\n\n/**\n * Renders the inspector controls for the `core/avatar` block.\n *\n * @param {Object} props React props.\n * @param {Function} props.setAttributes Callback for updating block attributes.\n * @param {Object} props.avatar Avatar data returned by `useCommentAvatar` or `useUserAvatar`, with the `minSize` and `maxSize` bounds of the size control.\n * @param {Object} props.attributes Block attributes: `size`, `isLink`, `linkTarget` and `userId`.\n * @param {boolean} props.selectUser Whether to render the user selection control.\n *\n * @return {React.JSX.Element} React element.\n */\nconst AvatarInspectorControls = ( {\n\tsetAttributes,\n\tavatar,\n\tattributes,\n\tselectUser,\n} ) => {\n\tconst dropdownMenuProps = useToolsPanelDropdownMenuProps();\n\tconst helpText = useAvatarHelpText();\n\treturn (\n\t\t<InspectorControls>\n\t\t\t<ToolsPanel\n\t\t\t\tlabel={ __( 'Settings' ) }\n\t\t\t\tresetAll={ () => {\n\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\tsize: 96,\n\t\t\t\t\t\tisLink: false,\n\t\t\t\t\t\tlinkTarget: '_self',\n\t\t\t\t\t\tuserId: undefined,\n\t\t\t\t\t} );\n\t\t\t\t} }\n\t\t\t\tdropdownMenuProps={ dropdownMenuProps }\n\t\t\t>\n\t\t\t\t{ helpText && (\n\t\t\t\t\t<Text className=\"wp-block-avatar__help-text\">\n\t\t\t\t\t\t{ helpText }\n\t\t\t\t\t</Text>\n\t\t\t\t) }\n\t\t\t\t<ToolsPanelItem\n\t\t\t\t\tlabel={ __( 'Image size' ) }\n\t\t\t\t\tisShownByDefault\n\t\t\t\t\thasValue={ () => attributes?.size !== 96 }\n\t\t\t\t\tonDeselect={ () => setAttributes( { size: 96 } ) }\n\t\t\t\t>\n\t\t\t\t\t<RangeControl\n\t\t\t\t\t\tlabel={ __( 'Image size' ) }\n\t\t\t\t\t\tonChange={ ( newSize ) =>\n\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\tsize: newSize,\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmin={ avatar.minSize }\n\t\t\t\t\t\tmax={ avatar.maxSize }\n\t\t\t\t\t\tinitialPosition={ attributes?.size }\n\t\t\t\t\t\tvalue={ attributes?.size }\n\t\t\t\t\t/>\n\t\t\t\t</ToolsPanelItem>\n\t\t\t\t<ToolsPanelItem\n\t\t\t\t\tlabel={ __( 'Link to user profile' ) }\n\t\t\t\t\tisShownByDefault\n\t\t\t\t\thasValue={ () => attributes?.isLink }\n\t\t\t\t\tonDeselect={ () => setAttributes( { isLink: false } ) }\n\t\t\t\t>\n\t\t\t\t\t<ToggleControl\n\t\t\t\t\t\tlabel={ __( 'Link to user profile' ) }\n\t\t\t\t\t\tonChange={ () =>\n\t\t\t\t\t\t\tsetAttributes( { isLink: ! attributes.isLink } )\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchecked={ attributes.isLink }\n\t\t\t\t\t/>\n\t\t\t\t</ToolsPanelItem>\n\t\t\t\t{ attributes.isLink && (\n\t\t\t\t\t<ToolsPanelItem\n\t\t\t\t\t\tlabel={ __( 'Open in new tab' ) }\n\t\t\t\t\t\tisShownByDefault\n\t\t\t\t\t\thasValue={ () => attributes?.linkTarget !== '_self' }\n\t\t\t\t\t\tonDeselect={ () =>\n\t\t\t\t\t\t\tsetAttributes( { linkTarget: '_self' } )\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ToggleControl\n\t\t\t\t\t\t\tlabel={ __( 'Open in new tab' ) }\n\t\t\t\t\t\t\tonChange={ ( value ) =>\n\t\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\t\tlinkTarget: value ? '_blank' : '_self',\n\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tchecked={ attributes.linkTarget === '_blank' }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</ToolsPanelItem>\n\t\t\t\t) }\n\t\t\t\t{ selectUser && (\n\t\t\t\t\t<ToolsPanelItem\n\t\t\t\t\t\tlabel={ __( 'User' ) }\n\t\t\t\t\t\tisShownByDefault\n\t\t\t\t\t\thasValue={ () => !! attributes?.userId }\n\t\t\t\t\t\tonDeselect={ () =>\n\t\t\t\t\t\t\tsetAttributes( { userId: undefined } )\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t<UserControl\n\t\t\t\t\t\t\tvalue={ attributes?.userId }\n\t\t\t\t\t\t\tonChange={ ( value ) => {\n\t\t\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\t\t\tuserId: value,\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</ToolsPanelItem>\n\t\t\t\t) }\n\t\t\t</ToolsPanel>\n\t\t</InspectorControls>\n\t);\n};\n\n/**\n * Wraps the avatar image in a placeholder link when the block links to the user\n * profile. The link is inert in the editor: it points at a fragment and its\n * click handler prevents navigation.\n *\n * @param {Object} props React props.\n * @param {React.ReactNode} props.children Avatar image to wrap.\n * @param {boolean} props.isLink Whether to wrap the children in a link.\n *\n * @return {React.ReactNode} The children, wrapped in a link when `isLink` is true.\n */\nconst AvatarLinkWrapper = ( { children, isLink } ) =>\n\tisLink ? (\n\t\t<a\n\t\t\thref=\"#avatar-pseudo-link\"\n\t\t\tclassName=\"wp-block-avatar__link\"\n\t\t\tonClick={ ( event ) => event.preventDefault() }\n\t\t>\n\t\t\t{ children }\n\t\t</a>\n\t) : (\n\t\tchildren\n\t);\n\n/**\n * Renders the avatar image inside a `ResizableBox` so its size can be adjusted\n * by dragging. Resizing keeps the aspect ratio and updates the `size` attribute.\n *\n * @param {Object} props React props.\n * @param {Function} props.setAttributes Callback for updating block attributes.\n * @param {Object} props.attributes Block attributes: `size` and `isLink`, plus the border and shadow support values applied to the image.\n * @param {Object} props.avatar Avatar data returned by `useCommentAvatar` or `useUserAvatar`, with the image `src` and `alt` and the `minSize` and `maxSize` resize bounds.\n * @param {Object} props.blockProps Props returned by `useBlockProps`, applied to the wrapper element.\n * @param {boolean} props.isSelected Whether the block is selected. Resize handles are only shown when it is.\n *\n * @return {React.JSX.Element} React element.\n */\nconst ResizableAvatar = ( {\n\tsetAttributes,\n\tattributes,\n\tavatar,\n\tblockProps,\n\tisSelected,\n} ) => {\n\tconst borderProps = useBorderProps( attributes );\n\tconst shadowProps = getShadowClassesAndStyles( attributes );\n\tconst doubledSizedSrc = addQueryArgs(\n\t\tremoveQueryArgs( avatar?.src, [ 's' ] ),\n\t\t{\n\t\t\ts: attributes?.size * 2,\n\t\t}\n\t);\n\treturn (\n\t\t<div { ...blockProps }>\n\t\t\t<AvatarLinkWrapper isLink={ attributes.isLink }>\n\t\t\t\t<ResizableBox\n\t\t\t\t\tsize={ {\n\t\t\t\t\t\twidth: attributes.size,\n\t\t\t\t\t\theight: attributes.size,\n\t\t\t\t\t} }\n\t\t\t\t\tshowHandle={ isSelected }\n\t\t\t\t\tonResizeStop={ ( event, direction, elt, delta ) => {\n\t\t\t\t\t\tsetAttributes( {\n\t\t\t\t\t\t\tsize: parseInt(\n\t\t\t\t\t\t\t\tattributes.size +\n\t\t\t\t\t\t\t\t\t( delta.height || delta.width ),\n\t\t\t\t\t\t\t\t10\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t} );\n\t\t\t\t\t} }\n\t\t\t\t\tlockAspectRatio\n\t\t\t\t\tenable={ {\n\t\t\t\t\t\ttop: false,\n\t\t\t\t\t\tright: ! isRTL(),\n\t\t\t\t\t\tbottom: true,\n\t\t\t\t\t\tleft: isRTL(),\n\t\t\t\t\t} }\n\t\t\t\t\tminWidth={ avatar.minSize }\n\t\t\t\t\tmaxWidth={ avatar.maxSize }\n\t\t\t\t>\n\t\t\t\t\t<img\n\t\t\t\t\t\tsrc={ doubledSizedSrc }\n\t\t\t\t\t\talt={ avatar.alt }\n\t\t\t\t\t\tclassName={ clsx(\n\t\t\t\t\t\t\t'avatar',\n\t\t\t\t\t\t\t'avatar-' + attributes.size,\n\t\t\t\t\t\t\t'photo',\n\t\t\t\t\t\t\t'wp-block-avatar__image',\n\t\t\t\t\t\t\tborderProps.className\n\t\t\t\t\t\t) }\n\t\t\t\t\t\tstyle={ {\n\t\t\t\t\t\t\t...borderProps.style,\n\t\t\t\t\t\t\t...shadowProps.style,\n\t\t\t\t\t\t} }\n\t\t\t\t\t/>\n\t\t\t\t</ResizableBox>\n\t\t\t</AvatarLinkWrapper>\n\t\t</div>\n\t);\n};\n\n/**\n * Renders the block for a comment author, resolving the avatar from the\n * `commentId` context. The user selection control is not offered here because\n * the author is determined by the comment.\n *\n * @param {Object} props React props.\n * @param {Object} props.attributes Block attributes.\n * @param {Object} props.context Inherited context, from which the comment ID is read.\n * @param {Function} props.setAttributes Callback for updating block attributes.\n * @param {boolean} props.isSelected Whether the block is selected.\n *\n * @return {React.JSX.Element} React element.\n */\nconst CommentEdit = ( { attributes, context, setAttributes, isSelected } ) => {\n\tconst { commentId } = context;\n\tconst blockProps = useBlockProps();\n\tconst avatar = useCommentAvatar( { commentId } );\n\treturn (\n\t\t<>\n\t\t\t<AvatarInspectorControls\n\t\t\t\tavatar={ avatar }\n\t\t\t\tsetAttributes={ setAttributes }\n\t\t\t\tattributes={ attributes }\n\t\t\t\tselectUser={ false }\n\t\t\t/>\n\t\t\t<ResizableAvatar\n\t\t\t\tattributes={ attributes }\n\t\t\t\tavatar={ avatar }\n\t\t\t\tblockProps={ blockProps }\n\t\t\t\tisSelected={ isSelected }\n\t\t\t\tsetAttributes={ setAttributes }\n\t\t\t/>\n\t\t</>\n\t);\n};\n\n/**\n * Renders the block for a user, resolving the avatar from the `userId`\n * attribute when set, and otherwise from the author of the post identified by\n * the `postType` and `postId` context.\n *\n * @param {Object} props React props.\n * @param {Object} props.attributes Block attributes, from which the `userId` is read.\n * @param {Object} props.context Inherited context, from which the post type and post ID are read.\n * @param {Function} props.setAttributes Callback for updating block attributes.\n * @param {boolean} props.isSelected Whether the block is selected.\n *\n * @return {React.JSX.Element} React element.\n */\nconst UserEdit = ( { attributes, context, setAttributes, isSelected } ) => {\n\tconst { postId, postType } = context;\n\tconst avatar = useUserAvatar( {\n\t\tuserId: attributes?.userId,\n\t\tpostId,\n\t\tpostType,\n\t} );\n\tconst blockProps = useBlockProps();\n\treturn (\n\t\t<>\n\t\t\t<AvatarInspectorControls\n\t\t\t\tselectUser\n\t\t\t\tattributes={ attributes }\n\t\t\t\tavatar={ avatar }\n\t\t\t\tsetAttributes={ setAttributes }\n\t\t\t/>\n\n\t\t\t<ResizableAvatar\n\t\t\t\tattributes={ attributes }\n\t\t\t\tavatar={ avatar }\n\t\t\t\tblockProps={ blockProps }\n\t\t\t\tisSelected={ isSelected }\n\t\t\t\tsetAttributes={ setAttributes }\n\t\t\t/>\n\t\t</>\n\t);\n};\n\n/**\n * Renders the `core/avatar` block on the editor. All props are forwarded to\n * either `CommentEdit` or `UserEdit`, depending on whether the block is used\n * inside a comment.\n *\n * @param {Object} props React props.\n * @param {Object} props.attributes Block attributes.\n * @param {Object} props.context Inherited context.\n * @param {number|null} [props.context.commentId] The comment ID when the block is used inside a comment. `null` in the Site Editor, where no comment is resolved but the comment variant is still rendered.\n * @param {string} [props.context.postType] The post type of the current post.\n * @param {number} [props.context.postId] The ID of the current post.\n * @param {Function} props.setAttributes Callback for updating block attributes.\n * @param {boolean} props.isSelected Whether the block is selected.\n *\n * @return {React.JSX.Element} React element.\n */\nexport default function Edit( props ) {\n\t// Don't show the Comment Edit controls if we have a comment ID set, or if we're in the Site Editor (where it is `null`).\n\tif ( props?.context?.commentId || props?.context?.commentId === null ) {\n\t\treturn <CommentEdit { ...props } />;\n\t}\n\treturn <UserEdit { ...props } />;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -70,6 +70,12 @@
|
|
|
70
70
|
"splitting": true,
|
|
71
71
|
"align": false,
|
|
72
72
|
"alignWide": false,
|
|
73
|
+
"background": {
|
|
74
|
+
"backgroundImage": true,
|
|
75
|
+
"backgroundSize": true,
|
|
76
|
+
"gradient": true,
|
|
77
|
+
"__experimentalSkipSerialization": true
|
|
78
|
+
},
|
|
73
79
|
"color": {
|
|
74
80
|
"__experimentalSkipSerialization": true,
|
|
75
81
|
"gradients": true,
|