Simon Lydell [Sat, 14 May 2016 10:58:19 +0000 (12:58 +0200)]
Pin the coffee-script version
The very latest commits of coffee-script break coffeelint. This pins the
coffee-script dependency to a commit that both compiles VimFx and runs
coffeelint as intended.
Simon Lydell [Fri, 13 May 2016 06:05:03 +0000 (08:05 +0200)]
Fix frame scripts being loaded more than once sometimes
1. Open several tabs.
2. Set Firefox to remember your tabs between sessions.
3. Restart Firefox. All but the current tab will now be in a "pending"
(unloaded) state.
4. Update/re-install VimFx.
5. Visit one of the pending tabs.
Now, the frame script will be loaded _twice_ in that tab, which for
example causes `f` to produce double-clicks. This is especially
noticeable during development, when you update/re-install VimFx all the
time.
The reason is that Firefox does not seem to load frame scripts in
pending tabs immediately. Instead, the URI to the frame script we asked
to load is remembered and then loaded when you actually visit the
pending tab in question. If you update VimFx before doing so, yet one
frame script URI will be pushed to that stack, causing _two_ instances
of it to be loaded when visiting the tab. Both of those will be from the
new VimFx version; the URIs are the same, and the file at that URI has
now been updated.
This commit attempts to solve this problem by generating a
`bootstrap-frame-$BUILD_TIME.js` file (which simply runs
`bootstrap.coffee`) and loading that as a frame script. This means that
old saved frame script URIs will point to non-existing files and thus
be harmless.
Simon Lydell [Sun, 8 May 2016 07:34:48 +0000 (09:34 +0200)]
Fix smooth scrolling speed in newer Firefox versions
The following pseudo-code used to work:
setFirefoxSpringConstant()
startScrollingSmoothly()
resetFirefoxSpringConstant()
// Some time later: Smooth scrolling finishes.
However, in some newer Firefox version that's changed.
`resetFirefoxSpringConstant` now has to be called when the smooth
scrolling is done, it seems. Unfortunately there appears to be no way of
knowing when that's the case. Instead, this commit introduces a timeout
before the spring constant pref is reset. The timeout can be customized
via the `scroll.reset_timeout` pref if needed. Special care was taken so
that, for example, holding `j` to scroll would only reset the pref
_once_ (after the last scroll command) and to the correct value.
Simon Lydell [Sun, 8 May 2016 06:31:56 +0000 (08:31 +0200)]
Improve copying of element text
Slack uses markdown-style backtick syntax for code spans. Example:
one `code` two
This is the rendered HTML for the above:
<span class="message_body">
one
<code class="special_formatting">
<span class="copyonly">`</span>code<span class="copyonly">`</span>
</code>
two
</span>
Previously, `.textContent` was used to copy element text. Because those
backticks actually are there in the DOM, they get copied too. However,
that's unexpected because they're not visible. The `yv` command is
supposed to be equivalent to `zv<hintchars>y`, but this meant that it
wasn't.
This commit instead creates an actual selection and then invokes
Firefox's `cmd_copy` command (which is exactly what `zv` followed by `y`
does). A difference is that now you can see the created selection flash
for a split second, but I actually like that visual feedback.
This fix also has a positive effect on the `yf` command when copying
`contenteditable` elements. Take this markup:
<div contenteditable="true">T</div>
Then type `<backspace>one<enter><enter>two` in it. Finally, copy the
element using `yf`.
Simon Lydell [Tue, 3 May 2016 08:17:06 +0000 (10:17 +0200)]
Ignore Lock keys such as NumLock and CapsLock
This makes it possible pressing NumLock and CapsLock in the middle of a
multi-key shortcut without aborting it, allowing to type some keys of shortcut
usinng NumLock and CapsLock.
Note that this remove support for using `<capslock>` and `<numlock>` in
shortcuts, but that was never a good idea anyway, since for example `<capslock>`
would _both_ trigger a VimFx command _and_ toggle CapsLock.
Simon Lydell [Sun, 3 Apr 2016 14:01:14 +0000 (16:01 +0200)]
Improve Find mode search start position
By default, Firefox starts searching after the end of the first selection range,
or from the top of the page if there are no selection ranges. This means that if
you search for "vim", a match for "vim" further up or down the page might be
selected, even though the word "vim" might already be onscreen, because of the
current selection (or lack thereof).
Vim starts searching in a similar way: After the cursor. The difference is that
in Vim, the cursor is _always_ onscreen. When you scroll, the cursor is "pushed
along" by the edges of the screen. This way, it is always very easy to tell
where you are going to start your search from. In Firefox, though, using the `/`
command can be quite disorienting.
Another Vim example: Let's say I searched for "vim" again (pressing `/vim` in
Vim). I then go through a few matches using `n`. Then I come to a block of text
that mentions "vim" _lots_ of times, and I realize that I'm not interested in
that block at all. Then it is easier to scroll (or "jump") past that block
rather than spamming `n` over and over (or trying to guess an appropriate
count). When doing the same in Firefox, though, after having scrolled past the
mentioned block of text, the next `n` keypress will scroll up right back to the
last match and continue the search there. This is pretty annoying to me.
While there's the Caret mode (which few people use) and the possibility to
select text in Firefox, there's usually no concept of a caret, and the caret
does not follow the scroll; it stays where it is, possibly offscreen. So where
should we start searching from, really?
This commit implements the following logic:
If there's a visible selection on screen, start searching after that point. If
not, start searching from the top of the current viewport. This works much more
intuitively. Note: Elements with `position: fixed;` are excluded when
determining "the top of the viewport".
Simon Lydell [Sun, 24 Apr 2016 10:01:52 +0000 (12:01 +0200)]
Improve "open link in new tab" interoperability
When opening a link in a new tab, such as when using the `F` or `gf` commands,
we now try to closely mimic what Firefox does when you click links using the
mouse, instead of directly using `gBrowser.loadOneTab(url, options)`.
This provides interoperability with the BackTrack Tab History add-on, which
fixes #720, and allows to remove Tree Style Tab-specific code.
Simon Lydell [Tue, 19 Apr 2016 18:16:40 +0000 (20:16 +0200)]
Move viewport calculations from hints.coffee to utils.coffee
It's cleaner and more reusable.
This also fixes a slight bug for markers in frames. Previously, if the frame had
padding and/or borders its calculated viewport was a tiny bit too large. Now,
padding and borders are taken into account.
Simon Lydell [Mon, 18 Apr 2016 19:22:38 +0000 (21:22 +0200)]
Change `<c-a>` to `<c-enter>` in Hints mode
Using `<c-a>` for marking _all_ elements was nice, because `<c-a>` usually means
"select all". However, it conflicts with the "hold ctrl when typing the last
hint character to toggle if the link opens in a new tab or not" feature. If the
last character was an "a" that wouldn't happen; instead, the `<c-a>` command
would be invoked. This commit changes to `<c-enter>` which should be conflict
free.
Simon Lydell [Wed, 6 Apr 2016 15:53:42 +0000 (17:53 +0200)]
Fix illogical code order in scrolling commands
Logically, one should set the `last_position_mark` mark _before_ jumping
somwhere. However, for the `G`, `g`, `$` and `0` commands, the message to set it
was sent _after_ the message to scroll was sent!
Simon Lydell [Fri, 1 Apr 2016 14:30:08 +0000 (16:30 +0200)]
Improve automatic mode switching on page load
Previously, Normal mode was _always_ entered on location change (page load)
(unless the page is blacklisted; then Ignore mode is entered instead). There
were to reasons for this: Handling the blacklist, and auto-exiting hints mode
(because hints left over from another page does not make sense in a new page).
However, this caused a few problems:
- If you used the `zF` command while a page was loading, the markers would
disappear when the page fired the "location change" event.
- There was an ugly special case for Find mode, making sure not to enter Normal
mode if currently in Find mode (see commit fc7e61e7c).
- Sometimes, you can enter Hints mode on a newly loaded page just before the
page fires the "location change" event, making hints annoyingly disappear.
This commit changes two things:
- Hints mode is automatically exited (by returning to Normal mode) on the
'pagehide' event instead.
- The current mode is only changed on location change _if needed._ That is, to
auto-exit Ignore mode after navigating away from a blacklisted page, or
auto-enter Ignore mode on blacklisted pages.
Simon Lydell [Fri, 1 Apr 2016 05:44:09 +0000 (07:44 +0200)]
Clear artificial hover on blur
Previously, if you focused an element using an `f` command and then pressed
`<tab>` to focus the next element, or if the element was automatically blurred,
the element would still look hovered until you pressed `<escape>`. This is
because many `f` commands lock the `:hover` pseudo-class on their target
element. This commit unlocks that pseudo-class if that element blurs, preventing
elements from getting "stuck". It is only done if the element itself is blurred,
not if anything else is. That's to make sure that dropdown menus opened using
`zf` don't close unexpectedly.
Simon Lydell [Wed, 16 Mar 2016 18:26:07 +0000 (19:26 +0100)]
Fix text input focus issues in non-multi-process
Sometimes when focusing text inputs, it wouldn't really be focused and VimFx
wouldn't recognize it as editable. This was because of commit 33d1fdeb, where I
somehow looked for the 'context' attribute instead of the 'contextmenu'
attribute.
Simon Lydell [Sun, 13 Mar 2016 11:55:49 +0000 (12:55 +0100)]
Disallow old version of VimFx to communicate with new version
Commit 865fdaba attempted to fix an issue where frame script message listeners
from the old version of VimFx wasn't shut down properly when VimFx was updated.
Since then, the problem has become very rare, but unfortunately still happens
occasionally. I really have no idea why it can still happen. It might even be
that there's nothing that can be done due to the way Firefox works.
This commit tries to make any leftover frame script message listeners useless,
by adding the `BUILD_TIME` in all message names.
Simon Lydell [Sun, 13 Mar 2016 08:13:31 +0000 (09:13 +0100)]
Simplify and improve Find mode auto-enter and -exit
In rare circumstances I've found that if you enter Find mode (via the `/`
command) very quickly after just having opened a new foreground tab which loads
a bit slowly, you could sometimes end up with the findbar focused but still in
Normal mode. This should no longer happen.
Simon Lydell [Wed, 9 Mar 2016 06:43:55 +0000 (07:43 +0100)]
Clarify the blacklist option
- Improve wording in the Add-ons Manager. Explicitly say that the list is space
separated, since several users had problems with that.
- Add default example blacklist patterns. It's much easier to adapt an example
than to write something from scratch (or copy-paste). The default patterns are
for example.com and example.org which are reserved for documentation purposes,
so it doesn't matter that those get blacklisted by default.
Simon Lydell [Mon, 7 Mar 2016 08:14:28 +0000 (09:14 +0100)]
Improve click simulation
- Don't leak 'command' events to web pages. They're only needed for XUL.
- Don't generate 'mousedown' and 'mouseup' when simlating clicks for browser UI
elements. They seem to sometimes trigger some buttons' actions twice. It also
caused background tabs to be selected before closed when clicking on their
close button, which caused the selected tab to change. However, an exception
had to be made for tabs. 'mousedown' seems to be the only relevant event
there.
Simon Lydell [Sun, 6 Mar 2016 19:35:25 +0000 (20:35 +0100)]
Improve `Cu.import`s
- Fixed two cases where things were accidentally imported into the global scope.
- Consistenly prefer the explicit `{a, b} = Cu.import('...', {})` style, rather
than the implicit import-all-into-global-scope `Cu.import('...')` style.
Simon Lydell [Sat, 5 Mar 2016 14:33:32 +0000 (15:33 +0100)]
Let `gL` deal with unvisited tabs instead of unread ones
Firefox considers a tab to be "unread" if it finishes loading in the background.
This means that if the current tab is loading, but very slowly, and you
therefore switch to another tab while waiting for it to finish, you can't use
`gl` to go back to the slowly-loading tab when it's done, because then it would
be marked as "unread", forcing you to use `gL` instead. This often tripped me
up.
This commit uses the notion of "unvisited" instead of "unread". This works much
better.
Simon Lydell [Sat, 5 Mar 2016 12:59:01 +0000 (13:59 +0100)]
Fix `gi` after searching issues on github
After searching for issues on github, the search input gets removed from the DOM
and replaced with a new one. This means that the last focused text input is no
longer on the page, but `gi` still tried to focus it. This commit checks that
the last focused element really is present in the DOM first.
Simon Lydell [Sat, 5 Mar 2016 12:29:52 +0000 (13:29 +0100)]
Fix focusType after searching issues on github
When searching for issues on github, the results are fetched with AJAX and then
inserted into the page. More accurately, the fetched content _replaces_ already
existing content on the page, including the search input. It turns out that
neither 'focus' nor 'blur' events are fired when a focused text input is removed
from the DOM (even though that actually blurs it and focuses `<body>`). This
caused VimFx to believe that the text input was still focused, which meant that
you had to press `<escape>` before you could use any VimFx commands. Using a
`MutationObserver`, this commit temporarily observes the currently focused
element (unless `focusType == 'none'`, because that's unnecessary and might
degrade performance). If the element gets removed, the current `focusType` is
updated, fixing the problem.
To check if an element gets removed from the DOM requires observing the _entire_
document tree, recursively. The `utils.onRemoved` function did (wrongly) not do
that, so it had to be updated.
Because of the update to `utils.onRemoved`, this commit also removes the
`MutationObserver`s for scrollable elements. The reason they were added in the
first place was to try to reduce memory consumption by pruning the list of
scrollable elements from elements removed from the DOM. However, the observers
were buggy: They were only triggered if _only_ the scrollable element was
removed, not if one of its parents were removed. Since this "buggy" behavior has
been used for quite some time now and it hasn't caused any memory problems, one
can draw the conclusion that the observers are not needed. That's good, because
it means that there's no need to add observers for the entire document on
basically _every_ page.
Simon Lydell [Mon, 29 Feb 2016 12:50:48 +0000 (13:50 +0100)]
Harden the `f` commands
It sucks that you can't trust the DOM. It sucks that on rare occasions, pressing
`f` shows no hints, but still enters Hints mode, leaving a
“element.href.startsWith is not a function” (or similar) error in the browser
console.
This commit tries to harden against such cases, by never trusting DOM properties
or methods to exist and be of the correct type. CoffeeScripts `?` is awesome for
this.
Simon Lydell [Sun, 28 Feb 2016 15:55:23 +0000 (16:55 +0100)]
Streamline `vimfx.on` events
_Always_ pass an object with event-specific properties, instead of sometimes
passing data directly. This is more consistent, and more future-proof since it
allows passing additional data without breaking backwards compatibility.
Simon Lydell [Sun, 28 Feb 2016 15:24:41 +0000 (16:24 +0100)]
Simplify the `config_file_directory` pref
- Set it to a normal system path, and let Firefox add `file://` and handle
Windows paths.
- Expand path starting with `~/` or `~\` to the user's home directory.
Simon Lydell [Sat, 27 Feb 2016 16:39:30 +0000 (17:39 +0100)]
Fix mutation errors in some `f` commands
For example, `2f` is supposed to open the first link in a new background tab and
the second link in the current tab. However, both were opened in background tabs
due to accidental mutation.
Simon Lydell [Fri, 26 Feb 2016 14:17:42 +0000 (15:17 +0100)]
Only allow `<late>` in single-key shortcuts
Previously, it was allowed in any shortcut sequence, but it only made a
difference for the last character. It really only makes sense to use `<late>`
with singe-key shortcuts.
Simon Lydell [Fri, 26 Feb 2016 13:31:33 +0000 (14:31 +0100)]
Use `prefs.get` directly in events-frame.coffee
... instead of using `messageManager.get`. This avoids synchronous messages,
which is a good thing. It violates the nice principle of only using the parsed
options of the `vimfx` object, but it doesn't really matter right now since only
four prefs are used in events-frame.coffee and they need little to none parsing.
One could probably pass the entire `vimfx.options` object down to frame scripts
when they start up and send updates whenever it updates, but let's do that when
a need for it comes up.