UNPKG

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