aboutsummaryrefslogtreecommitdiffstats
path: root/pages
diff options
context:
space:
mode:
authorStephen Blott2016-04-15 16:51:18 +0100
committerStephen Blott2016-04-16 14:15:33 +0100
commit5bfe6dc5d1e0aeb1ab3e372821997d83ba5c9164 (patch)
tree174c58b552cc0b869764d2dd28f14bb3f010ef2c /pages
parent014f53fb091ac8672d3efbeca13a494c15d8afcb (diff)
downloadvimium-5bfe6dc5d1e0aeb1ab3e372821997d83ba5c9164.tar.bz2
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.
Diffstat (limited to 'pages')
-rw-r--r--pages/help_dialog.coffee26
-rw-r--r--pages/hud.coffee7
-rw-r--r--pages/options.coffee2
-rw-r--r--pages/ui_component_server.coffee13
-rw-r--r--pages/vomnibar.coffee14
5 files changed, 26 insertions, 36 deletions
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