From ebe02ade9cf5f9392d149e6fa51ca0704acc6a2c Mon Sep 17 00:00:00 2001 From: thatcher Date: Tue, 11 Jul 2006 07:51:34 +0000 Subject: [PATCH] Reviewed by a tired Geoff. Bug 9597: [Drosera] hook up the variables table to show stack variables http://bugzilla.opendarwin.org/show_bug.cgi?id=9597 * Drosera/DebuggerDocument.m: (-[WebScriptObject isSelectorExcludedFromWebScript:]): (-[WebScriptObject webScriptAttributeKeysForScriptObject:]): (-[WebScriptObject localScopeVariableNamesForCallFrame:]): (-[WebScriptObject valueForScopeVariableNamed:inCallFrame:]): (-[WebScriptObject webView:didReceiveTitle:forFrame:]): (-[WebScriptObject webView:didLoadMainResourceForDataSource:]): (-[WebScriptObject webView:didParseSource:baseLineNumber:fromURL:sourceId:forWebFrame:]): (-[WebScriptObject webView:didEnterCallFrame:sourceId:line:forWebFrame:]): (-[WebScriptObject webView:willExecuteStatement:sourceId:line:forWebFrame:]): (-[WebScriptObject webView:willLeaveCallFrame:sourceId:line:forWebFrame:]): * Drosera/debugger.css: * Drosera/debugger.html: * Drosera/debugger.js: git-svn-id: https://svn.webkit.org/repository/webkit/trunk@15332 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- WebKitTools/ChangeLog | 22 ++++++ WebKitTools/Drosera/DebuggerDocument.m | 76 ++++++++++++++++-- WebKitTools/Drosera/debugger.css | 17 +++- WebKitTools/Drosera/debugger.html | 2 +- WebKitTools/Drosera/debugger.js | 105 ++++++++++++++++++++----- 5 files changed, 195 insertions(+), 27 deletions(-) diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog index 3811e60e6daa..d389f594a1ab 100644 --- a/WebKitTools/ChangeLog +++ b/WebKitTools/ChangeLog @@ -1,3 +1,25 @@ +2006-07-11 Timothy Hatcher + + Reviewed by a tired Geoff. + + Bug 9597: [Drosera] hook up the variables table to show stack variables + http://bugzilla.opendarwin.org/show_bug.cgi?id=9597 + + * Drosera/DebuggerDocument.m: + (-[WebScriptObject isSelectorExcludedFromWebScript:]): + (-[WebScriptObject webScriptAttributeKeysForScriptObject:]): + (-[WebScriptObject localScopeVariableNamesForCallFrame:]): + (-[WebScriptObject valueForScopeVariableNamed:inCallFrame:]): + (-[WebScriptObject webView:didReceiveTitle:forFrame:]): + (-[WebScriptObject webView:didLoadMainResourceForDataSource:]): + (-[WebScriptObject webView:didParseSource:baseLineNumber:fromURL:sourceId:forWebFrame:]): + (-[WebScriptObject webView:didEnterCallFrame:sourceId:line:forWebFrame:]): + (-[WebScriptObject webView:willExecuteStatement:sourceId:line:forWebFrame:]): + (-[WebScriptObject webView:willLeaveCallFrame:sourceId:line:forWebFrame:]): + * Drosera/debugger.css: + * Drosera/debugger.html: + * Drosera/debugger.js: + 2006-07-10 Tim Omernick Reviewed by Beth Dakin. diff --git a/WebKitTools/Drosera/DebuggerDocument.m b/WebKitTools/Drosera/DebuggerDocument.m index e5721bfe4748..12e841d8330d 100644 --- a/WebKitTools/Drosera/DebuggerDocument.m +++ b/WebKitTools/Drosera/DebuggerDocument.m @@ -35,6 +35,10 @@ static NSString *DebuggerStepIntoToolbarItem = @"DebuggerStepIntoToolbarItem"; static NSString *DebuggerStepOverToolbarItem = @"DebuggerStepOverToolbarItem"; static NSString *DebuggerStepOutToolbarItem = @"DebuggerStepOutToolbarItem"; +@interface WebScriptObject (WebScriptObjectPrivate) +- (unsigned int)count; +@end + @implementation DebuggerDocument + (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector { @@ -87,6 +91,63 @@ static NSString *DebuggerStepOutToolbarItem = @"DebuggerStepOutToolbarItem"; return [result autorelease]; } +- (NSArray *)webScriptAttributeKeysForScriptObject:(WebScriptObject *)object +{ + WebScriptObject *func = [object evaluateWebScript:@"(function () { var result = new Array(); for (var x in this) { result.push(x); } return result; })"]; + [object setValue:func forKey:@"__drosera_introspection"]; + + NSMutableArray *result = [[NSMutableArray alloc] init]; + WebScriptObject *variables = [object callWebScriptMethod:@"__drosera_introspection" withArguments:nil]; + unsigned length = [variables count]; + for (unsigned i = 0; i < length; i++) { + NSString *key = [variables webScriptValueAtIndex:i]; + if (![key isEqualToString:@"__drosera_introspection"]) + [result addObject:key]; + } + + [object removeWebScriptKey:@"__drosera_introspection"]; + + [result sortUsingSelector:@selector(compare:)]; + return [result autorelease]; +} + +- (NSArray *)localScopeVariableNamesForCallFrame:(int)frame +{ + WebScriptCallFrame *cframe = currentFrame; + for (unsigned count = 0; count < frame; count++) + cframe = [cframe caller]; + + if (![[cframe scopeChain] count]) + return nil; + + WebScriptObject *scope = [[cframe scopeChain] objectAtIndex:0]; // local is always first + return [self webScriptAttributeKeysForScriptObject:scope]; +} + +- (NSString *)valueForScopeVariableNamed:(NSString *)key inCallFrame:(int)frame +{ + WebScriptCallFrame *cframe = currentFrame; + for (unsigned count = 0; count < frame; count++) + cframe = [cframe caller]; + + if (![[cframe scopeChain] count]) + return nil; + + unsigned scopeCount = [[cframe scopeChain] count]; + for (unsigned i = 0; i < scopeCount; i++) { + WebScriptObject *scope = [[cframe scopeChain] objectAtIndex:i]; + id value = [scope valueForKey:key]; + if ([value isKindOfClass:NSClassFromString(@"WebScriptObject")]) + return [value callWebScriptMethod:@"toString" withArguments:nil]; + if (value && ![value isKindOfClass:[NSString class]]) + return [NSString stringWithFormat:@"%@", value]; + if (value) + return value; + } + + return nil; +} + #pragma mark - #pragma mark Pause & Step @@ -367,9 +428,10 @@ static NSString *DebuggerStepOutToolbarItem = @"DebuggerStepOutToolbarItem"; return; NSString *urlCopy = [[[[dataSource response] URL] absoluteString] copy]; - NSArray *args = [NSArray arrayWithObjects:(documentSourceCopy ? documentSourceCopy : @""), (urlCopy ? urlCopy : @""), [NSNumber numberWithBool:NO], nil]; + NSArray *args = [[NSArray alloc] initWithObjects:(documentSourceCopy ? documentSourceCopy : @""), (urlCopy ? urlCopy : @""), [NSNumber numberWithBool:NO], nil]; [[webView windowScriptObject] callWebScriptMethod:@"updateFileSource" withArguments:args]; + [args release]; [documentSourceCopy release]; [urlCopy release]; } @@ -395,9 +457,10 @@ static NSString *DebuggerStepOutToolbarItem = @"DebuggerStepOutToolbarItem"; urlCopy = [[[[dataSource response] URL] absoluteString] copy]; } - NSArray *args = [NSArray arrayWithObjects:sourceCopy, (documentSourceCopy ? documentSourceCopy : @""), (urlCopy ? urlCopy : @""), [NSNumber numberWithInt:sid], [NSNumber numberWithUnsignedInt:baseLine], nil]; + NSArray *args = [[NSArray alloc] initWithObjects:sourceCopy, (documentSourceCopy ? documentSourceCopy : @""), (urlCopy ? urlCopy : @""), [NSNumber numberWithInt:sid], [NSNumber numberWithUnsignedInt:baseLine], nil]; [[webView windowScriptObject] callWebScriptMethod:@"didParseScript" withArguments:args]; + [args release]; [sourceCopy release]; [documentSourceCopy release]; [urlCopy release]; @@ -416,8 +479,9 @@ static NSString *DebuggerStepOutToolbarItem = @"DebuggerStepOutToolbarItem"; currentFrame = [frame retain]; [old release]; - NSArray *args = [NSArray arrayWithObjects:[NSNumber numberWithInt:sid], [NSNumber numberWithInt:lineno], nil]; + NSArray *args = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:sid], [NSNumber numberWithInt:lineno], nil]; [[webView windowScriptObject] callWebScriptMethod:@"didEnterCallFrame" withArguments:args]; + [args release]; } - (void)webView:(WebView *)view willExecuteStatement:(WebScriptCallFrame *)frame sourceId:(int)sid line:(int)lineno forWebFrame:(WebFrame *)webFrame @@ -425,8 +489,9 @@ static NSString *DebuggerStepOutToolbarItem = @"DebuggerStepOutToolbarItem"; if (!webViewLoaded) return; - NSArray *args = [NSArray arrayWithObjects:[NSNumber numberWithInt:sid], [NSNumber numberWithInt:lineno], nil]; + NSArray *args = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:sid], [NSNumber numberWithInt:lineno], nil]; [[webView windowScriptObject] callWebScriptMethod:@"willExecuteStatement" withArguments:args]; + [args release]; } - (void)webView:(WebView *)view willLeaveCallFrame:(WebScriptCallFrame *)frame sourceId:(int)sid line:(int)lineno forWebFrame:(WebFrame *)webFrame @@ -434,8 +499,9 @@ static NSString *DebuggerStepOutToolbarItem = @"DebuggerStepOutToolbarItem"; if (!webViewLoaded) return; - NSArray *args = [NSArray arrayWithObjects:[NSNumber numberWithInt:sid], [NSNumber numberWithInt:lineno], nil]; + NSArray *args = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:sid], [NSNumber numberWithInt:lineno], nil]; [[webView windowScriptObject] callWebScriptMethod:@"willLeaveCallFrame" withArguments:args]; + [args release]; id old = currentFrame; currentFrame = [[frame caller] retain]; diff --git a/WebKitTools/Drosera/debugger.css b/WebKitTools/Drosera/debugger.css index 9d0e3135070c..2469943af9f4 100644 --- a/WebKitTools/Drosera/debugger.css +++ b/WebKitTools/Drosera/debugger.css @@ -27,7 +27,7 @@ */ img { padding: 0; margin: 0; } -body { margin: 0; padding: 0; } +body { margin: 0; padding: 0; overflow: hidden; } #main { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } #info { position: absolute; top: 0; height: 175px; left: 0; right: 0; } @@ -196,7 +196,20 @@ table { border: 0; } -td { padding: 3px 7px 3px 9px; height: 15px; box-sizing: border-box; } +td { + padding: 3px 7px 3px 9px; + height: 15px; + box-sizing: border-box; + -webkit-user-select: none; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +tr.current { + background-color: rgb(56, 117, 215); + color: white; +} .stackNumber { width: 2em; diff --git a/WebKitTools/Drosera/debugger.html b/WebKitTools/Drosera/debugger.html index 466f0c403cbf..c998a928ffd8 100644 --- a/WebKitTools/Drosera/debugger.html +++ b/WebKitTools/Drosera/debugger.html @@ -53,7 +53,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
Variable
+
Variable
Value
diff --git a/WebKitTools/Drosera/debugger.js b/WebKitTools/Drosera/debugger.js index 8025ca8e1594..7f9bcb459599 100644 --- a/WebKitTools/Drosera/debugger.js +++ b/WebKitTools/Drosera/debugger.js @@ -32,6 +32,7 @@ var scripts = new Array(); var currentFile = -1; var currentRow = null; var currentStack = null; +var currentCallFrame = null; var previousFiles = new Array(); var nextFiles = new Array(); var isResizingColumn = false; @@ -41,6 +42,43 @@ var steppingOver = false; var steppingStack = 0; var pauseOnNextStatement = false; +ScriptCallFrame = function (functionName, index, row) +{ + this.functionName = functionName; + this.index = index; + this.row = row; + this.localVariableNames = null; +} + +ScriptCallFrame.prototype.valueForScopeVariable = function (name) +{ + return DebuggerDocument.valueForScopeVariableNamed_inCallFrame_(name, this.index); +} + +ScriptCallFrame.prototype.loadVariables = function () +{ + if (!this.localVariableNames) + this.localVariableNames = DebuggerDocument.localScopeVariableNamesForCallFrame_(this.index); + + var variablesTable = document.getElementById("variablesTable"); + variablesTable.innerHTML = ""; + + for(var i = 0; i < this.localVariableNames.length; i++) { + var tr = document.createElement("tr"); + var td = document.createElement("td"); + td.innerText = this.localVariableNames[i]; + td.className = "variable"; + tr.appendChild(td); + + td = document.createElement("td"); + td.innerText = this.valueForScopeVariable(this.localVariableNames[i]); + tr.appendChild(td); + tr.addEventListener("click", selectVariable, true); + + variablesTable.appendChild(tr); + } +} + function sleep(numberMillis) { var now = new Date(); var exitTime = now.getTime() + numberMillis; @@ -112,12 +150,20 @@ function columnResizerDrag(event) { if (element.dragging == true) { var main = document.getElementById("rightPane"); var variableColumn = document.getElementById("variable"); + var rules = document.defaultView.getMatchedCSSRules(variableColumn, ""); + for (var i = 0; i < rules.length; i++) { + if (rules[i].selectorText == ".variable") { + var columnRule = rules[i]; + break; + } + } + var x = event.clientX + window.scrollX; var delta = element.dragLastX - x; var newWidth = constrainedWidthFromElement(variableColumn.clientWidth - delta, main); if ((variableColumn.clientWidth - delta) == newWidth) // the width wasn't constrained element.dragLastX = x; - variableColumn.style.width = newWidth + "px"; + columnRule.style.width = newWidth + "px"; element.style.left = newWidth + "px"; event.preventDefault(); } @@ -194,11 +240,12 @@ function resume() currentRow = null; } - if (currentStack) { - var stackframeTable = document.getElementById("stackframeTable"); - stackframeTable.innerHTML = ""; // clear the content - currentStack = null; - } + var stackframeTable = document.getElementById("stackframeTable"); + stackframeTable.innerHTML = ""; // clear the content + var variablesTable = document.getElementById("variablesTable"); + variablesTable.innerHTML = ""; // clear the content + currentStack = null; + currentCallFrame = null; pauseOnNextStatement = false; steppingOut = false; @@ -559,8 +606,9 @@ function updateFunctionStack() var stackframeTable = document.getElementById("stackframeTable"); stackframeTable.innerHTML = ""; // clear the content - currentStack = DebuggerDocument.currentFunctionStack(); - for(var i = 0; i < currentStack.length; i++) { + currentStack = new Array(); + var stack = DebuggerDocument.currentFunctionStack(); + for(var i = 0; i < stack.length; i++) { var tr = document.createElement("tr"); var td = document.createElement("td"); td.className = "stackNumber"; @@ -568,23 +616,42 @@ function updateFunctionStack() tr.appendChild(td); td = document.createElement("td"); - td.innerText = currentStack[i]; + td.innerText = stack[i]; tr.appendChild(td); + tr.addEventListener("click", selectStackFrame, true); stackframeTable.appendChild(tr); - } - var tr = document.createElement("tr"); - var td = document.createElement("td"); - td.className = "stackNumber"; - td.innerText = i; - tr.appendChild(td); + var frame = new ScriptCallFrame(stack[i], i, tr); + tr.callFrame = frame; + currentStack.push(frame); - td = document.createElement("td"); - td.innerText = "Global"; - tr.appendChild(td); + if (i == 0) { + addStyleClass(tr, "current"); + frame.loadVariables(); + currentCallFrame = frame; + } + } +} + +function selectStackFrame(event) +{ + var stackframeTable = document.getElementById("stackframeTable"); + var rows = stackframeTable.childNodes; + for (var i = 0; i < rows.length; i++) + removeStyleClass(rows[i], "current"); + addStyleClass(this, "current"); + this.callFrame.loadVariables(); + currentCallFrame = this.callFrame; +} - stackframeTable.appendChild(tr); +function selectVariable(event) +{ + var variablesTable = document.getElementById("variablesTable"); + var rows = variablesTable.childNodes; + for (var i = 0; i < rows.length; i++) + removeStyleClass(rows[i], "current"); + addStyleClass(this, "current"); } function loadFile(fileIndex, manageNavLists) -- 2.36.0