This change allows users to blacklist only some keys on a website.
These keys are not suppressed and the corresponding VimFx command is not executed.
Blacklist rules can now be of the form `<pattern>##<keyString1>#<keyString2>`.
Existing rules not using this syntax will continue to work.
Simon Lydell [Tue, 30 Sep 2014 19:17:04 +0000 (21:17 +0200)]
Try points one pixel into the elements from the edges
On newyorker.com, `transform: translate3d(0, 0, 0)` is applied on the
content container, to force hardware acceleration. It seems to move
everything a pixel, causing `document.elementFromPoint` to fail at the
edges of elements. This commit no longer looks exactly at the edges of
elements, but one pixel in, which seems to be a safer strategy. (The
marker is still nicely placed exactly on the edge, though.)
Example page:
http://www.newyorker.com/currency-tag/the-virtual-moleskine
Simon Lydell [Tue, 30 Sep 2014 18:51:27 +0000 (20:51 +0200)]
Improve markers for inline line-wrapped elements
If an inline line-wrapped element starts with a line break, its first
rect will have an area of almost zero. The marker used to end up on that
rect, seemingly on the line before the actual link, which was very
confusing. Now, such small areas are rounded to zero, and all
`visibleRects` that have a zero area are discarded, solving the problem.
An example can be found at the bottom of this page:
http://swrevisited.wordpress.com/esbr-facts/
Simon Lydell [Wed, 10 Sep 2014 19:01:04 +0000 (21:01 +0200)]
Improve marker placement and fix related bug
Before commit 89e1bc4 we used to recursively search the rect of an
element until it found a non-covered point; after that commit we changed
into only checking 6 simple locations of the element, for performance
reasons. However, this meant two problems:
- It was very confusing when markers ended up to the far right of
elements. Sometimes it was difficult to understand which element the
marker actually belonged to. Sometimes a tiny bit of the left side of
an element was covered (possible by a _transparent_ element!) causing
the marker to end up on the right instead, seemingly for no reason.
- Some elements are overlapped by one pixel both on the left and right
side (such as the github pagination links), causing no marker at all
to appear.
The solution is to use the best of both before the referenced commit and
after it. Now we check 3 (instead of 6) simple places: Only the 3 on the
left side. If the place is covered by another element, we try once to
the right of that element. So in total there may be 6 attempts, just as
before.
Author: Simon Lydell <simon.lydell@gmail.com>
Date: Sat Aug 2 16:01:36 2014 +0200
Improve marker generation performance
`getFirstNonCoveredPoint` used to recursively search the rect of an
element until it found a non-covered point. This works well most of the
time, but on some sites (such as prisjakt.se) it took way too much time.
Moreover, this technique required some CSS to be reset in a few special
cases, which is very costly performance-wise. It is also brittle and
makes the code unnecessarily complex.
Lastly, there was a bug in the algorithm that caused uncaught exceptions
sometimes (such as on youtube.com).
Now we use a much simpler approach instead.
`getFirstNonCoveredPoint` tries 6 different points of the element:
If all of those are covered (or are reported as covered because of one
of the CSS special cases we used to reset) then the whole element is
simply considered to be covered. This seems to work really well.
The above means that the markers can now be placed at any of the points
in the above figure.
The result is much faster, simpler and more robust.
Simon Lydell [Sun, 7 Sep 2014 17:42:20 +0000 (19:42 +0200)]
Improve coding style
- Almost all code is now wrapped at 80 chars, except a few special cases
such as the `commands = [...]` block in commands.coffee. I didn’t
bother to go through help.coffee and window-utils.coffee too much
since they need rewrites anyway.
- Consistent use of parenthesis when calling functions.
- Consistent use of single quotes over double quotes.
- Consistent spacing.
- Removed unused or unnecessary code.
- Refactored unload.coffee into unloader.coffee, which should be easier
to understand.
- Comments are now full sentences.
- This also fixes a few very minor bugs.
I’ve deliberately left out mode-hints/{hints,marker}.coffee to avoid
large merge conflicts with #330.
Simon Lydell [Sat, 16 Aug 2014 15:54:35 +0000 (17:54 +0200)]
Enhance marker frame handling
Previously the frame elements themselves were required to get a marker
in order to make markers for any elements inside the frame, which was
pretty confusing. Now all frames visible in the viewport are gone
through to add markers their elements.
Simon Lydell [Wed, 13 Aug 2014 19:38:36 +0000 (21:38 +0200)]
Fix #366: Allow autofocus when switching back to a tab
If a text input is focused and you switch to another window or tab
Firefox blurs the text input. When you switch back to the tab, Firefox
automatically focuses the text input again. Those focus events should be
allowed.
Kambfhase [Sat, 2 Aug 2014 21:23:59 +0000 (23:23 +0200)]
updates german locale
Localised some more UI strings to german. However, some descriptions are
still in english and not all translations are displayed. The latter will
be investigated separately.
Simon Lydell [Sat, 2 Aug 2014 14:01:36 +0000 (16:01 +0200)]
Improve marker generation performance
`getFirstNonCoveredPoint` used to recursively search the rect of an
element until it found a non-covered point. This works well most of the
time, but on some sites (such as prisjakt.se) it took way too much time.
Moreover, this technique required some CSS to be reset in a few special
cases, which is very costly performance-wise. It is also brittle and
makes the code unnecessarily complex.
Lastly, there was a bug in the algorithm that caused uncaught exceptions
sometimes (such as on youtube.com).
Now we use a much simpler approach instead.
`getFirstNonCoveredPoint` tries 6 different points of the element:
If all of those are covered (or are reported as covered because of one
of the CSS special cases we used to reset) then the whole element is
simply considered to be covered. This seems to work really well.
The above means that the markers can now be placed at any of the points
in the above figure.
The result is much faster, simpler and more robust.
Simon Lydell [Sun, 27 Jul 2014 10:33:52 +0000 (12:33 +0200)]
Fix #103: Make image zoom toggle keyboard accessible
When navigating directly to an image, and the image does not fit the
screen, it is re-sized so it does. The mouse cursor becomes a magnifying
glass when hovering the image. By clicking you can toggle between native
and re-sized.
As discussed in #355, to keep things simple we now make such images
markable. Using the default mappings and hintchars, the shortcut to
toggle zoom then becomes 'ff'.
This commit is based on #104 by @LordJZ.
Example image:
<http://upload.wikimedia.org/wikipedia/commons/e/e2/Rain_ot_ocean_beach.jpg>
Simon Lydell [Thu, 19 Jun 2014 21:17:54 +0000 (23:17 +0200)]
Only allow focus events immediately after an interaction
Replace the autofocus prevention with suppressing _all_ focus events
that didn’t happen directly after an interaction (keypress or click)
with the page.
Strictly speaking, autofocus may only happen during page load, which
means that we should only prevent focus events during page load.
However, it is very difficult to reliably determine when the page load
ends. Moreover, a page may load very slowly. Then it is likely that the
user tries to focus something before the page has loaded fully.
Therefore focus events that aren’t reasonably close to a user
interaction (click or key press) are blurred (regardless of whether the
page is loaded or not -- but that isn’t so bad: if the user doesn’t like
autofocus, he doesn’t like any automatic focusing, right? This is
actually useful on devdocs.io). There is a slight risk that the user
presses a key just before an autofocus, causing it not to be blurred,
but that’s not likely. Lastly, the autofocus prevention is restricted to
`<input>` elements, since only such elements are commonly autofocused.
Many sites have buttons which inserts a `<textarea>` when clicked (which
might take up to a second) and then focuses the `<textarea>`. Such focus
events should _not_ be blurred.
The wide rectangle belongs to the `<p>` while the other belongs to the
`<a>`. The top and bottom part of the `<a>` rectangle, outside of the
`<p>` rectangle (because the `font-size` of `<a>` is larger than the
`line-height`), are hidden due to `overflow: hidden;`.
`document.elementFromPoint()` will only return `<a>` in the area covered
by both rectangles. That is a problem since we start looking at the
top-left corner of the `<a>` rectangle, which will return whatever is
behind.
The solution is to add `line-height: normal;` temporarily to `<a>`,
causing the following (with a comparison to the right):
Simon Lydell [Sun, 15 Jun 2014 14:10:52 +0000 (16:10 +0200)]
Improve find mode. Fix #342. Better Esc handling.
Previously, find mode only worked if you used VimFx's shortcuts to enter
it. If you opened the find bar some other way, you weren't able to end
the search using Enter, and the n/N commands wouldn't repeat what you
just searched for. Now, find mode is entered as soon as the findbar
input gets focused, no matter how it was focused. Find mode is also
exited as soon as the findbar input is blurred. Previously, if you
happened to unfocus the findbar without using Esc or Enter, such as
clicking or tabbing away, then you'd still be in find mode, making all
keypresses focus the findbar input rather than activate commands.
If the active element is editable during a keypress we used to pass that
keypress along to the browser -- regardless of the current mode --
instead of activating commands. The findbar input is also an editable
element, but when it is focused we want Enter to close the findbar.
Therefore we used to not pass along Enter to the browser. If the user
mapped Enter to a command, that meant that it would be impossible to
press enter in an input to type a newline, submit a search query, etc.
Now, we only use this automatic insert mode in normal mode instead.
The above also fixed another problem. We used to always pass Esc to the
browser in normal mode, even if Esc is mapped to a command. Now, that is
not done if we’re blurring an element. That makes it possible to blur an
input inside a custom dialog without closing it (Esc almost always
closes custom dialogs). This makes it possible to use devdocs.io with
VimFx, which was very difficult before.
> - 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.