-
-
Notifications
You must be signed in to change notification settings - Fork 96
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
fix(event-manager): shadow dom event bubbling #758
fix(event-manager): shadow dom event bubbling #758
Conversation
Delegate events should be able to pass shadow dom boundry similar to native events. Closes aurelia#755
8d25fac
to
7563566
Compare
@bigopon Here's a small PR to fix the shadow dom boundry event bubbling issue |
We definitely need this in some form. I had to implement some custom stuff for my own vNext app because this doesn't work quite right with link clicks and routing, for example. So, I think we need a fix in the core and also some fix in the router....and we need to port it all to vNext. Two thoughts:
|
@EisenbergEffect Where would such a flag be implemented? Would this be something global? On the alternatives, lets brainstorm:
I think instanceof might be the only feasible and more elegant option . |
It could be implemented as a boolean property on the |
I think the combination of cc @fkleuver for awareness |
|
I've changed the string check to an I need some assistance for the boolean/setting. How would a dev set this bool? I'm a bit confused how to properly pass the setting from an app all the way down to the code handling the event bubbling. |
I think instanceof check combined with a existance check is pretty ok. About the bool check, let me have a look tonight |
@bigopon Did you have time to have a look at how I could introduce a flag? It would be awesome if I could wrap up this PR. |
We have class DelegateHandlerEntry {
constructor(eventName) {
this.eventName = eventName;
this.count = 0;
}
increment() {
this.count++;
if (this.count === 1) {
DOM.addEventListener(this.eventName, handleDelegatedEvent, false);
}
}
decrement() {
if (this.count === 0) {
emLogger.warn('The same EventListener was disposed multiple times.');
} else if (--this.count === 0) {
DOM.removeEventListener(this.eventName, handleDelegatedEvent, false);
}
}
} We can change the constructor to accept 1 more parameter, that it will determine if it should check for shadow root, and then we can change handler from a loose function, to event listener object: class DelegateHandlerEntry {
constructor(eventName, escapeShadowRoot) {
this.eventName = eventName;
this.count = 0;
this.escapeShadowRoot = escapeShadowRoot;
}
handleEvent(event) {
// this will be this instance
// so we can get the escapeShadowRoot value
}
increment() {
this.count++;
if (this.count === 1) {
// use this as handler, instead
DOM.addEventListener(this.eventName, this, false);
}
}
decrement() {
if (this.count === 0) {
emLogger.warn('The same EventListener was disposed multiple times.');
} else if (--this.count === 0) {
// use this to remove handler instead
DOM.removeEventListener(this.eventName, this, false);
}
}
} Though will need some more tests for these changes. Are you comfortable with writing tests for those changes? |
@bigopon Thanks for the input but I'm still a bit confused how an Aurelia app would pass this bool to the constructor. How does the consuming app set this to |
@michaelw85 During start up, one would do this: aurelia.container.get(EventManager).escapeShadowRoot = true; then we change the code here: Line 280 in b42630b
to this.defaultEventStrategy = new DefaultEventStrategy(this); So later, we could change here Line 180 in b42630b
Line 200 in b42630b
- handlerEntry = capturedHandlers[targetEvent] || (capturedHandlers[targetEvent] = new CapturedHandlerEntry(targetEvent));
+ handlerEntry = capturedHandlers[targetEvent] || (capturedHandlers[targetEvent] = new CapturedHandlerEntry(targetEvent, this.eventManager.escapeShadowRoot)); |
ok thanks I could give this a try. |
@michaelw85 after |
Only option I could think of as an alternative is to only read the option once at startup from the aurelia config. This would prevent any changes during run time. |
@michaelw85 we can do it that way by having the setter ignore 2nd and after assignment. Cc @EisenbergEffect @fkleuver for making a call with us |
I'm pretty ok with keeping it simple and letting people do this: aurelia.container.get(EventManager).escapeShadowRoot = true; While there is technically a possibility for things to stomp on each other, it seems unlikely. |
@bigopon Sorry it took a while I had to finish some other work first but here it is. |
@EisenbergEffect This PR is still waiting for review, could someone be assigned? |
Oops, seems like its my turn to slack. Ill review it tonight. Sorry for that. First glance is it needs some modification |
@michaelw85 nice 👍 . Can you help give |
Changing The dist files are not ignored at the moment should they be? Should I revert the changed of the dist in this PR or do you really mean delete? But I guess same question applies here is this related to this PR else I would prefer keeping it out of this one. |
Well, i just realized the title of this PR, so I think your argument is fair, and in agile spirit. We probably can go ahead with this. Just need to make @EisenbergEffect @fkleuver aware of this. |
Ok great lets finish this PR. If you create tasks/placeholders for the other changes just mention me and I will create PR's. |
The @michaelw85 If you can remove the dist folder from this PR, that would be great. |
@EisenbergEffect @bigopon I've reverted the dist changes as requested. |
Thanks @michaelw85 and @bigopon Doing a quick review now. This is technically a breaking change, but I somehow doubt that it's going to affect anyone. Does anyone here have concerns? Do we need to put this behind a flag? |
Doh. I see we did put a flag there. Just ignore me. Doing final review now...turning on my thinking cap. |
Add escapeShadowRoot to d.ts Related: aurelia#758 aurelia#755
Delegate events should be able to pass shadow dom boundry similar to native
events.
Closes #755