diff --git a/addons/web/static/src/js/chrome/action_manager.js b/addons/web/static/src/js/chrome/action_manager.js index 9221561f2d9..934473109a3 100644 --- a/addons/web/static/src/js/chrome/action_manager.js +++ b/addons/web/static/src/js/chrome/action_manager.js @@ -185,13 +185,17 @@ var ViewManagerAction = WidgetAction.extend({ * @param {int} [scrollTop] the number of pixels to scroll */ setScrollTop: function(scrollTop) { - this.widget.active_view.controller.setScrollTop(scrollTop); + var viewController = this.widget.active_view.controller; + if (viewController) { + viewController.setScrollTop(scrollTop); + } }, /** * @return {int} the number of pixels the webclient is scrolled when leaving the action */ getScrollTop: function() { - return this.widget.active_view.controller.getScrollTop(); + var viewController = this.widget.active_view.controller; + return viewController ? viewController.getScrollTop() : 0; }, /** * @return {Array} array of Objects that will be interpreted to display the breadcrumbs @@ -340,6 +344,16 @@ var ActionManager = Widget.extend({ // Hide the main ControlPanel for widgets that do not use it self.main_control_panel.do_hide(); } + + // most of the time, the self.$el element should already be empty, + // because we detached the old action just a few line up. However, + // it may happen that it is not empty, for example when a view + // manager was unable to load a view because of a crash. In any + // case, this is done as a safety measure to avoid the 'double view' + // situation that we had when the web client was unable to recover + // from a crash. + self.$el.empty(); + dom.append(self.$el, new_widget_fragment, { in_DOM: self.is_in_DOM, callbacks: [{widget: self.inner_widget}], diff --git a/addons/web/static/src/js/chrome/view_manager.js b/addons/web/static/src/js/chrome/view_manager.js index 02250d5cc15..d8f0e3776d9 100644 --- a/addons/web/static/src/js/chrome/view_manager.js +++ b/addons/web/static/src/js/chrome/view_manager.js @@ -59,7 +59,8 @@ var ViewManager = Widget.extend(ControlPanelMixin, { */ on_detach_callback: function() { this.is_in_DOM = false; - if (this.active_view && this.active_view.controller.on_detach_callback) { + var controller = this.active_view && this.active_view.controller; + if (controller && controller.on_detach_callback) { this.active_view.controller.on_detach_callback(); } }, @@ -282,7 +283,7 @@ var ViewManager = Widget.extend(ControlPanelMixin, { view.$fragment = view.$fragment.contents(); view.loaded.resolve(); }); - }); + }).fail(view.loaded.reject.bind(view.loaded)); } else { view.loaded = view.loaded.then(function() { view_options = _.extend({}, view_options, self.env);