PostMessage Example

by dshilkret

HTML

<iframe id="sandbox" style="display: none;" sandbox="allow-scripts" srcdoc=""></iframe>
<div id="template" style="display: none;">
    var parent;
    console.log( 'initializing iframe' );
    window.addEventListener('message', function(e){
        console.log( 'iframe heard a message', e );
        if (!parent) parent = e.source;
        if (e.data) execute( e.data );
    }, false);
    function execute(data){
        var alert,
            messageId = data.messageId,
            code = data.code,
            window = {
                alert: alert = function(text){ console.log( text ); }
            },
            value;
    
        try {
            value = eval( '' + code );
        } catch(e) {
            value = e;
        }
    
        //parent.postMessage({ isSafeEvalResponse: true, messageId: messageId, value: value }, "*");
    }
</div>
<textarea id="code">alert('this should go to the console');</textarea><br>
<button id="eval">evaluate &#8594;</button> <input id="result" /><br>
<button id="reset">reset</button>

CSS

#code {
    font-family: monospace;
    width: 30em;
    height: 10em;
}

JavaScript

// click handler

$('#eval').click(function(){
    var code = $('#code').val();
    safeEval( code ).done(function(v){
        $('#result').val( v );
    });
    alert('this should still work');
});


// safe eval def and init

(function(){

    var messageId = 0,
        iframe = $( '<iframe id="sandbox">' )
                    .hide()
                    .attr('sandbox', 'allow-scripts')
                    .attr('srcdoc', '<' + 'script>' + $('#template').text() + '<' + '/script>')
    				.on( 'load' )
                    .appendTo($('body'));
    var iframePost = iframe[0].contentWindow.postMessage;
    
    $('#reset').click(function(){
        iframePost = iframe[0].contentWindow.postMessage;
        iframePost(null, "*");
    });

    // safe eval function

    function safeEval(code){
        var d = $.Deferred();

        try {
            var mId = ++messageId,
                eventNamespace = '.safeEval_' + mId;
            window.addEventListener('message', function(e){
                console.log( 'wait... why is THIS being called???' );
                console.log( e );
                d.resolve( e.data );
            }, false);
            /*
            $(window).one( 'message' + eventNamespace, function(e){
                console.log( 'wait... why is THIS being called???' );
                console.log( e );
                d.resolve( e.data );
            });
            */
            iframePost({ messageId: mId, code: code }, "*");
        } catch (e) {
            d.resolve( e );
        }

        return d.promise();
    }
    
    window.safeEval = safeEval;

}());