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?
This documentation about what the value of `amount` should be should go into the method's doc string. Comments inside the body of the function should be read as implementation notes, not notes about the contract for callers.