Fully remove videoController on video removal (#469)

* Check if video is part of DOM before removing
* Fully remove controller when video is removed
 - Remove eventListeners registered by controller when deleted. 
 - Store reference to functions to allow this
* Give each videoController object a reference to the visible controller div
This commit is contained in:
jacobcolbert
2019-05-02 02:06:06 -04:00
committed by Ilya Grigorik
parent 2310423c94
commit 04eaa51cda

View File

@@ -103,7 +103,7 @@
function defineVideoController() { function defineVideoController() {
tc.videoController = function(target, parent) { tc.videoController = function(target, parent) {
if (target.dataset['vscid']) { if (target.dataset['vscid']) {
return; return target.vsc;
} }
this.video = target; this.video = target;
@@ -123,9 +123,9 @@
} else { } else {
tc.settings.speeds[target.src] = tc.settings.lastSpeed; tc.settings.speeds[target.src] = tc.settings.lastSpeed;
} }
this.initializeControls(); this.div = this.initializeControls();
target.addEventListener('play', function(event) { target.addEventListener('play', this.handlePlay = function(event) {
if (!tc.settings.rememberSpeed) { if (!tc.settings.rememberSpeed) {
if (!tc.settings.speeds[target.src]) { if (!tc.settings.speeds[target.src]) {
tc.settings.speeds[target.src] = this.speed; tc.settings.speeds[target.src] = this.speed;
@@ -137,7 +137,7 @@
target.playbackRate = tc.settings.speeds[target.src]; target.playbackRate = tc.settings.speeds[target.src];
}.bind(this)); }.bind(this));
target.addEventListener('ratechange', function(event) { target.addEventListener('ratechange', this.handleRatechange = function(event) {
// Ignore ratechange events on unitialized videos. // Ignore ratechange events on unitialized videos.
// 0 == No information is available about the media resource. // 0 == No information is available about the media resource.
if (event.target.readyState > 0) { if (event.target.readyState > 0) {
@@ -160,7 +160,11 @@
} }
tc.videoController.prototype.remove = function() { tc.videoController.prototype.remove = function() {
this.parentElement.removeChild(this); this.div.remove();
this.video.removeEventListener('play',this.handlePlay);
this.video.removeEventListener('ratechange',this.handleRatechange);
delete this.video.dataset['vscid'];
delete this.video.vsc;
} }
tc.videoController.prototype.initializeControls = function() { tc.videoController.prototype.initializeControls = function() {
@@ -225,6 +229,7 @@
// the first element of the target, which may not be the parent. // the first element of the target, which may not be the parent.
this.parent.insertBefore(fragment, this.parent.firstChild); this.parent.insertBefore(fragment, this.parent.firstChild);
} }
return wrapper;
} }
} }
@@ -341,17 +346,17 @@
function checkForVideo(node, parent, added) { function checkForVideo(node, parent, added) {
// Only proceed with supposed removal if node is missing from DOM
if (!added && document.body.contains(node)) {
return;
}
if (node.nodeName === 'VIDEO' || (node.nodeName === 'AUDIO' && tc.settings.audioBoolean)) { if (node.nodeName === 'VIDEO' || (node.nodeName === 'AUDIO' && tc.settings.audioBoolean)) {
if (added) { if (added) {
new tc.videoController(node, parent); node.vsc = new tc.videoController(node, parent);
} else { } else {
let id = node.dataset['vscid']; let id = node.dataset['vscid'];
if (id) { if (id) {
let ctrl = document.querySelector(`div[data-vscid="${id}"]`) node.vsc.remove();
if (ctrl) {
ctrl.remove();
}
delete node.dataset['vscid'];
} }
} }
} else if (node.children != undefined) { } else if (node.children != undefined) {
@@ -388,7 +393,7 @@
} }
forEach.call(mediaTags, function(video) { forEach.call(mediaTags, function(video) {
new tc.videoController(video); video.vsc = new tc.videoController(video);
}); });
var frameTags = document.getElementsByTagName('iframe'); var frameTags = document.getElementsByTagName('iframe');