second
[josuexyz/.git] / node_modules / debug / src / browser.js
1 /**
2  * This is the web browser implementation of `debug()`.
3  *
4  * Expose `debug()` as the module.
5  */
6
7 exports = module.exports = require('./debug');
8 exports.log = log;
9 exports.formatArgs = formatArgs;
10 exports.save = save;
11 exports.load = load;
12 exports.useColors = useColors;
13 exports.storage = 'undefined' != typeof chrome
14                && 'undefined' != typeof chrome.storage
15                   ? chrome.storage.local
16                   : localstorage();
17
18 /**
19  * Colors.
20  */
21
22 exports.colors = [
23   'lightseagreen',
24   'forestgreen',
25   'goldenrod',
26   'dodgerblue',
27   'darkorchid',
28   'crimson'
29 ];
30
31 /**
32  * Currently only WebKit-based Web Inspectors, Firefox >= v31,
33  * and the Firebug extension (any Firefox version) are known
34  * to support "%c" CSS customizations.
35  *
36  * TODO: add a `localStorage` variable to explicitly enable/disable colors
37  */
38
39 function useColors() {
40   // NB: In an Electron preload script, document will be defined but not fully
41   // initialized. Since we know we're in Chrome, we'll just detect this case
42   // explicitly
43   if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') {
44     return true;
45   }
46
47   // is webkit? http://stackoverflow.com/a/16459606/376773
48   // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
49   return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
50     // is firebug? http://stackoverflow.com/a/398120/376773
51     (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
52     // is firefox >= v31?
53     // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
54     (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
55     // double check webkit in userAgent just in case we are in a worker
56     (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
57 }
58
59 /**
60  * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
61  */
62
63 exports.formatters.j = function(v) {
64   try {
65     return JSON.stringify(v);
66   } catch (err) {
67     return '[UnexpectedJSONParseError]: ' + err.message;
68   }
69 };
70
71
72 /**
73  * Colorize log arguments if enabled.
74  *
75  * @api public
76  */
77
78 function formatArgs(args) {
79   var useColors = this.useColors;
80
81   args[0] = (useColors ? '%c' : '')
82     + this.namespace
83     + (useColors ? ' %c' : ' ')
84     + args[0]
85     + (useColors ? '%c ' : ' ')
86     + '+' + exports.humanize(this.diff);
87
88   if (!useColors) return;
89
90   var c = 'color: ' + this.color;
91   args.splice(1, 0, c, 'color: inherit')
92
93   // the final "%c" is somewhat tricky, because there could be other
94   // arguments passed either before or after the %c, so we need to
95   // figure out the correct index to insert the CSS into
96   var index = 0;
97   var lastC = 0;
98   args[0].replace(/%[a-zA-Z%]/g, function(match) {
99     if ('%%' === match) return;
100     index++;
101     if ('%c' === match) {
102       // we only are interested in the *last* %c
103       // (the user may have provided their own)
104       lastC = index;
105     }
106   });
107
108   args.splice(lastC, 0, c);
109 }
110
111 /**
112  * Invokes `console.log()` when available.
113  * No-op when `console.log` is not a "function".
114  *
115  * @api public
116  */
117
118 function log() {
119   // this hackery is required for IE8/9, where
120   // the `console.log` function doesn't have 'apply'
121   return 'object' === typeof console
122     && console.log
123     && Function.prototype.apply.call(console.log, console, arguments);
124 }
125
126 /**
127  * Save `namespaces`.
128  *
129  * @param {String} namespaces
130  * @api private
131  */
132
133 function save(namespaces) {
134   try {
135     if (null == namespaces) {
136       exports.storage.removeItem('debug');
137     } else {
138       exports.storage.debug = namespaces;
139     }
140   } catch(e) {}
141 }
142
143 /**
144  * Load `namespaces`.
145  *
146  * @return {String} returns the previously persisted debug modes
147  * @api private
148  */
149
150 function load() {
151   var r;
152   try {
153     r = exports.storage.debug;
154   } catch(e) {}
155
156   // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
157   if (!r && typeof process !== 'undefined' && 'env' in process) {
158     r = process.env.DEBUG;
159   }
160
161   return r;
162 }
163
164 /**
165  * Enable namespaces listed in `localStorage.debug` initially.
166  */
167
168 exports.enable(load());
169
170 /**
171  * Localstorage attempts to return the localstorage.
172  *
173  * This is necessary because safari throws
174  * when a user disables cookies/localstorage
175  * and you attempt to access it.
176  *
177  * @return {LocalStorage}
178  * @api private
179  */
180
181 function localstorage() {
182   try {
183     return window.localStorage;
184   } catch (e) {}
185 }