1
0
mirror of https://github.com/videojs/video.js.git synced 2025-02-08 12:05:47 +02:00

feat(track): make label property mutable and fire a labelchange event when the label is changed (#6928)

Allows the editing of a track's label after its creation. Menu buttons will listen for the labelchange event and update their content accordingly.

This is technically divergent from the spec, which says it's readonly, but it can be useful for Video.js users.

Co-authored-by: Claudia Hinkle <chinkle@chinkle-mn1.linkedin.biz>
This commit is contained in:
claudiah12 2020-11-10 18:11:53 -05:00 committed by GitHub
parent 0140b28cc3
commit ee0637c078
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 92 additions and 14 deletions

View File

@ -38,11 +38,13 @@ class TrackButton extends MenuButton {
tracks.addEventListener('removetrack', updateHandler);
tracks.addEventListener('addtrack', updateHandler);
tracks.addEventListener('labelchange', updateHandler);
this.player_.on('ready', updateHandler);
this.player_.on('dispose', function() {
tracks.removeEventListener('removetrack', updateHandler);
tracks.removeEventListener('addtrack', updateHandler);
tracks.removeEventListener('labelchange', updateHandler);
});
}

View File

@ -2,6 +2,7 @@
* @file track-list.js
*/
import EventTarget from '../event-target';
import {isEvented} from '../mixins/evented';
/**
* Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and
@ -76,6 +77,26 @@ class TrackList extends EventTarget {
target: this
});
}
/**
* Triggered when a track label is changed.
*
* @event TrackList#addtrack
* @type {EventTarget~Event}
* @property {Track} track
* A reference to track that was added.
*/
track.labelchange_ = () => {
this.trigger({
track,
type: 'labelchange',
target: this
});
};
if (isEvented(track)) {
track.addEventListener('labelchange', track.labelchange_);
}
}
/**
@ -161,7 +182,8 @@ class TrackList extends EventTarget {
TrackList.prototype.allowedEvents_ = {
change: 'change',
addtrack: 'addtrack',
removetrack: 'removetrack'
removetrack: 'removetrack',
labelchange: 'labelchange'
};
// emulate attribute EventHandler support to allow for feature detection

View File

@ -42,10 +42,11 @@ class Track extends EventTarget {
const trackProps = {
id: options.id || 'vjs_track_' + Guid.newGUID(),
kind: options.kind || '',
label: options.label || '',
language: options.language || ''
};
let label = options.label || '';
/**
* @memberof Track
* @member {string} id
@ -64,15 +65,6 @@ class Track extends EventTarget {
* @readonly
*/
/**
* @memberof Track
* @member {string} label
* The label of this track. Cannot be changed after creation.
* @instance
*
* @readonly
*/
/**
* @memberof Track
* @member {string} language
@ -91,6 +83,35 @@ class Track extends EventTarget {
set() {}
});
}
/**
* @memberof Track
* @member {string} label
* The label of this track. Cannot be changed after creation.
* @instance
*
* @fires Track#labelchange
*/
Object.defineProperty(this, 'label', {
get() {
return label;
},
set(newLabel) {
if (newLabel !== label) {
label = newLabel;
/**
* An event that fires when label changes on this track.
*
* > Note: This is not part of the spec!
*
* @event Track#labelchange
* @type {EventTarget~Event}
*/
this.trigger('labelchange');
}
}
});
}
}

View File

@ -21,17 +21,15 @@ const TrackBaseline = function(TrackClass, options) {
tech.dispose();
});
QUnit.test('kind, label, language, id, are read only', function(assert) {
QUnit.test('kind, language, id, are read only', function(assert) {
const tech = new TechFaker();
const track = new TrackClass(Object.assign({tech}, options));
track.kind = 'subtitles';
track.label = 'Spanish';
track.language = 'es';
track.id = '2';
assert.equal(track.kind, options.kind, 'we have a kind');
assert.equal(track.label, options.label, 'we have a label');
assert.equal(track.language, options.language, 'we have a language');
assert.equal(track.id, options.id, 'we have an id');

View File

@ -1,5 +1,6 @@
/* eslint-env qunit */
import TrackList from '../../../src/js/tracks/track-list.js';
import EventTarget from '../../../src/js/event-target.js';
const newTrack = function(id) {
return {
@ -161,3 +162,16 @@ QUnit.test('a "removetrack" event is triggered when tracks are removed', functio
assert.equal(rms, 3, 'we got ' + rms + ' "removetrack" events');
assert.equal(tracks, 3, 'we got a track with every event');
});
QUnit.test('labelchange event is fired for the list when a child track fires labelchange', function(assert) {
const trackList = new TrackList([new EventTarget()]);
let labelchanges = 0;
const labelchangeHandler = (e) => {
labelchanges++;
};
trackList.on('labelchange', labelchangeHandler);
trackList[0].trigger('labelchange');
assert.equal(labelchanges, '1', 'labelchange event is fired on tracklist');
});

View File

@ -35,3 +35,24 @@ QUnit.test('defaults when items not provided', function(assert) {
assert.equal(track.language, '', 'language defaults to empty string');
assert.ok(track.id.match(/vjs_track_\d+/), 'id defaults to vjs_track_GUID');
});
QUnit.test('label is updated and labelchange event is fired when label is changed', function(assert) {
const track = new Track({
tech: defaultTech
});
let eventsTriggered = 0;
track.addEventListener('labelchange', () => {
eventsTriggered++;
});
track.label = 'English (auto)';
assert.equal(eventsTriggered, 1, 'one label change');
assert.equal(track.label, 'English (auto)');
track.label = 'English (auto)';
assert.equal(eventsTriggered, 1, 'additional label change not fired when new label is the same as old');
assert.equal(track.label, 'English (auto)');
track.off();
});