mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
start of Meteor UI Events
This commit is contained in:
@@ -650,4 +650,69 @@ var moveWithOwnersIntoTbody = function (range) {
|
||||
return tbody;
|
||||
};
|
||||
|
||||
///// EVENTS
|
||||
|
||||
// XXX could write the form of arguments for this function
|
||||
// in several different ways, including simply as an event map.
|
||||
DomRange.prototype.on = function (events, selector, handler) {
|
||||
var parentNode = this.parentNode();
|
||||
if (! parentNode)
|
||||
// if we're not in the DOM, silently fail.
|
||||
return;
|
||||
|
||||
var eventTypes = [];
|
||||
events.replace(/[^ /]+/g, function (e) {
|
||||
eventTypes.push(e);
|
||||
});
|
||||
|
||||
if (! handler && (typeof selector === 'function')) {
|
||||
// omitted `selector`
|
||||
handler = selector;
|
||||
selector = null;
|
||||
} else if (! selector) {
|
||||
// take `""` to `null`
|
||||
selector = null;
|
||||
}
|
||||
|
||||
for (var i = 0, N = eventTypes.length; i < N; i++) {
|
||||
var type = eventTypes[i];
|
||||
|
||||
var eventDict = parentNode.$_uievents;
|
||||
if (! eventDict)
|
||||
eventDict = (parentNode.$_uievents = {});
|
||||
|
||||
var info = eventDict[type];
|
||||
if (! info) {
|
||||
info = eventDict[type] = {};
|
||||
info.handlers = [];
|
||||
}
|
||||
var handlerRecord = {
|
||||
elem: parentNode,
|
||||
type: type,
|
||||
selector: selector,
|
||||
$ui: this.component,
|
||||
handler: handler
|
||||
};
|
||||
// It's important that lowLevelHandler be a different
|
||||
// instance for each handlerRecord, because its identity
|
||||
// is used to remove it. Capture handlerRecord in a
|
||||
// closure so that we have access to it, even when
|
||||
// the var changes, and so we don't pull in the rest of
|
||||
// the stack frame.
|
||||
handlerRecord.lowLevelHandler = (function (h) {
|
||||
return function (evt) {
|
||||
if ((! selector) && evt.currentTarget !== evt.target)
|
||||
// no selector means only fire on target
|
||||
return;
|
||||
return h.handler.call(h.$ui, evt);
|
||||
};
|
||||
})(handlerRecord);
|
||||
|
||||
info.handlers.push(handlerRecord);
|
||||
|
||||
$(parentNode).on(type, selector || '*',
|
||||
handlerRecord.lowLevelHandler);
|
||||
}
|
||||
};
|
||||
|
||||
UI.DomRange = DomRange;
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
var DomRange = UI.DomRange;
|
||||
var parseHTML = UI.DomBackend.parseHTML;
|
||||
|
||||
// fake component; DomRange host
|
||||
var Comp = function (which) {
|
||||
@@ -16,6 +17,18 @@ var isEndMarker = function (n) {
|
||||
return (n.$ui && n === n.$ui.dom.end);
|
||||
};
|
||||
|
||||
var inDocument = function (range, func) {
|
||||
var onscreen = document.createElement("DIV");
|
||||
onscreen.style.display = 'none';
|
||||
document.body.appendChild(onscreen);
|
||||
DomRange.insert(range.component, onscreen);
|
||||
try {
|
||||
func(range);
|
||||
} finally {
|
||||
document.body.removeChild(onscreen);
|
||||
}
|
||||
};
|
||||
|
||||
Tinytest.add("ui - DomRange - basic", function (test) {
|
||||
var r = new DomRange;
|
||||
r.which = 'R';
|
||||
@@ -593,6 +606,45 @@ Tinytest.add("ui - DomRange - tables", function (test) {
|
||||
test.equal(tbody.childNodes[4].nodeName, 'TR');
|
||||
});
|
||||
|
||||
Tinytest.add("ui - DomRange - basic events", function (test) {
|
||||
// test.equal doesn't work on arrays of DOM nodes, so
|
||||
// we need this. It's `===` that descends recursively
|
||||
// into any arrays.
|
||||
var arrayEqual = function (a, b) {
|
||||
test.equal(_.isArray(a), _.isArray(b));
|
||||
if (_.isArray(a)) {
|
||||
test.equal(a.length, b.length);
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
arrayEqual(a[i], b[i]);
|
||||
}
|
||||
} else {
|
||||
test.isTrue(a[i] === b[i]);
|
||||
}
|
||||
};
|
||||
|
||||
var htmlRange = function (html) {
|
||||
var r = new DomRange;
|
||||
_.each(parseHTML(html), function (node) {
|
||||
r.add(node);
|
||||
});
|
||||
return r;
|
||||
};
|
||||
|
||||
inDocument(
|
||||
htmlRange("<span>Foo</span>"),
|
||||
function (r) {
|
||||
var buf = [];
|
||||
|
||||
r.on('click', 'span', function (evt) {
|
||||
buf.push([evt.type, evt.target, evt.currentTarget]);
|
||||
});
|
||||
|
||||
arrayEqual(buf, []);
|
||||
var span = r.elements()[0];
|
||||
span.click();
|
||||
arrayEqual(buf, [['click', span, span]]);
|
||||
});
|
||||
});
|
||||
|
||||
// TO TEST STILL:
|
||||
// - external remove element
|
||||
|
||||
Reference in New Issue
Block a user