The "real" tab elements are the rectangles to the left of the dotted vertical
lines. The triangle parts are made using the `::before` or `::after`
pseudo-elements of the tabs.
When calling `.elementFromPoint()` on a pseudo-element, its parent element is
returned. But calling `.getBoundingClientRect()` on the parent element returns a
rectangle only around the the parent element, excluding the pseudo-element.
Because of the pseudo-elements overlap the next tab, the second tab is
considered covered by the first tab.
Previously, a point to the right of the first tab would then be tried. But since
the pseudo-element isn't included in `.getBoundingClientRect()` that would mean
the point marked with a `+`, which is actually to the _left_ of the original
point, not to the right! That obviously didn't work.
With this commit, if the "try-right point" is to the left of the initial point
and the covering element and the queried element are in the same frame, the
point is tried again but this time forcing the element to be considered located
at that point, solving the issue.
Using pseudo-elements to create non-rectangular tabs is quite common, so this
will help on other sites as well.
Simon Lydell [Sun, 24 Jan 2016 09:22:55 +0000 (10:22 +0100)]
Remove check for 'close' class for clickable elements
It gave too many false positives because of the word 'closed' in many classes.
Instead of trying to switch to a regex to avoid those cases, I'm trying to
completely remove the check. Hopefully the other matching rules are enough.
Simon Lydell [Sat, 23 Jan 2016 18:31:37 +0000 (19:31 +0100)]
Remove hints and help on shutdown
Previously, if you disabled VimFx by using the `f` command to click VimFx's
"Disable" button in the Add-ons Manager, the hint markers would be left behind
(though losing their styling). This meant that the entire page would be covered
by a transparent element impossible to remove (other than closing the tab) and
impossible to click through.
A similar thing happened if you left the help dialog open in another tab while
disabling VimFx.
This commit makes sure that both those pieces of UI are removed on shutdown.
Simon Lydell [Thu, 21 Jan 2016 06:47:18 +0000 (07:47 +0100)]
Recognize more elements as clickable
- Elements with `data-` attributes used for clickable things by Bootstrap are
now recognized. This is a huge win since Bootstrap is very popular and many
developers use it with semantically unclickable elements (even though the
Bootstrap documentation always reminds of accessibility concerns). Since these
elements are or _should have been_ semantically clickable elements, they are
always treated as such, in order not to give them too bad hints.
- A few `aria-` attributes are now recognized as semantically clickable.
- ARIA roles are now treated as _semantically_ clickable, instead of just
clickable.
- "Close" buttons are now attempted to be recognized. This is useful for many of
those obtrusive EU cookie law notices. Recognizing Bootstrap elements also
helps greatly here.
- Finally, elements with 'click' event listeners (added using
`element.addEventListener('click', ...)`) are now recognized, by using a
Firefox API. This is really useful on DuckDuckGo's image search. Fixes #671
and fixes #672.
Note that event delegation is not supported, since that would require
inspecting the code of the event listeners. One _could_ inspect the global
`jQuery` object (if any) to get to solve that problem to a great extent (like
Firefox's devtools do), but I'm not sure if that's a good idea.
It should also be noted that I tried recognizing elements matching
`/\bjs-/.test(element.className)`, but that proved give too many false
positives.
Simon Lydell [Fri, 22 Jan 2016 06:40:01 +0000 (07:40 +0100)]
Never prevent autofocus in XUL pages
- Every time I go to `about:config` I wish that the filter field was focused.
- Even though `vim.markPageInteraction()` was called, the "click to go to
command" feature of the help dialog sometimes failed to autofocus the text
input for the command.
Thus, I think it's sensible to simply _not_ prevent autofocus in XUL pages. Such
pages are few and well-behaved (it seems).
Simon Lydell [Thu, 21 Jan 2016 16:34:04 +0000 (17:34 +0100)]
Improve autofocus prevention after `[` and `]`
When you go to the next page of GitHub’s code search results, the page is loaded
with AJAX. GitHub then annoyingly focuses its search input. This autofocus
cannot be prevented in a reliable way, because the case is indistinguishable
from a button whose job is to focus some text input. However, after the `[` and
`]` command we know for sure that we can prevent the next focus. This commit
resets the `vim.state.hasInteraction` flag in those commands to allow for this
behavior, by adding the `value=true` parameter to `vim.markPageInteraction()`
and passing in `false`.
Simon Lydell [Tue, 12 Jan 2016 08:13:55 +0000 (09:13 +0100)]
Fix misplaced hint markers when zoomed
Hint markers are supposed to be centered vertically on the non-covered point.
This didn't work properly when zoomed, but now does. For simplicity, that fix
removed the "make sure the marker stays within its element" constraint, which
turned out to be nice and more consistent. The hint markers are now _always_
centered vertically on the non-covered point, even for very small links.
This commit also fixes hint marker placement in the devtools when the devtools
have been independently zoomed. The above issue needed to be fixed before this
could be fixed. Fixes #667.
Simon Lydell [Mon, 11 Jan 2016 18:32:02 +0000 (19:32 +0100)]
Fix memory leak in non-multi-process Firefox
Apparently, 'overflow' and 'underflow' events in web page content can be caught
in UI listeners in non-multi-process. `event.target` of 'overflow' events in the
browser UI are saved as scrollable elements, which accidentaly included web page
elements as well. Holding on to such elements after their owner tab is closed
caused a memory leak (ghost windows). This commit checks that the overflown
elements really are UI elements before saving them.
Simon Lydell [Sat, 9 Jan 2016 16:39:07 +0000 (17:39 +0100)]
Fix `:hover` clearing on click in multi-process
Because clicks simulated by VimFx apparently cannot be caught in non-frame
listeners (which is good), _two_ real clicks were needed to clear `:hover`. This
commit fixes that, which allowed for a nice code cleanup. Instead, a temporary
hack is used for non-multi-process to make it work there.
Simon Lydell [Wed, 6 Jan 2016 13:22:25 +0000 (14:22 +0100)]
Lock `:hover` when clicking with the `f` commands
Fixes #388.
Note that this commit also adds `pointer-evets: none;` to the hints container,
allowing to generate hints for elements only visible because of the mouse
pointer hovering something. Getting hints for hover-menus opened by `zf` but not
for hover-menus opened by moving the mouse was too confusing. The reason
`pointer-events: none;` wasn’t added before was that it prevented from scrolling
while hints were shown. While that was nice, it was just an edge case that
doesn't really matter. It is better to allow hints for hover-menus.
Simon Lydell [Wed, 6 Jan 2016 09:40:50 +0000 (10:40 +0100)]
Improve element matching for the `zF` command
- Always exclude `<menuitem>`s. They are never clickable by VimFx. (This could
be seen in the Responsive Design View).
- Oddly, `<menuseparator>`s are considered focusable, but of course shouldn't
get hints. Now they don't anymore.
- Make sure that browser elements in the web page content area (such as in the
Responsive Design View) only show up when their containing tab is selected.
Simon Lydell [Wed, 30 Dec 2015 15:43:26 +0000 (16:43 +0100)]
Make 'frameCanReceiveEvents' more robust
Instead of using a combination of `.readyState in ['interactive', 'complete']`
and the 'DOMWindowCreated' event, only set 'frameCanReceiveEvents' to `true`
when `.readyState == 'complete'`. Also, set it to `false` on the 'pagehide'
event. This simplifies things a bit, and hopefully makes VimFx more responsive
on slowly-loading pages. See #588.
Simon Lydell [Mon, 21 Dec 2015 07:16:00 +0000 (08:16 +0100)]
Treat contenteditable elements as other text inputs
This lets `gi` focus contenteditable elements, which are often indistinguishable
from `<input>`s and `<textarea>`. It also allowed for some nice code cleanup.
Simon Lydell [Sun, 13 Dec 2015 10:03:19 +0000 (11:03 +0100)]
Improve the help dialog UX
- The search field is no longer autofocused. This is to allow the following
points. It also allows to try out commands while the dialog is open; see #619.
- The scrolling commands now scroll the help dialog if it is open (regardless of
whether it is scrollable or not, instead of confusingly scrolling the page
behind it).
- The search field is focused by pressing `/` (or `a/` or `g/`).
- The search field is hidden until focused, reducing the risk of it obscuring
text.
Simon Lydell [Wed, 9 Dec 2015 16:45:05 +0000 (17:45 +0100)]
Reset typed keys in "autoInsertMode"
Previously, if you typed for example a 'g' in a text input, click
outside it to unfocus, and then tried to use the `/` command, `g/` would be
triggered instead.
Simon Lydell [Tue, 8 Dec 2015 18:36:31 +0000 (19:36 +0100)]
Make it possible to scroll browser elements
The dev tools can contain scrollbars. This commit makes it possible to focus
such scrollable elements with `zF` and then scroll them using all of VimFx's
scrolling commands.