diff options
Diffstat (limited to 'javascript/videojs/src/js/poster-image.js')
| -rw-r--r-- | javascript/videojs/src/js/poster-image.js | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/javascript/videojs/src/js/poster-image.js b/javascript/videojs/src/js/poster-image.js new file mode 100644 index 0000000..ea0e02e --- /dev/null +++ b/javascript/videojs/src/js/poster-image.js @@ -0,0 +1,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; |
