Sam Potts 1 year ago
parent
commit
2371619486
10 changed files with 256 additions and 872 deletions
  1. 2
    1
      .prettierrc
  2. 20
    49
      demo/src/js/demo.js
  3. 1
    1
      package.json
  4. 3
    1
      src/js/captions.js
  5. 87
    308
      src/js/controls.js
  6. 94
    284
      src/js/listeners.js
  7. 20
    74
      src/js/plyr.js
  8. 5
    15
      src/js/support.js
  9. 14
    68
      src/js/ui.js
  10. 10
    71
      src/js/utils/events.js

+ 2
- 1
.prettierrc View File

@@ -2,5 +2,6 @@
2 2
     "useTabs": false,
3 3
     "tabWidth": 4,
4 4
     "singleQuote": true,
5
-    "trailingComma": "all"
5
+    "trailingComma": "all",
6
+    "printWidth": 120
6 7
 }

+ 20
- 49
demo/src/js/demo.js View File

@@ -12,9 +12,7 @@ import Raven from 'raven-js';
12 12
     // Raven / Sentry
13 13
     // For demo site (https://plyr.io) only
14 14
     if (isLive) {
15
-        Raven.config(
16
-            'https://d4ad9866ad834437a4754e23937071e4@sentry.io/305555',
17
-        ).install();
15
+        Raven.config('https://d4ad9866ad834437a4754e23937071e4@sentry.io/305555').install();
18 16
     }
19 17
 
20 18
     document.addEventListener('DOMContentLoaded', () => {
@@ -130,7 +128,7 @@ import Raven from 'raven-js';
130 128
                     google: 'AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c',
131 129
                 },
132 130
                 ads: {
133
-                    // enabled: true,
131
+                    enabled: true,
134 132
                     publisherId: '918848828995742',
135 133
                 },
136 134
             });
@@ -174,47 +172,40 @@ import Raven from 'raven-js';
174 172
                             title: 'View From A Blue Moon',
175 173
                             sources: [
176 174
                                 {
177
-                                    src:
178
-                                        'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4',
175
+                                    src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4',
179 176
                                     type: 'video/mp4',
180 177
                                     size: 576,
181 178
                                 },
182 179
                                 {
183
-                                    src:
184
-                                        'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-720p.mp4',
180
+                                    src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-720p.mp4',
185 181
                                     type: 'video/mp4',
186 182
                                     size: 720,
187 183
                                 },
188 184
                                 {
189
-                                    src:
190
-                                        'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-1080p.mp4',
185
+                                    src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-1080p.mp4',
191 186
                                     type: 'video/mp4',
192 187
                                     size: 1080,
193 188
                                 },
194 189
                                 {
195
-                                    src:
196
-                                        'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-1440p.mp4',
190
+                                    src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-1440p.mp4',
197 191
                                     type: 'video/mp4',
198 192
                                     size: 1440,
199 193
                                 },
200 194
                             ],
201
-                            poster:
202
-                                'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg',
195
+                            poster: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg',
203 196
                             tracks: [
204 197
                                 {
205 198
                                     kind: 'captions',
206 199
                                     label: 'English',
207 200
                                     srclang: 'en',
208
-                                    src:
209
-                                        'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt',
201
+                                    src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt',
210 202
                                     default: true,
211 203
                                 },
212 204
                                 {
213 205
                                     kind: 'captions',
214 206
                                     label: 'French',
215 207
                                     srclang: 'fr',
216
-                                    src:
217
-                                        'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt',
208
+                                    src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt',
218 209
                                 },
219 210
                             ],
220 211
                         };
@@ -224,17 +215,14 @@ import Raven from 'raven-js';
224 215
                     case types.audio:
225 216
                         player.source = {
226 217
                             type: 'audio',
227
-                            title:
228
-                                'Kishi Bashi – “It All Began With A Burst”',
218
+                            title: 'Kishi Bashi – “It All Began With A Burst”',
229 219
                             sources: [
230 220
                                 {
231
-                                    src:
232
-                                        'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3',
221
+                                    src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3',
233 222
                                     type: 'audio/mp3',
234 223
                                 },
235 224
                                 {
236
-                                    src:
237
-                                        'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg',
225
+                                    src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg',
238 226
                                     type: 'audio/ogg',
239 227
                                 },
240 228
                             ],
@@ -247,8 +235,7 @@ import Raven from 'raven-js';
247 235
                             type: 'video',
248 236
                             sources: [
249 237
                                 {
250
-                                    src:
251
-                                        'https://youtube.com/watch?v=bTqVqk7FSmY',
238
+                                    src: 'https://youtube.com/watch?v=bTqVqk7FSmY',
252 239
                                     provider: 'youtube',
253 240
                                 },
254 241
                             ],
@@ -277,26 +264,16 @@ import Raven from 'raven-js';
277 264
                 currentType = type;
278 265
 
279 266
                 // Remove active classes
280
-                Array.from(buttons).forEach(button =>
281
-                    toggleClass(button.parentElement, 'active', false),
282
-                );
267
+                Array.from(buttons).forEach(button => toggleClass(button.parentElement, 'active', false));
283 268
 
284 269
                 // Set active on parent
285
-                toggleClass(
286
-                    document.querySelector(`[data-source="${type}"]`),
287
-                    'active',
288
-                    true,
289
-                );
270
+                toggleClass(document.querySelector(`[data-source="${type}"]`), 'active', true);
290 271
 
291 272
                 // Show cite
292
-                Array.from(document.querySelectorAll('.plyr__cite')).forEach(
293
-                    cite => {
294
-                        cite.setAttribute('hidden', '');
295
-                    },
296
-                );
297
-                document
298
-                    .querySelector(`.plyr__cite--${type}`)
299
-                    .removeAttribute('hidden');
273
+                Array.from(document.querySelectorAll('.plyr__cite')).forEach(cite => {
274
+                    cite.setAttribute('hidden', '');
275
+                });
276
+                document.querySelector(`.plyr__cite--${type}`).removeAttribute('hidden');
300 277
             }
301 278
 
302 279
             // Bind to each button
@@ -364,13 +341,7 @@ import Raven from 'raven-js';
364 341
             a.async = 1;
365 342
             a.src = g;
366 343
             m.parentNode.insertBefore(a, m);
367
-        })(
368
-            window,
369
-            document,
370
-            'script',
371
-            'https://www.google-analytics.com/analytics.js',
372
-            'ga',
373
-        );
344
+        })(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
374 345
         window.ga('create', 'UA-40881672-11', 'auto');
375 346
         window.ga('send', 'pageview');
376 347
     }

+ 1
- 1
package.json View File

