diff --git a/src/g-component.html b/src/g-component.html
index 1c88059674..8185b0aa41 100644
--- a/src/g-component.html
+++ b/src/g-component.html
@@ -87,7 +87,8 @@
function instanceReady() {
// delegate host events
- bindHostEvents.call(this.$protected);
+ //bindHostEvents.call(this.$protected);
+ accumulateHostEvents.call(this.$protected, this.__events);
// TODO(sjmiles): ideally delegated events are set up per root
// not on the host node (see above)
bindAccumulatedEvents(this, this.__events);
@@ -303,7 +304,7 @@
propertySetChanged: function(inChange, inWatched) {
if (inChange.mutation == 'add') {
//log.watch && console.log('[%s] propertySetChanged: adding watch for [%s]', this.node.localName, inChange.propertyName);
- api.addWatch.call(this, inChange.propertyName, inWatched);
+ api.addWatch.call(this, inChange.propertyName, null, inWatched);
//this.propertyChanged(inChange.propertyName);
}
},
@@ -442,14 +443,14 @@
}.bind(this), inTimeout || 0);
},
dispatch: function(inMethodName, inArguments) {
- // TODO(sjmiles): have 'controller' dispatch this method itself
if (this[inMethodName]) {
this[inMethodName].apply(this, inArguments);
}
},
- send: function(inType, inDetail) {
- log.events && console.log('[%s]: sending [%s]', this.node.localName, inType);
- this.node.dispatchEvent(
+ send: function(inType, inDetail, inToNode) {
+ var node = inToNode || this.node;
+ log.events && console.log('[%s]: sending [%s]', node.localName, inType);
+ node.dispatchEvent(
new CustomEvent(inType, {bubbles: true, detail: inDetail})
);
},
@@ -736,12 +737,15 @@
var dispatch = function(inNode, inHandlerName, inArguments) {
if (inNode && inNode.$protected) {
+ log.events && console.group('[%s] dispatch [%s]', inNode.localName, inHandlerName);
inNode.$protected.dispatch(inHandlerName, inArguments);
+ log.events && console.groupEnd();
}
};
// automagic host-event binding
+ /*
var bindHostEvents = function() {
// TODO(sjmiles): must walk the prototype tree
// to bind the superset of eventDelegate maps
@@ -764,7 +768,38 @@
inNode.addEventListener(inEventName, fn);
log.events && console.log('[%s] bindHostEvent: [%s] to [%s]', inNode.localName, inEventName, inHandler);
};
+ */
+ var accumulateHostEvents = function(inEvents) {
+ // TODO(sjmiles): must walk the prototype tree to operate on the union of
+ // eventDelegates maps
+ var p = this;
+ while (p) {
+ if (p.hasOwnProperty('eventDelegates')) {
+ for (var n in p.eventDelegates) {
+ inEvents[n] = 1;
+ //bindHostEvent(this.node, n, p.eventDelegates[n]);
+ }
+ }
+ p = p.__proto__;
+ }
+ };
+
+ var findHostHandler = function(inEventName) {
+ // TODO(sjmiles): walking the tree again is inefficient; combine with code
+ // in accumulateHostEvents into something more sane
+ var p = this;
+ while (p) {
+ if (p.hasOwnProperty('eventDelegates')) {
+ var h = p.eventDelegates[inEventName];
+ if (h) {
+ return h;
+ }
+ }
+ p = p.__proto__;
+ }
+ };
+
//
// new experimental late bound events
//
@@ -807,29 +842,50 @@
}
};
+ // TODO(sjmiles): lots of work on the code here as we bash out a design
+ // we like, cruftiness increasing in the process. Will be cleaned up when
+ // design solidifies.
function __(inEvent) {
- var on = prefix + inEvent.type;
- log.events && console.group("[%s]: __ [%s]", this.localName, on);
+ inEvent.on = prefix + inEvent.type;
+ //var on = prefix + inEvent.type;
+ log.events && console.group("[%s]: __ [%s]", this.localName, inEvent.on);
var t = inEvent.target;
while (t && t != this) {
t = deref(t);
- log.events && console.dir(t);
- if (t.attributes) {
- var h = t.getAttribute(on);
- if (h) {
- var c = findController(t);
- log.events && console.log('found handler [%s] for controller', h, c);
- if (c == this) {
- log.events && console.log('invoking [%s]', h);
- if (this.$protected[h]) {
- this.$protected[h](inEvent, inEvent.detail, t);
- }
- }
+ var c = findController(t);
+ if (c == this) {
+ log.events && console.log('node [%s]', t.localName);
+ handleHostEvent.call(this, t, inEvent);
+ handleEvent.call(this, t, inEvent);
+ if (inEvent.cancelBubble) {
+ return;
}
}
t = t.parentNode;
}
+ // if we are a top-level component, we have to fire our own host events
+ if (t == this && !findController(t)) {
+ handleHostEvent.call(this, t, inEvent);
+ }
log.events && console.groupEnd();
};
+
+ function handleEvent(inNode, inEvent) {
+ if (inNode.attributes) {
+ var h = inNode.getAttribute(inEvent.on);
+ if (h) {
+ log.events && console.log('[%s] found handler name [%s]', this.localName, h);
+ dispatch(this, h, [inEvent, inEvent.detail, inNode]);
+ }
+ }
+ };
+
+ function handleHostEvent(inNode, inEvent) {
+ var h = findHostHandler.call(inNode.$protected, inEvent.type);
+ if (h) {
+ log.events && console.log('[%s] found host handler name [%s]', inNode.localName, h);
+ dispatch(inNode, h, [inEvent, inEvent.detail, inNode]);
+ }
+ };
\ No newline at end of file
diff --git a/src/g-selector.html b/src/g-selector.html
index 3ca4224bcf..b94a82f179 100644
--- a/src/g-selector.html
+++ b/src/g-selector.html
@@ -5,7 +5,7 @@
* license that can be found in the LICENSE file.
*/
-->
-
+