Comparar commits

..

1 Commits

Autor SHA1 Mensagem Data
Gary Katsevman 19ee5100ea v5.1.0 dist 2015-11-02 11:27:43 -05:00
46 arquivos alterados com 1000 adições e 2958 exclusões
-2
Ver Arquivo
@@ -34,14 +34,12 @@
"notEqual",
"notStrictEqual",
"ok",
"throws",
"QUnit",
"raises",
"start",
"stop",
"strictEqual",
"test",
"throws",
"sinon"
]
}
-35
Ver Arquivo
@@ -6,41 +6,6 @@ _(none)_
--------------------
## 5.2.4 (2015-11-25)
* @gesinger checked for track changes before tech started listening ([view](https://github.com/videojs/video.js/pull/2835))
* @gesinger fixed handler explosion for cuechange events ([view](https://github.com/videojs/video.js/pull/2849))
* @mmcc fixed vertical volume ([view](https://github.com/videojs/video.js/pull/2859))
## 5.2.3 (2015-11-24)
* @gkatsev fixed clearing out errors ([view](https://github.com/videojs/video.js/pull/2850))
## 5.2.2 (2015-11-23)
* @DatTran fixed bower paths. Fixes #2740 ([view](https://github.com/videojs/video.js/pull/2775))
* @nbibler ensured classes begin with alpha characters. Fixes #2828 ([view](https://github.com/videojs/video.js/pull/2829))
* @bcvio fixed returning current source rather than blob url ([view](https://github.com/videojs/video.js/pull/2833))
* @tomaspinho added ended event to API docs ([view](https://github.com/videojs/video.js/pull/2836))
* @paladox updated xhr from deprecated ver to v2.2 ([view](https://github.com/videojs/video.js/pull/2837))
## 5.2.1 (2015-11-16)
* @dmlap Check a component is a function before new-ing ([view](https://github.com/videojs/video.js/pull/2814))
* @ksjun corrected the registerTech export ([view](https://github.com/videojs/video.js/pull/2816))
## 5.2.0 (2015-11-10)
* @gkatsev made initListeners more general and added Tech.isTech. Fixes #2767 ([view](https://github.com/videojs/video.js/pull/2773))
* @dmlap updated swf to 5.0.1 ([view](https://github.com/videojs/video.js/pull/2795))
* @gkatsev added a tech registry. Fixes #2772 ([view](https://github.com/videojs/video.js/pull/2782))
* @Lillemanden impoved logic for dividing RTMP paths ([view](https://github.com/videojs/video.js/pull/2787))
* @bdeitte added a test for improved RTMP path dividing logic ([view](https://github.com/videojs/video.js/pull/2794))
* @paladox updated grunt-cli dependency ([view](https://github.com/videojs/video.js/pull/2555))
* @paladox updated grunt-contrib-jshint ([view](https://github.com/videojs/video.js/pull/2554))
* @siebrand updated dutch translations ([view](https://github.com/videojs/video.js/pull/2556))
* @misteroneill exposed DOM helpers ([view](https://github.com/videojs/video.js/pull/2754))
* @incompl fixed broken link to reduced test cases article ([view](https://github.com/videojs/video.js/pull/2801))
* @zjruan updated text track prototype loops to blacklist constructor for IE8 ([view](https://github.com/videojs/video.js/pull/2565))
* @gkatsev fixed usage of textTracksToJson ([view](https://github.com/videojs/video.js/pull/2797))
* @gkatsev updated contrib.json to use / as branch-name separator in feature-accept ([view](https://github.com/videojs/video.js/pull/2803))
* @gkatsev updated MediaLoader to check for techs in their registry ([view](https://github.com/videojs/video.js/pull/2798))
## 5.1.0 (2015-11-02)
* @typcn bumped grunt-sass to ^1.0.0 to support node 4.x ([view](https://github.com/videojs/video.js/pull/2645))
* @gkatsev removed unhelpful isCrossOrigin test ([view](https://github.com/videojs/video.js/pull/2715))
+1 -1
Ver Arquivo
@@ -28,7 +28,7 @@ Guidelines for bug reports:
2. Check if the issue has already been fixed — try to reproduce it using the latest `master` branch in the repository.
3. Isolate the problem — **create a [reduced test case](https://css-tricks.com/reduced-test-cases/)** with a live example. You can possibly use [this JSBin example](http://jsbin.com/axedog/7/edit) as a starting point.
3. Isolate the problem — **create a [reduced test case](http://css-tricks.com/6263-reduced-test-cases/)** with a live example. You can possibly use [this JSBin example](http://jsbin.com/axedog/7/edit) as a starting point.
A good bug report should be as detailed as possible, so that others won't have to follow up for the essential details.
+2 -2
Ver Arquivo
@@ -2,8 +2,8 @@
"name": "video.js",
"description": "An HTML5 and Flash video player with a common API and skin for both.",
"main": [
"dist/video.js",
"dist/video-js.css"
"src/js/video.js",
"src/css/video-js.scss"
],
"moduleType": "es6",
"keywords": [
+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": "5.2.4",
"version": "5.1.0",
"keywords": [
"videojs",
"html5",
+3 -3
Ver Arquivo
@@ -398,7 +398,7 @@
{ "prompt": "text", "id": "prNum", "desc": "What is the the pull request number?" },
{ "get": "{{meta.urls.repo_api}}/pulls/{{prNum}}", "desc": "Get the PR information", "id": "pr" },
{ "get": "{{meta.urls.repo_api}}/pulls/{{prNum}}/commits", "desc": "Get the PR commits to access author info", "id": "prCommits" },
[ "git checkout -b {{pr.user.login}}/{{pr.head.ref}} {{pr.base.ref}}", "Create a new branch for merging the changes" ],
[ "git checkout -b {{pr.user.login}}-{{pr.head.ref}} {{pr.base.ref}}", "Create a new branch for merging the changes" ],
[ "git fetch {{pr.head.repo.ssh_url}} {{pr.head.ref}}", "Fetch the changes" ],
[ "git merge --no-commit --squash FETCH_HEAD", "Merge the changes in without committing so they can be squashed" ],
[ "grunt test", "Run tests to make sure they still pass" ],
@@ -408,10 +408,10 @@
[ "git commit -a --author='{{prCommits.[0].commit.author.name}} <{{prCommits.[0].commit.author.email}}>' -m '{{line}}. closes #{{prNum}}'", "Commit the changes" ],
{ "prompt": "confirm", "desc": "Does everything look ok?" },
[ "git checkout {{pr.base.ref}}", "Check out the base branch" ],
[ "git merge {{pr.user.login}}/{{pr.head.ref}}", "Merge the changes" ],
[ "git merge {{pr.user.login}}-{{pr.head.ref}}", "Merge the changes" ],
[ "git push origin {{pr.base.ref}}", "Push the changes to your remote copy of the project" ],
[ "git push upstream {{pr.base.ref}}", "Push the changes to the main project" ],
[ "git branch -D {{pr.user.login}}/{{pr.head.ref}}", "Delete the local branch used for merging" ]
[ "git branch -D {{pr.user.login}}-{{pr.head.ref}}", "Delete the local branch used for merging" ]
]
}
}
+326 -866
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+8 -8
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+12 -12
Ver Arquivo
@@ -1,26 +1,26 @@
videojs.addLanguage("nl",{
"Play": "Afspelen",
"Pause": "Pauze",
"Current Time": "Huidige tijd",
"Current Time": "Huidige Tijd",
"Duration Time": "Looptijd",
"Remaining Time": "Resterende tijd",
"Stream Type": "Streamtype",
"Remaining Time": "Resterende Tijd",
"Stream Type": "Stream Type",
"LIVE": "LIVE",
"Loaded": "Geladen",
"Progress": "Status",
"Fullscreen": "Volledig scherm",
"Non-Fullscreen": "Geen volledig scherm",
"Mute": "Geluid uit",
"Unmuted": "Geluid aan",
"Playback Rate": "Weergavesnelheid",
"Mute": "Geluid Uit",
"Unmuted": "Geluid Aan",
"Playback Rate": "Weergave Rate",
"Subtitles": "Ondertiteling",
"subtitles off": "Ondertiteling uit",
"Captions": "Ondertiteling",
"captions off": "Ondertiteling uit",
"Captions": "Onderschriften",
"captions off": "Onderschriften uit",
"Chapters": "Hoofdstukken",
"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.",
"You aborted the media playback": "Je hebt de media weergave afgebroken.",
"A network error caused the media download to fail part-way.": "De media download 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, veroorzaakt door een server of netwerkfout of het formaat word niet ondersteund.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "De media weergave is afgebroken omdat deze beschadigd is of de media gebruikt functionaliteit die niet door je browser word ondersteund.",
"No compatible source was found for this media.": "Voor deze media is geen ondersteunde bron gevonden."
});
Arquivo binário não exibido.
+2 -3
Ver Arquivo
@@ -499,7 +499,7 @@ about what's required to play video. */
/* Same as ul background */ }
/* Button Pop-up Menu */
.vjs-menu-button-popup .vjs-menu .vjs-menu-content {
.vjs-menu-button-popup .vjs-menu ul {
background-color: #2B333F;
background-color: rgba(43, 51, 63, 0.7);
position: absolute;
@@ -911,8 +911,7 @@ width and height to zero. */
border-top-color: transparent; }
.vjs-menu-button-popup.vjs-volume-menu-button-vertical .vjs-menu {
left: 0.5em;
height: 8em; }
left: 0.5em; }
.vjs-menu-button-popup.vjs-volume-menu-button-horizontal .vjs-menu {
left: -2em; }
+1 -1
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
BIN
Ver Arquivo
Arquivo binário não exibido.
+326 -866
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+21 -23
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+8 -8
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+1 -1
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+12 -12
Ver Arquivo
@@ -1,26 +1,26 @@
{
"Play": "Afspelen",
"Pause": "Pauze",
"Current Time": "Huidige tijd",
"Current Time": "Huidige Tijd",
"Duration Time": "Looptijd",
"Remaining Time": "Resterende tijd",
"Stream Type": "Streamtype",
"Remaining Time": "Resterende Tijd",
"Stream Type": "Stream Type",
"LIVE": "LIVE",
"Loaded": "Geladen",
"Progress": "Status",
"Fullscreen": "Volledig scherm",
"Non-Fullscreen": "Geen volledig scherm",
"Mute": "Geluid uit",
"Unmuted": "Geluid aan",
"Playback Rate": "Weergavesnelheid",
"Mute": "Geluid Uit",
"Unmuted": "Geluid Aan",
"Playback Rate": "Weergave Rate",
"Subtitles": "Ondertiteling",
"subtitles off": "Ondertiteling uit",
"Captions": "Ondertiteling",
"captions off": "Ondertiteling uit",
"Captions": "Onderschriften",
"captions off": "Onderschriften uit",
"Chapters": "Hoofdstukken",
"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.",
"You aborted the media playback": "Je hebt de media weergave afgebroken.",
"A network error caused the media download to fail part-way.": "De media download 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, veroorzaakt door een server of netwerkfout of het formaat word niet ondersteund.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "De media weergave is afgebroken omdat deze beschadigd is of de media gebruikt functionaliteit die niet door je browser word ondersteund.",
"No compatible source was found for this media.": "Voor deze media is geen ondersteunde bron gevonden."
}
+5 -5
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": "5.2.4",
"version": "5.1.0",
"copyright": "Copyright Brightcove, Inc. <https://www.brightcove.com/>",
"license": "Apache-2.0",
"keywords": [
@@ -30,9 +30,9 @@
"tsml": "1.0.1",
"videojs-font": "1.4.0",
"videojs-ie8": "1.1.0",
"videojs-swf": "5.0.1",
"videojs-swf": "5.0.0-rc1",
"vtt.js": "git+https://github.com/gkatsev/vtt.js.git#vjs-v0.12.1",
"xhr": "~2.2.0"
"xhr": "2.1.0"
},
"devDependencies": {
"babel": "^5.2.2",
@@ -48,14 +48,14 @@
"grunt-aws-s3": "^0.12.1",
"grunt-banner": "^0.4.0",
"grunt-browserify": "3.5.1",
"grunt-cli": "~0.1.13",
"grunt-cli": "~0.1.0",
"grunt-concurrent": "^1.0.0",
"grunt-contrib-clean": "~0.4.0a",
"grunt-contrib-concat": "^0.5.1",
"grunt-contrib-connect": "~0.7.1",
"grunt-contrib-copy": "^0.8.0",
"grunt-contrib-cssmin": "~0.6.0",
"grunt-contrib-jshint": "~0.11.3",
"grunt-contrib-jshint": "^0.11.0",
"grunt-contrib-less": "~0.6.4",
"grunt-contrib-uglify": "^0.8.0",
"grunt-contrib-watch": "~0.1.4",
-1
Ver Arquivo
@@ -96,7 +96,6 @@ width and height to zero. */
.vjs-menu-button-popup.vjs-volume-menu-button-vertical .vjs-menu {
left: 0.5em;
height: 8em;
}
.vjs-menu-button-popup.vjs-volume-menu-button-horizontal .vjs-menu {
left: -2em;
+1 -1
Ver Arquivo
@@ -10,7 +10,7 @@
}
/* Button Pop-up Menu */
.vjs-menu-button-popup .vjs-menu .vjs-menu-content {
.vjs-menu-button-popup .vjs-menu ul {
@include background-color-with-alpha($primary-background-color, $primary-background-transparency);
position: absolute;
+22 -118
Ver Arquivo
@@ -369,18 +369,6 @@ class Component {
// If there's no .player_, this is a player
let ComponentClass = Component.getComponent(componentClassName);
if (!ComponentClass) {
throw new Error(`Component ${componentClassName} does not exist`);
}
// data stored directly on the videojs object may be
// misidentified as a component to retain
// backwards-compatibility with 4.x. check to make sure the
// component class can be instantiated.
if (typeof ComponentClass !== 'function') {
return null;
}
component = new ComponentClass(this.player_ || this, options);
// child is a component instance
@@ -505,10 +493,7 @@ class Component {
// `this` is `parent`
let parentOptions = this.options_;
let handleAdd = (child) => {
let name = child.name;
let opts = child.opts;
let handleAdd = (name, opts) => {
// Allow options for children to be set at the parent options
// e.g. videojs(id, { controlBar: false });
// instead of videojs(id, { children: { controlBar: false });
@@ -536,57 +521,33 @@ class Component {
// Add a direct reference to the child by name on the parent instance.
// If two of the same component are used, different names should be supplied
// for each
let newChild = this.addChild(name, opts);
if (newChild) {
this[name] = newChild;
}
this[name] = this.addChild(name, opts);
};
// Allow for an array of children details to passed in the options
let workingChildren;
let Tech = Component.getComponent('Tech');
if (Array.isArray(children)) {
workingChildren = children;
} else {
workingChildren = Object.keys(children);
}
for (let i = 0; i < children.length; i++) {
let child = children[i];
let name;
let opts;
workingChildren
// children that are in this.options_ but also in workingChildren would
// give us extra children we do not want. So, we want to filter them out.
.concat(Object.keys(this.options_)
.filter(function(child) {
return !workingChildren.some(function(wchild) {
if (typeof wchild === 'string') {
return child === wchild;
} else {
return child === wchild.name;
}
});
}))
.map((child) => {
let name, opts;
if (typeof child === 'string') {
// ['myComponent']
name = child;
opts = {};
} else {
// [{ name: 'myComponent', otherOption: true }]
name = child.name;
opts = child;
}
if (typeof child === 'string') {
name = child;
opts = children[name] || this.options_[name] || {};
} else {
name = child.name;
opts = child;
handleAdd(name, opts);
}
return {name, opts};
})
.filter((child) => {
// we have to make sure that child.name isn't in the techOrder since
// techs are registerd as Components but can't aren't compatible
// See https://github.com/videojs/video.js/issues/2772
let c = Component.getComponent(child.opts.componentClass ||
toTitleCase(child.name));
return c && !Tech.isTech(c);
})
.forEach(handleAdd);
} else {
Object.getOwnPropertyNames(children).forEach(function(name){
handleAdd(name, children[name]);
});
}
}
}
@@ -838,46 +799,6 @@ class Component {
}, 1);
}
/**
* Finds a single DOM element matching `selector` within the component's
* `contentEl` or another custom context.
*
* @method $
* @param {String} selector
* A valid CSS selector, which will be passed to `querySelector`.
*
* @param {Element|String} [context=document]
* A DOM element within which to query. Can also be a selector
* string in which case the first matching element will be used
* as context. If missing (or no element matches selector), falls
* back to `document`.
*
* @return {Element|null}
*/
$(selector, context) {
return Dom.$(selector, context || this.contentEl());
}
/**
* Finds a all DOM elements matching `selector` within the component's
* `contentEl` or another custom context.
*
* @method $$
* @param {String} selector
* A valid CSS selector, which will be passed to `querySelectorAll`.
*
* @param {Element|String} [context=document]
* A DOM element within which to query. Can also be a selector
* string in which case the first matching element will be used
* as context. If missing (or no element matches selector), falls
* back to `document`.
*
* @return {NodeList}
*/
$$(selector, context) {
return Dom.$$(selector, context || this.contentEl());
}
/**
* Check if a component's element has a CSS class name
*
@@ -902,7 +823,7 @@ class Component {
}
/**
* Remove a CSS class name from the component's element
* Remove and return a CSS class name from the component's element
*
* @param {String} classToRemove Classname to remove
* @return {Component}
@@ -913,23 +834,6 @@ class Component {
return this;
}
/**
* Add or remove a CSS class name from the component's element
*
* @param {String} classToToggle
* @param {Boolean|Function} [predicate]
* Can be a function that returns a Boolean. If `true`, the class
* will be added; if `false`, the class will be removed. If not
* given, the class will be added if not present and vice versa.
*
* @return {Component}
* @method toggleClass
*/
toggleClass(classToToggle, predicate) {
Dom.toggleElClass(this.el_, classToToggle, predicate);
return this;
}
/**
* Show the component element if hidden
*
+13 -48
Ver Arquivo
@@ -35,7 +35,6 @@ import TextTrackSettings from './tracks/text-track-settings.js';
import ModalDialog from './modal-dialog';
// Require html5 tech, at least for disposing the original video tag
import Tech from './tech/tech.js';
import Html5 from './tech/html5.js';
/**
@@ -281,8 +280,8 @@ class Player extends Component {
// of the player in a way that's still overrideable by CSS, just like the
// video element
this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions');
let defaultsStyleEl = Dom.$('.vjs-styles-defaults');
let head = Dom.$('head');
let defaultsStyleEl = document.querySelector('.vjs-styles-defaults');
let head = document.querySelector('head');
head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild);
// Pass in the width/height/aspectRatio options which will update the style el
@@ -415,7 +414,6 @@ class Player extends Component {
let width;
let height;
let aspectRatio;
let idClass;
// The aspect ratio is either used directly or to calculate width and height.
if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') {
@@ -452,12 +450,7 @@ class Player extends Component {
height = width * ratioMultiplier;
}
// Ensure the CSS class is valid by starting with an alpha character
if (/^[^a-zA-Z]/.test(this.id())) {
idClass = 'dimensions-'+this.id();
} else {
idClass = this.id()+'-dimensions';
}
let idClass = this.id()+'-dimensions';
// Ensure the right class is still on the player for the style element
this.addClass(idClass);
@@ -493,7 +486,7 @@ class Player extends Component {
// get rid of the HTML5 video tag as soon as we are using another tech
if (techName !== 'Html5' && this.tag) {
Tech.getTech('Html5').disposeMediaElement(this.tag);
Component.getComponent('Html5').disposeMediaElement(this.tag);
this.tag.player = null;
this.tag = null;
}
@@ -533,12 +526,7 @@ class Player extends Component {
}
// Initialize tech instance
let techComponent = Tech.getTech(techName);
// Support old behavior of techs being registered as components.
// Remove once that deprecated behavior is removed.
if (!techComponent) {
techComponent = Component.getComponent(techName);
}
let techComponent = Component.getComponent(techName);
this.tech_ = new techComponent(techOptions);
// player.triggerReady is always async, so don't need this to be async
@@ -603,7 +591,7 @@ class Player extends Component {
unloadTech_() {
// Save the current text tracks so that we can reuse the same text tracks with the next tech
this.textTracks_ = this.textTracks();
this.textTracksJson_ = textTrackConverter.textTracksToJson(this.tech_);
this.textTracksJson_ = textTrackConverter.textTracksToJson(this);
this.isReady_ = false;
@@ -1665,13 +1653,7 @@ class Player extends Component {
// Loop through each playback technology in the options order
for (let i = 0, j = this.options_.techOrder; i < j.length; i++) {
let techName = toTitleCase(j[i]);
let tech = Tech.getTech(techName);
// Support old behavior of techs being registered as components.
// Remove once that deprecated behavior is removed.
if (!tech) {
tech = Component.getComponent(techName);
}
let tech = Component.getComponent(techName);
// Check if the current tech is defined before continuing
if (!tech) {
@@ -1703,12 +1685,8 @@ class Player extends Component {
// Loop through each playback technology in the options order
for (var i=0,j=this.options_.techOrder;i<j.length;i++) {
let techName = toTitleCase(j[i]);
let tech = Tech.getTech(techName);
// Support old behavior of techs being registered as components.
// Remove once that deprecated behavior is removed.
if (!tech) {
tech = Component.getComponent(techName);
}
let tech = Component.getComponent(techName);
// Check if the current tech is defined before continuing
if (!tech) {
log.error(`The "${techName}" tech is undefined. Skipped browser support check for that tech.`);
@@ -1769,12 +1747,7 @@ class Player extends Component {
return this.techGet_('src');
}
let currentTech = Tech.getTech(this.techName_);
// Support old behavior of techs being registered as components.
// Remove once that deprecated behavior is removed.
if (!currentTech) {
currentTech = Component.getComponent(this.techName_);
}
let currentTech = Component.getComponent(this.techName_);
// case: Array of source objects to choose from and pick the best to play
if (Array.isArray(source)) {
@@ -2107,7 +2080,6 @@ class Player extends Component {
if (err === null) {
this.error_ = err;
this.removeClass('vjs-error');
this.errorDisplay.close();
return this;
}
@@ -2118,6 +2090,9 @@ class Player extends Component {
this.error_ = new MediaError(err);
}
// fire an error event on the player
this.trigger('error');
// add the vjs-error classname to the player
this.addClass('vjs-error');
@@ -2125,9 +2100,6 @@ class Player extends Component {
// ie8 just logs "[object object]" if you just log the error object
log.error(`(CODE:${this.error_.code} ${MediaError.errorTypes[this.error_.code]})`, this.error_.message, this.error_);
// fire an error event on the player
this.trigger('error');
return this;
}
@@ -2718,13 +2690,6 @@ Player.prototype.handleUserInactive_;
*/
Player.prototype.handleTimeUpdate_;
/**
* Fired when video playback ends
*
* @event ended
*/
Player.prototype.handleTechEnded_;
/**
* Fired when the volume changes
*
+1 -1
Ver Arquivo
@@ -22,7 +22,7 @@ function FlashRtmpDecorator(Flash) {
// Look for the normal URL separator we expect, '&'.
// If found, we split the URL into two pieces around the
// first '&'.
let connEnd = src.search(/&(?!\w+=)/);
let connEnd = src.indexOf('&');
let streamBegin;
if (connEnd !== -1) {
streamBegin = connEnd + 1;
-1
Ver Arquivo
@@ -548,5 +548,4 @@ Flash.getEmbedCode = function(swf, flashVars, params, attributes){
FlashRtmpDecorator(Flash);
Component.registerComponent('Flash', Flash);
Tech.registerTech('Flash', Flash);
export default Flash;
+2 -9
Ver Arquivo
@@ -492,13 +492,7 @@ class Html5 extends Tech {
* @return {Object}
* @method currentSrc
*/
currentSrc() {
if (this.currentSource_) {
return this.currentSource_.src;
} else {
return this.el_.currentSrc;
}
}
currentSrc() { return this.el_.currentSrc; }
/**
* Get poster
@@ -777,7 +771,7 @@ class Html5 extends Tech {
this.remoteTextTracks().removeTrack_(track);
tracks = this.$$('track');
tracks = this.el().querySelectorAll('track');
i = tracks.length;
while (i--) {
@@ -1093,5 +1087,4 @@ Html5.disposeMediaElement = function(el){
};
Component.registerComponent('Html5', Html5);
Tech.registerTech('Html5', Html5);
export default Html5;
+2 -8
Ver Arquivo
@@ -1,8 +1,7 @@
/**
* @file loader.js
*/
import Component from '../component.js';
import Tech from './tech.js';
import Component from '../component';
import window from 'global/window';
import toTitleCase from '../utils/to-title-case.js';
@@ -27,12 +26,7 @@ class MediaLoader extends Component {
if (!options.playerOptions['sources'] || options.playerOptions['sources'].length === 0) {
for (let i=0, j=options.playerOptions['techOrder']; i<j.length; i++) {
let techName = toTitleCase(j[i]);
let tech = Tech.getTech(techName);
// Support old behavior of techs being registered as components.
// Remove once that deprecated behavior is removed.
if (!techName) {
tech = Component.getComponent(techName);
}
let tech = Component.getComponent(techName);
// Check if the browser supports this technology
if (tech && tech.isSupported()) {
+4 -57
Ver Arquivo
@@ -321,8 +321,9 @@ class Tech extends Component {
window['WebVTT'] = true;
}
let updateDisplay = () => this.trigger('texttrackchange');
let textTracksChanges = () => {
let textTracksChanges = Fn.bind(this, function() {
let updateDisplay = () => this.trigger('texttrackchange');
updateDisplay();
for (let i = 0; i < tracks.length; i++) {
@@ -332,9 +333,8 @@ class Tech extends Component {
track.addEventListener('cuechange', updateDisplay);
}
}
};
});
textTracksChanges();
tracks.addEventListener('change', textTracksChanges);
this.on('dispose', function() {
@@ -437,58 +437,6 @@ class Tech extends Component {
return '';
}
/*
* Return whether the argument is a Tech or not.
* Can be passed either a Class like `Html5` or a instance like `player.tech_`
*
* @param {Object} component An item to check
* @return {Boolean} Whether it is a tech or not
*/
static isTech(component) {
return component.prototype instanceof Tech ||
component instanceof Tech ||
component === Tech;
}
/**
* Registers a Tech
*
* @param {String} name Name of the Tech to register
* @param {Object} tech The tech to register
* @static
* @method registerComponent
*/
static registerTech(name, tech) {
if (!Tech.techs_) {
Tech.techs_ = {};
}
if (!Tech.isTech(tech)) {
throw new Error(`Tech ${name} must be a Tech`);
}
Tech.techs_[name] = tech;
return tech;
}
/**
* Gets a component by name
*
* @param {String} name Name of the component to get
* @return {Component}
* @static
* @method getComponent
*/
static getTech(name) {
if (Tech.techs_ && Tech.techs_[name]) {
return Tech.techs_[name];
}
if (window && window.videojs && window.videojs[name]) {
log.warn(`The ${name} tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)`);
return window.videojs[name];
}
}
}
/*
@@ -689,5 +637,4 @@ Tech.withSourceHandlers = function(_Tech){
Component.registerComponent('Tech', Tech);
// Old name for Tech
Component.registerComponent('MediaTechController', Tech);
Tech.registerTech('Tech', Tech);
export default Tech;
+1 -3
Ver Arquivo
@@ -21,9 +21,7 @@ let TextTrackCueList = function(cues) {
list = document.createElement('custom');
for (let prop in TextTrackCueList.prototype) {
if (prop !== 'constructor') {
list[prop] = TextTrackCueList.prototype[prop];
}
list[prop] = TextTrackCueList.prototype[prop];
}
}
+1 -2
Ver Arquivo
@@ -44,8 +44,7 @@ let trackToJson_ = function(track) {
* @function textTracksToJson
*/
let textTracksToJson = function(tech) {
let trackEls = tech.$$('track');
let trackEls = tech.el().querySelectorAll('track');
let trackObjs = Array.prototype.map.call(trackEls, (t) => t.track);
let tracks = Array.prototype.map.call(trackEls, function(trackEl) {
+1 -3
Ver Arquivo
@@ -26,9 +26,7 @@ let TextTrackList = function(tracks) {
list = document.createElement('custom');
for (let prop in TextTrackList.prototype) {
if (prop !== 'constructor') {
list[prop] = TextTrackList.prototype[prop];
}
list[prop] = TextTrackList.prototype[prop];
}
}
+50 -46
Ver Arquivo
@@ -27,33 +27,33 @@ class TextTrackSettings extends Component {
this.options_.persistTextTrackSettings = this.options_.playerOptions.persistTextTrackSettings;
}
Events.on(this.$('.vjs-done-button'), 'click', Fn.bind(this, function() {
Events.on(this.el().querySelector('.vjs-done-button'), 'click', Fn.bind(this, function() {
this.saveSettings();
this.hide();
}));
Events.on(this.$('.vjs-default-button'), 'click', Fn.bind(this, function() {
this.$('.vjs-fg-color > select').selectedIndex = 0;
this.$('.vjs-bg-color > select').selectedIndex = 0;
this.$('.window-color > select').selectedIndex = 0;
this.$('.vjs-text-opacity > select').selectedIndex = 0;
this.$('.vjs-bg-opacity > select').selectedIndex = 0;
this.$('.vjs-window-opacity > select').selectedIndex = 0;
this.$('.vjs-edge-style select').selectedIndex = 0;
this.$('.vjs-font-family select').selectedIndex = 0;
this.$('.vjs-font-percent select').selectedIndex = 2;
Events.on(this.el().querySelector('.vjs-default-button'), 'click', Fn.bind(this, function() {
this.el().querySelector('.vjs-fg-color > select').selectedIndex = 0;
this.el().querySelector('.vjs-bg-color > select').selectedIndex = 0;
this.el().querySelector('.window-color > select').selectedIndex = 0;
this.el().querySelector('.vjs-text-opacity > select').selectedIndex = 0;
this.el().querySelector('.vjs-bg-opacity > select').selectedIndex = 0;
this.el().querySelector('.vjs-window-opacity > select').selectedIndex = 0;
this.el().querySelector('.vjs-edge-style select').selectedIndex = 0;
this.el().querySelector('.vjs-font-family select').selectedIndex = 0;
this.el().querySelector('.vjs-font-percent select').selectedIndex = 2;
this.updateDisplay();
}));
Events.on(this.$('.vjs-fg-color > select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.$('.vjs-bg-color > select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.$('.window-color > select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.$('.vjs-text-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.$('.vjs-bg-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.$('.vjs-window-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.$('.vjs-font-percent select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.$('.vjs-edge-style select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.$('.vjs-font-family select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.el().querySelector('.vjs-fg-color > select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.el().querySelector('.vjs-bg-color > select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.el().querySelector('.window-color > select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.el().querySelector('.vjs-text-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.el().querySelector('.vjs-bg-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.el().querySelector('.vjs-window-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.el().querySelector('.vjs-font-percent select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.el().querySelector('.vjs-edge-style select'), 'change', Fn.bind(this, this.updateDisplay));
Events.on(this.el().querySelector('.vjs-font-family select'), 'change', Fn.bind(this, this.updateDisplay));
if (this.options_.persistTextTrackSettings) {
this.restoreSettings();
@@ -74,7 +74,7 @@ class TextTrackSettings extends Component {
}
/**
* Get texttrack settings
* Get texttrack settings
* Settings are
* .vjs-edge-style
* .vjs-font-family
@@ -83,21 +83,23 @@ class TextTrackSettings extends Component {
* .vjs-bg-color
* .vjs-bg-opacity
* .window-color
* .vjs-window-opacity
* .vjs-window-opacity
*
* @return {Object}
* @return {Object}
* @method getValues
*/
getValues() {
const textEdge = getSelectedOptionValue(this.$('.vjs-edge-style select'));
const fontFamily = getSelectedOptionValue(this.$('.vjs-font-family select'));
const fgColor = getSelectedOptionValue(this.$('.vjs-fg-color > select'));
const textOpacity = getSelectedOptionValue(this.$('.vjs-text-opacity > select'));
const bgColor = getSelectedOptionValue(this.$('.vjs-bg-color > select'));
const bgOpacity = getSelectedOptionValue(this.$('.vjs-bg-opacity > select'));
const windowColor = getSelectedOptionValue(this.$('.window-color > select'));
const windowOpacity = getSelectedOptionValue(this.$('.vjs-window-opacity > select'));
const fontPercent = window['parseFloat'](getSelectedOptionValue(this.$('.vjs-font-percent > select')));
const el = this.el();
const textEdge = getSelectedOptionValue(el.querySelector('.vjs-edge-style select'));
const fontFamily = getSelectedOptionValue(el.querySelector('.vjs-font-family select'));
const fgColor = getSelectedOptionValue(el.querySelector('.vjs-fg-color > select'));
const textOpacity = getSelectedOptionValue(el.querySelector('.vjs-text-opacity > select'));
const bgColor = getSelectedOptionValue(el.querySelector('.vjs-bg-color > select'));
const bgOpacity = getSelectedOptionValue(el.querySelector('.vjs-bg-opacity > select'));
const windowColor = getSelectedOptionValue(el.querySelector('.window-color > select'));
const windowOpacity = getSelectedOptionValue(el.querySelector('.vjs-window-opacity > select'));
const fontPercent = window['parseFloat'](getSelectedOptionValue(el.querySelector('.vjs-font-percent > select')));
let result = {
'backgroundOpacity': bgOpacity,
@@ -119,7 +121,7 @@ class TextTrackSettings extends Component {
}
/**
* Set texttrack settings
* Set texttrack settings
* Settings are
* .vjs-edge-style
* .vjs-font-family
@@ -128,20 +130,22 @@ class TextTrackSettings extends Component {
* .vjs-bg-color
* .vjs-bg-opacity
* .window-color
* .vjs-window-opacity
* .vjs-window-opacity
*
* @param {Object} values Object with texttrack setting values
* @method setValues
*/
setValues(values) {
setSelectedOption(this.$('.vjs-edge-style select'), values.edgeStyle);
setSelectedOption(this.$('.vjs-font-family select'), values.fontFamily);
setSelectedOption(this.$('.vjs-fg-color > select'), values.color);
setSelectedOption(this.$('.vjs-text-opacity > select'), values.textOpacity);
setSelectedOption(this.$('.vjs-bg-color > select'), values.backgroundColor);
setSelectedOption(this.$('.vjs-bg-opacity > select'), values.backgroundOpacity);
setSelectedOption(this.$('.window-color > select'), values.windowColor);
setSelectedOption(this.$('.vjs-window-opacity > select'), values.windowOpacity);
const el = this.el();
setSelectedOption(el.querySelector('.vjs-edge-style select'), values.edgeStyle);
setSelectedOption(el.querySelector('.vjs-font-family select'), values.fontFamily);
setSelectedOption(el.querySelector('.vjs-fg-color > select'), values.color);
setSelectedOption(el.querySelector('.vjs-text-opacity > select'), values.textOpacity);
setSelectedOption(el.querySelector('.vjs-bg-color > select'), values.backgroundColor);
setSelectedOption(el.querySelector('.vjs-bg-opacity > select'), values.backgroundOpacity);
setSelectedOption(el.querySelector('.window-color > select'), values.windowColor);
setSelectedOption(el.querySelector('.vjs-window-opacity > select'), values.windowOpacity);
let fontPercent = values.fontPercent;
@@ -149,11 +153,11 @@ class TextTrackSettings extends Component {
fontPercent = fontPercent.toFixed(2);
}
setSelectedOption(this.$('.vjs-font-percent > select'), fontPercent);
setSelectedOption(el.querySelector('.vjs-font-percent > select'), fontPercent);
}
/**
* Restore texttrack settings
* Restore texttrack settings
*
* @method restoreSettings
*/
@@ -170,7 +174,7 @@ class TextTrackSettings extends Component {
}
/**
* Save texttrack settings to local storage
* Save texttrack settings to local storage
*
* @method saveSettings
*/
@@ -190,7 +194,7 @@ class TextTrackSettings extends Component {
}
/**
* Update display of texttrack settings
* Update display of texttrack settings
*
* @method updateDisplay
*/
+35 -186
Ver Arquivo
@@ -7,59 +7,6 @@ import * as Guid from './guid.js';
import log from './log.js';
import tsml from 'tsml';
/**
* Detect if a value is a string with any non-whitespace characters.
*
* @param {String} str
* @return {Boolean}
*/
function isNonBlankString(str) {
return typeof str === 'string' && /\S/.test(str);
}
/**
* Throws an error if the passed string has whitespace. This is used by
* class methods to be relatively consistent with the classList API.
*
* @param {String} str
* @return {Boolean}
*/
function throwIfWhitespace(str) {
if (/\s/.test(str)) {
throw new Error('class has illegal whitespace characters');
}
}
/**
* Produce a regular expression for matching a class name.
*
* @param {String} className
* @return {RegExp}
*/
function classRegExp(className) {
return new RegExp('(^|\\s)' + className + '($|\\s)');
}
/**
* Creates functions to query the DOM using a given method.
*
* @function createQuerier
* @private
* @param {String} method
* @return {Function}
*/
function createQuerier(method) {
return function (selector, context) {
if (!isNonBlankString(selector)) {
return document[method](null);
}
if (isNonBlankString(context)) {
context = document.querySelector(context);
}
return (isEl(context) ? context : document)[method](selector);
};
}
/**
* Shorthand for document.getElementById()
* Also allows for CSS (jQuery) ID syntax. But nothing other than IDs.
@@ -234,99 +181,47 @@ export function removeElData(el) {
/**
* Check if an element has a CSS class
*
* @function hasElClass
* @param {Element} element Element to check
* @param {String} classToCheck Classname to check
* @function hasElClass
*/
export function hasElClass(element, classToCheck) {
if (element.classList) {
return element.classList.contains(classToCheck);
} else {
throwIfWhitespace(classToCheck);
return classRegExp(classToCheck).test(element.className);
}
return ((' ' + element.className + ' ').indexOf(' ' + classToCheck + ' ') !== -1);
}
/**
* Add a CSS class name to an element
*
* @function addElClass
* @param {Element} element Element to add class name to
* @param {String} classToAdd Classname to add
* @function addElClass
*/
export function addElClass(element, classToAdd) {
if (element.classList) {
element.classList.add(classToAdd);
// Don't need to `throwIfWhitespace` here because `hasElClass` will do it
// in the case of classList not being supported.
} else if (!hasElClass(element, classToAdd)) {
element.className = (element.className + ' ' + classToAdd).trim();
if (!hasElClass(element, classToAdd)) {
element.className = element.className === '' ? classToAdd : element.className + ' ' + classToAdd;
}
return element;
}
/**
* Remove a CSS class name from an element
*
* @function removeElClass
* @param {Element} element Element to remove from class name
* @param {String} classToRemove Classname to remove
* @function removeElClass
*/
export function removeElClass(element, classToRemove) {
if (element.classList) {
element.classList.remove(classToRemove);
} else {
throwIfWhitespace(classToRemove);
element.className = element.className.split(/\s+/).filter(function(c) {
return c !== classToRemove;
}).join(' ');
if (!hasElClass(element, classToRemove)) {return;}
let classNames = element.className.split(' ');
// no arr.indexOf in ie8, and we don't want to add a big shim
for (let i = classNames.length - 1; i >= 0; i--) {
if (classNames[i] === classToRemove) {
classNames.splice(i,1);
}
}
return element;
}
/**
* Adds or removes a CSS class name on an element depending on an optional
* condition or the presence/absence of the class name.
*
* @function toggleElClass
* @param {Element} element
* @param {String} classToToggle
* @param {Boolean|Function} [predicate]
* Can be a function that returns a Boolean. If `true`, the class
* will be added; if `false`, the class will be removed. If not
* given, the class will be added if not present and vice versa.
*/
export function toggleElClass(element, classToToggle, predicate) {
// This CANNOT use `classList` internally because IE does not support the
// second parameter to the `classList.toggle()` method! Which is fine because
// `classList` will be used by the add/remove functions.
let has = hasElClass(element, classToToggle);
if (typeof predicate === 'function') {
predicate = predicate(element, classToToggle);
}
if (typeof predicate !== 'boolean') {
predicate = !has;
}
// If the necessary class operation matches the current state of the
// element, no action is required.
if (predicate === has) {
return;
}
if (predicate) {
addElClass(element, classToToggle);
} else {
removeElClass(element, classToToggle);
}
return element;
element.className = classNames.join(' ');
}
/**
@@ -397,7 +292,7 @@ export function getElAttributes(tag) {
* Attempt to block the ability to select text while dragging controls
*
* @return {Boolean}
* @function blockTextSelection
* @method blockTextSelection
*/
export function blockTextSelection() {
document.body.focus();
@@ -410,7 +305,7 @@ export function blockTextSelection() {
* Turn off text selection blocking
*
* @return {Boolean}
* @function unblockTextSelection
* @method unblockTextSelection
*/
export function unblockTextSelection() {
document.onselectstart = function() {
@@ -423,9 +318,9 @@ export function unblockTextSelection() {
* getBoundingClientRect technique from
* John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/
*
* @function findElPosition
* @param {Element} el Element from which to get offset
* @return {Object}
* @return {Object=}
* @method findElPosition
*/
export function findElPosition(el) {
let box;
@@ -464,10 +359,10 @@ export function findElPosition(el) {
* Returns an object with x and y coordinates.
* The base on the coordinates are the bottom left of the element.
*
* @function getPointerPosition
* @param {Element} el Element on which to get the pointer position on
* @param {Event} event Event object
* @return {Object} This object will have x and y coordinates corresponding to the mouse position
* @return {Object=} position This object will have x and y coordinates corresponding to the mouse position
* @metho getPointerPosition
*/
export function getPointerPosition(el, event) {
let position = {};
@@ -494,9 +389,8 @@ export function getPointerPosition(el, event) {
/**
* Determines, via duck typing, whether or not a value is a DOM element.
*
* @function isEl
* @param {Mixed} value
* @return {Boolean}
* @param {Mixed} value
* @return {Boolean}
*/
export function isEl(value) {
return !!value && typeof value === 'object' && value.nodeType === 1;
@@ -533,25 +427,18 @@ export function emptyEl(el) {
* from falling into the trap of simply writing to `innerHTML`, which is
* an XSS concern.
*
* The content for an element can be passed in multiple types and
* combinations, whose behavior is as follows:
* The content for an element can be passed in multiple types, whose
* behavior is as follows:
*
* - String
* Normalized into a text node.
*
* - Element, TextNode
* Passed through.
*
* - Array
* A one-dimensional array of strings, elements, nodes, or functions (which
* return single strings, elements, or nodes).
*
* - Function
* If the sole argument, is expected to produce a string, element,
* node, or array.
* - String: Normalized into a text node.
* - Node: An Element or TextNode is passed through.
* - Array: A one-dimensional array of strings, nodes, or functions (which
* return single strings or nodes).
* - Function: If the sole argument, is expected to produce a string, node,
* or array.
*
* @function normalizeContent
* @param {String|Element|TextNode|Array|Function} content
* @param {String|Element|Array|Function} content
* @return {Array}
*/
export function normalizeContent(content) {
@@ -587,8 +474,7 @@ export function normalizeContent(content) {
*
* @function appendContent
* @param {Element} el
* @param {String|Element|TextNode|Array|Function} content
* See: `normalizeContent`
* @param {String|Element|Array|Function} content
* @return {Element}
*/
export function appendContent(el, content) {
@@ -602,46 +488,9 @@ export function appendContent(el, content) {
*
* @function insertContent
* @param {Element} el
* @param {String|Element|TextNode|Array|Function} content
* See: `normalizeContent`
* @param {String|Element|Array|Function} content
* @return {Element}
*/
export function insertContent(el, content) {
return appendContent(emptyEl(el), content);
}
/**
* Finds a single DOM element matching `selector` within the optional
* `context` of another DOM element (defaulting to `document`).
*
* @function $
* @param {String} selector
* A valid CSS selector, which will be passed to `querySelector`.
*
* @param {Element|String} [context=document]
* A DOM element within which to query. Can also be a selector
* string in which case the first matching element will be used
* as context. If missing (or no element matches selector), falls
* back to `document`.
*
* @return {Element|null}
*/
export const $ = createQuerier('querySelector');
/**
* Finds a all DOM elements matching `selector` within the optional
* `context` of another DOM element (defaulting to `document`).
*
* @function $$
* @param {String} selector
* A valid CSS selector, which will be passed to `querySelectorAll`.
*
* @param {Element|String} [context=document]
* A DOM element within which to query. Can also be a selector
* string in which case the first matching element will be used
* as context. If missing (or no element matches selector), falls
* back to `document`.
*
* @return {NodeList}
*/
export const $$ = createQuerier('querySelectorAll');
+19 -190
Ver Arquivo
@@ -26,7 +26,6 @@ import createDeprecationProxy from './utils/create-deprecation-proxy.js';
import xhr from 'xhr';
// Include the built-in techs
import Tech from './tech/tech.js';
import Html5 from './tech/html5.js';
import Flash from './tech/flash.js';
@@ -99,10 +98,10 @@ var videojs = function(id, options, ready){
};
// Add default styles
let style = Dom.$('.vjs-styles-defaults');
let style = document.querySelector('.vjs-styles-defaults');
if (!style) {
style = stylesheet.createStyleElement('vjs-styles-defaults');
let head = Dom.$('head');
let head = document.querySelector('head');
head.insertBefore(style, head.firstChild);
stylesheet.setTextContent(style, `
.video-js {
@@ -203,50 +202,7 @@ videojs.getComponent = Component.getComponent;
* @mixes videojs
* @method registerComponent
*/
videojs.registerComponent = (name, comp) => {
if (Tech.isTech(comp)) {
log.warn(`The ${name} tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)`);
}
Component.registerComponent.call(Component, name, comp);
};
/**
* Get a Tech class object by name
* ```js
* var Html5 = videojs.getTech('Html5');
* // Create a new instance of the component
* var html5 = new Html5(options);
* ```
*
* @return {Tech} Tech identified by name
* @mixes videojs
* @method getComponent
*/
videojs.getTech = Tech.getTech;
/**
* Register a Tech so it can referred to by name.
* This is used in the tech order for the player.
*
* ```js
* // get the Html5 Tech
* var Html5 = videojs.getTech('Html5');
* var MyTech = videojs.extend(Html5, {});
* // Register the new Tech
* VjsButton.registerTech('Tech', MyTech);
* var player = videojs('myplayer', {
* techOrder: ['myTech', 'html5']
* });
* ```
*
* @param {String} The class name of the tech
* @param {Tech} The tech class
* @return {Tech} The newly registered Tech
* @mixes videojs
* @method registerTech
*/
videojs.registerTech = Tech.registerTech;
videojs.registerComponent = Component.registerComponent;
/**
* A suite of browser and device tests
@@ -545,149 +501,22 @@ videojs.xhr = xhr;
*/
videojs.TextTrack = TextTrack;
/**
* Determines, via duck typing, whether or not a value is a DOM element.
*
* @method isEl
* @param {Mixed} value
* @return {Boolean}
*/
videojs.isEl = Dom.isEl;
/**
* Determines, via duck typing, whether or not a value is a text node.
*
* @method isTextNode
* @param {Mixed} value
* @return {Boolean}
*/
videojs.isTextNode = Dom.isTextNode;
/**
* Check if an element has a CSS class
*
* @method hasClass
* @param {Element} element Element to check
* @param {String} classToCheck Classname to check
*/
videojs.hasClass = Dom.hasElClass;
/**
* Add a CSS class name to an element
*
* @method addClass
* @param {Element} element Element to add class name to
* @param {String} classToAdd Classname to add
*/
videojs.addClass = Dom.addElClass;
/**
* Remove a CSS class name from an element
*
* @method removeClass
* @param {Element} element Element to remove from class name
* @param {String} classToRemove Classname to remove
*/
videojs.removeClass = Dom.removeElClass;
/**
* Adds or removes a CSS class name on an element depending on an optional
* condition or the presence/absence of the class name.
*
* @method toggleElClass
* @param {Element} element
* @param {String} classToToggle
* @param {Boolean|Function} [predicate]
* Can be a function that returns a Boolean. If `true`, the class
* will be added; if `false`, the class will be removed. If not
* given, the class will be added if not present and vice versa.
*/
videojs.toggleClass = Dom.toggleElClass;
/**
* Apply attributes to an HTML element.
*
* @method setAttributes
* @param {Element} el Target element.
* @param {Object=} attributes Element attributes to be applied.
*/
videojs.setAttributes = Dom.setElAttributes;
/**
* Get an element's attribute values, as defined on the HTML tag
* Attributes are not the same as properties. They're defined on the tag
* or with setAttribute (which shouldn't be used with HTML)
* This will return true or false for boolean attributes.
*
* @method getAttributes
* @param {Element} tag Element from which to get tag attributes
* @return {Object}
*/
videojs.getAttributes = Dom.getElAttributes;
/**
* Empties the contents of an element.
*
* @method emptyEl
* @param {Element} el
* @return {Element}
*/
videojs.emptyEl = Dom.emptyEl;
/**
* Normalizes and appends content to an element.
*
* The content for an element can be passed in multiple types and
* combinations, whose behavior is as follows:
*
* - String
* Normalized into a text node.
*
* - Element, TextNode
* Passed through.
*
* - Array
* A one-dimensional array of strings, elements, nodes, or functions (which
* return single strings, elements, or nodes).
*
* - Function
* If the sole argument, is expected to produce a string, element,
* node, or array.
*
* @method appendContent
* @param {Element} el
* @param {String|Element|TextNode|Array|Function} content
* @return {Element}
*/
videojs.appendContent = Dom.appendContent;
/**
* Normalizes and inserts content into an element; this is identical to
* `appendContent()`, except it empties the element first.
*
* The content for an element can be passed in multiple types and
* combinations, whose behavior is as follows:
*
* - String
* Normalized into a text node.
*
* - Element, TextNode
* Passed through.
*
* - Array
* A one-dimensional array of strings, elements, nodes, or functions (which
* return single strings, elements, or nodes).
*
* - Function
* If the sole argument, is expected to produce a string, element,
* node, or array.
*
* @method insertContent
* @param {Element} el
* @param {String|Element|TextNode|Array|Function} content
* @return {Element}
*/
videojs.insertContent = Dom.insertContent;
// REMOVING: We probably should add this to the migration plugin
// // Expose but deprecate the window[componentName] method for accessing components
// Object.getOwnPropertyNames(Component.components).forEach(function(name){
// let component = Component.components[name];
//
// // A deprecation warning as the constuctor
// module.exports[name] = function(player, options, ready){
// log.warn('Using videojs.'+name+' to access the '+name+' component has been deprecated. Please use videojs.getComponent("componentName")');
//
// return new Component(player, options, ready);
// };
//
// // Allow the prototype and class methods to be accessible still this way
// // Though anything that attempts to override class methods will no longer work
// assign(module.exports[name], component);
// });
/*
* Custom Universal Module Definition (UMD)
-54
Ver Arquivo
@@ -5,21 +5,6 @@ import * as browser from '../../src/js/utils/browser.js';
import document from 'global/document';
import TestHelpers from './test-helpers.js';
class TestComponent1 extends Component {}
class TestComponent2 extends Component {}
class TestComponent3 extends Component {}
class TestComponent4 extends Component {}
TestComponent1.prototype.options_ = {
children: [
'testComponent2',
'testComponent3'
]
};
Component.registerComponent('TestComponent1', TestComponent1);
Component.registerComponent('TestComponent2', TestComponent2);
Component.registerComponent('TestComponent3', TestComponent3);
Component.registerComponent('TestComponent4', TestComponent4);
q.module('Component', {
'setup': function() {
this.clock = sinon.useFakeTimers();
@@ -55,14 +40,6 @@ test('should add a child component', function(){
ok(comp.getChildById(child.id()) === child);
});
test('addChild should throw if the child does not exist', function() {
var comp = new Component(getFakePlayer());
throws(function() {
comp.addChild('non-existent-child');
}, new Error('Component Non-existent-child does not exist'), 'addChild threw');
});
test('should init child components from options', function(){
var comp = new Component(getFakePlayer(), {
children: {
@@ -134,16 +111,6 @@ test('should do a deep merge of child options', function(){
Component.prototype.options_ = null;
});
test('should init child components from component options', function(){
let testComp = new TestComponent1(TestHelpers.makePlayer(), {
testComponent2: false,
testComponent4: {}
});
ok(!testComp.childNameIndex_.testComponent2, 'we do not have testComponent2');
ok(testComp.childNameIndex_.testComponent4, 'we have a testComponent4');
});
test('should allows setting child options at the parent options level', function(){
var parent, options;
@@ -166,7 +133,6 @@ test('should allows setting child options at the parent options level', function
ok(false, 'Child with `false` option was initialized');
}
equal(parent.children()[0].options_['foo'], true, 'child options set when children array is used');
equal(parent.children().length, 1, 'we should only have one child');
// using children object
options = {
@@ -189,7 +155,6 @@ test('should allows setting child options at the parent options level', function
ok(false, 'Child with `false` option was initialized');
}
equal(parent.children()[0].options_['foo'], true, 'child options set when children object is used');
equal(parent.children().length, 1, 'we should only have one child');
});
test('should dispose of component and children', function(){
@@ -471,10 +436,6 @@ test('should add and remove a CSS class', function(){
ok(comp.el().className.indexOf('test-class') !== -1);
comp.removeClass('test-class');
ok(comp.el().className.indexOf('test-class') === -1);
comp.toggleClass('test-class');
ok(comp.el().className.indexOf('test-class') !== -1);
comp.toggleClass('test-class');
ok(comp.el().className.indexOf('test-class') === -1);
});
test('should show and hide an element', function(){
@@ -699,18 +660,3 @@ test('should provide interval methods that automatically get cleared on componen
ok(intervalsFired === 5, 'Interval was cleared when component was disposed');
});
test('$ and $$ functions', function() {
var comp = new Component(getFakePlayer());
var contentEl = document.createElement('div');
var children = [
document.createElement('div'),
document.createElement('div')
];
comp.contentEl_ = contentEl;
children.forEach(child => contentEl.appendChild(child));
strictEqual(comp.$('div'), children[0], '$ defaults to contentEl as scope');
strictEqual(comp.$$('div').length, children.length, '$$ defaults to contentEl as scope');
});
+70 -33
Ver Arquivo
@@ -17,6 +17,36 @@ q.module('Player', {
}
});
// Compiler doesn't like using 'this' in setup/teardown.
// module("Player", {
// /**
// * @this {*}
// */
// setup: function(){
// window.player1 = true; // using window works
// },
// /**
// * @this {*}
// */
// teardown: function(){
// // if (this.player && this.player.el() !== null) {
// // this.player.dispose();
// // this.player = null;
// // }
// }
// });
// Object.size = function(obj) {
// var size = 0, key;
// for (key in obj) {
// console.log('key', key)
// if (obj.hasOwnProperty(key)) size++;
// }
// return size;
// };
test('should create player instance that inherits from component and dispose it', function(){
var player = TestHelpers.makePlayer();
@@ -169,21 +199,6 @@ test('should set the width, height, and aspect ratio via a css class', function(
ok(confirmSetting('padding-top', '25%'), 'aspect ratio percent should match the newly set aspect ratio');
});
test('should use an class name that begins with an alpha character', function(){
let alphaPlayer = TestHelpers.makePlayer({ id: 'alpha1' });
let numericPlayer = TestHelpers.makePlayer({ id: '1numeric' });
let getStyleText = function(styleEl){
return (styleEl.styleSheet && styleEl.styleSheet.cssText) || styleEl.innerHTML;
};
alphaPlayer.width(100);
numericPlayer.width(100);
ok(/\s*\.alpha1-dimensions\s*\{/.test(getStyleText(alphaPlayer.styleEl_)), 'appends -dimensions to an alpha player ID');
ok(/\s*\.dimensions-1numeric\s*\{/.test(getStyleText(numericPlayer.styleEl_)), 'prepends dimensions- to a numeric player ID');
});
test('should wrap the original tag in the player div', function(){
var tag = TestHelpers.makeTag();
var container = document.createElement('div');
@@ -309,6 +324,24 @@ test('should set controls and trigger events', function() {
player.dispose();
});
// Can't figure out how to test fullscreen events with tests
// Browsers aren't triggering the events at least
// asyncTest('should trigger the fullscreenchange event', function() {
// expect(3);
// var player = TestHelpers.makePlayer();
// player.on('fullscreenchange', function(){
// ok(true, 'fullscreenchange event fired');
// ok(this.isFullscreen() === true, 'isFullscreen is true');
// ok(this.el().className.indexOf('vjs-fullscreen') !== -1, 'vjs-fullscreen class added');
// player.dispose();
// start();
// });
// player.requestFullscreen();
// });
test('should toggle user the user state between active and inactive', function(){
var player = TestHelpers.makePlayer({});
@@ -408,6 +441,28 @@ test('make sure that controls listeners do not get added too many times', functi
player.dispose();
});
// test('should use custom message when encountering an unsupported video type',
// function() {
// videojs.options['notSupportedMessage'] = 'Video no go <a href="">link</a>';
// var fixture = document.getElementById('qunit-fixture');
// var html =
// '<video id="example_1">' +
// '<source src="fake.foo" type="video/foo">' +
// '</video>';
// fixture.innerHTML += html;
// var tag = document.getElementById('example_1');
// var player = new Player(tag, { techOrder: ['techFaker'] });
// var incompatibilityMessage = player.el().getElementsByTagName('p')[0];
// // ie8 capitalizes tag names
// equal(incompatibilityMessage.innerHTML.toLowerCase(), 'video no go <a href="">link</a>');
// player.dispose();
// });
test('should register players with generated ids', function(){
var fixture, video, player, id;
fixture = document.getElementById('qunit-fixture');
@@ -804,21 +859,3 @@ test('createModal() options object', function() {
strictEqual(modal.options_.label, 'boo', 'modal options are set properly');
modal.close();
});
test('you can clear error in the error event', function() {
let player = TestHelpers.makePlayer();
sinon.stub(log, 'error');
player.error({code: 4});
ok(player.error(), 'we have an error');
player.error(null);
player.one('error', function() {
player.error(null);
});
player.error({code: 4});
ok(!player.error(), 'we no longer have an error');
log.error.restore();
});
-4
Ver Arquivo
@@ -22,10 +22,6 @@ test('test streamToParts', function() {
ok(parts.connection === 'http://myurl.com/');
ok(parts.stream === 'streaming&/is/fun');
parts = Flash.streamToParts('http://myurl.com/really?streaming=fun&really=fun');
ok(parts.connection === 'http://myurl.com/');
ok(parts.stream === 'really?streaming=fun&really=fun');
parts = Flash.streamToParts('http://myurl.com/streaming/is/fun');
ok(parts.connection === 'http://myurl.com/streaming/is/');
ok(parts.stream === 'fun');
-6
Ver Arquivo
@@ -249,12 +249,6 @@ if (Html5.supportsNativeTextTracks()) {
equal(adds[2][0], rems[2][0], 'removetrack event handler removed');
});
}
test('should always return currentSource_ if set', function(){
let currentSrc = Html5.prototype.currentSrc;
equal(currentSrc.call({el_: {currentSrc:'test1'}}), 'test1', 'sould return source from element if nothing else set');
equal(currentSrc.call({currentSource_:{src: 'test2'}}), 'test2', 'sould return source from currentSource_, if nothing else set');
equal(currentSrc.call({currentSource_:{src: 'test2'}, el_:{currentSrc:'test1'}}), 'test2', 'sould return source from source set, not from element');
});
test('should fire makeup events when a video tag is initialized late', function(){
let lateInit = Html5.prototype.handleLateInit_;
+2 -1
Ver Arquivo
@@ -2,6 +2,7 @@
// can run without HTML5 or Flash, of which PhantomJS supports neither.
import Tech from '../../../src/js/tech/tech.js';
import Component from '../../../src/js/component.js';
/**
* @constructor
@@ -53,5 +54,5 @@ class TechFaker extends Tech {
static canPlaySource(srcObj) { return srcObj.type !== 'video/unsupported-format'; }
}
Tech.registerTech('TechFaker', TechFaker);
Component.registerComponent('TechFaker', TechFaker);
export default TechFaker;
-17
Ver Arquivo
@@ -1,9 +1,6 @@
var noop = function() {}, clock, oldTextTracks;
import Tech from '../../../src/js/tech/tech.js';
import Html5 from '../../../src/js/tech/html5.js';
import Flash from '../../../src/js/tech/flash.js';
import Button from '../../../src/js/button.js';
import { createTimeRange } from '../../../src/js/utils/time-ranges.js';
import extendFn from '../../../src/js/extend.js';
import MediaError from '../../../src/js/media-error.js';
@@ -274,17 +271,3 @@ test('delegates seekable to the source handler', function(){
tech.seekable();
equal(seekableCount, 1, 'called the source handler');
});
test('Tech.isTech returns correct answers for techs and components', function() {
let isTech = Tech.isTech;
ok(isTech(Tech), 'Tech is a Tech');
ok(isTech(Html5), 'Html5 is a Tech');
ok(isTech(new Html5({}, {})), 'An html5 instance is a Tech');
ok(isTech(Flash), 'Flash is a Tech');
ok(!isTech(5), 'A number is not a Tech');
ok(!isTech('this is a tech'), 'A string is not a Tech');
ok(!isTech(Button), 'A Button is not a Tech');
ok(!isTech(new Button({}, {})), 'A Button instance is not a Tech');
ok(!isTech(isTech), 'A function is not a Tech');
});
@@ -57,10 +57,6 @@ if (Html5.supportsNativeTextTracks()) {
tt.addTrack_(emulatedTrack);
let tech = {
$$() {
return [nativeTrack];
},
el() {
return {
querySelectorAll() {
@@ -107,10 +103,6 @@ if (Html5.supportsNativeTextTracks()) {
let addRemotes = 0;
let tech = {
$$() {
return [nativeTrack];
},
el() {
return {
querySelectorAll() {
@@ -175,10 +167,6 @@ q.test('textTracksToJson produces good json output for emulated only', function(
tt.addTrack_(emulatedTrack);
let tech = {
$$() {
return [];
},
el() {
return {
querySelectorAll() {
@@ -229,10 +217,6 @@ q.test('jsonToTextTracks calls addRemoteTextTrack on the tech with emulated trac
let addRemotes = 0;
let tech = {
$$() {
return [];
},
el() {
return {
querySelectorAll() {
+36 -36
Ver Arquivo
@@ -35,17 +35,17 @@ test('should update settings', function() {
player.textTrackSettings.setValues(newSettings);
deepEqual(player.textTrackSettings.getValues(), newSettings, 'values are updated');
equal(player.$('.vjs-fg-color > select').selectedIndex, 1, 'fg-color is set to new value');
equal(player.$('.vjs-bg-color > select').selectedIndex, 1, 'bg-color is set to new value');
equal(player.$('.window-color > select').selectedIndex, 1, 'window-color is set to new value');
equal(player.$('.vjs-text-opacity > select').selectedIndex, 1, 'text-opacity is set to new value');
equal(player.$('.vjs-bg-opacity > select').selectedIndex, 1, 'bg-opacity is set to new value');
equal(player.$('.vjs-window-opacity > select').selectedIndex, 1, 'window-opacity is set to new value');
equal(player.$('.vjs-edge-style select').selectedIndex, 1, 'edge-style is set to new value');
equal(player.$('.vjs-font-family select').selectedIndex, 1, 'font-family is set to new value');
equal(player.$('.vjs-font-percent select').selectedIndex, 3, 'font-percent is set to new value');
equal(player.el().querySelector('.vjs-fg-color > select').selectedIndex, 1, 'fg-color is set to new value');
equal(player.el().querySelector('.vjs-bg-color > select').selectedIndex, 1, 'bg-color is set to new value');
equal(player.el().querySelector('.window-color > select').selectedIndex, 1, 'window-color is set to new value');
equal(player.el().querySelector('.vjs-text-opacity > select').selectedIndex, 1, 'text-opacity is set to new value');
equal(player.el().querySelector('.vjs-bg-opacity > select').selectedIndex, 1, 'bg-opacity is set to new value');
equal(player.el().querySelector('.vjs-window-opacity > select').selectedIndex, 1, 'window-opacity is set to new value');
equal(player.el().querySelector('.vjs-edge-style select').selectedIndex, 1, 'edge-style is set to new value');
equal(player.el().querySelector('.vjs-font-family select').selectedIndex, 1, 'font-family is set to new value');
equal(player.el().querySelector('.vjs-font-percent select').selectedIndex, 3, 'font-percent is set to new value');
Events.trigger(player.$('.vjs-done-button'), 'click');
Events.trigger(player.el().querySelector('.vjs-done-button'), 'click');
deepEqual(safeParseTuple(window.localStorage.getItem('vjs-text-track-settings'))[1], newSettings, 'values are saved');
player.dispose();
@@ -57,32 +57,32 @@ test('should restore default settings', function() {
persistTextTrackSettings: true
});
player.$('.vjs-fg-color > select').selectedIndex = 1;
player.$('.vjs-bg-color > select').selectedIndex = 1;
player.$('.window-color > select').selectedIndex = 1;
player.$('.vjs-text-opacity > select').selectedIndex = 1;
player.$('.vjs-bg-opacity > select').selectedIndex = 1;
player.$('.vjs-window-opacity > select').selectedIndex = 1;
player.$('.vjs-edge-style select').selectedIndex = 1;
player.$('.vjs-font-family select').selectedIndex = 1;
player.$('.vjs-font-percent select').selectedIndex = 3;
player.el().querySelector('.vjs-fg-color > select').selectedIndex = 1;
player.el().querySelector('.vjs-bg-color > select').selectedIndex = 1;
player.el().querySelector('.window-color > select').selectedIndex = 1;
player.el().querySelector('.vjs-text-opacity > select').selectedIndex = 1;
player.el().querySelector('.vjs-bg-opacity > select').selectedIndex = 1;
player.el().querySelector('.vjs-window-opacity > select').selectedIndex = 1;
player.el().querySelector('.vjs-edge-style select').selectedIndex = 1;
player.el().querySelector('.vjs-font-family select').selectedIndex = 1;
player.el().querySelector('.vjs-font-percent select').selectedIndex = 3;
Events.trigger(player.$('.vjs-done-button'), 'click');
Events.trigger(player.$('.vjs-default-button'), 'click');
Events.trigger(player.$('.vjs-done-button'), 'click');
Events.trigger(player.el().querySelector('.vjs-done-button'), 'click');
Events.trigger(player.el().querySelector('.vjs-default-button'), 'click');
Events.trigger(player.el().querySelector('.vjs-done-button'), 'click');
deepEqual(player.textTrackSettings.getValues(), {}, 'values are defaulted');
deepEqual(window.localStorage.getItem('vjs-text-track-settings'), null, 'values are saved');
equal(player.$('.vjs-fg-color > select').selectedIndex, 0, 'fg-color is set to default value');
equal(player.$('.vjs-bg-color > select').selectedIndex, 0, 'bg-color is set to default value');
equal(player.$('.window-color > select').selectedIndex, 0, 'window-color is set to default value');
equal(player.$('.vjs-text-opacity > select').selectedIndex, 0, 'text-opacity is set to default value');
equal(player.$('.vjs-bg-opacity > select').selectedIndex, 0, 'bg-opacity is set to default value');
equal(player.$('.vjs-window-opacity > select').selectedIndex, 0, 'window-opacity is set to default value');
equal(player.$('.vjs-edge-style select').selectedIndex, 0, 'edge-style is set to default value');
equal(player.$('.vjs-font-family select').selectedIndex, 0, 'font-family is set to default value');
equal(player.$('.vjs-font-percent select').selectedIndex, 2, 'font-percent is set to default value');
equal(player.el().querySelector('.vjs-fg-color > select').selectedIndex, 0, 'fg-color is set to default value');
equal(player.el().querySelector('.vjs-bg-color > select').selectedIndex, 0, 'bg-color is set to default value');
equal(player.el().querySelector('.window-color > select').selectedIndex, 0, 'window-color is set to default value');
equal(player.el().querySelector('.vjs-text-opacity > select').selectedIndex, 0, 'text-opacity is set to default value');
equal(player.el().querySelector('.vjs-bg-opacity > select').selectedIndex, 0, 'bg-opacity is set to default value');
equal(player.el().querySelector('.vjs-window-opacity > select').selectedIndex, 0, 'window-opacity is set to default value');
equal(player.el().querySelector('.vjs-edge-style select').selectedIndex, 0, 'edge-style is set to default value');
equal(player.el().querySelector('.vjs-font-family select').selectedIndex, 0, 'font-family is set to default value');
equal(player.el().querySelector('.vjs-font-percent select').selectedIndex, 2, 'font-percent is set to default value');
player.dispose();
});
@@ -91,7 +91,7 @@ test('should open on click', function() {
var player = TestHelpers.makePlayer({
tracks: tracks
});
Events.trigger(player.$('.vjs-texttrack-settings'), 'click');
Events.trigger(player.el().querySelector('.vjs-texttrack-settings'), 'click');
ok(!player.textTrackSettings.hasClass('vjs-hidden'), 'settings open');
player.dispose();
@@ -101,8 +101,8 @@ test('should close on done click', function() {
var player = TestHelpers.makePlayer({
tracks: tracks
});
Events.trigger(player.$('.vjs-texttrack-settings'), 'click');
Events.trigger(player.$('.vjs-done-button'), 'click');
Events.trigger(player.el().querySelector('.vjs-texttrack-settings'), 'click');
Events.trigger(player.el().querySelector('.vjs-done-button'), 'click');
ok(player.textTrackSettings.hasClass('vjs-hidden'), 'settings closed');
player.dispose();
@@ -141,7 +141,7 @@ test('if persist option is set, save settings when "done"', function() {
save++;
};
Events.trigger(player.$('.vjs-done-button'), 'click');
Events.trigger(player.el().querySelector('.vjs-done-button'), 'click');
equal(save, 1, 'save was called');
@@ -171,7 +171,7 @@ test('do not try to restore or save settings if persist option is not set', func
equal(restore, 0, 'restore was not called');
Events.trigger(player.$('.vjs-done-button'), 'click');
Events.trigger(player.el().querySelector('.vjs-done-button'), 'click');
// saveSettings is called but does nothing
equal(save, 1, 'save was not called');
-56
Ver Arquivo
@@ -2,7 +2,6 @@ import ChaptersButton from '../../../src/js/control-bar/text-track-controls/chap
import SubtitlesButton from '../../../src/js/control-bar/text-track-controls/subtitles-button.js';
import CaptionsButton from '../../../src/js/control-bar/text-track-controls/captions-button.js';
import TextTrack from '../../../src/js/tracks/text-track.js';
import TextTrackDisplay from '../../../src/js/tracks/text-track-display.js';
import Html5 from '../../../src/js/tech/html5.js';
import Flash from '../../../src/js/tech/flash.js';
@@ -343,58 +342,3 @@ if (Html5.supportsNativeTextTracks()) {
emulatedTt.on('addtrack', addtrack);
});
}
test('should check for text track changes when emulating text tracks', function() {
let tech = new Tech();
let numTextTrackChanges = 0;
tech.on('texttrackchange', function() {
numTextTrackChanges++;
});
tech.emulateTextTracks();
equal(numTextTrackChanges, 1, 'we got a texttrackchange event');
});
test('removes cuechange event when text track is hidden for emulated tracks', function() {
let player = TestHelpers.makePlayer();
let tt = new TextTrack({
tech: player.tech_,
mode: 'showing'
});
tt.addCue({
id: '1',
startTime: 2,
endTime: 5
});
player.tech_.textTracks().addTrack_(tt);
player.tech_.emulateTextTracks();
let numTextTrackChanges = 0;
player.tech_.on('texttrackchange', function() {
numTextTrackChanges++;
});
tt.mode = 'showing';
equal(numTextTrackChanges, 1,
'texttrackchange should be called once for mode change');
tt.mode = 'showing';
equal(numTextTrackChanges, 2,
'texttrackchange should be called once for mode change');
player.tech_.currentTime = function() {
return 3;
};
player.tech_.trigger('timeupdate');
equal(numTextTrackChanges, 3,
'texttrackchange should be triggered once for the cuechange');
tt.mode = 'hidden';
equal(numTextTrackChanges, 4,
'texttrackchange should be called once for the mode change');
player.tech_.currentTime = function() {
return 7;
};
player.tech_.trigger('timeupdate');
equal(numTextTrackChanges, 4,
'texttrackchange should be not be called since mode is hidden');
});
+10 -184
Ver Arquivo
@@ -62,164 +62,23 @@ test('should get and remove data from an element', function(){
ok(!Dom.hasElData(el), 'cached item emptied');
});
test('addElClass()', function(){
test('should add and remove a class name on an element', function(){
var el = document.createElement('div');
expect(5);
Dom.addElClass(el, 'test-class');
strictEqual(el.className, 'test-class', 'adds a single class');
ok(el.className === 'test-class', 'class added');
Dom.addElClass(el, 'test-class');
strictEqual(el.className, 'test-class', 'does not duplicate classes');
throws(function(){
Dom.addElClass(el, 'foo foo-bar');
}, 'throws when attempting to add a class with whitespace');
Dom.addElClass(el, 'test2_className');
strictEqual(el.className, 'test-class test2_className', 'adds second class');
Dom.addElClass(el, 'FOO');
strictEqual(el.className, 'test-class test2_className FOO', 'adds third class');
});
test('removeElClass()', function() {
var el = document.createElement('div');
el.className = 'test-class foo foo test2_className FOO bar';
expect(5);
ok(el.className === 'test-class', 'same class not duplicated');
Dom.addElClass(el, 'test-class2');
ok(el.className === 'test-class test-class2', 'added second class');
Dom.removeElClass(el, 'test-class');
strictEqual(el.className, 'foo foo test2_className FOO bar', 'removes one class');
Dom.removeElClass(el, 'foo');
strictEqual(el.className, 'test2_className FOO bar', 'removes all instances of a class');
throws(function(){
Dom.removeElClass(el, 'test2_className bar');
}, 'throws when attempting to remove a class with whitespace');
Dom.removeElClass(el, 'test2_className');
strictEqual(el.className, 'FOO bar', 'removes another class');
Dom.removeElClass(el, 'FOO');
strictEqual(el.className, 'bar', 'removes another class');
ok(el.className === 'test-class2', 'removed first class');
});
test('hasElClass()', function(){
test('should read class names on an element', function(){
var el = document.createElement('div');
el.className = 'test-class foo foo test2_className FOO bar';
strictEqual(Dom.hasElClass(el, 'test-class'), true, 'class detected');
strictEqual(Dom.hasElClass(el, 'foo'), true, 'class detected');
strictEqual(Dom.hasElClass(el, 'test2_className'), true, 'class detected');
strictEqual(Dom.hasElClass(el, 'FOO'), true, 'class detected');
strictEqual(Dom.hasElClass(el, 'bar'), true, 'class detected');
strictEqual(Dom.hasElClass(el, 'test2'), false, 'valid substring - but not a class - correctly not detected');
strictEqual(Dom.hasElClass(el, 'className'), false, 'valid substring - but not a class - correctly not detected');
throws(function(){
Dom.hasElClass(el, 'FOO bar');
}, 'throws when attempting to detect a class with whitespace');
});
test('toggleElClass()', function() {
let el = Dom.createEl('div', {className: 'foo bar'});
let predicateToggles = [
{
toggle: 'foo',
predicate: true,
className: 'foo bar',
message: 'if predicate `true` matches state of the element, do nothing'
},
{
toggle: 'baz',
predicate: false,
className: 'foo bar',
message: 'if predicate `false` matches state of the element, do nothing'
},
{
toggle: 'baz',
predicate: true,
className: 'foo bar baz',
message: 'if predicate `true` differs from state of the element, add the class'
},
{
toggle: 'foo',
predicate: false,
className: 'bar baz',
message: 'if predicate `false` differs from state of the element, remove the class'
},
{
toggle: 'bar',
predicate: () => true,
className: 'bar baz',
message: 'if a predicate function returns `true`, matching the state of the element, do nothing'
},
{
toggle: 'foo',
predicate: () => false,
className: 'bar baz',
message: 'if a predicate function returns `false`, matching the state of the element, do nothing'
},
{
toggle: 'foo',
predicate: () => true,
className: 'bar baz foo',
message: 'if a predicate function returns `true`, differing from state of the element, add the class'
},
{
toggle: 'foo',
predicate: () => false,
className: 'bar baz',
message: 'if a predicate function returns `false`, differing from state of the element, remove the class'
},
{
toggle: 'foo',
predicate: Function.prototype,
className: 'bar baz foo',
message: 'if a predicate function returns `undefined` and the element does not have the class, add the class'
},
{
toggle: 'bar',
predicate: Function.prototype,
className: 'baz foo',
message: 'if a predicate function returns `undefined` and the element has the class, remove the class'
},
{
toggle: 'bar',
predicate: () => [],
className: 'baz foo bar',
message: 'if a predicate function returns a defined non-boolean value and the element does not have the class, add the class'
},
{
toggle: 'baz',
predicate: () => 'this is incorrect',
className: 'foo bar',
message: 'if a predicate function returns a defined non-boolean value and the element has the class, remove the class'
},
];
expect(3 + predicateToggles.length);
Dom.toggleElClass(el, 'bar');
strictEqual(el.className, 'foo', 'toggles a class off, if present');
Dom.toggleElClass(el, 'bar');
strictEqual(el.className, 'foo bar', 'toggles a class on, if absent');
throws(function(){
Dom.toggleElClass(el, 'foo bar');
}, 'throws when attempting to toggle a class with whitespace');
predicateToggles.forEach(x => {
Dom.toggleElClass(el, x.toggle, x.predicate);
strictEqual(el.className, x.className, x.message);
});
Dom.addElClass(el, 'test-class1');
ok(Dom.hasElClass(el, 'test-class1') === true, 'class detected');
ok(Dom.hasElClass(el, 'test-class') === false, 'substring correctly not detected');
});
test('should set element attributes from object', function(){
@@ -434,37 +293,4 @@ test('Dom.appendContent', function(assert) {
assert.strictEqual(el.firstChild.nextSibling, p2, 'the second paragraph was appended');
});
test('$() and $$()', function() {
let fixture = document.getElementById('qunit-fixture');
let container = document.createElement('div');
let children = [
document.createElement('div'),
document.createElement('div'),
document.createElement('div'),
];
children.forEach(child => container.appendChild(child));
fixture.appendChild(container);
let totalDivCount = document.getElementsByTagName('div').length;
expect(12);
strictEqual(Dom.$('#qunit-fixture'), fixture, 'can find an element in the document context');
strictEqual(Dom.$$('div').length, totalDivCount, 'finds elements in the document context');
strictEqual(Dom.$('div', container), children[0], 'can find an element in a DOM element context');
strictEqual(Dom.$$('div', container).length, children.length, 'finds elements in a DOM element context');
strictEqual(Dom.$('#qunit-fixture', document.querySelector('unknown')), fixture, 'falls back to document given a bad context element');
strictEqual(Dom.$$('div', document.querySelector('unknown')).length, totalDivCount, 'falls back to document given a bad context element');
strictEqual(Dom.$('#qunit-fixture', 'body'), fixture, 'can find an element in a selector context');
strictEqual(Dom.$$('div', '#qunit-fixture').length, 1 + children.length, 'finds elements in a selector context');
strictEqual(Dom.$('#qunit-fixture', 'unknown'), fixture, 'falls back to document given a bad context selector');
strictEqual(Dom.$$('div', 'unknown').length, totalDivCount, 'falls back to document given a bad context selector');
strictEqual(Dom.$('div', children[0]), null, 'returns null for missing elements');
strictEqual(Dom.$$('div', children[0]).length, 0, 'returns 0 for missing elements');
});
-27
Ver Arquivo
@@ -1,7 +1,6 @@
import videojs from '../../src/js/video.js';
import TestHelpers from './test-helpers.js';
import Player from '../../src/js/player.js';
import * as Dom from '../../src/js/utils/dom.js';
import log from '../../src/js/utils/log.js';
import document from 'global/document';
@@ -79,29 +78,3 @@ test('should expose options and players properties for backward-compatibility',
ok(typeof videojs.options, 'object', 'options should be an object');
ok(typeof videojs.players, 'object', 'players should be an object');
});
test('should expose DOM functions', function() {
// Keys are videojs methods, values are Dom methods.
let methods = {
isEl: 'isEl',
isTextNode: 'isTextNode',
hasClass: 'hasElClass',
addClass: 'addElClass',
removeClass: 'removeElClass',
toggleClass: 'toggleElClass',
setAttributes: 'setElAttributes',
getAttributes: 'getElAttributes',
emptyEl: 'emptyEl',
insertContent: 'insertContent',
appendContent: 'appendContent'
};
let keys = Object.keys(methods);
expect(keys.length);
keys.forEach(function(vjsName) {
let domName = methods[vjsName];
strictEqual(videojs[vjsName], Dom[domName], `videojs.${vjsName} is a reference to Dom.${domName}`);
});
});