1 /* eslint-env browser */
4 * This is the web browser implementation of `debug()`.
8 exports.formatArgs = formatArgs;
11 exports.useColors = useColors;
12 exports.storage = localstorage();
98 * Currently only WebKit-based Web Inspectors, Firefox >= v31,
99 * and the Firebug extension (any Firefox version) are known
100 * to support "%c" CSS customizations.
102 * TODO: add a `localStorage` variable to explicitly enable/disable colors
105 // eslint-disable-next-line complexity
106 function useColors() {
107 // NB: In an Electron preload script, document will be defined but not fully
108 // initialized. Since we know we're in Chrome, we'll just detect this case
110 if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
114 // Internet Explorer and Edge do not support colors.
115 if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
119 // Is webkit? http://stackoverflow.com/a/16459606/376773
120 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
121 return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
122 // Is firebug? http://stackoverflow.com/a/398120/376773
123 (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
124 // Is firefox >= v31?
125 // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
126 (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
127 // Double check webkit in userAgent just in case we are in a worker
128 (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
132 * Colorize log arguments if enabled.
137 function formatArgs(args) {
138 args[0] = (this.useColors ? '%c' : '') +
140 (this.useColors ? ' %c' : ' ') +
142 (this.useColors ? '%c ' : ' ') +
143 '+' + module.exports.humanize(this.diff);
145 if (!this.useColors) {
149 const c = 'color: ' + this.color;
150 args.splice(1, 0, c, 'color: inherit');
152 // The final "%c" is somewhat tricky, because there could be other
153 // arguments passed either before or after the %c, so we need to
154 // figure out the correct index to insert the CSS into
157 args[0].replace(/%[a-zA-Z%]/g, match => {
158 if (match === '%%') {
162 if (match === '%c') {
163 // We only are interested in the *last* %c
164 // (the user may have provided their own)
169 args.splice(lastC, 0, c);
173 * Invokes `console.log()` when available.
174 * No-op when `console.log` is not a "function".
178 function log(...args) {
179 // This hackery is required for IE8/9, where
180 // the `console.log` function doesn't have 'apply'
181 return typeof console === 'object' &&
183 console.log(...args);
189 * @param {String} namespaces
192 function save(namespaces) {
195 exports.storage.setItem('debug', namespaces);
197 exports.storage.removeItem('debug');
201 // XXX (@Qix-) should we be logging these?
208 * @return {String} returns the previously persisted debug modes
214 r = exports.storage.getItem('debug');
217 // XXX (@Qix-) should we be logging these?
220 // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
221 if (!r && typeof process !== 'undefined' && 'env' in process) {
222 r = process.env.DEBUG;
229 * Localstorage attempts to return the localstorage.
231 * This is necessary because safari throws
232 * when a user disables cookies/localstorage
233 * and you attempt to access it.
235 * @return {LocalStorage}
239 function localstorage() {
241 // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
242 // The Browser also has localStorage in the global context.
246 // XXX (@Qix-) should we be logging these?
250 module.exports = require('./common')(exports);
252 const {formatters} = module.exports;
255 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
258 formatters.j = function (v) {
260 return JSON.stringify(v);
262 return '[UnexpectedJSONParseError]: ' + error.message;