diff options
| author | Stephen Blott | 2016-03-05 06:36:16 +0000 | 
|---|---|---|
| committer | Stephen Blott | 2016-03-06 11:27:45 +0000 | 
| commit | 0822f8244d328233752c7f986a70e805ee238979 (patch) | |
| tree | d0e313d7ccf3d77e50923a195709840610d8f585 | |
| parent | 755c9fb4f837a9f8b80d51610e86c3ba2ea1999f (diff) | |
| download | vimium-0822f8244d328233752c7f986a70e805ee238979.tar.bz2 | |
Initialize UI components only when they're needed.
HUD: Initialize only when the frame receives the focus and Vimium is enabled.
Vomnibar: Initialize in the top frame when Vimium is enabled in *any* frame.
Warning:  There may be a race condition here.  Specifically, if Vimium
is disabled in the main/top frame (T) but enabled in another frame (A), then the
initialisation could happen in frame A before frame T is listening, so
frame T would miss the initialization message (which is only sent once).
Message listeners are installed early (and probably installed first in
the main/top frame), and the `isEnabledForUrl` messaging takes some
time, so perhaps it's OK.  But it *is* a race condition.
Fixes #1838.
| -rw-r--r-- | content_scripts/hud.coffee | 2 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 21 | ||||
| -rw-r--r-- | tests/dom_tests/dom_tests.coffee | 1 | ||||
| -rw-r--r-- | tests/dom_tests/vomnibar_test.coffee | 1 | 
4 files changed, 20 insertions, 5 deletions
| diff --git a/content_scripts/hud.coffee b/content_scripts/hud.coffee index e56644df..aa8a6bbd 100644 --- a/content_scripts/hud.coffee +++ b/content_scripts/hud.coffee @@ -86,7 +86,7 @@ HUD =    isReady: do ->      ready = false      DomUtils.documentReady -> ready = true -    -> ready and document.body != null +    -> ready and document.body != null and @hudUI?    enabled: -> true diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 2e57ee1a..5acabcfc 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -149,6 +149,7 @@ initializePreDomReady = ->      # A frame has received the focus.  We don't care here (the Vomnibar/UI-component handles this).      frameFocused: ->      checkEnabledAfterURLChange: checkEnabledAfterURLChange +    initializeTopFrame: initializeTopFrame      runInTopFrame: ({sourceFrameId, registryEntry}) ->        Utils.invokeCommandString registryEntry.command, [sourceFrameId, registryEntry] if DomUtils.isTopFrame() @@ -218,9 +219,6 @@ initializeOnDomReady = ->      isEnabledForUrl = false      chrome.runtime.sendMessage = ->      window.removeEventListener "focus", onFocus -  # We only initialize the vomnibar in the tab's main frame, because it's only ever opened there. -  Vomnibar.init() if DomUtils.isTopFrame() -  HUD.init()  registerFrame = ->    # Don't register frameset containers; focusing them is no use. @@ -436,6 +434,17 @@ extend window,                indicator: false +initializeTopFrame = (request = null) -> +  initializeTopFrame = -> # Only do this initialization once. +  # We only initialize the vomnibar in the tab's top/main frame, because it's only ever opened there. +  if DomUtils.isTopFrame() +    Vomnibar.init() +  else +    # Ignore requests from other frames (if we're not the top frame). +    unless request? +      # Tell the top frame to initialize the Vomnibar. +      chrome.runtime.sendMessage handler: "sendMessageToFrames", message: name: "initializeTopFrame" +  # Checks if Vimium should be enabled or not in this frame.  As a side effect, it also informs the background  # page whether this frame has the focus, allowing the background page to track the active frame's URL.  checkIfEnabledForUrl = (frameIsFocused = windowIsFocused()) -> @@ -443,7 +452,11 @@ checkIfEnabledForUrl = (frameIsFocused = windowIsFocused()) ->    chrome.runtime.sendMessage { handler: "isEnabledForUrl", url: url, frameIsFocused: frameIsFocused }, (response) ->      { isEnabledForUrl, passKeys } = response      installListeners() # But only if they have not been installed already. -    if HUD.isReady() and not isEnabledForUrl +    # Initialize UI components. We only initialize these once we know that Vimium is enabled; see #1838. +    if isEnabledForUrl +      initializeTopFrame() +      HUD.init() if frameIsFocused +    else if HUD.isReady()        # Quickly hide any HUD we might already be showing, e.g. if we entered insert mode on page load.        HUD.hide()      normalMode?.setPassKeys passKeys diff --git a/tests/dom_tests/dom_tests.coffee b/tests/dom_tests/dom_tests.coffee index 0745e5b2..3797a37b 100644 --- a/tests/dom_tests/dom_tests.coffee +++ b/tests/dom_tests/dom_tests.coffee @@ -1,6 +1,7 @@  # Install frontend event handlers.  installListeners() +HUD.init()  installListener = (element, event, callback) ->    element.addEventListener event, (-> callback.apply(this, arguments)), true diff --git a/tests/dom_tests/vomnibar_test.coffee b/tests/dom_tests/vomnibar_test.coffee index 3eda6234..0898e33a 100644 --- a/tests/dom_tests/vomnibar_test.coffee +++ b/tests/dom_tests/vomnibar_test.coffee @@ -1,5 +1,6 @@  vomnibarFrame = null  SearchEngines.refresh "" +Vomnibar.init()  context "Keep selection within bounds", | 
