forward child stdio to the inspector console

This commit is contained in:
Danny Coates 2010-07-20 18:59:26 -06:00
Родитель 859fb0ccb1
Коммит 43941de400
6 изменённых файлов: 747 добавлений и 717 удалений

Просмотреть файл

@ -1,68 +1,68 @@
#!/usr/bin/env node
var net = require('net'),
http = require('http'),
sys = require('sys'),
path = require('path'),
ws = require('../lib/ws'),
paperboy = require('../lib/paperboy'),
spawn = require('child_process').spawn;
http = require('http'),
sys = require('sys'),
path = require('path'),
ws = require('../lib/ws'),
paperboy = require('../lib/paperboy'),
spawn = require('child_process').spawn;
//////////////////////////////////////////////////////////
// Node side
// Node side
var seq = 0;
var buffer = '';
var current = false;
function request(data) {
var message = 'Content-Length: ' + data.length + '\r\n\r\n' + data;
debug.write(message);
var message = 'Content-Length: ' + data.length + '\r\n\r\n' + data;
debug.write(message);
}
function makeMessage() {
return {
headersDone: false,
headers: null,
contentLength: 0,
body: ''
};
return {
headersDone: false,
headers: null,
contentLength: 0,
body: ''
};
}
function parseBody() {
if (buffer.length >= current.contentLength) {
current.body = buffer.slice(0, current.contentLength);
buffer = buffer.slice(current.contentLength);
if (current.body.length > 0 && wsServer) {
wsServer.broadcast(current.body);
}
current = false;
parse();
}
if (buffer.length >= current.contentLength) {
current.body = buffer.slice(0, current.contentLength);
buffer = buffer.slice(current.contentLength);
if (current.body.length > 0 && wsServer) {
wsServer.broadcast(current.body);
}
current = false;
parse();
}
}
function parse() {
if (current && current.headersDone) {
parseBody();
return;
}
if (!current) current = makeMessage();
var offset = buffer.indexOf('\r\n\r\n');
if (offset > 0) {
current.headersDone = true;
current.headers = buffer.substr(0, offset+4);
var m = /Content-Length: (\d+)/.exec(current.headers);
if (m[1]) {
current.contentLength = parseInt(m[1], 10);
}
else {
sys.debug('no Content-Length');
}
buffer = buffer.slice(offset+4);
parse();
}
if (current && current.headersDone) {
parseBody();
return;
}
if (!current) current = makeMessage();
var offset = buffer.indexOf('\r\n\r\n');
if (offset > 0) {
current.headersDone = true;
current.headers = buffer.substr(0, offset+4);
var m = /Content-Length: (\d+)/.exec(current.headers);
if (m[1]) {
current.contentLength = parseInt(m[1], 10);
}
else {
sys.debug('no Content-Length');
}
buffer = buffer.slice(offset+4);
parse();
}
}
function attachDebugger() {
@ -70,12 +70,12 @@ function attachDebugger() {
conn.setEncoding('ascii');
conn.on('data', function(data) {
buffer += data;
parse();
buffer += data;
parse();
});
conn.on('end', function() {
process.exit();
process.exit();
});
return conn;
}
@ -83,7 +83,7 @@ function attachDebugger() {
var debug = null;
///////////////////////////////////////////////////////////
// Browser side
// Browser side
var WEBROOT = path.join(path.dirname(__filename), '../front-end');
@ -115,7 +115,7 @@ wsServer.on('connection', function(conn) {
});
////////////////////////////////////////////////////////
// Startup
// Startup
var fileToDebug = null;
var port = 8080;
@ -147,7 +147,7 @@ process.argv.forEach(function(arg) {
}
else if (parts[0] === '--help') {
console.log('Usage: node [node_options] debug-agent.js [options]');
console.log('Options:');
console.log('Options:');
console.log('--start=[file]\t\tstarts [file] in a child process with node_g --debug');
console.log('--start-brk=[file]\tsame as start with --debug-brk');
console.log('--agent-port=[port]\tport to host the inspector (default 8080)');
@ -164,12 +164,26 @@ if (fileToDebug != null) {
flag = flag + debugPort;
var debugProcess = spawn('node_g', [flag, fileToDebug]);
debugProcess.stdout.setEncoding('utf8');
debugProcess.stdout.on('data', function(data) {
sys.print(data)
sys.print(data);
wsServer.broadcast(JSON.stringify({
seq: 0,
type: 'event',
event: 'stdout',
body: data
}));
});
debugProcess.stderr.setEncoding('utf8');
debugProcess.stderr.on('data', function(data) {
sys.debug(data);
console.error(data);
wsServer.broadcast(JSON.stringify({
seq: 0,
type: 'event',
event: 'stderr',
body: data
}));
});
debugProcess.on('exit', function(code) {

Просмотреть файл

@ -5,13 +5,13 @@
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
@ -32,360 +32,360 @@ if (!window.InspectorBackend) {
WebInspector.InspectorBackendStub = function()
{
this._attachedWindowHeight = 0;
this._timelineEnabled = false;
this._attachedWindowHeight = 0;
this._timelineEnabled = false;
}
WebInspector.InspectorBackendStub.prototype = {
wrapCallback: function(func)
{
return func;
},
wrapCallback: function(func)
{
return func;
},
closeWindow: function()
{
this._windowVisible = false;
},
closeWindow: function()
{
this._windowVisible = false;
},
attach: function()
{
},
attach: function()
{
},
detach: function()
{
},
detach: function()
{
},
storeLastActivePanel: function(panel)
{
},
storeLastActivePanel: function(panel)
{
},
clearConsoleMessages: function()
{
WebInspector.console.clearMessages();
},
clearConsoleMessages: function()
{
WebInspector.console.clearMessages();
},
getOuterHTML: function()
{
},
getOuterHTML: function()
{
},
setOuterHTML: function()
{
},
setOuterHTML: function()
{
},
addInspectedNode: function()
{
},
addInspectedNode: function()
{
},
search: function(sourceRow, query)
{
},
search: function(sourceRow, query)
{
},
moveByUnrestricted: function(x, y)
{
},
moveByUnrestricted: function(x, y)
{
},
getResourceContent: function(callId, identifier)
{
WebInspector.didGetResourceContent(callId, "");
},
getResourceContent: function(callId, identifier)
{
WebInspector.didGetResourceContent(callId, "");
},
highlightDOMNode: function(node)
{
},
highlightDOMNode: function(node)
{
},
hideDOMNodeHighlight: function()
{
},
hideDOMNodeHighlight: function()
{
},
inspectedWindow: function()
{
return window;
},
inspectedWindow: function()
{
return window;
},
loaded: function()
{
},
loaded: function()
{
},
localizedStringsURL: function()
{
return undefined;
},
localizedStringsURL: function()
{
return undefined;
},
windowUnloading: function()
{
return false;
},
windowUnloading: function()
{
return false;
},
hiddenPanels: function()
{
return "";
},
hiddenPanels: function()
{
return "";
},
enableResourceTracking: function()
{
WebInspector.resourceTrackingWasEnabled();
},
enableResourceTracking: function()
{
WebInspector.resourceTrackingWasEnabled();
},
disableResourceTracking: function()
{
WebInspector.resourceTrackingWasDisabled();
},
disableResourceTracking: function()
{
WebInspector.resourceTrackingWasDisabled();
},
enableSearchingForNode: function()
{
WebInspector.searchingForNodeWasEnabled();
},
enableSearchingForNode: function()
{
WebInspector.searchingForNodeWasEnabled();
},
disableSearchingForNode: function()
{
WebInspector.searchingForNodeWasDisabled();
},
disableSearchingForNode: function()
{
WebInspector.searchingForNodeWasDisabled();
},
enableMonitoringXHR: function()
{
WebInspector.monitoringXHRWasEnabled();
},
enableMonitoringXHR: function()
{
WebInspector.monitoringXHRWasEnabled();
},
disableMonitoringXHR: function()
{
WebInspector.monitoringXHRWasDisabled();
},
disableMonitoringXHR: function()
{
WebInspector.monitoringXHRWasDisabled();
},
reloadPage: function()
{
},
reloadPage: function()
{
},
enableDebugger: function()
{
WebInspector.InspectorController.initialize();
},
enableDebugger: function()
{
WebInspector.InspectorController.initialize();
},
disableDebugger: function()
{
WebInspector.InspectorController.close();
},
disableDebugger: function()
{
WebInspector.InspectorController.close();
},
setBreakpoint: function(callId, sourceID, line, enabled, condition)
{
WebInspector.InspectorController.setBreakpoint(callId, sourceID, line, enabled, condition);
WebInspector.didSetBreakpoint(callId, true, line);
},
setBreakpoint: function(callId, sourceID, line, enabled, condition)
{
WebInspector.InspectorController.setBreakpoint(callId, sourceID, line, enabled, condition);
WebInspector.didSetBreakpoint(callId, true, line);
},
removeBreakpoint: function(sourceID, line)
{
WebInspector.InspectorController.clearBreakpoint(sourceID, line);
},
removeBreakpoint: function(sourceID, line)
{
WebInspector.InspectorController.clearBreakpoint(sourceID, line);
},
activateBreakpoints: function()
{
var bps = WebInspector.breakpointManager._breakpoints;
Object.keys(bps).forEach(
function(key) {
bps[key].enabled = true;
});
this._breakpointsActivated = true;
},
activateBreakpoints: function()
{
var bps = WebInspector.breakpointManager._breakpoints;
Object.keys(bps).forEach(
function(key) {
bps[key].enabled = true;
});
this._breakpointsActivated = true;
},
deactivateBreakpoints: function()
{
var bps = WebInspector.breakpointManager._breakpoints;
Object.keys(bps).forEach(
function(key) {
bps[key].enabled = false;
});
this._breakpointsActivated = false;
},
deactivateBreakpoints: function()
{
var bps = WebInspector.breakpointManager._breakpoints;
Object.keys(bps).forEach(
function(key) {
bps[key].enabled = false;
});
this._breakpointsActivated = false;
},
pause: function()
{
WebInspector.InspectorController.pause();
},
pause: function()
{
WebInspector.InspectorController.pause();
},
setPauseOnExceptionsState: function(value)
{
WebInspector.updatePauseOnExceptionsState(value);
},
setPauseOnExceptionsState: function(value)
{
WebInspector.updatePauseOnExceptionsState(value);
},
editScriptSource: function()
{
WebInspector.didEditScriptSource(callId, false);
},
editScriptSource: function()
{
WebInspector.didEditScriptSource(callId, false);
},
getScriptSource: function(callId, sourceID)
{
WebInspector.didGetScriptSource(callId, null);
},
getScriptSource: function(callId, sourceID)
{
WebInspector.didGetScriptSource(callId, null);
},
resume: function()
{
WebInspector.InspectorController.resume();
},
resume: function()
{
WebInspector.InspectorController.resume();
},
enableProfiler: function()
{
WebInspector.profilerWasEnabled();
},
enableProfiler: function()
{
WebInspector.profilerWasEnabled();
},
disableProfiler: function()
{
WebInspector.profilerWasDisabled();
},
disableProfiler: function()
{
WebInspector.profilerWasDisabled();
},
startProfiling: function()
{
},
startProfiling: function()
{
},
stopProfiling: function()
{
},
stopProfiling: function()
{
},
getProfileHeaders: function(callId)
{
WebInspector.didGetProfileHeaders(callId, []);
},
getProfileHeaders: function(callId)
{
WebInspector.didGetProfileHeaders(callId, []);
},
getProfile: function(callId, uid)
{
},
getProfile: function(callId, uid)
{
},
takeHeapSnapshot: function()
{
},
takeHeapSnapshot: function()
{
},
databaseTableNames: function(database)
{
return [];
},
databaseTableNames: function(database)
{
return [];
},
stepIntoStatement: function()
{
WebInspector.InspectorController.resume('in');
},
stepIntoStatement: function()
{
WebInspector.InspectorController.resume('in');
},
stepOutOfFunction: function()
{
WebInspector.InspectorController.resume('out');
},
stepOutOfFunction: function()
{
WebInspector.InspectorController.resume('out');
},
stepOverStatement: function()
{
WebInspector.InspectorController.resume('next');
},
stepOverStatement: function()
{
WebInspector.InspectorController.resume('next');
},
saveApplicationSettings: function()
{
},
saveApplicationSettings: function()
{
},
saveSessionSettings: function()
{
},
saveSessionSettings: function()
{
},
dispatchOnInjectedScript: function()
{
console.log("injected: " + JSON.stringify(arguments));
switch(arguments[2]) {
case 'getProperties':
var id = arguments[1];
dispatchOnInjectedScript: function()
{
console.log("injected: " + JSON.stringify(arguments));
switch(arguments[2]) {
case 'getProperties':
var id = arguments[1];
var _decode = function(local)
{
var n = local.name || 'arguments[' + argi + ']';
argi += 1;
var p = {name: n};
switch (local.value.type) {
case 'object':
p.value = {
description: local.value.className,
hasChildren: true,
injectedScriptId: local.value.ref
};
break;
case 'function':
p.value = {
description: 'function ' + n + '()',
hasChildren: true,
injectedScriptId: local.value.ref
};
break;
case 'undefined':
p.value = {description: 'undefined'};
break;
case 'null':
p.value = {description: 'null'};
break;
default:
p.value = {description: local.value.value};
break;
}
return p;
};
if (id.scopeId !== undefined) {
var x = JSON.parse(arguments[3]);
if(x[0] && x[0].isLocal)
{
var obj = x[0];
var props = obj.locals.map(_decode);
var argi = 0;
props = props.concat(obj.arguments.map(_decode));
WebInspector.Callback.processCallback(arguments[0], props);
}
else {
WebInspector.InspectorController.getScope(id.frameId, id.scopeId, arguments[0]);
}
}
else {
WebInspector.InspectorController.lookup(id, arguments[0]);
}
break;
case 'evaluate':
var expr = JSON.parse(arguments[3])[0];
WebInspector.InspectorController.evaluate(expr, arguments[0]);
break;
case 'evaluateInCallFrame':
var args = JSON.parse(arguments[3]);
var frameId = args[0];
var expr = args[1];
//HACK: protect against evaluating known dangerous expressions,
// i.e. ones that crash node
if (['require', 'exports', 'module', '__filename', '__dirname'].indexOf(expr) > -1) {
WebInspector.Callback.processCallback(arguments[0], null);
}
else {
WebInspector.InspectorController.evaluate(expr, arguments[0], frameId);
}
break;
default:
// so the callback list doesn't leak
WebInspector.Callback.processCallback(arguments[0], null);
break;
}
},
releaseWrapperObjectGroup: function()
{
},
setInjectedScriptSource: function()
{
},
addScriptToEvaluateOnLoad: function()
{
},
removeAllScriptsToEvaluateOnLoad: function()
{
},
performSearch: function()
{
},
searchCanceled: function()
{
var _decode = function(local)
{
var n = local.name || 'arguments[' + argi + ']';
argi += 1;
var p = {name: n};
switch (local.value.type) {
case 'object':
p.value = {
description: local.value.className,
hasChildren: true,
injectedScriptId: local.value.ref
};
break;
case 'function':
p.value = {
description: 'function ' + n + '()',
hasChildren: true,
injectedScriptId: local.value.ref
};
break;
case 'undefined':
p.value = {description: 'undefined'};
break;
case 'null':
p.value = {description: 'null'};
break;
default:
p.value = {description: local.value.value};
break;
}
return p;
};
if (id.scopeId !== undefined) {
var x = JSON.parse(arguments[3]);
if(x[0] && x[0].isLocal)
{
var obj = x[0];
var props = obj.locals.map(_decode);
var argi = 0;
props = props.concat(obj.arguments.map(_decode));
WebInspector.Callback.processCallback(arguments[0], props);
}
else {
WebInspector.InspectorController.getScope(id.frameId, id.scopeId, arguments[0]);
}
}
else {
WebInspector.InspectorController.lookup(id, arguments[0]);
}
break;
case 'evaluate':
var expr = JSON.parse(arguments[3])[0];
WebInspector.InspectorController.evaluate(expr, arguments[0]);
break;
case 'evaluateInCallFrame':
var args = JSON.parse(arguments[3]);
var frameId = args[0];
var expr = args[1];
//HACK: protect against evaluating known dangerous expressions,
// i.e. ones that crash node
if (['require', 'exports', 'module', '__filename', '__dirname'].indexOf(expr) > -1) {
WebInspector.Callback.processCallback(arguments[0], null);
}
else {
WebInspector.InspectorController.evaluate(expr, arguments[0], frameId);
}
break;
default:
// so the callback list doesn't leak
WebInspector.Callback.processCallback(arguments[0], null);
break;
}
},
releaseWrapperObjectGroup: function()
{
},
setInjectedScriptSource: function()
{
},
addScriptToEvaluateOnLoad: function()
{
},
removeAllScriptsToEvaluateOnLoad: function()
{
},
performSearch: function()
{
},
searchCanceled: function()
{
}
}
InspectorBackend = new WebInspector.InspectorBackendStub();

Просмотреть файл

@ -1,283 +1,299 @@
WebInspector.InspectorController = (function() {
var seq = 0;
var callbacks = {};
var breakpoints = {};
var makeRequest = function(command, params) {
var msg = {
seq: seq++,
type: 'request',
command: command
}
if (params) {
Object.keys(params).forEach(function(key) {
msg[key] = params[key];
});
}
return msg;
};
var sendRequest = function(command, params, callId) {
var msg = makeRequest(command, params);
if (typeof callId !== 'undefined') {
callbacks[msg.seq] = callId;
}
socket.send(JSON.stringify(msg));
}
var socket = null;
var controller = {
initialize: function() {
if (['http:', 'https:'].indexOf(window.location.protocol) > -1) {
var addr = window.location.host;
}
else {
var addr = '127.0.0.1:8080'; //FIXME
}
socket = new WebSocket('ws://' + addr);
socket.onmessage = function(event) {
parseMessage(event.data);
};
socket.onclose = function() {
breakpoints = {};
callbacks = {};
WebInspector.debuggerWasDisabled();
WebInspector.panels.scripts.reset();
console.log('socket closed');
};
socket.onopen = function() {
console.log('socket open');
WebInspector.debuggerWasEnabled();
sendRequest('scripts', {
arguments: { includeSource: true, types: 4 }});
};
},
close: function() {
socket.close();
socket = null;
},
setBreakpoint: function(callId, sourceID, line, enabled, condition) {
var bp = breakpoints[sourceID + ':' + line];
if(bp) {
sendRequest('changebreakpoint', {
arguments: {
breakpoint: bp,
enabled: enabled,
condition: condition}});
}
else {
sendRequest('setbreakpoint',{
arguments: {
type: 'scriptId',
target: sourceID,
line: line - 1,
enabled: enabled,
condition: condition
}}, sourceID + ':' + line);
}
},
clearBreakpoint: function(sourceID, line) {
var id = sourceID + ':' + line;
sendRequest('clearbreakpoint', {
arguments: { breakpoint: breakpoints[id] }}, id);
},
listBreakpoints: function() {
sendRequest('listbreakpoints');
},
getBacktrace: function() {
sendRequest('backtrace',{arguments: { inlineRefs: true }});
},
pause: function() {
sendRequest('suspend');
},
resume: function(step) {
if(step) {
var params = {arguments: { stepaction: step }};
}
sendRequest('continue', params);
},
getScope: function(frameId, scopeId, callId) {
sendRequest('scope', {
arguments: {
number: scopeId,
frameNumber: frameId,
inlineRefs:true }},
callId);
},
lookup: function(ref, callId) {
sendRequest('lookup', {
arguments: { handles: [ref], inlineRefs:true }},
callId);
},
evaluate: function(expr, callId, frameId) {
var args = { expression: expr, disable_break: true };
if (frameId != null) {
args.frame = frameId;
args.global = false;
}
else {
args.global = true;
}
sendRequest('evaluate', {arguments: args}, callId);
},
_valueOf: function(value) {
var p = {};
switch (value.type) {
case 'object':
p.value = {
description: value.className,
hasChildren: true,
injectedScriptId: value.ref || value.handle,
type: 'object'
};
break;
case 'function':
p.value = {
description: value.text || 'function()',
hasChildren: true,
injectedScriptId: value.ref || value.handle,
type: 'function'
};
break;
case 'undefined':
p.value = {description: 'undefined'};
break;
case 'null':
p.value = {description: 'null'};
break;
default:
p.value = {description: value.value};
break;
}
return p;
},
_property: function(prop) {
var p = controller._valueOf(prop.value);
p.name = String(prop.name);
return p;
},
refToProperties: function(ref) {
if (ref) {
return ref.properties.map(controller._property);
}
}
};
var parseResponse = function(msg) {
var callId = callbacks[msg.request_seq];
delete callbacks[msg.request_seq];
switch (msg.command) {
case 'scripts':
msg.body.forEach(function(s) {
WebInspector.parsedScriptSource(s.id, s.name, s.source, s.lineOffset, 0);
});
sendRequest('listbreakpoints');
break;
case 'scope':
WebInspector.Callback.processCallback(callId, controller.refToProperties(msg.body.object));
break;
case 'suspend':
if (msg.success && !msg.running) {
controller.getBacktrace();
}
break;
case 'lookup':
console.log(JSON.stringify(msg));
var ref = msg.body[Object.keys(msg.body)[0]];
WebInspector.Callback.processCallback(callId, controller.refToProperties(ref));
break;
case 'evaluate':
console.log(JSON.stringify(msg));
if (msg.success) {
WebInspector.Callback.processCallback(callId, controller._valueOf(msg.body));
}
else {
WebInspector.Callback.processCallback(callId, {value: msg.message, isException: true});
}
break;
case 'setbreakpoint':
breakpoints[callId] = msg.body.breakpoint;
break;
case 'clearbreakpoint':
delete breakpoints[callId];
break;
case 'listbreakpoints':
breakpoints = {};
WebInspector.breakpointManager.reset();
msg.body.breakpoints.forEach(function(bp) {
if(bp.type === 'scriptId') {
var l = bp.line + 1;
var url = WebInspector.panels.scripts._sourceIDMap[bp.script_id].sourceURL;
breakpoints[bp.script_id + ':' + l] = bp.number;
WebInspector.breakpointManager.setBreakpoint(bp.script_id, url, l, !!bp.active, bp.condition)
}
});
break;
case 'backtrace':
var callFrames = msg.body.frames.map(function(frame) {
var f = {
type: 'function',
functionName: frame.func.inferredName,
sourceID: frame.func.scriptId,
line: frame.line + 1,
id: frame.index
};
f.scopeChain = frame.scopes.map(function(scope) {
var c = {};
switch (scope.type) {
case 0:
break;
case 1:
c.isLocal = true;
c.thisObject = {description: frame.receiver.className, hasChildren: true, injectedScriptId: frame.receiver.ref};
c.locals = frame.locals;
c.arguments = frame.arguments;
break;
case 2:
c.isWithBlock = true;
break;
case 3:
c.isClosure = true;
break;
case 4:
c.isElement = true;
break;
default:
break;
}
c.injectedScriptId = {frameId: frame.index, scopeId: scope.index, isLocal: !!c.isLocal};
return c;
});
return f;
});
WebInspector.pausedScript(callFrames);
break;
default:
console.log(JSON.stringify(msg));
break;
}
};
var parseEvent = function(msg) {
switch (msg.event) {
case 'break':
controller.getBacktrace();
console.log(JSON.stringify(msg.body));
break;
case 'exception':
console.error(JSON.stringify(msg.body));
break;
default:
console.log(JSON.stringify(msg.body));
break;
}
};
var parseMessage = function(data) {
var msg = JSON.parse(data);
if (msg.type === 'response') {
parseResponse(msg);
}
else {
parseEvent(msg);
}
};
var seq = 0;
var callbacks = {};
var breakpoints = {};
var makeRequest = function(command, params) {
var msg = {
seq: seq++,
type: 'request',
command: command
}
if (params) {
Object.keys(params).forEach(function(key) {
msg[key] = params[key];
});
}
return msg;
};
var sendRequest = function(command, params, callId) {
var msg = makeRequest(command, params);
if (typeof callId !== 'undefined') {
callbacks[msg.seq] = callId;
}
socket.send(JSON.stringify(msg));
}
var socket = null;
var controller = {
initialize: function() {
if (['http:', 'https:'].indexOf(window.location.protocol) > -1) {
var addr = window.location.host;
}
else {
var addr = '127.0.0.1:8080'; //FIXME
}
socket = new WebSocket('ws://' + addr);
socket.onmessage = function(event) {
parseMessage(event.data);
};
socket.onclose = function() {
breakpoints = {};
callbacks = {};
WebInspector.debuggerWasDisabled();
WebInspector.panels.scripts.reset();
console.log('socket closed');
};
socket.onopen = function() {
console.log('socket open');
WebInspector.debuggerWasEnabled();
sendRequest('scripts', {
arguments: { includeSource: true, types: 4 }});
};
},
close: function() {
socket.close();
socket = null;
},
setBreakpoint: function(callId, sourceID, line, enabled, condition) {
var bp = breakpoints[sourceID + ':' + line];
if(bp) {
sendRequest('changebreakpoint', {
arguments: {
breakpoint: bp,
enabled: enabled,
condition: condition}});
}
else {
sendRequest('setbreakpoint',{
arguments: {
type: 'scriptId',
target: sourceID,
line: line - 1,
enabled: enabled,
condition: condition
}}, sourceID + ':' + line);
}
},
clearBreakpoint: function(sourceID, line) {
var id = sourceID + ':' + line;
sendRequest('clearbreakpoint', {
arguments: { breakpoint: breakpoints[id] }}, id);
},
listBreakpoints: function() {
sendRequest('listbreakpoints');
},
getBacktrace: function() {
sendRequest('backtrace',{arguments: { inlineRefs: true }});
},
pause: function() {
sendRequest('suspend');
},
resume: function(step) {
if(step) {
var params = {arguments: { stepaction: step }};
}
sendRequest('continue', params);
},
getScope: function(frameId, scopeId, callId) {
sendRequest('scope', {
arguments: {
number: scopeId,
frameNumber: frameId,
inlineRefs:true }},
callId);
},
lookup: function(ref, callId) {
sendRequest('lookup', {
arguments: { handles: [ref], inlineRefs:true }},
callId);
},
evaluate: function(expr, callId, frameId) {
var args = { expression: expr, disable_break: true };
if (frameId != null) {
args.frame = frameId;
args.global = false;
}
else {
args.global = true;
}
sendRequest('evaluate', {arguments: args}, callId);
},
_valueOf: function(value) {
var p = {};
switch (value.type) {
case 'object':
p.value = {
description: value.className,
hasChildren: true,
injectedScriptId: value.ref || value.handle,
type: 'object'
};
break;
case 'function':
p.value = {
description: value.text || 'function()',
hasChildren: true,
injectedScriptId: value.ref || value.handle,
type: 'function'
};
break;
case 'undefined':
p.value = {description: 'undefined'};
break;
case 'null':
p.value = {description: 'null'};
break;
default:
p.value = {description: value.value};
break;
}
return p;
},
_property: function(prop) {
var p = controller._valueOf(prop.value);
p.name = String(prop.name);
return p;
},
refToProperties: function(ref) {
if (ref) {
return ref.properties.map(controller._property);
}
}
};
var parseResponse = function(msg) {
var callId = callbacks[msg.request_seq];
delete callbacks[msg.request_seq];
switch (msg.command) {
case 'scripts':
msg.body.forEach(function(s) {
WebInspector.parsedScriptSource(s.id, s.name, s.source, s.lineOffset, 0);
});
sendRequest('listbreakpoints');
break;
case 'scope':
WebInspector.Callback.processCallback(callId, controller.refToProperties(msg.body.object));
break;
case 'suspend':
if (msg.success && !msg.running) {
controller.getBacktrace();
}
break;
case 'lookup':
console.log(JSON.stringify(msg));
var ref = msg.body[Object.keys(msg.body)[0]];
WebInspector.Callback.processCallback(callId, controller.refToProperties(ref));
break;
case 'evaluate':
console.log(JSON.stringify(msg));
if (msg.success) {
WebInspector.Callback.processCallback(callId, controller._valueOf(msg.body));
}
else {
WebInspector.Callback.processCallback(callId, {value: msg.message, isException: true});
}
break;
case 'setbreakpoint':
breakpoints[callId] = msg.body.breakpoint;
break;
case 'clearbreakpoint':
delete breakpoints[callId];
break;
case 'listbreakpoints':
breakpoints = {};
WebInspector.breakpointManager.reset();
msg.body.breakpoints.forEach(function(bp) {
if(bp.type === 'scriptId') {
var l = bp.line + 1;
var url = WebInspector.panels.scripts._sourceIDMap[bp.script_id].sourceURL;
breakpoints[bp.script_id + ':' + l] = bp.number;
WebInspector.breakpointManager.setBreakpoint(bp.script_id, url, l, !!bp.active, bp.condition)
}
});
break;
case 'backtrace':
var callFrames = msg.body.frames.map(function(frame) {
var f = {
type: 'function',
functionName: frame.func.inferredName,
sourceID: frame.func.scriptId,
line: frame.line + 1,
id: frame.index
};
f.scopeChain = frame.scopes.map(function(scope) {
var c = {};
switch (scope.type) {
case 0:
break;
case 1:
c.isLocal = true;
c.thisObject = {description: frame.receiver.className, hasChildren: true, injectedScriptId: frame.receiver.ref};
c.locals = frame.locals;
c.arguments = frame.arguments;
break;
case 2:
c.isWithBlock = true;
break;
case 3:
c.isClosure = true;
break;
case 4:
c.isElement = true;
break;
default:
break;
}
c.injectedScriptId = {frameId: frame.index, scopeId: scope.index, isLocal: !!c.isLocal};
return c;
});
return f;
});
WebInspector.pausedScript(callFrames);
break;
default:
console.log(JSON.stringify(msg));
break;
}
};
var parseEvent = function(msg) {
switch (msg.event) {
case 'break':
controller.getBacktrace();
break;
case 'exception':
console.error(JSON.stringify(msg.body));
break;
case 'stdout':
console.log(JSON.stringify(msg.body));
WebInspector.addConsoleMessage({
source: WebInspector.ConsoleMessage.MessageSource.JS,
type: WebInspector.ConsoleMessage.MessageType.Log,
level: WebInspector.ConsoleMessage.MessageLevel.Log,
repeatCount: 1,
message: 'stdout: ' + msg.body});
break;
case 'stderr':
WebInspector.addConsoleMessage({
source: WebInspector.ConsoleMessage.MessageSource.JS,
type: WebInspector.ConsoleMessage.MessageType.Log,
level: WebInspector.ConsoleMessage.MessageLevel.Error,
repeatCount: 1,
message: 'stderr: ' + msg.body});
break;
default:
console.log(JSON.stringify(msg.body));
break;
}
};
var parseMessage = function(data) {
var msg = JSON.parse(data);
if (msg.type === 'response') {
parseResponse(msg);
}
else {
parseEvent(msg);
}
};
return controller;
return controller;
}());

Просмотреть файл

@ -32,102 +32,102 @@ if (!window.InspectorFrontendHost) {
WebInspector.InspectorFrontendHostStub = function()
{
this._attachedWindowHeight = 0;
this.showContextMenu = function(event, items) {
if(chrome && chrome.experimental) {
chrome.experimental.contextMenus.removeAll();
items.forEach(function(item) {
chrome.experimental.contextMenus.create({
title: item.label,
onclick: function() {
WebInspector.contextMenuItemSelected(item.id);
}
});
});
}
};
this._attachedWindowHeight = 0;
this.showContextMenu = function(event, items) {
if(chrome && chrome.experimental) {
chrome.experimental.contextMenus.removeAll();
items.forEach(function(item) {
chrome.experimental.contextMenus.create({
title: item.label,
onclick: function() {
WebInspector.contextMenuItemSelected(item.id);
}
});
});
}
};
}
WebInspector.InspectorFrontendHostStub.prototype = {
platform: function()
{
var match = navigator.userAgent.match(/Windows NT/);
if (match)
return "windows";
match = navigator.userAgent.match(/Mac OS X/);
if (match)
return "mac";
return "linux";
},
platform: function()
{
var match = navigator.userAgent.match(/Windows NT/);
if (match)
return "windows";
match = navigator.userAgent.match(/Mac OS X/);
if (match)
return "mac";
return "linux";
},
port: function()
{
return "unknown";
},
port: function()
{
return "unknown";
},
bringToFront: function()
{
this._windowVisible = true;
},
bringToFront: function()
{
this._windowVisible = true;
},
closeWindow: function()
{
this._windowVisible = false;
},
closeWindow: function()
{
this._windowVisible = false;
},
attach: function()
{
},
attach: function()
{
},
detach: function()
{
},
detach: function()
{
},
search: function(sourceRow, query)
{
},
search: function(sourceRow, query)
{
},
setAttachedWindowHeight: function(height)
{
},
setAttachedWindowHeight: function(height)
{
},
moveWindowBy: function(x, y)
{
},
moveWindowBy: function(x, y)
{
},
loaded: function()
{
document.getElementById("dock-status-bar-item").style.display='none';
WebInspector.populateApplicationSettings();
WebInspector.applicationSettings.installSetting("scriptsSidebarWidth", "scripts-sidebar-width", 250);
WebInspector.applicationSettings.installSetting("consoleSidebarWidth", "console-sidebar-width", 250);
WebInspector.showScriptsPanel();
WebInspector.panels.scripts._pauseOnExceptionButton.disabled = true;
WebInspector.panels.scripts._enableDebugging();
},
loaded: function()
{
document.getElementById("dock-status-bar-item").style.display='none';
WebInspector.populateApplicationSettings();
WebInspector.applicationSettings.installSetting("scriptsSidebarWidth", "scripts-sidebar-width", 250);
WebInspector.applicationSettings.installSetting("consoleSidebarWidth", "console-sidebar-width", 250);
WebInspector.showScriptsPanel();
WebInspector.panels.scripts._pauseOnExceptionButton.disabled = true;
WebInspector.panels.scripts._enableDebugging();
},
localizedStringsURL: function()
{
return undefined;
},
localizedStringsURL: function()
{
return undefined;
},
hiddenPanels: function()
{
return "elements,resources,timeline,profiles,storage,audits";
},
hiddenPanels: function()
{
return "elements,resources,timeline,profiles,storage,audits";
},
inspectedURLChanged: function(url)
{
},
inspectedURLChanged: function(url)
{
},
copyText: function()
{
},
copyText: function()
{
},
canAttachWindow: function()
{
return false;
}
canAttachWindow: function()
{
return false;
}
}
InspectorFrontendHost = new WebInspector.InspectorFrontendHostStub();

Просмотреть файл

@ -1,5 +1,5 @@
<script>
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.create({url:"index.html"});
chrome.tabs.create({url:"index.html"});
});
</script>

Просмотреть файл

@ -1,9 +1,9 @@
var http = require('http'),
sys = require('sys');
sys = require('sys');
var x = 0;
http.createServer(function (req, res) {
x += 1;
x += 1;
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World ' + x);
}).listen(8124, "127.0.0.1");