From 5bfe6dc5d1e0aeb1ab3e372821997d83ba5c9164 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Fri, 15 Apr 2016 16:51:18 +0100 Subject: Rework UI component focus handling. The code to handle the focus for UI components has been tweaked and adapted over time, and has become quite complicated (and brittle). This reworks it from scratch, and co-locates similar code which does related things. Fixes #2099. --- pages/help_dialog.coffee | 26 ++++++-------------------- pages/hud.coffee | 7 +++---- pages/options.coffee | 2 +- pages/ui_component_server.coffee | 13 +++++++++---- pages/vomnibar.coffee | 14 +++++++------- 5 files changed, 26 insertions(+), 36 deletions(-) (limited to 'pages') diff --git a/pages/help_dialog.coffee b/pages/help_dialog.coffee index 0e4a8973..0300ec00 100644 --- a/pages/help_dialog.coffee +++ b/pages/help_dialog.coffee @@ -6,7 +6,7 @@ # top-level frame), and then we don't need to be concerned about nested help dialog frames. HelpDialog = dialogElement: null - showing: true + isShowing: -> true # This setting is pulled out of local storage. It's false by default. getShowAdvancedCommands: -> Settings.get("helpDialog_showAdvancedCommands") @@ -30,9 +30,7 @@ HelpDialog = @hide() unless @dialogElement.contains event.target , false - isReady: -> true - - show: (html) -> + show: ({html}) -> for own placeholder, htmlString of html @dialogElement.querySelector("#help-dialog-#{placeholder}").innerHTML = htmlString @@ -48,15 +46,8 @@ HelpDialog = chrome.runtime.sendMessage handler: "copyToClipboard", data: commandName HUD.showForDuration("Yanked #{commandName}.", 2000) - @exitOnEscape = new Mode name: "help-page-escape", exitOnEscape: true - @exitOnEscape.onExit (event) => @hide() if event?.type == "keydown" - - hide: -> - @exitOnEscape?.exit() - UIComponentServer.postMessage "hide" - - toggle: (html) -> - if @showing then @hide() else @show html + hide: -> UIComponentServer.hide() + toggle: (html) -> @hide() # # Advanced commands are hidden by default so they don't overwhelm new and casual users. @@ -77,13 +68,8 @@ HelpDialog = UIComponentServer.registerHandler (event) -> switch event.data.name ? event.data - when "frameFocused" - # We normally close when we lose the focus. However, we do not close on the options page. This allows - # users to view the help dialog while typing in the key-mappings input. - HelpDialog.hide() unless event.data.focusFrameId == frameId or try window.top.isVimiumOptionsPage - when "hide" - HelpDialog.hide() - else + when "hide" then HelpDialog.hide() + when "activate" HelpDialog.init() HelpDialog.show event.data diff --git a/pages/hud.coffee b/pages/hud.coffee index 17ac52be..d2e35cec 100644 --- a/pages/hud.coffee +++ b/pages/hud.coffee @@ -50,7 +50,7 @@ handlers = document.getElementById("hud").innerText = data.text document.getElementById("hud").classList.add "vimiumUIComponentVisible" document.getElementById("hud").classList.remove "vimiumUIComponentHidden" - hide: -> + hidden: -> # We get a flicker when the HUD later becomes visible again (with new text) unless we reset its contents # here. document.getElementById("hud").innerText = "" @@ -96,8 +96,7 @@ handlers = " (No matches)" countElement.textContent = if showMatchText then countText else "" -UIComponentServer.registerHandler (event) -> - {data} = event - handlers[data.name]? data +UIComponentServer.registerHandler ({data}) -> + handlers[data.name ? data]? data FindModeHistory.init() diff --git a/pages/options.coffee b/pages/options.coffee index c708efa7..3e1843a7 100644 --- a/pages/options.coffee +++ b/pages/options.coffee @@ -234,7 +234,7 @@ initOptionsPage = -> event.preventDefault() activateHelpDialog = -> - HelpDialog.show chrome.extension.getBackgroundPage().helpDialogHtml(true, true, "Command Listing"), frameId + HelpDialog.toggle chrome.extension.getBackgroundPage().helpDialogHtml true, true, "Command Listing" saveOptions = -> Option.saveOptions() diff --git a/pages/ui_component_server.coffee b/pages/ui_component_server.coffee index 4210a60e..9f72dd92 100644 --- a/pages/ui_component_server.coffee +++ b/pages/ui_component_server.coffee @@ -2,14 +2,12 @@ # Fetch the Vimium secret, register the port received from the parent window, and stop listening for messages # on the window object. vimiumSecret is accessible only within the current instance of Vimium. So a # malicious host page trying to register its own port can do no better than guessing. -registerPort = (event) -> +window.addEventListener "message", registerPort = (event) -> chrome.storage.local.get "vimiumSecret", ({vimiumSecret: secret}) -> return unless event.source == window.parent and event.data == secret UIComponentServer.portOpen event.ports[0] window.removeEventListener "message", registerPort -window.addEventListener "message", registerPort - UIComponentServer = ownerPagePort: null handleMessage: null @@ -23,6 +21,9 @@ UIComponentServer = postMessage: (message) -> @ownerPagePort?.postMessage message + hide: -> + @postMessage "hide" + # We require both that the DOM is ready and that the port has been opened before the UI component is ready. # These events can happen in either order. We count them, and notify the content script when we've seen # both. @@ -34,7 +35,11 @@ UIComponentServer = else 1 - -> @postMessage "uiComponentIsReady" if ++uiComponentIsReadyCount == 2 + -> + if ++uiComponentIsReadyCount == 2 + @postMessage {name: "setIframeFrameId", iframeFrameId: window.frameId} if window.frameId? + @postMessage "uiComponentIsReady" root = exports ? window root.UIComponentServer = UIComponentServer +root.isVimiumUIComponent = true diff --git a/pages/vomnibar.coffee b/pages/vomnibar.coffee index 0332b12f..449c0bac 100644 --- a/pages/vomnibar.coffee +++ b/pages/vomnibar.coffee @@ -38,7 +38,7 @@ Vomnibar = class VomnibarUI constructor: -> @refreshInterval = 0 - @postHideCallback = null + @onHiddenCallback = null @initDom() setQuery: (query) -> @input.value = query @@ -56,14 +56,14 @@ class VomnibarUI # 3. Only once the "hidden" message is received here is any required action invoked (in onHidden). # This ensures that the vomnibar is actually hidden before any new tab is created, and avoids flicker after # opening a link in a new tab then returning to the original tab (see #1485). - hide: (@postHideCallback = null) -> + hide: (@onHiddenCallback = null) -> UIComponentServer.postMessage "hide" @reset() - @completer?.reset() onHidden: -> - @postHideCallback?() - @postHideCallback = null + @onHiddenCallback?() + @onHiddenCallback = null + @reset() reset: -> @clearUpdateTimer() @@ -75,6 +75,7 @@ class VomnibarUI @selection = @initialSelectionValue @keywords = [] @seenTabToOpenCompletionList = false + @completer?.reset() updateSelection: -> # For custom search engines, we suppress the leading term (e.g. the "w" of "w query terms") within the @@ -331,10 +332,9 @@ class BackgroundCompleter UIComponentServer.registerHandler (event) -> switch event.data.name ? event.data - when "frameFocused" then Vomnibar.hide() when "hide" then Vomnibar.hide() when "hidden" then Vomnibar.onHidden() - else Vomnibar.activate event.data + when "activate" then Vomnibar.activate event.data root = exports ? window root.Vomnibar = Vomnibar -- cgit v1.2.3 From f3aba1914dc645d4de15ff6e6a9104dcb99018ee Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sat, 16 Apr 2016 14:30:05 +0100 Subject: Remove dead code from the HUD initialization. --- pages/hud.coffee | 4 ---- 1 file changed, 4 deletions(-) (limited to 'pages') diff --git a/pages/hud.coffee b/pages/hud.coffee index d2e35cec..e35e587e 100644 --- a/pages/hud.coffee +++ b/pages/hud.coffee @@ -63,7 +63,6 @@ handlers = inputElement = document.createElement "span" inputElement.contentEditable = "plaintext-only" - setTextInInputElement inputElement, data.text if data.text inputElement.id = "hud-find-input" hud.appendChild inputElement @@ -77,9 +76,6 @@ handlers = hud.appendChild countElement inputElement.focus() - # Replace \u00A0 ( ) with a normal space. - UIComponentServer.postMessage {name: "search", query: inputElement.textContent.replace "\u00A0", " "} - findMode = historyIndex: -1 partialQuery: "" -- cgit v1.2.3 From ae1a54157291c0bcc69a6e8652bc15e69b72b4e4 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sat, 16 Apr 2016 16:36:35 +0100 Subject: Do not focus a hidden help dialog. When the help dialog UI component has been created but subsequently hidden, `gf` was nevertheless selecting it. --- pages/help_dialog.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'pages') diff --git a/pages/help_dialog.coffee b/pages/help_dialog.coffee index 0300ec00..7fee8bf9 100644 --- a/pages/help_dialog.coffee +++ b/pages/help_dialog.coffee @@ -6,7 +6,8 @@ # top-level frame), and then we don't need to be concerned about nested help dialog frames. HelpDialog = dialogElement: null - isShowing: -> true + showing: false + isShowing: -> @showing # This setting is pulled out of local storage. It's false by default. getShowAdvancedCommands: -> Settings.get("helpDialog_showAdvancedCommands") @@ -69,8 +70,10 @@ HelpDialog = UIComponentServer.registerHandler (event) -> switch event.data.name ? event.data when "hide" then HelpDialog.hide() + when "hidden" then HelpDialog.showing = false when "activate" HelpDialog.init() + HelpDialog.showing = true HelpDialog.show event.data root = exports ? window -- cgit v1.2.3 From e07a252508eea45c4dcadc92cdad02d42df2f5f8 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sat, 16 Apr 2016 16:54:12 +0100 Subject: Minor code review. --- pages/help_dialog.coffee | 2 +- pages/hud.coffee | 4 +--- pages/ui_component_server.coffee | 7 ++----- 3 files changed, 4 insertions(+), 9 deletions(-) (limited to 'pages') diff --git a/pages/help_dialog.coffee b/pages/help_dialog.coffee index 7fee8bf9..2ea4353c 100644 --- a/pages/help_dialog.coffee +++ b/pages/help_dialog.coffee @@ -48,7 +48,7 @@ HelpDialog = HUD.showForDuration("Yanked #{commandName}.", 2000) hide: -> UIComponentServer.hide() - toggle: (html) -> @hide() + toggle: -> @hide() # # Advanced commands are hidden by default so they don't overwhelm new and casual users. diff --git a/pages/hud.coffee b/pages/hud.coffee index e35e587e..fcc7b1dd 100644 --- a/pages/hud.coffee +++ b/pages/hud.coffee @@ -92,7 +92,5 @@ handlers = " (No matches)" countElement.textContent = if showMatchText then countText else "" -UIComponentServer.registerHandler ({data}) -> - handlers[data.name ? data]? data - +UIComponentServer.registerHandler ({data}) -> handlers[data.name ? data]? data FindModeHistory.init() diff --git a/pages/ui_component_server.coffee b/pages/ui_component_server.coffee index 9f72dd92..488ff0ed 100644 --- a/pages/ui_component_server.coffee +++ b/pages/ui_component_server.coffee @@ -18,11 +18,8 @@ UIComponentServer = registerHandler: (@handleMessage) -> - postMessage: (message) -> - @ownerPagePort?.postMessage message - - hide: -> - @postMessage "hide" + postMessage: (message) -> @ownerPagePort?.postMessage message + hide: -> @postMessage "hide" # We require both that the DOM is ready and that the port has been opened before the UI component is ready. # These events can happen in either order. We count them, and notify the content script when we've seen -- cgit v1.2.3 From 025b7f930205e9dfbae5f2dff5c7c1fd4a45e4c1 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 17 Apr 2016 10:18:08 +0100 Subject: Use register/unregister frame in help dialog. Remove special-purpose code from `gf`. Instead, register the help dialog frame when it launches, and unregister it when it's hidden. This way, when the helpd-dialog frame is hidden, it simply isn't available for `gf` and for link hints. --- pages/help_dialog.coffee | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'pages') diff --git a/pages/help_dialog.coffee b/pages/help_dialog.coffee index 2ea4353c..111ef73e 100644 --- a/pages/help_dialog.coffee +++ b/pages/help_dialog.coffee @@ -6,8 +6,7 @@ # top-level frame), and then we don't need to be concerned about nested help dialog frames. HelpDialog = dialogElement: null - showing: false - isShowing: -> @showing + isShowing: -> true # This setting is pulled out of local storage. It's false by default. getShowAdvancedCommands: -> Settings.get("helpDialog_showAdvancedCommands") @@ -70,11 +69,13 @@ HelpDialog = UIComponentServer.registerHandler (event) -> switch event.data.name ? event.data when "hide" then HelpDialog.hide() - when "hidden" then HelpDialog.showing = false when "activate" HelpDialog.init() - HelpDialog.showing = true HelpDialog.show event.data + Frame.postMessage "registerFrame" + when "hidden" + # Unregister the frame, so that it's not available for `gf` or linkk hints. + Frame.postMessage "unregisterFrame" root = exports ? window root.HelpDialog = HelpDialog -- cgit v1.2.3 From d43f18bd5ce7c39e8e663a657027b233707e2926 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 17 Apr 2016 11:13:27 +0100 Subject: More code review of UI-component focus handling. --- pages/help_dialog.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pages') diff --git a/pages/help_dialog.coffee b/pages/help_dialog.coffee index 111ef73e..990fa063 100644 --- a/pages/help_dialog.coffee +++ b/pages/help_dialog.coffee @@ -74,7 +74,7 @@ UIComponentServer.registerHandler (event) -> HelpDialog.show event.data Frame.postMessage "registerFrame" when "hidden" - # Unregister the frame, so that it's not available for `gf` or linkk hints. + # Unregister the frame, so that it's not available for `gf` or link hints. Frame.postMessage "unregisterFrame" root = exports ? window -- cgit v1.2.3