diff options
| author | Stephen Blott | 2016-04-28 13:51:44 +0100 |
|---|---|---|
| committer | Stephen Blott | 2016-04-28 13:55:08 +0100 |
| commit | f83e99fd42a4cf412c79fb15c58f59c105c25723 (patch) | |
| tree | 673e75c9d372fd70ae0742a05c76c581f0faff32 | |
| parent | ac340e2346247b5cd1878e1a814d4c151df3e892 (diff) | |
| download | vimium-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.coffee | 16 | ||||
| -rw-r--r-- | content_scripts/ui_component.coffee | 7 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 9 | ||||
| -rw-r--r-- | content_scripts/vomnibar.coffee | 8 | ||||
| -rw-r--r-- | lib/dom_utils.coffee | 11 |
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 |
