2006-10-06 David Smith <catfish.man@gmail.com>
authorbdash <bdash@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 7 Oct 2006 03:31:22 +0000 (03:31 +0000)
committerbdash <bdash@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 7 Oct 2006 03:31:22 +0000 (03:31 +0000)
        Reviewed by Timothy.

        Bug 9665: [Drosera] Conditional breakpoints. http://bugs.webkit.org/show_bug.cgi?id=9665

        * Drosera/Drosera.xcodeproj/project.pbxproj: Added new files
        * Drosera/breakpointEditor.css: Added.
        * Drosera/breakpointEditor.html: Added.
        * Drosera/breakpointEditor.js: Added.
        * Drosera/debugger.js: Added conditional breakpoint support, and the ability to open the breakpoint editor window on option-clicking a breakpoint.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@16871 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKitTools/ChangeLog
WebKitTools/Drosera/Drosera.xcodeproj/project.pbxproj
WebKitTools/Drosera/breakpointEditor.css [new file with mode: 0644]
WebKitTools/Drosera/breakpointEditor.html [new file with mode: 0644]
WebKitTools/Drosera/breakpointEditor.js [new file with mode: 0644]
WebKitTools/Drosera/debugger.js

index c4175cc878f5fb43ce5f95cfd69368600825cd1d..ede04cf27d8930d84ffe89073d41ab81db942cc7 100644 (file)
@@ -1,3 +1,15 @@
+2006-10-06  David Smith  <catfish.man@gmail.com>
+
+        Reviewed by Timothy.
+
+        Bug 9665: [Drosera] Conditional breakpoints. http://bugs.webkit.org/show_bug.cgi?id=9665
+
+        * Drosera/Drosera.xcodeproj/project.pbxproj: Added new files
+        * Drosera/breakpointEditor.css: Added.
+        * Drosera/breakpointEditor.html: Added.
+        * Drosera/breakpointEditor.js: Added.
+        * Drosera/debugger.js: Added conditional breakpoint support, and the ability to open the breakpoint editor window on option-clicking a breakpoint.
+
 2006-10-06  Nikolas Zimmermann  <zimmermann@kde.org>
 
         Reviewed by Tim H.
index 2349c6a7494f55b1d10c3e2d81c81adaf53ccdf2..f22bd1082a0112c26302341809ad7e5197a109f7 100644 (file)
@@ -53,6 +53,9 @@
                1CD8D56C0A49043E00E5677B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; };
                1CD8D5A60A49102900E5677B /* Drosera.app in Resources */ = {isa = PBXBuildFile; fileRef = 8D15AC370486D014006FF6A4 /* Drosera.app */; };
                5D2C827F0A816BA700C193FD /* Drosera.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1C3487970A81208400101C5C /* Drosera.icns */; };
+               63A9E23F0AD4869300C079EE /* breakpointEditor.css in Resources */ = {isa = PBXBuildFile; fileRef = 63A9E23C0AD4869300C079EE /* breakpointEditor.css */; };
+               63A9E2400AD4869400C079EE /* breakpointEditor.html in Resources */ = {isa = PBXBuildFile; fileRef = 63A9E23D0AD4869300C079EE /* breakpointEditor.html */; };
+               63A9E2410AD4869400C079EE /* breakpointEditor.js in Resources */ = {isa = PBXBuildFile; fileRef = 63A9E23E0AD4869300C079EE /* breakpointEditor.js */; };
                8D15AC2D0486D014006FF6A4 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 2A37F4B6FDCFA73011CA2CEA /* MainMenu.nib */; };
                8D15AC2E0486D014006FF6A4 /* Debugger.nib in Resources */ = {isa = PBXBuildFile; fileRef = 2A37F4B4FDCFA73011CA2CEA /* Debugger.nib */; };
                8D15AC310486D014006FF6A4 /* DebuggerDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4ACFDCFA73011CA2CEA /* DebuggerDocument.m */; settings = {ATTRIBUTES = (); }; };
                2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
                2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
                32DBCF750370BD2300C91783 /* Drosera.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Drosera.pch; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+               63A9E23C0AD4869300C079EE /* breakpointEditor.css */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = breakpointEditor.css; sourceTree = "<group>"; };
