Comparar commits

..

7 Commits

Autor SHA1 Mensagem Data
Gary Katsevman d482e278d8 remove broken test as there's no need to duplicate it 2017-10-18 15:14:34 -04:00
Gary Katsevman 803777227b prettify separator comment 2017-10-17 15:51:02 -04:00
Gary Katsevman 30fa4813c6 copy our regular embed tests into div embed tests 2017-10-17 15:42:45 -04:00
Gary Katsevman c82b615f01 data-setup with divs as well 2017-10-12 17:51:21 -04:00
Gary Katsevman 0bc2a4d4d5 add an embeds page 2017-10-12 17:48:23 -04:00
Gary Katsevman d59769821d remove debugger statement 2017-10-02 23:08:10 -07:00
Gary Katsevman 2d01479fb5 WIP initial div embed PR 2017-10-02 18:46:33 -04:00
20 arquivos alterados com 576 adições e 632 exclusões
-59
Ver Arquivo
@@ -1,62 +1,3 @@
<a name="6.3.3"></a>
## [6.3.3](https://github.com/videojs/video.js/compare/v6.3.2...v6.3.3) (2017-10-10)
### Bug Fixes
* a possible breaking change caused by the use of remainingTimeDisplay ([#4655](https://github.com/videojs/video.js/issues/4655)) ([b1de506](https://github.com/videojs/video.js/commit/b1de506))
### Documentation
* **hooks:** Fix Typo ([#4652](https://github.com/videojs/video.js/issues/4652)) ([6738f76](https://github.com/videojs/video.js/commit/6738f76))
<a name="6.3.2"></a>
## [6.3.2](https://github.com/videojs/video.js/compare/v6.3.1...v6.3.2) (2017-10-04)
### Bug Fixes
* Fix a typo in current time display component. ([#4647](https://github.com/videojs/video.js/issues/4647)) ([4658c7b](https://github.com/videojs/video.js/commit/4658c7b))
### Documentation
* Document how to add a version number to a plugin ([#4642](https://github.com/videojs/video.js/issues/4642)) ([85a34d1](https://github.com/videojs/video.js/commit/85a34d1))
<a name="6.3.1"></a>
## [6.3.1](https://github.com/videojs/video.js/compare/v6.3.0...v6.3.1) (2017-10-03)
### Bug Fixes
* Make sure time displays use correctly-formatted time. ([#4643](https://github.com/videojs/video.js/issues/4643)) ([20f7fe9](https://github.com/videojs/video.js/commit/20f7fe9))
<a name="6.3.0"></a>
# [6.3.0](https://github.com/videojs/video.js/compare/v6.2.8...v6.3.0) (2017-10-03)
### Features
* Add remainingTimeDisplay method to Player ([#4620](https://github.com/videojs/video.js/issues/4620)) ([445eb26](https://github.com/videojs/video.js/commit/445eb26))
* display currentTime as duration and remainingTime as 0 on ended ([#4634](https://github.com/videojs/video.js/issues/4634)) ([f51d36b](https://github.com/videojs/video.js/commit/f51d36b))
* Do not set focus in sub-menus to prevent undesirable scrolling behavior in iOS ([#4607](https://github.com/videojs/video.js/issues/4607)) ([1ac8065](https://github.com/videojs/video.js/commit/1ac8065))
### Bug Fixes
* reset to a play/pause button when seeking after ended ([#4614](https://github.com/videojs/video.js/issues/4614)) ([335bcde](https://github.com/videojs/video.js/commit/335bcde))
### Chores
* alias rollup-dev to watch for development ([#4615](https://github.com/videojs/video.js/issues/4615)) ([edde614](https://github.com/videojs/video.js/commit/edde614))
* **lang:** Update Dutch ([#4588](https://github.com/videojs/video.js/issues/4588)) ([5ca0992](https://github.com/videojs/video.js/commit/5ca0992))
* **lang:** Update Vietnamese ([#4625](https://github.com/videojs/video.js/issues/4625)) ([ac58dbf](https://github.com/videojs/video.js/commit/ac58dbf))
* **package:** update grunt-browserify to version 5.2.0 ([#4578](https://github.com/videojs/video.js/issues/4578)) ([6cd785a](https://github.com/videojs/video.js/commit/6cd785a))
* **package:** update remark-validate-links to version 7.0.0 ([#4585](https://github.com/videojs/video.js/issues/4585)) ([7929677](https://github.com/videojs/video.js/commit/7929677))
### Code Refactoring
* Create a base time display class, and use it ([#4633](https://github.com/videojs/video.js/issues/4633)) ([fa6f884](https://github.com/videojs/video.js/commit/fa6f884))
### Documentation
* Document playbackRates ([#4602](https://github.com/videojs/video.js/issues/4602)) ([9d249bb](https://github.com/videojs/video.js/commit/9d249bb))
* update player reference in advanced plugins doc ([#4622](https://github.com/videojs/video.js/issues/4622)) ([d8ea23e](https://github.com/videojs/video.js/commit/d8ea23e))
<a name="6.2.8"></a>
## [6.2.8](https://github.com/videojs/video.js/compare/v6.2.7...v6.2.8) (2017-09-01)
+3 -3
Ver Arquivo
@@ -35,10 +35,10 @@ if (args.prerelease || npmargs.some(function(arg) { return /next/.test(arg); }))
ghrelease(options, function(err, result) {
if (err) {
console.error('Unable to publish release to github');
console.error('err:', err);
console.error('result:', result);
console.log('Unable to publish release to github');
console.log(err);
} else {
console.log('Publish release to github!');
console.log(result);
}
});
+62 -86
Ver Arquivo
@@ -1,6 +1,6 @@
# Hooks
Hooks exist so that users can globally hook into certain Video.js lifecycle moments.
Hooks exist so that users can "hook" on to certain Video.js player lifecycle
## Table of Contents
@@ -14,157 +14,133 @@ Hooks exist so that users can globally hook into certain Video.js lifecycle mome
## Current Hooks
Currently, the following hooks are available:
Currently, the following hooks are avialable:
### beforesetup
`beforesetup` occurs just before a player is created. This allows:
`beforesetup` is called just before the player is created. This allows:
* Modification of the options passed to the Video.js function (e.g., `videojs('some-id, options)`).
* Modification of the DOM video element that will be used for the player that will be created.
* modification of the options passed to the Video.js function (`videojs('some-id, options)`)
* modification of the dom video element that will be used for the player
`beforesetup` hook functions should:
* Take two arguments:
1. `videoEl`: DOM `<video>` element that Video.js is going to use to create a player.
1. `options`: The options object that Video.js was called with and will be passed to the player during creation.
* Return an options object that will be merged with the originally provided options.
* take two arguments
1. videoEl: dom video element that Video.js is going to use to create a player
1. options: options that Video.js was intialized with and will later pass to the player during creation
* return options that will merge and override options that Video.js with intialized with
#### Example
Example: adding beforesetup hook
```js
videojs.hook('beforesetup', function(videoEl, options) {
// videoEl will be the video element with id="some-id" since that
// gets passed to videojs() below. On subsequent calls, it will be
// different.
var beforeSetup = function(videoEl, options) {
// videoEl.id will be some-id here, since that is what Video.js
// was created with
videoEl.className += ' some-super-class';
// autoplay will be true here, since we passed it as such.
if (options.autoplay) {
// autoplay will be true here, since we passed in as such
(options.autoplay) {
options.autoplay = false
}
// Options that are returned here will be merged with old options.
//
// In this example options will now be:
// {autoplay: false, controls: true}
//
// This has the practical effect of always disabling autoplay no matter
// what options are passed to videojs().
// options that are returned here will be merged with old options
// in this example options will now be
// {autoplay: false, controls: true}
return options;
});
};
// Create a new player.
videojs.hook('beforesetup', beforeSetup);
videojs('some-id', {autoplay: true, controls: true});
```
### setup
`setup` occurs just after a player is created. This allows:
`setup` is called just after the player is created. This allows:
* Plugins or other custom functionality to initialize on the player.
* Changes to the player object itself.
* plugin or custom functionality to intialize on the player
* changes to the player object itself
`setup` hook functions:
* Take one argument:
1. `player`: the player that Video.js created
* Take one argument
* player: the player that Video.js created
* Don't have to return anything
#### Example
Example: adding a setup hook
```js
videojs.registerPlugin('foo', function() {
var setup = function(player) {
// initialize the foo plugin
player.foo();
};
var foo = function() {};
// This basic plugin will add the "some-super-class" class to a player.
this.addClass('some-super-class');
});
videojs.hook('setup', function(player) {
// Initialize the foo plugin after any player is created.
player.foo();
});
// Create a new player.
videojs('some-id', {autoplay: true, controls: true});
videojs.registerPlugin('foo', foo);
videojs.hook('setup', setup);
var player = videojs('some-id', {autoplay: true, controls: true});
```
## Usage
### Adding
Hooks can be added using `videojs.hook(<name>, function)` before running the `videojs()` function.
In order to use hooks you must first include Video.js in the page or script that you are using. Then you add hooks using `videojs.hook(<name>, function)` before running the `videojs()` function.
#### Example
Example: adding hooks
```js
videojs.hook('beforesetup', function(videoEl, options) {
// This hook will be called twice. Once for "vid1" and once for "vid2".
// The options will match what is passed to videojs() for each of them.
// videoEl will be the element with id=vid1
// options will contain {autoplay: false}
});
videojs.hook('setup', function(player) {
// This hook will be called twice. Once for "vid1" and once for "vid2".
// The player value will be the player that is created for each element.
// player will be the same player that is defined below
// as `var player`
});
videojs('vid1', {autoplay: false});
videojs('vid2', {autoplay: true});
var player = videojs('vid1', {autoplay: false});
```
After adding your hooks, they will automatically be run at the correct time in the Video.js lifecycle.
### Adding Once
In some cases, you may only want your hook to run once. In these cases, use `videojs.hookOnce(<name>, function)` before running the `videojs()` function.
#### Example
```js
videojs.hookOnce('beforesetup', function(videoEl, options) {
// This hook will be called once for "vid1", but not for "vid2".
// The options will match what is passed to videojs().
});
videojs.hookOnce('setup', function(player) {
// This hook will be called once for "vid1", but not for "vid2".
// The player value will be the player that is created for each element.
});
videojs('vid1', {autoplay: false});
videojs('vid2', {autoplay: true});
```
After adding your hooks they will automatically be run at the correct time in the Video.js lifecycle.
### Getting
To access the array of functions that currently exists for any hook, use the `videojs.hooks` function.
To access the array of hooks that currently exists and will be run on the Video.js object you can use the `videojs.hooks` function.
#### Example
Example: getting all hooks attached to Video.js
```js
// Get an array of all the 'beforesetup' hooks.
var beforeSetupHooks = videojs.hooks('beforesetup');
// Get an array of all the 'setup' hooks.
var setupHooks = videojs.hooks('setup');
```
### Removing
To stop hooks from being executed during any future Video.js lifecycles you can remove them using `videojs.removeHook`.
To stop hooks from being executed during the Video.js lifecycle you will remove them using `videojs.removeHook`.
#### Example
Example: remove a hook that was defined by you
```js
var beforeSetup = function(videoEl, options) {};
// Add the hook.
// add the hook
videojs.hook('beforesetup', beforeSetup);
// Remove the same hook.
// remove that same hook
videojs.removeHook('beforesetup', beforeSetup);
```
You can also use `videojs.hooks` in conjunction with `videojs.removeHook` but it may have unexpected results if used during an asynchronous callbacks as other plugins/functionality may have added hooks.
Example: using `videojs.hooks` and `videojs.removeHook` to remove a hook
```js
// add the hook
videojs.hook('setup', function(videoEl, options) {});
var setupHooks = videojs.hooks('setup');
// remove the hook you just added
videojs.removeHook('setup', setupHooks[setupHooks.length - 1]);
```
-19
Ver Arquivo
@@ -225,25 +225,6 @@ The `dispose` method has several effects:
In addition, if the player is disposed, the disposal of all its advanced plugin instances will be triggered as well.
#### Version
Adding a version number to a plugin is done by defining a `VERSION` property on the plugin before registering it:
```js
ExamplePlugin.VERSION = '1.0.1';
videojs.registerPlugin('examplePlugin', ExamplePlugin);
```
Retrieve it using `videojs.getPluginVersion`:
```js
var version = videojs.getPluginVersion('examplePlugin');
console.log(version); // 1.0.1
```
Note that the [plugin generator](https://github.com/videojs/generator-videojs-plugin) already takes care of adding a version number for you.
### Advanced Example Advanced Plugin
What follows is a complete ES6 advanced plugin that logs a custom message when the player's state changes between playing and paused. It uses all the described advanced features:
+21 -68
Ver Arquivo
@@ -1,84 +1,37 @@
{
"Audio Player": "Audiospeler",
"Video Player": "Videospeler",
"Play": "Afspelen",
"Pause": "Pauzeren",
"Replay": "Opnieuw afspelen",
"Pause": "Pauze",
"Current Time": "Huidige tijd",
"Duration Time": "Tijdsduur",
"Duration Time": "Looptijd",
"Remaining Time": "Resterende tijd",
"Stream Type": "Streamtype",
"LIVE": "LIVE",
"Loaded": "Geladen",
"Progress": "Voortgang",
"Progress Bar": "Voortgangsbalk",
"progress bar timing: currentTime={1} duration={2}": "{1} van {2}",
"Progress": "Status",
"Fullscreen": "Volledig scherm",
"Non-Fullscreen": "Geen volledig scherm",
"Mute": "Dempen",
"Unmute": "Niet dempen",
"Playback Rate": "Afspeelsnelheid",
"Mute": "Geluid uit",
"Unmute": "Geluid aan",
"Playback Rate": "Weergavesnelheid",
"Subtitles": "Ondertiteling",
"subtitles off": "ondertiteling uit",
"Captions": "Bijschriften",
"captions off": "bijschriften uit",
"Chapters": "Hoofdstukken",
"Descriptions": "Beschrijvingen",
"descriptions off": "beschrijvingen uit",
"Audio Track": "Audiospoor",
"Volume Level": "Geluidsniveau",
"You aborted the media playback": "U heeft het afspelen van de media afgebroken",
"A network error caused the media download to fail part-way.": "Een netwerkfout heeft ervoor gezorgd dat het downloaden van de media halverwege is mislukt.",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "De media kon niet worden geladen, dit komt doordat of de server of het netwerk mislukt of doordat het formaat niet wordt ondersteund.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Het afspelen van de media is afgebroken door een probleem met beschadeigde gegevens of doordat de media functies gebruikt die uw browser niet ondersteund.",
"No compatible source was found for this media.": "Er is geen geschikte bron voor deze media gevonden.",
"The media is encrypted and we do not have the keys to decrypt it.": "De media is versleuteld en we hebben de sleutels niet om deze te ontsleutelen.",
"Play Video": "Video afspelen",
"descriptions off": "beschrijvingen off",
"You aborted the media playback": "U hebt de mediaweergave afgebroken.",
"A network error caused the media download to fail part-way.": "De mediadownload is mislukt door een netwerkfout.",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "De media kon niet worden geladen, vanwege een server- of netwerkfout of doordat het formaat niet wordt ondersteund.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "De mediaweergave is afgebroken vanwege beschadigde data of het mediabestand gebruikt functies die niet door uw browser worden ondersteund.",
"No compatible source was found for this media.": "Voor deze media is geen ondersteunde bron gevonden.",
"Play Video": "Video Afspelen",
"Close": "Sluiten",
"Close Modal Dialog": "Extra venster sluiten",
"Modal Window": "Extra venster",
"This is a modal window": "Dit is een extra venster",
"This modal can be closed by pressing the Escape key or activating the close button.": "Dit venster kan worden gesloten door op de Escape-toets te drukken of door de sluiten-knop te activeren.",
", opens captions settings dialog": ", opent instellingen-venster voor bijschriften",
", opens subtitles settings dialog": ", opent instellingen-venster voor ondertitelingen",
", opens descriptions settings dialog": ", opent instellingen-venster voor beschrijvingen",
", selected": ", geselecteerd",
"captions settings": "bijschriften-instellingen",
"subtitles settings": "ondertiteling-instellingen",
"descriptions settings": "beschrijvingen-instellingen",
"Text": "Tekst",
"White": "Wit",
"Black": "Zwart",
"Red": "Rood",
"Green": "Groen",
"Blue": "Blauw",
"Yellow": "Geel",
"Magenta": "Magenta",
"Cyan": "Cyaan",
"Background": "Achtergrond",
"Window": "Venster",
"Transparent": "Transparant",
"Semi-Transparent": "Semi-transparant",
"Opaque": "Ondoorzichtig",
"Font Size": "Lettergrootte",
"Text Edge Style": "Stijl tekstrand",
"None": "Geen",
"Raised": "Verhoogd",
"Depressed": "Ingedrukt",
"Uniform": "Uniform",
"Dropshadow": "Schaduw",
"Font Family": "Lettertype",
"Proportional Sans-Serif": "Proportioneel sans-serif",
"Monospace Sans-Serif": "Monospace sans-serif",
"Proportional Serif": "Proportioneel serif",
"Monospace Serif": "Monospace serif",
"Casual": "Luchtig",
"Script": "Script",
"Small Caps": "Kleine hoofdletters",
"Reset": "Herstellen",
"restore all settings to the default values": "alle instellingen naar de standaardwaarden herstellen",
"Done": "Klaar",
"Caption Settings Dialog": "Venster voor bijschriften-instellingen",
"Beginning of dialog window. Escape will cancel and close the window.": "Begin van dialoogvenster. Escape zal annuleren en het venster sluiten.",
"End of dialog window.": "Einde van dialoogvenster."
}
"Modal Window": "Modal Venster",
"This is a modal window": "Dit is een modaal venster",
"This modal can be closed by pressing the Escape key or activating the close button.": "Dit modaal venster kan gesloten worden door op Escape te drukken of de 'sluiten' knop te activeren.",
", opens captions settings dialog": ", opent bijschriften instellingen venster",
", opens subtitles settings dialog": ", opent ondertiteling instellingen venster",
", opens descriptions settings dialog": ", opent beschrijvingen instellingen venster",
", selected": ", selected"
}
+8 -51
Ver Arquivo
@@ -1,6 +1,4 @@
{
"Audio Player": "Trình phát Audio",
"Video Player": "Trình phát Video",
"Play": "Phát",
"Pause": "Tạm dừng",
"Replay": "Phát lại",
@@ -11,8 +9,6 @@
"LIVE": "TRỰC TIẾP",
"Loaded": "Đã tải",
"Progress": "Tiến trình",
"Progress Bar": "Thanh tiến trình",
"progress bar timing: currentTime={1} duration={2}": "{1} của {2}",
"Fullscreen": "Toàn màn hình",
"Non-Fullscreen": "Thoát toàn màn hình",
"Mute": "Tắt tiếng",
@@ -23,62 +19,23 @@
"Captions": "Chú thích",
"captions off": "tắt chú thích",
"Chapters": "Chương",
"Close Modal Dialog": "Đóng hộp thoại",
"Descriptions": "Mô tả",
"descriptions off": "tắt mô tả",
"Audio Track": "Track âm thanh",
"Volume Level": "Mức âm lượng",
"You aborted the media playback": "Bạn đã hủy việc phát lại media.",
"A network error caused the media download to fail part-way.": "Một lỗi mạng dẫn đến việc tải media bị lỗi.",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video không tải được, mạng hay server có lỗi hoặc định dạng không được hỗ trợ.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Phát media đã bị hủy do một sai lỗi hoặc media sử dụng những tính năng trình duyệt không hỗ trợ.",
"No compatible source was found for this media.": "Không có nguồn tương thích cho media này.",
"The media is encrypted and we do not have the keys to decrypt it.": "Media đã được mã hóa và chúng tôi không có để giải mã nó.",
"The media is encrypted and we do not have the keys to decrypt it.": "Media đã được mã hóa và chúng tôi không thể giải mã nó.",
"Play Video": "Phát Video",
"Close": "Đóng",
"Close Modal Dialog": "Đóng cửa sổ",
"Modal Window": "Cửa sổ",
"This is a modal window": "Đây là một cửa sổ",
"This modal can be closed by pressing the Escape key or activating the close button.": "Cửa sổ này có thể thoát bằng việc nhấn phím Esc hoặc kích hoạt nút đóng.",
", opens captions settings dialog": ", mở hộp thoại cài đặt chú thích",
", opens subtitles settings dialog": ", mở hộp thoại cài đặt phụ đề",
", opens descriptions settings dialog": ", mở hộp thoại cài đặt mô tả",
", selected": ", đã chọn",
"captions settings": "cài đặt chú thích",
"subtitles settings": "cài đặt phụ đề",
"descriptions settings": "cài đặt mô tả",
"Text": "Văn bản",
"White": "Trắng",
"Black": "Đen",
"Red": "Đỏ",
"Green": "Xanh lá cây",
"Blue": "Xanh da trời",
"Yellow": "Vàng",
"Magenta": "Đỏ tươi",
"Cyan": "Lam",
"Background": "Nền",
"Window": "Cửa sổ",
"Transparent": "Trong suốt",
"Semi-Transparent": "Bán trong suốt",
"Opaque": "Mờ",
"Font Size": "Kích cỡ phông chữ",
"Text Edge Style": "Dạng viền văn bản",
"None": "None",
"Raised": "Raised",
"Depressed": "Depressed",
"Uniform": "Uniform",
"Dropshadow": "Dropshadow",
"Font Family": "Phông chữ",
"Proportional Sans-Serif": "Proportional Sans-Serif",
"Monospace Sans-Serif": "Monospace Sans-Serif",
"Proportional Serif": "Proportional Serif",
"Monospace Serif": "Monospace Serif",
"Casual": "Casual",
"Script": "Script",
"Small Caps": "Small Caps",
"Reset": "Đặt lại",
"restore all settings to the default values": "khôi phục lại tất cả các cài đặt về giá trị mặc định",
"Done": "Xong",
"Caption Settings Dialog": "Hộp thoại cài đặt chú thích",
"Beginning of dialog window. Escape will cancel and close the window.": "Bắt đầu cửa sổ hộp thoại. Esc sẽ thoát và đóng cửa sổ.",
"End of dialog window.": "Kết thúc cửa sổ hộp thoại."
}
"This modal can be closed by pressing the Escape key or activating the close button.": "Cửa sổ này có thể đóng lại bằng việc nhấn phím Esc hoặc kích hoạt nút đóng.",
", opens captions settings dialog": ", mở hộp thoại thiết lập chú thích",
", opens subtitles settings dialog": ", mở hộp thoại thiết lập phụ đề",
", opens descriptions settings dialog": ", mở hộp thoại thiết lập mô tả",
", selected": ", đã chọn"
}
+1 -1
Ver Arquivo
@@ -1,7 +1,7 @@
{
"name": "video.js",
"description": "An HTML5 and Flash video player with a common API and skin for both.",
"version": "6.3.3",
"version": "6.2.8",
"main": "./dist/video.cjs.js",
"style": "./dist/video-js.css",
"copyright": "Copyright Brightcove, Inc. <https://www.brightcove.com/>",
+165
Ver Arquivo
@@ -0,0 +1,165 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Video.js Sandbox</title>
<script src='../node_modules/es5-shim/es5-shim.js'></script>
<script src='../node_modules/es6-shim/es6-shim.js'></script>
<link href="../build/temp/video-js.css" rel="stylesheet" type="text/css">
<script src="../dist/video.js"></script>
<script src='../node_modules/videojs-flash/dist/videojs-flash.js'></script>
<script src="https://unpkg.com/videojs-contrib-hls@latest/dist/videojs-contrib-hls.js"></script>
<script src="../build/temp/lang/es.js"></script>
<!-- Set the location of the flash SWF -->
<script>
// videojs.options.flash.swf = 'http://vjs.zencdn.net/swf/5.3/video-js.swf';
videojs.options.flash.swf = 'http://localhost:8000/video-js-swf/dist/video-js.swf';
</script>
<style>
.source-el { background: #FF6961; }
.source-js { background: #77DD77; }
.options-src { background: #AEC6CF; }
.source-el.data-setup { background: red; }
.source-js.data-setup { background: green; }
.options-src.data-setup { background: blue; }
.video-js {
height: 150px;
width: 300px;
}
.wrapper {
display: grid;
margin: 0 auto;
grid-gap: 10px;
grid-template-columns: 300px 300px 300px;
}
.panel > p:first-child {
border-bottom: black 1px solid;
}
</style>
</head>
<body>
<p>All the various ways to embed and source video elements.</p>
<p>Pastel color background represent programmatic setup.</p>
<p>Vibrant color background represent data-setup.</p>
<div class="wrapper">
<div class="panel source-el">
<p>js setup with source element</p>
<p>Div embed, source element</p>
<div id="vid01" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png">
<source src="./oceans.mp4" type='video/mp4'>
</div>
<p>Video embed, source element</p>
<video id="vid11" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png">
<source src="./oceans.mp4" type='video/mp4'>
</video>
<p>injested div el, source element</p>
<div data-vjs-player>
<video id="vid21" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png">
<source src="./oceans.mp4" type='video/mp4'>
</video>
</div>
</div>
<div class="panel options-src">
<p>js setup with sources options</p>
<p>Div embed, js source</p>
<div id="vid05" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png">
</div>
<p>Video embed, js source</p>
<video id="vid15" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png">
</video>
<p>injested div el, js source</p>
<div data-vjs-player>
<video id="vid25" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png">
</video>
</div>
</div>
<div class="panel source-js">
<p>js setup with js method sources</p>
<p>Div embed, js source</p>
<div id="vid02" class="video-js" controls>
</div>
<p>Video embed, js source</p>
<video id="vid12" class="video-js" controls>
</video>
<p>injested div el, js source</p>
<div data-vjs-player>
<video id="vid22" class="video-js" controls>
</video>
</div>
</div>
<div class="panel source-el data-setup">
<p>data-setup with sourrce elements</p>
<p>Div embed, source element</p>
<div id="vid03" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png" data-setup="{}">
<source src="./oceans.mp4" type='video/mp4'>
</div>
<p>Video embed, source element</p>
<video id="vid13" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png" data-setup="{}">
<source src="./oceans.mp4" type='video/mp4'>
</video>
<p>injested div el, source element</p>
<div data-vjs-player>
<video id="vid23" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png" data-setup="{}">
<source src="./oceans.mp4" type='video/mp4'>
</video>
</div>
</div>
<div class="panel options-src data-setup">
<p>data-setup embeds with sources options</p>
<p>Div embed, source element</p>
<div id="vid04" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png" data-setup='{"sources": [{"src":"./oceans.mp4", "type":"video/mp4"}]}'>
</div>
<p>Video embed, source element</p>
<video id="vid14" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png" data-setup='{"sources": [{"src":"./oceans.mp4", "type":"video/mp4"}]}'>
</video>
<p>injested div el, source element</p>
<div data-vjs-player>
<video id="vid24" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png" data-setup='{"sources": [{"src":"./oceans.mp4", "type":"video/mp4"}]}'>
</video>
</div>
</div>
<div class="panel source-js data-setup">
<p>js setup with js method sources</p>
<p>Div embed, js source</p>
<div id="vid06" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png" data-setup="{}">
</div>
<p>Video embed, js source</p>
<video id="vid16" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png" data-setup="{}">
</video>
<p>injested div el, js source</p>
<div data-vjs-player>
<video id="vid26" class="video-js" controls poster="//vjs.zencdn.net/v/oceans.png" data-setup="{}">
</video>
</div>
</div>
</div>
<script>
var player01 = videojs('vid01');
var player11 = videojs('vid11');
var player21 = videojs('vid21');
var player01 = videojs('vid02');
var player11 = videojs('vid12');
var player21 = videojs('vid22');
var player05 = videojs('vid05', {sources: [{src:'./oceans.mp4',type:'video/mp4'}]});
var player15 = videojs('vid15', {sources: [{src:'./oceans.mp4',type:'video/mp4'}]});
var player25 = videojs('vid25', {sources: [{src:'./oceans.mp4',type:'video/mp4'}]});
player01.src({src:'./oceans.mp4', type:'video/mp4'});
player11.src({src:'./oceans.mp4', type:'video/mp4'});
player21.src({src:'./oceans.mp4', type:'video/mp4'});
player01.poster('//vjs.zencdn.net/v/oceans.png');
player11.poster('//vjs.zencdn.net/v/oceans.png');
player21.poster('//vjs.zencdn.net/v/oceans.png');
setTimeout(function() {
videojs.players.vid06 && videojs.players.vid06.src({src:'./oceans.mp4', type:'video/mp4'});
videojs.players.vid16 && videojs.players.vid16.src({src:'./oceans.mp4', type:'video/mp4'});
videojs.players.vid26 && videojs.players.vid26.src({src:'./oceans.mp4', type:'video/mp4'});
});
</script>
</body>
</html>
-26
Ver Arquivo
@@ -57,25 +57,6 @@ class PlayToggle extends Button {
}
}
/**
* This gets called once after the video has ended and the user seeks so that
* we can change the replay button back to a play button.
*
* @param {EventTarget~Event} [event]
* The event that caused this function to run.
*
* @listens Player#seeked
*/
handleSeeked(event) {
this.removeClass('vjs-ended');
if (this.player_.paused()) {
this.handlePause(event);
} else {
this.handlePlay(event);
}
}
/**
* Add the vjs-playing class to the element so it can change appearance.
*
@@ -110,19 +91,12 @@ class PlayToggle extends Button {
/**
* Add the vjs-ended class to the element so it can change appearance
*
* @param {EventTarget~Event} [event]
* The event that caused this function to run.
*
* @listens Player#ended
*/
handleEnded(event) {
this.removeClass('vjs-playing');
this.addClass('vjs-ended');
// change the button text to "Replay"
this.controlText('Replay');
// on the next seek remove the replay button
this.one(this.player_, 'seeked', this.handleSeeked);
}
}
@@ -1,15 +1,18 @@
/**
* @file current-time-display.js
*/
import TimeDisplay from './time-display';
import document from 'global/document';
import Component from '../../component.js';
import * as Dom from '../../utils/dom.js';
import {bind, throttle} from '../../utils/fn.js';
import formatTime from '../../utils/format-time.js';
/**
* Displays the current time
*
* @extends Component
*/
class CurrentTimeDisplay extends TimeDisplay {
class CurrentTimeDisplay extends Component {
/**
* Creates an instance of this class.
@@ -22,17 +25,48 @@ class CurrentTimeDisplay extends TimeDisplay {
*/
constructor(player, options) {
super(player, options);
this.on(player, 'ended', this.handleEnded);
this.throttledUpdateContent = throttle(bind(this, this.updateContent), 25);
this.on(player, 'timeupdate', this.throttledUpdateContent);
}
/**
* Builds the default DOM `className`.
* Create the `Component`'s DOM element
*
* @return {string}
* The DOM `className` for this object.
* @return {Element}
* The element that was created.
*/
buildCSSClass() {
return 'vjs-current-time';
createEl() {
const el = super.createEl('div', {
className: 'vjs-current-time vjs-time-control vjs-control'
});
this.contentEl_ = Dom.createEl('div', {
className: 'vjs-current-time-display'
}, {
// tell screen readers not to automatically read the time as it changes
'aria-live': 'off'
}, Dom.createEl('span', {
className: 'vjs-control-text',
textContent: this.localize('Current Time')
}));
this.updateTextNode_();
el.appendChild(this.contentEl_);
return el;
}
/**
* Updates the "current time" text node with new content using the
* contents of the `formattedTime_` property.
*
* @private
*/
updateTextNode_() {
if (this.textNode_) {
this.contentEl_.removeChild(this.textNode_);
}
this.textNode_ = document.createTextNode(` ${this.formattedTime_ || '0:00'}`);
this.contentEl_.appendChild(this.textNode_);
}
/**
@@ -46,36 +80,15 @@ class CurrentTimeDisplay extends TimeDisplay {
updateContent(event) {
// Allows for smooth scrubbing, when player can't keep up.
const time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
const formattedTime = formatTime(time, this.player_.duration());
this.updateFormattedTime_(time);
}
/**
* When the player fires ended there should be no time left. Sadly
* this is not always the case, lets make it seem like that is the case
* for users.
*
* @param {EventTarget~Event} [event]
* The `ended` event that caused this to run.
*
* @listens Player#ended
*/
handleEnded(event) {
if (!this.player_.duration()) {
return;
if (formattedTime !== this.formattedTime_) {
this.formattedTime_ = formattedTime;
this.requestAnimationFrame(this.updateTextNode_);
}
this.updateFormattedTime_(this.player_.duration());
}
}
/**
* The text that should display over the `CurrentTimeDisplay`s controls. Added to for localization.
*
* @type {string}
* @private
*/
CurrentTimeDisplay.prototype.controlText_ = 'Current Time';
Component.registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
export default CurrentTimeDisplay;
@@ -1,15 +1,18 @@
/**
* @file duration-display.js
*/
import TimeDisplay from './time-display';
import document from 'global/document';
import Component from '../../component.js';
import * as Dom from '../../utils/dom.js';
import {bind, throttle} from '../../utils/fn.js';
import formatTime from '../../utils/format-time.js';
/**
* Displays the duration
*
* @extends Component
*/
class DurationDisplay extends TimeDisplay {
class DurationDisplay extends Component {
/**
* Creates an instance of this class.
@@ -23,24 +26,57 @@ class DurationDisplay extends TimeDisplay {
constructor(player, options) {
super(player, options);
this.throttledUpdateContent = throttle(bind(this, this.updateContent), 25);
this.on(player, [
'durationchange',
// Also listen for timeupdate (in the parent) and loadedmetadata because removing those
// Also listen for timeupdate and loadedmetadata because removing those
// listeners could have broken dependent applications/libraries. These
// can likely be removed for 7.0.
'loadedmetadata'
'loadedmetadata',
'timeupdate'
], this.throttledUpdateContent);
}
/**
* Builds the default DOM `className`.
* Create the `Component`'s DOM element
*
* @return {string}
* The DOM `className` for this object.
* @return {Element}
* The element that was created.
*/
buildCSSClass() {
return 'vjs-duration';
createEl() {
const el = super.createEl('div', {
className: 'vjs-duration vjs-time-control vjs-control'
});
this.contentEl_ = Dom.createEl('div', {
className: 'vjs-duration-display'
}, {
// tell screen readers not to automatically read the time as it changes
'aria-live': 'off'
}, Dom.createEl('span', {
className: 'vjs-control-text',
textContent: this.localize('Duration Time')
}));
this.updateTextNode_();
el.appendChild(this.contentEl_);
return el;
}
/**
* Updates the "current time" text node with new content using the
* contents of the `formattedTime_` property.
*
* @private
*/
updateTextNode_() {
if (this.textNode_) {
this.contentEl_.removeChild(this.textNode_);
}
this.textNode_ = document.createTextNode(` ${this.formattedTime_ || '0:00'}`);
this.contentEl_.appendChild(this.textNode_);
}
/**
@@ -59,18 +95,11 @@ class DurationDisplay extends TimeDisplay {
if (duration && this.duration_ !== duration) {
this.duration_ = duration;
this.updateFormattedTime_(duration);
this.formattedTime_ = formatTime(duration);
this.requestAnimationFrame(this.updateTextNode_);
}
}
}
/**
* The text that should display over the `DurationDisplay`s controls. Added to for localization.
*
* @type {string}
* @private
*/
DurationDisplay.prototype.controlText_ = 'Duration Time';
Component.registerComponent('DurationDisplay', DurationDisplay);
export default DurationDisplay;
@@ -1,14 +1,18 @@
/**
* @file remaining-time-display.js
*/
import TimeDisplay from './time-display';
import document from 'global/document';
import Component from '../../component.js';
import * as Dom from '../../utils/dom.js';
import {bind, throttle} from '../../utils/fn.js';
import formatTime from '../../utils/format-time.js';
/**
* Displays the time left in the video
*
* @extends Component
*/
class RemainingTimeDisplay extends TimeDisplay {
class RemainingTimeDisplay extends Component {
/**
* Creates an instance of this class.
@@ -21,33 +25,48 @@ class RemainingTimeDisplay extends TimeDisplay {
*/
constructor(player, options) {
super(player, options);
this.on(player, 'durationchange', this.throttledUpdateContent);
this.on(player, 'ended', this.handleEnded);
this.throttledUpdateContent = throttle(bind(this, this.updateContent), 25);
this.on(player, ['timeupdate', 'durationchange'], this.throttledUpdateContent);
}
/**
* Builds the default DOM `className`.
* Create the `Component`'s DOM element
*
* @return {string}
* The DOM `className` for this object.
* @return {Element}
* The element that was created.
*/
buildCSSClass() {
return 'vjs-remaining-time';
createEl() {
const el = super.createEl('div', {
className: 'vjs-remaining-time vjs-time-control vjs-control'
});
this.contentEl_ = Dom.createEl('div', {
className: 'vjs-remaining-time-display'
}, {
// tell screen readers not to automatically read the time as it changes
'aria-live': 'off'
}, Dom.createEl('span', {
className: 'vjs-control-text',
textContent: this.localize('Remaining Time')
}));
this.updateTextNode_();
el.appendChild(this.contentEl_);
return el;
}
/**
* The remaining time display prefixes numbers with a "minus" character.
*
* @param {number} time
* A numeric time, in seconds.
*
* @return {string}
* A formatted time
* Updates the "remaining time" text node with new content using the
* contents of the `formattedTime_` property.
*
* @private
*/
formatTime_(time) {
return '-' + super.formatTime_(time);
updateTextNode_() {
if (this.textNode_) {
this.contentEl_.removeChild(this.textNode_);
}
this.textNode_ = document.createTextNode(` -${this.formattedTime_ || '0:00'}`);
this.contentEl_.appendChild(this.textNode_);
}
/**
@@ -60,44 +79,16 @@ class RemainingTimeDisplay extends TimeDisplay {
* @listens Player#durationchange
*/
updateContent(event) {
if (!this.player_.duration()) {
return;
}
if (this.player_.duration()) {
const formattedTime = formatTime(this.player_.remainingTime());
// @deprecated We should only use remainingTimeDisplay
// as of video.js 7
if (this.player_.remainingTimeDisplay) {
this.updateFormattedTime_(this.player_.remainingTimeDisplay());
} else {
this.updateFormattedTime_(this.player_.remainingTime());
if (formattedTime !== this.formattedTime_) {
this.formattedTime_ = formattedTime;
this.requestAnimationFrame(this.updateTextNode_);
}
}
}
/**
* When the player fires ended there should be no time left. Sadly
* this is not always the case, lets make it seem like that is the case
* for users.
*
* @param {EventTarget~Event} [event]
* The `ended` event that caused this to run.
*
* @listens Player#ended
*/
handleEnded(event) {
if (!this.player_.duration()) {
return;
}
this.updateFormattedTime_(0);
}
}
/**
* The text that should display over the `RemainingTimeDisplay`s controls. Added to for localization.
*
* @type {string}
* @private
*/
RemainingTimeDisplay.prototype.controlText_ = 'Remaining Time';
Component.registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
export default RemainingTimeDisplay;
@@ -1,129 +0,0 @@
/**
* @file time-display.js
*/
import document from 'global/document';
import Component from '../../component.js';
import * as Dom from '../../utils/dom.js';
import {bind, throttle} from '../../utils/fn.js';
import formatTime from '../../utils/format-time.js';
/**
* Displays the time left in the video
*
* @extends Component
*/
class TimeDisplay extends Component {
/**
* Creates an instance of this class.
*
* @param {Player} player
* The `Player` that this class should be attached to.
*
* @param {Object} [options]
* The key/value store of player options.
*/
constructor(player, options) {
super(player, options);
this.throttledUpdateContent = throttle(bind(this, this.updateContent), 25);
this.on(player, 'timeupdate', this.throttledUpdateContent);
}
/**
* Create the `Component`'s DOM element
*
* @return {Element}
* The element that was created.
*/
createEl(plainName) {
const className = this.buildCSSClass();
const el = super.createEl('div', {
className: `${className} vjs-time-control vjs-control`
});
this.contentEl_ = Dom.createEl('div', {
className: `${className}-display`
}, {
// tell screen readers not to automatically read the time as it changes
'aria-live': 'off'
}, Dom.createEl('span', {
className: 'vjs-control-text',
textContent: this.localize(this.contentText_)
}));
this.updateTextNode_();
el.appendChild(this.contentEl_);
return el;
}
/**
* Updates the "remaining time" text node with new content using the
* contents of the `formattedTime_` property.
*
* @private
*/
updateTextNode_() {
if (this.textNode_) {
this.contentEl_.removeChild(this.textNode_);
}
this.textNode_ = document.createTextNode(this.formattedTime_ || '0:00');
this.contentEl_.appendChild(this.textNode_);
}
/**
* Generates a formatted time for this component to use in display.
*
* @param {number} time
* A numeric time, in seconds.
*
* @return {string}
* A formatted time
*
* @private
*/
formatTime_(time) {
return formatTime(time);
}
/**
* Updates the time display text node if it has what was passed in changed
* the formatted time.
*
* @param {number} time
* The time to update to
*
* @private
*/
updateFormattedTime_(time) {
const formattedTime = this.formatTime_(time);
if (formattedTime === this.formattedTime_) {
return;
}
this.formattedTime_ = formattedTime;
this.requestAnimationFrame(this.updateTextNode_);
}
/**
* To be filled out in the child class, should update the displayed time
* in accordance with the fact that the current time has changed.
*
* @param {EventTarget~Event} [event]
* The `timeupdate` event that caused this to run.
*
* @listens Player#timeupdate
*/
updateContent(event) {}
}
/**
* The text that should display over the `TimeDisplay`s controls. Added to for localization.
*
* @type {string}
* @private
*/
TimeDisplay.prototype.controlText_ = 'Time';
Component.registerComponent('TimeDisplay', TimeDisplay);
export default TimeDisplay;
+2 -7
Ver Arquivo
@@ -8,7 +8,6 @@ import * as Dom from '../utils/dom.js';
import * as Fn from '../utils/fn.js';
import * as Events from '../utils/events.js';
import toTitleCase from '../utils/to-title-case.js';
import { IS_IOS } from '../utils/browser.js';
import document from 'global/document';
/**
@@ -340,12 +339,8 @@ class MenuButton extends Component {
this.buttonPressed_ = true;
this.menu.lockShowing();
this.menuButton_.el_.setAttribute('aria-expanded', 'true');
// set the focus into the submenu, except on iOS where it is resulting in
// undesired scrolling behavior when the player is in an iframe
if (!IS_IOS && !Dom.isInFrame()) {
this.menu.focus();
}
// set the focus into the submenu
this.menu.focus();
}
}
+30 -18
Ver Arquivo
@@ -363,6 +363,7 @@ class Player extends Component {
// now remove immediately so native controls don't flash.
// May be turned back on by HTML5 tech if nativeControlsForTouch is true
tag.controls = false;
tag.removeAttribute('controls');
/*
* Store the internal state of scrubbing
@@ -508,16 +509,34 @@ class Player extends Component {
* The DOM element that gets created.
*/
createEl() {
const tag = this.tag;
let tag = this.tag;
let el;
const playerElIngest = this.playerElIngest_ = tag.parentNode && tag.parentNode.hasAttribute && tag.parentNode.hasAttribute('data-vjs-player');
let playerElIngest = this.playerElIngest_ = tag.parentNode && tag.parentNode.hasAttribute && tag.parentNode.hasAttribute('data-vjs-player');
const divEmbed = this.tag.tagName.toLowerCase() === 'div';
if (playerElIngest) {
el = this.el_ = tag.parentNode;
} else {
} else if (!divEmbed) {
el = this.el_ = super.createEl('div');
}
// Copy over all the attributes from the tag, including ID and class
// ID will now reference player box, not the video tag
const attrs = Dom.getAttributes(tag);
if (divEmbed) {
el = this.el_ = tag;
tag = this.tag = document.createElement('video');
while (el.children.length) {
tag.appendChild(el.firstChild);
el.removeChild(el.firstChild);
}
el.appendChild(tag);
playerElIngest = this.playerElIngest_ = el;
}
// set tabindex to -1 so we could focus on the player element
tag.setAttribute('tabindex', '-1');
@@ -525,17 +544,21 @@ class Player extends Component {
tag.removeAttribute('width');
tag.removeAttribute('height');
// Copy over all the attributes from the tag, including ID and class
// ID will now reference player box, not the video tag
const attrs = Dom.getAttributes(tag);
Object.getOwnPropertyNames(attrs).forEach(function(attr) {
// workaround so we don't totally break IE7
// http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7
if (attr === 'class') {
el.className += ' ' + attrs[attr];
if (divEmbed) {
tag.className += ' ' + attrs[attr];
}
} else {
el.setAttribute(attr, attrs[attr]);
if (divEmbed) {
tag.setAttribute(attr, attrs[attr]);
}
}
});
@@ -1787,17 +1810,6 @@ class Player extends Component {
return this.duration() - this.currentTime();
}
/**
* A remaining time function that is intented to be used when
* the time is to be displayed directly to the user.
*
* @return {number}
* The rounded time remaining in seconds
*/
remainingTimeDisplay() {
return Math.floor(this.duration()) - Math.floor(this.currentTime());
}
//
// Kind of like an array of portions of the video that have been downloaded.
+7
Ver Arquivo
@@ -31,6 +31,7 @@ const autoSetup = function() {
// through each list of elements to build up a new, combined list of elements.
const vids = document.getElementsByTagName('video');
const audios = document.getElementsByTagName('audio');
const divs = document.getElementsByTagName('div');
const mediaEls = [];
if (vids && vids.length > 0) {
@@ -45,6 +46,12 @@ const autoSetup = function() {
}
}
if (divs && divs.length > 0) {
for (let i = 0, e = divs.length; i < e; i++) {
mediaEls.push(divs[i]);
}
}
// Check if any media elements exist
if (mediaEls && mediaEls.length > 0) {
-17
Ver Arquivo
@@ -85,23 +85,6 @@ export function isEl(value) {
return isObject(value) && value.nodeType === 1;
}
/**
* Determines if the current DOM is embedded in an iframe.
*
* @return {boolean}
*
*/
export function isInFrame() {
// We need a try/catch here because Safari will throw errors when attempting
// to get either `parent` or `self`
try {
return window.parent !== window.self;
} catch (x) {
return true;
}
}
/**
* Creates functions to query the DOM using a given method.
*
+2 -22
Ver Arquivo
@@ -140,8 +140,8 @@ videojs.hooks_ = {};
* @param {string} type
* the lifecyle to get hooks from
*
* @param {Function|Function[]} [fn]
* Optionally add a hook (or hooks) to the lifecycle that your are getting.
* @param {Function} [fn]
* Optionally add a hook to the lifecycle that your are getting.
*
* @return {Array}
* an array of hooks, or an empty array if there are none.
@@ -167,26 +167,6 @@ videojs.hook = function(type, fn) {
videojs.hooks(type, fn);
};
/**
* Add a function hook that will only run once to a specific videojs lifecycle.
*
* @param {string} type
* the lifecycle to hook the function to.
*
* @param {Function|Function[]}
* The function or array of functions to attach.
*/
videojs.hookOnce = function(type, fn) {
videojs.hooks(type, [].concat(fn).map(original => {
const wrapper = (...args) => {
videojs.removeHook(type, wrapper);
original(...args);
};
return wrapper;
}));
};
/**
* Remove a hook from a specific videojs lifecycle.
*
+136 -1
Ver Arquivo
@@ -17,7 +17,7 @@ QUnit.module('video.js', {
QUnit.test('should create a video tag and have access children in old IE', function(assert) {
const fixture = document.getElementById('qunit-fixture');
fixture.innerHTML += '<video id="test_vid_id"><source type="video/mp4"></video>';
fixture.innerHTML += '<video id="test_vid_id"><source type="video/mp4"></source></video>';
const vid = document.getElementById('test_vid_id');
@@ -331,3 +331,138 @@ QUnit.test('should create a new tag for movingMediaElementInDOM', function(asser
Html5.isSupported = oldIS;
Html5.nativeSourceHandler.canPlayType = oldCPT;
});
/* **************************************************** *
* div embed tests copied from video emebed tests above *
* **************************************************** */
QUnit.module('video.js div embed', {
beforeEach() {
this.clock = sinon.useFakeTimers();
},
afterEach() {
this.clock.restore();
}
});
QUnit.test('should return a video player instance', function(assert) {
const fixture = document.getElementById('qunit-fixture');
fixture.innerHTML += '<div id="test_vid_id"></div>' +
'<div id="test_vid_id2"></div>';
const player = videojs('test_vid_id', { techOrder: ['techFaker'] });
assert.ok(player, 'created player from tag');
assert.ok(player.id() === 'test_vid_id');
assert.ok(videojs.getPlayers().test_vid_id === player,
'added player to global reference');
const playerAgain = videojs('test_vid_id');
assert.ok(player === playerAgain, 'did not create a second player from same tag');
assert.equal(player, playerAgain, 'we did not make a new player');
const tag2 = document.getElementById('test_vid_id2');
const player2 = videojs(tag2, { techOrder: ['techFaker'] });
assert.ok(player2.id() === 'test_vid_id2', 'created player from element');
player.dispose();
player2.dispose();
});
QUnit.test('should log about already initalized players if options already passed',
function(assert) {
const origWarnLog = log.warn;
const fixture = document.getElementById('qunit-fixture');
const warnLogs = [];
log.warn = (args) => {
warnLogs.push(args);
};
fixture.innerHTML += '<div id="test_vid_id"></div>';
const player = videojs('test_vid_id', { techOrder: ['techFaker'] });
assert.ok(player, 'created player from tag');
assert.equal(player.id(), 'test_vid_id', 'player has the right ID');
assert.equal(warnLogs.length, 0, 'no warn logs');
const playerAgain = videojs('test_vid_id');
assert.equal(player, playerAgain, 'did not create a second player from same tag');
assert.equal(warnLogs.length, 0, 'no warn logs');
const playerAgainWithOptions = videojs('test_vid_id', { techOrder: ['techFaker'] });
assert.equal(player,
playerAgainWithOptions,
'did not create a second player from same tag');
assert.equal(warnLogs.length, 1, 'logged a warning');
assert.equal(warnLogs[0],
'Player "test_vid_id" is already initialised. Options will not be applied.',
'logged the right message');
log.warn = origWarnLog;
player.dispose();
});
QUnit.test('should return a video player instance from el html5 tech', function(assert) {
const fixture = document.getElementById('qunit-fixture');
fixture.innerHTML += '<div id="test_vid_id"></div>' +
'<div id="test_vid_id2"></div>';
const vid = document.querySelector('#test_vid_id');
const player = videojs(vid);
assert.ok(player, 'created player from tag');
assert.ok(player.id() === 'test_vid_id');
assert.ok(videojs.getPlayers().test_vid_id === player,
'added player to global reference');
const playerAgain = videojs(vid);
assert.ok(player === playerAgain, 'did not create a second player from same tag');
assert.equal(player, playerAgain, 'we did not make a new player');
const tag2 = document.getElementById('test_vid_id2');
const player2 = videojs(tag2, { techOrder: ['techFaker'] });
assert.ok(player2.id() === 'test_vid_id2', 'created player from element');
player.dispose();
player2.dispose();
});
QUnit.test('should return a video player instance from el techfaker', function(assert) {
const fixture = document.getElementById('qunit-fixture');
fixture.innerHTML += '<div id="test_vid_id"></div>' +
'<div id="test_vid_id2"></div>';
const vid = document.querySelector('#test_vid_id');
const player = videojs(vid, {techOrder: ['techFaker']});
assert.ok(player, 'created player from tag');
assert.ok(player.id() === 'test_vid_id');
assert.ok(videojs.getPlayers().test_vid_id === player,
'added player to global reference');
const playerAgain = videojs(vid);
assert.ok(player === playerAgain, 'did not create a second player from same tag');
assert.equal(player, playerAgain, 'we did not make a new player');
const tag2 = document.getElementById('test_vid_id2');
const player2 = videojs(tag2, { techOrder: ['techFaker'] });
assert.ok(player2.id() === 'test_vid_id2', 'created player from element');
player.dispose();
player2.dispose();
});
+3 -22
Ver Arquivo
@@ -1,7 +1,6 @@
/* eslint-env qunit */
import videojs from '../../src/js/video.js';
import document from 'global/document';
import sinon from 'sinon';
import log from '../../src/js/utils/log.js';
QUnit.module('video.js:hooks ', {
@@ -24,7 +23,9 @@ QUnit.test('should be able to add a hook', function(assert) {
assert.equal(videojs.hooks_.bar.length, 2, 'should have 2 bar hooks');
assert.equal(videojs.hooks_.foo.length, 1, 'should have 1 foo hook');
videojs.hook('foo', [function() {}, function() {}, function() {}]);
videojs.hook('foo', function() {});
videojs.hook('foo', function() {});
videojs.hook('foo', function() {});
assert.equal(videojs.hooks_.foo.length, 4, 'should have 4 foo hooks');
assert.equal(videojs.hooks_.bar.length, 2, 'should have 2 bar hooks');
});
@@ -103,26 +104,6 @@ QUnit.test('should be get all hooks for a type and add at the same time', functi
assert.deepEqual(videojs.hooks_.bar, barHooks, 'should return the exact bar list from videojs.hooks_');
});
QUnit.test('should be able to add a hook that runs once', function(assert) {
const spies = [
sinon.spy(),
sinon.spy(),
sinon.spy()
];
videojs.hookOnce('foo', spies);
assert.equal(videojs.hooks_.foo.length, 3, 'should have 3 foo hooks');
videojs.hooks('foo').forEach(fn => fn());
spies.forEach((spy, i) => {
assert.ok(spy.calledOnce, `spy #${i + 1} was called`);
});
assert.equal(videojs.hooks_.foo.length, 0, 'should have 0 foo hooks');
});
QUnit.test('should trigger beforesetup and setup during videojs setup', function(assert) {
const vjsOptions = {techOrder: ['techFaker']};
let setupCalled = false;