mirror of
https://github.com/videojs/video.js.git
synced 2025-07-15 01:34:23 +02:00
Restore the original video tag attributes on a tech change
set attributes of video tag and not only values add unsupported attribute to the video tag - test failing helper to set attributes on an element from a map of values dummy compare of html content with a sort of the attributes ignore html attributes order for comparition save original tag attributes restore original tag attributes n creation and overwrite if required by settings replace object.keys with vjs.obj.each for ie<9 fix spacing API consistency, getAttributeValues renamed to getElementAttributes clear variable naming move setElementAttributes close to getElementAttributes
This commit is contained in:
@ -391,6 +391,22 @@ vjs.IS_CHROME = (/Chrome/i).test(vjs.USER_AGENT);
|
|||||||
|
|
||||||
vjs.TOUCH_ENABLED = !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch);
|
vjs.TOUCH_ENABLED = !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply attributes to an HTML element.
|
||||||
|
* @param {Element} el Target element.
|
||||||
|
* @param {Object=} attributes Element attributes to be applied.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
vjs.setElementAttributes = function(el, attributes){
|
||||||
|
vjs.obj.each(attributes, function(attrName, attrValue) {
|
||||||
|
if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
|
||||||
|
el.removeAttribute(attrName);
|
||||||
|
} else {
|
||||||
|
el.setAttribute(attrName,attrValue === true ? '' : attrValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an element's attribute values, as defined on the HTML tag
|
* Get an element's attribute values, as defined on the HTML tag
|
||||||
* Attributs are not the same as properties. They're defined on the tag
|
* Attributs are not the same as properties. They're defined on the tag
|
||||||
@ -400,7 +416,7 @@ vjs.TOUCH_ENABLED = !!(('ontouchstart' in window) || window.DocumentTouch && doc
|
|||||||
* @return {Object}
|
* @return {Object}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
vjs.getAttributeValues = function(tag){
|
vjs.getElementAttributes = function(tag){
|
||||||
var obj, knownBooleans, attrs, attrName, attrVal;
|
var obj, knownBooleans, attrs, attrName, attrVal;
|
||||||
|
|
||||||
obj = {};
|
obj = {};
|
||||||
|
@ -81,10 +81,13 @@ vjs.Html5.prototype.createEl = function(){
|
|||||||
el = clone;
|
el = clone;
|
||||||
player.tag = null;
|
player.tag = null;
|
||||||
} else {
|
} else {
|
||||||
el = vjs.createEl('video', {
|
el = vjs.createEl('video', {});
|
||||||
id:player.id() + '_html5_api',
|
vjs.setElementAttributes(el,
|
||||||
className:'vjs-tech'
|
vjs.obj.merge(player.tagAttributes||{}, {
|
||||||
});
|
id:player.id() + '_html5_api',
|
||||||
|
'class':'vjs-tech'
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// associate the player with the new tag
|
// associate the player with the new tag
|
||||||
el['player'] = player;
|
el['player'] = player;
|
||||||
@ -93,12 +96,14 @@ vjs.Html5.prototype.createEl = function(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update specific tag settings, in case they were overridden
|
// Update specific tag settings, in case they were overridden
|
||||||
var attrs = ['autoplay','preload','loop','muted'];
|
var settingsAttrs = ['autoplay','preload','loop','muted'];
|
||||||
for (var i = attrs.length - 1; i >= 0; i--) {
|
for (var i = settingsAttrs.length - 1; i >= 0; i--) {
|
||||||
var attr = attrs[i];
|
var attr = settingsAttrs[i];
|
||||||
if (player.options_[attr] !== null) {
|
var overwriteAttrs = {};
|
||||||
el[attr] = player.options_[attr];
|
if (typeof player.options_[attr] !== 'undefined') {
|
||||||
|
overwriteAttrs[attr] = player.options_[attr];
|
||||||
}
|
}
|
||||||
|
vjs.setElementAttributes(el, overwriteAttrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return el;
|
return el;
|
||||||
|
@ -32,6 +32,8 @@ vjs.Player = vjs.Component.extend({
|
|||||||
init: function(tag, options, ready){
|
init: function(tag, options, ready){
|
||||||
this.tag = tag; // Store the original tag used to set options
|
this.tag = tag; // Store the original tag used to set options
|
||||||
|
|
||||||
|
this.tagAttributes = (tag) ? vjs.getElementAttributes(tag) : {}; // Store the tag attributes used to restore html5 tech
|
||||||
|
|
||||||
// Make sure tag ID exists
|
// Make sure tag ID exists
|
||||||
tag.id = tag.id || 'vjs_video_' + vjs.guid++;
|
tag.id = tag.id || 'vjs_video_' + vjs.guid++;
|
||||||
|
|
||||||
@ -135,7 +137,7 @@ vjs.Player.prototype.getTagSettings = function(tag){
|
|||||||
'tracks': []
|
'tracks': []
|
||||||
};
|
};
|
||||||
|
|
||||||
vjs.obj.merge(options, vjs.getAttributeValues(tag));
|
vjs.obj.merge(options, vjs.getElementAttributes(tag));
|
||||||
|
|
||||||
// Get tag children settings
|
// Get tag children settings
|
||||||
if (tag.hasChildNodes()) {
|
if (tag.hasChildNodes()) {
|
||||||
@ -148,9 +150,9 @@ vjs.Player.prototype.getTagSettings = function(tag){
|
|||||||
// Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/
|
// Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/
|
||||||
childName = child.nodeName.toLowerCase();
|
childName = child.nodeName.toLowerCase();
|
||||||
if (childName === 'source') {
|
if (childName === 'source') {
|
||||||
options['sources'].push(vjs.getAttributeValues(child));
|
options['sources'].push(vjs.getElementAttributes(child));
|
||||||
} else if (childName === 'track') {
|
} else if (childName === 'track') {
|
||||||
options['tracks'].push(vjs.getAttributeValues(child));
|
options['tracks'].push(vjs.getElementAttributes(child));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,10 +113,10 @@ test('should read tag attributes from elements, including HTML5 in all browsers'
|
|||||||
|
|
||||||
document.getElementById('qunit-fixture').innerHTML += tags;
|
document.getElementById('qunit-fixture').innerHTML += tags;
|
||||||
|
|
||||||
var vid1Vals = vjs.getAttributeValues(document.getElementById('vid1'));
|
var vid1Vals = vjs.getElementAttributes(document.getElementById('vid1'));
|
||||||
var vid2Vals = vjs.getAttributeValues(document.getElementById('vid2'));
|
var vid2Vals = vjs.getElementAttributes(document.getElementById('vid2'));
|
||||||
var sourceVals = vjs.getAttributeValues(document.getElementById('source'));
|
var sourceVals = vjs.getElementAttributes(document.getElementById('source'));
|
||||||
var trackVals = vjs.getAttributeValues(document.getElementById('track'));
|
var trackVals = vjs.getElementAttributes(document.getElementById('track'));
|
||||||
|
|
||||||
// was using deepEqual, but ie8 would send all properties as attributes
|
// was using deepEqual, but ie8 would send all properties as attributes
|
||||||
|
|
||||||
@ -152,6 +152,22 @@ test('should read tag attributes from elements, including HTML5 in all browsers'
|
|||||||
equal(trackVals['title'], 'test');
|
equal(trackVals['title'], 'test');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test('should set tag attributes from object', function(){
|
||||||
|
|
||||||
|
var tags = '<video id="vid1" controls data-test="ok"></video>';
|
||||||
|
|
||||||
|
document.getElementById('qunit-fixture').innerHTML += tags;
|
||||||
|
var el = document.getElementById('vid1');
|
||||||
|
vjs.setElementAttributes(el, {controls: false,'data-test': 'asdf'});
|
||||||
|
|
||||||
|
var vid1Vals = vjs.getElementAttributes(document.getElementById('vid1'));
|
||||||
|
|
||||||
|
equal(vid1Vals['controls'], undefined);
|
||||||
|
equal(vid1Vals['id'], 'vid1');
|
||||||
|
equal(vid1Vals['data-test'], 'asdf');
|
||||||
|
});
|
||||||
|
|
||||||
test('should get the right style values for an element', function(){
|
test('should get the right style values for an element', function(){
|
||||||
var el = document.createElement('div');
|
var el = document.createElement('div');
|
||||||
var container = document.createElement('div');
|
var container = document.createElement('div');
|
||||||
|
@ -73,7 +73,7 @@ test('should accept options from multiple sources and override in correct order'
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should get tag, source, and track settings', function(){
|
test('should get tag, source, and track settings', function(){
|
||||||
// Partially tested in lib->getAttributeValues
|
// Partially tested in lib->getElementAttributes
|
||||||
|
|
||||||
var fixture = document.getElementById('qunit-fixture');
|
var fixture = document.getElementById('qunit-fixture');
|
||||||
|
|
||||||
@ -494,3 +494,33 @@ test('Data attributes on the video element should persist in the new wrapper ele
|
|||||||
|
|
||||||
equal(player.el().getAttribute('data-id'), dataId, 'data-id should be available on the new player element after creation');
|
equal(player.el().getAttribute('data-id'), dataId, 'data-id should be available on the new player element after creation');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should restore all video tags attribute after a tech switch', function(){
|
||||||
|
var fixture = document.getElementById('qunit-fixture');
|
||||||
|
var html = '<video id="example_1" class="vjs-tech" preload="" webkit-playsinline="" autoplay=""></video>';
|
||||||
|
fixture.innerHTML += html;
|
||||||
|
|
||||||
|
var tag = document.getElementById('example_1');
|
||||||
|
var player = new videojs.Player(tag, {techOrder:['html5']});
|
||||||
|
var techOptions = vjs.obj.merge({ 'source': '', 'parentEl': player.el_ }, player.options_['html5']);
|
||||||
|
vjs.Html5.disposeMediaElement(player.tag);
|
||||||
|
player.tag = null;
|
||||||
|
player.tech = new vjs.Html5(player, techOptions);
|
||||||
|
|
||||||
|
PlayerTest.htmlEqualWithSort(player.tech.el_.outerHTML, html.replace('example_1','example_1_html5_api'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should restore all video tags attribute after a tech switch and keep options', function(){
|
||||||
|
var fixture = document.getElementById('qunit-fixture');
|
||||||
|
var html = '<video id="example_1" class="vjs-tech" preload="none" autoplay=""></video>';
|
||||||
|
fixture.innerHTML += html;
|
||||||
|
|
||||||
|
var tag = document.getElementById('example_1');
|
||||||
|
var player = new videojs.Player(tag, {techOrder:['html5'], autoplay:false});
|
||||||
|
var techOptions = vjs.obj.merge({ 'source': '', 'parentEl': player.el_ }, player.options_['html5']);
|
||||||
|
vjs.Html5.disposeMediaElement(player.tag);
|
||||||
|
player.tag = null;
|
||||||
|
player.tech = new vjs.Html5(player, techOptions);
|
||||||
|
|
||||||
|
PlayerTest.htmlEqualWithSort(player.tech.el_.outerHTML, html.replace('example_1','example_1_html5_api').replace(' autoplay=""',''));
|
||||||
|
});
|
||||||
|
@ -17,5 +17,16 @@ var PlayerTest = {
|
|||||||
playerOptions['techOrder'] = ['mediaFaker'];
|
playerOptions['techOrder'] = ['mediaFaker'];
|
||||||
|
|
||||||
return player = new videojs.Player(videoTag, playerOptions);
|
return player = new videojs.Player(videoTag, playerOptions);
|
||||||
|
},
|
||||||
|
htmlEqualWithSort : function(htmlResult,htmlExpected) {
|
||||||
|
function htmlTransform(str) {
|
||||||
|
str = str.replace(/[<|>]/g,' ');
|
||||||
|
str = str.trim();
|
||||||
|
str = str.replace(/\s{2,}/g, ' ');
|
||||||
|
return str.split(' ').sort().join(' ');
|
||||||
|
}
|
||||||
|
htmlResult= htmlResult.split(' ').sort().join(' ');
|
||||||
|
equal(htmlTransform(htmlResult),htmlTransform(htmlExpected));
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user