aboutsummaryrefslogtreecommitdiffstats
path: root/content_scripts/hud.coffee
diff options
context:
space:
mode:
Diffstat (limited to 'content_scripts/hud.coffee')
-rw-r--r--content_scripts/hud.coffee99
1 files changed, 99 insertions, 0 deletions
diff --git a/content_scripts/hud.coffee b/content_scripts/hud.coffee
new file mode 100644
index 00000000..f38d6b45
--- /dev/null
+++ b/content_scripts/hud.coffee
@@ -0,0 +1,99 @@
+#
+# A heads-up-display (HUD) for showing Vimium page operations.
+# Note: you cannot interact with the HUD until document.body is available.
+#
+HUD =
+ tween: null
+ hudUI: null
+ _displayElement: null
+
+ # This HUD is styled to precisely mimick the chrome HUD on Mac. Use the "has_popup_and_link_hud.html"
+ # test harness to tweak these styles to match Chrome's. One limitation of our HUD display is that
+ # it doesn't sit on top of horizontal scrollbars like Chrome's HUD does.
+
+ init: ->
+ @hudUI = new UIComponent "pages/hud.html", "vimiumHUDFrame", ({data}) =>
+ this[data.name]? data
+ @tween = new Tween "iframe.vimiumHUDFrame.vimiumUIComponentVisible", @hudUI.shadowDOM
+
+ showForDuration: (text, duration) ->
+ @show(text)
+ @_showForDurationTimerId = setTimeout((=> @hide()), duration)
+
+ show: (text) ->
+ return unless @enabled()
+ clearTimeout(@_showForDurationTimerId)
+ @hudUI.show {name: "show", text}
+ @tween.fade 1.0, 150
+
+ # Hide the HUD.
+ # If :immediate is falsy, then the HUD is faded out smoothly (otherwise it is hidden immediately).
+ # If :updateIndicator is truthy, then we also refresh the mode indicator. The only time we don't update the
+ # mode indicator, is when hide() is called for the mode indicator itself.
+ hide: (immediate = false, updateIndicator = true) ->
+ return unless @tween?
+ clearTimeout(@_showForDurationTimerId)
+ @tween.stop()
+ if immediate
+ unless updateIndicator
+ @hudUI.hide()
+ @hudUI.postMessage {name: "hide"}
+ Mode.setIndicator() if updateIndicator
+ else
+ @tween.fade 0, 150, => @hide true, updateIndicator
+
+ isReady: do ->
+ ready = false
+ DomUtils.documentReady -> ready = true
+ -> ready and document.body != null
+
+ # A preference which can be toggled in the Options page. */
+ enabled: -> !settings.get("hideHud")
+
+class Tween
+ opacity: 0
+ intervalId: -1
+ styleElement: null
+
+ constructor: (@cssSelector, insertionPoint = document.documentElement) ->
+ @styleElement = document.createElement "style"
+
+ unless @styleElement.style
+ # We're in an XML document, so we shouldn't inject any elements. See the comment in UIComponent.
+ Tween::fade = Tween::stop = Tween::updateStyle = ->
+ return
+
+ @styleElement.type = "text/css"
+ @styleElement.innerHTML = ""
+ insertionPoint.appendChild @styleElement
+
+ fade: (toAlpha, duration, onComplete) ->
+ clearInterval @intervalId
+ startTime = (new Date()).getTime()
+ fromAlpha = @opacity
+ alphaStep = toAlpha - fromAlpha
+
+ performStep = =>
+ elapsed = (new Date()).getTime() - startTime
+ if (elapsed >= duration)
+ clearInterval @intervalId
+ @updateStyle toAlpha
+ onComplete?()
+ else
+ value = (elapsed / duration) * alphaStep + fromAlpha
+ @updateStyle value
+
+ @updateStyle @opacity
+ @intervalId = setInterval performStep, 50
+
+ stop: -> clearInterval @intervalId
+
+ updateStyle: (@opacity) ->
+ @styleElement.innerHTML = """
+ #{@cssSelector} {
+ opacity: #{@opacity};
+ }
+ """
+
+root = exports ? window
+root.HUD = HUD