From 1ad4261ecb3102a5ebc4b5cac05171e5bcabbd4b Mon Sep 17 00:00:00 2001 From: Kenneth Kufluk Date: Wed, 2 Mar 2016 09:39:25 -0800 Subject: [PATCH] Resolve 'frame is null' errors As shown in pull request #120 and currently shown on twitter.com home timeline when scrolling rapidly, the waitForReady function can complain that the frame is null. The probable cause is that the waitForReady method isn't torn down in the destroy method. So if an iframe is destroyed before it initialises, it can throw this kind of error. twitter.com: `Uncaught TypeError: Cannot read property 'contentWindow' of null` I've pulled out the function and added an unbind. I think this makes sense. (Edited through github editor - needs verification/testing) --- src/stack/PostMessageTransport.js | 40 ++++++++++++++++++------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/stack/PostMessageTransport.js b/src/stack/PostMessageTransport.js index ee254ca4..1c7562ae 100644 --- a/src/stack/PostMessageTransport.js +++ b/src/stack/PostMessageTransport.js @@ -85,6 +85,28 @@ easyXDM.stack.PostMessageTransport = function(config){ pub.up.incoming(event.data.substring(config.channel.length + 1), origin); } } + + + /** + * This adds the listener for messages when the frame is ready. + * @private + * @param {Object} event The messageevent + */ + // add the event handler for listening + function _window_waitForReady(event){ + if (event.data == config.channel + "-ready") { + // #ifdef debug + trace("firing onReady"); + // #endif + // replace the eventlistener + callerWindow = ("postMessage" in frame.contentWindow) ? frame.contentWindow : frame.contentWindow.document; + un(window, "message", _window_waitForReady); + on(window, "message", _window_onMessage); + setTimeout(function(){ + pub.up.callback(true); + }, 0); + } + }; return (pub = { outgoing: function(message, domain, fn){ @@ -97,6 +119,7 @@ easyXDM.stack.PostMessageTransport = function(config){ // #ifdef debug trace("destroy"); // #endif + un(window, "message", _window_waitForReady); un(window, "message", _window_onMessage); if (frame) { callerWindow = null; @@ -110,22 +133,7 @@ easyXDM.stack.PostMessageTransport = function(config){ // #endif targetOrigin = getLocation(config.remote); if (config.isHost) { - // add the event handler for listening - var waitForReady = function(event){ - if (event.data == config.channel + "-ready") { - // #ifdef debug - trace("firing onReady"); - // #endif - // replace the eventlistener - callerWindow = ("postMessage" in frame.contentWindow) ? frame.contentWindow : frame.contentWindow.document; - un(window, "message", waitForReady); - on(window, "message", _window_onMessage); - setTimeout(function(){ - pub.up.callback(true); - }, 0); - } - }; - on(window, "message", waitForReady); + on(window, "message", _window_waitForReady); // set up the iframe apply(config.props, {