Comparar commits

..

2 Commits

Autor SHA1 Mensagem Data
Pat O'Neill ec5b60329f chore: Add package-lock.json file. (#4641) 2017-10-19 11:49:04 -04:00
Pat O'Neill 0287f6e076 fix: Make sure we remove vjs-ended from the play toggle in all appropriate cases. (#4661) 2017-10-13 13:46:51 -04:00
4 arquivos alterados com 14151 adições e 673 exclusões
+14150
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+1 -1
Ver Arquivo
@@ -67,7 +67,6 @@ class PlayToggle extends Button {
* @listens Player#seeked
*/
handleSeeked(event) {
// remove the ended class
this.removeClass('vjs-ended');
if (this.player_.paused()) {
@@ -86,6 +85,7 @@ class PlayToggle extends Button {
* @listens Player#play
*/
handlePlay(event) {
this.removeClass('vjs-ended');
this.removeClass('vjs-paused');
this.addClass('vjs-playing');
// change the button text to "Pause"
-175
Ver Arquivo
@@ -458,8 +458,6 @@ class Player extends Component {
this.on('stageclick', this.handleStageClick_);
this.changingSrc_ = false;
this.watchForSourceSet_();
}
/**
@@ -824,179 +822,6 @@ class Player extends Component {
`);
}
/**
* Modify the video/audio element so that we can detect when
* the source is changed. Fires `sourceset` just after the source has changed
*
* @fires Player#sourceset
*/
watchForSourceSet_() {
// if we cannot overwrite the src property, there is no support
// iOS 7 safari for instance cannot do this.
try {
const el = document.createElement('video');
Object.defineProperty(el, 'src', {
get() {},
set() {}
});
} catch (e) {
return;
}
const el = this.el().getElementsByTagName('video')[0] || this.el().getElementsByTagName('audio')[0];
if (!el) {
if (!this.isReady_) {
this.ready(() => this.watchForSourceSet_());
}
return;
}
// we need to fire sourceset when the player is ready
// if we find that the media element had a src when it was
// given to us
if (this.tagAttributes && this.tagAttributes.src) {
this.ready(() => {
this.trigger('sourceset');
});
}
const proto = window.HTMLMediaElement.prototype;
const srcDescriptor = {
get() {
return proto.getAttribute.call(this, 'src');
},
set(v) {
return proto.setAttribute.call(this, 'src', v);
},
enumerable: true
};
// preserve getters/setters already on `el.src` if they exist
if (Object.getOwnPropertyDescriptor(el, 'src')) {
Object.assign(srcDescriptor, Object.getOwnPropertyDescriptor(el, 'src'));
} else if (Object.getOwnPropertyDescriptor(proto, 'src')) {
Object.assign(srcDescriptor, Object.getOwnPropertyDescriptor(proto, 'src'));
}
Object.defineProperty(el, 'src', {
get: srcDescriptor.get.bind(el),
set: (v) => {
const retval = srcDescriptor.set.call(el, v);
this.ready(() => this.trigger('sourceset'), true);
return retval;
},
configurable: true,
enumerable: srcDescriptor.enumerable
});
const oldSetAttribute = el.setAttribute;
el.setAttribute = (n, v) => {
const retval = oldSetAttribute.call(el, n, v);
if (n === 'src') {
this.ready(() => this.trigger('sourceset'), true);
}
return retval;
};
const oldLoad = el.load;
el.load = () => {
const retval = oldLoad.call(el);
this.ready(() => this.trigger('sourceset'), true);
return retval;
};
this.on('dispose', () => {
if (!el) {
return;
}
el.load = oldLoad.bind(el);
el.setAttribute = oldSetAttribute.bind(el);
Object.defineProperty(el, 'src', srcDescriptor);
});
// observer video tag changes, we do this when tech loads on iOS
this.on('sourceset', this.handleSourceSet_);
}
/**
* Update the internal source cache based on the `sourceset` event.
*
* @param {EventTarget~Event} e
* The sourceset event that triggered this function to run.
*/
handleSourceSet_(e) {
const el = this.el().getElementsByTagName('video')[0] || this.el().getElementsByTagName('audio')[0];
if (!el) {
return;
}
// get what the video element thinks the source is
let src = el.src;
let sources = Array.prototype.map.call(el.getElementsByTagName('source'), (sourceEl) => {
return {src: sourceEl.src, type: sourceEl.type};
});
if (!sources.length && !src) {
return;
}
if (el.getAttribute('src') === null) {
src = null;
}
if (src) {
let type;
if (sources && !type) {
// get the source type from our sources list
for (let i = 0; i < sources.length; i++) {
if (sources[i].src === src) {
type = sources[i].type;
break;
}
}
}
if (!type) {
type = 'video/mp4';
if ((/\.mp3$/).test(src)) {
type = 'audio/mpeg';
}
}
src = {src, type};
}
if (!src && sources.length) {
src = sources[0];
} else if (src && !sources.length) {
sources = [src];
}
if (!this.cache_.src || this.cache_.src !== src.src) {
this.cache_.src = src.src;
}
if (!this.cache_.source || this.cache_.source.src !== src.src) {
this.cache_.source = src;
this.cache_.sources = sources;
}
}
/**
* Load/Create an instance of playback {@link Tech} including element
* and API methods. Then append the `Tech` element in `Player` as a child.
-497
Ver Arquivo
@@ -1,497 +0,0 @@
/* eslint-env qunit */
import videojs from '../../src/js/video.js';
import document from 'global/document';
import window from 'global/window';
const wait = 100;
let qunitFn = 'module';
// if we cannot overwrite the src property, there is no support
try {
const el = document.createElement('video');
Object.defineProperty(el, 'src', {
get() {},
set() {}
});
} catch (e) {
qunitFn = 'skip';
}
const Html5 = videojs.getTech('Html5');
const oldMovingMedia = Html5.prototype.movingMediaElementInDOM;
const validateSource = function(assert, player, sources, checkMediaElSource = true) {
const tech = player.tech_;
const mediaEl = tech.el();
assert.deepEqual(player.currentSource(), sources[0], 'currentSource is correct');
assert.equal(player.src(), sources[0].src, 'src is correct');
assert.deepEqual(player.currentSources(), sources, 'currentSources is correct');
// when we are dealing with <source> elements mediaEl.src will be null
if (checkMediaElSource) {
assert.equal(mediaEl.src, sources[0].src, 'mediaEl.src is correct');
assert.equal(mediaEl.getAttribute('src'), sources[0].src, 'mediaEl attribute is correct');
assert.equal(tech.src(), sources[0].src, 'tech is correct');
}
};
QUnit[qunitFn]('sourceset', function(hooks) {
['video el', 'change video el', 'audio el', 'change audio el'].forEach((testName) => {
QUnit.module(`source before player - ${testName}`, {
beforeEach() {
if (testName === 'change video el' || testName === 'change audio el') {
Html5.prototype.movingMediaElementInDOM = false;
}
this.hook = (player) => player.on('sourceset', () => this.sourcesets++);
videojs.hook('setup', this.hook);
this.sourcesets = 0;
this.fixture = document.getElementById('qunit-fixture');
if ((/audio/i).test(testName)) {
this.mediaEl = document.createElement('audio');
this.testSrc = {
src: 'http://vjs.zencdn.net/v/oceans.mp3',
type: 'audio/mpeg'
};
} else {
this.mediaEl = document.createElement('video');
this.testSrc = {
src: 'http://vjs.zencdn.net/v/oceans.mp4',
type: 'video/mp4'
};
}
this.sourceOne = {src: 'http://example.com/one.mp4', type: 'video/mp4'};
this.sourceTwo = {src: 'http://example.com/two.mp4', type: 'video/mp4'};
if ((/audio/).test(testName)) {
this.sourceOne = {src: 'http://example.com/one.mp3', type: 'audio/mpeg'};
this.sourceTwo = {src: 'http://example.com/two.mp3', type: 'audio/mpeg'};
}
this.mediaEl.className = 'video-js';
this.fixture.appendChild(this.mediaEl);
},
afterEach(assert) {
const done = assert.async();
// reset sourceset to 0 so we can track if more happen
this.sourcesets = 0;
window.setTimeout(() => {
assert.equal(this.sourcesets, 0, 'no additional sourcesets');
this.player.dispose();
assert.equal(this.sourcesets, 0, 'no source set on dispose');
videojs.removeHook('setup', this.hook);
Html5.prototype.movingMediaElementInDOM = oldMovingMedia;
done();
}, wait);
}
});
QUnit.test('data-setup x1', function(assert) {
const done = assert.async();
this.mediaEl.setAttribute('data-setup', JSON.stringify({sources: [this.testSrc]}));
this.player = videojs(this.mediaEl);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.testSrc]);
done();
});
});
QUnit.test('data-setup, x2', function(assert) {
const done = assert.async();
this.mediaEl.setAttribute('data-setup', JSON.stringify({sources: [this.sourceOne, this.sourceTwo]}));
this.player = videojs(this.mediaEl);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceOne, this.sourceTwo]);
done();
});
});
QUnit.test('videojs({sources: [...]}) x1', function(assert) {
const done = assert.async();
this.player = videojs(this.mediaEl, {sources: [this.testSrc]});
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.testSrc]);
done();
});
});
QUnit.test('videojs({sources: [...]}) x2', function(assert) {
const done = assert.async();
this.player = videojs(this.mediaEl, {sources: [this.sourceOne, this.sourceTwo]});
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceOne, this.sourceTwo]);
done();
});
});
QUnit.test('player.src({...})', function(assert) {
const done = assert.async();
this.player = videojs(this.mediaEl);
this.player.src(this.testSrc);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.testSrc]);
done();
});
});
QUnit.test('player.src({...}) x2', function(assert) {
const done = assert.async();
this.player = videojs(this.mediaEl);
this.player.src([this.sourceOne, this.sourceTwo]);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceOne, this.sourceTwo]);
done();
});
});
QUnit.test('mediaEl.src = ...;', function(assert) {
const done = assert.async();
this.mediaEl.src = this.testSrc.src;
this.player = videojs(this.mediaEl);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.testSrc]);
done();
});
});
QUnit.test('mediaEl.setAttribute("src", ...)"', function(assert) {
const done = assert.async();
this.mediaEl.setAttribute('src', this.testSrc.src);
this.player = videojs(this.mediaEl);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.testSrc]);
done();
});
});
QUnit.test('<source> x1', function(assert) {
const done = assert.async();
this.source = document.createElement('source');
this.source.src = this.testSrc.src;
this.source.type = this.testSrc.type;
this.mediaEl.appendChild(this.source);
this.player = videojs(this.mediaEl);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.testSrc]);
done();
});
});
QUnit.test('<source> x2', function(assert) {
const done = assert.async();
this.source = document.createElement('source');
this.source.src = this.sourceOne.src;
this.source.type = this.sourceOne.type;
this.source2 = document.createElement('source');
this.source2.src = this.sourceTwo.src;
this.source2.type = this.sourceTwo.type;
this.mediaEl.appendChild(this.source);
this.mediaEl.appendChild(this.source2);
this.player = videojs(this.mediaEl);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceOne, this.sourceTwo]);
done();
});
});
QUnit.test('no source', function(assert) {
const done = assert.async();
this.player = videojs(this.mediaEl);
window.setTimeout(() => {
assert.equal(this.sourcesets, 0, 'no sourceset');
done();
}, wait);
});
QUnit.module(`source change - ${testName}`, {
beforeEach(assert) {
const done = assert.async();
if (testName === 'change video el' || testName === 'change audio el') {
Html5.prototype.movingMediaElementInDOM = false;
}
this.hook = (player) => player.on('sourceset', () => this.sourcesets++);
videojs.hook('setup', this.hook);
this.sourcesets = 0;
this.fixture = document.getElementById('qunit-fixture');
if ((/audio/i).test(testName)) {
this.mediaEl = document.createElement('audio');
this.testSrc = {
src: 'http://vjs.zencdn.net/v/oceans.mp3',
type: 'audio/mpeg'
};
} else {
this.mediaEl = document.createElement('video');
this.testSrc = {
src: 'http://vjs.zencdn.net/v/oceans.mp4',
type: 'video/mp4'
};
}
this.sourceOne = {src: 'http://example.com/one.mp4', type: 'video/mp4'};
this.sourceTwo = {src: 'http://example.com/two.mp4', type: 'video/mp4'};
if ((/audio/).test(testName)) {
this.sourceOne = {src: 'http://example.com/one.mp3', type: 'audio/mpeg'};
this.sourceTwo = {src: 'http://example.com/two.mp3', type: 'audio/mpeg'};
}
this.mediaEl.className = 'video-js';
this.mediaEl.src = this.testSrc.src;
this.fixture.appendChild(this.mediaEl);
this.player = videojs(this.mediaEl);
this.player.ready(() => {
this.mediaEl = this.player.tech_.el();
});
// intial sourceset should happen on player.ready
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.testSrc]);
done();
});
},
afterEach(assert) {
const done = assert.async();
// reset sourceset to 0 so we can track if more happen
this.sourcesets = 0;
window.setTimeout(() => {
assert.equal(this.sourcesets, 0, 'no additional sourcesets');
this.player.dispose();
assert.equal(this.sourcesets, 0, 'no source set on dispose');
videojs.removeHook('setup', this.hook);
Html5.prototype.movingMediaElementInDOM = oldMovingMedia;
done();
}, wait);
}
});
QUnit.test('player.src({...})', function(assert) {
const done = assert.async();
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.testSrc]);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceOne]);
done();
});
this.player.src(this.sourceOne);
});
this.player.src(this.testSrc);
});
QUnit.test('player.src({...}) x2 at the same time', function(assert) {
const done = assert.async();
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceOne]);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceTwo]);
done();
});
});
this.player.src(this.sourceOne);
this.player.src(this.sourceTwo);
});
QUnit.test('mediaEl.src = ...', function(assert) {
const done = assert.async();
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.testSrc]);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceOne]);
done();
});
this.mediaEl.src = this.sourceOne.src;
});
this.mediaEl.src = this.testSrc.src;
});
QUnit.test('mediaEl.src = ... x2 at the same time', function(assert) {
const done = assert.async();
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceOne]);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceTwo]);
done();
});
});
this.mediaEl.src = this.sourceOne.src;
this.mediaEl.src = this.sourceTwo.src;
});
QUnit.test('mediaEl.setAttribute("src", ...)', function(assert) {
const done = assert.async();
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.testSrc]);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceOne]);
done();
});
this.mediaEl.setAttribute('src', this.sourceOne.src);
});
this.mediaEl.setAttribute('src', this.testSrc.src);
});
QUnit.test('mediaEl.setAttribute("src", ...) x2 at the same time', function(assert) {
const done = assert.async();
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceOne]);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceTwo]);
done();
});
});
this.mediaEl.setAttribute('src', this.sourceOne.src);
this.mediaEl.setAttribute('src', this.sourceTwo.src);
});
QUnit.test('mediaEl.load()', function(assert) {
const done = assert.async();
const source = document.createElement('source');
source.src = this.testSrc.src;
source.type = this.testSrc.type;
// the only way to unset a source, so that we use the source
// elements instead
this.mediaEl.removeAttribute('src');
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.testSrc], false);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceOne], false);
done();
});
source.src = this.sourceOne.src;
source.type = this.sourceOne.type;
this.mediaEl.load();
});
this.mediaEl.appendChild(source);
this.mediaEl.load();
});
QUnit.test('mediaEl.load() x2 at the same time', function(assert) {
const done = assert.async();
const source = document.createElement('source');
source.src = this.sourceOne.src;
source.type = this.sourceOne.type;
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceOne], false);
this.player.one('sourceset', () => {
validateSource(assert, this.player, [this.sourceTwo], false);
done();
});
});
// the only way to unset a source, so that we use the source
// elements instead
this.mediaEl.removeAttribute('src');
this.mediaEl.appendChild(source);
this.mediaEl.load();
source.src = this.sourceTwo.src;
source.type = this.sourceTwo.type;
this.mediaEl.load();
});
QUnit.test('adding a <source> without load()', function(assert) {
const done = assert.async();
const source = document.createElement('source');
source.src = this.testSrc.src;
source.type = this.testSrc.type;
this.mediaEl.appendChild(source);
window.setTimeout(() => {
assert.equal(this.sourcesets, 1, 'does not trigger sourceset');
done();
}, wait);
});
QUnit.test('changing a <source>s src without load()', function(assert) {
const done = assert.async();
const source = document.createElement('source');
source.src = this.testSrc.src;
source.type = this.testSrc.type;
this.mediaEl.appendChild(source);
source.src = this.testSrc.src;
window.setTimeout(() => {
assert.equal(this.sourcesets, 1, 'does not trigger sourceset');
done();
}, wait);
});
});
});