[IMP] web: introduces event bubbling in widgets

This commit adds event bubbling in the event dispatcher mixin (which
inherits from parentedmixins).  To do this, it introduces a new small
class 'OdooEvent', which register the target and if the event is stopped.

Also, widgets have a new 'custom_events' dictionary to easily register
callbacks like the event dictionary.
This commit is contained in:
Géry Debongnie
2015-05-15 09:16:34 +02:00
committed by Aaron Bohy
parent 97a5eee0ac
commit a9522cb46f
2 changed files with 43 additions and 0 deletions
@@ -114,6 +114,22 @@ var ParentedMixin = {
},
};
function OdooEvent (target, name, data) {
this.target = target;
this.name = name;
this.data = Object.create(null);
_.extend(this.data, data);
this.stopped = false;
}
OdooEvent.prototype.stop_propagation = function () {
this.stopped = true;
};
OdooEvent.prototype.is_stopped = function () {
return this.stopped;
};
/**
* Backbone's events. Do not ever use it directly, use EventDispatcherMixin instead.
*
@@ -256,6 +272,16 @@ var EventDispatcherMixin = _.extend({}, ParentedMixin, {
this.__edispatcherEvents.trigger.apply(this.__edispatcherEvents, arguments);
return this;
},
trigger_up: function(name, info) {
var event = new OdooEvent(this, name, info);
this._trigger_up(event);
},
_trigger_up: function(event) {
this.__edispatcherEvents.trigger(event.name, event);
if (!event.is_stopped() && (parent = this.getParent())) {
parent._trigger_up(event);
}
},
destroy: function() {
var self = this;
_.each(this.__edispatcherRegisteredEvents, function(event) {
@@ -64,6 +64,7 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, {
className: null,
attributes: {},
events: {},
custom_events: {},
/**
* The name of the QWeb template that will be used for rendering. Must be
* redefined in subclasses or the default render() method can not be used.
@@ -94,6 +95,7 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, {
}
// FIXME: this should not be
this.setElement(this._make_descriptive());
this.delegateCustomEvents();
},
/**
* Method called between init and start. Performs asynchronous calls required by start.
@@ -303,6 +305,21 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, {
}
}
},
delegateCustomEvents: function () {
if (_.isEmpty(this.custom_events)) { return; }
for (var key in this.custom_events) {
if (!this.custom_events.hasOwnProperty(key)) { continue; }
var method = this.proxy(this.custom_events[key]);
this.on(key, this, wrap_handler(method));
}
function wrap_handler(callback) {
return function (event) {
event.stop_propagation();
callback(event);
};
}
},
undelegateEvents: function () {
this.$el.off('.widget_events');
},