Skip to content

Commit

Permalink
Merge pull request #392 from canjs/390-enter-event
Browse files Browse the repository at this point in the history
adds enter event delegation
  • Loading branch information
James Atherton committed Nov 30, 2017
2 parents c5ab5c1 + 70f81b4 commit f36c036
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 14 deletions.
20 changes: 20 additions & 0 deletions dom/events/delegate/delegate-test.js
Expand Up @@ -7,6 +7,7 @@ var domDispatch = require('../../dispatch/dispatch');
require('../inserted/inserted');
require('./delegate');
require('./enter-leave');
require('../enter/enter');

var QUnit = require('../../../test/qunit');
var isServer = require('../../../test/helpers').isServer;
Expand Down Expand Up @@ -113,4 +114,23 @@ if (supportsMatchesMethod) {
relatedTarget: div
}, [], true);
});

test("delegated custom events", 2, function () {
stop();
var frag = buildFrag("<div><input type='text'></div>");

var div = frag.firstChild;

document.getElementById('qunit-fixture').appendChild(div);

var handler = function(ev){
ok(true, "called");
domEvents.removeDelegateListener.call(div, "enter", "input", handler);
var dE = domData.get.call(this, "delegateEvents");
equal(dE, undefined, "data removed");
start();
};
domEvents.addDelegateListener.call(div, "enter", "input", handler);
domDispatch.call(div.firstChild, {type: "keyup", keyCode: 13}, [], true);
});
}
29 changes: 15 additions & 14 deletions dom/events/delegate/delegate.js
Expand Up @@ -5,6 +5,7 @@ var domData = require("../../data/data");
var domMatches = require("../../matches/matches");
var each = require("../../../js/each/each");
var isEmptyObject = require("../../../js/is-empty-object/is-empty-object");
var canCid = require("can-cid");

var dataName = "delegateEvents";

Expand Down Expand Up @@ -33,17 +34,17 @@ var useCapture = function(eventType) {
* el.appendChild(sub);
*
* function delegateEventsHandler() {
* console.log("delegate event fired");
* console.log("delegate event fired");
* }
*
* events.addDelegateListener.call(el, "click", ".foo", delegateEventsHandler, false);
*
* events.removeDelegateListener.call(el, "click", ".foo", delegateEventsHandler);
* ```
*/
var handleEvent = function(ev){
var handleEvent = function (overrideEventType, ev) {
var events = domData.get.call(this, dataName);
var eventTypeEvents = events[ev.type];
var eventTypeEvents = events[overrideEventType || ev.type];
// contains the element and the handlers to call back
var matches = [];

Expand All @@ -69,27 +70,26 @@ var handleEvent = function(ev){
});
cur = cur.parentNode;
} while (cur && cur !== ev.currentTarget);

}

// make sure `cancelBubble` is set
var oldStopProp = ev.stopPropagation;
ev.stopPropagation = function() {
oldStopProp.apply(this, arguments);
this.cancelBubble = true;
};
this.cancelBubble = true;
};

for(var i = 0; i < matches.length; i++) {
var match = matches[i];
var delegates = match.delegates;

for(var d = 0, dLen = delegates.length; d < dLen; d++) {
if( delegates[d].handler.call(match.target, ev) === false) {
if (delegates[d].handler.call(match.target, ev) === false) {
return false;
}
if (ev.cancelBubble) {
return;
}
return;
}
}
}
};
Expand All @@ -108,8 +108,6 @@ var handleEvent = function(ev){
* Delegate events are limited to firing in the bubble phase.
*/
domEvents.addDelegateListener = function(eventType, selector, handler) {


var events = domData.get.call(this, dataName),
eventTypeEvents;

Expand All @@ -120,7 +118,10 @@ domEvents.addDelegateListener = function(eventType, selector, handler) {
// if the first of that event type, bind
if (!(eventTypeEvents = events[eventType])) {
eventTypeEvents = events[eventType] = {};
domEvents.addEventListener.call(this, eventType, handleEvent, useCapture(eventType));

var delegateHandler = handleEvent.bind(this, eventType);
domData.set.call(this, canCid(handler), delegateHandler);
domEvents.addEventListener.call(this, eventType, delegateHandler, useCapture(eventType));
}

if (!eventTypeEvents[selector]) {
Expand All @@ -131,7 +132,6 @@ domEvents.addDelegateListener = function(eventType, selector, handler) {
handler: handler,
selector: selector
});

};

/**
Expand Down Expand Up @@ -165,7 +165,8 @@ domEvents.removeDelegateListener = function(eventType, selector, handler) {
delete eventTypeEvents[selector];
// if there are no more events for that eventType, unbind
if(isEmptyObject(eventTypeEvents)) {
domEvents.removeEventListener.call(this, eventType, handleEvent, useCapture(eventType));
var delegateHandler = domData.get.call(this, canCid(handler));
domEvents.removeEventListener.call(this, eventType, delegateHandler, useCapture(eventType));
delete events[eventType];
if(isEmptyObject(events)) {
domData.clean.call(this, dataName);
Expand Down

0 comments on commit f36c036

Please sign in to comment.