Commit 1a956785 authored by Nick Stenning's avatar Nick Stenning

Fix Hypothesis on local HTML documents

The only thing stopping Hypothesis from working on local (i.e. file://
URL) HTML documents is the failure of the discovery module due to quirks
in the `postMessage` security policy.

This commit works around that issue so that embedding or injecting
Hypothesis on local HTML documents works as expected.

Fixes #2005.
parent 8137324b
...@@ -86,6 +86,15 @@ module.exports = class Discovery ...@@ -86,6 +86,15 @@ module.exports = class Discovery
_onMessage: (event) => _onMessage: (event) =>
{source, origin, data} = event {source, origin, data} = event
# If `origin` is 'null' the source frame is a file URL or loaded over some
# other scheme for which the `origin` is undefined. In this case, the only
# way to ensure the message arrives is to use the wildcard origin. See:
#
# https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
#
if origin is 'null'
origin = '*'
# Check if the message is at all related to our discovery mechanism # Check if the message is at all related to our discovery mechanism
match = data.match? /^__cross_frame_dhcp_(discovery|offer|request|ack)(?::(\d+))?$/ match = data.match? /^__cross_frame_dhcp_(discovery|offer|request|ack)(?::(\d+))?$/
return unless match return unless match
......
...@@ -74,6 +74,18 @@ describe 'Discovery', -> ...@@ -74,6 +74,18 @@ describe 'Discovery', ->
matcher = sinon.match(/__cross_frame_dhcp_ack:\d+/) matcher = sinon.match(/__cross_frame_dhcp_ack:\d+/)
assert.calledWith(fakeTopWindow.postMessage, matcher, 'top') assert.calledWith(fakeTopWindow.postMessage, matcher, 'top')
it 'sends an "ack" to the wildcard origin if a request comes from a frame with null origin', ->
fakeFrameWindow.addEventListener.yields({
data: '__cross_frame_dhcp_request'
source: fakeTopWindow
origin: 'null'
})
server.startDiscovery(->)
assert.called(fakeTopWindow.postMessage)
matcher = sinon.match(/__cross_frame_dhcp_ack:\d+/)
assert.calledWith(fakeTopWindow.postMessage, matcher, '*')
it 'calls the discovery callback on receiving "request"', -> it 'calls the discovery callback on receiving "request"', ->
fakeFrameWindow.addEventListener.yields({ fakeFrameWindow.addEventListener.yields({
data: '__cross_frame_dhcp_request' data: '__cross_frame_dhcp_request'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment