mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
first working version of fixed event bugs
This commit is contained in:
@@ -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];
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -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.
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
},
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -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();
|
||||
@@ -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() {
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user