Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use existing add/removeEventListener for elements #146

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Conversation

matthewp
Copy link
Contributor

@matthewp matthewp commented Feb 7, 2017

This makes it possible to use can-define with HTML elements so that both
property events and DOM events can be listened to and fire correctly.

The method for doing this is to call to the existing addEventListener
if one exists, otherwise to do the default action of calling to
eventLifecycle.addAndSetup.

Closes #145

This tries defering to the element's own addEventListener.
@@ -281,7 +283,7 @@ make = {
if (newVal !== current) {
setData.call(this, newVal);

canEvent.dispatch.call(this, {
canEvent.trigger.call(this, {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should make this .emit eventually to comply with event-emitter like apis.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This a problem, using .trigger makes computes not work (because domDispatch calls the handlers like DOM event handlers and canEvent.dispatch calls them like compute handler).

So I'm not sure how to fix this without checking to see if the event is for a property or not.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think you should also make this listen able via .on 👍

can-define.js Outdated
@@ -719,6 +719,14 @@ define.setup = function(props, sealed) {
};
define.replaceWith = replaceWith;
define.eventsProto = eventsProto;
define.addBaseEvents = function(objPrototype){
objPrototype._baseEvents = objPrototype.addEventListener &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will _baseEvents be shared by everything?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_baseEvents is going to be shared by every instance of objPrototype. As can-event mutates this (it keeps event listeners on this) ... a single _baseEvents could be a problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow where the problem is, but ok, how else would you recommend doing this?

Copy link
Contributor Author

@matthewp matthewp Feb 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally did it was something like (inside of the eventsProto addEventListener):

var baseAddEventListener = this.__proto__.addEventListener &&
this.__proto__.addEventListener !== eventsProto.addEventListener ?
 this.__proto__.addEventListener :
eventLifecycle.addAndSetup;

return baseAddEventListener.apply(this, arguments);

But it seemed wasteful to do this check every time addEventListener is called when it can be established when the type is created. But it would get around having to put an object on the prototype.

@matthewp
Copy link
Contributor Author

matthewp commented Feb 7, 2017

Going to do this first: canjs/can-event#30

And then update this PR to use that.

This makes it possible to use can-define with HTML elements so that both
property events and DOM events can be listened to and fire correctly.

This is done by using the can-event/lifecycle/lifecycle mixin, and
passing it our existing addEventListener (where it exists), rather than
using canEvent.addEventListener as lifecycle did before.

Closes #145
Upgrading to can-event 3.1.0 makes it possible to implement the event
lifecycle stuff.
@matthewp
Copy link
Contributor Author

Not quite ready to merge, there's still an issue here.

This demonstrates that using computes doesn't work with this approach.
The reason is that domDispatch works differently than canEvent.dispatch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants