2018-01-30 13:26:21 -05:00
|
|
|
/**
|
|
|
|
* @file resize-manager.js
|
|
|
|
*/
|
|
|
|
import window from 'global/window';
|
|
|
|
import { debounce } from './utils/fn.js';
|
|
|
|
import * as Events from './utils/events.js';
|
|
|
|
import mergeOptions from './utils/merge-options.js';
|
|
|
|
import Component from './component.js';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A Resize Manager. It is in charge of triggering `playerresize` on the player in the right conditions.
|
|
|
|
*
|
|
|
|
* It'll either create an iframe and use a debounced resize handler on it or use the new {@link https://wicg.github.io/ResizeObserver/|ResizeObserver}.
|
|
|
|
*
|
|
|
|
* If the ResizeObserver is available natively, it will be used. A polyfill can be passed in as an option.
|
|
|
|
* If a `playerresize` event is not needed, the ResizeManager component can be removed from the player, see the example below.
|
|
|
|
* @example <caption>How to disable the resize manager</caption>
|
|
|
|
* const player = videojs('#vid', {
|
|
|
|
* resizeManager: false
|
|
|
|
* });
|
|
|
|
*
|
|
|
|
* @see {@link https://wicg.github.io/ResizeObserver/|ResizeObserver specification}
|
|
|
|
*
|
|
|
|
* @extends Component
|
|
|
|
*/
|
|
|
|
class ResizeManager extends Component {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create the ResizeManager.
|
|
|
|
*
|
|
|
|
* @param {Object} player
|
|
|
|
* The `Player` that this class should be attached to.
|
|
|
|
*
|
|
|
|
* @param {Object} [options]
|
|
|
|
* The key/value store of ResizeManager options.
|
|
|
|
*
|
|
|
|
* @param {Object} [options.ResizeObserver]
|
|
|
|
* A polyfill for ResizeObserver can be passed in here.
|
|
|
|
* If this is set to null it will ignore the native ResizeObserver and fall back to the iframe fallback.
|
|
|
|
*/
|
|
|
|
constructor(player, options) {
|
|
|
|
let RESIZE_OBSERVER_AVAILABLE = options.ResizeObserver || window.ResizeObserver;
|
|
|
|
|
|
|
|
// if `null` was passed, we want to disable the ResizeObserver
|
|
|
|
if (options.ResizeObserver === null) {
|
|
|
|
RESIZE_OBSERVER_AVAILABLE = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only create an element when ResizeObserver isn't available
|
2018-08-10 16:21:13 -04:00
|
|
|
const options_ = mergeOptions({
|
|
|
|
createEl: !RESIZE_OBSERVER_AVAILABLE,
|
|
|
|
reportTouchActivity: false
|
|
|
|
}, options);
|
2018-01-30 13:26:21 -05:00
|
|
|
|
|
|
|
super(player, options_);
|
|
|
|
|
|
|
|
this.ResizeObserver = options.ResizeObserver || window.ResizeObserver;
|
|
|
|
this.loadListener_ = null;
|
|
|
|
this.resizeObserver_ = null;
|
|
|
|
this.debouncedHandler_ = debounce(() => {
|
|
|
|
this.resizeHandler();
|
2018-08-28 16:24:26 -04:00
|
|
|
}, 100, false, this);
|
2018-01-30 13:26:21 -05:00
|
|
|
|
|
|
|
if (RESIZE_OBSERVER_AVAILABLE) {
|
|
|
|
this.resizeObserver_ = new this.ResizeObserver(this.debouncedHandler_);
|
|
|
|
this.resizeObserver_.observe(player.el());
|
|
|
|
|
|
|
|
} else {
|
|
|
|
this.loadListener_ = () => {
|
2018-09-11 11:26:15 -04:00
|
|
|
if (!this.el_ || !this.el_.contentWindow) {
|
2018-08-28 16:24:26 -04:00
|
|
|
return;
|
2018-01-30 13:26:21 -05:00
|
|
|
}
|
2018-08-28 16:24:26 -04:00
|
|
|
|
|
|
|
Events.on(this.el_.contentWindow, 'resize', this.debouncedHandler_);
|
2018-01-30 13:26:21 -05:00
|
|
|
};
|
|
|
|
|
2018-08-28 16:24:26 -04:00
|
|
|
this.one('load', this.loadListener_);
|
2018-01-30 13:26:21 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
createEl() {
|
|
|
|
return super.createEl('iframe', {
|
|
|
|
className: 'vjs-resize-manager'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called when a resize is triggered on the iframe or a resize is observed via the ResizeObserver
|
|
|
|
*
|
|
|
|
* @fires Player#playerresize
|
|
|
|
*/
|
|
|
|
resizeHandler() {
|
|
|
|
/**
|
|
|
|
* Called when the player size has changed
|
|
|
|
*
|
|
|
|
* @event Player#playerresize
|
|
|
|
* @type {EventTarget~Event}
|
|
|
|
*/
|
2018-08-28 16:24:26 -04:00
|
|
|
// make sure player is still around to trigger
|
|
|
|
// prevents this from causing an error after dispose
|
|
|
|
if (!this.player_ || !this.player_.trigger) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-30 13:26:21 -05:00
|
|
|
this.player_.trigger('playerresize');
|
|
|
|
}
|
|
|
|
|
|
|
|
dispose() {
|
2018-08-28 16:24:26 -04:00
|
|
|
if (this.debouncedHandler_) {
|
|
|
|
this.debouncedHandler_.cancel();
|
|
|
|
}
|
|
|
|
|
2018-01-30 13:26:21 -05:00
|
|
|
if (this.resizeObserver_) {
|
2018-05-16 12:02:41 -04:00
|
|
|
if (this.player_.el()) {
|
|
|
|
this.resizeObserver_.unobserve(this.player_.el());
|
|
|
|
}
|
2018-01-30 13:26:21 -05:00
|
|
|
this.resizeObserver_.disconnect();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.el_ && this.el_.contentWindow) {
|
|
|
|
Events.off(this.el_.contentWindow, 'resize', this.debouncedHandler_);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.loadListener_) {
|
|
|
|
this.off('load', this.loadListener_);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.ResizeObserver = null;
|
|
|
|
this.resizeObserver = null;
|
|
|
|
this.debouncedHandler_ = null;
|
|
|
|
this.loadListener_ = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Component.registerComponent('ResizeManager', ResizeManager);
|
|
|
|
export default ResizeManager;
|