Created
June 17, 2015 22:03
-
-
Save rhumlover/f016bb010afa375df239 to your computer and use it in GitHub Desktop.
Fancy ScopedFrame
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Worker = require 'models/worker' | |
class ScopedFrame | |
# Private | |
_uniqueId = (prefix) -> | |
return prefix + Math.random().toString(36).slice(2) | |
_messageReceivedByParent = (message) -> | |
{origin, data} = message | |
return if origin isnt location.origin | |
return if (not data.sid) or data.sid isnt @sid | |
@worker.trigger data.transactionId, data.data | |
false | |
_messageReceivedByIframe = (message) -> | |
{data} = message | |
if data.sid and data.sid is @sid | |
message.reply = _reply.bind @, message | |
@worker.trigger data.action, data.data, message | |
false | |
_reply = (firstMessage, data) -> | |
{sid, transactionId, action} = firstMessage.data | |
message = { | |
sid | |
transactionId | |
action | |
data | |
} | |
window.postMessage message, firstMessage.origin | |
# Exposed | |
constructor: (options) -> | |
{@content, @style, @onLoad} = options | |
@sid = _uniqueId 'sid-' | |
@rendered = no | |
@worker = new Worker() | |
render: -> | |
return if @rendered | |
el = document.createElement 'iframe' | |
if @style? | |
Object.keys(@style).forEach( | |
(key) -> el.style[key] = @[key] | |
@style | |
) | |
document.body.appendChild el | |
ifWindow = el.contentWindow | |
ifDocument = ifWindow.document | |
ifDocument.open() | |
ifDocument.write @content | |
ifDocument.close() | |
window.addEventListener 'message', _messageReceivedByParent.bind(@), false | |
ifWindow.addEventListener 'message', _messageReceivedByIframe.bind(@), false | |
ifDocument.onreadystatechange = => | |
if ifDocument.readyState is 'interactive' then @onLoad?() | |
@rendered = yes | |
@el = el | |
getWindow: -> | |
@el.contentWindow | |
listen: (action) -> | |
unless @rendered | |
console.warn 'ScopedFrame: trying to listen for a message in an unrendered document. Render your ScopedFrame first.' | |
return | |
@worker.listen action, @el.contentWindow | |
send: (action, data) -> | |
unless @rendered | |
console.warn 'ScopedFrame: trying to send a message to an unrendered document. Render your ScopedFrame first.' | |
return | |
message = { | |
transactionId: _uniqueId 'tid-' | |
@sid | |
action | |
data | |
} | |
@el.contentWindow.postMessage message, location.origin | |
eventStream = @worker.listen message.transactionId | |
eventStream.onReply = eventStream.then | |
eventStream | |
module.exports = ScopedFrame |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment