From 1ae621489da091e6d9430da248d0e6eaab606f35 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Mon, 16 Mar 2015 09:35:24 +0000 Subject: Activate vomnibar in window.top. This changes vomnibar commands to activate not in the current frame, but in window.top. Consequently, the vomnibar always appears in the same position, and we don't get odd looking vomnibars in small frames. Apart from the better UX, this seems to be the right thing to do. Vomnibar commands apply to tabs (not frames). Currently incomplete: - On exit, the focus is not returned to the frame which originally had the focus. (It's returned to window.top). - The vomnibar can lose the focus and not hide itself for various frame/click combinations. --- content_scripts/ui_component.coffee | 3 +++ 1 file changed, 3 insertions(+) (limited to 'content_scripts/ui_component.coffee') diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee index dadc84b5..b582cb5d 100644 --- a/content_scripts/ui_component.coffee +++ b/content_scripts/ui_component.coffee @@ -36,6 +36,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 so that the focus listener below isn't triggered + # immediately. + window.focus() window.addEventListener "focus", @onFocus = (event) => if event.target == window window.removeEventListener "focus", @onFocus -- cgit v1.2.3 From efada88f419933c5bd1478faada3b4eff3082103 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Tue, 17 Mar 2015 09:18:52 +0000 Subject: Activate vomnibar in window.top; refocus original frame. --- content_scripts/ui_component.coffee | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'content_scripts/ui_component.coffee') diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee index b582cb5d..3a4af6b5 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" @@ -27,8 +28,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() @@ -51,7 +52,14 @@ class UIComponent @iframeElement.classList.add "vimiumUIComponentHidden" window.removeEventListener "focus", @onFocus if @onFocus @onFocus = null - window.focus() if focusWindow + if focusWindow and @options?.frameId? + chrome.runtime.sendMessage + handler: "sendMessageToFrame" + frameId: frameId + targetFrameId: @options.frameId + name: "focusFrame" + highlight: true # true for debugging; should be false when live. + @options = null @showing = false root = exports ? window -- cgit v1.2.3 From aa8d00fd9779d4061431dbdcb7a70b9c39e8049a Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Tue, 17 Mar 2015 09:47:46 +0000 Subject: Activate vomnibar in window.top; simplify messaging. --- content_scripts/ui_component.coffee | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'content_scripts/ui_component.coffee') diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee index 3a4af6b5..82398727 100644 --- a/content_scripts/ui_component.coffee +++ b/content_scripts/ui_component.coffee @@ -54,11 +54,11 @@ class UIComponent @onFocus = null if focusWindow and @options?.frameId? chrome.runtime.sendMessage - handler: "sendMessageToFrame" - frameId: frameId - targetFrameId: @options.frameId - name: "focusFrame" - highlight: true # true for debugging; should be false when live. + handler: "sendMessageToFrames" + message: + name: "focusFrame" + frameId: @options.frameId + highlight: true # true for debugging; should be false when live. @options = null @showing = false -- cgit v1.2.3 From 9461d30b0d19fd65dc43e18bebec1fe0fd3ee818 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Tue, 17 Mar 2015 10:32:40 +0000 Subject: Activate vomnibar in window.top; hide on focus. --- content_scripts/ui_component.coffee | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'content_scripts/ui_component.coffee') diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee index 82398727..64dddf67 100644 --- a/content_scripts/ui_component.coffee +++ b/content_scripts/ui_component.coffee @@ -15,6 +15,11 @@ class UIComponent # Hide the iframe, but don't interfere with the focus. @hide false + # If any frame in the current tab receives the focus, then we hide the vomnibar. + chrome.runtime.onMessage.addListener (request) => + @hide false if @showing and request.name == "frameFocused" + false # Free up response handler. + # Open a port and pass it to the iframe via window.postMessage. openPort: -> messageChannel = new MessageChannel() @@ -37,21 +42,11 @@ 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 so that the focus listener below isn't triggered - # immediately. - window.focus() - window.addEventListener "focus", @onFocus = (event) => - if event.target == window - window.removeEventListener "focus", @onFocus - @onFocus = null - @postMessage "hide" @showing = true hide: (focusWindow = true)-> @iframeElement.classList.remove "vimiumUIComponentShowing" @iframeElement.classList.add "vimiumUIComponentHidden" - window.removeEventListener "focus", @onFocus if @onFocus - @onFocus = null if focusWindow and @options?.frameId? chrome.runtime.sendMessage handler: "sendMessageToFrames" -- cgit v1.2.3 From 8bc811aae1118e28faa7c17e67b039c67f637274 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Tue, 17 Mar 2015 11:42:58 +0000 Subject: Activate vomnibar in window.top; hide on focus, fixed. --- content_scripts/ui_component.coffee | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'content_scripts/ui_component.coffee') diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee index 64dddf67..3d8cef29 100644 --- a/content_scripts/ui_component.coffee +++ b/content_scripts/ui_component.coffee @@ -15,9 +15,9 @@ class UIComponent # Hide the iframe, but don't interfere with the focus. @hide false - # If any frame in the current tab receives the focus, then we hide the vomnibar. + # If any other frame in the current tab receives the focus, then we hide the vomnibar. chrome.runtime.onMessage.addListener (request) => - @hide false if @showing and request.name == "frameFocused" + @hide false if @showing and request.name == "frameFocused" and request.frameId != frameId false # Free up response handler. # Open a port and pass it to the iframe via window.postMessage. @@ -42,11 +42,21 @@ 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 + @onFocus = null + @postMessage "hide" @showing = true hide: (focusWindow = true)-> @iframeElement.classList.remove "vimiumUIComponentShowing" @iframeElement.classList.add "vimiumUIComponentHidden" + window.removeEventListener "focus", @onFocus if @onFocus + @onFocus = null if focusWindow and @options?.frameId? chrome.runtime.sendMessage handler: "sendMessageToFrames" -- cgit v1.2.3 From 4399e2e4fffc4faba9f1505dfc0ad3150a948632 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Tue, 17 Mar 2015 12:06:15 +0000 Subject: Activate vomnibar in window.top; more clean up. --- content_scripts/ui_component.coffee | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'content_scripts/ui_component.coffee') diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee index 3d8cef29..185d525a 100644 --- a/content_scripts/ui_component.coffee +++ b/content_scripts/ui_component.coffee @@ -15,9 +15,11 @@ 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 vomnibar. + # 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) => - @hide false if @showing and request.name == "frameFocused" and request.frameId != frameId + @hide false if @showing and request.name == "frameFocused" and request.focusFrameId != frameId false # Free up response handler. # Open a port and pass it to the iframe via window.postMessage. @@ -57,12 +59,12 @@ class UIComponent @iframeElement.classList.add "vimiumUIComponentHidden" window.removeEventListener "focus", @onFocus if @onFocus @onFocus = null - if focusWindow and @options?.frameId? + if focusWindow and @options?.sourceFrameId? chrome.runtime.sendMessage handler: "sendMessageToFrames" message: name: "focusFrame" - frameId: @options.frameId + frameId: @options.sourceFrameId highlight: true # true for debugging; should be false when live. @options = null @showing = false -- cgit v1.2.3 From 71d33fdeaa5c081de5041a6a0909d452e1564633 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Tue, 17 Mar 2015 13:21:02 +0000 Subject: Activate vomnibar in window.top; fix race condition on close. --- content_scripts/ui_component.coffee | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'content_scripts/ui_component.coffee') diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee index 185d525a..727f6c27 100644 --- a/content_scripts/ui_component.coffee +++ b/content_scripts/ui_component.coffee @@ -19,7 +19,7 @@ class UIComponent # 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) => - @hide false if @showing and request.name == "frameFocused" and request.focusFrameId != frameId + @postMessage "hide" if @showing and request.name == "frameFocused" and request.focusFrameId != frameId false # Free up response handler. # Open a port and pass it to the iframe via window.postMessage. @@ -55,19 +55,29 @@ class UIComponent @showing = true hide: (focusWindow = true)-> - @iframeElement.classList.remove "vimiumUIComponentShowing" - @iframeElement.classList.add "vimiumUIComponentHidden" + @refocusSourceFrame @options?.sourceFrameId if focusWindow and @options?.sourceFrameId? window.removeEventListener "focus", @onFocus if @onFocus @onFocus = null - if focusWindow and @options?.sourceFrameId? - chrome.runtime.sendMessage - handler: "sendMessageToFrames" - message: - name: "focusFrame" - frameId: @options.sourceFrameId - highlight: true # true for debugging; should be false when live. + @iframeElement.classList.remove "vimiumUIComponentShowing" + @iframeElement.classList.add "vimiumUIComponentHidden" @options = null @showing = false + # Refocus the frame from which the UI component was opened. + # After hiding the UI component, Chrome refocuses the containing frame. To avoid a race condition, we need + # to wait until that frame receives the focus, before then focusing the frame which should now have the + # focus. + refocusSourceFrame: (sourceFrameId) -> + window.addEventListener "focus", handler = (event) -> + if event.target == window + window.removeEventListener "focus", handler + chrome.runtime.sendMessage + handler: "sendMessageToFrames" + message: + name: "focusFrame" + frameId: sourceFrameId + highlight: false + highlightOnlyIfNotTop: true + root = exports ? window root.UIComponent = UIComponent -- cgit v1.2.3 From b65f285aa65b2cfbdaefb4d7c445dbd5e684fbbf Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Tue, 17 Mar 2015 14:29:12 +0000 Subject: Activate vomnibar in window.top; more clean up. Clean up, and fixes following code review from @mrmr1993. --- content_scripts/ui_component.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'content_scripts/ui_component.coffee') diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee index 727f6c27..ee74c3a8 100644 --- a/content_scripts/ui_component.coffee +++ b/content_scripts/ui_component.coffee @@ -20,7 +20,7 @@ class UIComponent # other UI components. chrome.runtime.onMessage.addListener (request) => @postMessage "hide" if @showing and request.name == "frameFocused" and request.focusFrameId != frameId - false # Free up response handler. + false # Free up the sendResponse handler. # Open a port and pass it to the iframe via window.postMessage. openPort: -> -- cgit v1.2.3 From bfa6c88b41acac4c98d06f324f25f8bb7b328614 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Thu, 23 Apr 2015 11:07:36 +0100 Subject: Activate vomnibar in window.top; no flicker and tidy up. 1. Rework event handling to eliminate frame flicker (a la #1485). 2. Tidy up logic. Which should make this more robust. --- content_scripts/ui_component.coffee | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'content_scripts/ui_component.coffee') diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee index ee74c3a8..ea0bf776 100644 --- a/content_scripts/ui_component.coffee +++ b/content_scripts/ui_component.coffee @@ -55,7 +55,7 @@ class UIComponent @showing = true hide: (focusWindow = true)-> - @refocusSourceFrame @options?.sourceFrameId if focusWindow and @options?.sourceFrameId? + @refocusSourceFrame @options?.sourceFrameId if focusWindow window.removeEventListener "focus", @onFocus if @onFocus @onFocus = null @iframeElement.classList.remove "vimiumUIComponentShowing" @@ -63,14 +63,13 @@ class UIComponent @options = null @showing = false - # Refocus the frame from which the UI component was opened. + # 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 receives the focus, before then focusing the frame which should now have the - # focus. + # to wait until that frame first receives the focus, before then focusing the frame which should now have + # the focus. refocusSourceFrame: (sourceFrameId) -> - window.addEventListener "focus", handler = (event) -> - if event.target == window - window.removeEventListener "focus", handler + if @showing and sourceFrameId? and sourceFrameId != frameId + refocusSourceFrame = -> chrome.runtime.sendMessage handler: "sendMessageToFrames" message: @@ -79,5 +78,15 @@ class UIComponent 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 -- cgit v1.2.3