@wordpress/block-library 8.22.0 → 8.24.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 +4 -0
- package/build/block/edit.js +11 -13
- package/build/block/edit.js.map +1 -1
- package/build/block/edit.native.js +3 -4
- package/build/block/edit.native.js.map +1 -1
- package/build/button/edit.js +61 -9
- package/build/button/edit.js.map +1 -1
- package/build/code/transforms.js +20 -7
- package/build/code/transforms.js.map +1 -1
- package/build/column/edit.js +1 -1
- package/build/column/edit.js.map +1 -1
- package/build/column/edit.native.js +1 -1
- package/build/column/edit.native.js.map +1 -1
- package/build/comments/edit/comments-inspector-controls.js +1 -0
- package/build/comments/edit/comments-inspector-controls.js.map +1 -1
- package/build/cover/edit/index.js +2 -1
- package/build/cover/edit/index.js.map +1 -1
- package/build/cover/edit/inspector-controls.js +1 -0
- package/build/cover/edit/inspector-controls.js.map +1 -1
- package/build/details/edit.js +1 -2
- package/build/details/edit.js.map +1 -1
- package/build/file/edit.js +8 -9
- package/build/file/edit.js.map +1 -1
- package/build/file/view.js +4 -6
- package/build/file/view.js.map +1 -1
- package/build/form/index.js +1 -1
- package/build/form/index.js.map +1 -1
- package/build/form-submit-button/edit.js +2 -1
- package/build/form-submit-button/edit.js.map +1 -1
- package/build/gallery/gap-styles.js +12 -7
- package/build/gallery/gap-styles.js.map +1 -1
- package/build/group/edit.js +4 -7
- package/build/group/edit.js.map +1 -1
- package/build/html/transforms.js +7 -2
- package/build/html/transforms.js.map +1 -1
- package/build/image/deprecated.js +8 -0
- package/build/image/deprecated.js.map +1 -1
- package/build/image/edit.js +17 -18
- package/build/image/edit.js.map +1 -1
- package/build/image/edit.native.js +22 -15
- package/build/image/edit.native.js.map +1 -1
- package/build/image/image.js +35 -27
- package/build/image/image.js.map +1 -1
- package/build/image/index.js +2 -3
- package/build/image/index.js.map +1 -1
- package/build/image/view.js +234 -266
- package/build/image/view.js.map +1 -1
- package/build/missing/index.js +1 -1
- package/build/navigation/edit/overlay-menu-preview.js +1 -1
- package/build/navigation/edit/overlay-menu-preview.js.map +1 -1
- package/build/navigation/use-template-part-area-label.js +2 -1
- package/build/navigation/use-template-part-area-label.js.map +1 -1
- package/build/navigation/view.js +153 -176
- package/build/navigation/view.js.map +1 -1
- package/build/navigation-link/edit.js +1 -1
- package/build/navigation-link/edit.js.map +1 -1
- package/build/navigation-link/index.js +2 -1
- package/build/navigation-link/index.js.map +1 -1
- package/build/pattern/edit.js +2 -4
- package/build/pattern/edit.js.map +1 -1
- package/build/post-author/edit.js +0 -1
- package/build/post-author/edit.js.map +1 -1
- package/build/post-featured-image/edit.js +21 -6
- package/build/post-featured-image/edit.js.map +1 -1
- package/build/post-template/edit.js +2 -8
- package/build/post-template/edit.js.map +1 -1
- package/build/post-template/index.js +1 -1
- package/build/post-terms/edit.js +0 -2
- package/build/post-terms/edit.js.map +1 -1
- package/build/preformatted/transforms.js +1 -4
- package/build/preformatted/transforms.js.map +1 -1
- package/build/query/edit/query-content.js +1 -0
- package/build/query/edit/query-content.js.map +1 -1
- package/build/query/view.js +52 -60
- package/build/query/view.js.map +1 -1
- package/build/quote/index.js +6 -0
- package/build/quote/index.js.map +1 -1
- package/build/search/view.js +66 -74
- package/build/search/view.js.map +1 -1
- package/build/template-part/edit/advanced-controls.js +1 -0
- package/build/template-part/edit/advanced-controls.js.map +1 -1
- package/build/template-part/edit/index.js +3 -7
- package/build/template-part/edit/index.js.map +1 -1
- package/build/template-part/index.js +6 -2
- package/build/template-part/index.js.map +1 -1
- package/build/template-part/variations.js +5 -1
- package/build/template-part/variations.js.map +1 -1
- package/build/utils/remove-anchor-tag.js +17 -0
- package/build/utils/remove-anchor-tag.js.map +1 -0
- package/build-module/block/edit.js +11 -13
- package/build-module/block/edit.js.map +1 -1
- package/build-module/block/edit.native.js +3 -4
- package/build-module/block/edit.native.js.map +1 -1
- package/build-module/button/edit.js +65 -13
- package/build-module/button/edit.js.map +1 -1
- package/build-module/code/transforms.js +20 -7
- package/build-module/code/transforms.js.map +1 -1
- package/build-module/column/edit.js +1 -1
- package/build-module/column/edit.js.map +1 -1
- package/build-module/column/edit.native.js +1 -1
- package/build-module/column/edit.native.js.map +1 -1
- package/build-module/comments/edit/comments-inspector-controls.js +1 -0
- package/build-module/comments/edit/comments-inspector-controls.js.map +1 -1
- package/build-module/cover/edit/index.js +2 -1
- package/build-module/cover/edit/index.js.map +1 -1
- package/build-module/cover/edit/inspector-controls.js +1 -0
- package/build-module/cover/edit/inspector-controls.js.map +1 -1
- package/build-module/details/edit.js +1 -2
- package/build-module/details/edit.js.map +1 -1
- package/build-module/file/edit.js +8 -9
- package/build-module/file/edit.js.map +1 -1
- package/build-module/file/view.js +5 -7
- package/build-module/file/view.js.map +1 -1
- package/build-module/form/index.js +1 -1
- package/build-module/form/index.js.map +1 -1
- package/build-module/form-submit-button/edit.js +2 -1
- package/build-module/form-submit-button/edit.js.map +1 -1
- package/build-module/gallery/gap-styles.js +13 -8
- package/build-module/gallery/gap-styles.js.map +1 -1
- package/build-module/group/edit.js +4 -7
- package/build-module/group/edit.js.map +1 -1
- package/build-module/html/transforms.js +7 -2
- package/build-module/html/transforms.js.map +1 -1
- package/build-module/image/deprecated.js +8 -0
- package/build-module/image/deprecated.js.map +1 -1
- package/build-module/image/edit.js +18 -19
- package/build-module/image/edit.js.map +1 -1
- package/build-module/image/edit.native.js +23 -16
- package/build-module/image/edit.native.js.map +1 -1
- package/build-module/image/image.js +36 -28
- package/build-module/image/image.js.map +1 -1
- package/build-module/image/index.js +2 -3
- package/build-module/image/index.js.map +1 -1
- package/build-module/image/view.js +235 -267
- package/build-module/image/view.js.map +1 -1
- package/build-module/missing/index.js +1 -1
- package/build-module/navigation/edit/overlay-menu-preview.js +1 -1
- package/build-module/navigation/edit/overlay-menu-preview.js.map +1 -1
- package/build-module/navigation/use-template-part-area-label.js +2 -1
- package/build-module/navigation/use-template-part-area-label.js.map +1 -1
- package/build-module/navigation/view.js +154 -177
- package/build-module/navigation/view.js.map +1 -1
- package/build-module/navigation-link/edit.js +2 -2
- package/build-module/navigation-link/edit.js.map +1 -1
- package/build-module/navigation-link/index.js +2 -1
- package/build-module/navigation-link/index.js.map +1 -1
- package/build-module/pattern/edit.js +2 -4
- package/build-module/pattern/edit.js.map +1 -1
- package/build-module/post-author/edit.js +0 -1
- package/build-module/post-author/edit.js.map +1 -1
- package/build-module/post-featured-image/edit.js +21 -6
- package/build-module/post-featured-image/edit.js.map +1 -1
- package/build-module/post-template/edit.js +2 -8
- package/build-module/post-template/edit.js.map +1 -1
- package/build-module/post-template/index.js +1 -1
- package/build-module/post-terms/edit.js +0 -2
- package/build-module/post-terms/edit.js.map +1 -1
- package/build-module/preformatted/transforms.js +1 -4
- package/build-module/preformatted/transforms.js.map +1 -1
- package/build-module/query/edit/query-content.js +1 -0
- package/build-module/query/edit/query-content.js.map +1 -1
- package/build-module/query/view.js +53 -61
- package/build-module/query/view.js.map +1 -1
- package/build-module/quote/index.js +6 -0
- package/build-module/quote/index.js.map +1 -1
- package/build-module/search/view.js +67 -75
- package/build-module/search/view.js.map +1 -1
- package/build-module/template-part/edit/advanced-controls.js +1 -0
- package/build-module/template-part/edit/advanced-controls.js.map +1 -1
- package/build-module/template-part/edit/index.js +5 -9
- package/build-module/template-part/edit/index.js.map +1 -1
- package/build-module/template-part/index.js +6 -2
- package/build-module/template-part/index.js.map +1 -1
- package/build-module/template-part/variations.js +5 -1
- package/build-module/template-part/variations.js.map +1 -1
- package/build-module/utils/remove-anchor-tag.js +11 -0
- package/build-module/utils/remove-anchor-tag.js.map +1 -0
- package/build-style/cover/style-rtl.css +14 -14
- package/build-style/cover/style.css +14 -14
- package/build-style/editor-rtl.css +15 -6
- package/build-style/editor.css +15 -6
- package/build-style/gallery/style-rtl.css +28 -0
- package/build-style/gallery/style.css +28 -0
- package/build-style/image/style-rtl.css +19 -13
- package/build-style/image/style.css +19 -13
- package/build-style/post-featured-image/editor-rtl.css +9 -0
- package/build-style/post-featured-image/editor.css +9 -0
- package/build-style/quote/style-rtl.css +3 -0
- package/build-style/quote/style.css +3 -0
- package/build-style/read-more/style-rtl.css +2 -2
- package/build-style/read-more/style.css +2 -2
- package/build-style/style-rtl.css +66 -29
- package/build-style/style.css +66 -29
- package/package.json +32 -32
- package/src/block/edit.js +20 -20
- package/src/block/edit.native.js +5 -13
- package/src/button/edit.js +76 -10
- package/src/buttons/test/__snapshots__/edit.native.js.snap +0 -6
- package/src/buttons/test/edit.native.js +0 -27
- package/src/code/transforms.js +14 -8
- package/src/column/edit.js +1 -1
- package/src/column/edit.native.js +1 -1
- package/src/comments/edit/comments-inspector-controls.js +1 -0
- package/src/cover/edit/index.js +1 -0
- package/src/cover/edit/inspector-controls.js +1 -0
- package/src/cover/style.scss +1 -1
- package/src/cover/test/edit.js +1 -1
- package/src/details/edit.js +0 -1
- package/src/editor.scss +6 -6
- package/src/file/edit.js +11 -10
- package/src/file/index.php +30 -11
- package/src/file/view.js +5 -7
- package/src/form/index.js +1 -1
- package/src/form-submit-button/edit.js +1 -0
- package/src/gallery/gap-styles.js +10 -9
- package/src/gallery/style.scss +1 -0
- package/src/group/edit.js +4 -11
- package/src/heading/test/__snapshots__/index.native.js.snap +6 -0
- package/src/heading/test/index.native.js +40 -0
- package/src/html/transforms.js +5 -2
- package/src/image/block.json +2 -3
- package/src/image/deprecated.js +8 -0
- package/src/image/edit.js +16 -21
- package/src/image/edit.native.js +17 -18
- package/src/image/image.js +48 -51
- package/src/image/index.php +57 -49
- package/src/image/style.scss +18 -13
- package/src/image/view.js +281 -324
- package/src/missing/block.json +1 -1
- package/src/navigation/edit/overlay-menu-preview.js +1 -1
- package/src/navigation/index.php +46 -402
- package/src/navigation/use-template-part-area-label.js +4 -2
- package/src/navigation/view.js +159 -192
- package/src/navigation-link/block.json +2 -1
- package/src/navigation-link/edit.js +2 -2
- package/src/navigation-link/index.php +57 -0
- package/src/paragraph/test/__snapshots__/transforms.native.js.snap +6 -0
- package/src/paragraph/test/edit.native.js +37 -1
- package/src/paragraph/test/transforms.native.js +1 -0
- package/src/pattern/edit.js +7 -4
- package/src/pattern/index.php +6 -1
- package/src/post-author/edit.js +0 -1
- package/src/post-featured-image/edit.js +38 -5
- package/src/post-featured-image/editor.scss +19 -0
- package/src/post-template/block.json +0 -1
- package/src/post-template/edit.js +1 -5
- package/src/post-terms/edit.js +0 -2
- package/src/preformatted/transforms.js +1 -4
- package/src/query/edit/query-content.js +1 -0
- package/src/query/index.php +42 -24
- package/src/query/view.js +58 -65
- package/src/query-pagination-next/index.php +3 -3
- package/src/query-pagination-numbers/index.php +1 -1
- package/src/query-pagination-previous/index.php +3 -3
- package/src/quote/block.json +6 -0
- package/src/quote/style.scss +4 -0
- package/src/read-more/style.scss +1 -1
- package/src/search/index.php +40 -40
- package/src/search/view.js +58 -63
- package/src/template-part/edit/advanced-controls.js +1 -0
- package/src/template-part/edit/index.js +7 -14
- package/src/template-part/index.js +4 -3
- package/src/template-part/index.php +4 -4
- package/src/template-part/variations.js +4 -2
- package/src/utils/remove-anchor-tag.js +10 -0
- package/tsconfig.json +1 -0
package/src/image/view.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { store } from '@wordpress/interactivity';
|
|
4
|
+
import { store, getContext, getElement } from '@wordpress/interactivity';
|
|
5
5
|
|
|
6
6
|
const focusableSelectors = [
|
|
7
7
|
'a[href]',
|
|
@@ -17,7 +17,7 @@ const focusableSelectors = [
|
|
|
17
17
|
'[tabindex]:not([tabindex^="-"])',
|
|
18
18
|
];
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
21
|
* Stores a context-bound scroll handler.
|
|
22
22
|
*
|
|
23
23
|
* This callback could be defined inline inside of the store
|
|
@@ -32,7 +32,7 @@ const focusableSelectors = [
|
|
|
32
32
|
*/
|
|
33
33
|
let scrollCallback;
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
/**
|
|
36
36
|
* Tracks whether user is touching screen; used to
|
|
37
37
|
* differentiate behavior for touch and mouse input.
|
|
38
38
|
*
|
|
@@ -40,7 +40,7 @@ let scrollCallback;
|
|
|
40
40
|
*/
|
|
41
41
|
let isTouching = false;
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
/**
|
|
44
44
|
* Tracks the last time the screen was touched; used to
|
|
45
45
|
* differentiate behavior for touch and mouse input.
|
|
46
46
|
*
|
|
@@ -48,7 +48,7 @@ let isTouching = false;
|
|
|
48
48
|
*/
|
|
49
49
|
let lastTouchTime = 0;
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
/**
|
|
52
52
|
* Lightbox page-scroll handler: prevents scrolling.
|
|
53
53
|
*
|
|
54
54
|
* This handler is added to prevent scrolling behaviors that
|
|
@@ -64,338 +64,296 @@ let lastTouchTime = 0;
|
|
|
64
64
|
* instead to not rely on JavaScript, but this seems to be the best approach
|
|
65
65
|
* for now that provides the best visual experience.
|
|
66
66
|
*
|
|
67
|
-
* @param {Object}
|
|
67
|
+
* @param {Object} ctx Context object with the `core/image` namespace.
|
|
68
68
|
*/
|
|
69
|
-
function handleScroll(
|
|
69
|
+
function handleScroll( ctx ) {
|
|
70
70
|
// We can't override the scroll behavior on mobile devices
|
|
71
71
|
// because doing so breaks the pinch to zoom functionality, and we
|
|
72
72
|
// want to allow users to zoom in further on the high-res image.
|
|
73
73
|
if ( ! isTouching && Date.now() - lastTouchTime > 450 ) {
|
|
74
74
|
// We are unable to use event.preventDefault() to prevent scrolling
|
|
75
75
|
// because the scroll event can't be canceled, so we reset the position instead.
|
|
76
|
-
window.scrollTo(
|
|
77
|
-
context.core.image.scrollLeftReset,
|
|
78
|
-
context.core.image.scrollTopReset
|
|
79
|
-
);
|
|
76
|
+
window.scrollTo( ctx.scrollLeftReset, ctx.scrollTopReset );
|
|
80
77
|
}
|
|
81
78
|
}
|
|
82
79
|
|
|
83
|
-
store(
|
|
84
|
-
{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
},
|
|
91
|
-
},
|
|
80
|
+
const { state, actions, callbacks } = store( 'core/image', {
|
|
81
|
+
state: {
|
|
82
|
+
windowWidth: window.innerWidth,
|
|
83
|
+
windowHeight: window.innerHeight,
|
|
84
|
+
get roleAttribute() {
|
|
85
|
+
const ctx = getContext();
|
|
86
|
+
return ctx.lightboxEnabled ? 'dialog' : null;
|
|
92
87
|
},
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
showLightbox: ( { context, event } ) => {
|
|
97
|
-
// We can't initialize the lightbox until the reference
|
|
98
|
-
// image is loaded, otherwise the UX is broken.
|
|
99
|
-
if ( ! context.core.image.imageLoaded ) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
context.core.image.initialized = true;
|
|
103
|
-
context.core.image.lastFocusedElement =
|
|
104
|
-
window.document.activeElement;
|
|
105
|
-
context.core.image.scrollDelta = 0;
|
|
106
|
-
context.core.image.pointerType = event.pointerType;
|
|
107
|
-
|
|
108
|
-
context.core.image.lightboxEnabled = true;
|
|
109
|
-
setStyles( context, context.core.image.imageRef );
|
|
110
|
-
|
|
111
|
-
context.core.image.scrollTopReset =
|
|
112
|
-
window.pageYOffset ||
|
|
113
|
-
document.documentElement.scrollTop;
|
|
114
|
-
|
|
115
|
-
// In most cases, this value will be 0, but this is included
|
|
116
|
-
// in case a user has created a page with horizontal scrolling.
|
|
117
|
-
context.core.image.scrollLeftReset =
|
|
118
|
-
window.pageXOffset ||
|
|
119
|
-
document.documentElement.scrollLeft;
|
|
120
|
-
|
|
121
|
-
// We define and bind the scroll callback here so
|
|
122
|
-
// that we can pass the context and as an argument.
|
|
123
|
-
// We may be able to change this in the future if we
|
|
124
|
-
// define the scroll callback in the store instead, but
|
|
125
|
-
// this approach seems to tbe clearest for now.
|
|
126
|
-
scrollCallback = handleScroll.bind( null, context );
|
|
127
|
-
|
|
128
|
-
// We need to add a scroll event listener to the window
|
|
129
|
-
// here because we are unable to otherwise access it via
|
|
130
|
-
// the Interactivity API directives. If we add a native way
|
|
131
|
-
// to access the window, we can remove this.
|
|
132
|
-
window.addEventListener(
|
|
133
|
-
'scroll',
|
|
134
|
-
scrollCallback,
|
|
135
|
-
false
|
|
136
|
-
);
|
|
137
|
-
},
|
|
138
|
-
hideLightbox: async ( { context } ) => {
|
|
139
|
-
context.core.image.hideAnimationEnabled = true;
|
|
140
|
-
if ( context.core.image.lightboxEnabled ) {
|
|
141
|
-
// We want to wait until the close animation is completed
|
|
142
|
-
// before allowing a user to scroll again. The duration of this
|
|
143
|
-
// animation is defined in the styles.scss and depends on if the
|
|
144
|
-
// animation is 'zoom' or 'fade', but in any case we should wait
|
|
145
|
-
// a few milliseconds longer than the duration, otherwise a user
|
|
146
|
-
// may scroll too soon and cause the animation to look sloppy.
|
|
147
|
-
setTimeout( function () {
|
|
148
|
-
window.removeEventListener(
|
|
149
|
-
'scroll',
|
|
150
|
-
scrollCallback
|
|
151
|
-
);
|
|
152
|
-
// If we don't delay before changing the focus,
|
|
153
|
-
// the focus ring will appear on Firefox before
|
|
154
|
-
// the image has finished animating, which looks broken.
|
|
155
|
-
context.core.image.lightboxTriggerRef.focus( {
|
|
156
|
-
preventScroll: true,
|
|
157
|
-
} );
|
|
158
|
-
}, 450 );
|
|
159
|
-
|
|
160
|
-
context.core.image.lightboxEnabled = false;
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
handleKeydown: ( { context, actions, event } ) => {
|
|
164
|
-
if ( context.core.image.lightboxEnabled ) {
|
|
165
|
-
if ( event.key === 'Tab' || event.keyCode === 9 ) {
|
|
166
|
-
// If shift + tab it change the direction
|
|
167
|
-
if (
|
|
168
|
-
event.shiftKey &&
|
|
169
|
-
window.document.activeElement ===
|
|
170
|
-
context.core.image.firstFocusableElement
|
|
171
|
-
) {
|
|
172
|
-
event.preventDefault();
|
|
173
|
-
context.core.image.lastFocusableElement.focus();
|
|
174
|
-
} else if (
|
|
175
|
-
! event.shiftKey &&
|
|
176
|
-
window.document.activeElement ===
|
|
177
|
-
context.core.image.lastFocusableElement
|
|
178
|
-
) {
|
|
179
|
-
event.preventDefault();
|
|
180
|
-
context.core.image.firstFocusableElement.focus();
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (
|
|
185
|
-
event.key === 'Escape' ||
|
|
186
|
-
event.keyCode === 27
|
|
187
|
-
) {
|
|
188
|
-
actions.core.image.hideLightbox( {
|
|
189
|
-
context,
|
|
190
|
-
event,
|
|
191
|
-
} );
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
},
|
|
195
|
-
// This is fired just by lazily loaded
|
|
196
|
-
// images on the page, not all images.
|
|
197
|
-
handleLoad: ( { context, effects, ref } ) => {
|
|
198
|
-
context.core.image.imageLoaded = true;
|
|
199
|
-
context.core.image.imageCurrentSrc = ref.currentSrc;
|
|
200
|
-
effects.core.image.setButtonStyles( {
|
|
201
|
-
context,
|
|
202
|
-
ref,
|
|
203
|
-
} );
|
|
204
|
-
},
|
|
205
|
-
handleTouchStart: () => {
|
|
206
|
-
isTouching = true;
|
|
207
|
-
},
|
|
208
|
-
handleTouchMove: ( { context, event } ) => {
|
|
209
|
-
// On mobile devices, we want to prevent triggering the
|
|
210
|
-
// scroll event because otherwise the page jumps around as
|
|
211
|
-
// we reset the scroll position. This also means that closing
|
|
212
|
-
// the lightbox requires that a user perform a simple tap. This
|
|
213
|
-
// may be changed in the future if we find a better alternative
|
|
214
|
-
// to override or reset the scroll position during swipe actions.
|
|
215
|
-
if ( context.core.image.lightboxEnabled ) {
|
|
216
|
-
event.preventDefault();
|
|
217
|
-
}
|
|
218
|
-
},
|
|
219
|
-
handleTouchEnd: () => {
|
|
220
|
-
// We need to wait a few milliseconds before resetting
|
|
221
|
-
// to ensure that pinch to zoom works consistently
|
|
222
|
-
// on mobile devices when the lightbox is open.
|
|
223
|
-
lastTouchTime = Date.now();
|
|
224
|
-
isTouching = false;
|
|
225
|
-
},
|
|
226
|
-
},
|
|
227
|
-
},
|
|
88
|
+
get ariaModal() {
|
|
89
|
+
const ctx = getContext();
|
|
90
|
+
return ctx.lightboxEnabled ? 'true' : null;
|
|
228
91
|
},
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
roleAttribute: ( { context } ) => {
|
|
233
|
-
return context.core.image.lightboxEnabled
|
|
234
|
-
? 'dialog'
|
|
235
|
-
: null;
|
|
236
|
-
},
|
|
237
|
-
ariaModal: ( { context } ) => {
|
|
238
|
-
return context.core.image.lightboxEnabled
|
|
239
|
-
? 'true'
|
|
240
|
-
: null;
|
|
241
|
-
},
|
|
242
|
-
dialogLabel: ( { context } ) => {
|
|
243
|
-
return context.core.image.lightboxEnabled
|
|
244
|
-
? context.core.image.dialogLabel
|
|
245
|
-
: null;
|
|
246
|
-
},
|
|
247
|
-
lightboxObjectFit: ( { context } ) => {
|
|
248
|
-
if ( context.core.image.initialized ) {
|
|
249
|
-
return 'cover';
|
|
250
|
-
}
|
|
251
|
-
},
|
|
252
|
-
enlargedImgSrc: ( { context } ) => {
|
|
253
|
-
return context.core.image.initialized
|
|
254
|
-
? context.core.image.imageUploadedSrc
|
|
255
|
-
: 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
|
|
256
|
-
},
|
|
257
|
-
},
|
|
258
|
-
},
|
|
92
|
+
get dialogLabel() {
|
|
93
|
+
const ctx = getContext();
|
|
94
|
+
return ctx.lightboxEnabled ? ctx.dialogLabel : null;
|
|
259
95
|
},
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
context.core.image.imageCurrentSrc = ref.currentSrc;
|
|
272
|
-
}
|
|
273
|
-
},
|
|
274
|
-
initLightbox: async ( { context, ref } ) => {
|
|
275
|
-
if ( context.core.image.lightboxEnabled ) {
|
|
276
|
-
const focusableElements =
|
|
277
|
-
ref.querySelectorAll( focusableSelectors );
|
|
278
|
-
context.core.image.firstFocusableElement =
|
|
279
|
-
focusableElements[ 0 ];
|
|
280
|
-
context.core.image.lastFocusableElement =
|
|
281
|
-
focusableElements[
|
|
282
|
-
focusableElements.length - 1
|
|
283
|
-
];
|
|
284
|
-
|
|
285
|
-
// Move focus to the dialog when opening it.
|
|
286
|
-
ref.focus();
|
|
287
|
-
}
|
|
288
|
-
},
|
|
289
|
-
setButtonStyles: ( { context, ref } ) => {
|
|
290
|
-
const {
|
|
291
|
-
naturalWidth,
|
|
292
|
-
naturalHeight,
|
|
293
|
-
offsetWidth,
|
|
294
|
-
offsetHeight,
|
|
295
|
-
} = ref;
|
|
296
|
-
|
|
297
|
-
// If the image isn't loaded yet, we can't
|
|
298
|
-
// calculate where the button should be.
|
|
299
|
-
if ( naturalWidth === 0 || naturalHeight === 0 ) {
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
const figure = ref.parentElement;
|
|
304
|
-
const figureWidth = ref.parentElement.clientWidth;
|
|
305
|
-
|
|
306
|
-
// We need special handling for the height because
|
|
307
|
-
// a caption will cause the figure to be taller than
|
|
308
|
-
// the image, which means we need to account for that
|
|
309
|
-
// when calculating the placement of the button in the
|
|
310
|
-
// top right corner of the image.
|
|
311
|
-
let figureHeight = ref.parentElement.clientHeight;
|
|
312
|
-
const caption = figure.querySelector( 'figcaption' );
|
|
313
|
-
if ( caption ) {
|
|
314
|
-
const captionComputedStyle =
|
|
315
|
-
window.getComputedStyle( caption );
|
|
316
|
-
figureHeight =
|
|
317
|
-
figureHeight -
|
|
318
|
-
caption.offsetHeight -
|
|
319
|
-
parseFloat( captionComputedStyle.marginTop ) -
|
|
320
|
-
parseFloat( captionComputedStyle.marginBottom );
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
const buttonOffsetTop = figureHeight - offsetHeight;
|
|
324
|
-
const buttonOffsetRight = figureWidth - offsetWidth;
|
|
325
|
-
|
|
326
|
-
// In the case of an image with object-fit: contain, the
|
|
327
|
-
// size of the <img> element can be larger than the image itself,
|
|
328
|
-
// so we need to calculate where to place the button.
|
|
329
|
-
if ( context.core.image.scaleAttr === 'contain' ) {
|
|
330
|
-
// Natural ratio of the image.
|
|
331
|
-
const naturalRatio = naturalWidth / naturalHeight;
|
|
332
|
-
// Offset ratio of the image.
|
|
333
|
-
const offsetRatio = offsetWidth / offsetHeight;
|
|
334
|
-
|
|
335
|
-
if ( naturalRatio >= offsetRatio ) {
|
|
336
|
-
// If it reaches the width first, keep
|
|
337
|
-
// the width and compute the height.
|
|
338
|
-
const referenceHeight =
|
|
339
|
-
offsetWidth / naturalRatio;
|
|
340
|
-
context.core.image.imageButtonTop =
|
|
341
|
-
( offsetHeight - referenceHeight ) / 2 +
|
|
342
|
-
buttonOffsetTop +
|
|
343
|
-
10;
|
|
344
|
-
context.core.image.imageButtonRight =
|
|
345
|
-
buttonOffsetRight + 10;
|
|
346
|
-
} else {
|
|
347
|
-
// If it reaches the height first, keep
|
|
348
|
-
// the height and compute the width.
|
|
349
|
-
const referenceWidth =
|
|
350
|
-
offsetHeight * naturalRatio;
|
|
351
|
-
context.core.image.imageButtonTop =
|
|
352
|
-
buttonOffsetTop + 10;
|
|
353
|
-
context.core.image.imageButtonRight =
|
|
354
|
-
( offsetWidth - referenceWidth ) / 2 +
|
|
355
|
-
buttonOffsetRight +
|
|
356
|
-
10;
|
|
357
|
-
}
|
|
358
|
-
} else {
|
|
359
|
-
context.core.image.imageButtonTop =
|
|
360
|
-
buttonOffsetTop + 10;
|
|
361
|
-
context.core.image.imageButtonRight =
|
|
362
|
-
buttonOffsetRight + 10;
|
|
363
|
-
}
|
|
364
|
-
},
|
|
365
|
-
setStylesOnResize: ( { state, context, ref } ) => {
|
|
366
|
-
if (
|
|
367
|
-
context.core.image.lightboxEnabled &&
|
|
368
|
-
( state.core.image.windowWidth ||
|
|
369
|
-
state.core.image.windowHeight )
|
|
370
|
-
) {
|
|
371
|
-
setStyles( context, ref );
|
|
372
|
-
}
|
|
373
|
-
},
|
|
374
|
-
},
|
|
375
|
-
},
|
|
96
|
+
get lightboxObjectFit() {
|
|
97
|
+
const ctx = getContext();
|
|
98
|
+
if ( ctx.initialized ) {
|
|
99
|
+
return 'cover';
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
get enlargedImgSrc() {
|
|
103
|
+
const ctx = getContext();
|
|
104
|
+
return ctx.initialized
|
|
105
|
+
? ctx.imageUploadedSrc
|
|
106
|
+
: 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
|
|
376
107
|
},
|
|
377
108
|
},
|
|
378
|
-
{
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
109
|
+
actions: {
|
|
110
|
+
showLightbox( event ) {
|
|
111
|
+
const ctx = getContext();
|
|
112
|
+
// We can't initialize the lightbox until the reference
|
|
113
|
+
// image is loaded, otherwise the UX is broken.
|
|
114
|
+
if ( ! ctx.imageLoaded ) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
ctx.initialized = true;
|
|
118
|
+
ctx.lastFocusedElement = window.document.activeElement;
|
|
119
|
+
ctx.scrollDelta = 0;
|
|
120
|
+
ctx.pointerType = event.pointerType;
|
|
121
|
+
|
|
122
|
+
ctx.lightboxEnabled = true;
|
|
123
|
+
setStyles( ctx, ctx.imageRef );
|
|
124
|
+
|
|
125
|
+
ctx.scrollTopReset =
|
|
126
|
+
window.pageYOffset || document.documentElement.scrollTop;
|
|
127
|
+
|
|
128
|
+
// In most cases, this value will be 0, but this is included
|
|
129
|
+
// in case a user has created a page with horizontal scrolling.
|
|
130
|
+
ctx.scrollLeftReset =
|
|
131
|
+
window.pageXOffset || document.documentElement.scrollLeft;
|
|
132
|
+
|
|
133
|
+
// We define and bind the scroll callback here so
|
|
134
|
+
// that we can pass the context and as an argument.
|
|
135
|
+
// We may be able to change this in the future if we
|
|
136
|
+
// define the scroll callback in the store instead, but
|
|
137
|
+
// this approach seems to tbe clearest for now.
|
|
138
|
+
scrollCallback = handleScroll.bind( null, ctx );
|
|
139
|
+
|
|
140
|
+
// We need to add a scroll event listener to the window
|
|
141
|
+
// here because we are unable to otherwise access it via
|
|
142
|
+
// the Interactivity API directives. If we add a native way
|
|
143
|
+
// to access the window, we can remove this.
|
|
144
|
+
window.addEventListener( 'scroll', scrollCallback, false );
|
|
387
145
|
},
|
|
388
|
-
|
|
146
|
+
hideLightbox() {
|
|
147
|
+
const ctx = getContext();
|
|
148
|
+
ctx.hideAnimationEnabled = true;
|
|
149
|
+
if ( ctx.lightboxEnabled ) {
|
|
150
|
+
// We want to wait until the close animation is completed
|
|
151
|
+
// before allowing a user to scroll again. The duration of this
|
|
152
|
+
// animation is defined in the styles.scss and depends on if the
|
|
153
|
+
// animation is 'zoom' or 'fade', but in any case we should wait
|
|
154
|
+
// a few milliseconds longer than the duration, otherwise a user
|
|
155
|
+
// may scroll too soon and cause the animation to look sloppy.
|
|
156
|
+
setTimeout( function () {
|
|
157
|
+
window.removeEventListener( 'scroll', scrollCallback );
|
|
158
|
+
// If we don't delay before changing the focus,
|
|
159
|
+
// the focus ring will appear on Firefox before
|
|
160
|
+
// the image has finished animating, which looks broken.
|
|
161
|
+
ctx.lightboxTriggerRef.focus( {
|
|
162
|
+
preventScroll: true,
|
|
163
|
+
} );
|
|
164
|
+
}, 450 );
|
|
165
|
+
|
|
166
|
+
ctx.lightboxEnabled = false;
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
handleKeydown( event ) {
|
|
170
|
+
const ctx = getContext();
|
|
171
|
+
if ( ctx.lightboxEnabled ) {
|
|
172
|
+
if ( event.key === 'Tab' || event.keyCode === 9 ) {
|
|
173
|
+
// If shift + tab it change the direction
|
|
174
|
+
if (
|
|
175
|
+
event.shiftKey &&
|
|
176
|
+
window.document.activeElement ===
|
|
177
|
+
ctx.firstFocusableElement
|
|
178
|
+
) {
|
|
179
|
+
event.preventDefault();
|
|
180
|
+
ctx.lastFocusableElement.focus();
|
|
181
|
+
} else if (
|
|
182
|
+
! event.shiftKey &&
|
|
183
|
+
window.document.activeElement ===
|
|
184
|
+
ctx.lastFocusableElement
|
|
185
|
+
) {
|
|
186
|
+
event.preventDefault();
|
|
187
|
+
ctx.firstFocusableElement.focus();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if ( event.key === 'Escape' || event.keyCode === 27 ) {
|
|
192
|
+
actions.hideLightbox( event );
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
// This is fired just by lazily loaded
|
|
197
|
+
// images on the page, not all images.
|
|
198
|
+
handleLoad() {
|
|
199
|
+
const ctx = getContext();
|
|
200
|
+
const { ref } = getElement();
|
|
201
|
+
ctx.imageLoaded = true;
|
|
202
|
+
ctx.imageCurrentSrc = ref.currentSrc;
|
|
203
|
+
callbacks.setButtonStyles();
|
|
204
|
+
},
|
|
205
|
+
handleTouchStart() {
|
|
206
|
+
isTouching = true;
|
|
207
|
+
},
|
|
208
|
+
handleTouchMove( event ) {
|
|
209
|
+
const ctx = getContext();
|
|
210
|
+
// On mobile devices, we want to prevent triggering the
|
|
211
|
+
// scroll event because otherwise the page jumps around as
|
|
212
|
+
// we reset the scroll position. This also means that closing
|
|
213
|
+
// the lightbox requires that a user perform a simple tap. This
|
|
214
|
+
// may be changed in the future if we find a better alternative
|
|
215
|
+
// to override or reset the scroll position during swipe actions.
|
|
216
|
+
if ( ctx.lightboxEnabled ) {
|
|
217
|
+
event.preventDefault();
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
handleTouchEnd() {
|
|
221
|
+
// We need to wait a few milliseconds before resetting
|
|
222
|
+
// to ensure that pinch to zoom works consistently
|
|
223
|
+
// on mobile devices when the lightbox is open.
|
|
224
|
+
lastTouchTime = Date.now();
|
|
225
|
+
isTouching = false;
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
callbacks: {
|
|
229
|
+
initOriginImage() {
|
|
230
|
+
const ctx = getContext();
|
|
231
|
+
const { ref } = getElement();
|
|
232
|
+
ctx.imageRef = ref;
|
|
233
|
+
ctx.lightboxTriggerRef =
|
|
234
|
+
ref.parentElement.querySelector( '.lightbox-trigger' );
|
|
235
|
+
if ( ref.complete ) {
|
|
236
|
+
ctx.imageLoaded = true;
|
|
237
|
+
ctx.imageCurrentSrc = ref.currentSrc;
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
initLightbox() {
|
|
241
|
+
const ctx = getContext();
|
|
242
|
+
const { ref } = getElement();
|
|
243
|
+
if ( ctx.lightboxEnabled ) {
|
|
244
|
+
const focusableElements =
|
|
245
|
+
ref.querySelectorAll( focusableSelectors );
|
|
246
|
+
ctx.firstFocusableElement = focusableElements[ 0 ];
|
|
247
|
+
ctx.lastFocusableElement =
|
|
248
|
+
focusableElements[ focusableElements.length - 1 ];
|
|
249
|
+
|
|
250
|
+
// Move focus to the dialog when opening it.
|
|
251
|
+
ref.focus();
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
setButtonStyles() {
|
|
255
|
+
const { ref } = getElement();
|
|
256
|
+
const { naturalWidth, naturalHeight, offsetWidth, offsetHeight } =
|
|
257
|
+
ref;
|
|
258
|
+
|
|
259
|
+
// If the image isn't loaded yet, we can't
|
|
260
|
+
// calculate where the button should be.
|
|
261
|
+
if ( naturalWidth === 0 || naturalHeight === 0 ) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const figure = ref.parentElement;
|
|
266
|
+
const figureWidth = ref.parentElement.clientWidth;
|
|
267
|
+
|
|
268
|
+
// We need special handling for the height because
|
|
269
|
+
// a caption will cause the figure to be taller than
|
|
270
|
+
// the image, which means we need to account for that
|
|
271
|
+
// when calculating the placement of the button in the
|
|
272
|
+
// top right corner of the image.
|
|
273
|
+
let figureHeight = ref.parentElement.clientHeight;
|
|
274
|
+
const caption = figure.querySelector( 'figcaption' );
|
|
275
|
+
if ( caption ) {
|
|
276
|
+
const captionComputedStyle = window.getComputedStyle( caption );
|
|
277
|
+
if (
|
|
278
|
+
! [ 'absolute', 'fixed' ].includes(
|
|
279
|
+
captionComputedStyle.position
|
|
280
|
+
)
|
|
281
|
+
) {
|
|
282
|
+
figureHeight =
|
|
283
|
+
figureHeight -
|
|
284
|
+
caption.offsetHeight -
|
|
285
|
+
parseFloat( captionComputedStyle.marginTop ) -
|
|
286
|
+
parseFloat( captionComputedStyle.marginBottom );
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const buttonOffsetTop = figureHeight - offsetHeight;
|
|
291
|
+
const buttonOffsetRight = figureWidth - offsetWidth;
|
|
292
|
+
|
|
293
|
+
const ctx = getContext();
|
|
294
|
+
|
|
295
|
+
// In the case of an image with object-fit: contain, the
|
|
296
|
+
// size of the <img> element can be larger than the image itself,
|
|
297
|
+
// so we need to calculate where to place the button.
|
|
298
|
+
if ( ctx.scaleAttr === 'contain' ) {
|
|
299
|
+
// Natural ratio of the image.
|
|
300
|
+
const naturalRatio = naturalWidth / naturalHeight;
|
|
301
|
+
// Offset ratio of the image.
|
|
302
|
+
const offsetRatio = offsetWidth / offsetHeight;
|
|
303
|
+
|
|
304
|
+
if ( naturalRatio >= offsetRatio ) {
|
|
305
|
+
// If it reaches the width first, keep
|
|
306
|
+
// the width and compute the height.
|
|
307
|
+
const referenceHeight = offsetWidth / naturalRatio;
|
|
308
|
+
ctx.imageButtonTop =
|
|
309
|
+
( offsetHeight - referenceHeight ) / 2 +
|
|
310
|
+
buttonOffsetTop +
|
|
311
|
+
16;
|
|
312
|
+
ctx.imageButtonRight = buttonOffsetRight + 16;
|
|
313
|
+
} else {
|
|
314
|
+
// If it reaches the height first, keep
|
|
315
|
+
// the height and compute the width.
|
|
316
|
+
const referenceWidth = offsetHeight * naturalRatio;
|
|
317
|
+
ctx.imageButtonTop = buttonOffsetTop + 16;
|
|
318
|
+
ctx.imageButtonRight =
|
|
319
|
+
( offsetWidth - referenceWidth ) / 2 +
|
|
320
|
+
buttonOffsetRight +
|
|
321
|
+
16;
|
|
322
|
+
}
|
|
323
|
+
} else {
|
|
324
|
+
ctx.imageButtonTop = buttonOffsetTop + 16;
|
|
325
|
+
ctx.imageButtonRight = buttonOffsetRight + 16;
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
setStylesOnResize() {
|
|
329
|
+
const ctx = getContext();
|
|
330
|
+
const { ref } = getElement();
|
|
331
|
+
if (
|
|
332
|
+
ctx.lightboxEnabled &&
|
|
333
|
+
( state.windowWidth || state.windowHeight )
|
|
334
|
+
) {
|
|
335
|
+
setStyles( ctx, ref );
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
} );
|
|
340
|
+
|
|
341
|
+
window.addEventListener(
|
|
342
|
+
'resize',
|
|
343
|
+
debounce( () => {
|
|
344
|
+
state.windowWidth = window.innerWidth;
|
|
345
|
+
state.windowHeight = window.innerHeight;
|
|
346
|
+
} )
|
|
389
347
|
);
|
|
390
348
|
|
|
391
|
-
|
|
349
|
+
/**
|
|
392
350
|
* Computes styles for the lightbox and adds them to the document.
|
|
393
351
|
*
|
|
394
352
|
* @function
|
|
395
|
-
* @param {Object}
|
|
396
|
-
* @param {Object}
|
|
353
|
+
* @param {Object} ctx - Context for the `core/image` namespace.
|
|
354
|
+
* @param {Object} ref - The element reference.
|
|
397
355
|
*/
|
|
398
|
-
function setStyles(
|
|
356
|
+
function setStyles( ctx, ref ) {
|
|
399
357
|
// The reference img element lies adjacent
|
|
400
358
|
// to the event target button in the DOM.
|
|
401
359
|
let {
|
|
@@ -413,7 +371,7 @@ function setStyles( context, ref ) {
|
|
|
413
371
|
|
|
414
372
|
// If it has object-fit: contain, recalculate the original sizes
|
|
415
373
|
// and the screen position without the blank spaces.
|
|
416
|
-
if (
|
|
374
|
+
if ( ctx.scaleAttr === 'contain' ) {
|
|
417
375
|
if ( naturalRatio > originalRatio ) {
|
|
418
376
|
const heightWithoutSpace = originalWidth / naturalRatio;
|
|
419
377
|
// Recalculate screen position without the top space.
|
|
@@ -433,14 +391,10 @@ function setStyles( context, ref ) {
|
|
|
433
391
|
// the image's dimensions in the lightbox are the same
|
|
434
392
|
// as those of the image in the content.
|
|
435
393
|
let imgMaxWidth = parseFloat(
|
|
436
|
-
|
|
437
|
-
? context.core.image.targetWidth
|
|
438
|
-
: naturalWidth
|
|
394
|
+
ctx.targetWidth !== 'none' ? ctx.targetWidth : naturalWidth
|
|
439
395
|
);
|
|
440
396
|
let imgMaxHeight = parseFloat(
|
|
441
|
-
|
|
442
|
-
? context.core.image.targetHeight
|
|
443
|
-
: naturalHeight
|
|
397
|
+
ctx.targetHeight !== 'none' ? ctx.targetHeight : naturalHeight
|
|
444
398
|
);
|
|
445
399
|
|
|
446
400
|
// Ratio of the biggest image stored in the database.
|
|
@@ -558,16 +512,19 @@ function setStyles( context, ref ) {
|
|
|
558
512
|
--wp--lightbox-image-width: ${ lightboxImgWidth }px;
|
|
559
513
|
--wp--lightbox-image-height: ${ lightboxImgHeight }px;
|
|
560
514
|
--wp--lightbox-scale: ${ containerScale };
|
|
515
|
+
--wp--lightbox-scrollbar-width: ${
|
|
516
|
+
window.innerWidth - document.documentElement.clientWidth
|
|
517
|
+
}px;
|
|
561
518
|
}
|
|
562
519
|
`;
|
|
563
520
|
}
|
|
564
521
|
|
|
565
|
-
|
|
522
|
+
/**
|
|
566
523
|
* Debounces a function call.
|
|
567
524
|
*
|
|
568
525
|
* @function
|
|
569
526
|
* @param {Function} func - A function to be called
|
|
570
|
-
* @param {number}
|
|
527
|
+
* @param {number} wait - The time to wait before calling the function
|
|
571
528
|
*/
|
|
572
529
|
function debounce( func, wait = 50 ) {
|
|
573
530
|
let timeout;
|