Skip to content

Instantly share code, notes, and snippets.

@leebyron
Created September 13, 2011 08:41
Show Gist options
  • Save leebyron/1213423 to your computer and use it in GitHub Desktop.
Save leebyron/1213423 to your computer and use it in GitHub Desktop.
Sorted Events
diff --git a/html/js/javelin/core/Event.js b/html/js/javelin/core/Event.js
index 94df448..0848521 100644
--- a/html/js/javelin/core/Event.js
+++ b/html/js/javelin/core/Event.js
@@ -267,7 +267,12 @@ JX.install('Event', {
/**
* @task info
*/
- nodes : {}
+ nodes : {},
+
+ /**
+ * @task info
+ */
+ nodeDistances : {}
},
/**
diff --git a/html/js/javelin/core/Stratcom.js b/html/js/javelin/core/Stratcom.js
index f44cc0d..33da9af 100644
--- a/html/js/javelin/core/Stratcom.js
+++ b/html/js/javelin/core/Stratcom.js
@@ -240,10 +240,12 @@ JX.install('Stratcom', {
dispatch : function(event) {
var path = [];
var nodes = {};
- var push = function(key, node) {
+ var distances = {};
+ var push = function(key, node, distance) {
// we explicitly only store the first occurrence of each key
if (!nodes.hasOwnProperty(key)) {
nodes[key] = node;
+ distances[key] = distance;
path.push(key);
}
};
@@ -262,23 +264,25 @@ JX.install('Stratcom', {
target = null;
}
+ var distance = 0;
var cursor = target;
while (cursor && cursor.getAttribute) {
- push('tag:' + cursor.nodeName.toLowerCase(), cursor);
+ push('tag:' + cursor.nodeName.toLowerCase(), cursor, distance);
var id = cursor.id;
if (id) {
- push('id:' + id, cursor);
+ push('id:' + id, cursor, distance);
}
var sigils = cursor.getAttribute('data-sigil');
if (sigils) {
sigils = sigils.split(' ');
for (var ii = 0; ii < sigils.length; ii++) {
- push(sigils[ii], cursor);
+ push(sigils[ii], cursor, distance);
}
}
+ ++distance;
cursor = cursor.parentNode;
}
@@ -294,6 +298,7 @@ JX.install('Stratcom', {
.setType(etype)
.setTarget(target)
.setNodes(nodes)
+ .setNodeDistances(distances)
.setPath(path.reverse());
// Don't touch this for debugging purposes
@@ -319,32 +324,52 @@ JX.install('Stratcom', {
}
var path = proxy.getPath();
+ var distances = proxy.getNodeDistances();
var len = path.length;
var hits = {};
+ var hitDistances = {};
var matches;
+ var distance;
for (var root = -1; root < len; ++root) {
matches = scope[(root == -1) ? this._auto : path[root]];
+
+ // use distance of target node (0) for cases where path is null
+ distance = (root == -1) ? 0 : (distances[path[root]] || 0);
+
if (matches) {
for (var ii = 0; ii < matches.length; ++ii) {
hits[matches[ii]] = (hits[matches[ii]] || 0) + 1;
+ // node in sigil set closest to target node
+ hitDistances[matches[ii]] =
+ Math.min(hitDistances[matches[ii]] || distance, distance);
}
}
}
- var exec = [];
+ var listeners = [];
for (var k in hits) {
if (hits[k] == this._need[k]) {
var handler = this._handlers[k];
if (handler) {
- exec.push(handler);
+ listeners.push({
+ distance: hitDistances[k],
+ handler: handler
+ });
}
}
}
+ // Sort listeners by sigil with the shortest distance from target node
+ if (distances) {
+ listeners.sort(function(a, b) {
+ return a.distance - b.distance;
+ });
+ }
+
this._execContext.push({
- handlers: exec,
+ listeners: listeners,
event: proxy,
cursor: 0
});
@@ -378,11 +403,11 @@ JX.install('Stratcom', {
pass : function() {
var context = this._execContext[this._execContext.length - 1];
var event = context.event;
- var handlers = context.handlers;
- while (context.cursor < handlers.length) {
+ var listeners = context.listeners;
+ while (context.cursor < listeners.length) {
var cursor = context.cursor++;
- if (handlers[cursor]){
- handlers[cursor](event);
+ if (listeners[cursor]) {
+ listeners[cursor].handler(event);
}
if (event.getStopped()) {
break;
@leebyron
Copy link
Author

After catching listeners whose sigil set match the event sigil path, sort them by closest matching sigil to the target node.

Then you can do something like:

<div data-sigil="one">
  <div data-sigil="two">
    <div data-sigil="three">
      <div>
        Click me
      </div>
    </div>
  </div>
</div>
JX.Stratcom.listen('click', ['one'], function() { console.log('1'); });
JX.Stratcom.listen('click', ['two'], function() { console.log('2'); });
JX.Stratcom.listen('click', ['three'], function() { console.log('3'); });
// Can specify both high priority (captures at target node)
JX.Stratcom.listen('click', null, function() { console.log('*'); });
// ...or low-priority (captures at window node) event catch-alls.
JX.Stratcom.listen('click', null, function() { if (!JX.Stratcom.pass()) { console.log('* low-pri'); } });

when clicked gives this response:

3
2
1

  • low-pri

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment