-
Notifications
You must be signed in to change notification settings - Fork 27.4k
fix(jqLite): fix event.stopImmediatePropagation() so it works as expected #4833
fix(jqLite): fix event.stopImmediatePropagation() so it works as expected #4833
Conversation
Hi @petebacondarwin. That PR and mine are just similar in concept, but not in scope. #4337 is about adding a way to immediate stop propagation of Kind regards. |
Seem like two different issues to me. Mine adds the stopImmediatePropagation feature to scopes where the other attempts to correct similar functionality on the DOM element level. Both are relevant. |
Rebased to latest code from master. |
I'm sorry, but I wasn't able to verify your CLA signature. CLA signature is required for any code contributions to AngularJS. Please sign our CLA and ensure that the CLA signature email address and the email address in this PR's commits match. If you signed the CLA as a corporation, please let me know the company's name. Thanks a bunch! PS: If you signed the CLA in the past then most likely the email addresses don't match. Please sign the CLA again or update the email address in the commit of this PR. |
Hi Igor. That's odd. I had signed the CLA before I first sent the PR, a month ago, using the very same email address. Anyway, I've just signed it again. My real name is Michael Benford. Kind regards. |
Rebased to latest master. |
I see the |
Are there any updates on this or is there a way to monkey patch this into jqLite in the meantime? |
Is there any update on this? |
+1 |
jqLite(a).on('click', function(e) { | ||
spyOn(e, 'stopPropagation'); | ||
e.stopImmediatePropagation(); | ||
expect(e.stopPropagation).toHaveBeenCalled(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this expectation is inside of a callback - such expectations are not guaranteed to be executed so it's better to refactor this by exposing the spy outside of the closure and moving the expectation after the browserTrigger call on line 926
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@IgorMinar That expectation can't be moved elsewhere because any overridden property/method (stopPropagation
, preventDefault
etc) are deleted after the on
method returns. So the only safe place I can access the event is inside that callback. I believe that's why there's another spec using that pattern as well.
I could use a flag spy in order to guarantee that the test will either pass or fail. What do you think about it?
I'm inclined to just document the differences between jqLite and jQuery and not merge this PR because don't know of any use-case that would absolutely need it. Angular core certainly doesn't need it and that's the primary customer for jqLite. jqLite has no aspiration to ever be full replacement for jQuery. The goal is to have the best of jQuery in a compact format that can be bundled with the core. On several occasions we had discussions that made us think that exposing jqLite publicly was a mistake, but I recognize that for small apps it's all they really need and big apps will almost always use jQuery anyway. So unless you can convince me that this is something that many or most apps need, I we should just go ahead and document the difference. |
@IgorMinar the problem as I see it, is that this is not a jquery feature, but a native DOM feature. It's exclusion breaks expected behavior. In our app, we use this to prevent directives that listen to keyboard events from triggering prematurely if another directive is also listening to the same key event. |
Hi Igor. @alexraginskiy has pretty much summed it up. That's why I've named this PR "fix" instead of "feature". In addition to that, jqLite currently exposes In case you guys decide not to fix the method, I think it should be either deleted or overridden to throw an exception so other people would be aware right away that they can't use it. |
Any updates on this issue? I see the PR is invalid right now and I could rebase it again on top of master, but I'd rather do it (and address Igor's comments on the code) if I know there's a chance for the PR to be eventually used. |
@caitp how do you feel about this one? |
jQuery's implementation does call the native event's I see that the 1.x tags are not calling native I think @mzgol might be a better one to ask about this though. |
Let's get this in guys. @mbenford can you please update this PR? |
@mzgol can you own this please? |
@IgorMinar Will do. |
Sure. |
jQuery 1.x did get this patch as well; it's just that currently Angular is tested on 1.10.x which doesn't have it. We'll soon be on jQuery 2.1.1, though, so it doesn't make much sense to update testing jQuery to 1.11.1 now. |
@mzgol Since this is going into v1.3, should I rebase the PR on a branch other than master? Or is master v1.3 already? |
you should rebase the PR against master, it's already bitrotten against master! don't worry about the rest |
@caitp Thanks. |
I've rebased my branch on top of master and addressed Igor's concerns on the code. I've also added support for the native |
@mbenford Ping? |
@mzgol Pong. :) I'm sorry for not having rebased this PR yet. I've been very busy lately, but I'll try to do it tonight. |
@mzgol Done. |
…cted jqLite doesn't override the default implementation of event.stopImmediatePropagation() and so it doesn't work as expected, i.e, it doesn't prevent the rest of the event handlers from being executed.
Refactor the spec for isDefaultPrevent method so it fails if the existing expectations aren't executed.
@mzgol Rebased again on top of master. |
Landed. Sorry for the delay! |
jqLite doesn't override the default implementation of
event.stopImmediatePropagation
and so it doesn't work as expected, i.e, it doesn't prevent the rest of the event handlers from being executed. I've fixed that for events handled withon
and triggered bytriggerHandler
.For the sake of consistency with jQuery, I've also added an
isImmediatePropagationStopped
function to the event object so one can tell whether the immediate propagation was stopped or not.Lastly, this implementation won't immediate stop propagation to event handlers created with
element.addEventListener
. I could have easily solved that by makingstopImmediatePropagation
call its native counterpart, but that would render it incompatible with jQuery's implementation. In order to comply with jQuery, I would have to add anoriginalEvent
property to the event object so one could calloriginalEvent.stopImmediatePropagation()
, but I've found it hard to correctly implement without making the code overly complex.