UNPKG

atom-nuclide

Version:

A unified developer experience for web and mobile development, built as a suite of features on top of Atom to provide hackability and the support of an active community.

151 lines (112 loc) 4.13 kB
// This function will be injected into the target process. module.exports = function injection(require, debug, options) { var consoleIsWrapped = false, nextMessageId = 0, messagesCache = {}; var makeMirror = debug.get('MakeMirror'); function ConsoleMessage(fn, wrapper, args) { var location = getCallerFuncLocation(wrapper); this.id = nextMessageId++; this.source = 'console-api'; this.level = getLevel(fn); this.type = this.level == 'log' ? fn : undefined; this.line = location.line; this.column = location.column; this.url = location.url; this.repeatCount = 0; this.timestamp = Date.now(); this.parameters = args; } function getLevel(fn) { return ['warning', 'error', 'debug', 'log'].indexOf(fn) > -1 ? fn : 'log'; } function getCallerFuncLocation(wrapper) { var oldPrepareStackTrace = Error.prepareStackTrace, error = new Error(), callerFrame; Error.prepareStackTrace = function(error, stack) { return stack; }; Error.captureStackTrace(error, wrapper); callerFrame = error.stack[0]; Error.prepareStackTrace = oldPrepareStackTrace; var fileName = callerFrame.getFileName(); fileName = debug.convert.v8NameToInspectorUrl(fileName); var url = fileName || callerFrame.getEvalOrigin(); return { url: url, line: callerFrame.getLineNumber(), column: callerFrame.getColumnNumber() }; } function clearMessages() { messagesCache = {}; } function wrapConsole() { if (consoleIsWrapped) return; var specials = ['assert']; Object.keys(console).forEach(function(fn) { if (/^_/.test(fn)) return; if (specials.indexOf(fn) > -1) return; console['_'+fn] = console[fn]; console[fn] = wrapFunction(fn, console[fn]); }); console.assert = wrapAssertFunction('assert', console.assert); consoleIsWrapped = true; } function unwrapConsole() { if (!consoleIsWrapped) return; clearMessages(); Object.keys(console).forEach(function(fn) { if (!/^_/.test(fn)) { console[fn] = console['_' + fn]; delete console['_' + fn]; } }); consoleIsWrapped = false; } function wrapFunction(fn, func) { return function WRAPPED_BY_NODE_INSPECTOR() { var args = []; Array.prototype.push.apply(args, arguments); sendMessageToInspector(fn, WRAPPED_BY_NODE_INSPECTOR, args); return func.apply(console, args); }; } function wrapAssertFunction(fn, func) { return function wrapper(condition) { var args = []; Array.prototype.push.apply(args, arguments); if (!condition) sendMessageToInspector(fn, wrapper, args); return func.apply(console, args); }; } function sendMessageToInspector(fn, wrapper, args) { var message = new ConsoleMessage(fn, wrapper, args); var cache = messagesCache[message.id] = {}; message.parameters = message.parameters.map(function(arg) { return debug.serializeAndCacheMirror(cache, makeMirror(arg)); }); debug.command('Console.messageAdded', { message: message }); } debug.register('Console.messageAdded', debug.commandToEvent); debug.register('Console.messagesCleared', debug.commandToEvent); debug.register('Console.messageRepeatCountUpdated', debug.commandToEvent); debug.register('Console.clearMessages', function(request, response) { clearMessages(); debug.command('Console.messagesCleared'); }); debug.register('Console._lookupConsoleId', function(request, response) { var messageId = request.arguments.messageId; var objectId = request.arguments.objectId; var cache = messagesCache[messageId]; if (!cache) return response.failed('Console message #' + messageId + '# not found'); var mirror = cache[objectId]; if (!mirror) return response.failed('Object #' + objectId + '# not found'); //serialize body and append serialized refs to response response.body = debug.serializeAndCacheMirror(cache, mirror, response); }); debug.on('close', unwrapConsole); wrapConsole(); };