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?
Yes, it's fiendishly clever and frighteningly confusing.  It's been slightly refactored, but all of the unusual logic and overloading in `getDimension` is inherited from the existing implementation.  I will add a docstring, but I'd prefer not to refactor it further.  Or, perhaps I should say, I'm *scared* to refactor it further!