Title: [112064] trunk
Revision
112064
Author
[email protected]
Date
2012-03-26 01:56:30 -0700 (Mon, 26 Mar 2012)

Log Message

Web Inspector: breakpoints should be disabled while live editing _javascript_.
https://bugs.webkit.org/show_bug.cgi?id=81947

Reviewed by Yury Semikhatsky.

Source/WebCore:

This change disables (removes from the backend) the breakpoints while editing script.
Undoing or committing the change restores the breakpoints. Main logic is implemented within
_javascript_SourceFrame, but it required minor tweaking of the text editor: more correct
undo/redo wrapper and better detection of the noop opterations.

* inspector/front-end/_javascript_SourceFrame.js:
(WebInspector._javascript_SourceFrame):
(WebInspector._javascript_SourceFrame.prototype.afterTextChanged):
(WebInspector._javascript_SourceFrame.prototype.beforeTextChanged):
(WebInspector._javascript_SourceFrame.prototype.didEditContent):
(WebInspector._javascript_SourceFrame.prototype.addBreakpoint):
(WebInspector._javascript_SourceFrame.prototype.removeBreakpoint):
(WebInspector._javascript_SourceFrame.prototype._onMouseDown):
* inspector/front-end/TextEditorModel.js:
(WebInspector.TextEditorModel.endsWithBracketRegex.):
* inspector/front-end/TextViewer.js:
(WebInspector.TextEditorMainPanel.prototype.handleUndoRedo.before):
(WebInspector.TextEditorMainPanel.prototype.handleUndoRedo.after):
(WebInspector.TextEditorMainPanel.prototype.handleUndoRedo):
(WebInspector.TextEditorMainPanel.prototype._applyDomUpdates):

LayoutTests:

* inspector/editor/highlighter-basics-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (112063 => 112064)


--- trunk/LayoutTests/ChangeLog	2012-03-26 08:55:28 UTC (rev 112063)
+++ trunk/LayoutTests/ChangeLog	2012-03-26 08:56:30 UTC (rev 112064)
@@ -1,3 +1,12 @@
+2012-03-26  Pavel Feldman  <[email protected]>
+
+        Web Inspector: breakpoints should be disabled while live editing _javascript_.
+        https://bugs.webkit.org/show_bug.cgi?id=81947
+
+        Reviewed by Yury Semikhatsky.
+
+        * inspector/editor/highlighter-basics-expected.txt:
+
 2012-03-26  Csaba Osztrogonác  <[email protected]>
 
         Unreviewed gardening, remove non-existing tests from Skipped lists.

Modified: trunk/LayoutTests/inspector/editor/highlighter-basics-expected.txt (112063 => 112064)


--- trunk/LayoutTests/inspector/editor/highlighter-basics-expected.txt	2012-03-26 08:55:28 UTC (rev 112063)
+++ trunk/LayoutTests/inspector/editor/highlighter-basics-expected.txt	2012-03-26 08:56:30 UTC (rev 112064)
@@ -33,7 +33,7 @@
 1 : /** : _javascript_-comment[0-5]
 2 :  * line #1 : _javascript_-comment[0-10]
 3 :  * line #2 : _javascript_-comment[0-10]
-4 : /** : _javascript_-comment[0-10]
+4 : /** : null
 5 :  * line #1 : null
 6 :  * line #2 : null
 7 :  * line #3 : null
@@ -44,7 +44,7 @@
 12 :  * line #8 : null
 13 :  * var a = new A(); //*/ : null
 14 : some text : null
-15 :  * line #6 : null
+15 :  * line #6 : _javascript_-comment[0-10]
 16 :  * line #7 : _javascript_-comment[0-10]
 17 :  * line #8 : _javascript_-comment[0-10]
 18 :  * var a = new A(); //*/ : _javascript_-comment[0-24]

Modified: trunk/Source/WebCore/ChangeLog (112063 => 112064)


