@@ -2,6 +2,7 @@ import mobilecss from '../assets/mobile-video-drawer.css';
2
2
import dax from '../assets/dax.svg' ;
3
3
import info from '../assets/info-solid.svg' ;
4
4
import { createPolicy , html , trustedUnsafe } from '../../../dom-utils.js' ;
5
+ import { DDGVideoThumbnailOverlay } from './ddg-video-thumbnail-overlay-mobile' ;
5
6
6
7
/**
7
8
* @typedef {ReturnType<import("../text").overlayCopyVariants> } TextVariants
@@ -19,6 +20,7 @@ export class DDGVideoDrawerMobile extends HTMLElement {
19
20
static OPT_OUT = 'opt-out' ;
20
21
static DISMISS = 'dismiss' ;
21
22
static THUMBNAIL_CLICK = 'thumbnail-click' ;
23
+ static DID_EXIT = 'did-exit' ;
22
24
23
25
policy = createPolicy ( ) ;
24
26
/** @type {boolean } */
@@ -29,8 +31,11 @@ export class DDGVideoDrawerMobile extends HTMLElement {
29
31
container ;
30
32
/** @type {HTMLElement | null } */
31
33
drawer ;
32
- /** @type {import('./ddg-video-thumbnail-overlay-mobile').DDGVideoThumbnailOverlay } */
33
- thumbnailOverlay ;
34
+ /** @type {HTMLElement | null } */
35
+ overlay ;
36
+
37
+ /** @type {'idle'|'animating' } */
38
+ animationState = 'idle' ;
34
39
35
40
connectedCallback ( ) {
36
41
this . createMarkupAndStyles ( ) ;
@@ -44,17 +49,10 @@ export class DDGVideoDrawerMobile extends HTMLElement {
44
49
const content = this . mobileHtml ( ) ;
45
50
overlayElement . innerHTML = this . policy . createHTML ( content ) ;
46
51
shadow . append ( style , overlayElement ) ;
47
- this . setupElements ( overlayElement ) ;
48
- this . setupEventHandlers ( ) ;
52
+ this . setupEventHandlers ( overlayElement ) ;
49
53
this . animateOverlay ( 'in' ) ;
50
54
}
51
55
52
- /** @param {HTMLElement } container */
53
- setupElements ( container ) {
54
- this . container = container ;
55
- this . drawer = container . querySelector ( '.ddg-mobile-drawer' ) ;
56
- }
57
-
58
56
/**
59
57
* @returns {string }
60
58
*/
@@ -102,47 +100,72 @@ export class DDGVideoDrawerMobile extends HTMLElement {
102
100
* @param {'in'|'out' } direction
103
101
*/
104
102
animateOverlay ( direction ) {
105
- const overlay = this . container ?. querySelector ( '.ddg-mobile-drawer- overlay' ) ;
106
- if ( ! overlay ) return ;
103
+ if ( ! this . overlay ) return ;
104
+ this . animationState = 'animating' ;
107
105
108
106
switch ( direction ) {
109
107
case 'in' :
110
- overlay . classList . remove ( 'animateOut' ) ;
111
- overlay . classList . add ( 'animateIn' ) ;
108
+ this . overlay . classList . remove ( 'animateOut' ) ;
109
+ this . overlay . classList . add ( 'animateIn' ) ;
112
110
break ;
113
111
case 'out' :
114
- overlay . classList . remove ( 'animateIn' ) ;
115
- overlay . classList . add ( 'animateOut' ) ;
112
+ this . overlay . classList . remove ( 'animateIn' ) ;
113
+ this . overlay . classList . add ( 'animateOut' ) ;
116
114
break ;
117
115
}
118
116
}
119
117
120
- setupEventHandlers ( ) {
121
- if ( ! this . container ) {
118
+ /**
119
+ * @param {() => void } callback
120
+ */
121
+ onAnimationEnd ( callback ) {
122
+ if ( this . animationState !== 'animating' ) callback ( ) ;
123
+
124
+ this . overlay ?. addEventListener (
125
+ 'animationend' ,
126
+ ( ) => {
127
+ callback ( ) ;
128
+ } ,
129
+ { once : true } ,
130
+ ) ;
131
+ }
132
+
133
+ /**
134
+ * @param {HTMLElement } [container]
135
+ * @returns
136
+ */
137
+ setupEventHandlers ( container ) {
138
+ if ( ! container ) {
122
139
console . warn ( 'Error setting up drawer component' ) ;
123
140
return ;
124
141
}
125
142
126
- const switchElem = this . container . querySelector ( '[role=switch]' ) ;
127
- const infoButton = this . container . querySelector ( '.info-button' ) ;
128
- const remember = this . container . querySelector ( 'input[name="ddg-remember"]' ) ;
129
- const cancelElement = this . container . querySelector ( '.ddg-vpo-cancel' ) ;
130
- const watchInPlayer = this . container . querySelector ( '.ddg-vpo-open' ) ;
131
- const overlay = this . container . querySelector ( '.ddg-mobile-drawer-overlay' ) ;
132
- const background = this . container . querySelector ( '.ddg-mobile-drawer-background' ) ;
143
+ const switchElem = container . querySelector ( '[role=switch]' ) ;
144
+ const infoButton = container . querySelector ( '.info-button' ) ;
145
+ const remember = container . querySelector ( 'input[name="ddg-remember"]' ) ;
146
+ const cancelElement = container . querySelector ( '.ddg-vpo-cancel' ) ;
147
+ const watchInPlayer = container . querySelector ( '.ddg-vpo-open' ) ;
148
+ const background = container . querySelector ( '.ddg-mobile-drawer-background' ) ;
149
+ const overlay = container . querySelector ( '.ddg-mobile-drawer-overlay' ) ;
150
+ const drawer = container . querySelector ( '.ddg-mobile-drawer' ) ;
133
151
134
152
if (
135
153
! cancelElement ||
136
154
! watchInPlayer ||
137
155
! switchElem ||
138
156
! infoButton ||
139
- ! overlay ||
140
157
! background ||
158
+ ! overlay ||
159
+ ! drawer ||
141
160
! ( remember instanceof HTMLInputElement )
142
161
) {
143
162
return console . warn ( 'missing elements' ) ;
144
163
}
145
164
165
+ this . container = container ;
166
+ this . overlay = /** @type {HTMLElement } */ ( overlay ) ;
167
+ this . drawer = /** @type {HTMLElement } */ ( drawer ) ;
168
+
146
169
infoButton . addEventListener ( 'click' , ( ) => {
147
170
this . dispatchEvent ( new Event ( DDGVideoDrawerMobile . OPEN_INFO ) ) ;
148
171
} ) ;
@@ -173,10 +196,15 @@ export class DDGVideoDrawerMobile extends HTMLElement {
173
196
this . animateOverlay ( 'out' ) ;
174
197
175
198
const mouseEvent = /** @type {MouseEvent } */ ( e ) ;
176
- const isClickOnOverlay = this . thumbnailOverlay ?. isMouseEventWithinBounds ( mouseEvent ) ;
177
- const event = isClickOnOverlay ? DDGVideoDrawerMobile . THUMBNAIL_CLICK : DDGVideoDrawerMobile . DISMISS ;
199
+ let eventName = DDGVideoDrawerMobile . DISMISS ;
200
+ for ( const element of document . elementsFromPoint ( mouseEvent . clientX , mouseEvent . clientY ) ) {
201
+ if ( element . tagName === DDGVideoThumbnailOverlay . CUSTOM_TAG_NAME . toUpperCase ( ) ) {
202
+ eventName = DDGVideoDrawerMobile . THUMBNAIL_CLICK ;
203
+ break ;
204
+ }
205
+ }
178
206
179
- this . dispatchEvent ( new CustomEvent ( event ) ) ;
207
+ this . dispatchEvent ( new CustomEvent ( eventName ) ) ;
180
208
} ) ;
181
209
182
210
watchInPlayer . addEventListener ( 'click' , ( e ) => {
@@ -185,5 +213,9 @@ export class DDGVideoDrawerMobile extends HTMLElement {
185
213
e . stopImmediatePropagation ( ) ;
186
214
this . dispatchEvent ( new CustomEvent ( DDGVideoDrawerMobile . OPT_IN , { detail : { remember : remember . checked } } ) ) ;
187
215
} ) ;
216
+
217
+ overlay . addEventListener ( 'animationend' , ( ) => {
218
+ this . animationState = 'idle' ;
219
+ } ) ;
188
220
}
189
221
}
0 commit comments