diff options
Diffstat (limited to 'content_scripts/vimium_frontend.coffee')
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 85 |
1 files changed, 39 insertions, 46 deletions
diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 037d01d3..13d1377d 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -1,8 +1,5 @@ # -# This content script takes input from its webpage and executes commands locally on behalf of the background -# page. It must be run prior to domReady so that we perform some operations very early. We tell the -# background page that we're in domReady and ready to accept normal commands by connectiong to a port named -# "domReady". +# This content script must be run prior to domReady so that we perform some operations very early. # isEnabledForUrl = true @@ -30,10 +27,8 @@ textInputXPath = (-> DomUtils.makeXPath(inputElements) )() -# -# Give this frame a unique (non-zero) id. -# -frameId = 1 + Math.floor(Math.random()*999999999) +# This is set by Frame.registerFrameId(). A frameId of 0 indicates that this is the top frame in the tab. +frameId = null # For debugging only. This logs to the console on the background page. bgLog = (args...) -> @@ -138,6 +133,7 @@ window.initializeModes = -> # Complete initialization work that sould be done prior to DOMReady. # initializePreDomReady = -> + Frame.init() checkIfEnabledForUrl() requestHandlers = @@ -209,30 +205,28 @@ onFocus = (event) -> window.addEventListener "focus", onFocus window.addEventListener "hashchange", onFocus -# -# Initialization tasks that must wait for the document to be ready. -# initializeOnDomReady = -> - # Tell the background page we're in the dom ready state. - chrome.runtime.connect(name: "domReady").onDisconnect.addListener -> - # We disable content scripts when we lose contact with the background page. - isEnabledForUrl = false - chrome.runtime.sendMessage = -> - window.removeEventListener "focus", onFocus - -registerFrame = -> - # Don't register frameset containers; focusing them is no use. - unless document.body?.tagName.toLowerCase() == "frameset" - chrome.runtime.sendMessage - handler: "registerFrame" - frameId: frameId - -# Unregister the frame if we're going to exit. -unregisterFrame = -> - chrome.runtime.sendMessage - handler: "unregisterFrame" - frameId: frameId - tab_is_closing: DomUtils.isTopFrame() + # Tell the background page we're in the domReady state. + Frame.postMessage "domReady" + +Frame = + port: null + listeners: {} + + addEventListener: (handler, callback) -> @listeners[handler] = callback + postMessage: (handler, request = {}) -> @port.postMessage extend request, {handler} + registerFrameId: ({chromeFrameId}) -> frameId = window.frameId = chromeFrameId + + init: (callback) -> + @port = chrome.runtime.connect name: "frames" + + @port.onMessage.addListener (request) => + (@listeners[request.handler] ? this[request.handler]) request + + @port.onDisconnect.addListener -> + # We disable the content scripts when we lose contact with the background page. + isEnabledForUrl = false + window.removeEventListener "focus", onFocus handleShowHUDforDuration = ({ text, duration }) -> if DomUtils.isTopFrame() @@ -271,12 +265,12 @@ DomUtils.documentReady -> # Called from the backend in order to change frame focus. # focusThisFrame = (request) -> - if window.innerWidth < 3 or window.innerHeight < 3 - # This frame is too small to focus. Cancel and tell the background frame to focus the next one instead. - # This affects sites like Google Inbox, which have many tiny iframes. See #1317. - # Here we're assuming that there is at least one frame large enough to focus. - chrome.runtime.sendMessage({ handler: "nextFrame", frameId: frameId }) - return + unless request.forceFocusThisFrame + if window.innerWidth < 3 or window.innerHeight < 3 or document.body?.tagName.toLowerCase() == "frameset" + # This frame is too small to focus or it's a frameset. Cancel and tell the background page to focus the + # next frame instead. This affects sites like Google Inbox, which have many tiny iframes. See #1317. + chrome.runtime.sendMessage handler: "nextFrame", frameId: frameId + return window.focus() flashFrame() if request.highlight @@ -317,7 +311,7 @@ extend window, goToRoot: -> window.location.href = window.location.origin - mainFrame: -> focusThisFrame highlight: true + mainFrame: -> focusThisFrame highlight: true, forceFocusThisFrame: true toggleViewSource: -> chrome.runtime.sendMessage { handler: "getCurrentTabUrl" }, (url) -> @@ -451,10 +445,9 @@ initializeTopFrame = (request = null) -> # 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. -checkIfEnabledForUrl = (frameIsFocused = windowIsFocused()) -> - url = window.location.toString() - chrome.runtime.sendMessage { handler: "isEnabledForUrl", url: url, frameIsFocused: frameIsFocused }, (response) -> - { isEnabledForUrl, passKeys } = response +checkIfEnabledForUrl = do -> + Frame.addEventListener "isEnabledForUrl", (response) -> + {isEnabledForUrl, passKeys, frameIsFocused} = response installListeners() # But only if they have not been installed already. # Initialize UI components. We only initialize these once we know that Vimium is enabled; see #1838. if isEnabledForUrl @@ -472,14 +465,15 @@ checkIfEnabledForUrl = (frameIsFocused = windowIsFocused()) -> if isEnabledForUrl and not passKeys then "enabled" else if isEnabledForUrl then "partial" else "disabled" - null + + (frameIsFocused = windowIsFocused()) -> + Frame.postMessage "isEnabledForUrl", {frameIsFocused, url: window.location.toString()} # When we're informed by the background page that a URL in this tab has changed, we check if we have the # correct enabled state (but only if this frame has the focus). checkEnabledAfterURLChange = -> checkIfEnabledForUrl() if windowIsFocused() - window.handleEscapeForFindMode = -> document.body.classList.remove("vimiumFindMode") # removing the class does not re-color existing selections. we recreate the current selection so it reverts @@ -662,11 +656,10 @@ window.HelpDialog ?= initializePreDomReady() DomUtils.documentReady initializeOnDomReady -DomUtils.documentReady registerFrame -window.addEventListener "unload", unregisterFrame root = exports ? window root.handlerStack = handlerStack root.frameId = frameId +root.Frame = Frame root.windowIsFocused = windowIsFocused root.bgLog = bgLog |
