aboutsummaryrefslogtreecommitdiffstats
path: root/content_scripts/ui_component.coffee
diff options
context:
space:
mode:
authorStephen Blott2015-04-25 07:06:31 +0100
committerStephen Blott2015-04-25 07:06:31 +0100
commit9100b1d48aa9c09d792d9e2c9251e6a6c62f81bf (patch)
treee005bacd529ec8efa63243b45225051fc9af3417 /content_scripts/ui_component.coffee
parentef44d0ff49cec17a758b65c10ba4c0ecbc0c2ece (diff)
parentbfa6c88b41acac4c98d06f324f25f8bb7b328614 (diff)
downloadvimium-9100b1d48aa9c09d792d9e2c9251e6a6c62f81bf.tar.bz2
Merge branch 'vomnibar-in-main-window' into vomnibar-in-main-window-merge
Conflicts: background_scripts/main.coffee content_scripts/vimium_frontend.coffee
Diffstat (limited to 'content_scripts/ui_component.coffee')
-rw-r--r--content_scripts/ui_component.coffee47
1 files changed, 42 insertions, 5 deletions
diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee
index dadc84b5..ea0bf776 100644
--- a/content_scripts/ui_component.coffee
+++ b/content_scripts/ui_component.coffee
@@ -2,6 +2,7 @@ class UIComponent
iframeElement: null
iframePort: null
showing: null
+ options: null
constructor: (iframeUrl, className, @handleMessage) ->
@iframeElement = document.createElement "iframe"
@@ -14,6 +15,13 @@ class UIComponent
# Hide the iframe, but don't interfere with the focus.
@hide false
+ # If any other frame in the current tab receives the focus, then we hide the UI component.
+ # NOTE(smblott) This is correct for the vomnibar, but might be incorrect (and need to be revisited) for
+ # other UI components.
+ chrome.runtime.onMessage.addListener (request) =>
+ @postMessage "hide" if @showing and request.name == "frameFocused" and request.focusFrameId != frameId
+ false # Free up the sendResponse handler.
+
# Open a port and pass it to the iframe via window.postMessage.
openPort: ->
messageChannel = new MessageChannel()
@@ -27,8 +35,8 @@ class UIComponent
postMessage: (message) ->
@iframePort.postMessage message
- activate: (message) ->
- @postMessage message if message?
+ activate: (@options) ->
+ @postMessage @options if @options?
@show() unless @showing
@iframeElement.focus()
@@ -36,6 +44,9 @@ class UIComponent
@postMessage message if message?
@iframeElement.classList.remove "vimiumUIComponentHidden"
@iframeElement.classList.add "vimiumUIComponentShowing"
+ # The window may not have the focus. We focus it now, to prevent the "focus" listener below from firing
+ # immediately.
+ window.focus()
window.addEventListener "focus", @onFocus = (event) =>
if event.target == window
window.removeEventListener "focus", @onFocus
@@ -44,12 +55,38 @@ class UIComponent
@showing = true
hide: (focusWindow = true)->
- @iframeElement.classList.remove "vimiumUIComponentShowing"
- @iframeElement.classList.add "vimiumUIComponentHidden"
+ @refocusSourceFrame @options?.sourceFrameId if focusWindow
window.removeEventListener "focus", @onFocus if @onFocus
@onFocus = null
- window.focus() if focusWindow
+ @iframeElement.classList.remove "vimiumUIComponentShowing"
+ @iframeElement.classList.add "vimiumUIComponentHidden"
+ @options = null
@showing = false
+ # Refocus the frame from which the UI component was opened. This may be different from the current frame.
+ # After hiding the UI component, Chrome refocuses the containing frame. To avoid a race condition, we need
+ # to wait until that frame first receives the focus, before then focusing the frame which should now have
+ # the focus.
+ refocusSourceFrame: (sourceFrameId) ->
+ if @showing and sourceFrameId? and sourceFrameId != frameId
+ refocusSourceFrame = ->
+ chrome.runtime.sendMessage
+ handler: "sendMessageToFrames"
+ message:
+ name: "focusFrame"
+ frameId: sourceFrameId
+ highlight: false
+ highlightOnlyIfNotTop: true
+
+ if windowIsFocused() and false
+ # We already have the focus.
+ refocusSourceFrame()
+ else
+ # We don't yet have the focus (but we'll be getting it soon).
+ window.addEventListener "focus", handler = (event) ->
+ if event.target == window
+ window.removeEventListener "focus", handler
+ refocusSourceFrame()
+
root = exports ? window
root.UIComponent = UIComponent