Skip to content

Commit

Permalink
first working version of fixed event bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
dgreensp committed Apr 26, 2012
1 parent 4583a9e commit e533a18
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 15 deletions.
45 changes: 44 additions & 1 deletion packages/liveui/liverange.js
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ Meteor.ui = Meteor.ui || {};
var startIndex = start_range_skip || 0;
var after = end.nextSibling;
for(var n = start; n && n !== after; n = n.nextSibling) {
var startData = tag && n[tag] && n[tag][0];
var startData = n[tag] && n[tag][0];
if (startData && startIndex < startData.length) {
// immediate child range that starts with n
var range = startData[startIndex];
Expand Down Expand Up @@ -550,4 +550,47 @@ Meteor.ui = Meteor.ui || {};
return result;
};

Meteor.ui._LiveRange.prototype.findParent = function(withSameContainer) {
var tag = this.tag;

if (this._end_idx + 1 < this._end[tag][1].length) {
// immediately enclosing range ends at same node as this one
return this._end[tag][1][this._end_idx + 1];
}

var node = this._end.nextSibling;
while (node) {
var endIndex = 0;
var startData = node[tag] && node[tag][0];
if (startData && startData.length) {
// skip over sibling of this range
var r = startData[0];
node = r._end;
endIndex = r._end_idx + 1;
}
if (endIndex < node[tag][1].length)
return node[tag][1][endIndex];
node = node.nextSibling;
}

if (withSameContainer)
return null;

return Meteor.ui._LiveRange.findRange(tag, this.containerNode());
};

Meteor.ui._LiveRange.findRange = function(tag, node) {
while (node) {
var endData = node[tag] && node[tag][1];
if (endData.length)
return endData[0];
node = node.nextSibling;
}

if (! node.parentNode)
return null;

return Meteor.ui._LiveRange.findRange(tag, node.parentNode);
};

})();
51 changes: 42 additions & 9 deletions packages/liveui/liveui.js
Original file line number Diff line number Diff line change
Expand Up @@ -419,19 +419,19 @@ Meteor.ui = Meteor.ui || {};
patcher.diffpatch(copyFunc);
});

attach_secondary_events(tgtRange);
};

Meteor.ui._wire_up = function(cx, range, html_func, react_data) {
// wire events
var data = react_data || {};
if (data.events) {
for(var n = range.firstNode();
n && n.previousSibling !== range.lastNode();
n = n.nextSibling) {
Meteor.ui._setupEvents(n, data.events, data.event_data);
}
range.events = data.events;
range.event_data = data.event_data;
}

attach_primary_events(range);

// record that if we see this range offscreen during a flush,
// we are to kill the context (mark it killed and invalidate it).
// Kill old context from previous update.
Expand Down Expand Up @@ -480,6 +480,10 @@ Meteor.ui = Meteor.ui || {};
in_range);
};

var renderElse = function() {
return Meteor.ui.render(else_func, react_data);
};

var callbacks = {
added: function(doc, before_idx) {
var frag = renderItem(doc);
Expand All @@ -491,15 +495,18 @@ Meteor.ui = Meteor.ui || {};
else
range_list[before_idx].insert_before(frag);

attach_secondary_events(range);

range_list.splice(before_idx, 0, range);
},
removed: function(doc, at_idx) {
if (range_list.length === 1)
if (range_list.length === 1) {
cleanup_frag(
outer_range.replace_contents(Meteor.ui.render(
else_func, react_data)));
else
outer_range.replace_contents(renderElse()));
attach_secondary_events(outer_range);
} else {
cleanup_frag(range_list[at_idx].extract());
}

range_list.splice(at_idx, 1);
},
Expand Down Expand Up @@ -561,4 +568,30 @@ Meteor.ui = Meteor.ui || {};
range.destroy(true);
};

// Attach events specified by `range` to top-level nodes in `range`.
var attach_primary_events = function(range) {
if (range.events) {
for(var n = range.firstNode();
n && n.previousSibling !== range.lastNode();
n = n.nextSibling) {
Meteor.ui._setupEvents(n, range.events, range.event_data);
}
}
};

// Attach events specified by enclosing ranges of `range`, at the
// same DOM level, to nodes in `range`.
var attach_secondary_events = function(range) {
for(var r = range; r; r = r.findParent(true)) {
if (r === range)
continue;

for(var n = range.firstNode();
n && n.previousSibling !== range.lastNode();
n = n.nextSibling) {
Meteor.ui._setupEvents(n, r.events, r.event_data);
}

}
};
})();
5 changes: 0 additions & 5 deletions packages/liveui/liveui_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -1225,13 +1225,11 @@ Tinytest.add("liveui - events", function(test) {
Meteor.flush();

// selector that specifies a top-level div
// FAILS in 0.3.3
event_buf.length = 0;
div = OnscreenDiv(Meteor.ui.render(function() {
return '<div id="foozy">Foo</div>';
}, {events: eventmap("click div")}));
simulateEvent(getid("foozy"), 'click');
test.expect_fail();
test.equal(event_buf, ['click div']);
div.kill();
Meteor.flush();
Expand All @@ -1248,7 +1246,6 @@ Tinytest.add("liveui - events", function(test) {

// replaced top-level elements still have event handlers
// even if not replaced by the chunk wih the handlers
// FAILS in 0.3.3
var R = ReactiveVar("p");
event_buf.length = 0;
div = OnscreenDiv(Meteor.ui.render(function() {
Expand All @@ -1262,13 +1259,11 @@ Tinytest.add("liveui - events", function(test) {
R.set("div"); // change tag, which is sure to replace element
Meteor.flush();
simulateEvent(getid("foozy"), 'click'); // still clickable?
test.expect_fail();
test.equal(event_buf, ['click']);
event_buf.length = 0;
R.set("p");
Meteor.flush();
simulateEvent(getid("foozy"), 'click');
test.expect_fail();
test.equal(event_buf, ['click']);
event_buf.length = 0;

Expand Down

0 comments on commit e533a18

Please sign in to comment.