@@ -1,6 +1,6 @@
1 1
 {
2 2
     "name": "plyr",
3
-    "version": "3.3.23",
3
+    "version": "3.4.0-beta.1",
4 4
     "description":
5 5
         "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
6 6
     "homepage": "https://plyr.io",

+ 3
- 1
src/js/captions.js View File

@@ -84,7 +84,9 @@ const captions = {
84 84
         // * toggled:   The real captions state
85 85
 
86 86
         const languages = dedupe(
87
-            Array.from(navigator.languages || navigator.language || navigator.userLanguage).map(language => language.split('-')[0]),
87
+            Array.from(navigator.languages || navigator.language || navigator.userLanguage).map(
88
+                language => language.split('-')[0],
89
+            ),
88 90
         );
89 91
 
90 92
         let language = (this.storage.get('language') || this.config.captions.language || 'auto').toLowerCase();

+ 87
- 308
src/js/controls.js View File

@@ -23,9 +23,7 @@ const controls = {
23 23
     // Get icon URL
24 24
     getIconUrl() {
25 25
         const url = new URL(this.config.iconUrl, window.location);
26
-        const cors =
27
-            url.host !== window.location.host ||
28
-            (browser.isIE && !window.svg4everybody);
26
+        const cors = url.host !== window.location.host || (browser.isIE && !window.svg4everybody);
29 27
 
30 28
         return {
31 29
             url: this.config.iconUrl,
@@ -36,82 +34,37 @@ const controls = {
36 34
     // Find the UI controls
37 35
     findElements() {
38 36
         try {
39
-            this.elements.controls = getElement.call(
40
-                this,
41
-                this.config.selectors.controls.wrapper,
42
-            );
37
+            this.elements.controls = getElement.call(this, this.config.selectors.controls.wrapper);
43 38
 
44 39
             // Buttons
45 40
             this.elements.buttons = {
46
-                play: getElements.call(
47
-                    this,
48
-                    this.config.selectors.buttons.play,
49
-                ),
50
-                pause: getElement.call(
51
-                    this,
52
-                    this.config.selectors.buttons.pause,
53
-                ),
54
-                restart: getElement.call(
55
-                    this,
56
-                    this.config.selectors.buttons.restart,
57
-                ),
58
-                rewind: getElement.call(
59
-                    this,
60
-                    this.config.selectors.buttons.rewind,
61
-                ),
62
-                fastForward: getElement.call(
63
-                    this,
64
-                    this.config.selectors.buttons.fastForward,
65
-                ),
41
+                play: getElements.call(this, this.config.selectors.buttons.play),
42
+                pause: getElement.call(this, this.config.selectors.buttons.pause),
43
+                restart: getElement.call(this, this.config.selectors.buttons.restart),
44
+                rewind: getElement.call(this, this.config.selectors.buttons.rewind),
45
+                fastForward: getElement.call(this, this.config.selectors.buttons.fastForward),
66 46
                 mute: getElement.call(this, this.config.selectors.buttons.mute),
67 47
                 pip: getElement.call(this, this.config.selectors.buttons.pip),
68
-                airplay: getElement.call(
69
-                    this,
70
-                    this.config.selectors.buttons.airplay,
71
-                ),
72
-                settings: getElement.call(
73
-                    this,
74
-                    this.config.selectors.buttons.settings,
75
-                ),
76
-                captions: getElement.call(
77
-                    this,
78
-                    this.config.selectors.buttons.captions,
79
-                ),
80
-                fullscreen: getElement.call(
81
-                    this,
82
-                    this.config.selectors.buttons.fullscreen,
83
-                ),
48
+                airplay: getElement.call(this, this.config.selectors.buttons.airplay),
49
+                settings: getElement.call(this, this.config.selectors.buttons.settings),
50
+                captions: getElement.call(this, this.config.selectors.buttons.captions),
51
+                fullscreen: getElement.call(this, this.config.selectors.buttons.fullscreen),
84 52
             };
85 53
 
86 54
             // Progress
87
-            this.elements.progress = getElement.call(
88
-                this,
89
-                this.config.selectors.progress,
90
-            );
55
+            this.elements.progress = getElement.call(this, this.config.selectors.progress);
91 56
 
92 57
             // Inputs
93 58
             this.elements.inputs = {
94 59
                 seek: getElement.call(this, this.config.selectors.inputs.seek),
95
-                volume: getElement.call(
96
-                    this,
97
-                    this.config.selectors.inputs.volume,
98
-                ),
60
+                volume: getElement.call(this, this.config.selectors.inputs.volume),
99 61
             };
100 62
 
101 63
             // Display
102 64
             this.elements.display = {
103
-                buffer: getElement.call(
104
-                    this,
105
-                    this.config.selectors.display.buffer,
106
-                ),
107
-                currentTime: getElement.call(
108
-                    this,
109
-                    this.config.selectors.display.currentTime,
110
-                ),
111
-                duration: getElement.call(
112
-                    this,
113
-                    this.config.selectors.display.duration,
114
-                ),
65
+                buffer: getElement.call(this, this.config.selectors.display.buffer),
66
+                currentTime: getElement.call(this, this.config.selectors.display.currentTime),
67
+                duration: getElement.call(this, this.config.selectors.display.duration),
115 68
             };
116 69
 
117 70
             // Seek tooltip
@@ -124,10 +77,7 @@ const controls = {
124 77
             return true;
125 78
         } catch (error) {
126 79
             // Log it
127
-            this.debug.warn(
128
-                'It looks like there is a problem with your custom controls HTML',
129
-                error,
130
-            );
80
+            this.debug.warn('It looks like there is a problem with your custom controls HTML', error);
131 81
 
132 82
             // Restore native video controls
133 83
             this.toggleNativeControls(true);
@@ -140,9 +90,7 @@ const controls = {
140 90
     createIcon(type, attributes) {
141 91
         const namespace = 'http://www.w3.org/2000/svg';
142 92
         const iconUrl = controls.getIconUrl.call(this);
143
-        const iconPath = `${!iconUrl.cors ? iconUrl.url : ''}#${
144
-            this.config.iconPrefix
145
-        }`;
93
+        const iconPath = `${!iconUrl.cors ? iconUrl.url : ''}#${this.config.iconPrefix}`;
146 94
 
147 95
         // Create <svg>
148 96
         const icon = document.createElementNS(namespace, 'svg');
@@ -164,11 +112,7 @@ const controls = {
164 112
         if ('href' in use) {
165 113
             use.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
166 114
         } else {
167
-            use.setAttributeNS(
168
-                'http://www.w3.org/1999/xlink',
169
-                'xlink:href',
170
-                path,
171
-            );
115
+            use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', path);
172 116
         }
173 117
 
174 118
         // Add <use> to <svg>
@@ -187,9 +131,7 @@ const controls = {
187 131
         const text = universals[type] || i18n.get(type, this.config);
188 132
 
189 133
         const attributes = Object.assign({}, attr, {
190
-            class: [attr.class, this.config.classNames.hidden]
191
-                .filter(Boolean)
192
-                .join(' '),
134
+            class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' '),
193 135
         });
194 136
         return createElement('span', attributes, text);
195 137
     },
@@ -276,9 +218,7 @@ const controls = {
276 218
                 break;
277 219
 
278 220
             case 'play-large':
279
-                attributes.class += ` ${
280
-                    this.config.classNames.control
281
-                }--overlaid`;
221
+                attributes.class += ` ${this.config.classNames.control}--overlaid`;
282 222
                 type = 'play';
283 223
                 label = 'play';
284 224
                 icon = 'play';
@@ -320,13 +260,7 @@ const controls = {
320 260
         }
321 261
 
322 262
         // Merge attributes
323
-        extend(
324
-            attributes,
325
-            getAttributesFromSelector(
326
-                this.config.selectors.buttons[type],
327
-                attributes,
328
-            ),
329
-        );
263
+        extend(attributes, getAttributesFromSelector(this.config.selectors.buttons[type], attributes));
330 264
 
331 265
         setAttributes(button, attributes);
332 266
 
@@ -426,16 +360,12 @@ const controls = {
426 360
 
427 361
     // Create time display
428 362
     createTime(type) {
429
-        const attributes = getAttributesFromSelector(
430
-            this.config.selectors.display[type],
431
-        );
363
+        const attributes = getAttributesFromSelector(this.config.selectors.display[type]);
432 364
 
433 365
         const container = createElement(
434 366
             'div',
435 367
             extend(attributes, {
436
-                class: `${this.config.classNames.display.time} ${
437
-                    attributes.class ? attributes.class : ''
438
-                }`.trim(),
368
+                class: `${this.config.classNames.display.time} ${attributes.class ? attributes.class : ''}`.trim(),
439 369
                 'aria-label': i18n.get(type, this.config),
440 370
             }),
441 371
             '00:00',
@@ -470,10 +400,7 @@ const controls = {
470 400
                     return;
471 401
                 }
472 402
 
473
-                const isRadioButton = matches(
474
-                    menuItem,
475
-                    '[role="menuitemradio"]',
476
-                );
403
+                const isRadioButton = matches(menuItem, '[role="menuitemradio"]');
477 404
 
478 405
                 // Show the respective menu
479 406
                 if (!isRadioButton && [32, 39].includes(event.which)) {
@@ -482,10 +409,7 @@ const controls = {
482 409
                     let target;
483 410
 
484 411
                     if (event.which !== 32) {
485
-                        if (
486
-                            event.which === 40 ||
487
-                            (isRadioButton && event.which === 39)
488
-                        ) {
412
+                        if (event.which === 40 || (isRadioButton && event.which === 39)) {
489 413
                             target = menuItem.nextElementSibling;
490 414
 
491 415
                             if (!is.element(target)) {
@@ -508,26 +432,15 @@ const controls = {
508 432
     },
509 433
 
510 434
     // Create a settings menu item
511
-    createMenuItem({
512
-        value,
513
-        list,
514
-        type,
515
-        title,
516
-        badge = null,
517
-        checked = false,
518
-    }) {
519
-        const attributes = getAttributesFromSelector(
520
-            this.config.selectors.inputs[type],
521
-        );
435
+    createMenuItem({ value, list, type, title, badge = null, checked = false }) {
436
+        const attributes = getAttributesFromSelector(this.config.selectors.inputs[type]);
522 437
 
523 438
         const menuItem = createElement(
524 439
             'button',
525 440
             extend(attributes, {
526 441
                 type: 'button',
527 442
                 role: 'menuitemradio',
528
-                class: `${this.config.classNames.control} ${
529
-                    attributes.class ? attributes.class : ''
530
-                }`.trim(),
443
+                class: `${this.config.classNames.control} ${attributes.class ? attributes.class : ''}`.trim(),
531 444
                 'aria-checked': checked,
532 445
                 value,
533 446
             }),
@@ -555,15 +468,10 @@ const controls = {
555 468
                 if (checked) {
556 469
                     Array.from(menuItem.parentNode.children)
557 470
                         .filter(node => matches(node, '[role="menuitemradio"]'))
558
-                        .forEach(node =>
559
-                            node.setAttribute('aria-checked', 'false'),
560
-                        );
471
+                        .forEach(node => node.setAttribute('aria-checked', 'false'));
561 472
                 }
562 473
 
563
-                menuItem.setAttribute(
564
-                    'aria-checked',
565
-                    checked ? 'true' : 'false',
566
-                );
474
+                menuItem.setAttribute('aria-checked', checked ? 'true' : 'false');
567 475
             },
568 476
         });
569 477
 
@@ -597,11 +505,7 @@ const controls = {
597 505
                         break;
598 506
                 }
599 507
 
600
-                controls.showMenuPanel.call(
601
-                    this,
602
-                    'home',
603
-                    event.type === 'keyup',
604
-                );
508
+                controls.showMenuPanel.call(this, 'home', event.type === 'keyup');
605 509
             },
606 510
             type,
607 511
             false,
@@ -644,17 +548,12 @@ const controls = {
644 548
 
645 549
         // Update range
646 550
         if (is.element(this.elements.inputs.volume)) {
647
-            controls.setRange.call(
648
-                this,
649
-                this.elements.inputs.volume,
650
-                this.muted ? 0 : this.volume,
651
-            );
551
+            controls.setRange.call(this, this.elements.inputs.volume, this.muted ? 0 : this.volume);
652 552
         }
653 553
 
654 554
         // Update mute state
655 555
         if (is.element(this.elements.buttons.mute)) {
656
-            this.elements.buttons.mute.pressed =
657
-                this.muted || this.volume === 0;
556
+            this.elements.buttons.mute.pressed = this.muted || this.volume === 0;
658 557
         }
659 558
     },
660 559
 
@@ -681,9 +580,7 @@ const controls = {
681 580
 
682 581
         const setProgress = (target, input) => {
683 582
             const value = is.number(input) ? input : 0;
684
-            const progress = is.element(target)
685
-                ? target
686
-                : this.elements.display.buffer;
583
+            const progress = is.element(target) ? target : this.elements.display.buffer;
687 584
 
688 585
             // Update value and label
689 586
             if (is.element(progress)) {
@@ -707,11 +604,7 @@ const controls = {
707 604
 
708 605
                     // Set seek range value only if it's a 'natural' time event
709 606
                     if (event.type === 'timeupdate') {
710
-                        controls.setRange.call(
711
-                            this,
712
-                            this.elements.inputs.seek,
713
-                            value,
714
-                        );
607
+                        controls.setRange.call(this, this.elements.inputs.seek, value);
715 608
                     }
716 609
 
717 610
                     break;
@@ -719,10 +612,7 @@ const controls = {
719 612
                 // Check buffer status
720 613
                 case 'playing':
721 614
                 case 'progress':
722
-                    setProgress(
723
-                        this.elements.display.buffer,
724
-                        this.buffered * 100,
725
-                    );
615
+                    setProgress(this.elements.display.buffer, this.buffered * 100);
726 616
 
727 617
                     break;
728 618
 
@@ -750,9 +640,7 @@ const controls = {
750 640
             const format = i18n.get('seekLabel', this.config);
751 641
             range.setAttribute(
752 642
                 'aria-valuetext',
753
-                format
754
-                    .replace('{currentTime}', currentTime)
755
-                    .replace('{duration}', duration),
643
+                format.replace('{currentTime}', currentTime).replace('{duration}', duration),
756 644
             );
757 645
         } else if (matches(range, this.config.selectors.inputs.volume)) {
758 646
             const percent = range.value * 100;
@@ -802,10 +690,7 @@ const controls = {
802 690
         if (is.event(event)) {
803 691
             percent = 100 / clientRect.width * (event.pageX - clientRect.left);
804 692
         } else if (hasClass(this.elements.display.seekTooltip, visible)) {
805
-            percent = parseFloat(
806
-                this.elements.display.seekTooltip.style.left,
807
-                10,
808
-            );
693
+            percent = parseFloat(this.elements.display.seekTooltip.style.left, 10);
809 694
         } else {
810 695
             return;
811 696
         }
@@ -818,21 +703,14 @@ const controls = {
818 703
         }
819 704
 
820 705
         // Display the time a click would seek to
821
-        controls.updateTimeDisplay.call(
822
-            this,
823
-            this.elements.display.seekTooltip,
824
-            this.duration / 100 * percent,
825
-        );
706
+        controls.updateTimeDisplay.call(this, this.elements.display.seekTooltip, this.duration / 100 * percent);
826 707
 
827 708
         // Set position
828 709
         this.elements.display.seekTooltip.style.left = `${percent}%`;
829 710
 
830 711
         // Show/hide the tooltip
831 712
         // If the event is a moues in/out and percentage is inside bounds
832
-        if (
833
-            is.event(event) &&
834
-            ['mouseenter', 'mouseleave'].includes(event.type)
835
-        ) {
713
+        if (is.event(event) && ['mouseenter', 'mouseleave'].includes(event.type)) {
836 714
             toggle(event.type === 'mouseenter');
837 715
         }
838 716
     },
@@ -840,9 +718,7 @@ const controls = {
840 718
     // Handle time change event
841 719
     timeUpdate(event) {
842 720
         // Only invert if only one time element is displayed and used for both duration and currentTime
843
-        const invert =
844
-            !is.element(this.elements.display.duration) &&
845
-            this.config.invertTime;
721
+        const invert = !is.element(this.elements.display.duration) && this.config.invertTime;
846 722
 
847 723
         // Duration
848 724
         controls.updateTimeDisplay.call(
@@ -864,10 +740,7 @@ const controls = {
864 740
     // Show the duration on metadataloaded or durationchange events
865 741
     durationUpdate() {
866 742
         // Bail if no UI or durationchange event triggered after playing/seek when invertTime is false
867
-        if (
868
-            !this.supported.ui ||
869
-            (!this.config.invertTime && this.currentTime)
870
-        ) {
743
+        if (!this.supported.ui || (!this.config.invertTime && this.currentTime)) {
871 744
             return;
872 745
         }
873 746
 
@@ -883,10 +756,7 @@ const controls = {
883 756
 
884 757
         // Update ARIA values
885 758
         if (is.element(this.elements.inputs.seek)) {
886
-            this.elements.inputs.seek.setAttribute(
887
-                'aria-valuemax',
888
-                this.duration,
889
-            );
759
+            this.elements.inputs.seek.setAttribute('aria-valuemax', this.duration);
890 760
         }
891 761
 
892 762
         // If there's a spot to display duration
@@ -894,20 +764,12 @@ const controls = {
894 764
 
895 765
         // If there's only one time display, display duration there
896 766
         if (!hasDuration && this.config.displayDuration && this.paused) {
897
-            controls.updateTimeDisplay.call(
898
-                this,
899
-                this.elements.display.currentTime,
900
-                this.duration,
901
-            );
767
+            controls.updateTimeDisplay.call(this, this.elements.display.currentTime, this.duration);
902 768
         }
903 769
 
904 770
         // If there's a duration element, update content
905 771
         if (hasDuration) {
906
-            controls.updateTimeDisplay.call(
907
-                this,
908
-                this.elements.display.duration,
909
-                this.duration,
910
-            );
772
+            controls.updateTimeDisplay.call(this, this.elements.display.duration, this.duration);
911 773
         }
912 774
 
913 775
         // Update the tooltip (if visible)
@@ -936,13 +798,8 @@ const controls = {
936 798
             }
937 799
 
938 800
             // Unsupported value
939
-            if (
940
-                !is.empty(this.options[setting]) &&
941
-                !this.options[setting].includes(value)
942
-            ) {
943
-                this.debug.warn(
944
-                    `Unsupported value of '${value}' for ${setting}`,
945
-                );
801
+            if (!is.empty(this.options[setting]) && !this.options[setting].includes(value)) {
802
+                this.debug.warn(`Unsupported value of '${value}' for ${setting}`);
946 803
                 return;
947 804
             }
948 805
 
@@ -964,9 +821,7 @@ const controls = {
964 821
         }
965 822
 
966 823
         // Update the label
967
-        const label = this.elements.settings.buttons[setting].querySelector(
968
-            `.${this.config.classNames.menu.value}`,
969
-        );
824
+        const label = this.elements.settings.buttons[setting].querySelector(`.${this.config.classNames.menu.value}`);
970 825
         label.innerHTML = controls.getLabel.call(this, setting, value);
971 826
 
972 827
         // Find the radio option and check it
@@ -981,16 +836,11 @@ const controls = {
981 836
     getLabel(setting, value) {
982 837
         switch (setting) {
983 838
             case 'speed':
984
-                return value === 1
985
-                    ? i18n.get('normal', this.config)
986
-                    : `${value}&times;`;
839
+                return value === 1 ? i18n.get('normal', this.config) : `${value}&times;`;
987 840
 
988 841
             case 'quality':
989 842
                 if (is.number(value)) {
990
-                    const label = i18n.get(
991
-                        `qualityLabel.${value}`,
992
-                        this.config,
993
-                    );
843
+                    const label = i18n.get(`qualityLabel.${value}`, this.config);
994 844
 
995 845
                     if (!label.length) {
996 846
                         return `${value}p`;
@@ -1017,20 +867,15 @@ const controls = {
1017 867
         }
1018 868
 
1019 869
         const type = 'quality';
1020
-        const list = this.elements.settings.panels.quality.querySelector(
1021
-            '[role="menu"]',
1022
-        );
870
+        const list = this.elements.settings.panels.quality.querySelector('[role="menu"]');
1023 871
 
1024 872
         // Set options if passed and filter based on uniqueness and config
1025 873
         if (is.array(options)) {
1026
-            this.options.quality = dedupe(options).filter(quality =>
1027
-                this.config.quality.options.includes(quality),
1028
-            );
874
+            this.options.quality = dedupe(options).filter(quality => this.config.quality.options.includes(quality));
1029 875
         }
1030 876
 
1031 877
         // Toggle the pane and tab
1032
-        const toggle =
1033
-            !is.empty(this.options.quality) && this.options.quality.length > 1;
878
+        const toggle = !is.empty(this.options.quality) && this.options.quality.length > 1;
1034 879
         controls.toggleMenuButton.call(this, type, toggle);
1035 880
 
1036 881
         // Empty the menu
@@ -1130,9 +975,7 @@ const controls = {
1130 975
 
1131 976
         // TODO: Captions or language? Currently it's mixed
1132 977
         const type = 'captions';
1133
-        const list = this.elements.settings.panels.captions.querySelector(
1134
-            '[role="menu"]',
1135
-        );
978
+        const list = this.elements.settings.panels.captions.querySelector('[role="menu"]');
1136 979
         const tracks = captions.getTracks.call(this);
1137 980
         const toggle = Boolean(tracks.length);
1138 981
 
@@ -1155,9 +998,7 @@ const controls = {
1155 998
             value,
1156 999
             checked: this.captions.toggled && this.currentTrack === value,
1157 1000
             title: captions.getLabel.call(this, track),
1158
-            badge:
1159
-                track.language &&
1160
-                controls.createBadge.call(this, track.language.toUpperCase()),
1001
+            badge: track.language && controls.createBadge.call(this, track.language.toUpperCase()),
1161 1002
             list,
1162 1003
             type: 'language',
1163 1004
         }));
@@ -1185,9 +1026,7 @@ const controls = {
1185 1026
         }
1186 1027
 
1187 1028
         const type = 'speed';
1188
-        const list = this.elements.settings.panels.speed.querySelector(
1189
-            '[role="menu"]',
1190
-        );
1029
+        const list = this.elements.settings.panels.speed.querySelector('[role="menu"]');
1191 1030
 
1192 1031
         // Set the speed options
1193 1032
         if (is.array(options)) {
@@ -1197,13 +1036,10 @@ const controls = {
1197 1036
         }
1198 1037
 
1199 1038
         // Set options if passed and filter based on config
1200
-        this.options.speed = this.options.speed.filter(speed =>
1201
-            this.config.speed.options.includes(speed),
1202
-        );
1039
+        this.options.speed = this.options.speed.filter(speed => this.config.speed.options.includes(speed));
1203 1040
 
1204 1041
         // Toggle the pane and tab
1205
-        const toggle =
1206
-            !is.empty(this.options.speed) && this.options.speed.length > 1;
1042
+        const toggle = !is.empty(this.options.speed) && this.options.speed.length > 1;
1207 1043
         controls.toggleMenuButton.call(this, type, toggle);
1208 1044
 
1209 1045
         // Empty the menu
@@ -1233,9 +1069,7 @@ const controls = {
1233 1069
     // Check if we need to hide/show the settings menu
1234 1070
     checkMenu() {
1235 1071
         const { buttons } = this.elements.settings;
1236
-        const visible =
1237
-            !is.empty(buttons) &&
1238
-            Object.values(buttons).some(button => !button.hidden);
1072
+        const visible = !is.empty(buttons) && Object.values(buttons).some(button => !button.hidden);
1239 1073
 
1240 1074
         toggleHidden(this.elements.settings.menu, !visible);
1241 1075
     },
@@ -1250,13 +1084,10 @@ const controls = {
1250 1084
             return;
1251 1085
         }
1252 1086
 
1253
-        const show = is.boolean(input)
1254
-            ? input
1255
-            : is.element(popup) && popup.hasAttribute('hidden');
1087
+        const show = is.boolean(input) ? input : is.element(popup) && popup.hasAttribute('hidden');
1256 1088
 
1257 1089
         if (is.event(input)) {
1258
-            const isMenuItem =
1259
-                is.element(popup) && popup.contains(input.target);
1090
+            const isMenuItem = is.element(popup) && popup.contains(input.target);
1260 1091
             const isButton = input.target === this.elements.buttons.settings;
1261 1092
 
1262 1093
             // If the click was inside the form or if the click
@@ -1281,17 +1112,11 @@ const controls = {
1281 1112
         if (is.element(popup)) {
1282 1113
             toggleHidden(popup, !show);
1283 1114
 
1284
-            toggleClass(
1285
-                this.elements.container,
1286
-                this.config.classNames.menu.open,
1287
-                show,
1288
-            );
1115
+            toggleClass(this.elements.container, this.config.classNames.menu.open, show);
1289 1116
 
1290 1117
             // Focus the first item if key interaction
1291 1118
             if (show && is.event(input) && input.type === 'keyup') {
1292
-                const pane = Object.values(this.elements.settings.panels).find(
1293
-                    pane => !pane.hidden,
1294
-                );
1119
+                const pane = Object.values(this.elements.settings.panels).find(pane => !pane.hidden);
1295 1120
                 const firstItem = pane.querySelector('[role^="menuitem"]');
1296 1121
 
1297 1122
                 setFocus.call(this, firstItem, true);
@@ -1324,9 +1149,7 @@ const controls = {
1324 1149
 
1325 1150
     // Show a panel in the menu
1326 1151
     showMenuPanel(type = '', tabFocus = false) {
1327
-        const target = document.getElementById(
1328
-            `plyr-settings-${this.id}-${type}`,
1329
-        );
1152
+        const target = document.getElementById(`plyr-settings-${this.id}-${type}`);
1330 1153
 
1331 1154
         // Nothing to show, bail
1332 1155
         if (!is.element(target)) {
@@ -1335,9 +1158,7 @@ const controls = {
1335 1158
 
1336 1159
         // Hide all other panels
1337 1160
         const container = target.parentNode;
1338
-        const current = Array.from(container.children).find(
1339
-            node => !node.hidden,
1340
-        );
1161
+        const current = Array.from(container.children).find(node => !node.hidden);
1341 1162
 
1342 1163
         // If we can do fancy animations, we'll animate the height/width
1343 1164
         if (support.transitions && !support.reducedMotion) {
@@ -1351,10 +1172,7 @@ const controls = {
1351 1172
             // Restore auto height/width
1352 1173
             const restore = event => {
1353 1174
                 // We're only bothered about height and width on the container
1354
-                if (
1355
-                    event.target !== container ||
1356
-                    !['width', 'height'].includes(event.propertyName)
1357
-                ) {
1175
+                if (event.target !== container || !['width', 'height'].includes(event.propertyName)) {
1358 1176
                     return;
1359 1177
                 }
1360 1178
 
@@ -1389,10 +1207,7 @@ const controls = {
1389 1207
     // TODO: Set order based on order in the config.controls array?
1390 1208
     create(data) {
1391 1209
         // Create the container
1392
-        const container = createElement(
1393
-            'div',
1394
-            getAttributesFromSelector(this.config.selectors.controls.wrapper),
1395
-        );
1210
+        const container = createElement('div', getAttributesFromSelector(this.config.selectors.controls.wrapper));
1396 1211
 
1397 1212
         // Restart button
1398 1213
         if (this.config.controls.includes('restart')) {
@@ -1411,17 +1226,12 @@ const controls = {
1411 1226
 
1412 1227
         // Fast forward button
1413 1228
         if (this.config.controls.includes('fast-forward')) {
1414
-            container.appendChild(
1415
-                controls.createButton.call(this, 'fast-forward'),
1416
-            );
1229
+            container.appendChild(controls.createButton.call(this, 'fast-forward'));
1417 1230
         }
1418 1231
 
1419 1232
         // Progress
1420 1233
         if (this.config.controls.includes('progress')) {
1421
-            const progress = createElement(
1422
-                'div',
1423
-                getAttributesFromSelector(this.config.selectors.progress),
1424
-            );
1234
+            const progress = createElement('div', getAttributesFromSelector(this.config.selectors.progress));
1425 1235
 
1426 1236
             // Seek range slider
1427 1237
             progress.appendChild(
@@ -1455,9 +1265,7 @@ const controls = {
1455 1265
 
1456 1266
         // Media current time display
1457 1267
         if (this.config.controls.includes('current-time')) {
1458
-            container.appendChild(
1459
-                controls.createTime.call(this, 'currentTime'),
1460
-            );
1268
+            container.appendChild(controls.createTime.call(this, 'currentTime'));
1461 1269
         }
1462 1270
 
1463 1271
         // Media duration display
@@ -1505,10 +1313,7 @@ const controls = {
1505 1313
         }
1506 1314
 
1507 1315
         // Settings button / menu
1508
-        if (
1509
-            this.config.controls.includes('settings') &&
1510
-            !is.empty(this.config.settings)
1511
-        ) {
1316
+        if (this.config.controls.includes('settings') && !is.empty(this.config.settings)) {
1512 1317
             const control = createElement('div', {
1513 1318
                 class: 'plyr__menu',
1514 1319
                 hidden: '',
@@ -1550,20 +1355,13 @@ const controls = {
1550 1355
                 // TODO: bundle this with the createMenuItem helper and bindings
1551 1356
                 const menuItem = createElement(
1552 1357
                     'button',
1553
-                    extend(
1554
-                        getAttributesFromSelector(
1555
-                            this.config.selectors.buttons.settings,
1556
-                        ),
1557
-                        {
1558
-                            type: 'button',
1559
-                            class: `${this.config.classNames.control} ${
1560
-                                this.config.classNames.control
1561
-                            }--forward`,
1562
-                            role: 'menuitem',
1563
-                            'aria-haspopup': true,
1564
-                            hidden: '',
1565
-                        },
1566
-                    ),
1358
+                    extend(getAttributesFromSelector(this.config.selectors.buttons.settings), {
1359
+                        type: 'button',
1360
+                        class: `${this.config.classNames.control} ${this.config.classNames.control}--forward`,
1361
+                        role: 'menuitem',
1362
+                        'aria-haspopup': true,
1363
+                        hidden: '',
1364
+                    }),
1567 1365
                 );
1568 1366
 
1569 1367
                 // Bind menu shortcuts for keyboard users
@@ -1574,11 +1372,7 @@ const controls = {
1574 1372
                     controls.showMenuPanel.call(this, type, false);
1575 1373
                 });
1576 1374
 
1577
-                const flex = createElement(
1578
-                    'span',
1579
-                    null,
1580
-                    i18n.get(type, this.config),
1581
-                );
1375
+                const flex = createElement('span', null, i18n.get(type, this.config));
1582 1376
 
1583 1377
                 const value = createElement('span', {
1584 1378
                     class: this.config.classNames.menu.value,
@@ -1600,9 +1394,7 @@ const controls = {
1600 1394
                 // Back button
1601 1395
                 const backButton = createElement('button', {
1602 1396
                     type: 'button',
1603
-                    class: `${this.config.classNames.control} ${
1604
-                        this.config.classNames.control
1605
-                    }--back`,
1397
+                    class: `${this.config.classNames.control} ${this.config.classNames.control}--back`,
1606 1398
                 });
1607 1399
 
1608 1400
                 // Visible label
@@ -1688,25 +1480,18 @@ const controls = {
1688 1480
 
1689 1481
         // Toggle fullscreen button
1690 1482
         if (this.config.controls.includes('fullscreen')) {
1691
-            container.appendChild(
1692
-                controls.createButton.call(this, 'fullscreen'),
1693
-            );
1483
+            container.appendChild(controls.createButton.call(this, 'fullscreen'));
1694 1484
         }
1695 1485
 
1696 1486
         // Larger overlaid play button
1697 1487
         if (this.config.controls.includes('play-large')) {
1698
-            this.elements.container.appendChild(
1699
-                controls.createButton.call(this, 'play-large'),
1700
-            );
1488
+            this.elements.container.appendChild(controls.createButton.call(this, 'play-large'));
1701 1489
         }
1702 1490
 
1703 1491
         this.elements.controls = container;
1704 1492
 
1705 1493
         if (this.isHTML5) {
1706
-            controls.setQualityMenu.call(
1707
-                this,
1708
-                html5.getQualityOptions.call(this),
1709
-            );
1494
+            controls.setQualityMenu.call(this, html5.getQualityOptions.call(this));
1710 1495
         }
1711 1496
 
1712 1497
         controls.setSpeedMenu.call(this);
@@ -1793,9 +1578,7 @@ const controls = {
1793 1578
 
1794 1579
         // Inject to custom location
1795 1580
         if (is.string(this.config.selectors.controls.container)) {
1796
-            target = document.querySelector(
1797
-                this.config.selectors.controls.container,
1798
-            );
1581
+            target = document.querySelector(this.config.selectors.controls.container);
1799 1582
         }
1800 1583
 
1801 1584
         // Inject into the container by default
@@ -1804,9 +1587,7 @@ const controls = {
1804 1587
         }
1805 1588
 
1806 1589
         // Inject controls HTML (needs to be before captions, hence "afterbegin")
1807
-        const insertMethod = is.element(container)
1808
-            ? 'insertAdjacentElement'
1809
-            : 'insertAdjacentHTML';
1590
+        const insertMethod = is.element(container) ? 'insertAdjacentElement' : 'insertAdjacentHTML';
1810 1591
         target[insertMethod]('afterbegin', container);
1811 1592
 
1812 1593
         // Find the elements if need be
@@ -1822,9 +1603,7 @@ const controls = {
1822 1603
         // Setup tooltips
1823 1604
         if (this.config.tooltips.controls) {
1824 1605
             const { classNames, selectors } = this.config;
1825
-            const selector = `${selectors.controls.wrapper} ${
1826
-                selectors.labels
1827
-            } .${classNames.hidden}`;
1606
+            const selector = `${selectors.controls.wrapper} ${selectors.labels} .${classNames.hidden}`;
1828 1607
             const labels = getElements.call(this, selector);
1829 1608
 
1830 1609
             Array.from(labels).forEach(label => {

+ 94
- 284
src/js/listeners.js View File

@@ -6,14 +6,7 @@ import controls from './controls';
6 6
 import ui from './ui';
7 7
 import { repaint } from './utils/animation';
8 8
 import browser from './utils/browser';
9
-import {
10
-    getElement,
11
-    getElements,
12
-    hasClass,
13
-    matches,
14
-    toggleClass,
15
-    toggleHidden,
16
-} from './utils/elements';
9
+import { getElement, getElements, hasClass, matches, toggleClass, toggleHidden } from './utils/elements';
17 10
 import { on, once, toggleListener, triggerEvent } from './utils/events';
18 11
 import is from './utils/is';
19 12
 
@@ -69,38 +62,13 @@ class Listeners {
69 62
                     return;
70 63
                 }
71 64
 
72
-                if (
73
-                    event.which === 32 &&
74
-                    matches(focused, 'button, [role^="menuitem"]')
75
-                ) {
65
+                if (event.which === 32 && matches(focused, 'button, [role^="menuitem"]')) {
76 66
                     return;
77 67
                 }
78 68
             }
79 69
 
80 70
             // Which keycodes should we prevent default
81
-            const preventDefault = [
82
-                32,
83
-                37,
84
-                38,
85
-                39,
86
-                40,
87
-                48,
88
-                49,
89
-                50,
90
-                51,
91
-                52,
92
-                53,
93
-                54,
94
-                56,
95
-                57,
96
-                67,
97
-                70,
98
-                73,
99
-                75,
100
-                76,
101
-                77,
102
-                79,
103
-            ];
71
+            const preventDefault = [32, 37, 38, 39, 40, 48, 49, 50, 51, 52, 53, 54, 56, 57, 67, 70, 73, 75, 76, 77, 79];
104 72
 
105 73
             // If the code is found prevent default (e.g. prevent scrolling for arrows)
106 74
             if (preventDefault.includes(code)) {
@@ -195,11 +163,7 @@ class Listeners {
195 163
 
196 164
             // Escape is handle natively when in full screen
197 165
             // So we only need to worry about non native
198
-            if (
199
-                !player.fullscreen.enabled &&
200
-                player.fullscreen.active &&
201
-                code === 27
202
-            ) {
166
+            if (!player.fullscreen.enabled && player.fullscreen.active && code === 27) {
203 167
                 player.fullscreen.toggle();
204 168
             }
205 169
 
@@ -222,11 +186,7 @@ class Listeners {
222 186
         player.touch = true;
223 187
 
224 188
         // Add touch class
225
-        toggleClass(
226
-            player.elements.container,
227
-            player.config.classNames.isTouch,
228
-            true,
229
-        );
189
+        toggleClass(player.elements.container, player.config.classNames.isTouch, true);
230 190
     }
231 191
 
232 192
     setTabFocus(event) {
@@ -272,11 +232,7 @@ class Listeners {
272 232
                 return;
273 233
             }
274 234
 
275
-            toggleClass(
276
-                document.activeElement,
277
-                player.config.classNames.tabFocus,
278
-                true,
279
-            );
235
+            toggleClass(document.activeElement, player.config.classNames.tabFocus, true);
280 236
         }, 10);
281 237
     }
282 238
 
@@ -286,38 +242,17 @@ class Listeners {
286 242
 
287 243
         // Keyboard shortcuts
288 244
         if (player.config.keyboard.global) {
289
-            toggleListener.call(
290
-                player,
291
-                window,
292
-                'keydown keyup',
293
-                this.handleKey,
294
-                toggle,
295
-                false,
296
-            );
245
+            toggleListener.call(player, window, 'keydown keyup', this.handleKey, toggle, false);
297 246
         }
298 247
 
299 248
         // Click anywhere closes menu
300
-        toggleListener.call(
301
-            player,
302
-            document.body,
303
-            'click',
304
-            this.toggleMenu,
305
-            toggle,
306
-        );
249
+        toggleListener.call(player, document.body, 'click', this.toggleMenu, toggle);
307 250
 
308 251
         // Detect touch by events
309 252
         once.call(player, document.body, 'touchstart', this.firstTouch);
310 253
 
311 254
         // Tab focus detection
312
-        toggleListener.call(
313
-            player,
314
-            document.body,
315
-            'keydown focus blur',
316
-            this.setTabFocus,
317
-            toggle,
318
-            false,
319
-            true,
320
-        );
255
+        toggleListener.call(player, document.body, 'keydown focus blur', this.setTabFocus, toggle, false, true);
321 256
     }
322 257
 
323 258
     // Container listeners
@@ -326,13 +261,7 @@ class Listeners {
326 261
 
327 262
         // Keyboard shortcuts
328 263
         if (!player.config.keyboard.global && player.config.keyboard.focused) {
329
-            on.call(
330
-                player,
331
-                player.elements.container,
332
-                'keydown keyup',
333
-                this.handleKey,
334
-                false,
335
-            );
264
+            on.call(player, player.elements.container, 'keydown keyup', this.handleKey, false);
336 265
         }
337 266
 
338 267
         // Toggle controls on mouse events and entering fullscreen
@@ -350,9 +279,7 @@ class Listeners {
350 279
                 }
351 280
 
352 281
                 // Show, then hide after a timeout unless another control event occurs
353
-                const show = ['touchstart', 'touchmove', 'mousemove'].includes(
354
-                    event.type,
355
-                );
282
+                const show = ['touchstart', 'touchmove', 'mousemove'].includes(event.type);
356 283
 
357 284
                 let delay = 0;
358 285
 
@@ -366,10 +293,7 @@ class Listeners {
366 293
                 clearTimeout(player.timers.controls);
367 294
 
368 295
                 // Set new timer to prevent flicker when seeking
369
-                player.timers.controls = setTimeout(
370
-                    () => ui.toggleControls.call(player, false),
371
-                    delay,
372
-                );
296
+                player.timers.controls = setTimeout(() => ui.toggleControls.call(player, false), delay);
373 297
             },
374 298
         );
375 299
     }
@@ -379,16 +303,11 @@ class Listeners {
379 303
         const { player } = this;
380 304
 
381 305
         // Time change on media
382
-        on.call(player, player.media, 'timeupdate seeking seeked', event =>
383
-            controls.timeUpdate.call(player, event),
384
-        );
306
+        on.call(player, player.media, 'timeupdate seeking seeked', event => controls.timeUpdate.call(player, event));
385 307
 
386 308
         // Display duration
387
-        on.call(
388
-            player,
389
-            player.media,
390
-            'durationchange loadeddata loadedmetadata',
391
-            event => controls.durationUpdate.call(player, event),
309
+        on.call(player, player.media, 'durationchange loadeddata loadedmetadata', event =>
310
+            controls.durationUpdate.call(player, event),
392 311
         );
393 312
 
394 313
         // Check for audio tracks on load
@@ -408,30 +327,20 @@ class Listeners {
408 327
         });
409 328
 
410 329
         // Check for buffer progress
411
-        on.call(
412
-            player,
413
-            player.media,
414
-            'progress playing seeking seeked',
415
-            event => controls.updateProgress.call(player, event),
330
+        on.call(player, player.media, 'progress playing seeking seeked', event =>
331
+            controls.updateProgress.call(player, event),
416 332
         );
417 333
 
418 334
         // Handle volume changes
419
-        on.call(player, player.media, 'volumechange', event =>
420
-            controls.updateVolume.call(player, event),
421
-        );
335
+        on.call(player, player.media, 'volumechange', event => controls.updateVolume.call(player, event));
422 336
 
423 337
         // Handle play/pause
424
-        on.call(
425
-            player,
426
-            player.media,
427
-            'playing play pause ended emptied timeupdate',
428
-            event => ui.checkPlaying.call(player, event),
338
+        on.call(player, player.media, 'playing play pause ended emptied timeupdate', event =>
339
+            ui.checkPlaying.call(player, event),
429 340
         );
430 341
 
431 342
         // Loading state
432
-        on.call(player, player.media, 'waiting canplay seeked playing', event =>
433
-            ui.checkLoading.call(player, event),
434
-        );
343
+        on.call(player, player.media, 'waiting canplay seeked playing', event => ui.checkLoading.call(player, event));
435 344
 
436 345
         // If autoplay, then load advertisement if required
437 346
         // TODO: Show some sort of loading state while the ad manager loads else there's a delay before ad shows
@@ -443,23 +352,14 @@ class Listeners {
443 352
             // If ads are enabled, wait for them first
444 353
             if (player.ads.enabled && !player.ads.initialized) {
445 354
                 // Wait for manager response
446
-                player.ads.managerPromise
447
-                    .then(() => player.ads.play())
448
-                    .catch(() => player.play());
355
+                player.ads.managerPromise.then(() => player.ads.play()).catch(() => player.play());
449 356
             }
450 357
         });
451 358
 
452 359
         // Click video
453
-        if (
454
-            player.supported.ui &&
455
-            player.config.clickToPlay &&
456
-            !player.isAudio
457
-        ) {
360
+        if (player.supported.ui && player.config.clickToPlay && !player.isAudio) {
458 361
             // Re-fetch the wrapper
459
-            const wrapper = getElement.call(
460
-                player,
461
-                `.${player.config.classNames.video}`,
462
-            );
362
+            const wrapper = getElement.call(player, `.${player.config.classNames.video}`);
463 363
 
464 364
             // Bail if there's no wrapper (this should never happen)
465 365
             if (!is.element(wrapper)) {
@@ -467,42 +367,31 @@ class Listeners {
467 367
             }
468 368
 
469 369
             // On click play, pause ore restart
470
-            on.call(
471
-                player,
472
-                player.elements.container,
473
-                'click touchstart',
474
-                event => {
475
-                    const targets = [player.elements.container, wrapper];
476
-
477
-                    // Ignore if click if not container or in video wrapper
478
-                    if (
479
-                        !targets.includes(event.target) &&
480
-                        !wrapper.contains(event.target)
481
-                    ) {
482
-                        return;
483
-                    }
370
+            on.call(player, player.elements.container, 'click touchstart', event => {
371
+                const targets = [player.elements.container, wrapper];
484 372
 
485
-                    // First touch on touch devices will just show controls (if we're hiding controls)
486
-                    // If controls are shown then it'll toggle like a pointer device
487
-                    if (
488
-                        player.config.hideControls &&
489
-                        player.touch &&
490
-                        hasClass(
491
-                            player.elements.container,
492
-                            player.config.classNames.hideControls,
493
-                        )
494
-                    ) {
495
-                        return;
496
-                    }
373
+                // Ignore if click if not container or in video wrapper
374
+                if (!targets.includes(event.target) && !wrapper.contains(event.target)) {
375
+                    return;
376
+                }
497 377
 
498
-                    if (player.ended) {
499
-                        player.restart();
500
-                        player.play();
501
-                    } else {
502
-                        player.togglePlay();
503
-                    }
504
-                },
505
-            );
378
+                // First touch on touch devices will just show controls (if we're hiding controls)
379
+                // If controls are shown then it'll toggle like a pointer device
380
+                if (
381
+                    player.config.hideControls &&
382
+                    player.touch &&
383
+                    hasClass(player.elements.container, player.config.classNames.hideControls)
384
+                ) {
385
+                    return;
386
+                }
387
+
388
+                if (player.ended) {
389
+                    player.restart();
390
+                    player.play();
391
+                } else {
392
+                    player.togglePlay();
393
+                }
394
+            });
506 395
         }
507 396
 
508 397
         // Disable right click
@@ -545,19 +434,12 @@ class Listeners {
545 434
         // Quality change
546 435
         on.call(player, player.media, 'qualitychange', event => {
547 436
             // Update UI
548
-            controls.updateSetting.call(
549
-                player,
550
-                'quality',
551
-                null,
552
-                event.detail.quality,
553
-            );
437
+            controls.updateSetting.call(player, 'quality', null, event.detail.quality);
554 438
         });
555 439
 
556 440
         // Proxy events to container
557 441
         // Bubble up key events for Edge
558
-        const proxyEvents = player.config.events
559
-            .concat(['keyup', 'keydown'])
560
-            .join(' ');
442
+        const proxyEvents = player.config.events.concat(['keyup', 'keydown']).join(' ');
561 443
 
562 444
         on.call(player, player.media, proxyEvents, event => {
563 445
             let { detail = {} } = event;
@@ -567,13 +449,7 @@ class Listeners {
567 449
                 detail = player.media.error;
568 450
             }
569 451
 
570
-            triggerEvent.call(
571
-                player,
572
-                player.elements.container,
573
-                event.type,
574
-                true,
575
-                detail,
576
-            );
452
+            triggerEvent.call(player, player.elements.container, event.type, true, detail);
577 453
         });
578 454
     }
579 455
 
@@ -625,28 +501,13 @@ class Listeners {
625 501
         }
626 502
 
627 503
         // Pause
628
-        this.bind(
629
-            player.elements.buttons.restart,
630
-            'click',
631
-            player.restart,
632
-            'restart',
633
-        );
504
+        this.bind(player.elements.buttons.restart, 'click', player.restart, 'restart');
634 505
 
635 506
         // Rewind
636
-        this.bind(
637
-            player.elements.buttons.rewind,
638
-            'click',
639
-            player.rewind,
640
-            'rewind',
641
-        );
507
+        this.bind(player.elements.buttons.rewind, 'click', player.rewind, 'rewind');
642 508
 
643 509
         // Rewind
644
-        this.bind(
645
-            player.elements.buttons.fastForward,
646
-            'click',
647
-            player.forward,
648
-            'fastForward',
649
-        );
510
+        this.bind(player.elements.buttons.fastForward, 'click', player.forward, 'fastForward');
650 511
 
651 512
         // Mute toggle
652 513
         this.bind(
@@ -659,9 +520,7 @@ class Listeners {
659 520
         );
660 521
 
661 522
         // Captions toggle
662
-        this.bind(player.elements.buttons.captions, 'click', () =>
663
-            player.toggleCaptions(),
664
-        );
523
+        this.bind(player.elements.buttons.captions, 'click', () => player.toggleCaptions());
665 524
 
666 525
         // Fullscreen toggle
667 526
         this.bind(
@@ -684,12 +543,7 @@ class Listeners {
684 543
         );
685 544
 
686 545
         // Airplay
687
-        this.bind(
688
-            player.elements.buttons.airplay,
689
-            'click',
690
-            player.airplay,
691
-            'airplay',
692
-        );
546
+        this.bind(player.elements.buttons.airplay, 'click', player.airplay, 'airplay');
693 547
 
694 548
         // Settings menu - click toggle
695 549
         this.bind(player.elements.buttons.settings, 'click', event => {
@@ -731,39 +585,30 @@ class Listeners {
731 585
         });
732 586
 
733 587
         // Pause while seeking
734
-        this.bind(
735
-            player.elements.inputs.seek,
736
-            'mousedown mouseup keydown keyup touchstart touchend',
737
-            event => {
738
-                const seek = event.currentTarget;
739
-                const code = event.keyCode ? event.keyCode : event.which;
740
-                const eventType = event.type;
741
-                const attribute = 'play-on-seeked';
742
-
743
-                if (
744
-                    (eventType === 'keydown' || eventType === 'keyup') &&
745
-                    (code !== 39 && code !== 37)
746
-                ) {
747
-                    return;
748
-                }
749
-                // Was playing before?
750
-                const play = seek.hasAttribute(attribute);
751
-
752
-                // Done seeking
753
-                const done = ['mouseup', 'touchend', 'keyup'].includes(
754
-                    event.type,
755
-                );
588
+        this.bind(player.elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', event => {
589
+            const seek = event.currentTarget;
590
+            const code = event.keyCode ? event.keyCode : event.which;
591
+            const eventType = event.type;
592
+            const attribute = 'play-on-seeked';
756 593
 
757
-                // If we're done seeking and it was playing, resume playback
758
-                if (play && done) {
759
-                    seek.removeAttribute(attribute);
760
-                    player.play();
761
-                } else if (!done && player.playing) {
762
-                    seek.setAttribute(attribute, '');
763
-                    player.pause();
764
-                }
765
-            },
766
-        );
594
+            if ((eventType === 'keydown' || eventType === 'keyup') && (code !== 39 && code !== 37)) {
595
+                return;
596
+            }
597
+            // Was playing before?
598
+            const play = seek.hasAttribute(attribute);
599
+
600
+            // Done seeking
601
+            const done = ['mouseup', 'touchend', 'keyup'].includes(event.type);
602
+
603
+            // If we're done seeking and it was playing, resume playback
604
+            if (play && done) {
605
+                seek.removeAttribute(attribute);
606
+                player.play();
607
+            } else if (!done && player.playing) {
608
+                seek.setAttribute(attribute, '');
609
+                player.pause();
610
+            }
611
+        });
767 612
 
768 613
         // Fix range inputs on iOS
769 614
         // Super weird iOS bug where after you interact with an <input type="range">,
@@ -771,9 +616,7 @@ class Listeners {
771 616
         if (browser.isIos) {
772 617
             const inputs = getElements.call(player, 'input[type="range"]');
773 618
 
774
-            Array.from(inputs).forEach(input =>
775
-                this.bind(input, inputEvent, event => repaint(event.target)),
776
-            );
619
+            Array.from(inputs).forEach(input => this.bind(input, inputEvent, event => repaint(event.target)));
777 620
         }
778 621
 
779 622
         // Seek
@@ -799,10 +642,7 @@ class Listeners {
799 642
 
800 643
         // Current time invert
801 644
         // Only if one time element is used for both currentTime and duration
802
-        if (
803
-            player.config.toggleInvert &&
804
-            !is.element(player.elements.display.duration)
805
-        ) {
645
+        if (player.config.toggleInvert && !is.element(player.elements.display.duration)) {
806 646
             this.bind(player.elements.display.currentTime, 'click', () => {
807 647
                 // Do nothing if we're at the start
808 648
                 if (player.currentTime === 0) {
@@ -827,39 +667,25 @@ class Listeners {
827 667
 
828 668
         // Polyfill for lower fill in <input type="range"> for webkit
829 669
         if (browser.isWebkit) {
830
-            Array.from(getElements.call(player, 'input[type="range"]')).forEach(
831
-                element => {
832
-                    this.bind(element, 'input', event =>
833
-                        controls.updateRangeFill.call(player, event.target),
834
-                    );
835
-                },
836
-            );
670
+            Array.from(getElements.call(player, 'input[type="range"]')).forEach(element => {
671
+                this.bind(element, 'input', event => controls.updateRangeFill.call(player, event.target));
672
+            });
837 673
         }
838 674
 
839 675
         // Seek tooltip
840
-        this.bind(
841
-            player.elements.progress,
842
-            'mouseenter mouseleave mousemove',
843
-            event => controls.updateSeekTooltip.call(player, event),
676
+        this.bind(player.elements.progress, 'mouseenter mouseleave mousemove', event =>
677
+            controls.updateSeekTooltip.call(player, event),
844 678
         );
845 679
 
846 680
         // Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)
847 681
         this.bind(player.elements.controls, 'mouseenter mouseleave', event => {
848
-            player.elements.controls.hover =
849
-                !player.touch && event.type === 'mouseenter';
682
+            player.elements.controls.hover = !player.touch && event.type === 'mouseenter';
850 683
         });
851 684
 
852 685
         // Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)
853
-        this.bind(
854
-            player.elements.controls,
855
-            'mousedown mouseup touchstart touchend touchcancel',
856
-            event => {
857
-                player.elements.controls.pressed = [
858
-                    'mousedown',
859
-                    'touchstart',
860
-                ].includes(event.type);
861
-            },
862
-        );
686
+        this.bind(player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {
687
+            player.elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);
688
+        });
863 689
 
864 690
         // Focus in/out on controls
865 691
         this.bind(player.elements.controls, 'focusin focusout', event => {
@@ -867,11 +693,7 @@ class Listeners {
867 693
             const isFocusIn = event.type === 'focusin';
868 694
 
869 695
             // Skip transition to prevent focus from scrolling the parent element
870
-            toggleClass(
871
-                elements.controls,
872
-                config.classNames.noTransition,
873
-                isFocusIn,
874
-            );
696
+            toggleClass(elements.controls, config.classNames.noTransition, isFocusIn);
875 697
 
876 698
             // Toggle
877 699
             ui.toggleControls.call(player, isFocusIn);
@@ -880,11 +702,7 @@ class Listeners {
880 702
             if (isFocusIn) {
881 703
                 // Restore transition
882 704
                 setTimeout(() => {
883
-                    toggleClass(
884
-                        elements.controls,
885
-                        config.classNames.noTransition,
886
-                        false,
887
-                    );
705
+                    toggleClass(elements.controls, config.classNames.noTransition, false);
888 706
                 }, 0);
889 707
 
890 708
                 // Delay a little more for keyboard users
@@ -894,10 +712,7 @@ class Listeners {
894 712
                 clearTimeout(timers.controls);
895 713
 
896 714
                 // Hide
897
-                timers.controls = setTimeout(
898
-                    () => ui.toggleControls.call(player, false),
899
-                    delay,
900
-                );
715
+                timers.controls = setTimeout(() => ui.toggleControls.call(player, false), delay);
901 716
             }
902 717
         });
903 718
 
@@ -911,9 +726,7 @@ class Listeners {
911 726
                 const inverted = event.webkitDirectionInvertedFromDevice;
912 727
 
913 728
                 // Get delta from event. Invert if `inverted` is true
914
-                const [x, y] = [event.deltaX, -event.deltaY].map(
915
-                    value => (inverted ? -value : value),
916
-                );
729
+                const [x, y] = [event.deltaX, -event.deltaY].map(value => (inverted ? -value : value));
917 730
 
918 731
                 // Using the biggest delta, normalize to 1 or -1 (or 0 if no delta)
919 732
                 const direction = Math.sign(Math.abs(x) > Math.abs(y) ? x : y);
@@ -923,10 +736,7 @@ class Listeners {
923 736
 
924 737
                 // Don't break page scrolling at max and min
925 738
                 const { volume } = player.media;
926
-                if (
927
-                    (direction === 1 && volume < 1) ||
928
-                    (direction === -1 && volume > 0)
929
-                ) {
739
+                if ((direction === 1 && volume < 1) || (direction === -1 && volume > 0)) {
930 740
                     event.preventDefault();
931 741
                 }
932 742
             },

+ 20
- 74
src/js/plyr.js View File

@@ -52,11 +52,7 @@ class Plyr {
52 52
         }
53 53
 
54 54
         // jQuery, NodeList or Array passed, use first element
55
-        if (
56
-            (window.jQuery && this.media instanceof jQuery) ||
57
-            is.nodeList(this.media) ||
58
-            is.array(this.media)
59
-        ) {
55
+        if ((window.jQuery && this.media instanceof jQuery) || is.nodeList(this.media) || is.array(this.media)) {
60 56
             // eslint-disable-next-line
61 57
             this.media = this.media[0];
62 58
         }
@@ -69,9 +65,7 @@ class Plyr {
69 65
             options || {},
70 66
             (() => {
71 67
                 try {
72
-                    return JSON.parse(
73
-                        this.media.getAttribute('data-plyr-config'),
74
-                    );
68
+                    return JSON.parse(this.media.getAttribute('data-plyr-config'));
75 69
                 } catch (e) {
76 70
                     return {};
77 71
                 }
@@ -199,21 +193,14 @@ class Plyr {
199 193
                     }
200 194
                 } else {
201 195
                     // <div> with attributes
202
-                    this.provider = this.media.getAttribute(
203
-                        this.config.attributes.embed.provider,
204
-                    );
196
+                    this.provider = this.media.getAttribute(this.config.attributes.embed.provider);
205 197
 
206 198
                     // Remove attribute
207
-                    this.media.removeAttribute(
208
-                        this.config.attributes.embed.provider,
209
-                    );
199
+                    this.media.removeAttribute(this.config.attributes.embed.provider);
210 200
                 }
211 201
 
212 202
                 // Unsupported or missing provider
213
-                if (
214
-                    is.empty(this.provider) ||
215
-                    !Object.keys(providers).includes(this.provider)
216
-                ) {
203
+                if (is.empty(this.provider) || !Object.keys(providers).includes(this.provider)) {
217 204
                     this.debug.error('Setup failed: Invalid provider');
218 205
                     return;
219 206
                 }
@@ -235,10 +222,7 @@ class Plyr {
235 222
                 if (this.media.hasAttribute('autoplay')) {
236 223
                     this.config.autoplay = true;
237 224
                 }
238
-                if (
239
-                    this.media.hasAttribute('playsinline') ||
240
-                    this.media.hasAttribute('webkit-playsinline')
241
-                ) {
225
+                if (this.media.hasAttribute('playsinline') || this.media.hasAttribute('webkit-playsinline')) {
242 226
                     this.config.playsinline = true;
243 227
                 }
244 228
                 if (this.media.hasAttribute('muted')) {
@@ -256,11 +240,7 @@ class Plyr {
256 240
         }
257 241
 
258 242
         // Check for support again but with type
259
-        this.supported = support.check(
260
-            this.type,
261
-            this.provider,
262
-            this.config.playsinline,
263
-        );
243
+        this.supported = support.check(this.type, this.provider, this.config.playsinline);
264 244
 
265 245
         // If no support for even API, bail
266 246
         if (!this.supported.api) {
@@ -293,14 +273,9 @@ class Plyr {
293 273
 
294 274
         // Listen for events if debugging
295 275
         if (this.config.debug) {
296
-            on.call(
297
-                this,
298
-                this.elements.container,
299
-                this.config.events.join(' '),
300
-                event => {
301
-                    this.debug.log(`event: ${event.type}`);
302
-                },
303
-            );
276
+            on.call(this, this.elements.container, this.config.events.join(' '), event => {
277
+                this.debug.log(`event: ${event.type}`);
278
+            });
304 279
         }
305 280
 
306 281
         // Setup interface
@@ -450,9 +425,7 @@ class Plyr {
450 425
      * @param {number} seekTime - how far to rewind in seconds. Defaults to the config.seekTime
451 426
      */
452 427
     rewind(seekTime) {
453
-        this.currentTime =
454
-            this.currentTime -
455
-            (is.number(seekTime) ? seekTime : this.config.seekTime);
428
+        this.currentTime = this.currentTime - (is.number(seekTime) ? seekTime : this.config.seekTime);
456 429
     }
457 430
 
458 431
     /**
@@ -460,9 +433,7 @@ class Plyr {
460 433
      * @param {number} seekTime - how far to fast forward in seconds. Defaults to the config.seekTime
461 434
      */
462 435
     forward(seekTime) {
463
-        this.currentTime =
464
-            this.currentTime +
465
-            (is.number(seekTime) ? seekTime : this.config.seekTime);
436
+        this.currentTime = this.currentTime + (is.number(seekTime) ? seekTime : this.config.seekTime);
466 437
     }
467 438
 
468 439
     /**
@@ -479,9 +450,7 @@ class Plyr {
479 450
         const inputIsValid = is.number(input) && input > 0;
480 451
 
481 452
         // Set
482
-        this.media.currentTime = inputIsValid
483
-            ? Math.min(input, this.duration)
484
-            : 0;
453
+        this.media.currentTime = inputIsValid ? Math.min(input, this.duration) : 0;
485 454
 
486 455
         // Logging
487 456
         this.debug.log(`Seeking to ${this.currentTime} seconds`);
@@ -531,10 +500,7 @@ class Plyr {
531 500
 
532 501
         // Media duration can be NaN or Infinity before the media has loaded
533 502
         const realDuration = (this.media || {}).duration;
534
-        const duration =
535
-            !is.number(realDuration) || realDuration === Infinity
536
-                ? 0
537
-                : realDuration;
503
+        const duration = !is.number(realDuration) || realDuration === Infinity ? 0 : realDuration;
538 504
 
539 505
         // If config duration is funky, use regular duration
540 506
         return fauxDuration || duration;
@@ -728,9 +694,7 @@ class Plyr {
728 694
 
729 695
         if (!options.includes(quality)) {
730 696
             const value = closest(options, quality);
731
-            this.debug.warn(
732
-                `Unsupported quality option: ${quality}, using ${value} instead`,
733
-            );
697
+            this.debug.warn(`Unsupported quality option: ${quality}, using ${value} instead`);
734 698
             quality = value;
735 699
         }
736 700
 
@@ -929,9 +893,7 @@ class Plyr {
929 893
         const toggle = is.boolean(input) ? input : this.pip === states.inline;
930 894
 
931 895
         // Toggle based on current state
932
-        this.media.webkitSetPresentationMode(
933
-            toggle ? states.pip : states.inline,
934
-        );
896
+        this.media.webkitSetPresentationMode(toggle ? states.pip : states.inline);
935 897
     }
936 898
 
937 899
     /**
@@ -964,27 +926,16 @@ class Plyr {
964 926
         // Don't toggle if missing UI support or if it's audio
965 927
         if (this.supported.ui && !this.isAudio) {
966 928
             // Get state before change
967
-            const isHidden = hasClass(
968
-                this.elements.container,
969
-                this.config.classNames.hideControls,
970
-            );
929
+            const isHidden = hasClass(this.elements.container, this.config.classNames.hideControls);
971 930
 
972 931
             // Negate the argument if not undefined since adding the class to hides the controls
973 932
             const force = typeof toggle === 'undefined' ? undefined : !toggle;
974 933
 
975 934
             // Apply and get updated state
976
-            const hiding = toggleClass(
977
-                this.elements.container,
978
-                this.config.classNames.hideControls,
979
-                force,
980
-            );
935
+            const hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force);
981 936
 
982 937
             // Close menu
983
-            if (
984
-                hiding &&
985
-                this.config.controls.includes('settings') &&
986
-                !is.empty(this.config.settings)
987
-            ) {
938
+            if (hiding && this.config.controls.includes('settings') && !is.empty(this.config.settings)) {
988 939
                 controls.toggleMenu.call(this, false);
989 940
             }
990 941
 
@@ -1074,12 +1025,7 @@ class Plyr {
1074 1025
                 replaceElement(this.elements.original, this.elements.container);
1075 1026
 
1076 1027
                 // Event
1077
-                triggerEvent.call(
1078
-                    this,
1079
-                    this.elements.original,
1080
-                    'destroyed',
1081
-                    true,
1082
-                );
1028
+                triggerEvent.call(this, this.elements.original, 'destroyed', true);
1083 1029
 
1084 1030
                 // Callback
1085 1031
                 if (is.function(callback)) {

+ 5
- 15
src/js/support.js View File

@@ -25,13 +25,9 @@ const support = {
25 25
     // Check for support
26 26
     // Basic functionality vs full UI
27 27
     check(type, provider, playsinline) {
28
-        const canPlayInline =
29
-            browser.isIPhone && playsinline && support.playsinline;
28
+        const canPlayInline = browser.isIPhone && playsinline && support.playsinline;
30 29
         const api = support[type] || provider !== 'html5';
31
-        const ui =
32
-            api &&
33
-            support.rangeInput &&
34
-            (type !== 'video' || !browser.isIPhone || canPlayInline);
30
+        const ui = api && support.rangeInput && (type !== 'video' || !browser.isIPhone || canPlayInline);
35 31
 
36 32
         return {
37 33
             api,
@@ -41,9 +37,7 @@ const support = {
41 37
 
42 38
     // Picture-in-picture support
43 39
     // Safari only currently
44
-    pip: (() =>
45
-        !browser.isIPhone &&
46
-        is.function(createElement('video').webkitSetPresentationMode))(),
40
+    pip: (() => !browser.isIPhone && is.function(createElement('video').webkitSetPresentationMode))(),
47 41
 
48 42
     // Airplay support
49 43
     // Safari only currently
@@ -75,9 +69,7 @@ const support = {
75 69
         }
76 70
 
77 71
         try {
78
-            return Boolean(
79
-                type && this.media.canPlayType(type).replace(/no/, ''),
80
-            );
72
+            return Boolean(type && this.media.canPlayType(type).replace(/no/, ''));
81 73
         } catch (err) {
82 74
             return false;
83 75
         }
@@ -102,9 +94,7 @@ const support = {
102 94
 
103 95
     // Reduced motion iOS & MacOS setting
104 96
     // https://webkit.org/blog/7551/responsive-design-for-motion/
105
-    reducedMotion:
106
-        'matchMedia' in window &&
107
-        window.matchMedia('(prefers-reduced-motion)').matches,
97
+    reducedMotion: 'matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches,
108 98
 };
109 99
 
110 100
 export default support;

+ 14
- 68
src/js/ui.js View File

@@ -14,16 +14,8 @@ import loadImage from './utils/loadImage';
14 14
 
15 15
 const ui = {
16 16
     addStyleHook() {
17
-        toggleClass(
18
-            this.elements.container,
19
-            this.config.selectors.container.replace('.', ''),
20
-            true,
21
-        );
22
-        toggleClass(
23
-            this.elements.container,
24
-            this.config.classNames.uiSupported,
25
-            this.supported.ui,
26
-        );
17
+        toggleClass(this.elements.container, this.config.selectors.container.replace('.', ''), true);
18
+        toggleClass(this.elements.container, this.config.classNames.uiSupported, this.supported.ui);
27 19
     },
28 20
 
29 21
     // Toggle native HTML5 media controls
@@ -43,9 +35,7 @@ const ui = {
43 35
 
44 36
         // Don't setup interface if no support
45 37
         if (!this.supported.ui) {
46
-            this.debug.warn(
47
-                `Basic support only for ${this.provider} ${this.type}`,
48
-            );
38
+            this.debug.warn(`Basic support only for ${this.provider} ${this.type}`);
49 39
 
50 40
             // Restore native controls
51 41
             ui.toggleNativeControls.call(this, true);
@@ -103,25 +93,13 @@ const ui = {
103 93
         );
104 94
 
105 95
         // Check for airplay support
106
-        toggleClass(
107
-            this.elements.container,
108
-            this.config.classNames.airplay.supported,
109
-            support.airplay && this.isHTML5,
110
-        );
96
+        toggleClass(this.elements.container, this.config.classNames.airplay.supported, support.airplay && this.isHTML5);
111 97
 
112 98
         // Add iOS class
113
-        toggleClass(
114
-            this.elements.container,
115
-            this.config.classNames.isIos,
116
-            browser.isIos,
117
-        );
99
+        toggleClass(this.elements.container, this.config.classNames.isIos, browser.isIos);
118 100
 
119 101
         // Add touch class
120
-        toggleClass(
121
-            this.elements.container,
122
-            this.config.classNames.isTouch,
123
-            this.touch,
124
-        );
102
+        toggleClass(this.elements.container, this.config.classNames.isTouch, this.touch);
125 103
 
126 104
         // Ready for API calls
127 105
         this.ready = true;
@@ -171,9 +149,7 @@ const ui = {
171 149
             }
172 150
 
173 151
             // Default to media type
174
-            const title = !is.empty(this.config.title)
175
-                ? this.config.title
176
-                : 'video';
152
+            const title = !is.empty(this.config.title) ? this.config.title : 'video';
177 153
             const format = i18n.get('frameTitle', this.config);
178 154
 
179 155
             iframe.setAttribute('title', format.replace('{title}', title));
@@ -182,11 +158,7 @@ const ui = {
182 158
 
183 159
     // Toggle poster
184 160
     togglePoster(enable) {
185
-        toggleClass(
186
-            this.elements.container,
187
-            this.config.classNames.posterEnabled,
188
-            enable,
189
-        );
161
+        toggleClass(this.elements.container, this.config.classNames.posterEnabled, enable);
190 162
     },
191 163
 
192 164
     // Set the poster image (async)
@@ -217,9 +189,7 @@ const ui = {
217 189
                 .then(() => {
218 190
                     // Prevent race conditions
219 191
                     if (poster !== this.poster) {
220
-                        throw new Error(
221
-                            'setPoster cancelled by later call to setPoster',
222
-                        );
192
+                        throw new Error('setPoster cancelled by later call to setPoster');
223 193
                     }
224 194
                 })
225 195
                 .then(() => {
@@ -237,21 +207,9 @@ const ui = {
237 207
     // Check playing state
238 208
     checkPlaying(event) {
239 209
         // Class hooks
240
-        toggleClass(
241
-            this.elements.container,
242
-            this.config.classNames.playing,
243
-            this.playing,
244
-        );
245
-        toggleClass(
246
-            this.elements.container,
247
-            this.config.classNames.paused,
248
-            this.paused,
249
-        );
250
-        toggleClass(
251
-            this.elements.container,
252
-            this.config.classNames.stopped,
253
-            this.stopped,
254
-        );
210
+        toggleClass(this.elements.container, this.config.classNames.playing, this.playing);
211
+        toggleClass(this.elements.container, this.config.classNames.paused, this.paused);
212
+        toggleClass(this.elements.container, this.config.classNames.stopped, this.stopped);
255 213
 
256 214
         // Set state
257 215
         Array.from(this.elements.buttons.play || []).forEach(target => {
@@ -277,11 +235,7 @@ const ui = {
277 235
         // Timer to prevent flicker when seeking
278 236
         this.timers.loading = setTimeout(() => {
279 237
             // Update progress bar loading class state
280
-            toggleClass(
281
-                this.elements.container,
282
-                this.config.classNames.loading,
283
-                this.loading,
284
-            );
238
+            toggleClass(this.elements.container, this.config.classNames.loading, this.loading);
285 239
 
286 240
             // Update controls visibility
287 241
             ui.toggleControls.call(this);
@@ -294,15 +248,7 @@ const ui = {
294 248
 
295 249
         if (controls && this.config.hideControls) {
296 250
             // Show controls if force, loading, paused, or button interaction, otherwise hide
297
-            this.toggleControls(
298
-                Boolean(
299
-                    force ||
300
-                        this.loading ||
301
-                        this.paused ||
302
-                        controls.pressed ||
303
-                        controls.hover,
304
-                ),
305
-            );
251
+            this.toggleControls(Boolean(force || this.loading || this.paused || controls.pressed || controls.hover));
306 252
         }
307 253
     },
308 254
 };

+ 10
- 71
src/js/utils/events.js View File

@@ -27,21 +27,9 @@ const supportsPassiveListeners = (() => {
27 27
 })();
28 28
 
29 29
 // Toggle event listener
30
-export function toggleListener(
31
-    element,
32
-    event,
33
-    callback,
34
-    toggle = false,
35
-    passive = true,
36
-    capture = false,
37
-) {
30
+export function toggleListener(element, event, callback, toggle = false, passive = true, capture = false) {
38 31
     // Bail if no element, event, or callback
39
-    if (
40
-        !element ||
41
-        !('addEventListener' in element) ||
42
-        is.empty(event) ||
43
-        !is.function(callback)
44
-    ) {
32
+    if (!element || !('addEventListener' in element) || is.empty(event) || !is.function(callback)) {
45 33
         return;
46 34
     }
47 35
 
@@ -69,74 +57,28 @@ export function toggleListener(
69 57
             this.eventListeners.push({ element, type, callback, options });
70 58
         }
71 59
 
72
-        element[toggle ? 'addEventListener' : 'removeEventListener'](
73
-            type,
74
-            callback,
75
-            options,
76
-        );
60
+        element[toggle ? 'addEventListener' : 'removeEventListener'](type, callback, options);
77 61
     });
78 62
 }
79 63
 
80 64
 // Bind event handler
81
-export function on(
82
-    element,
83
-    events = '',
84
-    callback,
85
-    passive = true,
86
-    capture = false,
87
-) {
88
-    toggleListener.call(
89
-        this,
90
-        element,
91
-        events,
92
-        callback,
93
-        true,
94
-        passive,
95
-        capture,
96
-    );
65
+export function on(element, events = '', callback, passive = true, capture = false) {
66
+    toggleListener.call(this, element, events, callback, true, passive, capture);
97 67
 }
98 68
 
99 69
 // Unbind event handler
100
-export function off(
101
-    element,
102
-    events = '',
103
-    callback,
104
-    passive = true,
105
-    capture = false,
106
-) {
107
-    toggleListener.call(
108
-        this,
109
-        element,
110
-        events,
111
-        callback,
112
-        false,
113
-        passive,
114
-        capture,
115
-    );
70
+export function off(element, events = '', callback, passive = true, capture = false) {
71
+    toggleListener.call(this, element, events, callback, false, passive, capture);
116 72
 }
117 73
 
118 74
 // Bind once-only event handler
119
-export function once(
120
-    element,
121
-    events = '',
122
-    callback,
123
-    passive = true,
124
-    capture = false,
125
-) {
75
+export function once(element, events = '', callback, passive = true, capture = false) {
126 76
     function onceCallback(...args) {
127 77
         off(element, events, onceCallback, passive, capture);
128 78
         callback.apply(this, args);
129 79
     }
130 80
 
131
-    toggleListener.call(
132
-        this,
133
-        element,
134
-        events,
135
-        onceCallback,
136
-        true,
137
-        passive,
138
-        capture,
139
-    );
81
+    toggleListener.call(this, element, events, onceCallback, true, passive, capture);
140 82
 }
141 83
 
142 84
 // Trigger event
@@ -173,9 +115,6 @@ export function unbindListeners() {
173 115
 // Run method when / if player is ready
174 116
 export function ready() {
175 117
     return new Promise(
176
-        resolve =>
177
-            this.ready
178
-                ? setTimeout(resolve, 0)
179
-                : on.call(this, this.elements.container, 'ready', resolve),
118
+        resolve => (this.ready ? setTimeout(resolve, 0) : on.call(this, this.elements.container, 'ready', resolve)),
180 119
     ).then(() => {});
181 120
 }