From: Evert Timberg Date: Mon, 14 Dec 2020 10:03:08 +0000 (-0500) Subject: Prevent double plugin registers from losing the list of plugins (#8162) X-Git-Tag: v3.0.0-beta.8~70 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=93c3467182474f89c4931326d4846a42ea3a5862;p=thirdparty%2FChart.js.git Prevent double plugin registers from losing the list of plugins (#8162) When `Chart.register()` was called twice in a row, the list of plugin descriptors on the chart instance would be cleared. The next chart update would then restart all of the plugins, not knowing that they were already started. In the case of the Legend and Title, this causes two boxes to appear in the layout system thus drawing twice. --- diff --git a/src/core/core.plugins.js b/src/core/core.plugins.js index 91e3c61a4..5ebd25fa0 100644 --- a/src/core/core.plugins.js +++ b/src/core/core.plugins.js @@ -1,5 +1,6 @@ import defaults from './core.defaults'; import registry from './core.registry'; +import {isNullOrUndef} from '../helpers'; import {callback as callCallback, mergeIf, valueOrDefault} from '../helpers/helpers.core'; /** @@ -58,8 +59,15 @@ export default class PluginService { } invalidate() { - this._oldCache = this._cache; - this._cache = undefined; + // When plugins are registered, there is the possibility of a double + // invalidate situation. In this case, we only want to invalidate once. + // If we invalidate multiple times, the `_oldCache` is lost and all of the + // plugins are restarted without being correctly stopped. + // See https://github.com/chartjs/Chart.js/issues/8147 + if (!isNullOrUndef(this._cache)) { + this._oldCache = this._cache; + this._cache = undefined; + } } /** diff --git a/test/specs/core.plugin.tests.js b/test/specs/core.plugin.tests.js index c709846d1..af93dc53a 100644 --- a/test/specs/core.plugin.tests.js +++ b/test/specs/core.plugin.tests.js @@ -342,5 +342,24 @@ describe('Chart.plugins', function() { expect(plugin.hook).not.toHaveBeenCalled(); }); + + it('should not restart plugins when a double register occurs', function() { + var results = []; + var chart = window.acquireChart({ + plugins: [{ + start: function() { + results.push(1); + } + }] + }); + + Chart.register({id: 'abc', hook: function() {}}); + Chart.register({id: 'def', hook: function() {}}); + + chart.update(); + + // The plugin on the chart should only be started once + expect(results).toEqual([1]); + }); }); });