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.
Simon Lydell [Fri, 26 Feb 2016 08:55:14 +0000 (09:55 +0100)]
Save the focusType instead of getting it on every keydown
This is simpler and more efficient. Also, we were basically already storing the
current focusType, since the button uses it to grey out when a text is focused.
Config API changes:
- `match` objects no longer have a `focus` property. It has been replaced with
the `likelyConflict` property. (Theoretically a breaking change.)
- `vim.focusType` is now available and contains the current focus type.
- The `focusTypeChange` event now passes only the current `vim` object to
listeners, instead of an object of data. Use `vim.focusType` to get the new
focusType. (Theoretically a breaking change.)
> Fix "invokeListener is not a function" uncaught errors
The commit indeed solved the above problem, but apparently replaced it with
another. When `invokeListener` has been `null`ed out, a copy of it can try to
reference things that also have been `null`ed out. So instead of storing copies
of it, we now check if the function exists before calling it. Otherwise, simply
do nothing. This commit also applies this to _all_ places `invokeListener` is
used.
Simon Lydell [Wed, 24 Feb 2016 12:29:13 +0000 (13:29 +0100)]
Improve Ignore mode and the blacklist
When you reloaded the page or visited some other page in the same time while in
Ignore mode, you'd always end up in Normal mode (unless the newly loaded page
was blacklisted). Now, you stay in Ignore mode in that case. This lets you press
`i` and browse around in that tab in Ignore mode, without having to press `i`
again any time a full page reload is caused.
However, if Ignore mode was entered automatically because of the blacklist, it
is also exited as expected if you browse to a non-blacklisted page.
This new behavior is possible by tracking the "type" of the Ignore mode. There
are currently two types, 'explicit' and 'blacklist', which correspond to the
above two cases.
Simon Lydell [Wed, 24 Feb 2016 07:03:39 +0000 (08:03 +0100)]
Fix issues when updating VimFx
After having updated VimFx, trying to use the `f` command on toggle buttons
often failed. This was because the frame script message listeners from the old
version wasn't shut down properly, which resulted in there being _two_ listeners
for the message to simulate a click on an element. The effects of this was
especially noticeable on toggle buttons, because clicking a toggle button twice
is a no-op. That gave the impression of VimFx failing to simulate a click at
all.
I think this erraneous shutdown behavior must have been introduced in commit 24b701e9, which switched from a synchronous message passing to an asynchronous
one in bootstrap.coffee. Previously, the shutdown message listener for frame
scripts had to be added after a timeout. Since mentioned commit, that timeout is
added in the response callback for the mentioned asynchronous message, which
should make the timeout unnecessary, but the timeout was still kept in that
commit. It shouldn't matter, but somehow it does. Removing the timeout fixes the
double message listeners problem, and does not seem to re-introduce the problems
that were fixed be adding the timeout in the first place (commit ec3a4394).
Simon Lydell [Tue, 23 Feb 2016 08:13:46 +0000 (09:13 +0100)]
Fix `@popupPassThrough` for menus in frames
When a menu, such as a context menu is open, VimFx is automatically disabled to
allow using the access keys of the open menu, as well as pressing `<escape>` to
close the menu. However, this used not to work for the context menus in the
devtools and in about:config. Now it does.
This also fixes a bug where VimFx stopped being automatically disabled after
closing a sub-menu of a context menu.
Simon Lydell [Tue, 23 Feb 2016 07:54:42 +0000 (08:54 +0100)]
Treat everything in the devtools as adjustable
Many things in the devtools can be "adjusted" with the arrow keys. For example,
if you `console.log` an object you can click it to get an interactive inspection
tree of that object. The tree can be navigated using the arrow keys, but not if
you, for example, use the arrow keys for VimFx's scrolling commands. With this
commit, that is no longer a problem.
Simon Lydell [Sun, 21 Feb 2016 14:35:12 +0000 (15:35 +0100)]
Replace element `instanceof` checks with `.localName`
KISS.
Note: `instanceof` checks are still often useful for XUL elements, because some
interfaces are extended by several elements.
Also note that `.localName` is used instead of `.nodeName` because many XUL
pages embed HTML elements. When mixing namespaces like that, the `.nodeName`s of
HTML elements will start with `html:`, while `.localName` skips the prefix.
`.localName` also nicely always returns valid HTML node names in lowercase.
Simon Lydell [Mon, 22 Feb 2016 18:29:26 +0000 (19:29 +0100)]
Split `gl` into `gl` and `gL`
`gl` selects the most recent tab. Simple, right? But what if you open a
background tab? Which is the most recent tab now? Or if you open several
background tabs?
Previously, if you opened several background tabs and then pressed `gl`, the
last opened new background tab would be selected. That behavior just happened to
be.
In my opinion, it is more consistent if `gl` always selects the last _visited_
tab. An unread background tab has _not_ been visited (yet). This commit makes
this change.
If there is only one visited tab (but possibly several unread tabs), a
notification is shown telling that there is no most recent tab.
The `gL` command selects the oldest unread tab. This is useful when having
opened a bunch of background tabs. `gL` then lets you step them through in the
order you opened them. (If there are no unread tabs, a notification is shown.)
In other words, `gl` deals with _visited_ tabs only (from now on), while `gL`
deals with _unread_ tabs only.
The motivation for this commit came from piroor/treestyletab#874.
Mentioned commit attempted to fix a problem where `vim.mode` could be
`undefined` in some `vimfx.on(...)` listeners. The button uses such an event
listener, and uses `vim.mode` in the key for a `translate(key)` call, which
caused `translate` to throw an error. This was because `vim.mode` wasn't set
until after a timeout. The fix was to emit the events after the same timeout.
However, the above solution is very unreliable, and the problem still slipped
through every now and then.
The reason the first timeout was added in the first place was to allow calling
`vimfx.getCurrentVim()` inside `vimfx.on(...)` listeners. This commit removes
both timeouts, while still preserving that behavior by splitting the contructor
of `Vim` into a new method, `._start`. This should be bullet-proof, less hacky
and faster.
Simon Lydell [Sun, 21 Feb 2016 14:05:49 +0000 (15:05 +0100)]
Add partial support for the wasavi extension
It's editor is now recognized as an editable element, but pressing `<escape>` in
its insert mode still blurs the editor instead of exiting its insert mode.
(`<escape>`) should ideally only blur in wasavi's normal mode.
- `element.style.zIndex`: Always string.
- `element.style.zIndex = value`: Turns `value` into a string.
- `a = '5'; a++`: `a` is now `6`.
- `element.style.zIndex++`: If the previous value was `'5'`, the new value is
`'6'`. This method was used before above commit.
- `element.style.zIndex += 1`: If the previous value was `'5'`, the new value is
`'51'`. This was introduced by above commit.
The above really shows that you should always be explicit about types. Since
`element.style.zIndex` is always a string, `element.style.zIndex++` was a
terrible hack that happened to work, but caused a bug when it was rewritten to
a seemingly equivalent expression.
This commit first reads the `z-index` of the element and explicitly makes it a
`Number`, allowing incrementing to work as expected.
Simon Lydell [Fri, 19 Feb 2016 06:55:41 +0000 (07:55 +0100)]
Reduce unnecessary vertical code alignment
While it may look nice many times, it causes annoying merge conflicts.
Especially aligning all `require(...)` calls has bitten me many times, since
adding or removing one often requires reformatting the entire block.
This commit attempts to remove vertical alignment (especially around `=`) for
the sake of smaller diffs and simpler merges.
Vertical alignment has been kept, though, where it really makes the code easier
to read and you're likely to edit all of the aligned lines anyway if changing
one of them. The most common example is code dealing with X and Y coordinates
and having to do the same thing to both of them. Only the words X, Y, left,
right, top, bottom, width, height etc. differ between the lines. It's easier to
see that they are really up-to-date with each other if the common parts are
aligned.