diff --git a/docs/guides/player-workflows.md b/docs/guides/player-workflows.md index f4dcfa54f2..491cf9ef2a 100644 --- a/docs/guides/player-workflows.md +++ b/docs/guides/player-workflows.md @@ -54,6 +54,10 @@ Additionally, these actions are recursively applied to _all_ the player's child > **Note**: Do _not_ remove players via standard DOM removal methods: this will leave listeners and other objects in memory that you might not be able to clean up! +### Checking if a Player is Disposed + +At times, it is useful to know whether or not a player reference in your code is stale. The `isDisposed()` method is available on all components (including players) for this purpose. + ### Signs of an Undisposed Player Seeing an error such as: diff --git a/src/js/component.js b/src/js/component.js index 7bf0ae6f63..cb84e798b7 100644 --- a/src/js/component.js +++ b/src/js/component.js @@ -58,6 +58,8 @@ class Component { this.player_ = player; } + this.isDisposed_ = false; + // Hold the reference to the parent component via `addChild` method this.parentComponent_ = null; @@ -124,6 +126,11 @@ class Component { */ dispose() { + // Bail out if the component has already been disposed. + if (this.isDisposed_) { + return; + } + /** * Triggered when a `Component` is disposed. * @@ -131,11 +138,13 @@ class Component { * @type {EventTarget~Event} * * @property {boolean} [bubbles=false] - * set to false so that the close event does not + * set to false so that the dispose event does not * bubble up */ this.trigger({type: 'dispose', bubbles: false}); + this.isDisposed_ = true; + // Dispose all children. if (this.children_) { for (let i = this.children_.length - 1; i >= 0; i--) { @@ -168,6 +177,16 @@ class Component { this.player_ = null; } + /** + * Determine whether or not this component has been disposed. + * + * @return {boolean} + * If the component has been disposed, will be `true`. Otherwise, `false`. + */ + isDisposed() { + return Boolean(this.isDisposed_); + } + /** * Return the {@link Player} that the `Component` has attached to. * diff --git a/test/unit/component.test.js b/test/unit/component.test.js index 0da9d90511..41928c779c 100644 --- a/test/unit/component.test.js +++ b/test/unit/component.test.js @@ -340,6 +340,7 @@ QUnit.test('should dispose of component and children', function(assert) { const child = comp.addChild('Component'); assert.ok(comp.children().length === 1); + assert.notOk(comp.isDisposed(), 'the component reports that it is not disposed'); // Add a listener comp.on('click', function() { @@ -370,6 +371,7 @@ QUnit.test('should dispose of component and children', function(assert) { !Object.getOwnPropertyNames(data).length, 'original listener data object was emptied' ); + assert.ok(comp.isDisposed(), 'the component reports that it is disposed'); }); QUnit.test('should add and remove event listeners to element', function(assert) {