aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Blott2014-11-14 12:01:39 +0000
committerStephen Blott2014-11-14 12:01:39 +0000
commit9bb2b1b6db5d7276408857d9032d2a9c1b0fe9dd (patch)
tree32e6f27102504bd1d2b1f750b5acd0f99b4b304b
parente12b9422580c898af381ba97fa9806bfe3264e96 (diff)
downloadvimium-9bb2b1b6db5d7276408857d9032d2a9c1b0fe9dd.tar.bz2
Smooth scroll; move doScrollBy to it's own object.
The main reason for doing this is so that we can add the (now) CoreScroller callbacks to the handler stack earlier, and therefore track @keyIsDown correctly at startup, while also keeping local state local.
-rw-r--r--content_scripts/scroller.coffee54
1 files changed, 26 insertions, 28 deletions
diff --git a/content_scripts/scroller.coffee b/content_scripts/scroller.coffee
index ecb739ec..e418a930 100644
--- a/content_scripts/scroller.coffee
+++ b/content_scripts/scroller.coffee
@@ -3,7 +3,6 @@
# input elements. This mechanism allows us to decide whether to scroll a div or to scroll the whole document.
#
activatedElement = null
-settings = null
scrollProperties =
x: {
@@ -83,38 +82,37 @@ checkVisibility = (element) ->
# continues scrolling at least until its corresponding keyup event is received. We never initiate a new
# animator on keyboard repeat.
-# Scroll by a relative amount (a number) in some direction, possibly smoothly.
-doScrollBy = do ->
- # This is logical time. Time is advanced each time an animator is activated, and on each keyup event.
- time = 0
- lastEvent = null
- keyHandler = null
- keyIsDown = false
-
- (element, direction, amount) ->
+CoreScroller =
+ init: (frontendSettings) ->
+ @settings = frontendSettings
+ @time = 0
+ @lastEvent = null
+ @keyIsDown = false
+ handlerStack.push
+ keydown: (event) =>
+ @keyIsDown = true
+ @lastEvent = event
+ keyup: =>
+ @keyIsDown = false
+ @time += 1
+
+ # Scroll element by a relative amount (a number) in some direction.
+ scroll: (element, direction, amount) ->
return unless amount
- keyHandler ?= handlerStack.push
- keydown: ->
- keyIsDown = true unless event.repeat
- lastEvent = event
- keyup: ->
- keyIsDown = false
- time += 1
-
- unless settings.get "smoothScroll"
+ unless @settings.get "smoothScroll"
# Jump scrolling.
performScroll element, direction, amount
checkVisibility element
return
# We don't activate new animators on keyboard repeats.
- return if lastEvent?.repeat
+ return if @lastEvent?.repeat
- activationTime = ++time
+ activationTime = ++@time
- isKeyStillDown = ->
- time == activationTime and keyIsDown
+ isMyKeyStillDown = =>
+ @time == activationTime and @keyIsDown
# Store amount's sign and make amount positive; the logic is clearer when amount is positive.
sign = Math.sign amount
@@ -149,14 +147,14 @@ doScrollBy = do ->
# The constants in the duration calculation, above, are chosen to provide reasonable scroll speeds for
# scrolls resulting from distinct keypresses. For continuous scrolls (where the key remains depressed),
# some scrolls are too slow, and others too fast. Here, we compensate a bit.
- if isKeyStillDown() and 50 <= totalElapsed and 0.5 <= calibration <= 1.6
+ if isMyKeyStillDown() and 50 <= totalElapsed and 0.5 <= calibration <= 1.6
calibration *= 1.05 if 1.05 * calibration * amount <= 150 # Speed up slow scrolls.
calibration *= 0.95 if 150 <= 0.95 * calibration * amount # Slow down fast scrolls.
# Calculate the initial delta, rounding up to ensure progress. Then, adjust delta to account for the
# current scroll state.
delta = Math.ceil amount * (elapsed / duration) * calibration
- delta = if isKeyStillDown() then delta else Math.max 0, Math.min delta, amount - totalDelta
+ delta = if isMyKeyStillDown() then delta else Math.max 0, Math.min delta, amount - totalDelta
if delta and performScroll element, direction, sign * delta
totalDelta += delta
@@ -169,8 +167,8 @@ doScrollBy = do ->
Scroller =
init: (frontendSettings) ->
- settings = frontendSettings
handlerStack.push DOMActivate: -> activatedElement = event.target
+ CoreScroller.init frontendSettings
# scroll the active element in :direction by :amount * :factor.
# :factor is needed because :amount can take on string values, which scrollBy converts to element dimensions.
@@ -188,7 +186,7 @@ Scroller =
element = findScrollableElement activatedElement, direction, amount, factor
elementAmount = factor * getDimension element, direction, amount
- doScrollBy element, direction, elementAmount
+ CoreScroller.scroll element, direction, elementAmount
scrollTo: (direction, pos) ->
return unless document.body or activatedElement
@@ -196,7 +194,7 @@ Scroller =
element = findScrollableElement activatedElement, direction, pos
amount = getDimension(element,direction,pos) - element[scrollProperties[direction].axisName]
- doScrollBy element, direction, amount
+ CoreScroller.scroll element, direction, amount
root = exports ? window
root.Scroller = Scroller