> - Only `<a>` elements with a `href` attribute should be matched, since
> HTML5 allows `<a>` elements to omit `href`:
>
> > If the a element has no href attribute, then the element represents
> > a placeholder for where a link might otherwise have been placed, if
> > it had been relevant, consisting of just the element's contents.
>
> Reference:
> <http://developers.whatwg.org/text-level-semantics.html#the-a-element>
That’s the spec. In the reality, people use all sorts of weird markup.
Some sites (such as StackExchange sites) leave out the `href` property
and use the anchor as a JavaScript-powered button (instead of just using
the `button` element).
This commit reverts the change to link matching in be94b559b. A side
effect is that sites using links without `href` in compliance with the
spec will get extranous markers for those links. It’s better to show too
many markers than too few, though.
Simon Lydell [Sun, 1 Jun 2014 18:59:35 +0000 (20:59 +0200)]
Fix: Autofocus prevention got stuck by navigating the history
Either going forward and backward in the history, or using
`history.pushState()` caused the autofocus prevention to get stuck,
making it impossible to focus inputs.
> - We used to take care of the case where markable elements have no area
> since all of the children are floated and/or absolutely positioned.
> For performance I’ve removed that. Let’s re-add it if we find some
> website that needs it. The old implementation used the computed style
> for this, which has turned out to be really slow.
Since then I _have_ found such cases. A link in a menu could contain a
span of text floated to the left and an icon floated to the right.
So I’ve re-added support. Best of all, with better performance than the
old implementation; computed style is _not_ used.
It turns out that if the width _and_ the height of an element is 0 (thus
making the area 0, too) it is really hidden. But if only one of the
width and height is 0 (also making the area 0), then it is because
everything inside it is floated and/or absolutely positioned (and that
`element` hasn’t been made to “contain” the floats). Then there’s no
need to check any computed style. Just recursively test each child until
a visible one is found and return its shape instead of the parent.
The reasoning behind choosing the first visible child is as follows:
- It’s the best bet for the cases with menu items I found. We want the
marker at the beginning of the menu item. The text spans, floated to
the left, are likely the first children.
- We _could_ add the same hint to _all_ the visible children. But that’s
a bad idea for a couple of reasons:
- It would be inconsistent with all other elements. Even elements with
an area can contain floated elements, which are also clickable. But
those do not get any hints. (It would be too expensive
performance-wise to give them hints, for no real benefit.) Therefore
we shouldn’t do it in this case either.
- In the found cases with menu items we only want _one_ hint, for the
whole menu item. We should optimize for the likely cases.
- It would be unnecessarily complex and slow.
Simon Lydell [Fri, 30 May 2014 09:29:36 +0000 (11:29 +0200)]
Improve marker generation. Fix #325.
- Elements covered by other elements do no longer get hints. This makes
it easier to use drop-down menus when there are lots of links behind
it.
- Elements partly outside the screen now get hints, too.
- Partly covered elements get hints, too. The hint is placed in the
first non-covered point of the element.
- Line-wrapped links now get their hint in a better place. This is
easiest to explain with a picture. # = old hint location, * = new hint
location (approximately)
#---------+
| *Line-|
|wrapped |
+---------+
Such links also used to count the whole of that box as its area. Now
only the actual text is counted, giving the marker a more fair weight.
- We used to take care of the case where markable elements have no area
since all of the children are floated and/or absolutely positioned.
For performance I’ve removed that. Let’s re-add it if we find some
website that needs it. The old implementation used the computed style
for this, which has turned out to be really slow.
- We used to check if elements were hidden with CSS (if `opacity: 0;` or
`visibility: hidden;`), but we don’t anymore, since it noticeably
slows down the marker creation (checking computed styles is slow). It
does not appear to be necessary anymore. It was added to fix #164, but
the problems there now seem fixed even without this check.
- The code should be more documented now than before.
- The performance is better than before. It does not seem like the new
algorithms are slower. And since I’ve removed two slow areas, it might
be a little faster.
Simon Lydell [Sun, 25 May 2014 20:15:41 +0000 (22:15 +0200)]
Raise the z-indexes used to trump youtube
Youtube uses 1999999999 as z-index for its top bar, which is a lot
higher than VimFx used for the help dialog and markers. This caused the
top bar to overlap the help dialog, and, more importantly, the markers,
making it impossible to see the marker for the search box, for example.
This commit raises VimFx’s z-indexes to trump Youtube.
Simon Lydell [Sun, 25 May 2014 19:20:56 +0000 (21:20 +0200)]
Fix #309: Autofocus prevention is broken
Autofocus was broken by some Firefox update, possibly version 29. This
commit fixes it again. It also fixes a bug where autofocus was prevented
even on blacklisted sites, and cleans the code a bit.
Simon Lydell [Fri, 16 May 2014 18:49:38 +0000 (20:49 +0200)]
Slightly improve markable element matching
- Only `<a>` elements with a `href` attribute should be matched, since
HTML5 allows `<a>` elements to omit `href`:
> If the a element has no href attribute, then the element represents
> a placeholder for where a link might otherwise have been placed, if
> it had been relevant, consisting of just the element's contents.
- Elements with the `tabindex` attribute should be matched, but not
`tabindex=-1`, which means explicitly saying that the element should
_not_ be focusable.
Simon Lydell [Fri, 16 May 2014 18:42:31 +0000 (20:42 +0200)]
Let the Esc command close tab groups
Since commit 1fd30eca9 makes opening the tab groups view (ctrl-shift-e)
about the same as focusing a text input (passing all key strokes to the
browser), the Esc command must be able to exit from it.
Simon Lydell [Fri, 16 May 2014 18:26:16 +0000 (20:26 +0200)]
Fix #280: Use `[rel]` for prev/next link matching
The standard way of marking up the previous or next page of a series is
to use a `<link>` or `<a>` element with a `rel` attribute.
We don’t bother with `<link>`s since the commands are substitutes for
clicking a visible element. (And at least in my experience, they’re not
commonly used.) Moreover, if there’s a `<link>` with a `rel` attribute,
there’s likely a corresponding `<a>`, too.
We first try to find a nicely marked up link, then we fall back on
pattern matching of the text contents of the links.
The spec on the `rel` attribute:
<http://www.w3.org/TR/html5/links.html#linkTypes>
How Google handles it:
<https://support.google.com/webmasters/answer/1663744?hl=en>
Simon Lydell [Tue, 13 May 2014 19:40:54 +0000 (21:40 +0200)]
Fix #318: Support Tab Groups
Just like when a text input is focused, send all keys to the browser.
This allows you to type the name of a tab to select it. Moreover,
commands doesn’t make sense when Tab Groups is opened, since they affect
the current tab, which is hidden _behind_ Tab Groups, out of view!
Simon Lydell [Sun, 26 Jan 2014 14:21:07 +0000 (15:21 +0100)]
Refactor follow prev/next links
- Simplified everything.
- Made it more DRY.
- Patterns can include the * and ! wildcards, just like the black list.
- Patterns must match either at the beginning or at the end of the link
text.
- Patterns don’t match in the middle of words. Works with non-English
characters too.
Simon Lydell [Tue, 28 Jan 2014 18:52:29 +0000 (19:52 +0100)]
Improve popup passthrough check performance
Commit 468ed83 sure made the popup passthrough check more robust.
However, querying for all popups (hundreds) and looping them through on
each keypress is not optimal for performance. The solution? Use the best
of both of the old and new passthrough check.
Looking back, the issue with the old event-based passthrough check was
not that passthrough sometimes wasn’t triggered. It was that passthrough
sometimes got stuck, effectively disabling the extension. So it is not
the 'popupshowing' event that is unreliable, it is the 'popuphidden'
event. So we now use the events for toggling passthrough mode, just like
before. But when `popupPassthrough == true`, we don’t trust it. Then we
loop through all popups to see if any of them actually is open. This
means that it is only when a popup (might) be open that we use the more
expensive check, which is a good tradeoff. Even then, you probably won’t
even notice a lag or anything.