+               63A9E23D0AD4869300C079EE /* breakpointEditor.html */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.html; path = breakpointEditor.html; sourceTree = "<group>"; };
+               63A9E23E0AD4869300C079EE /* breakpointEditor.js */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.javascript; path = breakpointEditor.js; sourceTree = "<group>"; };
                8D15AC360486D014006FF6A4 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
-               8D15AC370486D014006FF6A4 /* Drosera.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = Drosera.app; sourceTree = BUILT_PRODUCTS_DIR; };
+               8D15AC370486D014006FF6A4 /* Drosera.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Drosera.app; sourceTree = BUILT_PRODUCTS_DIR; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                                1C6F861F0A599F65004FCD89 /* console.js */,
                                1C6F84540A58EE06004FCD89 /* console.html */,
                                1C6F84530A58EE06004FCD89 /* console.css */,
+                               63A9E23C0AD4869300C079EE /* breakpointEditor.css */,
+                               63A9E23D0AD4869300C079EE /* breakpointEditor.html */,
+                               63A9E23E0AD4869300C079EE /* breakpointEditor.js */,
                        );
                        name = Classes;
                        sourceTree = "<group>";
                                1C6F84560A58EE06004FCD89 /* console.html in Resources */,
                                1C6F86730A59A18B004FCD89 /* console.js in Resources */,
                                1C3487980A81208400101C5C /* Drosera.icns in Resources */,
+                               63A9E23F0AD4869300C079EE /* breakpointEditor.css in Resources */,
+                               63A9E2400AD4869400C079EE /* breakpointEditor.html in Resources */,
+                               63A9E2410AD4869400C079EE /* breakpointEditor.js in Resources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/WebKitTools/Drosera/breakpointEditor.css b/WebKitTools/Drosera/breakpointEditor.css
new file mode 100644 (file)
index 0000000..e4e0d79
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006 David Smith (catfish.man@gmail.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  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. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+body { margin: 0; padding: 5px; overflow: hidden; }
+
+#main {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+}
+
+#save {
+    position: absolute;
+    bottom: 5px;
+    right: 5px;
+}
+
+#input {
+    position: absolute;
+    top: 20px;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    -webkit-user-modify: read-write;
+    -webkit-nbsp-mode: space;
+    -webkit-line-break: after-white-space;
+    word-wrap: break-word;
+    outline: none;
+    font-family: monospace;
+    font-size: 11px;
+    line-height: 14px;
+    padding: 8px;
+}
diff --git a/WebKitTools/Drosera/breakpointEditor.html b/WebKitTools/Drosera/breakpointEditor.html
new file mode 100644 (file)
index 0000000..40d01ec
--- /dev/null
@@ -0,0 +1,43 @@
+<!--
+Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+Copyright (C) 2006 David Smith (catfish.man@gmail.com)
+
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1.  Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer. 
+2.  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. 
+3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+    its contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission. 
+
+THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+    <title>Breakpoint Editor</title>
+    <script type="text/javascript" src="breakpointEditor.js"></script> 
+    <style type="text/css">
+        @import "breakpointEditor.css";
+    </style>
+</head>
+<body onload="loaded()" onunload="saveBreakpoint()">
+<div id="input"></div>
+</body>
+</html>
diff --git a/WebKitTools/Drosera/breakpointEditor.js b/WebKitTools/Drosera/breakpointEditor.js
new file mode 100644 (file)
index 0000000..051e936
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006 David Smith (catfish.man@gmail.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  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. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+var mainWindow = window.opener;
+var inputElement = null;
+var lineNumber = 0;
+var file = 0;
+
+function loaded()
+{
+    file = mainWindow.currentFile;
+    lineNumber = mainWindow.files[file].breakpointEditorWindows.indexOf(window);
+    
+    document.getElementsByTagName("title")[0].textContents = "Edit Breakpoint on Line " + lineNumber;
+    
+    var functionBody = mainWindow.files[file].breakpoints[lineNumber];
+    if(functionBody == "break")
+        functionBody = "return 1;";
+    else {
+        var startIndex = functionBody.indexOf("{") + 1;
+        var endIndex = functionBody.lastIndexOf("}");
+        functionBody = functionBody.substring(startIndex, endIndex);
+    }
+        
+    inputElement = document.getElementById("input");
+    inputElement.innerText = functionBody;
+    inputElement.focus();
+}
+
+function saveBreakpoint()
+{
+    mainWindow.finishEditingBreakpoint(lineNumber, file, "__drosera_breakpoint_conditional_func = function() { " + inputElement.innerText + " }; __drosera_breakpoint_conditional_func();");
+}
\ No newline at end of file
index 474d65b073f91e9693dcbd732d5fa7c5876691da..0ed00d189f85c4c5b5a3887767b476913377a41c 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006 David Smith (catfish.man@gmail.com)
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,6 +46,7 @@ var steppingStack = 0;
 var pauseOnNextStatement = false;
 var pausedWhileLeavingFrame = false;
 var consoleWindow = null;
+var enabledBreakpoint = "break";
 
 ScriptCallFrame = function (functionName, index, row)
 {
@@ -306,25 +308,59 @@ function removeStyleClass(element, className)
 function addBreakPoint(event)
 {
     var row = event.target.parentNode;
+    var file = files[currentFile];
+    var lineNum = parseInt(event.target.title);
+    
     if (hasStyleClass(row, "breakpoint")) {
-        if (hasStyleClass(row, "disabled")) {
-            removeStyleClass(row, "disabled");
-            files[currentFile].breakpoints[parseInt(event.target.title)] = 1;
-        } else {
-            addStyleClass(row, "disabled");
-            files[currentFile].breakpoints[parseInt(event.target.title)] = -1;
-        }
-    } else {
-        addStyleClass(row, "breakpoint");
-        removeStyleClass(row, "disabled");
-        files[currentFile].breakpoints[parseInt(event.target.title)] = 1;
-    }
+        if(event.altKey && file.breakpoints[lineNum] != null)
+            showBreakpointEditor(file, lineNum);
+        else
+            toggleBreakpoint(row, file, lineNum);    
+    } else
+        createBreakpoint(row, file, lineNum);
+}
+
+function createBreakpoint(row, file, lineNum)
+{
+    addStyleClass(row, "breakpoint");
+    removeStyleClass(row, "disabled");
+    file.breakpoints[lineNum] = enabledBreakpoint;
+    file.disabledBreakpoints[lineNum] = null;
+}
+
+function showBreakpointEditor(file, lineNum)
+{
+    var editors = file.breakpointEditorWindows;
+
+    if (editors[lineNum] == null)
+        editors[lineNum] = window.open("breakpointEditor.html", ("Edit Breakpoint On Line " + lineNum), "top=200, left=200, width=400, height=200, toolbar=no, resizable=yes");
+    else
+        editors[lineNum].focus();
+        
+    event.preventDefault();
+}
+
+function toggleBreakpoint(row, file, lineNum)
+{
+    if (hasStyleClass(row, "disabled"))
+        removeStyleClass(row, "disabled");    
+    else
+        addStyleClass(row, "disabled");
+    
+    var temp = file.breakpoints[lineNum];
+    file.breakpoints[lineNum] = file.disabledBreakpoints[lineNum];
+    file.disabledBreakpoints[lineNum] = temp;
+}
+
+function finishEditingBreakpoint(line, file, newFunction)
+{
+    files[file].breakpoints[line] = newFunction;
+    files[file].breakpointEditorWindows[line] = null;
 }
 
 function moveBreakPoint(event)
 {
     if (hasStyleClass(event.target.parentNode, "breakpoint")) {
-        files[currentFile].breakpoints[parseInt(event.target.title)] = 0;
         draggingBreakpoint = event.target;
         draggingBreakpoint.started = false;
         draggingBreakpoint.dragLastY = event.clientY + window.scrollY;
@@ -351,11 +387,21 @@ function breakpointDrag(event)
     var deltaX = draggingBreakpoint.dragLastX - x;
     var deltaY = draggingBreakpoint.dragLastY - y;
     if (draggingBreakpoint.started || deltaX > 4 || deltaY > 4 || deltaX < -4 || deltaY < -4) {
+    
         if (!draggingBreakpoint.started) {
             draggingBreakpoint.isDisabled = hasStyleClass(draggingBreakpoint.parentNode, "disabled");
             removeStyleClass(draggingBreakpoint.parentNode, "breakpoint");
             removeStyleClass(draggingBreakpoint.parentNode, "disabled");
             draggingBreakpoint.started = true;
+            
+            var lineNum = parseInt(draggingBreakpoint.title);
+            
+            if(draggingBreakpoint.isDisabled)
+                draggingBreakpoint.breakFunction = files[currentFile].disabledBreakpoints[lineNum];
+            else
+                draggingBreakpoint.breakFunction = files[currentFile].breakpoints[lineNum];
+            files[currentFile].breakpoints[lineNum] = null;
+            files[currentFile].disabledBreakpoints[lineNum] = null;
 
             var dragImage = sourcesDocument.createElement("img");
             if (draggingBreakpoint.isDisabled)
@@ -398,7 +444,7 @@ function breakpointDragEnd(event)
     var dragImage = sourcesDocument.getElementById("breakpointDrag");
     if (!dragImage)
         return;
-
+        
     dragImage.parentNode.removeChild(dragImage);
 
     var x = event.clientX + window.scrollX;
@@ -419,12 +465,18 @@ function breakpointDragEnd(event)
     var tr = table.childNodes.item(row - 1);
     if (!tr)
         return;
-
-    if (draggingBreakpoint.isDisabled)
+        
+    if(draggingBreakpoint.isDisabled) {
         addStyleClass(tr, "disabled");
-    addStyleClass(tr, "breakpoint");
-    file.breakpoints[row] = (draggingBreakpoint.isDisabled ? -1 : 1);
+        file.disabledBreakpoints[row] = draggingBreakpoint.breakFunction;
+        file.breakpoints[row] = null;
+    } else {
+        file.disabledBreakpoints[row] = null;
+        file.breakpoints[row] = draggingBreakpoint.breakFunction;
+    }
 
+    addStyleClass(tr, "breakpoint");
+    
     draggingBreakpoint = null;
 }
 
@@ -764,6 +816,8 @@ function didParseScript(source, fileSource, url, sourceId, baseLineNumber)
         file = new Object();
         file.scripts = new Array();
         file.breakpoints = new Array();
+        file.disabledBreakpoints = new Array();
+        file.breakpointEditorWindows = new Array();
         file.source = (fileSource.length ? fileSource : source);
         file.url = (url.length ? url : null);
         file.loaded = false;
@@ -836,8 +890,11 @@ function willExecuteStatement(sourceId, line, fromLeavingFrame)
         return;
 
     lastStatement = [sourceId, line];
-
-    if (pauseOnNextStatement || file.breakpoints[line] == 1 || (steppingOver && !steppingStack)) {
+    
+    var breakpoint = file.breakpoints[line];
+    var shouldBreak = breakpoint && (breakpoint == "break" || DebuggerDocument.evaluateScript_inCallFrame_(breakpoint, 0) == 1);
+    
+    if (pauseOnNextStatement || shouldBreak || (steppingOver && !steppingStack)) {
         pause();
         pauseOnNextStatement = false;
         pausedWhileLeavingFrame = fromLeavingFrame || false;