21 /******/ })(); |
21 /******/ })(); |
22 /******/ |
22 /******/ |
23 /************************************************************************/ |
23 /************************************************************************/ |
24 var __webpack_exports__ = {}; |
24 var __webpack_exports__ = {}; |
25 |
25 |
26 ;// CONCATENATED MODULE: external "@wordpress/interactivity" |
26 ;// external "@wordpress/interactivity" |
27 var x = (y) => { |
27 var x = (y) => { |
28 var x = {}; __webpack_require__.d(x, y); return x |
28 var x = {}; __webpack_require__.d(x, y); return x |
29 } |
29 } |
30 var y = (x) => (() => (x)) |
30 var y = (x) => (() => (x)) |
31 const interactivity_namespaceObject = x({ ["getContext"]: () => (__WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__.getContext), ["getElement"]: () => (__WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__.getElement), ["store"]: () => (__WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__.store) }); |
31 const interactivity_namespaceObject = x({ ["getContext"]: () => (__WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__.getContext), ["getElement"]: () => (__WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__.getElement), ["store"]: () => (__WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__.store), ["withSyncEvent"]: () => (__WEBPACK_EXTERNAL_MODULE__wordpress_interactivity_8e89b257__.withSyncEvent) }); |
32 ;// CONCATENATED MODULE: ./node_modules/@wordpress/block-library/build-module/image/view.js |
32 ;// ./node_modules/@wordpress/block-library/build-module/image/view.js |
33 /** |
33 /** |
34 * WordPress dependencies |
34 * WordPress dependencies |
35 */ |
35 */ |
36 |
36 |
37 |
37 |
48 * for touch and mouse input. |
48 * for touch and mouse input. |
49 * |
49 * |
50 * @type {number} |
50 * @type {number} |
51 */ |
51 */ |
52 let lastTouchTime = 0; |
52 let lastTouchTime = 0; |
53 |
|
54 /** |
|
55 * Stores the image reference of the currently opened lightbox. |
|
56 * |
|
57 * @type {HTMLElement} |
|
58 */ |
|
59 let imageRef; |
|
60 |
|
61 /** |
|
62 * Stores the button reference of the currently opened lightbox. |
|
63 * |
|
64 * @type {HTMLElement} |
|
65 */ |
|
66 let buttonRef; |
|
67 const { |
53 const { |
68 state, |
54 state, |
69 actions, |
55 actions, |
70 callbacks |
56 callbacks |
71 } = (0,interactivity_namespaceObject.store)('core/image', { |
57 } = (0,interactivity_namespaceObject.store)('core/image', { |
72 state: { |
58 state: { |
73 currentImage: {}, |
59 currentImageId: null, |
|
60 get currentImage() { |
|
61 return state.metadata[state.currentImageId]; |
|
62 }, |
74 get overlayOpened() { |
63 get overlayOpened() { |
75 return state.currentImage.currentSrc; |
64 return state.currentImageId !== null; |
76 }, |
65 }, |
77 get roleAttribute() { |
66 get roleAttribute() { |
78 return state.overlayOpened ? 'dialog' : null; |
67 return state.overlayOpened ? 'dialog' : null; |
79 }, |
68 }, |
80 get ariaModal() { |
69 get ariaModal() { |
81 return state.overlayOpened ? 'true' : null; |
70 return state.overlayOpened ? 'true' : null; |
82 }, |
71 }, |
83 get enlargedSrc() { |
72 get enlargedSrc() { |
84 return state.currentImage.uploadedSrc || 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs='; |
73 return state.currentImage.uploadedSrc || 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs='; |
85 }, |
74 }, |
|
75 get figureStyles() { |
|
76 return state.overlayOpened && `${state.currentImage.figureStyles?.replace(/margin[^;]*;?/g, '')};`; |
|
77 }, |
86 get imgStyles() { |
78 get imgStyles() { |
87 return state.overlayOpened && `${state.currentImage.imgStyles?.replace(/;$/, '')}; object-fit:cover;`; |
79 return state.overlayOpened && `${state.currentImage.imgStyles?.replace(/;$/, '')}; object-fit:cover;`; |
|
80 }, |
|
81 get imageButtonRight() { |
|
82 const { |
|
83 imageId |
|
84 } = (0,interactivity_namespaceObject.getContext)(); |
|
85 return state.metadata[imageId].imageButtonRight; |
|
86 }, |
|
87 get imageButtonTop() { |
|
88 const { |
|
89 imageId |
|
90 } = (0,interactivity_namespaceObject.getContext)(); |
|
91 return state.metadata[imageId].imageButtonTop; |
|
92 }, |
|
93 get isContentHidden() { |
|
94 const ctx = (0,interactivity_namespaceObject.getContext)(); |
|
95 return state.overlayEnabled && state.currentImageId === ctx.imageId; |
|
96 }, |
|
97 get isContentVisible() { |
|
98 const ctx = (0,interactivity_namespaceObject.getContext)(); |
|
99 return !state.overlayEnabled && state.currentImageId === ctx.imageId; |
88 } |
100 } |
89 }, |
101 }, |
90 actions: { |
102 actions: { |
91 showLightbox() { |
103 showLightbox() { |
92 const ctx = (0,interactivity_namespaceObject.getContext)(); |
104 const { |
|
105 imageId |
|
106 } = (0,interactivity_namespaceObject.getContext)(); |
93 |
107 |
94 // Bails out if the image has not loaded yet. |
108 // Bails out if the image has not loaded yet. |
95 if (!ctx.imageRef?.complete) { |
109 if (!state.metadata[imageId].imageRef?.complete) { |
96 return; |
110 return; |
97 } |
111 } |
98 |
112 |
99 // Stores the positons of the scroll to fix it until the overlay is |
113 // Stores the positions of the scroll to fix it until the overlay is |
100 // closed. |
114 // closed. |
101 state.scrollTopReset = document.documentElement.scrollTop; |
115 state.scrollTopReset = document.documentElement.scrollTop; |
102 state.scrollLeftReset = document.documentElement.scrollLeft; |
116 state.scrollLeftReset = document.documentElement.scrollLeft; |
103 |
117 |
104 // Moves the information of the expaned image to the state. |
118 // Sets the current expanded image in the state and enables the overlay. |
105 ctx.currentSrc = ctx.imageRef.currentSrc; |
|
106 imageRef = ctx.imageRef; |
|
107 buttonRef = ctx.buttonRef; |
|
108 state.currentImage = ctx; |
|
109 state.overlayEnabled = true; |
119 state.overlayEnabled = true; |
|
120 state.currentImageId = imageId; |
110 |
121 |
111 // Computes the styles of the overlay for the animation. |
122 // Computes the styles of the overlay for the animation. |
112 callbacks.setOverlayStyles(); |
123 callbacks.setOverlayStyles(); |
113 }, |
124 }, |
114 hideLightbox() { |
125 hideLightbox() { |
115 if (state.overlayEnabled) { |
126 if (state.overlayEnabled) { |
|
127 // Starts the overlay closing animation. The showClosingAnimation |
|
128 // class is used to avoid showing it on page load. |
|
129 state.showClosingAnimation = true; |
|
130 state.overlayEnabled = false; |
|
131 |
116 // Waits until the close animation has completed before allowing a |
132 // Waits until the close animation has completed before allowing a |
117 // user to scroll again. The duration of this animation is defined in |
133 // user to scroll again. The duration of this animation is defined in |
118 // the `styles.scss` file, but in any case we should wait a few |
134 // the `styles.scss` file, but in any case we should wait a few |
119 // milliseconds longer than the duration, otherwise a user may scroll |
135 // milliseconds longer than the duration, otherwise a user may scroll |
120 // too soon and cause the animation to look sloppy. |
136 // too soon and cause the animation to look sloppy. |
121 setTimeout(function () { |
137 setTimeout(function () { |
122 // Delays before changing the focus. Otherwise the focus ring will |
138 // Delays before changing the focus. Otherwise the focus ring will |
123 // appear on Firefox before the image has finished animating, which |
139 // appear on Firefox before the image has finished animating, which |
124 // looks broken. |
140 // looks broken. |
125 buttonRef.focus({ |
141 state.currentImage.buttonRef.focus({ |
126 preventScroll: true |
142 preventScroll: true |
127 }); |
143 }); |
128 |
144 |
129 // Resets the current image to mark the overlay as closed. |
145 // Resets the current image id to mark the overlay as closed. |
130 state.currentImage = {}; |
146 state.currentImageId = null; |
131 imageRef = null; |
|
132 buttonRef = null; |
|
133 }, 450); |
147 }, 450); |
134 |
148 } |
135 // Starts the overlay closing animation. The showClosingAnimation |
149 }, |
136 // class is used to avoid showing it on page load. |
150 handleKeydown: (0,interactivity_namespaceObject.withSyncEvent)(event => { |
137 state.showClosingAnimation = true; |
|
138 state.overlayEnabled = false; |
|
139 } |
|
140 }, |
|
141 handleKeydown(event) { |
|
142 if (state.overlayEnabled) { |
151 if (state.overlayEnabled) { |
143 // Focuses the close button when the user presses the tab key. |
152 // Focuses the close button when the user presses the tab key. |
144 if (event.key === 'Tab') { |
153 if (event.key === 'Tab') { |
145 event.preventDefault(); |
154 event.preventDefault(); |
146 const { |
155 const { |
151 // Closes the lightbox when the user presses the escape key. |
160 // Closes the lightbox when the user presses the escape key. |
152 if (event.key === 'Escape') { |
161 if (event.key === 'Escape') { |
153 actions.hideLightbox(); |
162 actions.hideLightbox(); |
154 } |
163 } |
155 } |
164 } |
156 }, |
165 }), |
157 handleTouchMove(event) { |
166 handleTouchMove: (0,interactivity_namespaceObject.withSyncEvent)(event => { |
158 // On mobile devices, prevents triggering the scroll event because |
167 // On mobile devices, prevents triggering the scroll event because |
159 // otherwise the page jumps around when it resets the scroll position. |
168 // otherwise the page jumps around when it resets the scroll position. |
160 // This also means that closing the lightbox requires that a user |
169 // This also means that closing the lightbox requires that a user |
161 // perform a simple tap. This may be changed in the future if there is a |
170 // perform a simple tap. This may be changed in the future if there is a |
162 // better alternative to override or reset the scroll position during |
171 // better alternative to override or reset the scroll position during |
163 // swipe actions. |
172 // swipe actions. |
164 if (state.overlayEnabled) { |
173 if (state.overlayEnabled) { |
165 event.preventDefault(); |
174 event.preventDefault(); |
166 } |
175 } |
167 }, |
176 }), |
168 handleTouchStart() { |
177 handleTouchStart() { |
169 isTouching = true; |
178 isTouching = true; |
170 }, |
179 }, |
171 handleTouchEnd() { |
180 handleTouchEnd() { |
172 // Waits a few milliseconds before resetting to ensure that pinch to |
181 // Waits a few milliseconds before resetting to ensure that pinch to |
325 // image in iOS Safari, perhaps due to an inconsistency in how browsers |
335 // image in iOS Safari, perhaps due to an inconsistency in how browsers |
326 // handle absolute positioning and CSS transformation. In any case, |
336 // handle absolute positioning and CSS transformation. In any case, |
327 // adding 1 pixel to the container width and height solves the problem, |
337 // adding 1 pixel to the container width and height solves the problem, |
328 // though this can be removed if the issue is fixed in the future. |
338 // though this can be removed if the issue is fixed in the future. |
329 state.overlayStyles = ` |
339 state.overlayStyles = ` |
330 :root { |
|
331 --wp--lightbox-initial-top-position: ${screenPosY}px; |
340 --wp--lightbox-initial-top-position: ${screenPosY}px; |
332 --wp--lightbox-initial-left-position: ${screenPosX}px; |
341 --wp--lightbox-initial-left-position: ${screenPosX}px; |
333 --wp--lightbox-container-width: ${containerWidth + 1}px; |
342 --wp--lightbox-container-width: ${containerWidth + 1}px; |
334 --wp--lightbox-container-height: ${containerHeight + 1}px; |
343 --wp--lightbox-container-height: ${containerHeight + 1}px; |
335 --wp--lightbox-image-width: ${lightboxImgWidth}px; |
344 --wp--lightbox-image-width: ${lightboxImgWidth}px; |
336 --wp--lightbox-image-height: ${lightboxImgHeight}px; |
345 --wp--lightbox-image-height: ${lightboxImgHeight}px; |
337 --wp--lightbox-scale: ${containerScale}; |
346 --wp--lightbox-scale: ${containerScale}; |
338 --wp--lightbox-scrollbar-width: ${window.innerWidth - document.documentElement.clientWidth}px; |
347 --wp--lightbox-scrollbar-width: ${window.innerWidth - document.documentElement.clientWidth}px; |
339 } |
348 `; |
340 `; |
|
341 }, |
349 }, |
342 setButtonStyles() { |
350 setButtonStyles() { |
343 const ctx = (0,interactivity_namespaceObject.getContext)(); |
351 const { |
|
352 imageId |
|
353 } = (0,interactivity_namespaceObject.getContext)(); |
344 const { |
354 const { |
345 ref |
355 ref |
346 } = (0,interactivity_namespaceObject.getElement)(); |
356 } = (0,interactivity_namespaceObject.getElement)(); |
347 ctx.imageRef = ref; |
357 state.metadata[imageId].imageRef = ref; |
|
358 state.metadata[imageId].currentSrc = ref.currentSrc; |
348 const { |
359 const { |
349 naturalWidth, |
360 naturalWidth, |
350 naturalHeight, |
361 naturalHeight, |
351 offsetWidth, |
362 offsetWidth, |
352 offsetHeight |
363 offsetHeight |
372 figureHeight = figureHeight - caption.offsetHeight - parseFloat(captionComputedStyle.marginTop) - parseFloat(captionComputedStyle.marginBottom); |
383 figureHeight = figureHeight - caption.offsetHeight - parseFloat(captionComputedStyle.marginTop) - parseFloat(captionComputedStyle.marginBottom); |
373 } |
384 } |
374 } |
385 } |
375 const buttonOffsetTop = figureHeight - offsetHeight; |
386 const buttonOffsetTop = figureHeight - offsetHeight; |
376 const buttonOffsetRight = figureWidth - offsetWidth; |
387 const buttonOffsetRight = figureWidth - offsetWidth; |
|
388 let imageButtonTop = buttonOffsetTop + 16; |
|
389 let imageButtonRight = buttonOffsetRight + 16; |
377 |
390 |
378 // In the case of an image with object-fit: contain, the size of the |
391 // In the case of an image with object-fit: contain, the size of the |
379 // <img> element can be larger than the image itself, so it needs to |
392 // <img> element can be larger than the image itself, so it needs to |
380 // calculate where to place the button. |
393 // calculate where to place the button. |
381 if (ctx.scaleAttr === 'contain') { |
394 if (state.metadata[imageId].scaleAttr === 'contain') { |
382 // Natural ratio of the image. |
395 // Natural ratio of the image. |
383 const naturalRatio = naturalWidth / naturalHeight; |
396 const naturalRatio = naturalWidth / naturalHeight; |
384 // Offset ratio of the image. |
397 // Offset ratio of the image. |
385 const offsetRatio = offsetWidth / offsetHeight; |
398 const offsetRatio = offsetWidth / offsetHeight; |
386 if (naturalRatio >= offsetRatio) { |
399 if (naturalRatio >= offsetRatio) { |
387 // If it reaches the width first, it keeps the width and compute the |
400 // If it reaches the width first, it keeps the width and compute the |
388 // height. |
401 // height. |
389 const referenceHeight = offsetWidth / naturalRatio; |
402 const referenceHeight = offsetWidth / naturalRatio; |
390 ctx.imageButtonTop = (offsetHeight - referenceHeight) / 2 + buttonOffsetTop + 16; |
403 imageButtonTop = (offsetHeight - referenceHeight) / 2 + buttonOffsetTop + 16; |
391 ctx.imageButtonRight = buttonOffsetRight + 16; |
404 imageButtonRight = buttonOffsetRight + 16; |
392 } else { |
405 } else { |
393 // If it reaches the height first, it keeps the height and compute |
406 // If it reaches the height first, it keeps the height and compute |
394 // the width. |
407 // the width. |
395 const referenceWidth = offsetHeight * naturalRatio; |
408 const referenceWidth = offsetHeight * naturalRatio; |
396 ctx.imageButtonTop = buttonOffsetTop + 16; |
409 imageButtonTop = buttonOffsetTop + 16; |
397 ctx.imageButtonRight = (offsetWidth - referenceWidth) / 2 + buttonOffsetRight + 16; |
410 imageButtonRight = (offsetWidth - referenceWidth) / 2 + buttonOffsetRight + 16; |
398 } |
411 } |
399 } else { |
412 } |
400 ctx.imageButtonTop = buttonOffsetTop + 16; |
413 state.metadata[imageId].imageButtonTop = imageButtonTop; |
401 ctx.imageButtonRight = buttonOffsetRight + 16; |
414 state.metadata[imageId].imageButtonRight = imageButtonRight; |
402 } |
|
403 }, |
415 }, |
404 setOverlayFocus() { |
416 setOverlayFocus() { |
405 if (state.overlayEnabled) { |
417 if (state.overlayEnabled) { |
406 // Moves the focus to the dialog when it opens. |
418 // Moves the focus to the dialog when it opens. |
407 const { |
419 const { |