CodeCommitsIssuesPull requestsActionsInsightsSecurity
master

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS
SSH

Download ZIP

client.js

735lines · modecode

1!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Coupe=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
2var Client, Evented, Frame, Promise, cache, clientId, createClient, debug, frame,
3 __hasProp = {}.hasOwnProperty,
4 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
5
6Promise = _dereq_('./promise').Promise;
7
8Evented = _dereq_('./events').Evented;
9
10clientId = (Math.random() * 1000000) | 0;
11
12debug = _dereq_('debug')("bus:client(" + clientId + ")");
13
14Frame = (function(_super) {
15 __extends(Frame, _super);
16
17 function Frame(opts) {
18 this.opts = opts;
19 this.ready = new Promise;
20 if (!document.body) {
21 document.addEventListener('DOMContentLoaded', this.createIframe.bind(this));
22 } else {
23 this.createIframe();
24 }
25 }
26
27 Frame.prototype.createIframe = function() {
28 this.frame = document.createElement('iframe');
29 this.frame.style.display = 'none';
30 this.addListener(this.frame);
31 this.frame.src = "" + opts.host + "#" + clientId;
32 return document.body.appendChild(this.frame);
33 };
34
35 Frame.prototype.addListener = function(frame) {
36 return window.addEventListener('message', (function(_this) {
37 return function(_arg) {
38 var data, source;
39 data = _arg.data, source = _arg.source;
40 if (source !== frame.contentWindow) {
41 return;
42 }
43 switch (data.type) {
44 case 'bus:ready':
45 debug("Ready");
46 return _this.ready.resolve();
47 case 'bus:set':
48 debug("Received", data.key);
49 _this.trigger('set', data);
50 return _this.trigger("set:" + data.key, data);
51 }
52 };
53 })(this));
54 };
55
56 Frame.prototype.send = function(body) {
57 return this.ready.then((function(_this) {
58 return function() {
59 debug("Sending", body);
60 return _this.frame.contentWindow.postMessage(body, '*');
61 };
62 })(this));
63 };
64
65 Frame.prototype.client = function(siteId) {
66 return new Client(this, siteId);
67 };
68
69 return Frame;
70
71})(Evented);
72
73Client = (function(_super) {
74 __extends(Client, _super);
75
76 function Client(frame, opts) {
77 var _base;
78 this.frame = frame;
79 this.opts = opts;
80 (_base = this.opts).siteId || (_base.siteId = '');
81 this.frame.on('set', (function(_this) {
82 return function(data) {
83 var key, siteId, splitPos;
84 splitPos = data.key.indexOf(':');
85 siteId = data.key.substring(0, splitPos);
86 key = data.key.substring(splitPos + 1);
87 if (siteId === _this.opts.siteId) {
88 data.key = key;
89 _this.trigger('set', data);
90 return _this.trigger("set:" + key, data);
91 }
92 };
93 })(this));
94 }
95
96 Client.prototype.set = function(key, value) {
97 key = "" + this.opts.siteId + ":" + key;
98 debug("Setting", key, "to", value);
99 return this.frame.send({
100 type: 'bus:set',
101 key: key,
102 value: value
103 });
104 };
105
106 Client.prototype.clear = function(key) {
107 key = "" + this.opts.siteId + ":" + key;
108 debug("Clearing", key);
109 return this.frame.send({
110 type: 'bus:clear',
111 key: key
112 });
113 };
114
115 Client.prototype.flash = function(key, value) {
116 key = "" + this.opts.siteId + ":" + key;
117 debug("Flashing", key, "to", value);
118 return this.frame.send({
119 type: 'bus:flash',
120 key: key,
121 value: value
122 });
123 };
124
125 return Client;
126
127})(Evented);
128
129cache = {};
130
131frame = null;
132
133createClient = function(opts) {
134 if (typeof opts === 'string') {
135 opts = {
136 siteId: opts
137 };
138 }
139 if (!cache[siteId]) {
140 if (!frame) {
141 frame = new Frame(opts);
142 }
143 cache[siteId] = new Client(frame, opts);
144 }
145 return cache[siteId];
146};
147
148module.exports = {
149 Client: Client,
150 Frame: Frame,
151 createClient: createClient
152};
153
154
155},{"./events":2,"./promise":3,"debug":4}],2:[function(_dereq_,module,exports){
156var Evented,
157 __slice = [].slice;
158
159Evented = (function() {
160 function Evented() {}
161
162 Evented.prototype.on = function(event, handler, ctx, once) {
163 var _base;
164 if (once == null) {
165 once = false;
166 }
167 if (this.bindings == null) {
168 this.bindings = {};
169 }
170 if ((_base = this.bindings)[event] == null) {
171 _base[event] = [];
172 }
173 return this.bindings[event].push({
174 handler: handler,
175 ctx: ctx,
176 once: once
177 });
178 };
179
180 Evented.prototype.once = function(event, handler, ctx) {
181 return this.on(event, handler, ctx, true);
182 };
183
184 Evented.prototype.off = function(event, handler) {
185 var i, _ref, _results;
186 if (((_ref = this.bindings) != null ? _ref[event] : void 0) == null) {
187 return;
188 }
189 if (handler == null) {
190 return delete this.bindings[event];
191 } else {
192 i = 0;
193 _results = [];
194 while (i < this.bindings[event].length) {
195 if (this.bindings[event][i].handler === handler) {
196 _results.push(this.bindings[event].splice(i, 1));
197 } else {
198 _results.push(i++);
199 }
200 }
201 return _results;
202 }
203 };
204
205 Evented.prototype.trigger = function() {
206 var args, ctx, event, handler, i, once, _ref, _ref1, _results;
207 event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
208 if ((_ref = this.bindings) != null ? _ref[event] : void 0) {
209 i = 0;
210 _results = [];
211 while (i < this.bindings[event].length) {
212 _ref1 = this.bindings[event][i], handler = _ref1.handler, ctx = _ref1.ctx, once = _ref1.once;
213 handler.apply(ctx != null ? ctx : this, args);
214 if (once) {
215 _results.push(this.bindings[event].splice(i, 1));
216 } else {
217 _results.push(i++);
218 }
219 }
220 return _results;
221 }
222 };
223
224 return Evented;
225
226})();
227
228module.exports = {
229 Evented: Evented
230};
231
232
233},{}],3:[function(_dereq_,module,exports){
234var Promise;
235
236Promise = (function() {
237 function Promise() {
238 this.ready = false;
239 this.waiting = [];
240 }
241
242 Promise.prototype.then = function(fn) {
243 if (this.ready) {
244 return fn();
245 } else {
246 return this.waiting.push(fn);
247 }
248 };
249
250 Promise.prototype.resolve = function() {
251 var fn, _i, _len, _ref;
252 this.ready = true;
253 if (this.waiting != null) {
254 _ref = this.waiting;
255 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
256 fn = _ref[_i];
257 fn();
258 }
259 return this.waiting = [];
260 }
261 };
262
263 return Promise;
264
265})();
266
267module.exports = {
268 Promise: Promise
269};
270
271
272},{}],4:[function(_dereq_,module,exports){
273
274/**
275 * This is the web browser implementation of `debug()`.
276 *
277 * Expose `debug()` as the module.
278 */
279
280exports = module.exports = _dereq_('./debug');
281exports.log = log;
282exports.formatArgs = formatArgs;
283exports.save = save;
284exports.load = load;
285exports.useColors = useColors;
286
287/**
288 * Colors.
289 */
290
291exports.colors = [
292 'lightseagreen',
293 'forestgreen',
294 'goldenrod',
295 'dodgerblue',
296 'darkorchid',
297 'crimson'
298];
299
300/**
301 * Currently only WebKit-based Web Inspectors, Firefox >= v31,
302 * and the Firebug extension (any Firefox version) are known
303 * to support "%c" CSS customizations.
304 *
305 * TODO: add a `localStorage` variable to explicitly enable/disable colors
306 */
307
308function useColors() {
309 // is webkit? http://stackoverflow.com/a/16459606/376773
310 return ('WebkitAppearance' in document.documentElement.style) ||
311 // is firebug? http://stackoverflow.com/a/398120/376773
312 (window.console && (console.firebug || (console.exception && console.table))) ||
313 // is firefox >= v31?
314 // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
315 (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31);
316}
317
318/**
319 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
320 */
321
322exports.formatters.j = function(v) {
323 return JSON.stringify(v);
324};
325
326
327/**
328 * Colorize log arguments if enabled.
329 *
330 * @api public
331 */
332
333function formatArgs() {
334 var args = arguments;
335 var useColors = this.useColors;
336
337 args[0] = (useColors ? '%c' : '')
338 + this.namespace
339 + (useColors ? ' %c' : ' ')
340 + args[0]
341 + (useColors ? '%c ' : ' ')
342 + '+' + exports.humanize(this.diff);
343
344 if (!useColors) return args;
345
346 var c = 'color: ' + this.color;
347 args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));
348
349 // the final "%c" is somewhat tricky, because there could be other
350 // arguments passed either before or after the %c, so we need to
351 // figure out the correct index to insert the CSS into
352 var index = 0;
353 var lastC = 0;
354 args[0].replace(/%[a-z%]/g, function(match) {
355 if ('%%' === match) return;
356 index++;
357 if ('%c' === match) {
358 // we only are interested in the *last* %c
359 // (the user may have provided their own)
360 lastC = index;
361 }
362 });
363
364 args.splice(lastC, 0, c);
365 return args;
366}
367
368/**
369 * Invokes `console.log()` when available.
370 * No-op when `console.log` is not a "function".
371 *
372 * @api public
373 */
374
375function log() {
376 // This hackery is required for IE8,
377 // where the `console.log` function doesn't have 'apply'
378 return 'object' == typeof console
379 && 'function' == typeof console.log
380 && Function.prototype.apply.call(console.log, console, arguments);
381}
382
383/**
384 * Save `namespaces`.
385 *
386 * @param {String} namespaces
387 * @api private
388 */
389
390function save(namespaces) {
391 try {
392 if (null == namespaces) {
393 localStorage.removeItem('debug');
394 } else {
395 localStorage.debug = namespaces;
396 }
397 } catch(e) {}
398}
399
400/**
401 * Load `namespaces`.
402 *
403 * @return {String} returns the previously persisted debug modes
404 * @api private
405 */
406
407function load() {
408 var r;
409 try {
410 r = localStorage.debug;
411 } catch(e) {}
412 return r;
413}
414
415/**
416 * Enable namespaces listed in `localStorage.debug` initially.
417 */
418
419exports.enable(load());
420
421},{"./debug":5}],5:[function(_dereq_,module,exports){
422
423/**
424 * This is the common logic for both the Node.js and web browser
425 * implementations of `debug()`.
426 *
427 * Expose `debug()` as the module.
428 */
429
430exports = module.exports = debug;
431exports.coerce = coerce;
432exports.disable = disable;
433exports.enable = enable;
434exports.enabled = enabled;
435exports.humanize = _dereq_('ms');
436
437/**
438 * The currently active debug mode names, and names to skip.
439 */
440
441exports.names = [];
442exports.skips = [];
443
444/**
445 * Map of special "%n" handling functions, for the debug "format" argument.
446 *
447 * Valid key names are a single, lowercased letter, i.e. "n".
448 */
449
450exports.formatters = {};
451
452/**
453 * Previously assigned color.
454 */
455
456var prevColor = 0;
457
458/**
459 * Previous log timestamp.
460 */
461
462var prevTime;
463
464/**
465 * Select a color.
466 *
467 * @return {Number}
468 * @api private
469 */
470
471function selectColor() {
472 return exports.colors[prevColor++ % exports.colors.length];
473}
474
475/**
476 * Create a debugger with the given `namespace`.
477 *
478 * @param {String} namespace
479 * @return {Function}
480 * @api public
481 */
482
483function debug(namespace) {
484
485 // define the `disabled` version
486 function disabled() {
487 }
488 disabled.enabled = false;
489
490 // define the `enabled` version
491 function enabled() {
492
493 var self = enabled;
494
495 // set `diff` timestamp
496 var curr = +new Date();
497 var ms = curr - (prevTime || curr);
498 self.diff = ms;
499 self.prev = prevTime;
500 self.curr = curr;
501 prevTime = curr;
502
503 // add the `color` if not set
504 if (null == self.useColors) self.useColors = exports.useColors();
505 if (null == self.color && self.useColors) self.color = selectColor();
506
507 var args = Array.prototype.slice.call(arguments);
508
509 args[0] = exports.coerce(args[0]);
510
511 if ('string' !== typeof args[0]) {
512 // anything else let's inspect with %o
513 args = ['%o'].concat(args);
514 }
515
516 // apply any `formatters` transformations
517 var index = 0;
518 args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {
519 // if we encounter an escaped % then don't increase the array index
520 if (match === '%%') return match;
521 index++;
522 var formatter = exports.formatters[format];
523 if ('function' === typeof formatter) {
524 var val = args[index];
525 match = formatter.call(self, val);
526
527 // now we need to remove `args[index]` since it's inlined in the `format`
528 args.splice(index, 1);
529 index--;
530 }
531 return match;
532 });
533
534 if ('function' === typeof exports.formatArgs) {
535 args = exports.formatArgs.apply(self, args);
536 }
537 var logFn = enabled.log || exports.log || console.log.bind(console);
538 logFn.apply(self, args);
539 }
540 enabled.enabled = true;
541
542 var fn = exports.enabled(namespace) ? enabled : disabled;
543
544 fn.namespace = namespace;
545
546 return fn;
547}
548
549/**
550 * Enables a debug mode by namespaces. This can include modes
551 * separated by a colon and wildcards.
552 *
553 * @param {String} namespaces
554 * @api public
555 */
556
557function enable(namespaces) {
558 exports.save(namespaces);
559
560 var split = (namespaces || '').split(/[\s,]+/);
561 var len = split.length;
562
563 for (var i = 0; i < len; i++) {
564 if (!split[i]) continue; // ignore empty strings
565 namespaces = split[i].replace(/\*/g, '.*?');
566 if (namespaces[0] === '-') {
567 exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
568 } else {
569 exports.names.push(new RegExp('^' + namespaces + '$'));
570 }
571 }
572}
573
574/**
575 * Disable debug output.
576 *
577 * @api public
578 */
579
580function disable() {
581 exports.enable('');
582}
583
584/**
585 * Returns true if the given mode name is enabled, false otherwise.
586 *
587 * @param {String} name
588 * @return {Boolean}
589 * @api public
590 */
591
592function enabled(name) {
593 var i, len;
594 for (i = 0, len = exports.skips.length; i < len; i++) {
595 if (exports.skips[i].test(name)) {
596 return false;
597 }
598 }
599 for (i = 0, len = exports.names.length; i < len; i++) {
600 if (exports.names[i].test(name)) {
601 return true;
602 }
603 }
604 return false;
605}
606
607/**
608 * Coerce `val`.
609 *
610 * @param {Mixed} val
611 * @return {Mixed}
612 * @api private
613 */
614
615function coerce(val) {
616 if (val instanceof Error) return val.stack || val.message;
617 return val;
618}
619
620},{"ms":6}],6:[function(_dereq_,module,exports){
621/**
622 * Helpers.
623 */
624
625var s = 1000;
626var m = s * 60;
627var h = m * 60;
628var d = h * 24;
629var y = d * 365.25;
630
631/**
632 * Parse or format the given `val`.
633 *
634 * Options:
635 *
636 * - `long` verbose formatting [false]
637 *
638 * @param {String|Number} val
639 * @param {Object} options
640 * @return {String|Number}
641 * @api public
642 */
643
644module.exports = function(val, options){
645 options = options || {};
646 if ('string' == typeof val) return parse(val);
647 return options.long
648 ? long(val)
649 : short(val);
650};
651
652/**
653 * Parse the given `str` and return milliseconds.
654 *
655 * @param {String} str
656 * @return {Number}
657 * @api private
658 */
659
660function parse(str) {
661 var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);
662 if (!match) return;
663 var n = parseFloat(match[1]);
664 var type = (match[2] || 'ms').toLowerCase();
665 switch (type) {
666 case 'years':
667 case 'year':
668 case 'y':
669 return n * y;
670 case 'days':
671 case 'day':
672 case 'd':
673 return n * d;
674 case 'hours':
675 case 'hour':
676 case 'h':
677 return n * h;
678 case 'minutes':
679 case 'minute':
680 case 'm':
681 return n * m;
682 case 'seconds':
683 case 'second':
684 case 's':
685 return n * s;
686 case 'ms':
687 return n;
688 }
689}
690
691/**
692 * Short format for `ms`.
693 *
694 * @param {Number} ms
695 * @return {String}
696 * @api private
697 */
698
699function short(ms) {
700 if (ms >= d) return Math.round(ms / d) + 'd';
701 if (ms >= h) return Math.round(ms / h) + 'h';
702 if (ms >= m) return Math.round(ms / m) + 'm';
703 if (ms >= s) return Math.round(ms / s) + 's';
704 return ms + 'ms';
705}
706
707/**
708 * Long format for `ms`.
709 *
710 * @param {Number} ms
711 * @return {String}
712 * @api private
713 */
714
715function long(ms) {
716 return plural(ms, d, 'day')
717 || plural(ms, h, 'hour')
718 || plural(ms, m, 'minute')
719 || plural(ms, s, 'second')
720 || ms + ' ms';
721}
722
723/**
724 * Pluralization helper.
725 */
726
727function plural(ms, n, name) {
728 if (ms < n) return;
729 if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
730 return Math.ceil(ms / n) + ' ' + name + 's';
731}
732
733},{}]},{},[1])
734(1)
735});