diff options
| author | Stephen Blott | 2016-03-18 06:20:20 +0000 |
|---|---|---|
| committer | Stephen Blott | 2016-03-18 07:21:25 +0000 |
| commit | 51e67b8c623cb68b9be2e172dffc7790da0ae288 (patch) | |
| tree | 69f92ad692d1b850e396af8dd31c40935534d74a | |
| parent | 5f1acf3c66d9e128883a7a54409a08a42ab9ea05 (diff) | |
| download | vimium-51e67b8c623cb68b9be2e172dffc7790da0ae288.tar.bz2 | |
Refactor the front-end initialisation sequence.
The front-end initialisation sequence has become quite confused.
This simplifies it, makes things which must be idemtpotent explicit and
renames some functions to make it clear when they run. It also avoids a
situation where we were possibly installing a `domReady` function to
initialise the HUD multiple times.
Should be a no-op functionality wise.
| -rw-r--r-- | content_scripts/hud.coffee | 2 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 66 | ||||
| -rw-r--r-- | tests/dom_tests/dom_tests.coffee | 4 |
3 files changed, 38 insertions, 34 deletions
diff --git a/content_scripts/hud.coffee b/content_scripts/hud.coffee index aa8a6bbd..92de975b 100644 --- a/content_scripts/hud.coffee +++ b/content_scripts/hud.coffee @@ -46,7 +46,7 @@ HUD = # If :updateIndicator is truthy, then we also refresh the mode indicator. The only time we don't update the # mode indicator, is when hide() is called for the mode indicator itself. hide: (immediate = false, updateIndicator = true) -> - return unless @tween? + return unless @tween? and @isReady() clearTimeout(@_showForDurationTimerId) @tween.stop() if immediate diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index d96e6c65..3acd8ff1 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -4,6 +4,7 @@ isEnabledForUrl = true isIncognitoMode = chrome.extension.inIncognitoContext +normalMode = null # We track whther the current window has the focus or not. windowIsFocused = do -> @@ -122,17 +123,23 @@ class NormalMode extends KeyHandlerMode Utils.invokeCommandString registryEntry.command for i in [0...count] # Only exported for tests. -window.initializeModes = -> +window.installModes = installModes = -> # Install the permanent modes. The permanently-installed insert mode tracks focus/blur events, and # activates/deactivates itself accordingly. normalMode is exported only for the tests. - window.normalMode = new NormalMode + window.normalMode = normalMode = new NormalMode new InsertMode permanent: true + new GrabBackFocus if isEnabledForUrl Scroller.init() + FindModeHistory.init() + +initializeOnEnabledStateKnown = Utils.makeIdempotent -> + installModes() # # Complete initialization work that sould be done prior to DOMReady. # initializePreDomReady = -> + installListeners() Frame.init() checkIfEnabledForUrl() @@ -145,7 +152,7 @@ initializePreDomReady = -> # A frame has received the focus. We don't care here (the Vomnibar/UI-component handles this). frameFocused: -> checkEnabledAfterURLChange: checkEnabledAfterURLChange - initializeTopFrame: initializeTopFrame + initializeTopFrameUIComponents: initializeTopFrameUIComponents runInTopFrame: ({sourceFrameId, registryEntry}) -> Utils.invokeCommandString registryEntry.command, [sourceFrameId, registryEntry] if DomUtils.isTopFrame() @@ -169,18 +176,12 @@ installListener = (element, event, callback) -> # Note: We install the listeners even if Vimium is disabled. See comment in commit # 6446cf04c7b44c3d419dc450a73b60bcaf5cdf02. # -window.installListeners = installListeners = (isEnabledForUrl) -> - # Prevent this initialization from happening more than once. - window.installListeners = installListeners = -> +window.installListeners = installListeners = Utils.makeIdempotent -> # Key event handlers fire on window before they do on document. Prefer window for key events so the page # can't set handlers to grab the keys before us. for type in ["keydown", "keypress", "keyup", "click", "focus", "blur", "mousedown", "scroll"] do (type) -> installListener window, type, (event) -> handlerStack.bubbleEvent type, event installListener document, "DOMActivate", (event) -> handlerStack.bubbleEvent 'DOMActivate', event - # Initialize mode state. - initializeModes() - FindModeHistory.init() - new GrabBackFocus if isEnabledForUrl # # Whenever we get the focus: @@ -421,19 +422,22 @@ extend window, targetElement: document.activeElement indicator: false +# Initialize UI components which are only installed in the main/top frame. +initializeTopFrameUIComponents = Utils.makeIdempotent (request = null) -> + DomUtils.documentReady -> + # 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 (because we're not the top frame). + unless request? + # Tell the top frame to initialize the Vomnibar. We already have "DOMContentLoaded". This ensures + # that the listener in the main/top frame (which are installed pre-DomReady) is ready. + chrome.runtime.sendMessage handler: "sendMessageToFrames", message: name: "initializeTopFrameUIComponents" -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() - DomUtils.documentReady Vomnibar.init.bind Vomnibar - else - # Ignore requests from other frames (we're not the top frame). - unless request? - # Tell the top frame to initialize the Vomnibar. We wait until "DOMContentLoaded" to ensure that the - # listener in the main/top frame (which are installed pre-DomReady) is already installed. - DomUtils.documentReady -> - chrome.runtime.sendMessage handler: "sendMessageToFrames", message: name: "initializeTopFrame" +# Initialize UI components which are only installed in all frames (i.e., the HUD). +initializeAllFrameUIComponents = Utils.makeIdempotent -> + DomUtils.documentReady HUD.init.bind HUD # 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 and set @@ -441,16 +445,16 @@ initializeTopFrame = (request = null) -> checkIfEnabledForUrl = do -> Frame.addEventListener "isEnabledForUrl", (response) -> {isEnabledForUrl, passKeys, frameIsFocused} = response - installListeners isEnabledForUrl - normalMode?.setPassKeys passKeys - # Initialize UI components. We only initialize these once we know that Vimium is enabled; see #1838. + initializeOnEnabledStateKnown() + normalMode.setPassKeys passKeys + # Initialize UI components, if necessary. We only initialize these once we know that Vimium is enabled; + # see #1838. We need to check this every time so that we can change state from disabled to enabled. if isEnabledForUrl - initializeTopFrame() - if frameIsFocused and not HUD.isReady() - DomUtils.documentReady HUD.init.bind HUD - 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() + initializeTopFrameUIComponents() + initializeAllFrameUIComponents() if frameIsFocused + else + # Hide the HUD if we're not enabled. + HUD.hide() if HUD.isReady() (frameIsFocused = windowIsFocused()) -> Frame.postMessage "isEnabledForUrl", {frameIsFocused, url: window.location.toString()} diff --git a/tests/dom_tests/dom_tests.coffee b/tests/dom_tests/dom_tests.coffee index b1d1e586..c3f4ecc1 100644 --- a/tests/dom_tests/dom_tests.coffee +++ b/tests/dom_tests/dom_tests.coffee @@ -1,6 +1,6 @@ # Install frontend event handlers. -installListeners true +installListeners() HUD.init() Frame.registerFrameId chromeFrameId: 0 @@ -28,7 +28,7 @@ commandName = commandCount = null initializeModeState = -> Mode.reset() handlerStack.reset() - initializeModes() + installModes() normalMode.setPassKeys "p" normalMode.setKeyMapping m: options: {}, command: "m" # A mapped key. |
