Update: SignalR 1.1.0; T4MVC 3.6.4; Json.NET
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
///#source 1 1 /ClientSource/Scripts/Modules/jQuery-SignalR/jquery.signalR-1.0.1.js
|
///#source 1 1 /ClientSource/Scripts/Modules/jQuery-SignalR/jquery.signalR-1.1.0.js
|
||||||
/* jquery.signalR.core.js */
|
/* jquery.signalR.core.js */
|
||||||
/*global window:false */
|
/*global window:false */
|
||||||
/*!
|
/*!
|
||||||
* ASP.NET SignalR JavaScript Library v1.0.1
|
* ASP.NET SignalR JavaScript Library v1.1.0
|
||||||
* http://signalr.net/
|
* http://signalr.net/
|
||||||
*
|
*
|
||||||
* Copyright Microsoft Open Technologies, Inc. All rights reserved.
|
* Copyright Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
@@ -121,6 +121,26 @@
|
|||||||
return new signalR.fn.init(url, qs, logging);
|
return new signalR.fn.init(url, qs, logging);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
signalR._ = {
|
||||||
|
defaultContentType: "application/x-www-form-urlencoded; charset=UTF-8",
|
||||||
|
ieVersion: (function () {
|
||||||
|
var version,
|
||||||
|
matches;
|
||||||
|
|
||||||
|
if (window.navigator.appName === 'Microsoft Internet Explorer') {
|
||||||
|
// Check if the user agent has the pattern "MSIE (one or more numbers).(one or more numbers)";
|
||||||
|
matches = /MSIE ([0-9]+\.[0-9]+)/.exec(window.navigator.userAgent);
|
||||||
|
|
||||||
|
if (matches) {
|
||||||
|
version = window.parseFloat(matches[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// undefined value means not IE
|
||||||
|
return version;
|
||||||
|
})()
|
||||||
|
};
|
||||||
|
|
||||||
signalR.events = events;
|
signalR.events = events;
|
||||||
|
|
||||||
signalR.changeState = changeState;
|
signalR.changeState = changeState;
|
||||||
@@ -148,6 +168,7 @@
|
|||||||
/// <param name="requestedTransport" type="Object">The designated transports that the user has specified.</param>
|
/// <param name="requestedTransport" type="Object">The designated transports that the user has specified.</param>
|
||||||
/// <param name="connection" type="signalR">The connection that will be using the requested transports. Used for logging purposes.</param>
|
/// <param name="connection" type="signalR">The connection that will be using the requested transports. Used for logging purposes.</param>
|
||||||
/// <returns type="Object" />
|
/// <returns type="Object" />
|
||||||
|
|
||||||
if ($.isArray(requestedTransport)) {
|
if ($.isArray(requestedTransport)) {
|
||||||
// Go through transport array and remove an "invalid" tranports
|
// Go through transport array and remove an "invalid" tranports
|
||||||
for (var i = requestedTransport.length - 1; i >= 0; i--) {
|
for (var i = requestedTransport.length - 1; i >= 0; i--) {
|
||||||
@@ -167,6 +188,12 @@
|
|||||||
connection.log("Invalid transport: " + requestedTransport.toString());
|
connection.log("Invalid transport: " + requestedTransport.toString());
|
||||||
requestedTransport = null;
|
requestedTransport = null;
|
||||||
}
|
}
|
||||||
|
else if (requestedTransport === "auto" && signalR._.ieVersion <= 8)
|
||||||
|
{
|
||||||
|
// If we're doing an auto transport and we're IE8 then force longPolling, #1764
|
||||||
|
return ["longPolling"];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return requestedTransport;
|
return requestedTransport;
|
||||||
}
|
}
|
||||||
@@ -226,6 +253,8 @@
|
|||||||
|
|
||||||
ajaxDataType: "json",
|
ajaxDataType: "json",
|
||||||
|
|
||||||
|
contentType: "application/json; charset=UTF-8",
|
||||||
|
|
||||||
logging: false,
|
logging: false,
|
||||||
|
|
||||||
state: signalR.connectionState.disconnected,
|
state: signalR.connectionState.disconnected,
|
||||||
@@ -332,6 +361,8 @@
|
|||||||
connection.log("Using jsonp because this browser doesn't support CORS");
|
connection.log("Using jsonp because this browser doesn't support CORS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connection.contentType = signalR._.defaultContentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection.ajaxDataType = config.jsonp ? "jsonp" : "json";
|
connection.ajaxDataType = config.jsonp ? "jsonp" : "json";
|
||||||
@@ -348,7 +379,7 @@
|
|||||||
if (index >= transports.length) {
|
if (index >= transports.length) {
|
||||||
if (!connection.transport) {
|
if (!connection.transport) {
|
||||||
// No transport initialized successfully
|
// No transport initialized successfully
|
||||||
$(connection).triggerHandler(events.onError, "SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");
|
$(connection).triggerHandler(events.onError, ["SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."]);
|
||||||
deferred.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");
|
deferred.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");
|
||||||
// Stop the connection if it has connected and move it into the disconnected state
|
// Stop the connection if it has connected and move it into the disconnected state
|
||||||
connection.stop();
|
connection.stop();
|
||||||
@@ -397,6 +428,7 @@
|
|||||||
global: false,
|
global: false,
|
||||||
cache: false,
|
cache: false,
|
||||||
type: "GET",
|
type: "GET",
|
||||||
|
contentType: connection.contentType,
|
||||||
data: {},
|
data: {},
|
||||||
dataType: connection.ajaxDataType,
|
dataType: connection.ajaxDataType,
|
||||||
error: function (error) {
|
error: function (error) {
|
||||||
@@ -437,7 +469,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!res.ProtocolVersion || res.ProtocolVersion !== "1.2") {
|
if (!res.ProtocolVersion || res.ProtocolVersion !== "1.2") {
|
||||||
$(connection).triggerHandler(events.onError, "You are using a version of the client that isn't compatible with the server. Client version 1.2, server version " + res.ProtocolVersion + ".");
|
$(connection).triggerHandler(events.onError, ["You are using a version of the client that isn't compatible with the server. Client version 1.2, server version " + res.ProtocolVersion + "."]);
|
||||||
deferred.reject("You are using a version of the client that isn't compatible with the server. Client version 1.2, server version " + res.ProtocolVersion + ".");
|
deferred.reject("You are using a version of the client that isn't compatible with the server. Client version 1.2, server version " + res.ProtocolVersion + ".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -709,6 +741,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isConnectedOrReconnecting(connection) {
|
||||||
|
return connection.state === signalR.connectionState.connected ||
|
||||||
|
connection.state === signalR.connectionState.reconnecting;
|
||||||
|
}
|
||||||
|
|
||||||
signalR.transports._logic = {
|
signalR.transports._logic = {
|
||||||
pingServer: function (connection, transport) {
|
pingServer: function (connection, transport) {
|
||||||
/// <summary>Pings the server</summary>
|
/// <summary>Pings the server</summary>
|
||||||
@@ -725,6 +762,7 @@
|
|||||||
global: false,
|
global: false,
|
||||||
cache: false,
|
cache: false,
|
||||||
type: "GET",
|
type: "GET",
|
||||||
|
contentType: connection.contentType,
|
||||||
data: {},
|
data: {},
|
||||||
dataType: connection.ajaxDataType,
|
dataType: connection.ajaxDataType,
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
@@ -746,7 +784,7 @@
|
|||||||
addQs: function (url, connection) {
|
addQs: function (url, connection) {
|
||||||
var appender = url.indexOf("?") !== -1 ? "&" : "?",
|
var appender = url.indexOf("?") !== -1 ? "&" : "?",
|
||||||
firstChar;
|
firstChar;
|
||||||
|
|
||||||
if (!connection.qs) {
|
if (!connection.qs) {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
@@ -768,7 +806,7 @@
|
|||||||
throw new Error("Connections query string property must be either a string or object.");
|
throw new Error("Connections query string property must be either a string or object.");
|
||||||
},
|
},
|
||||||
|
|
||||||
getUrl: function (connection, transport, reconnecting, appendReconnectUrl) {
|
getUrl: function (connection, transport, reconnecting, poll) {
|
||||||
/// <summary>Gets the url for making a GET based connect request</summary>
|
/// <summary>Gets the url for making a GET based connect request</summary>
|
||||||
var baseUrl = transport === "webSockets" ? "" : connection.baseUrl,
|
var baseUrl = transport === "webSockets" ? "" : connection.baseUrl,
|
||||||
url = baseUrl + connection.appRelativeUrl,
|
url = baseUrl + connection.appRelativeUrl,
|
||||||
@@ -783,11 +821,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!reconnecting) {
|
if (!reconnecting) {
|
||||||
url = url + "/connect";
|
url += "/connect";
|
||||||
} else {
|
} else {
|
||||||
if (appendReconnectUrl) {
|
if (poll) {
|
||||||
url = url + "/reconnect";
|
// longPolling transport specific
|
||||||
|
url += "/poll";
|
||||||
|
} else {
|
||||||
|
url += "/reconnect";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connection.messageId) {
|
if (connection.messageId) {
|
||||||
qs += "&messageId=" + window.encodeURIComponent(connection.messageId);
|
qs += "&messageId=" + window.encodeURIComponent(connection.messageId);
|
||||||
}
|
}
|
||||||
@@ -822,6 +864,7 @@
|
|||||||
url: url,
|
url: url,
|
||||||
global: false,
|
global: false,
|
||||||
type: connection.ajaxDataType === "jsonp" ? "GET" : "POST",
|
type: connection.ajaxDataType === "jsonp" ? "GET" : "POST",
|
||||||
|
contentType: signalR._.defaultContentType,
|
||||||
dataType: connection.ajaxDataType,
|
dataType: connection.ajaxDataType,
|
||||||
data: {
|
data: {
|
||||||
data: data
|
data: data
|
||||||
@@ -859,6 +902,7 @@
|
|||||||
timeout: 1000,
|
timeout: 1000,
|
||||||
global: false,
|
global: false,
|
||||||
type: "POST",
|
type: "POST",
|
||||||
|
contentType: connection.contentType,
|
||||||
dataType: connection.ajaxDataType,
|
dataType: connection.ajaxDataType,
|
||||||
data: {}
|
data: {}
|
||||||
});
|
});
|
||||||
@@ -895,8 +939,8 @@
|
|||||||
this.updateGroups(connection, data.GroupsToken);
|
this.updateGroups(connection, data.GroupsToken);
|
||||||
|
|
||||||
if (data.Messages) {
|
if (data.Messages) {
|
||||||
$.each(data.Messages, function () {
|
$.each(data.Messages, function (index, message) {
|
||||||
$connection.triggerHandler(events.onReceived, [this]);
|
$connection.triggerHandler(events.onReceived, [message]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -964,6 +1008,32 @@
|
|||||||
return connection.state === signalR.connectionState.reconnecting;
|
return connection.state === signalR.connectionState.reconnecting;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
clearReconnectTimeout: function (connection) {
|
||||||
|
if (connection && connection._.reconnectTimeout) {
|
||||||
|
window.clearTimeout(connection._.reconnectTimeout);
|
||||||
|
delete connection._.reconnectTimeout;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
reconnect: function (connection, transportName) {
|
||||||
|
var transport = signalR.transports[transportName],
|
||||||
|
that = this;
|
||||||
|
|
||||||
|
// We should only set a reconnectTimeout if we are currently connected
|
||||||
|
// and a reconnectTimeout isn't already set.
|
||||||
|
if (isConnectedOrReconnecting(connection) && !connection._.reconnectTimeout) {
|
||||||
|
|
||||||
|
connection._.reconnectTimeout = window.setTimeout(function () {
|
||||||
|
transport.stop(connection);
|
||||||
|
|
||||||
|
if (that.ensureReconnectingState(connection)) {
|
||||||
|
connection.log(transportName + " reconnecting");
|
||||||
|
transport.start(connection);
|
||||||
|
}
|
||||||
|
}, connection.reconnectDelay);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
foreverFrame: {
|
foreverFrame: {
|
||||||
count: 0,
|
count: 0,
|
||||||
connections: {}
|
connections: {}
|
||||||
@@ -990,10 +1060,6 @@
|
|||||||
|
|
||||||
supportsKeepAlive: true,
|
supportsKeepAlive: true,
|
||||||
|
|
||||||
attemptingReconnect: false,
|
|
||||||
|
|
||||||
currentSocketID: 0,
|
|
||||||
|
|
||||||
send: function (connection, data) {
|
send: function (connection, data) {
|
||||||
connection.socket.send(data);
|
connection.socket.send(data);
|
||||||
},
|
},
|
||||||
@@ -1022,14 +1088,11 @@
|
|||||||
|
|
||||||
connection.log("Connecting to websocket endpoint '" + url + "'");
|
connection.log("Connecting to websocket endpoint '" + url + "'");
|
||||||
connection.socket = new window.WebSocket(url);
|
connection.socket = new window.WebSocket(url);
|
||||||
connection.socket.ID = ++that.currentSocketID;
|
|
||||||
connection.socket.onopen = function () {
|
connection.socket.onopen = function () {
|
||||||
opened = true;
|
opened = true;
|
||||||
connection.log("Websocket opened");
|
connection.log("Websocket opened");
|
||||||
|
|
||||||
if (that.attemptingReconnect) {
|
transportLogic.clearReconnectTimeout(connection);
|
||||||
that.attemptingReconnect = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onSuccess) {
|
if (onSuccess) {
|
||||||
onSuccess();
|
onSuccess();
|
||||||
@@ -1044,7 +1107,7 @@
|
|||||||
// Only handle a socket close if the close is from the current socket.
|
// Only handle a socket close if the close is from the current socket.
|
||||||
// Sometimes on disconnect the server will push down an onclose event
|
// Sometimes on disconnect the server will push down an onclose event
|
||||||
// to an expired socket.
|
// to an expired socket.
|
||||||
if (this.ID === that.currentSocketID) {
|
if (this === connection.socket) {
|
||||||
if (!opened) {
|
if (!opened) {
|
||||||
if (onFailed) {
|
if (onFailed) {
|
||||||
onFailed();
|
onFailed();
|
||||||
@@ -1087,24 +1150,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
reconnect: function (connection) {
|
reconnect: function (connection) {
|
||||||
var that = this;
|
transportLogic.reconnect(connection, this.name);
|
||||||
|
|
||||||
if (connection.state !== signalR.connectionState.disconnected) {
|
|
||||||
if (!that.attemptingReconnect) {
|
|
||||||
that.attemptingReconnect = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.setTimeout(function () {
|
|
||||||
if (that.attemptingReconnect) {
|
|
||||||
that.stop(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transportLogic.ensureReconnectingState(connection)) {
|
|
||||||
connection.log("Websocket reconnecting");
|
|
||||||
that.start(connection);
|
|
||||||
}
|
|
||||||
}, connection.reconnectDelay);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
lostConnection: function (connection) {
|
lostConnection: function (connection) {
|
||||||
@@ -1113,6 +1159,9 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
stop: function (connection) {
|
stop: function (connection) {
|
||||||
|
// Don't trigger a reconnect after stopping
|
||||||
|
transportLogic.clearReconnectTimeout(connection);
|
||||||
|
|
||||||
if (connection.socket !== null) {
|
if (connection.socket !== null) {
|
||||||
connection.log("Closing the Websocket");
|
connection.log("Closing the Websocket");
|
||||||
connection.socket.close();
|
connection.socket.close();
|
||||||
@@ -1144,10 +1193,6 @@
|
|||||||
|
|
||||||
supportsKeepAlive: true,
|
supportsKeepAlive: true,
|
||||||
|
|
||||||
reconnectTimeout: false,
|
|
||||||
|
|
||||||
currentEventSourceID: 0,
|
|
||||||
|
|
||||||
timeOut: 3000,
|
timeOut: 3000,
|
||||||
|
|
||||||
start: function (connection, onSuccess, onFailed) {
|
start: function (connection, onSuccess, onFailed) {
|
||||||
@@ -1176,7 +1221,6 @@
|
|||||||
try {
|
try {
|
||||||
connection.log("Attempting to connect to SSE endpoint '" + url + "'");
|
connection.log("Attempting to connect to SSE endpoint '" + url + "'");
|
||||||
connection.eventSource = new window.EventSource(url);
|
connection.eventSource = new window.EventSource(url);
|
||||||
connection.eventSource.ID = ++that.currentEventSourceID;
|
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
connection.log("EventSource failed trying to connect with error " + e.Message);
|
connection.log("EventSource failed trying to connect with error " + e.Message);
|
||||||
@@ -1227,9 +1271,7 @@
|
|||||||
window.clearTimeout(connectTimeOut);
|
window.clearTimeout(connectTimeOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (that.reconnectTimeout) {
|
transportLogic.clearReconnectTimeout(connection);
|
||||||
window.clearTimeout(that.reconnectTimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opened === false) {
|
if (opened === false) {
|
||||||
opened = true;
|
opened = true;
|
||||||
@@ -1258,7 +1300,7 @@
|
|||||||
// Only handle an error if the error is from the current Event Source.
|
// Only handle an error if the error is from the current Event Source.
|
||||||
// Sometimes on disconnect the server will push down an error event
|
// Sometimes on disconnect the server will push down an error event
|
||||||
// to an expired Event Source.
|
// to an expired Event Source.
|
||||||
if (this.ID === that.currentEventSourceID) {
|
if (this === connection.eventSource) {
|
||||||
if (!opened) {
|
if (!opened) {
|
||||||
if (onFailed) {
|
if (onFailed) {
|
||||||
onFailed();
|
onFailed();
|
||||||
@@ -1286,16 +1328,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
reconnect: function (connection) {
|
reconnect: function (connection) {
|
||||||
var that = this;
|
transportLogic.reconnect(connection, this.name);
|
||||||
|
|
||||||
that.reconnectTimeout = window.setTimeout(function () {
|
|
||||||
that.stop(connection);
|
|
||||||
|
|
||||||
if (transportLogic.ensureReconnectingState(connection)) {
|
|
||||||
connection.log("EventSource reconnecting");
|
|
||||||
that.start(connection);
|
|
||||||
}
|
|
||||||
}, connection.reconnectDelay);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
lostConnection: function (connection) {
|
lostConnection: function (connection) {
|
||||||
@@ -1307,14 +1340,17 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
stop: function (connection) {
|
stop: function (connection) {
|
||||||
|
// Don't trigger a reconnect after stopping
|
||||||
|
transportLogic.clearReconnectTimeout(connection);
|
||||||
|
|
||||||
if (connection && connection.eventSource) {
|
if (connection && connection.eventSource) {
|
||||||
connection.log("EventSource calling close()");
|
connection.log("EventSource calling close()");
|
||||||
connection.eventSource.ID = null;
|
|
||||||
connection.eventSource.close();
|
connection.eventSource.close();
|
||||||
connection.eventSource = null;
|
connection.eventSource = null;
|
||||||
delete connection.eventSource;
|
delete connection.eventSource;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
abort: function (connection, async) {
|
abort: function (connection, async) {
|
||||||
transportLogic.ajaxAbort(connection, async);
|
transportLogic.ajaxAbort(connection, async);
|
||||||
}
|
}
|
||||||
@@ -1333,7 +1369,46 @@
|
|||||||
var signalR = $.signalR,
|
var signalR = $.signalR,
|
||||||
events = $.signalR.events,
|
events = $.signalR.events,
|
||||||
changeState = $.signalR.changeState,
|
changeState = $.signalR.changeState,
|
||||||
transportLogic = signalR.transports._logic;
|
transportLogic = signalR.transports._logic,
|
||||||
|
// 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.
|
||||||
|
loadPreventer = (function () {
|
||||||
|
var loadingFixIntervalId = null,
|
||||||
|
loadingFixInterval = 1000,
|
||||||
|
attachedTo = 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
prevent: function () {
|
||||||
|
// Prevent additional iframe removal procedures from newer browsers
|
||||||
|
if (signalR._.ieVersion <= 8) {
|
||||||
|
// We only ever want to set the interval one time, so on the first attachedTo
|
||||||
|
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>");
|
||||||
|
|
||||||
|
$("body").append(tempFrame);
|
||||||
|
tempFrame.remove();
|
||||||
|
tempFrame = null;
|
||||||
|
}, loadingFixInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
attachedTo++;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cancel: function () {
|
||||||
|
// Only clear the interval if there's only one more object that the loadPreventer is attachedTo
|
||||||
|
if (attachedTo === 1) {
|
||||||
|
window.clearInterval(loadingFixIntervalId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachedTo > 0) {
|
||||||
|
attachedTo--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
signalR.transports.foreverFrame = {
|
signalR.transports.foreverFrame = {
|
||||||
name: "foreverFrame",
|
name: "foreverFrame",
|
||||||
@@ -1357,6 +1432,9 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start preventing loading icon
|
||||||
|
// This will only perform work if the loadPreventer is not attached to another connection.
|
||||||
|
loadPreventer.prevent();
|
||||||
|
|
||||||
// Build the url
|
// Build the url
|
||||||
url = transportLogic.getUrl(connection, this.name);
|
url = transportLogic.getUrl(connection, this.name);
|
||||||
@@ -1435,6 +1513,10 @@
|
|||||||
|
|
||||||
stop: function (connection) {
|
stop: function (connection) {
|
||||||
var cw = null;
|
var cw = null;
|
||||||
|
|
||||||
|
// Stop attempting to prevent loading icon
|
||||||
|
loadPreventer.cancel();
|
||||||
|
|
||||||
if (connection.frame) {
|
if (connection.frame) {
|
||||||
if (connection.frame.stop) {
|
if (connection.frame.stop) {
|
||||||
connection.frame.stop();
|
connection.frame.stop();
|
||||||
@@ -1540,7 +1622,23 @@
|
|||||||
initialConnectedFired = true;
|
initialConnectedFired = true;
|
||||||
onSuccess();
|
onSuccess();
|
||||||
connection.log("Longpolling connected");
|
connection.log("Longpolling connected");
|
||||||
};
|
},
|
||||||
|
reconnectErrors = 0,
|
||||||
|
reconnectTimeoutId = null,
|
||||||
|
fireReconnected = function (instance) {
|
||||||
|
window.clearTimeout(reconnectTimeoutId);
|
||||||
|
reconnectTimeoutId = null;
|
||||||
|
|
||||||
|
if (changeState(connection,
|
||||||
|
signalR.connectionState.reconnecting,
|
||||||
|
signalR.connectionState.connected) === true) {
|
||||||
|
// Successfully reconnected!
|
||||||
|
connection.log("Raising the reconnect event");
|
||||||
|
$(instance).triggerHandler(events.onReconnect);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 1 hour
|
||||||
|
maxFireReconnectedTimeout = 3600000;
|
||||||
|
|
||||||
if (connection.pollXhr) {
|
if (connection.pollXhr) {
|
||||||
connection.log("Polling xhr requests already exists, aborting.");
|
connection.log("Polling xhr requests already exists, aborting.");
|
||||||
@@ -1557,7 +1655,8 @@
|
|||||||
var messageId = instance.messageId,
|
var messageId = instance.messageId,
|
||||||
connect = (messageId === null),
|
connect = (messageId === null),
|
||||||
reconnecting = !connect,
|
reconnecting = !connect,
|
||||||
url = transportLogic.getUrl(instance, that.name, reconnecting, raiseReconnect);
|
polling = !raiseReconnect,
|
||||||
|
url = transportLogic.getUrl(instance, that.name, reconnecting, polling);
|
||||||
|
|
||||||
// If we've disconnected during the time we've tried to re-instantiate the poll then stop.
|
// If we've disconnected during the time we've tried to re-instantiate the poll then stop.
|
||||||
if (isDisconnecting(instance) === true) {
|
if (isDisconnecting(instance) === true) {
|
||||||
@@ -1571,10 +1670,20 @@
|
|||||||
cache: false,
|
cache: false,
|
||||||
type: "GET",
|
type: "GET",
|
||||||
dataType: connection.ajaxDataType,
|
dataType: connection.ajaxDataType,
|
||||||
|
contentType: connection.contentType,
|
||||||
success: function (minData) {
|
success: function (minData) {
|
||||||
var delay = 0,
|
var delay = 0,
|
||||||
data;
|
data;
|
||||||
|
|
||||||
|
// Reset our reconnect errors so if we transition into a reconnecting state again we trigger
|
||||||
|
// reconnected quickly
|
||||||
|
reconnectErrors = 0;
|
||||||
|
|
||||||
|
// If there's currently a timeout to trigger reconnect, fire it now before processing messages
|
||||||
|
if (reconnectTimeoutId !== null) {
|
||||||
|
fireReconnected();
|
||||||
|
}
|
||||||
|
|
||||||
fireConnect();
|
fireConnect();
|
||||||
|
|
||||||
if (minData) {
|
if (minData) {
|
||||||
@@ -1607,11 +1716,21 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
error: function (data, textStatus) {
|
error: function (data, textStatus) {
|
||||||
|
// Stop trying to trigger reconnect, connection is in an error state
|
||||||
|
// If we're not in the reconnect state this will noop
|
||||||
|
window.clearTimeout(reconnectTimeoutId);
|
||||||
|
reconnectTimeoutId = null;
|
||||||
|
|
||||||
if (textStatus === "abort") {
|
if (textStatus === "abort") {
|
||||||
connection.log("Aborted xhr requst.");
|
connection.log("Aborted xhr requst.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Increment our reconnect errors, we assume all errors to be reconnect errors
|
||||||
|
// In the case that it's our first error this will cause Reconnect to be fired
|
||||||
|
// after 1 second due to reconnectErrors being = 1.
|
||||||
|
reconnectErrors++;
|
||||||
|
|
||||||
if (connection.state !== signalR.connectionState.reconnecting) {
|
if (connection.state !== signalR.connectionState.reconnecting) {
|
||||||
connection.log("An error occurred using longPolling. Status = " + textStatus + ". " + data.responseText);
|
connection.log("An error occurred using longPolling. Status = " + textStatus + ". " + data.responseText);
|
||||||
$(instance).triggerHandler(events.onError, [data.responseText]);
|
$(instance).triggerHandler(events.onError, [data.responseText]);
|
||||||
@@ -1629,15 +1748,15 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// This will only ever pass after an error has occured via the poll ajax procedure.
|
// This will only ever pass after an error has occured via the poll ajax procedure.
|
||||||
if (reconnecting && raiseReconnect === true) {
|
if (reconnecting && raiseReconnect === true) {
|
||||||
if (changeState(connection,
|
// We wait to reconnect depending on how many times we've failed to reconnect.
|
||||||
signalR.connectionState.reconnecting,
|
// This is essentially a heuristic that will exponentially increase in wait time before
|
||||||
signalR.connectionState.connected) === true) {
|
// triggering reconnected. This depends on the "error" handler of Poll to cancel this
|
||||||
// Successfully reconnected!
|
// timeout if it triggers before the Reconnected event fires.
|
||||||
connection.log("Raising the reconnect event");
|
// The Math.min at the end is to ensure that the reconnect timeout does not overflow.
|
||||||
$(instance).triggerHandler(events.onReconnect);
|
reconnectTimeoutId = window.setTimeout(function () { fireReconnected(instance); }, Math.min(1000 * (Math.pow(2, reconnectErrors) - 1), maxFireReconnectedTimeout));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}(connection));
|
}(connection));
|
||||||
|
|
||||||
@@ -1693,20 +1812,17 @@
|
|||||||
return event + eventNamespace;
|
return event + eventNamespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Array.prototype.map
|
// Equivalent to Array.prototype.map
|
||||||
if (!Array.prototype.hasOwnProperty("map")) {
|
function map(arr, fun, thisp) {
|
||||||
Array.prototype.map = function (fun, thisp) {
|
var i,
|
||||||
var arr = this,
|
length = arr.length,
|
||||||
i,
|
result = [];
|
||||||
length = arr.length,
|
for (i = 0; i < length; i += 1) {
|
||||||
result = [];
|
if (arr.hasOwnProperty(i)) {
|
||||||
for (i = 0; i < length; i += 1) {
|
result[i] = fun.call(thisp, arr[i], i, arr);
|
||||||
if (arr.hasOwnProperty(i)) {
|
|
||||||
result[i] = fun.call(thisp, arr[i], i, arr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
}
|
||||||
};
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getArgValue(a) {
|
function getArgValue(a) {
|
||||||
@@ -1815,7 +1931,7 @@
|
|||||||
|
|
||||||
var self = this,
|
var self = this,
|
||||||
args = $.makeArray(arguments).slice(1),
|
args = $.makeArray(arguments).slice(1),
|
||||||
argValues = args.map(getArgValue),
|
argValues = map(args, getArgValue),
|
||||||
data = { H: self.hubName, M: methodName, A: argValues, I: callbackId },
|
data = { H: self.hubName, M: methodName, A: argValues, I: callbackId },
|
||||||
d = $.Deferred(),
|
d = $.Deferred(),
|
||||||
callback = function (minResult) {
|
callback = function (minResult) {
|
||||||
@@ -2004,6 +2120,6 @@
|
|||||||
/*global window:false */
|
/*global window:false */
|
||||||
/// <reference path="jquery.signalR.core.js" />
|
/// <reference path="jquery.signalR.core.js" />
|
||||||
(function ($) {
|
(function ($) {
|
||||||
$.signalR.version = "1.0.1";
|
$.signalR.version = "1.1.0";
|
||||||
}(window.jQuery));
|
}(window.jQuery));
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<bundle minify="true" runOnBuild="true">
|
<bundle minify="true" runOnBuild="true">
|
||||||
<file>/ClientSource/Scripts/Modules/jQuery-SignalR/jquery.signalR-1.0.1.js</file>
|
<file>/ClientSource/Scripts/Modules/jQuery-SignalR/jquery.signalR-1.1.0.js</file>
|
||||||
</bundle>
|
</bundle>
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+198
-82
@@ -1,7 +1,7 @@
|
|||||||
/* jquery.signalR.core.js */
|
/* jquery.signalR.core.js */
|
||||||
/*global window:false */
|
/*global window:false */
|
||||||
/*!
|
/*!
|
||||||
* ASP.NET SignalR JavaScript Library v1.0.1
|
* ASP.NET SignalR JavaScript Library v1.1.0
|
||||||
* http://signalr.net/
|
* http://signalr.net/
|
||||||
*
|
*
|
||||||
* Copyright Microsoft Open Technologies, Inc. All rights reserved.
|
* Copyright Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
@@ -120,6 +120,26 @@
|
|||||||
return new signalR.fn.init(url, qs, logging);
|
return new signalR.fn.init(url, qs, logging);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
signalR._ = {
|
||||||
|
defaultContentType: "application/x-www-form-urlencoded; charset=UTF-8",
|
||||||
|
ieVersion: (function () {
|
||||||
|
var version,
|
||||||
|
matches;
|
||||||
|
|
||||||
|
if (window.navigator.appName === 'Microsoft Internet Explorer') {
|
||||||
|
// Check if the user agent has the pattern "MSIE (one or more numbers).(one or more numbers)";
|
||||||
|
matches = /MSIE ([0-9]+\.[0-9]+)/.exec(window.navigator.userAgent);
|
||||||
|
|
||||||
|
if (matches) {
|
||||||
|
version = window.parseFloat(matches[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// undefined value means not IE
|
||||||
|
return version;
|
||||||
|
})()
|
||||||
|
};
|
||||||
|
|
||||||
signalR.events = events;
|
signalR.events = events;
|
||||||
|
|
||||||
signalR.changeState = changeState;
|
signalR.changeState = changeState;
|
||||||
@@ -147,6 +167,7 @@
|
|||||||
/// <param name="requestedTransport" type="Object">The designated transports that the user has specified.</param>
|
/// <param name="requestedTransport" type="Object">The designated transports that the user has specified.</param>
|
||||||
/// <param name="connection" type="signalR">The connection that will be using the requested transports. Used for logging purposes.</param>
|
/// <param name="connection" type="signalR">The connection that will be using the requested transports. Used for logging purposes.</param>
|
||||||
/// <returns type="Object" />
|
/// <returns type="Object" />
|
||||||
|
|
||||||
if ($.isArray(requestedTransport)) {
|
if ($.isArray(requestedTransport)) {
|
||||||
// Go through transport array and remove an "invalid" tranports
|
// Go through transport array and remove an "invalid" tranports
|
||||||
for (var i = requestedTransport.length - 1; i >= 0; i--) {
|
for (var i = requestedTransport.length - 1; i >= 0; i--) {
|
||||||
@@ -166,6 +187,12 @@
|
|||||||
connection.log("Invalid transport: " + requestedTransport.toString());
|
connection.log("Invalid transport: " + requestedTransport.toString());
|
||||||
requestedTransport = null;
|
requestedTransport = null;
|
||||||
}
|
}
|
||||||
|
else if (requestedTransport === "auto" && signalR._.ieVersion <= 8)
|
||||||
|
{
|
||||||
|
// If we're doing an auto transport and we're IE8 then force longPolling, #1764
|
||||||
|
return ["longPolling"];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return requestedTransport;
|
return requestedTransport;
|
||||||
}
|
}
|
||||||
@@ -225,6 +252,8 @@
|
|||||||
|
|
||||||
ajaxDataType: "json",
|
ajaxDataType: "json",
|
||||||
|
|
||||||
|
contentType: "application/json; charset=UTF-8",
|
||||||
|
|
||||||
logging: false,
|
logging: false,
|
||||||
|
|
||||||
state: signalR.connectionState.disconnected,
|
state: signalR.connectionState.disconnected,
|
||||||
@@ -331,6 +360,8 @@
|
|||||||
connection.log("Using jsonp because this browser doesn't support CORS");
|
connection.log("Using jsonp because this browser doesn't support CORS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connection.contentType = signalR._.defaultContentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection.ajaxDataType = config.jsonp ? "jsonp" : "json";
|
connection.ajaxDataType = config.jsonp ? "jsonp" : "json";
|
||||||
@@ -347,7 +378,7 @@
|
|||||||
if (index >= transports.length) {
|
if (index >= transports.length) {
|
||||||
if (!connection.transport) {
|
if (!connection.transport) {
|
||||||
// No transport initialized successfully
|
// No transport initialized successfully
|
||||||
$(connection).triggerHandler(events.onError, "SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");
|
$(connection).triggerHandler(events.onError, ["SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."]);
|
||||||
deferred.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");
|
deferred.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");
|
||||||
// Stop the connection if it has connected and move it into the disconnected state
|
// Stop the connection if it has connected and move it into the disconnected state
|
||||||
connection.stop();
|
connection.stop();
|
||||||
@@ -396,6 +427,7 @@
|
|||||||
global: false,
|
global: false,
|
||||||
cache: false,
|
cache: false,
|
||||||
type: "GET",
|
type: "GET",
|
||||||
|
contentType: connection.contentType,
|
||||||
data: {},
|
data: {},
|
||||||
dataType: connection.ajaxDataType,
|
dataType: connection.ajaxDataType,
|
||||||
error: function (error) {
|
error: function (error) {
|
||||||
@@ -436,7 +468,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!res.ProtocolVersion || res.ProtocolVersion !== "1.2") {
|
if (!res.ProtocolVersion || res.ProtocolVersion !== "1.2") {
|
||||||
$(connection).triggerHandler(events.onError, "You are using a version of the client that isn't compatible with the server. Client version 1.2, server version " + res.ProtocolVersion + ".");
|
$(connection).triggerHandler(events.onError, ["You are using a version of the client that isn't compatible with the server. Client version 1.2, server version " + res.ProtocolVersion + "."]);
|
||||||
deferred.reject("You are using a version of the client that isn't compatible with the server. Client version 1.2, server version " + res.ProtocolVersion + ".");
|
deferred.reject("You are using a version of the client that isn't compatible with the server. Client version 1.2, server version " + res.ProtocolVersion + ".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -708,6 +740,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isConnectedOrReconnecting(connection) {
|
||||||
|
return connection.state === signalR.connectionState.connected ||
|
||||||
|
connection.state === signalR.connectionState.reconnecting;
|
||||||
|
}
|
||||||
|
|
||||||
signalR.transports._logic = {
|
signalR.transports._logic = {
|
||||||
pingServer: function (connection, transport) {
|
pingServer: function (connection, transport) {
|
||||||
/// <summary>Pings the server</summary>
|
/// <summary>Pings the server</summary>
|
||||||
@@ -724,6 +761,7 @@
|
|||||||
global: false,
|
global: false,
|
||||||
cache: false,
|
cache: false,
|
||||||
type: "GET",
|
type: "GET",
|
||||||
|
contentType: connection.contentType,
|
||||||
data: {},
|
data: {},
|
||||||
dataType: connection.ajaxDataType,
|
dataType: connection.ajaxDataType,
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
@@ -745,7 +783,7 @@
|
|||||||
addQs: function (url, connection) {
|
addQs: function (url, connection) {
|
||||||
var appender = url.indexOf("?") !== -1 ? "&" : "?",
|
var appender = url.indexOf("?") !== -1 ? "&" : "?",
|
||||||
firstChar;
|
firstChar;
|
||||||
|
|
||||||
if (!connection.qs) {
|
if (!connection.qs) {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
@@ -767,7 +805,7 @@
|
|||||||
throw new Error("Connections query string property must be either a string or object.");
|
throw new Error("Connections query string property must be either a string or object.");
|
||||||
},
|
},
|
||||||
|
|
||||||
getUrl: function (connection, transport, reconnecting, appendReconnectUrl) {
|
getUrl: function (connection, transport, reconnecting, poll) {
|
||||||
/// <summary>Gets the url for making a GET based connect request</summary>
|
/// <summary>Gets the url for making a GET based connect request</summary>
|
||||||
var baseUrl = transport === "webSockets" ? "" : connection.baseUrl,
|
var baseUrl = transport === "webSockets" ? "" : connection.baseUrl,
|
||||||
url = baseUrl + connection.appRelativeUrl,
|
url = baseUrl + connection.appRelativeUrl,
|
||||||
@@ -782,11 +820,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!reconnecting) {
|
if (!reconnecting) {
|
||||||
url = url + "/connect";
|
url += "/connect";
|
||||||
} else {
|
} else {
|
||||||
if (appendReconnectUrl) {
|
if (poll) {
|
||||||
url = url + "/reconnect";
|
// longPolling transport specific
|
||||||
|
url += "/poll";
|
||||||
|
} else {
|
||||||
|
url += "/reconnect";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connection.messageId) {
|
if (connection.messageId) {
|
||||||
qs += "&messageId=" + window.encodeURIComponent(connection.messageId);
|
qs += "&messageId=" + window.encodeURIComponent(connection.messageId);
|
||||||
}
|
}
|
||||||
@@ -821,6 +863,7 @@
|
|||||||
url: url,
|
url: url,
|
||||||
global: false,
|
global: false,
|
||||||
type: connection.ajaxDataType === "jsonp" ? "GET" : "POST",
|
type: connection.ajaxDataType === "jsonp" ? "GET" : "POST",
|
||||||
|
contentType: signalR._.defaultContentType,
|
||||||
dataType: connection.ajaxDataType,
|
dataType: connection.ajaxDataType,
|
||||||
data: {
|
data: {
|
||||||
data: data
|
data: data
|
||||||
@@ -858,6 +901,7 @@
|
|||||||
timeout: 1000,
|
timeout: 1000,
|
||||||
global: false,
|
global: false,
|
||||||
type: "POST",
|
type: "POST",
|
||||||
|
contentType: connection.contentType,
|
||||||
dataType: connection.ajaxDataType,
|
dataType: connection.ajaxDataType,
|
||||||
data: {}
|
data: {}
|
||||||
});
|
});
|
||||||
@@ -894,8 +938,8 @@
|
|||||||
this.updateGroups(connection, data.GroupsToken);
|
this.updateGroups(connection, data.GroupsToken);
|
||||||
|
|
||||||
if (data.Messages) {
|
if (data.Messages) {
|
||||||
$.each(data.Messages, function () {
|
$.each(data.Messages, function (index, message) {
|
||||||
$connection.triggerHandler(events.onReceived, [this]);
|
$connection.triggerHandler(events.onReceived, [message]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -963,6 +1007,32 @@
|
|||||||
return connection.state === signalR.connectionState.reconnecting;
|
return connection.state === signalR.connectionState.reconnecting;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
clearReconnectTimeout: function (connection) {
|
||||||
|
if (connection && connection._.reconnectTimeout) {
|
||||||
|
window.clearTimeout(connection._.reconnectTimeout);
|
||||||
|
delete connection._.reconnectTimeout;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
reconnect: function (connection, transportName) {
|
||||||
|
var transport = signalR.transports[transportName],
|
||||||
|
that = this;
|
||||||
|
|
||||||
|
// We should only set a reconnectTimeout if we are currently connected
|
||||||
|
// and a reconnectTimeout isn't already set.
|
||||||
|
if (isConnectedOrReconnecting(connection) && !connection._.reconnectTimeout) {
|
||||||
|
|
||||||
|
connection._.reconnectTimeout = window.setTimeout(function () {
|
||||||
|
transport.stop(connection);
|
||||||
|
|
||||||
|
if (that.ensureReconnectingState(connection)) {
|
||||||
|
connection.log(transportName + " reconnecting");
|
||||||
|
transport.start(connection);
|
||||||
|
}
|
||||||
|
}, connection.reconnectDelay);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
foreverFrame: {
|
foreverFrame: {
|
||||||
count: 0,
|
count: 0,
|
||||||
connections: {}
|
connections: {}
|
||||||
@@ -989,10 +1059,6 @@
|
|||||||
|
|
||||||
supportsKeepAlive: true,
|
supportsKeepAlive: true,
|
||||||
|
|
||||||
attemptingReconnect: false,
|
|
||||||
|
|
||||||
currentSocketID: 0,
|
|
||||||
|
|
||||||
send: function (connection, data) {
|
send: function (connection, data) {
|
||||||
connection.socket.send(data);
|
connection.socket.send(data);
|
||||||
},
|
},
|
||||||
@@ -1021,14 +1087,11 @@
|
|||||||
|
|
||||||
connection.log("Connecting to websocket endpoint '" + url + "'");
|
connection.log("Connecting to websocket endpoint '" + url + "'");
|
||||||
connection.socket = new window.WebSocket(url);
|
connection.socket = new window.WebSocket(url);
|
||||||
connection.socket.ID = ++that.currentSocketID;
|
|
||||||
connection.socket.onopen = function () {
|
connection.socket.onopen = function () {
|
||||||
opened = true;
|
opened = true;
|
||||||
connection.log("Websocket opened");
|
connection.log("Websocket opened");
|
||||||
|
|
||||||
if (that.attemptingReconnect) {
|
transportLogic.clearReconnectTimeout(connection);
|
||||||
that.attemptingReconnect = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onSuccess) {
|
if (onSuccess) {
|
||||||
onSuccess();
|
onSuccess();
|
||||||
@@ -1043,7 +1106,7 @@
|
|||||||
// Only handle a socket close if the close is from the current socket.
|
// Only handle a socket close if the close is from the current socket.
|
||||||
// Sometimes on disconnect the server will push down an onclose event
|
// Sometimes on disconnect the server will push down an onclose event
|
||||||
// to an expired socket.
|
// to an expired socket.
|
||||||
if (this.ID === that.currentSocketID) {
|
if (this === connection.socket) {
|
||||||
if (!opened) {
|
if (!opened) {
|
||||||
if (onFailed) {
|
if (onFailed) {
|
||||||
onFailed();
|
onFailed();
|
||||||
@@ -1086,24 +1149,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
reconnect: function (connection) {
|
reconnect: function (connection) {
|
||||||
var that = this;
|
transportLogic.reconnect(connection, this.name);
|
||||||
|
|
||||||
if (connection.state !== signalR.connectionState.disconnected) {
|
|
||||||
if (!that.attemptingReconnect) {
|
|
||||||
that.attemptingReconnect = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.setTimeout(function () {
|
|
||||||
if (that.attemptingReconnect) {
|
|
||||||
that.stop(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transportLogic.ensureReconnectingState(connection)) {
|
|
||||||
connection.log("Websocket reconnecting");
|
|
||||||
that.start(connection);
|
|
||||||
}
|
|
||||||
}, connection.reconnectDelay);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
lostConnection: function (connection) {
|
lostConnection: function (connection) {
|
||||||
@@ -1112,6 +1158,9 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
stop: function (connection) {
|
stop: function (connection) {
|
||||||
|
// Don't trigger a reconnect after stopping
|
||||||
|
transportLogic.clearReconnectTimeout(connection);
|
||||||
|
|
||||||
if (connection.socket !== null) {
|
if (connection.socket !== null) {
|
||||||
connection.log("Closing the Websocket");
|
connection.log("Closing the Websocket");
|
||||||
connection.socket.close();
|
connection.socket.close();
|
||||||
@@ -1143,10 +1192,6 @@
|
|||||||
|
|
||||||
supportsKeepAlive: true,
|
supportsKeepAlive: true,
|
||||||
|
|
||||||
reconnectTimeout: false,
|
|
||||||
|
|
||||||
currentEventSourceID: 0,
|
|
||||||
|
|
||||||
timeOut: 3000,
|
timeOut: 3000,
|
||||||
|
|
||||||
start: function (connection, onSuccess, onFailed) {
|
start: function (connection, onSuccess, onFailed) {
|
||||||
@@ -1175,7 +1220,6 @@
|
|||||||
try {
|
try {
|
||||||
connection.log("Attempting to connect to SSE endpoint '" + url + "'");
|
connection.log("Attempting to connect to SSE endpoint '" + url + "'");
|
||||||
connection.eventSource = new window.EventSource(url);
|
connection.eventSource = new window.EventSource(url);
|
||||||
connection.eventSource.ID = ++that.currentEventSourceID;
|
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
connection.log("EventSource failed trying to connect with error " + e.Message);
|
connection.log("EventSource failed trying to connect with error " + e.Message);
|
||||||
@@ -1226,9 +1270,7 @@
|
|||||||
window.clearTimeout(connectTimeOut);
|
window.clearTimeout(connectTimeOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (that.reconnectTimeout) {
|
transportLogic.clearReconnectTimeout(connection);
|
||||||
window.clearTimeout(that.reconnectTimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opened === false) {
|
if (opened === false) {
|
||||||
opened = true;
|
opened = true;
|
||||||
@@ -1257,7 +1299,7 @@
|
|||||||
// Only handle an error if the error is from the current Event Source.
|
// Only handle an error if the error is from the current Event Source.
|
||||||
// Sometimes on disconnect the server will push down an error event
|
// Sometimes on disconnect the server will push down an error event
|
||||||
// to an expired Event Source.
|
// to an expired Event Source.
|
||||||
if (this.ID === that.currentEventSourceID) {
|
if (this === connection.eventSource) {
|
||||||
if (!opened) {
|
if (!opened) {
|
||||||
if (onFailed) {
|
if (onFailed) {
|
||||||
onFailed();
|
onFailed();
|
||||||
@@ -1285,16 +1327,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
reconnect: function (connection) {
|
reconnect: function (connection) {
|
||||||
var that = this;
|
transportLogic.reconnect(connection, this.name);
|
||||||
|
|
||||||
that.reconnectTimeout = window.setTimeout(function () {
|
|
||||||
that.stop(connection);
|
|
||||||
|
|
||||||
if (transportLogic.ensureReconnectingState(connection)) {
|
|
||||||
connection.log("EventSource reconnecting");
|
|
||||||
that.start(connection);
|
|
||||||
}
|
|
||||||
}, connection.reconnectDelay);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
lostConnection: function (connection) {
|
lostConnection: function (connection) {
|
||||||
@@ -1306,14 +1339,17 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
stop: function (connection) {
|
stop: function (connection) {
|
||||||
|
// Don't trigger a reconnect after stopping
|
||||||
|
transportLogic.clearReconnectTimeout(connection);
|
||||||
|
|
||||||
if (connection && connection.eventSource) {
|
if (connection && connection.eventSource) {
|
||||||
connection.log("EventSource calling close()");
|
connection.log("EventSource calling close()");
|
||||||
connection.eventSource.ID = null;
|
|
||||||
connection.eventSource.close();
|
connection.eventSource.close();
|
||||||
connection.eventSource = null;
|
connection.eventSource = null;
|
||||||
delete connection.eventSource;
|
delete connection.eventSource;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
abort: function (connection, async) {
|
abort: function (connection, async) {
|
||||||
transportLogic.ajaxAbort(connection, async);
|
transportLogic.ajaxAbort(connection, async);
|
||||||
}
|
}
|
||||||
@@ -1332,7 +1368,46 @@
|
|||||||
var signalR = $.signalR,
|
var signalR = $.signalR,
|
||||||
events = $.signalR.events,
|
events = $.signalR.events,
|
||||||
changeState = $.signalR.changeState,
|
changeState = $.signalR.changeState,
|
||||||
transportLogic = signalR.transports._logic;
|
transportLogic = signalR.transports._logic,
|
||||||
|
// 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.
|
||||||
|
loadPreventer = (function () {
|
||||||
|
var loadingFixIntervalId = null,
|
||||||
|
loadingFixInterval = 1000,
|
||||||
|
attachedTo = 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
prevent: function () {
|
||||||
|
// Prevent additional iframe removal procedures from newer browsers
|
||||||
|
if (signalR._.ieVersion <= 8) {
|
||||||
|
// We only ever want to set the interval one time, so on the first attachedTo
|
||||||
|
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>");
|
||||||
|
|
||||||
|
$("body").append(tempFrame);
|
||||||
|
tempFrame.remove();
|
||||||
|
tempFrame = null;
|
||||||
|
}, loadingFixInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
attachedTo++;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cancel: function () {
|
||||||
|
// Only clear the interval if there's only one more object that the loadPreventer is attachedTo
|
||||||
|
if (attachedTo === 1) {
|
||||||
|
window.clearInterval(loadingFixIntervalId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachedTo > 0) {
|
||||||
|
attachedTo--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
signalR.transports.foreverFrame = {
|
signalR.transports.foreverFrame = {
|
||||||
name: "foreverFrame",
|
name: "foreverFrame",
|
||||||
@@ -1356,6 +1431,9 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start preventing loading icon
|
||||||
|
// This will only perform work if the loadPreventer is not attached to another connection.
|
||||||
|
loadPreventer.prevent();
|
||||||
|
|
||||||
// Build the url
|
// Build the url
|
||||||
url = transportLogic.getUrl(connection, this.name);
|
url = transportLogic.getUrl(connection, this.name);
|
||||||
@@ -1434,6 +1512,10 @@
|
|||||||
|
|
||||||
stop: function (connection) {
|
stop: function (connection) {
|
||||||
var cw = null;
|
var cw = null;
|
||||||
|
|
||||||
|
// Stop attempting to prevent loading icon
|
||||||
|
loadPreventer.cancel();
|
||||||
|
|
||||||
if (connection.frame) {
|
if (connection.frame) {
|
||||||
if (connection.frame.stop) {
|
if (connection.frame.stop) {
|
||||||
connection.frame.stop();
|
connection.frame.stop();
|
||||||
@@ -1539,7 +1621,23 @@
|
|||||||
initialConnectedFired = true;
|
initialConnectedFired = true;
|
||||||
onSuccess();
|
onSuccess();
|
||||||
connection.log("Longpolling connected");
|
connection.log("Longpolling connected");
|
||||||
};
|
},
|
||||||
|
reconnectErrors = 0,
|
||||||
|
reconnectTimeoutId = null,
|
||||||
|
fireReconnected = function (instance) {
|
||||||
|
window.clearTimeout(reconnectTimeoutId);
|
||||||
|
reconnectTimeoutId = null;
|
||||||
|
|
||||||
|
if (changeState(connection,
|
||||||
|
signalR.connectionState.reconnecting,
|
||||||
|
signalR.connectionState.connected) === true) {
|
||||||
|
// Successfully reconnected!
|
||||||
|
connection.log("Raising the reconnect event");
|
||||||
|
$(instance).triggerHandler(events.onReconnect);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 1 hour
|
||||||
|
maxFireReconnectedTimeout = 3600000;
|
||||||
|
|
||||||
if (connection.pollXhr) {
|
if (connection.pollXhr) {
|
||||||
connection.log("Polling xhr requests already exists, aborting.");
|
connection.log("Polling xhr requests already exists, aborting.");
|
||||||
@@ -1556,7 +1654,8 @@
|
|||||||
var messageId = instance.messageId,
|
var messageId = instance.messageId,
|
||||||
connect = (messageId === null),
|
connect = (messageId === null),
|
||||||
reconnecting = !connect,
|
reconnecting = !connect,
|
||||||
url = transportLogic.getUrl(instance, that.name, reconnecting, raiseReconnect);
|
polling = !raiseReconnect,
|
||||||
|
url = transportLogic.getUrl(instance, that.name, reconnecting, polling);
|
||||||
|
|
||||||
// If we've disconnected during the time we've tried to re-instantiate the poll then stop.
|
// If we've disconnected during the time we've tried to re-instantiate the poll then stop.
|
||||||
if (isDisconnecting(instance) === true) {
|
if (isDisconnecting(instance) === true) {
|
||||||
@@ -1570,10 +1669,20 @@
|
|||||||
cache: false,
|
cache: false,
|
||||||
type: "GET",
|
type: "GET",
|
||||||
dataType: connection.ajaxDataType,
|
dataType: connection.ajaxDataType,
|
||||||
|
contentType: connection.contentType,
|
||||||
success: function (minData) {
|
success: function (minData) {
|
||||||
var delay = 0,
|
var delay = 0,
|
||||||
data;
|
data;
|
||||||
|
|
||||||
|
// Reset our reconnect errors so if we transition into a reconnecting state again we trigger
|
||||||
|
// reconnected quickly
|
||||||
|
reconnectErrors = 0;
|
||||||
|
|
||||||
|
// If there's currently a timeout to trigger reconnect, fire it now before processing messages
|
||||||
|
if (reconnectTimeoutId !== null) {
|
||||||
|
fireReconnected();
|
||||||
|
}
|
||||||
|
|
||||||
fireConnect();
|
fireConnect();
|
||||||
|
|
||||||
if (minData) {
|
if (minData) {
|
||||||
@@ -1606,11 +1715,21 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
error: function (data, textStatus) {
|
error: function (data, textStatus) {
|
||||||
|
// Stop trying to trigger reconnect, connection is in an error state
|
||||||
|
// If we're not in the reconnect state this will noop
|
||||||
|
window.clearTimeout(reconnectTimeoutId);
|
||||||
|
reconnectTimeoutId = null;
|
||||||
|
|
||||||
if (textStatus === "abort") {
|
if (textStatus === "abort") {
|
||||||
connection.log("Aborted xhr requst.");
|
connection.log("Aborted xhr requst.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Increment our reconnect errors, we assume all errors to be reconnect errors
|
||||||
|
// In the case that it's our first error this will cause Reconnect to be fired
|
||||||
|
// after 1 second due to reconnectErrors being = 1.
|
||||||
|
reconnectErrors++;
|
||||||
|
|
||||||
if (connection.state !== signalR.connectionState.reconnecting) {
|
if (connection.state !== signalR.connectionState.reconnecting) {
|
||||||
connection.log("An error occurred using longPolling. Status = " + textStatus + ". " + data.responseText);
|
connection.log("An error occurred using longPolling. Status = " + textStatus + ". " + data.responseText);
|
||||||
$(instance).triggerHandler(events.onError, [data.responseText]);
|
$(instance).triggerHandler(events.onError, [data.responseText]);
|
||||||
@@ -1628,15 +1747,15 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// This will only ever pass after an error has occured via the poll ajax procedure.
|
// This will only ever pass after an error has occured via the poll ajax procedure.
|
||||||
if (reconnecting && raiseReconnect === true) {
|
if (reconnecting && raiseReconnect === true) {
|
||||||
if (changeState(connection,
|
// We wait to reconnect depending on how many times we've failed to reconnect.
|
||||||
signalR.connectionState.reconnecting,
|
// This is essentially a heuristic that will exponentially increase in wait time before
|
||||||
signalR.connectionState.connected) === true) {
|
// triggering reconnected. This depends on the "error" handler of Poll to cancel this
|
||||||
// Successfully reconnected!
|
// timeout if it triggers before the Reconnected event fires.
|
||||||
connection.log("Raising the reconnect event");
|
// The Math.min at the end is to ensure that the reconnect timeout does not overflow.
|
||||||
$(instance).triggerHandler(events.onReconnect);
|
reconnectTimeoutId = window.setTimeout(function () { fireReconnected(instance); }, Math.min(1000 * (Math.pow(2, reconnectErrors) - 1), maxFireReconnectedTimeout));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}(connection));
|
}(connection));
|
||||||
|
|
||||||
@@ -1692,20 +1811,17 @@
|
|||||||
return event + eventNamespace;
|
return event + eventNamespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Array.prototype.map
|
// Equivalent to Array.prototype.map
|
||||||
if (!Array.prototype.hasOwnProperty("map")) {
|
function map(arr, fun, thisp) {
|
||||||
Array.prototype.map = function (fun, thisp) {
|
var i,
|
||||||
var arr = this,
|
length = arr.length,
|
||||||
i,
|
result = [];
|
||||||
length = arr.length,
|
for (i = 0; i < length; i += 1) {
|
||||||
result = [];
|
if (arr.hasOwnProperty(i)) {
|
||||||
for (i = 0; i < length; i += 1) {
|
result[i] = fun.call(thisp, arr[i], i, arr);
|
||||||
if (arr.hasOwnProperty(i)) {
|
|
||||||
result[i] = fun.call(thisp, arr[i], i, arr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
}
|
||||||
};
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getArgValue(a) {
|
function getArgValue(a) {
|
||||||
@@ -1814,7 +1930,7 @@
|
|||||||
|
|
||||||
var self = this,
|
var self = this,
|
||||||
args = $.makeArray(arguments).slice(1),
|
args = $.makeArray(arguments).slice(1),
|
||||||
argValues = args.map(getArgValue),
|
argValues = map(args, getArgValue),
|
||||||
data = { H: self.hubName, M: methodName, A: argValues, I: callbackId },
|
data = { H: self.hubName, M: methodName, A: argValues, I: callbackId },
|
||||||
d = $.Deferred(),
|
d = $.Deferred(),
|
||||||
callback = function (minResult) {
|
callback = function (minResult) {
|
||||||
@@ -2003,5 +2119,5 @@
|
|||||||
/*global window:false */
|
/*global window:false */
|
||||||
/// <reference path="jquery.signalR.core.js" />
|
/// <reference path="jquery.signalR.core.js" />
|
||||||
(function ($) {
|
(function ($) {
|
||||||
$.signalR.version = "1.0.1";
|
$.signalR.version = "1.1.0";
|
||||||
}(window.jQuery));
|
}(window.jQuery));
|
||||||
+1
-1
@@ -336,7 +336,7 @@ namespace Links
|
|||||||
private const string URLPATH = "~/ClientSource/Scripts/Modules/jQuery-SignalR";
|
private const string URLPATH = "~/ClientSource/Scripts/Modules/jQuery-SignalR";
|
||||||
public static string Url() { return T4MVCHelpers.ProcessVirtualPath(URLPATH); }
|
public static string Url() { return T4MVCHelpers.ProcessVirtualPath(URLPATH); }
|
||||||
public static string Url(string fileName) { return T4MVCHelpers.ProcessVirtualPath(URLPATH + "/" + fileName); }
|
public static string Url(string fileName) { return T4MVCHelpers.ProcessVirtualPath(URLPATH + "/" + fileName); }
|
||||||
public static readonly string jquery_signalR_1_0_1_js = T4MVCHelpers.IsProduction() && T4Extensions.FileExists(URLPATH + "/jquery.signalR-1.0.1.min.js") ? Url("jquery.signalR-1.0.1.min.js") : Url("jquery.signalR-1.0.1.js");
|
public static readonly string jquery_signalR_1_1_0_js = T4MVCHelpers.IsProduction() && T4Extensions.FileExists(URLPATH + "/jquery.signalR-1.1.0.min.js") ? Url("jquery.signalR-1.1.0.min.js") : Url("jquery.signalR-1.1.0.js");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+58
-32
@@ -1,6 +1,6 @@
|
|||||||
<#
|
<#
|
||||||
/*
|
/*
|
||||||
T4MVC Version 3.6.1
|
T4MVC Version 3.6.4
|
||||||
Find latest version and documentation at http://mvccontrib.codeplex.com/wikipage?title=T4MVC
|
Find latest version and documentation at http://mvccontrib.codeplex.com/wikipage?title=T4MVC
|
||||||
Discuss on StackOverflow or on Codeplex (https://t4mvc.codeplex.com/discussions)
|
Discuss on StackOverflow or on Codeplex (https://t4mvc.codeplex.com/discussions)
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ Please use in accordance to the MvcContrib license (http://mvccontrib.codeplex.c
|
|||||||
#>
|
#>
|
||||||
<#@ template language="C#" debug="true" hostspecific="true" #>
|
<#@ template language="C#" debug="true" hostspecific="true" #>
|
||||||
<#@ assembly name="System.Core" #>
|
<#@ assembly name="System.Core" #>
|
||||||
<#@ assembly name="Microsoft.VisualStudio.Shell.Interop.8.0" #>
|
<#@ assembly name="Microsoft.VisualStudio.Shell.Interop" #>
|
||||||
<#@ assembly name="EnvDTE" #>
|
<#@ assembly name="EnvDTE" #>
|
||||||
<#@ assembly name="EnvDTE80" #>
|
<#@ assembly name="EnvDTE80" #>
|
||||||
<#@ assembly name="VSLangProj" #>
|
<#@ assembly name="VSLangProj" #>
|
||||||
@@ -34,7 +34,7 @@ Please use in accordance to the MvcContrib license (http://mvccontrib.codeplex.c
|
|||||||
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
|
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
|
||||||
<# // To debug, uncomment the next two lines !!
|
<# // To debug, uncomment the next two lines !!
|
||||||
// System.Diagnostics.Debugger.Launch();
|
// System.Diagnostics.Debugger.Launch();
|
||||||
// System.Diagnostics.Debugger.Break();
|
// System.Diagnostics.Debugger.Break();
|
||||||
#>
|
#>
|
||||||
<#settings=MvcSettings.Load(Host);#>
|
<#settings=MvcSettings.Load(Host);#>
|
||||||
<#PrepareDataToRender(this); #>
|
<#PrepareDataToRender(this); #>
|
||||||
@@ -499,7 +499,7 @@ void PrepareDataToRender(TextTransformation tt)
|
|||||||
var serviceProvider = Host as IServiceProvider;
|
var serviceProvider = Host as IServiceProvider;
|
||||||
if (serviceProvider != null)
|
if (serviceProvider != null)
|
||||||
{
|
{
|
||||||
Dte = serviceProvider.GetService(typeof(SDTE)) as DTE;
|
Dte = (EnvDTE.DTE)serviceProvider.GetService(typeof(EnvDTE.DTE));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fail if we couldn't get the DTE. This can happen when trying to run in TextTransform.exe
|
// Fail if we couldn't get the DTE. This can happen when trying to run in TextTransform.exe
|
||||||
@@ -530,7 +530,7 @@ Project GetProjectContainingT4File(DTE dte)
|
|||||||
|
|
||||||
// If the .tt file is not opened, open it
|
// If the .tt file is not opened, open it
|
||||||
if (projectItem.Document == null)
|
if (projectItem.Document == null)
|
||||||
projectItem.Open(Constants.vsViewKindCode);
|
projectItem.Open(EnvDTE.Constants.vsViewKindCode);
|
||||||
|
|
||||||
return projectItem.ContainingProject;
|
return projectItem.ContainingProject;
|
||||||
}
|
}
|
||||||
@@ -872,13 +872,13 @@ void AddViewsRecursive(ProjectItems items, ViewsFolderInfo viewsFolder, bool use
|
|||||||
// Go through all the files in the subfolder to get the view names
|
// Go through all the files in the subfolder to get the view names
|
||||||
foreach (ProjectItem item in items)
|
foreach (ProjectItem item in items)
|
||||||
{
|
{
|
||||||
if (item.Kind == Constants.vsProjectItemKindPhysicalFile)
|
if (item.Kind == EnvDTE.Constants.vsProjectItemKindPhysicalFile)
|
||||||
{
|
{
|
||||||
if (Path.GetExtension(item.Name).Equals(".master", StringComparison.OrdinalIgnoreCase))
|
if (Path.GetExtension(item.Name).Equals(".master", StringComparison.OrdinalIgnoreCase))
|
||||||
continue; // ignore master files
|
continue; // ignore master files
|
||||||
viewsFolder.AddView(item, useNonQualifiedViewNames);
|
viewsFolder.AddView(item, useNonQualifiedViewNames);
|
||||||
}
|
}
|
||||||
else if (item.Kind == Constants.vsProjectItemKindPhysicalFolder)
|
else if (item.Kind == EnvDTE.Constants.vsProjectItemKindPhysicalFolder)
|
||||||
{
|
{
|
||||||
string folderName = Path.GetFileName(item.Name);
|
string folderName = Path.GetFileName(item.Name);
|
||||||
if (folderName.Equals("App_LocalResources", StringComparison.OrdinalIgnoreCase))
|
if (folderName.Equals("App_LocalResources", StringComparison.OrdinalIgnoreCase))
|
||||||
@@ -968,7 +968,7 @@ void ProcessStaticFiles(Project project, string folder)
|
|||||||
void ProcessStaticFilesRecursive(ProjectItem projectItem, string path)
|
void ProcessStaticFilesRecursive(ProjectItem projectItem, string path)
|
||||||
{
|
{
|
||||||
int nestedLevel = BuildClassStructureForProvidedPath(path);
|
int nestedLevel = BuildClassStructureForProvidedPath(path);
|
||||||
ProcessStaticFilesRecursive(projectItem, path, false /*hasSameNameAsParent*/);
|
ProcessStaticFilesRecursive(projectItem, path, new HashSet<String>());
|
||||||
for(int i = 0; i < nestedLevel; ++i) {#>
|
for(int i = 0; i < nestedLevel; ++i) {#>
|
||||||
}
|
}
|
||||||
<#+
|
<#+
|
||||||
@@ -976,19 +976,21 @@ void ProcessStaticFilesRecursive(ProjectItem projectItem, string path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessStaticFilesRecursive(ProjectItem projectItem, string path, bool hasSameNameAsParent)
|
void ProcessStaticFilesRecursive(ProjectItem projectItem, string path, HashSet<String> nameSet)
|
||||||
{
|
{
|
||||||
|
// The passed in HashSet is to guarantee uniqueness with our parent and siblings
|
||||||
|
string name = SanitizeWithNoConflicts(projectItem.Name, nameSet);
|
||||||
|
|
||||||
|
// This HashSet is to guarantee uniqueness of our direct children
|
||||||
|
// We add our own name to it to avoid class name conflicts (http://mvccontrib.codeplex.com/workitem/7153)
|
||||||
|
var childrenNameSet = new HashSet<String>();
|
||||||
|
childrenNameSet.Add(name);
|
||||||
|
|
||||||
if (IsFolder(projectItem))
|
if (IsFolder(projectItem))
|
||||||
{
|
{
|
||||||
string className = EscapeID(Sanitize(projectItem.Name));
|
#>
|
||||||
// If the folder name is the same as the parent, add a modifier to avoid class name conflicts
|
|
||||||
// http://mvccontrib.codeplex.com/workitem/7153
|
|
||||||
if (hasSameNameAsParent)
|
|
||||||
{
|
|
||||||
className += "_";
|
|
||||||
} #>
|
|
||||||
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
||||||
public static class <#=className #> {
|
public static class <#=EscapeID(name)#> {
|
||||||
private const string URLPATH = "<#=path#>/<#=projectItem.Name#>";
|
private const string URLPATH = "<#=path#>/<#=projectItem.Name#>";
|
||||||
public static string Url() { return T4MVCHelpers.ProcessVirtualPath(URLPATH); }
|
public static string Url() { return T4MVCHelpers.ProcessVirtualPath(URLPATH); }
|
||||||
public static string Url(string fileName) { return T4MVCHelpers.ProcessVirtualPath(URLPATH + "/" + fileName); }
|
public static string Url(string fileName) { return T4MVCHelpers.ProcessVirtualPath(URLPATH + "/" + fileName); }
|
||||||
@@ -1001,7 +1003,7 @@ foreach (ProjectItem item in projectItem.ProjectItems)
|
|||||||
ProcessStaticFilesRecursive(
|
ProcessStaticFilesRecursive(
|
||||||
item,
|
item,
|
||||||
path + "/" + projectItem.Name,
|
path + "/" + projectItem.Name,
|
||||||
item.Name == projectItem.Name);
|
childrenNameSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
PopIndent();
|
PopIndent();
|
||||||
@@ -1017,24 +1019,24 @@ if (!settings.ExcludedStaticFileExtensions.Any(extension => projectItem.Name.End
|
|||||||
if (projectItem.Name.EndsWith(".js") && !projectItem.Name.EndsWith(".min.js")) {
|
if (projectItem.Name.EndsWith(".js") && !projectItem.Name.EndsWith(".min.js")) {
|
||||||
string minifiedName = projectItem.Name.Replace(".js", ".min.js");
|
string minifiedName = projectItem.Name.Replace(".js", ".min.js");
|
||||||
if (AddTimestampToStaticLink(projectItem)) { #>
|
if (AddTimestampToStaticLink(projectItem)) { #>
|
||||||
public static readonly string <#=Sanitize(projectItem.Name)#> = T4MVCHelpers.IsProduction() && T4Extensions.FileExists(URLPATH + "/<#=minifiedName#>") ? Url("<#=minifiedName#>")+"?"+T4MVCHelpers.TimestampString(URLPATH + "/<#=minifiedName#>") : Url("<#=projectItem.Name#>")+"?"+T4MVCHelpers.TimestampString(URLPATH + "/<#=projectItem.Name#>");
|
public static readonly string <#=name#> = T4MVCHelpers.IsProduction() && T4Extensions.FileExists(URLPATH + "/<#=minifiedName#>") ? Url("<#=minifiedName#>")+"?"+T4MVCHelpers.TimestampString(URLPATH + "/<#=minifiedName#>") : Url("<#=projectItem.Name#>")+"?"+T4MVCHelpers.TimestampString(URLPATH + "/<#=projectItem.Name#>");
|
||||||
<#+} else {#>
|
<#+} else {#>
|
||||||
public static readonly string <#=Sanitize(projectItem.Name)#> = T4MVCHelpers.IsProduction() && T4Extensions.FileExists(URLPATH + "/<#=minifiedName#>") ? Url("<#=minifiedName#>") : Url("<#=projectItem.Name#>");
|
public static readonly string <#=name#> = T4MVCHelpers.IsProduction() && T4Extensions.FileExists(URLPATH + "/<#=minifiedName#>") ? Url("<#=minifiedName#>") : Url("<#=projectItem.Name#>");
|
||||||
<#+} #>
|
<#+} #>
|
||||||
<#+}
|
<#+}
|
||||||
else if (projectItem.Name.EndsWith(".css") && !projectItem.Name.EndsWith(".min.css")) {
|
else if (projectItem.Name.EndsWith(".css") && !projectItem.Name.EndsWith(".min.css")) {
|
||||||
string minifiedName = projectItem.Name.Replace(".css", ".min.css");
|
string minifiedName = projectItem.Name.Replace(".css", ".min.css");
|
||||||
if (AddTimestampToStaticLink(projectItem)) { #>
|
if (AddTimestampToStaticLink(projectItem)) { #>
|
||||||
public static readonly string <#=Sanitize(projectItem.Name)#> = T4MVCHelpers.IsProduction() && T4Extensions.FileExists(URLPATH + "/<#=minifiedName#>") ? Url("<#=minifiedName#>")+"?"+T4MVCHelpers.TimestampString(URLPATH + "/<#=minifiedName#>") : Url("<#=projectItem.Name#>")+"?"+T4MVCHelpers.TimestampString(URLPATH + "/<#=projectItem.Name#>");
|
public static readonly string <#=name#> = T4MVCHelpers.IsProduction() && T4Extensions.FileExists(URLPATH + "/<#=minifiedName#>") ? Url("<#=minifiedName#>")+"?"+T4MVCHelpers.TimestampString(URLPATH + "/<#=minifiedName#>") : Url("<#=projectItem.Name#>")+"?"+T4MVCHelpers.TimestampString(URLPATH + "/<#=projectItem.Name#>");
|
||||||
<#+} else {#>
|
<#+} else {#>
|
||||||
public static readonly string <#=Sanitize(projectItem.Name)#> = T4MVCHelpers.IsProduction() && T4Extensions.FileExists(URLPATH + "/<#=minifiedName#>") ? Url("<#=minifiedName#>") : Url("<#=projectItem.Name#>");
|
public static readonly string <#=name#> = T4MVCHelpers.IsProduction() && T4Extensions.FileExists(URLPATH + "/<#=minifiedName#>") ? Url("<#=minifiedName#>") : Url("<#=projectItem.Name#>");
|
||||||
<#+} #>
|
<#+} #>
|
||||||
<#+}
|
<#+}
|
||||||
else if (AddTimestampToStaticLink(projectItem)) { #>
|
else if (AddTimestampToStaticLink(projectItem)) { #>
|
||||||
public static readonly string <#=Sanitize(projectItem.Name)#> = Url("<#=projectItem.Name#>")+"?"+T4MVCHelpers.TimestampString(URLPATH + "/<#=projectItem.Name#>");
|
public static readonly string <#=name#> = Url("<#=projectItem.Name#>")+"?"+T4MVCHelpers.TimestampString(URLPATH + "/<#=projectItem.Name#>");
|
||||||
<#+}
|
<#+}
|
||||||
else { #>
|
else { #>
|
||||||
public static readonly string <#=Sanitize(projectItem.Name)#> = Url("<#=projectItem.Name#>");
|
public static readonly string <#=name#> = Url("<#=projectItem.Name#>");
|
||||||
<#+}
|
<#+}
|
||||||
} #>
|
} #>
|
||||||
<#+
|
<#+
|
||||||
@@ -1042,7 +1044,7 @@ if (!settings.ExcludedStaticFileExtensions.Any(extension => projectItem.Name.End
|
|||||||
// Just register them on the same path as their parent item
|
// Just register them on the same path as their parent item
|
||||||
foreach (ProjectItem item in projectItem.ProjectItems)
|
foreach (ProjectItem item in projectItem.ProjectItems)
|
||||||
{
|
{
|
||||||
ProcessStaticFilesRecursive(item, path, false);
|
ProcessStaticFilesRecursive(item, path, childrenNameSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1231,7 +1233,7 @@ static string UniqueFullName(CodeType codeType)
|
|||||||
// Return whether a ProjectItem is a folder and not a file
|
// Return whether a ProjectItem is a folder and not a file
|
||||||
static bool IsFolder(ProjectItem item)
|
static bool IsFolder(ProjectItem item)
|
||||||
{
|
{
|
||||||
return (item.Kind == Constants.vsProjectItemKindPhysicalFolder);
|
return (item.Kind == EnvDTE.Constants.vsProjectItemKindPhysicalFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
static string MakeClassName(string ns, string classname)
|
static string MakeClassName(string ns, string classname)
|
||||||
@@ -1240,6 +1242,20 @@ static string MakeClassName(string ns, string classname)
|
|||||||
String.IsNullOrEmpty(classname) ? ns : ns + "." + codeProvider.CreateEscapedIdentifier(classname);
|
String.IsNullOrEmpty(classname) ? ns : ns + "." + codeProvider.CreateEscapedIdentifier(classname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static string SanitizeWithNoConflicts(string token, HashSet<string> names)
|
||||||
|
{
|
||||||
|
string name = Sanitize(token);
|
||||||
|
|
||||||
|
while (names.Contains(name))
|
||||||
|
{
|
||||||
|
name += "_";
|
||||||
|
}
|
||||||
|
|
||||||
|
names.Add(name);
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
static string Sanitize(string token)
|
static string Sanitize(string token)
|
||||||
{
|
{
|
||||||
if (token == null) return null;
|
if (token == null) return null;
|
||||||
@@ -1606,7 +1622,7 @@ class FunctionInfo
|
|||||||
public bool IsPublic { get { return _method.Access == vsCMAccess.vsCMAccessPublic; } }
|
public bool IsPublic { get { return _method.Access == vsCMAccess.vsCMAccessPublic; } }
|
||||||
public List<MethodParamInfo> Parameters { get; private set; }
|
public List<MethodParamInfo> Parameters { get; private set; }
|
||||||
public bool CanBeCalledWithoutParameters { get; private set; }
|
public bool CanBeCalledWithoutParameters { get; private set; }
|
||||||
|
|
||||||
private bool IsTaskBased { get {return ReturnTypeImpl.FullName == "System.Threading.Tasks.Task<System.Web.Mvc.ActionResult>"; } }
|
private bool IsTaskBased { get {return ReturnTypeImpl.FullName == "System.Threading.Tasks.Task<System.Web.Mvc.ActionResult>"; } }
|
||||||
|
|
||||||
// Write out all the parameters as part of a method declaration
|
// Write out all the parameters as part of a method declaration
|
||||||
@@ -2056,7 +2072,7 @@ abstract class XmlSettings : XmlSettingsBase
|
|||||||
var serviceProvider = host as IServiceProvider;
|
var serviceProvider = host as IServiceProvider;
|
||||||
if (serviceProvider != null)
|
if (serviceProvider != null)
|
||||||
{
|
{
|
||||||
this.DTE = serviceProvider.GetService(typeof(SDTE)) as DTE;
|
this.DTE = (EnvDTE.DTE)serviceProvider.GetService(typeof(EnvDTE.DTE));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fail if we couldn't get the DTE. This can happen when trying to run in TextTransform.exe
|
// Fail if we couldn't get the DTE. This can happen when trying to run in TextTransform.exe
|
||||||
@@ -2069,7 +2085,7 @@ abstract class XmlSettings : XmlSettingsBase
|
|||||||
|
|
||||||
// If the .tt file is not opened, open it
|
// If the .tt file is not opened, open it
|
||||||
if (this.ProjectItem.Document == null)
|
if (this.ProjectItem.Document == null)
|
||||||
this.ProjectItem.Open(Constants.vsViewKindCode);
|
this.ProjectItem.Open(EnvDTE.Constants.vsViewKindCode);
|
||||||
|
|
||||||
this.Project = this.ProjectItem.ContainingProject;
|
this.Project = this.ProjectItem.ContainingProject;
|
||||||
|
|
||||||
@@ -2290,6 +2306,7 @@ class Manager
|
|||||||
private EnvDTE.DTE dte;
|
private EnvDTE.DTE dte;
|
||||||
private Action<String> checkOutAction;
|
private Action<String> checkOutAction;
|
||||||
private Action<IEnumerable<String>> projectSyncAction;
|
private Action<IEnumerable<String>> projectSyncAction;
|
||||||
|
private IVsQueryEditQuerySave2 queryEditSave;
|
||||||
|
|
||||||
public override String DefaultProjectNamespace
|
public override String DefaultProjectNamespace
|
||||||
{
|
{
|
||||||
@@ -2339,6 +2356,7 @@ class Manager
|
|||||||
templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
|
templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
|
||||||
checkOutAction = (String fileName) => dte.SourceControl.CheckOutItem(fileName);
|
checkOutAction = (String fileName) => dte.SourceControl.CheckOutItem(fileName);
|
||||||
projectSyncAction = (IEnumerable<String> keepFileNames) => ProjectSync(templateProjectItem, keepFileNames);
|
projectSyncAction = (IEnumerable<String> keepFileNames) => ProjectSync(templateProjectItem, keepFileNames);
|
||||||
|
queryEditSave = (IVsQueryEditQuerySave2)hostServiceProvider.GetService(typeof(SVsQueryEditQuerySave));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable<String> keepFileNames)
|
private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable<String> keepFileNames)
|
||||||
@@ -2362,9 +2380,17 @@ class Manager
|
|||||||
|
|
||||||
private void CheckoutFileIfRequired(String fileName)
|
private void CheckoutFileIfRequired(String fileName)
|
||||||
{
|
{
|
||||||
var sc = dte.SourceControl;
|
if (queryEditSave != null)
|
||||||
if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName))
|
{
|
||||||
checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null));
|
uint pfEditVerdict;
|
||||||
|
queryEditSave.QuerySaveFile(fileName, 0, null, out pfEditVerdict);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var sc = dte.SourceControl;
|
||||||
|
if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName))
|
||||||
|
checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,11 @@
|
|||||||
<package id="knockoutjs" version="2.2.1" targetFramework="net45" />
|
<package id="knockoutjs" version="2.2.1" targetFramework="net45" />
|
||||||
<package id="Microsoft.AspNet.Mvc" version="4.0.20710.0" targetFramework="net45" />
|
<package id="Microsoft.AspNet.Mvc" version="4.0.20710.0" targetFramework="net45" />
|
||||||
<package id="Microsoft.AspNet.Razor" version="2.0.20715.0" targetFramework="net45" />
|
<package id="Microsoft.AspNet.Razor" version="2.0.20715.0" targetFramework="net45" />
|
||||||
<package id="Microsoft.AspNet.SignalR" version="1.0.1" targetFramework="net45" />
|
<package id="Microsoft.AspNet.SignalR" version="1.1.0" targetFramework="net45" />
|
||||||
<package id="Microsoft.AspNet.SignalR.Core" version="1.0.1" targetFramework="net45" />
|
<package id="Microsoft.AspNet.SignalR.Core" version="1.1.0" targetFramework="net45" />
|
||||||
<package id="Microsoft.AspNet.SignalR.JS" version="1.0.1" targetFramework="net45" />
|
<package id="Microsoft.AspNet.SignalR.JS" version="1.1.0" targetFramework="net45" />
|
||||||
<package id="Microsoft.AspNet.SignalR.Owin" version="1.0.1" targetFramework="net45" />
|
<package id="Microsoft.AspNet.SignalR.Owin" version="1.1.0" targetFramework="net45" />
|
||||||
<package id="Microsoft.AspNet.SignalR.SystemWeb" version="1.0.1" targetFramework="net45" />
|
<package id="Microsoft.AspNet.SignalR.SystemWeb" version="1.1.0" targetFramework="net45" />
|
||||||
<package id="Microsoft.AspNet.WebApi" version="4.0.20710.0" targetFramework="net45" />
|
<package id="Microsoft.AspNet.WebApi" version="4.0.20710.0" targetFramework="net45" />
|
||||||
<package id="Microsoft.AspNet.WebApi.Client" version="4.0.20710.0" targetFramework="net45" />
|
<package id="Microsoft.AspNet.WebApi.Client" version="4.0.20710.0" targetFramework="net45" />
|
||||||
<package id="Microsoft.AspNet.WebApi.Core" version="4.0.20710.0" targetFramework="net45" />
|
<package id="Microsoft.AspNet.WebApi.Core" version="4.0.20710.0" targetFramework="net45" />
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<package id="Microsoft.SqlServer.Compact" version="4.0.8876.1" targetFramework="net45" />
|
<package id="Microsoft.SqlServer.Compact" version="4.0.8876.1" targetFramework="net45" />
|
||||||
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
|
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
|
||||||
<package id="Modernizr" version="2.6.2" targetFramework="net45" />
|
<package id="Modernizr" version="2.6.2" targetFramework="net45" />
|
||||||
<package id="Newtonsoft.Json" version="5.0.4" targetFramework="net45" />
|
<package id="Newtonsoft.Json" version="5.0.5" targetFramework="net45" />
|
||||||
<package id="Owin" version="1.0" targetFramework="net45" />
|
<package id="Owin" version="1.0" targetFramework="net45" />
|
||||||
<package id="RazorGenerator.Mvc" version="2.0.1" targetFramework="net45" />
|
<package id="RazorGenerator.Mvc" version="2.0.1" targetFramework="net45" />
|
||||||
<package id="Rx-Core" version="2.1.30214.0" targetFramework="net45" />
|
<package id="Rx-Core" version="2.1.30214.0" targetFramework="net45" />
|
||||||
@@ -35,8 +35,8 @@
|
|||||||
<package id="Rx-Main" version="2.1.30214.0" targetFramework="net45" />
|
<package id="Rx-Main" version="2.1.30214.0" targetFramework="net45" />
|
||||||
<package id="Rx-PlatformServices" version="2.1.30214.0" targetFramework="net45" />
|
<package id="Rx-PlatformServices" version="2.1.30214.0" targetFramework="net45" />
|
||||||
<package id="SqlServerCompact" version="4.0.8854.1" targetFramework="net45" />
|
<package id="SqlServerCompact" version="4.0.8854.1" targetFramework="net45" />
|
||||||
<package id="T4MVC" version="3.6.1" targetFramework="net45" />
|
<package id="T4MVC" version="3.6.4" targetFramework="net45" />
|
||||||
<package id="T4MVCExtensions" version="3.6.1" targetFramework="net45" />
|
<package id="T4MVCExtensions" version="3.6.4" targetFramework="net45" />
|
||||||
<package id="TinyMCE" version="3.5.8" targetFramework="net45" />
|
<package id="TinyMCE" version="3.5.8" targetFramework="net45" />
|
||||||
<package id="TinyMCE.JQuery" version="3.5.8" targetFramework="net45" />
|
<package id="TinyMCE.JQuery" version="3.5.8" targetFramework="net45" />
|
||||||
<package id="WebActivatorEx" version="2.0.1" targetFramework="net45" />
|
<package id="WebActivatorEx" version="2.0.1" targetFramework="net45" />
|
||||||
|
|||||||
Reference in New Issue
Block a user