summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorChristophe Matthieu <chm@odoo.com>2016-09-01 15:26:41 +0200
committerGéry Debongnie <ged@odoo.com>2016-11-04 14:07:35 +0100
commita8e79e960aa962b4b89710918a03a5983bf492c6 (patch)
tree92d5dcc5685adf5c49c64d7b8e2d1d644470409c /addons/web/static/src
parent3cb337945628ffc243072c93a47f6fc55d0f03fd (diff)
[FIX] bus,im_odoo_support, web*: fix various memory leaks
* Tip are never destroyed when change view mode * unbind methods * mail: memory leak with unbind methods * web: memory leak because 'ui-autocomplete' is never destroyed * web_editor: memory leak for wrong unbind on destroy * web: memory leak: must remove fileupload handler * bus: memory leak: correctly debind handlers on window in bus.Bus * remove handlers on switch buttons and views $buttons * remove handlers on breadcrumbs * web: memory leak: correctly debind handlers * im_odoo_support: memory leak: remove fileupload handler odoo_support Note: part of this commit was actually authored by aab
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/js/control_panel.js19
-rw-r--r--addons/web/static/src/js/framework/view.js6
-rw-r--r--addons/web/static/src/js/view_manager.js8
-rw-r--r--addons/web/static/src/js/views/form_relational_widgets.js3
-rw-r--r--addons/web/static/src/js/views/form_view.js7
-rw-r--r--addons/web/static/src/js/views/graph_view.js6
-rw-r--r--addons/web/static/src/js/views/list_view.js2
-rw-r--r--addons/web/static/src/js/views/pivot_view.js6
-rw-r--r--addons/web/static/src/js/widgets/sidebar.js4
9 files changed, 56 insertions, 5 deletions
diff --git a/addons/web/static/src/js/control_panel.js b/addons/web/static/src/js/control_panel.js
index 18a03d8d55c..dba2ea0bb2a 100644
--- a/addons/web/static/src/js/control_panel.js
+++ b/addons/web/static/src/js/control_panel.js
@@ -77,6 +77,10 @@ var ControlPanel = Widget.extend({
return this._super();
},
+ destroy: function() {
+ this._clear_breadcrumbs_handlers();
+ return this._super.apply(this, arguments);
+ },
/**
* @return {Object} the Bus the ControlPanel is listening on
*/
@@ -109,7 +113,9 @@ var ControlPanel = Widget.extend({
// Render the breadcrumbs
if (status.breadcrumbs) {
- new_cp_content.$breadcrumbs = this._render_breadcrumbs(status.breadcrumbs);
+ this._clear_breadcrumbs_handlers();
+ this.$breadcrumbs = this._render_breadcrumbs(status.breadcrumbs);
+ new_cp_content.$breadcrumbs = this.$breadcrumbs;
}
// Detach control_panel old content and attach new elements
@@ -205,6 +211,17 @@ var ControlPanel = Widget.extend({
}
},
/**
+ * Private function that removes event handlers attached on the currently
+ * displayed breadcrumbs.
+ */
+ _clear_breadcrumbs_handlers: function () {
+ if (this.$breadcrumbs) {
+ _.each(this.$breadcrumbs, function ($bc) {
+ $bc.off();
+ });
+ }
+ },
+ /**
* Private function that updates the SearchView's visibility and extend the
* breadcrumbs area if the SearchView is not visible
* @param {openerp.web.SearchView} [searchview] the searchview Widget
diff --git a/addons/web/static/src/js/framework/view.js b/addons/web/static/src/js/framework/view.js
index b234d02390f..bc06d062819 100644
--- a/addons/web/static/src/js/framework/view.js
+++ b/addons/web/static/src/js/framework/view.js
@@ -258,6 +258,12 @@ var View = Widget.extend({
get_context: function () {
return {};
},
+ destroy: function () {
+ if (this.$buttons) {
+ this.$buttons.off();
+ }
+ return this._super.apply(this, arguments);
+ },
});
return View;
diff --git a/addons/web/static/src/js/view_manager.js b/addons/web/static/src/js/view_manager.js
index 2ae53aabb22..d23d68d0f93 100644
--- a/addons/web/static/src/js/view_manager.js
+++ b/addons/web/static/src/js/view_manager.js
@@ -413,6 +413,14 @@ var ViewManager = Widget.extend(ControlPanelMixin, {
}
this.active_view.controller.do_load_state(state, warm);
},
+ destroy: function () {
+ if (this.control_elements) {
+ if (this.control_elements.$switch_buttons) {
+ this.control_elements.$switch_buttons.off();
+ }
+ }
+ return this._super.apply(this, arguments);
+ },
});
return ViewManager;
diff --git a/addons/web/static/src/js/views/form_relational_widgets.js b/addons/web/static/src/js/views/form_relational_widgets.js
index be926614bda..61ffc70631a 100644
--- a/addons/web/static/src/js/views/form_relational_widgets.js
+++ b/addons/web/static/src/js/views/form_relational_widgets.js
@@ -101,6 +101,9 @@ var FieldMany2One = common.AbstractField.extend(common.CompletionFieldMixin, com
delete this.$dropdown;
}
if (this.$input) {
+ if (this.$input.data('ui-autocomplete')) {
+ this.$input.autocomplete("destroy");
+ }
this.$input.closest(".modal .modal-content").off('scroll');
this.$input.off('keyup blur autocompleteclose autocompleteopen ' +
'focus focusout change keydown');
diff --git a/addons/web/static/src/js/views/form_view.js b/addons/web/static/src/js/views/form_view.js
index 80fc6bdfa59..27753aab766 100644
--- a/addons/web/static/src/js/views/form_view.js
+++ b/addons/web/static/src/js/views/form_view.js
@@ -116,6 +116,9 @@ var FormView = View.extend(common.FieldManagerMixin, {
if (this.$el) {
this.$el.off('.formBlur');
}
+ if (this.$pager) {
+ this.$pager.off();
+ }
this._super();
},
load_form: function(data) {
@@ -242,9 +245,7 @@ var FormView = View.extend(common.FieldManagerMixin, {
return;
}
var action = $el.data('pager-action');
- var def = $.when(self.execute_pager_action(action));
- $el.attr("disabled");
- def.always(function() {
+ $.when(self.execute_pager_action(action)).always(function() {
$el.removeAttr("disabled");
});
});
diff --git a/addons/web/static/src/js/views/graph_view.js b/addons/web/static/src/js/views/graph_view.js
index 3ab3ddc31b3..1ef5eab879f 100644
--- a/addons/web/static/src/js/views/graph_view.js
+++ b/addons/web/static/src/js/views/graph_view.js
@@ -130,6 +130,12 @@ var GraphView = View.extend({
this.widget.set_measure(this.active_measure);
}
},
+ destroy: function () {
+ if (this.$buttons) {
+ this.$buttons.find('button').off(); // remove jquery's tooltip() handlers
+ }
+ return this._super.apply(this, arguments);
+ },
});
core.view_registry.add('graph', GraphView);
diff --git a/addons/web/static/src/js/views/list_view.js b/addons/web/static/src/js/views/list_view.js
index 3e01ea0c4f6..9d758111c15 100644
--- a/addons/web/static/src/js/views/list_view.js
+++ b/addons/web/static/src/js/views/list_view.js
@@ -280,7 +280,7 @@ var ListView = View.extend( /** @lends instance.web.ListView# */ {
if (!this.$buttons) {
this.$buttons = $(QWeb.render("ListView.buttons", {'widget': this}));
- this.$buttons.find('.o_list_button_add').click(this.proxy('do_add_record'));
+ this.$buttons.on('click', '.o_list_button_add', this.proxy('do_add_record'));
$node = $node || this.options.$buttons;
if ($node) {
diff --git a/addons/web/static/src/js/views/pivot_view.js b/addons/web/static/src/js/views/pivot_view.js
index c1752cbe10e..a3649da9d7f 100644
--- a/addons/web/static/src/js/views/pivot_view.js
+++ b/addons/web/static/src/js/views/pivot_view.js
@@ -814,6 +814,12 @@ var PivotView = View.extend({
error: crash_manager.rpc_error.bind(crash_manager)
});
},
+ destroy: function () {
+ if (this.$buttons) {
+ this.$buttons.find('button').off(); // remove jquery's tooltip() handlers
+ }
+ return this._super.apply(this, arguments);
+ },
});
function traverse_tree(root, f, arg1, arg2, arg3) {
diff --git a/addons/web/static/src/js/widgets/sidebar.js b/addons/web/static/src/js/widgets/sidebar.js
index 9ea15be128b..63f418b4e4a 100644
--- a/addons/web/static/src/js/widgets/sidebar.js
+++ b/addons/web/static/src/js/widgets/sidebar.js
@@ -52,6 +52,10 @@ var Sidebar = Widget.extend({
event.preventDefault();
});
},
+ destroy: function() {
+ $(window).off(this.fileupload_id);
+ return this._super.apply(this, arguments);
+ },
redraw: function() {
var self = this;
self.$el.html(QWeb.render('Sidebar', {widget: self}));