////////////////////////////////////////////////////////////////////////// // // // This is a generated file. You can view the original // // source in your browser if your browser supports source maps. // // // // If you are using Chrome, open the Developer Tools and click the gear // // icon in its lower right corner. In the General Settings panel, turn // // on 'Enable source maps'. // // // // If you are using Firefox 23, go to `about:config` and set the // // `devtools.debugger.source-maps-enabled` preference to true. // // (The preference should be on by default in Firefox 24; versions // // older than 23 do not support source maps.) // // // ////////////////////////////////////////////////////////////////////////// (function () { /* Imports */ var Meteor = Package.meteor.Meteor; var check = Package.check.check; var Match = Package.check.Match; var Random = Package.random.Random; var EJSON = Package.ejson.EJSON; var JSON = Package.json.JSON; var _ = Package.underscore._; var Tracker = Package.tracker.Tracker; var Deps = Package.tracker.Deps; var Log = Package.logging.Log; var Retry = Package.retry.Retry; var LocalCollection = Package.minimongo.LocalCollection; var Minimongo = Package.minimongo.Minimongo; /* Package-scope variables */ var DDP, LivedataTest, SockJS, toSockjsUrl, toWebsocketUrl, Heartbeat, SUPPORTED_DDP_VERSIONS, MethodInvocation, parseDDP, stringifyDDP, RandomStream, makeRpcSeed, allConnections; (function () { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ddp/common.js // // // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // /** // 1 * @namespace DDP // 2 * @summary The namespace for DDP-related methods. // 3 */ // 4 DDP = {}; // 5 LivedataTest = {}; // 6 // 7 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }).call(this); (function () { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ddp/sockjs-0.3.4.js // // // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // XXX METEOR changes in // 1 // 2 /* SockJS client, version 0.3.4, http://sockjs.org, MIT License // 3 // 4 Copyright (c) 2011-2012 VMware, Inc. // 5 // 6 Permission is hereby granted, free of charge, to any person obtaining a copy // 7 of this software and associated documentation files (the "Software"), to deal // 8 in the Software without restriction, including without limitation the rights // 9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // 10 copies of the Software, and to permit persons to whom the Software is // 11 furnished to do so, subject to the following conditions: // 12 // 13 The above copyright notice and this permission notice shall be included in // 14 all copies or substantial portions of the Software. // 15 // 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // 18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // 19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // 20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // 22 THE SOFTWARE. // 23 */ // 24 // 25 // Commented out JSO implementation (use json package instead). // 26 // JSON2 by Douglas Crockford (minified). // 27 // var JSON;JSON||(JSON={}),function(){function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i=="object"&&typeof i.toJSON=="function"&&(i=i.toJSON(a)),typeof rep=="function"&&(i=rep.call(b,a,i));switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";gap+=indent,h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c // 29 // 30 // [*] Including lib/index.js // 31 // Public object // 32 SockJS = (function(){ // 33 var _document = document; // 34 var _window = window; // 35 var utils = {}; // 36 // 37 // 38 // [*] Including lib/reventtarget.js // 39 /* // 40 * ***** BEGIN LICENSE BLOCK ***** // 41 * Copyright (c) 2011-2012 VMware, Inc. // 42 * // 43 * For the license see COPYING. // 44 * ***** END LICENSE BLOCK ***** // 45 */ // 46 // 47 /* Simplified implementation of DOM2 EventTarget. // 48 * http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget // 49 */ // 50 var REventTarget = function() {}; // 51 REventTarget.prototype.addEventListener = function (eventType, listener) { // 52 if(!this._listeners) { // 53 this._listeners = {}; // 54 } // 55 if(!(eventType in this._listeners)) { // 56 this._listeners[eventType] = []; // 57 } // 58 var arr = this._listeners[eventType]; // 59 if(utils.arrIndexOf(arr, listener) === -1) { // 60 arr.push(listener); // 61 } // 62 return; // 63 }; // 64 // 65 REventTarget.prototype.removeEventListener = function (eventType, listener) { // 66 if(!(this._listeners && (eventType in this._listeners))) { // 67 return; // 68 } // 69 var arr = this._listeners[eventType]; // 70 var idx = utils.arrIndexOf(arr, listener); // 71 if (idx !== -1) { // 72 if(arr.length > 1) { // 73 this._listeners[eventType] = arr.slice(0, idx).concat( arr.slice(idx+1) ); // 74 } else { // 75 delete this._listeners[eventType]; // 76 } // 77 return; // 78 } // 79 return; // 80 }; // 81 // 82 REventTarget.prototype.dispatchEvent = function (event) { // 83 var t = event.type; // 84 var args = Array.prototype.slice.call(arguments, 0); // 85 if (this['on'+t]) { // 86 this['on'+t].apply(this, args); // 87 } // 88 if (this._listeners && t in this._listeners) { // 89 for(var i=0; i < this._listeners[t].length; i++) { // 90 this._listeners[t][i].apply(this, args); // 91 } // 92 } // 93 }; // 94 // [*] End of lib/reventtarget.js // 95 // 96 // 97 // [*] Including lib/simpleevent.js // 98 /* // 99 * ***** BEGIN LICENSE BLOCK ***** // 100 * Copyright (c) 2011-2012 VMware, Inc. // 101 * // 102 * For the license see COPYING. // 103 * ***** END LICENSE BLOCK ***** // 104 */ // 105 // 106 var SimpleEvent = function(type, obj) { // 107 this.type = type; // 108 if (typeof obj !== 'undefined') { // 109 for(var k in obj) { // 110 if (!obj.hasOwnProperty(k)) continue; // 111 this[k] = obj[k]; // 112 } // 113 } // 114 }; // 115 // 116 SimpleEvent.prototype.toString = function() { // 117 var r = []; // 118 for(var k in this) { // 119 if (!this.hasOwnProperty(k)) continue; // 120 var v = this[k]; // 121 if (typeof v === 'function') v = '[function]'; // 122 r.push(k + '=' + v); // 123 } // 124 return 'SimpleEvent(' + r.join(', ') + ')'; // 125 }; // 126 // [*] End of lib/simpleevent.js // 127 // 128 // 129 // [*] Including lib/eventemitter.js // 130 /* // 131 * ***** BEGIN LICENSE BLOCK ***** // 132 * Copyright (c) 2011-2012 VMware, Inc. // 133 * // 134 * For the license see COPYING. // 135 * ***** END LICENSE BLOCK ***** // 136 */ // 137 // 138 var EventEmitter = function(events) { // 139 var that = this; // 140 that._events = events || []; // 141 that._listeners = {}; // 142 }; // 143 EventEmitter.prototype.emit = function(type) { // 144 var that = this; // 145 that._verifyType(type); // 146 if (that._nuked) return; // 147 // 148 var args = Array.prototype.slice.call(arguments, 1); // 149 if (that['on'+type]) { // 150 that['on'+type].apply(that, args); // 151 } // 152 if (type in that._listeners) { // 153 for(var i = 0; i < that._listeners[type].length; i++) { // 154 that._listeners[type][i].apply(that, args); // 155 } // 156 } // 157 }; // 158 // 159 EventEmitter.prototype.on = function(type, callback) { // 160 var that = this; // 161 that._verifyType(type); // 162 if (that._nuked) return; // 163 // 164 if (!(type in that._listeners)) { // 165 that._listeners[type] = []; // 166 } // 167 that._listeners[type].push(callback); // 168 }; // 169 // 170 EventEmitter.prototype._verifyType = function(type) { // 171 var that = this; // 172 if (utils.arrIndexOf(that._events, type) === -1) { // 173 utils.log('Event ' + JSON.stringify(type) + // 174 ' not listed ' + JSON.stringify(that._events) + // 175 ' in ' + that); // 176 } // 177 }; // 178 // 179 EventEmitter.prototype.nuke = function() { // 180 var that = this; // 181 that._nuked = true; // 182 for(var i=0; i // 234 // https://github.com/sockjs/sockjs-client/issues/79 // 235 utils.isSameOriginScheme = function(url_a, url_b) { // 236 if (!url_b) url_b = _window.location.href; // 237 // 238 return (url_a.split(':')[0] // 239 === // 240 url_b.split(':')[0]); // 241 }; // 242 // // 243 // 244 // 245 utils.getParentDomain = function(url) { // 246 // ipv4 ip address // 247 if (/^[0-9.]*$/.test(url)) return url; // 248 // ipv6 ip address // 249 if (/^\[/.test(url)) return url; // 250 // no dots // 251 if (!(/[.]/.test(url))) return url; // 252 // 253 var parts = url.split('.').slice(1); // 254 return parts.join('.'); // 255 }; // 256 // 257 utils.objectExtend = function(dst, src) { // 258 for(var k in src) { // 259 if (src.hasOwnProperty(k)) { // 260 dst[k] = src[k]; // 261 } // 262 } // 263 return dst; // 264 }; // 265 // 266 var WPrefix = '_jp'; // 267 // 268 utils.polluteGlobalNamespace = function() { // 269 if (!(WPrefix in _window)) { // 270 _window[WPrefix] = {}; // 271 } // 272 }; // 273 // 274 utils.closeFrame = function (code, reason) { // 275 return 'c'+JSON.stringify([code, reason]); // 276 }; // 277 // 278 utils.userSetCode = function (code) { // 279 return code === 1000 || (code >= 3000 && code <= 4999); // 280 }; // 281 // 282 // See: http://www.erg.abdn.ac.uk/~gerrit/dccp/notes/ccid2/rto_estimator/ // 283 // and RFC 2988. // 284 utils.countRTO = function (rtt) { // 285 var rto; // 286 if (rtt > 100) { // 287 rto = 3 * rtt; // rto > 300msec // 288 } else { // 289 rto = rtt + 200; // 200msec < rto <= 300msec // 290 } // 291 return rto; // 292 } // 293 // 294 utils.log = function() { // 295 if (_window.console && console.log && console.log.apply) { // 296 console.log.apply(console, arguments); // 297 } // 298 }; // 299 // 300 utils.bind = function(fun, that) { // 301 if (fun.bind) { // 302 return fun.bind(that); // 303 } else { // 304 return function() { // 305 return fun.apply(that, arguments); // 306 }; // 307 } // 308 }; // 309 // 310 utils.flatUrl = function(url) { // 311 return url.indexOf('?') === -1 && url.indexOf('#') === -1; // 312 }; // 313 // 314 // `relativeTo` is an optional absolute URL. If provided, `url` will be // 315 // interpreted relative to `relativeTo`. Defaults to `document.location`. // 316 // // 317 utils.amendUrl = function(url, relativeTo) { // 318 var baseUrl; // 319 if (relativeTo === undefined) { // 320 baseUrl = _document.location; // 321 } else { // 322 var protocolMatch = /^([a-z0-9.+-]+:)/i.exec(relativeTo); // 323 if (protocolMatch) { // 324 var protocol = protocolMatch[0].toLowerCase(); // 325 var rest = relativeTo.substring(protocol.length); // 326 var hostMatch = /[a-z0-9\.-]+(:[0-9]+)?/.exec(rest); // 327 if (hostMatch) // 328 var host = hostMatch[0]; // 329 } // 330 if (! protocol || ! host) // 331 throw new Error("relativeTo must be an absolute url"); // 332 baseUrl = { // 333 protocol: protocol, // 334 host: host // 335 }; // 336 } // 337 if (!url) { // 338 throw new Error('Wrong url for SockJS'); // 339 } // 340 if (!utils.flatUrl(url)) { // 341 throw new Error('Only basic urls are supported in SockJS'); // 342 } // 343 // 344 // '//abc' --> 'http://abc' // 345 if (url.indexOf('//') === 0) { // 346 url = baseUrl.protocol + url; // 347 } // 348 // '/abc' --> 'http://localhost:1234/abc' // 349 if (url.indexOf('/') === 0) { // 350 url = baseUrl.protocol + '//' + baseUrl.host + url; // 351 } // 352 // // 353 // strip trailing slashes // 354 url = url.replace(/[/]+$/,''); // 355 // 356 // We have a full url here, with proto and host. For some browsers // 357 // http://localhost:80/ is not in the same origin as http://localhost/ // 358 // Remove explicit :80 or :443 in such cases. See #74 // 359 var parts = url.split("/"); // 360 if ((parts[0] === "http:" && /:80$/.test(parts[2])) || // 361 (parts[0] === "https:" && /:443$/.test(parts[2]))) { // 362 parts[2] = parts[2].replace(/:(80|443)$/, ""); // 363 } // 364 url = parts.join("/"); // 365 return url; // 366 }; // 367 // 368 // IE doesn't support [].indexOf. // 369 utils.arrIndexOf = function(arr, obj){ // 370 for(var i=0; i < arr.length; i++){ // 371 if(arr[i] === obj){ // 372 return i; // 373 } // 374 } // 375 return -1; // 376 }; // 377 // 378 utils.arrSkip = function(arr, obj) { // 379 var idx = utils.arrIndexOf(arr, obj); // 380 if (idx === -1) { // 381 return arr.slice(); // 382 } else { // 383 var dst = arr.slice(0, idx); // 384 return dst.concat(arr.slice(idx+1)); // 385 } // 386 }; // 387 // 388 // Via: https://gist.github.com/1133122/2121c601c5549155483f50be3da5305e83b8c5df // 389 utils.isArray = Array.isArray || function(value) { // 390 return {}.toString.call(value).indexOf('Array') >= 0 // 391 }; // 392 // 393 utils.delay = function(t, fun) { // 394 if(typeof t === 'function') { // 395 fun = t; // 396 t = 0; // 397 } // 398 return setTimeout(fun, t); // 399 }; // 400 // 401 // 402 // Chars worth escaping, as defined by Douglas Crockford: // 403 // https://github.com/douglascrockford/JSON-js/blob/47a9882cddeb1e8529e07af9736218075372b8ac/json2.js#L196 // 404 var json_escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, json_lookup = { // 406 "\u0000":"\\u0000","\u0001":"\\u0001","\u0002":"\\u0002","\u0003":"\\u0003", // 407 "\u0004":"\\u0004","\u0005":"\\u0005","\u0006":"\\u0006","\u0007":"\\u0007", // 408 "\b":"\\b","\t":"\\t","\n":"\\n","\u000b":"\\u000b","\f":"\\f","\r":"\\r", // 409 "\u000e":"\\u000e","\u000f":"\\u000f","\u0010":"\\u0010","\u0011":"\\u0011", // 410 "\u0012":"\\u0012","\u0013":"\\u0013","\u0014":"\\u0014","\u0015":"\\u0015", // 411 "\u0016":"\\u0016","\u0017":"\\u0017","\u0018":"\\u0018","\u0019":"\\u0019", // 412 "\u001a":"\\u001a","\u001b":"\\u001b","\u001c":"\\u001c","\u001d":"\\u001d", // 413 "\u001e":"\\u001e","\u001f":"\\u001f","\"":"\\\"","\\":"\\\\", // 414 "\u007f":"\\u007f","\u0080":"\\u0080","\u0081":"\\u0081","\u0082":"\\u0082", // 415 "\u0083":"\\u0083","\u0084":"\\u0084","\u0085":"\\u0085","\u0086":"\\u0086", // 416 "\u0087":"\\u0087","\u0088":"\\u0088","\u0089":"\\u0089","\u008a":"\\u008a", // 417 "\u008b":"\\u008b","\u008c":"\\u008c","\u008d":"\\u008d","\u008e":"\\u008e", // 418 "\u008f":"\\u008f","\u0090":"\\u0090","\u0091":"\\u0091","\u0092":"\\u0092", // 419 "\u0093":"\\u0093","\u0094":"\\u0094","\u0095":"\\u0095","\u0096":"\\u0096", // 420 "\u0097":"\\u0097","\u0098":"\\u0098","\u0099":"\\u0099","\u009a":"\\u009a", // 421 "\u009b":"\\u009b","\u009c":"\\u009c","\u009d":"\\u009d","\u009e":"\\u009e", // 422 "\u009f":"\\u009f","\u00ad":"\\u00ad","\u0600":"\\u0600","\u0601":"\\u0601", // 423 "\u0602":"\\u0602","\u0603":"\\u0603","\u0604":"\\u0604","\u070f":"\\u070f", // 424 "\u17b4":"\\u17b4","\u17b5":"\\u17b5","\u200c":"\\u200c","\u200d":"\\u200d", // 425 "\u200e":"\\u200e","\u200f":"\\u200f","\u2028":"\\u2028","\u2029":"\\u2029", // 426 "\u202a":"\\u202a","\u202b":"\\u202b","\u202c":"\\u202c","\u202d":"\\u202d", // 427 "\u202e":"\\u202e","\u202f":"\\u202f","\u2060":"\\u2060","\u2061":"\\u2061", // 428 "\u2062":"\\u2062","\u2063":"\\u2063","\u2064":"\\u2064","\u2065":"\\u2065", // 429 "\u2066":"\\u2066","\u2067":"\\u2067","\u2068":"\\u2068","\u2069":"\\u2069", // 430 "\u206a":"\\u206a","\u206b":"\\u206b","\u206c":"\\u206c","\u206d":"\\u206d", // 431 "\u206e":"\\u206e","\u206f":"\\u206f","\ufeff":"\\ufeff","\ufff0":"\\ufff0", // 432 "\ufff1":"\\ufff1","\ufff2":"\\ufff2","\ufff3":"\\ufff3","\ufff4":"\\ufff4", // 433 "\ufff5":"\\ufff5","\ufff6":"\\ufff6","\ufff7":"\\ufff7","\ufff8":"\\ufff8", // 434 "\ufff9":"\\ufff9","\ufffa":"\\ufffa","\ufffb":"\\ufffb","\ufffc":"\\ufffc", // 435 "\ufffd":"\\ufffd","\ufffe":"\\ufffe","\uffff":"\\uffff"}; // 436 // 437 // Some extra characters that Chrome gets wrong, and substitutes with // 438 // something else on the wire. // 439 var extra_escapable = /[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g, extra_lookup; // 441 // 442 // JSON Quote string. Use native implementation when possible. // 443 var JSONQuote = (JSON && JSON.stringify) || function(string) { // 444 json_escapable.lastIndex = 0; // 445 if (json_escapable.test(string)) { // 446 string = string.replace(json_escapable, function(a) { // 447 return json_lookup[a]; // 448 }); // 449 } // 450 return '"' + string + '"'; // 451 }; // 452 // 453 // This may be quite slow, so let's delay until user actually uses bad // 454 // characters. // 455 var unroll_lookup = function(escapable) { // 456 var i; // 457 var unrolled = {} // 458 var c = [] // 459 for(i=0; i<65536; i++) { // 460 c.push( String.fromCharCode(i) ); // 461 } // 462 escapable.lastIndex = 0; // 463 c.join('').replace(escapable, function (a) { // 464 unrolled[ a ] = '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); // 465 return ''; // 466 }); // 467 escapable.lastIndex = 0; // 468 return unrolled; // 469 }; // 470 // 471 // Quote string, also taking care of unicode characters that browsers // 472 // often break. Especially, take care of unicode surrogates: // 473 // http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Surrogates // 474 utils.quote = function(string) { // 475 var quoted = JSONQuote(string); // 476 // 477 // In most cases this should be very fast and good enough. // 478 extra_escapable.lastIndex = 0; // 479 if(!extra_escapable.test(quoted)) { // 480 return quoted; // 481 } // 482 // 483 if(!extra_lookup) extra_lookup = unroll_lookup(extra_escapable); // 484 // 485 return quoted.replace(extra_escapable, function(a) { // 486 return extra_lookup[a]; // 487 }); // 488 } // 489 // 490 var _all_protocols = ['websocket', // 491 'xdr-streaming', // 492 'xhr-streaming', // 493 'iframe-eventsource', // 494 'iframe-htmlfile', // 495 'xdr-polling', // 496 'xhr-polling', // 497 'iframe-xhr-polling', // 498 'jsonp-polling']; // 499 // 500 utils.probeProtocols = function() { // 501 var probed = {}; // 502 for(var i=0; i<_all_protocols.length; i++) { // 503 var protocol = _all_protocols[i]; // 504 // User can have a typo in protocol name. // 505 probed[protocol] = SockJS[protocol] && // 506 SockJS[protocol].enabled(); // 507 } // 508 return probed; // 509 }; // 510 // 511 utils.detectProtocols = function(probed, protocols_whitelist, info) { // 512 var pe = {}, // 513 protocols = []; // 514 if (!protocols_whitelist) protocols_whitelist = _all_protocols; // 515 for(var i=0; i 0) { // 525 maybe_push(protos); // 526 } // 527 } // 528 } // 529 // 530 // 1. Websocket // 531 if (info.websocket !== false) { // 532 maybe_push(['websocket']); // 533 } // 534 // 535 // 2. Streaming // 536 if (pe['xhr-streaming'] && !info.null_origin) { // 537 protocols.push('xhr-streaming'); // 538 } else { // 539 if (pe['xdr-streaming'] && !info.cookie_needed && !info.null_origin) { // 540 protocols.push('xdr-streaming'); // 541 } else { // 542 maybe_push(['iframe-eventsource', // 543 'iframe-htmlfile']); // 544 } // 545 } // 546 // 547 // 3. Polling // 548 if (pe['xhr-polling'] && !info.null_origin) { // 549 protocols.push('xhr-polling'); // 550 } else { // 551 if (pe['xdr-polling'] && !info.cookie_needed && !info.null_origin) { // 552 protocols.push('xdr-polling'); // 553 } else { // 554 maybe_push(['iframe-xhr-polling', // 555 'jsonp-polling']); // 556 } // 557 } // 558 return protocols; // 559 } // 560 // [*] End of lib/utils.js // 561 // 562 // 563 // [*] Including lib/dom.js // 564 /* // 565 * ***** BEGIN LICENSE BLOCK ***** // 566 * Copyright (c) 2011-2012 VMware, Inc. // 567 * // 568 * For the license see COPYING. // 569 * ***** END LICENSE BLOCK ***** // 570 */ // 571 // 572 // May be used by htmlfile jsonp and transports. // 573 var MPrefix = '_sockjs_global'; // 574 utils.createHook = function() { // 575 var window_id = 'a' + utils.random_string(8); // 576 if (!(MPrefix in _window)) { // 577 var map = {}; // 578 _window[MPrefix] = function(window_id) { // 579 if (!(window_id in map)) { // 580 map[window_id] = { // 581 id: window_id, // 582 del: function() {delete map[window_id];} // 583 }; // 584 } // 585 return map[window_id]; // 586 } // 587 } // 588 return _window[MPrefix](window_id); // 589 }; // 590 // 591 // 592 // 593 utils.attachMessage = function(listener) { // 594 utils.attachEvent('message', listener); // 595 }; // 596 utils.attachEvent = function(event, listener) { // 597 if (typeof _window.addEventListener !== 'undefined') { // 598 _window.addEventListener(event, listener, false); // 599 } else { // 600 // IE quirks. // 601 // According to: http://stevesouders.com/misc/test-postmessage.php // 602 // the message gets delivered only to 'document', not 'window'. // 603 _document.attachEvent("on" + event, listener); // 604 // I get 'window' for ie8. // 605 _window.attachEvent("on" + event, listener); // 606 } // 607 }; // 608 // 609 utils.detachMessage = function(listener) { // 610 utils.detachEvent('message', listener); // 611 }; // 612 utils.detachEvent = function(event, listener) { // 613 if (typeof _window.addEventListener !== 'undefined') { // 614 _window.removeEventListener(event, listener, false); // 615 } else { // 616 _document.detachEvent("on" + event, listener); // 617 _window.detachEvent("on" + event, listener); // 618 } // 619 }; // 620 // 621 // 622 var on_unload = {}; // 623 // Things registered after beforeunload are to be called immediately. // 624 var after_unload = false; // 625 // 626 var trigger_unload_callbacks = function() { // 627 for(var ref in on_unload) { // 628 on_unload[ref](); // 629 delete on_unload[ref]; // 630 }; // 631 }; // 632 // 633 var unload_triggered = function() { // 634 if(after_unload) return; // 635 after_unload = true; // 636 trigger_unload_callbacks(); // 637 }; // 638 // 639 // 'unload' alone is not reliable in opera within an iframe, but we // 640 // can't use `beforeunload` as IE fires it on javascript: links. // 641 utils.attachEvent('unload', unload_triggered); // 642 // 643 utils.unload_add = function(listener) { // 644 var ref = utils.random_string(8); // 645 on_unload[ref] = listener; // 646 if (after_unload) { // 647 utils.delay(trigger_unload_callbacks); // 648 } // 649 return ref; // 650 }; // 651 utils.unload_del = function(ref) { // 652 if (ref in on_unload) // 653 delete on_unload[ref]; // 654 }; // 655 // 656 // 657 utils.createIframe = function (iframe_url, error_callback) { // 658 var iframe = _document.createElement('iframe'); // 659 var tref, unload_ref; // 660 var unattach = function() { // 661 clearTimeout(tref); // 662 // Explorer had problems with that. // 663 try {iframe.onload = null;} catch (x) {} // 664 iframe.onerror = null; // 665 }; // 666 var cleanup = function() { // 667 if (iframe) { // 668 unattach(); // 669 // This timeout makes chrome fire onbeforeunload event // 670 // within iframe. Without the timeout it goes straight to // 671 // onunload. // 672 setTimeout(function() { // 673 if(iframe) { // 674 iframe.parentNode.removeChild(iframe); // 675 } // 676 iframe = null; // 677 }, 0); // 678 utils.unload_del(unload_ref); // 679 } // 680 }; // 681 var onerror = function(r) { // 682 if (iframe) { // 683 cleanup(); // 684 error_callback(r); // 685 } // 686 }; // 687 var post = function(msg, origin) { // 688 try { // 689 // When the iframe is not loaded, IE raises an exception // 690 // on 'contentWindow'. // 691 if (iframe && iframe.contentWindow) { // 692 iframe.contentWindow.postMessage(msg, origin); // 693 } // 694 } catch (x) {}; // 695 }; // 696 // 697 iframe.src = iframe_url; // 698 iframe.style.display = 'none'; // 699 iframe.style.position = 'absolute'; // 700 iframe.onerror = function(){onerror('onerror');}; // 701 iframe.onload = function() { // 702 // `onload` is triggered before scripts on the iframe are // 703 // executed. Give it few seconds to actually load stuff. // 704 clearTimeout(tref); // 705 tref = setTimeout(function(){onerror('onload timeout');}, 2000); // 706 }; // 707 _document.body.appendChild(iframe); // 708 tref = setTimeout(function(){onerror('timeout');}, 15000); // 709 unload_ref = utils.unload_add(cleanup); // 710 return { // 711 post: post, // 712 cleanup: cleanup, // 713 loaded: unattach // 714 }; // 715 }; // 716 // 717 utils.createHtmlfile = function (iframe_url, error_callback) { // 718 var doc = new ActiveXObject('htmlfile'); // 719 var tref, unload_ref; // 720 var iframe; // 721 var unattach = function() { // 722 clearTimeout(tref); // 723 }; // 724 var cleanup = function() { // 725 if (doc) { // 726 unattach(); // 727 utils.unload_del(unload_ref); // 728 iframe.parentNode.removeChild(iframe); // 729 iframe = doc = null; // 730 CollectGarbage(); // 731 } // 732 }; // 733 var onerror = function(r) { // 734 if (doc) { // 735 cleanup(); // 736 error_callback(r); // 737 } // 738 }; // 739 var post = function(msg, origin) { // 740 try { // 741 // When the iframe is not loaded, IE raises an exception // 742 // on 'contentWindow'. // 743 if (iframe && iframe.contentWindow) { // 744 iframe.contentWindow.postMessage(msg, origin); // 745 } // 746 } catch (x) {}; // 747 }; // 748 // 749 doc.open(); // 750 doc.write('' + // 751 'document.domain="' + document.domain + '";' + // 752 ''); // 753 doc.close(); // 754 doc.parentWindow[WPrefix] = _window[WPrefix]; // 755 var c = doc.createElement('div'); // 756 doc.body.appendChild(c); // 757 iframe = doc.createElement('iframe'); // 758 c.appendChild(iframe); // 759 iframe.src = iframe_url; // 760 tref = setTimeout(function(){onerror('timeout');}, 15000); // 761 unload_ref = utils.unload_add(cleanup); // 762 return { // 763 post: post, // 764 cleanup: cleanup, // 765 loaded: unattach // 766 }; // 767 }; // 768 // [*] End of lib/dom.js // 769 // 770 // 771 // [*] Including lib/dom2.js // 772 /* // 773 * ***** BEGIN LICENSE BLOCK ***** // 774 * Copyright (c) 2011-2012 VMware, Inc. // 775 * // 776 * For the license see COPYING. // 777 * ***** END LICENSE BLOCK ***** // 778 */ // 779 // 780 var AbstractXHRObject = function(){}; // 781 AbstractXHRObject.prototype = new EventEmitter(['chunk', 'finish']); // 782 // 783 AbstractXHRObject.prototype._start = function(method, url, payload, opts) { // 784 var that = this; // 785 // 786 try { // 787 that.xhr = new XMLHttpRequest(); // 788 } catch(x) {}; // 789 // 790 if (!that.xhr) { // 791 try { // 792 that.xhr = new _window.ActiveXObject('Microsoft.XMLHTTP'); // 793 } catch(x) {}; // 794 } // 795 if (_window.ActiveXObject || _window.XDomainRequest) { // 796 // IE8 caches even POSTs // 797 url += ((url.indexOf('?') === -1) ? '?' : '&') + 't='+(+new Date); // 798 } // 799 // 800 // Explorer tends to keep connection open, even after the // 801 // tab gets closed: http://bugs.jquery.com/ticket/5280 // 802 that.unload_ref = utils.unload_add(function(){that._cleanup(true);}); // 803 try { // 804 that.xhr.open(method, url, true); // 805 } catch(e) { // 806 // IE raises an exception on wrong port. // 807 that.emit('finish', 0, ''); // 808 that._cleanup(); // 809 return; // 810 }; // 811 // 812 if (!opts || !opts.no_credentials) { // 813 // Mozilla docs says https://developer.mozilla.org/en/XMLHttpRequest : // 814 // "This never affects same-site requests." // 815 that.xhr.withCredentials = 'true'; // 816 } // 817 if (opts && opts.headers) { // 818 for(var key in opts.headers) { // 819 that.xhr.setRequestHeader(key, opts.headers[key]); // 820 } // 821 } // 822 // 823 that.xhr.onreadystatechange = function() { // 824 if (that.xhr) { // 825 var x = that.xhr; // 826 switch (x.readyState) { // 827 case 3: // 828 // IE doesn't like peeking into responseText or status // 829 // on Microsoft.XMLHTTP and readystate=3 // 830 try { // 831 var status = x.status; // 832 var text = x.responseText; // 833 } catch (x) {}; // 834 // IE returns 1223 for 204: http://bugs.jquery.com/ticket/1450 // 835 if (status === 1223) status = 204; // 836 // 837 // IE does return readystate == 3 for 404 answers. // 838 if (text && text.length > 0) { // 839 that.emit('chunk', status, text); // 840 } // 841 break; // 842 case 4: // 843 var status = x.status; // 844 // IE returns 1223 for 204: http://bugs.jquery.com/ticket/1450 // 845 if (status === 1223) status = 204; // 846 // 847 that.emit('finish', status, x.responseText); // 848 that._cleanup(false); // 849 break; // 850 } // 851 } // 852 }; // 853 that.xhr.send(payload); // 854 }; // 855 // 856 AbstractXHRObject.prototype._cleanup = function(abort) { // 857 var that = this; // 858 if (!that.xhr) return; // 859 utils.unload_del(that.unload_ref); // 860 // 861 // IE needs this field to be a function // 862 that.xhr.onreadystatechange = function(){}; // 863 // 864 if (abort) { // 865 try { // 866 that.xhr.abort(); // 867 } catch(x) {}; // 868 } // 869 that.unload_ref = that.xhr = null; // 870 }; // 871 // 872 AbstractXHRObject.prototype.close = function() { // 873 var that = this; // 874 that.nuke(); // 875 that._cleanup(true); // 876 }; // 877 // 878 var XHRCorsObject = utils.XHRCorsObject = function() { // 879 var that = this, args = arguments; // 880 utils.delay(function(){that._start.apply(that, args);}); // 881 }; // 882 XHRCorsObject.prototype = new AbstractXHRObject(); // 883 // 884 var XHRLocalObject = utils.XHRLocalObject = function(method, url, payload) { // 885 var that = this; // 886 utils.delay(function(){ // 887 that._start(method, url, payload, { // 888 no_credentials: true // 889 }); // 890 }); // 891 }; // 892 XHRLocalObject.prototype = new AbstractXHRObject(); // 893 // 894 // 895 // 896 // References: // 897 // http://ajaxian.com/archives/100-line-ajax-wrapper // 898 // http://msdn.microsoft.com/en-us/library/cc288060(v=VS.85).aspx // 899 var XDRObject = utils.XDRObject = function(method, url, payload) { // 900 var that = this; // 901 utils.delay(function(){that._start(method, url, payload);}); // 902 }; // 903 XDRObject.prototype = new EventEmitter(['chunk', 'finish']); // 904 XDRObject.prototype._start = function(method, url, payload) { // 905 var that = this; // 906 var xdr = new XDomainRequest(); // 907 // IE caches even POSTs // 908 url += ((url.indexOf('?') === -1) ? '?' : '&') + 't='+(+new Date); // 909 // 910 var onerror = xdr.ontimeout = xdr.onerror = function() { // 911 that.emit('finish', 0, ''); // 912 that._cleanup(false); // 913 }; // 914 xdr.onprogress = function() { // 915 that.emit('chunk', 200, xdr.responseText); // 916 }; // 917 xdr.onload = function() { // 918 that.emit('finish', 200, xdr.responseText); // 919 that._cleanup(false); // 920 }; // 921 that.xdr = xdr; // 922 that.unload_ref = utils.unload_add(function(){that._cleanup(true);}); // 923 try { // 924 // Fails with AccessDenied if port number is bogus // 925 that.xdr.open(method, url); // 926 that.xdr.send(payload); // 927 } catch(x) { // 928 onerror(); // 929 } // 930 }; // 931 // 932 XDRObject.prototype._cleanup = function(abort) { // 933 var that = this; // 934 if (!that.xdr) return; // 935 utils.unload_del(that.unload_ref); // 936 // 937 that.xdr.ontimeout = that.xdr.onerror = that.xdr.onprogress = // 938 that.xdr.onload = null; // 939 if (abort) { // 940 try { // 941 that.xdr.abort(); // 942 } catch(x) {}; // 943 } // 944 that.unload_ref = that.xdr = null; // 945 }; // 946 // 947 XDRObject.prototype.close = function() { // 948 var that = this; // 949 that.nuke(); // 950 that._cleanup(true); // 951 }; // 952 // 953 // 1. Is natively via XHR // 954 // 2. Is natively via XDR // 955 // 3. Nope, but postMessage is there so it should work via the Iframe. // 956 // 4. Nope, sorry. // 957 utils.isXHRCorsCapable = function() { // 958 if (_window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest()) { // 959 return 1; // 960 } // 961 // XDomainRequest doesn't work if page is served from file:// // 962 if (_window.XDomainRequest && _document.domain) { // 963 return 2; // 964 } // 965 if (IframeTransport.enabled()) { // 966 return 3; // 967 } // 968 return 4; // 969 }; // 970 // [*] End of lib/dom2.js // 971 // 972 // 973 // [*] Including lib/sockjs.js // 974 /* // 975 * ***** BEGIN LICENSE BLOCK ***** // 976 * Copyright (c) 2011-2012 VMware, Inc. // 977 * // 978 * For the license see COPYING. // 979 * ***** END LICENSE BLOCK ***** // 980 */ // 981 // 982 var SockJS = function(url, dep_protocols_whitelist, options) { // 983 if (!(this instanceof SockJS)) { // 984 // makes `new` optional // 985 return new SockJS(url, dep_protocols_whitelist, options); // 986 } // 987 // 988 var that = this, protocols_whitelist; // 989 that._options = {devel: false, debug: false, protocols_whitelist: [], // 990 info: undefined, rtt: undefined}; // 991 if (options) { // 992 utils.objectExtend(that._options, options); // 993 } // 994 that._base_url = utils.amendUrl(url); // 995 that._server = that._options.server || utils.random_number_string(1000); // 996 if (that._options.protocols_whitelist && // 997 that._options.protocols_whitelist.length) { // 998 protocols_whitelist = that._options.protocols_whitelist; // 999 } else { // 1000 // Deprecated API // 1001 if (typeof dep_protocols_whitelist === 'string' && // 1002 dep_protocols_whitelist.length > 0) { // 1003 protocols_whitelist = [dep_protocols_whitelist]; // 1004 } else if (utils.isArray(dep_protocols_whitelist)) { // 1005 protocols_whitelist = dep_protocols_whitelist // 1006 } else { // 1007 protocols_whitelist = null; // 1008 } // 1009 if (protocols_whitelist) { // 1010 that._debug('Deprecated API: Use "protocols_whitelist" option ' + // 1011 'instead of supplying protocol list as a second ' + // 1012 'parameter to SockJS constructor.'); // 1013 } // 1014 } // 1015 that._protocols = []; // 1016 that.protocol = null; // 1017 that.readyState = SockJS.CONNECTING; // 1018 that._ir = createInfoReceiver(that._base_url); // 1019 that._ir.onfinish = function(info, rtt) { // 1020 that._ir = null; // 1021 if (info) { // 1022 if (that._options.info) { // 1023 // Override if user supplies the option // 1024 info = utils.objectExtend(info, that._options.info); // 1025 } // 1026 if (that._options.rtt) { // 1027 rtt = that._options.rtt; // 1028 } // 1029 that._applyInfo(info, rtt, protocols_whitelist); // 1030 that._didClose(); // 1031 } else { // 1032 that._didClose(1002, 'Can\'t connect to server', true); // 1033 } // 1034 }; // 1035 }; // 1036 // Inheritance // 1037 SockJS.prototype = new REventTarget(); // 1038 // 1039 SockJS.version = "0.3.4"; // 1040 // 1041 SockJS.CONNECTING = 0; // 1042 SockJS.OPEN = 1; // 1043 SockJS.CLOSING = 2; // 1044 SockJS.CLOSED = 3; // 1045 // 1046 SockJS.prototype._debug = function() { // 1047 if (this._options.debug) // 1048 utils.log.apply(utils, arguments); // 1049 }; // 1050 // 1051 SockJS.prototype._dispatchOpen = function() { // 1052 var that = this; // 1053 if (that.readyState === SockJS.CONNECTING) { // 1054 if (that._transport_tref) { // 1055 clearTimeout(that._transport_tref); // 1056 that._transport_tref = null; // 1057 } // 1058 that.readyState = SockJS.OPEN; // 1059 that.dispatchEvent(new SimpleEvent("open")); // 1060 } else { // 1061 // The server might have been restarted, and lost track of our // 1062 // connection. // 1063 that._didClose(1006, "Server lost session"); // 1064 } // 1065 }; // 1066 // 1067 SockJS.prototype._dispatchMessage = function(data) { // 1068 var that = this; // 1069 if (that.readyState !== SockJS.OPEN) // 1070 return; // 1071 that.dispatchEvent(new SimpleEvent("message", {data: data})); // 1072 }; // 1073 // 1074 SockJS.prototype._dispatchHeartbeat = function(data) { // 1075 var that = this; // 1076 if (that.readyState !== SockJS.OPEN) // 1077 return; // 1078 that.dispatchEvent(new SimpleEvent('heartbeat', {})); // 1079 }; // 1080 // 1081 SockJS.prototype._didClose = function(code, reason, force) { // 1082 var that = this; // 1083 if (that.readyState !== SockJS.CONNECTING && // 1084 that.readyState !== SockJS.OPEN && // 1085 that.readyState !== SockJS.CLOSING) // 1086 throw new Error('INVALID_STATE_ERR'); // 1087 if (that._ir) { // 1088 that._ir.nuke(); // 1089 that._ir = null; // 1090 } // 1091 // 1092 if (that._transport) { // 1093 that._transport.doCleanup(); // 1094 that._transport = null; // 1095 } // 1096 // 1097 var close_event = new SimpleEvent("close", { // 1098 code: code, // 1099 reason: reason, // 1100 wasClean: utils.userSetCode(code)}); // 1101 // 1102 if (!utils.userSetCode(code) && // 1103 that.readyState === SockJS.CONNECTING && !force) { // 1104 if (that._try_next_protocol(close_event)) { // 1105 return; // 1106 } // 1107 close_event = new SimpleEvent("close", {code: 2000, // 1108 reason: "All transports failed", // 1109 wasClean: false, // 1110 last_event: close_event}); // 1111 } // 1112 that.readyState = SockJS.CLOSED; // 1113 // 1114 utils.delay(function() { // 1115 that.dispatchEvent(close_event); // 1116 }); // 1117 }; // 1118 // 1119 SockJS.prototype._didMessage = function(data) { // 1120 var that = this; // 1121 var type = data.slice(0, 1); // 1122 switch(type) { // 1123 case 'o': // 1124 that._dispatchOpen(); // 1125 break; // 1126 case 'a': // 1127 var payload = JSON.parse(data.slice(1) || '[]'); // 1128 for(var i=0; i < payload.length; i++){ // 1129 that._dispatchMessage(payload[i]); // 1130 } // 1131 break; // 1132 case 'm': // 1133 var payload = JSON.parse(data.slice(1) || 'null'); // 1134 that._dispatchMessage(payload); // 1135 break; // 1136 case 'c': // 1137 var payload = JSON.parse(data.slice(1) || '[]'); // 1138 that._didClose(payload[0], payload[1]); // 1139 break; // 1140 case 'h': // 1141 that._dispatchHeartbeat(); // 1142 break; // 1143 } // 1144 }; // 1145 // 1146 SockJS.prototype._try_next_protocol = function(close_event) { // 1147 var that = this; // 1148 if (that.protocol) { // 1149 that._debug('Closed transport:', that.protocol, ''+close_event); // 1150 that.protocol = null; // 1151 } // 1152 if (that._transport_tref) { // 1153 clearTimeout(that._transport_tref); // 1154 that._transport_tref = null; // 1155 } // 1156 // 1157 while(1) { // 1158 var protocol = that.protocol = that._protocols.shift(); // 1159 if (!protocol) { // 1160 return false; // 1161 } // 1162 // Some protocols require access to `body`, what if were in // 1163 // the `head`? // 1164 if (SockJS[protocol] && // 1165 SockJS[protocol].need_body === true && // 1166 (!_document.body || // 1167 (typeof _document.readyState !== 'undefined' // 1168 && _document.readyState !== 'complete'))) { // 1169 that._protocols.unshift(protocol); // 1170 that.protocol = 'waiting-for-load'; // 1171 utils.attachEvent('load', function(){ // 1172 that._try_next_protocol(); // 1173 }); // 1174 return true; // 1175 } // 1176 // 1177 if (!SockJS[protocol] || // 1178 !SockJS[protocol].enabled(that._options)) { // 1179 that._debug('Skipping transport:', protocol); // 1180 } else { // 1181 var roundTrips = SockJS[protocol].roundTrips || 1; // 1182 var to = ((that._options.rto || 0) * roundTrips) || 5000; // 1183 that._transport_tref = utils.delay(to, function() { // 1184 if (that.readyState === SockJS.CONNECTING) { // 1185 // I can't understand how it is possible to run // 1186 // this timer, when the state is CLOSED, but // 1187 // apparently in IE everythin is possible. // 1188 that._didClose(2007, "Transport timeouted"); // 1189 } // 1190 }); // 1191 // 1192 var connid = utils.random_string(8); // 1193 var trans_url = that._base_url + '/' + that._server + '/' + connid; // 1194 that._debug('Opening transport:', protocol, ' url:'+trans_url, // 1195 ' RTO:'+that._options.rto); // 1196 that._transport = new SockJS[protocol](that, trans_url, // 1197 that._base_url); // 1198 return true; // 1199 } // 1200 } // 1201 }; // 1202 // 1203 SockJS.prototype.close = function(code, reason) { // 1204 var that = this; // 1205 if (code && !utils.userSetCode(code)) // 1206 throw new Error("INVALID_ACCESS_ERR"); // 1207 if(that.readyState !== SockJS.CONNECTING && // 1208 that.readyState !== SockJS.OPEN) { // 1209 return false; // 1210 } // 1211 that.readyState = SockJS.CLOSING; // 1212 that._didClose(code || 1000, reason || "Normal closure"); // 1213 return true; // 1214 }; // 1215 // 1216 SockJS.prototype.send = function(data) { // 1217 var that = this; // 1218 if (that.readyState === SockJS.CONNECTING) // 1219 throw new Error('INVALID_STATE_ERR'); // 1220 if (that.readyState === SockJS.OPEN) { // 1221 that._transport.doSend(utils.quote('' + data)); // 1222 } // 1223 return true; // 1224 }; // 1225 // 1226 SockJS.prototype._applyInfo = function(info, rtt, protocols_whitelist) { // 1227 var that = this; // 1228 that._options.info = info; // 1229 that._options.rtt = rtt; // 1230 that._options.rto = utils.countRTO(rtt); // 1231 that._options.info.null_origin = !_document.domain; // 1232 // Servers can override base_url, eg to provide a randomized domain name and // 1233 // avoid browser per-domain connection limits. // 1234 if (info.base_url) // 1235 // // 1236 that._base_url = utils.amendUrl(info.base_url, that._base_url); // 1237 // // 1238 var probed = utils.probeProtocols(); // 1239 that._protocols = utils.detectProtocols(probed, protocols_whitelist, info); // 1240 // // 1241 // https://github.com/sockjs/sockjs-client/issues/79 // 1242 // Hack to avoid XDR when using different protocols // 1243 // We're on IE trying to do cross-protocol. jsonp only. // 1244 if (!utils.isSameOriginScheme(that._base_url) && // 1245 2 === utils.isXHRCorsCapable()) { // 1246 that._protocols = ['jsonp-polling']; // 1247 } // 1248 // // 1249 }; // 1250 // [*] End of lib/sockjs.js // 1251 // 1252 // 1253 // [*] Including lib/trans-websocket.js // 1254 /* // 1255 * ***** BEGIN LICENSE BLOCK ***** // 1256 * Copyright (c) 2011-2012 VMware, Inc. // 1257 * // 1258 * For the license see COPYING. // 1259 * ***** END LICENSE BLOCK ***** // 1260 */ // 1261 // 1262 var WebSocketTransport = SockJS.websocket = function(ri, trans_url) { // 1263 var that = this; // 1264 var url = trans_url + '/websocket'; // 1265 if (url.slice(0, 5) === 'https') { // 1266 url = 'wss' + url.slice(5); // 1267 } else { // 1268 url = 'ws' + url.slice(4); // 1269 } // 1270 that.ri = ri; // 1271 that.url = url; // 1272 var Constructor = _window.WebSocket || _window.MozWebSocket; // 1273 // 1274 that.ws = new Constructor(that.url); // 1275 that.ws.onmessage = function(e) { // 1276 that.ri._didMessage(e.data); // 1277 }; // 1278 // Firefox has an interesting bug. If a websocket connection is // 1279 // created after onunload, it stays alive even when user // 1280 // navigates away from the page. In such situation let's lie - // 1281 // let's not open the ws connection at all. See: // 1282 // https://github.com/sockjs/sockjs-client/issues/28 // 1283 // https://bugzilla.mozilla.org/show_bug.cgi?id=696085 // 1284 that.unload_ref = utils.unload_add(function(){that.ws.close()}); // 1285 that.ws.onclose = function() { // 1286 that.ri._didMessage(utils.closeFrame(1006, "WebSocket connection broken")); // 1287 }; // 1288 }; // 1289 // 1290 WebSocketTransport.prototype.doSend = function(data) { // 1291 this.ws.send('[' + data + ']'); // 1292 }; // 1293 // 1294 WebSocketTransport.prototype.doCleanup = function() { // 1295 var that = this; // 1296 var ws = that.ws; // 1297 if (ws) { // 1298 ws.onmessage = ws.onclose = null; // 1299 ws.close(); // 1300 utils.unload_del(that.unload_ref); // 1301 that.unload_ref = that.ri = that.ws = null; // 1302 } // 1303 }; // 1304 // 1305 WebSocketTransport.enabled = function() { // 1306 return !!(_window.WebSocket || _window.MozWebSocket); // 1307 }; // 1308 // 1309 // In theory, ws should require 1 round trip. But in chrome, this is // 1310 // not very stable over SSL. Most likely a ws connection requires a // 1311 // separate SSL connection, in which case 2 round trips are an // 1312 // absolute minumum. // 1313 WebSocketTransport.roundTrips = 2; // 1314 // [*] End of lib/trans-websocket.js // 1315 // 1316 // 1317 // [*] Including lib/trans-sender.js // 1318 /* // 1319 * ***** BEGIN LICENSE BLOCK ***** // 1320 * Copyright (c) 2011-2012 VMware, Inc. // 1321 * // 1322 * For the license see COPYING. // 1323 * ***** END LICENSE BLOCK ***** // 1324 */ // 1325 // 1326 var BufferedSender = function() {}; // 1327 BufferedSender.prototype.send_constructor = function(sender) { // 1328 var that = this; // 1329 that.send_buffer = []; // 1330 that.sender = sender; // 1331 }; // 1332 BufferedSender.prototype.doSend = function(message) { // 1333 var that = this; // 1334 that.send_buffer.push(message); // 1335 if (!that.send_stop) { // 1336 that.send_schedule(); // 1337 } // 1338 }; // 1339 // 1340 // For polling transports in a situation when in the message callback, // 1341 // new message is being send. If the sending connection was started // 1342 // before receiving one, it is possible to saturate the network and // 1343 // timeout due to the lack of receiving socket. To avoid that we delay // 1344 // sending messages by some small time, in order to let receiving // 1345 // connection be started beforehand. This is only a halfmeasure and // 1346 // does not fix the big problem, but it does make the tests go more // 1347 // stable on slow networks. // 1348 BufferedSender.prototype.send_schedule_wait = function() { // 1349 var that = this; // 1350 var tref; // 1351 that.send_stop = function() { // 1352 that.send_stop = null; // 1353 clearTimeout(tref); // 1354 }; // 1355 tref = utils.delay(25, function() { // 1356 that.send_stop = null; // 1357 that.send_schedule(); // 1358 }); // 1359 }; // 1360 // 1361 BufferedSender.prototype.send_schedule = function() { // 1362 var that = this; // 1363 if (that.send_buffer.length > 0) { // 1364 var payload = '[' + that.send_buffer.join(',') + ']'; // 1365 that.send_stop = that.sender(that.trans_url, payload, function(success, abort_reason) { // 1366 that.send_stop = null; // 1367 if (success === false) { // 1368 that.ri._didClose(1006, 'Sending error ' + abort_reason); // 1369 } else { // 1370 that.send_schedule_wait(); // 1371 } // 1372 }); // 1373 that.send_buffer = []; // 1374 } // 1375 }; // 1376 // 1377 BufferedSender.prototype.send_destructor = function() { // 1378 var that = this; // 1379 if (that._send_stop) { // 1380 that._send_stop(); // 1381 } // 1382 that._send_stop = null; // 1383 }; // 1384 // 1385 var jsonPGenericSender = function(url, payload, callback) { // 1386 var that = this; // 1387 // 1388 if (!('_send_form' in that)) { // 1389 var form = that._send_form = _document.createElement('form'); // 1390 var area = that._send_area = _document.createElement('textarea'); // 1391 area.name = 'd'; // 1392 form.style.display = 'none'; // 1393 form.style.position = 'absolute'; // 1394 form.method = 'POST'; // 1395 form.enctype = 'application/x-www-form-urlencoded'; // 1396 form.acceptCharset = "UTF-8"; // 1397 form.appendChild(area); // 1398 _document.body.appendChild(form); // 1399 } // 1400 var form = that._send_form; // 1401 var area = that._send_area; // 1402 var id = 'a' + utils.random_string(8); // 1403 form.target = id; // 1404 form.action = url + '/jsonp_send?i=' + id; // 1405 // 1406 var iframe; // 1407 try { // 1408 // ie6 dynamic iframes with target="" support (thanks Chris Lambacher) // 1409 iframe = _document.createElement('