xdomain-rails 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1077 @@
1
+ // XDomain - v0.6.15 - https://github.com/jpillora/xdomain
2
+ // Jaime Pillora <dev@jpillora.com> - MIT Copyright 2014
3
+ (function(window,undefined) {// XHook - v1.2.4 - https://github.com/jpillora/xhook
4
+ // Jaime Pillora <dev@jpillora.com> - MIT Copyright 2014
5
+ (function(window,undefined) {var AFTER, BEFORE, COMMON_EVENTS, EventEmitter, FIRE, FormData, NativeFormData, OFF, ON, READY_STATE, UPLOAD_EVENTS, XHookHttpRequest, XMLHTTP, convertHeaders, document, fakeEvent, mergeObjects, proxyEvents, slice, xhook, _base,
6
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
7
+
8
+ document = window.document;
9
+
10
+ BEFORE = 'before';
11
+
12
+ AFTER = 'after';
13
+
14
+ READY_STATE = 'readyState';
15
+
16
+ ON = 'addEventListener';
17
+
18
+ OFF = 'removeEventListener';
19
+
20
+ FIRE = 'dispatchEvent';
21
+
22
+ XMLHTTP = 'XMLHttpRequest';
23
+
24
+ FormData = 'FormData';
25
+
26
+ UPLOAD_EVENTS = ['load', 'loadend', 'loadstart'];
27
+
28
+ COMMON_EVENTS = ['progress', 'abort', 'error', 'timeout'];
29
+
30
+ (_base = Array.prototype).indexOf || (_base.indexOf = function(item) {
31
+ var i, x, _i, _len;
32
+ for (i = _i = 0, _len = this.length; _i < _len; i = ++_i) {
33
+ x = this[i];
34
+ if (x === item) {
35
+ return i;
36
+ }
37
+ }
38
+ return -1;
39
+ });
40
+
41
+ slice = function(o, n) {
42
+ return Array.prototype.slice.call(o, n);
43
+ };
44
+
45
+ mergeObjects = function(src, dst) {
46
+ var k, v;
47
+ for (k in src) {
48
+ v = src[k];
49
+ if (k === "returnValue") {
50
+ continue;
51
+ }
52
+ try {
53
+ dst[k] = src[k];
54
+ } catch (_error) {}
55
+ }
56
+ return dst;
57
+ };
58
+
59
+ proxyEvents = function(events, src, dst) {
60
+ var event, p, _i, _len;
61
+ p = function(event) {
62
+ return function(e) {
63
+ var clone, k, val;
64
+ clone = {};
65
+ for (k in e) {
66
+ if (k === "returnValue") {
67
+ continue;
68
+ }
69
+ val = e[k];
70
+ clone[k] = val === src ? dst : val;
71
+ }
72
+ clone;
73
+ return dst[FIRE](event, clone);
74
+ };
75
+ };
76
+ for (_i = 0, _len = events.length; _i < _len; _i++) {
77
+ event = events[_i];
78
+ src["on" + event] = p(event);
79
+ }
80
+ };
81
+
82
+ fakeEvent = function(type) {
83
+ var msieEventObject;
84
+ if (document.createEventObject != null) {
85
+ msieEventObject = document.createEventObject();
86
+ msieEventObject.type = type;
87
+ return msieEventObject;
88
+ } else {
89
+ try {
90
+ return new Event(type);
91
+ } catch (_error) {
92
+ return {
93
+ type: type
94
+ };
95
+ }
96
+ }
97
+ };
98
+
99
+ EventEmitter = function(nodeStyle) {
100
+ var emitter, events, listeners;
101
+ events = {};
102
+ listeners = function(event) {
103
+ return events[event] || [];
104
+ };
105
+ emitter = {};
106
+ emitter[ON] = function(event, callback, i) {
107
+ events[event] = listeners(event);
108
+ if (events[event].indexOf(callback) >= 0) {
109
+ return;
110
+ }
111
+ i = i === undefined ? events[event].length : i;
112
+ events[event].splice(i, 0, callback);
113
+ };
114
+ emitter[OFF] = function(event, callback) {
115
+ var i;
116
+ i = listeners(event).indexOf(callback);
117
+ if (i === -1) {
118
+ return;
119
+ }
120
+ listeners(event).splice(i, 1);
121
+ };
122
+ emitter[FIRE] = function() {
123
+ var args, event, i, legacylistener, listener, _i, _len, _ref;
124
+ args = slice(arguments);
125
+ event = args.shift();
126
+ if (!nodeStyle) {
127
+ args[0] = mergeObjects(args[0], fakeEvent(event));
128
+ }
129
+ legacylistener = emitter["on" + event];
130
+ if (legacylistener) {
131
+ legacylistener.apply(undefined, args);
132
+ }
133
+ _ref = listeners(event).concat(listeners("*"));
134
+ for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
135
+ listener = _ref[i];
136
+ listener.apply(undefined, args);
137
+ }
138
+ };
139
+ if (nodeStyle) {
140
+ emitter.listeners = function(event) {
141
+ return slice(listeners(event));
142
+ };
143
+ emitter.on = emitter[ON];
144
+ emitter.off = emitter[OFF];
145
+ emitter.fire = emitter[FIRE];
146
+ emitter.once = function(e, fn) {
147
+ var fire;
148
+ fire = function() {
149
+ emitter.off(e, fire);
150
+ return fn.apply(null, arguments);
151
+ };
152
+ return emitter.on(e, fire);
153
+ };
154
+ emitter.destroy = function() {
155
+ return events = {};
156
+ };
157
+ }
158
+ return emitter;
159
+ };
160
+
161
+ xhook = EventEmitter(true);
162
+
163
+ xhook.EventEmitter = EventEmitter;
164
+
165
+ xhook[BEFORE] = function(handler, i) {
166
+ if (handler.length < 1 || handler.length > 2) {
167
+ throw "invalid hook";
168
+ }
169
+ return xhook[ON](BEFORE, handler, i);
170
+ };
171
+
172
+ xhook[AFTER] = function(handler, i) {
173
+ if (handler.length < 2 || handler.length > 3) {
174
+ throw "invalid hook";
175
+ }
176
+ return xhook[ON](AFTER, handler, i);
177
+ };
178
+
179
+ xhook.enable = function() {
180
+ window[XMLHTTP] = XHookHttpRequest;
181
+ };
182
+
183
+ xhook.disable = function() {
184
+ window[XMLHTTP] = xhook[XMLHTTP];
185
+ };
186
+
187
+ convertHeaders = xhook.headers = function(h, dest) {
188
+ var header, headers, k, name, v, value, _i, _len, _ref;
189
+ if (dest == null) {
190
+ dest = {};
191
+ }
192
+ switch (typeof h) {
193
+ case "object":
194
+ headers = [];
195
+ for (k in h) {
196
+ v = h[k];
197
+ name = k.toLowerCase();
198
+ headers.push("" + name + ":\t" + v);
199
+ }
200
+ return headers.join('\n');
201
+ case "string":
202
+ headers = h.split('\n');
203
+ for (_i = 0, _len = headers.length; _i < _len; _i++) {
204
+ header = headers[_i];
205
+ if (/([^:]+):\s*(.+)/.test(header)) {
206
+ name = (_ref = RegExp.$1) != null ? _ref.toLowerCase() : void 0;
207
+ value = RegExp.$2;
208
+ if (dest[name] == null) {
209
+ dest[name] = value;
210
+ }
211
+ }
212
+ }
213
+ return dest;
214
+ }
215
+ };
216
+
217
+ NativeFormData = window[FormData];
218
+
219
+ if (NativeFormData) {
220
+ xhook[FormData] = NativeFormData;
221
+ window[FormData] = function(form) {
222
+ var entries;
223
+ this.fd = form ? new NativeFormData(form) : new NativeFormData();
224
+ this.form = form;
225
+ entries = [];
226
+ Object.defineProperty(this, 'entries', {
227
+ get: function() {
228
+ var fentries;
229
+ fentries = !form ? [] : slice(form.querySelectorAll("input,select")).filter(function(e) {
230
+ var _ref;
231
+ return ((_ref = e.type) !== 'checkbox' && _ref !== 'radio') || e.checked;
232
+ }).map(function(e) {
233
+ return [e.name, e.type === "file" ? e.files : e.value];
234
+ });
235
+ return fentries.concat(entries);
236
+ }
237
+ });
238
+ this.append = (function(_this) {
239
+ return function() {
240
+ var args;
241
+ args = slice(arguments);
242
+ entries.push(args);
243
+ return _this.fd.append.apply(_this.fd, args);
244
+ };
245
+ })(this);
246
+ };
247
+ }
248
+
249
+ xhook[XMLHTTP] = window[XMLHTTP];
250
+
251
+ XHookHttpRequest = window[XMLHTTP] = function() {
252
+ var currentState, emitFinal, emitReadyState, facade, hasError, hasErrorHandler, readBody, readHead, request, response, setReadyState, transiting, writeBody, writeHead, xhr;
253
+ xhr = new xhook[XMLHTTP]();
254
+ hasError = false;
255
+ transiting = false;
256
+ request = {};
257
+ request.headers = {};
258
+ request.headerNames = {};
259
+ response = {};
260
+ response.headers = {};
261
+ readHead = function() {
262
+ var key, name, val, _ref;
263
+ response.status = xhr.status;
264
+ response.statusText = xhr.statusText;
265
+ _ref = convertHeaders(xhr.getAllResponseHeaders());
266
+ for (key in _ref) {
267
+ val = _ref[key];
268
+ if (!response.headers[key]) {
269
+ name = key.toLowerCase();
270
+ response.headers[name] = val;
271
+ }
272
+ }
273
+ };
274
+ readBody = function() {
275
+ try {
276
+ response.text = xhr.responseText;
277
+ } catch (_error) {}
278
+ try {
279
+ response.xml = xhr.responseXML;
280
+ } catch (_error) {}
281
+ response.data = xhr.response || response.text;
282
+ };
283
+ writeHead = function() {
284
+ facade.status = response.status;
285
+ facade.statusText = response.statusText;
286
+ };
287
+ writeBody = function() {
288
+ if (response.hasOwnProperty('text')) {
289
+ facade.responseText = response.text;
290
+ }
291
+ if (response.hasOwnProperty('xml')) {
292
+ facade.responseXML = response.xml;
293
+ }
294
+ facade.response = response.data || null;
295
+ };
296
+ emitReadyState = function(n) {
297
+ while (n > currentState && currentState < 4) {
298
+ facade[READY_STATE] = ++currentState;
299
+ if (currentState === 1) {
300
+ facade[FIRE]("loadstart", {});
301
+ }
302
+ if (currentState === 2) {
303
+ writeHead();
304
+ }
305
+ if (currentState === 4) {
306
+ writeHead();
307
+ writeBody();
308
+ }
309
+ facade[FIRE]("readystatechange", {});
310
+ if (currentState === 4) {
311
+ setTimeout(emitFinal, 0);
312
+ }
313
+ }
314
+ };
315
+ emitFinal = function() {
316
+ if (!hasError) {
317
+ facade[FIRE]("load", {});
318
+ }
319
+ facade[FIRE]("loadend", {});
320
+ if (hasError) {
321
+ facade[READY_STATE] = 0;
322
+ }
323
+ };
324
+ currentState = 0;
325
+ setReadyState = function(n) {
326
+ var hooks, process;
327
+ if (n !== 4) {
328
+ emitReadyState(n);
329
+ return;
330
+ }
331
+ hooks = xhook.listeners(AFTER);
332
+ process = function() {
333
+ var hook;
334
+ if (!hooks.length) {
335
+ return emitReadyState(4);
336
+ }
337
+ hook = hooks.shift();
338
+ if (hook.length === 2) {
339
+ hook(request, response);
340
+ return process();
341
+ } else if (hook.length === 3 && request.async) {
342
+ return hook(request, response, process);
343
+ } else {
344
+ return process();
345
+ }
346
+ };
347
+ process();
348
+ };
349
+ facade = request.xhr = EventEmitter();
350
+ xhr.onreadystatechange = function(event) {
351
+ try {
352
+ if (xhr[READY_STATE] === 2) {
353
+ readHead();
354
+ }
355
+ } catch (_error) {}
356
+ if (xhr[READY_STATE] === 4) {
357
+ transiting = false;
358
+ readHead();
359
+ readBody();
360
+ }
361
+ setReadyState(xhr[READY_STATE]);
362
+ };
363
+ hasErrorHandler = function() {
364
+ hasError = true;
365
+ };
366
+ facade[ON]('error', hasErrorHandler);
367
+ facade[ON]('timeout', hasErrorHandler);
368
+ facade[ON]('abort', hasErrorHandler);
369
+ facade[ON]('progress', function() {
370
+ if (currentState < 3) {
371
+ setReadyState(3);
372
+ } else {
373
+ facade[FIRE]("readystatechange", {});
374
+ }
375
+ });
376
+ proxyEvents(COMMON_EVENTS, xhr, facade);
377
+ if ('withCredentials' in xhr || xhook.addWithCredentials) {
378
+ facade.withCredentials = false;
379
+ }
380
+ facade.status = 0;
381
+ facade.open = function(method, url, async, user, pass) {
382
+ request.method = method;
383
+ request.url = url;
384
+ request.async = async !== false;
385
+ request.user = user;
386
+ request.pass = pass;
387
+ setReadyState(1);
388
+ };
389
+ facade.send = function(body) {
390
+ var hooks, k, modk, process, send, _i, _len, _ref;
391
+ _ref = ['type', 'timeout', 'withCredentials'];
392
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
393
+ k = _ref[_i];
394
+ modk = k === "type" ? "responseType" : k;
395
+ if (modk in facade) {
396
+ request[k] = facade[modk];
397
+ }
398
+ }
399
+ request.body = body;
400
+ send = function() {
401
+ var header, value, _j, _len1, _ref1, _ref2;
402
+ transiting = true;
403
+ xhr.open(request.method, request.url, request.async, request.user, request.pass);
404
+ _ref1 = ['type', 'timeout', 'withCredentials'];
405
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
406
+ k = _ref1[_j];
407
+ modk = k === "type" ? "responseType" : k;
408
+ if (k in request) {
409
+ xhr[modk] = request[k];
410
+ }
411
+ }
412
+ _ref2 = request.headers;
413
+ for (header in _ref2) {
414
+ value = _ref2[header];
415
+ xhr.setRequestHeader(header, value);
416
+ }
417
+ if (window[FormData] && request.body instanceof window[FormData]) {
418
+ request.body = request.body.fd;
419
+ }
420
+ xhr.send(request.body);
421
+ };
422
+ hooks = xhook.listeners(BEFORE);
423
+ process = function() {
424
+ var done, hook;
425
+ if (!hooks.length) {
426
+ return send();
427
+ }
428
+ done = function(userResponse) {
429
+ if (typeof userResponse === 'object' && (typeof userResponse.status === 'number' || typeof response.status === 'number')) {
430
+ mergeObjects(userResponse, response);
431
+ if (__indexOf.call(userResponse, 'data') < 0) {
432
+ userResponse.data = userResponse.response || userResponse.text;
433
+ }
434
+ setReadyState(4);
435
+ return;
436
+ }
437
+ process();
438
+ };
439
+ done.head = function(userResponse) {
440
+ mergeObjects(userResponse, response);
441
+ return setReadyState(2);
442
+ };
443
+ done.progress = function(userResponse) {
444
+ mergeObjects(userResponse, response);
445
+ return setReadyState(3);
446
+ };
447
+ hook = hooks.shift();
448
+ if (hook.length === 1) {
449
+ return done(hook(request));
450
+ } else if (hook.length === 2 && request.async) {
451
+ return hook(request, done);
452
+ } else {
453
+ return done();
454
+ }
455
+ };
456
+ process();
457
+ };
458
+ facade.abort = function() {
459
+ if (transiting) {
460
+ xhr.abort();
461
+ } else {
462
+ facade[FIRE]('abort', {});
463
+ }
464
+ };
465
+ facade.setRequestHeader = function(header, value) {
466
+ var lName, name;
467
+ lName = header != null ? header.toLowerCase() : void 0;
468
+ name = request.headerNames[lName] = request.headerNames[lName] || header;
469
+ if (request.headers[name]) {
470
+ value = request.headers[name] + ', ' + value;
471
+ }
472
+ request.headers[name] = value;
473
+ };
474
+ facade.getResponseHeader = function(header) {
475
+ var name;
476
+ name = header != null ? header.toLowerCase() : void 0;
477
+ return response.headers[name];
478
+ };
479
+ facade.getAllResponseHeaders = function() {
480
+ return convertHeaders(response.headers);
481
+ };
482
+ if (xhr.overrideMimeType) {
483
+ facade.overrideMimeType = function() {
484
+ return xhr.overrideMimeType.apply(xhr, arguments);
485
+ };
486
+ }
487
+ if (xhr.upload) {
488
+ facade.upload = request.upload = EventEmitter();
489
+ proxyEvents(COMMON_EVENTS.concat(UPLOAD_EVENTS), xhr.upload, facade.upload);
490
+ }
491
+ return facade;
492
+ };
493
+
494
+ if (typeof this.define === "function" && this.define.amd) {
495
+ define("xhook", [], function() {
496
+ return xhook;
497
+ });
498
+ } else {
499
+ (this.exports || this).xhook = xhook;
500
+ }
501
+ }.call(this,window));
502
+ var CHECK_INTERVAL, COMPAT_VERSION, XD_CHECK, addMasters, addSlaves, connect, console, createSocket, currentOrigin, document, feature, frames, getFrame, guid, handler, initMaster, initSlave, instOf, jsonEncode, listen, location, log, logger, masters, onMessage, parseUrl, slaves, slice, sockets, startPostMessage, strip, toRegExp, warn, xdomain, xhook, _i, _len, _ref;
503
+
504
+ slaves = null;
505
+
506
+ addSlaves = function(s) {
507
+ var origin, path;
508
+ if (slaves === null) {
509
+ slaves = {};
510
+ initMaster();
511
+ }
512
+ for (origin in s) {
513
+ path = s[origin];
514
+ log("adding slave: " + origin);
515
+ slaves[origin] = path;
516
+ }
517
+ };
518
+
519
+ frames = {};
520
+
521
+ getFrame = function(origin, proxyPath) {
522
+ var frame;
523
+ if (frames[origin]) {
524
+ return frames[origin];
525
+ }
526
+ frame = document.createElement("iframe");
527
+ frame.id = frame.name = guid();
528
+ log("creating iframe " + frame.id);
529
+ frame.src = "" + origin + proxyPath;
530
+ frame.setAttribute('style', 'display:none;');
531
+ document.body.appendChild(frame);
532
+ return frames[origin] = frame.contentWindow;
533
+ };
534
+
535
+ initMaster = function() {
536
+ var convertFormData, convertToArrayBuffer, handleRequest;
537
+ convertToArrayBuffer = function(args, done) {
538
+ var isBlob, isFile, name, obj, reader;
539
+ name = args[0], obj = args[1];
540
+ isBlob = instOf(obj, 'Blob');
541
+ isFile = instOf(obj, 'File');
542
+ if (!(isBlob || isFile)) {
543
+ return 0;
544
+ }
545
+ reader = new FileReader();
546
+ reader.onload = function() {
547
+ args[1] = null;
548
+ if (isFile) {
549
+ args[2] = obj.name;
550
+ }
551
+ return done(['XD_BLOB', args, this.result, obj.type]);
552
+ };
553
+ reader.readAsArrayBuffer(obj);
554
+ return 1;
555
+ };
556
+ convertFormData = function(entries, send) {
557
+ var c;
558
+ entries.forEach(function(args, i) {
559
+ var file, name, value, _i, _len;
560
+ name = args[0], value = args[1];
561
+ if (instOf(value, 'FileList')) {
562
+ entries.splice(i, 1);
563
+ for (_i = 0, _len = value.length; _i < _len; _i++) {
564
+ file = value[_i];
565
+ entries.splice(i, 0, [name, file]);
566
+ }
567
+ }
568
+ });
569
+ c = 0;
570
+ entries.forEach(function(args, i) {
571
+ c += convertToArrayBuffer(args, function(newargs) {
572
+ entries[i] = newargs;
573
+ if (--c === 0) {
574
+ send();
575
+ }
576
+ });
577
+ });
578
+ if (c === 0) {
579
+ send();
580
+ }
581
+ };
582
+ handleRequest = function(request, socket) {
583
+ var entries, obj, send;
584
+ socket.on("xhr-event", function() {
585
+ return request.xhr.dispatchEvent.apply(null, arguments);
586
+ });
587
+ socket.on("xhr-upload-event", function() {
588
+ return request.xhr.upload.dispatchEvent.apply(null, arguments);
589
+ });
590
+ obj = strip(request);
591
+ obj.headers = request.headers;
592
+ if (request.withCredentials) {
593
+ obj.credentials = document.cookie;
594
+ }
595
+ send = function() {
596
+ return socket.emit("request", obj);
597
+ };
598
+ if (request.body) {
599
+ obj.body = request.body;
600
+ if (instOf(obj.body, 'FormData')) {
601
+ entries = obj.body.entries;
602
+ obj.body = ["XD_FD", entries];
603
+ convertFormData(entries, send);
604
+ return;
605
+ }
606
+ }
607
+ send();
608
+ };
609
+ xhook.addWithCredentials = true;
610
+ return xhook.before(function(request, callback) {
611
+ var frame, p, socket;
612
+ p = parseUrl(request.url);
613
+ if (!p || p.origin === currentOrigin) {
614
+ return callback();
615
+ }
616
+ if (!slaves[p.origin]) {
617
+ if (p) {
618
+ log("no slave matching: '" + p.origin + "'");
619
+ }
620
+ return callback();
621
+ }
622
+ log("proxying request to slave: '" + p.origin + "'");
623
+ if (request.async === false) {
624
+ warn("sync not supported");
625
+ return callback();
626
+ }
627
+ frame = getFrame(p.origin, slaves[p.origin]);
628
+ socket = connect(frame);
629
+ socket.on("response", function(resp) {
630
+ callback(resp);
631
+ return socket.close();
632
+ });
633
+ request.xhr.addEventListener('abort', function() {
634
+ return socket.emit("abort");
635
+ });
636
+ if (socket.ready) {
637
+ handleRequest(request, socket);
638
+ } else {
639
+ socket.once('ready', function() {
640
+ return handleRequest(request, socket);
641
+ });
642
+ }
643
+ });
644
+ };
645
+
646
+ masters = null;
647
+
648
+ addMasters = function(m) {
649
+ var origin, path;
650
+ if (masters === null) {
651
+ masters = {};
652
+ initSlave();
653
+ }
654
+ for (origin in m) {
655
+ path = m[origin];
656
+ log("adding master: " + origin);
657
+ masters[origin] = path;
658
+ }
659
+ };
660
+
661
+ initSlave = function() {
662
+ listen(function(origin, socket) {
663
+ var master, masterRegex, pathRegex, regex;
664
+ if (origin === "null") {
665
+ origin = "*";
666
+ }
667
+ pathRegex = null;
668
+ for (master in masters) {
669
+ regex = masters[master];
670
+ try {
671
+ masterRegex = toRegExp(master);
672
+ if (masterRegex.test(origin)) {
673
+ pathRegex = toRegExp(regex);
674
+ break;
675
+ }
676
+ } catch (_error) {}
677
+ }
678
+ if (!pathRegex) {
679
+ warn("blocked request from: '" + origin + "'");
680
+ return;
681
+ }
682
+ socket.once("request", function(req) {
683
+ var args, blob, entries, fd, k, p, v, xhr, _i, _len, _ref;
684
+ log("request: " + req.method + " " + req.url);
685
+ p = parseUrl(req.url);
686
+ if (!(p && pathRegex.test(p.path))) {
687
+ warn("blocked request to path: '" + p.path + "' by regex: " + pathRegex);
688
+ socket.close();
689
+ return;
690
+ }
691
+ xhr = new XMLHttpRequest();
692
+ xhr.open(req.method, req.url);
693
+ xhr.addEventListener("*", function(e) {
694
+ return socket.emit('xhr-event', e.type, strip(e));
695
+ });
696
+ if (xhr.upload) {
697
+ xhr.upload.addEventListener("*", function(e) {
698
+ return socket.emit('xhr-upload-event', e.type, strip(e));
699
+ });
700
+ }
701
+ socket.once("abort", function() {
702
+ return xhr.abort();
703
+ });
704
+ xhr.onreadystatechange = function() {
705
+ var resp;
706
+ if (xhr.readyState !== 4) {
707
+ return;
708
+ }
709
+ resp = {
710
+ status: xhr.status,
711
+ statusText: xhr.statusText,
712
+ data: xhr.response,
713
+ headers: xhook.headers(xhr.getAllResponseHeaders())
714
+ };
715
+ try {
716
+ resp.text = xhr.responseText;
717
+ } catch (_error) {}
718
+ return socket.emit('response', resp);
719
+ };
720
+ if (req.withCredentials) {
721
+ req.headers['XDomain-Cookie'] = req.credentials;
722
+ }
723
+ if (req.timeout) {
724
+ xhr.timeout = req.timeout;
725
+ }
726
+ if (req.type) {
727
+ xhr.responseType = req.type;
728
+ }
729
+ _ref = req.headers;
730
+ for (k in _ref) {
731
+ v = _ref[k];
732
+ xhr.setRequestHeader(k, v);
733
+ }
734
+ if (req.body instanceof Array && req.body[0] === "XD_FD") {
735
+ fd = new xhook.FormData();
736
+ entries = req.body[1];
737
+ for (_i = 0, _len = entries.length; _i < _len; _i++) {
738
+ args = entries[_i];
739
+ if (args[0] === "XD_BLOB" && args.length === 4) {
740
+ blob = new Blob([args[2]], {
741
+ type: args[3]
742
+ });
743
+ args = args[1];
744
+ args[1] = blob;
745
+ }
746
+ fd.append.apply(fd, args);
747
+ }
748
+ req.body = fd;
749
+ }
750
+ xhr.send(req.body || null);
751
+ });
752
+ log("slave listening for requests on socket: " + socket.id);
753
+ });
754
+ if (window === window.parent) {
755
+ return warn("slaves must be in an iframe");
756
+ } else {
757
+ return window.parent.postMessage("XDPING_" + COMPAT_VERSION, '*');
758
+ }
759
+ };
760
+
761
+ onMessage = function(fn) {
762
+ if (document.addEventListener) {
763
+ return window.addEventListener("message", fn);
764
+ } else {
765
+ return window.attachEvent("onmessage", fn);
766
+ }
767
+ };
768
+
769
+ XD_CHECK = "XD_CHECK";
770
+
771
+ handler = null;
772
+
773
+ sockets = {};
774
+
775
+ jsonEncode = true;
776
+
777
+ startPostMessage = function() {
778
+ return onMessage(function(e) {
779
+ var d, extra, id, sock;
780
+ d = e.data;
781
+ if (typeof d === "string") {
782
+ if (/^XDPING(_(V\d+))?$/.test(d) && RegExp.$2 !== COMPAT_VERSION) {
783
+ return warn("your master is not compatible with your slave, check your xdomain.js version");
784
+ } else if (/^xdomain-/.test(d)) {
785
+ d = d.split(",");
786
+ } else if (jsonEncode) {
787
+ try {
788
+ d = JSON.parse(d);
789
+ } catch (_error) {
790
+ return;
791
+ }
792
+ }
793
+ }
794
+ if (!(d instanceof Array)) {
795
+ return;
796
+ }
797
+ id = d.shift();
798
+ if (!/^xdomain-/.test(id)) {
799
+ return;
800
+ }
801
+ sock = sockets[id];
802
+ if (sock === null) {
803
+ return;
804
+ }
805
+ if (sock === undefined) {
806
+ if (!handler) {
807
+ return;
808
+ }
809
+ sock = createSocket(id, e.source);
810
+ handler(e.origin, sock);
811
+ }
812
+ extra = typeof d[1] === "string" ? ": '" + d[1] + "'" : "";
813
+ log("receive socket: " + id + ": '" + d[0] + "'" + extra);
814
+ sock.fire.apply(sock, d);
815
+ });
816
+ };
817
+
818
+ createSocket = function(id, frame) {
819
+ var check, checks, emit, pendingEmits, ready, sock;
820
+ ready = false;
821
+ sock = sockets[id] = xhook.EventEmitter(true);
822
+ sock.id = id;
823
+ sock.once('close', function() {
824
+ sock.destroy();
825
+ return sock.close();
826
+ });
827
+ pendingEmits = [];
828
+ sock.emit = function() {
829
+ var args, extra;
830
+ args = slice(arguments);
831
+ extra = typeof args[1] === "string" ? ": '" + args[1] + "'" : "";
832
+ log("send socket: " + id + ": " + args[0] + extra);
833
+ args.unshift(id);
834
+ if (ready) {
835
+ emit(args);
836
+ } else {
837
+ pendingEmits.push(args);
838
+ }
839
+ };
840
+ emit = function(args) {
841
+ if (jsonEncode) {
842
+ args = JSON.stringify(args);
843
+ }
844
+ frame.postMessage(args, "*");
845
+ };
846
+ sock.close = function() {
847
+ sock.emit('close');
848
+ log("close socket: " + id);
849
+ sockets[id] = null;
850
+ };
851
+ sock.once(XD_CHECK, function(obj) {
852
+ jsonEncode = typeof obj === "string";
853
+ ready = sock.ready = true;
854
+ sock.emit('ready');
855
+ log("ready socket: " + id + " (emit #" + pendingEmits.length + " pending)");
856
+ while (pendingEmits.length) {
857
+ emit(pendingEmits.shift());
858
+ }
859
+ });
860
+ checks = 0;
861
+ check = (function(_this) {
862
+ return function() {
863
+ frame.postMessage([id, XD_CHECK, {}], "*");
864
+ if (ready) {
865
+ return;
866
+ }
867
+ if (checks++ === xdomain.timeout / CHECK_INTERVAL) {
868
+ warn("Timeout waiting on iframe socket");
869
+ } else {
870
+ setTimeout(check, CHECK_INTERVAL);
871
+ }
872
+ };
873
+ })(this);
874
+ setTimeout(check);
875
+ log("new socket: " + id);
876
+ return sock;
877
+ };
878
+
879
+ connect = function(target) {
880
+ var s;
881
+ s = createSocket(guid(), target);
882
+ return s;
883
+ };
884
+
885
+ listen = function(h) {
886
+ handler = h;
887
+ };
888
+
889
+ 'use strict';
890
+
891
+ xhook = (this.exports || this).xhook;
892
+
893
+ xdomain = function(o) {
894
+ if (!o) {
895
+ return;
896
+ }
897
+ if (o.masters) {
898
+ addMasters(o.masters);
899
+ }
900
+ if (o.slaves) {
901
+ addSlaves(o.slaves);
902
+ }
903
+ };
904
+
905
+ xdomain.masters = addMasters;
906
+
907
+ xdomain.slaves = addSlaves;
908
+
909
+ xdomain.debug = false;
910
+
911
+ xdomain.timeout = 15e3;
912
+
913
+ CHECK_INTERVAL = 100;
914
+
915
+ document = window.document;
916
+
917
+ location = window.location;
918
+
919
+ currentOrigin = xdomain.origin = location.protocol + '//' + location.host;
920
+
921
+ guid = function() {
922
+ return 'xdomain-' + Math.round(Math.random() * Math.pow(2, 32)).toString(16);
923
+ };
924
+
925
+ slice = function(o, n) {
926
+ return Array.prototype.slice.call(o, n);
927
+ };
928
+
929
+ console = window.console || {};
930
+
931
+ logger = function(type) {
932
+ return function(str) {
933
+ str = "xdomain (" + currentOrigin + "): " + str;
934
+ if (type in xdomain) {
935
+ xdomain[type](str);
936
+ }
937
+ if (type === 'log' && !xdomain.debug) {
938
+ return;
939
+ }
940
+ if (type in console) {
941
+ console[type](str);
942
+ } else if (type === 'warn') {
943
+ alert(str);
944
+ }
945
+ };
946
+ };
947
+
948
+ log = logger('log');
949
+
950
+ warn = logger('warn');
951
+
952
+ _ref = ['postMessage', 'JSON'];
953
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
954
+ feature = _ref[_i];
955
+ if (!window[feature]) {
956
+ warn("requires '" + feature + "' and this browser does not support it");
957
+ return;
958
+ }
959
+ }
960
+
961
+ instOf = function(obj, global) {
962
+ if (!(global in window)) {
963
+ return false;
964
+ }
965
+ return obj instanceof window[global];
966
+ };
967
+
968
+ COMPAT_VERSION = "V1";
969
+
970
+ parseUrl = xdomain.parseUrl = function(url) {
971
+ if (/^((https?:)?\/\/[^\/\?]+)(\/.*)?/.test(url)) {
972
+ return {
973
+ origin: (RegExp.$2 ? '' : location.protocol) + RegExp.$1,
974
+ path: RegExp.$3
975
+ };
976
+ } else {
977
+ log("failed to parse absolute url: " + url);
978
+ return null;
979
+ }
980
+ };
981
+
982
+ toRegExp = function(obj) {
983
+ var str;
984
+ if (obj instanceof RegExp) {
985
+ return obj;
986
+ }
987
+ str = obj.toString().replace(/\W/g, function(str) {
988
+ return "\\" + str;
989
+ }).replace(/\\\*/g, ".*");
990
+ return new RegExp("^" + str + "$");
991
+ };
992
+
993
+ strip = function(src) {
994
+ var dst, k, v, _ref1;
995
+ dst = {};
996
+ for (k in src) {
997
+ if (k === "returnValue") {
998
+ continue;
999
+ }
1000
+ v = src[k];
1001
+ if ((_ref1 = typeof v) !== "function" && _ref1 !== "object") {
1002
+ dst[k] = v;
1003
+ }
1004
+ }
1005
+ return dst;
1006
+ };
1007
+
1008
+ (function() {
1009
+ var attrs, fn, k, prefix, script, _j, _k, _len1, _len2, _ref1, _ref2;
1010
+ attrs = {
1011
+ debug: function(value) {
1012
+ if (typeof value !== "string") {
1013
+ return;
1014
+ }
1015
+ return xdomain.debug = value !== "false";
1016
+ },
1017
+ slave: function(value) {
1018
+ var p, s;
1019
+ if (!value) {
1020
+ return;
1021
+ }
1022
+ p = parseUrl(value);
1023
+ if (!p) {
1024
+ return;
1025
+ }
1026
+ s = {};
1027
+ s[p.origin] = p.path;
1028
+ return addSlaves(s);
1029
+ },
1030
+ master: function(value) {
1031
+ var m, p;
1032
+ if (!value) {
1033
+ return;
1034
+ }
1035
+ if (value === "*") {
1036
+ p = {
1037
+ origin: "*",
1038
+ path: "*"
1039
+ };
1040
+ } else {
1041
+ p = parseUrl(value);
1042
+ }
1043
+ if (!p) {
1044
+ return;
1045
+ }
1046
+ m = {};
1047
+ m[p.origin] = p.path.replace(/^\//, "") ? p.path : "*";
1048
+ return addMasters(m);
1049
+ }
1050
+ };
1051
+ _ref1 = document.getElementsByTagName("script");
1052
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
1053
+ script = _ref1[_j];
1054
+ if (/xdomain/.test(script.src)) {
1055
+ _ref2 = ['', 'data-'];
1056
+ for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
1057
+ prefix = _ref2[_k];
1058
+ for (k in attrs) {
1059
+ fn = attrs[k];
1060
+ fn(script.getAttribute(prefix + k));
1061
+ }
1062
+ }
1063
+ }
1064
+ }
1065
+ })();
1066
+
1067
+ startPostMessage();
1068
+
1069
+ if (typeof this.define === "function" && this.define.amd) {
1070
+ define("xdomain", ["xhook"], function(xh) {
1071
+ xhook = xh;
1072
+ return xdomain;
1073
+ });
1074
+ } else {
1075
+ (this.exports || this).xdomain = xdomain;
1076
+ }
1077
+ }.call(this,window));