This implements automatic focus management for modal panels using the
excellent focus-trap module.
Upon being shown, modals will have their first tabbable element
automatically focused, and shifting focus with the tab key (or more
correctly the core:focus-next command) will be limited to the contents
of the modal. If the modal does not have any tabbable elements, focus()
will be sent to the panel's root element (if it implements it).
I'm happy to update this to *always* calls focus on the panel's root
element, but then modal implementers would need to handle that and
focus things on their own. I'd argue the tabbable element behavior
is more accessible though :)
This has the effect of not automatically closing most of Atom's own
modals whenever the tab key is pressed, which was an odd nonstandard
behavior, IMO.
This also automates returning focus to the element that had focus before
the modal was shown, something up until now had to be implemented in
every modal in Atom.
This likely breaks a few contracts for existing Atom packages that
create modals, but I've found this doesn't conflict behaviorally with
well-behaved modals like the command palette which implement their own
focus management (which can be removed if this lands).
Released under CC0.
This was bootstrapped with running `decaffeinate` on both command-registry
and its spec, but involved a line-by-line eyeing and updating for idioms
and, in one case, correctness:
For some reason, copying the keys to the new dispatchedEvent in
coffeescript (command-registry.coffee:235) currently does not result in a thrown
exception, as it should when trying to write over the read-only property
`isTrusted`, so I added a check to ensure that the key did not already
exist in the new event. Moreover, other definitions of `preventDefault`,
`stopPropagation` and friends, which are also enumerable afaict, would
also overwrite the ones defined just prior (command-registry.coffee:220
and command-registry.js:325), so that check ensures we don't overwrite
those either.
Test plan: `./script/lint && ./script/test`, and a lengthy smoke test of
various commands through keybindings, command palette, and package
interfaces.
Released under CC0.
Previously, we were calculating the position preceding block decorations
for the row following the end of the highlighted range, but that's
actually wrong. We just want the position following block decorations of
the end of the highlighted range, plus one line height. This prevents us
from incorrectly rendering the end of highlight after block decorations
that immediately follow the end of the highlighted range.
When there are block decorations, we compute a `marginTop` style for
line numbers, so that they can be aligned correctly to the corresponding
line nodes.
This commit fixes a regression in the logic that calculated the
`marginTop` value, which was failing to correctly render line numbers
when block decorations were located right before the end of a tile, or
exactly at
the beginning of it.
At the cost of a very minimal reduction in layout performance, we gain
reliable rendering at all line heights and don't have to worry about
characters that extend above/below the footprint of a line.
Signed-off-by: Nathan Sobo <nathan@github.com>