aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Blott2016-04-28 13:51:44 +0100
committerStephen Blott2016-04-28 13:55:08 +0100
commitf83e99fd42a4cf412c79fb15c58f59c105c25723 (patch)
tree673e75c9d372fd70ae0742a05c76c581f0faff32
parentac340e2346247b5cd1878e1a814d4c151df3e892 (diff)
downloadvimium-f83e99fd42a4cf412c79fb15c58f59c105c25723.tar.bz2
Fix UI-component initialization issues.
This fixes some UI component initialization issues. It's a long story... The problem. - Go to this page: http://www.thejournal.ie/seanad-election-results-2016-2737768-Apr2016/ - Click one of the links from the "Most Popular" box on the right. - Navigate back (`H`) and, as the original page is loading, activate the Vomnibar. In 1.54 this renders Vimium unusable. In `master` this renders the Vomnibar unsable, but the rest of Vimium usable. It seems the source of the issue is that we're initializing UI components too soon. We need to wait until the `readyState` is "complete". With this PR: - The Vomnibar is initialised when the `readyState` is "complete" (in the top frame only, and only if Vimium is enabled). Requests arriving prior to then are silently discarded. - The HUD is also initialized only when the `readyState` is "complete"; however, requests arriving before then are queued. So, if the user immediately enters insert mode, then the "Insert mode" indicator will eventually be displayed. - The help dialog silently discards requests until the `readyState` is "complete. I'm posting this as a PR because: 1. It needs some visibility. 2. With this, if the `readyState` *never* reaches "complete", then the Vomnibar would be unusable. And that's pretty serious.
-rw-r--r--content_scripts/hud.coffee16
-rw-r--r--content_scripts/ui_component.coffee7
-rw-r--r--content_scripts/vimium_frontend.coffee9
-rw-r--r--content_scripts/vomnibar.coffee8
-rw-r--r--lib/dom_utils.coffee11
5 files changed, 32 insertions, 19 deletions
diff --git a/content_scripts/hud.coffee b/content_scripts/hud.coffee
index 0d3a6f95..b2780491 100644
--- a/content_scripts/hud.coffee
+++ b/content_scripts/hud.coffee
@@ -22,15 +22,17 @@ HUD =
@_showForDurationTimerId = setTimeout((=> @hide()), duration)
show: (text) ->
- @init()
- clearTimeout(@_showForDurationTimerId)
- @hudUI.activate {name: "show", text}
- @tween.fade 1.0, 150
+ DomUtils.documentComplete =>
+ @init()
+ clearTimeout(@_showForDurationTimerId)
+ @hudUI.activate {name: "show", text}
+ @tween.fade 1.0, 150
showFindMode: (@findMode = null) ->
- @init()
- @hudUI.activate name: "showFindMode"
- @tween.fade 1.0, 150
+ DomUtils.documentComplete =>
+ @init()
+ @hudUI.activate name: "showFindMode"
+ @tween.fade 1.0, 150
search: (data) ->
@findMode.findInPlace data.query
diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee
index 59e4fe41..203f0c8c 100644
--- a/content_scripts/ui_component.coffee
+++ b/content_scripts/ui_component.coffee
@@ -68,10 +68,9 @@ class UIComponent
# Post a message (if provided), then call continuation (if provided). We wait for documentReady() to ensure
# that the @iframePort set (so that we can use @iframePort.use()).
postMessage: (message = null, continuation = null) ->
- DomUtils.documentReady =>
- @iframePort.use (port) ->
- port.postMessage message if message?
- continuation?()
+ @iframePort?.use (port) ->
+ port.postMessage message if message?
+ continuation?()
activate: (@options = null) ->
@postMessage @options, =>
diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee
index 4d081e90..7ff03ee5 100644
--- a/content_scripts/vimium_frontend.coffee
+++ b/content_scripts/vimium_frontend.coffee
@@ -143,7 +143,7 @@ initializeOnEnabledStateKnown = (isEnabledForUrl) ->
if isEnabledForUrl
# We only initialize (and activate) the Vomnibar in the top frame. Also, we do not initialize the
# Vomnibar until we know that Vimium is enabled. Thereafter, there's no more initialization to do.
- Vomnibar.init() if DomUtils.isTopFrame()
+ DomUtils.documentComplete Vomnibar.init.bind Vomnibar if DomUtils.isTopFrame()
initializeOnEnabledStateKnown = ->
#
@@ -635,10 +635,11 @@ window.HelpDialog ?=
abort: -> @helpUI.hide false if @isShowing()
toggle: (request) ->
- @helpUI ?= new UIComponent "pages/help_dialog.html", "vimiumHelpDialogFrame", ->
- if @isShowing()
+ DomUtils.documentComplete =>
+ @helpUI ?= new UIComponent "pages/help_dialog.html", "vimiumHelpDialogFrame", ->
+ if @helpUI? and @isShowing()
@helpUI.hide()
- else
+ else if @helpUI?
@helpUI.activate extend request,
name: "activate", focus: true
diff --git a/content_scripts/vomnibar.coffee b/content_scripts/vomnibar.coffee
index cbd2892c..49c4288e 100644
--- a/content_scripts/vomnibar.coffee
+++ b/content_scripts/vomnibar.coffee
@@ -56,10 +56,10 @@ Vomnibar =
# selectFirst - Optional, boolean. Whether to select the first entry.
# newTab - Optional, boolean. Whether to open the result in a new tab.
open: (sourceFrameId, options) ->
- @init()
- # The Vomnibar cannot coexist with the help dialog (it causes focus issues).
- HelpDialog.abort()
- @vomnibarUI.activate extend options, { name: "activate", sourceFrameId, focus: true }
+ if @vomnibarUI?
+ # The Vomnibar cannot coexist with the help dialog (it causes focus issues).
+ HelpDialog.abort()
+ @vomnibarUI.activate extend options, { name: "activate", sourceFrameId, focus: true }
root = exports ? window
root.Vomnibar = Vomnibar
diff --git a/lib/dom_utils.coffee b/lib/dom_utils.coffee
index 3d719337..07598a85 100644
--- a/lib/dom_utils.coffee
+++ b/lib/dom_utils.coffee
@@ -13,6 +13,17 @@ DomUtils =
(callback) -> if isReady then callback() else callbacks.push callback
+ documentComplete: do ->
+ [isComplete, callbacks] = [document.readyState == "complete", []]
+ unless isComplete
+ window.addEventListener "load", onLoad = ->
+ window.removeEventListener "load", onLoad
+ isComplete = true
+ callback() for callback in callbacks
+ callbacks = null
+
+ (callback) -> if isComplete then callback() else callbacks.push callback
+
createElement: (tagName) ->
element = document.createElement tagName
if element instanceof HTMLElement