--- trunk/Source/WebCore/ChangeLog	2012-03-26 08:55:28 UTC (rev 112063)
+++ trunk/Source/WebCore/ChangeLog	2012-03-26 08:56:30 UTC (rev 112064)
@@ -1,3 +1,31 @@
+2012-03-26  Pavel Feldman  <[email protected]>
+
+        Web Inspector: breakpoints should be disabled while live editing _javascript_.
+        https://bugs.webkit.org/show_bug.cgi?id=81947
+
+        Reviewed by Yury Semikhatsky.
+
+        This change disables (removes from the backend) the breakpoints while editing script.
+        Undoing or committing the change restores the breakpoints. Main logic is implemented within
+        _javascript_SourceFrame, but it required minor tweaking of the text editor: more correct
+        undo/redo wrapper and better detection of the noop opterations.
+
+        * inspector/front-end/_javascript_SourceFrame.js:
+        (WebInspector._javascript_SourceFrame):
+        (WebInspector._javascript_SourceFrame.prototype.afterTextChanged):
+        (WebInspector._javascript_SourceFrame.prototype.beforeTextChanged):
+        (WebInspector._javascript_SourceFrame.prototype.didEditContent):
+        (WebInspector._javascript_SourceFrame.prototype.addBreakpoint):
+        (WebInspector._javascript_SourceFrame.prototype.removeBreakpoint):
+        (WebInspector._javascript_SourceFrame.prototype._onMouseDown):
+        * inspector/front-end/TextEditorModel.js:
+        (WebInspector.TextEditorModel.endsWithBracketRegex.):
+        * inspector/front-end/TextViewer.js:
+        (WebInspector.TextEditorMainPanel.prototype.handleUndoRedo.before):
+        (WebInspector.TextEditorMainPanel.prototype.handleUndoRedo.after):
+        (WebInspector.TextEditorMainPanel.prototype.handleUndoRedo):
+        (WebInspector.TextEditorMainPanel.prototype._applyDomUpdates):
+
 2012-03-25  Nat Duca  <[email protected]>
 
         [chromium] Route willBeginFrame from compositor to WebWidget

Modified: trunk/Source/WebCore/inspector/front-end/_javascript_SourceFrame.js (112063 => 112064)


--- trunk/Source/WebCore/inspector/front-end/_javascript_SourceFrame.js	2012-03-26 08:55:28 UTC (rev 112063)
+++ trunk/Source/WebCore/inspector/front-end/_javascript_SourceFrame.js	2012-03-26 08:56:30 UTC (rev 112064)
@@ -40,7 +40,6 @@
     this._scriptsPanel = scriptsPanel;
     this._model = model;
     this._uiSourceCode = uiSourceCode;
-    this._breakpoints = {};
 
     WebInspector.SourceFrame.call(this, uiSourceCode.url);
 
@@ -110,7 +109,7 @@
 
             function addConditionalBreakpoint()
             {
-                this.addBreakpoint(lineNumber, true, true, true);
+                this.addBreakpoint(lineNumber, true, true, true, false);
                 function didEditBreakpointCondition(committed, condition)
                 {
                     this.removeBreakpoint(lineNumber);
@@ -159,68 +158,53 @@
 
     afterTextChanged: function(oldRange, newRange)
     {
-        if (!oldRange || !newRange)
-            return;
-
-        // Adjust execution line number.
-        if (typeof this._executionLineNumber === "number") {
-            var newExecutionLineNumber = this._lineNumberAfterEditing(this._executionLineNumber, oldRange, newRange);
-            this.clearExecutionLine();
-            this.setExecutionLine(newExecutionLineNumber);
-        }
-
-        // Adjust breakpoints.
-        var oldBreakpoints = this._breakpoints;
-        this._breakpoints = {};
-        for (var lineNumber in oldBreakpoints) {
-            lineNumber = Number(lineNumber);
-            var breakpoint = oldBreakpoints[lineNumber];
-            var newLineNumber = this._lineNumberAfterEditing(lineNumber, oldRange, newRange);
-            if (lineNumber === newLineNumber)
-                this._breakpoints[lineNumber] = breakpoint;
-            else {
-                this.removeBreakpoint(lineNumber);
-                this.addBreakpoint(newLineNumber, breakpoint.resolved, breakpoint.conditional, breakpoint.enabled);
-            }
-        }
-
-        this._scriptsPanel.setScriptSourceIsDirty(this._uiSourceCode, this.textModel.copyRange() !== this._originalContent);
+        var isDirty = this.textModel.copyRange() !== this._originalContent;
+        if (isDirty)
+            this._scriptsPanel.setScriptSourceIsDirty(this._uiSourceCode, true);
+        else
+            this.didEditContent(null, this._originalContent);
     },
 
     beforeTextChanged: function()
     {
-        if (!this._javaScriptSourceFrameState) {
-            this._javaScriptSourceFrameState = {
-                executionLineNumber: this._executionLineNumber,
-                breakpoints: this._breakpoints
+        if (!this._isDirty) {
+            // Disable all breakpoints in the model, store them as muted breakpoints.
+            for (var lineNumber = 0; lineNumber < this.textModel.linesCount; ++lineNumber) {
+                var breakpoint = this.textModel.getAttribute(lineNumber, "breakpoint");
+                if (breakpoint) {
+                    this._model.removeBreakpoint(this._uiSourceCode, lineNumber);
+                    // Re-adding decoration only.
+                    this.addBreakpoint(lineNumber, breakpoint.resolved, breakpoint.conditional, breakpoint.enabled, true); 
+                }
             }
         }
+
+        this._isDirty = true;
         WebInspector.SourceFrame.prototype.beforeTextChanged.call(this);
     },
 
     didEditContent: function(error, content)
     {
         delete this._editingContent;
+
         WebInspector.SourceFrame.prototype.didEditContent.call(this, error, content);
         if (error)
             return;
 
         this._originalContent = content;
-        var newBreakpoints = {};
-        for (var lineNumber in this._breakpoints) {
-            newBreakpoints[lineNumber] = this._breakpoints[lineNumber];
-            this.removeBreakpoint(Number(lineNumber));
-        }
+        this._isDirty = false;
 
-        for (var lineNumber in this._javaScriptSourceFrameState.breakpoints)
-            this._model.removeBreakpoint(this._uiSourceCode, Number(lineNumber));
-
-        for (var lineNumber in newBreakpoints) {
-            var breakpoint = newBreakpoints[lineNumber];
-            this._setBreakpoint(Number(lineNumber), breakpoint.condition, breakpoint.enabled);
+        // Restore all muted breakpoints.
+        for (var lineNumber = 0; lineNumber < this.textModel.linesCount; ++lineNumber) {
+            var breakpoint = this.textModel.getAttribute(lineNumber, "breakpoint");
+            if (breakpoint) {
+                // Remove fake decoration
+                this.removeBreakpoint(lineNumber);
+                // Set new breakpoint
+                this._setBreakpoint(lineNumber, breakpoint.condition, breakpoint.enabled);
+            }
         }
         this._scriptsPanel.setScriptSourceIsDirty(this._uiSourceCode, false);
-        delete this._javaScriptSourceFrameState;
     },
 
     _getPopoverAnchor: function(element, event)
@@ -332,16 +316,18 @@
         return container;
     },
 
-    addBreakpoint: function(lineNumber, resolved, conditional, enabled)
+    addBreakpoint: function(lineNumber, resolved, conditional, enabled, mutedWhileEditing)
     {
-        this._breakpoints[lineNumber] = {
+        var breakpoint = {
             resolved: resolved,
             conditional: conditional,
             enabled: enabled
         };
+        this.textModel.setAttribute(lineNumber, "breakpoint", breakpoint);
+
         this.textViewer.beginUpdates();
         this.textViewer.addDecoration(lineNumber, "webkit-breakpoint");
-        if (!enabled)
+        if (!enabled || mutedWhileEditing)
             this.textViewer.addDecoration(lineNumber, "webkit-breakpoint-disabled");
         if (conditional)
             this.textViewer.addDecoration(lineNumber, "webkit-breakpoint-conditional");
@@ -350,7 +336,7 @@
 
     removeBreakpoint: function(lineNumber)
     {
-        delete this._breakpoints[lineNumber];
+        this.textModel.removeAttribute(lineNumber, "breakpoint");
         this.textViewer.beginUpdates();
         this.textViewer.removeDecoration(lineNumber, "webkit-breakpoint");
         this.textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
@@ -366,6 +352,9 @@
 
     _onMouseDown: function(event)
     {
+        if (this._isDirty)
+            return;
+
         if (event.button != 0 || event.altKey || event.ctrlKey || event.metaKey)
             return;
         var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");

Modified: trunk/Source/WebCore/inspector/front-end/TextEditorModel.js (112063 => 112064)


--- trunk/Source/WebCore/inspector/front-end/TextEditorModel.js	2012-03-26 08:55:28 UTC (rev 112063)
+++ trunk/Source/WebCore/inspector/front-end/TextEditorModel.js	2012-03-26 08:56:30 UTC (rev 112064)
@@ -160,11 +160,19 @@
             postCaret += newLines[0].length;
         } else {
             this._setLine(range.startLine, prefix + newLines[0]);
+
             for (var i = 1; i < newLines.length; ++i)
-                this._insertLine(range.startLine + i, newLines[i]);
+                this._lines.splice(range.startLine + i, 0, newLines[i]);
+            // Adjust attributes, attributes move with the first character of line.
+            var spliceParameters = new Array(newLines.length + 1); // 2 + number of items to insert.
+            spliceParameters[0] = range.startColumn ? range.startLine + 1 : range.startLine;
+            spliceParameters[1] = 0;
+            this._attributes.splice.apply(this._attributes, spliceParameters);
+
             this._setLine(range.startLine + newLines.length - 1, newLines[newLines.length - 1] + suffix);
             postCaret = newLines[newLines.length - 1].length;
         }
+
         return new WebInspector.TextRange(range.startLine, range.startColumn,
                                           range.startLine + newLines.length - 1, postCaret);
     },
@@ -177,8 +185,11 @@
         var prefix = this._lines[range.startLine].substring(0, range.startColumn);
         var suffix = this._lines[range.endLine].substring(range.endColumn);
 
-        if (range.endLine > range.startLine)
-            this._removeLines(range.startLine + 1, range.endLine - range.startLine);
+        if (range.endLine > range.startLine) {
+            this._lines.splice(range.startLine + 1, range.endLine - range.startLine);
+            // Adjust attributes, attributes move with the first character of line.
+            this._attributes.splice(range.startColumn ? range.startLine + 1 : range.startLine, range.endLine - range.startLine);
+        }
         this._setLine(range.startLine, prefix + suffix);
     },
 
@@ -187,18 +198,6 @@
         this._lines[lineNumber] = text;
     },
 
-    _removeLines: function(fromLine, count)
-    {
-        this._lines.splice(fromLine, count);
-        this._attributes.splice(fromLine, count);
-    },
-
-    _insertLine: function(lineNumber, text)
-    {
-        this._lines.splice(lineNumber, 0, text);
-        this._attributes.splice(lineNumber, 0, {});
-    },
-
     wordRange: function(lineNumber, column)
     {
         return new WebInspector.TextRange(lineNumber, this.wordStart(lineNumber, column, true), lineNumber, this.wordEnd(lineNumber, column, true));
@@ -282,38 +281,43 @@
         return command;
     },
 
-    undo: function(callback)
+    undo: function(beforeCallback, afterCallback)
     {
         this._markRedoableState();
 
         this._inUndo = true;
-        var range = this._doUndo(this._undoStack, callback);
+        var range = this._doUndo(this._undoStack, beforeCallback, afterCallback);
         delete this._inUndo;
 
         return range;
     },
 
-    redo: function(callback)
+    redo: function(beforeCallback, afterCallback)
     {
         this.markUndoableState();
 
         this._inRedo = true;
-        var range = this._doUndo(this._redoStack, callback);
+        var range = this._doUndo(this._redoStack, beforeCallback, afterCallback);
         delete this._inRedo;
 
         return range;
     },
 
-    _doUndo: function(stack, callback)
+    _doUndo: function(stack, beforeCallback, afterCallback)
     {
         var range = null;
         for (var i = stack.length - 1; i >= 0; --i) {
             var command = stack[i];
             stack.length = i;
 
+            if (beforeCallback)
+                beforeCallback();
+
             range = this.setText(command.range, command.text);
-            if (callback)
-                callback(command.range, range);
+
+            if (afterCallback)
+                afterCallback(command.range, range);
+
             if (i > 0 && stack[i - 1].explicit)
                 return range;
         }

Modified: trunk/Source/WebCore/inspector/front-end/TextViewer.js (112063 => 112064)


--- trunk/Source/WebCore/inspector/front-end/TextViewer.js	2012-03-26 08:55:28 UTC (rev 112063)
+++ trunk/Source/WebCore/inspector/front-end/TextViewer.js	2012-03-26 08:56:30 UTC (rev 112064)
@@ -1069,15 +1069,19 @@
             return false;
 
         this.beginUpdates();
-        this._enterTextChangeMode();
 
-        function callback(oldRange, newRange)
+        function before()
         {
-            this._exitTextChangeMode(oldRange, newRange);
             this._enterTextChangeMode();
         }
-        var range = redo ? this._textModel.redo(callback.bind(this)) : this._textModel.undo(callback.bind(this));
-        this._exitTextChangeMode(null, null);
+
+        function after(oldRange, newRange)
+        {
+            this._exitTextChangeMode(oldRange, newRange);
+        }
+
+        var range = redo ? this._textModel.redo(before.bind(this), after.bind(this)) : this._textModel.undo(before.bind(this), after.bind(this));
+
         this.endUpdates();
 
         // Restore location post-repaint.
@@ -1754,11 +1758,7 @@
             return;
         }
 
-        // This is a "foreign" call outside of this class. Should be before we delete the dirty lines flag.
-        this._enterTextChangeMode();
-
         var dirtyLines = this._dirtyLines;
-        delete this._dirtyLines;
 
         var firstChunkNumber = this._chunkNumberForLine(dirtyLines.start);
         var startLine = this._textChunks[firstChunkNumber].startLine;
@@ -1836,8 +1836,19 @@
         else
             var oldRange = new WebInspector.TextRange(startLine, startColumn, endLine - 1, endColumn);
 
-        var newRange = this._setText(oldRange, lines.join("\n"));
+        var newContent = lines.join("\n");
+        if (this._textModel.copyRange(oldRange) === newContent) {
+            delete this._dirtyLines;
+            return; // Noop
+        }
 
+        // This is a "foreign" call outside of this class. Should be before we delete the dirty lines flag.
+        this._enterTextChangeMode();
+
+        delete this._dirtyLines;
+
+        var newRange = this._setText(oldRange, newContent);
+
         this._paintScheduledLines(true);
         this._restoreSelection(selection);
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to