summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js
diff options
context:
space:
mode:
authorGéry Debongnie <ged@odoo.com>2015-04-21 09:52:17 +0200
committerAaron Bohy <aab@odoo.com>2015-05-15 09:16:34 +0200
commita9522cb46ffc750faece04bb2cb96fa2b22a7131 (patch)
treed202c8dccb9ed5f75c711619bfbcf2f8c27696bc /addons/web/static/src/js
parent97a5eee0ac8930ef3d533182e8eaaf0e2909c6f4 (diff)
[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.
Diffstat (limited to 'addons/web/static/src/js')
-rw-r--r--addons/web/static/src/js/framework/mixins.js26
-rw-r--r--addons/web/static/src/js/framework/widget.js17
2 files changed, 43 insertions, 0 deletions
diff --git a/addons/web/static/src/js/framework/mixins.js b/addons/web/static/src/js/framework/mixins.js
index 68c19f6b9f4..e9f9b2c94b0 100644
--- a/addons/web/static/src/js/framework/mixins.js
+++ b/addons/web/static/src/js/framework/mixins.js
@@ -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) {
diff --git a/addons/web/static/src/js/framework/widget.js b/addons/web/static/src/js/framework/widget.js
index ad68f4e9410..f606e8482ca 100644
--- a/addons/web/static/src/js/framework/widget.js
+++ b/addons/web/static/src/js/framework/widget.js
@@ -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');
},