1
0
mirror of https://github.com/videojs/video.js.git synced 2025-01-17 10:46:00 +02:00

Merge branch 'master' of git://github.com/zencoder/video-js

This commit is contained in:
Steve Heffernan 2013-03-09 15:45:09 -08:00
commit 8c6138797a
13 changed files with 212 additions and 25 deletions

6
.gitignore vendored
View File

@ -8,5 +8,11 @@ test/*.map
node_modules
npm-debug.log
sandbox/*
!sandbox/*.example
*.swp
*.swo
*.orig

View File

@ -45,10 +45,22 @@ body.vjs-full-window {
/* Poster Styles */
.vjs-poster {
margin: 0 auto; padding: 0; cursor: pointer;
/* Scale with the size of the player div. Works when poster is vertically shorter, but stretches when it's less wide. */
position: relative; width: 100%; max-height: 100%;
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: contain;
cursor: pointer;
height: 100%;
margin: 0;
padding: 0;
position: relative;
width: 100%;
}
.vjs-poster img {
display: block;
margin: 0 auto;
max-height: 100%;
padding: 0;
width: 100%;
}
/* Text Track Styles */
@ -330,7 +342,7 @@ so you can upgrade to newer versions easier. You can remove all these styles by
---------------------------------------------------------*/
.vjs-default-skin .vjs-big-play-button {
display: block; /* Start hidden */ z-index: 2;
position: absolute; top: 50%; left: 50%; width: 8.0em; height: 8.0em; margin: -42px 0 0 -42px; text-align: center; vertical-align: center; cursor: pointer !important;
position: absolute; top: 50%; left: 50%; width: 8.0em; height: 8.0em; margin: -42px 0 0 -42px; text-align: center; vertical-align: middle; cursor: pointer !important;
border: 0.2em solid #fff; opacity: 0.95;
-webkit-border-radius: 25px; -moz-border-radius: 25px; border-radius: 25px;

View File

@ -23,7 +23,7 @@ vjs.Component = function(player, options, ready){
this.name_ = options['name'] || null;
// Create element if one wasn't provided in potions
// Create element if one wasn't provided in options
this.el_ = options['el'] || this.createEl();
this.children_ = [];
@ -288,8 +288,8 @@ vjs.Component.prototype.addChild = function(child, options){
// Add the UI object's element to the container div (box)
// Having an element is not required
if (typeof component.el === 'function' && component.el()) {
this.el_.appendChild(component.el());
if (typeof component['el'] === 'function' && component['el']()) {
this.el_.appendChild(component['el']());
}
// Return so it can stored on parent object if desired.
@ -618,6 +618,8 @@ vjs.Component.prototype.dimension = function(widthOrHeight, num, skipListeners){
// Check if using css width/height (% or px) and adjust
if ((''+num).indexOf('%') !== -1 || (''+num).indexOf('px') !== -1) {
this.el_.style[widthOrHeight] = num;
} else if (num === 'auto') {
this.el_.style[widthOrHeight] = '';
} else {
this.el_.style[widthOrHeight] = num+'px';
}

49
src/js/controls.js vendored
View File

@ -786,6 +786,18 @@ vjs.SeekHandle.prototype.createEl = function(){
*/
vjs.VolumeControl = function(player, options){
goog.base(this, player, options);
// hide volume controls when they're not supported by the current tech
if (player.tech && player.tech.features.volumeControl === false) {
this.hide();
}
player.on('loadstart', vjs.bind(this, function(){
if (player.tech.features.volumeControl === false) {
this.hide();
} else {
this.show();
}
}));
};
goog.inherits(vjs.VolumeControl, vjs.Component);
@ -903,6 +915,18 @@ vjs.MuteToggle = function(player, options){
goog.base(this, player, options);
player.on('volumechange', vjs.bind(this, this.update));
// hide mute toggle if the current tech doesn't support volume control
if (player.tech && player.tech.features.volumeControl === false) {
this.hide();
}
player.on('loadstart', vjs.bind(this, function(){
if (player.tech.features.volumeControl === false) {
this.hide();
} else {
this.show();
}
}));
};
goog.inherits(vjs.MuteToggle, vjs.Button);
@ -969,17 +993,22 @@ vjs.PosterImage = function(player, options){
goog.inherits(vjs.PosterImage, vjs.Button);
vjs.PosterImage.prototype.createEl = function(){
var el = vjs.createEl('img', {
className: 'vjs-poster',
// Don't want poster to be tabbable.
tabIndex: -1
});
// src throws errors if no poster was defined.
if (this.player_.poster()) {
el.src = this.player_.poster();
var el = vjs.createEl('div', {
className: 'vjs-poster',
// Don't want poster to be tabbable.
tabIndex: -1
}),
poster = this.player_.poster();
if (poster) {
if ('backgroundSize' in el.style) {
el.style.backgroundImage = 'url("' + poster + '")';
} else {
el.appendChild(vjs.createEl('img', { src: poster }));
}
}
return el;
};

View File

@ -75,7 +75,6 @@ vjs.options = {
// Default of web browser is 300x150. Should rely on source width/height.
'width': 300,
'height': 150,
// defaultVolume: 0.85,
'defaultVolume': 0.00, // The freakin seaguls are driving me crazy!

View File

@ -269,8 +269,8 @@ vjs.USER_AGENT = navigator.userAgent;
* @type {Boolean}
* @constant
*/
vjs.IS_IPHONE = !!vjs.USER_AGENT.match(/iPad/i);
vjs.IS_IPAD = !!vjs.USER_AGENT.match(/iPhone/i);
vjs.IS_IPHONE = !!vjs.USER_AGENT.match(/iPhone/i);
vjs.IS_IPAD = !!vjs.USER_AGENT.match(/iPad/i);
vjs.IS_IPOD = !!vjs.USER_AGENT.match(/iPod/i);
vjs.IS_IOS = vjs.IS_IPHONE || vjs.IS_IPAD || vjs.IS_IPOD;

View File

@ -68,6 +68,9 @@ vjs.Html5.prototype.createEl = function(){
className:'vjs-tech'
});
}
// associate the player with the new tag
el['player'] = player;
vjs.insertFirst(el, player.el());
}
@ -204,6 +207,12 @@ vjs.Html5.canPlaySource = function(srcObj){
// Check Media Type
};
vjs.Html5.canControlVolume = function(){
var volume = vjs.TEST_VID.volume;
vjs.TEST_VID.volume = (volume / 2) + 0.1;
return volume !== vjs.TEST_VID.volume;
};
// List of all HTML5 events (various uses).
vjs.Html5.Events = 'loadstart,suspend,abort,error,emptied,stalled,loadedmetadata,loadeddata,canplay,canplaythrough,playing,waiting,seeking,seeked,ended,durationchange,timeupdate,progress,play,pause,ratechange,volumechange'.split(',');
@ -221,8 +230,10 @@ vjs.Html5.prototype.features = {
: false,
// In iOS, if you move a video element in the DOM, it breaks video playback.
movingMediaElementInDOM: !vjs.IS_IOS
movingMediaElementInDOM: !vjs.IS_IOS,
// volume cannot be changed from 1 on iOS
volumeControl: vjs.Html5.canControlVolume()
};
// Android

View File

@ -169,11 +169,11 @@ vjs.Player.prototype.createEl = function(){
// Default state of video is paused
this.addClass('vjs-paused');
// Make box use width/height of tag, or default 300x150
// Make box use width/height of tag, or rely on default implementation
// Enforce with CSS since width/height attrs don't work on divs
this.width(this.options_['width'], true); // (true) Skip resize listener on load
this.height(this.options_['height'], true);
// Wrap video tag in div (el/box) container
if (tag.parentNode) {
tag.parentNode.insertBefore(el, tag);
@ -220,7 +220,7 @@ vjs.Player.prototype.loadTech = function(techName, source){
};
// Grab tech-specific options from player options and add source and parent element to use.
var techOptions = vjs.obj.merge({ source: source, parentEl: this.el_ }, this.options_[techName.toLowerCase()]);
var techOptions = vjs.obj.merge({ 'source': source, 'parentEl': this.el_ }, this.options_[techName.toLowerCase()]);
if (source) {
if (source.src == this.cache_.src && this.cache_.currentTime > 0) {

View File

@ -26,6 +26,7 @@
'test/unit/player.js',
'test/unit/core.js',
'test/unit/media.html5.js',
'test/unit/controls.js',
'test/unit/plugins.js'
];
var compiledTests = "build/files/test.minified.video.js";

View File

@ -184,4 +184,9 @@ test('should change the width and height of a component', function(){
comp.width(321);
ok(comp.width() === 321, 'integer values working');
comp.width('auto');
comp.height('auto');
ok(comp.width() === 1000, 'forced width was removed');
ok(comp.height() === 0, 'forced height was removed');
});

78
test/unit/controls.js vendored Normal file
View File

@ -0,0 +1,78 @@
module('Controls');
test('should hide volume control if it\'s not supported', function() {
var noop, player, volumeControl, muteToggle;
noop = function(){};
player = {
id: noop,
on: noop,
ready: noop,
tech: {
features: {
volumeControl: false
}
}
};
volumeControl = new vjs.VolumeControl(player);
muteToggle = new vjs.MuteToggle(player);
equal(volumeControl.el().style.display, 'none', 'volumeControl is not hidden');
equal(muteToggle.el().style.display, 'none', 'muteToggle is not hidden');
});
test('should test and toggle volume control on `loadstart`', function(){
var noop, listeners, player, volumeControl, muteToggle;
noop = function(){};
listeners = [];
player = {
id: noop,
on: function(event, callback){
listeners.push(callback);
},
ready: noop,
volume: function(){
return 1;
},
muted: function(){
return false;
},
tech: {
features: {
volumeControl: true
}
}
};
volumeControl = new vjs.VolumeControl(player);
muteToggle = new vjs.MuteToggle(player);
equal(volumeControl.el().style.display,
'',
'volumeControl is hidden initially');
equal(muteToggle.el().style.display,
'',
'muteToggle is hidden initially');
player.tech.features.volumeControl = false;
listeners.forEach(function(listener) {
listener();
});
equal(volumeControl.el().style.display,
'none',
'volumeControl does not hide itself');
equal(muteToggle.el().style.display,
'none',
'muteToggle does not hide itself');
player.tech.features.volumeControl = true;
listeners.forEach(function(listener) {
listener();
});
equal(volumeControl.el().style.display,
'block',
'volumeControl does not show itself');
equal(muteToggle.el().style.display,
'block',
'muteToggle does not show itself');
});

View File

@ -1 +1,37 @@
module('HTML5');
test('should detect whether the volume can be changed', function(){
var testVid, ConstVolumeVideo;
if (!{}['__defineSetter__']) {
ok(true, 'your browser does not support this test, skipping it');
return;
}
testVid = vjs.TEST_VID;
ConstVolumeVideo = function(){
this.volume = 1;
this.__defineSetter__('volume', function(){});
};
vjs.TEST_VID = new ConstVolumeVideo();
ok(!vjs.Html5.canControlVolume());
vjs.TEST_VID = testVid;
});
test('should re-link the player if the tech is moved', function(){
var player, tech, el;
el = document.createElement('div');
el.innerHTML = '<div />';
player = {
id: function(){ return 'id'; },
el: function(){ return el; },
options_: {},
ready: function(){}
};
tech = new vjs.Html5(player, {});
tech.features = {
movingMediaElementInDOM: false
};
tech.createEl();
strictEqual(player, tech.el()['player']);
});

View File

@ -155,6 +155,14 @@ test('should set the width and height of the player', function(){
player.dispose();
});
test('should not force width and height', function() {
var player = PlayerTest.makePlayer({ width: 'auto', height: 'auto' });
ok(player.el().style.width === '', 'Width is not forced');
ok(player.el().style.height === '', 'Height is not forced');
player.dispose();
});
test('should accept options from multiple sources and override in correct order', function(){
var tag = PlayerTest.makeTag();
var container = document.createElement('div');