From 8dcd08d3c4decdf896ecc2ba2bfe7c660bd10da9 Mon Sep 17 00:00:00 2001 From: Akira Sudoh Date: Mon, 30 Mar 2020 11:00:29 +0900 Subject: [PATCH] fix(data-table): ensure cleaning-up events This change ensure Carbon handle management API is used for attaching events in vanilla data table, to avoid orphaned events. Fixes #5742. --- .../src/components/data-table/data-table.js | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/packages/components/src/components/data-table/data-table.js b/packages/components/src/components/data-table/data-table.js index 67bdce3027b8..7366b3f22936 100644 --- a/packages/components/src/components/data-table/data-table.js +++ b/packages/components/src/components/data-table/data-table.js @@ -10,14 +10,17 @@ import mixin from '../../globals/js/misc/mixin'; import createComponent from '../../globals/js/mixins/create-component'; import initComponentBySearch from '../../globals/js/mixins/init-component-by-search'; import eventedState from '../../globals/js/mixins/evented-state'; +import handles from '../../globals/js/mixins/handles'; import eventMatches from '../../globals/js/misc/event-matches'; +import on from '../../globals/js/misc/on'; const toArray = arrayLike => Array.prototype.slice.call(arrayLike); class DataTable extends mixin( createComponent, initComponentBySearch, - eventedState + eventedState, + handles ) { /** * Data Table @@ -54,30 +57,27 @@ class DataTable extends mixin( this.refreshRows(); - this.element.addEventListener('mouseover', evt => { - const eventElement = eventMatches(evt, this.options.selectorChildRow); + this.manage(on(this.element, 'mouseover', this._expandableHoverToggle)); + this.manage(on(this.element, 'mouseout', this._expandableHoverToggle)); - if (eventElement) { - this._expandableHoverToggle(eventElement, true); - } - }); - - this.element.addEventListener('click', evt => { - const eventElement = eventMatches(evt, this.options.eventTrigger); - const searchContainer = this.element.querySelector( - this.options.selectorToolbarSearchContainer - ); + this.manage( + on(this.element, 'click', evt => { + const eventElement = eventMatches(evt, this.options.eventTrigger); + const searchContainer = this.element.querySelector( + this.options.selectorToolbarSearchContainer + ); - if (eventElement) { - this._toggleState(eventElement, evt); - } + if (eventElement) { + this._toggleState(eventElement, evt); + } - if (searchContainer) { - this._handleDocumentClick(evt); - } - }); + if (searchContainer) { + this._handleDocumentClick(evt); + } + }) + ); - this.element.addEventListener('keydown', this._keydownHandler); + this.manage(on(this.element, 'keydown', this._keydownHandler)); this.state = { checkboxCount: 0, @@ -225,8 +225,11 @@ class DataTable extends mixin( }; _actionBarToggle = toggleOn => { + let handleTransitionEnd; const transition = evt => { - this.batchActionEl.removeEventListener('transitionend', transition); + if (handleTransitionEnd) { + handleTransitionEnd = this.unmanage(handleTransitionEnd).release(); + } if (evt.target.matches(this.options.selectorActions)) { if (this.batchActionEl.dataset.active === 'false') { @@ -245,7 +248,9 @@ class DataTable extends mixin( this.batchActionEl.classList.remove(this.options.classActionBarActive); } if (this.batchActionEl) { - this.batchActionEl.addEventListener('transitionend', transition); + handleTransitionEnd = this.manage( + on(this.batchActionEl, 'transitionend', transition) + ); } }; @@ -288,19 +293,14 @@ class DataTable extends mixin( }); }; - _expandableHoverToggle = element => { - element.previousElementSibling.classList.add( - this.options.classExpandableRowHover - ); - - const mouseout = () => { - element.previousElementSibling.classList.remove( - this.options.classExpandableRowHover + _expandableHoverToggle = evt => { + const element = eventMatches(evt, this.options.selectorChildRow); + if (element) { + element.previousElementSibling.classList.toggle( + this.options.classExpandableRowHover, + evt.type === 'mouseover' ); - element.removeEventListener('mouseout', mouseout); - }; - - element.addEventListener('mouseout', mouseout); + } }; _toggleState = (element, evt) => {