diff --git a/src/js/component.js b/src/js/component.js index e6188a1192..1951f9ac23 100644 --- a/src/js/component.js +++ b/src/js/component.js @@ -7,7 +7,6 @@ import window from 'global/window'; import evented from './mixins/evented'; import stateful from './mixins/stateful'; import * as Dom from './utils/dom.js'; -import DomData from './utils/dom-data'; import * as Fn from './utils/fn.js'; import * as Guid from './utils/guid.js'; import {toTitleCase, toLowerCase} from './utils/string-cases.js'; @@ -178,9 +177,6 @@ class Component { this.el_.parentNode.removeChild(this.el_); } - if (DomData.has(this.el_)) { - DomData.delete(this.el_); - } this.el_ = null; } diff --git a/src/js/mixins/evented.js b/src/js/mixins/evented.js index 045493d370..c03273cebc 100644 --- a/src/js/mixins/evented.js +++ b/src/js/mixins/evented.js @@ -8,6 +8,7 @@ import * as Events from '../utils/events'; import * as Fn from '../utils/fn'; import * as Obj from '../utils/obj'; import EventTarget from '../event-target'; +import DomData from '../utils/dom-data'; import log from '../utils/log'; const objName = (obj) => { @@ -499,6 +500,11 @@ function evented(target, options = {}) { // When any evented object is disposed, it removes all its listeners. target.on('dispose', () => { target.off(); + [target, target.el_, target.eventBusEl_].forEach(function(val) { + if (val && DomData.has(val)) { + DomData.delete(val); + } + }); window.setTimeout(() => { target.eventBusEl_ = null; }, 0); diff --git a/test/unit/mixins/evented.test.js b/test/unit/mixins/evented.test.js index 54d3e30b2f..0e392f6fe0 100644 --- a/test/unit/mixins/evented.test.js +++ b/test/unit/mixins/evented.test.js @@ -2,8 +2,10 @@ import sinon from 'sinon'; import evented from '../../../src/js/mixins/evented'; import log from '../../../src/js/utils/log'; +import DomData from '../../../src/js/utils/dom-data'; import * as Dom from '../../../src/js/utils/dom'; import * as Obj from '../../../src/js/utils/obj'; +import * as Events from '../../../src/js/utils/events.js'; // Common errors thrown by evented objects. const errors = { @@ -569,3 +571,31 @@ QUnit.test('off() can remove a listener from an array of events on a different t target: b.eventBusEl_ }); }); + +QUnit.test('Removes DomData on dispose', function(assert) { + const el_ = Dom.createEl('div'); + const eventBusEl_ = Dom.createEl('span', {className: 'vjs-event-bus'}); + const target = evented({el_, eventBusEl_}, {eventBusKey: 'eventBusEl_'}); + + assert.equal(DomData.get(eventBusEl_).handlers.dispose.length, 1, 'event bus has dispose handler'); + assert.notOk(DomData.get(target), 'evented obj has no handlers'); + assert.notOk(DomData.get(el_), 'evented el_ has handlers'); + + target.on('foo', () => {}); + + assert.equal(DomData.get(eventBusEl_).handlers.foo.length, 1, 'foo handler added to bus'); + + Events.on(eventBusEl_, 'bar', () => {}); + assert.equal(DomData.get(eventBusEl_).handlers.bar.length, 1, 'bar handler added to bus'); + + Events.on(el_, 'foo', () => {}); + assert.equal(DomData.get(el_).handlers.foo.length, 1, 'foo handler added to el_'); + + Events.on(target, 'foo', () => {}); + assert.equal(DomData.get(target).handlers.foo.length, 1, 'foo handler added to evented object'); + + target.trigger('dispose'); + assert.notOk(DomData.get(eventBusEl_), 'eventBusEl_ DomData deleted'); + assert.notOk(DomData.get(target), 'evented object DomData deleted'); + assert.notOk(DomData.get(el_), 'el_ DomData deleted'); +});