1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
/**
* @file poster-image.js
*/
import ClickableComponent from './clickable-component.js';
import Component from './component.js';
import * as Dom from './utils/dom.js';
import {silencePromise} from './utils/promise';
/** @import Player from './player' */
/**
* A `ClickableComponent` that handles showing the poster image for the player.
*
* @extends ClickableComponent
*/
class PosterImage extends ClickableComponent {
/**
* Create an instance of this class.
*
* @param {Player} player
* The `Player` that this class should attach to.
*
* @param {Object} [options]
* The key/value store of player options.
*/
constructor(player, options) {
super(player, options);
this.update();
this.update_ = (e) => this.update(e);
player.on('posterchange', this.update_);
}
/**
* Clean up and dispose of the `PosterImage`.
*/
dispose() {
this.player().off('posterchange', this.update_);
super.dispose();
}
/**
* Create the `PosterImage`s DOM element.
*
* @return {Element}
* The element that gets created.
*/
createEl() {
// The el is an empty div to keep position in the DOM
// A picture and img el will be inserted when a source is set
return Dom.createEl('div', { className: 'vjs-poster'});
}
/**
* Get or set the `PosterImage`'s crossOrigin option.
*
* @param {string|null} [value]
* The value to set the crossOrigin to. If an argument is
* given, must be one of `'anonymous'` or `'use-credentials'`, or 'null'.
*
* @return {string|null}
* - The current crossOrigin value of the `Player` when getting.
* - undefined when setting
*/
crossOrigin(value) {
// `null` can be set to unset a value
if (typeof value === 'undefined') {
if (this.$('img')) {
// If the poster's element exists, give its value
return this.$('img').crossOrigin;
} else if (this.player_.tech_ && this.player_.tech_.isReady_) {
// If not but the tech is ready, query the tech
return this.player_.crossOrigin();
}
// Otherwise check options as the poster is usually set before the state of crossorigin
// can be retrieved by the getter
return this.player_.options_.crossOrigin || this.player_.options_.crossorigin || null;
}
if (value !== null && value !== 'anonymous' && value !== 'use-credentials') {
this.player_.log.warn(`crossOrigin must be null, "anonymous" or "use-credentials", given "${value}"`);
return;
}
if (this.$('img')) {
this.$('img').crossOrigin = value;
}
return;
}
/**
* An {@link EventTarget~EventListener} for {@link Player#posterchange} events.
*
* @listens Player#posterchange
*
* @param {Event} [event]
* The `Player#posterchange` event that triggered this function.
*/
update(event) {
const url = this.player().poster();
this.setSrc(url);
// If there's no poster source we should display:none on this component
// so it's not still clickable or right-clickable
if (url) {
this.show();
} else {
this.hide();
}
}
/**
* Set the source of the `PosterImage` depending on the display method. (Re)creates
* the inner picture and img elementss when needed.
*
* @param {string} [url]
* The URL to the source for the `PosterImage`. If not specified or falsy,
* any source and ant inner picture/img are removed.
*/
setSrc(url) {
if (!url) {
this.el_.textContent = '';
return;
}
if (!this.$('img')) {
this.el_.appendChild(Dom.createEl(
'picture', {
className: 'vjs-poster',
// Don't want poster to be tabbable.
tabIndex: -1
},
{},
Dom.createEl('img', {
loading: 'lazy',
crossOrigin: this.crossOrigin()
}, {
alt: ''
})
));
}
this.$('img').src = url;
}
/**
* An {@link EventTarget~EventListener} for clicks on the `PosterImage`. See
* {@link ClickableComponent#handleClick} for instances where this will be triggered.
*
* @listens tap
* @listens click
* @listens keydown
*
* @param {Event} event
+ The `click`, `tap` or `keydown` event that caused this function to be called.
*/
handleClick(event) {
// We don't want a click to trigger playback when controls are disabled
if (!this.player_.controls()) {
return;
}
if (this.player_.tech(true)) {
this.player_.tech(true).focus();
}
if (this.player_.paused()) {
silencePromise(this.player_.play());
} else {
this.player_.pause();
}
}
}
/**
* Get or set the `PosterImage`'s crossorigin option. For the HTML5 player, this
* sets the `crossOrigin` property on the `<img>` tag to control the CORS
* behavior.
*
* @param {string|null} [value]
* The value to set the `PosterImages`'s crossorigin to. If an argument is
* given, must be one of `anonymous` or `use-credentials`.
*
* @return {string|null|undefined}
* - The current crossorigin value of the `Player` when getting.
* - undefined when setting
*/
PosterImage.prototype.crossorigin = PosterImage.prototype.crossOrigin;
Component.registerComponent('PosterImage', PosterImage);
export default PosterImage;
|