Smooth scrolling via requestAnimationFrame, with keyboard repeat

This is a continuation of #1235.

Changes from there:
- Some minor tidy up.
- Handle keyboard repeat (the most recently activated animator keeps going at least until we get a `keyup` event).
- On keyboard repeat, scrolling stops as soon as the key is release.

And, as @mrmr1993 pointed out:
- For distinct key presses, we end up in the same place as we would without smooth scrolling (except for one corner case -- when we're scrolling an embedded element).

Issues:
- ~~See my comment close to where `smoothScrollLock` is set.  There's a race condition.~~
- ~~Also, smooth scrolling cannot be started less than 50ms after the previous smooth scroll completed.  I couldn't trigger this.  Perhaps somebody with nimbler fingers can.~~

I'm on Debian, Could somebody (@philc? @mrmr1993? Anybody else?) try it out on other platforms?
The contract of this method is confusing. Why is "amount" overloaded to mean multiple things? When amount is numeric, we just return it? This could use a doc string.