diff options
| author | Stephen Blott | 2014-12-29 17:28:37 +0000 |
|---|---|---|
| committer | Stephen Blott | 2014-12-29 17:28:37 +0000 |
| commit | f7541ed966859ae893600f5cfd17a1965efd0822 (patch) | |
| tree | 386ac078c3d08c2dba9c6b0a11b49cf0063ed382 | |
| parent | 6c1bbf0ab5781951364464c5fa68ad22f74c9fee (diff) | |
| parent | 7499675455941251eaa69c93e7c66bfb1c6ae35c (diff) | |
| download | vimium-f7541ed966859ae893600f5cfd17a1965efd0822.tar.bz2 | |
Merge branch 'smblott-uicomponent-iframe' into post-1.46-with-uicomponent-iframe
Conflicts:
content_scripts/vimium_frontend.coffee
manifest.json
| -rw-r--r-- | background_scripts/commands.coffee | 3 | ||||
| -rw-r--r-- | background_scripts/main.coffee | 5 | ||||
| -rw-r--r-- | content_scripts/ui_component.coffee | 52 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 1 | ||||
| -rw-r--r-- | manifest.json | 1 | ||||
| -rw-r--r-- | pages/test_ui_component.coffee | 8 | ||||
| -rw-r--r-- | pages/test_ui_component.html | 11 | ||||
| -rw-r--r-- | pages/ui_component_server.coffee | 27 | ||||
| -rw-r--r-- | tests/dom_tests/chrome.coffee | 5 | ||||
| -rw-r--r-- | tests/dom_tests/dom_tests.html | 1 | ||||
| -rw-r--r-- | tests/unit_tests/test_chrome_stubs.coffee | 4 |
11 files changed, 117 insertions, 1 deletions
diff --git a/background_scripts/commands.coffee b/background_scripts/commands.coffee index 585ef572..63b870cc 100644 --- a/background_scripts/commands.coffee +++ b/background_scripts/commands.coffee @@ -91,6 +91,7 @@ Commands = commandGroups: pageNavigation: ["scrollDown", + "activateTestUIComponent", "scrollUp", "scrollLeft", "scrollRight", @@ -252,6 +253,7 @@ defaultKeyMappings = "m": "Marks.activateCreateMode" "`": "Marks.activateGotoMode" + "D": "activateTestUIComponent" # This is a mapping of: commandIdentifier => [description, options]. @@ -263,6 +265,7 @@ commandDescriptions = scrollUp: ["Scroll up"] scrollLeft: ["Scroll left"] scrollRight: ["Scroll right"] + activateTestUIComponent: ["UI component test"] scrollToTop: ["Scroll to the top of the page", { noRepeat: true }] scrollToBottom: ["Scroll to the bottom of the page", { noRepeat: true }] diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index 3753fd75..d01a3f6c 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -19,6 +19,11 @@ namedKeyRegex = /^(<(?:[amc]-.|(?:[amc]-)?[a-z0-9]{2,5})>)(.*)$/ selectionChangedHandlers = [] tabLoadedHandlers = {} # tabId -> function() +# A secret, available only within the current instantiation of Vimium. The secret is big, likely unguessable +# in practice, but less than 2^31. +chrome.storage.local.set + vimiumSecret: Math.floor Math.random() * 2000000000 + completionSources = bookmarks: new BookmarkCompleter() history: new HistoryCompleter() diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee new file mode 100644 index 00000000..d89f0cc8 --- /dev/null +++ b/content_scripts/ui_component.coffee @@ -0,0 +1,52 @@ +class UIComponent + iframeElement: null + iframePort: null + showing: null + showStyle: "display: block;" + hideStyle: "display: none;" + + constructor: (iframeUrl, className, @handleMessage) -> + @iframeElement = document.createElement "iframe" + @iframeElement.className = className + @iframeElement.seamless = "seamless" + @iframeElement.src = chrome.runtime.getURL iframeUrl + @iframeElement.addEventListener "load", => @openPort() + document.documentElement.appendChild @iframeElement + @showing = true # The iframe is visible now. + # Hide the iframe, but don't interfere with the focus. + @hide false + + # Open a port and pass it to the iframe via window.postMessage. + openPort: -> + messageChannel = new MessageChannel() + @iframePort = messageChannel.port1 + @iframePort.onmessage = (event) => @handleMessage event + + # Get vimiumSecret so the iframe can determine that our message isn't the page impersonating us. + chrome.storage.local.get "vimiumSecret", ({vimiumSecret: secret}) => + @iframeElement.contentWindow.postMessage secret, chrome.runtime.getURL(""), [messageChannel.port2] + + postMessage: (message) -> + @iframePort.postMessage message + + activate: (message) -> + @postMessage message if message? + if @showing + # NOTE(smblott) Experimental. Not sure this is a great idea. If the iframe was already showing, then + # the user gets no visual feedback when it is re-focused. So flash its border. + borderWas = @iframeElement.style.border + @iframeElement.style.border = '5px solid yellow' + setTimeout((=> @iframeElement.style.border = borderWas), 200) + else + @iframeElement.setAttribute "style", @showStyle + @showing = true + @iframeElement.focus() + + hide: (focusWindow=true)-> + if @showing + @iframeElement.setAttribute "style", @hideStyle + window.focus() if focusWindow + @showing = false + +root = exports ? window +root.UIComponent = UIComponent diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 2de08c39..114786e8 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -198,7 +198,6 @@ window.addEventListener "focus", -> # initializeOnDomReady = -> enterInsertModeIfElementIsFocused() if isEnabledForUrl - # Tell the background page we're in the dom ready state. chrome.runtime.connect({ name: "domReady" }) CursorHider.init() diff --git a/manifest.json b/manifest.json index 4996d93f..96739d2e 100644 --- a/manifest.json +++ b/manifest.json @@ -37,6 +37,7 @@ "lib/dom_utils.js", "lib/handler_stack.js", "lib/clipboard.js", + "content_scripts/ui_component.js", "content_scripts/link_hints.js", "content_scripts/vomnibar.js", "content_scripts/scroller.js", diff --git a/pages/test_ui_component.coffee b/pages/test_ui_component.coffee new file mode 100644 index 00000000..e140fb14 --- /dev/null +++ b/pages/test_ui_component.coffee @@ -0,0 +1,8 @@ +UIComponentServer.registerHandler (event) -> + document.body.innerHTML = event.data + +window.addEventListener "keydown", (event) -> + if KeyboardUtils.isEscape event + UIComponentServer.postMessage "hide" + else + UIComponentServer.postMessage event.keyCode diff --git a/pages/test_ui_component.html b/pages/test_ui_component.html new file mode 100644 index 00000000..06af346c --- /dev/null +++ b/pages/test_ui_component.html @@ -0,0 +1,11 @@ +<html> + <head> + <title>Test</title> + <script type="text/javascript" src="../lib/keyboard_utils.js"></script> + <script type="text/javascript" src="ui_component_server.js"></script> + <script type="text/javascript" src="test_ui_component.js"></script> + <link rel="stylesheet" type="text/css" href="../content_scripts/vimium.css" /> + </head> + <body> + </body> +</html> diff --git a/pages/ui_component_server.coffee b/pages/ui_component_server.coffee new file mode 100644 index 00000000..8b43095b --- /dev/null +++ b/pages/ui_component_server.coffee @@ -0,0 +1,27 @@ + +# Fetch the Vimium secret, register the port recieved from the parent window, and stop listening for messages +# on the window object. vimiumSecret is accessible only within the current instantion of Vimium. So a +# malicious host page trying to register its own port can do no better than guessing. +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 + + portOpen: (@ownerPagePort) -> + @ownerPagePort.onmessage = (event) => + @handleMessage event if @handleMessage + + registerHandler: (@handleMessage) -> + + postMessage: (message) -> + @ownerPagePort.postMessage message if @ownerPagePort + +root = exports ? window +root.UIComponentServer = UIComponentServer diff --git a/tests/dom_tests/chrome.coffee b/tests/dom_tests/chrome.coffee index 15ed4339..ad4ae74b 100644 --- a/tests/dom_tests/chrome.coffee +++ b/tests/dom_tests/chrome.coffee @@ -20,5 +20,10 @@ root.chrome = { } sendMessage: -> getManifest: -> + getURL: (url) -> "../../#{url}" } + storage: + local: + get: -> + set: -> } diff --git a/tests/dom_tests/dom_tests.html b/tests/dom_tests/dom_tests.html index 6378807f..863c5611 100644 --- a/tests/dom_tests/dom_tests.html +++ b/tests/dom_tests/dom_tests.html @@ -34,6 +34,7 @@ <script type="text/javascript" src="../../lib/dom_utils.js"></script> <script type="text/javascript" src="../../lib/handler_stack.js"></script> <script type="text/javascript" src="../../lib/clipboard.js"></script> + <script type="text/javascript" src="../../content_scripts/ui_component.js"></script> <script type="text/javascript" src="../../content_scripts/link_hints.js"></script> <!-- TODO(smblott) The following is being overridden by the inclusion of "../../pages/vomnibar.js", below, because they both define the same Vomnibar class/object. As a result, there are currently no tests diff --git a/tests/unit_tests/test_chrome_stubs.coffee b/tests/unit_tests/test_chrome_stubs.coffee index 80750337..3258bcd6 100644 --- a/tests/unit_tests/test_chrome_stubs.coffee +++ b/tests/unit_tests/test_chrome_stubs.coffee @@ -42,6 +42,10 @@ exports.chrome = getAll: () -> true storage: + # chrome.storage.local + local: + set: -> + # chrome.storage.onChanged onChanged: addListener: (func) -> @func = func |
