Skip to content

Commit

Permalink
Stop using jQuery for managing the iframe in the foreverFrame transport
Browse files Browse the repository at this point in the history
- Hopefully this will avoid "SCRIPT70: Permission denied" errors in IE

#2508
  • Loading branch information
halter73 committed Sep 18, 2013
1 parent e2a9dab commit ea88f3d
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 20 deletions.
Expand Up @@ -10,6 +10,11 @@
events = $.signalR.events,
changeState = $.signalR.changeState,
transportLogic = signalR.transports._logic,
createFrame = function () {
var frame = window.document.createElement("iframe");
frame.setAttribute("style", "position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;");
return frame;
},
// Used to prevent infinite loading icon spins in older versions of ie
// We build this object inside a closure so we don't pollute the rest of
// the foreverFrame transport with unnecessary functions/utilities.
Expand All @@ -26,10 +31,11 @@
if (attachedTo === 0) {
// Create and destroy iframe every 3 seconds to prevent loading icon, super hacky
loadingFixIntervalId = window.setInterval(function () {
var tempFrame = $("<iframe style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;' src=''></iframe>");
var tempFrame = createFrame();

window.document.body.appendChild(tempFrame);
window.document.body.removeChild(tempFrame);

$("body").append(tempFrame);
tempFrame.remove();
tempFrame = null;
}, loadingFixInterval);
}
Expand Down Expand Up @@ -61,7 +67,11 @@
var that = this,
frameId = (transportLogic.foreverFrame.count += 1),
url,
frame = $("<iframe data-signalr-connection-id='" + connection.id + "' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;' src=''></iframe>");
frame = createFrame(),
frameLoadHandler = function () {
connection.log("Forever frame iframe finished loading and is no longer receiving messages, reconnecting.");
that.reconnect(connection);
};

if (window.EventSource) {
// If the browser supports SSE, don't use Forever Frame
Expand All @@ -72,6 +82,8 @@
return;
}

frame.setAttribute("data-signalr-connection-id", connection.id);

// Start preventing loading icon
// This will only perform work if the loadPreventer is not attached to another connection.
loadPreventer.prevent();
Expand All @@ -81,21 +93,20 @@
url += "&frameId=" + frameId;

// Set body prior to setting URL to avoid caching issues.
$("body").append(frame);
window.document.body.appendChild(frame);

frame.prop("src", url);
transportLogic.foreverFrame.connections[frameId] = connection;
connection.log("Binding to iframe's load event.");

connection.log("Binding to iframe's readystatechange event.");
frame.bind("readystatechange", function () {
if ($.inArray(this.readyState, ["loaded", "complete"]) >= 0) {
connection.log("Forever frame iframe readyState changed to " + this.readyState + ", reconnecting");
if (frame.addEventListener) {
frame.addEventListener("load", frameLoadHandler, false);
} else if (frame.attachEvent) {
frame.attachEvent("onload", frameLoadHandler);
}

that.reconnect(connection);
}
});
frame.src = url;
transportLogic.foreverFrame.connections[frameId] = connection;

connection.frame = frame[0];
connection.frame = frame;
connection.frameId = frameId;

if (onSuccess) {
Expand Down Expand Up @@ -137,16 +148,22 @@
},

receive: function (connection, data) {
var cw;
var cw,
body;

transportLogic.processMessages(connection, data);
// Delete the script & div elements
connection.frameMessageCount = (connection.frameMessageCount || 0) + 1;
if (connection.frameMessageCount > 50) {
connection.frameMessageCount = 0;
cw = connection.frame.contentWindow || connection.frame.contentDocument;
if (cw && cw.document) {
$("body", cw.document).empty();
if (cw && cw.document && cw.document.body) {
body = cw.document.body;

// Remove all the child elements from the iframe's body to conserver memory
while (body.firstChild) {
body.removeChild(body.firstChild);
}
}
}
},
Expand All @@ -171,7 +188,12 @@
connection.log("SignalR: Error occured when stopping foreverFrame transport. Message = " + e.message);
}
}
$(connection.frame).remove();

// Ensure the iframe is where we left it
if (connection.frame.parentNode === window.document.body) {
window.document.body.removeChild(connection.frame);
}

delete transportLogic.foreverFrame.connections[connection.frameId];
connection.frame = null;
connection.frameId = null;
Expand Down
Expand Up @@ -5,6 +5,8 @@

function failConnection() {
$("iframe").each(function () {
var loadEvent;

if (this.stop) {
this.stop();
} else {
Expand All @@ -18,7 +20,20 @@
console.log("Network Mock Error occured, unable to stop iframe. Message = " + e.message);
}
}
$(this).triggerHandler("readystatechange");

if (window.document.createEvent) {
loadEvent = window.document.createEvent("Event");
loadEvent.initEvent("load", true, true);
} else {
loadEvent = window.document.createEventObject();
loadEvent.eventType = "load";
}

if (this.dispatchEvent) {
this.dispatchEvent(loadEvent);
} else {
this.fireEvent("onload", loadEvent);
}
});
}

Expand Down

0 comments on commit ea88f3d

Please sign in to comment.