• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  // Internet Explorer and Edge do not support colors.
53  if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
54    return false;
55  }
56
57  // is webkit? http://stackoverflow.com/a/16459606/376773
58  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
59  return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
60    // is firebug? http://stackoverflow.com/a/398120/376773
61    (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
62    // is firefox >= v31?
63    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
64    (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
65    // double check webkit in userAgent just in case we are in a worker
66    (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
67}
68
69/**
70 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
71 */
72
73exports.formatters.j = function(v) {
74  try {
75    return JSON.stringify(v);
76  } catch (err) {
77    return '[UnexpectedJSONParseError]: ' + err.message;
78  }
79};
80
81
82/**
83 * Colorize log arguments if enabled.
84 *
85 * @api public
86 */
87
88function formatArgs(args) {
89  var useColors = this.useColors;
90
91  args[0] = (useColors ? '%c' : '')
92    + this.namespace
93    + (useColors ? ' %c' : ' ')
94    + args[0]
95    + (useColors ? '%c ' : ' ')
96    + '+' + exports.humanize(this.diff);
97
98  if (!useColors) return;
99
100  var c = 'color: ' + this.color;
101  args.splice(1, 0, c, 'color: inherit')
102
103  // the final "%c" is somewhat tricky, because there could be other
104  // arguments passed either before or after the %c, so we need to
105  // figure out the correct index to insert the CSS into
106  var index = 0;
107  var lastC = 0;
108  args[0].replace(/%[a-zA-Z%]/g, function(match) {
109    if ('%%' === match) return;
110    index++;
111    if ('%c' === match) {
112      // we only are interested in the *last* %c
113      // (the user may have provided their own)
114      lastC = index;
115    }
116  });
117
118  args.splice(lastC, 0, c);
119}
120
121/**
122 * Invokes `console.log()` when available.
123 * No-op when `console.log` is not a "function".
124 *
125 * @api public
126 */
127
128function log() {
129  // this hackery is required for IE8/9, where
130  // the `console.log` function doesn't have 'apply'
131  return 'object' === typeof console
132    && console.log
133    && Function.prototype.apply.call(console.log, console, arguments);
134}
135
136/**
137 * Save `namespaces`.
138 *
139 * @param {String} namespaces
140 * @api private
141 */
142
143function save(namespaces) {
144  try {
145    if (null == namespaces) {
146      exports.storage.removeItem('debug');
147    } else {
148      exports.storage.debug = namespaces;
149    }
150  } catch(e) {}
151}
152
153/**
154 * Load `namespaces`.
155 *
156 * @return {String} returns the previously persisted debug modes
157 * @api private
158 */
159
160function load() {
161  var r;
162  try {
163    r = exports.storage.debug;
164  } catch(e) {}
165
166  // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
167  if (!r && typeof process !== 'undefined' && 'env' in process) {
168    r = process.env.DEBUG;
169  }
170
171  return r;
172}
173
174/**
175 * Enable namespaces listed in `localStorage.debug` initially.
176 */
177
178exports.enable(load());
179
180/**
181 * Localstorage attempts to return the localstorage.
182 *
183 * This is necessary because safari throws
184 * when a user disables cookies/localstorage
185 * and you attempt to access it.
186 *
187 * @return {LocalStorage}
188 * @api private
189 */
190
191function localstorage() {
192  try {
193    return window.localStorage;
194  } catch (e) {}
195}
196