browser.js 5.6 KB

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