Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix poster-switching tests for IE8, and fix quote handling for other browsers #838

Closed
wants to merge 7 commits into from
3 changes: 3 additions & 0 deletions src/js/media/flash.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,9 @@ vjs.Flash.prototype.load = function(){
vjs.Flash.prototype.poster = function(){
this.el_.vjs_getProperty('poster');
};
vjs.Flash.prototype.setPoster = function(){
// poster images are not handled by the Flash tech so make this a no-op
};

vjs.Flash.prototype.buffered = function(){
return vjs.createTimeRange(0, this.el_.vjs_getProperty('buffered'));
Expand Down
3 changes: 3 additions & 0 deletions src/js/media/html5.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,9 @@ vjs.Html5.prototype.src = function(src){ this.el_.src = src; };
vjs.Html5.prototype.load = function(){ this.el_.load(); };
vjs.Html5.prototype.currentSrc = function(){ return this.el_.currentSrc; };

vjs.Html5.prototype.poster = function(){ return this.el_.poster; };
vjs.Html5.prototype.setPoster = function(val){ this.el_.poster = val; };

vjs.Html5.prototype.preload = function(){ return this.el_.preload; };
vjs.Html5.prototype.setPreload = function(val){ this.el_.preload = val; };

Expand Down
17 changes: 11 additions & 6 deletions src/js/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -1093,11 +1093,18 @@ vjs.Player.prototype.poster_;
* @return {vjs.Player} self when setting
*/
vjs.Player.prototype.poster = function(src){
if (src !== undefined) {
this.poster_ = src;
return this;
if (src === undefined) {
return this.poster_;
}
return this.poster_;

// update the internal poster variable
this.poster_ = src;

// update the tech's poster
this.techCall('setPoster', src);

// alert components that the poster has been set
this.trigger('posterchange');
};

/**
Expand Down Expand Up @@ -1381,5 +1388,3 @@ vjs.Player.prototype.listenForUserActivity = function(){
}

})();


53 changes: 43 additions & 10 deletions src/js/poster.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,65 @@ vjs.PosterImage = vjs.Button.extend({
init: function(player, options){
vjs.Button.call(this, player, options);

if (player.poster()) {
this.src(player.poster());
}

if (!player.poster() || !player.controls()) {
this.hide();
}

player.on('posterchange', vjs.bind(this, function(){
this.src(player.poster());
}));

player.on('play', vjs.bind(this, this.hide));
}
});

vjs.PosterImage.prototype.createEl = function(){
var el = vjs.createEl('div', {
className: 'vjs-poster',
className: 'vjs-poster',

// Don't want poster to be tabbable.
tabIndex: -1
});

if (!('backgroundSize' in el.style)) {
// setup an img element as a fallback for IE8
el.appendChild(vjs.createEl('img'));
}

// Don't want poster to be tabbable.
tabIndex: -1
}),
poster = this.player_.poster();
return el;
};

vjs.PosterImage.prototype.src = function(url){
var el = this.el(), imgFallback;

if (poster) {
// getter
if (url === undefined) {
if ('backgroundSize' in el.style) {
el.style.backgroundImage = 'url("' + poster + '")';
} else {
el.appendChild(vjs.createEl('img', { src: poster }));
if (el.style.backgroundImage) {
// parse the poster url from the background-image value
return (/url\(['"]?(.*)['"]?\)/).exec(el.style.backgroundImage)[1];
}

// the poster is not specified
return '';
}
return el.querySelector('img').src;
}

return el;
// setter
// To ensure the poster image resizes while maintaining its original aspect
// ratio, use a div with `background-size` when available. For browsers that
// do not support `background-size` (e.g. IE8), fall back on using a regular
// img element.
if ('backgroundSize' in el.style) {
el.style.backgroundImage = 'url("' + url + '")';
} else {
el.querySelector('img').src = url;
}
};

vjs.PosterImage.prototype.onClick = function(){
Expand Down
61 changes: 61 additions & 0 deletions test/unit/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,64 @@ test('calculateDistance should use changedTouches, if available', function() {

equal(slider.calculateDistance(event), 0.5, 'we should have touched exactly in the center, so, the ratio should be half');
});

test('the poster getter should work correctly even when background-size is not available', function() {
var noop = function(){},
url = 'http://example.com/poster.jpg',
player = {
controls: noop,
id: noop,
on: noop,
ready: noop,
poster: function(){
return url;
}
},
poster = new vjs.PosterImage(player);

// mock out el() to return an element that behaves like IE8
poster.el = function(){
return {
style: {},
querySelector: function() {
return {
src: url
};
}
};
};

equal(url, poster.src(), 'the poster url is returned');
});

test('the poster setter should reuse an img when background-size is not available', function() {
var noop = function(){},
url = 'http://example.com/poster.jpg',
img = {},
player = {
controls: noop,
id: noop,
on: noop,
ready: noop,
poster: function(){
return url;
}
},
poster = new vjs.PosterImage(player);

// mock out el() to return an element that behaves like IE8
poster.el = function(){
return {
appendChild: function() {
ok(false, 'a new img should not be added to the poster');
},
style: {},
querySelector: function() {
return img;
}
};
};

poster.src(url);
equal(img.src, url, 'the img is reused for the new src');
});
4 changes: 4 additions & 0 deletions test/unit/mediafaker.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ vjs.MediaFaker.prototype.createEl = function(){
return el;
};

// fake a poster attribute to mimic the video element
vjs.MediaFaker.prototype.poster = function(){ return this.el().poster; };
vjs.MediaFaker.prototype['setPoster'] = function(val){ this.el().poster = val; };

vjs.MediaFaker.prototype.currentTime = function(){ return 0; };
vjs.MediaFaker.prototype.seeking = function(){ return false; };
vjs.MediaFaker.prototype.volume = function(){ return 0; };
Expand Down
75 changes: 75 additions & 0 deletions test/unit/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,81 @@ test('should transfer the poster attribute unmodified', function(){
player.dispose();
});

test('should allow the poster to be changed after init', function() {
var tag, fixture, updatedPoster, player, posterElement, posterElementUrl, imageElement;
tag = PlayerTest.makeTag();
tag.setAttribute('poster', 'http://example.com/poster.jpg');
fixture = document.getElementById('qunit-fixture');

fixture.appendChild(tag);
player = new vjs.Player(tag, {
'techOrder': ['mediaFaker']
});

updatedPoster = 'http://example.com/updated-poster.jpg';
player.poster(updatedPoster);

strictEqual(player.poster(), updatedPoster, 'the updated poster is returned');
strictEqual(player.tech.el().poster, updatedPoster, 'the poster attribute is updated');

posterElement = document.querySelector('.vjs-poster');
ok(posterElement, 'vjs-poster element should exist');

if (!('backgroundSize' in posterElement.style)) {
imageElement = document.getElementsByTagName('img')[0];
ok(imageElement, 'image element should exist if the poster div has no background-size CSS property');
var imageElementSrc = imageElement.getAttribute('src');
strictEqual(imageElementSrc,
updatedPoster,
'the poster img src is updated');
} else {
posterElementUrl = posterElement.style.backgroundImage.replace(/"/g, '');
strictEqual(posterElementUrl,
'url(' + updatedPoster + ')',
'the poster div background is updated');
}

player.dispose();
});

test('should ignore setting an undefined poster after init', function() {
var tag, fixture, updatedPoster, originalPoster, player, posterElement, posterElementUrl, imageElement;
tag = PlayerTest.makeTag();
tag.setAttribute('poster', 'http://example.com/poster.jpg');
fixture = document.getElementById('qunit-fixture');

fixture.appendChild(tag);
player = new vjs.Player(tag, {
'techOrder': ['mediaFaker']
});

originalPoster = player.poster();

updatedPoster = undefined;
player.poster(updatedPoster);
strictEqual(player.poster(), originalPoster, 'the original poster is returned');
strictEqual(player.tech.el().poster, originalPoster, 'the poster attribute is unchanged');

posterElement = document.querySelector('.vjs-poster');
ok(posterElement, 'vjs-poster element should exist');

if (!('backgroundSize' in posterElement.style)) {
imageElement = document.getElementsByTagName('img')[0];
ok(imageElement, 'image element should exist if the poster div has no background-size CSS property');
var imageElementSrc = imageElement.getAttribute('src');
strictEqual(imageElementSrc,
originalPoster,
'the poster img src is not updated');
} else {
posterElementUrl = posterElement.style.backgroundImage.replace(/"/g, '');
strictEqual(posterElementUrl,
'url(' + originalPoster + ')',
'the poster div background is unchanged');
}

player.dispose();
});

test('should load a media controller', function(){
var player = PlayerTest.makePlayer({
preload: 'none',
Expand Down