Use ResizeObserver when available for better and more performant resizing information, otherwise, fall back to a throttled resize event on an iframe that's the size of the player.
Allows a video.js user to disable this by setting resizeManager: false as an option since the component will not be initialized.
Add a debounce util.
This reverts #4800 (e0ed0b5) because we end up getting two playerresize events with the dimension methods now.
This will allow middleware to interact with calls to play() from the tech. This will require a method of indicating to middleware previously run that a middleware down the chain has terminated or stopped execution.
* Adds middleware mediator method that runs middleware from the player to the tech and a second time back up to the player. This category was created because play is both a setter(changes the playback state) and a getter(gets a native play promise if available). This also has the ability to tell whether a middleware has terminated before reaching the tech.
* Adds a middleware.TERMINATOR sentinel value that is available on the videojs object
* Adds play to the allowedMediators
* Adds paused to the allowedGetters
* Adds a sandbox example of a play mediator middleware
Chrome has started pausing autoplaying video elements when they are
moved in the DOM. Here we need to make sure that if the video started
autoplaying, after we move the element in the DOM we call play again.
Fixes#4720.
The core goal here is to make sure the following works in light of some middleware process that makes setting the source more async than next tick:
```js
player.src('...');
player.ready(() => player.play());
```
In fact, given this change, we should even be able to do:
```js
player.src('...');
player.play();
```
Unlike #4665, which would have clarified/changed the meaning of "ready", it remains a reflection of the tech's state and we make better use of the ability to queue things on that state and on the middleware `setSource` process.
A we retained a lot of references to DOM elements in various components. Here we clear it up. Also, make sure that we remove unused listeners as they can retain objects as well.
Update evented mixin to null out the eventBusEl_ after the component is disposed.
Add a feature for components, to tell it not to auto-initialize the evented mixin.
Re-enable the tests that were removed in #4640.
Add the ability to initialize Video.js with an element named video-js. This is because sometimes, seeing the native element is undesirable, plus, it's cool to have our own element.
Can be used just like the video embed.
IE9 is supported but only with dynamic sources as the source element can only be used inside of the video element.
We added a feature so that remote text tracks can auto-removed when a source changes. However, in 6.x we changed the source behavior to be asynchronous meaning that some text tracks were accidentally being removed when they weren't supposed to be.
For example:
```js
var player = videojs('my-player');
player.src({src: 'video.mp4', type: 'video/mp4'});
// set second arg to false so that they get auto-removed on source change
player.addRemoteTextTrack({kind: 'captions', src: 'text.vtt', srclang: 'en'}, false);
```
Now when the player loads, this captions track is actually missing because it was removed.
Instead of adding auto-removal tracks immediately to the list, wait until we've selected a source before adding them in.
Fixes#4403 and #4315.
Video.js players can accept a number of standard <video> element options (autoplay, muted, loop, etc), but not currently playsinline, which is now part of the [HTML spec](https://html.spec.whatwg.org/multipage/embedded-content.html#attr-video-playsinline). We should add it to the list of <video> attributes that can be provided to the player as options.
Prevent ClickableComponents re-adding event listeners each time enabled() is called.
* Keeps track of enabled state (this.enabled_)
* enable() doesn't do anything if the component is enabled, so the event handlers are not re-added
Fixes#4312
This adds a beforepluginsetup event as well as beforepluginsetup:$name and pluginsetup:$name events.
The drive behind this is improving the ability for people to make cross-plugin dependencies in a more robust manner.
Android Chrome now supports playbackRate properly, so removes the blacklist added in #3246 for newer Chrome versions.
Adds `browser.CHROME_VERSION` as a necessary evil.
No longer blacklists for Chrome 58+ -- this could possibly be fixed since 52, but 58 is all I've been able to test on and most users should keep Chrome up to date.
In the new middleware work, the way that new sources were loaded was refactored. We also recently made techs and components work either TitleCased or camelcased. There was one comparison that didn't do the proper check and cause the tech to be reloaded, even if the two techs were the same.
Previously timeupdate would fire before the video was playing, and the tech was not ready. This caused issues when preload was set to auto, because cuechange would fire before the video was even started for cues with a startTime of 0.
Wait for tech to be ready before watching for timeupdate
update unit tests to use TechFaker
Add a unit test to verify that we wait for Tech to be ready.
Increase timeout because IE8 can take more than 5 minutes to run.
Increase browser disconnect timeout so that browsers that succeed but don't report back to karma don't fail the build.
Make webpack more quiet.
Dispose players created in hooks tests which also increase stability.
This fixes a lot of the issues from #2746 by making the dialog inherit from our actual ModalDialog which now has tab focus trapping.
The Captions Settings dialog has some accessibility issues:
- Field labels and fields are not explicitly associated
- Keyboard focus does not move into the dialog when it is opened
- Keyboard focus is not trapped inside the dialog while it is open
- Keyboard focus does not return to the control which opened the dialog when it is closed
- The extent (top and bottom) of the dialog is not indicated to screen readers
- The dialog cannot be closed with the Esc key
- The meaning of '---' in the select fields is not clear
- The control to close the dialog is labeled "Done" rather than "Close"
- The purpose of the "Defaults" button may not be obvious, and its effect may not be apparent to screen reader users
- Focus highlighting (outline) on the Default and Done buttons is *very* hard to see
- Pressing the Done button doesn’t seem to have the same effect as pressing the Close (x) button; does it trigger the same focus movement
- This requirement to move it back to the triggering element is tricky, since clicking on that item in the CC menu dismisses the CC menu. I need to think about this a little more - either the menu should open again, or the focus should go to the main CC Menu Button
- The focus outline on the whole dialog goes too far to the left (all the way to the edge of the video window, not just to the edge of the dialog)
Fixes#2746.
Currently, the ARIA value of VolumeBar tracks the value of volume. It should instead track the position of the slider on VolumeBar, which tracks volume except when the player is muted, in which case it's 0.
Fixes#4064.
If the modal dialog was opened and the focus was preset inside the
player, move the focus to the modal dialog.
When the modal dialog is closed, move the focus back to the previously
active element.
When focus is inside the dialog, trap tab focus. This was inspired by https://github.com/gdkraus/accessible-modal-dialog and ally.js.
Fix the structure of elements in menus so that actionable elements are not children of actionable elements, as required by ARIA.
Remove unnecessary aria-labels on menus.
* Fixes#3986
* update `techOptions` to look for `TitleCase`/`camelCase` user tech options
* remove deprecated usage of Tech as Component
* add a unit test to verify that registerTech works
* change defaultTech_ to defaultTechOrder_
IE8 can't run the html5 tech and the mute toggle tests rely on a working
volume and mute functionality which tech faker does not have. Instead of
implementing it in tech faker, skip it on non-html5 environments.
If a user changed the volume to zero either via the mouse or keyboard, clicking unmute will now restore the volume back to this last position. Previously, the mute and volume values were completely not linked.
Fixes#3909.
Middleware registration now only accept a factory method which takes a player reference and returns some object that represents the middleware with the various methods on it.
Also, add a use to register a middleware for all types.
Advanced plugins introduced the concept of mixins and added two: evented and stateful.
This provides Components with the benefits of the stateful mixin
Advanced plugins introduced the concept of mixins and added two: evented and stateful.
This refactors Component to use the evented mixin, granting it event broadcast/handling capabilities.
Add middleware support. Middleware can function as go-between between the player and the tech. For example, it can modify the duration that the tech returns to the player. In addition, middleware allow for supporting custom video sources and types.
Currently, middleware can only intercept timeline methods like duration, currentTime, and setCurrentTime.
For example,
```js
videojs.use('video/foo', {
setSource(src, next) {
next(null, {
src: 'http://example.com/video.mp4',
type: 'video/mp4'
});
}
});
```
Will allow you to set a source with type `video/foo` which will play back `video.mp4`.
This makes setting the source asynchronous, which aligns it with the spec a bit more. Methods like play can still be called synchronously on the player after setting the source and the player will play once the source has loaded.
`sourceOrder` option was removed as well and it will now always use source ordering.
BREAKING CHANGE: setting the source is now asynchronous. `sourceOrder` option removed and made the default.
Switch to `keepTooltipsInside` by default and simplify DOM structure around the time tooltips and progress control.
BREAKING CHANGE: removal of `keepTooltipsInside` option.
* Switch to es3 preset for babel so that it runs last. Plugins run before presets and presets run in reverse order. Also, we ran into a weird bug in babel that causes `default` not to be quoted in some cases (https://github.com/babel/babel/issues/4799) which we've worked around here.
* Restore the es-shims for tests and the ie8 fallback script.
* Do a null-check around `Player.players`.
* use more round fractions (like 0.5 and 1) to avoid rounding issues.
Remove method chaining from videojs. This helps keep the methods consistent especially since play() now returns a Promise in some cases. Also, it can add some performance benefits.
BREAKING CHANGE: player methods no longer return a player instance when called. Fixes#3704.
Return the native Promise from `play()` if it exists. `undefined` is returned otherwise.
This comes in as part of the greater effort to remove method chaining.
BREAKING CHANGE: `play()` no longer returns the player object but instead the native Promise or nothing.
Prevent techs (and others) from being registered via registerComponent.
* `registerComponent` now throws if given an object that is not a subclass of Component (or Component itself).
* `registerComponent` now throws if given a non-empty string as its name argument.
BREAKING CHANGE: registerComponent now throws if no name or not a component is passed in.
`Player#tech` can now be called without passing an object into it. It no longer requires passing an object into it, so, current code will not break.
If nothing is passed in, a warning will be logged about knowing what you're doing. If anything is passed in, the warning is silenced.
This is both a change as well as a bug fix. We tried to have better awareness of when the underlying video element changed underneath us so we can dispose of the source handler but that broke some use cases of MSE. Given that we weren't able to fix it in a reasonable non-breaking and non-invasive solution, we're taking it out.
BREAKING CHANGE: remove the double loadstart handlers that dispose the tech/source handlers if a secondary loadstart event is heard.
Add a log levels and history api: `videojs.log.level()` and `videojs.log.history()`.
`.level()` will return the current level and you can also set it to be one of: `all`, `error`, `off`, or `warn`.
`.history()` will return a list of all things logged since videojs loaded. It can be disabled via `videojs.log.history.disable()` (and re-enabled with `enable()`) as well as cleared with `videojs.log.history.clear()`.
If the videojs embed code (a video element) is wrapped in a div with the
'data-vjs-player' attribute on it, that element will be used for the
player div and a new one will not be created. In addition, on browsers
like iOS that don't support moving the media element inside the DOM, we
will not need to clone the element and we could continue to re-use the
same video element give to us in the embed code.
This could also be extended in the future to change our embed code to a
div-only approach if we so choose.
Chrome has a bug where if you add a remote text track and try to use it programmatically, you won't get any cues displayed. So, just switch to always emulated mode.
Also, add IS_SAFARI and IS_ANY_SAFARI to the browsers.
This adds nativeAudioTracks and nativeVideoTracks tech options, this will disable hooking into the native track APIs. This would be useful when using videojs-contrib-hls on Edge.
* Refactored ChaptersButton, broke logic into several methods.
* Fixed the issues in #3447 about in some browsers tracks have an empty cues array instead of null. * Now we always subscribe to load event, and force an update. Also, track changes are handled, so chapters track can now be changed at runtime.
* Fixed the issue in #3447 about chapters menu items are not selectable. Now automatic update of the selected item based on player time works fine.
* Implemented the usage of the chapters track's label attribute as menu title, if it's present. If not, we fall back to the localized "Chapters" title.
* Refined the menu styling, so that vjs-menu-title telement won't get the hover effect, It would confuse users, because they might believe that the title item is a clickable item too.
This allows a user to register a new Player component with videojs to be used when videojs is called. If a player has been created already when trying to register a Player component, an error is thrown.
Fixes#3335 and #3016.
Tech#addRemoteTextTrack now accepts a second parameter - a boolean named manualCleanup which defaults to true preserving backwards compatibility. When that value is set to false the text track will be removed from the video element whenever a source change occurs.
Safari 10 automatically dedupes duplicate class names in an element. So,
our test was failing because we had an extra "foo" in the check. This is
an unlikely scenario that has browser variations, so, better to just
remove it.
Calling into the SWF too often is expensive. Current time and buffered don't actually change that often but it's very common to call them a couple times in the handling of a single event. Cache their return values for 100ms so the performance penalty of going through ExternalInterface is limited.
Adds `currentSource` and `currentSources` methods to the player that return the current source object, containing `currentSrc()` and `currentType()`, and all source objects that were given to the player.
Fixes#2443
enable() and disable() on clickable components is only cosmetic. "Disabled" implies the control should not be functional.
* Remove event listeners on disable() and add back on enable().
* Move adding listeners from constructor to enable
* Remove tabindex from disabled components and add disabled attribute to disabled buttons to prevent keyboard access.
HTML5 tech will return NaN instead of Infinity if playback has not started. Fires a durationupdate event once the reported duration can be believed if the duration is still Infinity, so controls can update.
Fixes#3079.
If a player is fluid and does not have a width set, and preload is set to none, the height of the player is zero. This includes where preload is forced to none by mobile Chrome as in #3606.
* If the player has the .vjs-fluid class when initialised, fluid is set to true, so adding the class behaves the same as {fluid: true} in the setup options.
* The fluid(bool) setter calls player.updateStyleEl_(). Otherwise it won't be triggered in createEl() if an aspect ratio is not also set.
* Corrects the test for a set videoWidth() in updateStyleEl_() - videoWidth() returns 0 if the width is unknown. This allows the default 16:9 to kick in rather than using 0:0.
* Disable HLS hack on Firefox for Android
* Fix canPlayType patching tests
* Add test to ensure that canPlayType is not patched in Firefox for Android
* Fix assertion message in Firefox for Android test
* Guard against exceptions in an event handler to stop them from breaking further processing of event handlers
* Added a test for try/catch behavior for exceptions originating in event handlers
- Get rid of our custom XHR shim. Export it as videojs.xhr.
- Updated XHR to be stubbed everywhere in tests to prevent errors.
- Added npm install to the review process
closes#2318closes#2594
This is important for enforcing the model that techs should
work the same for everything.
closes#2590fixes#2060
- Made techGet and techCall private functions
- Made loadTech, techName, and unloadTech private
- Cleaned up all other private method naming in the player
- Removed some unneeded comments
- Fixed a console error in dom tests from loading a track source
- Switched to non-fetching poster urls in tests to prevent errors
- Stubbed XHR for TextTrack tests to prevent log errors
- Fixed text track console errors that stubbing async didn't catch
because there's some async happening in tracks that makes it so
- XHR isn't even used until the test is complete
- Removed extra code
- Added player.dispose more places and fixed attributes test
Delay manual progress checks until the tech is ready to avoid errors.
The Flash tech errors if buffered() is called before the SWF has loaded,
for instance.
closes#2316fixes#2288
rel #2289
- Broke out RTMP tests into their own file.
- Cleaned up the currentTime test to not create the swf
- Cleaned up the flash dispose test
- Cleaned up formatting for additional flash tests
--skip-ci
Use primary code ('en') if specific code ('en-us') doesn not match
Always re-merge languages
closes#2177
Updated language function to lowercase internally
Updated component.localize to not require stubbing
Preparing to export utility functions on the videojs object
closes#2182
Change el() to getEl() for consistency
Cleaned up DOM functions library
Clean up and document videojs object API
Fixed mergeOptions to modify the first object instead of a copy
More cleanup of the main video.js file and documentation
Fixed issues with mergeOptions
Cleaned up the addLanguage function
Removed unnecessary underscores in private module vars
closes#2166closes#2126
this.tech.emitTapEvents(); should be handled by the tech
De-dupe the bufferedPercent code in both Tech and Player
Have the player generate the tech ID
Added autoplay/preload/loop/muted to tech option
Remove the watch for native timeupdates
Fixed the JSDoc for bufferedPercent
Removed the unit test for native timeupdate
Added cute whitespaces
buffer should always return a TimeRange
Broke out bind, guid, and element data functions from Lib
Separated out more dom functions in to dom.js
Broke out URL functions into url.js
Removed setLocalStorage since it wasn't being used
Moved browser tests out of lib
Moved log functions into their own file
Removed trim() since it wasn't being used
Moved formatTime into its own file
Moved round into its own file and renamed roundFloat()
Moved capitalize into its own file and renamed as toTitleCase()
Moved createTimeRange into its own file
Removed Lib.arr.forEach infavor of the native forEach
Removed Lib.obj.create in favor of native Object.create (ES6-sham)
Removed obj.each in favor of native Object.getOwnPropertyNames().forEach()
Removed obj.merge and copy. Using lodash.assign instead.
Replaced Lib.obj.isPlain with lodash.isPlainObject
Removed Lib.obj.isArray in favor of the native Array.isArray
Also removed the lib.js tests file as all tests have been moved
or removed.
Removed Lib.isEmpty in favor of !Object.getOwnPropertyNames().length
Switched Util.mergeOptions and deepMerge to use new mergeOptions()
Moved Lib.TEST_VID to Html5.TEST_VID
Removed Lib references everywhere. Woo!
Attempting to fix sourcemap test errors by setting grunt-browserify version
Switched to object.assign from lodash.assign
Removed unused 'inherits' dependency
Reorganzied test files and added '.test' to file names
Combined js/core.js and js/video.js
Moved events.js into the utils directory
Fix for #1561. If the HTML tech is being constructed without a video element to work off of, make sure that the controls attribute is only added under the same circumstances it would be at player init. Before this fix, if you loaded the Flash tech and then switched to the HTML tech, you would see the native controls underneath the video.js controls.
Fix controls attribute test on iOS
iOS uses native controls by default and so was failing the assertions that native controls weren't used. Force custom controls for this test case to make it work like everywhere else.
Update nativeControlsForTouch default
The default value changed so fix the predicate that tested for whether it was in use.
closes#1811, closes#1564, closes#1561
On ended, pause player if not paused or looping
IE11 (and maybe other browsers as well) only fire 'ended' event when the
video ends and doesn't fire pause. This makes IE11 not reset it's state
into a paused state that allows a user to replay immediately. However, a
two clicks on the play/pause button will allow you to replay.
In Chrome, we get first a pause event and then an ended event. When
'loop' is set, neither the last pause nor ended fire.
In the flash tech, the pause and ended events fire like in chrome in all
browsers.
Add tests for onEnded change
Appease jshint.
Trying to create a player-like subclass of component requires overriding languages() but that method was being minified. Add it to externs so that it can be overridden after minification. Fixes#1420.
Clear out pending errors on player disposal.
Source selection errors are dispatched asynchronously so that there is an opportunity to override the error message. If the player is disposed during that period, the error timeout wasn't being cleared properly. Fix for #1480.
Fix whitespace
When defining variables inline with declarations, stick to one variable per line.
Add vjs.isNaN to have a better cross browser isNaN checker.
Previously, only undefined was ignored, so, it tried setting the
dimension using null and NaN as values. In most browsers this isn't a
problem, but in particular on IE8, things break.
With this PR, all three of those values will be ignored.
add base documentation for language support
typo fix
added utility function for adding languages per conversation with @heff. Includes test.
move addLanguage to core. update both core and util tests. added export property
added language sandbox for demo
fix comment
doc udpate
remove build instructions
add addLanguage API to doc
fix deep merge in test
test update
update local reference to string for compiled tests