-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
[post-1.46] Enable link hints for all elements with click listeners + support jQuery delegated events, and drop some legacy link hint conditions #1409
Conversation
…ests for filtered link hint mode
100c63a
to
2b476cf
Compare
markChildrenThatHaveDelegatedOnClickListener: (element) -> | ||
return unless element.hasAttribute "vimium-jquery-delegated-events-selectors" | ||
|
||
selectorsStr = element.getAttribute "vimium-jquery-delegated-events-selectors" |
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 could be rewritten to avoid 2 DOM calls, remove some redundancy:
selectorsStr = element.getAttribute "vimium-jquery-delegated-events-selectors"
return unless selectorsStr?
I'd purposely left this out since it bloats the PR, and doesn't add much value. I can't think of many situations where an element will remain in the DOM and visible but have its click event listener removed. Maybe work on this in a separate branch, so we can consider the merits of the I've left a few comments on the code for you to take a look over. |
…ts, that only have delegated events assigned philc#1404
… a container to hold delegated events for children philc#1404
… are listened with deprecated `.live()` function (jQuery 1.7+) philc#1404
…where delegated event listener has been removed
…egated' events don't affect each other
2b476cf
to
712df45
Compare
Thanks for the comments, they have been addressed. In regards of And that's the reason I also don't want to create a separate PR for it -- if you look at those commits separately, you will not be convinced that it is an important change to merge. While here... well, it is sort of a part of the issue. And the code amount is small, comparing to other changes: 10 lines of But if you believe this brings too much risk, I'm fine to delete these 3 commits. |
…elegated onclick listeners
712df45
to
d8c0f65
Compare
selectors = selectorsStr.split("|").filter (x) -> !!x | ||
|
||
for selector in selectors | ||
for child in element.querySelectorAll(selector) |
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.
I have been running this for a while, it is wrong to use querySelectorAll
here. Selectors were extracted from jQuery's .on()
function, and jQuery supports more kinds of selectors than querySelectorAll
(it uses Sizzle in some cases).
An example I found on trello.com is the following selector: a[href=#]
.
jQuery returns some links, while querySelectorAll
throws an exception.
Now, it sounds safe to use jQuery defined on a page — it is definitely defined as we reach this function, we don't bother if jQuery treats same selectors differently in different versions, etc.
But it seems like we cannot access jQuery, defined on the page, from the content script... Is that right, @mrmr1993?
If that's true, what would be the best way to handle this situation?
I can easily think of the following approaches:
- Catch
querySelectorAll
's exceptions and simply ignore those selectors. - Introduce jQuery (or Sizzle) as a part of vimium distribution.
But I like neither of them 😄
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.
it seems like we cannot access jQuery, defined on the page, from the content script... Is that right, @mrmr1993?
Unfortunately it is. I would send a custom event from the content script and mark the elements we want when we catch it in the injected code. Obviously then we can resume code execution in link hints with another custom event.
Since a lot of the time we don't have to do this, we should also only send the event when we have a querySelector
match on the delegated event selector.
The code here unmarks elements which have
(or similar) which still have a click listener. I'd rather err on the side of overreporting clickable elements, so maybe separating this out until the implementation is right would be better. For this, querying Edit: I didn't notice you'd already done |
Ping @z0rch, can you take a look at my comments here? |
Sorry for the silence, I agree with both comments, just didn't have time to look into that last week. However I do have time this week 😄 |
This PR is based on @mrmr1993's #1405, with added fix for #1404.
Currently
addEventListener()
andjQuery.on()
are hooked to provide missing link hints..live()
is based on.on()
since jQuery v1.7 (which was released in Nov. 2011), so it is hooked as well.I decided not to spend time on supporting older versions.
Ideally, it would be nice to hook
removeEventListener()
andjQuery.off()
as well -- I'll look into this later.jQuery.off()removeEventListener()UPDATE (done):
There is a bug with number of link hints appearing when listeners for both "normal" and "delegated" events are assigned on the same element. Corresponding test is currently disabled.I'll look more into that, but you are more than welcome to provide an early feedback for this PR.UPDATE 2: Agreed not to touch
removeEventListener()
andjQuery.off()
in this PR since we cannot properly handle all cases.#1408 is also fixed as a part of this PR, as I used that functionality to create new tests. It appeared to be simply a missing setup data.