Comparar commits
1 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 19ee5100ea |
@@ -34,14 +34,12 @@
|
||||
"notEqual",
|
||||
"notStrictEqual",
|
||||
"ok",
|
||||
"throws",
|
||||
"QUnit",
|
||||
"raises",
|
||||
"start",
|
||||
"stop",
|
||||
"strictEqual",
|
||||
"test",
|
||||
"throws",
|
||||
"sinon"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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" ]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
externo
+326
-866
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
externo
+8
-8
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
+1
-1
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
+12
-12
@@ -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.
externo
+2
-3
@@ -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; }
|
||||
|
||||
externo
+1
-1
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
BIN
Arquivo binário não exibido.
externo
+326
-866
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
externo
+21
-23
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
+8
-8
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
+1
-1
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+12
-12
@@ -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
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -548,5 +548,4 @@ Flash.getEmbedCode = function(swf, flashVars, params, attributes){
|
||||
FlashRtmpDecorator(Flash);
|
||||
|
||||
Component.registerComponent('Flash', Flash);
|
||||
Tech.registerTech('Flash', Flash);
|
||||
export default Flash;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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
@@ -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');
|
||||
});
|
||||
|
||||
@@ -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}`);
|
||||
});
|
||||
});
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário