-
Notifications
You must be signed in to change notification settings - Fork 7.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: playerresize event in all cases #4864
Changes from all commits
332e896
92adf24
2ea72f9
e7fa09b
5902483
439ac9e
c98a945
5219730
a063076
818a574
8b1cee1
e0400e5
e66acb1
a2494d5
4fed939
69ad100
157adcf
b9c5967
18854a3
6b7c278
902bfde
4fa8e31
1ffd0aa
a8f6ebb
fec334b
a742ad4
5cb16a3
e891260
062d31f
93449c0
18d354b
3041792
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/** | ||
* @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 | ||
const options_ = mergeOptions({createEl: !RESIZE_OBSERVER_AVAILABLE}, options); | ||
|
||
super(player, options_); | ||
|
||
this.ResizeObserver = options.ResizeObserver || window.ResizeObserver; | ||
this.loadListener_ = null; | ||
this.resizeObserver_ = null; | ||
this.debouncedHandler_ = debounce(() => { | ||
this.resizeHandler(); | ||
}, 100, false, player); | ||
|
||
if (RESIZE_OBSERVER_AVAILABLE) { | ||
this.resizeObserver_ = new this.ResizeObserver(this.debouncedHandler_); | ||
this.resizeObserver_.observe(player.el()); | ||
|
||
} else { | ||
this.loadListener_ = () => { | ||
if (this.el_.contentWindow) { | ||
Events.on(this.el_.contentWindow, 'resize', this.debouncedHandler_); | ||
} | ||
this.off('load', this.loadListener_); | ||
}; | ||
|
||
this.on('load', this.loadListener_); | ||
} | ||
} | ||
|
||
createEl() { | ||
return super.createEl('iframe', { | ||
className: 'vjs-resize-manager' | ||
}); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe the element will be created even when it's not needed. Should we suppress the creation of it when There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line in the constructor will make it so no element is created if ResizeObserver is used: https://github.com/videojs/video.js/pull/4864/files#diff-8947c14c969c2d82a892c5fac0d0efd0R19 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I didn't notice that. Carry on. 👍 |
||
|
||
/** | ||
* 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} | ||
*/ | ||
this.player_.trigger('playerresize'); | ||
} | ||
|
||
dispose() { | ||
if (this.resizeObserver_) { | ||
this.resizeObserver_.unobserve(this.player_.el()); | ||
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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the event trigger would have worked in IE8 as well - since we're reverting this for the ResizeObserver and that's only available after IE8, is this a breaking change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are falling back to using an iframe for playerresize events when ResizeObserver isn't available, currently, that's basically everywhere, though, chrome will be shipping ResizeObserver soon.