From b83db271354ee8ecabf4a39c96f3a187dd5535d5 Mon Sep 17 00:00:00 2001 From: MOENS Alexandre Date: Tue, 21 Aug 2018 12:00:49 +0200 Subject: [PATCH] [FIX] web: JournalDashboardGraph widget crash Mk.II Hardening of commit:995610c065bf0242cb5023cfad2940234395739e The JournalDashboardGraph requires nv, which is lazyloaded. However it requires nvd3.js which is loaded after nv.d3.js. A function called in destroy is defined by nv.d3.js, which can make the crashhappen with the right (wrong) timing. opw 1873749 --- .../web/static/src/js/fields/basic_fields.js | 2 +- .../static/tests/fields/basic_fields_tests.js | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index d624651ac85..71aab9f7992 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -2055,7 +2055,7 @@ var JournalDashboardGraph = AbstractField.extend({ return this._super.apply(this, arguments); }, destroy: function () { - if ('nv' in window) { + if ('nv' in window && nv.utils && nv.utils.offWindowResize) { // if the widget is destroyed before the lazy loaded libs (nv) are // actually loaded (i.e. after the widget has actually started), // nv is undefined, but the handler isn't bound yet anyway diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js index fade0282f69..1133bed08b5 100644 --- a/addons/web/static/tests/fields/basic_fields_tests.js +++ b/addons/web/static/tests/fields/basic_fields_tests.js @@ -1902,6 +1902,45 @@ QUnit.module('basic_fields', { assert.verifySteps(['destroy']); }); + QUnit.test('graph dashboard widget can be destroyed when nv is partially loaded', function (assert) { + // this test ensures that the JournalDashboardGraph widget doesn't crash + // when being destroyed before nv has been completely loaded + assert.expect(2); + + testUtils.patch(basicFields.JournalDashboardGraph, { + destroy: function () { + assert.step('destroy'); + // nv is fully loaded only when nvd3.js has been loaded + // which happens sequentially after nv.d3.js + // we simulate this race condition with: + var offWindowResize = window.nv.utils.offWindowResize; + window.nv.utils.offWindowResize = undefined; + this._super.apply(this, arguments); + window.nv.utils.offWindowResize = offWindowResize; + }, + }); + + var kanban = createView({ + View: KanbanView, + model: 'partner', + data: this.data, + arch: '' + + '' + + '' + + '
' + + '' + + '
' + + '
' + + '
', + domain: [['id', 'in', [1]]], + }); + + kanban.destroy(); + testUtils.unpatch(basicFields.JournalDashboardGraph); + + assert.verifySteps(['destroy']); + }); + QUnit.module('AceEditor'); QUnit.test('ace widget on text fields works', function (assert) {